|
|
|
@@ -2,7 +2,7 @@
|
|
|
|
|
|
|
|
|
|
static inline Vec3 PredictOrigin(Vec3& vOrigin, Vec3 vVelocity, float flLatency, bool bTrace = true, Vec3 vMins = {}, Vec3 vMaxs = {}, unsigned int nMask = MASK_SOLID)
|
|
|
|
|
{
|
|
|
|
|
if (vVelocity.IsZero())
|
|
|
|
|
if (vVelocity.IsZero() || !flLatency)
|
|
|
|
|
return vOrigin;
|
|
|
|
|
|
|
|
|
|
Vec3 vTo = vOrigin + vVelocity * flLatency;
|
|
|
|
@@ -16,14 +16,17 @@ static inline Vec3 PredictOrigin(Vec3& vOrigin, Vec3 vVelocity, float flLatency,
|
|
|
|
|
return vOrigin + (vTo - vOrigin) * trace.fraction;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CAutoDetonate::PredictPlayers(CBaseEntity* pLocal, float flLatency)
|
|
|
|
|
void CAutoDetonate::PredictPlayers(CTFPlayer* pLocal, float flLatency, bool bLocal)
|
|
|
|
|
{
|
|
|
|
|
m_mRestore.clear();
|
|
|
|
|
if (!m_mRestore.empty())
|
|
|
|
|
RestorePlayers();
|
|
|
|
|
|
|
|
|
|
for (auto pEntity : H::Entities.GetGroup(EGroupType::PLAYERS_ALL))
|
|
|
|
|
{
|
|
|
|
|
auto pPlayer = pEntity->As<CTFPlayer>();
|
|
|
|
|
if (pPlayer == pLocal || pPlayer->IsDormant() || !pPlayer->IsAlive() || pPlayer->IsAGhost())
|
|
|
|
|
if (!bLocal
|
|
|
|
|
? (pPlayer == pLocal || pPlayer->IsDormant() || !pPlayer->IsAlive() || pPlayer->IsAGhost())
|
|
|
|
|
: (pLocal != pPlayer || !pLocal->IsAlive() || pLocal->IsAGhost()))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
m_mRestore[pPlayer] = pPlayer->GetAbsOrigin();
|
|
|
|
@@ -35,9 +38,45 @@ void CAutoDetonate::PredictPlayers(CBaseEntity* pLocal, float flLatency)
|
|
|
|
|
void CAutoDetonate::RestorePlayers()
|
|
|
|
|
{
|
|
|
|
|
for (auto& [pEntity, vRestore] : m_mRestore)
|
|
|
|
|
{
|
|
|
|
|
pEntity->SetAbsOrigin(vRestore);
|
|
|
|
|
m_mRestore.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool GetRadius(EGroupType entityGroup, CBaseEntity* pProjectile, float& flRadius, CTFWeaponBase*& pWeapon)
|
|
|
|
|
{
|
|
|
|
|
if (entityGroup == EGroupType::MISC_LOCAL_STICKIES)
|
|
|
|
|
pWeapon = pProjectile->As<CTFGrenadePipebombProjectile>()->m_hOriginalLauncher().Get()->As<CTFWeaponBase>();
|
|
|
|
|
else
|
|
|
|
|
pWeapon = pProjectile->As<CTFProjectile_Flare>()->m_hLauncher().Get()->As<CTFWeaponBase>();
|
|
|
|
|
if (!pWeapon)
|
|
|
|
|
{
|
|
|
|
|
pWeapon = H::Entities.GetWeapon();
|
|
|
|
|
if (!pWeapon)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (entityGroup == EGroupType::MISC_LOCAL_STICKIES)
|
|
|
|
|
{
|
|
|
|
|
auto pPipebomb = pProjectile->As<CTFGrenadePipebombProjectile>();
|
|
|
|
|
if (!pPipebomb->m_flCreationTime() || I::GlobalVars->curtime < pPipebomb->m_flCreationTime() + SDK::AttribHookValue(0.8f, "sticky_arm_time", pWeapon))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
flRadius *= 146.f;
|
|
|
|
|
if (!pPipebomb->m_bTouched())
|
|
|
|
|
{
|
|
|
|
|
static auto tf_grenadelauncher_livetime = U::ConVars.FindVar("tf_grenadelauncher_livetime");
|
|
|
|
|
static auto tf_sticky_radius_ramp_time = U::ConVars.FindVar("tf_sticky_radius_ramp_time");
|
|
|
|
|
static auto tf_sticky_airdet_radius = U::ConVars.FindVar("tf_sticky_airdet_radius");
|
|
|
|
|
float flLiveTime = tf_grenadelauncher_livetime ? tf_grenadelauncher_livetime->GetFloat() : 0.8f;
|
|
|
|
|
float flRampTime = tf_sticky_radius_ramp_time ? tf_sticky_radius_ramp_time->GetFloat() : 2.f;
|
|
|
|
|
float flAirdetRadius = tf_sticky_airdet_radius ? tf_sticky_airdet_radius->GetFloat() : 0.85f;
|
|
|
|
|
flRadius *= Math::RemapValClamped(I::GlobalVars->curtime - pPipebomb->m_flCreationTime(), flLiveTime, flLiveTime + flRampTime, flAirdetRadius, 1.f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
flRadius *= 110.f;
|
|
|
|
|
flRadius = SDK::AttribHookValue(flRadius, "mult_explosion_radius", pWeapon);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool CheckEntities(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd, CBaseEntity* pProjectile, float flRadius, Vec3 vOrigin)
|
|
|
|
@@ -102,46 +141,63 @@ bool CAutoDetonate::CheckDetonation(CTFPlayer* pLocal, EGroupType entityGroup, f
|
|
|
|
|
for (auto pProjectile : vProjectiles)
|
|
|
|
|
{
|
|
|
|
|
float flRadius = flRadiusScale;
|
|
|
|
|
|
|
|
|
|
CTFWeaponBase* pWeapon = nullptr;
|
|
|
|
|
if (entityGroup == EGroupType::MISC_LOCAL_STICKIES)
|
|
|
|
|
pWeapon = pProjectile->As<CTFGrenadePipebombProjectile>()->m_hOriginalLauncher().Get()->As<CTFWeaponBase>();
|
|
|
|
|
else
|
|
|
|
|
pWeapon = pProjectile->As<CTFProjectile_Flare>()->m_hLauncher().Get()->As<CTFWeaponBase>();
|
|
|
|
|
if (!pWeapon)
|
|
|
|
|
{
|
|
|
|
|
pWeapon = H::Entities.GetWeapon();
|
|
|
|
|
if (!pWeapon)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (!GetRadius(entityGroup, pProjectile, flRadius, pWeapon))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (entityGroup == EGroupType::MISC_LOCAL_STICKIES)
|
|
|
|
|
{
|
|
|
|
|
auto pPipebomb = pProjectile->As<CTFGrenadePipebombProjectile>();
|
|
|
|
|
if (!pPipebomb->m_flCreationTime() || I::GlobalVars->curtime < pPipebomb->m_flCreationTime() + SDK::AttribHookValue(0.8f, "sticky_arm_time", pWeapon))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
flRadius *= 146.f;
|
|
|
|
|
if (!pPipebomb->m_bTouched())
|
|
|
|
|
{
|
|
|
|
|
static auto tf_grenadelauncher_livetime = U::ConVars.FindVar("tf_grenadelauncher_livetime");
|
|
|
|
|
static auto tf_sticky_radius_ramp_time = U::ConVars.FindVar("tf_sticky_radius_ramp_time");
|
|
|
|
|
static auto tf_sticky_airdet_radius = U::ConVars.FindVar("tf_sticky_airdet_radius");
|
|
|
|
|
float flLiveTime = tf_grenadelauncher_livetime ? tf_grenadelauncher_livetime->GetFloat() : 0.8f;
|
|
|
|
|
float flRampTime = tf_sticky_radius_ramp_time ? tf_sticky_radius_ramp_time->GetFloat() : 2.f;
|
|
|
|
|
float flAirdetRadius = tf_sticky_airdet_radius ? tf_sticky_airdet_radius->GetFloat() : 0.85f;
|
|
|
|
|
flRadius *= Math::RemapValClamped(I::GlobalVars->curtime - pPipebomb->m_flCreationTime(), flLiveTime, flLiveTime + flRampTime, flAirdetRadius, 1.f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
flRadius *= 110.f;
|
|
|
|
|
flRadius = SDK::AttribHookValue(flRadius, "mult_explosion_radius", pWeapon);
|
|
|
|
|
Vec3 vOrigin = PredictOrigin(pProjectile->m_vecOrigin(), pProjectile->GetAbsVelocity(), flLatency);
|
|
|
|
|
|
|
|
|
|
PredictPlayers(pLocal, flLatency);
|
|
|
|
|
bool bCheck = CheckEntities(pLocal, pWeapon, nullptr, pProjectile, flRadius, vOrigin);
|
|
|
|
|
PredictPlayers(pLocal, 0.f);
|
|
|
|
|
bCheck = bCheck && CheckEntities(pLocal, pWeapon, pCmd, pProjectile, flRadius, pProjectile->m_vecOrigin());
|
|
|
|
|
RestorePlayers();
|
|
|
|
|
if (bCheck && CheckEntities(pLocal, pWeapon, pCmd, pProjectile, flRadius, pProjectile->m_vecOrigin()))
|
|
|
|
|
if (bCheck)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool CheckLocal(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pProjectile, float flRadius, Vec3 vOrigin)
|
|
|
|
|
{
|
|
|
|
|
flRadius += 1;
|
|
|
|
|
|
|
|
|
|
Vec3 vPos = {}; reinterpret_cast<CCollisionProperty*>(pLocal->GetCollideable())->CalcNearestPoint(vOrigin, &vPos);
|
|
|
|
|
if (vOrigin.DistTo(vPos) > flRadius)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!SDK::VisPosProjectile(pProjectile, pLocal, vOrigin, pLocal->GetAbsOrigin() + pLocal->m_vecViewOffset(), MASK_SHOT))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CAutoDetonate::CheckSelf(CTFPlayer* pLocal, EGroupType entityGroup)
|
|
|
|
|
{
|
|
|
|
|
if (!(Vars::Aimbot::Projectile::AutoDetonate.Value & Vars::Aimbot::Projectile::AutoDetonateEnum::PreventSelfDamage) || !pLocal->IsAlive() || pLocal->IsAGhost())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
auto& vProjectiles = H::Entities.GetGroup(entityGroup);
|
|
|
|
|
if (vProjectiles.empty())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
float flLatency = std::max(F::Backtrack.GetReal() - 0.05f, 0.f);
|
|
|
|
|
|
|
|
|
|
for (auto pProjectile : vProjectiles)
|
|
|
|
|
{
|
|
|
|
|
float flRadius = 1.f;
|
|
|
|
|
CTFWeaponBase* pWeapon = nullptr;
|
|
|
|
|
if (!GetRadius(entityGroup, pProjectile, flRadius, pWeapon))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Vec3 vOrigin = PredictOrigin(pProjectile->m_vecOrigin(), pProjectile->GetAbsVelocity(), flLatency);
|
|
|
|
|
|
|
|
|
|
PredictPlayers(pLocal, 0.f, true);
|
|
|
|
|
bool bCheck = CheckLocal(pLocal, pWeapon, pProjectile, flRadius, vOrigin)
|
|
|
|
|
&& CheckLocal(pLocal, pWeapon, pProjectile, flRadius, pProjectile->m_vecOrigin());
|
|
|
|
|
RestorePlayers();
|
|
|
|
|
if (bCheck)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -153,7 +209,13 @@ void CAutoDetonate::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCm
|
|
|
|
|
if (!Vars::Aimbot::Projectile::AutoDetonate.Value)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if ((Vars::Aimbot::Projectile::AutoDetonate.Value & Vars::Aimbot::Projectile::AutoDetonateEnum::Stickies && CheckDetonation(pLocal, EGroupType::MISC_LOCAL_STICKIES, Vars::Aimbot::Projectile::AutodetRadius.Value / 100, pCmd))
|
|
|
|
|
|| (Vars::Aimbot::Projectile::AutoDetonate.Value & Vars::Aimbot::Projectile::AutoDetonateEnum::Flares && CheckDetonation(pLocal, EGroupType::MISC_LOCAL_FLARES, Vars::Aimbot::Projectile::AutodetRadius.Value / 100, pCmd)))
|
|
|
|
|
if ((Vars::Aimbot::Projectile::AutoDetonate.Value & Vars::Aimbot::Projectile::AutoDetonateEnum::Stickies
|
|
|
|
|
&& CheckDetonation(pLocal, EGroupType::MISC_LOCAL_STICKIES, Vars::Aimbot::Projectile::AutodetRadius.Value / 100, pCmd)
|
|
|
|
|
&& !CheckSelf(pLocal, EGroupType::MISC_LOCAL_STICKIES))
|
|
|
|
|
|| (Vars::Aimbot::Projectile::AutoDetonate.Value & Vars::Aimbot::Projectile::AutoDetonateEnum::Flares
|
|
|
|
|
&& CheckDetonation(pLocal, EGroupType::MISC_LOCAL_FLARES, Vars::Aimbot::Projectile::AutodetRadius.Value / 100, pCmd))
|
|
|
|
|
&& !CheckSelf(pLocal, EGroupType::MISC_LOCAL_FLARES))
|
|
|
|
|
{
|
|
|
|
|
pCmd->buttons |= IN_ATTACK2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|