restructure hitscan

misc fixes
This commit is contained in:
rei-2
2026-05-11 22:13:29 -04:00
parent 58aac8c48d
commit ef959fa11a
30 changed files with 496 additions and 432 deletions
+4 -6
View File
@@ -10,11 +10,12 @@
#include "../Misc/Misc.h"
#include "../Visuals/Visuals.h"
bool CAimbot::ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
bool CAimbot::ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
{
if (!pWeapon || !pLocal->CanAttack()
|| !SDK::AttribHookValue(1, "mult_dmg", pWeapon)
|| I::EngineVGui->IsGameUIVisible())
|| I::EngineVGui->IsGameUIVisible()
|| pCmd->weaponselect)
return false;
return true;
@@ -54,11 +55,8 @@ void CAimbot::RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
if (abs(G::AimPoint.m_iTickCount - I::GlobalVars->tickcount) > G::AimPoint.m_iDuration)
G::AimPoint = {};
if (pCmd->weaponselect)
return;
F::AutoRocketJump.Run(pLocal, pWeapon, pCmd);
if (!ShouldRun(pLocal, pWeapon))
if (!ShouldRun(pLocal, pWeapon, pCmd))
return;
F::AutoDetonate.Run(pLocal, pCmd);
+1 -1
View File
@@ -4,7 +4,7 @@
class CAimbot
{
private:
bool ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
bool ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
void RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
void RunAimbot(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd, bool bSecondaryType = false);
@@ -3,6 +3,7 @@
#include "../Aimbot.h"
#include "../../Ticks/Ticks.h"
#include "../../Resolver/Resolver.h"
#include "../../NoSpread/NoSpread.h"
#include "../../Simulation/MovementSimulation/MovementSimulation.h"
#include "../../Visuals/Visuals.h"
@@ -143,14 +144,108 @@ static inline std::vector<Target_t> GetTargets(CTFPlayer* pLocal, CTFWeaponBase*
std::vector<HitscanHitbox_t> CAimbotHitscan::GetHitboxes(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pTarget)
{
std::vector<HitscanHitbox_t> vHitboxes = {};
if (pWeapon->GetWeaponID() == TF_WEAPON_LASER_POINTER)
{
CObjectSentrygun* pSentry = nullptr;
for (auto pEntity : H::Entities.GetGroup(EntityEnum::BuildingTeam))
{
if (pEntity->IsSentrygun() && pEntity->As<CBaseObject>()->m_hBuilder().GetEntryIndex() == I::EngineClient->GetLocalPlayer())
{
pSentry = pEntity->As<CObjectSentrygun>();
break;
}
}
if (!pSentry)
return vHitboxes;
Vec3 vOrigin = pTarget->m_vecOrigin();
{
MoveStorage tMoveStorage; // run movesim based on ping
F::MoveSim.Initialize(pTarget, tMoveStorage);
if (!tMoveStorage.m_bFailed)
{
for (int i = 1 - TIME_TO_TICKS(F::Backtrack.GetReal()); i <= 0; i++)
{
F::MoveSim.RunTick(tMoveStorage);
vOrigin = tMoveStorage.m_vPredictedOrigin;
}
}
F::MoveSim.Restore(tMoveStorage);
}
if (!SDK::VisPosWorld(nullptr, pTarget, pSentry->m_vecOrigin() + pSentry->GetOffset() / 2 * pSentry->m_flModelScale(), vOrigin + pTarget->GetOffset() / 2))
return vHitboxes;
vHitboxes.emplace_back(nullptr, vOrigin);
return vHitboxes;
}
if (!pTarget->IsPlayer())
{
vHitboxes.emplace_back();
return vHitboxes;
}
if (auto pSet = pTarget->As<CBaseAnimating>()->GetHitboxSet())
{
std::vector<std::tuple<const mstudiobbox_t*, int, int>> vBones;
for (int nHitbox = 0; nHitbox < pSet->numhitboxes; nHitbox++)
{
int iPriority = GetHitboxPriority(nHitbox, pLocal, pWeapon, pTarget);
if (iPriority == -1)
continue;
auto pBox = pSet->pHitbox(nHitbox);
if (!pBox)
continue;
vBones.emplace_back(pBox, nHitbox, iPriority);
}
std::sort(vBones.begin(), vBones.end(), [&](const auto& a, const auto& b) -> bool
{
return std::get<2>(a) < std::get<2>(b);
});
vHitboxes.reserve(vBones.size());
for (auto& [pBox, nHitbox, _] : vBones)
vHitboxes.emplace_back(pBox, std::nullopt, nHitbox);
}
return vHitboxes;
}
int CAimbotHitscan::GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pTarget)
{
if (!F::AimbotGlobal.IsHitboxValid(pTarget, nHitbox, Vars::Aimbot::Hitscan::Hitboxes.Value))
return -1;
bool bHeadshot = false;
if (pTarget->IsPlayer())
switch (pWeapon->GetWeaponID())
{
case TF_WEAPON_SNIPERRIFLE:
case TF_WEAPON_SNIPERRIFLE_DECAP:
case TF_WEAPON_SNIPERRIFLE_CLASSIC:
{
auto pSniperRifle = pWeapon->As<CTFSniperRifle>();
if (G::CanHeadshot
|| pLocal->InCond(TF_COND_AIMING) && (pSniperRifle->GetRifleType() == RIFLE_JARATE && SDK::AttribHookValue(0, "jarate_duration", pWeapon) > 0 || Vars::Aimbot::Hitscan::Modifiers.Value & Vars::Aimbot::Hitscan::ModifiersEnum::WaitForHeadshot))
bHeadshot = true;
break;
}
case TF_WEAPON_REVOLVER:
{
if (SDK::AttribHookValue(0, "set_weapon_mode", pWeapon) == 1 && (pWeapon->AmbassadorCanHeadshot() || Vars::Aimbot::Hitscan::Modifiers.Value & Vars::Aimbot::Hitscan::ModifiersEnum::WaitForHeadshot))
bHeadshot = true;
}
}
if (Vars::Aimbot::Hitscan::Hitboxes.Value & Vars::Aimbot::Hitscan::HitboxesEnum::BodyaimIfLethal && bHeadshot)
{
auto pPlayer = pTarget->As<CTFPlayer>();
switch (pWeapon->GetWeaponID())
{
case TF_WEAPON_SNIPERRIFLE:
@@ -159,54 +254,29 @@ int CAimbotHitscan::GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponB
{
auto pSniperRifle = pWeapon->As<CTFSniperRifle>();
if (G::CanHeadshot
|| pLocal->InCond(TF_COND_AIMING) && (pSniperRifle->GetRifleType() == RIFLE_JARATE && SDK::AttribHookValue(0, "jarate_duration", pWeapon) > 0 || Vars::Aimbot::Hitscan::Modifiers.Value & Vars::Aimbot::Hitscan::ModifiersEnum::WaitForHeadshot))
bHeadshot = true;
int iDamage = ceilf(std::max(pSniperRifle->m_flChargedDamage(), 50.f) * pSniperRifle->GetBodyshotMult(pPlayer));
if (pPlayer->m_iHealth() <= iDamage)
bHeadshot = false;
break;
}
case TF_WEAPON_REVOLVER:
{
if (SDK::AttribHookValue(0, "set_weapon_mode", pWeapon) == 1 && (pWeapon->AmbassadorCanHeadshot() || Vars::Aimbot::Hitscan::Modifiers.Value & Vars::Aimbot::Hitscan::ModifiersEnum::WaitForHeadshot))
bHeadshot = true;
}
}
if (Vars::Aimbot::Hitscan::Hitboxes.Value & Vars::Aimbot::Hitscan::HitboxesEnum::BodyaimIfLethal && bHeadshot)
{
auto pPlayer = pTarget->As<CTFPlayer>();
switch (pWeapon->GetWeaponID())
if (SDK::AttribHookValue(0, "set_weapon_mode", pWeapon) == 1)
{
case TF_WEAPON_SNIPERRIFLE:
case TF_WEAPON_SNIPERRIFLE_DECAP:
case TF_WEAPON_SNIPERRIFLE_CLASSIC:
{
auto pSniperRifle = pWeapon->As<CTFSniperRifle>();
float flDistTo = pTarget->m_vecOrigin().DistTo(pLocal->m_vecOrigin());
int iDamage = ceilf(std::max(pSniperRifle->m_flChargedDamage(), 50.f) * pSniperRifle->GetBodyshotMult(pPlayer));
float flMult = SDK::AttribHookValue(1, "mult_dmg", pWeapon);
int iDamage = ceilf(Math::RemapVal(flDistTo, 90.f, 900.f, 60.f, 21.f) * flMult);
if (pPlayer->m_iHealth() <= iDamage)
bHeadshot = false;
break;
}
case TF_WEAPON_REVOLVER:
{
if (SDK::AttribHookValue(0, "set_weapon_mode", pWeapon) == 1)
{
float flDistTo = pTarget->m_vecOrigin().DistTo(pLocal->m_vecOrigin());
float flMult = SDK::AttribHookValue(1, "mult_dmg", pWeapon);
int iDamage = ceilf(Math::RemapVal(flDistTo, 90.f, 900.f, 60.f, 21.f) * flMult);
if (pPlayer->m_iHealth() <= iDamage)
bHeadshot = false;
}
}
}
}
}
}
bool bHeadOnly = bHeadshot && Vars::Aimbot::Hitscan::Hitboxes.Value & Vars::Aimbot::Hitscan::HitboxesEnum::HeadshotOnly;
int iHeadPriority = bHeadOnly || bHeadshot ? 0 : 1;
int iHeadPriority = bHeadshot ? 0 : 1;
int iBodyPriority = bHeadOnly ? -1 : bHeadshot ? 1 : 0;
int iMiscPriority = bHeadOnly ? -1 : 2;
int iLimbPriority = bHeadOnly ? -1 : 3;
@@ -224,23 +294,102 @@ int CAimbotHitscan::GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponB
return iLimbPriority;
};
void CAimbotHitscan::GetHitboxInfo(HitscanHitbox_t& tHitbox, CBaseEntity* pTarget, matrix3x4* aBones, const matrix3x4** pTransform, Vec3* pMins, Vec3* pMaxs)
{
if (pMins && pMaxs)
{
if (tHitbox.m_pBox)
{
*pMins = tHitbox.m_pBox->bbmin;
*pMaxs = tHitbox.m_pBox->bbmax;
}
else if (pTarget)
{
*pMins = pTarget->m_vecMins();
*pMaxs = pTarget->m_vecMaxs();
}
}
if (pTransform)
{
if (aBones && tHitbox.m_pBox)
*pTransform = &aBones[tHitbox.m_pBox->bone];
else if (tHitbox.m_vPos)
*pTransform = &m_mMatrix, Math::MatrixInitialize(m_mMatrix, *tHitbox.m_vPos, false);
else if (pTarget)
*pTransform = &pTarget->m_Collision()->CollisionToWorldTransform();
}
}
void CAimbotHitscan::GetHullInfo(CBaseEntity* pTarget, TickRecord* pRecord, const matrix3x4** pTransform, Vec3* pMins, Vec3* pMaxs, float* pModelScale)
{
if (!pTarget->IsPlayer())
return; // only really important for player targets to check that our trace will be in the bbox
if (pModelScale)
*pModelScale = pTarget->As<CBaseAnimating>()->m_flModelScale();
if (pMins && pMaxs)
{
float flModelScale = pModelScale ? *pModelScale : 1.f;
auto pGameRules = I::TFGameRules();
auto pViewVectors = pGameRules ? pGameRules->GetViewVectors() : nullptr;
*pMins = (pViewVectors ? pViewVectors->m_vHullMin : Vec3(-24, -24, 0)) * flModelScale;
*pMaxs = (pViewVectors ? pViewVectors->m_vHullMax : Vec3(24, 24, 82)) * flModelScale;
}
if (pTransform && pRecord)
*pTransform = &m_mHullMatrix, Math::MatrixInitialize(m_mHullMatrix, pRecord->m_vOrigin, false);
}
std::vector<Vec3> CAimbotHitscan::GetHitboxPoints(CBaseEntity* pTarget, CTFWeaponBase* pWeapon, const Vec3& vMins, const Vec3& vMaxs, int nHitbox)
{
std::vector<Vec3> vPoints = { Vec3() };
bool bPlayer = pTarget->IsPlayer();
if (bPlayer && !F::AimbotGlobal.ShouldMultipoint(pTarget, nHitbox, Vars::Aimbot::Hitscan::MultipointHitboxes.Value)
|| pWeapon->GetWeaponID() == TF_WEAPON_LASER_POINTER)
return vPoints;
switch (Vars::Aimbot::General::AimType.Value)
{
case Vars::Aimbot::General::AimTypeEnum::Smooth:
case Vars::Aimbot::General::AimTypeEnum::Assistive:
if (!Vars::Aimbot::General::AssistStrength.Value)
return vPoints; // triggerbot
}
float flScale = !bPlayer ? 0.5f : Vars::Aimbot::Hitscan::MultipointScale.Value / 100;
Vec3 vMinsS = (vMins - vMaxs) / 2 * flScale;
Vec3 vMaxsS = (vMaxs - vMins) / 2 * flScale;
vPoints = {
Vec3(),
Vec3(vMinsS.x, vMinsS.y, vMaxsS.z),
Vec3(vMaxsS.x, vMinsS.y, vMaxsS.z),
Vec3(vMinsS.x, vMaxsS.y, vMaxsS.z),
Vec3(vMaxsS.x, vMaxsS.y, vMaxsS.z),
Vec3(vMinsS.x, vMinsS.y, vMinsS.z),
Vec3(vMaxsS.x, vMinsS.y, vMinsS.z),
Vec3(vMinsS.x, vMaxsS.y, vMinsS.z),
Vec3(vMaxsS.x, vMaxsS.y, vMinsS.z)
};
return vPoints;
}
int CAimbotHitscan::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
{
if (Vars::Aimbot::General::Ignore.Value & Vars::Aimbot::General::IgnoreEnum::Unsimulated && H::Entities.GetChoke(tTarget.m_pEntity->entindex()) > Vars::Aimbot::General::TickTolerance.Value)
return false;
m_vEyePos = pLocal->GetShootPos();
const float flMaxRangeSqr = powf(pWeapon->GetRange(), 2.f);
auto pModel = tTarget.m_pEntity->GetModel();
if (!pModel) return false;
auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel);
if (!pHDR) return false;
auto pSet = pHDR->pHitboxSet(tTarget.m_pEntity->As<CBaseAnimating>()->m_nHitboxSet());
if (!pSet) return false;
float flMaxRangeSqr = powf(pWeapon->GetRange(), 2.f);
bool bPlayer = tTarget.m_pEntity->IsPlayer();
bool bWrangler = pWeapon->GetWeaponID() == TF_WEAPON_LASER_POINTER;
std::vector<TickRecord*> vRecords = {};
if (F::Backtrack.GetRecords(tTarget.m_pEntity, vRecords))
if (F::Backtrack.GetRecords(tTarget.m_pEntity, vRecords) && !bWrangler)
{
vRecords = F::Backtrack.GetValidRecords(vRecords, pLocal);
if (vRecords.empty())
@@ -255,286 +404,108 @@ int CAimbotHitscan::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase*
vRecords = { &F::Backtrack.m_tRecord };
}
auto vHitboxes = GetHitboxes(pLocal, pWeapon, tTarget.m_pEntity);
if (vHitboxes.empty())
return false;
int iReturn = false;
bool bPeekCheck = false;
std::optional<Vec3> vPeekPos = std::nullopt;
if (Vars::Aimbot::Hitscan::PeekAmount.Value && pWeapon->GetWeaponSpread())
{
switch (Vars::Aimbot::Hitscan::PeekCheck.Value)
{
case Vars::Aimbot::Hitscan::PeekCheckEnum::Off: break;
case Vars::Aimbot::Hitscan::PeekCheckEnum::DoubletapOnly: bPeekCheck = F::Ticks.GetTicks(pWeapon); break;
case Vars::Aimbot::Hitscan::PeekCheckEnum::Always: bPeekCheck = true; break;
case Vars::Aimbot::Hitscan::PeekCheckEnum::DoubletapOnly:
if (!F::Ticks.GetTicks(pWeapon))
break;
[[fallthrough]];
case Vars::Aimbot::Hitscan::PeekCheckEnum::Always:
vPeekPos = m_vEyePos - pLocal->m_vecVelocity() * TICKS_TO_TIME(Vars::Aimbot::Hitscan::PeekAmount.Value);
}
}
Vec3 vPeekPos = bPeekCheck ? m_vEyePos + pLocal->m_vecVelocity() * TICKS_TO_TIME(-Vars::Aimbot::Hitscan::PeekAmount.Value) : Vec3();
// if we're doubletapping, we can't change viewangles so work around that
static int iTargetBone = 0;
Vec3* pDoubletapAngle = F::Ticks.GetShootAngle();
if (pDoubletapAngle && tTarget.m_iTargetType == TargetEnum::Player)
Vec3* pHoldAngle = F::Ticks.GetShootAngle(); if (pHoldAngle && bPlayer && vRecords.size() > 1)
{
Vec3 vHoldAngle = *pHoldAngle - F::NoSpread.GetOffset();
std::sort(vRecords.begin(), vRecords.end(), [&](const TickRecord* a, const TickRecord* b) -> bool
{
Vec3 vPosA = { a->m_aBones[iTargetBone][0][3], a->m_aBones[iTargetBone][1][3], a->m_aBones[iTargetBone][2][3] };
Vec3 vPosB = { b->m_aBones[iTargetBone][0][3], b->m_aBones[iTargetBone][1][3], b->m_aBones[iTargetBone][2][3] };
Vec3 vAnglesA = Math::CalcAngle(m_vEyePos, vPosA);
Vec3 vAnglesB = Math::CalcAngle(m_vEyePos, vPosB);
return pDoubletapAngle->DeltaAngle(vAnglesA).Length2D() < pDoubletapAngle->DeltaAngle(vAnglesB).Length2D();
return vHoldAngle.DeltaAngle(vAnglesA).Length2DSqr() < vHoldAngle.DeltaAngle(vAnglesB).Length2DSqr();
});
}
// wrangler
if (pWeapon->GetWeaponID() == TF_WEAPON_LASER_POINTER)
{
tTarget.m_vPos = tTarget.m_pEntity->m_vecOrigin();
MoveStorage tMoveStorage; // run movesim based on ping
F::MoveSim.Initialize(tTarget.m_pEntity, tMoveStorage);
if (!tMoveStorage.m_bFailed)
{
for (int i = 1 - TIME_TO_TICKS(F::Backtrack.GetReal()); i <= 0; i++)
{
F::MoveSim.RunTick(tMoveStorage);
tTarget.m_vPos = tMoveStorage.m_vPredictedOrigin;
}
}
F::MoveSim.Restore(tMoveStorage);
float flBoneScale = std::max(Vars::Aimbot::Hitscan::BoneSizeMinimumScale.Value, Vars::Aimbot::Hitscan::MultipointScale.Value / 100.f);
float flBoneSubtract = Vars::Aimbot::Hitscan::BoneSizeSubtract.Value;
Vec3 vMins = tTarget.m_pEntity->m_vecMins();
Vec3 vMaxs = tTarget.m_pEntity->m_vecMaxs();
Vec3 vCheckMins = (vMins + flBoneSubtract) * flBoneScale;
Vec3 vCheckMaxs = (vMaxs - flBoneSubtract) * flBoneScale;
const matrix3x4 mTransform = { { 1, 0, 0, tTarget.m_vPos.x }, { 0, 1, 0, tTarget.m_vPos.y }, { 0, 0, 1, tTarget.m_vPos.z } };
tTarget.m_vPos += tTarget.m_pEntity->GetOffset() / 2;
if (m_vEyePos.DistToSqr(tTarget.m_vPos) > flMaxRangeSqr)
return false;
if (SDK::VisPosWorld(pLocal, tTarget.m_pEntity, m_vEyePos, tTarget.m_vPos))
{
Vec3 vAngles; bool bChanged = Aim(G::CurrentUserCmd->viewangles, Math::CalcAngle(m_vEyePos, tTarget.m_vPos), vAngles);
Vec3 vForward; Math::AngleVectors(vAngles, &vForward);
float flDist = m_vEyePos.DistTo(tTarget.m_vPos);
if (!F::AimbotGlobal.ShouldAimAtAngle(vAngles))
return false;
if (!bChanged || Math::RayToOBB(m_vEyePos, vForward, vCheckMins, vCheckMaxs, mTransform) && SDK::VisPos(pLocal, tTarget.m_pEntity, m_vEyePos, m_vEyePos + vForward * flDist))
{
tTarget.m_vAngleTo = vAngles;
tTarget.m_pRecord = vRecords.front();
return true;
}
else
tTarget.m_vAngleTo = vAngles;
iReturn = 2;
}
return iReturn;
}
// non player
if (tTarget.m_iTargetType != TargetEnum::Player)
{
float flBoneScale = std::max(Vars::Aimbot::Hitscan::BoneSizeMinimumScale.Value, Vars::Aimbot::Hitscan::MultipointScale.Value / 100.f);
float flBoneSubtract = Vars::Aimbot::Hitscan::BoneSizeSubtract.Value;
Vec3 vMins = tTarget.m_pEntity->m_vecMins();
Vec3 vMaxs = tTarget.m_pEntity->m_vecMaxs();
Vec3 vCheckMins = (vMins + flBoneSubtract) * flBoneScale;
Vec3 vCheckMaxs = (vMaxs - flBoneSubtract) * flBoneScale;
const matrix3x4& mTransform = tTarget.m_pEntity->m_Collision()->CollisionToWorldTransform();
std::vector<Vec3> vPoints = { Vec3() };
//if (Vars::Aimbot::Hitscan::MultipointScale.Value > 0.f)
{
bool bTriggerbot = (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth
|| Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Assistive)
&& !Vars::Aimbot::General::AssistStrength.Value;
if (!bTriggerbot)
{
float flScale = 0.5f; //Vars::Aimbot::Hitscan::MultipointScale.Value / 100;
Vec3 vMinsS = (vMins - vMaxs) / 2 * flScale;
Vec3 vMaxsS = (vMaxs - vMins) / 2 * flScale;
vPoints = {
Vec3(),
Vec3(vMinsS.x, vMinsS.y, vMaxsS.z),
Vec3(vMaxsS.x, vMinsS.y, vMaxsS.z),
Vec3(vMinsS.x, vMaxsS.y, vMaxsS.z),
Vec3(vMaxsS.x, vMaxsS.y, vMaxsS.z),
Vec3(vMinsS.x, vMinsS.y, vMinsS.z),
Vec3(vMaxsS.x, vMinsS.y, vMinsS.z),
Vec3(vMinsS.x, vMaxsS.y, vMinsS.z),
Vec3(vMaxsS.x, vMaxsS.y, vMinsS.z)
};
}
}
for (auto& vPoint : vPoints)
{
Vec3 vOrigin = tTarget.m_pEntity->GetCenter() + vPoint;
if (m_vEyePos.DistToSqr(vOrigin) > flMaxRangeSqr)
continue;
Vec3 vAngles; bool bChanged = Aim(G::CurrentUserCmd->viewangles, Math::CalcAngle(m_vEyePos, vOrigin), vAngles);
Vec3 vForward; Math::AngleVectors(vAngles, &vForward);
float flDist = m_vEyePos.DistTo(vOrigin);
if (!F::AimbotGlobal.ShouldAimAtAngle(vAngles) || !bChanged && !SDK::VisPos(pLocal, tTarget.m_pEntity, m_vEyePos, vOrigin))
continue;
if (!bChanged || Math::RayToOBB(m_vEyePos, vForward, vCheckMins, vCheckMaxs, mTransform) && SDK::VisPos(pLocal, tTarget.m_pEntity, m_vEyePos, m_vEyePos + vForward * flDist))
{
tTarget.m_vAngleTo = vAngles;
tTarget.m_pRecord = vRecords.front();;
tTarget.m_vPos = vOrigin;
return true;
}
else if (bChanged && SDK::VisPos(pLocal, tTarget.m_pEntity, m_vEyePos, vOrigin))
{
if (iReturn != 2 || vAngles.DeltaAngle(G::CurrentUserCmd->viewangles).Length2D() < tTarget.m_vAngleTo.DeltaAngle(G::CurrentUserCmd->viewangles).Length2D())
tTarget.m_vAngleTo = vAngles;
iReturn = 2;
}
}
return iReturn;
}
// player
std::vector<std::tuple<const mstudiobbox_t*, int, int>> vHitboxes;
for (int nHitbox = 0; nHitbox < pSet->numhitboxes; nHitbox++)
{
int iPriority = GetHitboxPriority(nHitbox, pLocal, pWeapon, tTarget.m_pEntity);
if (iPriority == -1)
continue;
auto pBox = pSet->pHitbox(nHitbox);
if (!pBox) continue;
vHitboxes.emplace_back(pBox, nHitbox, iPriority);
}
std::sort(vHitboxes.begin(), vHitboxes.end(), [&](const auto& a, const auto& b) -> bool
{
return std::get<2>(a) < std::get<2>(b);
});
float flModelScale = tTarget.m_pEntity->As<CBaseAnimating>()->m_flModelScale();
float flBoneScale = Vars::Aimbot::Hitscan::BoneSizeMinimumScale.Value;
float flBoneScale = std::max(Vars::Aimbot::Hitscan::BoneSizeMinimumScale.Value, Vars::Aimbot::Hitscan::MultipointScale.Value / 100.f);
float flBoneSubtract = Vars::Aimbot::Hitscan::BoneSizeSubtract.Value;
float flModelScale = 1.f;
Vec3 vMins, vMaxs, vHullMins, vHullMaxs;
const matrix3x4* pTransform = &m_mMatrix, *pHullTransform = nullptr;
auto pGameRules = I::TFGameRules();
auto pViewVectors = pGameRules ? pGameRules->GetViewVectors() : nullptr;
Vec3 vHullMins = (pViewVectors ? pViewVectors->m_vHullMin : Vec3(-24, -24, 0)) * flModelScale;
Vec3 vHullMaxs = (pViewVectors ? pViewVectors->m_vHullMax : Vec3(24, 24, 82)) * flModelScale;
GetHullInfo(tTarget.m_pEntity, nullptr, nullptr, &vHullMins, &vHullMaxs, &flModelScale);
for (auto pRecord : vRecords)
{
bool bRunPeekCheck = bPeekCheck;
bool bRunPeekCheck = vPeekPos.has_value();
auto aBones = pRecord->m_aBones;
if (!aBones)
continue;
const matrix3x4 mTransform = { { 1, 0, 0, pRecord->m_vOrigin.x }, { 0, 1, 0, pRecord->m_vOrigin.y }, { 0, 0, 1, pRecord->m_vOrigin.z } };
for (auto& [pBox, nHitbox, _] : vHitboxes)
GetHullInfo(tTarget.m_pEntity, bPlayer && !bWrangler ? pRecord : nullptr, &pHullTransform);
for (auto& tHitbox : vHitboxes)
{
Vec3 vMins = pBox->bbmin;
Vec3 vMaxs = pBox->bbmax;
GetHitboxInfo(tHitbox, tTarget.m_pEntity, aBones, &pTransform, &vMins, &vMaxs);
Vec3 vCheckMins = (vMins + flBoneSubtract / flModelScale) * flBoneScale;
Vec3 vCheckMaxs = (vMaxs - flBoneSubtract / flModelScale) * flBoneScale;
Vec3 vAngle; Math::MatrixAngles(aBones[pBox->bone], vAngle);
Vec3 vOffset;
{
Vec3 vOrigin, vCenter;
Math::VectorTransform({}, aBones[pBox->bone], vOrigin);
Math::VectorTransform((vMins + vMaxs) / 2, aBones[pBox->bone], vCenter);
vOffset = vCenter - vOrigin;
}
std::vector<Vec3> vPoints = { Vec3() };
if (F::AimbotGlobal.ShouldMultipoint(tTarget.m_pEntity, nHitbox, Vars::Aimbot::Hitscan::MultipointHitboxes.Value))
{
flBoneScale = std::max(flBoneScale, Vars::Aimbot::Hitscan::MultipointScale.Value / 100.f);
bool bTriggerbot = (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth
|| Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Assistive)
&& !Vars::Aimbot::General::AssistStrength.Value;
if (!bTriggerbot)
{
float flScale = Vars::Aimbot::Hitscan::MultipointScale.Value / 100;
Vec3 vMinsS = (vMins - vMaxs) / 2 * flScale;
Vec3 vMaxsS = (vMaxs - vMins) / 2 * flScale;
vPoints = {
Vec3(),
Vec3(vMinsS.x, vMinsS.y, vMaxsS.z),
Vec3(vMaxsS.x, vMinsS.y, vMaxsS.z),
Vec3(vMinsS.x, vMaxsS.y, vMaxsS.z),
Vec3(vMaxsS.x, vMaxsS.y, vMaxsS.z),
Vec3(vMinsS.x, vMinsS.y, vMinsS.z),
Vec3(vMaxsS.x, vMinsS.y, vMinsS.z),
Vec3(vMinsS.x, vMaxsS.y, vMinsS.z),
Vec3(vMaxsS.x, vMaxsS.y, vMinsS.z)
};
}
}
Vec3 vOrigin; Math::VectorTransform({}, *pTransform, vOrigin);
Vec3 vCenter; Math::VectorTransform((vMins + vMaxs) / 2, *pTransform, vCenter);
Vec3 vOffset = vCenter - vOrigin;
std::vector<Vec3> vPoints = GetHitboxPoints(tTarget.m_pEntity, pWeapon, vMins, vMaxs, tHitbox.m_iHitbox);
for (auto& vPoint : vPoints)
{
Vec3 vOrigin; Math::VectorTransform(vPoint, aBones[pBox->bone], vOrigin); vOrigin += vOffset;
Math::VectorTransform(vPoint, *pTransform, vOrigin); vOrigin += vOffset;
if (m_vEyePos.DistToSqr(vOrigin) > flMaxRangeSqr)
continue;
if (bRunPeekCheck)
{
bRunPeekCheck = false;
if (!SDK::VisPos(pLocal, tTarget.m_pEntity, vPeekPos, vOrigin))
goto nextTick; // if we can't hit our primary hitbox, don't bother
if (!SDK::VisPos(pLocal, tTarget.m_pEntity, *vPeekPos, vOrigin))
goto skip; // if we can't hit our primary hitbox, don't bother
}
Vec3 vAngles; bool bChanged = Aim(G::CurrentUserCmd->viewangles, Math::CalcAngle(m_vEyePos, vOrigin), vAngles);
Vec3 vForward; Math::AngleVectors(vAngles, &vForward);
float flDist = m_vEyePos.DistTo(vOrigin);
if (pHoldAngle) vAngles -= F::NoSpread.GetOffset(); // hold angle recorded with nospread, correct it
if (!F::AimbotGlobal.ShouldAimAtAngle(vAngles) || !bChanged && !SDK::VisPos(pLocal, tTarget.m_pEntity, m_vEyePos, vOrigin))
continue;
// for the time being, no vischecks against other hitboxes
if ((!bChanged || Math::RayToOBB(m_vEyePos, vForward, vCheckMins, vCheckMaxs, aBones[pBox->bone], flModelScale) && SDK::VisPos(pLocal, tTarget.m_pEntity, m_vEyePos, m_vEyePos + vForward * flDist))
&& Math::RayToOBB(m_vEyePos, vForward, vHullMins, vHullMaxs, mTransform))
Vec3 vForward; Math::AngleVectors(vAngles, &vForward);
if ((!bChanged || Math::RayToOBB(m_vEyePos, vForward, vCheckMins, vCheckMaxs, *pTransform, flModelScale) && SDK::VisPos(pLocal, tTarget.m_pEntity, m_vEyePos, m_vEyePos + vForward * m_vEyePos.DistTo(vOrigin)))
&& (!pHullTransform || Math::RayToOBB(m_vEyePos, vForward, vHullMins, vHullMaxs, *pHullTransform)))
{
iTargetBone = pBox->bone;
tTarget.m_vAngleTo = vAngles;
tTarget.m_pRecord = pRecord;
tTarget.m_vPos = vOrigin;
tTarget.m_nAimedHitbox = nHitbox;
tTarget.m_bBacktrack = true;
if (tHitbox.m_pBox)
{
tTarget.m_bBacktrack = true;
tTarget.m_nAimedHitbox = tHitbox.m_iHitbox;
iTargetBone = tHitbox.m_pBox->bone;
}
return true;
}
else if (bChanged && SDK::VisPos(pLocal, tTarget.m_pEntity, m_vEyePos, vOrigin))
{
if (iReturn != 2 || vAngles.DeltaAngle(G::CurrentUserCmd->viewangles).Length2D() < tTarget.m_vAngleTo.DeltaAngle(G::CurrentUserCmd->viewangles).Length2D())
if (iReturn != 2 || vAngles.DeltaAngle(G::CurrentUserCmd->viewangles).Length2DSqr() < tTarget.m_vAngleTo.DeltaAngle(G::CurrentUserCmd->viewangles).Length2DSqr())
tTarget.m_vAngleTo = vAngles;
iReturn = 2;
}
}
}
nextTick:
continue;
skip: continue;
}
return iReturn;
@@ -613,19 +584,17 @@ bool CAimbotHitscan::ShouldFire(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser
return true;
}
bool CAimbotHitscan::Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod)
bool CAimbotHitscan::Aim(const Vec3& vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod)
{
auto pLocal = H::Entities.GetLocal();
Vec3 vPunch = pLocal ? pLocal->m_vecPunchAngle() : Vec3();
if (Vec3* pDoubletapAngle = F::Ticks.GetShootAngle())
if (Vec3* pHoldAngle = F::Ticks.GetShootAngle())
{
vOut = *pDoubletapAngle - vPunch;
vOut = *pHoldAngle;
return true;
}
bool bReturn = false;
vToAngle -= vPunch;
if (auto pLocal = H::Entities.GetLocal())
vToAngle -= pLocal->m_vecPunchAngle();
switch (iMethod)
{
case Vars::Aimbot::General::AimTypeEnum::Plain:
@@ -640,8 +609,8 @@ bool CAimbotHitscan::Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod)
case Vars::Aimbot::General::AimTypeEnum::Assistive:
Vec3 vMouseDelta = G::CurrentUserCmd->viewangles.DeltaAngle(G::LastUserCmd->viewangles);
Vec3 vTargetDelta = vToAngle.DeltaAngle(G::LastUserCmd->viewangles);
float flMouseDelta = vMouseDelta.Length2D(), flTargetDelta = vTargetDelta.Length2D();
vTargetDelta = vTargetDelta.Normalized() * std::min(flMouseDelta, flTargetDelta);
float flMouseDelta = vMouseDelta.Length2DSqr(), flTargetDelta = vTargetDelta.Length2DSqr();
vTargetDelta = vTargetDelta.Normalized() * sqrtf(std::min(flMouseDelta, flTargetDelta));
vOut = vCurAngle - vMouseDelta + vMouseDelta.LerpAngle(vTargetDelta, Vars::Aimbot::General::AssistStrength.Value / 100.f);
bReturn = true;
break;
@@ -3,18 +3,34 @@
#include "../AimbotGlobal/AimbotGlobal.h"
struct HitscanHitbox_t
{
const mstudiobbox_t* m_pBox = nullptr; // bone
std::optional<Vec3> m_vPos = std::nullopt; // custom position
// otherwise use entity transform
int m_iHitbox = 0;
};
class CAimbotHitscan
{
private:
std::vector<HitscanHitbox_t> GetHitboxes(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pTarget);
int GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pTarget);
void GetHitboxInfo(HitscanHitbox_t& tHitbox, CBaseEntity* pTarget, matrix3x4* aBones = nullptr, const matrix3x4** pTransform = nullptr, Vec3* pMins = nullptr, Vec3* pMaxs = nullptr);
void GetHullInfo(CBaseEntity* pTarget, TickRecord* pRecord = nullptr, const matrix3x4** pTransform = nullptr, Vec3* pMins = nullptr, Vec3* pMaxs = nullptr, float* pModelScale = nullptr);
std::vector<Vec3> GetHitboxPoints(CBaseEntity* pTarget, CTFWeaponBase* pWeapon, const Vec3& vMins, const Vec3& vMaxs, int nHitbox = 0);
int CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
bool Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod = Vars::Aimbot::General::AimType.Value);
bool Aim(const Vec3& vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod = Vars::Aimbot::General::AimType.Value);
void Aim(CUserCmd* pCmd, Vec3& vAngles, int iMethod = Vars::Aimbot::General::AimType.Value);
bool ShouldFire(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd, const Target_t& tTarget);
Vec3 m_vEyePos = {};
matrix3x4 m_mMatrix = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 } };
matrix3x4 m_mHullMatrix = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 } };
public:
void Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
};
@@ -434,12 +434,12 @@ int CAimbotMelee::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pW
bool CAimbotMelee::Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod)
bool CAimbotMelee::Aim(const Vec3& vCurAngle, const Vec3& vToAngle, Vec3& vOut, int iMethod)
{
/*
if (Vec3* pDoubletapAngle = F::Ticks.GetShootAngle())
if (Vec3* pHoldAngle = F::Ticks.GetShootAngle())
{
vOut = *pDoubletapAngle;
vOut = *pHoldAngle;
return true;
}
*/
@@ -459,8 +459,8 @@ bool CAimbotMelee::Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod)
case Vars::Aimbot::General::AimTypeEnum::Assistive:
Vec3 vMouseDelta = G::CurrentUserCmd->viewangles.DeltaAngle(G::LastUserCmd->viewangles);
Vec3 vTargetDelta = vToAngle.DeltaAngle(G::LastUserCmd->viewangles);
float flMouseDelta = vMouseDelta.Length2D(), flTargetDelta = vTargetDelta.Length2D();
vTargetDelta = vTargetDelta.Normalized() * std::min(flMouseDelta, flTargetDelta);
float flMouseDelta = vMouseDelta.Length2DSqr(), flTargetDelta = vTargetDelta.Length2DSqr();
vTargetDelta = vTargetDelta.Normalized() * sqrtf(std::min(flMouseDelta, flTargetDelta));
vOut = vCurAngle - vMouseDelta + vMouseDelta.LerpAngle(vTargetDelta, Vars::Aimbot::General::AssistStrength.Value / 100.f);
bReturn = true;
break;
@@ -11,7 +11,7 @@ private:
bool CanBackstab(CBaseEntity* pTarget, CTFPlayer* pLocal, Vec3 vEyeAngles);
int CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
bool Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod = Vars::Aimbot::General::AimType.Value);
bool Aim(const Vec3& vCurAngle, const Vec3& vToAngle, Vec3& vOut, int iMethod = Vars::Aimbot::General::AimType.Value);
void Aim(CUserCmd* pCmd, Vec3& vAngles, int iMethod = Vars::Aimbot::General::AimType.Value);
bool FindNearestBuildPoint(CBaseObject* pBuilding, CTFPlayer* pLocal, Vec3& vPoint);
@@ -1333,17 +1333,14 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
(Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth
|| Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Assistive))
{ // loop and see if closest hitbox is head
auto pModel = tTarget.m_pEntity->GetModel();
if (!pModel) break;
auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel);
if (!pHDR) break;
auto pSet = pHDR->pHitboxSet(tTarget.m_pEntity->As<CTFPlayer>()->m_nHitboxSet());
if (!pSet) break;
auto aBones = F::Backtrack.GetBones(tTarget.m_pEntity);
if (!aBones)
break;
auto pSet = tTarget.m_pEntity->As<CTFPlayer>()->GetHitboxSet();
if (!pSet)
break;
Vec3 vOffset = tOriginal.m_vOrigin - tTarget.m_vPos;
Vec3 vPos = trace.endpos + F::ProjSim.GetVelocity().Normalized() * 16 + vOffset;
@@ -1733,9 +1730,9 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas
bool CAimbotProjectile::Aim(const Vec3& vCurAngle, const Vec3& vToAngle, Vec3& vOut, int iMethod)
{
/*
if (Vec3* pDoubletapAngle = F::Ticks.GetShootAngle())
if (Vec3* pHoldAngle = F::Ticks.GetShootAngle())
{
vOut = *pDoubletapAngle;
vOut = *pHoldAngle;
return true;
}
*/
@@ -1755,8 +1752,8 @@ bool CAimbotProjectile::Aim(const Vec3& vCurAngle, const Vec3& vToAngle, Vec3& v
case Vars::Aimbot::General::AimTypeEnum::Assistive:
Vec3 vMouseDelta = G::CurrentUserCmd->viewangles.DeltaAngle(G::LastUserCmd->viewangles);
Vec3 vTargetDelta = vToAngle.DeltaAngle(G::LastUserCmd->viewangles);
float flMouseDelta = vMouseDelta.Length2D(), flTargetDelta = vTargetDelta.Length2D();
vTargetDelta = vTargetDelta.Normalized() * std::min(flMouseDelta, flTargetDelta);
float flMouseDelta = vMouseDelta.Length2DSqr(), flTargetDelta = vTargetDelta.Length2DSqr();
vTargetDelta = vTargetDelta.Normalized() * sqrtf(std::min(flMouseDelta, flTargetDelta));
vOut = vCurAngle - vMouseDelta + vMouseDelta.LerpAngle(vTargetDelta, Vars::Aimbot::General::AssistStrength.Value / 100.f);
bReturn = true;
break;
@@ -3,6 +3,17 @@
#include "../../Simulation/ProjectileSimulation/ProjectileSimulation.h"
#include "../../Simulation/MovementSimulation/MovementSimulation.h"
bool CAutoRocketJump::ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
{
if (!pLocal->IsAlive() || pLocal->IsAGhost()
|| !pWeapon
|| I::EngineVGui->IsGameUIVisible()
|| m_iFrame == -1 && pCmd->weaponselect)
return false;
return true;
}
bool CAutoRocketJump::SetAngles(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
{
m_vAngles = pCmd->viewangles;
@@ -102,7 +113,7 @@ bool CAutoRocketJump::SetAngles(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser
void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
{
if (!pWeapon || !pLocal->IsAlive() || pLocal->IsAGhost() || I::EngineVGui->IsGameUIVisible())
if (!ShouldRun(pLocal, pWeapon, pCmd))
{
m_iFrame = -1;
return;
@@ -127,13 +138,8 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p
case TF_WEAPON_PARTICLE_CANNON: bValidWeapon = true;
}
}
if (!bValidWeapon)
{
m_iFrame = -1;
return;
}
if (m_iFrame == -1 && (bCurrGrounded && bBeggars ? G::Attacking == 1 : G::CanPrimaryAttack || G::Reloading)
if (bValidWeapon && m_iFrame == -1 && (bCurrGrounded && bBeggars ? G::Attacking == 1 : G::CanPrimaryAttack || G::Reloading)
&& SetAngles(pLocal, pWeapon, pCmd))
{
bool bWillHit = false;
@@ -4,6 +4,7 @@
class CAutoRocketJump
{
private:
bool ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
bool SetAngles(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
Vec3 m_vAngles = {};
+8 -10
View File
@@ -149,15 +149,15 @@ std::vector<TickRecord*> CBacktrack::GetValidRecords(std::vector<TickRecord*>& v
return {};
std::vector<TickRecord*> vReturn = {};
float flCorrect = std::clamp(GetReal(MAX_FLOWS, false) + ROUND_TO_TICKS(GetFakeInterp()), 0.f, m_flMaxUnlag);
int iServerTick = m_iTickCount + GetAnticipatedChoke() + Vars::Backtrack::Offset.Value + TIME_TO_TICKS(GetReal(FLOW_OUTGOING));
float flCorrect = std::clamp(GetReal(MAX_FLOWS, false) + ROUND_TO_TICKS(GetFakeInterp()), 0.f, m_flMaxUnlag) + flTimeMod;
int iServerTick = m_iTickCount + TIME_TO_TICKS(GetReal(FLOW_OUTGOING)) + GetAnticipatedChoke() + Vars::Backtrack::Offset.Value;
if (!Vars::Misc::Game::AntiCheatCompatibility.Value && GetWindow())
{
for (auto pRecord : vRecords)
{
float flDelta = fabsf(flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(pRecord->m_flSimTime + flTimeMod)));
if (flDelta > GetWindow())
float flDelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(pRecord->m_flSimTime));
if (fabsf(flDelta) > GetWindow())
continue;
vReturn.push_back(pRecord);
@@ -169,8 +169,8 @@ std::vector<TickRecord*> CBacktrack::GetValidRecords(std::vector<TickRecord*>& v
float flMinDelta = 0.2f;
for (auto pRecord : vRecords)
{
float flDelta = fabsf(flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(pRecord->m_flSimTime + flTimeMod)));
if (flDelta > flMinDelta)
float flDelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(pRecord->m_flSimTime));
if (fabsf(flDelta) > flMinDelta)
continue;
flMinDelta = flDelta;
@@ -188,18 +188,16 @@ std::vector<TickRecord*> CBacktrack::GetValidRecords(std::vector<TickRecord*>& v
return pLocal->m_vecOrigin().DistToSqr(a->m_vOrigin) < pLocal->m_vecOrigin().DistToSqr(b->m_vOrigin);
});
else
{
std::sort(vReturn.begin(), vReturn.end(), [&](const TickRecord* a, const TickRecord* b) -> bool
{
if (Vars::Backtrack::PreferOnShot.Value && a->m_bOnShot != b->m_bOnShot)
return a->m_bOnShot > b->m_bOnShot;
const float flADelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(a->m_flSimTime + flTimeMod));
const float flBDelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(b->m_flSimTime + flTimeMod));
float flADelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(a->m_flSimTime));
float flBDelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(b->m_flSimTime));
return fabsf(flADelta) < fabsf(flBDelta);
});
}
}
return vReturn;
}
+33 -2
View File
@@ -5,13 +5,21 @@
#include <utility>
#include <boost/algorithm/string/replace.hpp>
#define AddCommand(sCommand, fCommand) \
#define AddCommand(sCommand, ...) \
{ \
FNV1A::Hash32Const(sCommand), \
[](const std::deque<const char*>& vArgs) \
fCommand \
__VA_ARGS__ \
},
//struct ConVarValues_t
//{
// int m_iValue;
// float m_flValue;
// const char* m_sValue;
//};
//static std::unordered_map<ConVar*, ConVarValues_t> s_mConVarValues = {};
static std::unordered_map<uint32_t, CommandCallback> s_mCommands = {
AddCommand("setcvar",
{
@@ -89,6 +97,29 @@ static std::unordered_map<uint32_t, CommandCallback> s_mCommands = {
}
reinterpret_cast<void(*)()>(0)();
})
//AddCommand("recordcvars",
//{
// for (ConCommandBase* pBase = I::CVar->GetCommands(); pBase; pBase = pBase->m_pNext)
// {
// if (pBase->IsCommand())
// continue;
// auto pCVar = reinterpret_cast<ConVar*>(pBase);
// s_mConVarValues[pCVar] = { pCVar->GetInt(), pCVar->GetFloat(), pCVar->GetString() };
// }
//})
//AddCommand("diffcvars",
//{
// for (auto& [pCVar, tValues] : s_mConVarValues)
// {
// if (auto iOld = tValues.m_iValue, iNew = pCVar->GetInt(); iOld != iNew)
// SDK::Output(pCVar->GetName(), std::format("int: {} -> {}", iOld, iNew).c_str());
// else if (auto flOld = tValues.m_flValue, flNew = pCVar->GetFloat(); flOld != flNew)
// SDK::Output(pCVar->GetName(), std::format("float: {} -> {}", flOld, flNew).c_str());
// else if (auto sOld = tValues.m_sValue, sNew = pCVar->GetString(); sOld != sNew || FNV1A::Hash32(sOld) != FNV1A::Hash32(sNew))
// SDK::Output(pCVar->GetName(), std::format("string: {} -> {}", sOld, sNew).c_str());
// }
//})
};
bool CCommands::Run(const char* sCmd, std::deque<const char*>& vArgs)
+1
View File
@@ -1,5 +1,6 @@
#pragma once
#include "../../SDK/SDK.h"
#include <functional>
using CommandCallback = const std::function<void(std::deque<const char*>&)>;
+27 -3
View File
@@ -3,20 +3,44 @@
#include "NoSpreadProjectile/NoSpreadProjectile.h"
#include "NoSpreadHitscan/NoSpreadHitscan.h"
bool CNoSpread::ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
bool CNoSpread::ShouldRun(CTFWeaponBase* pWeapon)
{
if (!Vars::Aimbot::General::NoSpread.Value
|| !pWeapon || !pLocal->CanAttack())
|| !pWeapon || G::Attacking != 1)
return false;
return true;
}
void CNoSpread::StoreAngle(CUserCmd* pCmd, bool bFinal)
{
if (!Vars::Aimbot::General::NoSpread.Value)
{
m_vOffset = {};
return;
}
if (G::PrimaryWeaponType == EWeaponType::HITSCAN && I::ClientState->chokedcommands && m_vOffset)
return;
if (!bFinal)
m_vAngles = pCmd->viewangles;
else
m_vOffset = pCmd->viewangles - m_vAngles;
}
void CNoSpread::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
{
if (!ShouldRun(pLocal, pWeapon))
StoreAngle(pCmd, false);
if (!ShouldRun(pWeapon))
return;
F::NoSpreadHitscan.Run(pLocal, pWeapon, pCmd);
F::NoSpreadProjectile.Run(pLocal, pWeapon, pCmd);
StoreAngle(pCmd, true);
}
Vec3 CNoSpread::GetOffset()
{
return m_vOffset;
}
+6 -1
View File
@@ -4,10 +4,15 @@
class CNoSpread
{
private:
bool ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
bool ShouldRun(CTFWeaponBase* pWeapon);
void StoreAngle(CUserCmd* pCmd, bool bFinal);
Vec3 m_vAngles = {};
Vec3 m_vOffset = {};
public:
void Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
Vec3 GetOffset();
};
ADD_FEATURE(CNoSpread, NoSpread);
@@ -19,13 +19,14 @@ void CNoSpreadHitscan::Reset()
m_bSynced = false;
}
bool CNoSpreadHitscan::ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, bool bCreateMove)
bool CNoSpreadHitscan::ShouldRun(CTFWeaponBase* pWeapon)
{
if (G::PrimaryWeaponType != EWeaponType::HITSCAN
|| (bCreateMove ? pWeapon->GetWeaponSpread() : S::CTFWeaponBaseGun_GetWeaponSpread.Call<float>(pWeapon)) <= 0.f)
if (pWeapon
? G::PrimaryWeaponType != EWeaponType::HITSCAN || pWeapon->GetWeaponSpread() <= 0.f
: !Vars::Aimbot::General::NoSpread.Value || !I::EngineClient->IsInGame())
return false;
return bCreateMove ? G::Attacking == 1 : true;
return true;
}
int CNoSpreadHitscan::GetSeed(CUserCmd* pCmd)
@@ -66,7 +67,7 @@ std::string CNoSpreadHitscan::GetFormat(int iServerTime)
void CNoSpreadHitscan::AskForPlayerPerf()
{
if (!Vars::Aimbot::General::NoSpread.Value || !I::EngineClient->IsInGame())
if (!ShouldRun())
return Reset();
if (G::Choking)
@@ -83,7 +84,7 @@ void CNoSpreadHitscan::AskForPlayerPerf()
bool CNoSpreadHitscan::ParsePlayerPerf(const std::string& sMsg)
{
if (!Vars::Aimbot::General::NoSpread.Value)
if (!ShouldRun())
return false;
std::smatch tMatch; std::regex_match(sMsg, tMatch, std::regex(R"((\d+.\d+)\s\d+\s\d+\s\d+.\d+\s\d+.\d+\svel\s\d+.\d+)"));
@@ -129,7 +130,7 @@ bool CNoSpreadHitscan::ParsePlayerPerf(const std::string& sMsg)
void CNoSpreadHitscan::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
{
if (!ShouldRun(pLocal, pWeapon, true))
if (!ShouldRun(pWeapon))
return;
m_iSeed = GetSeed(pCmd);
@@ -194,13 +195,9 @@ void CNoSpreadHitscan::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd*
void CNoSpreadHitscan::Draw(CTFPlayer* pLocal)
{
if (!(Vars::Menu::Indicators.Value & Vars::Menu::IndicatorsEnum::SeedPrediction) || !Vars::Aimbot::General::NoSpread.Value || !pLocal->IsAlive())
if (!(Vars::Menu::Indicators.Value & Vars::Menu::IndicatorsEnum::SeedPrediction) || !ShouldRun() || !pLocal->IsAlive())
return;
//auto pWeapon = H::Entities.GetWeapon();
//if (!pWeapon || !ShouldRun(pLocal, pWeapon))
// return;
int x = Vars::Menu::SeedPredictionDisplay.Value.x;
int y = Vars::Menu::SeedPredictionDisplay.Value.y + 8;
const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS);
@@ -6,6 +6,7 @@
class CNoSpreadHitscan
{
private:
bool ShouldRun(CTFWeaponBase* pWeapon = nullptr);
int GetSeed(CUserCmd* pCmd);
float CalcMantissaStep(float flV);
std::string GetFormat(int iServerTime);
@@ -19,7 +20,6 @@ private:
public:
void Reset();
bool ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, bool bCreateMove = false);
void AskForPlayerPerf();
bool ParsePlayerPerf(const std::string& sMsg);
@@ -1,16 +1,16 @@
#include "NoSpreadProjectile.h"
bool CNoSpreadProjectile::ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
bool CNoSpreadProjectile::ShouldRun(CTFWeaponBase* pWeapon)
{
if (G::PrimaryWeaponType != EWeaponType::PROJECTILE)
return false;
return G::Attacking == 1;
return true;
}
void CNoSpreadProjectile::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
{
if (!ShouldRun(pLocal, pWeapon))
if (!ShouldRun(pWeapon))
return;
switch (pWeapon->GetWeaponID())
@@ -4,7 +4,7 @@
class CNoSpreadProjectile
{
private:
bool ShouldRun(CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
bool ShouldRun(CTFWeaponBase* pWeapon);
public:
void Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
+5 -5
View File
@@ -389,14 +389,14 @@ void CTicks::SaveShootAngle(CUserCmd* pCmd, bool bSendPacket)
static auto sv_maxusrcmdprocessticks_holdaim = H::ConVars.FindVar("sv_maxusrcmdprocessticks_holdaim");
if (bSendPacket)
m_bShootAngle = false;
else if (!m_bShootAngle && G::Attacking == 1 && sv_maxusrcmdprocessticks_holdaim->GetBool())
m_vShootAngle = pCmd->viewangles, m_bShootAngle = true;
m_vShootAngle = std::nullopt;
else if (!m_vShootAngle && G::Attacking == 1 && sv_maxusrcmdprocessticks_holdaim->GetBool())
m_vShootAngle = pCmd->viewangles;
}
Vec3* CTicks::GetShootAngle()
{
if (m_bShootAngle && I::ClientState->chokedcommands)
return &m_vShootAngle;
if (m_vShootAngle && I::ClientState->chokedcommands)
return &m_vShootAngle.value();
return nullptr;
}
+1 -3
View File
@@ -17,9 +17,7 @@ private:
bool m_bGoalReached = true;
Vec3 m_vShootPos = {};
bool m_bShootAngle = false;
Vec3 m_vShootAngle = {};
std::optional<Vec3> m_vShootAngle = std::nullopt;
bool m_bPredictAntiwarp = false;
bool m_bTimingUnsure = false; // we aren't sure when we'll actually fire, hold aim
+5 -7
View File
@@ -437,12 +437,9 @@ std::vector<DrawBox_t> CVisuals::GetHitboxes(matrix3x4* aBones, CBaseAnimating*
std::vector<DrawBox_t> vBoxes = {};
auto pModel = pEntity->GetModel();
if (!pModel) return vBoxes;
auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel);
if (!pHDR) return vBoxes;
auto pSet = pHDR->pHitboxSet(pEntity->m_nHitboxSet());
if (!pSet) return vBoxes;
auto pSet = pEntity->GetHitboxSet();
if (!pSet)
return vBoxes;
if (vHitboxes.empty())
{
@@ -453,7 +450,8 @@ std::vector<DrawBox_t> CVisuals::GetHitboxes(matrix3x4* aBones, CBaseAnimating*
for (int nHitbox : vHitboxes)
{
auto pBox = pSet->pHitbox(nHitbox);
if (!pBox) continue;
if (!pBox)
continue;
bool bTargeted = nHitbox == iTarget;
Vec3 vAngle; Math::MatrixAngles(aBones[pBox->bone], vAngle);
@@ -2,42 +2,44 @@
#include "../../SDK.h"
mstudiohitboxset_t* CBaseAnimating::GetHitboxSet()
{
auto pHDR = GetStudiomodel();
if (!pHDR)
return nullptr;
return pHDR->pHitboxSet(m_nHitboxSet());
}
int CBaseAnimating::GetHitboxGroup(int nHitbox)
{
auto pModel = GetModel();
if (!pModel) return -1;
auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel);
if (!pHDR) return -1;
auto pSet = pHDR->pHitboxSet(m_nHitboxSet());
if (!pSet) return -1;
auto pSet = GetHitboxSet();
if (!pSet)
return -1;
auto pBox = pSet->pHitbox(nHitbox);
if (!pBox) return -1;
if (!pBox)
return -1;
return pBox->group;
}
int CBaseAnimating::GetNumOfHitboxes()
{
auto pModel = GetModel();
if (!pModel) return 0;
auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel);
if (!pHDR) return 0;
auto pSet = pHDR->pHitboxSet(m_nHitboxSet());
if (!pSet) return 0;
auto pSet = GetHitboxSet();
if (!pSet)
return 0;
return pSet->numhitboxes;
}
Vec3 CBaseAnimating::GetHitboxOrigin(matrix3x4* aBones, int nHitbox, Vec3 vOffset)
{
auto pModel = GetModel();
if (!pModel) return {};
auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel);
if (!pHDR) return {};
auto pSet = pHDR->pHitboxSet(m_nHitboxSet());
if (!pSet || pSet->numhitboxes <= nHitbox) return {};
auto pSet = GetHitboxSet();
if (!pSet || pSet->numhitboxes <= nHitbox)
return {};
auto pBox = pSet->pHitbox(nHitbox);
if (!pBox) return {};
if (!pBox)
return {};
Vec3 vOut; Math::VectorTransform(vOffset, aBones[pBox->bone], vOut);
return vOut;
@@ -45,14 +47,12 @@ Vec3 CBaseAnimating::GetHitboxOrigin(matrix3x4* aBones, int nHitbox, Vec3 vOffse
Vec3 CBaseAnimating::GetHitboxCenter(matrix3x4* aBones, int nHitbox, Vec3 vOffset)
{
auto pModel = GetModel();
if (!pModel) return {};
auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel);
if (!pHDR) return {};
auto pSet = pHDR->pHitboxSet(m_nHitboxSet());
if (!pSet || pSet->numhitboxes <= nHitbox) return {};
auto pSet = GetHitboxSet();
if (!pSet || pSet->numhitboxes <= nHitbox)
return {};
auto pBox = pSet->pHitbox(nHitbox);
if (!pBox) return {};
if (!pBox)
return {};
Vec3 vOut; Math::VectorTransform((pBox->bbmin + pBox->bbmax) / 2 + vOffset, aBones[pBox->bone], vOut);
return vOut;
@@ -60,14 +60,12 @@ Vec3 CBaseAnimating::GetHitboxCenter(matrix3x4* aBones, int nHitbox, Vec3 vOffse
void CBaseAnimating::GetHitboxInfo(matrix3x4* aBones, int nHitbox, Vec3* pCenter, Vec3* pMins, Vec3* pMaxs, matrix3x4* pMatrix, Vec3 vOffset)
{
auto pModel = GetModel();
if (!pModel) return;
auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel);
if (!pHDR) return;
auto pSet = pHDR->pHitboxSet(m_nHitboxSet());
if (!pSet || pSet->numhitboxes <= nHitbox) return;
auto pSet = GetHitboxSet();
if (!pSet || pSet->numhitboxes <= nHitbox)
return;
auto pBox = pSet->pHitbox(nHitbox);
if (!pBox) return;
if (!pBox)
return;
if (pMins)
*pMins = pBox->bbmin;
@@ -56,6 +56,7 @@ public:
return bReturn;
}
mstudiohitboxset_t* GetHitboxSet();
int GetHitboxGroup(int nHitbox);
int GetNumOfHitboxes();
Vec3 GetHitboxOrigin(matrix3x4* aBones, int nHitbox, Vec3 vOffset = {});
@@ -33,6 +33,15 @@ Vec3 CBaseEntity::GetRenderCenter()
return GetRenderOrigin() + (vMaxs - vMins) / 2;
}
studiohdr_t* CBaseEntity::GetStudiomodel()
{
auto pModel = GetModel();
if (!pModel)
return nullptr;
return I::ModelInfoClient->GetStudiomodel(pModel);
}
int CBaseEntity::IsInValidTeam()
{
switch (int nTeamNum = m_iTeamNum())
@@ -296,6 +296,7 @@ public:
Vec3 GetOffset();
Vec3 GetCenter();
Vec3 GetRenderCenter();
studiohdr_t* GetStudiomodel();
int IsInValidTeam();
int SolidMask();
int GetHitboxToBase(int nHitbox);
+8 -10
View File
@@ -121,16 +121,14 @@ bool CTFPlayer::IsCritBoosted()
|| InCond(TF_COND_CRITBOOSTED_RUNE_TEMP))
return true;
auto pWeapon = m_hActiveWeapon()->As<CTFWeaponBase>();
if (!pWeapon)
return false;
auto pWeaponInfo = pWeapon->m_pWeaponInfo();
if (!pWeaponInfo)
return false;
if (InCond(TF_COND_CRITBOOSTED_RAGE_BUFF) && pWeaponInfo->m_iWeaponType == TF_WPN_TYPE_PRIMARY)
return true;
if (auto pWeapon = m_hActiveWeapon()->As<CTFWeaponBase>())
{
if (auto pWeaponInfo = pWeapon->m_pWeaponInfo())
{
if (InCond(TF_COND_CRITBOOSTED_RAGE_BUFF) && pWeaponInfo->m_iWeaponType == TF_WPN_TYPE_PRIMARY)
return true;
}
}
return false;
}
+3 -5
View File
@@ -7,12 +7,10 @@ bool CConVars::Unlock()
{
if (!m_bUnlocked)
{
ConCommandBase* pCmdBase = I::CVar->GetCommands();
while (pCmdBase != nullptr)
for (ConCommandBase* pBase = I::CVar->GetCommands(); pBase; pBase = pBase->m_pNext)
{
m_mFlagMap[pCmdBase] = pCmdBase->m_nFlags;
pCmdBase->m_nFlags &= ~(FCVAR_HIDDEN | FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT | FCVAR_NOT_CONNECTED);
pCmdBase = pCmdBase->m_pNext;
m_mFlagMap[pBase] = pBase->m_nFlags;
pBase->m_nFlags &= ~(FCVAR_HIDDEN | FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT | FCVAR_NOT_CONNECTED);
}
m_bUnlocked = true;
+16 -17
View File
@@ -254,10 +254,10 @@ void CEntities::Store()
if (n != I::EngineClient->GetLocalPlayer())
{
bool bDormant = pPlayer->IsDormant();
float flSimTime = pPlayer->m_flSimulationTime(), flOldSimTime = pPlayer->m_flOldSimulationTime();
if (float flDeltaTime = m_aDeltaTimes[n] = TICKS_TO_TIME(std::clamp(TIME_TO_TICKS(flSimTime - flOldSimTime) - iLag, 0, 24)))
if (float flOldSimTime = m_aSimTimes[n], flSimTime = m_aSimTimes[n] = pPlayer->m_flSimulationTime();
m_aDeltaTimes[n] = flSimTime != flOldSimTime)
{
m_aLagTimes[n] = flDeltaTime;
m_aDeltaTimes[n] = m_aLagTimes[n] = TICKS_TO_TIME(std::clamp(TIME_TO_TICKS(flSimTime - flOldSimTime) - iLag, 1, 24));
m_aSetTicks[n] = I::GlobalVars->tickcount;
if (!bDormant)
{
@@ -267,12 +267,11 @@ void CEntities::Store()
if (pPlayer->IsAlive())
F::CheaterDetection.ReportChoke(pPlayer, m_aChokes[n]);
m_aOldAngles[n] = m_aEyeAngles[n], m_aEyeAngles[n] = pPlayer->As<CTFPlayer>()->GetEyeAngles();
}
else
m_aOrigins[n].clear();
m_aOldAngles[n] = m_aEyeAngles[n];
m_aEyeAngles[n] = pPlayer->As<CTFPlayer>()->GetEyeAngles();
}
m_aChokes[n] = I::GlobalVars->tickcount - m_aSetTicks[n];
}
@@ -507,18 +506,18 @@ CTFPlayerResource* CEntities::GetResource()
return m_pPlayerResource;
}
const std::vector<CBaseEntity*>& CEntities::GetGroup(byte iGroup) { return m_aGroups[iGroup]; }
const std::vector<CBaseEntity*>& CEntities::GetGroup(uint8_t iGroup) { return m_aGroups[iGroup]; }
float CEntities::GetDeltaTime(byte iIndex) { return iIndex < MAX_PLAYERS ? m_aDeltaTimes[iIndex] : TICK_INTERVAL; }
float CEntities::GetLagTime(byte iIndex) { return iIndex < MAX_PLAYERS ? m_aLagTimes[iIndex] : TICK_INTERVAL; }
int CEntities::GetChoke(byte iIndex) { return iIndex < MAX_PLAYERS ? m_aChokes[iIndex] : 0; }
Vec3 CEntities::GetEyeAngles(byte iIndex) { return iIndex < MAX_PLAYERS ? m_aEyeAngles[iIndex] : Vec3(); }
Vec3 CEntities::GetDeltaAngles(byte iIndex) { return iIndex < MAX_PLAYERS ? m_aEyeAngles[iIndex].DeltaAngle(m_aOldAngles[iIndex]) / GetLagTime(iIndex) * (F::Backtrack.GetReal() + TICKS_TO_TIME(F::Backtrack.GetAnticipatedChoke())) : Vec3(); }
bool CEntities::GetLagCompensation(byte iIndex) { return iIndex < MAX_PLAYERS ? m_aLagCompensation[iIndex] : false; }
void CEntities::SetLagCompensation(byte iIndex, bool bLagComp) { if (iIndex < MAX_PLAYERS) m_aLagCompensation[iIndex] = bLagComp; }
Vec3* CEntities::GetAvgVelocity(byte iIndex) { return iIndex < MAX_PLAYERS && iIndex != I::EngineClient->GetLocalPlayer() ? &m_aAvgVelocities[iIndex] : nullptr; }
void CEntities::SetAvgVelocity(byte iIndex, Vec3 vAvgVelocity) { if (iIndex < MAX_PLAYERS) m_aAvgVelocities[iIndex] = vAvgVelocity; }
std::deque<VelFixRecord>* CEntities::GetOrigins(byte iIndex) { return iIndex < MAX_PLAYERS ? &m_aOrigins[iIndex] : nullptr; }
float CEntities::GetDeltaTime(uint16_t iIndex) { return iIndex < MAX_PLAYERS ? m_aDeltaTimes[iIndex] : TICK_INTERVAL; }
float CEntities::GetLagTime(uint16_t iIndex) { return iIndex < MAX_PLAYERS ? m_aLagTimes[iIndex] : TICK_INTERVAL; }
int CEntities::GetChoke(uint16_t iIndex) { return iIndex < MAX_PLAYERS ? m_aChokes[iIndex] : 0; }
Vec3 CEntities::GetEyeAngles(uint16_t iIndex) { return iIndex < MAX_PLAYERS ? m_aEyeAngles[iIndex] : Vec3(); }
Vec3 CEntities::GetDeltaAngles(uint16_t iIndex) { return iIndex < MAX_PLAYERS ? m_aEyeAngles[iIndex].DeltaAngle(m_aOldAngles[iIndex]) / GetLagTime(iIndex) * (F::Backtrack.GetReal() + TICKS_TO_TIME(F::Backtrack.GetAnticipatedChoke())) : Vec3(); }
bool CEntities::GetLagCompensation(uint16_t iIndex) { return iIndex < MAX_PLAYERS ? m_aLagCompensation[iIndex] : false; }
void CEntities::SetLagCompensation(uint16_t iIndex, bool bLagComp) { if (iIndex < MAX_PLAYERS) m_aLagCompensation[iIndex] = bLagComp; }
Vec3* CEntities::GetAvgVelocity(uint16_t iIndex) { return iIndex < MAX_PLAYERS && iIndex != I::EngineClient->GetLocalPlayer() ? &m_aAvgVelocities[iIndex] : nullptr; }
void CEntities::SetAvgVelocity(uint16_t iIndex, Vec3 vAvgVelocity) { if (iIndex < MAX_PLAYERS) m_aAvgVelocities[iIndex] = vAvgVelocity; }
std::deque<VelFixRecord>* CEntities::GetOrigins(uint16_t iIndex) { return iIndex < MAX_PLAYERS ? &m_aOrigins[iIndex] : nullptr; }
uint32_t CEntities::GetModel(unsigned short iIndex) { return iIndex < MAX_EDICTS ? m_aModels[iIndex] : 0; }
bool CEntities::GetDormancy(unsigned short iIndex) { return iIndex < MAX_EDICTS ? m_aDormancy[iIndex] : false; }
+12 -12
View File
@@ -35,7 +35,7 @@ private:
std::array<std::vector<CBaseEntity*>, EntityEnum::GroupsMax> m_aGroups = {};
std::array<float, MAX_PLAYERS> m_aDeltaTimes = {}, m_aLagTimes = {};
std::array<float, MAX_PLAYERS> m_aSimTimes = {}, m_aDeltaTimes = {}, m_aLagTimes = {};
std::array<int, MAX_PLAYERS> m_aChokes = {}, m_aSetTicks = {};
std::array<Vec3, MAX_PLAYERS> m_aOldAngles = {}, m_aEyeAngles = {};
std::array<bool, MAX_PLAYERS> m_aLagCompensation = {};
@@ -71,18 +71,18 @@ public:
CTFWeaponBase* GetWeapon();
CTFPlayerResource* GetResource();
const std::vector<CBaseEntity*>& GetGroup(byte iGroup);
const std::vector<CBaseEntity*>& GetGroup(uint8_t iGroup);
float GetDeltaTime(byte iIndex);
float GetLagTime(byte iIndex);
int GetChoke(byte iIndex);
Vec3 GetEyeAngles(byte iIndex);
Vec3 GetDeltaAngles(byte iIndex);
bool GetLagCompensation(byte iIndex);
void SetLagCompensation(byte iIndex, bool bLagComp);
Vec3* GetAvgVelocity(byte iIndex);
void SetAvgVelocity(byte iIndex, Vec3 vAvgVelocity);
std::deque<VelFixRecord>* GetOrigins(byte iIndex);
float GetDeltaTime(uint16_t iIndex);
float GetLagTime(uint16_t iIndex);
int GetChoke(uint16_t iIndex);
Vec3 GetEyeAngles(uint16_t iIndex);
Vec3 GetDeltaAngles(uint16_t iIndex);
bool GetLagCompensation(uint16_t iIndex);
void SetLagCompensation(uint16_t iIndex, bool bLagComp);
Vec3* GetAvgVelocity(uint16_t iIndex);
void SetAvgVelocity(uint16_t iIndex, Vec3 vAvgVelocity);
std::deque<VelFixRecord>* GetOrigins(uint16_t iIndex);
uint32_t GetModel(unsigned short iIndex);
bool GetDormancy(unsigned short iIndex);
+21
View File
@@ -337,6 +337,27 @@ namespace Math
return vOut;
}
inline void MatrixInitialize(matrix3x4& mMatrix, const Vec3& vOrigin, const Vec3& vXAxis, const Vec3& vYAxis, const Vec3& vZAxis)
{
mMatrix[0][0] = vXAxis.x, mMatrix[0][1] = vYAxis.x, mMatrix[0][2] = vZAxis.x, mMatrix[0][3] = vOrigin.x;
mMatrix[1][0] = vXAxis.y, mMatrix[1][1] = vYAxis.y, mMatrix[1][2] = vZAxis.y, mMatrix[1][3] = vOrigin.y;
mMatrix[2][0] = vXAxis.z, mMatrix[2][1] = vYAxis.z, mMatrix[2][2] = vZAxis.z, mMatrix[2][3] = vOrigin.z;
}
inline void MatrixInitialize(matrix3x4& mMatrix, const Vec3& vOrigin = {}, bool bAxes = true)
{
if (bAxes)
{
mMatrix[0][0] = 1, mMatrix[0][1] = 0, mMatrix[0][2] = 0;
mMatrix[1][0] = 0, mMatrix[1][1] = 1, mMatrix[1][2] = 0;
mMatrix[2][0] = 0, mMatrix[2][1] = 0, mMatrix[2][2] = 1;
}
mMatrix[0][3] = vOrigin.x;
mMatrix[1][3] = vOrigin.y;
mMatrix[2][3] = vOrigin.z;
}
inline void MatrixCopy(const matrix3x4& mIn, matrix3x4& mOut)
{
for (int i = 0; i < 3; i++)