This commit is contained in:
rei-2
2025-08-25 13:01:40 -04:00
parent 6972f4b1c8
commit 3e8fb49622
9 changed files with 55 additions and 10 deletions
+1
View File
@@ -990,6 +990,7 @@
<ClCompile Include="src\Hooks\CL_ReadPackets.cpp" />
<ClCompile Include="src\Hooks\CMatchInviteNotification_OnTick.cpp" />
<ClCompile Include="src\Hooks\CMaterial_Uncache.cpp" />
<ClCompile Include="src\Hooks\CTFWeaponBase_CanFireRandomCriticalShot.cpp" />
<ClCompile Include="src\Hooks\IEngineTrace_SetTraceEntity.cpp" />
<ClCompile Include="src\Hooks\CNetChannel_SendDatagram.cpp" />
<ClCompile Include="src\Hooks\CNetChannel_SendNetMsg.cpp" />
+1
View File
@@ -195,6 +195,7 @@
<ClCompile Include="src\Hooks\CTFRocketLauncher_CheckReloadMisfire.cpp" />
<ClCompile Include="src\Features\Visuals\Groups\Groups.cpp" />
<ClCompile Include="src\Hooks\CInput_ValidateUserCmd.cpp" />
<ClCompile Include="src\Hooks\CTFWeaponBase_CanFireRandomCriticalShot.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Utils\UtlVector\UtlVector.h" />
+21 -3
View File
@@ -9,10 +9,12 @@
#define TF_DAMAGE_CRIT_CHANCE_MELEE 0.15f
#define TF_DAMAGE_CRIT_DURATION_RAPID 2.0f
#define STATS_SEND_FREQUENCY 1.f
#define SEED_ATTEMPTS 4096
#define BUCKET_ATTEMPTS 1000
//#define SERVER_CRIT_DATA
#define SERVER_CRIT_DATA
int CCritHack::GetCritCommand(CTFWeaponBase* pWeapon, int iCommandNumber, bool bCrit, bool bSafe)
{
@@ -227,6 +229,16 @@ void CCritHack::UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
if (auto pResource = H::Entities.GetResource())
{
m_iResourceDamage = pResource->m_iDamage(I::EngineClient->GetLocalPlayer());
/* // more of a proof of concept for resyncing crit damage
if (m_flLastDamageTime < I::GlobalVars->curtime + STATS_SEND_FREQUENCY * 2)
{ // attempt to resync damages
m_iRangedDamage = m_iResourceDamage - m_iMeleeDamage;
float flObservedCritChance = pWeapon->m_flObservedCritChance();
m_iCritDamage = (TF_DAMAGE_CRIT_MULTIPLIER * flObservedCritChance * m_iResourceDamage) / (1 + 2 * flObservedCritChance);
SDK::Output("Info", std::format("{}, {}", m_iRangedDamage, m_iCritDamage).c_str());
}
*/
m_iDesyncDamage = m_iRangedDamage + m_iMeleeDamage - m_iResourceDamage;
}
}
@@ -278,6 +290,8 @@ void CCritHack::Reset()
m_flDamageTilFlip = 0;
m_mHealthHistory.clear();
//m_flLastDamageTime = 0.f;
}
@@ -295,11 +309,13 @@ int CCritHack::GetCritRequest(CUserCmd* pCmd, CTFWeaponBase* pWeapon)
void CCritHack::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
{
if (!pWeapon || !pLocal->IsAlive() || !I::EngineClient->IsInGame()
|| pLocal->IsCritBoosted() || pWeapon->m_flCritTime() > I::GlobalVars->curtime || !WeaponCanCrit(pWeapon))
if (!pWeapon || !pLocal->IsAlive() || pLocal->IsAGhost() || !I::EngineClient->IsInGame())
return;
UpdateInfo(pLocal, pWeapon);
if (pLocal->IsCritBoosted() || pWeapon->m_flCritTime() > I::GlobalVars->curtime || !WeaponCanCrit(pWeapon))
return;
if (pWeapon->GetWeaponID() == TF_WEAPON_MINIGUN && pCmd->buttons & IN_ATTACK)
pCmd->buttons &= ~IN_ATTACK2;
@@ -445,6 +461,8 @@ void CCritHack::Event(IGameEvent* pEvent, uint32_t uHash, CTFPlayer* pLocal)
}
}
//m_flLastDamageTime = I::GlobalVars->curtime;
CTFWeaponBase* pWeapon = nullptr;
for (int i = 0; i < MAX_WEAPONS; i++)
{
+5
View File
@@ -52,6 +52,8 @@ private:
float m_flCritChance = 0.f;
float m_flMultCritChance = 1.f;
//float m_flLastDamageTime = 0.f;
public:
void Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
void Event(IGameEvent* pEvent, uint32_t uHash, CTFPlayer* pLocal);
@@ -60,6 +62,9 @@ public:
bool WeaponCanCrit(CTFWeaponBase* pWeapon, bool bWeaponOnly = false);
int PredictCmdNum(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
float GetCritDamage() { return m_iCritDamage; }
float GetRangedDamage() { return m_iRangedDamage; }
};
ADD_FEATURE(CCritHack, CritHack);
+1 -1
View File
@@ -211,7 +211,7 @@ void CMisc::AntiAFK(CTFPlayer* pLocal, CUserCmd* pCmd)
void CMisc::InstantRespawnMVM(CTFPlayer* pLocal)
{
if (!Vars::Misc::MannVsMachine::InstantRespawn.Value || !pLocal->IsAlive())
if (!Vars::Misc::MannVsMachine::InstantRespawn.Value || pLocal->IsAlive())
return;
KeyValues* kv = new KeyValues("MVM_Revive_Response");
@@ -17,13 +17,14 @@ bool CSpectatorList::GetSpectators(CTFPlayer* pTarget)
auto pPlayer = I::ClientEntityList->GetClientEntity(n)->As<CTFPlayer>();
bool bLocal = n == I::EngineClient->GetLocalPlayer();
if (pResource->m_bValid(n) && pResource->m_iTeam(I::EngineClient->GetLocalPlayer()) != TEAM_SPECTATOR && pResource->m_iTeam(n) == TEAM_SPECTATOR)
if (pResource->m_bValid(n) && !pResource->IsFakePlayer(n)
&& pResource->m_iTeam(I::EngineClient->GetLocalPlayer()) != TEAM_SPECTATOR && pResource->m_iTeam(n) == TEAM_SPECTATOR)
{
m_vSpectators.emplace_back(F::PlayerUtils.GetPlayerName(n, pResource->GetName(n)), "possible", -1.f, false, n);
continue;
}
if (pTarget->entindex() == n
if (pTarget->entindex() == n || pResource->IsFakePlayer(n)
|| !pPlayer || !pPlayer->IsPlayer() || pPlayer->IsAlive()
|| pTarget->IsDormant() != pPlayer->IsDormant()
|| pResource->m_iTeam(iTarget) != pResource->m_iTeam(n))
@@ -2,7 +2,6 @@
#include "../Features/CritHack/CritHack.h"
MAKE_HOOK(CTFWeaponBase_CalcIsAttackCritical, S::CTFWeaponBase_CalcIsAttackCritical(), void,
void* rcx)
{
@@ -0,0 +1,20 @@
#include "../SDK/SDK.h"
#include "../Features/CritHack/CritHack.h"
MAKE_SIGNATURE(CTFWeaponBase_CanFireRandomCriticalShot, "client.dll", "F3 0F 58 0D ? ? ? ? 0F 2F 89", 0x0);
MAKE_HOOK(CTFWeaponBase_CanFireRandomCriticalShot, S::CTFWeaponBase_CanFireRandomCriticalShot(), bool,
void* rcx, float flCritChance)
{ // not present on the client so it will always be a crit behind otherwise
int nRandomRangedCritDamage = F::CritHack.GetCritDamage();
int nTotalDamage = F::CritHack.GetRangedDamage();
if (!nTotalDamage)
return true;
auto pWeapon = reinterpret_cast<CTFWeaponBase*>(rcx);
float flNormalizedDamage = nRandomRangedCritDamage / TF_DAMAGE_CRIT_MULTIPLIER;
pWeapon->m_flObservedCritChance() = flNormalizedDamage / (flNormalizedDamage + (nTotalDamage - nRandomRangedCritDamage));
return CALL_ORIGINAL(rcx, flCritChance);
}
@@ -45,7 +45,7 @@ bool CTFPlayer::InCond(ETFCond eCond)
switch (eCond / 32)
{
case 0:
return m_nPlayerCond() & (1 << eCond);
return m_nPlayerCond() & (1 << eCond) || _condition_bits() & (1 << eCond);
case 1:
return m_nPlayerCondEx() & (1 << (eCond - 32));
case 2:
@@ -63,7 +63,7 @@ void CTFPlayer::AddCond(ETFCond eCond)
switch (eCond / 32)
{
case 0:
m_nPlayerCond() |= (1 << eCond); break;
m_nPlayerCond() |= (1 << eCond), _condition_bits() |= (1 << eCond); break;
case 1:
m_nPlayerCondEx() |= (1 << (eCond - 32)); break;
case 2:
@@ -80,7 +80,7 @@ void CTFPlayer::RemoveCond(ETFCond eCond)
switch (eCond / 32)
{
case 0:
m_nPlayerCond() &= ~(1 << eCond); break;
m_nPlayerCond() &= ~(1 << eCond), _condition_bits() &= ~(1 << eCond); break;
case 1:
m_nPlayerCondEx() &= ~(1 << (eCond - 32)); break;
case 2: