mirror of
https://github.com/rei-2/Amalgam
synced 2026-10-10 04:43:09 +08:00
restructure hitscan
misc fixes
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "../../SDK/SDK.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
using CommandCallback = const std::function<void(std::deque<const char*>&)>;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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++)
|
||||
|
||||
Reference in New Issue
Block a user