From 1cde95b455832fdec426fef3cb09df4643c9055a Mon Sep 17 00:00:00 2001 From: rei-2 <174158077+rei-2@users.noreply.github.com> Date: Fri, 13 Feb 2026 20:04:58 -0500 Subject: [PATCH] rework how points are handled in projectile aim --- .../Aimbot/AimbotHitscan/AimbotHitscan.cpp | 12 +- .../Aimbot/AimbotMelee/AimbotMelee.cpp | 38 +- .../AimbotProjectile/AimbotProjectile.cpp | 809 +++++++++--------- .../AimbotProjectile/AimbotProjectile.h | 81 +- .../Aimbot/AutoAirblast/AutoAirblast.cpp | 2 +- .../Aimbot/AutoAirblast/AutoAirblast.h | 2 +- .../Aimbot/AutoRocketJump/AutoRocketJump.cpp | 31 +- Amalgam/src/Features/ImGui/Menu/Menu.cpp | 23 +- .../MovementSimulation/MovementSimulation.cpp | 238 +++--- .../MovementSimulation/MovementSimulation.h | 20 +- .../ProjectileSimulation.cpp | 60 +- .../ProjectileSimulation.h | 4 +- Amalgam/src/SDK/Definitions/Types.h | 10 + Amalgam/src/SDK/Vars.h | 6 +- 14 files changed, 703 insertions(+), 633 deletions(-) diff --git a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp index 6efdc0dc..d6eb6155 100644 --- a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp @@ -300,17 +300,17 @@ int CAimbotHitscan::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* tTarget.m_vPos = tTarget.m_pEntity->m_vecOrigin(); // not lag compensated (i assume) so run movesim based on ping - MoveStorage tStorage; - F::MoveSim.Initialize(tTarget.m_pEntity, tStorage); - if (!tStorage.m_bFailed) + MoveStorage tMoveStorage; + 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(tStorage); - tTarget.m_vPos = tStorage.m_vPredictedOrigin; + F::MoveSim.RunTick(tMoveStorage); + tTarget.m_vPos = tMoveStorage.m_vPredictedOrigin; } } - F::MoveSim.Restore(tStorage); + 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; diff --git a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp index e215a5ce..a50beb67 100644 --- a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp @@ -139,18 +139,18 @@ void CAimbotMelee::UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCm if ((Vars::Aimbot::Melee::SwingPrediction.Value && iSimTicks || m_iDoubletapTicks) && G::CanPrimaryAttack && pWeapon->m_flSmackTime() < 0.f) { - std::unordered_map mStorage; + std::unordered_map mMoveStorage; - F::MoveSim.Initialize(pLocal, mStorage[I::EngineClient->GetLocalPlayer()], false, !m_iDoubletapTicks); + F::MoveSim.Initialize(pLocal, mMoveStorage[I::EngineClient->GetLocalPlayer()], false, !m_iDoubletapTicks); for (auto& tTarget : vTargets) - F::MoveSim.Initialize(tTarget.m_pEntity, mStorage[tTarget.m_pEntity->entindex()], false); + F::MoveSim.Initialize(tTarget.m_pEntity, mMoveStorage[tTarget.m_pEntity->entindex()], false); int iMax = std::max(iSimTicks, m_iDoubletapTicks); int iTicks = iMax; bool bSwung = false; for (int i = 0; i < iTicks; i++) // intended for plocal to collide with targets { { - auto& tStorage = mStorage[I::EngineClient->GetLocalPlayer()]; + auto& tMoveStorage = mMoveStorage[I::EngineClient->GetLocalPlayer()]; if (!bSwung && (!m_iDoubletapTicks || Vars::Doubletap::AntiWarp.Value && pLocal->m_hGroundEntity() || iMax - i <= iSwingTicks)) { @@ -160,18 +160,18 @@ void CAimbotMelee::UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCm if (pLocal->InCond(TF_COND_SHIELD_CHARGE)) { // demo charge fix for swing pred - tStorage.m_MoveData.m_flMaxSpeed = tStorage.m_MoveData.m_flClientMaxSpeed = SDK::MaxSpeed(pLocal, false, true); - pLocal->m_flMaxspeed() = tStorage.m_MoveData.m_flMaxSpeed; + tMoveStorage.m_MoveData.m_flMaxSpeed = tMoveStorage.m_MoveData.m_flClientMaxSpeed = SDK::MaxSpeed(pLocal, false, true); + pLocal->m_flMaxspeed() = tMoveStorage.m_MoveData.m_flMaxSpeed; pLocal->RemoveCond(TF_COND_SHIELD_CHARGE); } } if (m_iDoubletapTicks && Vars::Doubletap::AntiWarp.Value && pLocal->m_hGroundEntity()) - F::Ticks.AntiWarp(pLocal, pCmd->viewangles.y, tStorage.m_MoveData.m_flForwardMove, tStorage.m_MoveData.m_flSideMove, iMax - i - 1); + F::Ticks.AntiWarp(pLocal, pCmd->viewangles.y, tMoveStorage.m_MoveData.m_flForwardMove, tMoveStorage.m_MoveData.m_flSideMove, iMax - i - 1); - F::MoveSim.RunTick(tStorage); + F::MoveSim.RunTick(tMoveStorage); m_mRecordMap[I::EngineClient->GetLocalPlayer()].emplace_front( pLocal->m_flSimulationTime() + TICKS_TO_TIME(i + 1), - tStorage.m_MoveData.m_vecAbsOrigin, + tMoveStorage.m_MoveData.m_vecAbsOrigin, pLocal->m_vecMins(), pLocal->m_vecMaxs() ); } @@ -180,26 +180,26 @@ void CAimbotMelee::UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCm { for (auto& tTarget : vTargets) { - auto& tStorage = mStorage[tTarget.m_pEntity->entindex()]; - if (tStorage.m_bFailed) + auto& tMoveStorage = mMoveStorage[tTarget.m_pEntity->entindex()]; + if (tMoveStorage.m_bFailed) continue; - F::MoveSim.RunTick(tStorage); + F::MoveSim.RunTick(tMoveStorage); m_mRecordMap[tTarget.m_pEntity->entindex()].emplace_front( - !Vars::Aimbot::Melee::SwingPredictLag.Value || tStorage.m_bPredictNetworked ? tTarget.m_pEntity->m_flSimulationTime() + TICKS_TO_TIME(i + 1) : 0.f, - Vars::Aimbot::Melee::SwingPredictLag.Value ? tStorage.m_vPredictedOrigin : tStorage.m_MoveData.m_vecAbsOrigin, + !Vars::Aimbot::Melee::SwingPredictLag.Value || tMoveStorage.m_bPredictNetworked ? tTarget.m_pEntity->m_flSimulationTime() + TICKS_TO_TIME(i + 1) : 0.f, + Vars::Aimbot::Melee::SwingPredictLag.Value ? tMoveStorage.m_vPredictedOrigin : tMoveStorage.m_MoveData.m_vecAbsOrigin, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs() ); } } } - m_vEyePos = mStorage[I::EngineClient->GetLocalPlayer()].m_MoveData.m_vecAbsOrigin + pLocal->m_vecViewOffset(); + m_vEyePos = mMoveStorage[I::EngineClient->GetLocalPlayer()].m_MoveData.m_vecAbsOrigin + pLocal->m_vecViewOffset(); m_flRange = pWeapon->GetSwingRange(); if (Vars::Visuals::Simulation::SwingLines.Value && Vars::Visuals::Simulation::PlayerPath.Value) { - for (auto& [iIndex, tStorage] : mStorage) - m_mPaths[iIndex] = tStorage.m_vPath; + for (auto& [iIndex, tMoveStorage] : mMoveStorage) + m_mPaths[iIndex] = tMoveStorage.m_vPath; const bool bAlwaysDraw = !Vars::Aimbot::General::AutoShoot.Value || Vars::Debug::Info.Value; if (bAlwaysDraw) @@ -218,8 +218,8 @@ void CAimbotMelee::UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCm } } - for (auto& [_, tStorage] : mStorage) - F::MoveSim.Restore(tStorage); + for (auto& [_, tMoveStorage] : mMoveStorage) + F::MoveSim.Restore(tMoveStorage); } m_bShouldSwing = m_iDoubletapTicks <= iSwingTicks || Vars::Doubletap::AntiWarp.Value && pLocal->m_hGroundEntity(); diff --git a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp index 464bb497..aa66e3a0 100644 --- a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp @@ -1,8 +1,6 @@ #include "AimbotProjectile.h" #include "../Aimbot.h" -#include "../../Simulation/MovementSimulation/MovementSimulation.h" -#include "../../Simulation/ProjectileSimulation/ProjectileSimulation.h" #include "../../EnginePrediction/EnginePrediction.h" #include "../../Ticks/Ticks.h" #include "../AutoAirblast/AutoAirblast.h" @@ -264,9 +262,9 @@ static inline int GetSplashMode(CTFWeaponBase* pWeapon) return Vars::Aimbot::Projectile::RocketSplashModeEnum::Regular; } -static inline float PrimeTime(CTFWeaponBase* pWeapon) +static inline float ArmTime(CTFWeaponBase* pWeapon) { - if (Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::UsePrimeTime && pWeapon->GetWeaponID() == TF_WEAPON_PIPEBOMBLAUNCHER) + if (Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::UseArmTime && pWeapon->GetWeaponID() == TF_WEAPON_PIPEBOMBLAUNCHER) { static auto tf_grenadelauncher_livetime = H::ConVars.FindVar("tf_grenadelauncher_livetime"); const float flLiveTime = tf_grenadelauncher_livetime->GetFloat(); @@ -331,14 +329,16 @@ static inline int GetHitboxPriority(int nHitbox, Target_t& tTarget, Info_t& tInf return -1; }; -std::unordered_map CAimbotProjectile::GetDirectPoints(Target_t& tTarget, CBaseEntity* pProjectile) +std::unordered_map CAimbotProjectile::GetDirectPoints() { std::unordered_map mPoints = {}; + auto& tTarget = *m_tInfo.m_pTarget; + const Vec3 vMins = tTarget.m_pEntity->m_vecMins(), vMaxs = tTarget.m_pEntity->m_vecMaxs(); for (int i = 0; i < 3; i++) { - int iPriority = GetHitboxPriority(i, tTarget, m_tInfo, pProjectile); + int iPriority = GetHitboxPriority(i, tTarget, m_tInfo, m_tInfo.m_pProjectile); if (iPriority == -1) continue; @@ -397,9 +397,9 @@ static inline std::vector> ComputeSphere(float flRadius, in float flRotateX = Vars::Aimbot::Projectile::SplashRotateX.Value < 0.f ? SDK::StdRandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateX.Value; float flRotateY = Vars::Aimbot::Projectile::SplashRotateY.Value < 0.f ? SDK::StdRandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateY.Value; - int iPointType = Vars::Aimbot::Projectile::SplashGrates.Value ? PointTypeEnum::Regular | PointTypeEnum::Obscured : PointTypeEnum::Regular; + int iPointType = Vars::Aimbot::Projectile::SplashGrates.Value ? PointTypeEnum::Out | PointTypeEnum::In : PointTypeEnum::Out; if (Vars::Aimbot::Projectile::RocketSplashMode.Value == Vars::Aimbot::Projectile::RocketSplashModeEnum::SpecialHeavy) - iPointType |= PointTypeEnum::ObscuredExtra | PointTypeEnum::ObscuredMulti; + iPointType |= PointTypeEnum::Out2 | PointTypeEnum::In2; float a = PI * (3.f - sqrtf(5.f)); for (int n = 0; n < iSamples; n++) @@ -441,7 +441,7 @@ static inline void TracePoint(Vec3& vPoint, int& iType, Vec3& vTargetEye, Info_t }; #endif - if (iType & PointTypeEnum::Regular) + if (iType & PointTypeEnum::Out) { SDK::TraceHull(vTargetEye, vPoint, tInfo.m_vHull * -1, tInfo.m_vHull, MASK_SOLID, &filter, &trace); #ifdef SPLASH_DEBUG5 @@ -461,21 +461,22 @@ static inline void TracePoint(Vec3& vPoint, int& iType, Vec3& vTargetEye, Info_t if (bErase) iType = 0; else if (bNormal) - iType &= ~PointTypeEnum::Regular; + iType &= ~PointTypeEnum::Out; else - iType &= ~PointTypeEnum::Obscured; + iType &= ~PointTypeEnum::In; } - if (iType & PointTypeEnum::ObscuredExtra) + if (iType & PointTypeEnum::Out2) { bErase = false, bNormal = false; size_t iOriginalSize = vPoints.size(); { // necessary performance wise? - if (bNormal = (tInfo.m_vLocalEye - vTargetEye).Dot(vTargetEye - vPoint) > 0.f) + //if (bNormal = (tInfo.m_vLocalEye - vTargetEye).Dot(vTargetEye - vPoint) > 0.f) + if (bNormal = (tInfo.m_vLocalEye - vTargetEye).DotNormalized(vTargetEye - vPoint) > Vars::Aimbot::Projectile::Out2NormalCheck.Value) goto breakOutExtra; - if (!(iOriginalType & PointTypeEnum::Regular)) // don't do the same trace over again + if (!(iOriginalType & PointTypeEnum::Out)) // don't do the same trace over again { SDK::Trace(vTargetEye, vPoint, MASK_SOLID, &filter, &trace); #ifdef SPLASH_DEBUG5 @@ -520,9 +521,9 @@ static inline void TracePoint(Vec3& vPoint, int& iType, Vec3& vTargetEye, Info_t if (vPoints.size() != iOriginalSize) iType = 0; else if (bErase || bNormal) - iType &= ~PointTypeEnum::ObscuredExtra; + iType &= ~PointTypeEnum::Out2; } - if (iType & PointTypeEnum::Obscured) + if (iType & PointTypeEnum::In) { bErase = false, bNormal = false; size_t iOriginalSize = vPoints.size(); @@ -565,7 +566,7 @@ static inline void TracePoint(Vec3& vPoint, int& iType, Vec3& vTargetEye, Info_t #endif if (!bNormal && trace.surface.flags & SURF_NODRAW) { - if (bNormal = !(iType & PointTypeEnum::ObscuredMulti)) + if (bNormal = !(iType & PointTypeEnum::In2)) goto breakOut; CGameTrace trace2 = {}; @@ -601,18 +602,18 @@ static inline void TracePoint(Vec3& vPoint, int& iType, Vec3& vTargetEye, Info_t if (vPoints.size() != iOriginalSize) iType = 0; else if (bErase || bNormal) - iType &= ~PointTypeEnum::Obscured; + iType &= ~PointTypeEnum::In; else - iType &= ~PointTypeEnum::Regular; + iType &= ~PointTypeEnum::Out; } } // possibly add air splash for autodet weapons -std::vector CAimbotProjectile::GetSplashPoints(Target_t& tTarget, std::vector>& vSpherePoints, int iSimTime) +std::vector CAimbotProjectile::GetSplashPoints(Vec3 vOrigin, std::vector>& vSpherePoints, int iSimTime) { std::vector> vPointDistances = {}; - Vec3 vTargetEye = tTarget.m_vPos + m_tInfo.m_vTargetEye; + Vec3 vTargetEye = vOrigin + m_tInfo.m_vTargetEye; auto checkPoint = [&](CGameTrace& trace, bool& bErase, bool& bNormal) { @@ -628,7 +629,7 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& tTarget, std:: } if (!bNormal) { - CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, iSimTime, tPoint.m_tSolution); + CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, iSimTime, tPoint.m_tSolution, true, !m_tInfo.m_iArmTime ? 0 : -1); if (m_tInfo.m_flGravity) { Vec3 vPos = m_tInfo.m_vLocalEye + Vec3(0, 0, (m_tInfo.m_flGravity * 800.f * pow(tPoint.m_tSolution.m_flTime, 2)) / 2); @@ -640,10 +641,10 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& tTarget, std:: return false; bErase = tPoint.m_tSolution.m_iCalculated == CalculatedEnum::Good; - if (!bErase /*|| !m_tInfo.m_flPrimeTime && int(tPoint.m_tSolution.m_flTime / TICK_INTERVAL) + 1 != iSimTime*/) + if (!bErase) return false; - vPointDistances.emplace_back(tPoint, tPoint.m_vPoint.DistTo(tTarget.m_vPos)); + vPointDistances.emplace_back(tPoint, tPoint.m_vPoint.DistTo(vOrigin)); return true; }; @@ -653,14 +654,14 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& tTarget, std:: Vec3 vPoint = it->first + vTargetEye; int& iType = it->second; - Solution_t solution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, iSimTime, solution, false); + Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, iSimTime, tSolution, false); - if (solution.m_iCalculated == CalculatedEnum::Bad) + if (tSolution.m_iCalculated == CalculatedEnum::Bad) iType = 0; - else if (abs(solution.m_flTime - TICKS_TO_TIME(iSimTime)) < m_tInfo.m_flRadiusTime || m_tInfo.m_flPrimeTime && iSimTime == m_tInfo.m_iPrimeTime) + else if (abs(tSolution.m_flTime - TICKS_TO_TIME(iSimTime)) < m_tInfo.m_flRadiusTime || m_tInfo.m_iArmTime && iSimTime == m_tInfo.m_iArmTime) TracePoint(vPoint, iType, vTargetEye, m_tInfo, vPointDistances, checkPoint, i++); - if (!(iType & ~PointTypeEnum::ObscuredMulti)) + if (!(iType & ~PointTypeEnum::In2)) it = vSpherePoints.erase(it); else ++it; @@ -673,22 +674,22 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& tTarget, std:: std::vector vPoints = {}; int iSplashCount = std::min( - m_tInfo.m_flPrimeTime && iSimTime == m_tInfo.m_iPrimeTime ? Vars::Aimbot::Projectile::SplashCountDirect.Value : m_tInfo.m_iSplashCount, + m_tInfo.m_iArmTime && iSimTime == m_tInfo.m_iArmTime ? Vars::Aimbot::Projectile::SplashCountDirect.Value : m_tInfo.m_iSplashCount, int(vPointDistances.size()) ); for (int i = 0; i < iSplashCount; i++) vPoints.push_back(vPointDistances[i].first); - const Vec3 vOriginal = tTarget.m_pEntity->GetAbsOrigin(); - tTarget.m_pEntity->SetAbsOrigin(tTarget.m_vPos); + const Vec3 vOriginal = m_tInfo.m_pTarget->m_pEntity->GetAbsOrigin(); + m_tInfo.m_pTarget->m_pEntity->SetAbsOrigin(vOrigin); for (auto it = vPoints.begin(); it != vPoints.end();) { - auto& vPoint = *it; - bool bValid = vPoint.m_tSolution.m_iCalculated != CalculatedEnum::Pending; + auto& tPoint = *it; + bool bValid = tPoint.m_tSolution.m_iCalculated != CalculatedEnum::Pending; if (bValid) { - Vec3 vPos; tTarget.m_pEntity->m_Collision()->CalcNearestPoint(vPoint.m_vPoint, &vPos); - bValid = vPoint.m_vPoint.DistTo(vPos) < m_tInfo.m_flRadius; + Vec3 vPos; m_tInfo.m_pTarget->m_pEntity->m_Collision()->CalcNearestPoint(tPoint.m_vPoint, &vPos); + bValid = tPoint.m_vPoint.DistTo(vPos) < m_tInfo.m_flRadius; } if (bValid) @@ -696,15 +697,15 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& tTarget, std:: else it = vPoints.erase(it); } - tTarget.m_pEntity->SetAbsOrigin(vOriginal); + m_tInfo.m_pTarget->m_pEntity->SetAbsOrigin(vOriginal); return vPoints; } -void CAimbotProjectile::SetupSplashPoints(Target_t& tTarget, std::vector>& vSpherePoints, std::vector& vSimplePoints) +void CAimbotProjectile::SetupSplashPoints(Vec3& vPos, std::vector>& vSpherePoints, std::vector& vSimplePoints) { vSimplePoints.clear(); - Vec3 vTargetEye = tTarget.m_vPos + m_tInfo.m_vTargetEye; + Vec3 vTargetEye = vPos + m_tInfo.m_vTargetEye; auto checkPoint = [&](CGameTrace& trace, bool& bErase, bool& bNormal) { @@ -745,29 +746,29 @@ void CAimbotProjectile::SetupSplashPoints(Target_t& tTarget, std::vector CAimbotProjectile::GetSplashPointsSimple(Target_t& tTarget, std::vector& vSpherePoints, int iSimTime) +std::vector CAimbotProjectile::GetSplashPointsSimple(Vec3 vOrigin, std::vector& vSpherePoints, int iSimTime) { std::vector> vPointDistances = {}; - Vec3 vTargetEye = tTarget.m_vPos + m_tInfo.m_vTargetEye; + Vec3 vTargetEye = vOrigin + m_tInfo.m_vTargetEye; auto checkPoint = [&](Vec3& vPoint, bool& bErase) { Point_t tPoint = { vPoint, {} }; - CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, iSimTime, tPoint.m_tSolution); + CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, iSimTime, tPoint.m_tSolution, true, !m_tInfo.m_iArmTime ? 0 : -1); bErase = tPoint.m_tSolution.m_iCalculated == CalculatedEnum::Good; - if (!bErase /*|| !m_tInfo.m_flPrimeTime && int(tPoint.m_tSolution.m_flTime / TICK_INTERVAL) + 1 != iSimTime*/) + if (!bErase) return false; - vPointDistances.emplace_back(tPoint, tPoint.m_vPoint.DistTo(tTarget.m_vPos)); + vPointDistances.emplace_back(tPoint, tPoint.m_vPoint.DistTo(vOrigin)); return true; }; for (auto it = vSpherePoints.begin(); it != vSpherePoints.end();) @@ -789,22 +790,22 @@ std::vector CAimbotProjectile::GetSplashPointsSimple(Target_t& tTarget, std::vector vPoints = {}; int iSplashCount = std::min( - m_tInfo.m_flPrimeTime && iSimTime == m_tInfo.m_iPrimeTime ? Vars::Aimbot::Projectile::SplashCountDirect.Value : m_tInfo.m_iSplashCount, + m_tInfo.m_iArmTime && iSimTime == m_tInfo.m_iArmTime ? Vars::Aimbot::Projectile::SplashCountDirect.Value : m_tInfo.m_iSplashCount, int(vPointDistances.size()) ); for (int i = 0; i < iSplashCount; i++) vPoints.push_back(vPointDistances[i].first); - const Vec3 vOriginal = tTarget.m_pEntity->GetAbsOrigin(); - tTarget.m_pEntity->SetAbsOrigin(tTarget.m_vPos); + const Vec3 vOriginal = m_tInfo.m_pTarget->m_pEntity->GetAbsOrigin(); + m_tInfo.m_pTarget->m_pEntity->SetAbsOrigin(vOrigin); for (auto it = vPoints.begin(); it != vPoints.end();) { - auto& vPoint = *it; - bool bValid = vPoint.m_tSolution.m_iCalculated != CalculatedEnum::Pending; + auto& tPoint = *it; + bool bValid = tPoint.m_tSolution.m_iCalculated != CalculatedEnum::Pending; if (bValid) { - Vec3 vPos = {}; tTarget.m_pEntity->m_Collision()->CalcNearestPoint(vPoint.m_vPoint, &vPos); - bValid = vPoint.m_vPoint.DistTo(vPos) < m_tInfo.m_flRadius; + Vec3 vPos = {}; m_tInfo.m_pTarget->m_pEntity->m_Collision()->CalcNearestPoint(tPoint.m_vPoint, &vPos); + bValid = tPoint.m_vPoint.DistTo(vPos) < m_tInfo.m_flRadius; } if (bValid) @@ -812,7 +813,7 @@ std::vector CAimbotProjectile::GetSplashPointsSimple(Target_t& tTarget, else it = vPoints.erase(it); } - tTarget.m_pEntity->SetAbsOrigin(vOriginal); + m_tInfo.m_pTarget->m_pEntity->SetAbsOrigin(vOriginal); return vPoints; } @@ -922,7 +923,7 @@ static inline void SolveProjectileSpeed(CTFWeaponBase* pWeapon, const Vec3& vLoc flDragTime = powf(flTime, 2) * flDrag / (flOverride ? flOverride : 1.5f); // rough estimate to prevent m_flTime being too low flVelocity = flVelocity - flVelocity * flTime * flDrag; } -void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, bool bAccuracy) +void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, bool bAccuracy, int iTolerance) { if (tOut.m_iCalculated != CalculatedEnum::Pending) return; @@ -957,15 +958,16 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge tOut.m_flYaw = flYaw = vAngleTo.y - m_tInfo.m_vAngFix.y; } - int iTimeTo = int(tOut.m_flTime / TICK_INTERVAL) + 1; + int iTimeTo = ceilf(tOut.m_flTime / TICK_INTERVAL); + bool bGood = iTolerance != -1 ? abs(iTimeTo - iSimTime) <= iTolerance : iTimeTo <= iSimTime; if (!m_tInfo.m_vOffset.IsZero()) { - if (tOut.m_iCalculated = iTimeTo > iSimTime ? CalculatedEnum::Time : CalculatedEnum::Pending) + if (tOut.m_iCalculated = bGood ? CalculatedEnum::Pending : CalculatedEnum::Time) return; } else { - tOut.m_iCalculated = iTimeTo > iSimTime ? CalculatedEnum::Time : CalculatedEnum::Good; + tOut.m_iCalculated = bGood ? CalculatedEnum::Pending : CalculatedEnum::Time; return; } @@ -999,18 +1001,18 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge } } #endif - ProjectileInfo tProjInfo = {}; - if (tOut.m_iCalculated = !F::ProjSim.GetInfo(m_tInfo.m_pLocal, m_tInfo.m_pWeapon, { flPitch, flYaw, 0 }, tProjInfo, iFlags) ? CalculatedEnum::Bad : CalculatedEnum::Pending) + m_tProjInfo = {}; + if (tOut.m_iCalculated = !F::ProjSim.GetInfo(m_tInfo.m_pLocal, m_tInfo.m_pWeapon, { flPitch, flYaw, 0 }, m_tProjInfo, iFlags) ? CalculatedEnum::Bad : CalculatedEnum::Pending) return; { // calculate trajectory from projectile origin float flVelocity = m_tInfo.m_flVelocity, flDragTime = 0.f; - SolveProjectileSpeed(m_tInfo.m_pWeapon, tProjInfo.m_vPos, vTargetPos, flVelocity, flDragTime, m_tInfo.m_flGravity); + SolveProjectileSpeed(m_tInfo.m_pWeapon, m_tProjInfo.m_vPos, vTargetPos, flVelocity, flDragTime, m_tInfo.m_flGravity); - Vec3 vDelta = vTargetPos - tProjInfo.m_vPos; + Vec3 vDelta = vTargetPos - m_tProjInfo.m_vPos; float flDist = vDelta.Length2D(); - Vec3 vAngleTo = Math::CalcAngle(tProjInfo.m_vPos, vTargetPos); + Vec3 vAngleTo = Math::CalcAngle(m_tProjInfo.m_vPos, vTargetPos); if (!flGrav) tOut.m_flPitch = -DEG2RAD(vAngleTo.x); else @@ -1024,9 +1026,9 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge } { // correct yaw - Vec3 vShootPos = (tProjInfo.m_vPos - vLocalPos).To2D(); + Vec3 vShootPos = (m_tProjInfo.m_vPos - vLocalPos).To2D(); Vec3 vTarget = vTargetPos - vLocalPos; - Vec3 vForward; Math::AngleVectors(tProjInfo.m_vAng, &vForward); vForward.Normalize2D(); + Vec3 vForward; Math::AngleVectors(m_tProjInfo.m_vAng, &vForward); vForward.Normalize2D(); float flB = 2 * (vShootPos.x * vForward.x + vShootPos.y * vForward.y); float flC = vShootPos.Length2DSqr() - vTarget.Length2DSqr(); auto vSolutions = Math::SolveQuadratic(1.f, flB, flC); @@ -1041,14 +1043,14 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge { // correct pitch if (flGrav) { - flPitch -= tProjInfo.m_vAng.x; + flPitch -= m_tProjInfo.m_vAng.x; tOut.m_flPitch = -RAD2DEG(tOut.m_flPitch) + flPitch - m_tInfo.m_vAngFix.x; } else { - Vec3 vShootPos = Math::RotatePoint(tProjInfo.m_vPos - vLocalPos, {}, { 0, -flYaw, 0 }); vShootPos.y = 0; + Vec3 vShootPos = Math::RotatePoint(m_tProjInfo.m_vPos - vLocalPos, {}, { 0, -flYaw, 0 }); vShootPos.y = 0; Vec3 vTarget = Math::RotatePoint(vTargetPos - vLocalPos, {}, { 0, -flYaw, 0 }); - Vec3 vForward; Math::AngleVectors(tProjInfo.m_vAng - Vec3(0, flYaw, 0), &vForward); vForward.y = 0; vForward.Normalize(); + Vec3 vForward; Math::AngleVectors(m_tProjInfo.m_vAng - Vec3(0, flYaw, 0), &vForward); vForward.y = 0; vForward.Normalize(); float flB = 2 * (vShootPos.x * vForward.x + vShootPos.z * vForward.z); float flC = (powf(vShootPos.x, 2) + powf(vShootPos.z, 2)) - (powf(vTarget.x, 2) + powf(vTarget.z, 2)); auto vSolutions = Math::SolveQuadratic(1.f, flB, flC); @@ -1060,14 +1062,19 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge } } - iTimeTo = int(tOut.m_flTime / TICK_INTERVAL) + 1; - tOut.m_iCalculated = iTimeTo > iSimTime ? CalculatedEnum::Time : CalculatedEnum::Good; + iTimeTo = ceilf(tOut.m_flTime / TICK_INTERVAL); + bGood = iTolerance != -1 ? abs(iTimeTo - iSimTime) <= iTolerance : iTimeTo <= iSimTime; + tOut.m_iCalculated = bGood ? CalculatedEnum::Good : CalculatedEnum::Time; } -bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Target_t& tTarget, Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash, bool* pHitSolid, std::vector* pProjectilePath) +bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int iSimTime, bool bSplash, bool bSecondTest) { + auto pLocal = m_tInfo.m_pLocal; + auto pWeapon = m_tInfo.m_pWeapon; + auto& tTarget = *m_tInfo.m_pTarget; + int iFlags = ProjSimEnum::Trace | ProjSimEnum::InitCheck | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum; #ifdef SPLASH_DEBUG5 if (Vars::Visuals::Trajectory::Override.Value) @@ -1096,9 +1103,9 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar } s_mTraceCount["Trace init check test"]++; #endif - ProjectileInfo tProjInfo = {}; - if (!F::ProjSim.GetInfo(pLocal, pWeapon, vAngles, tProjInfo, iFlags) - || !F::ProjSim.Initialize(tProjInfo)) + m_tProjInfo = {}; + if (!F::ProjSim.GetInfo(pLocal, pWeapon, vAngles, m_tProjInfo, iFlags) + || !F::ProjSim.Initialize(m_tProjInfo)) return false; CGameTrace trace = {}; @@ -1123,24 +1130,24 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar F::ProjSim.SetupTrace(filter, nMask, pWeapon); #ifdef SPLASH_DEBUG4 - Vec3 vHull = tProjInfo.m_vHull.Max(1); + Vec3 vHull = m_tProjInfo.m_vHull.Max(1); G::BoxStorage.emplace_back(vPoint, vHull * -1, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 0), Color_t(0, 0, 0, 0)); #endif - if (!tProjInfo.m_flGravity) + if (!m_tProjInfo.m_flGravity) { - SDK::TraceHull(tProjInfo.m_vPos, vPoint, tProjInfo.m_vHull * -1, tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(m_tProjInfo.m_vPos, vPoint, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); #ifdef SPLASH_DEBUG5 s_mTraceCount["Nograv trace"]++; #endif #ifdef SPLASH_DEBUG4 - G::LineStorage.emplace_back(std::pair(tProjInfo.m_vPos, trace.endpos), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 0)); + G::LineStorage.emplace_back(std::pair(m_tProjInfo.m_vPos, trace.endpos), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 0)); #endif if (trace.fraction < 0.999f && trace.m_pEnt != tTarget.m_pEntity) return false; } - bool bDidHit = false, bPrimeTime = false; + bool bDidHit = false, bArmTime = false; const RestoreInfo_t tOriginal = { tTarget.m_pEntity->GetAbsOrigin(), tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs() }; tTarget.m_pEntity->SetAbsOrigin(tTarget.m_vPos); tTarget.m_pEntity->m_vecMins() = { std::clamp(tTarget.m_pEntity->m_vecMins().x, -24.f, 0.f), std::clamp(tTarget.m_pEntity->m_vecMins().y, -24.f, 0.f), tTarget.m_pEntity->m_vecMins().z }; @@ -1148,7 +1155,7 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar for (int n = 1; n <= iSimTime; n++) { Vec3 vOld = F::ProjSim.GetOrigin(); - F::ProjSim.RunTick(tProjInfo); + F::ProjSim.RunTick(m_tProjInfo); Vec3 vNew = F::ProjSim.GetOrigin(); if (bDidHit) @@ -1159,7 +1166,7 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar if (!bSplash) { - SDK::TraceHull(vOld, vNew, tProjInfo.m_vHull * -1, tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(vOld, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); #ifdef SPLASH_DEBUG5 s_mTraceCount["Direct trace"]++; #endif @@ -1170,12 +1177,12 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar else { static Vec3 vStaticPos = {}; - if (n == 1 || bPrimeTime) + if (n == 1 || bArmTime) vStaticPos = vOld; - if (n % Vars::Aimbot::Projectile::SplashTraceInterval.Value && n != iSimTime && !bPrimeTime) + if (n % Vars::Aimbot::Projectile::SplashTraceInterval.Value && n != iSimTime && !bArmTime) continue; - SDK::TraceHull(vStaticPos, vNew, tProjInfo.m_vHull * -1, tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(vStaticPos, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); #ifdef SPLASH_DEBUG5 s_mTraceCount["Splash trace"]++; #endif @@ -1186,17 +1193,14 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar } if (trace.DidHit()) { - if (pHitSolid) - *pHitSolid = true; - bool bTime = bSplash - ? trace.endpos.DistTo(vPoint) < tProjInfo.m_flVelocity * TICK_INTERVAL + tProjInfo.m_vHull.z + ? trace.endpos.DistTo(vPoint) < m_tProjInfo.m_flVelocity * TICK_INTERVAL + m_tProjInfo.m_vHull.z : iSimTime - n < 5 || pWeapon->GetWeaponID() == TF_WEAPON_LUNCHBOX; // projectile so slow it causes problems if we don't waive this check bool bTarget = trace.m_pEnt == tTarget.m_pEntity || bSplash; bool bValid = bTarget && bTime; if (bValid && bSplash) { - bValid = SDK::VisPosWorld(nullptr, tTarget.m_pEntity, trace.endpos, vPoint, nMask); + bValid = (trace.endpos - vPoint).IsZero(0.01f) || SDK::VisPosWorld(nullptr, tTarget.m_pEntity, trace.endpos, vPoint, nMask); #ifdef SPLASH_DEBUG5 s_mTraceCount["Splash vispos"]++; #endif @@ -1215,7 +1219,7 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar } CGameTrace eyeTrace = {}; - SDK::Trace(vFrom, tTarget.m_vPos + tTarget.m_pEntity->As()->GetViewOffset(), MASK_SHOT, &filter, &eyeTrace); + SDK::Trace(vFrom, tTarget.m_vPos + m_tInfo.m_vTargetEye, MASK_SHOT, &filter, &eyeTrace); bValid = eyeTrace.fraction == 1.f; #ifdef SPLASH_DEBUG5 s_mTraceCount["Eye trace"]++; @@ -1230,7 +1234,9 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar G::BoxStorage.pop_back(); if (bValid) G::BoxStorage.emplace_back(vPoint, vHull * -1, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 255, 0), Color_t(0, 0, 0, 0)); - else if (!bTime) + else if (bTime) + G::BoxStorage.emplace_back(vPoint, vHull * -1, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 255), Color_t(0, 0, 0, 0)); + else { G::BoxStorage.emplace_back(vPoint, vHull * -1, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 255), Color_t(0, 0, 0, 0)); if (bSplash) @@ -1239,8 +1245,6 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar G::BoxStorage.emplace_back(vPoint, Vec3(-1, -1, -1), Vec3(1, 1, 1), Vec3(), I::GlobalVars->curtime + 5.f, Color_t(255, 255, 255), Color_t(0, 0, 0, 0)); } } - else - G::BoxStorage.emplace_back(vPoint, vHull * -1, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 255), Color_t(0, 0, 0, 0)); #endif if (bValid) @@ -1248,12 +1252,12 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar if (bSplash) { int iPopCount = Vars::Aimbot::Projectile::SplashTraceInterval.Value - trace.fraction * Vars::Aimbot::Projectile::SplashTraceInterval.Value; - for (int i = 0; i < iPopCount && !tProjInfo.m_vPath.empty(); i++) - tProjInfo.m_vPath.pop_back(); + for (int i = 0; i < iPopCount && !m_tProjInfo.m_vPath.empty(); i++) + m_tProjInfo.m_vPath.pop_back(); } // attempted to have a headshot check though this seems more detrimental than useful outside of smooth aimbot - if (tTarget.m_nAimedHitbox == HITBOX_HEAD && pProjectilePath && + if (tTarget.m_nAimedHitbox == HITBOX_HEAD && !bSecondTest && (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 @@ -1295,7 +1299,7 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar else if (!bSplash && bTarget && pWeapon->GetWeaponID() == TF_WEAPON_PIPEBOMBLAUNCHER) { // run for more ticks to check for splash iSimTime = n + 5; - bSplash = bPrimeTime = true; + bSplash = bArmTime = true; } else break; @@ -1303,38 +1307,155 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar if (!bSplash) trace.endpos = vNew; - if (!bTarget || bSplash && !bPrimeTime) + if (!bTarget || bSplash && !bArmTime) break; } } tTarget.m_pEntity->SetAbsOrigin(tOriginal.m_vOrigin); tTarget.m_pEntity->m_vecMins() = tOriginal.m_vMins; tTarget.m_pEntity->m_vecMaxs() = tOriginal.m_vMaxs; - - if (bDidHit && pProjectilePath) - { - tProjInfo.m_vPath.push_back(trace.endpos); - *pProjectilePath = tProjInfo.m_vPath; - } + m_tProjInfo.m_vPath.push_back(trace.endpos); return bDidHit; } +bool CAimbotProjectile::HandlePoint(const Vec3& vOrigin, int iSimTime, float flPitch, float flYaw, float flTime, const Vec3& vPoint, bool bSplash) +{ + bool bReturn = false; + + Vec3 vAngles; Aim(G::CurrentUserCmd->viewangles, { flPitch, flYaw, 0.f }, vAngles); + + const Vec3 vOriginal = m_tInfo.m_pTarget->m_vPos; + m_tInfo.m_pTarget->m_vPos = vOrigin; + if (!m_tInfo.m_pProjectile + ? TestAngle(vPoint, vAngles, iSimTime, bSplash) + : TestAngle(m_tInfo.m_pProjectile, vPoint, vAngles, iSimTime, bSplash)) + { + bReturn = m_iResult = true; + m_flTimeTo = flTime + m_tInfo.m_flLatency; + } + else if (m_iResult != 1 && !m_tInfo.m_pProjectile) + { + switch (Vars::Aimbot::General::AimType.Value) + { + case Vars::Aimbot::General::AimTypeEnum::Smooth: + if (Vars::Aimbot::General::AssistStrength.Value == 100.f) + break; + [[fallthrough]]; + case Vars::Aimbot::General::AimTypeEnum::Assistive: + { + Vec3 vPlainAngles = { flPitch, flYaw, 0.f }; + if (TestAngle(vPoint, vPlainAngles, iSimTime, bSplash, true)) + bReturn = m_iResult = 2; + } + } + } + m_tInfo.m_pTarget->m_vPos = vOriginal; + + if (bReturn) + { + m_vAngleTo = vAngles, m_vPredicted = vOrigin, m_vTarget = vPoint; + if (m_bVisuals) + { + m_vPlayerPath.clear(); + int iCount = std::min(iSimTime + TIME_TO_TICKS(m_tInfo.m_flLatency) + 1, int(m_tMoveStorage.m_vPath.size())); + for (int i = 0; i < iCount; i++) + m_vPlayerPath.push_back(m_tMoveStorage.m_vPath[i]); + m_vProjectilePath = m_tProjInfo.m_vPath; + } + } + + return bReturn; +} + +bool CAimbotProjectile::HandleDirect(std::vector& vDirectHistory) +{ + if (vDirectHistory.empty()) + return false; + + std::sort(vDirectHistory.begin(), vDirectHistory.end(), [&](const Direct_t& a, const Direct_t& b) -> bool + { + return a.m_iPriority < b.m_iPriority; + }); + m_flTimeTo = vDirectHistory.front().m_flTime + m_tInfo.m_flLatency; + + for (auto& tHistory : vDirectHistory) + { + if (HandlePoint(tHistory.m_vOrigin, tHistory.m_iSimtime, tHistory.m_flPitch, tHistory.m_flYaw, tHistory.m_flTime, tHistory.m_vPoint)) + return true; + } + + return false; +} + +bool CAimbotProjectile::HandleSplash(std::vector& vSplashHistory) +{ + if (vSplashHistory.empty()) + return false; + + std::sort(vSplashHistory.begin(), vSplashHistory.end(), [&](const Splash_t& a, const Splash_t& b) -> bool + { + return a.m_flTimeTo < b.m_flTimeTo; + }); + + float flSize = m_tInfo.m_pTarget->m_pEntity->GetSize().Length(); + int iPoints = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashPointsDirect.Value : Vars::Aimbot::Projectile::SplashPointsArc.Value; + auto vSpherePoints = ComputeSphere(m_tInfo.m_flRadius + flSize, iPoints); +#ifdef SPLASH_DEBUG3 + for (auto& [vPoint, _] : vSpherePoints) + G::BoxStorage.emplace_back(vSplashHistory.front().m_vOrigin + m_tInfo.m_vTargetEye + vPoint, Vec3(-1, -1, -1), Vec3(1, 1, 1), Vec3(), I::GlobalVars->curtime + 60.f, Color_t(0, 0, 0, 0), Vars::Colors::Local.Value); +#endif + + int iMulti = Vars::Aimbot::Projectile::SplashMode.Value; + static std::vector vSimplePoints = {}; + if (iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Single) + { + SetupSplashPoints(vSplashHistory.front().m_vOrigin, vSpherePoints, vSimplePoints); + if (vSimplePoints.empty()) + return false; + } + + float flLowestDistance = std::numeric_limits::max(); + for (auto& tHistory : vSplashHistory) + { + if (m_tInfo.m_iArmTime && tHistory.m_iSimtime < m_tInfo.m_iArmTime) + continue; + + std::vector vSplashPoints = {}; + if (iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Multi) + vSplashPoints = GetSplashPoints(tHistory.m_vOrigin, vSpherePoints, tHistory.m_iSimtime); + else + vSplashPoints = GetSplashPointsSimple(tHistory.m_vOrigin, vSimplePoints, tHistory.m_iSimtime); + + for (auto& tPoint : vSplashPoints) + { + float flDistance = tHistory.m_vOrigin.DistTo(tPoint.m_vPoint); + if (flDistance > flLowestDistance) + continue; + + if (HandlePoint(tHistory.m_vOrigin, tHistory.m_iSimtime, tPoint.m_tSolution.m_flPitch, tPoint.m_tSolution.m_flYaw, tPoint.m_tSolution.m_flTime, tPoint.m_vPoint, true)) + flLowestDistance = flDistance; + } + } + + return flLowestDistance != std::numeric_limits::max(); +} + int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, bool bVisuals) { //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; - ProjectileInfo tProjInfo = {}; - if (!F::ProjSim.GetInfo(pLocal, pWeapon, {}, tProjInfo, ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum) - || !F::ProjSim.Initialize(tProjInfo, false)) + m_tProjInfo = {}; + if (!F::ProjSim.GetInfo(pLocal, pWeapon, {}, m_tProjInfo, ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum) + || !F::ProjSim.Initialize(m_tProjInfo, false)) return false; - MoveStorage tStorage; - F::MoveSim.Initialize(tTarget.m_pEntity, tStorage); + m_tMoveStorage = {}; + F::MoveSim.Initialize(tTarget.m_pEntity, m_tMoveStorage); tTarget.m_vPos = tTarget.m_pEntity->m_vecOrigin(); - m_tInfo = { pLocal, pWeapon }; + m_tInfo = { pLocal, pWeapon, &tTarget }; m_tInfo.m_vLocalEye = pLocal->GetShootPos(); m_tInfo.m_vTargetEye = tTarget.m_pEntity->As()->GetViewOffset(); m_tInfo.m_flLatency = F::Backtrack.GetReal() + TICKS_TO_TIME(F::Backtrack.GetAnticipatedChoke()); @@ -1343,220 +1464,141 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas m_tInfo.m_flVelocity = vVelocity.Length(); m_tInfo.m_vAngFix = Math::VectorAngles(vVelocity); - m_tInfo.m_vHull = tProjInfo.m_vHull.Min(3); - m_tInfo.m_vOffset = tProjInfo.m_vPos - m_tInfo.m_vLocalEye; m_tInfo.m_vOffset.y *= -1; + m_tInfo.m_vHull = m_tProjInfo.m_vHull.Min(3); + m_tInfo.m_vOffset = m_tProjInfo.m_vPos - m_tInfo.m_vLocalEye; m_tInfo.m_vOffset.y *= -1; m_tInfo.m_flOffsetTime = m_tInfo.m_vOffset.Length() / m_tInfo.m_flVelocity; // silly float flSize = tTarget.m_pEntity->GetSize().Length(); - m_tInfo.m_flGravity = tProjInfo.m_flGravity; + m_tInfo.m_flGravity = m_tProjInfo.m_flGravity; m_tInfo.m_iSplashCount = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashCountDirect.Value : Vars::Aimbot::Projectile::SplashCountArc.Value; m_tInfo.m_flRadius = GetSplashRadius(pWeapon, pLocal); m_tInfo.m_flRadiusTime = m_tInfo.m_flRadius / m_tInfo.m_flVelocity; m_tInfo.m_flBoundingTime = m_tInfo.m_flRadiusTime + flSize / m_tInfo.m_flVelocity; m_tInfo.m_iSplashMode = GetSplashMode(pWeapon); - m_tInfo.m_flPrimeTime = PrimeTime(pWeapon); - m_tInfo.m_iPrimeTime = TIME_TO_TICKS(m_tInfo.m_flPrimeTime); + m_tInfo.m_iArmTime = TIME_TO_TICKS(ArmTime(pWeapon)); - int iReturn = false; - int iMaxTime = TIME_TO_TICKS(std::min(tProjInfo.m_flLifetime, Vars::Aimbot::Projectile::MaxSimulationTime.Value)); + int iMaxTime = TIME_TO_TICKS(std::min(m_tProjInfo.m_flLifetime, Vars::Aimbot::Projectile::MaxSimulationTime.Value)); int iSplash = Vars::Aimbot::Projectile::SplashPrediction.Value && m_tInfo.m_flRadius ? Vars::Aimbot::Projectile::SplashPrediction.Value : Vars::Aimbot::Projectile::SplashPredictionEnum::Off; - int iMulti = Vars::Aimbot::Projectile::SplashMode.Value; - int iPoints = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashPointsDirect.Value : Vars::Aimbot::Projectile::SplashPointsArc.Value; - auto mDirectPoints = iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Only ? std::unordered_map() : GetDirectPoints(tTarget); - auto vSpherePoints = !iSplash ? std::vector>() : ComputeSphere(m_tInfo.m_flRadius + flSize, iPoints); -#ifdef SPLASH_DEBUG3 - for (auto& [vPoint, _] : vSpherePoints) - G::BoxStorage.emplace_back(tTarget.m_pEntity->m_vecOrigin() + m_tInfo.m_vTargetEye + vPoint, Vec3(-1, -1, -1), Vec3(1, 1, 1), Vec3(), I::GlobalVars->curtime + 60.f, Color_t(0, 0, 0, 0), Vars::Colors::Local.Value); -#endif + auto mDirectPoints = iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Only ? std::unordered_map() : GetDirectPoints(); + + std::vector vDirectHistory = {}; + std::vector vSplashHistory = {}; - Vec3 vAngleTo, vPredicted, vTarget; - int iLowestPriority = std::numeric_limits::max(); float flLowestDist = std::numeric_limits::max(); - int iLowestSmoothPriority = iLowestPriority; float flLowestSmoothDist = flLowestDist; for (int i = 1 - TIME_TO_TICKS(m_tInfo.m_flLatency); i <= iMaxTime; i++) { - if (!tStorage.m_bFailed) + if (!m_tMoveStorage.m_bFailed) { - F::MoveSim.RunTick(tStorage); - tTarget.m_vPos = tStorage.m_vPredictedOrigin; + F::MoveSim.RunTick(m_tMoveStorage); + tTarget.m_vPos = m_tMoveStorage.m_vPredictedOrigin; } if (i < 0) continue; bool bDirectBreaks = true; - std::vector vSplashPoints = {}; if (iSplash) { Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, false); if (tSolution.m_iCalculated != CalculatedEnum::Bad) { - bDirectBreaks = false; - const float flTimeTo = tSolution.m_flTime - TICKS_TO_TIME(i); + + bDirectBreaks = false; if (flTimeTo < m_tInfo.m_flBoundingTime) { - static std::vector vSimplePoints = {}; - if (iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Single) - { - SetupSplashPoints(tTarget, vSpherePoints, vSimplePoints); - if (!vSimplePoints.empty()) - iMulti++; - else - { - iSplash = Vars::Aimbot::Projectile::SplashPredictionEnum::Off; - goto skipSplash; - } - } - - if ((iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Multi ? vSpherePoints.empty() : vSimplePoints.empty()) - || flTimeTo < -m_tInfo.m_flBoundingTime && (m_tInfo.m_flPrimeTime ? i > m_tInfo.m_iPrimeTime : true)) - break; - else if (m_tInfo.m_flPrimeTime ? i >= m_tInfo.m_iPrimeTime : true) - { - if (iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Multi) - vSplashPoints = GetSplashPoints(tTarget, vSpherePoints, i); - else - vSplashPoints = GetSplashPointsSimple(tTarget, vSimplePoints, i); - } + bDirectBreaks = flTimeTo < -m_tInfo.m_flBoundingTime && (!m_tInfo.m_iArmTime || m_tInfo.m_iArmTime < i); + if (!bDirectBreaks) + vSplashHistory.emplace_back(History_t(tTarget.m_vPos, i), fabsf(flTimeTo)); } } } - skipSplash: + + for (auto& [iIndex, vOffset] : mDirectPoints) + { + Vec3 vPoint = tTarget.m_vPos + vOffset; + if (Vars::Aimbot::Projectile::HuntsmanPullPoint.Value && tTarget.m_nAimedHitbox == HITBOX_HEAD) + { + vPoint = PullPoint(vPoint, m_tInfo.m_vLocalEye, m_tInfo, tTarget.m_pEntity->m_vecMins() + m_tInfo.m_vHull, tTarget.m_pEntity->m_vecMaxs() - m_tInfo.m_vHull, tTarget.m_vPos); + if (Vars::Aimbot::Projectile::HuntsmanPullNoZ.Value) + vPoint.z = tTarget.m_vPos.z + vOffset.z; + } + + Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, i, tSolution); + switch (tSolution.m_iCalculated) + { + case CalculatedEnum::Good: + if (m_tInfo.m_iArmTime && m_tInfo.m_iArmTime > i && !m_tMoveStorage.m_MoveData.m_vecVelocity.IsZero()) + break; + vDirectHistory.emplace_back(History_t(tTarget.m_vPos, i), tSolution.m_flPitch, tSolution.m_flYaw, tSolution.m_flTime, vPoint, iIndex); + [[fallthrough]]; + case CalculatedEnum::Bad: + mDirectPoints.erase(iIndex); + } + } if (bDirectBreaks && mDirectPoints.empty()) break; - - std::vector> vPoints = {}; - for (auto& [iIndex, vPoint] : mDirectPoints) - vPoints.emplace_back(Point_t(tTarget.m_vPos + vPoint, {}), iIndex + (iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Prefer ? m_tInfo.m_iSplashCount : 0), iIndex); - for (auto& vPoint : vSplashPoints) - vPoints.emplace_back(vPoint, iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Include ? 3 : 0, -1); - - int j = 0; - for (auto& [vPoint, iPriority, iIndex] : vPoints) // get most ideal point - { - const bool bSplash = iIndex == -1; - Vec3 vOriginalPoint = vPoint.m_vPoint; - - if (Vars::Aimbot::Projectile::HuntsmanPullPoint.Value && tTarget.m_nAimedHitbox == HITBOX_HEAD) - vPoint.m_vPoint = PullPoint(vPoint.m_vPoint, m_tInfo.m_vLocalEye, m_tInfo, tTarget.m_pEntity->m_vecMins() + tProjInfo.m_vHull, tTarget.m_pEntity->m_vecMaxs() - tProjInfo.m_vHull, tTarget.m_vPos); - //vPoint.m_vPoint = PullPoint(vPoint.m_vPoint, m_tInfo.m_vLocalEye, m_tInfo, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), tTarget.m_vPos); - - float flDist = bSplash ? tTarget.m_vPos.DistTo(vPoint.m_vPoint) : flLowestDist; - bool bPriority = bSplash ? iPriority <= iLowestPriority : iPriority < iLowestPriority; - bool bTime = bSplash || m_tInfo.m_iPrimeTime < i || tStorage.m_MoveData.m_vecVelocity.IsZero(); - bool bDist = !bSplash || flDist < flLowestDist; - if (!bSplash && !bPriority) - mDirectPoints.erase(iIndex); - if (!bPriority || !bTime || !bDist) - continue; - - CalculateAngle(m_tInfo.m_vLocalEye, vPoint.m_vPoint, i, vPoint.m_tSolution); - if (!bSplash && (vPoint.m_tSolution.m_iCalculated == CalculatedEnum::Good || vPoint.m_tSolution.m_iCalculated == CalculatedEnum::Bad)) - mDirectPoints.erase(iIndex); - if (vPoint.m_tSolution.m_iCalculated != CalculatedEnum::Good) - continue; - - if (Vars::Aimbot::Projectile::HuntsmanPullPoint.Value && tTarget.m_nAimedHitbox == HITBOX_HEAD) - { - Solution_t tSolution; - CalculateAngle(m_tInfo.m_vLocalEye, vOriginalPoint, std::numeric_limits::max(), tSolution); - vPoint.m_tSolution.m_flPitch = tSolution.m_flPitch, vPoint.m_tSolution.m_flYaw = tSolution.m_flYaw; - } - - Vec3 vAngles; Aim(G::CurrentUserCmd->viewangles, { vPoint.m_tSolution.m_flPitch, vPoint.m_tSolution.m_flYaw, 0.f }, vAngles); - std::vector vProjLines; bool bHitSolid = false; - - if (TestAngle(pLocal, pWeapon, tTarget, vPoint.m_vPoint, vAngles, i, bSplash, &bHitSolid, &vProjLines)) - { - iLowestPriority = iPriority; flLowestDist = flDist; - vAngleTo = vAngles, vPredicted = tTarget.m_vPos, vTarget = vOriginalPoint; - m_flTimeTo = vPoint.m_tSolution.m_flTime + m_tInfo.m_flLatency; - if (bVisuals) - { - m_vPlayerPath = tStorage.m_vPath; - m_vPlayerPath.push_back(tStorage.m_MoveData.m_vecAbsOrigin); - m_vProjectilePath = vProjLines; - } - } - else switch (Vars::Aimbot::General::AimType.Value) - { - case Vars::Aimbot::General::AimTypeEnum::Smooth: - if (Vars::Aimbot::General::AssistStrength.Value == 100.f) - break; - [[fallthrough]]; - case Vars::Aimbot::General::AimTypeEnum::Assistive: - { - bPriority = bSplash ? iPriority <= iLowestSmoothPriority : iPriority < flLowestSmoothDist; - bDist = !bSplash || flDist < flLowestDist; - if (!bPriority || !bDist) - continue; - - Vec3 vPlainAngles; Aim({}, { vPoint.m_tSolution.m_flPitch, vPoint.m_tSolution.m_flYaw, 0.f }, vPlainAngles, Vars::Aimbot::General::AimTypeEnum::Plain); - if (TestAngle(pLocal, pWeapon, tTarget, vPoint.m_vPoint, vPlainAngles, i, bSplash, &bHitSolid)) - { - iLowestSmoothPriority = iPriority; flLowestSmoothDist = flDist; - vAngleTo = vAngles, vPredicted = tTarget.m_vPos; - if (bVisuals) - { - m_vPlayerPath = tStorage.m_vPath; - m_vPlayerPath.push_back(tStorage.m_MoveData.m_vecAbsOrigin); - } - iReturn = 2; - } - } - } - - if (!j && bHitSolid) - m_flTimeTo = vPoint.m_tSolution.m_flTime + m_tInfo.m_flLatency; - j++; - } } - F::MoveSim.Restore(tStorage); - tTarget.m_vPos = vTarget; - tTarget.m_vAngleTo = vAngleTo; - if (tTarget.m_iTargetType != TargetEnum::Player || !tStorage.m_bFailed) // don't attempt to aim at players when movesim fails + m_iResult = false; + switch (iSplash) { - bool bMain = iLowestPriority != std::numeric_limits::max(); - bool bAny = bMain || iLowestSmoothPriority != std::numeric_limits::max(); + case Vars::Aimbot::Projectile::SplashPredictionEnum::Off: + HandleDirect(vDirectHistory); + break; + case Vars::Aimbot::Projectile::SplashPredictionEnum::Include: + if (!HandleDirect(vDirectHistory)) + HandleSplash(vSplashHistory); + break; + case Vars::Aimbot::Projectile::SplashPredictionEnum::Prefer: + if (!HandleSplash(vSplashHistory)) + HandleDirect(vDirectHistory); + break; + case Vars::Aimbot::Projectile::SplashPredictionEnum::Only: + HandleSplash(vSplashHistory); + } + F::MoveSim.Restore(m_tMoveStorage); + + tTarget.m_vPos = m_vTarget; + tTarget.m_vAngleTo = m_vAngleTo; + if (tTarget.m_iTargetType != TargetEnum::Player || !m_tMoveStorage.m_bFailed) // don't attempt to aim at players when movesim fails + { + bool bMain = m_iResult == 1; + bool bAny = m_iResult; if (bVisuals && bAny && (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a || Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a)) { m_tInfo.m_vHull = m_tInfo.m_vHull.Max(1); float flProjectileTime = TICKS_TO_TIME(m_vProjectilePath.size()); - float flTargetTime = tStorage.m_bFailed ? flProjectileTime : TICKS_TO_TIME(m_vPlayerPath.size()); + float flTargetTime = m_tMoveStorage.m_bFailed ? flProjectileTime : TICKS_TO_TIME(m_vPlayerPath.size()); bool bBox = Vars::Visuals::Hitbox::BoundsEnabled.Value & Vars::Visuals::Hitbox::BoundsEnabledEnum::OnShot; bool bPoint = Vars::Visuals::Hitbox::BoundsEnabled.Value & Vars::Visuals::Hitbox::BoundsEnabledEnum::AimPoint; if (bBox) { if (Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a) - m_vBoxes.emplace_back(vPredicted, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flTargetTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); + m_vBoxes.emplace_back(m_vPredicted, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flTargetTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); if (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a) - m_vBoxes.emplace_back(vPredicted, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flTargetTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); + m_vBoxes.emplace_back(m_vPredicted, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flTargetTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); } if (bMain && bPoint) { if (Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a) - m_vBoxes.emplace_back(vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); + m_vBoxes.emplace_back(m_vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); if (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a) - m_vBoxes.emplace_back(vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); + m_vBoxes.emplace_back(m_vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); } } - - if (bMain) - return true; } - return iReturn; + return m_iResult; } -bool CAimbotProjectile::Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod) +bool CAimbotProjectile::Aim(const Vec3& vCurAngle, const Vec3& vToAngle, Vec3& vOut, int iMethod) { /* if (Vec3* pDoubletapAngle = F::Ticks.GetShootAngle()) @@ -1817,15 +1859,23 @@ bool CAimbotProjectile::RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser case TF_WEAPON_BAT_WOOD: case TF_WEAPON_BAT_GIFTWRAP: case TF_WEAPON_LUNCHBOX: - pCmd->buttons &= ~IN_ATTACK, pCmd->buttons |= IN_ATTACK2; + pCmd->buttons |= IN_ATTACK2, pCmd->buttons &= ~IN_ATTACK; break; - default: - pCmd->buttons |= IN_ATTACK; + case TF_WEAPON_ROCKETLAUNCHER: + case TF_WEAPON_ROCKETLAUNCHER_DIRECTHIT: + case TF_WEAPON_PARTICLE_CANNON: + case TF_WEAPON_RAYGUN: + case TF_WEAPON_DRG_POMSON: + case TF_WEAPON_CROSSBOW: + pCmd->buttons |= IN_ATTACK, pCmd->buttons &= ~IN_ATTACK2; if (pWeapon->m_iItemDefinitionIndex() == Soldier_m_TheBeggarsBazooka) { if (pWeapon->m_iClip1() > 0) pCmd->buttons &= ~IN_ATTACK; } + break; + default: + pCmd->buttons |= IN_ATTACK; } } @@ -1897,24 +1947,28 @@ void CAimbotProjectile::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* // TestAngle and CanHit shares a bunch of code, possibly merge somehow -bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pProjectile, Target_t& tTarget, Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash, std::vector* pProjectilePath) +bool CAimbotProjectile::TestAngle(CBaseEntity* pProjectile, const Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash) { - ProjectileInfo tProjInfo = {}; - F::ProjSim.GetInfo(pProjectile, tProjInfo); + auto pLocal = m_tInfo.m_pLocal; + auto pWeapon = m_tInfo.m_pWeapon; + auto& tTarget = *m_tInfo.m_pTarget; + + m_tProjInfo = {}; + F::ProjSim.GetInfo(pProjectile, m_tProjInfo); CGameTrace trace = {}; { CTraceFilterWorldAndPropsOnly filter = {}; Vec3 vEyePos = pLocal->GetShootPos(); // m_tInfo.m_vLocalEye is not actually our shootpos here - tProjInfo.m_vPos = pProjectile->GetAbsOrigin(); + m_tProjInfo.m_vPos = pProjectile->GetAbsOrigin(); Vec3 vPos = vPoint; if (m_tInfo.m_flGravity) vPos += Vec3(0, 0, (m_tInfo.m_flGravity * 800.f * pow(TICKS_TO_TIME(iSimTime), 2)) / 2); - Vec3 vForward = (vPos - tProjInfo.m_vPos).Normalized(); - tProjInfo.m_vAng = Math::VectorAngles(vForward); + Vec3 vForward = (vPos - m_tProjInfo.m_vPos).Normalized(); + m_tProjInfo.m_vAng = Math::VectorAngles(vForward); - SDK::Trace(tProjInfo.m_vPos, tProjInfo.m_vPos + vForward * MAX_TRACE_LENGTH, MASK_SOLID, &filter, &trace); + SDK::Trace(m_tProjInfo.m_vPos, m_tProjInfo.m_vPos + vForward * MAX_TRACE_LENGTH, MASK_SOLID, &filter, &trace); vAngles = Math::CalcAngle(vEyePos, trace.endpos); vForward = (vEyePos - trace.endpos).Normalized(); if (vForward.Dot(trace.plane.normal) <= 0) @@ -1927,7 +1981,7 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBa if (!F::AutoAirblast.CanAirblastEntity(pLocal, pWeapon, pProjectile, vAngles)) return false; } - if (!F::ProjSim.Initialize(tProjInfo, false, true)) + if (!F::ProjSim.Initialize(m_tProjInfo, false, true)) return false; CTraceFilterCollideable filter = {}; @@ -1936,20 +1990,22 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBa int nMask = MASK_SOLID; F::ProjSim.SetupTrace(filter, nMask, pProjectile); - if (!tProjInfo.m_flGravity) + if (!m_tProjInfo.m_flGravity) { - SDK::TraceHull(tProjInfo.m_vPos, vPoint, tProjInfo.m_vHull * -1, tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(m_tProjInfo.m_vPos, vPoint, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); if (trace.fraction < 0.999f && trace.m_pEnt != tTarget.m_pEntity) return false; } bool bDidHit = false; - const Vec3 vOriginal = tTarget.m_pEntity->GetAbsOrigin(); + const RestoreInfo_t tOriginal = { tTarget.m_pEntity->GetAbsOrigin(), tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs() }; tTarget.m_pEntity->SetAbsOrigin(tTarget.m_vPos); + tTarget.m_pEntity->m_vecMins() = { std::clamp(tTarget.m_pEntity->m_vecMins().x, -24.f, 0.f), std::clamp(tTarget.m_pEntity->m_vecMins().y, -24.f, 0.f), tTarget.m_pEntity->m_vecMins().z }; + tTarget.m_pEntity->m_vecMaxs() = { std::clamp(tTarget.m_pEntity->m_vecMaxs().x, 0.f, 24.f), std::clamp(tTarget.m_pEntity->m_vecMaxs().y, 0.f, 24.f), tTarget.m_pEntity->m_vecMaxs().z }; for (int n = 1; n <= iSimTime; n++) { Vec3 vOld = F::ProjSim.GetOrigin(); - F::ProjSim.RunTick(tProjInfo); + F::ProjSim.RunTick(m_tProjInfo); Vec3 vNew = F::ProjSim.GetOrigin(); if (bDidHit) @@ -1959,7 +2015,7 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBa } if (!bSplash) - SDK::TraceHull(vOld, vNew, tProjInfo.m_vHull * -1, tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(vOld, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); else { static Vec3 vStaticPos = {}; @@ -1968,13 +2024,13 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBa if (n % Vars::Aimbot::Projectile::SplashTraceInterval.Value && n != iSimTime) continue; - SDK::TraceHull(vStaticPos, vNew, tProjInfo.m_vHull * -1, tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(vStaticPos, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); vStaticPos = vNew; } if (trace.DidHit()) { bool bTime = bSplash - ? trace.endpos.DistTo(vPoint) < tProjInfo.m_flVelocity * TICK_INTERVAL + tProjInfo.m_vHull.z + ? trace.endpos.DistTo(vPoint) < m_tProjInfo.m_flVelocity * TICK_INTERVAL + m_tProjInfo.m_vHull.z : iSimTime - n < 5; bool bTarget = trace.m_pEnt == tTarget.m_pEntity || bSplash; bool bValid = bTarget && bTime; @@ -2003,8 +2059,8 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBa if (bSplash) { int iPopCount = Vars::Aimbot::Projectile::SplashTraceInterval.Value - trace.fraction * Vars::Aimbot::Projectile::SplashTraceInterval.Value; - for (int i = 0; i < iPopCount && !tProjInfo.m_vPath.empty(); i++) - tProjInfo.m_vPath.pop_back(); + for (int i = 0; i < iPopCount && !m_tProjInfo.m_vPath.empty(); i++) + m_tProjInfo.m_vPath.pop_back(); } bDidHit = true; @@ -2019,13 +2075,10 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBa break; } } - tTarget.m_pEntity->SetAbsOrigin(vOriginal); - - if (bDidHit && pProjectilePath) - { - tProjInfo.m_vPath.push_back(trace.endpos); - *pProjectilePath = tProjInfo.m_vPath; - } + tTarget.m_pEntity->SetAbsOrigin(tOriginal.m_vOrigin); + tTarget.m_pEntity->m_vecMins() = tOriginal.m_vMins; + tTarget.m_pEntity->m_vecMaxs() = tOriginal.m_vMaxs; + m_tProjInfo.m_vPath.push_back(trace.endpos); return bDidHit; } @@ -2033,16 +2086,16 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBa bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pProjectile) { - ProjectileInfo tProjInfo = {}; - F::ProjSim.GetInfo(pProjectile, tProjInfo); - if (!F::ProjSim.Initialize(tProjInfo, false, true)) + m_tProjInfo = {}; + F::ProjSim.GetInfo(pProjectile, m_tProjInfo); + if (!F::ProjSim.Initialize(m_tProjInfo, false, true)) return false; - MoveStorage tStorage; - F::MoveSim.Initialize(tTarget.m_pEntity, tStorage); + m_tMoveStorage = {}; + F::MoveSim.Initialize(tTarget.m_pEntity, m_tMoveStorage); tTarget.m_vPos = tTarget.m_pEntity->m_vecOrigin(); - m_tInfo = { pLocal, tProjInfo.m_pWeapon }; + m_tInfo = { pLocal, m_tProjInfo.m_pWeapon, &tTarget, pProjectile }; m_tInfo.m_flLatency = F::Backtrack.GetReal() + TICKS_TO_TIME(F::Backtrack.GetAnticipatedChoke()); m_tInfo.m_vHull = pProjectile->m_vecMaxs().Min(3); { @@ -2052,24 +2105,24 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa for (int i = TIME_TO_TICKS(m_tInfo.m_flLatency); i > 0; i--) { Vec3 vOld = F::ProjSim.GetOrigin(); - F::ProjSim.RunTick(tProjInfo); + F::ProjSim.RunTick(m_tProjInfo); Vec3 vNew = F::ProjSim.GetOrigin(); - SDK::TraceHull(vOld, vNew, tProjInfo.m_vHull * -1, tProjInfo.m_vHull, MASK_SOLID, &filter, &trace); - tProjInfo.m_vPos = trace.endpos; + SDK::TraceHull(vOld, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, MASK_SOLID, &filter, &trace); + m_tProjInfo.m_vPos = trace.endpos; } - m_tInfo.m_vLocalEye = tProjInfo.m_vPos; // just assume from the projectile without any offset, check validity later - pProjectile->SetAbsOrigin(tProjInfo.m_vPos); + m_tInfo.m_vLocalEye = m_tProjInfo.m_vPos; // just assume from the projectile without any offset, check validity later + pProjectile->SetAbsOrigin(m_tProjInfo.m_vPos); } m_tInfo.m_vTargetEye = tTarget.m_pEntity->As()->GetViewOffset(); - m_tInfo.m_flVelocity = tProjInfo.m_flVelocity; + m_tInfo.m_flVelocity = m_tProjInfo.m_flVelocity; - m_tInfo.m_flGravity = tProjInfo.m_flGravity; + m_tInfo.m_flGravity = m_tProjInfo.m_flGravity; m_tInfo.m_iSplashCount = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashCountDirect.Value : Vars::Aimbot::Projectile::SplashCountArc.Value; float flSize = tTarget.m_pEntity->GetSize().Length(); - m_tInfo.m_flRadius = GetSplashRadius(pProjectile, tProjInfo.m_pWeapon, tProjInfo.m_pOwner, Vars::Aimbot::Projectile::SplashRadius.Value / 100, pWeapon); + m_tInfo.m_flRadius = GetSplashRadius(pProjectile, m_tProjInfo.m_pWeapon, m_tProjInfo.m_pOwner, Vars::Aimbot::Projectile::SplashRadius.Value / 100, pWeapon); m_tInfo.m_flRadiusTime = m_tInfo.m_flRadius / m_tInfo.m_flVelocity; m_tInfo.m_flBoundingTime = m_tInfo.m_flRadiusTime + flSize / m_tInfo.m_flVelocity; @@ -2077,154 +2130,118 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa int iMaxTime = TIME_TO_TICKS(Vars::Aimbot::Projectile::MaxSimulationTime.Value); int iSplash = Vars::Aimbot::Projectile::SplashPrediction.Value && m_tInfo.m_flRadius ? Vars::Aimbot::Projectile::SplashPrediction.Value : Vars::Aimbot::Projectile::SplashPredictionEnum::Off; - int iMulti = Vars::Aimbot::Projectile::SplashMode.Value; - int iPoints = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashPointsDirect.Value : Vars::Aimbot::Projectile::SplashPointsArc.Value; + + auto mDirectPoints = iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Only ? std::unordered_map() : GetDirectPoints(); + + std::vector vDirectHistory = {}; + std::vector vSplashHistory = {}; - auto mDirectPoints = iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Only ? std::unordered_map() : GetDirectPoints(tTarget, pProjectile); - auto vSpherePoints = !iSplash ? std::vector>() : ComputeSphere(m_tInfo.m_flRadius + flSize, iPoints); - - Vec3 vAngleTo, vPredicted, vTarget; - int iLowestPriority = std::numeric_limits::max(); float flLowestDist = std::numeric_limits::max(); for (int i = 1 - TIME_TO_TICKS(m_tInfo.m_flLatency); i <= iMaxTime; i++) { - if (!tStorage.m_bFailed) + if (!m_tMoveStorage.m_bFailed) { - F::MoveSim.RunTick(tStorage); - tTarget.m_vPos = tStorage.m_vPredictedOrigin; + F::MoveSim.RunTick(m_tMoveStorage); + tTarget.m_vPos = m_tMoveStorage.m_vPredictedOrigin; } if (i < 0) continue; bool bDirectBreaks = true; - std::vector vSplashPoints = {}; if (iSplash) { - Solution_t solution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, solution, false); - if (solution.m_iCalculated != CalculatedEnum::Bad) + Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, false); + if (tSolution.m_iCalculated != CalculatedEnum::Bad) { - bDirectBreaks = false; + const float flTimeTo = tSolution.m_flTime - TICKS_TO_TIME(i); - const float flTimeTo = solution.m_flTime - TICKS_TO_TIME(i); + bDirectBreaks = false; if (flTimeTo < m_tInfo.m_flBoundingTime) { - static std::vector vSimplePoints = {}; - if (iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Single) - { - SetupSplashPoints(tTarget, vSpherePoints, vSimplePoints); - if (!vSimplePoints.empty()) - iMulti++; - else - { - iSplash = Vars::Aimbot::Projectile::SplashPredictionEnum::Off; - goto skipSplash; - } - } - - if ((iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Multi ? vSpherePoints.empty() : vSimplePoints.empty()) - || flTimeTo < -m_tInfo.m_flBoundingTime) - break; - else - { - if (iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Multi) - vSplashPoints = GetSplashPoints(tTarget, vSpherePoints, i); - else - vSplashPoints = GetSplashPointsSimple(tTarget, vSimplePoints, i); - } + bDirectBreaks = flTimeTo < -m_tInfo.m_flBoundingTime; + if (!bDirectBreaks) + vSplashHistory.emplace_back(History_t(tTarget.m_vPos, i), fabsf(flTimeTo)); } } } - skipSplash: - if (bDirectBreaks && mDirectPoints.empty()) - break; - std::vector> vPoints = {}; - for (auto& [iIndex, vPoint] : mDirectPoints) - vPoints.emplace_back(Point_t(tTarget.m_vPos + vPoint, {}), iIndex + (iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Prefer ? m_tInfo.m_iSplashCount : 0), iIndex); - for (auto& vPoint : vSplashPoints) - vPoints.emplace_back(vPoint, iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Include ? 3 : 0, -1); - - for (auto& [vPoint, iPriority, iIndex] : vPoints) // get most ideal point + for (auto& [iIndex, vOffset] : mDirectPoints) { - const bool bSplash = iIndex == -1; - Vec3 vOriginalPoint = vPoint.m_vPoint; - - if (Vars::Aimbot::Projectile::HuntsmanPullPoint.Value && tTarget.m_nAimedHitbox == HITBOX_HEAD) - vPoint.m_vPoint = PullPoint(vPoint.m_vPoint, m_tInfo.m_vLocalEye, m_tInfo, tTarget.m_pEntity->m_vecMins() + tProjInfo.m_vHull, tTarget.m_pEntity->m_vecMaxs() - tProjInfo.m_vHull, tTarget.m_vPos); - //vPoint.m_vPoint = PullPoint(vPoint.m_vPoint, m_tInfo.m_vLocalEye, m_tInfo, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), tTarget.m_vPos); - - float flDist = bSplash ? tTarget.m_vPos.DistTo(vPoint.m_vPoint) : flLowestDist; - bool bPriority = bSplash ? iPriority <= iLowestPriority : iPriority < iLowestPriority; - bool bTime = bSplash || tStorage.m_MoveData.m_vecVelocity.IsZero(); - bool bDist = !bSplash || flDist < flLowestDist; - if (!bSplash && !bPriority) - mDirectPoints.erase(iIndex); - if (!bPriority || !bTime || !bDist) - continue; - - CalculateAngle(m_tInfo.m_vLocalEye, vPoint.m_vPoint, i, vPoint.m_tSolution); - if (!bSplash && (vPoint.m_tSolution.m_iCalculated == CalculatedEnum::Good || vPoint.m_tSolution.m_iCalculated == CalculatedEnum::Bad)) - mDirectPoints.erase(iIndex); - if (vPoint.m_tSolution.m_iCalculated != CalculatedEnum::Good) - continue; - + Vec3 vPoint = tTarget.m_vPos + vOffset; if (Vars::Aimbot::Projectile::HuntsmanPullPoint.Value && tTarget.m_nAimedHitbox == HITBOX_HEAD) { - Solution_t tSolution; - CalculateAngle(m_tInfo.m_vLocalEye, vOriginalPoint, std::numeric_limits::max(), tSolution); - vPoint.m_tSolution.m_flPitch = tSolution.m_flPitch, vPoint.m_tSolution.m_flYaw = tSolution.m_flYaw; + vPoint = PullPoint(vPoint, m_tInfo.m_vLocalEye, m_tInfo, tTarget.m_pEntity->m_vecMins() + m_tInfo.m_vHull, tTarget.m_pEntity->m_vecMaxs() - m_tInfo.m_vHull, tTarget.m_vPos); + if (Vars::Aimbot::Projectile::HuntsmanPullNoZ.Value) + vPoint.z = tTarget.m_vPos.z + vOffset.z; } - Vec3 vAngles; Aim(G::CurrentUserCmd->viewangles, { vPoint.m_tSolution.m_flPitch, vPoint.m_tSolution.m_flYaw, 0.f }, vAngles, Vars::Aimbot::General::AimTypeEnum::Plain); - std::vector vProjLines; - - if (TestAngle(pLocal, pWeapon, pProjectile, tTarget, vPoint.m_vPoint, vAngles, i, bSplash, &vProjLines)) + Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, i, tSolution); + switch (tSolution.m_iCalculated) { - iLowestPriority = iPriority; flLowestDist = flDist; - vAngleTo = vAngles, vPredicted = tTarget.m_vPos, vTarget = vOriginalPoint; - m_flTimeTo = vPoint.m_tSolution.m_flTime + m_tInfo.m_flLatency; - m_vPlayerPath = tStorage.m_vPath; - m_vPlayerPath.push_back(tStorage.m_MoveData.m_vecAbsOrigin); - m_vProjectilePath = vProjLines; + case CalculatedEnum::Good: + vDirectHistory.emplace_back(History_t(tTarget.m_vPos, i), tSolution.m_flPitch, tSolution.m_flYaw, tSolution.m_flTime, vPoint, iIndex); + [[fallthrough]]; + case CalculatedEnum::Bad: + mDirectPoints.erase(iIndex); } } + if (bDirectBreaks && mDirectPoints.empty()) + break; } - F::MoveSim.Restore(tStorage); - tTarget.m_vPos = vTarget; - tTarget.m_vAngleTo = vAngleTo; - if (tTarget.m_iTargetType != TargetEnum::Player || !tStorage.m_bFailed) // don't attempt to aim at players when movesim fails + m_iResult = false; + switch (iSplash) { - if (iLowestPriority != std::numeric_limits::max()) + case Vars::Aimbot::Projectile::SplashPredictionEnum::Off: + HandleDirect(vDirectHistory); + break; + case Vars::Aimbot::Projectile::SplashPredictionEnum::Include: + if (!HandleDirect(vDirectHistory)) + HandleSplash(vSplashHistory); + break; + case Vars::Aimbot::Projectile::SplashPredictionEnum::Prefer: + if (!HandleSplash(vSplashHistory)) + HandleDirect(vDirectHistory); + break; + case Vars::Aimbot::Projectile::SplashPredictionEnum::Only: + HandleSplash(vSplashHistory); + } + F::MoveSim.Restore(m_tMoveStorage); + + tTarget.m_vPos = m_vTarget; + tTarget.m_vAngleTo = m_vAngleTo; + if (tTarget.m_iTargetType != TargetEnum::Player || !m_tMoveStorage.m_bFailed) // don't attempt to aim at players when movesim fails + { + bool bMain = m_iResult == 1; + + if (bMain) { if (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a || Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a) { m_tInfo.m_vHull = m_tInfo.m_vHull.Max(1); float flProjectileTime = TICKS_TO_TIME(m_vProjectilePath.size()); - float flTargetTime = tStorage.m_bFailed ? flProjectileTime : TICKS_TO_TIME(m_vPlayerPath.size()); + float flTargetTime = m_tMoveStorage.m_bFailed ? flProjectileTime : TICKS_TO_TIME(m_vPlayerPath.size()); bool bBox = Vars::Visuals::Hitbox::BoundsEnabled.Value & Vars::Visuals::Hitbox::BoundsEnabledEnum::OnShot; bool bPoint = Vars::Visuals::Hitbox::BoundsEnabled.Value & Vars::Visuals::Hitbox::BoundsEnabledEnum::AimPoint; if (bBox) { if (Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a) - m_vBoxes.emplace_back(vPredicted, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flTargetTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); + m_vBoxes.emplace_back(m_vPredicted, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flTargetTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); if (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a) - m_vBoxes.emplace_back(vPredicted, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flTargetTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); + m_vBoxes.emplace_back(m_vPredicted, tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs(), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flTargetTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); } if (bPoint) { if (Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a) - m_vBoxes.emplace_back(vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); + m_vBoxes.emplace_back(m_vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); if (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a) - m_vBoxes.emplace_back(vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); + m_vBoxes.emplace_back(m_vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); } } - - return true; } } - return false; + return m_iResult; } bool CAimbotProjectile::AutoAirblast(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd, CBaseEntity* pProjectile) diff --git a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h index 5dcd66b5..592f81ae 100644 --- a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h +++ b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h @@ -2,26 +2,18 @@ #include "../../../SDK/SDK.h" #include "../AimbotGlobal/AimbotGlobal.h" +#include "../../Simulation/MovementSimulation/MovementSimulation.h" +#include "../../Simulation/ProjectileSimulation/ProjectileSimulation.h" -Enum(PointType, None = 0, Regular = 1 << 0, Obscured = 1 << 1, ObscuredExtra = 1 << 2, ObscuredMulti = 1 << 3) +Enum(PointType, None = 0, Out = 1 << 0, In = 1 << 1, Out2 = 1 << 2, In2 = 1 << 3) Enum(Calculated, Pending, Good, Time, Bad) -struct Solution_t -{ - float m_flPitch = 0.f; - float m_flYaw = 0.f; - float m_flTime = 0.f; - int m_iCalculated = CalculatedEnum::Pending; -}; -struct Point_t -{ - Vec3 m_vPoint = {}; - Solution_t m_tSolution = {}; -}; struct Info_t { CTFPlayer* m_pLocal = nullptr; CTFWeaponBase* m_pWeapon = nullptr; + Target_t* m_pTarget = nullptr; + CBaseEntity* m_pProjectile = nullptr; Vec3 m_vLocalEye = {}; Vec3 m_vTargetEye = {}; @@ -39,31 +31,67 @@ struct Info_t float m_flOffsetTime = 0.f; int m_iSplashCount = 0; int m_iSplashMode = 0; - float m_flPrimeTime = 0; - int m_iPrimeTime = 0; + int m_iArmTime = 0; +}; + +struct Solution_t +{ + float m_flPitch = 0.f; + float m_flYaw = 0.f; + float m_flTime = 0.f; + int m_iCalculated = CalculatedEnum::Pending; +}; +struct Point_t +{ + Vec3 m_vPoint = {}; + Solution_t m_tSolution = {}; +}; + +struct History_t +{ + Vec3 m_vOrigin; + int m_iSimtime; +}; +struct Direct_t : History_t +{ + float m_flPitch; + float m_flYaw; + float m_flTime; + Vec3 m_vPoint; + int m_iPriority; +}; +struct Splash_t : History_t +{ + float m_flTimeTo; }; class CAimbotProjectile { private: - std::unordered_map GetDirectPoints(Target_t& tTarget, CBaseEntity* pProjectile = nullptr); - std::vector GetSplashPoints(Target_t& tTarget, std::vector>& vSpherePoints, int iSimTime); - void SetupSplashPoints(Target_t& tTarget, std::vector>& vSpherePoints, std::vector& vSimplePoints); - std::vector GetSplashPointsSimple(Target_t& tTarget, std::vector& vSpherePoints, int iSimTime); + std::unordered_map GetDirectPoints(); + std::vector GetSplashPoints(Vec3 vOrigin, std::vector>& vSpherePoints, int iSimTime); + void SetupSplashPoints(Vec3& vPos, std::vector>& vSpherePoints, std::vector& vSimplePoints); + std::vector GetSplashPointsSimple(Vec3 vOrigin, std::vector& vSpherePoints, int iSimTime); - void CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, bool bAccuracy = true); - bool TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Target_t& tTarget, Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash, bool* pHitSolid = nullptr, std::vector* pProjectilePath = nullptr); + void CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, bool bAccuracy = true, int iTolerance = -1); + bool TestAngle(const Vec3& vPoint, const Vec3& vAngles, int iSimTime, bool bSplash, bool bSecondTest = false); + + bool HandlePoint(const Vec3& vOrigin, int iSimTime, float flPitch, float flYaw, float flTime, const Vec3& vPoint, bool bSplash = false); + bool HandleDirect(std::vector& vDirectHistory); + bool HandleSplash(std::vector& vSplashHistory); int CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, bool bVisuals = true); bool RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd); bool CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pProjectile); - bool TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pProjectile, Target_t& tTarget, Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash, std::vector* pProjectilePath = nullptr); + bool TestAngle(CBaseEntity* pProjectile, const Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash); - 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& vAngle, int iMethod = Vars::Aimbot::General::AimType.Value); Info_t m_tInfo = {}; + MoveStorage m_tMoveStorage = {}; + ProjectileInfo m_tProjInfo = {}; bool m_bLastTickHeld = false; @@ -72,6 +100,13 @@ private: std::vector m_vProjectilePath = {}; std::vector m_vBoxes = {}; + Vec3 m_vAngleTo = {}; + Vec3 m_vPredicted = {}; + Vec3 m_vTarget = {}; + + int m_iResult = false; + bool m_bVisuals = true; + public: void Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd); float GetSplashRadius(CTFWeaponBase* pWeapon, CTFPlayer* pPlayer); diff --git a/Amalgam/src/Features/Aimbot/AutoAirblast/AutoAirblast.cpp b/Amalgam/src/Features/Aimbot/AutoAirblast/AutoAirblast.cpp index 1b43613c..4f929863 100644 --- a/Amalgam/src/Features/Aimbot/AutoAirblast/AutoAirblast.cpp +++ b/Amalgam/src/Features/Aimbot/AutoAirblast/AutoAirblast.cpp @@ -25,7 +25,7 @@ static inline bool ShouldTarget(CBaseEntity* pProjectile, CTFPlayer* pLocal) return true; } -bool CAutoAirblast::CanAirblastEntity(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pEntity, Vec3& vAngle) +bool CAutoAirblast::CanAirblastEntity(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pEntity, const Vec3& vAngle) { auto flRadius = SDK::AttribHookValue(1, "deflection_size_multiplier", pWeapon) * 128.f; diff --git a/Amalgam/src/Features/Aimbot/AutoAirblast/AutoAirblast.h b/Amalgam/src/Features/Aimbot/AutoAirblast/AutoAirblast.h index 602e8006..f8240ffb 100644 --- a/Amalgam/src/Features/Aimbot/AutoAirblast/AutoAirblast.h +++ b/Amalgam/src/Features/Aimbot/AutoAirblast/AutoAirblast.h @@ -5,7 +5,7 @@ class CAutoAirblast { public: void Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd); - bool CanAirblastEntity(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pEntity, Vec3& vAngle); + bool CanAirblastEntity(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pEntity, const Vec3& vAngle); }; ADD_FEATURE(CAutoAirblast, AutoAirblast); \ No newline at end of file diff --git a/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp b/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp index 10e7fdba..3c18d733 100644 --- a/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp +++ b/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp @@ -39,22 +39,22 @@ bool CAutoRocketJump::SetAngles(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser //float flOffset = pLocal->m_vecMaxs().x; float flOffset = sqrtf(2 * powf(vOffset.y, 2.f) + powf(vOffset.z, 2.f)); bool bShouldReturn = true; - MoveStorage tStorage; - if (F::MoveSim.Initialize(pLocal, tStorage, false)) + MoveStorage tMoveStorage; + if (F::MoveSim.Initialize(pLocal, tMoveStorage, false)) { for (int n = 1; n < 10; n++) { - F::MoveSim.RunTick(tStorage); + F::MoveSim.RunTick(tMoveStorage); if (!pLocal->IsOnGround() || pLocal->IsSwimming()) continue; - Vec3 vForward = tStorage.m_MoveData.m_vecVelocity.Normalized2D(); - vPoint = tStorage.m_MoveData.m_vecAbsOrigin - vForward * flOffset; //- Vec3(0, 0, 20); + Vec3 vForward = tMoveStorage.m_MoveData.m_vecVelocity.Normalized2D(); + vPoint = tMoveStorage.m_MoveData.m_vecAbsOrigin - vForward * flOffset; //- Vec3(0, 0, 20); bShouldReturn = false; break; } } - F::MoveSim.Restore(tStorage); + F::MoveSim.Restore(tMoveStorage); if (bShouldReturn) return false; } @@ -132,8 +132,6 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p m_iFrame = -1; return; } - else if (Vars::Misc::Movement::AutoRocketJump.Value || Vars::Misc::Movement::AutoCTap.Value) - pCmd->buttons &= ~IN_ATTACK2; // fix for retarded issue if (m_iFrame == -1 && (bCurrGrounded && bBeggars ? G::Attacking == 1 : G::CanPrimaryAttack || G::Reloading) && SetAngles(pLocal, pWeapon, pCmd)) @@ -141,18 +139,18 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p bool bWillHit = false; if (Vars::Misc::Movement::AutoRocketJump.Value || Vars::Misc::Movement::AutoCTap.Value) { - MoveStorage tStorage; + MoveStorage tMoveStorage; ProjectileInfo tProjInfo = {}; bool bProjSimSetup = F::ProjSim.GetInfo(pLocal, pWeapon, m_vAngles, tProjInfo, ProjSimEnum::Trace | ProjSimEnum::InitCheck | ProjSimEnum::NoRandomAngles) && F::ProjSim.Initialize(tProjInfo); - bool bMoveSimSetup = F::MoveSim.Initialize(pLocal, tStorage, false); // do move sim after to not mess with proj sim + bool bMoveSimSetup = F::MoveSim.Initialize(pLocal, tMoveStorage, false); // do move sim after to not mess with proj sim if (bMoveSimSetup && bProjSimSetup) { Vec3 vOriginal = F::ProjSim.GetOrigin(); int iSkip = bCurrGrounded ? Vars::Misc::Movement::AutoRocketJumpSkipGround.Value : Vars::Misc::Movement::AutoRocketJumpSkipAir.Value; for (int n = 1; n < 10; n++) { - F::MoveSim.RunTick(tStorage); + F::MoveSim.RunTick(tMoveStorage); if (n <= iSkip) continue; @@ -179,7 +177,7 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p return vPoint.DistTo(vPos) < TF_ROCKET_RADIUS_FOR_RJS && SDK::VisPosWorld(pLocal, pLocal, vPoint, vOrigin + pLocal->m_vecViewOffset(), MASK_SHOT); }; - bWillHit = WillHit(pLocal, tStorage.m_MoveData.m_vecAbsOrigin, trace.endpos + trace.plane.normal); + bWillHit = WillHit(pLocal, tMoveStorage.m_MoveData.m_vecAbsOrigin, trace.endpos + trace.plane.normal); if (bWillHit) { m_iDelay = n; @@ -194,7 +192,7 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p //G::LineStorage.clear(); G::BoxStorage.clear(); Vec3 vAngles = Math::VectorAngles(trace.plane.normal); G::BoxStorage.emplace_back(trace.endpos + trace.plane.normal, Vec3(-1.f, -1.f, -1.f), Vec3(1.f, 1.f, 1.f), vAngles, I::GlobalVars->curtime + 5.f, Color_t(), Color_t(0, 0, 0, 0), true); - G::LineStorage.emplace_back(std::pair(tStorage.m_MoveData.m_vecAbsOrigin + pLocal->m_vecViewOffset(), trace.endpos + trace.plane.normal), I::GlobalVars->curtime + 5.f, Color_t(), true); + G::LineStorage.emplace_back(std::pair(tMoveStorage.m_MoveData.m_vecAbsOrigin + pLocal->m_vecViewOffset(), trace.endpos + trace.plane.normal), I::GlobalVars->curtime + 5.f, Color_t(), true); } } } @@ -207,7 +205,7 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p // break; } } - F::MoveSim.Restore(tStorage); + F::MoveSim.Restore(tMoveStorage); } if (bWillHit) @@ -232,9 +230,6 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p } } } - - if (m_iFrame == -1 && pWeapon->GetWeaponID() == TF_WEAPON_PARTICLE_CANNON && G::OriginalCmd.buttons & IN_ATTACK2) - pCmd->buttons |= IN_ATTACK2; } if (m_iFrame != -1) @@ -245,7 +240,7 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p if (m_iFrame == 1) { if (!bBeggars) - pCmd->buttons |= IN_ATTACK; + pCmd->buttons |= IN_ATTACK, pCmd->buttons &= ~IN_ATTACK2; if (m_bFull) { diff --git a/Amalgam/src/Features/ImGui/Menu/Menu.cpp b/Amalgam/src/Features/ImGui/Menu/Menu.cpp index 3cbdfba7..47efc740 100644 --- a/Amalgam/src/Features/ImGui/Menu/Menu.cpp +++ b/Amalgam/src/Features/ImGui/Menu/Menu.cpp @@ -267,6 +267,7 @@ void CMenu::MenuAimbot(int iTab) if (Section("##Debug Projectile")) { FText("Ground"); + Divider(); FSlider(Vars::Aimbot::Projectile::GroundSamples, FSliderEnum::Left); FSlider(Vars::Aimbot::Projectile::GroundStraightFuzzyValue, FSliderEnum::Right); FSlider(Vars::Aimbot::Projectile::GroundLowMinimumSamples, FSliderEnum::Left); @@ -276,7 +277,9 @@ void CMenu::MenuAimbot(int iTab) FSlider(Vars::Aimbot::Projectile::GroundMaxChanges, FSliderEnum::Left); FSlider(Vars::Aimbot::Projectile::GroundMaxChangeTime, FSliderEnum::Right); - FText("\nAir"); + Divider(); + FText("Air"); + Divider(); FSlider(Vars::Aimbot::Projectile::AirSamples, FSliderEnum::Left); FSlider(Vars::Aimbot::Projectile::AirStraightFuzzyValue, FSliderEnum::Right); FSlider(Vars::Aimbot::Projectile::AirLowMinimumSamples, FSliderEnum::Left); @@ -286,7 +289,9 @@ void CMenu::MenuAimbot(int iTab) FSlider(Vars::Aimbot::Projectile::AirMaxChanges, FSliderEnum::Left); FSlider(Vars::Aimbot::Projectile::AirMaxChangeTime, FSliderEnum::Right); - FText(""); + Divider(); + FText("General"); + Divider(); FSlider(Vars::Aimbot::Projectile::VelocityAverageCount, FSliderEnum::Left); FSlider(Vars::Aimbot::Projectile::VerticalShift, FSliderEnum::Right); @@ -297,9 +302,12 @@ void CMenu::MenuAimbot(int iTab) FSlider(Vars::Aimbot::Projectile::HuntsmanAdd, FSliderEnum::Left); FSlider(Vars::Aimbot::Projectile::HuntsmanAddLow, FSliderEnum::Right); FSlider(Vars::Aimbot::Projectile::HuntsmanClamp, FSliderEnum::Left); - FToggle(Vars::Aimbot::Projectile::HuntsmanPullPoint, FToggleEnum::Right); - SetCursorPosY(GetCursorPosY() + 8); + FToggle(Vars::Aimbot::Projectile::HuntsmanPullPoint, FSliderEnum::Left); + FToggle(Vars::Aimbot::Projectile::HuntsmanPullNoZ, FToggleEnum::Right); + Divider(); + FText("Splash"); + Divider(); FSlider(Vars::Aimbot::Projectile::SplashPointsDirect, FSliderEnum::Left); FSlider(Vars::Aimbot::Projectile::SplashPointsArc, FSliderEnum::Right); FSlider(Vars::Aimbot::Projectile::SplashCountDirect, FSliderEnum::Left); @@ -310,9 +318,12 @@ void CMenu::MenuAimbot(int iTab) FSlider(Vars::Aimbot::Projectile::SplashNormalSkip, FSliderEnum::Right); FDropdown(Vars::Aimbot::Projectile::SplashMode, FDropdownEnum::Left); FDropdown(Vars::Aimbot::Projectile::RocketSplashMode, FDropdownEnum::Right, 0, &Hovered); FTooltip("Special splash type for rockets, more expensive", Hovered); - FToggle(Vars::Aimbot::Projectile::SplashGrates); - SetCursorPosY(GetCursorPosY() + 8); + FToggle(Vars::Aimbot::Projectile::SplashGrates, FSliderEnum::Left); + FSlider(Vars::Aimbot::Projectile::Out2NormalCheck, FSliderEnum::Right); + Divider(); + FText("Misc"); + Divider(); FSlider(Vars::Aimbot::Projectile::DeltaCount, FSliderEnum::Left); FDropdown(Vars::Aimbot::Projectile::DeltaMode, FDropdownEnum::Right); FDropdown(Vars::Aimbot::Projectile::MovesimFrictionFlags); diff --git a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp index dd8d8441..d7fde5af 100644 --- a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp +++ b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp @@ -5,32 +5,32 @@ static CUserCmd s_tDummyCmd = {}; -void CMovementSimulation::Store(MoveStorage& tStorage) +void CMovementSimulation::Store(MoveStorage& tMoveStorage) { - auto pMap = tStorage.m_pPlayer->GetPredDescMap(); + auto pMap = tMoveStorage.m_pPlayer->GetPredDescMap(); if (!pMap) return; - size_t iSize = tStorage.m_pPlayer->GetIntermediateDataSize(); - tStorage.m_pData = reinterpret_cast(I::MemAlloc->Alloc(iSize)); + size_t iSize = tMoveStorage.m_pPlayer->GetIntermediateDataSize(); + tMoveStorage.m_pData = reinterpret_cast(I::MemAlloc->Alloc(iSize)); - CPredictionCopy copy = { PC_NETWORKED_ONLY, tStorage.m_pData, PC_DATA_PACKED, tStorage.m_pPlayer, PC_DATA_NORMAL }; - copy.TransferData("MovementSimulationStore", tStorage.m_pPlayer->entindex(), pMap); + CPredictionCopy copy = { PC_NETWORKED_ONLY, tMoveStorage.m_pData, PC_DATA_PACKED, tMoveStorage.m_pPlayer, PC_DATA_NORMAL }; + copy.TransferData("MovementSimulationStore", tMoveStorage.m_pPlayer->entindex(), pMap); } -void CMovementSimulation::Reset(MoveStorage& tStorage) +void CMovementSimulation::Reset(MoveStorage& tMoveStorage) { - if (tStorage.m_pData) + if (tMoveStorage.m_pData) { - auto pMap = tStorage.m_pPlayer->GetPredDescMap(); + auto pMap = tMoveStorage.m_pPlayer->GetPredDescMap(); if (!pMap) return; - CPredictionCopy copy = { PC_NETWORKED_ONLY, tStorage.m_pPlayer, PC_DATA_NORMAL, tStorage.m_pData, PC_DATA_PACKED }; - copy.TransferData("MovementSimulationReset", tStorage.m_pPlayer->entindex(), pMap); + CPredictionCopy copy = { PC_NETWORKED_ONLY, tMoveStorage.m_pPlayer, PC_DATA_NORMAL, tMoveStorage.m_pData, PC_DATA_PACKED }; + copy.TransferData("MovementSimulationReset", tMoveStorage.m_pPlayer->entindex(), pMap); - I::MemAlloc->Free(tStorage.m_pData); - tStorage.m_pData = nullptr; + I::MemAlloc->Free(tMoveStorage.m_pData); + tMoveStorage.m_pData = nullptr; } } @@ -130,16 +130,16 @@ void CMovementSimulation::Store() -bool CMovementSimulation::Initialize(CBaseEntity* pEntity, MoveStorage& tStorage, bool bHitchance, bool bStrafe) +bool CMovementSimulation::Initialize(CBaseEntity* pEntity, MoveStorage& tMoveStorage, bool bHitchance, bool bStrafe) { if (!pEntity || !pEntity->IsPlayer() || !pEntity->As()->IsAlive()) { - tStorage.m_bInitFailed = tStorage.m_bFailed = true; + tMoveStorage.m_bInitFailed = tMoveStorage.m_bFailed = true; return false; } auto pPlayer = pEntity->As(); - tStorage.m_pPlayer = pPlayer; + tMoveStorage.m_pPlayer = pPlayer; // store vars m_bOldInPrediction = I::Prediction->m_bInPrediction; @@ -147,7 +147,7 @@ bool CMovementSimulation::Initialize(CBaseEntity* pEntity, MoveStorage& tStorage m_flOldFrametime = I::GlobalVars->frametime; // store restore data - Store(tStorage); + Store(tMoveStorage); // the hacks that make it work I::MoveHelper->SetHost(pPlayer); @@ -174,21 +174,21 @@ bool CMovementSimulation::Initialize(CBaseEntity* pEntity, MoveStorage& tStorage pPlayer->m_hGroundEntity() = nullptr; // fix for velocity.z being set to 0 even if in air } else if (Vars::Misc::Movement::Bunnyhop.Value && G::OriginalCmd.buttons & IN_JUMP) - tStorage.m_bBunnyHop = true; + tMoveStorage.m_bBunnyHop = true; // setup move data - if (!SetupMoveData(tStorage)) + if (!SetupMoveData(tMoveStorage)) { - tStorage.m_bFailed = true; + tMoveStorage.m_bFailed = true; return false; } - const int iStrafeSamples = tStorage.m_bDirectMove + const int iStrafeSamples = tMoveStorage.m_bDirectMove ? Vars::Aimbot::Projectile::GroundSamples.Value : Vars::Aimbot::Projectile::AirSamples.Value; // calculate strafe if desired - bool bCalculated = bStrafe ? StrafePrediction(tStorage, iStrafeSamples) : false; + bool bCalculated = bStrafe ? StrafePrediction(tMoveStorage, iStrafeSamples) : false; // really hope this doesn't work like shit if (bHitchance && bCalculated && !pPlayer->m_vecVelocity().IsZero() && Vars::Aimbot::Projectile::HitChance.Value) @@ -209,13 +209,13 @@ bool CMovementSimulation::Initialize(CBaseEntity* pEntity, MoveStorage& tStorage float flYaw = Math::NormalizeAngle(flYaw1 - flYaw2) / iTicks; flAverageYaw += flYaw; - if (tStorage.m_MoveData.m_flMaxSpeed) - flYaw *= std::clamp(pRecord1.m_vVelocity.Length2D() / tStorage.m_MoveData.m_flMaxSpeed, 0.f, 1.f); + if (tMoveStorage.m_MoveData.m_flMaxSpeed) + flYaw *= std::clamp(pRecord1.m_vVelocity.Length2D() / tMoveStorage.m_MoveData.m_flMaxSpeed, 0.f, 1.f); if ((i + 1) % iStrafeSamples == 0 || i == iSamples - 1) { flAverageYaw /= i % iStrafeSamples + 1; - if (fabsf(tStorage.m_flAverageYaw - flAverageYaw) > 0.5f) + if (fabsf(tMoveStorage.m_flAverageYaw - flAverageYaw) > 0.5f) flCurrentChance -= 1.f / ((iSamples - 1) / float(iStrafeSamples) + 1); flAverageYaw = 0.f; } @@ -225,45 +225,45 @@ bool CMovementSimulation::Initialize(CBaseEntity* pEntity, MoveStorage& tStorage { SDK::Output("MovementSimulation", std::format("Hitchance ({}% < {}%)", flCurrentChance * 100, Vars::Aimbot::Projectile::HitChance.Value).c_str(), { 80, 200, 120 }, Vars::Debug::Logging.Value); - tStorage.m_bFailed = true; + tMoveStorage.m_bFailed = true; return false; } } for (int i = 0; i < H::Entities.GetChoke(pPlayer->entindex()); i++) - RunTick(tStorage); + RunTick(tMoveStorage); return true; } -bool CMovementSimulation::SetupMoveData(MoveStorage& tStorage) +bool CMovementSimulation::SetupMoveData(MoveStorage& tMoveStorage) { - if (!tStorage.m_pPlayer) + if (!tMoveStorage.m_pPlayer) return false; - tStorage.m_MoveData.m_bFirstRunOfFunctions = false; - tStorage.m_MoveData.m_bGameCodeMovedPlayer = false; - tStorage.m_MoveData.m_nPlayerHandle = reinterpret_cast(tStorage.m_pPlayer)->GetRefEHandle(); + tMoveStorage.m_MoveData.m_bFirstRunOfFunctions = false; + tMoveStorage.m_MoveData.m_bGameCodeMovedPlayer = false; + tMoveStorage.m_MoveData.m_nPlayerHandle = reinterpret_cast(tMoveStorage.m_pPlayer)->GetRefEHandle(); - tStorage.m_MoveData.m_vecAbsOrigin = tStorage.m_pPlayer->m_vecOrigin(); - tStorage.m_MoveData.m_vecVelocity = tStorage.m_pPlayer->m_vecVelocity(); - tStorage.m_MoveData.m_flMaxSpeed = SDK::MaxSpeed(tStorage.m_pPlayer); - tStorage.m_MoveData.m_flClientMaxSpeed = tStorage.m_MoveData.m_flMaxSpeed; + tMoveStorage.m_MoveData.m_vecAbsOrigin = tMoveStorage.m_pPlayer->m_vecOrigin(); + tMoveStorage.m_MoveData.m_vecVelocity = tMoveStorage.m_pPlayer->m_vecVelocity(); + tMoveStorage.m_MoveData.m_flMaxSpeed = SDK::MaxSpeed(tMoveStorage.m_pPlayer); + tMoveStorage.m_MoveData.m_flClientMaxSpeed = tMoveStorage.m_MoveData.m_flMaxSpeed; - if (!tStorage.m_MoveData.m_vecVelocity.To2D().IsZero()) + if (!tMoveStorage.m_MoveData.m_vecVelocity.To2D().IsZero()) { - int iIndex = tStorage.m_pPlayer->entindex(); + int iIndex = tMoveStorage.m_pPlayer->entindex(); if (iIndex == I::EngineClient->GetLocalPlayer() && G::CurrentUserCmd) - tStorage.m_MoveData.m_vecViewAngles = G::CurrentUserCmd->viewangles; + tMoveStorage.m_MoveData.m_vecViewAngles = G::CurrentUserCmd->viewangles; else { - if (!tStorage.m_pPlayer->InCond(TF_COND_SHIELD_CHARGE)) - tStorage.m_MoveData.m_vecViewAngles = { 0.f, Math::VectorAngles(tStorage.m_MoveData.m_vecVelocity).y, 0.f }; + if (!tMoveStorage.m_pPlayer->InCond(TF_COND_SHIELD_CHARGE)) + tMoveStorage.m_MoveData.m_vecViewAngles = { 0.f, Math::VectorAngles(tMoveStorage.m_MoveData.m_vecVelocity).y, 0.f }; else - tStorage.m_MoveData.m_vecViewAngles = H::Entities.GetEyeAngles(iIndex); + tMoveStorage.m_MoveData.m_vecViewAngles = H::Entities.GetEyeAngles(iIndex); } - const auto& vRecords = m_mRecords[tStorage.m_pPlayer->entindex()]; + const auto& vRecords = m_mRecords[tMoveStorage.m_pPlayer->entindex()]; if (!vRecords.empty()) { auto& tRecord = vRecords.front(); @@ -272,28 +272,28 @@ bool CMovementSimulation::SetupMoveData(MoveStorage& tStorage) s_tDummyCmd.forwardmove = tRecord.m_vDirection.x; s_tDummyCmd.sidemove = -tRecord.m_vDirection.y; s_tDummyCmd.upmove = tRecord.m_vDirection.z; - SDK::FixMovement(&s_tDummyCmd, {}, tStorage.m_MoveData.m_vecViewAngles); - tStorage.m_MoveData.m_flForwardMove = s_tDummyCmd.forwardmove; - tStorage.m_MoveData.m_flSideMove = s_tDummyCmd.sidemove; - tStorage.m_MoveData.m_flUpMove = s_tDummyCmd.upmove; + SDK::FixMovement(&s_tDummyCmd, {}, tMoveStorage.m_MoveData.m_vecViewAngles); + tMoveStorage.m_MoveData.m_flForwardMove = s_tDummyCmd.forwardmove; + tMoveStorage.m_MoveData.m_flSideMove = s_tDummyCmd.sidemove; + tMoveStorage.m_MoveData.m_flUpMove = s_tDummyCmd.upmove; } } } - tStorage.m_MoveData.m_vecAngles = tStorage.m_MoveData.m_vecOldAngles = tStorage.m_MoveData.m_vecViewAngles; - if (auto pConstraintEntity = tStorage.m_pPlayer->m_hConstraintEntity().Get()) - tStorage.m_MoveData.m_vecConstraintCenter = pConstraintEntity->GetAbsOrigin(); + tMoveStorage.m_MoveData.m_vecAngles = tMoveStorage.m_MoveData.m_vecOldAngles = tMoveStorage.m_MoveData.m_vecViewAngles; + if (auto pConstraintEntity = tMoveStorage.m_pPlayer->m_hConstraintEntity().Get()) + tMoveStorage.m_MoveData.m_vecConstraintCenter = pConstraintEntity->GetAbsOrigin(); else - tStorage.m_MoveData.m_vecConstraintCenter = tStorage.m_pPlayer->m_vecConstraintCenter(); - tStorage.m_MoveData.m_flConstraintRadius = tStorage.m_pPlayer->m_flConstraintRadius(); - tStorage.m_MoveData.m_flConstraintWidth = tStorage.m_pPlayer->m_flConstraintWidth(); - tStorage.m_MoveData.m_flConstraintSpeedFactor = tStorage.m_pPlayer->m_flConstraintSpeedFactor(); + tMoveStorage.m_MoveData.m_vecConstraintCenter = tMoveStorage.m_pPlayer->m_vecConstraintCenter(); + tMoveStorage.m_MoveData.m_flConstraintRadius = tMoveStorage.m_pPlayer->m_flConstraintRadius(); + tMoveStorage.m_MoveData.m_flConstraintWidth = tMoveStorage.m_pPlayer->m_flConstraintWidth(); + tMoveStorage.m_MoveData.m_flConstraintSpeedFactor = tMoveStorage.m_pPlayer->m_flConstraintSpeedFactor(); - tStorage.m_flPredictedDelta = GetPredictedDelta(tStorage.m_pPlayer); - tStorage.m_flSimTime = tStorage.m_pPlayer->m_flSimulationTime(); - tStorage.m_flPredictedSimTime = tStorage.m_flSimTime + tStorage.m_flPredictedDelta; - tStorage.m_vPredictedOrigin = tStorage.m_MoveData.m_vecAbsOrigin; - tStorage.m_bDirectMove = tStorage.m_pPlayer->IsOnGround() || tStorage.m_pPlayer->IsSwimming(); + tMoveStorage.m_flPredictedDelta = GetPredictedDelta(tMoveStorage.m_pPlayer); + tMoveStorage.m_flSimTime = tMoveStorage.m_pPlayer->m_flSimulationTime(); + tMoveStorage.m_flPredictedSimTime = tMoveStorage.m_flSimTime + tMoveStorage.m_flPredictedDelta; + tMoveStorage.m_vPredictedOrigin = tMoveStorage.m_MoveData.m_vecAbsOrigin; + tMoveStorage.m_bDirectMove = tMoveStorage.m_pPlayer->IsOnGround() || tMoveStorage.m_pPlayer->IsSwimming(); return true; } @@ -390,15 +390,15 @@ static inline bool GetYawDifference(MoveData& tRecord1, MoveData& tRecord2, bool } } -void CMovementSimulation::GetAverageYaw(MoveStorage& tStorage, int iSamples) +void CMovementSimulation::GetAverageYaw(MoveStorage& tMoveStorage, int iSamples) { - auto pPlayer = tStorage.m_pPlayer; + auto pPlayer = tMoveStorage.m_pPlayer; auto& vRecords = m_mRecords[pPlayer->entindex()]; if (vRecords.empty()) return; - bool bGround = tStorage.m_bDirectMove; int iMinimumStrafes = 4; - float flMaxSpeed = SDK::MaxSpeed(tStorage.m_pPlayer, false, true); + bool bGround = tMoveStorage.m_bDirectMove; int iMinimumStrafes = 4; + float flMaxSpeed = SDK::MaxSpeed(tMoveStorage.m_pPlayer, false, true); float flLowMinimumDistance = bGround ? Vars::Aimbot::Projectile::GroundLowMinimumDistance.Value : Vars::Aimbot::Projectile::AirLowMinimumDistance.Value; float flLowMinimumSamples = bGround ? Vars::Aimbot::Projectile::GroundLowMinimumSamples.Value : Vars::Aimbot::Projectile::AirLowMinimumSamples.Value; float flHighMinimumDistance = bGround ? Vars::Aimbot::Projectile::GroundHighMinimumDistance.Value : Vars::Aimbot::Projectile::AirHighMinimumDistance.Value; @@ -462,7 +462,7 @@ void CMovementSimulation::GetAverageYaw(MoveStorage& tStorage, int iSamples) { float flDistance = 0.f; if (auto pLocal = H::Entities.GetLocal()) - flDistance = pLocal->m_vecOrigin().DistTo(tStorage.m_pPlayer->m_vecOrigin()); + flDistance = pLocal->m_vecOrigin().DistTo(tMoveStorage.m_pPlayer->m_vecOrigin()); iMinimum = flDistance < flLowMinimumDistance ? flLowMinimumSamples : Math::RemapVal(flDistance, flLowMinimumDistance, flHighMinimumDistance, flLowMinimumSamples + 1, flHighMinimumSamples); } @@ -470,31 +470,31 @@ void CMovementSimulation::GetAverageYaw(MoveStorage& tStorage, int iSamples) if (fabsf(flAverageYaw) < 0.36f) return; - tStorage.m_flAverageYaw = flAverageYaw; + tMoveStorage.m_flAverageYaw = flAverageYaw; SDK::Output("MovementSimulation", std::format("flAverageYaw calculated to {} from {} ({}) {}", flAverageYaw, iTicks, iMinimum, pPlayer->entindex() == I::EngineClient->GetLocalPlayer() ? "(local)" : "").c_str(), { 100, 255, 150 }, Vars::Debug::Logging.Value); } -bool CMovementSimulation::StrafePrediction(MoveStorage& tStorage, int iSamples) +bool CMovementSimulation::StrafePrediction(MoveStorage& tMoveStorage, int iSamples) { - if (tStorage.m_bDirectMove + if (tMoveStorage.m_bDirectMove ? !(Vars::Aimbot::Projectile::StrafePrediction.Value & Vars::Aimbot::Projectile::StrafePredictionEnum::Ground) : !(Vars::Aimbot::Projectile::StrafePrediction.Value & Vars::Aimbot::Projectile::StrafePredictionEnum::Air)) return false; - GetAverageYaw(tStorage, iSamples); + GetAverageYaw(tMoveStorage, iSamples); return true; } -bool CMovementSimulation::SetDuck(MoveStorage& tStorage, bool bDuck) // this only touches origin, bounds +bool CMovementSimulation::SetDuck(MoveStorage& tMoveStorage, bool bDuck) // this only touches origin, bounds { - if (bDuck == tStorage.m_pPlayer->m_bDucked()) + if (bDuck == tMoveStorage.m_pPlayer->m_bDucked()) return true; auto pGameRules = I::TFGameRules(); auto pViewVectors = pGameRules ? pGameRules->GetViewVectors() : nullptr; - float flScale = tStorage.m_pPlayer->m_flModelScale(); + float flScale = tMoveStorage.m_pPlayer->m_flModelScale(); - if (!tStorage.m_pPlayer->IsOnGround()) + if (!tMoveStorage.m_pPlayer->IsOnGround()) { Vec3 vHullMins = (pViewVectors ? pViewVectors->m_vHullMin : Vec3(-24, -24, 0)) * flScale; Vec3 vHullMaxs = (pViewVectors ? pViewVectors->m_vHullMax : Vec3(24, 24, 82)) * flScale; @@ -502,21 +502,21 @@ bool CMovementSimulation::SetDuck(MoveStorage& tStorage, bool bDuck) // this onl Vec3 vDuckHullMaxs = (pViewVectors ? pViewVectors->m_vDuckHullMax : Vec3(24, 24, 62)) * flScale; if (bDuck) - tStorage.m_MoveData.m_vecAbsOrigin += (vHullMaxs - vHullMins) - (vDuckHullMaxs - vDuckHullMins); + tMoveStorage.m_MoveData.m_vecAbsOrigin += (vHullMaxs - vHullMins) - (vDuckHullMaxs - vDuckHullMins); else { - Vec3 vOrigin = tStorage.m_MoveData.m_vecAbsOrigin - ((vHullMaxs - vHullMins) - (vDuckHullMaxs - vDuckHullMins)); + Vec3 vOrigin = tMoveStorage.m_MoveData.m_vecAbsOrigin - ((vHullMaxs - vHullMins) - (vDuckHullMaxs - vDuckHullMins)); CGameTrace trace = {}; CTraceFilterWorldAndPropsOnly filter = {}; - SDK::TraceHull(vOrigin, vOrigin, vHullMins, vHullMaxs, tStorage.m_pPlayer->SolidMask(), &filter, &trace); + SDK::TraceHull(vOrigin, vOrigin, vHullMins, vHullMaxs, tMoveStorage.m_pPlayer->SolidMask(), &filter, &trace); if (trace.DidHit()) return false; - tStorage.m_MoveData.m_vecAbsOrigin = vOrigin; + tMoveStorage.m_MoveData.m_vecAbsOrigin = vOrigin; } } - tStorage.m_pPlayer->m_bDucked() = bDuck; + tMoveStorage.m_pPlayer->m_bDucked() = bDuck; return true; } @@ -556,90 +556,90 @@ void CMovementSimulation::RestoreBounds(CTFPlayer* pPlayer) } } -void CMovementSimulation::RunTick(MoveStorage& tStorage, bool bPath, std::function* pCallback) +void CMovementSimulation::RunTick(MoveStorage& tMoveStorage, bool bPath, std::function* pCallback) { - if (tStorage.m_bFailed || !tStorage.m_pPlayer || !tStorage.m_pPlayer->IsPlayer()) + if (tMoveStorage.m_bFailed || !tMoveStorage.m_pPlayer || !tMoveStorage.m_pPlayer->IsPlayer()) return; if (bPath) - tStorage.m_vPath.push_back(tStorage.m_MoveData.m_vecAbsOrigin); + tMoveStorage.m_vPath.push_back(tMoveStorage.m_MoveData.m_vecAbsOrigin); // make sure frametime and prediction vars are right I::Prediction->m_bInPrediction = true; I::Prediction->m_bFirstTimePredicted = false; I::GlobalVars->frametime = I::Prediction->m_bEnginePaused ? 0.f : TICK_INTERVAL; - SetBounds(tStorage.m_pPlayer); + SetBounds(tMoveStorage.m_pPlayer); float flCorrection = 0.f; - if (tStorage.m_flAverageYaw) + if (tMoveStorage.m_flAverageYaw) { float flMult = 1.f; - if (!tStorage.m_bDirectMove && !tStorage.m_pPlayer->InCond(TF_COND_SHIELD_CHARGE)) + if (!tMoveStorage.m_bDirectMove && !tMoveStorage.m_pPlayer->InCond(TF_COND_SHIELD_CHARGE)) { - flCorrection = 90.f * sign(tStorage.m_flAverageYaw); + flCorrection = 90.f * sign(tMoveStorage.m_flAverageYaw); if (Vars::Aimbot::Projectile::MovesimFrictionFlags.Value & Vars::Aimbot::Projectile::MovesimFrictionFlagsEnum::RunReduce) - flMult = GetFrictionScale(tStorage.m_MoveData.m_vecVelocity.Length2D(), tStorage.m_flAverageYaw, tStorage.m_MoveData.m_vecVelocity.z + GetGravity() * TICK_INTERVAL); + flMult = GetFrictionScale(tMoveStorage.m_MoveData.m_vecVelocity.Length2D(), tMoveStorage.m_flAverageYaw, tMoveStorage.m_MoveData.m_vecVelocity.z + GetGravity() * TICK_INTERVAL); } - tStorage.m_MoveData.m_vecViewAngles.y += tStorage.m_flAverageYaw * flMult + flCorrection; + tMoveStorage.m_MoveData.m_vecViewAngles.y += tMoveStorage.m_flAverageYaw * flMult + flCorrection; } - else if (!tStorage.m_bDirectMove) - tStorage.m_MoveData.m_flForwardMove = tStorage.m_MoveData.m_flSideMove = 0.f; + else if (!tMoveStorage.m_bDirectMove) + tMoveStorage.m_MoveData.m_flForwardMove = tMoveStorage.m_MoveData.m_flSideMove = 0.f; - float flOldSpeed = tStorage.m_MoveData.m_flClientMaxSpeed; - if (tStorage.m_pPlayer->m_bDucked() && tStorage.m_pPlayer->IsOnGround() && !tStorage.m_pPlayer->IsSwimming()) - tStorage.m_MoveData.m_flClientMaxSpeed /= 3; + float flOldSpeed = tMoveStorage.m_MoveData.m_flClientMaxSpeed; + if (tMoveStorage.m_pPlayer->m_bDucked() && tMoveStorage.m_pPlayer->IsOnGround() && !tMoveStorage.m_pPlayer->IsSwimming()) + tMoveStorage.m_MoveData.m_flClientMaxSpeed /= 3; - if (tStorage.m_bBunnyHop && tStorage.m_pPlayer->IsOnGround() && !tStorage.m_pPlayer->m_bDucked()) + if (tMoveStorage.m_bBunnyHop && tMoveStorage.m_pPlayer->IsOnGround() && !tMoveStorage.m_pPlayer->m_bDucked()) { - tStorage.m_MoveData.m_nOldButtons = 0; - tStorage.m_MoveData.m_nButtons |= IN_JUMP; + tMoveStorage.m_MoveData.m_nOldButtons = 0; + tMoveStorage.m_MoveData.m_nButtons |= IN_JUMP; } - I::GameMovement->ProcessMovement(tStorage.m_pPlayer, &tStorage.m_MoveData); + I::GameMovement->ProcessMovement(tMoveStorage.m_pPlayer, &tMoveStorage.m_MoveData); if (pCallback) - (*pCallback)(tStorage.m_MoveData); + (*pCallback)(tMoveStorage.m_MoveData); - tStorage.m_MoveData.m_flClientMaxSpeed = flOldSpeed; + tMoveStorage.m_MoveData.m_flClientMaxSpeed = flOldSpeed; - tStorage.m_flSimTime += TICK_INTERVAL; - tStorage.m_bPredictNetworked = tStorage.m_flSimTime >= tStorage.m_flPredictedSimTime; - if (tStorage.m_bPredictNetworked) + tMoveStorage.m_flSimTime += TICK_INTERVAL; + tMoveStorage.m_bPredictNetworked = tMoveStorage.m_flSimTime >= tMoveStorage.m_flPredictedSimTime; + if (tMoveStorage.m_bPredictNetworked) { - tStorage.m_vPredictedOrigin = tStorage.m_MoveData.m_vecAbsOrigin; - tStorage.m_flPredictedSimTime += tStorage.m_flPredictedDelta; + tMoveStorage.m_vPredictedOrigin = tMoveStorage.m_MoveData.m_vecAbsOrigin; + tMoveStorage.m_flPredictedSimTime += tMoveStorage.m_flPredictedDelta; } - bool bLastbDirectMove = tStorage.m_bDirectMove; - tStorage.m_bDirectMove = tStorage.m_pPlayer->IsOnGround() || tStorage.m_pPlayer->IsSwimming(); + bool bLastbDirectMove = tMoveStorage.m_bDirectMove; + tMoveStorage.m_bDirectMove = tMoveStorage.m_pPlayer->IsOnGround() || tMoveStorage.m_pPlayer->IsSwimming(); - if (tStorage.m_flAverageYaw) - tStorage.m_MoveData.m_vecViewAngles.y -= flCorrection; - else if (tStorage.m_bDirectMove && !bLastbDirectMove - && !tStorage.m_MoveData.m_flForwardMove && !tStorage.m_MoveData.m_flSideMove - && tStorage.m_MoveData.m_vecVelocity.Length2D() > tStorage.m_MoveData.m_flMaxSpeed * 0.015f) + if (tMoveStorage.m_flAverageYaw) + tMoveStorage.m_MoveData.m_vecViewAngles.y -= flCorrection; + else if (tMoveStorage.m_bDirectMove && !bLastbDirectMove + && !tMoveStorage.m_MoveData.m_flForwardMove && !tMoveStorage.m_MoveData.m_flSideMove + && tMoveStorage.m_MoveData.m_vecVelocity.Length2D() > tMoveStorage.m_MoveData.m_flMaxSpeed * 0.015f) { - Vec3 vDirection = tStorage.m_MoveData.m_vecVelocity.Normalized2D() * 450.f; + Vec3 vDirection = tMoveStorage.m_MoveData.m_vecVelocity.Normalized2D() * 450.f; s_tDummyCmd.forwardmove = vDirection.x, s_tDummyCmd.sidemove = -vDirection.y; - SDK::FixMovement(&s_tDummyCmd, {}, tStorage.m_MoveData.m_vecViewAngles); - tStorage.m_MoveData.m_flForwardMove = s_tDummyCmd.forwardmove, tStorage.m_MoveData.m_flSideMove = s_tDummyCmd.sidemove; + SDK::FixMovement(&s_tDummyCmd, {}, tMoveStorage.m_MoveData.m_vecViewAngles); + tMoveStorage.m_MoveData.m_flForwardMove = s_tDummyCmd.forwardmove, tMoveStorage.m_MoveData.m_flSideMove = s_tDummyCmd.sidemove; } - RestoreBounds(tStorage.m_pPlayer); + RestoreBounds(tMoveStorage.m_pPlayer); } -void CMovementSimulation::RunTick(MoveStorage& tStorage, bool bPath, std::function fCallback) +void CMovementSimulation::RunTick(MoveStorage& tMoveStorage, bool bPath, std::function fCallback) { - RunTick(tStorage, bPath, &fCallback); + RunTick(tMoveStorage, bPath, &fCallback); } -void CMovementSimulation::Restore(MoveStorage& tStorage) +void CMovementSimulation::Restore(MoveStorage& tMoveStorage) { - if (tStorage.m_bInitFailed || !tStorage.m_pPlayer) + if (tMoveStorage.m_bInitFailed || !tMoveStorage.m_pPlayer) return; I::MoveHelper->SetHost(nullptr); - tStorage.m_pPlayer->m_pCurrentCommand() = nullptr; + tMoveStorage.m_pPlayer->m_pCurrentCommand() = nullptr; - Reset(tStorage); + Reset(tMoveStorage); I::Prediction->m_bInPrediction = m_bOldInPrediction; I::Prediction->m_bFirstTimePredicted = m_bOldFirstTimePredicted; diff --git a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h index 68d8f13c..8848a078 100644 --- a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h +++ b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h @@ -37,12 +37,12 @@ struct MoveData class CMovementSimulation { private: - void Store(MoveStorage& tStorage); - void Reset(MoveStorage& tStorage); + void Store(MoveStorage& tMoveStorage); + void Reset(MoveStorage& tMoveStorage); - bool SetupMoveData(MoveStorage& tStorage); - void GetAverageYaw(MoveStorage& tStorage, int iSamples); - bool StrafePrediction(MoveStorage& tStorage, int iSamples); + bool SetupMoveData(MoveStorage& tMoveStorage); + void GetAverageYaw(MoveStorage& tMoveStorage, int iSamples); + bool StrafePrediction(MoveStorage& tMoveStorage, int iSamples); void SetBounds(CTFPlayer* pPlayer); void RestoreBounds(CTFPlayer* pPlayer); @@ -57,11 +57,11 @@ private: public: void Store(); - bool Initialize(CBaseEntity* pEntity, MoveStorage& tStorage, bool bHitchance = true, bool bStrafe = true); - bool SetDuck(MoveStorage& tStorage, bool bDuck); - void RunTick(MoveStorage& tStorage, bool bPath = true, std::function* pCallback = nullptr); - void RunTick(MoveStorage& tStorage, bool bPath, std::function fCallback); - void Restore(MoveStorage& tStorage); + bool Initialize(CBaseEntity* pEntity, MoveStorage& tMoveStorage, bool bHitchance = true, bool bStrafe = true); + bool SetDuck(MoveStorage& tMoveStorage, bool bDuck); + void RunTick(MoveStorage& tMoveStorage, bool bPath = true, std::function* pCallback = nullptr); + void RunTick(MoveStorage& tMoveStorage, bool bPath, std::function fCallback); + void Restore(MoveStorage& tMoveStorage); float GetPredictedDelta(CBaseEntity* pEntity); }; diff --git a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp index 0fbac06a..4632b8ac 100644 --- a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp +++ b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp @@ -14,7 +14,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap bool bDucking = pPlayer->m_fFlags() & FL_DUCKING; bool bTrace = iFlags & ProjSimEnum::Trace; - bool bQuick = iFlags & ProjSimEnum::Quick; + bool bInterp = iFlags & ProjSimEnum::Interp; bool bMaxSpeed = iFlags & ProjSimEnum::MaxSpeed; bool bPredictCmdNum = iFlags & ProjSimEnum::PredictCmdNum; bool bNoRandomAngles = iFlags & ProjSimEnum::NoRandomAngles; @@ -23,13 +23,13 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap if (Vars::Visuals::Trajectory::Override.Value) { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { Vars::Visuals::Trajectory::OffsetX.Value, Vars::Visuals::Trajectory::OffsetY.Value, Vars::Visuals::Trajectory::OffsetZ.Value }, vPos, vAngle, !bTrace ? true : Vars::Visuals::Trajectory::Pipes.Value, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { Vars::Visuals::Trajectory::OffsetX.Value, Vars::Visuals::Trajectory::OffsetY.Value, Vars::Visuals::Trajectory::OffsetZ.Value }, vPos, vAngle, !bTrace ? true : Vars::Visuals::Trajectory::Pipes.Value, bInterp); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("custom"), vPos, vAngle, { Vars::Visuals::Trajectory::Hull.Value, Vars::Visuals::Trajectory::Hull.Value, Vars::Visuals::Trajectory::Hull.Value }, Vars::Visuals::Trajectory::Speed.Value, Vars::Visuals::Trajectory::Gravity.Value, Vars::Visuals::Trajectory::LifeTime.Value }; return true; } - if (!bQuick && G::CurrentUserCmd) + if (!bInterp && G::CurrentUserCmd) { switch (pWeapon->GetWeaponID()) { @@ -77,7 +77,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap case TF_WEAPON_ROCKETLAUNCHER: case TF_WEAPON_ROCKETLAUNCHER_DIRECTHIT: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, int(SDK::AttribHookValue(0, "centerfire_projectile", pWeapon)) == 1 ? 0.f : 12.f, bDucking ? 8.f : -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, int(SDK::AttribHookValue(0, "centerfire_projectile", pWeapon)) == 1 ? 0.f : 12.f, bDucking ? 8.f : -3.f }, vPos, vAngle, !bTrace ? true : false, bInterp); float flSpeed = pPlayer->InCond(TF_COND_RUNE_PRECISION) ? 3000.f : SDK::AttribHookValue(1100.f, "mult_projectile_speed", pWeapon); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("models/weapons/w_models/w_rocket.mdl"), vPos, vAngle, { 0.f, 0.f, 0.f }, flSpeed, 0.f }; @@ -89,7 +89,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap { bool bCowMangler = pWeapon->GetWeaponID() == TF_WEAPON_PARTICLE_CANNON; - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 8.f, bDucking ? 8.f : -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 8.f, bDucking ? 8.f : -3.f }, vPos, vAngle, !bTrace ? true : false, bInterp); if (pWeapon->GetWeaponID() == TF_WEAPON_DRG_POMSON) vPos.z -= 13.f; @@ -103,7 +103,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap bool bCannon = pWeapon->GetWeaponID() == TF_WEAPON_CANNON; float flMortar = bCannon ? SDK::AttribHookValue(0.f, "grenade_launcher_mortar_mode", pWeapon) : 0.f; - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bInterp); float flSpeed = SDK::AttribHookValue(pPlayer->InCond(TF_COND_RUNE_PRECISION) ? 3000.f : SDK::AttribHookValue(1200.f, "mult_projectile_speed", pWeapon), "mult_projectile_range", pWeapon); float flLifetime = flMortar @@ -115,7 +115,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap } case TF_WEAPON_PIPEBOMBLAUNCHER: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bInterp); float flCharge = flAutoCharge > 0.f && SDK::AttribHookValue(1, "mult_dmg", pWeapon) ? SDK::AttribHookValue(4.f, "stickybomb_charge_rate", pWeapon) * flAutoCharge @@ -126,33 +126,33 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap } case TF_WEAPON_FLAREGUN: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 12.f, bDucking ? 8.f : -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 12.f, bDucking ? 8.f : -3.f }, vPos, vAngle, !bTrace ? true : false, bInterp); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("models/weapons/w_models/w_flaregun_shell.mdl"), vPos, vAngle, { 0.f, 0.f, 0.f }, SDK::AttribHookValue(2000.f, "mult_projectile_speed", pWeapon), 0.3f * flGravity }; return true; } case TF_WEAPON_FLAREGUN_REVENGE: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 12.f, bDucking ? 8.f : -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 12.f, bDucking ? 8.f : -3.f }, vPos, vAngle, !bTrace ? true : false, bInterp); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("models/weapons/w_models/w_flaregun_shell.mdl"), vPos, vAngle, { 0.f, 0.f, 0.f }, 3000.f, 0.45f * flGravity }; return true; } case TF_WEAPON_COMPOUND_BOW: { - if (!bQuick && G::CurrentUserCmd && - I::GlobalVars->curtime - pWeapon->As()->m_flChargeBeginTime() >= TF_ARROW_MAX_CHARGE_TIME) + if (!bInterp && G::CurrentUserCmd && pWeapon->As()->m_flChargeBeginTime() > 0.f + && I::GlobalVars->curtime - pWeapon->As()->m_flChargeBeginTime() >= TF_ARROW_MAX_CHARGE_TIME) { float flAddX = float(SDK::RandomInt()) / VALVE_RAND_MAX * 12.f - 6.f; float flAddY = float(SDK::RandomInt()) / VALVE_RAND_MAX * 12.f - 6.f; if (bNoRandomAngles) vAngles -= { flAddX, flAddY }; - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bInterp); vAngle += { flAddX, flAddY }; } else - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bInterp); float flCharge = pWeapon->As()->m_flChargeBeginTime() > 0.f ? I::GlobalVars->curtime - pWeapon->As()->m_flChargeBeginTime() : 0.f; float flSpeed = bMaxSpeed ? 2600.f : Math::RemapVal(flCharge, 0.f, 1.f, 1800.f, 2600.f); @@ -165,7 +165,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap { bool bCrossbow = pWeapon->GetWeaponID() == TF_WEAPON_CROSSBOW; - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bInterp); auto uType = bCrossbow ? FNV1A::Hash32Const("models/weapons/w_models/w_syringe_proj.mdl") : FNV1A::Hash32Const("models/weapons/w_models/w_repair_claw.mdl"); tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, pWeapon->GetWeaponID() == TF_WEAPON_CROSSBOW ? Vec3(3.f, 3.f, 3.f) : Vec3(1.f, 1.f, 1.f), 2400.f, 0.2f * flGravity, 10.f /*arrows have some lifetime check for whatever reason*/ }; @@ -173,7 +173,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap } case TF_WEAPON_SYRINGEGUN_MEDIC: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 6.f, -8.f }, vPos, vAngle, !bTrace ? true : false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 6.f, -8.f }, vPos, vAngle, !bTrace ? true : false, bInterp); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("models/weapons/w_models/w_syringe_proj.mdl"), vPos, vAngle, { 1.f, 1.f, 1.f }, 1000.f, 0.3f * flGravity }; return true; @@ -183,21 +183,21 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap static auto tf_flamethrower_boxsize = H::ConVars.FindVar("tf_flamethrower_boxsize"); const float flHull = tf_flamethrower_boxsize->GetFloat(); - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 40.f, 5.f, 0.f }, vPos, vAngle, true, bQuick, false); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 40.f, 5.f, 0.f }, vPos, vAngle, true, bInterp, false); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("particles/flamethrower.pcf"), vPos, vAngle, { flHull, flHull, flHull }, 1000.f, 0.f, 0.285f }; return true; } case TF_WEAPON_FLAME_BALL: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 3.f, 7.f, -9.f }, vPos, vAngle, true, bQuick, false); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 3.f, 7.f, -9.f }, vPos, vAngle, true, bInterp, false); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("models/weapons/c_models/c_flameball/c_flameball.mdl"), vPos, vAngle, { 1.f, 1.f, 1.f /*damaging hull much bigger, shouldn't matter here*/ }, 3000.f, 0.f, 0.18f }; return true; } case TF_WEAPON_CLEAVER: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bInterp); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("models/workshop_partner/weapons/c_models/c_sd_cleaver/c_sd_cleaver.mdl"), vPos, vAngle, { 1.f, 1.f, 10.f /*weird, probably still inaccurate*/ }, 3000.f, 1.f, 2.2f }; return true; @@ -208,10 +208,10 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap static auto tf_scout_stunball_base_speed = H::ConVars.FindVar("tf_scout_stunball_base_speed"); const bool bWrapAssassin = pWeapon->GetWeaponID() == TF_WEAPON_BAT_GIFTWRAP; - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 0.f, 0.f, 0.f }, vPos, vAngle, true, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 0.f, 0.f, 0.f }, vPos, vAngle, true, bInterp); Vec3 vForward; Math::AngleVectors(vAngle, &vForward); - vPos = (bQuick ? pPlayer->GetAbsOrigin() : pPlayer->m_vecOrigin()) + (Vec3(0, 0, 50) + vForward * 32.f) * pPlayer->m_flModelScale(); // why? + vPos = (bInterp ? pPlayer->GetAbsOrigin() : pPlayer->m_vecOrigin()) + (Vec3(0, 0, 50) + vForward * 32.f) * pPlayer->m_flModelScale(); // why? auto uHash = bWrapAssassin ? FNV1A::Hash32Const("models/weapons/c_models/c_xms_festive_ornament.mdl") : FNV1A::Hash32Const("models/weapons/w_models/w_baseball.mdl"); tProjInfo = { pPlayer, pWeapon, uHash, vPos, vAngle, { 3.f, 3.f, 3.f }, tf_scout_stunball_base_speed->GetFloat(), 1.f, bWrapAssassin ? 2.3f : 100.f }; return true; @@ -219,7 +219,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap case TF_WEAPON_JAR: case TF_WEAPON_JAR_MILK: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bInterp); uint32_t uType = uType = FNV1A::Hash32Const("models/weapons/c_models/urinejar.mdl"); switch (pWeapon->m_iItemDefinitionIndex()) @@ -233,7 +233,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap } case TF_WEAPON_JAR_GAS: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bInterp); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("models/weapons/c_models/c_gascan/c_gascan.mdl"), vPos, vAngle, { 3.f, 3.f, 3.f }, 2000.f, 1.f, 2.2f }; return true; @@ -243,7 +243,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap static auto tf_grapplinghook_projectile_speed = H::ConVars.FindVar("tf_grapplinghook_projectile_speed"); static auto tf_grapplinghook_max_distance = H::ConVars.FindVar("tf_grapplinghook_max_distance"); - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, -8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, -8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bInterp); float flSpeed = tf_grapplinghook_projectile_speed->GetFloat(); if (pPlayer->InCond(TF_COND_RUNE_AGILITY)) @@ -270,7 +270,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap case Heavy_s_TheDalokohsBar: case Heavy_s_SecondBanana: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 0.f, 0.f, -8.f }, vPos, vAngle, true, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 0.f, 0.f, -8.f }, vPos, vAngle, true, bInterp); tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("models/weapons/c_models/c_sandwich/c_sandwich.mdl"), vPos, vAngle, { 17.f, 17.f, 7.f }, 500.f, 1.f * flGravity }; return true; @@ -286,7 +286,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap bool CProjectileSimulation::GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& tProjInfo, int iFlags, float flAutoCharge) { bool bInitCheck = iFlags & ProjSimEnum::InitCheck; - bool bQuick = iFlags & ProjSimEnum::Quick; + bool bInterp = iFlags & ProjSimEnum::Interp; const float flOldCurrentTime = I::GlobalVars->curtime; I::GlobalVars->curtime = TICKS_TO_TIME(pPlayer->m_nTickBase()); @@ -301,7 +301,7 @@ bool CProjectileSimulation::GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, CTraceFilterWorldAndPropsOnly filter = {}; filter.pSkip = pPlayer; - Vec3 vStart = bQuick ? pPlayer->GetEyePosition() : pPlayer->GetShootPos(); + Vec3 vStart = bInterp ? pPlayer->GetEyePosition() : pPlayer->GetShootPos(); Vec3 vEnd = tProjInfo.m_vPos; SDK::TraceHull(vStart, vEnd, tProjInfo.m_vHull * -1.f, tProjInfo.m_vHull, MASK_SOLID, &filter, &trace); @@ -456,7 +456,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate case FNV1A::Hash32Const("models/weapons/w_models/w_stickybomb2.mdl"): case FNV1A::Hash32Const("models/weapons/w_models/w_cannonball.mdl"): vVelocity += vUp * 200.f; - if (!(tProjInfo.m_iFlags & ProjSimEnum::Quick) && G::CurrentUserCmd) + if (!(tProjInfo.m_iFlags & ProjSimEnum::Interp) && G::CurrentUserCmd) { Vec3 vNewVelocity = vVelocity + vUp * SDK::RandomFloat(-10.f, 10.f) + vRight * SDK::RandomFloat(-10.f, 10.f); if (!(tProjInfo.m_iFlags & ProjSimEnum::NoRandomAngles)) @@ -630,7 +630,7 @@ float CProjectileSimulation::GetDesync() return I::GlobalVars->curtime - TICKS_TO_TIME(I::ClientState->m_ClockDriftMgr.m_nServerTick) - F::Backtrack.GetReal(); } -void CProjectileSimulation::SetupTrace(CTraceFilterCollideable& filter, int& nMask, CTFWeaponBase* pWeapon, int nTick, bool bQuick) +void CProjectileSimulation::SetupTrace(CTraceFilterCollideable& filter, int& nMask, CTFWeaponBase* pWeapon, int nTick, bool bInterp) { switch (nTick) { @@ -647,12 +647,12 @@ void CProjectileSimulation::SetupTrace(CTraceFilterCollideable& filter, int& nMa case TF_WEAPON_DRG_POMSON: case TF_WEAPON_SYRINGEGUN_MEDIC: case TF_WEAPON_BAT_GIFTWRAP: - if (bQuick) + if (bInterp) filter.iPlayer = PLAYER_ALL; } break; case 16: - if (bQuick) + if (bInterp) { switch (pWeapon->GetWeaponID()) { diff --git a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h index a0ddc65c..75f556aa 100644 --- a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h +++ b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h @@ -5,7 +5,7 @@ Enum(ProjSim, None = 0, Trace = 1 << 0, // trace when doing GetProjectileFireSetup InitCheck = 1 << 1, // validate starting position - Quick = 1 << 2, // use interpolation + Interp = 1 << 2, // use interpolation NoRandomAngles = 1 << 3, // don't do angle stuff for aimbot, nospread will pick that up PredictCmdNum = 1 << 4, // use crithack to predict command number MaxSpeed = 1 << 5 // default projectile speeds to their maximum @@ -53,7 +53,7 @@ private: public: bool GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& tProjInfo, int iFlags = ProjSimEnum::Trace | ProjSimEnum::InitCheck, float flAutoCharge = -1.f); - void SetupTrace(CTraceFilterCollideable& filter, int& nMask, CTFWeaponBase* pWeapon, int nTick = 0, bool bQuick = false); + void SetupTrace(CTraceFilterCollideable& filter, int& nMask, CTFWeaponBase* pWeapon, int nTick = 0, bool bInterp = false); void GetInfo(CBaseEntity* pProjectile, ProjectileInfo& tProjInfo); void SetupTrace(CTraceFilterCollideable& filter, int& nMask, CBaseEntity* pProjectile); diff --git a/Amalgam/src/SDK/Definitions/Types.h b/Amalgam/src/SDK/Definitions/Types.h index bda8416b..0164b129 100644 --- a/Amalgam/src/SDK/Definitions/Types.h +++ b/Amalgam/src/SDK/Definitions/Types.h @@ -275,6 +275,11 @@ public: return x * v.x + y * v.y; } + inline float DotNormalized(const Vec2& v) const + { + return (x * v.x + y * v.y) / (Length() * v.Length()); + } + inline bool IsZero(float flEpsilon = 0.001f) const { return fabsf(x) < flEpsilon && @@ -617,6 +622,11 @@ public: return x * v.x + y * v.y + z * v.z; } + inline float DotNormalized(const Vec3& v) const + { + return (x * v.x + y * v.y + z * v.z) / (Length() * v.Length()); + } + inline Vec3 Cross(const Vec3& v) const { return Vec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); diff --git a/Amalgam/src/SDK/Vars.h b/Amalgam/src/SDK/Vars.h index 3b2c42c3..fe4c361b 100644 --- a/Amalgam/src/SDK/Vars.h +++ b/Amalgam/src/SDK/Vars.h @@ -325,8 +325,8 @@ namespace Vars VA_LIST("Auto", "##Divider", "Head", "Body", "Feet", "##Divider", "Bodyaim if lethal", "Prioritize feet"), Auto = 1 << 0, Head = 1 << 1, Body = 1 << 2, Feet = 1 << 3, BodyaimIfLethal = 1 << 4, PrioritizeFeet = 1 << 5); CVarEnum(Modifiers, VA_LIST("Modifiers", "Projectile modifiers"), 0b1010, DROPDOWN_MULTI, nullptr, - VA_LIST("Charge weapon", "Cancel charge", "Use prime time"), - ChargeWeapon = 1 << 0, CancelCharge = 1 << 1, UsePrimeTime = 1 << 2); + VA_LIST("Charge weapon", "Cancel charge", "Use arm time"), + ChargeWeapon = 1 << 0, CancelCharge = 1 << 1, UseArmTime = 1 << 2); CVar(MaxSimulationTime, "Max simulation time", 2.f, SLIDER_MIN | SLIDER_PRECISION, 0.1f, 2.5f, 0.25f, "%gs"); CVar(HitChance, "Hit chance", 0.f, SLIDER_CLAMP | SLIDER_PRECISION, 0.f, 100.f, 10.f, "%g%%"); CVar(AutodetRadius, "Autodet radius", 90.f, SLIDER_CLAMP | SLIDER_PRECISION, 0.f, 100.f, 10.f, "%g%%"); @@ -361,6 +361,7 @@ namespace Vars CVar(HuntsmanAddLow, "Huntsman add low", 0.f, NOSAVE | DEBUGVAR | SLIDER_CLAMP | SLIDER_PRECISION, 0.f, 20.f); CVar(HuntsmanClamp, "Huntsman clamp", 5.f, NOSAVE | DEBUGVAR | SLIDER_CLAMP | SLIDER_PRECISION, 0.f, 10.f, 0.5f); CVar(HuntsmanPullPoint, "Huntsman pull point", false, NOSAVE | DEBUGVAR); + CVar(HuntsmanPullNoZ, "Pull no Z", false, NOSAVE | DEBUGVAR); CVar(SplashPointsDirect, "Splash points direct", 100, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 0, 400, 5); CVar(SplashPointsArc, "Splash points arc", 100, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 0, 400, 5); @@ -377,6 +378,7 @@ namespace Vars VA_LIST("Regular", "Special light", "Special heavy"), Regular, SpecialLight, SpecialHeavy); CVar(SplashGrates, "Splash grates", true, NOSAVE | DEBUGVAR); + CVar(Out2NormalCheck, "Out2 normal check", 0.7f, NOSAVE | DEBUGVAR | SLIDER_CLAMP | SLIDER_PRECISION, -1.f, 1.f, 0.1f); CVar(DeltaCount, "Delta count", 5, NOSAVE | DEBUGVAR, 1, 5); CVarEnum(DeltaMode, "Delta mode", 0, NOSAVE | DEBUGVAR, nullptr,