From ef5263ef9eb63e4781a4de7b418b96b2acd655b4 Mon Sep 17 00:00:00 2001 From: FlaminSarge Date: Mon, 12 Aug 2013 01:18:01 +0100 Subject: [PATCH] Add support for more CalcIsAttackCritical helpers. (bug 5576, r=asherkin) --- extensions/tf2/criticals.cpp | 123 +++++++++++++++++++++++++++++++++-- gamedata/sm-tf2.games.txt | 21 ++++++ 2 files changed, 140 insertions(+), 4 deletions(-) diff --git a/extensions/tf2/criticals.cpp b/extensions/tf2/criticals.cpp index f072cc36..ebf500fb 100644 --- a/extensions/tf2/criticals.cpp +++ b/extensions/tf2/criticals.cpp @@ -30,12 +30,18 @@ */ #include "criticals.h" +#include "util.h" IServerGameEnts *gameents = NULL; CDetour *calcIsAttackCriticalDetour = NULL; CDetour *calcIsAttackCriticalMeleeDetour = NULL; CDetour *calcIsAttackCriticalBowDetour = NULL; +CDetour *calcIsAttackCriticalKnifeDetour = NULL; +CDetour *calcIsAttackCriticalNoCritsDetour = NULL; +CDetour *calcIsAttackCriticalNoCritsMeleeDetour = NULL; + +int nextMeleeCritOffset = -1; IForward *g_critForward = NULL; @@ -79,7 +85,7 @@ int CheckBaseHandle(CBaseHandle &hndl) return index; } -DetourResult DetourCallback(CBaseEntity *pEnt) +DetourResult DetourCallback(CBaseEntity *pEnt, bool bMeleeNoCrits) { edict_t *pEdict = gameents->BaseEntityToEdict((CBaseEntity *)pEnt); @@ -108,6 +114,14 @@ DetourResult DetourCallback(CBaseEntity *pEnt) CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEnt + info.actual_offset); int index = CheckBaseHandle(hndl); + //Skip CTFWeaponBaseMelee::CalcIsAttackCriticalHelperNoCrits if m_iNextMeleeCrit is not 2 + if (bMeleeNoCrits) + { + CBaseEntity *pPlayer = UTIL_GetCBaseEntity(index, true); + if (pPlayer && *(uint32_t *)((intptr_t)pPlayer + nextMeleeCritOffset) != 2) + return Result_Ignore; + } + g_critForward->PushCell(index); //Client index g_critForward->PushCell(engine->IndexOfEdict(pEdict)); // Weapon index g_critForward->PushString(pEdict->GetClassName()); //Weapon classname @@ -136,7 +150,7 @@ DetourResult DetourCallback(CBaseEntity *pEnt) DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperMelee, bool) { - DetourResult result = DetourCallback((CBaseEntity *)this); + DetourResult result = DetourCallback((CBaseEntity *)this, false); if (result == Result_Ignore) { @@ -154,7 +168,7 @@ DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperMelee, bool) DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelper, bool) { - DetourResult result = DetourCallback((CBaseEntity *)this); + DetourResult result = DetourCallback((CBaseEntity *)this, false); if (result == Result_Ignore) { @@ -172,7 +186,7 @@ DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelper, bool) DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperBow, bool) { - DetourResult result = DetourCallback((CBaseEntity *)this); + DetourResult result = DetourCallback((CBaseEntity *)this, false); if (result == Result_Ignore) { @@ -188,11 +202,70 @@ DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperBow, bool) } } +DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperKnife, bool) +{ + DetourResult result = DetourCallback((CBaseEntity *)this, false); + + if (result == Result_Ignore) + { + return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperKnife)(); + } + else if (result == Result_NoCrit) + { + return 0; + } + else + { + return 1; + } +} + +DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperNoCrits, bool) +{ + DetourResult result = DetourCallback((CBaseEntity *)this, false); + + if (result == Result_Ignore) + { + return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperNoCrits)(); + } + else if (result == Result_NoCrit) + { + return 0; + } + else + { + return 1; + } +} + +DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperNoCritsMelee, bool) +{ + DetourResult result = DetourCallback((CBaseEntity *)this, true); + + if (result == Result_Ignore) + { + return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperNoCritsMelee)(); + } + else if (result == Result_NoCrit) + { + return 0; + } + else + { + return 1; + } +} + bool InitialiseCritDetours() { + sm_sendprop_info_t prop; + calcIsAttackCriticalDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelper, "CalcCritical"); calcIsAttackCriticalMeleeDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperMelee, "CalcCriticalMelee"); calcIsAttackCriticalBowDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperBow, "CalcCriticalBow"); + calcIsAttackCriticalKnifeDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperKnife, "CalcCriticalKnife"); + calcIsAttackCriticalNoCritsDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperNoCrits, "CalcCriticalNoCrits"); + calcIsAttackCriticalNoCritsMeleeDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperNoCritsMelee, "CalcCriticalNoCritsMelee"); bool HookCreated = false; @@ -214,6 +287,30 @@ bool InitialiseCritDetours() HookCreated = true; } + if (calcIsAttackCriticalKnifeDetour != NULL) + { + calcIsAttackCriticalKnifeDetour->EnableDetour(); + HookCreated = true; + } + + if (calcIsAttackCriticalNoCritsDetour != NULL) + { + calcIsAttackCriticalNoCritsDetour->EnableDetour(); + HookCreated = true; + } + + if (calcIsAttackCriticalNoCritsMeleeDetour != NULL) + { + calcIsAttackCriticalNoCritsMeleeDetour->EnableDetour(); + if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_iNextMeleeCrit", &prop)) + { + g_pSM->LogError(myself, "Failed to find m_iNextMeleeCrit prop offset"); + return false; + } + nextMeleeCritOffset = prop.actual_offset; + HookCreated = true; + } + if (HookCreated) { return true; @@ -243,4 +340,22 @@ void RemoveCritDetours() calcIsAttackCriticalBowDetour->Destroy(); calcIsAttackCriticalBowDetour = NULL; } + + if (calcIsAttackCriticalKnifeDetour != NULL) + { + calcIsAttackCriticalKnifeDetour->Destroy(); + calcIsAttackCriticalKnifeDetour = NULL; + } + + if (calcIsAttackCriticalNoCritsDetour != NULL) + { + calcIsAttackCriticalNoCritsDetour->Destroy(); + calcIsAttackCriticalNoCritsDetour = NULL; + } + + if (calcIsAttackCriticalNoCritsMeleeDetour != NULL) + { + calcIsAttackCriticalNoCritsMeleeDetour->Destroy(); + calcIsAttackCriticalNoCritsMeleeDetour = NULL; + } } diff --git a/gamedata/sm-tf2.games.txt b/gamedata/sm-tf2.games.txt index cab0bdd5..e4410efd 100644 --- a/gamedata/sm-tf2.games.txt +++ b/gamedata/sm-tf2.games.txt @@ -57,6 +57,27 @@ "mac" "@_ZN14CTFCompoundBow26CalcIsAttackCriticalHelperEv" "windows" "\xE8\x2A\x2A\x2A\x2A\x85\xC0\x74\x2A\x8D\x88\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x84\xC0\x74\x2A\xB0" } + "CalcCriticalKnife" + { + "library" "server" + "linux" "@_ZN8CTFKnife26CalcIsAttackCriticalHelperEv" + "mac" "@_ZN8CTFKnife26CalcIsAttackCriticalHelperEv" + "windows" "\x8B\x81\x54\x07\x00\x00\x83\xF8\xFF\x74\x2A\x8B\x15\x2A\x2A\x2A\x2A\x8B\xC8\x81\xE1\xFF\x0F\x00\x00\x03\xC9\x8D\x4C\xCA\x04\xC1\xE8\x0C\x39\x41\x04\x75\x2A\x8B\x01" + } + "CalcCriticalNoCrits" + { + "library" "server" + "linux" "@_ZN13CTFWeaponBase33CalcIsAttackCriticalHelperNoCritsEv" + "mac" "@_ZN13CTFWeaponBase33CalcIsAttackCriticalHelperNoCritsEv" + "windows" "\x56\x6A\x00\x68\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\x6A\x00\xE8\x2A\x2A\x2A\x2A\x50\xE8\x2A\x2A\x2A\x2A\x8B\xF0\x83\xC4\x14\x85\xF6\x74\x2A" + } + "CalcCriticalNoCritsMelee" + { + "library" "server" + "linux" "@_ZN18CTFWeaponBaseMelee33CalcIsAttackCriticalHelperNoCritsEv" + "mac" "@_ZN18CTFWeaponBaseMelee33CalcIsAttackCriticalHelperNoCritsEv" + "windows" "\x56\x57\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x8B\xF0\x85\xF6\x74\x2A\x8B\x06\x8B\x90\x40\x01\x00\x00\x8B\xCE\xFF\xD2\x84\xC0\x75\x2A\x5F\x32\xC0\x5E\xC3\x83\xBE\x80\x1D\x00\x00\x02" + } "Regenerate" { "library" "server"