fixes to melee aim

always include at least 1 bt record if we can
This commit is contained in:
rei-2 committed 2025-01-23 12:02:12 -05:00
1 parent d42d5d9976
commit 8a5264e567
8 files changed
+80 -98

No files matched your search

@@ -25,7 +25,7 @@ struct Target_t
int m_nPriority = 0;
int m_nAimedHitbox = -1;
TickRecord m_Tick = {};
TickRecord m_tRecord = {};
bool m_bBacktrack = false;
};
@@ -306,13 +306,13 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p
};
int iReturn = false;
for (auto& pTick : vRecords)
for (auto& tRecord : vRecords)
{
bool bRunPeekCheck = flSpread && (Vars::Aimbot::General::PeekDTOnly.Value ? F::Ticks.GetTicks(pWeapon) : true) && Vars::Aimbot::General::HitscanPeek.Value;
if (target.m_TargetType == ETargetType::Player || target.m_TargetType == ETargetType::Sentry)
{
auto aBones = pTick.m_BoneMatrix.m_aBones;
auto aBones = tRecord.m_BoneMatrix.m_aBones;
if (!aBones)
continue;
@@ -423,9 +423,9 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p
}
if (bWillHit)
{
flPreferredRecord = pTick.m_flSimTime;
flPreferredRecord = tRecord.m_flSimTime;
target.m_Tick = pTick;
target.m_tRecord = tRecord;
target.m_vPos = vTransformed;
target.m_nAimedHitbox = pair.second;
if (target.m_TargetType == ETargetType::Player)
@@ -483,7 +483,7 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p
target.m_vAngleTo = vAngles;
if (RayToOBB(vEyePos, vForward, vMins, vMaxs, transform)) // for the time being, no vischecks against other hitboxes
{
target.m_Tick = pTick;
target.m_tRecord = tRecord;
target.m_vPos = vTransformed;
return true;
}
@@ -743,7 +743,7 @@ void CAimbotHitscan::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pC
F::Resolver.Aimbot(target.m_pEntity->As<CTFPlayer>(), target.m_nAimedHitbox == HITBOX_HEAD);
if (target.m_bBacktrack)
pCmd->tick_count = TIME_TO_TICKS(target.m_Tick.m_flSimTime) + TIME_TO_TICKS(F::Backtrack.m_flFakeInterp);
pCmd->tick_count = TIME_TO_TICKS(target.m_tRecord.m_flSimTime) + TIME_TO_TICKS(F::Backtrack.m_flFakeInterp);
bool bLine = Vars::Visuals::Bullet::Enabled.Value;
bool bBoxes = Vars::Visuals::Hitbox::Enabled.Value & Vars::Visuals::Hitbox::EnabledEnum::OnShot;
@@ -757,7 +757,7 @@ void CAimbotHitscan::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pC
G::LineStorage.push_back({ { pLocal->GetShootPos(), target.m_vPos }, I::GlobalVars->curtime + 5.f, Vars::Colors::Bullet.Value, true });
if (bBoxes)
{
auto vBoxes = F::Visuals.GetHitboxes(target.m_Tick.m_BoneMatrix.m_aBones, target.m_pEntity->As<CBaseAnimating>(), {}, target.m_nAimedHitbox);
auto vBoxes = F::Visuals.GetHitboxes(target.m_tRecord.m_BoneMatrix.m_aBones, target.m_pEntity->As<CBaseAnimating>(), {}, target.m_nAimedHitbox);
G::BoxStorage.insert(G::BoxStorage.end(), vBoxes.begin(), vBoxes.end());
}
}
@@ -258,28 +258,20 @@ bool CAimbotMelee::CanBackstab(CBaseEntity* pTarget, CTFPlayer* pLocal, Vec3 vEy
return true;
}
int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Vec3 vEyePos, std::deque<TickRecord> newRecords)
int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Vec3 vEyePos, std::deque<TickRecord>& vSimRecords)
{
if (Vars::Aimbot::General::Ignore.Value & Vars::Aimbot::General::IgnoreEnum::Unsimulated && H::Entities.GetChoke(target.m_pEntity->entindex()) > Vars::Aimbot::General::TickTolerance.Value)
return false;
float flHull = SDK::AttribHookValue(18, "melee_bounds_multiplier", pWeapon);
float flRange = pWeapon->GetSwingRange(pLocal);
float flRange = SDK::AttribHookValue(pWeapon->GetSwingRange(pLocal), "melee_range_multiplier", pWeapon);
if (pLocal->m_flModelScale() > 1.0f)
{
flRange *= pLocal->m_flModelScale();
flRange *= pLocal->m_flModelScale();
flRange *= pLocal->m_flModelScale();
flHull *= pLocal->m_flModelScale();
}
flRange = SDK::AttribHookValue(flRange, "melee_range_multiplier", pWeapon);
if (flHull <= 0.f || flRange <= 0.f)
return false;
static Vec3 vSwingMins = { -flHull, -flHull, -flHull };
static Vec3 vSwingMaxs = { flHull, flHull, flHull };
CGameTrace trace = {};
CTraceFilterHitscan filter = {}; filter.pSkip = pLocal;
Vec3 vSwingMins = { -flHull, -flHull, -flHull };
Vec3 vSwingMaxs = { flHull, flHull, flHull };
std::deque<TickRecord> vRecords;
{
@@ -319,50 +311,44 @@ int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWe
}
}
}
if (!newRecords.empty())
if (!vSimRecords.empty())
{
for (TickRecord& pTick : newRecords)
for (TickRecord& tRecord : vSimRecords)
{
vRecords.pop_back();
vRecords.push_front({ pTick.m_flSimTime, {}, pTick.m_vOrigin });
vRecords.push_front({ tRecord.m_flSimTime, {}, tRecord.m_vOrigin, target.m_pEntity->m_vecMins(), target.m_pEntity->m_vecMaxs() });
}
for (TickRecord& pTick : vRecords)
pTick.m_flSimTime -= TICKS_TO_TIME(newRecords.size());
for (TickRecord& tRecord : vRecords)
tRecord.m_flSimTime -= TICKS_TO_TIME(vSimRecords.size());
}
std::deque<TickRecord> validRecords = target.m_TargetType == ETargetType::Player ? F::Backtrack.GetValidRecords(&vRecords, pLocal, true) : vRecords;
if (!Vars::Backtrack::Enabled.Value && !validRecords.empty())
validRecords = { validRecords.front() };
vRecords = target.m_TargetType == ETargetType::Player ? F::Backtrack.GetValidRecords(&vRecords, pLocal, true) : vRecords;
if (!Vars::Backtrack::Enabled.Value && !vRecords.empty())
vRecords = { vRecords.front() };
// this might be retarded
const float flTargetPos = (target.m_pEntity->m_vecMaxs().z - target.m_pEntity->m_vecMins().z) * 65.f / 82.f;
const float flLocalPos = (pLocal->m_vecMaxs().z - pLocal->m_vecMins().z) * 65.f / 82.f;
const Vec3 vDiff = { 0, 0, std::min(flTargetPos, flLocalPos) };
auto originTolerance = [target](float flTolerance)
{
target.m_pEntity->m_vecMins() += flTolerance;
target.m_pEntity->m_vecMaxs() -= flTolerance;
};
// account for origin tolerance
originTolerance(0.125f);
for (auto& pTick : validRecords)
CGameTrace trace = {};
CTraceFilterHitscan filter = {}; filter.pSkip = pLocal;
for (auto& tRecord : vRecords)
{
const Vec3 vRestore = target.m_pEntity->GetAbsOrigin();
target.m_pEntity->SetAbsOrigin(pTick.m_vOrigin);
Vec3 vRestoreOrigin = target.m_pEntity->GetAbsOrigin();
Vec3 vRestoreMins = target.m_pEntity->m_vecMins();
Vec3 vRestoreMaxs = target.m_pEntity->m_vecMaxs();
target.m_vPos = pTick.m_vOrigin + vDiff;
target.m_pEntity->SetAbsOrigin(tRecord.m_vOrigin);
target.m_pEntity->m_vecMins() = tRecord.m_vMins + 0.125f; // account for origin tolerance
target.m_pEntity->m_vecMaxs() = tRecord.m_vMaxs - 0.125f;
Vec3 vDiff = { 0, 0, std::clamp(vEyePos.z - tRecord.m_vOrigin.z, target.m_pEntity->m_vecMins().z, target.m_pEntity->m_vecMaxs().z) };
target.m_vPos = tRecord.m_vOrigin + vDiff;
target.m_vAngleTo = Aim(G::CurrentUserCmd->viewangles, Math::CalcAngle(vEyePos, target.m_vPos));
Vec3 vForward; Math::AngleVectors(target.m_vAngleTo, &vForward);
Vec3 vTraceEnd = vEyePos + (vForward * flRange);
SDK::Trace(vEyePos, vTraceEnd, MASK_SHOT | CONTENTS_GRATE, &filter, &trace);
SDK::TraceHull(vEyePos, vTraceEnd, {}, {}, MASK_SOLID, &filter, &trace);
bool bReturn = trace.m_pEnt && trace.m_pEnt == target.m_pEntity;
if (!bReturn)
{
SDK::TraceHull(vEyePos, vTraceEnd, vSwingMins, vSwingMaxs, MASK_SHOT | CONTENTS_GRATE, &filter, &trace);
SDK::TraceHull(vEyePos, vTraceEnd, vSwingMins, vSwingMaxs, MASK_SOLID, &filter, &trace);
bReturn = trace.m_pEnt && trace.m_pEnt == target.m_pEntity;
}
@@ -374,14 +360,15 @@ int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWe
bReturn = false;
}
target.m_pEntity->SetAbsOrigin(vRestore);
target.m_pEntity->SetAbsOrigin(vRestoreOrigin);
target.m_pEntity->m_vecMins() = vRestoreMins;
target.m_pEntity->m_vecMaxs() = vRestoreMaxs;
if (bReturn)
{
target.m_Tick = pTick;
target.m_tRecord = tRecord;
target.m_bBacktrack = target.m_TargetType == ETargetType::Player /*&& Vars::Backtrack::Enabled.Value*/;
originTolerance(-0.125f);
return true;
}
else if (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth)
@@ -393,14 +380,10 @@ int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWe
SDK::Trace(vEyePos, vTraceEnd, MASK_SHOT | CONTENTS_GRATE, &filter, &trace);
if (trace.m_pEnt && trace.m_pEnt == target.m_pEntity)
{
originTolerance(-0.125f);
return 2;
}
}
}
originTolerance(-0.125f);
return false;
}
@@ -508,7 +491,7 @@ void CAimbotMelee::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd
if (G::Attacking == 1)
{
if (target.m_bBacktrack)
pCmd->tick_count = TIME_TO_TICKS(target.m_Tick.m_flSimTime) + TIME_TO_TICKS(F::Backtrack.m_flFakeInterp);
pCmd->tick_count = TIME_TO_TICKS(target.m_tRecord.m_flSimTime) + TIME_TO_TICKS(F::Backtrack.m_flFakeInterp);
// bug: fast old records seem to be progressively more unreliable ?
}
@@ -525,7 +508,7 @@ void CAimbotMelee::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd
G::LineStorage.push_back({ { vEyePos, target.m_vPos }, I::GlobalVars->curtime + 5.f, Vars::Colors::Bullet.Value, true });
if (bBoxes)
{
auto vBoxes = F::Visuals.GetHitboxes(target.m_Tick.m_BoneMatrix.m_aBones, target.m_pEntity->As<CBaseAnimating>());
auto vBoxes = F::Visuals.GetHitboxes(target.m_tRecord.m_BoneMatrix.m_aBones, target.m_pEntity->As<CBaseAnimating>());
G::BoxStorage.insert(G::BoxStorage.end(), vBoxes.begin(), vBoxes.end());
}
if (bPath)
@@ -14,7 +14,7 @@ class CAimbotMelee
std::unordered_map<CBaseEntity*, std::deque<TickRecord>>& pRecordMap,
std::unordered_map<CBaseEntity*, std::deque<Vec3>>& mPaths);
bool CanBackstab(CBaseEntity* pTarget, CTFPlayer* pLocal, Vec3 vEyeAngles);
int CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Vec3 vEyePos, std::deque<TickRecord> newRecords);
int CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Vec3 vEyePos, std::deque<TickRecord>& vSimRecords);
Vec3 Aim(Vec3 vCurAngle, Vec3 vToAngle, int iMethod = Vars::Aimbot::General::AimType.Value);
void Aim(CUserCmd* pCmd, Vec3& vAngle);
+33 -31
View File
@@ -92,20 +92,6 @@ void CBacktrack::UpdateDatagram()
bool CBacktrack::WithinRewind(const TickRecord& record)
{
auto pNetChan = I::EngineClient->GetNetChannelInfo();
if (!pNetChan)
return false;
const float flCorrect = std::clamp(pNetChan->GetLatency(FLOW_OUTGOING) + ROUND_TO_TICKS(m_flFakeInterp) + ROUND_TO_TICKS(m_flFakeLatency), 0.f, m_flMaxUnlag) - pNetChan->GetLatency(FLOW_OUTGOING);
const int iServerTick = m_iTickCount + G::AnticipatedChoke + Vars::Backtrack::Offset.Value;
const float flDelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(record.m_flSimTime));
return fabsf(flDelta) < float(Vars::Backtrack::Window.Value) / 1000;
}
std::deque<TickRecord>* CBacktrack::GetRecords(CBaseEntity* pEntity)
{
if (m_mRecords[pEntity].empty())
@@ -116,22 +102,43 @@ std::deque<TickRecord>* CBacktrack::GetRecords(CBaseEntity* pEntity)
std::deque<TickRecord> CBacktrack::GetValidRecords(std::deque<TickRecord>* pRecords, CTFPlayer* pLocal, bool bDistance)
{
std::deque<TickRecord> validRecords = {};
if (!pRecords)
return validRecords;
std::deque<TickRecord> vRecords = {};
if (!pRecords || pRecords->empty())
return vRecords;
for (auto& pTick : *pRecords)
auto pNetChan = I::EngineClient->GetNetChannelInfo();
if (!pNetChan)
return vRecords;
float flCorrect = std::clamp(pNetChan->GetLatency(FLOW_OUTGOING) + ROUND_TO_TICKS(m_flFakeInterp) + ROUND_TO_TICKS(m_flFakeLatency), 0.f, m_flMaxUnlag) - pNetChan->GetLatency(FLOW_OUTGOING);
int iServerTick = m_iTickCount + G::AnticipatedChoke + Vars::Backtrack::Offset.Value;
for (auto& tRecord : *pRecords)
{
if (!WithinRewind(pTick))
float flDelta = fabsf(flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(tRecord.m_flSimTime)));
if (flDelta > float(Vars::Backtrack::Window.Value) / 1000)
continue;
validRecords.push_back(pTick);
vRecords.push_back(tRecord);
}
if (pLocal)
if (vRecords.empty())
{ // make sure there is at least 1 record
float flMinDelta = 0.2f;
for (auto& tRecord : *pRecords)
{
float flDelta = fabsf(flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(tRecord.m_flSimTime)));
if (flDelta > flMinDelta)
continue;
flMinDelta = flDelta;
vRecords = { tRecord };
}
}
else if (pLocal && vRecords.size() > 1)
{
if (bDistance)
std::sort(validRecords.begin(), validRecords.end(), [&](const TickRecord& a, const TickRecord& b) -> bool
std::sort(vRecords.begin(), vRecords.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;
@@ -140,14 +147,7 @@ std::deque<TickRecord> CBacktrack::GetValidRecords(std::deque<TickRecord>* pReco
});
else
{
auto pNetChan = I::EngineClient->GetNetChannelInfo();
if (!pNetChan)
return validRecords;
const float flCorrect = std::clamp(pNetChan->GetLatency(FLOW_OUTGOING) + ROUND_TO_TICKS(m_flFakeInterp) + ROUND_TO_TICKS(m_flFakeLatency), 0.f, m_flMaxUnlag) - pNetChan->GetLatency(FLOW_OUTGOING);
const int iServerTick = m_iTickCount + G::AnticipatedChoke + Vars::Backtrack::Offset.Value;
std::sort(validRecords.begin(), validRecords.end(), [&](const TickRecord& a, const TickRecord& b) -> bool
std::sort(vRecords.begin(), vRecords.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;
@@ -159,7 +159,7 @@ std::deque<TickRecord> CBacktrack::GetValidRecords(std::deque<TickRecord>* pReco
}
}
return validRecords;
return vRecords;
}
@@ -177,6 +177,8 @@ void CBacktrack::MakeRecords()
pPlayer->m_flSimulationTime(),
*reinterpret_cast<BoneMatrix*>(H::Entities.GetBones(pPlayer->entindex())),
pPlayer->m_vecOrigin(),
pPlayer->m_vecMins(),
pPlayer->m_vecMaxs(),
m_mDidShoot[pPlayer->entindex()]
};
+2 -2
View File
@@ -28,14 +28,14 @@ struct TickRecord
float m_flSimTime = 0.f;
BoneMatrix m_BoneMatrix = {};
Vec3 m_vOrigin = {};
Vec3 m_vMins = {};
Vec3 m_vMaxs = {};
bool m_bOnShot = false;
bool m_bInvalid = false;
};
class CBacktrack
{
bool WithinRewind(const TickRecord& record);
void SendLerp();
void UpdateDatagram();
void MakeRecords();
@@ -36,10 +36,7 @@ MAKE_HOOK(CBasePlayer_ItemPostFrame, S::CBasePlayer_ItemPostFrame(), void,
return CALL_ORIGINAL(rcx);
}
//SDK::Output("CBasePlayer_ItemPostFrame", std::format("{}; {}, {}, {}; {:#x}", TIME_TO_TICKS(pLocal->m_flNextAttack() - I::GlobalVars->curtime) == 31, I::GlobalVars->curtime - pWeapon->m_flTimeWeaponIdle(), I::GlobalVars->curtime - pLocal->m_flNextAttack(), I::GlobalVars->curtime - pWeapon->m_flNextPrimaryAttack(), uintptr_t(_ReturnAddress())).c_str());
CALL_ORIGINAL(rcx);
pWeapon->IncrementAmmo();
pWeapon->m_bReloadedThroughAnimEvent() = true;
//SDK::Output("CBasePlayer_ItemPostFrame", "");
}
+3 -3
View File
@@ -58,7 +58,7 @@ struct Ray_t
void Init(Vector const& start, Vector const& end)
{
m_Delta = end - start;
m_IsSwept = (m_Delta.LengthSqr() != 0);
m_IsSwept = m_Delta.LengthSqr() != 0;
m_Extents.Set();
m_IsRay = true;
m_StartOffset.Set();
@@ -68,10 +68,10 @@ struct Ray_t
void Init(Vector const& start, Vector const& end, Vector const& mins, Vector const& maxs)
{
m_Delta = end - start;
m_IsSwept = (m_Delta.LengthSqr() != 0);
m_IsSwept = m_Delta.LengthSqr() != 0;
m_Extents = maxs - mins;
m_Extents *= 0.5f;
m_IsRay = (m_Extents.LengthSqr() < 1e-6);
m_IsRay = m_Extents.LengthSqr() == 0;
m_StartOffset = mins + maxs;
m_StartOffset *= 0.5f;
m_Start = start + m_StartOffset;