extensions/tf2/criticals.cpp
changeset 4001 608bc5be1ef0
parent 3159 608c56ebced9
child 4092 f184c016f489
     1.1 --- a/extensions/tf2/criticals.cpp	Mon Aug 12 01:11:11 2013 +0100
     1.2 +++ b/extensions/tf2/criticals.cpp	Mon Aug 12 01:18:01 2013 +0100
     1.3 @@ -30,12 +30,18 @@
     1.4   */
     1.5  
     1.6  #include "criticals.h"
     1.7 +#include "util.h"
     1.8  
     1.9  IServerGameEnts *gameents = NULL;
    1.10  
    1.11  CDetour *calcIsAttackCriticalDetour = NULL;
    1.12  CDetour *calcIsAttackCriticalMeleeDetour = NULL;
    1.13  CDetour *calcIsAttackCriticalBowDetour = NULL;
    1.14 +CDetour *calcIsAttackCriticalKnifeDetour = NULL;
    1.15 +CDetour *calcIsAttackCriticalNoCritsDetour = NULL;
    1.16 +CDetour *calcIsAttackCriticalNoCritsMeleeDetour = NULL;
    1.17 +
    1.18 +int nextMeleeCritOffset = -1;
    1.19  
    1.20  IForward *g_critForward = NULL;
    1.21  
    1.22 @@ -79,7 +85,7 @@
    1.23  	return index;
    1.24  }
    1.25  
    1.26 -DetourResult DetourCallback(CBaseEntity *pEnt)
    1.27 +DetourResult DetourCallback(CBaseEntity *pEnt, bool bMeleeNoCrits)
    1.28  {
    1.29  	edict_t *pEdict = gameents->BaseEntityToEdict((CBaseEntity *)pEnt);
    1.30  
    1.31 @@ -108,6 +114,14 @@
    1.32  	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEnt + info.actual_offset);
    1.33  	int index = CheckBaseHandle(hndl);
    1.34  
    1.35 +	//Skip CTFWeaponBaseMelee::CalcIsAttackCriticalHelperNoCrits if m_iNextMeleeCrit is not 2
    1.36 +	if (bMeleeNoCrits)
    1.37 +	{
    1.38 +		CBaseEntity *pPlayer = UTIL_GetCBaseEntity(index, true);
    1.39 +		if (pPlayer && *(uint32_t *)((intptr_t)pPlayer + nextMeleeCritOffset) != 2)
    1.40 +			return Result_Ignore;
    1.41 +	}
    1.42 +
    1.43  	g_critForward->PushCell(index); //Client index
    1.44  	g_critForward->PushCell(engine->IndexOfEdict(pEdict)); // Weapon index
    1.45  	g_critForward->PushString(pEdict->GetClassName()); //Weapon classname
    1.46 @@ -136,7 +150,7 @@
    1.47  
    1.48  DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperMelee, bool)
    1.49  {
    1.50 -	DetourResult result = DetourCallback((CBaseEntity *)this);
    1.51 +	DetourResult result = DetourCallback((CBaseEntity *)this, false);
    1.52  
    1.53  	if (result == Result_Ignore)
    1.54  	{
    1.55 @@ -154,7 +168,7 @@
    1.56  
    1.57  DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelper, bool)
    1.58  {
    1.59 -	DetourResult result = DetourCallback((CBaseEntity *)this);
    1.60 +	DetourResult result = DetourCallback((CBaseEntity *)this, false);
    1.61  
    1.62  	if (result == Result_Ignore)
    1.63  	{
    1.64 @@ -172,7 +186,7 @@
    1.65  
    1.66  DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperBow, bool)
    1.67  {
    1.68 -	DetourResult result = DetourCallback((CBaseEntity *)this);
    1.69 +	DetourResult result = DetourCallback((CBaseEntity *)this, false);
    1.70  
    1.71  	if (result == Result_Ignore)
    1.72  	{
    1.73 @@ -188,11 +202,70 @@
    1.74  	}
    1.75  }
    1.76  
    1.77 +DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperKnife, bool)
    1.78 +{
    1.79 +	DetourResult result = DetourCallback((CBaseEntity *)this, false);
    1.80 +
    1.81 +	if (result == Result_Ignore)
    1.82 +	{
    1.83 +		return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperKnife)();
    1.84 +	}
    1.85 +	else if (result == Result_NoCrit)
    1.86 +	{
    1.87 +		return 0;
    1.88 +	}
    1.89 +	else
    1.90 +	{
    1.91 +		return 1;
    1.92 +	}
    1.93 +}
    1.94 +
    1.95 +DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperNoCrits, bool)
    1.96 +{
    1.97 +	DetourResult result = DetourCallback((CBaseEntity *)this, false);
    1.98 +
    1.99 +	if (result == Result_Ignore)
   1.100 +	{
   1.101 +		return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperNoCrits)();
   1.102 +	}
   1.103 +	else if (result == Result_NoCrit)
   1.104 +	{
   1.105 +		return 0;
   1.106 +	}
   1.107 +	else
   1.108 +	{
   1.109 +		return 1;
   1.110 +	}
   1.111 +}
   1.112 +
   1.113 +DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperNoCritsMelee, bool)
   1.114 +{
   1.115 +	DetourResult result = DetourCallback((CBaseEntity *)this, true);
   1.116 +
   1.117 +	if (result == Result_Ignore)
   1.118 +	{
   1.119 +		return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperNoCritsMelee)();
   1.120 +	}
   1.121 +	else if (result == Result_NoCrit)
   1.122 +	{
   1.123 +		return 0;
   1.124 +	}
   1.125 +	else
   1.126 +	{
   1.127 +		return 1;
   1.128 +	}
   1.129 +}
   1.130 +
   1.131  bool InitialiseCritDetours()
   1.132  {
   1.133 +	sm_sendprop_info_t prop;
   1.134 +
   1.135  	calcIsAttackCriticalDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelper, "CalcCritical");
   1.136  	calcIsAttackCriticalMeleeDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperMelee, "CalcCriticalMelee");
   1.137  	calcIsAttackCriticalBowDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperBow, "CalcCriticalBow");
   1.138 +	calcIsAttackCriticalKnifeDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperKnife, "CalcCriticalKnife");
   1.139 +	calcIsAttackCriticalNoCritsDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperNoCrits, "CalcCriticalNoCrits");
   1.140 +	calcIsAttackCriticalNoCritsMeleeDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperNoCritsMelee, "CalcCriticalNoCritsMelee");
   1.141  
   1.142  	bool HookCreated = false;
   1.143  
   1.144 @@ -214,6 +287,30 @@
   1.145  		HookCreated = true;
   1.146  	}
   1.147  
   1.148 +	if (calcIsAttackCriticalKnifeDetour != NULL)
   1.149 +	{
   1.150 +		calcIsAttackCriticalKnifeDetour->EnableDetour();
   1.151 +		HookCreated = true;
   1.152 +	}
   1.153 +
   1.154 +	if (calcIsAttackCriticalNoCritsDetour != NULL)
   1.155 +	{
   1.156 +		calcIsAttackCriticalNoCritsDetour->EnableDetour();
   1.157 +		HookCreated = true;
   1.158 +	}
   1.159 +
   1.160 +	if (calcIsAttackCriticalNoCritsMeleeDetour != NULL)
   1.161 +	{
   1.162 +		calcIsAttackCriticalNoCritsMeleeDetour->EnableDetour();
   1.163 +		if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_iNextMeleeCrit", &prop))
   1.164 +		{
   1.165 +			g_pSM->LogError(myself, "Failed to find m_iNextMeleeCrit prop offset");
   1.166 +			return false;
   1.167 +		}
   1.168 +		nextMeleeCritOffset = prop.actual_offset;
   1.169 +		HookCreated = true;
   1.170 +	}
   1.171 +
   1.172  	if (HookCreated)
   1.173  	{
   1.174  		return true;
   1.175 @@ -243,4 +340,22 @@
   1.176  		calcIsAttackCriticalBowDetour->Destroy();
   1.177  		calcIsAttackCriticalBowDetour = NULL;
   1.178  	}
   1.179 +	
   1.180 +	if (calcIsAttackCriticalKnifeDetour != NULL)
   1.181 +	{
   1.182 +		calcIsAttackCriticalKnifeDetour->Destroy();
   1.183 +		calcIsAttackCriticalKnifeDetour = NULL;
   1.184 +	}
   1.185 +
   1.186 +	if (calcIsAttackCriticalNoCritsDetour != NULL)
   1.187 +	{
   1.188 +		calcIsAttackCriticalNoCritsDetour->Destroy();
   1.189 +		calcIsAttackCriticalNoCritsDetour = NULL;
   1.190 +	}
   1.191 +
   1.192 +	if (calcIsAttackCriticalNoCritsMeleeDetour != NULL)
   1.193 +	{
   1.194 +		calcIsAttackCriticalNoCritsMeleeDetour->Destroy();
   1.195 +		calcIsAttackCriticalNoCritsMeleeDetour = NULL;
   1.196 +	}
   1.197  }