lob arc angles

fix vphys projectiles passing through bottom side of displacements in simulation
This commit is contained in:
rei-2
2026-03-19 17:55:31 -04:00
parent 0f3a2adeda
commit a95148a68e
27 changed files with 1515 additions and 1220 deletions
+2
View File
@@ -968,6 +968,7 @@
<ClCompile Include="src\Hooks\CHLTVCamera_CalcView.cpp" />
<ClCompile Include="src\Hooks\CInput_ValidateUserCmd.cpp" />
<ClCompile Include="src\Hooks\CModelLoader_Map_LoadModel.cpp" />
<ClCompile Include="src\Hooks\CM_TraceToDispTree.cpp" />
<ClCompile Include="src\Hooks\CTFPlayerShared_ShouldSuppressPrediction.cpp" />
<ClCompile Include="src\Hooks\CTFRocketLauncher_CheckReloadMisfire.cpp" />
<ClCompile Include="src\Hooks\CTFPlayer_FireBullet.cpp" />
@@ -1321,6 +1322,7 @@
<ClInclude Include="src\SDK\Definitions\Interfaces\ISpatialPartition.h" />
<ClInclude Include="src\SDK\Definitions\Misc\ServerClass.h" />
<ClInclude Include="src\SDK\Definitions\Misc\CSmartPtr.h" />
<ClInclude Include="src\SDK\Definitions\Misc\TraceInfo.h" />
<ClInclude Include="src\SDK\Definitions\Misc\VCollide.h" />
<ClInclude Include="src\SDK\Definitions\Steam\ISteamAppList.h" />
<ClInclude Include="src\SDK\Definitions\Steam\ISteamApps.h" />
+2
View File
@@ -205,6 +205,7 @@
<ClCompile Include="src\SDK\Definitions\Misc\CByteSwap.cpp" />
<ClCompile Include="src\Features\World\World.cpp" />
<ClCompile Include="src\Hooks\CModelLoader_Map_LoadModel.cpp" />
<ClCompile Include="src\Hooks\CM_TraceToDispTree.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Utils\UtlVector\UtlVector.h" />
@@ -608,6 +609,7 @@
<ClInclude Include="src\Features\World\World.h" />
<ClInclude Include="src\SDK\Definitions\Interfaces\WorldBrushData.h" />
<ClInclude Include="src\SDK\Definitions\Interfaces\CDispCollTree.h" />
<ClInclude Include="src\SDK\Definitions\Misc\TraceInfo.h" />
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
+11 -5
View File
@@ -7,6 +7,7 @@
#include "../Features/EnginePrediction/EnginePrediction.h"
#include "../Features/Visuals/Materials/Materials.h"
#include "../Features/Visuals/Visuals.h"
#include "../Features/Spectate/Spectate.h"
#include "../SDK/Events/Events.h"
#include <Psapi.h>
@@ -145,17 +146,22 @@ void CCore::Unload()
if (F::Menu.m_bIsOpen)
I::MatSystemSurface->SetCursorAlwaysVisible(false);
if (I::Input->CAM_IsThirdPerson())
H::ConVars.FindVar("cl_wpn_sway_interp")->SetValue(0.f);
H::ConVars.FindVar("cl_wpn_sway_scale")->SetValue(0.f);
F::Visuals.RestoreWorldModulation();
if (auto pLocal = H::Entities.GetLocal())
{
if (auto pLocal = H::Entities.GetLocal())
if (F::Spectate.HasTarget())
{
F::Spectate.NetUpdateStart(pLocal);
I::EngineClient->SetViewAngles(F::Spectate.m_vOldView);
}
if (I::Input->CAM_IsThirdPerson())
{
I::Input->CAM_ToFirstPerson();
pLocal->ThirdPersonSwitch();
}
}
F::Visuals.RestoreWorldModulation();
H::ConVars.FindVar("cl_wpn_sway_interp")->SetValue(0.f);
H::ConVars.FindVar("cl_wpn_sway_scale")->SetValue(0.f);
Sleep(250);
F::EnginePrediction.Unload();
+1 -1
View File
@@ -90,7 +90,7 @@ void CAimbot::Draw(CTFPlayer* pLocal)
if (Vars::Aimbot::General::AimFOV.Value >= 90.f)
return;
float flRadius = tanf(DEG2RAD(Vars::Aimbot::General::AimFOV.Value)) / tanf(DEG2RAD(G::FOV) / 2) * float(H::Draw.m_nScreenW) * (4.f / 6.f) / (16.f / 9.f);
float flRadius = tanf(Math::Deg2Rad(Vars::Aimbot::General::AimFOV.Value)) / tanf(Math::Deg2Rad(G::FOV) / 2) * float(H::Draw.m_nScreenW) * (4.f / 6.f) / (16.f / 9.f);
H::Draw.LineCircle(H::Draw.m_nScreenW / 2, H::Draw.m_nScreenH / 2, flRadius, 68, Vars::Colors::FOVCircle.Value);
}
@@ -283,7 +283,7 @@ int CAimbotHitscan::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase*
std::sort(vRecords.begin(), vRecords.end(), [&](const TickRecord* a, const TickRecord* b) -> bool
{
Vec3 vPosA = { a->m_aBones[iTargetBone][0][3], a->m_aBones[iTargetBone][1][3], a->m_aBones[iTargetBone][2][3] };
Vec3 vPosB = { a->m_aBones[iTargetBone][0][3], a->m_aBones[iTargetBone][1][3], a->m_aBones[iTargetBone][2][3] };
Vec3 vPosB = { b->m_aBones[iTargetBone][0][3], b->m_aBones[iTargetBone][1][3], b->m_aBones[iTargetBone][2][3] };
Vec3 vAnglesA = Math::CalcAngle(m_vEyePos, vPosA);
Vec3 vAnglesB = Math::CalcAngle(m_vEyePos, vPosB);
return pDoubletapAngle->DeltaAngle(vAnglesA).Length2D() < pDoubletapAngle->DeltaAngle(vAnglesB).Length2D();
@@ -650,7 +650,8 @@ bool CAimbotHitscan::Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod)
break;
}
Math::ClampAngles(vOut);
//if (iMethod != Vars::Aimbot::General::AimTypeEnum::Silent || Vars::Misc::Game::AntiCheatCompatibility.Value)
Math::ClampAngles(vOut);
return bReturn;
}
@@ -450,7 +450,8 @@ bool CAimbotMelee::Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod)
break;
}
Math::ClampAngles(vOut);
if (iMethod != Vars::Aimbot::General::AimTypeEnum::Silent || Vars::Misc::Game::AntiCheatCompatibility.Value)
Math::ClampAngles(vOut);
return bReturn;
}
@@ -178,7 +178,7 @@ static inline std::vector<Target_t> GetTargets(CTFPlayer* pLocal, CTFWeaponBase*
float CAimbotProjectile::GetSplashRadius(CTFWeaponBase* pWeapon, CTFPlayer* pPlayer)
float CAimbotProjectile::GetSplashRadius(CTFWeaponBase* pWeapon, CTFPlayer* pPlayer, float flScale)
{
float flRadius = 0.f;
switch (pWeapon->GetWeaponID())
@@ -193,6 +193,11 @@ float CAimbotProjectile::GetSplashRadius(CTFWeaponBase* pWeapon, CTFPlayer* pPla
case TF_WEAPON_FLAREGUN_REVENGE:
if (pWeapon->As<CTFFlareGun>()->GetFlareGunType() == FLAREGUN_SCORCHSHOT)
flRadius = TF_FLARE_DET_RADIUS;
break;
case TF_WEAPON_JAR:
case TF_WEAPON_JAR_MILK:
case TF_WEAPON_JAR_GAS:
return JAR_EXPLODE_RADIUS * flScale;
}
if (!flRadius)
return 0.f;
@@ -206,7 +211,7 @@ float CAimbotProjectile::GetSplashRadius(CTFWeaponBase* pWeapon, CTFPlayer* pPla
if (pPlayer->InCond(TF_COND_BLASTJUMPING) && SDK::AttribHookValue(1.f, "rocketjump_attackrate_bonus", pWeapon) != 1.f)
flRadius *= 0.8f;
}
return flRadius * Vars::Aimbot::Projectile::SplashRadius.Value / 100;
return flRadius * flScale;
}
float CAimbotProjectile::GetSplashRadius(CBaseEntity* pProjectile, CTFWeaponBase* pWeapon, CTFPlayer* pPlayer, float flScale, CTFWeaponBase* pAirblast)
@@ -233,6 +238,11 @@ float CAimbotProjectile::GetSplashRadius(CBaseEntity* pProjectile, CTFWeaponBase
case ETFClassID::CTFProjectile_Flare:
if (pWeapon && pWeapon->As<CTFFlareGun>()->GetFlareGunType() == FLAREGUN_SCORCHSHOT)
flRadius = TF_FLARE_DET_RADIUS;
break;
case ETFClassID::CTFProjectile_Jar:
case ETFClassID::CTFProjectile_JarMilk:
case ETFClassID::CTFProjectile_JarGas:
return JAR_EXPLODE_RADIUS * flScale;
}
if (pPlayer && pWeapon)
{
@@ -315,11 +325,17 @@ static inline int GetHitboxPriority(int nHitbox, Target_t& tTarget, Info_t& tInf
return -1;
};
std::unordered_map<int, Vec3> CAimbotProjectile::GetDirectPoints()
Directs_t CAimbotProjectile::GetDirects()
{
std::unordered_map<int, Vec3> mPoints = {};
Directs_t mDirects = {};
if (Vars::Aimbot::Projectile::SplashPrediction.Value == Vars::Aimbot::Projectile::SplashPredictionEnum::Only && m_tInfo.m_flRadius)
return mDirects;
auto& tTarget = *m_tInfo.m_pTarget;
byte iFlags = PointFlagsEnum::Regular;
if (Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::AlternateAngles)
iFlags |= PointFlagsEnum::Alternate;
const Vec3 vMins = tTarget.m_pEntity->m_vecMins(), vMaxs = tTarget.m_pEntity->m_vecMaxs();
for (int i = 0; i < 3; i++)
@@ -362,17 +378,35 @@ std::unordered_map<int, Vec3> CAimbotProjectile::GetDirectPoints()
vOff.x = std::clamp(vOff.x, vMins.x + Vars::Aimbot::Projectile::HuntsmanClamp.Value, vMaxs.x - Vars::Aimbot::Projectile::HuntsmanClamp.Value);
vOff.y = std::clamp(vOff.y, vMins.y + Vars::Aimbot::Projectile::HuntsmanClamp.Value, vMaxs.y - Vars::Aimbot::Projectile::HuntsmanClamp.Value);
vOff.z = std::clamp(vOff.z, vMins.z + Vars::Aimbot::Projectile::HuntsmanClamp.Value, vMaxs.z - Vars::Aimbot::Projectile::HuntsmanClamp.Value);
mPoints[iPriority] = vOff;
mDirects[iPriority] = { vOff, iFlags };
}
else
mPoints[iPriority] = Vec3(0, 0, vMaxs.z - Vars::Aimbot::Projectile::VerticalShift.Value);
mDirects[iPriority] = { Vec3(0, 0, vMaxs.z - Vars::Aimbot::Projectile::VerticalShift.Value), iFlags };
break;
case BOUNDS_BODY:
mDirects[iPriority] = { Vec3(0, 0, (vMaxs.z - vMins.z) / 2), iFlags };
break;
case BOUNDS_FEET:
mDirects[iPriority] = { Vec3(0, 0, vMins.z + Vars::Aimbot::Projectile::VerticalShift.Value), iFlags };
break;
case BOUNDS_BODY: mPoints[iPriority] = Vec3(0, 0, (vMaxs.z - vMins.z) / 2); break;
case BOUNDS_FEET: mPoints[iPriority] = Vec3(0, 0, vMins.z + Vars::Aimbot::Projectile::VerticalShift.Value); break;
}
}
return mPoints;
return mDirects;
}
Splashes_t CAimbotProjectile::GetSplashes()
{
Splashes_t vSplashes = {};
if (Vars::Aimbot::Projectile::SplashPrediction.Value == Vars::Aimbot::Projectile::SplashPredictionEnum::Off || !m_tInfo.m_flRadius)
return vSplashes;
vSplashes.push_back(PointFlagsEnum::Regular);
if (Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::AlternateAngles)
vSplashes.push_back(PointFlagsEnum::Alternate);
return vSplashes;
}
static inline std::vector<Vec3> ComputeSphere(float flRadius, int iSamples)
@@ -386,7 +420,7 @@ static inline std::vector<Vec3> ComputeSphere(float flRadius, int iSamples)
float flRotateX = Vars::Aimbot::Projectile::SplashRotateX.Value < 0.f ? SDK::RandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateX.Value;
float flRotateY = Vars::Aimbot::Projectile::SplashRotateY.Value < 0.f ? SDK::RandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateY.Value;
float a = PI * (3.f - sqrtf(5.f));
float a = Math::PI * (3.f - sqrtf(5.f));
for (int n = 0; n < iSamples; n++)
{
float t = a * n;
@@ -514,7 +548,7 @@ static inline void HandleFace(const Face_t& tFace, std::vector<Vec3>& vPoints, f
}
// possibly add air splash for autodet weapons
void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector<Vec3>& vSplashPoints)
void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector<Vec3>& vSplashPoints, byte iFlags)
{
vSplashPoints.clear();
@@ -558,10 +592,10 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector<Vec3>& vSpl
else
{
Point_t tPoint = { vPoint, {} };
CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, 0, tPoint.m_tSolution, CalculateFlagsEnum::None);
CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, 0, tPoint.m_tSolution, iFlags);
if (tPoint.m_tSolution.m_iCalculated == CalculateResultEnum::Bad)
return false;
vPoint -= Vec3(0, 0, (m_tInfo.m_flGravity * 800.f * pow(tPoint.m_tSolution.m_flTime, 2)) / 2);
vPoint -= Vec3(0, 0, (m_tInfo.m_flGravity * 800.f * powf(tPoint.m_tSolution.m_flTime, 2)) / 2);
vAngle = Vec3(tPoint.m_tSolution.m_flPitch, tPoint.m_tSolution.m_flYaw);
}
return fCheckNormal(trace.plane.normal, vPoint, &vAngle);
@@ -571,7 +605,7 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector<Vec3>& vSpl
{
Vec3 vPoint = vSpherePoints[i] + vTargetCenter;
Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, 0, tSolution, false);
Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, 0, tSolution, iFlags);
if (tSolution.m_iCalculated == CalculateResultEnum::Bad)
continue;
@@ -593,10 +627,10 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector<Vec3>& vSpl
else
{
Point_t tPoint = { vPoint, {} };
CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, 0, tPoint.m_tSolution, CalculateFlagsEnum::None);
CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, 0, tPoint.m_tSolution, iFlags);
if (tPoint.m_tSolution.m_iCalculated == CalculateResultEnum::Bad)
return false;
vPoint -= Vec3(0, 0, (m_tInfo.m_flGravity * 800.f * pow(tPoint.m_tSolution.m_flTime, 2)) / 2);
vPoint -= Vec3(0, 0, (m_tInfo.m_flGravity * 800.f * powf(tPoint.m_tSolution.m_flTime, 2)) / 2);
vAngle = Vec3(tPoint.m_tSolution.m_flPitch, tPoint.m_tSolution.m_flYaw);
}
return fCheckNormal(vNormal, vPoint, &vAngle);
@@ -624,7 +658,7 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector<Vec3>& vSpl
#endif
}
std::vector<Point_t> CAimbotProjectile::GetSplashPoints(Vec3 vOrigin, std::vector<Vec3>& vSplashPoints, int iSimTime)
std::vector<Point_t> CAimbotProjectile::GetSplashPoints(Vec3 vOrigin, std::vector<Vec3>& vSplashPoints, int iSimTime, byte iFlags)
{
std::vector<std::pair<Point_t, float>> vPointDistances = {};
@@ -634,7 +668,7 @@ std::vector<Point_t> CAimbotProjectile::GetSplashPoints(Vec3 vOrigin, std::vecto
for (auto it = vSplashPoints.begin(); it != vSplashPoints.end();)
{
Point_t tPoint = { *it, {} };
CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, iSimTime, tPoint.m_tSolution, CalculateFlagsEnum::Accuracy, !m_tInfo.m_iArmTime ? 0 : -1);
CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, iSimTime, tPoint.m_tSolution, iFlags, !m_tInfo.m_iArmTime ? 0 : -1);
if (tPoint.m_tSolution.m_iCalculated != CalculateResultEnum::Good)
{
++it;
@@ -710,13 +744,13 @@ static inline Vec3 PullPoint(const Vec3& vPoint, Vec3 vLocalPos, Info_t& tInfo,
const Vec3 vDelta = vTargetPos - vLocalPos;
const float flDist = vDelta.Length2D();
const float flRoot = pow(tInfo.m_flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(tInfo.m_flVelocity, 2));
const float flRoot = powf(tInfo.m_flVelocity, 4) - flGrav * (flGrav * powf(flDist, 2) + 2.f * vDelta.z * powf(tInfo.m_flVelocity, 2));
if (flRoot < 0.f)
return vPoint;
float flPitch = atan((pow(tInfo.m_flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
float flPitch = atan((powf(tInfo.m_flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
float flTime = flDist / (cos(flPitch) * tInfo.m_flVelocity) - tInfo.m_flOffsetTime;
return vLocalPos + Vec3(0, 0, (flGrav * pow(flTime, 2)) / 2);
return vLocalPos + Vec3(0, 0, (flGrav * powf(flTime, 2)) / 2);
};
vLocalPos = fHeightenLocalPos();
@@ -727,97 +761,145 @@ static inline Vec3 PullPoint(const Vec3& vPoint, Vec3 vLocalPos, Info_t& tInfo,
static inline void SolveProjectileSpeed(CTFWeaponBase* pWeapon, const Vec3& vLocalPos, const Vec3& vTargetPos, float& flVelocity, float& flDragTime, const float flGravity)
{
if (!F::ProjSim.m_pObj->IsDragEnabled() || F::ProjSim.m_pObj->m_dragBasis.IsZero())
return;
static inline float GetDrag(float flVelocity, ProjectileInfo* pInfo, int iFlags)
{ // stupid, would like not to hardcode magic values
if (!(iFlags & CalculateFlagsEnum::AccountDrag) || !F::ProjSim.m_pObj->m_dragCoefficient || !F::ProjSim.m_pObj->m_dragBasis)
return 0.f;
const float flGrav = flGravity * 800.0f;
const Vec3 vDelta = vTargetPos - vLocalPos;
const float flDist = vDelta.Length2D();
const float flRoot = pow(flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(flVelocity, 2));
if (flRoot < 0.f)
return;
const float flPitch = atan((pow(flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
const float flTime = flDist / (cos(flPitch) * flVelocity);
float flDrag = 0.f;
if (Vars::Aimbot::Projectile::DragOverride.Value)
flDrag = Vars::Aimbot::Projectile::DragOverride.Value;
return Vars::Aimbot::Projectile::DragOverride.Value;
if (!(iFlags & CalculateFlagsEnum::AlternateAngle))
{
switch (pInfo->m_uType)
{
case FNV1A::Hash32Const("models/weapons/w_models/w_grenade_grenadelauncher.mdl"):
if (!SDK::AttribHookValue(0, "grenade_no_spin", pInfo->m_pWeapon))
return Math::RemapVal(flVelocity, 1217.f, k_flMaxVelocity, 0.120f, 0.200f); // 0.120 normal, 0.200 capped, 0.300 v3000
else
return Math::RemapVal(flVelocity, 1217.f, k_flMaxVelocity, 0.060f, 0.085f); // 0.060 normal, 0.085 capped, 0.120 v3000
case FNV1A::Hash32Const("models/weapons/w_models/w_cannonball.mdl"):
return Math::RemapVal(flVelocity, 1454.f, k_flMaxVelocity, 0.385f, 0.530f); // 0.385 normal, 0.530 capped, 0.790 v3000
case FNV1A::Hash32Const("models/weapons/w_models/w_stickybomb.mdl"):
return Math::RemapVal(flVelocity, 922.f, k_flMaxVelocity, 0.085f, 0.190f); // 0.085 low, 0.190 capped, 0.230 v2400
case FNV1A::Hash32Const("models/workshop_partner/weapons/c_models/c_sd_cleaver/c_sd_cleaver.mdl"):
return 0.310f;
case FNV1A::Hash32Const("models/weapons/w_models/w_baseball.mdl"):
return 0.180f;
case FNV1A::Hash32Const("models/weapons/c_models/c_xms_festive_ornament.mdl"):
return 0.285f;
case FNV1A::Hash32Const("models/weapons/c_models/urinejar.mdl"):
case FNV1A::Hash32Const("models/workshop/weapons/c_models/c_madmilk/c_madmilk.mdl"):
case FNV1A::Hash32Const("models/weapons/c_models/c_breadmonster/c_breadmonster.mdl"):
case FNV1A::Hash32Const("models/weapons/c_models/c_breadmonster/c_breadmonster_milk.mdl"):
return 0.057f;
case FNV1A::Hash32Const("models/weapons/c_models/c_gascan/c_gascan.mdl"):
return 0.530f;
}
}
else
{
switch (pWeapon->m_iItemDefinitionIndex()) // the remaps are dumb but they work so /shrug
switch (pInfo->m_uType)
{
case Demoman_m_GrenadeLauncher:
case Demoman_m_GrenadeLauncherR:
case Demoman_m_FestiveGrenadeLauncher:
case Demoman_m_Autumn:
case Demoman_m_MacabreWeb:
case Demoman_m_Rainbow:
case Demoman_m_SweetDreams:
case Demoman_m_CoffinNail:
case Demoman_m_TopShelf:
case Demoman_m_Warhawk:
case Demoman_m_ButcherBird:
case Demoman_m_TheIronBomber: flDrag = Math::RemapVal(flVelocity, 1217.f, k_flMaxVelocity, 0.120f, 0.200f); break; // 0.120 normal, 0.200 capped, 0.300 v3000
case Demoman_m_TheLochnLoad: flDrag = Math::RemapVal(flVelocity, 1504.f, k_flMaxVelocity, 0.070f, 0.085f); break; // 0.070 normal, 0.085 capped, 0.120 v3000
case Demoman_m_TheLooseCannon: flDrag = Math::RemapVal(flVelocity, 1454.f, k_flMaxVelocity, 0.385f, 0.530f); break; // 0.385 normal, 0.530 capped, 0.790 v3000
case Demoman_s_StickybombLauncher:
case Demoman_s_StickybombLauncherR:
case Demoman_s_FestiveStickybombLauncher:
case Demoman_s_TheQuickiebombLauncher:
case Demoman_s_TheScottishResistance: flDrag = Math::RemapVal(flVelocity, 922.f, k_flMaxVelocity, 0.085f, 0.190f); break; // 0.085 low, 0.190 capped, 0.230 v2400
case Scout_s_TheFlyingGuillotine:
case Scout_s_TheFlyingGuillotineG: flDrag = 0.310f; break;
case Scout_t_TheSandman: flDrag = 0.180f; break;
case Scout_t_TheWrapAssassin: flDrag = 0.285f; break;
case Scout_s_MadMilk:
case Scout_s_MutatedMilk:
case Sniper_s_Jarate:
case Sniper_s_FestiveJarate:
case Sniper_s_TheSelfAwareBeautyMark: flDrag = 0.057f; break;
case FNV1A::Hash32Const("models/weapons/w_models/w_grenade_grenadelauncher.mdl"):
if (!SDK::AttribHookValue(0, "grenade_no_spin", pInfo->m_pWeapon))
return Math::RemapVal(flVelocity, 1217.f, k_flMaxVelocity, 0.056f, 0.062f);
else
return Math::RemapVal(flVelocity, 1217.f, k_flMaxVelocity, 0.030f, 0.033f);
case FNV1A::Hash32Const("models/weapons/w_models/w_cannonball.mdl"):
return Math::RemapVal(flVelocity, 1454.f, k_flMaxVelocity, 0.099f, 0.092f);
case FNV1A::Hash32Const("models/weapons/w_models/w_stickybomb.mdl"):
return Math::RemapVal(flVelocity, 922.f, k_flMaxVelocity, 0.048f, 0.060f);
case FNV1A::Hash32Const("models/workshop_partner/weapons/c_models/c_sd_cleaver/c_sd_cleaver.mdl"):
return 0.075f;
case FNV1A::Hash32Const("models/weapons/w_models/w_baseball.mdl"):
return 0.057f;
case FNV1A::Hash32Const("models/weapons/c_models/c_xms_festive_ornament.mdl"):
return 0.072f;
case FNV1A::Hash32Const("models/weapons/c_models/urinejar.mdl"):
case FNV1A::Hash32Const("models/workshop/weapons/c_models/c_madmilk/c_madmilk.mdl"):
case FNV1A::Hash32Const("models/weapons/c_models/c_breadmonster/c_breadmonster.mdl"):
case FNV1A::Hash32Const("models/weapons/c_models/c_breadmonster/c_breadmonster_milk.mdl"):
return 0.030f;
case FNV1A::Hash32Const("models/weapons/c_models/c_gascan/c_gascan.mdl"):
return 0.089f;
}
}
float flOverride = Vars::Aimbot::Projectile::TimeOverride.Value;
flDragTime = powf(flTime, 2) * flDrag / (flOverride ? flOverride : 1.5f); // rough estimate to prevent m_flTime being too low
flVelocity = flVelocity - flVelocity * flTime * flDrag;
return 0.f;
}
void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, int iFlags, int iTolerance)
static inline bool GetAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iFlags, Info_t& tInfo, float& flPitch, float& flYaw, float& flTime)
{
float flVelocity = tInfo.m_flVelocity;
float flGrav = tInfo.m_flGravity * 800.f;
Vec3 vDelta = vTargetPos - vLocalPos;
float flDist = vDelta.Length2D();
float flDrag = GetDrag(flVelocity, F::ProjSim.m_pCurrent, iFlags);
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vTargetPos);
flYaw = vAngleTo.y;
if (!flGrav)
flPitch = -Math::Deg2Rad(vAngleTo.x);
else
{
float flRoot = powf(flVelocity, 4) - flGrav * (flGrav * powf(flDist, 2) + 2.f * vDelta.z * powf(flVelocity, 2));
if (flRoot < 0.f)
return false;
if (!(iFlags & CalculateFlagsEnum::AlternateAngle))
flPitch = atan((powf(flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
else
flPitch = atan((powf(flVelocity, 2) + sqrt(flRoot)) / (flGrav * flDist));
if (flDrag)
{ // drag is handled in a stupid manner, would like something better than this
float flTime = flDist / (flVelocity * cos(flPitch));
flVelocity *= 1 - flDrag * flTime;
flRoot = powf(flVelocity, 4) - flGrav * (flGrav * powf(flDist, 2) + 2.f * vDelta.z * powf(flVelocity, 2));
if (flRoot < 0.f)
return false;
if (!(iFlags & CalculateFlagsEnum::AlternateAngle))
flPitch = atan((powf(flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
else
flPitch = atan((powf(flVelocity, 2) + sqrt(flRoot)) / (flGrav * flDist));
//flVelocity = flVelocity / (flDrag * flTime) * (1.f - powf(Math::E, -flDrag * flTime));
flVelocity = flVelocity / (1 + 0.5f * (1 - powf(Math::E, -flDrag * flTime)));
flVelocity *= 1 + vDelta.z / flVelocity * TICK_INTERVAL * flTime;
}
}
flTime = flDist / (flVelocity * cos(flPitch));
if (Vars::Aimbot::Projectile::TimeOverride.Value)
flTime *= Vars::Aimbot::Projectile::TimeOverride.Value;
return true;
}
void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, byte iFlags, int iTolerance)
{
if (tOut.m_iCalculated != CalculateResultEnum::Pending)
return;
const float flGrav = m_tInfo.m_flGravity * 800.f;
float flPitch, flYaw;
{ // basic trajectory pass
float flVelocity = m_tInfo.m_flVelocity, flDragTime = 0.f;
if (iFlags & CalculateFlagsEnum::AccountDrag && m_tInfo.m_pWeapon && F::ProjSim.m_pObj->IsDragEnabled() && !F::ProjSim.m_pObj->m_dragBasis.IsZero())
//Vec3 vForward, vRight, vUp; Math::AngleVectors(Math::CalcAngle(vLocalPos, vTargetPos), &vForward, &vRight, &vUp);
//Vec3 vShootPos = vLocalPos + (vForward * m_tInfo.m_vOffset.x) + (vRight * m_tInfo.m_vOffset.y) + (vUp * m_tInfo.m_vOffset.z);
if (!GetAngle(vLocalPos, vTargetPos, iFlags, m_tInfo, flPitch, flYaw, tOut.m_flTime))
{
Vec3 vForward, vRight, vUp; Math::AngleVectors(Math::CalcAngle(vLocalPos, vTargetPos), &vForward, &vRight, &vUp);
Vec3 vShootPos = vLocalPos + (vForward * m_tInfo.m_vOffset.x) + (vRight * m_tInfo.m_vOffset.y) + (vUp * m_tInfo.m_vOffset.z);
SolveProjectileSpeed(m_tInfo.m_pWeapon, vShootPos, vTargetPos, flVelocity, flDragTime, m_tInfo.m_flGravity);
tOut.m_iCalculated = CalculateResultEnum::Bad;
return;
}
Vec3 vDelta = vTargetPos - vLocalPos;
float flDist = vDelta.Length2D();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vTargetPos);
if (!flGrav)
flPitch = -DEG2RAD(vAngleTo.x);
else
{ // arch
float flRoot = pow(flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(flVelocity, 2));
if (tOut.m_iCalculated = flRoot < 0.f ? CalculateResultEnum::Bad : CalculateResultEnum::Pending)
return;
flPitch = atan((pow(flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
}
tOut.m_flTime = flDist / (cos(flPitch) * flVelocity) - m_tInfo.m_flOffsetTime + flDragTime;
tOut.m_flPitch = flPitch = -RAD2DEG(flPitch) - m_tInfo.m_vAngFix.x;
tOut.m_flYaw = flYaw = vAngleTo.y - m_tInfo.m_vAngFix.y;
tOut.m_flTime -= m_tInfo.m_flOffsetTime;
tOut.m_flPitch = flPitch = -Math::Rad2Deg(flPitch) - m_tInfo.m_vAngFix.x;
tOut.m_flYaw = flYaw -= m_tInfo.m_vAngFix.y;
}
int iTimeTo = ceilf(tOut.m_flTime / TICK_INTERVAL);
@@ -827,8 +909,11 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge
tOut.m_iCalculated = bGood ? CalculateResultEnum::Good : CalculateResultEnum::Time;
return;
}
else if (tOut.m_iCalculated = bGood ? CalculateResultEnum::Pending : CalculateResultEnum::Time)
else if (!bGood)
{
tOut.m_iCalculated = CalculateResultEnum::Time;
return;
}
int iSimFlags = (iFlags & CalculateFlagsEnum::SetupClip ? ProjSimEnum::Redirect : ProjSimEnum::None) | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum;
#ifdef SPLASH_DEBUG5
@@ -836,7 +921,7 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge
{
if (Vars::Visuals::Trajectory::Override.Value)
{
if (!Vars::Visuals::Trajectory::Pipes.Value)
if (!Vars::Visuals::Trajectory::ForwardRedirect.Value)
s_mTraceCount[__FUNCTION__": setup trace"]++;
}
else
@@ -861,63 +946,53 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge
}
#endif
m_tProjInfo = {};
if (tOut.m_iCalculated = !F::ProjSim.GetInfo(m_tInfo.m_pLocal, m_tInfo.m_pWeapon, { flPitch, flYaw, 0 }, m_tProjInfo, iSimFlags) ? CalculateResultEnum::Bad : CalculateResultEnum::Pending)
if (!F::ProjSim.GetInfo(m_tInfo.m_pLocal, m_tInfo.m_pWeapon, { flPitch, flYaw, 0 }, m_tProjInfo, iSimFlags))
{
tOut.m_iCalculated = CalculateResultEnum::Bad;
return;
}
{ // calculate trajectory from projectile origin
float flVelocity = m_tInfo.m_flVelocity, flDragTime = 0.f;
if (iFlags & CalculateFlagsEnum::AccountDrag && F::ProjSim.m_pObj->IsDragEnabled() && !F::ProjSim.m_pObj->m_dragBasis.IsZero())
SolveProjectileSpeed(m_tInfo.m_pWeapon, m_tProjInfo.m_vPos, vTargetPos, flVelocity, flDragTime, m_tInfo.m_flGravity);
Vec3 vDelta = vTargetPos - m_tProjInfo.m_vPos;
float flDist = vDelta.Length2D();
Vec3 vAngleTo = Math::CalcAngle(m_tProjInfo.m_vPos, vTargetPos);
if (!flGrav)
tOut.m_flPitch = -DEG2RAD(vAngleTo.x);
else
{ // arch
float flRoot = pow(flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(flVelocity, 2));
if (tOut.m_iCalculated = flRoot < 0.f ? CalculateResultEnum::Bad : CalculateResultEnum::Pending)
return;
tOut.m_flPitch = atan((pow(flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
}
tOut.m_flTime = flDist / (cos(tOut.m_flPitch) * flVelocity) + flDragTime;
}
{ // correct yaw
Vec3 vShootPos = (m_tProjInfo.m_vPos - vLocalPos).To2D();
Vec3 vTarget = vTargetPos - vLocalPos;
Vec3 vForward; Math::AngleVectors(m_tProjInfo.m_vAng, &vForward); vForward.Normalize2D();
float flB = 2 * (vShootPos.x * vForward.x + vShootPos.y * vForward.y);
float flC = vShootPos.Length2DSqr() - vTarget.Length2DSqr();
auto vSolutions = Math::SolveQuadratic(1.f, flB, flC);
if (!vSolutions.empty())
if (!GetAngle(m_tProjInfo.m_vPos, vTargetPos, iFlags, m_tInfo, tOut.m_flPitch, tOut.m_flYaw, tOut.m_flTime))
{
vShootPos += vForward * vSolutions.front();
tOut.m_flYaw = flYaw - (RAD2DEG(atan2(vShootPos.y, vShootPos.x)) - flYaw);
flYaw = RAD2DEG(atan2(vShootPos.y, vShootPos.x));
tOut.m_iCalculated = CalculateResultEnum::Bad;
return;
}
}
{ // correct pitch
if (flGrav)
{
flPitch -= m_tProjInfo.m_vAng.x;
tOut.m_flPitch = -RAD2DEG(tOut.m_flPitch) + flPitch - m_tInfo.m_vAngFix.x;
}
else
{
Vec3 vShootPos = Math::RotatePoint(m_tProjInfo.m_vPos - vLocalPos, {}, { 0, -flYaw, 0 }); vShootPos.y = 0;
Vec3 vTarget = Math::RotatePoint(vTargetPos - vLocalPos, {}, { 0, -flYaw, 0 });
Vec3 vForward; Math::AngleVectors(m_tProjInfo.m_vAng - Vec3(0, flYaw, 0), &vForward); vForward.y = 0; vForward.Normalize();
float flB = 2 * (vShootPos.x * vForward.x + vShootPos.z * vForward.z);
float flC = (powf(vShootPos.x, 2) + powf(vShootPos.z, 2)) - (powf(vTarget.x, 2) + powf(vTarget.z, 2));
{ // correct yaw
Vec3 vShootPos = (m_tProjInfo.m_vPos - vLocalPos).To2D();
Vec3 vTarget = vTargetPos - vLocalPos;
Vec3 vForward; Math::AngleVectors(m_tProjInfo.m_vAng, &vForward); vForward.Normalize2D();
float flB = 2 * (vShootPos.x * vForward.x + vShootPos.y * vForward.y);
float flC = vShootPos.Length2DSqr() - vTarget.Length2DSqr();
auto vSolutions = Math::SolveQuadratic(1.f, flB, flC);
if (!vSolutions.empty())
{
vShootPos += vForward * vSolutions.front();
tOut.m_flPitch = flPitch - (RAD2DEG(atan2(-vShootPos.z, vShootPos.x)) - flPitch);
tOut.m_flYaw = flYaw - (Math::Rad2Deg(atan2(vShootPos.y, vShootPos.x)) - flYaw);
flYaw = Math::Rad2Deg(atan2(vShootPos.y, vShootPos.x));
}
}
{ // correct pitch
if (m_tInfo.m_flGravity)
{
flPitch -= m_tProjInfo.m_vAng.x;
tOut.m_flPitch = -Math::Rad2Deg(tOut.m_flPitch) + flPitch - m_tInfo.m_vAngFix.x;
}
else
{
Vec3 vShootPos = Math::RotatePoint(m_tProjInfo.m_vPos - vLocalPos, {}, { 0, -flYaw, 0 }); vShootPos.y = 0;
Vec3 vTarget = Math::RotatePoint(vTargetPos - vLocalPos, {}, { 0, -flYaw, 0 });
Vec3 vForward; Math::AngleVectors(m_tProjInfo.m_vAng - Vec3(0, flYaw, 0), &vForward); vForward.y = 0; vForward.Normalize();
float flB = 2 * (vShootPos.x * vForward.x + vShootPos.z * vForward.z);
float flC = (powf(vShootPos.x, 2) + powf(vShootPos.z, 2)) - (powf(vTarget.x, 2) + powf(vTarget.z, 2));
auto vSolutions = Math::SolveQuadratic(1.f, flB, flC);
if (!vSolutions.empty())
{
vShootPos += vForward * vSolutions.front();
tOut.m_flPitch = flPitch - (Math::Rad2Deg(atan2(-vShootPos.z, vShootPos.x)) - flPitch);
}
}
}
}
@@ -934,12 +1009,13 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
auto pLocal = m_tInfo.m_pLocal;
auto pWeapon = m_tInfo.m_pWeapon;
auto& tTarget = *m_tInfo.m_pTarget;
int iTimingTolerance = TIME_TO_TICKS(m_tInfo.m_flBoundingTime);
int iSimFlags = ProjSimEnum::Redirect | ProjSimEnum::InitCheck | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum;
#ifdef SPLASH_DEBUG5
if (Vars::Visuals::Trajectory::Override.Value)
{
if (!Vars::Visuals::Trajectory::Pipes.Value)
if (!Vars::Visuals::Trajectory::ForwardRedirect.Value)
s_mTraceCount[__FUNCTION__": setup trace"]++;
}
else
@@ -1059,7 +1135,7 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
{
bool bTime = bSplash
? trace.endpos.DistTo(vPoint) < m_tProjInfo.m_flVelocity * TICK_INTERVAL + m_tProjInfo.m_vHull.z
: iSimTime - n < 5 || pWeapon->GetWeaponID() == TF_WEAPON_LUNCHBOX; // projectile so slow it causes problems if we don't waive this check
: iSimTime - n < iTimingTolerance;
bool bTarget = trace.m_pEnt == tTarget.m_pEntity || bSplash;
bool bValid = bTarget && bTime;
if (bValid && bSplash)
@@ -1143,8 +1219,9 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
}
else if (!bSplash && bTarget && pWeapon->GetWeaponID() == TF_WEAPON_PIPEBOMBLAUNCHER)
{ // run for more ticks to check for splash
iSimTime = n + 5;
iSimTime = n + iTimingTolerance;
bSplash = bArmTime = true;
filter.pSkip = tTarget.m_pEntity;
}
else
break;
@@ -1211,60 +1288,73 @@ bool CAimbotProjectile::HandlePoint(const Vec3& vOrigin, int iSimTime, float flP
return bReturn;
}
bool CAimbotProjectile::HandleDirect(std::vector<Direct_t>& vDirectHistory)
bool CAimbotProjectile::HandleDirect(DirectHistory_t& mDirectHistory)
{
if (vDirectHistory.empty())
if (mDirectHistory.empty())
return false;
std::sort(vDirectHistory.begin(), vDirectHistory.end(), [&](const Direct_t& a, const Direct_t& b) -> bool
{
return a.m_iPriority < b.m_iPriority;
});
m_flTimeTo = vDirectHistory.front().m_flTime + m_tInfo.m_flLatency;
for (auto& tHistory : vDirectHistory)
for (auto& vDirectHistory : mDirectHistory | std::views::values)
{
if (HandlePoint(tHistory.m_vOrigin, tHistory.m_iSimtime, tHistory.m_flPitch, tHistory.m_flYaw, tHistory.m_flTime, tHistory.m_vPoint))
return true;
std::sort(vDirectHistory.begin(), vDirectHistory.end(), [&](const Direct_t& a, const Direct_t& b) -> bool
{
return a.m_iPriority < b.m_iPriority;
});
m_flTimeTo = vDirectHistory.front().m_flTime + m_tInfo.m_flLatency;
for (auto& tHistory : vDirectHistory)
{
if (HandlePoint(tHistory.m_vOrigin, tHistory.m_iSimtime, tHistory.m_flPitch, tHistory.m_flYaw, tHistory.m_flTime, tHistory.m_vPoint))
return true;
}
}
return false;
}
bool CAimbotProjectile::HandleSplash(std::vector<Splash_t>& vSplashHistory)
bool CAimbotProjectile::HandleSplash(SplashHistory_t& mSplashHistory)
{
if (vSplashHistory.empty())
if (mSplashHistory.empty())
return false;
std::sort(vSplashHistory.begin(), vSplashHistory.end(), [&](const Splash_t& a, const Splash_t& b) -> bool
{
return a.m_flTimeTo < b.m_flTimeTo;
});
SetupSplashPoints(vSplashHistory.front().m_vOrigin, m_vSplashPoints);
if (m_vSplashPoints.empty())
return false;
float flLowestDistance = std::numeric_limits<float>::max();
for (auto& tHistory : vSplashHistory)
for (auto& [iType, vSplashHistory] : mSplashHistory)
{
if (m_tInfo.m_iArmTime && tHistory.m_iSimtime < m_tInfo.m_iArmTime)
continue;
std::sort(vSplashHistory.begin(), vSplashHistory.end(), [&](const Splash_t& a, const Splash_t& b) -> bool
{
return a.m_flTimeTo < b.m_flTimeTo;
});
byte iFlags = CalculateFlagsEnum::None;
if (iType == PointFlagsEnum::Alternate)
iFlags |= CalculateFlagsEnum::AlternateAngle;
SetupSplashPoints(vSplashHistory.front().m_vOrigin, m_vSplashPoints, iFlags);
if (m_vSplashPoints.empty())
return false;
std::vector<Point_t> vSplashPoints = {};
vSplashPoints = GetSplashPoints(tHistory.m_vOrigin, m_vSplashPoints, tHistory.m_iSimtime);
for (auto& tPoint : vSplashPoints)
iFlags |= CalculateFlagsEnum::Accuracy;
float flLowestDistance = std::numeric_limits<float>::max();
for (auto& tHistory : vSplashHistory)
{
float flDistance = tHistory.m_vOrigin.DistTo(tPoint.m_vPoint);
if (flDistance > flLowestDistance)
if (m_tInfo.m_iArmTime && tHistory.m_iSimtime < m_tInfo.m_iArmTime)
continue;
if (HandlePoint(tHistory.m_vOrigin, tHistory.m_iSimtime, tPoint.m_tSolution.m_flPitch, tPoint.m_tSolution.m_flYaw, tPoint.m_tSolution.m_flTime, tPoint.m_vPoint, true))
flLowestDistance = flDistance;
std::vector<Point_t> vSplashPoints = {};
vSplashPoints = GetSplashPoints(tHistory.m_vOrigin, m_vSplashPoints, tHistory.m_iSimtime, iFlags);
for (auto& tPoint : vSplashPoints)
{
float flDistance = tHistory.m_vOrigin.DistTo(tPoint.m_vPoint);
if (flDistance > flLowestDistance)
continue;
if (HandlePoint(tHistory.m_vOrigin, tHistory.m_iSimtime, tPoint.m_tSolution.m_flPitch, tPoint.m_tSolution.m_flYaw, tPoint.m_tSolution.m_flTime, tPoint.m_vPoint, true))
flLowestDistance = flDistance;
}
}
if (flLowestDistance != std::numeric_limits<float>::max())
return true;
}
return flLowestDistance != std::numeric_limits<float>::max();
return false;
}
int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, bool bVisuals)
@@ -1296,7 +1386,7 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas
m_tInfo.m_flGravity = m_tProjInfo.m_flGravity;
m_tInfo.m_iSplashCount = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashCountDirect.Value : Vars::Aimbot::Projectile::SplashCountArc.Value;
m_tInfo.m_flRadius = GetSplashRadius(pWeapon, pLocal);
m_tInfo.m_flRadius = GetSplashRadius(pWeapon, pLocal, Vars::Aimbot::Projectile::SplashRadius.Value / 100);
m_tInfo.m_flRadiusTime = m_tInfo.m_flRadius / m_tInfo.m_flVelocity;
m_tInfo.m_flBoundingTime = m_tInfo.m_flRadiusTime + tTarget.m_pEntity->GetSize().Length() / m_tInfo.m_flVelocity;
m_tInfo.m_iArmTime = TIME_TO_TICKS(ArmTime(pWeapon));
@@ -1310,14 +1400,13 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas
Directs_t mDirects = GetDirects();
Splashes_t vSplashes = GetSplashes();
DirectHistory_t mDirectHistory = {};
SplashHistory_t mSplashHistory = {};
int iMaxTime = TIME_TO_TICKS(std::min(m_tProjInfo.m_flLifetime, Vars::Aimbot::Projectile::MaxSimulationTime.Value));
int iSplash = Vars::Aimbot::Projectile::SplashPrediction.Value && m_tInfo.m_flRadius ? Vars::Aimbot::Projectile::SplashPrediction.Value : Vars::Aimbot::Projectile::SplashPredictionEnum::Off;
auto mDirectPoints = iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Only ? std::unordered_map<int, Vec3>() : GetDirectPoints();
std::vector<Direct_t> vDirectHistory = {};
std::vector<Splash_t> vSplashHistory = {};
for (int i = 1 - TIME_TO_TICKS(m_tInfo.m_flLatency); i <= iMaxTime; i++)
{
if (!m_tMoveStorage.m_bFailed)
@@ -1328,26 +1417,11 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas
if (i < 0)
continue;
bool bDirectBreaks = true;
if (iSplash)
for (auto& [iIndex, tOffset] : mDirects)
{
Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, CalculateFlagsEnum::None);
if (tSolution.m_iCalculated != CalculateResultEnum::Bad)
{
const float flTimeTo = tSolution.m_flTime - TICKS_TO_TIME(i);
Vec3& vOffset = tOffset.m_vOffset;
byte iType = tOffset.m_iFlags & -tOffset.m_iFlags;
bDirectBreaks = false;
if (flTimeTo < m_tInfo.m_flBoundingTime)
{
bDirectBreaks = flTimeTo < -m_tInfo.m_flBoundingTime && (!m_tInfo.m_iArmTime || m_tInfo.m_iArmTime < i);
if (!bDirectBreaks)
vSplashHistory.emplace_back(History_t(tTarget.m_vPos, i), fabsf(flTimeTo));
}
}
}
for (auto& [iIndex, vOffset] : mDirectPoints)
{
Vec3 vPoint = tTarget.m_vPos + vOffset;
if (Vars::Aimbot::Projectile::HuntsmanPullPoint.Value && tTarget.m_nAimedHitbox == HITBOX_HEAD)
{
@@ -1362,32 +1436,64 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas
case CalculateResultEnum::Good:
if (m_tInfo.m_iArmTime && m_tInfo.m_iArmTime > i && !m_tMoveStorage.m_MoveData.m_vecVelocity.IsZero())
break;
vDirectHistory.emplace_back(History_t(tTarget.m_vPos, i), tSolution.m_flPitch, tSolution.m_flYaw, tSolution.m_flTime, vPoint, iIndex);
mDirectHistory[iType].emplace_back(History_t(tTarget.m_vPos, i), tSolution.m_flPitch, tSolution.m_flYaw, tSolution.m_flTime, vPoint, iIndex);
[[fallthrough]];
case CalculateResultEnum::Bad:
mDirectPoints.erase(iIndex);
tOffset.m_iFlags &= ~iType;
if (!(tOffset.m_iFlags /*& (PointFlagsEnum::Regular | PointFlagsEnum::Alternate)*/))
mDirects.erase(iIndex);
}
}
if (bDirectBreaks && mDirectPoints.empty())
for (auto it = vSplashes.begin(); it != vSplashes.end();)
{
byte iFlags = CalculateFlagsEnum::AccountDrag;
if (*it == PointFlagsEnum::Alternate)
iFlags |= CalculateFlagsEnum::AlternateAngle;
Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, iFlags);
if (tSolution.m_iCalculated == CalculateResultEnum::Bad && mDirects.empty())
{
it = vSplashes.erase(it);
continue;
}
const float flTimeTo = tSolution.m_flTime - TICKS_TO_TIME(i);
if (flTimeTo > m_tInfo.m_flBoundingTime)
{
++it;
continue;
}
if (flTimeTo < -m_tInfo.m_flBoundingTime && (!m_tInfo.m_iArmTime || m_tInfo.m_iArmTime < i))
{
it = vSplashes.erase(it);
continue;
}
mSplashHistory[*it].emplace_back(History_t(tTarget.m_vPos, i), fabsf(flTimeTo));
++it;
}
if (mDirects.empty() && vSplashes.empty())
break;
}
m_iResult = false;
switch (iSplash)
switch (m_tInfo.m_flRadius ? Vars::Aimbot::Projectile::SplashPrediction.Value : Vars::Aimbot::Projectile::SplashPredictionEnum::Off)
{
case Vars::Aimbot::Projectile::SplashPredictionEnum::Off:
HandleDirect(vDirectHistory);
HandleDirect(mDirectHistory);
break;
case Vars::Aimbot::Projectile::SplashPredictionEnum::Include:
if (!HandleDirect(vDirectHistory))
HandleSplash(vSplashHistory);
if (!HandleDirect(mDirectHistory))
HandleSplash(mSplashHistory);
break;
case Vars::Aimbot::Projectile::SplashPredictionEnum::Prefer:
if (!HandleSplash(vSplashHistory))
HandleDirect(vDirectHistory);
if (!HandleSplash(mSplashHistory))
HandleDirect(mDirectHistory);
break;
case Vars::Aimbot::Projectile::SplashPredictionEnum::Only:
HandleSplash(vSplashHistory);
HandleSplash(mSplashHistory);
}
F::MoveSim.Restore(m_tMoveStorage);
@@ -1459,7 +1565,8 @@ bool CAimbotProjectile::Aim(const Vec3& vCurAngle, const Vec3& vToAngle, Vec3& v
break;
}
Math::ClampAngles(vOut);
if (iMethod != Vars::Aimbot::General::AimTypeEnum::Silent || Vars::Misc::Game::AntiCheatCompatibility.Value)
Math::ClampAngles(vOut);
return bReturn;
}
@@ -1960,14 +2067,13 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa
Directs_t mDirects = GetDirects();
Splashes_t vSplashes = GetSplashes();
DirectHistory_t mDirectHistory = {};
SplashHistory_t mSplashHistory = {};
int iMaxTime = TIME_TO_TICKS(Vars::Aimbot::Projectile::MaxSimulationTime.Value);
int iSplash = Vars::Aimbot::Projectile::SplashPrediction.Value && m_tInfo.m_flRadius ? Vars::Aimbot::Projectile::SplashPrediction.Value : Vars::Aimbot::Projectile::SplashPredictionEnum::Off;
auto mDirectPoints = iSplash == Vars::Aimbot::Projectile::SplashPredictionEnum::Only ? std::unordered_map<int, Vec3>() : GetDirectPoints();
std::vector<Direct_t> vDirectHistory = {};
std::vector<Splash_t> vSplashHistory = {};
for (int i = 1 - TIME_TO_TICKS(m_tInfo.m_flLatency); i <= iMaxTime; i++)
{
if (!m_tMoveStorage.m_bFailed)
@@ -1978,26 +2084,11 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa
if (i < 0)
continue;
bool bDirectBreaks = true;
if (iSplash)
for (auto& [iIndex, tOffset] : mDirects)
{
Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, CalculateFlagsEnum::None);
if (tSolution.m_iCalculated != CalculateResultEnum::Bad)
{
const float flTimeTo = tSolution.m_flTime - TICKS_TO_TIME(i);
Vec3& vOffset = tOffset.m_vOffset;
byte iType = tOffset.m_iFlags & -tOffset.m_iFlags;
bDirectBreaks = false;
if (flTimeTo < m_tInfo.m_flBoundingTime)
{
bDirectBreaks = flTimeTo < -m_tInfo.m_flBoundingTime;
if (!bDirectBreaks)
vSplashHistory.emplace_back(History_t(tTarget.m_vPos, i), fabsf(flTimeTo));
}
}
}
for (auto& [iIndex, vOffset] : mDirectPoints)
{
Vec3 vPoint = tTarget.m_vPos + vOffset;
if (Vars::Aimbot::Projectile::HuntsmanPullPoint.Value && tTarget.m_nAimedHitbox == HITBOX_HEAD)
{
@@ -2010,32 +2101,64 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa
switch (tSolution.m_iCalculated)
{
case CalculateResultEnum::Good:
vDirectHistory.emplace_back(History_t(tTarget.m_vPos, i), tSolution.m_flPitch, tSolution.m_flYaw, tSolution.m_flTime, vPoint, iIndex);
mDirectHistory[iType].emplace_back(History_t(tTarget.m_vPos, i), tSolution.m_flPitch, tSolution.m_flYaw, tSolution.m_flTime, vPoint, iIndex);
[[fallthrough]];
case CalculateResultEnum::Bad:
mDirectPoints.erase(iIndex);
tOffset.m_iFlags &= ~iType;
if (!(tOffset.m_iFlags /*& (PointFlagsEnum::Regular | PointFlagsEnum::Alternate)*/))
mDirects.erase(iIndex);
}
}
if (bDirectBreaks && mDirectPoints.empty())
for (auto it = vSplashes.begin(); it != vSplashes.end();)
{
byte iFlags = CalculateFlagsEnum::AccountDrag;
if (*it == PointFlagsEnum::Alternate)
iFlags |= CalculateFlagsEnum::AlternateAngle;
Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, CalculateFlagsEnum::None);
if (tSolution.m_iCalculated == CalculateResultEnum::Bad && mDirects.empty())
{
it = vSplashes.erase(it);
continue;
}
const float flTimeTo = tSolution.m_flTime - TICKS_TO_TIME(i);
if (flTimeTo > m_tInfo.m_flBoundingTime)
{
++it;
continue;
}
if (flTimeTo < -m_tInfo.m_flBoundingTime)
{
it = vSplashes.erase(it);
continue;
}
mSplashHistory[*it].emplace_back(History_t(tTarget.m_vPos, i), fabsf(flTimeTo));
++it;
}
if (mDirects.empty() && vSplashes.empty())
break;
}
m_iResult = false;
switch (iSplash)
switch (m_tInfo.m_flRadius ? Vars::Aimbot::Projectile::SplashPrediction.Value : Vars::Aimbot::Projectile::SplashPredictionEnum::Off)
{
case Vars::Aimbot::Projectile::SplashPredictionEnum::Off:
HandleDirect(vDirectHistory);
HandleDirect(mDirectHistory);
break;
case Vars::Aimbot::Projectile::SplashPredictionEnum::Include:
if (!HandleDirect(vDirectHistory))
HandleSplash(vSplashHistory);
if (!HandleDirect(mDirectHistory))
HandleSplash(mSplashHistory);
break;
case Vars::Aimbot::Projectile::SplashPredictionEnum::Prefer:
if (!HandleSplash(vSplashHistory))
HandleDirect(vDirectHistory);
if (!HandleSplash(mSplashHistory))
HandleDirect(mDirectHistory);
break;
case Vars::Aimbot::Projectile::SplashPredictionEnum::Only:
HandleSplash(vSplashHistory);
HandleSplash(mSplashHistory);
}
F::MoveSim.Restore(m_tMoveStorage);
@@ -5,7 +5,8 @@
#include "../../Simulation/MovementSimulation/MovementSimulation.h"
#include "../../Simulation/ProjectileSimulation/ProjectileSimulation.h"
Enum(CalculateFlags, None = 0, TwoPass = 1 << 0, SetupClip = 1 << 1, AccountDrag = 1 << 2, Accuracy = TwoPass | SetupClip | AccountDrag)
Enum(PointFlags, None = 0, Regular = 1 << 0, Alternate = 1 << 1)
Enum(CalculateFlags, None = 0, TwoPass = 1 << 0, SetupClip = 1 << 1, AccountDrag = 1 << 2, AlternateAngle = 1 << 3, Accuracy = TwoPass | SetupClip | AccountDrag)
Enum(CalculateResult, Pending, Good, Time, Bad)
struct Info_t
@@ -46,6 +47,14 @@ struct Point_t
Solution_t m_tSolution = {};
};
struct Offset_t
{
Vec3 m_vOffset;
byte m_iFlags;
};
using Directs_t = std::unordered_map<byte, Offset_t>;
using Splashes_t = std::vector<byte>;
struct History_t
{
Vec3 m_vOrigin;
@@ -63,20 +72,23 @@ struct Splash_t : History_t
{
float m_flTimeTo;
};
using DirectHistory_t = std::unordered_map<byte, std::vector<Direct_t>>;
using SplashHistory_t = std::unordered_map<byte, std::vector<Splash_t>>;
class CAimbotProjectile
{
private:
std::unordered_map<int, Vec3> GetDirectPoints();
void SetupSplashPoints(Vec3& vOrigin, std::vector<Vec3>& vSplashPoints);
std::vector<Point_t> GetSplashPoints(Vec3 vOrigin, std::vector<Vec3>& vSplashPoints, int iSimTime);
Directs_t GetDirects();
Splashes_t GetSplashes();
void SetupSplashPoints(Vec3& vOrigin, std::vector<Vec3>& vSplashPoints, byte iFlags = CalculateFlagsEnum::None);
std::vector<Point_t> GetSplashPoints(Vec3 vOrigin, std::vector<Vec3>& vSplashPoints, int iSimTime, byte iFlags = CalculateFlagsEnum::Accuracy);
void CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, int iFlags = CalculateFlagsEnum::Accuracy, int iTolerance = -1);
void CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, byte iFlags = CalculateFlagsEnum::Accuracy, int iTolerance = -1);
bool TestAngle(const Vec3& vPoint, const Vec3& vAngles, int iSimTime, bool bSplash, bool bSecondTest = false);
bool HandlePoint(const Vec3& vOrigin, int iSimTime, float flPitch, float flYaw, float flTime, const Vec3& vPoint, bool bSplash = false);
bool HandleDirect(std::vector<Direct_t>& vDirectHistory);
bool HandleSplash(std::vector<Splash_t>& vSplashHistory);
bool HandleDirect(DirectHistory_t& vDirectHistory);
bool HandleSplash(SplashHistory_t& vSplashHistory);
int CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, bool bVisuals = true);
bool RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
@@ -108,7 +120,7 @@ private:
public:
void Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd);
float GetSplashRadius(CTFWeaponBase* pWeapon, CTFPlayer* pPlayer);
float GetSplashRadius(CTFWeaponBase* pWeapon, CTFPlayer* pPlayer, float flScale = 1.f);
bool AutoAirblast(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd, CBaseEntity* pProjectile);
float GetSplashRadius(CBaseEntity* pProjectile, CTFWeaponBase* pWeapon = nullptr, CTFPlayer* pPlayer = nullptr, float flScale = 1.f, CTFWeaponBase* pAirblast = nullptr);
@@ -154,7 +154,7 @@ bool CAutoDetonate::CheckTargets(CTFPlayer* pLocal, EntityEnum::EntityEnum iGrou
bool CAutoDetonate::CheckSelf(CTFPlayer* pLocal, EntityEnum::EntityEnum iGroup)
{
if (!(Vars::Aimbot::Projectile::AutoDetonate.Value & Vars::Aimbot::Projectile::AutoDetonateEnum::PreventSelfDamage) || !pLocal->IsAlive() || pLocal->IsAGhost())
if (!(Vars::Aimbot::Projectile::AutoDetonate.Value & Vars::Aimbot::Projectile::AutoDetonateEnum::PreventSelfDamage) || !pLocal->IsAlive() || pLocal->IsAGhost() || pLocal->IsInvulnerable())
return false;
auto& vProjectiles = H::Entities.GetGroup(iGroup);
@@ -78,8 +78,8 @@ bool CAutoRocketJump::SetAngles(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser
if (!vSolutions.empty())
{
vShootPos += vForward * vSolutions.front();
m_vAngles.y = flYaw - (RAD2DEG(atan2(vShootPos.y, vShootPos.x)) - flYaw);
flYaw = RAD2DEG(atan2(vShootPos.y, vShootPos.x));
m_vAngles.y = flYaw - (Math::Rad2Deg(atan2(vShootPos.y, vShootPos.x)) - flYaw);
flYaw = Math::Rad2Deg(atan2(vShootPos.y, vShootPos.x));
}
}
@@ -93,7 +93,7 @@ bool CAutoRocketJump::SetAngles(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser
if (!vSolutions.empty())
{
vShootPos += vForward * vSolutions.front();
m_vAngles.x = flPitch - (RAD2DEG(atan2(-vShootPos.z, vShootPos.x)) - flPitch);
m_vAngles.x = flPitch - (Math::Rad2Deg(atan2(-vShootPos.z, vShootPos.x)) - flPitch);
}
}
+17 -9
View File
@@ -254,21 +254,29 @@ namespace ImGui
if (bVertical)
{
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x - flInset + vSize.x, vDrawPos.y + flSize }, uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight);
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flSize }, { vDrawPos.x - flInset + vSize.x, vDrawPos.y - flInset + vSize.y }, uBackground, H::Draw.Scale(3), ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight);
if (bTwoToneBorder)
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flSize - H::Draw.Scale() }, {vDrawPos.x - flInset + vSize.x, vDrawPos.y + flSize }, uBorder);
if (!bTwoToneBorder)
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x + vSize.x - flInset, vDrawPos.y + flSize }, uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight);
else
{
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x + vSize.x - flInset, vDrawPos.y + flSize - H::Draw.Scale() }, uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight);
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flSize - H::Draw.Scale() }, { vDrawPos.x + vSize.x - flInset, vDrawPos.y + flSize }, uBorder);
}
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flSize }, { vDrawPos.x + vSize.x - flInset, vDrawPos.y + vSize.y - flInset }, uBackground, H::Draw.Scale(3), ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight);
}
else
{
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x + flSize, vDrawPos.y - flInset + vSize.y }, uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomLeft);
pDrawList->AddRectFilled({ vDrawPos.x + flSize, vDrawPos.y + flInset }, { vDrawPos.x - flInset + vSize.x, vDrawPos.y - flInset + vSize.y }, uBackground, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomRight);
if (bTwoToneBorder)
pDrawList->AddRectFilled({ vDrawPos.x + flSize - H::Draw.Scale(), vDrawPos.y + flInset }, { vDrawPos.x + flSize, vDrawPos.y - flInset + vSize.y }, uBorder);
if (!bTwoToneBorder)
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x + flSize, vDrawPos.y + vSize.y - flInset }, uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomLeft);
else
{
pDrawList->AddRectFilled({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x + flSize - H::Draw.Scale(), vDrawPos.y + vSize.y - flInset }, uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomLeft);
pDrawList->AddRectFilled({ vDrawPos.x + flSize - H::Draw.Scale(), vDrawPos.y + flInset }, { vDrawPos.x + flSize, vDrawPos.y + vSize.y - flInset }, uBorder);
}
pDrawList->AddRectFilled({ vDrawPos.x + flSize, vDrawPos.y + flInset }, { vDrawPos.x + vSize.x - flInset, vDrawPos.y + vSize.y - flInset }, uBackground, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomRight);
}
flInset += H::Draw.Scale(0.5f) - 0.5f - H::Draw.Scale();
pDrawList->AddRect({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x - flInset + vSize.x, vDrawPos.y - flInset + vSize.y }, uBorder, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale());
pDrawList->AddRect({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x + vSize.x - flInset, vDrawPos.y + vSize.y - flInset }, uBorder, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale());
}
inline void Divider(float flPrePadding = H::Draw.Scale(8), float flPostPadding = H::Draw.Scale(7), float flInset = H::Draw.Scale(), ImU32 uBorder = F::Render.Background2)
{
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -140,7 +140,7 @@ void CMisc::AutoStrafe(CTFPlayer* pLocal, CUserCmd* pCmd)
break;
float flTurnScale = Math::RemapVal(Vars::Misc::Movement::AutoStrafeTurnScale.Value, 0.f, 1.f, 0.9f, 1.f);
float flRotation = DEG2RAD((flDirDelta > 0.f ? -90.f : 90.f) + flDirDelta * flTurnScale);
float flRotation = Math::Deg2Rad((flDirDelta > 0.f ? -90.f : 90.f) + flDirDelta * flTurnScale);
float flCosRot = cosf(flRotation), flSinRot = sinf(flRotation);
pCmd->forwardmove = flCosRot * flForward - flSinRot * flSide;
@@ -23,7 +23,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
if (Vars::Visuals::Trajectory::Override.Value)
{
SDK::GetProjectileFireSetup(pPlayer, vAngles, { Vars::Visuals::Trajectory::OffsetX.Value, Vars::Visuals::Trajectory::OffsetY.Value, Vars::Visuals::Trajectory::OffsetZ.Value }, vPos, vAngle, Vars::Visuals::Trajectory::ForwardRedirect.Value, !bRedirect ? 1.f : Vars::Visuals::Trajectory::ForwardCutoff.Value, bInterp);
SDK::GetProjectileFireSetup(pPlayer, vAngles, { Vars::Visuals::Trajectory::OffsetX.Value, Vars::Visuals::Trajectory::OffsetY.Value, Vars::Visuals::Trajectory::OffsetZ.Value }, vPos, vAngle, bRedirect ? Vars::Visuals::Trajectory::ForwardRedirect.Value : 0.f, Vars::Visuals::Trajectory::ForwardCutoff.Value, bInterp);
tProjInfo = { pPlayer, pWeapon, FNV1A::Hash32Const("custom"), vPos, vAngle, { Vars::Visuals::Trajectory::Hull.Value, Vars::Visuals::Trajectory::Hull.Value, Vars::Visuals::Trajectory::Hull.Value }, Vars::Visuals::Trajectory::Speed.Value, Vars::Visuals::Trajectory::Gravity.Value, Vars::Visuals::Trajectory::LifeTime.Value };
return true;
@@ -360,7 +360,9 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
if (!m_pEnv || !m_pObj)
return false;
//set drag
m_pCurrent = &tProjInfo;
// set drag
{
float flDrag = 0.f;
Vec3 vDragBasis = {};
@@ -403,7 +405,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
break;
case FNV1A::Hash32Const("models/weapons/w_models/w_baseball.mdl"):
flDrag = 1.f;
vDragBasis = { 0.009000f /*0.006645f*/, 0.006581f, 0.006710f};
vDragBasis = { 0.009000f /*0.006645f*/, 0.006581f, 0.006710f };
vAngDragBasis = { 0.002233f, 0.002246f, 0.002206f };
break;
case FNV1A::Hash32Const("models/weapons/c_models/c_xms_festive_ornament.mdl"):
@@ -443,7 +445,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
m_pObj->m_angDragBasis = vAngDragBasis;
}
//set position and velocity
// set position and velocity
{
Vec3 vVelocity, vAngularVelocity;
if (!bWorld)
@@ -478,7 +480,8 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
vAngularVelocity = { 600.f, float(SDK::RandomInt(-1200, 1200)), 0.f };
break;
}
vAngularVelocity = { 600.f, -1200.f, 0.f };
if (!tProjInfo.m_pWeapon || !SDK::AttribHookValue(0, "grenade_no_spin", tProjInfo.m_pWeapon))
vAngularVelocity = { 600.f, -1200.f, 0.f };
break;
case FNV1A::Hash32Const("models/workshop_partner/weapons/c_models/c_sd_cleaver/c_sd_cleaver.mdl"):
vVelocity = vForward * 10 + vUp;
@@ -554,12 +557,11 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
m_pObj->SetVelocity(&vVelocity, &vAngularVelocity);
}
//set m_pEnv params
// set m_pEnv params
{
float flMaxVelocity = 1000000.f;
float vMaxAngularVelocity = 1000000.f;
//only pipes need k_flMaxVelocity and k_flMaxAngularVelocity
switch (tProjInfo.m_uType)
{
case FNV1A::Hash32Const("custom"):
@@ -585,7 +587,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
params.maxAngularVelocity = vMaxAngularVelocity;
m_pEnv->SetPerformanceSettings(&params);
m_pEnv->SetAirDensity(2.f);
m_pEnv->SetAirDensity(AIR_DENSITY);
m_pEnv->SetGravity({ 0.f, 0.f, -(800.f * tProjInfo.m_flGravity) });
m_pEnv->ResetSimulationClock();
@@ -678,6 +680,9 @@ void CProjectileSimulation::SetupTrace(CTraceFilterCollideable& filter, int& nMa
}
}
}
if (m_pObj->m_dragCoefficient && m_pObj->m_angDragBasis)
nMask |= CONTENTS_DISPSOLID;
}
void CProjectileSimulation::SetupTrace(CTraceFilterCollideable& filter, int& nMask, CBaseEntity* pProjectile)
@@ -209,6 +209,7 @@ public:
IPhysicsEnvironment* m_pEnv = nullptr;
IPhysicsObject* m_pObj = nullptr;
ProjectileInfo* m_pCurrent = nullptr;
};
ADD_FEATURE(CProjectileSimulation, ProjSim);
@@ -21,7 +21,7 @@ void COffscreenArrows::DrawArrowTo(const Vec3& vFromPos, const Vec3& vToPos, Col
}
Vec3 vAngle = Math::VectorAngles({ vCenter.x - vScreen.x, vCenter.y - vScreen.y, 0 });
const float flDeg = DEG2RAD(vAngle.y);
const float flDeg = Math::Deg2Rad(vAngle.y);
const float flCos = cos(flDeg);
const float flSin = sin(flDeg);
+1 -1
View File
@@ -28,7 +28,7 @@ static std::vector<Vec3> SplashTrace(Vec3 vOrigin, float flRadius, Vec3 vNormal
std::vector<Vec3> vPoints = {};
for (float i = 0.f; i < iSegments; i++)
{
Vec3 vPoint = vOrigin + (vRight * cos(2 * PI * i / iSegments) + vUp * sin(2 * PI * i / iSegments)) * flRadius;
Vec3 vPoint = vOrigin + (vRight * cos(2 * Math::PI * i / iSegments) + vUp * sin(2 * Math::PI * i / iSegments)) * flRadius;
if (bTrace)
{
CGameTrace trace = {};
+73
View File
@@ -0,0 +1,73 @@
#include "../SDK/SDK.h"
#include "../SDK/Definitions/Misc/TraceInfo.h"
#include <optional>
MAKE_SIGNATURE(CM_TraceToDispTree_True, "engine.dll", "48 8B C4 48 89 58 ? 48 89 70 ? 57 48 81 EC ? ? ? ? F3 0F 10 01", 0x0);
MAKE_SIGNATURE(CM_TraceToDispTree_False, "engine.dll", "48 8B C4 48 89 58 ? 48 89 70 ? 57 48 83 EC ? F3 0F 10 01", 0x0);
MAKE_SIGNATURE(IntersectRayWithTriangle, "engine.dll", "48 8B C4 48 81 EC ? ? ? ? 80 BC 24", 0x0);
MAKE_SIGNATURE(CDispCollTree_SweepAABBTriIntersect, "engine.dll", "48 8B C4 48 89 70 ? 48 89 78 ? 55 41 56 41 57 48 8D 68", 0x0);
MAKE_SIGNATURE(CDispCollTree_EdgeCrossAxis_0, "engine.dll", "48 83 EC ? B8 ? ? ? ? 66 44 3B C0 75 ? B0 ? 48 83 C4 ? C3 48 8B 89 ? ? ? ? F3 0F 10 05 ? ? ? ? 0F 29 74 24 ? 0F 29 7C 24 ? 44 0F 29 04 24 41 0F B7 C0 66 45 85 C0 79 ? 25 ? ? ? ? 48 8D 04 40 F3 44 0F 10 04 81", 0x0);
#define DISPCOLL_DIST_EPSILON 0.03125f
static int s_iMask = 0;
static std::optional<Vec3> s_vOriginal = {};
static CDispCollTri* s_pTri = nullptr;
MAKE_HOOK(CM_TraceToDispTree_True, S::CM_TraceToDispTree_True(), float,
TraceInfo_t* pTraceInfo, CDispCollTree* pDispTree, float startFrac, float endFrac)
{
DEBUG_RETURN(CM_TraceToDispTree_True, pTraceInfo, pDispTree, startFrac, endFrac);
s_iMask = pTraceInfo->m_contents;
return CALL_ORIGINAL(pTraceInfo, pDispTree, startFrac, endFrac);
}
MAKE_HOOK(CM_TraceToDispTree_False, S::CM_TraceToDispTree_False(), float,
TraceInfo_t* pTraceInfo, CDispCollTree* pDispTree, float startFrac, float endFrac)
{
DEBUG_RETURN(CM_TraceToDispTree_False, pTraceInfo, pDispTree, startFrac, endFrac);
s_iMask = pTraceInfo->m_contents;
return CALL_ORIGINAL(pTraceInfo, pDispTree, startFrac, endFrac);
}
MAKE_HOOK(IntersectRayWithTriangle, S::IntersectRayWithTriangle(), float,
const Ray_t& ray, const Vector& v1, const Vector& v2, const Vector& v3, bool oneSided)
{
if (s_iMask & CONTENTS_DISPSOLID)
oneSided = false;
return CALL_ORIGINAL(ray, v1, v2, v3, oneSided);
}
MAKE_HOOK(CDispCollTree_SweepAABBTriIntersect, S::CDispCollTree_SweepAABBTriIntersect(), void,
void* rcx, const Ray_t& ray, const Vector& rayDir, int iTri, CDispCollTri* pTri, CBaseTrace* pTrace)
{
DEBUG_RETURN(CDispCollTree_SweepAABBTriIntersect, rcx, ray, rayDir, iTri, pTri, pTrace);
if (s_iMask & CONTENTS_DISPSOLID && pTri->m_vecNormal.Dot(ray.m_Delta) > DISPCOLL_DIST_EPSILON)
{
s_vOriginal = pTri->m_vecNormal, s_pTri = pTri;
pTri->m_vecNormal = -pTri->m_vecNormal;
}
CALL_ORIGINAL(rcx, ray, rayDir, iTri, pTri, pTrace);
if (s_vOriginal)
pTri->m_vecNormal = s_vOriginal.value(), s_vOriginal = std::nullopt;
}
MAKE_HOOK(CDispCollTree_EdgeCrossAxis_0, S::CDispCollTree_EdgeCrossAxis_0(), void,
void* rcx, const Ray_t& ray, unsigned short iPlane, CDispCollHelper* pHelper)
{
DEBUG_RETURN(CDispCollTree_EdgeCrossAxis_0, rcx, ray, iPlane, pHelper);
if (s_vOriginal)
s_pTri->m_vecNormal = s_vOriginal.value(), s_vOriginal = std::nullopt;
CALL_ORIGINAL(rcx, ray, iPlane, pHelper);
}
@@ -198,6 +198,7 @@
#define TF_ROCKET_RADIUS (146.f)
#define TF_FLARE_DET_RADIUS (110.f)
#define TF_FLARE_RADIUS_FOR_FJS (100.f)
#define JAR_EXPLODE_RADIUS (200.f)
#define TF_PLAYER_VIEW_OFFSET Vector( 0, 0, 64.0 )
#define TF_BURNING_FREQUENCY 0.5f
@@ -2,6 +2,7 @@
#include "../Misc/IAppSystem.h"
#include "../Types.h"
#define AIR_DENSITY 2
#define k_flMaxVelocity 2000.0f
#define k_flMaxAngularVelocity 360.0f * 10.0f
#define DEFAULT_MIN_FRICTION_MASS 10.0f
@@ -55,6 +55,7 @@
#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans
#define CONTENTS_LADDER 0x20000000
#define CONTENTS_HITBOX 0x40000000 // use accurate hitboxes on trace
#define CONTENTS_DISPSOLID 0x80000000 // no normal checks when tracing against displacements
// NOTE: These are stored in a short in the engine now. Don't use more than 16 bits
#define SURF_LIGHT 0x0001 // value will hold the light strength
@@ -0,0 +1,33 @@
#pragma once
#include "CUtlVector.h"
#include "BaseTypes.h"
#include "../Main/CGameTrace.h"
#include "../Types.h"
#define MAX_CHECK_COUNT_DEPTH 2
typedef uint32 TraceCounter_t;
typedef CUtlVector<TraceCounter_t> CTraceCounterVec;
struct TraceInfo_t
{
Vector m_start;
Vector m_end;
Vector m_mins;
Vector m_maxs;
Vector m_extents;
Vector m_delta;
Vector m_invDelta;
trace_t m_trace;
trace_t m_stabTrace;
int m_contents;
bool m_ispoint;
bool m_isswept;
void* m_pBSPData;
Vector m_DispStabDir;
int m_bDispHit;
bool m_bCheckPrimary;
int m_nCheckDepth;
TraceCounter_t m_Count[MAX_CHECK_COUNT_DEPTH];
CTraceCounterVec m_BrushCounters[MAX_CHECK_COUNT_DEPTH];
CTraceCounterVec m_DispCounters[MAX_CHECK_COUNT_DEPTH];
};
+33 -13
View File
@@ -1,5 +1,6 @@
#pragma once
#include <algorithm>
#include <numbers>
#include <string>
#include <format>
#include <array>
@@ -9,15 +10,34 @@
#include <map>
#include <ranges>
#define PI 3.14159265358979323846
#define M_RADPI 57.295779513082
#define DEG2RAD(x) ((float)(x) * (float)((float)(PI) / 180.f))
#define RAD2DEG(x) ((float)(x) * (float)(180.f / (float)(PI)))
#pragma warning (disable : 26495)
namespace Math
{
template <class T = float>
constexpr T PI_V = static_cast<T>(3.141592653589793);
constexpr float PI = PI_V<>;
template <class T = float>
constexpr T RAD_V = static_cast<T>(57.29577951308232);
constexpr float RAD = RAD_V<>;
template <class T = float>
constexpr T E_V = static_cast<T>(2.718281828459045);
constexpr float E = E_V<>;
template <class T = float>
inline T Deg2Rad(T v)
{
return v * PI_V<T> / T(180);
}
template <class T = float>
inline T Rad2Deg(T v)
{
return v * T(180) / PI_V<T>;
}
inline float DeltaAngle(const float flAngleA, const float flAngleB)
{
float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f);
@@ -698,15 +718,15 @@ public:
inline Vec3 ToAngle() const noexcept
{
return { RAD2DEG(atan2(-z, hypot(x, y))),
RAD2DEG(atan2(y, x)),
return { Math::Rad2Deg(atan2(-z, hypot(x, y))),
Math::Rad2Deg(atan2(y, x)),
0.f };
}
inline Vec3 FromAngle() const noexcept
{
return { cos(DEG2RAD(x)) * cos(DEG2RAD(y)),
cos(DEG2RAD(x)) * sin(DEG2RAD(y)),
-sin(DEG2RAD(x)) };
return { cos(Math::Deg2Rad(x)) * cos(Math::Deg2Rad(y)),
cos(Math::Deg2Rad(x)) * sin(Math::Deg2Rad(y)),
-sin(Math::Deg2Rad(x)) };
}
};
using Vector = Vec3;
@@ -749,9 +769,9 @@ private:
{
float sr, sp, sy, cr, cp, cy;
SinCos(DEG2RAD(vAngles[1]), &sy, &cy);
SinCos(DEG2RAD(vAngles[0]), &sp, &cp);
SinCos(DEG2RAD(vAngles[2]), &sr, &cr);
SinCos(Math::Deg2Rad(vAngles[1]), &sy, &cy);
SinCos(Math::Deg2Rad(vAngles[0]), &sp, &cp);
SinCos(Math::Deg2Rad(vAngles[2]), &sr, &cr);
// matrix = (YAW * PITCH) * ROLL
m2[0][0] = cp * cy;
+4 -4
View File
@@ -292,7 +292,7 @@ void CDraw::FillRoundRect(int x, int y, int w, int h, int iRadius, Color_t tColo
const float a = 90.f * i;
for (int j = 0; j < _iCount; j++)
{
const float _a = DEG2RAD(a + j * flDelta);
const float _a = Math::Deg2Rad(a + j * flDelta);
vVertices.emplace_back(Vertex_t({ { _x + iRadius * sinf(_a), _y - iRadius * cosf(_a) } }));
}
}
@@ -314,7 +314,7 @@ void CDraw::LineRoundRect(int x, int y, int w, int h, int iRadius, Color_t tColo
const float a = 90.f * i;
for (int j = 0; j < _iCount; j++)
{
const float _a = DEG2RAD(a + j * flDelta);
const float _a = Math::Deg2Rad(a + j * flDelta);
vVertices.emplace_back(Vertex_t({ { _x + iRadius * sinf(_a), _y - iRadius * cosf(_a) } }));
}
}
@@ -326,8 +326,8 @@ void CDraw::FillCircle(int x, int y, float iRadius, int iSegments, Color_t tColo
{
std::vector<Vertex_t> vVertices = {};
const float step = static_cast<float>(PI) * 2.0f / iSegments;
for (float a = 0; a < PI * 2.0f; a += step)
const float flStep = Math::PI * 2.f / iSegments;
for (float a = 0; a < Math::PI * 2.f; a += flStep)
vVertices.emplace_back(Vector2D{ iRadius * cosf(a) + x, iRadius * sinf(a) + y });
FillPolygon(vVertices, tColor);
+3 -3
View File
@@ -720,7 +720,7 @@ void SDK::FixMovement(CUserCmd* pCmd, const Vec3& vCurAngle, const Vec3& vTarget
float flCurYaw = vCurAngle.y + (bCurOOB ? 180.f : 0.f);
float flTargetYaw = vTargetAngle.y + (bTargetOOB ? 180.f : 0.f);
float flYaw = DEG2RAD(flTargetYaw - flCurYaw + vMoveAng.y);
float flYaw = Math::Deg2Rad(flTargetYaw - flCurYaw + vMoveAng.y);
pCmd->forwardmove = cos(flYaw) * flSpeed;
pCmd->sidemove = sin(flYaw) * flSpeed * (bTargetOOB ? -1 : 1);
@@ -766,8 +766,8 @@ Vec3 SDK::ComputeMove(const CUserCmd* pCmd, CTFPlayer* pLocal, const Vec3& vFrom
Vec3 vSilent = vDiff.To2D();
Vec3 vAngle = Math::VectorAngles(vSilent);
const float flYaw = DEG2RAD(vAngle.y - pCmd->viewangles.y);
const float flPitch = DEG2RAD(vAngle.x - pCmd->viewangles.x);
const float flYaw = Math::Deg2Rad(vAngle.y - pCmd->viewangles.y);
const float flPitch = Math::Deg2Rad(vAngle.x - pCmd->viewangles.x);
Vec3 vMove = { cos(flYaw) * 450.f, -sin(flYaw) * 450.f, -cos(flPitch) * 450.f };
if (!(I::EngineTrace->GetPointContents(pLocal->GetShootPos()) & CONTENTS_WATER)) // only apply upmove in water
+5 -5
View File
@@ -319,9 +319,9 @@ NAMESPACE_BEGIN(Vars)
CVarEnum(Hitboxes, VA_LIST("Hitboxes", "Projectile hitboxes"), 0b001111, DROPDOWN_MULTI, nullptr,
VA_LIST("Auto", "##Divider", "Head", "Body", "Feet", "##Divider", "Bodyaim if lethal", "Prioritize feet"),
Auto = 1 << 0, Head = 1 << 1, Body = 1 << 2, Feet = 1 << 3, BodyaimIfLethal = 1 << 4, PrioritizeFeet = 1 << 5);
CVarEnum(Modifiers, VA_LIST("Modifiers", "Projectile modifiers"), 0b1010, DROPDOWN_MULTI, nullptr,
VA_LIST("Charge weapon", "Cancel charge", "Use arm time"),
ChargeWeapon = 1 << 0, CancelCharge = 1 << 1, UseArmTime = 1 << 2);
CVarEnum(Modifiers, VA_LIST("Modifiers", "Projectile modifiers"), 0b0010, DROPDOWN_MULTI, nullptr,
VA_LIST("Charge weapon", "Cancel charge", "Use arm time", "Alternate angles"),
ChargeWeapon = 1 << 0, CancelCharge = 1 << 1, UseArmTime = 1 << 2, AlternateAngles = 1 << 3);
CVar(MaxSimulationTime, "Max simulation time", 2.f, SLIDER_MIN | SLIDER_PRECISION, 0.1f, 2.5f, 0.25f, "%gs");
CVar(HitChance, "Hit chance", 0.f, SLIDER_CLAMP | SLIDER_PRECISION, 0.f, 100.f, 10.f, "%g%%");
CVar(AutodetRadius, "Autodet radius", 90.f, SLIDER_CLAMP | SLIDER_PRECISION, 0.f, 100.f, 10.f, "%g%%");
@@ -670,8 +670,8 @@ NAMESPACE_BEGIN(Vars)
CVar(OffsetX, "Offset X", 16.f, NOSAVE | DEBUGVAR | SLIDER_PRECISION, -25.f, 25.f, 0.5f);
CVar(OffsetY, "Offset Y", 8.f, NOSAVE | DEBUGVAR | SLIDER_PRECISION, -25.f, 25.f, 0.5f);
CVar(OffsetZ, "Offset Z", -6.f, NOSAVE | DEBUGVAR | SLIDER_PRECISION, -25.f, 25.f, 0.5f);
CVar(ForwardRedirect, "Forward redirect", 2000.f, NOSAVE | DEBUGVAR | SLIDER_PRECISION, 0.f, 2000.f, 100.f);
CVar(ForwardCutoff, "Forward cutoff", 0.1f, NOSAVE | DEBUGVAR | SLIDER_PRECISION, 0.f, 1.f, 0.1f);
CVar(ForwardRedirect, "Forward redirect", 0.f, NOSAVE | DEBUGVAR | SLIDER_PRECISION, 0.f, 2000.f, 100.f);
CVar(ForwardCutoff, "Forward cutoff", 0.f, NOSAVE | DEBUGVAR | SLIDER_PRECISION, 0.f, 1.f, 0.1f);
CVar(Hull, "Hull", 5.f, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 0.f, 10.f, 0.5f);
CVar(Speed, "Speed", 1200.f, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 0.f, 5000.f, 50.f);
CVar(Gravity, "Gravity", 1.f, NOSAVE | DEBUGVAR | SLIDER_PRECISION, 0.f, 1.f, 0.1f);
+22 -22
View File
@@ -105,11 +105,11 @@ namespace Math
}
else
{
flYaw = RAD2DEG(atan2f(vForward.y, vForward.x));
flYaw = Rad2Deg(atan2f(vForward.y, vForward.x));
if (flYaw < 0)
flYaw += 360;
flPitch = RAD2DEG(atan2f(-vForward.z, vForward.Length2D()));
flPitch = Rad2Deg(atan2f(-vForward.z, vForward.Length2D()));
if (flPitch < 0)
flPitch += 360;
}
@@ -129,8 +129,8 @@ namespace Math
inline void AngleVectors(const Vec3& vAngles, Vec3* pForward = nullptr, Vec3* pRight = nullptr, Vec3* pUp = nullptr)
{
float sp, sy, sr, cp, cy, cr;
SinCos(DEG2RAD(vAngles.x), &sp, &cp);
SinCos(DEG2RAD(vAngles.y), &sy, &cy);
SinCos(Deg2Rad(vAngles.x), &sp, &cp);
SinCos(Deg2Rad(vAngles.y), &sy, &cy);
if (pForward)
{
@@ -141,7 +141,7 @@ namespace Math
if (pRight || pUp)
{
SinCos(DEG2RAD(vAngles.z), &sr, &cr);
SinCos(Deg2Rad(vAngles.z), &sr, &cr);
if (pRight)
{
@@ -165,8 +165,8 @@ namespace Math
float flHyp = std::sqrtf((vDelta.x * vDelta.x) + (vDelta.y * vDelta.y));
Vec3 vAngles = {
atanf(vDelta.z / flHyp) * float(M_RADPI),
atanf(vDelta.y / vDelta.x) * float(M_RADPI),
atanf(vDelta.z / flHyp) * RAD,
atanf(vDelta.y / vDelta.x) * RAD,
0.f
};
@@ -187,7 +187,7 @@ namespace Math
Vec3 vToForward = Vec3();
AngleVectors(vToAng, &vToForward);
float flResult = RAD2DEG(acos(vFromForward.Dot(vToForward)));
float flResult = Rad2Deg(acos(vFromForward.Dot(vToForward)));
if (!isfinite(flResult) || isinf(flResult) || isnan(flResult))
flResult = 0.f;
@@ -199,9 +199,9 @@ namespace Math
Vec3 vOffset = vPoint - vOrigin;
float sp, sy, sr, cp, cy, cr;
SinCos(DEG2RAD(vAngles.x), &sp, &cp);
SinCos(DEG2RAD(vAngles.y), &sy, &cy);
SinCos(DEG2RAD(vAngles.z), &sr, &cr);
SinCos(Deg2Rad(vAngles.x), &sp, &cp);
SinCos(Deg2Rad(vAngles.y), &sy, &cy);
SinCos(Deg2Rad(vAngles.z), &sr, &cr);
Vec3 vX = {
cy * cp,
@@ -277,9 +277,9 @@ namespace Math
inline void AngleMatrix(const Vec3& vAngles, matrix3x4& mMatrix, bool bClearOrigin = true)
{
float sp, sy, sr, cp, cy, cr;
SinCos(DEG2RAD(vAngles.x), &sp, &cp);
SinCos(DEG2RAD(vAngles.y), &sy, &cy);
SinCos(DEG2RAD(vAngles.z), &sr, &cr);
SinCos(Deg2Rad(vAngles.x), &sp, &cp);
SinCos(Deg2Rad(vAngles.y), &sy, &cy);
SinCos(Deg2Rad(vAngles.z), &sr, &cr);
mMatrix[0][0] = cp * cy;
mMatrix[1][0] = cp * sy;
@@ -315,14 +315,14 @@ namespace Math
float flLen = vForward.Length2D();
if (flLen > 0.001f)
{
vAngles.x = RAD2DEG(std::atan2(-vForward.z, flLen));
vAngles.y = RAD2DEG(std::atan2(vForward.y, vForward.x));
vAngles.z = RAD2DEG(std::atan2(vLeft.z, vUp.z));
vAngles.x = Rad2Deg(std::atan2(-vForward.z, flLen));
vAngles.y = Rad2Deg(std::atan2(vForward.y, vForward.x));
vAngles.z = Rad2Deg(std::atan2(vLeft.z, vUp.z));
}
else
{
vAngles.x = RAD2DEG(std::atan2(-vForward.z, flLen));
vAngles.y = RAD2DEG(std::atan2(-vLeft.x, vLeft.y));
vAngles.x = Rad2Deg(std::atan2(-vForward.z, flLen));
vAngles.y = Rad2Deg(std::atan2(-vLeft.x, vLeft.y));
vAngles.z = 0;
}
}
@@ -411,7 +411,7 @@ namespace Math
GetMatrixOrigin(mMatrix, vOut);
return vOut;
}
inline void ConcatTransforms(const matrix3x4& mIn1, const matrix3x4& mIn2, matrix3x4& mOut)
{
if (&mIn1 == &mOut)
@@ -461,7 +461,7 @@ namespace Math
float q = 2 * powf(b, 3) / 27 - b * c / 3 + d;
if (p == 0.f)
return pow(q, 1.f / 3);
return powf(q, 1.f / 3);
if (q == 0.f)
return 0.f;
@@ -476,7 +476,7 @@ namespace Math
return -2 * t * cosh(acosh(-g) / 3) - b / 3;
return 2 * t * cosh(acosh(g) / 3) - b / 3;
}
inline std::vector<float> SolveQuartic(float a, float b, float c, float d, float e)
{
std::vector<float> vRoots = {};