From 7f656f3d73f0387af0740796f5139fd6780e72ea Mon Sep 17 00:00:00 2001 From: BotoX Date: Sat, 28 Sep 2019 17:15:29 +0200 Subject: [PATCH] New plugin: FixVPhysicsCrush refactor FixGameUI to new syntax. --- FixGameUI/scripting/FixGameUI.sp | 64 ++++----- .../gamedata/FixVPhysicsCrush.games.txt | 19 +++ .../scripting/FixVPhysicsCrush.sp | 128 ++++++++++++++++++ 3 files changed, 176 insertions(+), 35 deletions(-) create mode 100644 FixVPhysicsCrush/gamedata/FixVPhysicsCrush.games.txt create mode 100644 FixVPhysicsCrush/scripting/FixVPhysicsCrush.sp diff --git a/FixGameUI/scripting/FixGameUI.sp b/FixGameUI/scripting/FixGameUI.sp index d088cd0b..9d571366 100644 --- a/FixGameUI/scripting/FixGameUI.sp +++ b/FixGameUI/scripting/FixGameUI.sp @@ -1,26 +1,24 @@ #pragma semicolon 1 +#pragma newdecls required #include -#include -#include -#include #include #include #include -public Plugin:myinfo = +public Plugin myinfo = { name = "FixGameUI", author = "hlstriker + GoD-Tony", - description = "Fixes game_ui entity bug.", + description = "Fixes game_ui entity bug and blocks DMG_CRUSH.", version = "1.0", url = "" } -new g_iAttachedGameUI[MAXPLAYERS+1]; -new Handle:g_hAcceptInput = INVALID_HANDLE; +Handle g_hAcceptInput; +int g_iAttachedGameUI[MAXPLAYERS + 1]; -public OnPluginStart() +public void OnPluginStart() { HookEvent("player_death", Event_PlayerDeath, EventHookMode_Post); @@ -30,17 +28,13 @@ public OnPluginStart() // Gamedata. Handle hConfig = LoadGameConfigFile("sdktools.games"); if (hConfig == INVALID_HANDLE) - { SetFailState("Couldn't load sdktools game config!"); - return; - } - new offset = GameConfGetOffset(hConfig, "AcceptInput"); + int offset = GameConfGetOffset(hConfig, "AcceptInput"); if (offset == -1) - { SetFailState("Failed to find AcceptInput offset"); - } - CloseHandle(hConfig); + + delete hConfig; // DHooks. g_hAcceptInput = DHookCreate(offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, Hook_AcceptInput); @@ -52,25 +46,25 @@ public OnPluginStart() } -public Action:Event_PlayerDeath(Handle:hEvent, const String:szName[], bool:bDontBroadcast) +public Action Event_PlayerDeath(Handle hEvent, const char[] szName, bool bDontBroadcast) { - new iClient = GetClientOfUserId(GetEventInt(hEvent, "userid")); - RemoveFromGameUI(iClient); - SetClientViewEntity(iClient, iClient); + int client = GetClientOfUserId(GetEventInt(hEvent, "userid")); + RemoveFromGameUI(client); + SetClientViewEntity(client, client); - new iFlags = GetEntityFlags(iClient); + int iFlags = GetEntityFlags(client); iFlags &= ~FL_ONTRAIN; iFlags &= ~FL_FROZEN; iFlags &= ~FL_ATCONTROLS; - SetEntityFlags(iClient, iFlags); + SetEntityFlags(client, iFlags); } -public OnClientDisconnect(iClient) +public void OnClientDisconnect(int client) { - RemoveFromGameUI(iClient); + RemoveFromGameUI(client); } -public GameUI_PlayerOn(const String:szOutput[], iCaller, iActivator, Float:fDelay) +public void GameUI_PlayerOn(const char[] szOutput, int iCaller, int iActivator, float fDelay) { if(!(1 <= iActivator <= MaxClients)) return; @@ -78,7 +72,7 @@ public GameUI_PlayerOn(const String:szOutput[], iCaller, iActivator, Float:fDela g_iAttachedGameUI[iActivator] = EntIndexToEntRef(iCaller); } -public GameUI_PlayerOff(const String:szOutput[], iCaller, iActivator, Float:fDelay) +public void GameUI_PlayerOff(const char[] szOutput, int iCaller, int iActivator, float fDelay) { if(!(1 <= iActivator <= MaxClients)) return; @@ -86,19 +80,19 @@ public GameUI_PlayerOff(const String:szOutput[], iCaller, iActivator, Float:fDel g_iAttachedGameUI[iActivator] = 0; } -RemoveFromGameUI(iClient) +void RemoveFromGameUI(int client) { - if(!g_iAttachedGameUI[iClient]) + if(!g_iAttachedGameUI[client]) return; - new iEnt = EntRefToEntIndex(g_iAttachedGameUI[iClient]); - if(iEnt == INVALID_ENT_REFERENCE) + int entity = EntRefToEntIndex(g_iAttachedGameUI[client]); + if(entity == INVALID_ENT_REFERENCE) return; - AcceptEntityInput(iEnt, "Deactivate", iClient, iEnt); + AcceptEntityInput(entity, "Deactivate", client, entity); } -public OnEntityCreated(entity, const String:classname[]) +public void OnEntityCreated(int entity, const char[] classname) { if (StrEqual(classname, "game_ui")) { @@ -106,14 +100,14 @@ public OnEntityCreated(entity, const String:classname[]) } } -public MRESReturn:Hook_AcceptInput(thisptr, Handle:hReturn, Handle:hParams) +public MRESReturn Hook_AcceptInput(int thisptr, Handle hReturn, Handle hParams) { - new String:sCommand[128]; + char sCommand[128]; DHookGetParamString(hParams, 1, sCommand, sizeof(sCommand)); - if (StrEqual(sCommand, "Deactivate")) + if (StrEqual(sCommand, "Deactivate", false)) { - new pPlayer = GetEntPropEnt(thisptr, Prop_Data, "m_player"); + int pPlayer = GetEntPropEnt(thisptr, Prop_Data, "m_player"); if (pPlayer == -1) { diff --git a/FixVPhysicsCrush/gamedata/FixVPhysicsCrush.games.txt b/FixVPhysicsCrush/gamedata/FixVPhysicsCrush.games.txt new file mode 100644 index 00000000..961ed42d --- /dev/null +++ b/FixVPhysicsCrush/gamedata/FixVPhysicsCrush.games.txt @@ -0,0 +1,19 @@ +"Games" +{ + "cstrike" + { + "Offsets" + { + "SetGameFlags" + { + "linux" "19" + "windows" "18" + } + "GetGameFlags" + { + "linux" "20" + "windows" "19" + } + } + } +} diff --git a/FixVPhysicsCrush/scripting/FixVPhysicsCrush.sp b/FixVPhysicsCrush/scripting/FixVPhysicsCrush.sp new file mode 100644 index 00000000..2b20909e --- /dev/null +++ b/FixVPhysicsCrush/scripting/FixVPhysicsCrush.sp @@ -0,0 +1,128 @@ +#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("FixGameUI.games"); + if(!hGameData) + SetFailState("Couldn't load FixGameUI 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); +}