diff --git a/Amalgam/Amalgam.vcxproj b/Amalgam/Amalgam.vcxproj
index 3c33541e..2b12e722 100644
--- a/Amalgam/Amalgam.vcxproj
+++ b/Amalgam/Amalgam.vcxproj
@@ -1260,6 +1260,7 @@
+
@@ -1293,6 +1294,7 @@
+
@@ -1308,11 +1310,18 @@
+
+
+
+
+
+
+
@@ -1320,6 +1329,7 @@
+
diff --git a/Amalgam/Amalgam.vcxproj.filters b/Amalgam/Amalgam.vcxproj.filters
index 4206cdb1..ab0414ad 100644
--- a/Amalgam/Amalgam.vcxproj.filters
+++ b/Amalgam/Amalgam.vcxproj.filters
@@ -611,6 +611,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp
index 148bfcd3..7d3e0c1b 100644
--- a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp
+++ b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp
@@ -379,11 +379,11 @@ int CAimbotMelee::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pW
Vec3 vTraceEnd = m_vEyePos + vForward * flRange;
SDK::TraceHull(m_vEyePos, vTraceEnd, {}, {}, MASK_SOLID, &filter, &trace);
- bool bReturn = trace.m_pEnt && trace.m_pEnt == tTarget.m_pEntity;
+ bool bReturn = trace.m_pEnt == tTarget.m_pEntity;
if (!bReturn)
{
SDK::TraceHull(m_vEyePos, vTraceEnd, vSwingMins, vSwingMaxs, MASK_SOLID, &filter, &trace);
- bReturn = trace.m_pEnt && trace.m_pEnt == tTarget.m_pEntity;
+ bReturn = trace.m_pEnt == tTarget.m_pEntity;
}
if (bReturn && Vars::Aimbot::Melee::AutoBackstab.Value && pWeapon->GetWeaponID() == TF_WEAPON_KNIFE)
@@ -411,7 +411,7 @@ int CAimbotMelee::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* pW
vTraceEnd = m_vEyePos + vForward * flRange;
SDK::TraceHull(m_vEyePos, vTraceEnd, vSwingMins, vSwingMaxs, MASK_SOLID, &filter, &trace);
- if (trace.m_pEnt && trace.m_pEnt == tTarget.m_pEntity)
+ if (trace.m_pEnt == tTarget.m_pEntity)
return 2;
}
}
diff --git a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp
index f95d42ac..72d2a42c 100644
--- a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp
+++ b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp
@@ -16,6 +16,9 @@
#ifdef SPLASH_DEBUG5
static std::map s_mTraceCount = {};
#endif
+#ifdef SPLASH_DEBUG2
+//#include "../../Visuals/Visuals.h"
+#endif
static inline std::vector GetTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
{
@@ -270,6 +273,16 @@ static inline float ArmTime(CTFWeaponBase* pWeapon)
return 0.f;
}
+static inline bool ShouldLob(Info_t& tInfo)
+{
+ return tInfo.m_flGravity && Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::LobAngles;
+}
+
+static inline bool ShouldLob(MoveStorage& tMoveStorage, Info_t& tInfo)
+{
+ return tInfo.m_bIgnoreTiming && (tMoveStorage.m_bFailed || tMoveStorage.m_pPlayer->IsOnGround());
+}
+
static inline bool AirSplash(CTFWeaponBase* pWeapon)
{
if (!(Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::AirSplash))
@@ -349,7 +362,7 @@ Directs_t CAimbotProjectile::GetDirects()
auto& tTarget = *m_tInfo.m_pTarget;
uint8_t iFlags = PointFlagsEnum::Regular;
- if (m_tInfo.m_flGravity && Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::LobAngles)
+ if (ShouldLob(m_tInfo))
iFlags |= PointFlagsEnum::Lob;
const Vec3 vMins = tTarget.m_pEntity->m_vecMins(), vMaxs = tTarget.m_pEntity->m_vecMaxs();
@@ -418,37 +431,36 @@ Splashes_t CAimbotProjectile::GetSplashes()
return vSplashes;
vSplashes.push_back(PointFlagsEnum::Regular);
- if (m_tInfo.m_flGravity && Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::LobAngles)
+ if (ShouldLob(m_tInfo))
vSplashes.push_back(PointFlagsEnum::Lob);
return vSplashes;
}
-static inline std::vector ComputePoints(float flRadius, int iSamples, bool bSphere)
+static inline std::vector ComputePoints(float flRadius, int iSamples)
{
std::vector vPoints = { { Vec3(0.f, 0.f, -1.f) * flRadius } };
+ if (!iSamples)
+ return vPoints;
- if (bSphere)
+ vPoints.reserve(iSamples + 1);
+
+ float flRotateX = Vars::Aimbot::Projectile::SplashRotateX.Value < 0.f ? SDK::StdRandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateX.Value;
+ float flRotateY = Vars::Aimbot::Projectile::SplashRotateY.Value < 0.f ? SDK::StdRandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateY.Value;
+
+ float a = Math::PI * (3.f - sqrtf(5.f));
+ for (int n = 0; n < iSamples; n++)
{
- vPoints.reserve(iSamples + 1);
+ float t = a * n;
+ float y = 1 - (n / (iSamples - 1.f)) * 2;
+ float r = sqrtf(1 - powf(y, 2));
+ float x = cosf(t) * r;
+ float z = sinf(t) * r;
- float flRotateX = Vars::Aimbot::Projectile::SplashRotateX.Value < 0.f ? SDK::StdRandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateX.Value;
- float flRotateY = Vars::Aimbot::Projectile::SplashRotateY.Value < 0.f ? SDK::StdRandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateY.Value;
+ Vec3 vPoint = Vec3(x, y, z) * flRadius;
+ vPoint = Math::RotatePoint(vPoint, {}, { flRotateX, flRotateY });
- float a = Math::PI * (3.f - sqrtf(5.f));
- for (int n = 0; n < iSamples; n++)
- {
- float t = a * n;
- float y = 1 - (n / (iSamples - 1.f)) * 2;
- float r = sqrtf(1 - powf(y, 2));
- float x = cosf(t) * r;
- float z = sinf(t) * r;
-
- Vec3 vPoint = Vec3(x, y, z) * flRadius;
- vPoint = Math::RotatePoint(vPoint, {}, { flRotateX, flRotateY });
-
- vPoints.push_back(vPoint);
- }
+ vPoints.push_back(vPoint);
}
return vPoints;
@@ -520,53 +532,111 @@ static inline void HandleTrace(const Vec3& vPoint, std::vector& vPoints
}
static float s_flTotal = 0.f;
-static inline void HandleFace(const Face_t& tFace, std::vector& vPoints, float flDensity, float flRadius, float flCutoff, const Vec3& vTargetEye, const Vec3& vTargetCenter, Info_t& tInfo, CGameTrace& trace, ITraceFilter& filter)
+static inline void HandleFace(Face_t& tFace, std::vector& vPoints, float flDensity, float flRadius, float flCutoff, const Vec3& vTargetEye, const Vec3& vTargetCenter, const Vec3& vTargetOrigin, Info_t& tInfo, CGameTrace& trace, ITraceFilter& filter)
{
float flRadiusSqr = powf(flRadius, 2);
float flRadius2Sqr = flRadiusSqr * 4;
- int nMask = MASK_SHOT;
- if (F::ProjSim.m_pObj->m_dragCoefficient && F::ProjSim.m_pObj->m_angDragBasis)
- nMask |= CONTENTS_DISPSOLID;
+ int nMask = F::ProjSim.m_bPhysics ? MASK_SHOT | CONTENTS_DISPSOLID : MASK_SHOT;
- for (int i = 0; ++i < tFace.m_vVertices.size() - 1;)
+ std::vector vVertices, vEpsilon;
+ if (tFace.m_iType != FaceTypeEnum::Prop)
+ vVertices = tFace.m_vVertices;
+ else
+ Math::ExpandPolygon(vVertices, tFace.m_vVertices, tFace.m_vNormal, SDK::StdRandomFloat(0.f, DIST_EPSILON), &vTargetEye);
+
+ for (int i = 0, n = int(tFace.m_vVertices.size()), o = SDK::StdRandomInt(0, n - 1); ++i < n - 1;)
{
- const Vec3& vVertex1 = tFace.m_vVertices[0], &vVertex2 = tFace.m_vVertices[i], &vVertex3 = tFace.m_vVertices[i + 1];
+ Vec3& vVertex1 = tFace.m_vVertices[o], &vVertex2 = tFace.m_vVertices[(o + i) % n], &vVertex3 = tFace.m_vVertices[(o + i + 1) % n];
Vec3 vDir21 = vVertex2 - vVertex1, vDir31 = vVertex3 - vVertex1;
float flArea = vDir21.Cross(vDir31).Length() / 2;
float flSamples = flDensity * flArea / flRadius2Sqr;
- int iSamples = flSamples < flCutoff ? fmodf(s_flTotal += flSamples, flCutoff) < flSamples : ceilf(flSamples);
+ int iSamples = flSamples > flCutoff ? ceilf(flSamples) : fmodf(s_flTotal += flSamples, flCutoff) < flSamples;
+ if (!iSamples)
+ continue;
-#if defined(SPLASH_DEBUG2) && defined(WORLD_DEBUG)
- if (iSamples)
- F::World.DrawFace({ { vVertex1, vVertex2, vVertex3 }, tFace.m_vNormal }, DrawTypeEnum::Edges | DrawTypeEnum::Faces);
+ // don't particularly like the hacky random epsilons
+ int iFaceClosest = SDK::StdRandomInt(iSamples < 2 ? 0 : iSamples < 4 ? 1 : 2, iSamples < 2 ? 1 : 2);
+ //int iEdgeClosest = SDK::StdRandomInt(iSamples < 8 ? 0 : iSamples < 16 ? 1 : 2, iSamples < 8 ? 1 : 2); // eats up a bit too much performance for my liking
+ int iEdgeRandom = SDK::StdRandomInt(iSamples < 8 ? 0 : iSamples < 16 ? 1 : 2, iSamples < 3 ? 0 : iSamples < 12 ? 1 : 2);
+ iEdgeRandom += iFaceClosest; //iEdgeClosest += iFaceClosest, iEdgeRandom += iEdgeClosest; //, iSamples += iEdgeRandom;
+#ifdef SPLASH_DEBUG2
+ Color_t tColor = { byte(SDK::StdRandomInt(0, 255)), byte(SDK::StdRandomInt(0, 255)), byte(SDK::StdRandomInt(0, 255)) };
+#ifdef WORLD_DEBUG
+ F::World.DrawFace({ { vVertex1, vVertex2, vVertex3 }, tFace.m_vNormal, tFace.m_iType }, DrawTypeEnum::Edges | DrawTypeEnum::Faces, tColor);
#endif
-
- for (int i = 0; i < iSamples; i++)
+#ifdef DEBUG_TEXT
+ F::Visuals.AddDebugText(std::format("{}:{}:{}"/*:{}"*/, iFaceClosest, /*iEdgeClosest,*/ iEdgeRandom, iSamples), (vVertex1 + vVertex2 + vVertex3) / 3, tColor);
+#endif
+#endif
+ for (int s = 0; s < iSamples; s++)
{
- float flRandom1 = SDK::StdRandomFloat(), flRandom2 = SDK::StdRandomFloat();
- if (flRandom1 + flRandom2 > 1)
- flRandom1 = 1 - flRandom1, flRandom2 = 1 - flRandom2;
-
- Vec3 vPoint = vVertex1 + vDir21 * flRandom1 + vDir31 * flRandom2 + tFace.m_vNormal * (tInfo.m_vHull + CALC_EPSILON);
+ Vec3 vPoint, vNormal = tFace.m_vNormal; bool bInside = true;
+ if (s < iFaceClosest) // closest point
+ {
+ float flEpsilon = s == 0 && (tFace.m_iType == FaceTypeEnum::BoxBrush || iFaceClosest != 1 || SDK::StdRandomBool()) ? CALC_EPSILON : DIST_EPSILON;
+ vPoint = Math::ClosestPointOnTriangle(vTargetOrigin, vVertex1, vVertex2, vVertex3, &bInside);
+ vPoint += { SDK::StdRandomFloat(-flEpsilon, flEpsilon), SDK::StdRandomFloat(-flEpsilon, flEpsilon), SDK::StdRandomFloat(-flEpsilon, flEpsilon) };
+ }
+ //else if (s < iEdgeClosest) // closest point on edge
+ //{
+ // float flEpsilon = SDK::StdRandomBool() ? CALC_EPSILON : DIST_EPSILON; bInside = false;
+ // switch (SDK::StdRandomInt(0, 2))
+ // {
+ // case 0: vPoint = Math::ClosestPointOnLine(vTargetOrigin, vVertex1, vVertex2); break;
+ // case 1: vPoint = Math::ClosestPointOnLine(vTargetOrigin, vVertex2, vVertex3); break;
+ // case 2: vPoint = Math::ClosestPointOnLine(vTargetOrigin, vVertex3, vVertex1); break;
+ // }
+ // vPoint += { SDK::StdRandomFloat(-flEpsilon, flEpsilon), SDK::StdRandomFloat(-flEpsilon, flEpsilon), SDK::StdRandomFloat(-flEpsilon, flEpsilon) };
+ //}
+ else if (s < iEdgeRandom) // random point on edge
+ {
+ float flEpsilon = SDK::StdRandomBool() ? CALC_EPSILON : DIST_EPSILON; bInside = false;
+ switch (SDK::StdRandomInt(0, 2))
+ {
+ case 0: vPoint = vVertex1.Lerp(vVertex2, SDK::StdRandomFloat()); break;
+ case 1: vPoint = vVertex2.Lerp(vVertex3, SDK::StdRandomFloat()); break;
+ case 2: vPoint = vVertex3.Lerp(vVertex1, SDK::StdRandomFloat()); break;
+ }
+ vPoint += { SDK::StdRandomFloat(-flEpsilon, flEpsilon), SDK::StdRandomFloat(-flEpsilon, flEpsilon), SDK::StdRandomFloat(-flEpsilon, flEpsilon) };
+ }
+ else // random point on face
+ {
+ float flRandom1 = SDK::StdRandomFloat(), flRandom2 = SDK::StdRandomFloat();
+ if (flRandom1 + flRandom2 > 1)
+ flRandom1 = 1 - flRandom1, flRandom2 = 1 - flRandom2;
+ vPoint = vVertex1 + vDir21 * flRandom1 + vDir31 * flRandom2;
+ }
+ vPoint += vNormal * (tInfo.m_vHull + CALC_EPSILON);
if (vPoint.DistToSqr(vTargetCenter) > flRadiusSqr)
continue;
+ if (!bInside)
+ {
+ if (vEpsilon.empty())
+ Math::ExpandPolygon(vEpsilon = vVertices, tFace.m_vNormal, -DIST_EPSILON);
+ Math::ClosestPointOnPolygon(vPoint, vEpsilon, vNormal, &bInside);
+
+ if (tFace.m_iType == FaceTypeEnum::Prop && !bInside)
+ vPoint += tFace.m_vNormal * SDK::StdRandomFloat(0.f, DIST_EPSILON);
+ }
+
#ifdef SPLASH_DEBUG5
- s_mTraceCount[__FUNCTION__": point contents"]++;
+ if (bInside) s_mTraceCount[__FUNCTION__": point contents"]++;
#endif
- if (I::EngineTrace->GetPointContents(vPoint) & MASK_SOLID)
+ if (bInside && I::EngineTrace->GetPointContents(vPoint) & MASK_SOLID)
continue;
- if (tFace.m_iType == FaceTypeEnum::Prop)
- vPoint += tFace.m_vNormal * DIST_EPSILON;
+ int nSubMask = nMask;
+ if (!bInside)
+ vNormal = (vTargetEye - vPoint).Normalized(), nSubMask &= ~CONTENTS_MOVEABLE;
- SDK::Trace(vPoint + tFace.m_vNormal * tInfo.m_flNormalOffset, vTargetEye, nMask, &filter, &trace);
+ SDK::Trace(vPoint + vNormal * tInfo.m_flNormalOffset, vTargetEye, nSubMask, &filter, &trace);
#ifdef SPLASH_DEBUG5
s_mTraceCount[__FUNCTION__": vispos"]++;
#endif
#ifdef SPLASH_DEBUG2
- DrawTrace(!trace.DidHit(), Vars::Colors::IndicatorMisc.Value, trace);
+ DrawTrace(trace.fraction == 1.f, Vars::Colors::IndicatorMisc.Value, trace);
#endif
if (trace.fraction != 1.f)
continue;
@@ -594,7 +664,7 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector& v
if (pAngle)
{
Vec3 vForward, vRight, vUp; Math::AngleVectors(*pAngle, &vForward, &vRight, &vUp);
- Vec3 vShootPos = m_tInfo.m_vLocalEye + (vForward * m_tInfo.m_vOffset.x) + (vRight * m_tInfo.m_vOffset.y) + (vUp * m_tInfo.m_vOffset.z);
+ Vec3 vShootPos = m_tInfo.m_vLocalEye + vForward * m_tInfo.m_vOffset.x + vRight * m_tInfo.m_vOffset.y + vUp * m_tInfo.m_vOffset.z;
vForward = (vShootPos - vPoint).Normalized();
return vForward.Dot(vNormal) > 0;
}
@@ -606,9 +676,10 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector& v
};
// Trace
- int iPoints = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashPointsDirect.Value : Vars::Aimbot::Projectile::SplashPointsArc.Value;
+ int iPoints = Vars::Aimbot::Projectile::SplashMode.Value == Vars::Aimbot::Projectile::SplashModeEnum::Face && !bAirSplash ? 0
+ : !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashPointsDirect.Value : Vars::Aimbot::Projectile::SplashPointsArc.Value;
{
- auto vPoints = ComputePoints(flRadius, iPoints, Vars::Aimbot::Projectile::SplashMode.Value == Vars::Aimbot::Projectile::SplashModeEnum::Trace || bAirSplash);
+ auto vPoints = ComputePoints(flRadius, iPoints);
for (int i = 0; i < vPoints.size(); i++)
{
@@ -626,7 +697,7 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector& v
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 * powf(tPoint.m_tSolution.m_flTime, 2)) / 2);
+ vPoint -= Vec3(0, 0, m_tInfo.m_flGravity * 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);
@@ -655,8 +726,8 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector& v
}
// Face
- float flDensity = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashDensityDirect.Value : Vars::Aimbot::Projectile::SplashDensityArc.Value;
- if (Vars::Aimbot::Projectile::SplashMode.Value == Vars::Aimbot::Projectile::SplashModeEnum::Face && flDensity)
+ if (float flDensity = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashDensityDirect.Value : Vars::Aimbot::Projectile::SplashDensityArc.Value;
+ Vars::Aimbot::Projectile::SplashMode.Value == Vars::Aimbot::Projectile::SplashModeEnum::Face && flDensity)
{
Vec3 vMins = vTargetCenter - flRadius, vMaxs = vTargetCenter + flRadius;
@@ -664,14 +735,14 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector& v
{
Vec3 vPoint = std::reduce(vVertices.begin(), vVertices.end()) / vVertices.size(), vAngle;
if (!m_tInfo.m_flGravity)
- vAngle = Math::CalcAngle(m_tInfo.m_vLocalEye, trace.endpos);
+ vAngle = Math::CalcAngle(m_tInfo.m_vLocalEye, vPoint);
else
{
Point_t tPoint = { vPoint, {} };
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 * powf(tPoint.m_tSolution.m_flTime, 2)) / 2);
+ vPoint -= Vec3(0, 0, m_tInfo.m_flGravity * 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);
@@ -686,7 +757,7 @@ void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector& v
float flCutoff = Vars::Aimbot::Projectile::SplashSamplesCutoff.Value * powf(vFaces.size(), 2); s_flTotal = SDK::StdRandomFloat();
for (auto& tFace : vFaces)
{
- HandleFace(tFace, vSplashPoints, flDensity, flRadius, flCutoff, vTargetEye, vTargetCenter, m_tInfo, trace, filter);
+ HandleFace(tFace, vSplashPoints, flDensity, flRadius, flCutoff, vTargetEye, vTargetCenter, vOrigin, m_tInfo, trace, filter);
//#if defined(SPLASH_DEBUG2) && defined(WORLD_DEBUG)
// F::World.DrawFace(tFace, DrawTypeEnum::Edges | DrawTypeEnum::Faces);
//#endif
@@ -720,7 +791,7 @@ std::vector CAimbotProjectile::GetSplashPoints(Vec3 vOrigin, std::vecto
flRadiusAirSqr = powf(m_tInfo.m_flRadius * Math::RemapVal(TICKS_TO_TIME(iSimTime), flLiveTime, flLiveTime + flRampTime, flAirdetRadius, 1.f), 2);
}
bool bLob = iFlags & CalculateFlagsEnum::LobAngle;
- int iTolerance = m_tInfo.m_bIgnoreTiming && bLob ? std::numeric_limits::max() : !m_tInfo.m_iArmTime ? 0 : -1;
+ int iTolerance = m_tInfo.m_bIgnoreTiming && bLob ? std::numeric_limits::max() : m_tInfo.m_iArmTime ? -1 : 0;
int iLimit = !bFirst ? m_tInfo.m_iSplashRestrict : std::max(m_tInfo.m_iSplashRestrict, Vars::Aimbot::Projectile::SplashRestrictFirst.Value);
bool bSort = !bLob || !m_tInfo.m_bIgnoreTiming;
@@ -787,20 +858,20 @@ static inline Vec3 PullPoint(const Vec3& vPoint, Vec3 vLocalPos, Info_t& tInfo,
{
auto fHeightenLocalPos = [&]()
{ // basic trajectory pass
- const float flGrav = tInfo.m_flGravity * 800.f;
+ float flGrav = tInfo.m_flGravity;
if (!flGrav)
return vPoint;
- const Vec3 vDelta = vTargetPos - vLocalPos;
- const float flDist = vDelta.Length2D();
+ Vec3 vDelta = vTargetPos - vLocalPos;
+ float flDist = vDelta.Length2D();
- const float flRoot = powf(tInfo.m_flVelocity, 4) - flGrav * (flGrav * powf(flDist, 2) + 2.f * vDelta.z * powf(tInfo.m_flVelocity, 2));
+ 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((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 * powf(flTime, 2)) / 2);
+ return vLocalPos + Vec3(0, 0, flGrav * powf(flTime, 2) / 2);
};
vLocalPos = fHeightenLocalPos();
@@ -821,7 +892,7 @@ static inline float GetDrag(float flVelocity, ProjectileInfo* pInfo, int iFlags)
{
auto fGetDrag = [&](std::function fGetTypeDrag)
{
- if (!F::ProjSim.m_pObj->m_dragCoefficient || !F::ProjSim.m_pObj->m_dragBasis)
+ if (!F::ProjSim.m_bPhysics)
return 0.f;
if (Vars::Aimbot::Projectile::DragOverride.Value)
@@ -902,7 +973,7 @@ static inline float GetDrag(float flVelocity, ProjectileInfo* pInfo, int iFlags)
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;
+ float flGrav = tInfo.m_flGravity;
Vec3 vDelta = vTargetPos - vLocalPos;
float flDist = vDelta.Length2D();
float flDrag = GetDrag(flVelocity, F::ProjSim.m_pCurrent, iFlags);
@@ -960,7 +1031,7 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge
float flPitch, flYaw;
{ // basic trajectory pass
//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);
+ //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))
{
tOut.m_iCalculated = CalculateResultEnum::Bad;
@@ -1134,7 +1205,7 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
#ifdef SPLASH_DEBUG4
Vec3 vHull = m_tProjInfo.m_vHull.Max(1);
- G::BoxStorage.emplace_back(vPoint, -vHull, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 0), Color_t(0, 0, 0, 0));
+ G::BoxStorage.emplace_back(vPoint, -vHull, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 0), Color_t(0, 0, 0, 0));
#endif
if (!m_tProjInfo.m_flGravity)
@@ -1146,7 +1217,7 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
#ifdef SPLASH_DEBUG4
G::LineStorage.emplace_back(std::pair(m_tProjInfo.m_vPos, trace.endpos), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 0));
#endif
- if (trace.fraction < 0.999f && trace.m_pEnt != tTarget.m_pEntity)
+ if (Math::FullFraction(m_tProjInfo.m_vPos, vPoint, trace) < 0.999f && trace.m_pEnt != tTarget.m_pEntity)
return false;
}
@@ -1157,7 +1228,7 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
bool bDidHit = false;
Vec3 vNew = F::ProjSim.GetOrigin();
int iTimingTolerance = TIME_TO_TICKS(m_tInfo.m_flBoundsTime);
- float flRadiusSqr = powf(m_tProjInfo.m_flVelocity * TICK_INTERVAL + m_tProjInfo.m_vHull.z, 2);
+ float flRadiusSqr = iType != PointTypeEnum::Direct ? powf(m_tProjInfo.m_flVelocity * TICK_INTERVAL + m_tProjInfo.m_vHull.z, 2) : std::numeric_limits::max();
uint8_t iTraceInterval = iFlags == PointFlagsEnum::Lob ? Vars::Aimbot::Projectile::LobTraceInterval.Value
: iType != PointTypeEnum::Direct ? Vars::Aimbot::Projectile::SplashTraceInterval.Value
: Vars::Aimbot::Projectile::DirectTraceInterval.Value;
@@ -1192,10 +1263,9 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
{
case PointTypeEnum::Direct:
case PointTypeEnum::Geometry:
- bHit = trace.DidHit();
- break;
+ bHit = trace.DidHit(); break;
case PointTypeEnum::Air:
- bHit = trace.endpos.DistToSqr(vPoint) < flRadiusSqr || trace.DidHit();
+ bHit = trace.endpos.DistToSqr(vPoint) < flRadiusSqr || trace.DidHit(); break;
}
if (bHit)
@@ -1204,24 +1274,22 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
switch (iType)
{
case PointTypeEnum::Direct:
- bTarget = trace.m_pEnt == tTarget.m_pEntity, bValid = bTarget && iSimTime - n < iTimingTolerance;
- break;
+ bTarget = trace.m_pEnt == tTarget.m_pEntity, bValid = bTarget && iSimTime - n < iTimingTolerance; break;
case PointTypeEnum::Geometry:
- bValid = trace.endpos.DistToSqr(vPoint) < flRadiusSqr;
- break;
+ bValid = trace.endpos.DistToSqr(vPoint) < flRadiusSqr; break;
case PointTypeEnum::Air:
- bValid = !trace.DidHit();
- break;
+ bValid = !trace.DidHit(); break;
}
if (bValid && iType != PointTypeEnum::Direct)
{
CGameTrace eyeTrace = {};
- SDK::Trace(trace.endpos + m_tInfo.m_flNormalOffset * trace.plane.normal, tTarget.m_vPos + m_tInfo.m_vTargetEye, MASK_SHOT, &filter, &eyeTrace);
+ SDK::Trace(trace.endpos + trace.plane.normal * m_tInfo.m_flNormalOffset, tTarget.m_vPos + m_tInfo.m_vTargetEye, MASK_SHOT, &filter, &eyeTrace);
bValid = eyeTrace.fraction == 1.f;
#ifdef SPLASH_DEBUG5
s_mTraceCount[__FUNCTION__": splash eye trace"]++;
#endif
#ifdef SPLASH_DEBUG4
+ //G::LineStorage.emplace_back(std::pair(trace.endpos, trace.endpos + trace.plane.normal * m_tInfo.m_flNormalOffset), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 255));
G::LineStorage.emplace_back(std::pair(eyeTrace.startpos, eyeTrace.endpos), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 255));
G::BoxStorage.emplace_back(trace.endpos + m_tInfo.m_flNormalOffset * trace.plane.normal, -vHull, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 255), Color_t(0, 0, 0, 0));
#endif
@@ -1230,17 +1298,8 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
#ifdef SPLASH_DEBUG4
if (bValid)
G::BoxStorage.emplace_back(vPoint, -vHull, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 255, 0), Color_t(0, 0, 0, 0));
- else if (bTarget)
- G::BoxStorage.emplace_back(vPoint, -vHull, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 255), Color_t(0, 0, 0, 0));
else
- {
- G::BoxStorage.emplace_back(vPoint, -vHull, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(127, 0, 255), Color_t(0, 0, 0, 0));
- if (iType != PointTypeEnum::Direct)
- {
- G::BoxStorage.emplace_back(trace.endpos, Vec3::Get(-1), Vec3::Get(1), Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 0), Color_t(0, 0, 0, 0));
- G::BoxStorage.emplace_back(vPoint, Vec3::Get(-1), Vec3::Get(1), Vec3(), I::GlobalVars->curtime + 5.f, Color_t(255, 255, 255), Color_t(0, 0, 0, 0));
- }
- }
+ G::BoxStorage.emplace_back(vPoint, -vHull, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 0), Color_t(0, 0, 0, 0));
#endif
if (bValid)
@@ -1272,7 +1331,7 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
Vec3 vOffset = tOriginal.m_vOrigin - tTarget.m_vPos;
Vec3 vPos = trace.endpos + F::ProjSim.GetVelocity().Normalized() * 16 + vOffset;
- float flClosest = std::numeric_limits::max(); int iClosest = -1;
+ float flLowestDistance = std::numeric_limits::max(); int iClosest = -1;
for (int nHitbox = 0; nHitbox < pSet->numhitboxes; ++nHitbox)
{
auto pBox = pSet->pHitbox(nHitbox);
@@ -1280,12 +1339,9 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
Vec3 vCenter; Math::VectorTransform({}, aBones[pBox->bone], vCenter);
- const float flDist = vPos.DistToSqr(vCenter);
- if (flDist < flClosest)
- {
- flClosest = flDist;
- iClosest = nHitbox;
- }
+ const float flDistance = vPos.DistToSqr(vCenter);
+ if (flDistance < flLowestDistance)
+ iClosest = nHitbox, flLowestDistance = flDistance;
}
if (iClosest != HITBOX_HEAD)
break;
@@ -1300,7 +1356,6 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i
filter.pSkip = tTarget.m_pEntity;
filter.iPlayer = PLAYER_NONE;
filter.bMisc = false;
- flRadiusSqr = std::numeric_limits::max();
continue;
}
else
@@ -1329,7 +1384,7 @@ bool CAimbotProjectile::HandlePoint(const Vec3& vOrigin, int iSimTime, float flP
m_tInfo.m_pTarget->m_vPos = vOrigin;
int iOriginalSimTime = iSimTime;
- if (m_tInfo.m_iArmTime || m_tInfo.m_bIgnoreTiming && iFlags == PointFlagsEnum::Lob)
+ if (m_tInfo.m_iArmTime && iType == PointTypeEnum::Geometry || m_tInfo.m_bIgnoreTiming && iFlags == PointFlagsEnum::Lob)
{
if (flTime > m_tProjInfo.m_flLifetime)
return false;
@@ -1344,7 +1399,7 @@ bool CAimbotProjectile::HandlePoint(const Vec3& vOrigin, int iSimTime, float flP
bReturn = m_iResult = true;
m_flTimeTo = flTime + m_tInfo.m_flLatency;
}
- else if (m_iResult != 1 && !m_tInfo.m_pProjectile)
+ else if (!m_iResult && !m_tInfo.m_pProjectile)
{
switch (Vars::Aimbot::General::AimType.Value)
{
@@ -1381,7 +1436,7 @@ bool CAimbotProjectile::HandlePoint(const Vec3& vOrigin, int iSimTime, float flP
}
}
- return bReturn;
+ return bReturn && m_iResult == 1;
}
bool CAimbotProjectile::HandleDirect(DirectHistory_t& mDirectHistory)
@@ -1487,7 +1542,7 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas
m_tInfo.m_vHull = m_tProjInfo.m_vHull.Min(3);
m_tInfo.m_vOffset = m_tProjInfo.m_vPos - m_tInfo.m_vLocalEye; m_tInfo.m_vOffset.y *= -1;
- m_tInfo.m_flOffsetTime = m_tInfo.m_vOffset.Length() / m_tInfo.m_flVelocity; // silly
+ m_tInfo.m_flOffsetTime = m_tInfo.m_vOffset.Length() / m_tInfo.m_flVelocity;
m_tInfo.m_flGravity = m_tProjInfo.m_flGravity;
m_tInfo.m_iSplashRestrict = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashRestrictDirect.Value : Vars::Aimbot::Projectile::SplashRestrictArc.Value;
@@ -1544,7 +1599,16 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas
iFlags |= CalculateFlagsEnum::LobAngle;
int iTolerance = m_tInfo.m_bIgnoreTiming && iType == PointFlagsEnum::Lob ? std::numeric_limits::max() : -1;
- Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, i, tSolution, iFlags, iTolerance);
+ Solution_t tSolution;
+ switch (iType)
+ {
+ case PointFlagsEnum::Lob:
+ if (ShouldLob(m_tMoveStorage, m_tInfo))
+ goto end;
+ tSolution.m_iCalculated = CalculateResultEnum::Bad; break;
+ default: end:
+ CalculateAngle(m_tInfo.m_vLocalEye, vPoint, i, tSolution, iFlags, iTolerance);
+ }
switch (tSolution.m_iCalculated)
{
case CalculateResultEnum::Good:
@@ -1560,7 +1624,7 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas
for (auto it = vSplashes.begin(); it != vSplashes.end();)
{
uint8_t iFlags = CalculateFlagsEnum::AccountDrag;
- if (!m_tInfo.m_bIgnoreTiming && *it == PointFlagsEnum::Lob)
+ if (*it == PointFlagsEnum::Lob && !m_tInfo.m_bIgnoreTiming)
iFlags |= CalculateFlagsEnum::LobAngle;
Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, iFlags);
@@ -1581,6 +1645,11 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas
it = vSplashes.erase(it);
continue;
}
+ if (*it == PointFlagsEnum::Lob && !ShouldLob(m_tMoveStorage, m_tInfo))
+ {
+ ++it;
+ continue;
+ }
mSplashHistory[*it].emplace_back(History_t(tTarget.m_vPos, i), fabsf(flTimeTo));
++it;
@@ -1841,6 +1910,9 @@ bool CAimbotProjectile::RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser
#endif
#if defined(SPLASH_DEBUG2) && defined(WORLD_DEBUG)
G::TriangleStorage.clear();
+#endif
+#if defined(SPLASH_DEBUG2) && defined(DEBUG_TEXT)
+ F::Visuals.ClearDebugText();
#endif
for (auto& tTarget : vTargets)
{
@@ -2026,7 +2098,7 @@ bool CAimbotProjectile::TestAngle(CBaseEntity* pProjectile, const Vec3& vPoint,
Vec3 vPos = vPoint;
if (m_tInfo.m_flGravity)
- vPos += Vec3(0, 0, (m_tInfo.m_flGravity * 800.f * pow(TICKS_TO_TIME(iSimTime), 2)) / 2);
+ vPos += Vec3(0, 0, m_tInfo.m_flGravity * pow(TICKS_TO_TIME(iSimTime), 2) / 2);
Vec3 vForward = (vPos - m_tProjInfo.m_vPos).Normalized();
m_tProjInfo.m_vAng = Math::VectorAngles(vForward);
@@ -2037,7 +2109,7 @@ bool CAimbotProjectile::TestAngle(CBaseEntity* pProjectile, const Vec3& vPoint,
return false;
SDK::Trace(vEyePos, trace.endpos, MASK_SOLID, &filter, &trace);
- if (trace.fraction < 0.999f)
+ if (Math::FullFraction(vEyePos, trace.endpos, trace) < 0.999f)
return false;
if (!F::AutoAirblast.CanAirblastEntity(pLocal, pWeapon, pProjectile, vAngles))
@@ -2055,7 +2127,7 @@ bool CAimbotProjectile::TestAngle(CBaseEntity* pProjectile, const Vec3& vPoint,
if (!m_tProjInfo.m_flGravity)
{
SDK::TraceHull(m_tProjInfo.m_vPos, vPoint, -m_tProjInfo.m_vHull, m_tProjInfo.m_vHull, nMask, &filter, &trace);
- if (trace.fraction < 0.999f && trace.m_pEnt != tTarget.m_pEntity)
+ if (Math::FullFraction(m_tProjInfo.m_vPos, vPoint, trace) < 0.999f && trace.m_pEnt != tTarget.m_pEntity)
return false;
}
@@ -2091,10 +2163,9 @@ bool CAimbotProjectile::TestAngle(CBaseEntity* pProjectile, const Vec3& vPoint,
{
case PointTypeEnum::Direct:
case PointTypeEnum::Geometry:
- bHit = trace.DidHit();
- break;
+ bHit = trace.DidHit(); break;
case PointTypeEnum::Air:
- bHit = trace.endpos.DistToSqr(vPoint) < flRadiusSqr || trace.DidHit();
+ bHit = trace.endpos.DistToSqr(vPoint) < flRadiusSqr || trace.DidHit(); break;
}
if (bHit)
@@ -2103,33 +2174,17 @@ bool CAimbotProjectile::TestAngle(CBaseEntity* pProjectile, const Vec3& vPoint,
switch (iType)
{
case PointTypeEnum::Direct:
- bTarget = trace.m_pEnt == tTarget.m_pEntity, bValid = bTarget && iSimTime - n < iTimingTolerance;
- break;
+ bTarget = trace.m_pEnt == tTarget.m_pEntity, bValid = bTarget && iSimTime - n < iTimingTolerance; break;
case PointTypeEnum::Geometry:
- bValid = trace.endpos.DistToSqr(vPoint) < flRadiusSqr;
- break;
+ bValid = trace.endpos.DistToSqr(vPoint) < flRadiusSqr; break;
case PointTypeEnum::Air:
- bValid = !trace.DidHit();
- break;
+ bValid = !trace.DidHit(); break;
}
if (bValid && iType != PointTypeEnum::Direct)
{
- bValid = SDK::VisPosWorld(nullptr, tTarget.m_pEntity, trace.endpos, vPoint, nMask);
- if (bValid)
- {
- Vec3 vFrom = trace.endpos;
- switch (pProjectile->GetClassID())
- {
- case ETFClassID::CTFProjectile_Rocket:
- case ETFClassID::CTFProjectile_SentryRocket:
- case ETFClassID::CTFProjectile_EnergyBall:
- vFrom += trace.plane.normal;
- }
-
- CGameTrace eyeTrace = {};
- SDK::Trace(vFrom, tTarget.m_vPos + tTarget.m_pEntity->As()->GetViewOffset(), MASK_SHOT, &filter, &eyeTrace);
- bValid = eyeTrace.fraction == 1.f;
- }
+ CGameTrace eyeTrace = {};
+ SDK::Trace(trace.endpos + trace.plane.normal * m_tInfo.m_flNormalOffset, tTarget.m_vPos + m_tInfo.m_vTargetEye, MASK_SHOT, &filter, &eyeTrace);
+ bValid = eyeTrace.fraction == 1.f;
}
if (bValid)
@@ -2244,7 +2299,16 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa
iFlags |= CalculateFlagsEnum::LobAngle;
int iTolerance = m_tInfo.m_bIgnoreTiming && iType == PointFlagsEnum::Lob ? std::numeric_limits::max() : -1;
- Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, i, tSolution, iFlags, iTolerance);
+ Solution_t tSolution;
+ switch (iType)
+ {
+ case PointFlagsEnum::Lob:
+ if (ShouldLob(m_tMoveStorage, m_tInfo))
+ goto end;
+ tSolution.m_iCalculated = CalculateResultEnum::Bad; break;
+ default: end:
+ CalculateAngle(m_tInfo.m_vLocalEye, vPoint, i, tSolution, iFlags, iTolerance);
+ }
switch (tSolution.m_iCalculated)
{
case CalculateResultEnum::Good:
@@ -2260,7 +2324,7 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa
for (auto it = vSplashes.begin(); it != vSplashes.end();)
{
uint8_t iFlags = CalculateFlagsEnum::AccountDrag;
- if (!m_tInfo.m_bIgnoreTiming && *it == PointFlagsEnum::Lob)
+ if (*it == PointFlagsEnum::Lob && !m_tInfo.m_bIgnoreTiming)
iFlags |= CalculateFlagsEnum::LobAngle;
Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, iFlags);
@@ -2281,6 +2345,11 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa
it = vSplashes.erase(it);
continue;
}
+ if (*it == PointFlagsEnum::Lob && !ShouldLob(m_tMoveStorage, m_tInfo))
+ {
+ ++it;
+ continue;
+ }
mSplashHistory[*it].emplace_back(History_t(tTarget.m_vPos, i), fabsf(flTimeTo));
++it;
diff --git a/Amalgam/src/Features/Aimbot/AutoDetonate/AutoDetonate.h b/Amalgam/src/Features/Aimbot/AutoDetonate/AutoDetonate.h
index 7ef2dbef..d2703a59 100644
--- a/Amalgam/src/Features/Aimbot/AutoDetonate/AutoDetonate.h
+++ b/Amalgam/src/Features/Aimbot/AutoDetonate/AutoDetonate.h
@@ -2,7 +2,6 @@
#include "../../../SDK/SDK.h"
#include "../AimbotGlobal/AimbotGlobal.h"
-#include
class CAutoDetonate
{
diff --git a/Amalgam/src/Features/ImGui/Menu/Menu.cpp b/Amalgam/src/Features/ImGui/Menu/Menu.cpp
index 83ce15e6..ca4c709a 100644
--- a/Amalgam/src/Features/ImGui/Menu/Menu.cpp
+++ b/Amalgam/src/Features/ImGui/Menu/Menu.cpp
@@ -3362,6 +3362,13 @@ void CMenu::MenuSettings(int iTab)
{
FDropdown(Vars::World::Faces, FDropdownEnum::Left);
FDropdown(Vars::World::Draw, FDropdownEnum::Right);
+ FSlider(Vars::World::Offset, FSliderEnum::Left);
+ FSlider(Vars::World::Resize, FSliderEnum::Right);
+ FColorPicker(Vars::World::BoxBrush, FColorPickerEnum::Left);
+ FColorPicker(Vars::World::PlaneBrush, FColorPickerEnum::Right);
+ FColorPicker(Vars::World::Displacement, FColorPickerEnum::Left);
+ FColorPicker(Vars::World::Prop, FColorPickerEnum::Right);
+ FColorPicker(Vars::World::Entity, FColorPickerEnum::Left);
} EndSection();
#endif
#ifdef DEBUG_HOOKS
diff --git a/Amalgam/src/Features/NoSpread/NoSpreadProjectile/NoSpreadProjectile.cpp b/Amalgam/src/Features/NoSpread/NoSpreadProjectile/NoSpreadProjectile.cpp
index 5697d992..c9fcdbdd 100644
--- a/Amalgam/src/Features/NoSpread/NoSpreadProjectile/NoSpreadProjectile.cpp
+++ b/Amalgam/src/Features/NoSpread/NoSpreadProjectile/NoSpreadProjectile.cpp
@@ -39,7 +39,8 @@ void CNoSpreadProjectile::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCm
switch (pWeapon->GetWeaponID())
{
case TF_WEAPON_COMPOUND_BOW:
- if (I::GlobalVars->curtime - pWeapon->As()->m_flChargeBeginTime() > TF_ARROW_MAX_CHARGE_TIME)
+ if (pWeapon->As()->m_flChargeBeginTime() > 0.f
+ && I::GlobalVars->curtime - pWeapon->As()->m_flChargeBeginTime() > TF_ARROW_MAX_CHARGE_TIME)
{
vAngAdd.x -= float(SDK::RandomInt()) / VALVE_RAND_MAX * 12.f - 6.f;
vAngAdd.y -= float(SDK::RandomInt()) / VALVE_RAND_MAX * 12.f - 6.f;
diff --git a/Amalgam/src/Features/Resolver/Resolver.h b/Amalgam/src/Features/Resolver/Resolver.h
index 47db7fee..2f475d9c 100644
--- a/Amalgam/src/Features/Resolver/Resolver.h
+++ b/Amalgam/src/Features/Resolver/Resolver.h
@@ -1,6 +1,5 @@
#pragma once
#include "../../SDK/SDK.h"
-#include
struct ResolveData
{
diff --git a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp
index 617e6f8e..ab9e5d4c 100644
--- a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp
+++ b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp
@@ -228,54 +228,13 @@ bool CMovementSimulation::Initialize(CBaseEntity* pEntity, MoveStorage& tMoveSto
tMoveStorage.m_bBunnyHop = true;
// setup move data
- if (!SetupMoveData(tMoveStorage))
- {
- tMoveStorage.m_bFailed = true;
- return false;
- }
-
- const int iStrafeSamples = tMoveStorage.m_bDirectMove
- ? Vars::Aimbot::Projectile::GroundSamples.Value
- : Vars::Aimbot::Projectile::AirSamples.Value;
+ SetupMoveData(tMoveStorage);
// calculate strafe if desired
- bool bCalculated = bStrafe ? StrafePrediction(tMoveStorage, iStrafeSamples) : false;
-
- // really hope this doesn't work like shit
- if (bHitchance && bCalculated && !pPlayer->m_vecVelocity().IsZero() && Vars::Aimbot::Projectile::HitChance.Value)
+ if (bStrafe)
{
- const auto& vRecords = m_mRecords[pPlayer->entindex()];
- const auto iSamples = vRecords.size();
-
- float flCurrentChance = 1.f, flAverageYaw = 0.f;
- for (size_t i = 0; i < iSamples; i++)
+ if (!StrafePrediction(tMoveStorage, bHitchance))
{
- if (vRecords.size() <= i + 2)
- break;
-
- const auto& pRecord1 = vRecords[i], &pRecord2 = vRecords[i + 1];
- const float flYaw1 = Math::VectorAngles(pRecord1.m_vDirection).y, flYaw2 = Math::VectorAngles(pRecord2.m_vDirection).y;
- const float flTime1 = pRecord1.m_flSimTime, flTime2 = pRecord2.m_flSimTime;
- const int iTicks = std::max(TIME_TO_TICKS(flTime1 - flTime2), 1);
-
- float flYaw = Math::NormalizeAngle(flYaw1 - flYaw2) / iTicks;
- flAverageYaw += flYaw;
- if (tMoveStorage.m_MoveData.m_flMaxSpeed)
- flYaw *= std::clamp(pRecord1.m_vVelocity.Length2D() / tMoveStorage.m_MoveData.m_flMaxSpeed, 0.f, 1.f);
-
- if ((i + 1) % iStrafeSamples == 0 || i == iSamples - 1)
- {
- flAverageYaw /= i % iStrafeSamples + 1;
- if (fabsf(tMoveStorage.m_flAverageYaw - flAverageYaw) > 0.5f)
- flCurrentChance -= 1.f / ((iSamples - 1) / float(iStrafeSamples) + 1);
- flAverageYaw = 0.f;
- }
- }
-
- if (flCurrentChance < Vars::Aimbot::Projectile::HitChance.Value / 100)
- {
- SDK::Output("MovementSimulation", std::format("Hitchance ({}% < {}%)", flCurrentChance * 100, Vars::Aimbot::Projectile::HitChance.Value).c_str(), { 80, 200, 120 }, Vars::Debug::Logging.Value);
-
tMoveStorage.m_bFailed = true;
return false;
}
@@ -288,11 +247,8 @@ bool CMovementSimulation::Initialize(CBaseEntity* pEntity, MoveStorage& tMoveSto
return true;
}
-bool CMovementSimulation::SetupMoveData(MoveStorage& tMoveStorage)
+void CMovementSimulation::SetupMoveData(MoveStorage& tMoveStorage)
{
- if (!tMoveStorage.m_pPlayer)
- return false;
-
tMoveStorage.m_MoveData.m_bFirstRunOfFunctions = false;
tMoveStorage.m_MoveData.m_bGameCodeMovedPlayer = false;
tMoveStorage.m_MoveData.m_nPlayerHandle = reinterpret_cast(tMoveStorage.m_pPlayer)->GetRefEHandle();
@@ -346,8 +302,6 @@ bool CMovementSimulation::SetupMoveData(MoveStorage& tMoveStorage)
tMoveStorage.m_flPredictedSimTime = tMoveStorage.m_flSimTime + tMoveStorage.m_flPredictedDelta;
tMoveStorage.m_vPredictedOrigin = tMoveStorage.m_MoveData.m_vecAbsOrigin;
tMoveStorage.m_bDirectMove = tMoveStorage.m_pPlayer->IsOnGround() || tMoveStorage.m_pPlayer->IsSwimming();
-
- return true;
}
static inline float GetGravity()
@@ -527,14 +481,57 @@ void CMovementSimulation::GetAverageYaw(MoveStorage& tMoveStorage, int iSamples)
SDK::Output("MovementSimulation", std::format("flAverageYaw calculated to {} from {} ({}){}", flAverageYaw, iTicks, iMinimum, bLocal ? " (local)" : "").c_str(), { 100, 255, 150 }, Vars::Debug::Logging.Value);
}
-bool CMovementSimulation::StrafePrediction(MoveStorage& tMoveStorage, int iSamples)
+bool CMovementSimulation::StrafePrediction(MoveStorage& tMoveStorage, bool bHitchance)
{
if (tMoveStorage.m_bDirectMove
? !(Vars::Aimbot::Projectile::StrafePrediction.Value & Vars::Aimbot::Projectile::StrafePredictionEnum::Ground)
: !(Vars::Aimbot::Projectile::StrafePrediction.Value & Vars::Aimbot::Projectile::StrafePredictionEnum::Air))
- return false;
+ return true;
+
+ const int iStrafeSamples = tMoveStorage.m_bDirectMove
+ ? Vars::Aimbot::Projectile::GroundSamples.Value
+ : Vars::Aimbot::Projectile::AirSamples.Value;
+
+ GetAverageYaw(tMoveStorage, iStrafeSamples);
+
+ // really hope this doesn't work like shit
+ if (bHitchance && !tMoveStorage.m_pPlayer->m_vecVelocity().IsZero() && Vars::Aimbot::Projectile::HitChance.Value)
+ {
+ const auto& vRecords = m_mRecords[tMoveStorage.m_pPlayer->entindex()];
+ const auto iSamples = vRecords.size();
+
+ float flCurrentChance = 1.f, flAverageYaw = 0.f;
+ for (size_t i = 0; i < iSamples; i++)
+ {
+ if (vRecords.size() <= i + 2)
+ break;
+
+ const auto& pRecord1 = vRecords[i], & pRecord2 = vRecords[i + 1];
+ const float flYaw1 = Math::VectorAngles(pRecord1.m_vDirection).y, flYaw2 = Math::VectorAngles(pRecord2.m_vDirection).y;
+ const float flTime1 = pRecord1.m_flSimTime, flTime2 = pRecord2.m_flSimTime;
+ const int iTicks = std::max(TIME_TO_TICKS(flTime1 - flTime2), 1);
+
+ float flYaw = Math::NormalizeAngle(flYaw1 - flYaw2) / iTicks;
+ flAverageYaw += flYaw;
+ if (tMoveStorage.m_MoveData.m_flMaxSpeed)
+ flYaw *= std::clamp(pRecord1.m_vVelocity.Length2D() / tMoveStorage.m_MoveData.m_flMaxSpeed, 0.f, 1.f);
+
+ if ((i + 1) % iStrafeSamples == 0 || i == iSamples - 1)
+ {
+ flAverageYaw /= i % iStrafeSamples + 1;
+ if (fabsf(tMoveStorage.m_flAverageYaw - flAverageYaw) > 0.5f)
+ flCurrentChance -= 1.f / ((iSamples - 1) / float(iStrafeSamples) + 1);
+ flAverageYaw = 0.f;
+ }
+ }
+
+ if (flCurrentChance < Vars::Aimbot::Projectile::HitChance.Value / 100)
+ {
+ SDK::Output("MovementSimulation", std::format("Hitchance ({}% < {}%)", flCurrentChance * 100, Vars::Aimbot::Projectile::HitChance.Value).c_str(), { 80, 200, 120 }, Vars::Debug::Logging.Value);
+ return false;
+ }
+ }
- GetAverageYaw(tMoveStorage, iSamples);
return true;
}
diff --git a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h
index 7e62d175..ad9bf13c 100644
--- a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h
+++ b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h
@@ -44,9 +44,9 @@ private:
void Store(MoveStorage& tMoveStorage);
void Reset(MoveStorage& tMoveStorage);
- bool SetupMoveData(MoveStorage& tMoveStorage);
+ void SetupMoveData(MoveStorage& tMoveStorage);
void GetAverageYaw(MoveStorage& tMoveStorage, int iSamples);
- bool StrafePrediction(MoveStorage& tMoveStorage, int iSamples);
+ bool StrafePrediction(MoveStorage& tMoveStorage, bool bHitchance = false);
void SetBounds(CTFPlayer* pPlayer);
void RestoreBounds(CTFPlayer* pPlayer);
diff --git a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp
index 36fb3804..4687a9a2 100644
--- a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp
+++ b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp
@@ -11,7 +11,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
return false;
static auto sv_gravity = H::ConVars.FindVar("sv_gravity");
- float flGravity = sv_gravity->GetFloat() / 800.f;
+ float flGravity = sv_gravity->GetFloat(); // vphysics projectiles affected by server start gravity
bool bDucking = pPlayer->m_fFlags() & FL_DUCKING;
bool bRedirect = iFlags & ProjSimEnum::Redirect;
@@ -118,7 +118,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, vHull, flSpeed, 0.f };
return true;
}
- case TF_WEAPON_GRENADELAUNCHER: // vphysics projectiles affected by server start gravity
+ case TF_WEAPON_GRENADELAUNCHER:
case TF_WEAPON_CANNON:
{
bool bCannon = pWeapon->GetWeaponID() == TF_WEAPON_CANNON;
@@ -133,7 +133,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
? pWeapon->As()->m_flDetonateTime() > 0.f ? pWeapon->As()->m_flDetonateTime() - I::GlobalVars->curtime : flMortar
: SDK::AttribHookValue(2.f, "fuse_mult", pWeapon);
flLifeTime = ceilf(flLifeTime / GRENADE_CHECK_INTERVAL) * GRENADE_CHECK_INTERVAL + GetDesync();
- tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, vHull, flSpeed, 1.f, flLifeTime };
+ tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, vHull, flSpeed, DEFAULT_GRAVITY, flLifeTime };
return true;
}
case TF_WEAPON_PIPEBOMBLAUNCHER:
@@ -145,7 +145,7 @@ 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 = SDK::AttribHookValue(bMaxSpeed ? 2400.f : Math::RemapVal(flCharge, 0.f, SDK::AttribHookValue(4.f, "stickybomb_charge_rate", pWeapon), 900.f, 2400.f), "mult_projectile_range", pWeapon);
- tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 4.f, 4.f, 4.f }, flSpeed, 1.f };
+ tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 5.f, 5.f, 5.f }, flSpeed, DEFAULT_GRAVITY };
return true;
}
case TF_WEAPON_FLAREGUN:
@@ -238,7 +238,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, 0.f, 0.f, bInterp);
auto uType = FNV1A::Hash32Const("models/workshop_partner/weapons/c_models/c_sd_cleaver/c_sd_cleaver.mdl");
- tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 1.f, 1.f, 10.f } /*weird, probably still inaccurate*/, 3000.f, 1.f, 2.2f };
+ tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 1.f, 1.f, 10.f } /*weird, probably still inaccurate*/, 3000.f, DEFAULT_GRAVITY, 2.2f };
return true;
}
case TF_WEAPON_BAT_WOOD:
@@ -252,7 +252,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
auto uType = bWrapAssassin ? FNV1A::Hash32Const("models/weapons/c_models/c_xms_festive_ornament.mdl") : FNV1A::Hash32Const("models/weapons/w_models/w_baseball.mdl");
Vec3 vForward; Math::AngleVectors(vAngle, &vForward);
vPos = (bInterp ? pPlayer->GetAbsOrigin() : pPlayer->m_vecOrigin()) + (Vec3(0, 0, 50) + vForward * 32.f) * pPlayer->m_flModelScale(); // why?
- tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 3.f, 3.f, 3.f }, tf_scout_stunball_base_speed->GetFloat(), 1.f, bWrapAssassin ? 2.3f : 100.f };
+ tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 3.f, 3.f, 3.f }, tf_scout_stunball_base_speed->GetFloat(), DEFAULT_GRAVITY, bWrapAssassin ? 2.3f : 100.f };
return true;
}
case TF_WEAPON_JAR:
@@ -267,7 +267,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
case Sniper_s_TheSelfAwareBeautyMark: uType = FNV1A::Hash32Const("models/weapons/c_models/c_breadmonster/c_breadmonster.mdl"); break;
case Scout_s_MutatedMilk: uType = FNV1A::Hash32Const("models/weapons/c_models/c_breadmonster/c_breadmonster_milk.mdl"); break;
}
- tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 3.f, 3.f, 3.f }, 1000.f, 1.f, 2.2f };
+ tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 3.f, 3.f, 3.f }, 1000.f, DEFAULT_GRAVITY, 2.2f };
return true;
}
case TF_WEAPON_JAR_GAS:
@@ -275,7 +275,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
SDK::GetProjectileFireSetup(pPlayer, vAngles, { 16.f, 8.f, -6.f }, vPos, vAngle, 0.f, 0.f, bInterp);
auto uType = FNV1A::Hash32Const("models/weapons/c_models/c_gascan/c_gascan.mdl");
- tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 3.f, 3.f, 3.f }, 2000.f, 1.f, 2.2f };
+ tProjInfo = { pPlayer, pWeapon, uType, vPos, vAngle, { 3.f, 3.f, 3.f }, 2000.f, DEFAULT_GRAVITY, 2.2f };
return true;
}
case TF_WEAPON_GRAPPLINGHOOK:
@@ -325,7 +325,7 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
return false;
}
-bool CProjectileSimulation::GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& tProjInfo, int iFlags, float flAutoCharge)
+bool CProjectileSimulation::GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const Vec3& vAngles, ProjectileInfo& tProjInfo, int iFlags, float flAutoCharge)
{
bool bInitCheck = iFlags & ProjSimEnum::InitCheck;
bool bInterp = iFlags & ProjSimEnum::Interp;
@@ -479,6 +479,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
m_pObj->m_dragBasis = vDragBasis;
m_pObj->m_angDragBasis = vAngDragBasis;
+ m_bPhysics = m_pObj->m_dragCoefficient && m_pObj->m_dragBasis;
}
// set position and velocity
@@ -586,11 +587,19 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
}
}
- if (bSimulate && !F::ProjSim.m_pObj->IsDragEnabled() && m_pObj->m_dragBasis.IsZero()) // don't include vphysics projectiles
- vVelocity.z += 400.f * tProjInfo.m_flGravity * TICK_INTERVAL; // i don't know why this makes it more accurate but it does
+ if (bSimulate && !m_bPhysics)
+ vVelocity.z += tProjInfo.m_flGravity * TICK_INTERVAL / 2;
- m_pObj->SetPosition(tProjInfo.m_vPos, tProjInfo.m_vAng, true);
- m_pObj->SetVelocity(&vVelocity, &vAngularVelocity);
+ if (m_bPhysics)
+ {
+ m_pObj->SetPosition(tProjInfo.m_vPos, tProjInfo.m_vAng, true);
+ m_pObj->SetVelocity(&vVelocity, &vAngularVelocity);
+ }
+ else
+ {
+ m_tObj.m_vOrigin = tProjInfo.m_vPos;
+ m_tObj.m_vVelocity = vVelocity;
+ }
}
// set m_pEnv params
@@ -624,7 +633,7 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
m_pEnv->SetPerformanceSettings(¶ms);
m_pEnv->SetAirDensity(AIR_DENSITY);
- m_pEnv->SetGravity({ 0.f, 0.f, -(800.f * tProjInfo.m_flGravity) });
+ m_pEnv->SetGravity({ 0.f, 0.f, -tProjInfo.m_flGravity });
m_pEnv->ResetSimulationClock();
}
@@ -632,7 +641,8 @@ bool CProjectileSimulation::Initialize(ProjectileInfo& tProjInfo, bool bSimulate
if (tProjInfo.m_uType == FNV1A::Hash32Const("custom"))
tProjInfo.m_uType = FNV1A::Hash32(Vars::Visuals::Trajectory::Type.Value.c_str());
- RunTick(tProjInfo, false); // simulate an initial time because dumb
+ if (m_bPhysics)
+ RunTick(tProjInfo, false); // simulate an initial time because dumb
return true;
}
@@ -642,15 +652,27 @@ void CProjectileSimulation::RunTick(ProjectileInfo& tProjInfo, bool bPath) // bu
if (bPath)
tProjInfo.m_vPath.push_back(GetOrigin());
- m_pEnv->Simulate(TICK_INTERVAL);
+ if (m_bPhysics)
+ m_pEnv->Simulate(TICK_INTERVAL);
+ else
+ {
+ Vec3& vOrigin = m_tObj.m_vOrigin;
+ Vec3& vVelocity = m_tObj.m_vVelocity;
+
+ if (tProjInfo.m_flGravity)
+ vVelocity.z -= tProjInfo.m_flGravity * TICK_INTERVAL;
+
+ vOrigin += vVelocity * TICK_INTERVAL;
+ }
/* // params.maxVelocity limits velocity uniformly
- Vec3 vVelocity, vAngular;
- m_pObj->GetVelocity(&vVelocity, &vAngular);
static auto sv_maxvelocity = H::ConVars.FindVar("sv_maxvelocity");
- const float flMaxVel = sv_maxvelocity->GetFloat();
- vVelocity = { std::clamp(vVelocity.x, -flMaxVel, flMaxVel), std::clamp(vVelocity.y, -flMaxVel, flMaxVel), std::clamp(vVelocity.z, -flMaxVel, flMaxVel) };
- m_pObj->SetVelocity(&vVelocity, &vAngular);
+
+ Vec3 vVelocity;
+ m_pObj->GetVelocity(&vVelocity, nullptr);
+ float flMaxVel = sv_maxvelocity->GetFloat();
+ vVelocity = vVelocity.Clamp(-flMaxVel, flMaxVel);
+ m_pObj->SetVelocity(&vVelocity, nullptr);
*/
}
@@ -659,8 +681,10 @@ Vec3 CProjectileSimulation::GetOrigin()
if (!m_pObj)
return {};
- Vec3 vOut;
- m_pObj->GetPosition(&vOut, nullptr);
+ if (!m_bPhysics)
+ return m_tObj.m_vOrigin;
+
+ Vec3 vOut; m_pObj->GetPosition(&vOut, nullptr);
return vOut;
}
@@ -669,8 +693,10 @@ Vec3 CProjectileSimulation::GetVelocity()
if (!m_pObj)
return {};
- Vec3 vOut;
- m_pObj->GetVelocity(&vOut, nullptr);
+ if (!m_bPhysics)
+ return m_tObj.m_vVelocity;
+
+ Vec3 vOut; m_pObj->GetVelocity(&vOut, nullptr);
return vOut;
}
diff --git a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h
index e06fca8c..14579b44 100644
--- a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h
+++ b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.h
@@ -12,6 +12,7 @@ Enum(ProjSim,
CorrectRandomAngles = 1 << 6 // or do, position matters
)
+#define DEFAULT_GRAVITY 800.f
#define GRENADE_CHECK_INTERVAL 0.195f
struct ProjectileInfo
@@ -30,7 +31,13 @@ struct ProjectileInfo
std::vector m_vPath = {};
- int m_iFlags = 0;
+ uint8_t m_iFlags = 0;
+};
+
+struct PhysicsObject_t
+{
+ Vec3 m_vOrigin = {};
+ Vec3 m_vVelocity = {};
};
class CProjectileSimulation
@@ -53,7 +60,7 @@ private:
};
public:
- bool GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vAngles, ProjectileInfo& tProjInfo, int iFlags = ProjSimEnum::Redirect | ProjSimEnum::InitCheck, float flAutoCharge = -1.f);
+ bool GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const Vec3& vAngles, ProjectileInfo& tProjInfo, int iFlags = ProjSimEnum::Redirect | ProjSimEnum::InitCheck, float flAutoCharge = -1.f);
void SetupTrace(CTraceFilterCollideable& filter, int& nMask, CTFWeaponBase* pWeapon, int nTick = 0, bool bInterp = false);
void GetInfo(CBaseEntity* pProjectile, ProjectileInfo& tProjInfo);
@@ -165,7 +172,7 @@ public:
float flReturn = 0.f;
static auto sv_gravity = H::ConVars.FindVar("sv_gravity");
- float flGravity = sv_gravity->GetFloat() / 800.f;
+ float flGravity = sv_gravity->GetFloat();
switch (pProjectile->GetClassID())
{
case ETFClassID::CBaseGrenade:
@@ -191,7 +198,7 @@ public:
case ETFClassID::CTFProjectile_ThrowableBreadMonster:
case ETFClassID::CTFProjectile_ThrowableBrick:
case ETFClassID::CTFProjectile_ThrowableRepel:
- flReturn = 1.f;
+ flReturn = DEFAULT_GRAVITY;
break;
case ETFClassID::CTFProjectile_HealingBolt:
flReturn = 0.2f * flGravity;
@@ -209,7 +216,11 @@ public:
}
IPhysicsEnvironment* m_pEnv = nullptr;
+
IPhysicsObject* m_pObj = nullptr;
+ PhysicsObject_t m_tObj = {};
+ bool m_bPhysics = false;
+
ProjectileInfo* m_pCurrent = nullptr;
};
diff --git a/Amalgam/src/Features/Visuals/Visuals.cpp b/Amalgam/src/Features/Visuals/Visuals.cpp
index 44660283..67f61b23 100644
--- a/Amalgam/src/Features/Visuals/Visuals.cpp
+++ b/Amalgam/src/Features/Visuals/Visuals.cpp
@@ -374,7 +374,7 @@ void CVisuals::DrawDebugInfo(CTFPlayer* pLocal)
Vec3 vOrigin = pLocal->m_vecOrigin();
H::Draw.StringOutlined(fFont, x, y += nTall * 2, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, std::format("Origin: ({:.3f}, {:.3f}, {:.3f})", vOrigin.x, vOrigin.y, vOrigin.z).c_str());
Vec3 vVelocity = pLocal->m_vecVelocity();
- H::Draw.StringOutlined(fFont, x, y += nTall, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, std::format("Velocity: {:.3f} ({:.3f}, {:.3f}, {:.3f})", vVelocity.Length(), vVelocity.x, vVelocity.y, vVelocity.z).c_str());
+ H::Draw.StringOutlined(fFont, x, y += nTall, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, std::format("Velocity: {:.3f}, {:.3f} ({:.3f}, {:.3f}, {:.3f})", vVelocity.Length(), vVelocity.Length2D(), vVelocity.x, vVelocity.y, vVelocity.z).c_str());
H::Draw.StringOutlined(fFont, x, y += nTall, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, std::format("Tickbase: {}", pLocal->m_nTickBase()).c_str());
//H::Draw.StringOutlined(fFont, x, y += nTall, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, std::format("Choke: {}, {}", G::Choking, I::ClientState->chokedcommands).c_str());
//H::Draw.StringOutlined(fFont, x, y += nTall, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, std::format("Ticks: {}, {}", F::Ticks.m_iShiftedTicks, F::Ticks.m_iShiftedGoal).c_str());
@@ -406,16 +406,41 @@ void CVisuals::DrawDebugInfo(CTFPlayer* pLocal)
{
if (Vars::Debug::Info.Value)
y += nTall;
- for (auto& [sString, tColor] : m_vDebugText)
+ for (auto& [sString, tColor, vPosition2D, vPosition3D] : m_vDebugText)
+ {
+ if (vPosition3D)
+ {
+ if (Vec3 vScreen; SDK::W2S(*vPosition3D, vScreen))
+ H::Draw.StringOutlined(fFont, vScreen.x, vScreen.y, tColor, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, sString.c_str());
+ }
+ else if (vPosition2D)
+ H::Draw.StringOutlined(fFont, vPosition2D->x, vPosition2D->y, tColor, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, sString.c_str());
+ else
H::Draw.StringOutlined(fFont, x, y += nTall, tColor, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, sString.c_str());
}
+ }
#endif
}
#ifdef DEBUG_TEXT
+void CVisuals::AddDebugText(const DebugText_t& sText)
+{
+ m_vDebugText.push_back(sText);
+}
+
void CVisuals::AddDebugText(const std::string& sString, Color_t tColor)
{
- m_vDebugText.emplace_back(sString, tColor);
+ m_vDebugText.emplace_back(sString, tColor, std::nullopt, std::nullopt);
+}
+
+void CVisuals::AddDebugText(const std::string& sString, const Vec2& vPosition, Color_t tColor)
+{
+ m_vDebugText.emplace_back(sString, tColor, vPosition, std::nullopt);
+}
+
+void CVisuals::AddDebugText(const std::string& sString, const Vec3& vPosition, Color_t tColor)
+{
+ m_vDebugText.emplace_back(sString, tColor, std::nullopt, vPosition);
}
void CVisuals::ClearDebugText()
@@ -863,7 +888,6 @@ void CVisuals::Store()
if (!F::Groups.GetGroup(pEntity, pGroup, false) || !(pGroup->m_iTrajectory & TrajectoryEnum::Enabled))
continue;
- bool bContains = m_mProjectiles.contains(pEntity);
Projectile_t& tProjectile = m_mProjectiles[pEntity];
mProjectiles[pEntity];
@@ -947,7 +971,7 @@ void CVisuals::Store()
}
}
- for (auto& [pEntity, tProjectile] : m_mProjectiles)
+ for (auto& pEntity : m_mProjectiles | std::views::keys)
{
if (!mProjectiles.contains(pEntity))
m_mProjectiles.erase(pEntity);
@@ -1212,11 +1236,17 @@ void CVisuals::CreateMove(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
{
for (auto& tFace : vFaces)
{
+ if (Vars::World::Offset.Value)
+ Math::OffsetPolygon(tFace.m_vVertices, tFace.m_vNormal, Vars::World::Offset.Value);
+ if (Vars::World::Resize.Value)
+ Math::ExpandPolygon(tFace.m_vVertices, tFace.m_vNormal, Vars::World::Resize.Value);
+
F::World.DrawFace(tFace, Vars::World::Draw.Value);
+
/*
for (int i = 0; ++i < tFace.m_vVertices.size() - 1;)
{
- const Vec3& vVertex1 = tFace.m_vVertices[0], & vVertex2 = tFace.m_vVertices[i], & vVertex3 = tFace.m_vVertices[i + 1];
+ const Vec3& vVertex1 = tFace.m_vVertices[0], &vVertex2 = tFace.m_vVertices[i], &vVertex3 = tFace.m_vVertices[i + 1];
Vec3 vDir21 = vVertex2 - vVertex1, vDir31 = vVertex3 - vVertex1;
float flArea = vDir21.Cross(vDir31).Length() / 2;
diff --git a/Amalgam/src/Features/Visuals/Visuals.h b/Amalgam/src/Features/Visuals/Visuals.h
index a3955b96..9f0bd3f9 100644
--- a/Amalgam/src/Features/Visuals/Visuals.h
+++ b/Amalgam/src/Features/Visuals/Visuals.h
@@ -1,8 +1,6 @@
#pragma once
#include "../../SDK/SDK.h"
-#include