diff --git a/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.cpp b/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.cpp index 58e567bd..43d7b15b 100644 --- a/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.cpp @@ -184,8 +184,15 @@ bool CAimbotGlobal::ShouldIgnore(CBaseEntity* pEntity, CTFPlayer* pLocal, CTFWea return false; auto pOwner = pBuilding->m_hBuilder().Get(); - if (pOwner && F::PlayerUtils.IsIgnored(pOwner->entindex())) - return true; + if (pOwner) + { + if (F::PlayerUtils.IsIgnored(pOwner->entindex())) + return true; + + if (Vars::Aimbot::General::Ignore.Value & Vars::Aimbot::General::IgnoreEnum::Friends && H::Entities.IsFriend(pOwner->entindex()) + || Vars::Aimbot::General::Ignore.Value & Vars::Aimbot::General::IgnoreEnum::Party && H::Entities.InParty(pOwner->entindex())) + return true; + } return false; } @@ -193,6 +200,9 @@ bool CAimbotGlobal::ShouldIgnore(CBaseEntity* pEntity, CTFPlayer* pLocal, CTFWea { auto pProjectile = pEntity->As(); + if (!(Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::Stickies)) + return true; + if (pLocal->m_iTeamNum() == pEntity->m_iTeamNum()) return true; @@ -210,6 +220,9 @@ bool CAimbotGlobal::ShouldIgnore(CBaseEntity* pEntity, CTFPlayer* pLocal, CTFWea case ETFClassID::CMerasmus: case ETFClassID::CTFBaseBoss: { + if (!(Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::NPCs)) + return true; + if (pEntity->m_iTeamNum() != 5) return true; @@ -218,11 +231,22 @@ bool CAimbotGlobal::ShouldIgnore(CBaseEntity* pEntity, CTFPlayer* pLocal, CTFWea case ETFClassID::CTFTankBoss: case ETFClassID::CZombie: { + if (!(Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::NPCs)) + return true; + if (pLocal->m_iTeamNum() == pEntity->m_iTeamNum()) return true; return false; } + case ETFClassID::CTFPumpkinBomb: + case ETFClassID::CTFGenericBomb: + { + if (!(Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::Bombs)) + return true; + + return false; + } } return true; diff --git a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp index 39fe49c8..7acaa6fd 100644 --- a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp @@ -184,7 +184,7 @@ int CAimbotHitscan::GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponB } } - if (Vars::Aimbot::Hitscan::Modifiers.Value & Vars::Aimbot::Hitscan::ModifiersEnum::BodyaimIfLethal && bHeadshot) + if (Vars::Aimbot::Hitscan::Hitboxes.Value & Vars::Aimbot::Hitscan::HitboxesEnum::BodyaimIfLethal && bHeadshot) { auto pPlayer = pTarget->As(); @@ -331,12 +331,16 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p std::rotate(vRecords.begin(), pivot, pivot + 1); } - auto RayToOBB = [](const Vec3& origin, const Vec3& direction, const Vec3& min, const Vec3& max, const matrix3x4& matrix) -> bool + auto RayToOBB = [&](const Vec3& vOrigin, const Vec3& vDirection, const Vec3& vMins, const Vec3& vMaxs, const matrix3x4& mMatrix, float flScale = 1.f) -> bool { - if (Vars::Aimbot::General::AimType.Value != Vars::Aimbot::General::AimTypeEnum::Smooth) - return true; + switch (Vars::Aimbot::General::AimType.Value) + { + case Vars::Aimbot::General::AimTypeEnum::Smooth: + case Vars::Aimbot::General::AimTypeEnum::Assistive: + return Math::RayToOBB(vOrigin, vDirection, vMins, vMaxs, mMatrix, flScale); + } - return Math::RayToOBB(origin, direction, min, max, matrix); + return true; }; int iReturn = false; @@ -369,7 +373,9 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p for (auto& [pBox, iHitbox, _] : vHitboxes) { - float flModelScale = powf(target.m_pEntity->As()->m_flModelScale(), 2); + float flModelScale = target.m_pEntity->As()->m_flModelScale(); + float flBoneScale = std::max(Vars::Aimbot::Hitscan::BoneSizeMinimumScale.Value, Vars::Aimbot::Hitscan::PointScale.Value / 100.f); + float flBoneSubtract = Vars::Aimbot::Hitscan::BoneSizeSubtract.Value; Vec3 vAngle; Math::MatrixAngles(aBones[pBox->bone], vAngle); Vec3 vMins = pBox->bbmin; @@ -386,7 +392,9 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p std::vector vPoints = { Vec3() }; if (Vars::Aimbot::Hitscan::PointScale.Value > 0.f) { - bool bTriggerbot = Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth && Vars::Aimbot::General::Smoothing.Value == 100.f; + bool bTriggerbot = (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth + || Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Assistive) + && !Vars::Aimbot::General::AssistStrength.Value; if (!bTriggerbot) { @@ -427,17 +435,21 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p auto vAngles = Aim(G::CurrentUserCmd->viewangles, Math::CalcAngle(pLocal->GetShootPos(), vOrigin)); Vec3 vForward; Math::AngleVectors(vAngles, &vForward); - target.m_vAngleTo = vAngles; - if (RayToOBB(vEyePos, vForward, vMins * flModelScale, vMaxs * flModelScale, aBones[pBox->bone])) // for the time being, no vischecks against other hitboxes + // for the time being, no vischecks against other hitboxes + Vec3 vCheckMins = (vMins + flBoneSubtract / flModelScale) * flBoneScale, vCheckMaxs = (vMaxs - flBoneSubtract / flModelScale) * flBoneScale; + if (RayToOBB(vEyePos, vForward, vCheckMins, vCheckMaxs, aBones[pBox->bone], flModelScale)) { flPreferredRecord = tRecord.m_flSimTime; + target.m_vAngleTo = vAngles; target.m_tRecord = tRecord; target.m_vPos = vOrigin; target.m_nAimedHitbox = iHitbox; target.m_bBacktrack = true; return true; } + else if (iReturn == 2 && vAngles.DeltaAngle(G::CurrentUserCmd->viewangles).Length2D() < target.m_vAngleTo.DeltaAngle(G::CurrentUserCmd->viewangles).Length2D()) + target.m_vAngleTo = vAngles; iReturn = 2; } } @@ -445,13 +457,18 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p } else { + float flBoneScale = std::max(Vars::Aimbot::Hitscan::BoneSizeMinimumScale.Value, Vars::Aimbot::Hitscan::PointScale.Value / 100.f); + float flBoneSubtract = Vars::Aimbot::Hitscan::BoneSizeSubtract.Value; + Vec3 vMins = target.m_pEntity->m_vecMins(); Vec3 vMaxs = target.m_pEntity->m_vecMaxs(); std::vector vPoints = { Vec3() }; //if (Vars::Aimbot::Hitscan::PointScale.Value > 0.f) { - bool bTriggerbot = Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth && Vars::Aimbot::General::Smoothing.Value == 100.f; + bool bTriggerbot = (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth + || Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Assistive) + && !Vars::Aimbot::General::AssistStrength.Value; if (!bTriggerbot) { @@ -493,13 +510,16 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p auto vAngles = Aim(G::CurrentUserCmd->viewangles, Math::CalcAngle(pLocal->GetShootPos(), vTransformed)); Vec3 vForward; Math::AngleVectors(vAngles, &vForward); - target.m_vAngleTo = vAngles; - if (RayToOBB(vEyePos, vForward, vMins, vMaxs, transform)) + Vec3 vCheckMins = (vMins + flBoneSubtract) * flBoneScale, vCheckMaxs = (vMaxs - flBoneSubtract) * flBoneScale; + if (RayToOBB(vEyePos, vForward, vCheckMins, vCheckMaxs, transform)) { + target.m_vAngleTo = vAngles; target.m_tRecord = tRecord; target.m_vPos = vTransformed; return true; } + else if (iReturn == 2 && vAngles.DeltaAngle(G::CurrentUserCmd->viewangles).Length2D() < target.m_vAngleTo.DeltaAngle(G::CurrentUserCmd->viewangles).Length2D()) + target.m_vAngleTo = vAngles; iReturn = 2; } } @@ -591,17 +611,15 @@ Vec3 CAimbotHitscan::Aim(Vec3 vCurAngle, Vec3 vToAngle, int iMethod) vReturn = vToAngle; break; case Vars::Aimbot::General::AimTypeEnum::Smooth: - { - auto shortDist = [](const float flAngleA, const float flAngleB) - { - const float flDelta = fmodf((flAngleA - flAngleB), 360.f); - return fmodf(2 * flDelta, 360.f) - flDelta; - }; - const float t = 1.f - Vars::Aimbot::General::Smoothing.Value / 100.f; - vReturn.x = vCurAngle.x - shortDist(vCurAngle.x, vToAngle.x) * t; - vReturn.y = vCurAngle.y - shortDist(vCurAngle.y, vToAngle.y) * t; + vReturn = vCurAngle.LerpAngle(vToAngle, Vars::Aimbot::General::AssistStrength.Value / 100.f); + break; + case Vars::Aimbot::General::AimTypeEnum::Assistive: + Vec3 vMouseDelta = G::CurrentUserCmd->viewangles.DeltaAngle(G::LastUserCmd->viewangles); + Vec3 vTargetDelta = vToAngle.DeltaAngle(G::LastUserCmd->viewangles); + float flMouseDelta = vMouseDelta.Length2D(), flTargetDelta = vTargetDelta.Length2D(); + vTargetDelta = vTargetDelta.Normalized() * std::min(flMouseDelta, flTargetDelta); + vReturn = vCurAngle - vMouseDelta + vMouseDelta.LerpAngle(vTargetDelta, Vars::Aimbot::General::AssistStrength.Value / 100.f); break; - } } return vReturn; @@ -614,6 +632,7 @@ void CAimbotHitscan::Aim(CUserCmd* pCmd, Vec3& vAngle) { case Vars::Aimbot::General::AimTypeEnum::Plain: case Vars::Aimbot::General::AimTypeEnum::Smooth: + case Vars::Aimbot::General::AimTypeEnum::Assistive: pCmd->viewangles = vAngle; I::EngineClient->SetViewAngles(vAngle); break; diff --git a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp index 28f7705a..d2b2ab36 100644 --- a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp @@ -116,8 +116,8 @@ int CAimbotMelee::GetSwingTime(CTFWeaponBase* pWeapon) } void CAimbotMelee::SimulatePlayers(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, std::vector targets, - Vec3& vEyePos, std::unordered_map>& pRecordMap, - std::unordered_map>& mPaths) + Vec3& vEyePos, std::unordered_map>& pRecordMap, + std::unordered_map>& mPaths) { // swing prediction / auto warp const int iSwingTicks = GetSwingTime(pWeapon); @@ -128,11 +128,11 @@ void CAimbotMelee::SimulatePlayers(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, st if ((Vars::Aimbot::Melee::SwingPrediction.Value || iDoubletapTicks) && pWeapon->m_flSmackTime() < 0.f && iMax) { PlayerStorage localStorage; - std::unordered_map targetStorage; + std::unordered_map targetStorage; F::MoveSim.Initialize(pLocal, localStorage, false, iDoubletapTicks); for (auto& target : targets) - F::MoveSim.Initialize(target.m_pEntity, targetStorage[target.m_pEntity], false); + F::MoveSim.Initialize(target.m_pEntity, targetStorage[target.m_pEntity->entindex()], false); for (int i = 0; i < iMax; i++) // intended for plocal to collide with targets { @@ -146,12 +146,14 @@ void CAimbotMelee::SimulatePlayers(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, st { for (auto& target : targets) { - F::MoveSim.RunTick(targetStorage[target.m_pEntity]); - if (!targetStorage[target.m_pEntity].m_bFailed) - pRecordMap[target.m_pEntity].push_front({ - !Vars::Aimbot::Melee::SwingPredictLag.Value || targetStorage[target.m_pEntity].m_bPredictNetworked ? target.m_pEntity->m_flSimulationTime() + TICKS_TO_TIME(i + 1) : 0.f, + auto& tStorage = targetStorage[target.m_pEntity->entindex()]; + + F::MoveSim.RunTick(tStorage); + if (!tStorage.m_bFailed) + pRecordMap[target.m_pEntity->entindex()].push_front({ + !Vars::Aimbot::Melee::SwingPredictLag.Value || tStorage.m_bPredictNetworked ? target.m_pEntity->m_flSimulationTime() + TICKS_TO_TIME(i + 1) : 0.f, {}, - Vars::Aimbot::Melee::SwingPredictLag.Value ? targetStorage[target.m_pEntity].m_vPredictedOrigin : targetStorage[target.m_pEntity].m_MoveData.m_vecAbsOrigin + Vars::Aimbot::Melee::SwingPredictLag.Value ? tStorage.m_vPredictedOrigin : tStorage.m_MoveData.m_vecAbsOrigin }); } } @@ -163,9 +165,9 @@ void CAimbotMelee::SimulatePlayers(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, st const bool bAlwaysDraw = !Vars::Aimbot::General::AutoShoot.Value || Vars::Debug::Info.Value; if (!bAlwaysDraw) { - mPaths[pLocal] = localStorage.m_vPath; + mPaths[pLocal->entindex()] = localStorage.m_vPath; for (auto& target : targets) - mPaths[target.m_pEntity] = targetStorage[target.m_pEntity].m_vPath; + mPaths[target.m_pEntity->entindex()] = targetStorage[target.m_pEntity->entindex()].m_vPath; } else { @@ -175,22 +177,22 @@ void CAimbotMelee::SimulatePlayers(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, st if (Vars::Colors::PlayerPath.Value.a) { - G::PathStorage.push_back({ localStorage.m_vPath, I::GlobalVars->curtime + 5.f, Vars::Colors::PlayerPath.Value, Vars::Visuals::Simulation::PlayerPath.Value }); + G::PathStorage.push_back({ localStorage.m_vPath, I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPath.Value, Vars::Visuals::Simulation::PlayerPath.Value }); for (auto& target : targets) - G::PathStorage.push_back({ targetStorage[target.m_pEntity].m_vPath, I::GlobalVars->curtime + 5.f, Vars::Colors::PlayerPath.Value, Vars::Visuals::Simulation::PlayerPath.Value }); + G::PathStorage.push_back({ targetStorage[target.m_pEntity->entindex()].m_vPath, I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPath.Value, Vars::Visuals::Simulation::PlayerPath.Value }); } if (Vars::Colors::PlayerPathClipped.Value.a) { - G::PathStorage.push_back({ localStorage.m_vPath, I::GlobalVars->curtime + 5.f, Vars::Colors::PlayerPathClipped.Value, Vars::Visuals::Simulation::PlayerPath.Value, true }); + G::PathStorage.push_back({ localStorage.m_vPath, I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPathClipped.Value, Vars::Visuals::Simulation::PlayerPath.Value, true }); for (auto& target : targets) - G::PathStorage.push_back({ targetStorage[target.m_pEntity].m_vPath, I::GlobalVars->curtime + 5.f, Vars::Colors::PlayerPathClipped.Value, Vars::Visuals::Simulation::PlayerPath.Value, true }); + G::PathStorage.push_back({ targetStorage[target.m_pEntity->entindex()].m_vPath, I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPathClipped.Value, Vars::Visuals::Simulation::PlayerPath.Value, true }); } } } F::MoveSim.Restore(localStorage); for (auto& target : targets) - F::MoveSim.Restore(targetStorage[target.m_pEntity]); + F::MoveSim.Restore(targetStorage[target.m_pEntity->entindex()]); } } @@ -366,7 +368,8 @@ int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWe return true; } - else if (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth) + else if (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth + || Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Assistive) { auto vAngle = Math::CalcAngle(vEyePos, target.m_vPos); @@ -398,17 +401,15 @@ Vec3 CAimbotMelee::Aim(Vec3 vCurAngle, Vec3 vToAngle, int iMethod) vReturn = vToAngle; break; case Vars::Aimbot::General::AimTypeEnum::Smooth: - { - auto shortDist = [](const float flAngleA, const float flAngleB) - { - const float flDelta = fmodf((flAngleA - flAngleB), 360.f); - return fmodf(2 * flDelta, 360.f) - flDelta; - }; - const float t = 1.f - Vars::Aimbot::General::Smoothing.Value / 100.f; - vReturn.x = vCurAngle.x - shortDist(vCurAngle.x, vToAngle.x) * t; - vReturn.y = vCurAngle.y - shortDist(vCurAngle.y, vToAngle.y) * t; + vReturn = vCurAngle.LerpAngle(vToAngle, Vars::Aimbot::General::AssistStrength.Value / 100.f); + break; + case Vars::Aimbot::General::AimTypeEnum::Assistive: + Vec3 vMouseDelta = G::CurrentUserCmd->viewangles.DeltaAngle(G::LastUserCmd->viewangles); + Vec3 vTargetDelta = vToAngle.DeltaAngle(G::LastUserCmd->viewangles); + float flMouseDelta = vMouseDelta.Length2D(), flTargetDelta = vTargetDelta.Length2D(); + vTargetDelta = vTargetDelta.Normalized() * std::min(flMouseDelta, flTargetDelta); + vReturn = vCurAngle - vMouseDelta + vMouseDelta.LerpAngle(vTargetDelta, Vars::Aimbot::General::AssistStrength.Value / 100.f); break; - } } return vReturn; @@ -421,6 +422,7 @@ void CAimbotMelee::Aim(CUserCmd* pCmd, Vec3& vAngle) { case Vars::Aimbot::General::AimTypeEnum::Plain: case Vars::Aimbot::General::AimTypeEnum::Smooth: + case Vars::Aimbot::General::AimTypeEnum::Assistive: pCmd->viewangles = vAngle; I::EngineClient->SetViewAngles(vAngle); break; @@ -467,13 +469,13 @@ void CAimbotMelee::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd const bool bShouldSwing = iDoubletapTicks <= (GetSwingTime(pWeapon) ? 14 : 0) || Vars::CL_Move::Doubletap::AntiWarp.Value && pLocal->m_hGroundEntity(); Vec3 vEyePos = pLocal->GetShootPos(); - std::unordered_map> pRecordMap; - std::unordered_map> mPaths; + std::unordered_map> pRecordMap; + std::unordered_map> mPaths; SimulatePlayers(pLocal, pWeapon, targets, vEyePos, pRecordMap, mPaths); for (auto& target : targets) { - const auto iResult = CanHit(target, pLocal, pWeapon, vEyePos, pRecordMap[target.m_pEntity]); + const auto iResult = CanHit(target, pLocal, pWeapon, vEyePos, pRecordMap[target.m_pEntity->entindex()]); if (!iResult) continue; if (iResult == 2) { @@ -519,13 +521,13 @@ void CAimbotMelee::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd { if (Vars::Colors::PlayerPath.Value.a) { - G::PathStorage.push_back({ mPaths[pLocal], I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPath.Value, Vars::Visuals::Simulation::PlayerPath.Value }); - G::PathStorage.push_back({ mPaths[target.m_pEntity], I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPath.Value, Vars::Visuals::Simulation::PlayerPath.Value }); + G::PathStorage.push_back({ mPaths[pLocal->entindex()], I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPath.Value, Vars::Visuals::Simulation::PlayerPath.Value }); + G::PathStorage.push_back({ mPaths[target.m_pEntity->entindex()], I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPath.Value, Vars::Visuals::Simulation::PlayerPath.Value }); } if (Vars::Colors::PlayerPathClipped.Value.a) { - G::PathStorage.push_back({ mPaths[pLocal], I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPathClipped.Value, Vars::Visuals::Simulation::PlayerPath.Value, true }); - G::PathStorage.push_back({ mPaths[target.m_pEntity], I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPathClipped.Value, Vars::Visuals::Simulation::PlayerPath.Value, true }); + G::PathStorage.push_back({ mPaths[pLocal->entindex()], I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPathClipped.Value, Vars::Visuals::Simulation::PlayerPath.Value, true }); + G::PathStorage.push_back({ mPaths[target.m_pEntity->entindex()], I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPathClipped.Value, Vars::Visuals::Simulation::PlayerPath.Value, true }); } } } diff --git a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.h b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.h index cfdfb72b..d3a83c8e 100644 --- a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.h +++ b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.h @@ -11,8 +11,8 @@ class CAimbotMelee int GetSwingTime(CTFWeaponBase* pWeapon); void SimulatePlayers(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, std::vector targets, Vec3& vEyePos, - std::unordered_map>& pRecordMap, - std::unordered_map>& mPaths); + std::unordered_map>& pRecordMap, + std::unordered_map>& mPaths); bool CanBackstab(CBaseEntity* pTarget, CTFPlayer* pLocal, Vec3 vEyeAngles); int CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Vec3 vEyePos, std::deque& vSimRecords); diff --git a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp index f3491b84..d3939acd 100644 --- a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp @@ -10,6 +10,11 @@ //#define SPLASH_DEBUG2 // obstructed splash visualization //#define SPLASH_DEBUG3 // points visualization //#define SPLASH_DEBUG4 // trace visualization +//#define SPLASH_DEBUG5 // trace count + +#ifdef SPLASH_DEBUG5 +static std::unordered_map mTraceCount = {}; +#endif std::vector CAimbotProjectile::GetTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) { @@ -186,30 +191,43 @@ static inline float PrimeTime(CTFWeaponBase* pWeapon) int CAimbotProjectile::GetHitboxPriority(int nHitbox, Target_t& target, Info_t& tInfo) { - bool bHeadshot = target.m_iTargetType == TargetEnum::Player && tInfo.m_pWeapon->GetWeaponID() == TF_WEAPON_COMPOUND_BOW; - if (Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::BodyaimIfLethal && bHeadshot) + bool bHeadshot = target.m_iTargetType == TargetEnum::Player && tInfo.m_pWeapon->GetWeaponID() == TF_WEAPON_COMPOUND_BOW + && Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::Head; + if (Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::BodyaimIfLethal && bHeadshot) { - float charge = I::GlobalVars->curtime - tInfo.m_pWeapon->As()->m_flChargeBeginTime(); - float damage = Math::RemapValClamped(charge, 0.f, 1.f, 50.f, 120.f); + float flCharge = I::GlobalVars->curtime - tInfo.m_pWeapon->As()->m_flChargeBeginTime(); + float flDamage = Math::RemapValClamped(flCharge, 0.f, 1.f, 50.f, 120.f); if (tInfo.m_pLocal->IsMiniCritBoosted()) - damage *= 1.36f; - if (damage >= target.m_pEntity->As()->m_iHealth()) + flDamage *= 1.36f; + if (flDamage >= target.m_pEntity->As()->m_iHealth()) bHeadshot = false; if (tInfo.m_pLocal->IsCritBoosted()) // for reliability bHeadshot = false; } - const bool bLower = target.m_iTargetType == TargetEnum::Player && Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::AimBlastAtFeet + bool bLower = target.m_iTargetType == TargetEnum::Player && Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::AimBlastAtFeet && target.m_pEntity->As()->IsOnGround() && tInfo.m_flRadius; if (bHeadshot) target.m_nAimedHitbox = HITBOX_HEAD; - switch (nHitbox) + if (!(Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::Auto)) { - case 0: return bHeadshot ? 0 : 2; // head - case 1: return bHeadshot ? 3 : (bLower ? 1 : 0); // body - case 2: return bHeadshot ? 3 : (bLower ? 0 : 1); // feet + switch (nHitbox) + { + case 0: return Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::Head ? 0 : 3; + case 1: return Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::Body ? 1 : 3; + case 2: return Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::Feet ? 2 : 3; + } + } + else + { + switch (nHitbox) + { + case 0: return Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::Head ? (bHeadshot ? 0 : 2) : 3; + case 1: return Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::Body ? (bHeadshot ? 3 : (bLower ? 1 : 0)) : 3; + case 2: return Vars::Aimbot::Projectile::Hitboxes.Value & Vars::Aimbot::Projectile::HitboxesEnum::Feet ? (bHeadshot ? 3 : (bLower ? 0 : 1)) : 3; + } } return 3; @@ -375,6 +393,9 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& target, std::v bool bErase = false, bNormal = false; SDK::TraceHull(vTargetEye, vPoint, tInfo.m_vHull * -1, tInfo.m_vHull, MASK_SOLID, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Splash regular"]++; +#endif #ifndef SPLASH_DEBUG1 checkPoint(trace, bErase, bNormal); #else @@ -398,6 +419,9 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& target, std::v case Vars::Aimbot::Projectile::RocketSplashModeEnum::Regular: { SDK::Trace(vPoint, vTargetEye, MASK_SHOT, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Splash grate check"]++; +#endif bNormal = trace.DidHit(); #ifdef SPLASH_DEBUG2 G::LineStorage.push_back({ { vPoint, trace.endpos }, I::GlobalVars->curtime + 60.f, bNormal ? Vars::Colors::IndicatorGood.Value : Vars::Colors::IndicatorBad.Value }); @@ -405,6 +429,9 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& target, std::v if (!bNormal) { SDK::TraceHull(vPoint, vTargetEye, tInfo.m_vHull * -1, tInfo.m_vHull, MASK_SOLID, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Splash grate"]++; +#endif #ifndef SPLASH_DEBUG2 checkPoint(trace, bErase, bNormal); #else @@ -417,6 +444,9 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& target, std::v case Vars::Aimbot::Projectile::RocketSplashModeEnum::SpecialLight: { SDK::Trace(vPoint, vTargetEye, MASK_SOLID, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Splash rocket"]++; +#endif bNormal = trace.fraction == 1.f /*|| trace.startsolid*/; if (!bNormal) { @@ -428,6 +458,9 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& target, std::v #endif { SDK::Trace(trace.endpos + trace.plane.normal, vTargetEye, MASK_SHOT, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Splash rocket check"]++; +#endif if (trace.fraction < 1.f) vPointDistances.pop_back(); } @@ -437,6 +470,9 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& target, std::v case Vars::Aimbot::Projectile::RocketSplashModeEnum::SpecialHeavy: { SDK::Trace(vTargetEye, vPoint, MASK_SOLID, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Splash rocket"]++; +#endif bErase = trace.fraction == 1.f /*|| trace.startsolid*/; if (!bNormal) { @@ -446,6 +482,9 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& target, std::v bool bAdded = false; SDK::Trace(vFrom, vTo, MASK_SOLID, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Splash rocket (2)"]++; +#endif if (trace.fraction < 1.f) { #ifndef SPLASH_DEBUG2 @@ -456,6 +495,9 @@ std::vector CAimbotProjectile::GetSplashPoints(Target_t& target, std::v #endif { SDK::Trace(trace.endpos + trace.plane.normal, vTargetEye, MASK_SHOT, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Splash rocket check"]++; +#endif bAdded = trace.fraction == 1.f; if (!bAdded) vPointDistances.pop_back(); @@ -571,7 +613,7 @@ static inline Vec3 PullPoint(Vec3 vPoint, Vec3 vLocalPos, Info_t& tInfo, Vec3 vM static inline void SolveProjectileSpeed(CTFWeaponBase* pWeapon, const Vec3& vLocalPos, const Vec3& vTargetPos, float& flVelocity, float& flDragTime, const float flGravity) { - if (F::ProjSim.obj->m_dragBasis.IsZero()) + if (!F::ProjSim.obj->IsDragEnabled() || F::ProjSim.obj->m_dragBasis.IsZero()) return; const float flGrav = flGravity * 800.0f; @@ -630,6 +672,14 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge float flPitch, flYaw; { // basic trajectory pass + float flVelocity = tInfo.m_flVelocity, flDragTime = 0.f; + if (F::ProjSim.obj->IsDragEnabled() && !F::ProjSim.obj->m_dragBasis.IsZero()) + { + Vec3 vForward, vRight, vUp; Math::AngleVectors(Math::CalcAngle(vLocalPos, vTargetPos), &vForward, &vRight, &vUp); + Vec3 vShootPos = vLocalPos + (vForward * tInfo.m_vOffset.x) + (vRight * tInfo.m_vOffset.y) + (vUp * tInfo.m_vOffset.z); + SolveProjectileSpeed(tInfo.m_pWeapon, vShootPos, vTargetPos, flVelocity, flDragTime, tInfo.m_flGravity); + } + Vec3 vDelta = vTargetPos - vLocalPos; float flDist = vDelta.Length2D(); @@ -638,14 +688,14 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge flPitch = -DEG2RAD(vAngleTo.x); else { // arch - float flRoot = pow(tInfo.m_flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(tInfo.m_flVelocity, 2)); + float flRoot = pow(flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(flVelocity, 2)); if (flRoot < 0.f) { out.m_iCalculated = 3; return; } - flPitch = atan((pow(tInfo.m_flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist)); + flPitch = atan((pow(flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist)); } - out.m_flTime = flDist / (cos(flPitch) * tInfo.m_flVelocity) - tInfo.m_flOffsetTime; + out.m_flTime = flDist / (cos(flPitch) * flVelocity) - tInfo.m_flOffsetTime + flDragTime; out.m_flPitch = flPitch = -RAD2DEG(flPitch) - tInfo.m_vAngFix.x; out.m_flYaw = flYaw = vAngleTo.y - tInfo.m_vAngFix.y; } @@ -656,6 +706,38 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge out.m_iCalculated = 2; return; } +#ifdef SPLASH_DEBUG5 + int iFlags = (bAccuracy ? ProjSimEnum::Trace : ProjSimEnum::None) | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum; + if (iFlags & ProjSimEnum::Trace) + { + if (Vars::Visuals::Trajectory::Overwrite.Value) + { + if (!Vars::Visuals::Trajectory::Pipes.Value) + mTraceCount["Setup trace"]++; + } + else + { + switch (tInfo.m_pWeapon->GetWeaponID()) + { + 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_FLAREGUN: + case TF_WEAPON_FLAREGUN_REVENGE: + case TF_WEAPON_COMPOUND_BOW: + case TF_WEAPON_CROSSBOW: + case TF_WEAPON_SHOTGUN_BUILDING_RESCUE: + case TF_WEAPON_SYRINGEGUN_MEDIC: + case TF_WEAPON_FLAME_BALL: + mTraceCount["Setup trace"]++; + } + } + } + if (iFlags & ProjSimEnum::InitCheck) + mTraceCount["Trace init check"]++; +#endif ProjectileInfo projInfo = {}; if (!F::ProjSim.GetInfo(tInfo.m_pLocal, tInfo.m_pWeapon, { flPitch, flYaw, 0 }, projInfo, (bAccuracy ? ProjSimEnum::Trace : ProjSimEnum::None) | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum)) { @@ -663,8 +745,8 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge } { // calculate trajectory from projectile origin - float flNewVel = tInfo.m_flVelocity, flDragTime = 0.f; - SolveProjectileSpeed(tInfo.m_pWeapon, projInfo.m_vPos, vTargetPos, flNewVel, flDragTime, tInfo.m_flGravity); + float flVelocity = tInfo.m_flVelocity, flDragTime = 0.f; + SolveProjectileSpeed(tInfo.m_pWeapon, projInfo.m_vPos, vTargetPos, flVelocity, flDragTime, tInfo.m_flGravity); Vec3 vDelta = vTargetPos - projInfo.m_vPos; float flDist = vDelta.Length2D(); @@ -674,23 +756,18 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge out.m_flPitch = -DEG2RAD(vNewAngleTo.x); else { // arch - float flRoot = pow(flNewVel, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(flNewVel, 2)); + float flRoot = pow(flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(flVelocity, 2)); if (flRoot < 0.f) { out.m_iCalculated = 3; return; } - out.m_flPitch = atan((pow(flNewVel, 2) - sqrt(flRoot)) / (flGrav * flDist)); + out.m_flPitch = atan((pow(flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist)); } - out.m_flTime = flDist / (cos(out.m_flPitch) * flNewVel) + flDragTime; + out.m_flTime = flDist / (cos(out.m_flPitch) * flVelocity) + flDragTime; } { // correct yaw - /* - flYaw -= projInfo.m_vAng.y; - out.m_flYaw = vNewAngleTo.y + flYaw - tInfo.m_vAngFix.y; - */ - ///* Vec3 vShootPos = projInfo.m_vPos - vLocalPos; vShootPos.z = 0; Vec3 vTarget = vTargetPos - vLocalPos; Vec3 vForward; Math::AngleVectors(projInfo.m_vAng, &vForward); vForward.z = 0; vForward.Normalize(); @@ -703,18 +780,14 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge out.m_flYaw = flYaw - (RAD2DEG(atan2(vShootPos.y, vShootPos.x)) - flYaw); flYaw = RAD2DEG(atan2(vShootPos.y, vShootPos.x)); } - //*/ } { // correct pitch - ///* if (flGrav) { flPitch -= projInfo.m_vAng.x; out.m_flPitch = -RAD2DEG(out.m_flPitch) + flPitch - tInfo.m_vAngFix.x; } - //*/ - ///* else { Vec3 vShootPos = Math::RotatePoint(projInfo.m_vPos - vLocalPos, {}, { 0, -flYaw, 0 }); vShootPos.y = 0; @@ -729,7 +802,6 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge out.m_flPitch = flPitch - (RAD2DEG(atan2(-vShootPos.z, vShootPos.x)) - flPitch); } } - //*/ } iTimeTo = int(out.m_flTime / TICK_INTERVAL) + 1; @@ -775,6 +847,38 @@ TraceType_t CTraceFilterProjectileNoPlayer::GetTraceType() const bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Target_t& target, Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash, std::deque* pProjectilePath) { +#ifdef SPLASH_DEBUG5 + int iFlags = ProjSimEnum::Trace | ProjSimEnum::InitCheck | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum; + if (iFlags & ProjSimEnum::Trace) + { + if (Vars::Visuals::Trajectory::Overwrite.Value) + { + if (!Vars::Visuals::Trajectory::Pipes.Value) + mTraceCount["Setup trace"]++; + } + else + { + switch (pWeapon->GetWeaponID()) + { + 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_FLAREGUN: + case TF_WEAPON_FLAREGUN_REVENGE: + case TF_WEAPON_COMPOUND_BOW: + case TF_WEAPON_CROSSBOW: + case TF_WEAPON_SHOTGUN_BUILDING_RESCUE: + case TF_WEAPON_SYRINGEGUN_MEDIC: + case TF_WEAPON_FLAME_BALL: + mTraceCount["Setup trace"]++; + } + } + } + if (iFlags & ProjSimEnum::InitCheck) + mTraceCount["Trace init check"]++; +#endif ProjectileInfo projInfo = {}; if (!F::ProjSim.GetInfo(pLocal, pWeapon, vAngles, projInfo, ProjSimEnum::Trace | ProjSimEnum::InitCheck | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum) || !F::ProjSim.Initialize(projInfo)) return false; @@ -793,6 +897,9 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar { CTraceFilterWorldAndPropsOnly filterWorld = {}; SDK::TraceHull(projInfo.m_vPos, vPoint, projInfo.m_vHull * -1, projInfo.m_vHull, MASK_SOLID, &filterWorld, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Nograv trace"]++; +#endif #ifdef SPLASH_DEBUG4 G::LineStorage.push_back({ { projInfo.m_vPos, vPoint }, I::GlobalVars->curtime + 5.f, { 0, 0, 0, 255 } }); #endif @@ -819,6 +926,9 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar if (!bSplash) { SDK::TraceHull(vOld, vNew, projInfo.m_vHull * -1, projInfo.m_vHull, MASK_SOLID, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Direct trace"]++; +#endif #ifdef SPLASH_DEBUG4 G::LineStorage.push_back({ { vOld, vNew }, I::GlobalVars->curtime + 5.f, { 255, 0, 0, 255 } }); @@ -833,6 +943,9 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar continue; SDK::TraceHull(vStaticPos, vNew, projInfo.m_vHull * -1, projInfo.m_vHull, MASK_SOLID, &filterSplash, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Splash trace"]++; +#endif #ifdef SPLASH_DEBUG4 G::LineStorage.push_back({ { vStaticPos, vNew }, I::GlobalVars->curtime + 5.f, { 255, 0, 0, 255 } }); #endif @@ -850,6 +963,10 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar bool bTarget = trace.m_pEnt == target.m_pEntity || bSplash; bool bTime = bSplash ? trace.endpos.DistTo(vPoint) < projInfo.m_flVelocity * TICK_INTERVAL + projInfo.m_vHull.z : iSimTime - n < 5; bool bValid = bTarget && bTime && (bSplash ? SDK::VisPosWorld(nullptr, target.m_pEntity, trace.endpos, vPoint, MASK_SOLID) : true); +#ifdef SPLASH_DEBUG5 + if (bTarget && bTime && bSplash) + mTraceCount["Splash vispos"]++; +#endif #ifdef SPLASH_DEBUG4 G::BoxStorage.pop_back(); @@ -870,63 +987,70 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar if (bValid) { - if (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth) + switch (Vars::Aimbot::General::AimType.Value) { - // attempted to have a headshot check though this seems more detrimental than useful outside of smooth aimbot - if (target.m_nAimedHitbox == HITBOX_HEAD) - { // i think this is accurate? nope, 220 - const Vec3 vOffset = (trace.endpos - vNew) + (vOriginal - target.m_vPos); + case Vars::Aimbot::General::AimTypeEnum::Smooth: + case Vars::Aimbot::General::AimTypeEnum::Assistive: + { + // attempted to have a headshot check though this seems more detrimental than useful outside of smooth aimbot + if (target.m_nAimedHitbox == HITBOX_HEAD) + { // i think this is accurate? nope, 220 + const Vec3 vOffset = (trace.endpos - vNew) + (vOriginal - target.m_vPos); - Vec3 vOld = F::ProjSim.GetOrigin() + vOffset; - F::ProjSim.RunTick(projInfo); - Vec3 vNew = F::ProjSim.GetOrigin() + vOffset; + Vec3 vOld = F::ProjSim.GetOrigin() + vOffset; + F::ProjSim.RunTick(projInfo); + Vec3 vNew = F::ProjSim.GetOrigin() + vOffset; - CGameTrace trace = {}; - SDK::Trace(vOld, vNew, MASK_SHOT, &filter, &trace); - trace.endpos -= vOffset; + CGameTrace trace = {}; + SDK::Trace(vOld, vNew, MASK_SHOT, &filter, &trace); +#ifdef SPLASH_DEBUG5 + mTraceCount["Huntsman trace"]++; +#endif + trace.endpos -= vOffset; - if (trace.DidHit() && (trace.m_pEnt != target.m_pEntity || trace.hitbox != HITBOX_HEAD)) - break; - - if (!trace.DidHit()) // loop and see if closest hitbox is head - { - auto pModel = target.m_pEntity->GetModel(); - if (!pModel) break; - auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel); - if (!pHDR) break; - auto pSet = pHDR->pHitboxSet(target.m_pEntity->As()->m_nHitboxSet()); - if (!pSet) break; - - auto pBones = H::Entities.GetBones(target.m_pEntity->entindex()); - if (!pBones) + if (trace.DidHit() && (trace.m_pEnt != target.m_pEntity || trace.hitbox != HITBOX_HEAD)) break; - Vec3 vForward = vOld - vNew; vForward.Normalize(); - const Vec3 vPos = trace.endpos + vForward * 16 + vOriginal - target.m_vPos; - - //G::LineStorage.clear(); - //G::LineStorage.push_back({ { pLocal->GetShootPos(), vPos }, I::GlobalVars->curtime + 5.f, Vars::Colors::Prediction.Value }); - - float closestDist = 0.f; int closestId = -1; - for (int i = 0; i < pSet->numhitboxes; ++i) + if (!trace.DidHit()) // loop and see if closest hitbox is head { - auto pBox = pSet->pHitbox(i); - if (!pBox) - continue; + auto pModel = target.m_pEntity->GetModel(); + if (!pModel) break; + auto pHDR = I::ModelInfoClient->GetStudiomodel(pModel); + if (!pHDR) break; + auto pSet = pHDR->pHitboxSet(target.m_pEntity->As()->m_nHitboxSet()); + if (!pSet) break; - Vec3 vCenter; Math::VectorTransform((pBox->bbmin + pBox->bbmax) / 2, pBones[pBox->bone], vCenter); + auto pBones = H::Entities.GetBones(target.m_pEntity->entindex()); + if (!pBones) + break; - const float flDist = vPos.DistTo(vCenter); - if (closestId != -1 && flDist < closestDist || closestId == -1) + Vec3 vForward = vOld - vNew; vForward.Normalize(); + const Vec3 vPos = trace.endpos + vForward * 16 + vOriginal - target.m_vPos; + + //G::LineStorage.clear(); + //G::LineStorage.push_back({ { pLocal->GetShootPos(), vPos }, I::GlobalVars->curtime + 5.f, Vars::Colors::Prediction.Value }); + + float closestDist = 0.f; int closestId = -1; + for (int i = 0; i < pSet->numhitboxes; ++i) { - closestDist = flDist; - closestId = i; - } - } + auto pBox = pSet->pHitbox(i); + if (!pBox) + continue; - if (closestId != 0) - break; - bDidHit = true; + Vec3 vCenter; Math::VectorTransform((pBox->bbmin + pBox->bbmax) / 2, pBones[pBox->bone], vCenter); + + const float flDist = vPos.DistTo(vCenter); + if (closestId != -1 && flDist < closestDist || closestId == -1) + { + closestDist = flDist; + closestId = i; + } + } + + if (closestId != 0) + break; + bDidHit = true; + } } } } @@ -973,6 +1097,38 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase int iMaxTime, iSplash; Info_t tInfo = { pLocal, pWeapon }; const float flSize = target.m_pEntity->m_vecMins().DistTo(target.m_pEntity->m_vecMaxs()); { +#ifdef SPLASH_DEBUG5 + int iFlags = ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum; + if (iFlags & ProjSimEnum::Trace) + { + if (Vars::Visuals::Trajectory::Overwrite.Value) + { + if (!Vars::Visuals::Trajectory::Pipes.Value) + mTraceCount["Setup trace"]++; + } + else + { + switch (tInfo.m_pWeapon->GetWeaponID()) + { + 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_FLAREGUN: + case TF_WEAPON_FLAREGUN_REVENGE: + case TF_WEAPON_COMPOUND_BOW: + case TF_WEAPON_CROSSBOW: + case TF_WEAPON_SHOTGUN_BUILDING_RESCUE: + case TF_WEAPON_SYRINGEGUN_MEDIC: + case TF_WEAPON_FLAME_BALL: + mTraceCount["Setup trace"]++; + } + } + } + if (iFlags & ProjSimEnum::InitCheck) + mTraceCount["Trace init check"]++; +#endif if (!F::ProjSim.GetInfo(pLocal, pWeapon, {}, projInfo, ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum) || !F::ProjSim.Initialize(projInfo, false)) return false; @@ -982,7 +1138,6 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase target.m_vPos = target.m_pEntity->m_vecOrigin(); tInfo.m_flLatency = F::Backtrack.GetReal() + TICKS_TO_TIME(F::Backtrack.GetAnticipatedChoke()); - tInfo.m_iLatency = TIME_TO_TICKS(tInfo.m_flLatency); iMaxTime = TIME_TO_TICKS(std::min(projInfo.m_flLifetime, Vars::Aimbot::Projectile::PredictionTime.Value)); @@ -1014,38 +1169,51 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase for (auto& [vPoint, _] : vSpherePoints) G::BoxStorage.push_back({ target.m_pEntity->m_vecOrigin() + tInfo.m_vTargetEye + vPoint * tInfo.m_flRadius / (tInfo.m_flRadius + flSize), { -1, -1, -1 }, { 1, 1, 1 }, {}, I::GlobalVars->curtime + 60.f, { 0, 0, 0, 0 }, Vars::Colors::Local.Value }); #endif + + bool bSingleSplash = Vars::Aimbot::Projectile::SplashMode.Value == Vars::Aimbot::Projectile::SplashModeEnum::Single; + bool bDoneRunningSplash = false; 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; i < iMaxTime; i++) + for (int i = 1 - TIME_TO_TICKS(tInfo.m_flLatency); i <= iMaxTime; i++) { - const int iSimTime = i - tInfo.m_iLatency; if (!storage.m_bFailed) { F::MoveSim.RunTick(storage); target.m_vPos = storage.m_vPredictedOrigin; } - if (iSimTime < 0) + if (i < 0) continue; + bool bDirectBreaks = true; std::vector vSplashPoints = {}; if (iSplash) { - Solution_t solution; CalculateAngle(tInfo.m_vLocalEye, target.m_vPos, tInfo, iSimTime, solution, false); + Solution_t solution; CalculateAngle(tInfo.m_vLocalEye, target.m_vPos, tInfo, i, solution, false); if (solution.m_iCalculated != 3) { - const float flTimeTo = solution.m_flTime - TICKS_TO_TIME(iSimTime); - if (flTimeTo < tInfo.m_flBoundingTime) + if (!bSingleSplash) { - if (vSpherePoints.empty() || flTimeTo < -tInfo.m_flBoundingTime && (tInfo.m_flPrimeTime ? iSimTime > tInfo.m_iPrimeTime : true)) - break; - else if (tInfo.m_flPrimeTime ? iSimTime >= tInfo.m_iPrimeTime : true) - vSplashPoints = GetSplashPoints(target, vSpherePoints, tInfo, iSimTime); + bDirectBreaks = false; + + const float flTimeTo = solution.m_flTime - TICKS_TO_TIME(i); + if (flTimeTo < tInfo.m_flBoundingTime) + { + if (vSpherePoints.empty() || flTimeTo < -tInfo.m_flBoundingTime && (tInfo.m_flPrimeTime ? i > tInfo.m_iPrimeTime : true)) + break; + else if (tInfo.m_flPrimeTime ? i >= tInfo.m_iPrimeTime : true) + vSplashPoints = GetSplashPoints(target, vSpherePoints, tInfo, i); + } + } + else if (TICKS_TO_TIME(i) > solution.m_flTime && !bDoneRunningSplash) + { + vSplashPoints = GetSplashPoints(target, vSpherePoints, tInfo, i); + bDoneRunningSplash = true; } } } - else if (mDirectPoints.empty()) + if (bDirectBreaks && mDirectPoints.empty()) break; std::vector> vPoints = {}; @@ -1059,37 +1227,35 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase const bool bSplash = iIndex == -1; Vec3 vOriginalPoint = vPoint.m_vPoint; - /* - if (target.m_nAimedHitbox == HITBOX_HEAD) - vPoint.m_vPoint = PullPoint(vPoint.m_vPoint, tInfo.m_vLocalEye, tInfo, target.m_pEntity->m_vecMins(), target.m_pEntity->m_vecMaxs(), target.m_vPos); - */ + if (Vars::Aimbot::Projectile::HuntsmanPullPoint.Value && target.m_nAimedHitbox == HITBOX_HEAD) + vPoint.m_vPoint = PullPoint(vPoint.m_vPoint, tInfo.m_vLocalEye, tInfo, target.m_pEntity->m_vecMins() + projInfo.m_vHull, target.m_pEntity->m_vecMaxs() - projInfo.m_vHull, target.m_vPos); + //vPoint.m_vPoint = PullPoint(vPoint.m_vPoint, tInfo.m_vLocalEye, tInfo, target.m_pEntity->m_vecMins(), target.m_pEntity->m_vecMaxs(), target.m_vPos); float flDist = bSplash ? target.m_vPos.DistTo(vPoint.m_vPoint) : flLowestDist; bool bPriority = bSplash ? iPriority <= iLowestPriority : iPriority < iLowestPriority; - bool bTime = bSplash || tInfo.m_iPrimeTime < iSimTime || storage.m_MoveData.m_vecVelocity.IsZero(); + bool bTime = bSplash || tInfo.m_iPrimeTime < i || storage.m_MoveData.m_vecVelocity.IsZero(); bool bDist = !bSplash || flDist < flLowestDist; if (!bSplash && !bPriority) mDirectPoints.erase(iIndex); if (!bPriority || !bTime || !bDist) continue; - CalculateAngle(tInfo.m_vLocalEye, vPoint.m_vPoint, tInfo, iSimTime, vPoint.m_Solution); - /* - if (target.m_nAimedHitbox == HITBOX_HEAD) - { - Solution_t tSolution; - CalculateAngle(tInfo.m_vLocalEye, vOriginalPoint, tInfo, std::numeric_limits::max(), tSolution); - vPoint.m_Solution.m_flPitch = tSolution.m_flPitch, vPoint.m_Solution.m_flYaw = tSolution.m_flYaw; - } - */ + CalculateAngle(tInfo.m_vLocalEye, vPoint.m_vPoint, tInfo, i, vPoint.m_Solution); if (!bSplash && (vPoint.m_Solution.m_iCalculated == 1 || vPoint.m_Solution.m_iCalculated == 3)) mDirectPoints.erase(iIndex); if (vPoint.m_Solution.m_iCalculated != 1) continue; + if (Vars::Aimbot::Projectile::HuntsmanPullPoint.Value && target.m_nAimedHitbox == HITBOX_HEAD) + { + Solution_t tSolution; + CalculateAngle(tInfo.m_vLocalEye, vOriginalPoint, tInfo, std::numeric_limits::max(), tSolution); + vPoint.m_Solution.m_flPitch = tSolution.m_flPitch, vPoint.m_Solution.m_flYaw = tSolution.m_flYaw; + } + Vec3 vAngles = Aim(G::CurrentUserCmd->viewangles, { vPoint.m_Solution.m_flPitch, vPoint.m_Solution.m_flYaw, 0.f }); std::deque vProjLines; - if (TestAngle(pLocal, pWeapon, target, vPoint.m_vPoint, vAngles, iSimTime, bSplash, &vProjLines)) + if (TestAngle(pLocal, pWeapon, target, vPoint.m_vPoint, vAngles, i, bSplash, &vProjLines)) { iLowestPriority = iPriority; flLowestDist = flDist; vAngleTo = vAngles, vPredicted = target.m_vPos, vTarget = vOriginalPoint; @@ -1099,21 +1265,27 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase pPlayerPath->push_back(storage.m_MoveData.m_vecAbsOrigin); *pProjectilePath = vProjLines; } - else if (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth - && Vars::Aimbot::General::Smoothing.Value != 0.f - && Vars::Aimbot::General::Smoothing.Value != 100.f) + else { - bPriority = bSplash ? iPriority <= iLowestSmoothPriority : iPriority < flLowestSmoothDist; - bDist = !bSplash || flDist < flLowestDist; - if (!bPriority || !bDist) - continue; - - Vec3 vPlainAngles = Aim({}, { vPoint.m_Solution.m_flPitch, vPoint.m_Solution.m_flYaw, 0.f }, Vars::Aimbot::General::AimTypeEnum::Plain); - if (TestAngle(pLocal, pWeapon, target, vPoint.m_vPoint, vPlainAngles, iSimTime, bSplash)) + switch (Vars::Aimbot::General::AimType.Value) { - iLowestSmoothPriority = iPriority; flLowestSmoothDist = flDist; - target.m_vAngleTo = vAngles; - iReturn = 2; + case Vars::Aimbot::General::AimTypeEnum::Smooth: + case Vars::Aimbot::General::AimTypeEnum::Assistive: + if (Vars::Aimbot::General::AssistStrength.Value != 0.f && Vars::Aimbot::General::AssistStrength.Value != 100.f) + { + bPriority = bSplash ? iPriority <= iLowestSmoothPriority : iPriority < flLowestSmoothDist; + bDist = !bSplash || flDist < flLowestDist; + if (!bPriority || !bDist) + continue; + + Vec3 vPlainAngles = Aim({}, { vPoint.m_Solution.m_flPitch, vPoint.m_Solution.m_flYaw, 0.f }, Vars::Aimbot::General::AimTypeEnum::Plain); + if (TestAngle(pLocal, pWeapon, target, vPoint.m_vPoint, vPlainAngles, i, bSplash)) + { + iLowestSmoothPriority = iPriority; flLowestSmoothDist = flDist; + target.m_vAngleTo = vAngles; + iReturn = 2; + } + } } } } @@ -1169,7 +1341,7 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase pBoxes->push_back(bBox); } } - if (Vars::Debug::Info.Value && target.m_nAimedHitbox == HITBOX_HEAD) // huntsman head, broken; removeme once 236 is fixed + if (Vars::Debug::Info.Value && target.m_nAimedHitbox == HITBOX_HEAD) // huntsman head, broken; removeme once 254 is fixed { const Vec3 vOriginOffset = target.m_pEntity->m_vecOrigin() - vPredicted; @@ -1210,17 +1382,15 @@ Vec3 CAimbotProjectile::Aim(Vec3 vCurAngle, Vec3 vToAngle, int iMethod) vReturn = vToAngle; break; case Vars::Aimbot::General::AimTypeEnum::Smooth: - { - auto shortDist = [](const float flAngleA, const float flAngleB) - { - const float flDelta = fmodf((flAngleA - flAngleB), 360.f); - return fmodf(2 * flDelta, 360.f) - flDelta; - }; - const float t = 1.f - Vars::Aimbot::General::Smoothing.Value / 100.f; - vReturn.x = vCurAngle.x - shortDist(vCurAngle.x, vToAngle.x) * t; - vReturn.y = vCurAngle.y - shortDist(vCurAngle.y, vToAngle.y) * t; + vReturn = vCurAngle.LerpAngle(vToAngle, Vars::Aimbot::General::AssistStrength.Value / 100.f); + break; + case Vars::Aimbot::General::AimTypeEnum::Assistive: + Vec3 vMouseDelta = G::CurrentUserCmd->viewangles.DeltaAngle(G::LastUserCmd->viewangles); + Vec3 vTargetDelta = vToAngle.DeltaAngle(G::LastUserCmd->viewangles); + float flMouseDelta = vMouseDelta.Length2D(), flTargetDelta = vTargetDelta.Length2D(); + vTargetDelta = vTargetDelta.Normalized() * std::min(flMouseDelta, flTargetDelta); + vReturn = vCurAngle - vMouseDelta + vMouseDelta.LerpAngle(vTargetDelta, Vars::Aimbot::General::AssistStrength.Value / 100.f); break; - } } return vReturn; @@ -1233,6 +1403,7 @@ void CAimbotProjectile::Aim(CUserCmd* pCmd, Vec3& vAngle) { case Vars::Aimbot::General::AimTypeEnum::Plain: case Vars::Aimbot::General::AimTypeEnum::Smooth: + case Vars::Aimbot::General::AimTypeEnum::Assistive: //pCmd->viewangles = vAngle; // retarded, overshooting with this uncommented I::EngineClient->SetViewAngles(vAngle); break; @@ -1412,8 +1583,17 @@ bool CAimbotProjectile::RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser void CAimbotProjectile::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd) { const bool bSuccess = RunMain(pLocal, pWeapon, pCmd); -#if defined(SPLASH_DEBUG1) || defined(SPLASH_DEBUG2) || defined(SPLASH_DEBUG4) - SDK::Output("Traces", std::format("{}", G::LineStorage.size()).c_str()); +#if defined(SPLASH_DEBUG5) + if (Vars::Aimbot::General::AimType.Value && !mTraceCount.empty()) + { + int iTraceCount = 0; + for (auto& [_, iTraces] : mTraceCount) + iTraceCount += iTraces; + SDK::Output("Traces", std::format("{}", iTraceCount).c_str()); + for (auto& [sType, iTraces] : mTraceCount) + SDK::Output("Traces", std::format("{}: {}", sType, iTraces).c_str()); + } + mTraceCount.clear(); #endif float flAmount = 0.f; diff --git a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h index 1c5e5590..36d0d86e 100644 --- a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h +++ b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h @@ -26,7 +26,6 @@ struct Info_t Vec3 m_vTargetEye = {}; float m_flLatency = 0.f; - int m_iLatency = 0; Vec3 m_vHull = {}; Vec3 m_vOffset = {}; diff --git a/Amalgam/src/Features/Aimbot/AutoDetonate/AutoDetonate.cpp b/Amalgam/src/Features/Aimbot/AutoDetonate/AutoDetonate.cpp index 0bf73fa7..1a05aeb6 100644 --- a/Amalgam/src/Features/Aimbot/AutoDetonate/AutoDetonate.cpp +++ b/Amalgam/src/Features/Aimbot/AutoDetonate/AutoDetonate.cpp @@ -96,35 +96,28 @@ static inline bool CheckEntities(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUse if (vOrigin.DistTo(vPos) > flRadius) continue; - bool isPlayer = Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::Players - && pEntity->IsPlayer() && !F::AimbotGlobal.ShouldIgnore(pEntity->As(), pLocal, pWeapon); - bool isSentry = Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::Sentry - && pEntity->IsSentrygun(); - bool isDispenser = Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::Dispenser - && pEntity->IsDispenser(); - bool isTeleporter = Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::Teleporter - && pEntity->IsTeleporter(); - bool isSticky = Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::Stickies - && pEntity->GetClassID() == ETFClassID::CTFGrenadePipebombProjectile && pEntity->As()->HasStickyEffects() && (pWeapon->m_iItemDefinitionIndex() == Demoman_s_TheQuickiebombLauncher || pWeapon->m_iItemDefinitionIndex() == Demoman_s_TheScottishResistance); - bool isNPC = Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::NPCs - && pEntity->IsNPC(); - bool isBomb = Vars::Aimbot::General::Target.Value & Vars::Aimbot::General::TargetEnum::Bombs - && pEntity->IsBomb(); - if (isPlayer || isSentry || isDispenser || isTeleporter || isNPC || isBomb || isSticky) + if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon)) + continue; + + if (Vars::Aimbot::Projectile::AutoDetonate.Value & Vars::Aimbot::Projectile::AutoDetonateEnum::IgnoreCloak && pEntity->IsPlayer()) { - if (!SDK::VisPosProjectile(pProjectile, pEntity, vOrigin, isPlayer ? pEntity->GetAbsOrigin() + pEntity->As()->GetViewOffset() : pEntity->GetCenter(), MASK_SHOT)) + auto pPlayer = pEntity->As(); + if (pPlayer->IsInvisible() && pPlayer->GetInvisPercentage() >= Vars::Aimbot::General::IgnoreCloakPercentage.Value) continue; - - if (pCmd && pWeapon && pWeapon->m_iItemDefinitionIndex() == Demoman_s_TheScottishResistance) - { - Vec3 vAngleTo = Math::CalcAngle(pLocal->GetShootPos(), vOrigin); - SDK::FixMovement(pCmd, vAngleTo); - pCmd->viewangles = vAngleTo; - G::PSilentAngles = true; - } - - return true; } + + if (!SDK::VisPosProjectile(pProjectile, pEntity, vOrigin, pEntity->IsPlayer() ? pEntity->GetAbsOrigin() + pEntity->As()->GetViewOffset() : pEntity->GetCenter(), MASK_SHOT)) + continue; + + if (pCmd && pWeapon && pWeapon->m_iItemDefinitionIndex() == Demoman_s_TheScottishResistance) + { + Vec3 vAngleTo = Math::CalcAngle(pLocal->GetShootPos(), vOrigin); + SDK::FixMovement(pCmd, vAngleTo); + pCmd->viewangles = vAngleTo; + G::PSilentAngles = true; + } + + return true; } return false; @@ -167,7 +160,7 @@ static inline bool CheckLocal(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEn if (vOrigin.DistTo(vPos) > flRadius) return false; - if (!SDK::VisPosProjectile(pProjectile, pLocal, vOrigin, pLocal->GetAbsOrigin() + pLocal->m_vecViewOffset(), MASK_SHOT)) + if (!SDK::VisPosWorld(pProjectile, pLocal, vOrigin, pLocal->GetAbsOrigin() + pLocal->m_vecViewOffset(), MASK_SHOT)) return false; return true; diff --git a/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp b/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp index 41d73a56..26c912ea 100644 --- a/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp +++ b/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp @@ -184,10 +184,9 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p if (Vars::Debug::Info.Value) { //G::LineStorage.clear(); G::BoxStorage.clear(); - //G::LineStorage.push_back({ { vOriginal, trace.endpos }, I::GlobalVars->curtime + 5.f, {}, true }); - G::LineStorage.push_back({ { pLocal->GetShootPos(), trace.endpos}, I::GlobalVars->curtime + 5.f, {}, true }); Vec3 angles; Math::VectorAngles(trace.plane.normal, angles); - G::BoxStorage.push_back({ trace.endpos, { -1.f, -1.f, -1.f }, { 1.f, 1.f, 1.f }, angles, I::GlobalVars->curtime + 5.f, {}, { 0, 0, 0, 0 }, true }); + G::BoxStorage.push_back({ trace.endpos + trace.plane.normal, { -1.f, -1.f, -1.f }, { 1.f, 1.f, 1.f }, angles, I::GlobalVars->curtime + 5.f, {}, { 0, 0, 0, 0 }, true }); + G::LineStorage.push_back({ { localStorage.m_MoveData.m_vecAbsOrigin + pLocal->m_vecViewOffset(), trace.endpos + trace.plane.normal }, I::GlobalVars->curtime + 5.f, {}, true }); } } diff --git a/Amalgam/src/Features/Backtrack/Backtrack.cpp b/Amalgam/src/Features/Backtrack/Backtrack.cpp index ab28eed3..86ddb942 100644 --- a/Amalgam/src/Features/Backtrack/Backtrack.cpp +++ b/Amalgam/src/Features/Backtrack/Backtrack.cpp @@ -37,7 +37,7 @@ float CBacktrack::GetReal(int iFlow, bool bNoFake) if (!pNetChan) return 0.f; - if (iFlow != -1) + if (iFlow != MAX_FLOWS) return pNetChan->GetLatency(iFlow) - (bNoFake && iFlow == FLOW_INCOMING ? m_flFakeLatency : 0.f); return pNetChan->GetLatency(FLOW_INCOMING) + pNetChan->GetLatency(FLOW_OUTGOING) - (bNoFake ? m_flFakeLatency : 0.f); } @@ -121,8 +121,8 @@ std::deque CBacktrack::GetValidRecords(std::deque* pReco if (!pNetChan) return vRecords; - float flCorrect = std::clamp(pNetChan->GetLatency(FLOW_OUTGOING) + pNetChan->GetLatency(FLOW_INCOMING) + ROUND_TO_TICKS(m_flFakeInterp), 0.f, m_flMaxUnlag); - int iServerTick = m_iTickCount + GetAnticipatedChoke() + Vars::Backtrack::Offset.Value + TIME_TO_TICKS(pNetChan->GetLatency(FLOW_OUTGOING)); + float flCorrect = std::clamp(F::Backtrack.GetReal(MAX_FLOWS, false) + ROUND_TO_TICKS(m_flFakeInterp), 0.f, m_flMaxUnlag); + int iServerTick = m_iTickCount + GetAnticipatedChoke() + Vars::Backtrack::Offset.Value + TIME_TO_TICKS(F::Backtrack.GetReal(FLOW_OUTGOING)); for (auto& tRecord : *pRecords) { @@ -278,10 +278,12 @@ void CBacktrack::Run(CUserCmd* pCmd) void CBacktrack::ResolverUpdate(CBaseEntity* pEntity) { + /* if (!pEntity) return; m_mRecords[pEntity].clear(); + */ } void CBacktrack::ReportShot(int iIndex) diff --git a/Amalgam/src/Features/Backtrack/Backtrack.h b/Amalgam/src/Features/Backtrack/Backtrack.h index 758e5c59..84e935aa 100644 --- a/Amalgam/src/Features/Backtrack/Backtrack.h +++ b/Amalgam/src/Features/Backtrack/Backtrack.h @@ -54,7 +54,7 @@ class CBacktrack public: float GetLerp(); float GetFake(); - float GetReal(int iFlow = -1, bool bNoFake = true); + float GetReal(int iFlow = MAX_FLOWS, bool bNoFake = true); int GetAnticipatedChoke(int iMethod = Vars::Aimbot::General::AimType.Value); std::deque* GetRecords(CBaseEntity* pEntity); diff --git a/Amalgam/src/Features/Binds/Binds.cpp b/Amalgam/src/Features/Binds/Binds.cpp index 9d58ffc7..5a6dbe2c 100644 --- a/Amalgam/src/Features/Binds/Binds.cpp +++ b/Amalgam/src/Features/Binds/Binds.cpp @@ -17,6 +17,24 @@ void CBinds::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) if (G::Unload || !F::Configs.m_bConfigLoaded) return; + for (int iKey = 0; iKey < 256; iKey++) + { + // don't delay inputs for binds + auto& tKey = m_mKeyStorage[iKey]; + + bool bOldIsDown = tKey.m_bIsDown; + bool bOldIsPressed = tKey.m_bIsPressed; + bool bOldIsDouble = tKey.m_bIsDouble; + bool bOldIsReleased = tKey.m_bIsReleased; + + U::KeyHandler.StoreKey(iKey, &tKey); + + tKey.m_bIsDown = tKey.m_bIsDown || bOldIsDown; + tKey.m_bIsPressed = tKey.m_bIsPressed || bOldIsPressed; + tKey.m_bIsDouble = tKey.m_bIsDouble || bOldIsDouble; + tKey.m_bIsReleased = tKey.m_bIsReleased || bOldIsReleased; + } + auto setVars = [](int iBind) { const bool bDefault = iBind == DEFAULT_BIND; @@ -123,6 +141,7 @@ void CBinds::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) }; getBinds(DEFAULT_BIND); + // clear inputs for binds for (int iKey = 0; iKey < 256; iKey++) U::KeyHandler.StoreKey(iKey, &m_mKeyStorage[iKey]); } diff --git a/Amalgam/src/Features/Configs/Configs.cpp b/Amalgam/src/Features/Configs/Configs.cpp index 252421d4..0c163ef9 100644 --- a/Amalgam/src/Features/Configs/Configs.cpp +++ b/Amalgam/src/Features/Configs/Configs.cpp @@ -190,7 +190,9 @@ void CConfigs::LoadJson(boost::property_tree::ptree& mapTree, std::string sName, // remove invalid materials for (auto it = val.begin(); it != val.end();) { - if (FNV1A::Hash32(it->first.c_str()) == FNV1A::Hash32Const("None") || FNV1A::Hash32(it->first.c_str()) != FNV1A::Hash32Const("Original") && !F::Materials.m_mMaterials.contains(FNV1A::Hash32(it->first.c_str()))) + auto uHash = FNV1A::Hash32(it->first.c_str()); + if (uHash == FNV1A::Hash32Const("None") + || uHash != FNV1A::Hash32Const("Original") && !F::Materials.m_mMaterials.contains(uHash)) it = val.erase(it); else ++it; diff --git a/Amalgam/src/Features/CritHack/CritHack.cpp b/Amalgam/src/Features/CritHack/CritHack.cpp index 76aa5c28..efa01e73 100644 --- a/Amalgam/src/Features/CritHack/CritHack.cpp +++ b/Amalgam/src/Features/CritHack/CritHack.cpp @@ -96,6 +96,8 @@ void CCritHack::GetTotalCrits(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) return; auto& tStorage = m_mStorage[iSlot]; + if (!tStorage.m_bActive) + return; static float flOldBucket = 0.f; static int iOldID = 0, iOldCritChecks = 0, iOldCritSeedRequests = 0; const float flBucket = pWeapon->m_flCritTokenBucket(); const int iID = pWeapon->GetWeaponID(), iCritChecks = pWeapon->m_nCritChecks(), iCritSeedRequests = pWeapon->m_nCritSeedRequests(); @@ -319,6 +321,8 @@ void CCritHack::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd) return; auto& tStorage = m_mStorage[iSlot]; + if (!tStorage.m_bActive) + return; if (pWeapon->GetWeaponID() == TF_WEAPON_MINIGUN && pCmd->buttons & IN_ATTACK) pCmd->buttons &= ~IN_ATTACK2; @@ -339,14 +343,8 @@ void CCritHack::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd) int closestCrit = !tStorage.m_vCritCommands.empty() ? tStorage.m_vCritCommands.front() : 0; int closestSkip = !tStorage.m_vSkipCommands.empty() ? tStorage.m_vSkipCommands.front() : 0; - //static bool bFirstTimePredicted = true; - //if (!I::ClientState->chokedcommands) - // bFirstTimePredicted = true; - //if (bAttacking && bFirstTimePredicted) if (bAttacking) { - // bFirstTimePredicted = false; - const bool bCanCrit = tStorage.m_iAvailableCrits > 0 && (!m_bCritBanned || pWeapon->GetSlot() == SLOT_MELEE) && !bStreamWait; const bool bPressed = Vars::CritHack::ForceCrits.Value || pWeapon->GetSlot() == SLOT_MELEE && Vars::CritHack::AlwaysMeleeCrit.Value && (Vars::Aimbot::General::AutoShoot.Value ? pCmd->buttons & IN_ATTACK && !(G::Buttons & IN_ATTACK) : Vars::Aimbot::General::AimType.Value); if (bCanCrit && bPressed && closestCrit) @@ -354,8 +352,6 @@ void CCritHack::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd) else if (Vars::CritHack::AvoidRandom.Value && closestSkip) pCmd->command_number = closestSkip; } - //else if (Vars::CritHack::AvoidRandom.Value && closestSkip) - // pCmd->command_number = closestSkip; //if (pCmd->command_number == closestCrit || pCmd->command_number == closestSkip) m_iWishRandomSeed = MD5_PseudoRandom(pCmd->command_number) & std::numeric_limits::max(); @@ -397,15 +393,6 @@ bool CCritHack::CalcIsAttackCriticalHandler(CTFPlayer* pLocal, CTFWeaponBase* pW if (!I::Prediction->m_bFirstTimePredicted || !pLocal || !pWeapon) return false; - if (pWeapon->GetWeaponID() == TF_WEAPON_MINIGUN || pWeapon->GetWeaponID() == TF_WEAPON_FLAMETHROWER) - { - static int iStaticAmmo = pLocal->GetAmmoCount(pWeapon->m_iPrimaryAmmoType()); - int iOldAmmo = iStaticAmmo; - int iNewAmmo = iStaticAmmo = pLocal->GetAmmoCount(pWeapon->m_iPrimaryAmmoType()); - if (iOldAmmo == iNewAmmo) - return false; - } - if (m_iWishRandomSeed) { *G::RandomSeed() = m_iWishRandomSeed; @@ -506,6 +493,9 @@ void CCritHack::Draw(CTFPlayer* pLocal) else { auto& tStorage = m_mStorage[iSlot]; + if (!tStorage.m_bActive) + return; + auto bRapidFire = pWeapon->IsRapidFire(); float flTickBase = TICKS_TO_TIME(pLocal->m_nTickBase()); diff --git a/Amalgam/src/Features/ImGui/Menu/Components.h b/Amalgam/src/Features/ImGui/Menu/Components.h index c5877091..eb982bb8 100644 --- a/Amalgam/src/Features/ImGui/Menu/Components.h +++ b/Amalgam/src/Features/ImGui/Menu/Components.h @@ -1812,8 +1812,6 @@ namespace ImGui } // convar wrappers - bool OldDisabled, OldTransparent; - template inline int GetBind(ConfigVar& var, bool bForce = false) { @@ -1846,14 +1844,16 @@ namespace ImGui return var.Map[iParent]; } + bool bPushedDisabled = false, bPushedTransparent = false; + template inline T FGet(ConfigVar& var, bool bDisable = false) { - OldDisabled = Disabled, OldTransparent = Transparent; - int iBind = GetBind(var); if (bDisable) { + bPushedDisabled = false, bPushedTransparent = false; + if (CurrentBind == DEFAULT_BIND) { if (Vars::Menu::MenuShowsBinds.Value && var.Map[DEFAULT_BIND] != var.Value) @@ -1865,14 +1865,18 @@ namespace ImGui if (tVal == var.Value) { - Disabled = true; + PushDisabled(true); + bPushedDisabled = true; return tVal; } } } } else - Transparent = CurrentBind != iBind && !(var.m_iFlags & (NOSAVE | NOBIND)); + { + PushTransparent(CurrentBind != iBind && !(var.m_iFlags & (NOSAVE | NOBIND))); + bPushedTransparent = true; + } } return var.Map[iBind]; } @@ -1899,7 +1903,10 @@ namespace ImGui } } - Disabled = OldDisabled, Transparent = OldTransparent; + if (bPushedDisabled) + PopDisabled(); + if (bPushedTransparent) + PopTransparent(); } template diff --git a/Amalgam/src/Features/ImGui/Menu/Menu.cpp b/Amalgam/src/Features/ImGui/Menu/Menu.cpp index 9e334906..52aa4337 100644 --- a/Amalgam/src/Features/ImGui/Menu/Menu.cpp +++ b/Amalgam/src/Features/ImGui/Menu/Menu.cpp @@ -132,13 +132,13 @@ void CMenu::MenuAimbot() TableNextColumn(); if (Section("General")) { - FDropdown("Aim type", Vars::Aimbot::General::AimType, { "Off", "Plain", "Smooth", "Silent", "Locking" }, {}, FDropdown_Left); + FDropdown("Aim type", Vars::Aimbot::General::AimType, { "Off", "Plain", "Smooth", "Silent", "Locking", "Assistive" }, {}, FDropdown_Left); FDropdown("Target selection", Vars::Aimbot::General::TargetSelection, { "FOV", "Distance" }, {}, FDropdown_Right); FDropdown("Target", Vars::Aimbot::General::Target, { "Players", "Sentries", "Dispensers", "Teleporters", "Stickies", "NPCs", "Bombs" }, {}, FDropdown_Multi | FDropdown_Left); FDropdown("Ignore", Vars::Aimbot::General::Ignore, { "Friends", "Party", "Invulnerable", "Cloaked", "Unsimulated players", "Dead Ringer", "Vaccinator", "Disguised", "Taunting" }, {}, FDropdown_Multi | FDropdown_Right); FSlider("Aim FOV", Vars::Aimbot::General::AimFOV, 0.f, 180.f, 1.f, "%g", FSlider_Clamp | FSlider_Precision); - PushTransparent(FGet(Vars::Aimbot::General::AimType) != Vars::Aimbot::General::AimTypeEnum::Smooth); - FSlider("Smoothing## Hitscan", Vars::Aimbot::General::Smoothing, 0.f, 100.f, 1.f, "%g%%", FSlider_Clamp | FSlider_Precision); + PushTransparent(FGet(Vars::Aimbot::General::AimType) != Vars::Aimbot::General::AimTypeEnum::Smooth && FGet(Vars::Aimbot::General::AimType) != Vars::Aimbot::General::AimTypeEnum::Assistive); + FSlider("Assist strength", Vars::Aimbot::General::AssistStrength, 0.f, 100.f, 1.f, "%g%%", FSlider_Clamp | FSlider_Precision); PopTransparent(); FSlider("Max targets", Vars::Aimbot::General::MaxTargets, 1, 6, 1, "%i", FSlider_Min); PushTransparent(!(FGet(Vars::Aimbot::General::Ignore) & Vars::Aimbot::General::IgnoreEnum::Cloaked)); @@ -195,20 +195,29 @@ void CMenu::MenuAimbot() TableNextColumn(); if (Section("Hitscan")) { - FDropdown("Hitboxes", Vars::Aimbot::Hitscan::Hitboxes, { "Head", "Body", "Pelvis", "Arms", "Legs" }, { 1 << 0, 1 << 2, 1 << 1, 1 << 3, 1 << 4 }, FDropdown_Multi, 0, nullptr, "Hitscan hitboxes"); - FDropdown("Modifiers## Hitscan", Vars::Aimbot::Hitscan::Modifiers, { "Tapfire", "Wait for headshot", "Wait for charge", "Scoped only", "Auto scope", "Bodyaim if lethal", "Auto rev minigun", "Extinguish team" }, {}, FDropdown_Multi, 0, nullptr, "Hitscan modifiers"); + FDropdown("Hitboxes## Hitscan", Vars::Aimbot::Hitscan::Hitboxes, { "Head", "Body", "Pelvis", "Arms", "Legs", "##Divider", "Bodyaim if lethal" }, {}, FDropdown_Multi | FDropdown_Left, 0, nullptr, "Hitscan hitboxes"); + FDropdown("Modifiers## Hitscan", Vars::Aimbot::Hitscan::Modifiers, { "Tapfire", "Wait for headshot", "Wait for charge", "Scoped only", "Auto scope", "Auto rev minigun", "Extinguish team" }, {}, FDropdown_Multi | FDropdown_Right, 0, nullptr, "Hitscan modifiers"); FSlider("Point scale", Vars::Aimbot::Hitscan::PointScale, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); PushTransparent(!(FGet(Vars::Aimbot::Hitscan::Modifiers) & Vars::Aimbot::Hitscan::ModifiersEnum::Tapfire)); FSlider("Tapfire distance", Vars::Aimbot::Hitscan::TapFireDist, 250.f, 1000.f, 50.f, "%g", FSlider_Min | FSlider_Precision); PopTransparent(); } EndSection(); + if (Vars::Debug::Info.Value) + { + if (Section("debug## hitscan")) + { + FSlider("bone size subtract", Vars::Aimbot::Hitscan::BoneSizeSubtract, 0.f, 4.f, 0.25f, "%g", FSlider_Min); + FSlider("bone size minimum scale", Vars::Aimbot::Hitscan::BoneSizeMinimumScale, 0.f, 1.f, 0.1f, "%g", FSlider_Clamp); + } EndSection(); + } if (Section("Projectile")) { FDropdown("Predict", Vars::Aimbot::Projectile::StrafePrediction, { "Air strafing", "Ground strafing" }, {}, FDropdown_Multi | FDropdown_Left); FDropdown("Splash", Vars::Aimbot::Projectile::SplashPrediction, { "Off", "Include", "Prefer", "Only" }, {}, FDropdown_Right); - FDropdown("Auto detonate", Vars::Aimbot::Projectile::AutoDetonate, { "Stickies", "Flares", "##Divider", "Ignore self damage" }, {}, FDropdown_Multi | FDropdown_Left); + FDropdown("Auto detonate", Vars::Aimbot::Projectile::AutoDetonate, { "Stickies", "Flares", "##Divider", "Prevent self damage", "Ignore cloak" }, {}, FDropdown_Multi | FDropdown_Left); FDropdown("Auto airblast", Vars::Aimbot::Projectile::AutoAirblast, { "Enabled", "##Divider", "Redirect simple", "Redirect advanced", "##Divider", "Respect FOV"}, {}, FDropdown_Multi | FDropdown_Right); // todo: finish redirect advanced!! - FDropdown("Modifiers## Projectile", Vars::Aimbot::Projectile::Modifiers, { "Charge shot", "Cancel charge", "Bodyaim if lethal", "Use prime time", "Aim blast at feet" }, {}, FDropdown_Multi, 0, nullptr, "Projectile modifiers"); + FDropdown("Hitboxes## Projectile", Vars::Aimbot::Projectile::Hitboxes, { "Auto", "##Divider", "Head", "Body", "Feet", "##Divider", "Bodyaim if lethal", "Aim blast at feet" }, {}, FDropdown_Multi | FDropdown_Left, 0, nullptr, "Projectile hitboxes"); + FDropdown("Modifiers## Projectile", Vars::Aimbot::Projectile::Modifiers, { "Charge shot", "Cancel charge", "Use prime time" }, {}, FDropdown_Multi | FDropdown_Right, 0, nullptr, "Projectile modifiers"); FSlider("Max simulation time", Vars::Aimbot::Projectile::PredictionTime, 0.1f, 10.f, 0.25f, "%gs", FSlider_Min | FSlider_Precision); PushTransparent(!FGet(Vars::Aimbot::Projectile::StrafePrediction)); FSlider("Hit chance", Vars::Aimbot::Projectile::Hitchance, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); @@ -254,15 +263,20 @@ void CMenu::MenuAimbot() FSlider("huntsman add", Vars::Aimbot::Projectile::HuntsmanAdd, 0.f, 20.f, 1.f, "%g", FSlider_Left | FSlider_Clamp | FSlider_Precision); FSlider("huntsman add low", Vars::Aimbot::Projectile::HuntsmanAddLow, 0.f, 20.f, 1.f, "%g", FSlider_Right | FSlider_Clamp | FSlider_Precision); FSlider("huntsman clamp", Vars::Aimbot::Projectile::HuntsmanClamp, 0.f, 10.f, 0.5f, "%g", FSlider_Left | FSlider_Clamp | FSlider_Precision); + FToggle("huntsman pull point", Vars::Aimbot::Projectile::HuntsmanPullPoint, FToggle_Right); + SetCursorPosY(GetCursorPosY() + 8); - FToggle("splash grates", Vars::Aimbot::Projectile::SplashGrates, FToggle_Left); - bool bHovered; FDropdown("rocket splash mode", Vars::Aimbot::Projectile::RocketSplashMode, { "regular", "special light", "special heavy" }, {}, FDropdown_Right, 0, &bHovered); - FTooltip("special splash type for rockets, more expensive", bHovered); - SetCursorPosY(GetCursorPosY() - 24); FSlider("splash points", Vars::Aimbot::Projectile::SplashPoints, 1, 400, 5, "%i", FSlider_Left | FSlider_Min); + FToggle("splash grates", Vars::Aimbot::Projectile::SplashGrates, FToggle_Right); + SetCursorPosY(GetCursorPosY() + 8); FSlider("direct splash count", Vars::Aimbot::Projectile::SplashCountDirect, 1, 100, 1, "%i", FSlider_Left | FSlider_Min); FSlider("arc splash count", Vars::Aimbot::Projectile::SplashCountArc, 1, 100, 1, "%i", FSlider_Right | FSlider_Min); FSlider("splash trace interval", Vars::Aimbot::Projectile::SplashTraceInterval, 1, 10, 1, "%i", FSlider_Left); + bool bHovered; + FDropdown("splash mode", Vars::Aimbot::Projectile::SplashMode, { "multi", "single" }, {}, FDropdown_Left, 0, & bHovered); + FTooltip("debug option to test performance,\nleave on multi if you want splash to work properly", bHovered); + FDropdown("rocket splash mode", Vars::Aimbot::Projectile::RocketSplashMode, { "regular", "special light", "special heavy" }, {}, FDropdown_Right, 0, &bHovered); + FTooltip("special splash type for rockets, more expensive", bHovered); FSlider("delta count", Vars::Aimbot::Projectile::DeltaCount, 1, 5, 1, "%i", FSlider_Left); FDropdown("delta mode", Vars::Aimbot::Projectile::DeltaMode, { "average", "max" }, {}, FDropdown_Right); } EndSection(); @@ -2205,11 +2219,11 @@ void CMenu::MenuSettings() FColorPicker("Color", &tTag.Color, 0, FColorPicker_Dropdown); PushDisabled(iID == DEFAULT_TAG || iID == IGNORED_TAG); - int iLabel = Disabled ? 0 : tTag.Label; - FDropdown("Type", &iLabel, { "Priority", "Label" }, {}, FDropdown_Right); - tTag.Label = iLabel; - if (Disabled) - tTag.Label = false; + int iLabel = Disabled ? 0 : tTag.Label; + FDropdown("Type", &iLabel, { "Priority", "Label" }, {}, FDropdown_Right); + tTag.Label = iLabel; + if (Disabled) + tTag.Label = false; PopDisabled(); } EndChild(); @@ -2226,7 +2240,7 @@ void CMenu::MenuSettings() SetCursorPos({ GetWindowWidth() - H::Draw.Scale(96), H::Draw.Scale(8) }); PushDisabled(tTag.Name.empty()); - bCreate = FButton("##CreateButton", FButton_None, { 40, 40 }); + bCreate = FButton("##CreateButton", FButton_None, { 40, 40 }); PopDisabled(); SetCursorPos({ GetWindowWidth() - H::Draw.Scale(84), H::Draw.Scale(28) }); PushTransparent(tTag.Name.empty()); @@ -2561,7 +2575,7 @@ void CMenu::AddDraggable(const char* sTitle, ConfigVar& var, bool bSh return; static std::unordered_map> old = {}; - DragBox_t info = FGet(var); + DragBox_t info = FGet(var, true); const float sizeX = H::Draw.Scale(100), sizeY = H::Draw.Scale(40); SetNextWindowSize({ sizeX, sizeY }, ImGuiCond_Always); if (!old.contains(sTitle) || info != old[sTitle].first || sizeX != old[sTitle].second) @@ -2599,7 +2613,7 @@ void CMenu::DrawBinds() return; static DragBox_t old = { -2147483648, -2147483648 }; - DragBox_t info = m_bIsOpen ? FGet(Vars::Menu::BindsDisplay) : Vars::Menu::BindsDisplay.Value; + DragBox_t info = m_bIsOpen ? FGet(Vars::Menu::BindsDisplay, true) : Vars::Menu::BindsDisplay.Value; if (info != old) SetNextWindowPos({ float(info.x), float(info.y) }, ImGuiCond_Always); @@ -2786,7 +2800,7 @@ void CMenu::DrawCameraWindow() return; static WindowBox_t old = { -2147483648, -2147483648 }; - WindowBox_t info = FGet(Vars::Visuals::Simulation::ProjectileWindow); + WindowBox_t info = FGet(Vars::Visuals::Simulation::ProjectileWindow, true); if (info != old) { SetNextWindowPos({ float(info.x), float(info.y) }, ImGuiCond_Always); @@ -2827,7 +2841,7 @@ void CMenu::DrawRadar() return; static WindowBox_t old = { -2147483648, -2147483648 }; - WindowBox_t info = FGet(Vars::Radar::Main::Window); + WindowBox_t info = FGet(Vars::Radar::Main::Window, true); if (info != old) { SetNextWindowPos({ float(info.x), float(info.y) }, ImGuiCond_Always); @@ -2864,19 +2878,8 @@ void CMenu::Render() using namespace ImGui; for (int iKey = 0; iKey < 256; iKey++) - { U::KeyHandler.StoreKey(iKey); - // don't drop inputs for binds - auto& tMainKey = U::KeyHandler.m_mKeyStorage[iKey]; - auto& tBindKey = F::Binds.m_mKeyStorage[iKey]; - tBindKey.m_bIsDown = tMainKey.m_bIsDown || tBindKey.m_bIsDown; - tBindKey.m_bIsPressed = tMainKey.m_bIsPressed || tBindKey.m_bIsPressed; - tBindKey.m_bIsDouble = tMainKey.m_bIsDouble || tBindKey.m_bIsDouble; - tBindKey.m_bIsReleased = tMainKey.m_bIsReleased || tBindKey.m_bIsReleased; - tBindKey.m_dPressTime = tMainKey.m_dPressTime; - } - if (!F::Configs.m_bConfigLoaded || !(ImGui::GetIO().DisplaySize.x > 160.f && ImGui::GetIO().DisplaySize.y > 28.f)) return; @@ -2901,8 +2904,19 @@ void CMenu::Render() AddDraggable("Seed prediction", Vars::Menu::SeedPredictionDisplay, FGet(Vars::Menu::Indicators) & Vars::Menu::IndicatorsEnum::SeedPrediction); F::Render.Cursor = GetMouseCursor(); - //vDisabled.clear(); - //vTransparent.clear(); + + if (!vDisabled.empty()) + { + IM_ASSERT_USER_ERROR(0, "Calling PopDisabled() too little times: stack overflow."); + Disabled = false; + vDisabled.clear(); + } + if (!vTransparent.empty()) + { + IM_ASSERT_USER_ERROR(0, "Calling PopTransparent() too little times: stack overflow."); + Transparent = false; + vTransparent.clear(); + } } else mActiveMap.clear(); diff --git a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp index bfeae5ee..adb3c488 100644 --- a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp +++ b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp @@ -3,7 +3,7 @@ #include "../../EnginePrediction/EnginePrediction.h" #include "../../CritHack/CritHack.h" -bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& out, int iFlags, float flAutoCharge) +bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& tInfo, int iFlags, float flAutoCharge) { if (!pPlayer || !pPlayer->IsAlive() || pPlayer->IsAGhost() || pPlayer->IsTaunting() || !pWeapon) return false; @@ -73,7 +73,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap if (Vars::Visuals::Trajectory::Overwrite.Value) { SDK::GetProjectileFireSetup(pPlayer, vAngles, { Vars::Visuals::Trajectory::OffX.Value, Vars::Visuals::Trajectory::OffY.Value, Vars::Visuals::Trajectory::OffZ.Value }, vPos, vAngle, !bTrace ? true : Vars::Visuals::Trajectory::Pipes.Value, bQuick); - out = { TF_PROJECTILE_NONE, 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::NoSpin.Value, Vars::Visuals::Trajectory::LifeTime.Value }; + tInfo = { TF_PROJECTILE_NONE, 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::NoSpin.Value, Vars::Visuals::Trajectory::LifeTime.Value }; return true; } @@ -84,7 +84,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap { 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); float flSpeed = pPlayer->InCond(TF_COND_RUNE_PRECISION) ? 3000.f : SDK::AttribHookValue(1100.f, "mult_projectile_speed", pWeapon); - out = { TF_PROJECTILE_ROCKET, vPos, vAngle, { 0.f, 0.f, 0.f }, flSpeed, 0.f, true }; + tInfo = { TF_PROJECTILE_ROCKET, vPos, vAngle, { 0.f, 0.f, 0.f }, flSpeed, 0.f, true }; return true; } case TF_WEAPON_PARTICLE_CANNON: @@ -97,7 +97,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap if (pWeapon->GetWeaponID() == TF_WEAPON_DRG_POMSON) vPos.z -= 13.f; float flSpeed = bCowMangler ? 1100.f : 1200.f; - out = { TF_PROJECTILE_ENERGY_RING, vPos, vAngle, bCowMangler ? Vec3() : Vec3(1.f, 1.f, 1.f), flSpeed, 0.f, true }; + tInfo = { TF_PROJECTILE_ENERGY_RING, vPos, vAngle, bCowMangler ? Vec3() : Vec3(1.f, 1.f, 1.f), flSpeed, 0.f, true }; return true; } case TF_WEAPON_GRENADELAUNCHER: // vphysics projectiles affected by server start gravity @@ -111,7 +111,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap float flLifetime = flMortar ? pWeapon->As()->m_flDetonateTime() > 0.f ? pWeapon->As()->m_flDetonateTime() - I::GlobalVars->curtime : flMortar : SDK::AttribHookValue(2.2f, "fuse_mult", pWeapon); - out = { bCannon ? TF_PROJECTILE_CANNONBALL : TF_PROJECTILE_PIPEBOMB, vPos, vAngle, { 6.f, 6.f, 6.f }, flSpeed, 1.f, pWeapon->m_iItemDefinitionIndex() == Demoman_m_TheLochnLoad, flLifetime }; + tInfo = { bCannon ? TF_PROJECTILE_CANNONBALL : TF_PROJECTILE_PIPEBOMB, vPos, vAngle, { 6.f, 6.f, 6.f }, flSpeed, 1.f, pWeapon->m_iItemDefinitionIndex() == Demoman_m_TheLochnLoad, flLifetime }; return true; } case TF_WEAPON_PIPEBOMBLAUNCHER: @@ -121,19 +121,19 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap ? SDK::AttribHookValue(4.f, "stickybomb_charge_rate", pWeapon) * flAutoCharge : (pWeapon->As()->m_flChargeBeginTime() > 0.f ? I::GlobalVars->curtime - pWeapon->As()->m_flChargeBeginTime() : 0.f); float flSpeed = Math::RemapValClamped(flCharge, 0.f, SDK::AttribHookValue(4.f, "stickybomb_charge_rate", pWeapon), 900.f, 2400.f); - out = { TF_PROJECTILE_PIPEBOMB_REMOTE, vPos, vAngle, { 6.f, 6.f, 6.f }, flSpeed, 1.f, false }; + tInfo = { TF_PROJECTILE_PIPEBOMB_REMOTE, vPos, vAngle, { 6.f, 6.f, 6.f }, flSpeed, 1.f, false }; return true; } case TF_WEAPON_FLAREGUN: { SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 12.f, bDucking ? 8.f : -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); - out = { TF_PROJECTILE_FLARE, vPos, vAngle, { 1.f, 1.f, 1.f }, SDK::AttribHookValue(2000.f, "mult_projectile_speed", pWeapon), 0.3f * flGravity, true}; + tInfo = { TF_PROJECTILE_FLARE, vPos, vAngle, { 1.f, 1.f, 1.f }, SDK::AttribHookValue(2000.f, "mult_projectile_speed", pWeapon), 0.3f * flGravity, true}; 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); - out = { TF_PROJECTILE_FLARE, vPos, vAngle, { 1.f, 1.f, 1.f }, 3000.f, 0.45f * flGravity, true }; + tInfo = { TF_PROJECTILE_FLARE, vPos, vAngle, { 1.f, 1.f, 1.f }, 3000.f, 0.45f * flGravity, true }; return true; } case TF_WEAPON_COMPOUND_BOW: @@ -142,30 +142,30 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap float flCharge = pWeapon->As()->m_flChargeBeginTime() > 0.f ? I::GlobalVars->curtime - pWeapon->As()->m_flChargeBeginTime() : 0.f; float flSpeed = Math::RemapValClamped(flCharge, 0.f, 1.f, 1800.f, 2600.f); flGravity = Math::RemapValClamped(flCharge, 0.f, 1.f, 0.5f, 0.1f) * flGravity; - out = { TF_PROJECTILE_ARROW, vPos, vAngle, { 1.f, 1.f, 1.f }, flSpeed, flGravity, true, 10.f /*arrows have some lifetime check for whatever reason*/ }; + tInfo = { TF_PROJECTILE_ARROW, vPos, vAngle, { 1.f, 1.f, 1.f }, flSpeed, flGravity, true, 10.f /*arrows have some lifetime check for whatever reason*/ }; return true; } case TF_WEAPON_CROSSBOW: case TF_WEAPON_SHOTGUN_BUILDING_RESCUE: { SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, 8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); - out = { TF_PROJECTILE_ARROW, 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, true, 10.f /*arrows have some lifetime check for whatever reason*/ }; + tInfo = { TF_PROJECTILE_ARROW, 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, true, 10.f /*arrows have some lifetime check for whatever reason*/ }; return true; } case TF_WEAPON_SYRINGEGUN_MEDIC: { SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 6.f, -8.f }, vPos, vAngle, !bTrace ? true : false, bQuick); - out = { TF_PROJECTILE_SYRINGE, vPos, vAngle, { 1.f, 1.f, 1.f }, 1000.f, 0.3f * flGravity, true }; + tInfo = { TF_PROJECTILE_SYRINGE, vPos, vAngle, { 1.f, 1.f, 1.f }, 1000.f, 0.3f * flGravity, true }; return true; } - case TF_WEAPON_FLAMETHROWER: // this inherits player velocity, possibly account for + case TF_WEAPON_FLAMETHROWER: { static auto tf_flamethrower_boxsize = U::ConVars.FindVar("tf_flamethrower_boxsize"); const float flHull = tf_flamethrower_boxsize ? tf_flamethrower_boxsize->GetFloat() : 12.f; bool bFlipped = cl_flipviewmodels ? cl_flipviewmodels->GetBool() : false; - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 40.f, bFlipped ? -5.f : 5.f /*doesn't flip*/, 0.f}, vPos, vAngle, true, bQuick); - out = { TF_PROJECTILE_FLAME_ROCKET, vPos, vAngle, { flHull, flHull, flHull }, 1000.f, 0.f, true, 0.33f }; + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 40.f, bFlipped ? -5.f : 5.f /*doesn't flip*/, 0.f }, vPos, vAngle, true, bQuick); + tInfo = { TF_PROJECTILE_FLAME_ROCKET, vPos, vAngle, { flHull, flHull, flHull }, 1000.f, 0.f, true, 0.285f }; return true; } case TF_WEAPON_FLAME_BALL: @@ -173,13 +173,13 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap bool bFlipped = cl_flipviewmodels ? cl_flipviewmodels->GetBool() : false; SDK::GetProjectileFireSetup(pPlayer, vAngles, { 70.f, bFlipped ? -7.f : 7.f /*doesn't flip*/, -9.f}, vPos, vAngle, !bTrace ? true : false, bQuick); - out = { TF_PROJECTILE_BALLOFFIRE, vPos, vAngle, { 1.f, 1.f, 1.f /*damaging hull much bigger, shouldn't matter here*/ }, 3000.f, 0.f, true, 0.2f }; + tInfo = { TF_PROJECTILE_BALLOFFIRE, vPos, vAngle, { 1.f, 1.f, 1.f /*damaging hull much bigger, shouldn't matter here*/ }, 3000.f, 0.f, true, 0.2f }; return true; } case TF_WEAPON_CLEAVER: { SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bQuick); - out = { TF_PROJECTILE_CLEAVER, vPos, vAngle, { 1.f, 1.f, 10.f /*weird, probably still inaccurate*/ }, 3000.f, 1.f, !bTrace ? true : false, 2.2f }; + tInfo = { TF_PROJECTILE_CLEAVER, vPos, vAngle, { 1.f, 1.f, 10.f /*weird, probably still inaccurate*/ }, 3000.f, 1.f, !bTrace ? true : false, 2.2f }; return true; } case TF_WEAPON_BAT_WOOD: @@ -192,25 +192,25 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap SDK::GetProjectileFireSetup(pPlayer, vAngles, { 0.f, 0.f, 0.f }, vPos, vAngle, true, bQuick); Vec3 vForward; Math::AngleVectors(vAngle, &vForward); vPos = (bQuick ? pPlayer->GetAbsOrigin() : pPlayer->m_vecOrigin()) + (Vec3(0, 0, 50) + vForward * 32.f) * pPlayer->m_flModelScale(); // why? - out = { bWrapAssassin ? TF_PROJECTILE_FESTIVE_ARROW : TF_PROJECTILE_THROWABLE, vPos, vAngle, { 3.f, 3.f, 3.f }, tf_scout_stunball_base_speed ? tf_scout_stunball_base_speed->GetInt() : 3000.f, 1.f, false, bWrapAssassin ? 2.3f : 100.f }; + tInfo = { bWrapAssassin ? TF_PROJECTILE_FESTIVE_ARROW : TF_PROJECTILE_THROWABLE, vPos, vAngle, { 3.f, 3.f, 3.f }, tf_scout_stunball_base_speed ? tf_scout_stunball_base_speed->GetInt() : 3000.f, 1.f, false, bWrapAssassin ? 2.3f : 100.f }; return true; } case TF_WEAPON_JAR: case TF_WEAPON_JAR_MILK: { SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bQuick); - out = { TF_PROJECTILE_JAR, vPos, vAngle, { 3.f, 3.f, 3.f }, 1000.f, 1.f, false, 2.2f }; + tInfo = { TF_PROJECTILE_JAR, vPos, vAngle, { 3.f, 3.f, 3.f }, 1000.f, 1.f, false, 2.2f }; return true; } case TF_WEAPON_JAR_GAS: { SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, true, bQuick); - out = { TF_PROJECTILE_JAR_GAS, vPos, vAngle, { 3.f, 3.f, 3.f }, 2000.f, 1.f, false, 2.2f }; + tInfo = { TF_PROJECTILE_JAR_GAS, vPos, vAngle, { 3.f, 3.f, 3.f }, 2000.f, 1.f, false, 2.2f }; return true; } case TF_WEAPON_GRAPPLINGHOOK: { - SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, -8.f, -3.f }, vPos, vAngle, false, bQuick); + SDK::GetProjectileFireSetup(pPlayer, vAngles, { 23.5f, -8.f, -3.f }, vPos, vAngle, !bTrace ? true : false, bQuick); static auto tf_grapplinghook_projectile_speed = U::ConVars.FindVar("tf_grapplinghook_projectile_speed"); static auto tf_grapplinghook_max_distance = U::ConVars.FindVar("tf_grapplinghook_max_distance"); float flSpeed = tf_grapplinghook_projectile_speed ? tf_grapplinghook_projectile_speed->GetFloat() : 1500.f; @@ -224,7 +224,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap } } float flLifetime = (tf_grapplinghook_max_distance ? tf_grapplinghook_max_distance->GetFloat() : 2000.f) / flSpeed; - out = { TF_PROJECTILE_GRAPPLINGHOOK, vPos, vAngle, { 1.2f, 1.2f, 1.2f }, flSpeed, 0.f, false, flLifetime }; + tInfo = { TF_PROJECTILE_GRAPPLINGHOOK, vPos, vAngle, { 1.2f, 1.2f, 1.2f }, flSpeed, 0.f, false, flLifetime }; return true; } } @@ -239,37 +239,38 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap case Heavy_s_SecondBanana: SDK::GetProjectileFireSetup(pPlayer, vAngles, { 0.f, 0.f, -8.f }, vPos, vAngle, true, bQuick); vAngle -= Vec3(10, 0, 0); - out = { TF_PROJECTILE_BREAD_MONSTER, vPos, vAngle, bQuick ? Vec3(4.f, 4.f, 4.f) : Vec3(17.f, 17.f, 17.f), 500.f, 1.f * flGravity, false }; + tInfo = { TF_PROJECTILE_BREAD_MONSTER, vPos, vAngle, bQuick ? Vec3(4.f, 4.f, 4.f) : Vec3(17.f, 17.f, 17.f), 500.f, 1.f * flGravity, false }; return true; } return false; } -bool CProjectileSimulation::GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& out, int iFlags, float flAutoCharge) +bool CProjectileSimulation::GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& tInfo, int iFlags, float flAutoCharge) { bool InitCheck = iFlags & ProjSimEnum::InitCheck; bool bQuick = iFlags & ProjSimEnum::Quick; const float flOldCurrentTime = I::GlobalVars->curtime; I::GlobalVars->curtime = TICKS_TO_TIME(pPlayer->m_nTickBase()); - bool bReturn = GetInfoMain(pPlayer, pWeapon, vAngles, out, iFlags, flAutoCharge); - out.m_bQuick = bQuick; + bool bReturn = GetInfoMain(pPlayer, pWeapon, vAngles, tInfo, iFlags, flAutoCharge); + tInfo.m_pOwner = pPlayer; + tInfo.m_bQuick = bQuick; I::GlobalVars->curtime = flOldCurrentTime; if (!bReturn || !InitCheck) return bReturn; const Vec3 vStart = bQuick ? pPlayer->GetEyePosition() : pPlayer->GetShootPos(); - const Vec3 vEnd = out.m_vPos; + const Vec3 vEnd = tInfo.m_vPos; CGameTrace trace = {}; CTraceFilterWorldAndPropsOnly filter = {}; - SDK::TraceHull(vStart, vEnd, out.m_vHull * -1.f, out.m_vHull, MASK_SOLID, &filter, &trace); + SDK::TraceHull(vStart, vEnd, tInfo.m_vHull * -1.f, tInfo.m_vHull, MASK_SOLID, &filter, &trace); return !trace.DidHit(); } -bool CProjectileSimulation::Initialize(ProjectileInfo& info, bool bSimulate) +bool CProjectileSimulation::Initialize(ProjectileInfo& tInfo, bool bSimulate) { if (!env) env = I::Physics->CreateEnvironment(); @@ -287,7 +288,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& info, bool bSimulate) params.rotInertiaLimit = 0.f; params.enableCollisions = false; - obj = env->CreatePolyObject(col, 0, info.m_vPos, info.m_vAng, ¶ms); + obj = env->CreatePolyObject(col, 0, tInfo.m_vPos, tInfo.m_vAng, ¶ms); obj->Wake(); } @@ -303,7 +304,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& info, bool bSimulate) // these values were dumped from the server by firing the projectiles with 0 0 0 angles // they are calculated in CPhysicsObject::RecomputeDragBases - switch (info.m_iType) + switch (tInfo.m_iType) { case TF_PROJECTILE_NONE: flDrag = Vars::Visuals::Trajectory::Drag.Value; @@ -360,10 +361,10 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& info, bool bSimulate) //set position and velocity { - Vec3 vForward, vRight, vUp; Math::AngleVectors(info.m_vAng, &vForward, &vRight, &vUp); - Vec3 vVelocity = vForward * info.m_flVelocity, vAngularVelocity; + Vec3 vForward, vRight, vUp; Math::AngleVectors(tInfo.m_vAng, &vForward, &vRight, &vUp); + Vec3 vVelocity = vForward * tInfo.m_flVelocity, vAngularVelocity; - switch (info.m_iType) + switch (tInfo.m_iType) { case TF_PROJECTILE_NONE: vVelocity += vUp * Vars::Visuals::Trajectory::UpVelocity.Value; @@ -373,7 +374,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& info, bool bSimulate) case TF_PROJECTILE_PIPEBOMB_REMOTE: case TF_PROJECTILE_PIPEBOMB_PRACTICE: case TF_PROJECTILE_CANNONBALL: - if (!info.m_bQuick && G::CurrentUserCmd) + if (!tInfo.m_bQuick && G::CurrentUserCmd) { vVelocity += vUp * 200.f + vUp * SDK::RandomFloat(-10.f, 10.f) + vRight * SDK::RandomFloat(-10.f, 10.f); vAngularVelocity = { 600.f, float(SDK::RandomInt(-1200, 1200)), 0.f }; @@ -385,29 +386,42 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& info, bool bSimulate) case TF_PROJECTILE_CLEAVER: vVelocity = vForward * 10 + vUp; vVelocity.Normalize(); - vVelocity *= info.m_flVelocity; + vVelocity *= tInfo.m_flVelocity; vAngularVelocity = { 0.f, 500.f, 0.f }; break; case TF_PROJECTILE_THROWABLE: case TF_PROJECTILE_FESTIVE_ARROW: vVelocity = vForward * 10 + vUp; vVelocity.Normalize(); - vVelocity *= info.m_flVelocity; + vVelocity *= tInfo.m_flVelocity; vAngularVelocity = { 0.f, 100.f, 0.f }; break; case TF_PROJECTILE_JAR: case TF_PROJECTILE_JAR_GAS: vVelocity += vUp * 200.f; vAngularVelocity = { 300.f, 0.f, 0.f }; + break; + case TF_PROJECTILE_FLAME_ROCKET: + if (bSimulate && tInfo.m_pOwner) + { + Vec3 vOwnerVelocity = tInfo.m_pOwner->m_vecVelocity(); + if (!vOwnerVelocity.IsZero()) + { + float flOwnerVelocity = vOwnerVelocity.Length(); + + float flDot = vForward.Dot(vOwnerVelocity) / flOwnerVelocity; + vVelocity = vForward * (tInfo.m_flVelocity + flOwnerVelocity * flDot); + } + } } - if (info.m_bNoSpin) + if (tInfo.m_bNoSpin) vAngularVelocity.Zero(); - if (bSimulate && obj->m_dragBasis.IsZero()) // don't include vphysics projectiles - vVelocity.z += 400.f * info.m_flGravity * TICK_INTERVAL; // i don't know why this makes it more accurate but it does + if (bSimulate && !F::ProjSim.obj->IsDragEnabled() && obj->m_dragBasis.IsZero()) // don't include vphysics projectiles + vVelocity.z += 400.f * tInfo.m_flGravity * TICK_INTERVAL; // i don't know why this makes it more accurate but it does - obj->SetPosition(info.m_vPos, info.m_vAng, true); + obj->SetPosition(tInfo.m_vPos, tInfo.m_vAng, true); obj->SetVelocity(&vVelocity, &vAngularVelocity); } @@ -417,7 +431,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& info, bool bSimulate) float vMaxAngularVelocity = 1000000.f; //only pipes need k_flMaxVelocity and k_flMaxAngularVelocity - switch (info.m_iType) + switch (tInfo.m_iType) { case TF_PROJECTILE_NONE: if (Vars::Visuals::Trajectory::MaxVelocity.Value) @@ -442,23 +456,23 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& info, bool bSimulate) env->SetPerformanceSettings(¶ms); env->SetAirDensity(2.f); - env->SetGravity({ 0.f, 0.f, -(800.f * info.m_flGravity) }); + env->SetGravity({ 0.f, 0.f, -(800.f * tInfo.m_flGravity) }); - env->ResetSimulationClock(); // not needed? + env->ResetSimulationClock(); } - RunTick(info, false); // simulate an initial time because dumb + RunTick(tInfo, false); // simulate an initial time because dumb return true; } -void CProjectileSimulation::RunTick(ProjectileInfo& info, bool bPath) +void CProjectileSimulation::RunTick(ProjectileInfo& tInfo, bool bPath) // bug: per frame projectile trace can cause inconsistencies? { if (!env) return; if (bPath) - info.m_vPath.push_back(GetOrigin()); + tInfo.m_vPath.push_back(GetOrigin()); env->Simulate(TICK_INTERVAL); diff --git a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h index 298c45e9..cb2496d8 100644 --- a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h +++ b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h @@ -23,6 +23,8 @@ struct ProjectileInfo bool m_bNoSpin = false; float m_flLifetime = 60.f; + CTFPlayer* m_pOwner = nullptr; + std::deque m_vPath = {}; bool m_bQuick = false; @@ -30,7 +32,7 @@ struct ProjectileInfo class CProjectileSimulation { - bool GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& out, int iFlags, float flAutoCharge); + bool GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& tInfo, int iFlags, float flAutoCharge); const objectparams_t g_PhysDefaultObjectParams = { @@ -48,9 +50,9 @@ class CProjectileSimulation }; public: - bool GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& out, int iFlags = ProjSimEnum::Trace | ProjSimEnum::InitCheck, float flAutoCharge = -1.f); - bool Initialize(ProjectileInfo& info, bool bSimulate = true); - void RunTick(ProjectileInfo& info, bool bPath = true); + bool GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& tInfo, int iFlags = ProjSimEnum::Trace | ProjSimEnum::InitCheck, float flAutoCharge = -1.f); + bool Initialize(ProjectileInfo& tInfo, bool bSimulate = true); + void RunTick(ProjectileInfo& tInfo, bool bPath = true); Vec3 GetOrigin(); Vec3 GetVelocity(); diff --git a/Amalgam/src/Features/Spectate/Spectate.cpp b/Amalgam/src/Features/Spectate/Spectate.cpp index 3753a6f6..58e7a227 100644 --- a/Amalgam/src/Features/Spectate/Spectate.cpp +++ b/Amalgam/src/Features/Spectate/Spectate.cpp @@ -21,6 +21,9 @@ void CSpectate::NetUpdateEnd(CTFPlayer* pLocal) } return; } + + m_pOriginalTarget = pLocal->m_hObserverTarget().Get(); + m_iOriginalMode = pLocal->m_iObserverMode(); if (!pEntity) return; @@ -36,6 +39,18 @@ void CSpectate::NetUpdateEnd(CTFPlayer* pLocal) pLocal->m_iObserverMode() = Vars::Visuals::ThirdPerson::Enabled.Value ? OBS_MODE_THIRDPERSON : OBS_MODE_FIRSTPERSON; pLocal->m_vecViewOffset() = pEntity->GetViewOffset(); Vars::Visuals::ThirdPerson::Enabled.Value ? I::Input->CAM_ToThirdPerson() : I::Input->CAM_ToFirstPerson(); + + m_pTargetTarget = pLocal->m_hObserverTarget().Get(); + m_iTargetMode = pLocal->m_iObserverMode(); +} + +void CSpectate::NetUpdateStart(CTFPlayer* pLocal) +{ + if (!pLocal || m_iTarget == -1) + return; + + pLocal->m_hObserverTarget().Set(m_pOriginalTarget); + pLocal->m_iObserverMode() = m_iOriginalMode; } void CSpectate::CreateMove(CTFPlayer* pLocal, CUserCmd* pCmd) diff --git a/Amalgam/src/Features/Spectate/Spectate.h b/Amalgam/src/Features/Spectate/Spectate.h index fe674f5b..1b5e6cd3 100644 --- a/Amalgam/src/Features/Spectate/Spectate.h +++ b/Amalgam/src/Features/Spectate/Spectate.h @@ -5,12 +5,18 @@ class CSpectate { public: void NetUpdateEnd(CTFPlayer* pLocal); + void NetUpdateStart(CTFPlayer* pLocal); void CreateMove(CTFPlayer* pLocal, CUserCmd* pCmd); void SetTarget(int iTarget); int m_iTarget = -1; int m_iIntendedTarget = -1; Vec3 m_vOldView = {}; // don't let spectating change viewangles + + CBaseEntity* m_pOriginalTarget; + int m_iOriginalMode = OBS_MODE_NONE; + CBaseEntity* m_pTargetTarget; + int m_iTargetMode = OBS_MODE_NONE; }; ADD_FEATURE(CSpectate, Spectate) \ No newline at end of file diff --git a/Amalgam/src/Features/TickHandler/TickHandler.cpp b/Amalgam/src/Features/TickHandler/TickHandler.cpp index ce5c7fa6..1c2f17ef 100644 --- a/Amalgam/src/Features/TickHandler/TickHandler.cpp +++ b/Amalgam/src/Features/TickHandler/TickHandler.cpp @@ -254,8 +254,8 @@ void CTickshiftHandler::CLMove(float accumulated_extra_samples, bool bFinalTick) #ifndef TICKBASE_DEBUG while (m_iShiftedTicks > m_iShiftedGoal) - //CLMoveFunc(accumulated_extra_samples, m_iShiftedTicks - 1 == m_iShiftedGoal); - CLMoveFunc(accumulated_extra_samples, bFinalTick); + CLMoveFunc(accumulated_extra_samples, m_iShiftedTicks - 1 == m_iShiftedGoal); + //CLMoveFunc(accumulated_extra_samples, bFinalTick); #else if (Vars::Debug::Info.Value) SDK::Output("Pre loop", "", { 0, 255, 255, 255 }); diff --git a/Amalgam/src/Features/Visuals/ESP/ESP.cpp b/Amalgam/src/Features/Visuals/ESP/ESP.cpp index 640d2e2d..bc27f34e 100644 --- a/Amalgam/src/Features/Visuals/ESP/ESP.cpp +++ b/Amalgam/src/Features/Visuals/ESP/ESP.cpp @@ -1,6 +1,7 @@ #include "ESP.h" #include "../../Players/PlayerUtils.h" +#include "../../Spectate/Spectate.h" #include "../../Simulation/MovementSimulation/MovementSimulation.h" MAKE_SIGNATURE(CTFPlayerSharedUtils_GetEconItemViewByLoadoutSlot, "client.dll", "48 89 6C 24 ? 56 41 54 41 55 41 56 41 57 48 83 EC", 0x0); @@ -27,13 +28,23 @@ void CESP::StorePlayers(CTFPlayer* pLocal) if (!(Vars::ESP::Draw.Value & Vars::ESP::DrawEnum::Players) || !Vars::ESP::Player.Value) return; + auto pObserverTarget = pLocal->m_hObserverTarget().Get(); + int iObserverMode = pLocal->m_iObserverMode(); + if (F::Spectate.m_iTarget != -1) + { + pObserverTarget = F::Spectate.m_pTargetTarget; + iObserverMode = F::Spectate.m_iTargetMode; + } + auto pResource = H::Entities.GetPR(); for (auto pEntity : H::Entities.GetGroup(EGroupType::PLAYERS_ALL)) { auto pPlayer = pEntity->As(); int iIndex = pPlayer->entindex(); - if (pLocal->m_iObserverMode() == OBS_MODE_FIRSTPERSON ? pLocal->m_hObserverTarget().Get() == pPlayer : iIndex == I::EngineClient->GetLocalPlayer()) + if ((iObserverMode == OBS_MODE_FIRSTPERSON || iObserverMode == OBS_MODE_THIRDPERSON) + ? pObserverTarget == pPlayer + : iIndex == I::EngineClient->GetLocalPlayer()) { if (!(Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::Local) || !I::Input->CAM_IsThirdPerson()) continue; diff --git a/Amalgam/src/Features/Visuals/SpectatorList/SpectatorList.cpp b/Amalgam/src/Features/Visuals/SpectatorList/SpectatorList.cpp index f2d7d1c9..98ed9d7f 100644 --- a/Amalgam/src/Features/Visuals/SpectatorList/SpectatorList.cpp +++ b/Amalgam/src/Features/Visuals/SpectatorList/SpectatorList.cpp @@ -1,6 +1,7 @@ #include "SpectatorList.h" #include "../../Players/PlayerUtils.h" +#include "../../Spectate/Spectate.h" bool CSpectatorList::GetSpectators(CTFPlayer* pTarget) { @@ -9,8 +10,19 @@ bool CSpectatorList::GetSpectators(CTFPlayer* pTarget) for (auto pEntity : H::Entities.GetGroup(EGroupType::PLAYERS_ALL)) { auto pPlayer = pEntity->As(); + int iIndex = pPlayer->entindex(); + bool bLocal = pEntity->entindex() == I::EngineClient->GetLocalPlayer(); - if (pPlayer->IsAlive() || pPlayer->m_hObserverTarget().Get() != pTarget || pEntity->entindex() == I::EngineClient->GetLocalPlayer() && !I::EngineClient->IsPlayingDemo()) + auto pObserverTarget = pPlayer->m_hObserverTarget().Get(); + int iObserverMode = pPlayer->m_iObserverMode(); + if (bLocal && F::Spectate.m_iTarget != -1) + { + pObserverTarget = F::Spectate.m_pOriginalTarget; + iObserverMode = F::Spectate.m_iOriginalMode; + } + + if (pPlayer->IsAlive() || pObserverTarget != pTarget + || bLocal && !I::EngineClient->IsPlayingDemo() && F::Spectate.m_iTarget == -1) { auto it = m_mRespawnCache.find(pPlayer->entindex()); if (it != m_mRespawnCache.end()) @@ -18,10 +30,8 @@ bool CSpectatorList::GetSpectators(CTFPlayer* pTarget) continue; } - int iIndex = pPlayer->entindex(); - std::string sMode; - switch (pPlayer->m_iObserverMode()) + switch (iObserverMode) { case OBS_MODE_FIRSTPERSON: sMode = "1st"; break; case OBS_MODE_THIRDPERSON: sMode = "3rd"; break; diff --git a/Amalgam/src/Features/Visuals/Visuals.cpp b/Amalgam/src/Features/Visuals/Visuals.cpp index 2e420317..521dd85d 100644 --- a/Amalgam/src/Features/Visuals/Visuals.cpp +++ b/Amalgam/src/Features/Visuals/Visuals.cpp @@ -118,7 +118,7 @@ void CVisuals::DrawPing(CTFPlayer* pLocal) H::Draw.StringOutlined(fFont, x, y += nTall, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, align, "Scoreboard %d ms", iLatencyScoreboard); } -static std::deque SplashTrace(Vec3 vOrigin, float flRadius, Vec3 vNormal = { 0, 0, 1 }, bool bTrace = true, int iSegments = 32) +static std::deque SplashTrace(Vec3 vOrigin, float flRadius, Vec3 vNormal = { 0, 0, 1 }, bool bTrace = true, int iSegments = 100) { if (!flRadius) return {}; @@ -134,7 +134,7 @@ static std::deque SplashTrace(Vec3 vOrigin, float flRadius, Vec3 vNormal = { CGameTrace trace = {}; CTraceFilterWorldAndPropsOnly filter = {}; - SDK::Trace(vOrigin, vPoint, MASK_SOLID, &filter, &trace); + SDK::Trace(vOrigin, vPoint, MASK_SHOT, &filter, &trace); vPoint = trace.endpos; } vPoints.push_back(vPoint); @@ -160,15 +160,12 @@ void CVisuals::ProjectileTrace(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const return; pWeapon = pPlayer->m_hActiveWeapon().Get()->As(); - if (!pWeapon || pWeapon->GetWeaponID() == TF_WEAPON_FLAMETHROWER) - return; - if (I::Input->CAM_IsThirdPerson()) vAngles = pPlayer->GetEyeAngles(); pPlayer->m_vecViewOffset() = pPlayer->GetViewOffset(); } - else if (!pPlayer || !pWeapon || pWeapon->GetWeaponID() == TF_WEAPON_FLAMETHROWER) + if (!pPlayer || !pWeapon || pWeapon->GetWeaponID() == TF_WEAPON_FLAMETHROWER) return; ProjectileInfo projInfo = {}; @@ -193,7 +190,7 @@ void CVisuals::ProjectileTrace(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const break; } } - + if (projInfo.m_vPath.empty()) return; @@ -584,6 +581,25 @@ std::vector CVisuals::GetHitboxes(matrix3x4 aBones[MAXSTUDIOBONES], CBa tFace = bTargeted ? Vars::Colors::TargetHitboxFaceClipped.Value : Vars::Colors::BoneHitboxFaceClipped.Value; if (tEdge.a || tFace.a) vBoxes.push_back({ vOrigin, vMins, vMaxs, vAngle, I::GlobalVars->curtime + Vars::Visuals::Hitbox::DrawDuration.Value, tEdge, tFace, true }); + + if (Vars::Debug::Info.Value) + { + float flBoneScale = std::max(Vars::Aimbot::Hitscan::BoneSizeMinimumScale.Value, Vars::Aimbot::Hitscan::PointScale.Value / 100.f); + float flBoneSubtract = Vars::Aimbot::Hitscan::BoneSizeSubtract.Value; + + Vec3 vCheckMins = (pBox->bbmin + flBoneSubtract / pEntity->m_flModelScale()) * flBoneScale * pEntity->m_flModelScale(); + Vec3 vCheckMaxs = (pBox->bbmax - flBoneSubtract / pEntity->m_flModelScale()) * flBoneScale * pEntity->m_flModelScale(); + + Color_t tEdge = bTargeted ? Vars::Colors::TargetHitboxEdge.Value : Vars::Colors::BoneHitboxEdge.Value; + Color_t tFace = bTargeted ? Vars::Colors::TargetHitboxFace.Value : Vars::Colors::BoneHitboxFace.Value; + if (tEdge.a || tFace.a) + vBoxes.push_back({ vOrigin, vCheckMins, vCheckMaxs, vAngle, I::GlobalVars->curtime + Vars::Visuals::Hitbox::DrawDuration.Value, tEdge, tFace }); + + tEdge = bTargeted ? Vars::Colors::TargetHitboxEdgeClipped.Value : Vars::Colors::BoneHitboxEdgeClipped.Value; + tFace = bTargeted ? Vars::Colors::TargetHitboxFaceClipped.Value : Vars::Colors::BoneHitboxFaceClipped.Value; + if (tEdge.a || tFace.a) + vBoxes.push_back({ vOrigin, vCheckMins, vCheckMaxs, vAngle, I::GlobalVars->curtime + Vars::Visuals::Hitbox::DrawDuration.Value, tEdge, tFace, true }); + } } return vBoxes; @@ -917,7 +933,7 @@ void CVisuals::Event(IGameEvent* pEvent, uint32_t uHash) if (!pBones) return; - auto vBoxes = F::Visuals.GetHitboxes(pBones, pEntity); + auto vBoxes = GetHitboxes(pBones, pEntity); G::BoxStorage.insert(G::BoxStorage.end(), vBoxes.begin(), vBoxes.end()); return; diff --git a/Amalgam/src/Hooks/CBaseEntity_SetAbsVelocity.cpp b/Amalgam/src/Hooks/CBaseEntity_SetAbsVelocity.cpp index 693b7fe3..d9ea5187 100644 --- a/Amalgam/src/Hooks/CBaseEntity_SetAbsVelocity.cpp +++ b/Amalgam/src/Hooks/CBaseEntity_SetAbsVelocity.cpp @@ -52,7 +52,7 @@ public: } }; -MAKE_SIGNATURE(CBasePlayer_PostDataUpdate_SetAbsVelocity_Call, "client.dll", "E8 ? ? ? ? 0F 28 74 24 ? 8B D6", 0x5); +MAKE_SIGNATURE(CBasePlayer_PostDataUpdate_SetAbsVelocity_Call, "client.dll", "0F 28 74 24 ? 8B D6", 0x0); MAKE_HOOK(CBaseEntity_SetAbsVelocity, S::CBaseEntity_SetAbsVelocity(), void, void* rcx, const Vec3& vecAbsVelocity) @@ -65,7 +65,7 @@ MAKE_HOOK(CBaseEntity_SetAbsVelocity, S::CBaseEntity_SetAbsVelocity(), void, const auto pPlayer = reinterpret_cast(rcx); if (pPlayer->IsDormant() || !G::VelocityMap.contains(pPlayer->entindex()) || G::VelocityMap[pPlayer->entindex()].empty()) return CALL_ORIGINAL(rcx, vecAbsVelocity); - + auto& vRecords = G::VelocityMap[pPlayer->entindex()]; bool bGrounded = pPlayer->IsOnGround(); diff --git a/Amalgam/src/Hooks/CBaseHudChatLine_InsertAndColorizeText.cpp b/Amalgam/src/Hooks/CBaseHudChatLine_InsertAndColorizeText.cpp index 2c638d54..ccc8a371 100644 --- a/Amalgam/src/Hooks/CBaseHudChatLine_InsertAndColorizeText.cpp +++ b/Amalgam/src/Hooks/CBaseHudChatLine_InsertAndColorizeText.cpp @@ -73,15 +73,17 @@ MAKE_HOOK(CBaseHudChatLine_InsertAndColorizeText, S::CBaseHudChatLine_InsertAndC continue; } + size_t iPos = 0; while (true) { std::string sMessage2 = sMessage; std::transform(sMessage2.begin(), sMessage2.end(), sMessage2.begin(), ::tolower); - auto iFind = sMessage2.find(sFind); + auto iFind = sMessage2.find(sFind, iPos); if (iFind == std::string::npos) break; + iPos = iFind + sReplace.length(); sMessage = sMessage.replace(iFind, sFind.length(), sReplace); } } diff --git a/Amalgam/src/Hooks/CL_Move.cpp b/Amalgam/src/Hooks/CL_Move.cpp index 4295ade4..00b955a2 100644 --- a/Amalgam/src/Hooks/CL_Move.cpp +++ b/Amalgam/src/Hooks/CL_Move.cpp @@ -15,6 +15,12 @@ MAKE_HOOK(CL_Move, S::CL_Move(), void, return CALL_ORIGINAL(accumulated_extra_samples, bFinalTick); F::Backtrack.m_iTickCount = I::GlobalVars->tickcount + 1; + if (!Vars::Misc::Game::NetworkFix.Value) + { + auto pNetChan = I::EngineClient->GetNetChannelInfo(); + if (pNetChan && !pNetChan->IsLoopback()) + F::Backtrack.m_iTickCount++; + } auto pLocal = H::Entities.GetLocal(); auto pWeapon = H::Entities.GetWeapon(); diff --git a/Amalgam/src/Hooks/CTFPlayerShared_InCond.cpp b/Amalgam/src/Hooks/CTFPlayerShared_InCond.cpp index 570ff2d7..ca1daefc 100644 --- a/Amalgam/src/Hooks/CTFPlayerShared_InCond.cpp +++ b/Amalgam/src/Hooks/CTFPlayerShared_InCond.cpp @@ -50,7 +50,8 @@ MAKE_HOOK(CTFPlayerShared_InCond, S::CTFPlayerShared_InCond(), bool, return false; break; case TF_COND_FREEZE_INPUT: - return false; + if (CALL_ORIGINAL(rcx, TF_COND_HALLOWEEN_KART) ? Vars::Misc::Automation::KartControl.Value : true) + return false; } return CALL_ORIGINAL(rcx, nCond); diff --git a/Amalgam/src/Hooks/IBaseClientDLL_FrameStageNotify.cpp b/Amalgam/src/Hooks/IBaseClientDLL_FrameStageNotify.cpp index 83e3057b..f5535308 100644 --- a/Amalgam/src/Hooks/IBaseClientDLL_FrameStageNotify.cpp +++ b/Amalgam/src/Hooks/IBaseClientDLL_FrameStageNotify.cpp @@ -11,16 +11,45 @@ #include "../Features/Visuals/Chams/Chams.h" #include "../Features/Visuals/Glow/Glow.h" #include "../Features/Spectate/Spectate.h" +#include "../Features/Binds/Binds.h" MAKE_HOOK(IBaseClientDLL_FrameStageNotify, U::Memory.GetVFunc(I::BaseClientDLL, 35), void, void* rcx, ClientFrameStage_t curStage) { + if (G::Unload) + return CALL_ORIGINAL(rcx, curStage); + + switch (curStage) + { + case FRAME_RENDER_START: + for (int iKey = 0; iKey < 256; iKey++) + { + // don't drop inputs for binds + auto& tKey = F::Binds.m_mKeyStorage[iKey]; + + bool bOldIsDown = tKey.m_bIsDown; + bool bOldIsPressed = tKey.m_bIsPressed; + bool bOldIsDouble = tKey.m_bIsDouble; + bool bOldIsReleased = tKey.m_bIsReleased; + + U::KeyHandler.StoreKey(iKey, &tKey); + + tKey.m_bIsDown = tKey.m_bIsDown || bOldIsDown; + tKey.m_bIsPressed = tKey.m_bIsPressed || bOldIsPressed; + tKey.m_bIsDouble = tKey.m_bIsDouble || bOldIsDouble; + tKey.m_bIsReleased = tKey.m_bIsReleased || bOldIsReleased; + } + } + CALL_ORIGINAL(rcx, curStage); switch (curStage) { case FRAME_NET_UPDATE_START: { + auto pLocal = H::Entities.GetLocal(); + F::Spectate.NetUpdateStart(pLocal); + H::Entities.Clear(); break; } diff --git a/Amalgam/src/SDK/Definitions/Types.h b/Amalgam/src/SDK/Definitions/Types.h index 8c7b41df..52a183af 100644 --- a/Amalgam/src/SDK/Definitions/Types.h +++ b/Amalgam/src/SDK/Definitions/Types.h @@ -167,6 +167,58 @@ public: return Max(v1).Min(v2); } + Vec2 Lerp(const Vec2& v, float t) const + { + return { x + (v.x - x) * t, y + (v.y - y) * t }; + } + + Vec2 Lerp(float v, float t) const + { + return { x + (v - x) * t, y + (v - y) * t }; + } + + Vec2 DeltaAngle(const Vec2& v) const + { + auto deltaAngle = [](const float flAngleA, const float flAngleB) + { + float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f); + return flOut += flOut < 0 ? 180.f : -180.f; + }; + + return { deltaAngle(x, v.x), deltaAngle(y, v.y) }; + } + + Vec2 DeltaAngle(float v) const + { + auto deltaAngle = [](const float flAngleA, const float flAngleB) + { + float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f); + return flOut += flOut < 0 ? 180.f : -180.f; + }; + + return { deltaAngle(x, v), deltaAngle(y, v) }; + } + + Vec2 LerpAngle(const Vec2& v, float t) const + { + auto shortDist = [](const float flAngleA, const float flAngleB) + { + const float flDelta = fmodf((flAngleA - flAngleB), 360.f); + return fmodf(2 * flDelta, 360.f) - flDelta; + }; + return { x - shortDist(x, v.x) * t, y - shortDist(y, v.y) * t }; + } + + Vec2 LerpAngle(float v, float t) const + { + auto shortDist = [](const float flAngleA, const float flAngleB) + { + const float flDelta = fmodf((flAngleA - flAngleB), 360.f); + return fmodf(2 * flDelta, 360.f) - flDelta; + }; + return { x - shortDist(x, v) * t, y - shortDist(y, v) * t }; + } + float Length(void) const { return sqrtf(x * x + y * y); @@ -376,6 +428,58 @@ public: return Max(v1).Min(v2); } + Vec3 Lerp(const Vec3& v, float t) const + { + return { x + (v.x - x) * t, y + (v.y - y) * t, z + (v.z - z) * t }; + } + + Vec3 Lerp(float v, float t) const + { + return { x + (v - x) * t, y + (v - y) * t, z + (v - z) * t }; + } + + Vec3 DeltaAngle(const Vec3& v) const + { + auto deltaAngle = [](const float flAngleA, const float flAngleB) + { + float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f); + return flOut += flOut < 0 ? 180.f : -180.f; + }; + + return { deltaAngle(x, v.x), deltaAngle(y, v.y), deltaAngle(z, v.z) }; + } + + Vec3 DeltaAngle(float v) const + { + auto deltaAngle = [](const float flAngleA, const float flAngleB) + { + float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f); + return flOut += flOut < 0 ? 180.f : -180.f; + }; + + return { deltaAngle(x, v), deltaAngle(y, v), deltaAngle(z, v) }; + } + + Vec3 LerpAngle(const Vec3& v, float t) const + { + auto shortDist = [](const float flAngleA, const float flAngleB) + { + const float flDelta = fmodf((flAngleA - flAngleB), 360.f); + return fmodf(2 * flDelta, 360.f) - flDelta; + }; + return { x - shortDist(x, v.x) * t, y - shortDist(y, v.y) * t, z - shortDist(z, v.z) * t }; + } + + Vec3 LerpAngle(float v, float t) const + { + auto shortDist = [](const float flAngleA, const float flAngleB) + { + const float flDelta = fmodf((flAngleA - flAngleB), 360.f); + return fmodf(2 * flDelta, 360.f) - flDelta; + }; + return { x - shortDist(x, v) * t, y - shortDist(y, v) * t, z - shortDist(z, v) * t }; + } + float Length(void) const { return sqrtf(x * x + y * y + z * z); diff --git a/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.cpp b/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.cpp index a002fd23..45159ffb 100644 --- a/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.cpp +++ b/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.cpp @@ -77,6 +77,14 @@ bool CTraceFilterProjectile::ShouldHitEntity(IHandleEntity* pServerEntity, int n case ETFClassID::CObjectSentrygun: case ETFClassID::CObjectDispenser: case ETFClassID::CObjectTeleporter: return true; + case ETFClassID::CTFMedigunShield: + { + auto pLocal = H::Entities.GetLocal(); + auto pWeapon = H::Entities.GetWeapon(); + + const int iTargetTeam = pEntity->m_iTeamNum(), iLocalTeam = pLocal ? pLocal->m_iTeamNum() : iTargetTeam; + return iTargetTeam != iLocalTeam; + } case ETFClassID::CTFPlayer: { auto pLocal = H::Entities.GetLocal(); diff --git a/Amalgam/src/SDK/Vars.h b/Amalgam/src/SDK/Vars.h index a0ea1f27..3e4d5c3a 100644 --- a/Amalgam/src/SDK/Vars.h +++ b/Amalgam/src/SDK/Vars.h @@ -117,12 +117,12 @@ namespace Vars NAMESPACE_BEGIN(Aimbot) SUBNAMESPACE_BEGIN(General) - CVarEnum(AimType, 0, NONE, Off, Plain, Smooth, Silent, Locking) + CVarEnum(AimType, 0, NONE, Off, Plain, Smooth, Silent, Locking, Assistive) CVarEnum(TargetSelection, 0, NONE, FOV, Distance) CVarEnum(Target, 0b0000001, NONE, Players = 1 << 0, Sentry = 1 << 1, Dispenser = 1 << 2, Teleporter = 1 << 3, Stickies = 1 << 4, NPCs = 1 << 5, Bombs = 1 << 6) CVarEnum(Ignore, 0b000000000, NONE, Friends = 1 << 0, Party = 1 << 1, Invulnerable = 1 << 2, Cloaked = 1 << 3, Unsimulated = 1 << 4, DeadRinger = 1 << 5, Vaccinator = 1 << 6, Disguised = 1 << 7, Taunting = 1 << 8) CVar(AimFOV, 30.f) - CVar(Smoothing, 25.f) + CVar(AssistStrength, 25.f) CVar(MaxTargets, 2) CVar(IgnoreCloakPercentage, 100) CVar(TickTolerance, 7) @@ -140,18 +140,22 @@ namespace Vars SUBNAMESPACE_END(Global) SUBNAMESPACE_BEGIN(Hitscan) - CVarEnum(Hitboxes, 0b00111, NONE, Head = 1 << 0, Pelvis = 1 << 1, Body = 1 << 2, Arms = 1 << 3, Legs = 1 << 4) - CVarEnum(Modifiers, 0b01000000, NONE, Tapfire = 1 << 0, WaitForHeadshot = 1 << 1, WaitForCharge = 1 << 2, ScopedOnly = 1 << 3, AutoScope = 1 << 4, BodyaimIfLethal = 1 << 5, AutoRev = 1 << 6, ExtinguishTeam = 1 << 7) + CVarEnum(Hitboxes, 0b000111, NONE, Head = 1 << 0, Body = 1 << 1, Pelvis = 1 << 2, Arms = 1 << 3, Legs = 1 << 4, BodyaimIfLethal = 1 << 5) + CVarEnum(Modifiers, 0b01000000, NONE, Tapfire = 1 << 0, WaitForHeadshot = 1 << 1, WaitForCharge = 1 << 2, ScopedOnly = 1 << 3, AutoScope = 1 << 4, AutoRev = 1 << 5, ExtinguishTeam = 1 << 6) CVar(PointScale, 0.f) CVar(TapFireDist, 1000.f) + + CVar(BoneSizeSubtract, 1.f, DEBUGVAR) + CVar(BoneSizeMinimumScale, 1.f, DEBUGVAR) SUBNAMESPACE_END(HITSCAN) SUBNAMESPACE_BEGIN(Projectile) CVarEnum(StrafePrediction, 0b11, NONE, Air = 1 << 0, Ground = 1 << 1) CVarEnum(SplashPrediction, 0, NONE, Off, Include, Prefer, Only) - CVarEnum(AutoDetonate, 0b00, NONE, Stickies = 1 << 0, Flares = 1 << 1, PreventSelfDamage = 1 << 2) + CVarEnum(AutoDetonate, 0b00, NONE, Stickies = 1 << 0, Flares = 1 << 1, PreventSelfDamage = 1 << 2, IgnoreCloak = 1 << 3) CVarEnum(AutoAirblast, 0b1000, NONE, Enabled = 1 << 0, RedirectSimple = 1 << 1, RedirectAdvanced = 1 << 2, RespectFOV = 1 << 3) - CVarEnum(Modifiers, 0b1010, NONE, ChargeWeapon = 1 << 0, CancelCharge = 1 << 1, BodyaimIfLethal = 1 << 2, UsePrimeTime = 1 << 3, AimBlastAtFeet = 1 << 4) + CVarEnum(Hitboxes, 0b001111, NONE, Auto = 1 << 0, Head = 1 << 1, Body = 1 << 2, Feet = 1 << 3, BodyaimIfLethal = 1 << 4, AimBlastAtFeet = 1 << 5) + CVarEnum(Modifiers, 0b1010, NONE, ChargeWeapon = 1 << 0, CancelCharge = 1 << 1, UsePrimeTime = 1 << 2) CVar(PredictionTime, 2.f) CVar(Hitchance, 0.f) CVar(AutodetRadius, 90.f) @@ -185,12 +189,14 @@ namespace Vars CVar(HuntsmanAdd, 0.f, DEBUGVAR) CVar(HuntsmanAddLow, 0.f, DEBUGVAR) CVar(HuntsmanClamp, 5.f, DEBUGVAR) - CVar(SplashGrates, true, DEBUGVAR) - CVarEnum(RocketSplashMode, 0, DEBUGVAR, Regular, SpecialLight, SpecialHeavy) + CVar(HuntsmanPullPoint, false, DEBUGVAR) CVar(SplashPoints, 100, DEBUGVAR) + CVar(SplashGrates, true, DEBUGVAR) CVar(SplashCountDirect, 100, DEBUGVAR) CVar(SplashCountArc, 5, DEBUGVAR) CVar(SplashTraceInterval, 10, DEBUGVAR) + CVarEnum(SplashMode, 0, DEBUGVAR, Multi, Single) + CVarEnum(RocketSplashMode, 0, DEBUGVAR, Regular, SpecialLight, SpecialHeavy) CVar(DeltaCount, 5, DEBUGVAR) CVarEnum(DeltaMode, 0, DEBUGVAR, Average, Max) SUBNAMESPACE_END(Projectile) diff --git a/Amalgam/src/Utils/Interfaces/Interfaces.cpp b/Amalgam/src/Utils/Interfaces/Interfaces.cpp index 99586c1f..fa0a1aec 100644 --- a/Amalgam/src/Utils/Interfaces/Interfaces.cpp +++ b/Amalgam/src/Utils/Interfaces/Interfaces.cpp @@ -9,7 +9,7 @@ #pragma warning (disable: 4172) -const char* SearchForDLL(const char* pszDLLSearch) +static const char* SearchForDLL(const char* pszDLLSearch) { HANDLE hProcessSnap = INVALID_HANDLE_VALUE; PROCESSENTRY32 pe32; diff --git a/Amalgam/src/Utils/Math/Math.h b/Amalgam/src/Utils/Math/Math.h index 356965a1..cef2c69f 100644 --- a/Amalgam/src/Utils/Math/Math.h +++ b/Amalgam/src/Utils/Math/Math.h @@ -302,16 +302,21 @@ namespace Math } } - inline bool RayToOBB(const Vec3& vOrigin, const Vec3& vDirection, const Vec3& vMins, const Vec3& vMaxs, const matrix3x4& mMatrix) + inline bool RayToOBB(const Vec3& vOrigin, const Vec3& vDirection, const Vec3& vMins, const Vec3& vMaxs, const matrix3x4& mMatrix, float flScale = 1.f) { + if (!flScale) + return false; + Vec3 vDelta = Vec3(mMatrix[0][3], mMatrix[1][3], mMatrix[2][3]) - vOrigin; - Vec3 X = { mMatrix[0][0], mMatrix[1][0], mMatrix[2][0] }; - Vec3 Y = { mMatrix[0][1], mMatrix[1][1], mMatrix[2][1] }; - Vec3 Z = { mMatrix[0][2], mMatrix[1][2], mMatrix[2][2] }; + Vec3 X = Vec3(mMatrix[0][0], mMatrix[1][0], mMatrix[2][0]) / flScale; + Vec3 Y = Vec3(mMatrix[0][1], mMatrix[1][1], mMatrix[2][1]) / flScale; + Vec3 Z = Vec3(mMatrix[0][2], mMatrix[1][2], mMatrix[2][2]) / flScale; + if (flScale != 1.f) + X /= flScale, Y /= flScale, Z /= flScale; - Vec3 f = { X.Dot(vDirection), Y.Dot(vDirection), Z.Dot(vDirection) }; - Vec3 e = { X.Dot(vDelta), Y.Dot(vDelta), Z.Dot(vDelta) }; + Vec3 f = Vec3(X.Dot(vDirection), Y.Dot(vDirection), Z.Dot(vDirection)); + Vec3 e = Vec3(X.Dot(vDelta), Y.Dot(vDelta), Z.Dot(vDelta)); float t[6] = { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f }; @@ -319,7 +324,7 @@ namespace Math { if (floatCompare(f[i], 0.f)) { - if (-e[i] + vMins[i] > 0.f || -e[i] + vMaxs[i] < 0.f) + if (-e[i] + vMins[i] * flScale > 0.f || -e[i] + vMaxs[i] * flScale < 0.f) return false; f[i] = 0.00001f; diff --git a/Amalgam/src/Utils/NetVars/NetVars.cpp b/Amalgam/src/Utils/NetVars/NetVars.cpp index dfbb4a8a..1d6bff52 100644 --- a/Amalgam/src/Utils/NetVars/NetVars.cpp +++ b/Amalgam/src/Utils/NetVars/NetVars.cpp @@ -8,7 +8,7 @@ int CNetVars::GetOffset(RecvTable* pTable, const char* szNetVar) auto uHash = FNV1A::Hash32(szNetVar); for (int i = 0; i < pTable->m_nProps; i++) { - RecvProp Prop = pTable->m_pProps[i]; + RecvProp& Prop = pTable->m_pProps[i]; if (uHash == FNV1A::Hash32(Prop.m_pVarName)) return Prop.GetOffset();