#pragma semicolon 1 #pragma newdecls required #include #include #include #define FVPHYSICS_NO_IMPACT_DMG 0x0400 // don't do impact damage to anything public Plugin myinfo = { name = "FixVPhysicsCrush", author = "BotoX", description = "", version = "0.0", url = "" }; Handle g_hAcceptInput; Handle g_hSetGameFlags; Handle g_hGetGameFlags; int g_hPhysicsObject; public void OnPluginStart() { Handle hGameData = LoadGameConfigFile("sdktools.games"); if(!hGameData) SetFailState("Couldn't load sdktools gamedata."); // CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID ) int Offset = GameConfGetOffset(hGameData, "AcceptInput"); if(Offset == -1) SetFailState("Failed to find AcceptInput offset."); g_hAcceptInput = DHookCreate(Offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, OnAcceptInput); if(g_hAcceptInput == INVALID_HANDLE) SetFailState("Failed to DHook AcceptInput."); DHookAddParam(g_hAcceptInput, HookParamType_CharPtr); DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity); DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity); DHookAddParam(g_hAcceptInput, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20 DHookAddParam(g_hAcceptInput, HookParamType_Int); hGameData = LoadGameConfigFile("FixVPhysicsCrush.games"); if(!hGameData) SetFailState("Couldn't load FixVPhysicsCrush gamedata."); // CPhysicsObject::SetGameFlags(unsigned short) StartPrepSDKCall(SDKCall_Raw); if(!PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, "SetGameFlags")) { delete hGameData; SetFailState("PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, \"SetGameFlags\") failed!"); } PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain); g_hSetGameFlags = EndPrepSDKCall(); // CPhysicsObject::GetGameFlags() StartPrepSDKCall(SDKCall_Raw); if(!PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, "GetGameFlags")) { delete hGameData; SetFailState("PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, \"GetGameFlags\") failed!"); } PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain); g_hGetGameFlags = EndPrepSDKCall(); int hCollisionGroup = FindSendPropInfo("CBaseEntity", "m_CollisionGroup"); if (hCollisionGroup == -1) SetFailState("Couldn't find CBaseEntity::m_CollisionGroup"); // CNetworkVar( int, m_CollisionGroup ); // IPhysicsObject *m_pPhysicsObject; g_hPhysicsObject = hCollisionGroup + 4; // Late load. int entity = INVALID_ENT_REFERENCE; while((entity = FindEntityByClassname(entity, "phys_thruster")) != INVALID_ENT_REFERENCE) { OnEntityCreated(entity, "phys_thruster"); } } public void OnEntityCreated(int entity, const char[] classname) { if(StrEqual(classname, "phys_thruster")) { DHookEntity(g_hAcceptInput, true, entity); } } public MRESReturn OnAcceptInput(int entity, Handle hReturn, Handle hParams) { char sCommand[128]; DHookGetParamString(hParams, 1, sCommand, sizeof(sCommand)); if(StrEqual(sCommand, "Activate", false)) { int attachedObject = GetEntPropEnt(entity, Prop_Data, "m_attachedObject"); if(attachedObject) { int vphysObj = GetVPhysicsObject(attachedObject); if(vphysObj) { int flags = VPhysicsGetGameFlags(vphysObj); flags |= FVPHYSICS_NO_IMPACT_DMG; VPhysicsSetGameFlags(vphysObj, flags); } } } } int VPhysicsGetGameFlags(int vphysicsObj) { return SDKCall(g_hGetGameFlags, vphysicsObj); } void VPhysicsSetGameFlags(int vphysicsObj, int flags) { SDKCall(g_hSetGameFlags, vphysicsObj, flags); } int GetVPhysicsObject(int entity) { return GetEntData(entity, g_hPhysicsObject, 4); }