diff --git a/Amalgam/Amalgam.vcxproj b/Amalgam/Amalgam.vcxproj index e16d0890..2eac861c 100644 --- a/Amalgam/Amalgam.vcxproj +++ b/Amalgam/Amalgam.vcxproj @@ -953,6 +953,7 @@ + @@ -966,6 +967,7 @@ + @@ -996,7 +998,6 @@ - @@ -1070,7 +1071,10 @@ + + + @@ -1252,7 +1256,10 @@ + + + @@ -1269,15 +1276,23 @@ + + + + + + + + @@ -1291,15 +1306,21 @@ + + + + + + + + - + - - - + @@ -1403,7 +1424,7 @@ - + diff --git a/Amalgam/Amalgam.vcxproj.filters b/Amalgam/Amalgam.vcxproj.filters index e7411e43..64cdebac 100644 --- a/Amalgam/Amalgam.vcxproj.filters +++ b/Amalgam/Amalgam.vcxproj.filters @@ -181,7 +181,6 @@ - @@ -201,6 +200,11 @@ + + + + + @@ -265,7 +269,7 @@ - + @@ -435,7 +439,7 @@ - + @@ -452,10 +456,8 @@ - + - - @@ -587,6 +589,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Amalgam/cpp.hint b/Amalgam/cpp.hint index 012f5af2..f39f9431 100644 --- a/Amalgam/cpp.hint +++ b/Amalgam/cpp.hint @@ -30,27 +30,23 @@ void Hooks::name::Init() { Hook.Create(reinterpret_cast(address), Func); } \ type callconvo Hooks::name::Func(__VA_ARGS__) #define CALL_ORIGINAL Hook.Original() -#define MAKE_INTERFACE_VERSION(type, name, dll, version) namespace I { inline type *name = nullptr; } \ + +#define MAKE_INTERFACE_VERSION(type, symbol, dll, version, ...) namespace I { inline type *symbol = nullptr; } \ namespace MAKE_INTERFACE_SCOPE \ {\ - inline InterfaceInit_t name##InterfaceInit_t(reinterpret_cast(&I::name), dll, version, -1, 0); \ + inline InterfaceInit_t symbol##InterfaceInit_t(reinterpret_cast(&I::symbol), dll, version, 0, __VA_ARGS__); \ } -#define MAKE_INTERFACE_SIGNATURE(type, name, dll, version, offset, deref) namespace I { inline type *name = nullptr; } \ +#define MAKE_INTERFACE_EXPORT(type, symbol, dll, name, deref, ...) namespace I { inline type *symbol = nullptr; } \ namespace MAKE_INTERFACE_SCOPE \ {\ - inline InterfaceInit_t name##InterfaceInit_t(reinterpret_cast(&I::name), dll, version, offset, deref); \ + inline InterfaceInit_t symbol##InterfaceInit_t(reinterpret_cast(&I::symbol), dll, name, 1, 0, deref, __VA_ARGS__); \ } -#define MAKE_INTERFACE_NULL(type, name) namespace I { inline type *name = nullptr; } -#define MAKE_INTERFACE_VERSION_SEARCH(type, name, dll, version) namespace I { inline type *name = nullptr; } \ +#define MAKE_INTERFACE_SIGNATURE(type, symbol, dll, signature, offset, deref, ...) namespace I { inline type *symbol = nullptr; } \ namespace MAKE_INTERFACE_SCOPE \ {\ - inline InterfaceInit_t name##InterfaceInit_t(reinterpret_cast(&I::name), dll, version, -1, 0, true); \ -} -#define MAKE_INTERFACE_SIGNATURE_SEARCH(type, name, dll, signature, offset, deref) namespace I { inline type *name = nullptr; } \ -namespace MAKE_INTERFACE_SCOPE \ -{\ - inline InterfaceInit_t name##InterfaceInit_t(reinterpret_cast(&I::name), dll, signature, offset, deref, true); \ + inline InterfaceInit_t symbol##InterfaceInit_t(reinterpret_cast(&I::symbol), dll, signature, 2, offset, deref, __VA_ARGS__); \ } +#define MAKE_INTERFACE_NULL(type, symbol) namespace I { inline type *symbol = nullptr; } #define NETVAR(_name, type, table, name) inline type& _name() \ { \ diff --git a/Amalgam/src/Features/Aimbot/Aimbot.cpp b/Amalgam/src/Features/Aimbot/Aimbot.cpp index 1e1383ab..b437695b 100644 --- a/Amalgam/src/Features/Aimbot/Aimbot.cpp +++ b/Amalgam/src/Features/Aimbot/Aimbot.cpp @@ -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(m_flFOV) / 2) * float(H::Draw.m_nScreenW) * (4.f / 6.f) / (16.f / 9.f); + 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); H::Draw.LineCircle(H::Draw.m_nScreenW / 2, H::Draw.m_nScreenH / 2, flRadius, 68, Vars::Colors::FOVCircle.Value); } diff --git a/Amalgam/src/Features/Aimbot/Aimbot.h b/Amalgam/src/Features/Aimbot/Aimbot.h index 4757edf7..8cbf9d3b 100644 --- a/Amalgam/src/Features/Aimbot/Aimbot.h +++ b/Amalgam/src/Features/Aimbot/Aimbot.h @@ -19,7 +19,6 @@ public: bool m_bRan = false; bool m_bRunningSecondary = false; - float m_flFOV = 0.f; DrawPath_t m_tPath = {}; }; diff --git a/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.cpp b/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.cpp index 54afd6e3..48d5ce4b 100644 --- a/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.cpp @@ -41,16 +41,16 @@ void CAimbotGlobal::SortTargetsPost(std::vector& vTargets, int iMethod { case Vars::Aimbot::General::TargetSelectionEnum::Hybrid: std::sort(vTargets.begin(), vTargets.end(), [&](const Target_t& a, const Target_t& b) -> bool - { - return a.m_flFOVTo < b.m_flFOVTo; - }); + { + return a.m_flFOVTo < b.m_flFOVTo; + }); break; } std::sort(vTargets.begin(), vTargets.end(), [&](const Target_t& a, const Target_t& b) -> bool - { - return a.m_nPriority > b.m_nPriority; - }); + { + return a.m_nPriority > b.m_nPriority; + }); } // this won't prevent shooting bones outside of fov diff --git a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp index d6eb6155..06c8a833 100644 --- a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp @@ -1,10 +1,10 @@ #include "AimbotHitscan.h" #include "../Aimbot.h" -#include "../../Resolver/Resolver.h" #include "../../Ticks/Ticks.h" -#include "../../Visuals/Visuals.h" +#include "../../Resolver/Resolver.h" #include "../../Simulation/MovementSimulation/MovementSimulation.h" +#include "../../Visuals/Visuals.h" static inline std::vector GetTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) { @@ -191,7 +191,7 @@ int CAimbotHitscan::GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponB { auto pSniperRifle = pWeapon->As(); - int iDamage = std::ceil(std::max(pSniperRifle->m_flChargedDamage(), 50.f) * pSniperRifle->GetBodyshotMult(pPlayer)); + int iDamage = ceilf(std::max(pSniperRifle->m_flChargedDamage(), 50.f) * pSniperRifle->GetBodyshotMult(pPlayer)); if (pPlayer->m_iHealth() <= iDamage) bHeadshot = false; break; @@ -203,7 +203,7 @@ int CAimbotHitscan::GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponB float flDistTo = pTarget->m_vecOrigin().DistTo(pLocal->m_vecOrigin()); float flMult = SDK::AttribHookValue(1, "mult_dmg", pWeapon); - int iDamage = std::ceil(Math::RemapVal(flDistTo, 90.f, 900.f, 60.f, 21.f) * flMult); + int iDamage = ceilf(Math::RemapVal(flDistTo, 90.f, 900.f, 60.f, 21.f) * flMult); if (pPlayer->m_iHealth() <= iDamage) bHeadshot = false; } @@ -281,13 +281,13 @@ int CAimbotHitscan::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* if (pDoubletapAngle && tTarget.m_iTargetType == TargetEnum::Player) { 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 vAnglesA = Math::CalcAngle(m_vEyePos, vPosA); - Vec3 vAnglesB = Math::CalcAngle(m_vEyePos, vPosB); - return pDoubletapAngle->DeltaAngle(vAnglesA).Length2D() < pDoubletapAngle->DeltaAngle(vAnglesB).Length2D(); - }); + { + 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 vAnglesA = Math::CalcAngle(m_vEyePos, vPosA); + Vec3 vAnglesB = Math::CalcAngle(m_vEyePos, vPosB); + return pDoubletapAngle->DeltaAngle(vAnglesA).Length2D() < pDoubletapAngle->DeltaAngle(vAnglesB).Length2D(); + }); } int iReturn = false; @@ -365,9 +365,9 @@ int CAimbotHitscan::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBase* vHitboxes.emplace_back(pBox, nHitbox, iPriority); } std::sort(vHitboxes.begin(), vHitboxes.end(), [&](const auto& a, const auto& b) -> bool - { - return std::get<2>(a) < std::get<2>(b); - }); + { + return std::get<2>(a) < std::get<2>(b); + }); float flModelScale = tTarget.m_pEntity->As()->m_flModelScale(); float flBoneScale = Vars::Aimbot::Hitscan::BoneSizeMinimumScale.Value; @@ -587,13 +587,13 @@ bool CAimbotHitscan::ShouldFire(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser auto pPlayer = tTarget.m_pEntity->As(); if (tTarget.m_nAimedHitbox == HITBOX_HEAD && (pWeapon->GetWeaponID() != TF_WEAPON_SNIPERRIFLE_CLASSIC || pSniperRifle->m_flChargedDamage() == 150.f)) { - int iDamage = std::ceil(std::max(pSniperRifle->m_flChargedDamage(), 50.f) * pSniperRifle->GetHeadshotMult(pPlayer)); + int iDamage = ceilf(std::max(pSniperRifle->m_flChargedDamage(), 50.f) * pSniperRifle->GetHeadshotMult(pPlayer)); if (pPlayer->m_iHealth() <= iDamage && (G::CanHeadshot || pLocal->IsCritBoosted())) break; } else { - int iDamage = std::ceil(std::max(pSniperRifle->m_flChargedDamage(), 50.f) * pSniperRifle->GetBodyshotMult(pPlayer)); + int iDamage = ceilf(std::max(pSniperRifle->m_flChargedDamage(), 50.f) * pSniperRifle->GetBodyshotMult(pPlayer)); if (pPlayer->m_iHealth() <= iDamage) break; } @@ -601,7 +601,7 @@ bool CAimbotHitscan::ShouldFire(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser else if (tTarget.m_pEntity->IsBuilding()) { auto pBuilding = tTarget.m_pEntity->As(); - int iDamage = std::ceil(std::max(pSniperRifle->m_flChargedDamage(), 50.f)); + int iDamage = ceilf(std::max(pSniperRifle->m_flChargedDamage(), 50.f)); if (pBuilding->m_iHealth() <= iDamage) break; } diff --git a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp index 516dc67f..56de90a4 100644 --- a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp @@ -208,7 +208,7 @@ void CAimbotMelee::UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCm G::BoxStorage.clear(); G::PathStorage.clear(); - for (auto& [_, vPath] : m_mPaths) + for (auto& vPath : m_mPaths | std::views::values) { if (Vars::Colors::PlayerPathIgnoreZ.Value.a) G::PathStorage.emplace_back(vPath, I::GlobalVars->curtime + Vars::Visuals::Simulation::DrawDuration.Value, Vars::Colors::PlayerPathIgnoreZ.Value, Vars::Visuals::Simulation::PlayerPath.Value); @@ -218,7 +218,7 @@ void CAimbotMelee::UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCm } } - for (auto& [_, tMoveStorage] : mMoveStorage) + for (auto& tMoveStorage : mMoveStorage | std::views::values) F::MoveSim.Restore(tMoveStorage); } @@ -278,34 +278,34 @@ bool CAimbotMelee::CanBackstab(CBaseEntity* pTarget, CTFPlayer* pLocal, Vec3 vEy float flPosVsOwnerViewMinDot = 0.5f + flExtra; float flViewAnglesMinDot = -0.3f + 0.0031f; // 0.00306795676297 ? - auto TestDots = [&](Vec3 vTargetAngles) - { - Vec3 vOwnerForward; Math::AngleVectors(vEyeAngles, &vOwnerForward); - vOwnerForward.Normalize2D(); + auto fTestDots = [&](Vec3 vTargetAngles) + { + Vec3 vOwnerForward; Math::AngleVectors(vEyeAngles, &vOwnerForward); + vOwnerForward.Normalize2D(); - Vec3 vTargetForward; Math::AngleVectors(vTargetAngles, &vTargetForward); - vTargetForward.Normalize2D(); + Vec3 vTargetForward; Math::AngleVectors(vTargetAngles, &vTargetForward); + vTargetForward.Normalize2D(); - const float flPosVsTargetViewDot = vToTarget.Dot(vTargetForward); // Behind? - const float flPosVsOwnerViewDot = vToTarget.Dot(vOwnerForward); // Facing? - const float flViewAnglesDot = vTargetForward.Dot(vOwnerForward); // Facestab? + const float flPosVsTargetViewDot = vToTarget.Dot(vTargetForward); // Behind? + const float flPosVsOwnerViewDot = vToTarget.Dot(vOwnerForward); // Facing? + const float flViewAnglesDot = vTargetForward.Dot(vOwnerForward); // Facestab? - return flPosVsTargetViewDot > flPosVsTargetViewMinDot && flPosVsOwnerViewDot > flPosVsOwnerViewMinDot && flViewAnglesDot > flViewAnglesMinDot; - }; + return flPosVsTargetViewDot > flPosVsTargetViewMinDot && flPosVsOwnerViewDot > flPosVsOwnerViewMinDot && flViewAnglesDot > flViewAnglesMinDot; + }; Vec3 vTargetAngles = { 0.f, H::Entities.GetEyeAngles(pTarget->entindex()).y, 0.f }; if (!Vars::Aimbot::Melee::BackstabAccountPing.Value) { - if (!TestDots(vTargetAngles)) + if (!fTestDots(vTargetAngles)) return false; } else { - if (Vars::Aimbot::Melee::BackstabDoubleTest.Value && !TestDots(vTargetAngles)) + if (Vars::Aimbot::Melee::BackstabDoubleTest.Value && !fTestDots(vTargetAngles)) return false; vTargetAngles.y += H::Entities.GetDeltaAngles(pTarget->entindex()).y; - if (!TestDots(vTargetAngles)) + if (!fTestDots(vTargetAngles)) return false; } diff --git a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp index 4fc069c3..9c959754 100644 --- a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp @@ -1,15 +1,17 @@ #include "AimbotProjectile.h" #include "../Aimbot.h" -#include "../../EnginePrediction/EnginePrediction.h" #include "../../Ticks/Ticks.h" +#include "../../EnginePrediction/EnginePrediction.h" +#include "../../World/World.h" #include "../AutoAirblast/AutoAirblast.h" +#include -//#define SPLASH_DEBUG1 // normal splash visualization -//#define SPLASH_DEBUG2 // obstructed splash visualization +//#define SPLASH_DEBUG1 // trace splash visualization +//#define SPLASH_DEBUG2 // plane splash visualization //#define SPLASH_DEBUG3 // points visualization -//#define SPLASH_DEBUG4 // trace visualization -//#define SPLASH_DEBUG5 // trace count +//#define SPLASH_DEBUG4 // test visualization +//#define SPLASH_DEBUG5 // trace/face count #ifdef SPLASH_DEBUG5 static std::map s_mTraceCount = {}; @@ -246,22 +248,6 @@ float CAimbotProjectile::GetSplashRadius(CBaseEntity* pProjectile, CTFWeaponBase return flRadius * flScale; } -static inline int GetSplashMode(CTFWeaponBase* pWeapon) -{ - if (Vars::Aimbot::Projectile::RocketSplashMode.Value) - { - switch (pWeapon->GetWeaponID()) - { - case TF_WEAPON_ROCKETLAUNCHER: - case TF_WEAPON_ROCKETLAUNCHER_DIRECTHIT: - case TF_WEAPON_PARTICLE_CANNON: - return Vars::Aimbot::Projectile::RocketSplashMode.Value; - } - } - - return Vars::Aimbot::Projectile::RocketSplashModeEnum::Regular; -} - static inline float ArmTime(CTFWeaponBase* pWeapon) { if (Vars::Aimbot::Projectile::Modifiers.Value & Vars::Aimbot::Projectile::ModifiersEnum::UseArmTime && pWeapon->GetWeaponID() == TF_WEAPON_PIPEBOMBLAUNCHER) @@ -389,405 +375,274 @@ std::unordered_map CAimbotProjectile::GetDirectPoints() return mPoints; } -static inline std::vector> ComputeSphere(float flRadius, int iSamples) +static inline std::vector ComputeSphere(float flRadius, int iSamples) { - std::vector> vPoints; - vPoints.reserve(iSamples); + std::vector vPoints = { { Vec3(0.f, 0.f, -1.f) * flRadius} }; - float flRotateX = Vars::Aimbot::Projectile::SplashRotateX.Value < 0.f ? SDK::StdRandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateX.Value; - float flRotateY = Vars::Aimbot::Projectile::SplashRotateY.Value < 0.f ? SDK::StdRandomFloat(0.f, 360.f) : Vars::Aimbot::Projectile::SplashRotateY.Value; - - int iPointType = Vars::Aimbot::Projectile::SplashGrates.Value ? PointTypeEnum::Out | PointTypeEnum::In : PointTypeEnum::Out; - if (Vars::Aimbot::Projectile::RocketSplashMode.Value == Vars::Aimbot::Projectile::RocketSplashModeEnum::SpecialHeavy) - iPointType |= PointTypeEnum::Out2 | PointTypeEnum::In2; - - float a = PI * (3.f - sqrtf(5.f)); - for (int n = 0; n < iSamples; n++) + if (Vars::Aimbot::Projectile::SplashMode.Value == Vars::Aimbot::Projectile::SplashModeEnum::Trace) { - 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; + vPoints.reserve(iSamples + 1); - Vec3 vPoint = Vec3(x, y, z) * flRadius; - vPoint = Math::RotatePoint(vPoint, {}, { flRotateX, flRotateY }); + 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; - vPoints.emplace_back(vPoint, iPointType); + float a = 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.emplace_back(Vec3(0.f, 0.f, -1.f) * flRadius, iPointType); return vPoints; }; -template -static inline void TracePoint(Vec3& vPoint, int& iType, Vec3& vTargetEye, Info_t& tInfo, T& vPoints, std::function checkPoint, int i = 0) -{ - // if anyone knows ways to further optimize this or just a better method, let me know! - - int iOriginalType = iType; - bool bErase = false, bNormal = false; - - CGameTrace trace = {}; - CTraceFilterWorldAndPropsOnly filter = {}; - #if defined(SPLASH_DEBUG1) || defined(SPLASH_DEBUG2) - auto drawTrace = [](bool bSuccess, Color_t tColor, CGameTrace& trace) - { - Vec3 vMins = Vec3(-1, -1, -1) / (bSuccess ? 1 : 2), vMaxs = Vec3(1, 1, 1) / (bSuccess ? 1 : 2); - Vec3 vAngles = Math::VectorAngles(trace.plane.normal); - G::BoxStorage.emplace_back(trace.endpos, vMins, vMaxs, vAngles, I::GlobalVars->curtime + 60.f, tColor.Alpha(tColor.a / (bSuccess ? 1 : 10)), Color_t(0, 0, 0, 0)); - G::LineStorage.emplace_back(std::pair(trace.startpos, trace.endpos), I::GlobalVars->curtime + 60.f, tColor.Alpha(tColor.a / (bSuccess ? 1 : 10))); - }; +static inline void DrawTrace(bool bSuccess, Color_t tColor, CGameTrace& trace) +{ + Vec3 vMins = -Vec3::Get(bSuccess ? 1.f : 0.5f), vMaxs = Vec3::Get(bSuccess ? 1.f : 0.5f); + Vec3 vAngles = Math::VectorAngles(trace.plane.normal); + G::BoxStorage.emplace_back(trace.endpos, vMins, vMaxs, vAngles, I::GlobalVars->curtime + 60.f, tColor.Alpha(tColor.a / (bSuccess ? 1 : 10)), Color_t(0, 0, 0, 0)); + G::LineStorage.emplace_back(std::pair(trace.startpos, trace.endpos), I::GlobalVars->curtime + 60.f, tColor.Alpha(tColor.a / (bSuccess ? 1 : 10))); +}; #endif - if (iType & PointTypeEnum::Out) - { - SDK::TraceHull(vTargetEye, vPoint, tInfo.m_vHull * -1, tInfo.m_vHull, MASK_SOLID, &filter, &trace); +static inline void HandleTrace(const Vec3& vPoint, std::vector& vPoints, const Vec3& vTargetEye, Info_t& tInfo, std::function fCheckPoint, CGameTrace& trace, ITraceFilter& filter, int i = 0) +{ + // out + SDK::TraceHull(vTargetEye, vPoint, -tInfo.m_vHull, tInfo.m_vHull, MASK_SOLID, &filter, &trace); #ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash out"]++; + s_mTraceCount[__FUNCTION__": splash out"]++; #endif - if (checkPoint(trace, bErase, bNormal)) - { - if (i % Vars::Aimbot::Projectile::SplashNormalSkip.Value) - vPoints.pop_back(); + if (fCheckPoint() && !(i % Vars::Aimbot::Projectile::SplashNormalSkip.Value)) + { + vPoints.push_back(trace.endpos); #ifdef SPLASH_DEBUG1 - else - drawTrace(!bNormal, Vars::Colors::Local.Value, trace); + DrawTrace(!bNormal, Vars::Colors::IndicatorGood.Value, trace); #endif - } - - if (bErase) - iType = 0; - else if (bNormal) - iType &= ~PointTypeEnum::Out; - else - iType &= ~PointTypeEnum::In; } - if (iType & PointTypeEnum::Out2) + + // in + if ((tInfo.m_vLocalEye - vTargetEye).Dot(vTargetEye - vPoint) > 0.f) + return; + + SDK::Trace(vPoint, vTargetEye, MASK_SHOT, &filter, &trace); +#ifdef SPLASH_DEBUG5 + s_mTraceCount[__FUNCTION__": splash in check"]++; +#endif +#ifdef SPLASH_DEBUG1 + DrawTrace(!trace.DidHit(), Vars::Colors::IndicatorMid.Value, trace); +#endif + if (trace.DidHit()) + return; + + SDK::TraceHull(vPoint, vTargetEye, -tInfo.m_vHull, tInfo.m_vHull, MASK_SOLID, &filter, &trace); +#ifdef SPLASH_DEBUG5 + s_mTraceCount[__FUNCTION__": splash in"]++; +#endif + + if (fCheckPoint()) { - bErase = false, bNormal = false; - size_t iOriginalSize = vPoints.size(); - - { - float flNormal = (tInfo.m_vLocalEye - vTargetEye).DotNormalized(vTargetEye - vPoint); - if (bNormal = Vars::Aimbot::Projectile::Out2NormalMin.Value > flNormal || flNormal > Vars::Aimbot::Projectile::Out2NormalMax.Value) - goto breakOutExtra; - - if (!(iOriginalType & PointTypeEnum::Out)) // don't do the same trace over again - { - SDK::Trace(vTargetEye, vPoint, MASK_SOLID, &filter, &trace); -#ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash out 1"]++; + vPoints.push_back(trace.endpos); +#ifdef SPLASH_DEBUG1 + DrawTrace(!bNormal, Vars::Colors::IndicatorBad.Value, trace); #endif - bNormal = !trace.m_pEnt || trace.fraction == 1.f; -#ifdef SPLASH_DEBUG2 - drawTrace(!bNormal, Vars::Colors::IndicatorTextMid.Value, trace); -#endif - if (bNormal) - goto breakOutExtra; - } - - switch (trace.m_pEnt->GetClassID()) - { // make sure we get past entity or prop - case ETFClassID::CWorld: - if (trace.hitbox) filter.iTeam = trace.hitbox - 1; - filter.pSkip = nullptr; - break; - default: - filter.pSkip = trace.m_pEnt; - } - SDK::Trace(trace.endpos - (vTargetEye - vPoint).Normalized(), vPoint, MASK_SOLID | CONTENTS_NOSKIP, &filter, &trace); - filter.pSkip = nullptr, filter.iTeam = -1; -#ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash out 2"]++; -#endif - bNormal = trace.fraction == 1.f || !trace.fraction || trace.fraction == trace.fractionleftsolid || trace.allsolid || trace.surface.flags & (/*SURF_NODRAW |*/ SURF_SKY); -#ifdef SPLASH_DEBUG2 - drawTrace(!bNormal, Vars::Colors::IndicatorTextBad.Value, trace); -#endif - if (bNormal) - goto breakOutExtra; - - if (checkPoint(trace, bErase, bNormal)) - { - SDK::Trace(trace.endpos + trace.plane.normal, vTargetEye, MASK_SHOT, &filter, &trace); -#ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash out rocket check"]++; -#endif -#ifdef SPLASH_DEBUG2 - drawTrace(trace.fraction >= 1.f, Vars::Colors::IndicatorTextMisc.Value, trace); -#endif - if (trace.fraction < 1.f) - vPoints.pop_back(); - } - } - - breakOutExtra: - if (vPoints.size() != iOriginalSize) - iType = 0; - else if (bErase || bNormal) - iType &= ~PointTypeEnum::Out2; } - if (iType & PointTypeEnum::In) +} + +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) +{ + float flRadiusSqr = powf(flRadius, 2); + float flRadius2Sqr = flRadiusSqr * 4; + + for (int i = 0; ++i < tFace.m_vVertices.size() - 1;) { - bErase = false, bNormal = false; - size_t iOriginalSize = vPoints.size(); + const Vec3& vVertex1 = tFace.m_vVertices[0], & vVertex2 = tFace.m_vVertices[i], & vVertex3 = tFace.m_vVertices[i + 1]; - if (bNormal = (tInfo.m_vLocalEye - vTargetEye).Dot(vTargetEye - vPoint) > 0.f) - goto breakOut; + 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); - if (tInfo.m_iSplashMode == Vars::Aimbot::Projectile::RocketSplashModeEnum::Regular) // just do this for non rockets, it's less expensive +#if defined(SPLASH_DEBUG2) && defined(WORLD_DEBUG) + if (iSamples) + F::World.DrawFace({ { vVertex1, vVertex2, vVertex3 }, tFace.m_vNormal }, DrawTypeEnum::Edges | DrawTypeEnum::Faces); +#endif + + for (int i = 0; i < iSamples; i++) { - SDK::Trace(vPoint, vTargetEye, MASK_SHOT, &filter, &trace); -#ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash in check"]++; -#endif - bNormal = trace.DidHit(); -#ifdef SPLASH_DEBUG2 - drawTrace(!bNormal, Vars::Colors::IndicatorGood.Value, trace); -#endif - if (bNormal) - goto breakOut; + float flRandom1 = SDK::RandomFloat(), flRandom2 = SDK::RandomFloat(); + if (flRandom1 + flRandom2 > 1) + flRandom1 = 1 - flRandom1, flRandom2 = 1 - flRandom2; - SDK::TraceHull(vPoint, vTargetEye, tInfo.m_vHull * -1, tInfo.m_vHull, MASK_SOLID, &filter, &trace); -#ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash in"]++; -#endif + Vec3 vPoint = vVertex1 + vDir21 * flRandom1 + vDir31 * flRandom2 + tFace.m_vNormal * (tInfo.m_vHull + CALC_EPSILON); + if (vPoint.DistToSqr(vTargetCenter) > flRadiusSqr) + continue; - checkPoint(trace, bErase, bNormal); -#ifdef SPLASH_DEBUG2 - drawTrace(!bNormal, Vars::Colors::Local.Value, trace); +#ifdef SPLASH_DEBUG5 + s_mTraceCount[__FUNCTION__": point contents"]++; #endif + if (I::EngineTrace->GetPointContents(vPoint) & MASK_SOLID) + continue; + + if (tFace.m_iType == FaceTypeEnum::Prop) + vPoint += tFace.m_vNormal * DIST_EPSILON; + + SDK::Trace(vPoint + tFace.m_vNormal * tInfo.m_flNormalOffset, vTargetEye, MASK_SHOT, &filter, &trace); +#ifdef SPLASH_DEBUG5 + s_mTraceCount[__FUNCTION__": vispos"]++; +#endif +#ifdef SPLASH_DEBUG2 + DrawTrace(!trace.DidHit(), Vars::Colors::IndicatorMisc.Value, trace); +#endif + if (trace.fraction != 1.f) + continue; + + vPoints.push_back(vPoint); } - else // currently experimental, there may be a more efficient way to do this? - { - SDK::Trace(vPoint, vTargetEye, MASK_SOLID | CONTENTS_NOSKIP, &filter, &trace); -#ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash in 1"]++; -#endif - bNormal = trace.fraction == 1.f || !trace.fraction || trace.allsolid || trace.surface.flags & SURF_SKY; -#ifdef SPLASH_DEBUG2 - drawTrace(!bNormal, Vars::Colors::IndicatorMid.Value, trace); -#endif - if (!bNormal && trace.surface.flags & SURF_NODRAW) - { - if (bNormal = !(iType & PointTypeEnum::In2)) - goto breakOut; - - CGameTrace trace2 = {}; - SDK::Trace(trace.endpos - (vPoint - vTargetEye).Normalized(), vTargetEye, MASK_SOLID | CONTENTS_NOSKIP, &filter, &trace2); -#ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash in 2"]++; -#endif - bNormal = trace2.fraction == 1.f || !trace2.fraction || trace2.fraction == trace2.fractionleftsolid || trace2.allsolid || trace2.surface.flags & (SURF_NODRAW | SURF_SKY); -#ifdef SPLASH_DEBUG2 - drawTrace(!bNormal, Vars::Colors::IndicatorBad.Value, trace2); -#endif - if (!bNormal) - trace = trace2; - } - if (bNormal) - goto breakOut; - - if (checkPoint(trace, bErase, bNormal)) - { - SDK::Trace(trace.endpos + trace.plane.normal, vTargetEye, MASK_SHOT, &filter, &trace); -#ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash in rocket check"]++; -#endif -#ifdef SPLASH_DEBUG2 - drawTrace(!bNormal, Vars::Colors::IndicatorMisc.Value, trace); -#endif - if (trace.fraction < 1.f) - vPoints.pop_back(); - } - } - - breakOut: - if (vPoints.size() != iOriginalSize) - iType = 0; - else if (bErase || bNormal) - iType &= ~PointTypeEnum::In; - else - iType &= ~PointTypeEnum::Out; } } // possibly add air splash for autodet weapons -std::vector CAimbotProjectile::GetSplashPoints(Vec3 vOrigin, std::vector>& vSpherePoints, int iSimTime) +void CAimbotProjectile::SetupSplashPoints(Vec3& vOrigin, std::vector& vSplashPoints) +{ + vSplashPoints.clear(); + + CGameTrace trace = {}; + CTraceFilterWorldAndPropsOnly filter = {}; + + m_tInfo.m_pTarget->m_vPos = vOrigin; + Vec3 vTargetEye = vOrigin + m_tInfo.m_vTargetEye; + Vec3 vTargetCenter = vOrigin + m_tInfo.m_pTarget->m_pEntity->GetOffset() / 2; + float flRadius = m_tInfo.m_flRadius + m_tInfo.m_pTarget->m_pEntity->GetSize().Length() / 2; + + auto fCheckNormal = [&](const Vec3& vNormal, const Vec3& vPoint, Vec3* pAngle = nullptr) + { + 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); + vForward = (vShootPos - vPoint).Normalized(); + return vForward.Dot(vNormal) > 0; + } + else + { + Vec3 vForward = (m_tInfo.m_vLocalEye - vPoint).Normalized(); + return vForward.Dot(vNormal) > 0; + } + }; + + // Trace + int iPoints = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashPointsDirect.Value : Vars::Aimbot::Projectile::SplashPointsArc.Value; + { + auto vSpherePoints = ComputeSphere(flRadius, iPoints); + + auto fCheckPointTrace = [&]() + { + if (!trace.m_pEnt || trace.fraction == 1.f || trace.surface.flags & SURF_SKY || !trace.m_pEnt->GetAbsVelocity().IsZero()) + return false; + + Vec3 vPoint = trace.endpos, vAngle; + if (!m_tInfo.m_flGravity) + vAngle = Math::CalcAngle(m_tInfo.m_vLocalEye, trace.endpos); + else + { + Point_t tPoint = { vPoint, {} }; + CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, 0, tPoint.m_tSolution, CalculateFlagsEnum::None); + 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); + vAngle = Vec3(tPoint.m_tSolution.m_flPitch, tPoint.m_tSolution.m_flYaw); + } + return fCheckNormal(trace.plane.normal, vPoint, &vAngle); + }; + + for (int i = 0; i < vSpherePoints.size(); i++) + { + Vec3 vPoint = vSpherePoints[i] + vTargetCenter; + + Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, 0, tSolution, false); + if (tSolution.m_iCalculated == CalculateResultEnum::Bad) + continue; + + HandleTrace(vPoint, vSplashPoints, vTargetEye, m_tInfo, fCheckPointTrace, trace, filter); + } + } + + // 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) + { + Vec3 vMins = vTargetCenter - flRadius, vMaxs = vTargetCenter + flRadius; + + NormalValidCallback fNormalValid = [&](const std::vector& vVertices, const Vec3& vNormal) + { + 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); + else + { + Point_t tPoint = { vPoint, {} }; + CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, 0, tPoint.m_tSolution, CalculateFlagsEnum::None); + 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); + vAngle = Vec3(tPoint.m_tSolution.m_flPitch, tPoint.m_tSolution.m_flYaw); + } + return fCheckNormal(vNormal, vPoint, &vAngle); + }; + F::World.SetNormalValidCallback(&fNormalValid); + std::vector vFaces = F::World.GetFacesInAABB(vMins, vMaxs, MASK_SOLID, &filter); + F::World.SetNormalValidCallback(); +#ifdef SPLASH_DEBUG5 + SDK::Output("Faces", std::format("{}", vFaces.size()).c_str(), {}, OUTPUT_CONSOLE); +#endif + + float flCutoff = Vars::Aimbot::Projectile::SplashSamplesCutoff.Value * powf(vFaces.size(), 2); s_flTotal = SDK::RandomFloat(); + for (auto& tFace : vFaces) + { + HandleFace(tFace, vSplashPoints, flDensity, flRadius, flCutoff, vTargetEye, vTargetCenter, m_tInfo, trace, filter); + //#if defined(SPLASH_DEBUG2) && defined(WORLD_DEBUG) + // F::World.DrawFace(tFace, DrawTypeEnum::Edges | DrawTypeEnum::Faces); + //#endif + } + } + +#ifdef SPLASH_DEBUG3 + for (auto& vPoint : vSplashPoints) + G::BoxStorage.emplace_back(vPoint, Vec3::Get(-1), Vec3::Get(1), Vec3(), I::GlobalVars->curtime + 60.f, Vars::Colors::Local.Value, Color_t(0, 0, 0, 0)); +#endif +} + +std::vector CAimbotProjectile::GetSplashPoints(Vec3 vOrigin, std::vector& vSplashPoints, int iSimTime) { std::vector> vPointDistances = {}; + m_tInfo.m_pTarget->m_vPos = vOrigin; Vec3 vTargetEye = vOrigin + m_tInfo.m_vTargetEye; - auto checkPoint = [&](CGameTrace& trace, bool& bErase, bool& bNormal) - { - bErase = !trace.m_pEnt || trace.fraction == 1.f || trace.surface.flags & SURF_SKY || !trace.m_pEnt->GetAbsVelocity().IsZero(); - if (bErase) - return false; - - Point_t tPoint = { trace.endpos, {} }; - if (!m_tInfo.m_flGravity) - { - Vec3 vForward = (m_tInfo.m_vLocalEye - trace.endpos).Normalized(); - bNormal = vForward.Dot(trace.plane.normal) <= 0; - } - if (!bNormal) - { - CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, iSimTime, tPoint.m_tSolution, true, !m_tInfo.m_iArmTime ? 0 : -1); - if (m_tInfo.m_flGravity) - { - Vec3 vPos = m_tInfo.m_vLocalEye + Vec3(0, 0, (m_tInfo.m_flGravity * 800.f * pow(tPoint.m_tSolution.m_flTime, 2)) / 2); - Vec3 vForward = (vPos - tPoint.m_vPoint).Normalized(); - bNormal = vForward.Dot(trace.plane.normal) <= 0; - } - } - if (bNormal) - return false; - - bErase = tPoint.m_tSolution.m_iCalculated == CalculatedEnum::Good; - if (!bErase) - return false; - - vPointDistances.emplace_back(tPoint, tPoint.m_vPoint.DistTo(vOrigin)); - return true; - }; - - int i = 0; - for (auto it = vSpherePoints.begin(); it != vSpherePoints.end();) + for (auto it = vSplashPoints.begin(); it != vSplashPoints.end();) { - Vec3 vPoint = it->first + vTargetEye; - int& iType = it->second; - - Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, iSimTime, tSolution, false); - - if (tSolution.m_iCalculated == CalculatedEnum::Bad) - iType = 0; - else if (abs(tSolution.m_flTime - TICKS_TO_TIME(iSimTime)) < m_tInfo.m_flRadiusTime || m_tInfo.m_iArmTime && iSimTime == m_tInfo.m_iArmTime) - TracePoint(vPoint, iType, vTargetEye, m_tInfo, vPointDistances, checkPoint, i++); - - if (!(iType & ~PointTypeEnum::In2)) - it = vSpherePoints.erase(it); - else + Point_t tPoint = { *it, {} }; + CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, iSimTime, tPoint.m_tSolution, CalculateFlagsEnum::Accuracy, !m_tInfo.m_iArmTime ? 0 : -1); + if (tPoint.m_tSolution.m_iCalculated != CalculateResultEnum::Good) + { ++it; - } - - std::sort(vPointDistances.begin(), vPointDistances.end(), [&](const auto& a, const auto& b) -> bool - { - return a.second < b.second; - }); - - std::vector vPoints = {}; - int iSplashCount = std::min( - m_tInfo.m_iArmTime && iSimTime == m_tInfo.m_iArmTime ? Vars::Aimbot::Projectile::SplashCountDirect.Value : m_tInfo.m_iSplashCount, - int(vPointDistances.size()) - ); - for (int i = 0; i < iSplashCount; i++) - vPoints.push_back(vPointDistances[i].first); - - const Vec3 vOriginal = m_tInfo.m_pTarget->m_pEntity->GetAbsOrigin(); - m_tInfo.m_pTarget->m_pEntity->SetAbsOrigin(vOrigin); - for (auto it = vPoints.begin(); it != vPoints.end();) - { - auto& tPoint = *it; - bool bValid = tPoint.m_tSolution.m_iCalculated != CalculatedEnum::Pending; - if (bValid) - { - Vec3 vPos; m_tInfo.m_pTarget->m_pEntity->m_Collision()->CalcNearestPoint(tPoint.m_vPoint, &vPos); - bValid = tPoint.m_vPoint.DistTo(vPos) < m_tInfo.m_flRadius; + continue; } - if (bValid) - ++it; - else - it = vPoints.erase(it); - } - m_tInfo.m_pTarget->m_pEntity->SetAbsOrigin(vOriginal); - - return vPoints; -} - -void CAimbotProjectile::SetupSplashPoints(Vec3& vPos, std::vector>& vSpherePoints, std::vector& vSimplePoints) -{ - vSimplePoints.clear(); - Vec3 vTargetEye = vPos + m_tInfo.m_vTargetEye; - - auto checkPoint = [&](CGameTrace& trace, bool& bErase, bool& bNormal) - { - bErase = !trace.m_pEnt || trace.fraction == 1.f || trace.surface.flags & SURF_SKY || !trace.m_pEnt->GetAbsVelocity().IsZero(); - if (bErase) - return false; - - Point_t tPoint = { trace.endpos, {} }; - if (!m_tInfo.m_flGravity) - { - Vec3 vForward = (m_tInfo.m_vLocalEye - trace.endpos).Normalized(); - bNormal = vForward.Dot(trace.plane.normal) <= 0; - } - if (!bNormal) - { - CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, 0, tPoint.m_tSolution, false); - if (m_tInfo.m_flGravity) - { - Vec3 vPos = m_tInfo.m_vLocalEye + Vec3(0, 0, (m_tInfo.m_flGravity * 800.f * pow(tPoint.m_tSolution.m_flTime, 2)) / 2); - Vec3 vForward = (vPos - tPoint.m_vPoint).Normalized(); - bNormal = vForward.Dot(trace.plane.normal) <= 0; - } - } - if (bNormal) - return false; - - if (tPoint.m_tSolution.m_iCalculated != CalculatedEnum::Bad) - { - vSimplePoints.emplace_back(tPoint.m_vPoint); - return true; - } - return false; - }; - - int i = 0; - for (auto& vSpherePoint : vSpherePoints) - { - Vec3 vPoint = vSpherePoint.first + vTargetEye; - int& iType = vSpherePoint.second; - - Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, 0, tSolution, false); - - if (tSolution.m_iCalculated != CalculatedEnum::Bad) - TracePoint(vPoint, iType, vTargetEye, m_tInfo, vSimplePoints, checkPoint, i++); - } -} - -std::vector CAimbotProjectile::GetSplashPointsSimple(Vec3 vOrigin, std::vector& vSpherePoints, int iSimTime) -{ - std::vector> vPointDistances = {}; - - Vec3 vTargetEye = vOrigin + m_tInfo.m_vTargetEye; - - auto checkPoint = [&](Vec3& vPoint, bool& bErase) - { - Point_t tPoint = { vPoint, {} }; - CalculateAngle(m_tInfo.m_vLocalEye, tPoint.m_vPoint, iSimTime, tPoint.m_tSolution, true, !m_tInfo.m_iArmTime ? 0 : -1); - - bErase = tPoint.m_tSolution.m_iCalculated == CalculatedEnum::Good; - if (!bErase) - return false; - - vPointDistances.emplace_back(tPoint, tPoint.m_vPoint.DistTo(vOrigin)); - return true; - }; - for (auto it = vSpherePoints.begin(); it != vSpherePoints.end();) - { - bool bErase = false; - - checkPoint(*it, bErase); - - if (bErase) - it = vSpherePoints.erase(it); - else - ++it; + vPointDistances.emplace_back(tPoint, tPoint.m_vPoint.DistToSqr(vOrigin)); + it = vSplashPoints.erase(it); } std::sort(vPointDistances.begin(), vPointDistances.end(), [&](const auto& a, const auto& b) -> bool @@ -808,7 +663,7 @@ std::vector CAimbotProjectile::GetSplashPointsSimple(Vec3 vOrigin, std: for (auto it = vPoints.begin(); it != vPoints.end();) { auto& tPoint = *it; - bool bValid = tPoint.m_tSolution.m_iCalculated != CalculatedEnum::Pending; + bool bValid = tPoint.m_tSolution.m_iCalculated != CalculateResultEnum::Pending; if (bValid) { Vec3 vPos = {}; m_tInfo.m_pTarget->m_pEntity->m_Collision()->CalcNearestPoint(tPoint.m_vPoint, &vPos); @@ -844,9 +699,9 @@ static inline float AABBLine(Vec3 vMins, Vec3 vMaxs, Vec3 vStart, Vec3 vDir) }; return std::max(std::max(c.x, c.y), c.z); } -static inline Vec3 PullPoint(Vec3 vPoint, Vec3 vLocalPos, Info_t& tInfo, Vec3 vMins, Vec3 vMaxs, Vec3 vTargetPos) +static inline Vec3 PullPoint(const Vec3& vPoint, Vec3 vLocalPos, Info_t& tInfo, const Vec3& vMins, const Vec3& vMaxs, const Vec3& vTargetPos) { - auto HeightenLocalPos = [&]() + auto fHeightenLocalPos = [&]() { // basic trajectory pass const float flGrav = tInfo.m_flGravity * 800.f; if (!flGrav) @@ -864,7 +719,7 @@ static inline Vec3 PullPoint(Vec3 vPoint, Vec3 vLocalPos, Info_t& tInfo, Vec3 vM return vLocalPos + Vec3(0, 0, (flGrav * pow(flTime, 2)) / 2); }; - vLocalPos = HeightenLocalPos(); + vLocalPos = fHeightenLocalPos(); Vec3 vForward, vRight, vUp; Math::AngleVectors(Math::CalcAngle(vLocalPos, vPoint), &vForward, &vRight, &vUp); vLocalPos += (vForward * tInfo.m_vOffset.x) + (vRight * tInfo.m_vOffset.y) + (vUp * tInfo.m_vOffset.z); return vLocalPos + (vPoint - vLocalPos) * fabsf(AABBLine(vMins + vTargetPos, vMaxs + vTargetPos, vLocalPos, vPoint - vLocalPos)); @@ -930,9 +785,9 @@ static inline void SolveProjectileSpeed(CTFWeaponBase* pWeapon, const Vec3& vLoc flDragTime = powf(flTime, 2) * flDrag / (flOverride ? flOverride : 1.5f); // rough estimate to prevent m_flTime being too low flVelocity = flVelocity - flVelocity * flTime * flDrag; } -void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, bool bAccuracy, int iTolerance) +void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, int iFlags, int iTolerance) { - if (tOut.m_iCalculated != CalculatedEnum::Pending) + if (tOut.m_iCalculated != CalculateResultEnum::Pending) return; const float flGrav = m_tInfo.m_flGravity * 800.f; @@ -940,7 +795,7 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge float flPitch, flYaw; { // basic trajectory pass float flVelocity = m_tInfo.m_flVelocity, flDragTime = 0.f; - if (F::ProjSim.m_pObj->IsDragEnabled() && !F::ProjSim.m_pObj->m_dragBasis.IsZero() && m_tInfo.m_pWeapon) + 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); @@ -956,7 +811,7 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge 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 ? CalculatedEnum::Bad : CalculatedEnum::Pending) + if (tOut.m_iCalculated = flRoot < 0.f ? CalculateResultEnum::Bad : CalculateResultEnum::Pending) return; flPitch = atan((pow(flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist)); } @@ -967,25 +822,22 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge int iTimeTo = ceilf(tOut.m_flTime / TICK_INTERVAL); bool bGood = iTolerance != -1 ? abs(iTimeTo - iSimTime) <= iTolerance : iTimeTo <= iSimTime; - if (!m_tInfo.m_vOffset.IsZero()) + if (!(iFlags & CalculateFlagsEnum::TwoPass) || m_tInfo.m_vOffset.IsZero()) { - if (tOut.m_iCalculated = bGood ? CalculatedEnum::Pending : CalculatedEnum::Time) - return; - } - else - { - tOut.m_iCalculated = bGood ? CalculatedEnum::Pending : CalculatedEnum::Time; + tOut.m_iCalculated = bGood ? CalculateResultEnum::Good : CalculateResultEnum::Time; return; } + else if (tOut.m_iCalculated = bGood ? CalculateResultEnum::Pending : CalculateResultEnum::Time) + return; - int iFlags = (bAccuracy ? ProjSimEnum::Redirect : ProjSimEnum::None) | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum; + int iSimFlags = (iFlags & CalculateFlagsEnum::SetupClip ? ProjSimEnum::Redirect : ProjSimEnum::None) | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum; #ifdef SPLASH_DEBUG5 - if (iFlags & ProjSimEnum::Redirect) + if (iSimFlags & ProjSimEnum::Redirect) { if (Vars::Visuals::Trajectory::Override.Value) { if (!Vars::Visuals::Trajectory::Pipes.Value) - s_mTraceCount["Setup trace calculate"]++; + s_mTraceCount[__FUNCTION__": setup trace"]++; } else { @@ -1003,18 +855,19 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge case TF_WEAPON_SHOTGUN_BUILDING_RESCUE: case TF_WEAPON_SYRINGEGUN_MEDIC: case TF_WEAPON_FLAME_BALL: - s_mTraceCount["Setup trace calculate"]++; + s_mTraceCount[__FUNCTION__": setup trace"]++; } } } #endif m_tProjInfo = {}; - if (tOut.m_iCalculated = !F::ProjSim.GetInfo(m_tInfo.m_pLocal, m_tInfo.m_pWeapon, { flPitch, flYaw, 0 }, m_tProjInfo, iFlags) ? CalculatedEnum::Bad : CalculatedEnum::Pending) + 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) return; { // calculate trajectory from projectile origin float flVelocity = m_tInfo.m_flVelocity, flDragTime = 0.f; - SolveProjectileSpeed(m_tInfo.m_pWeapon, m_tProjInfo.m_vPos, vTargetPos, flVelocity, flDragTime, m_tInfo.m_flGravity); + 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(); @@ -1025,7 +878,7 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge 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 ? CalculatedEnum::Bad : CalculatedEnum::Pending) + if (tOut.m_iCalculated = flRoot < 0.f ? CalculateResultEnum::Bad : CalculateResultEnum::Pending) return; tOut.m_flPitch = atan((pow(flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist)); } @@ -1071,7 +924,7 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge iTimeTo = ceilf(tOut.m_flTime / TICK_INTERVAL); bGood = iTolerance != -1 ? abs(iTimeTo - iSimTime) <= iTolerance : iTimeTo <= iSimTime; - tOut.m_iCalculated = bGood ? CalculatedEnum::Good : CalculatedEnum::Time; + tOut.m_iCalculated = bGood ? CalculateResultEnum::Good : CalculateResultEnum::Time; } @@ -1082,12 +935,12 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i auto pWeapon = m_tInfo.m_pWeapon; auto& tTarget = *m_tInfo.m_pTarget; - int iFlags = ProjSimEnum::Redirect | ProjSimEnum::InitCheck | ProjSimEnum::NoRandomAngles | ProjSimEnum::PredictCmdNum; + 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) - s_mTraceCount["Setup trace test"]++; + s_mTraceCount[__FUNCTION__": setup trace"]++; } else { @@ -1105,13 +958,13 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i case TF_WEAPON_SHOTGUN_BUILDING_RESCUE: case TF_WEAPON_SYRINGEGUN_MEDIC: case TF_WEAPON_FLAME_BALL: - s_mTraceCount["Setup trace"]++; + s_mTraceCount[__FUNCTION__": setup trace"]++; } } - s_mTraceCount["Trace init check"]++; + s_mTraceCount[__FUNCTION__": setup clip"]++; #endif m_tProjInfo = {}; - if (!F::ProjSim.GetInfo(pLocal, pWeapon, vAngles, m_tProjInfo, iFlags) + if (!F::ProjSim.GetInfo(pLocal, pWeapon, vAngles, m_tProjInfo, iSimFlags) || !F::ProjSim.Initialize(m_tProjInfo)) return false; @@ -1138,14 +991,14 @@ 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 * -1, 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(255, 0, 0), Color_t(0, 0, 0, 0)); #endif if (!m_tProjInfo.m_flGravity) { - SDK::TraceHull(m_tProjInfo.m_vPos, vPoint, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(m_tProjInfo.m_vPos, vPoint, -m_tProjInfo.m_vHull, m_tProjInfo.m_vHull, nMask, &filter, &trace); #ifdef SPLASH_DEBUG5 - s_mTraceCount["Nograv trace"]++; + s_mTraceCount[__FUNCTION__": nograv trace"]++; #endif #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)); @@ -1154,6 +1007,10 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i return false; } +#ifdef SPLASH_DEBUG4 + G::BoxStorage.pop_back(); +#endif + bool bDidHit = false, bArmTime = false; const RestoreInfo_t tOriginal = { tTarget.m_pEntity->GetAbsOrigin(), tTarget.m_pEntity->m_vecMins(), tTarget.m_pEntity->m_vecMaxs() }; tTarget.m_pEntity->SetAbsOrigin(tTarget.m_vPos); @@ -1173,9 +1030,9 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i if (!bSplash) { - SDK::TraceHull(vOld, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(vOld, vNew, -m_tProjInfo.m_vHull, m_tProjInfo.m_vHull, nMask, &filter, &trace); #ifdef SPLASH_DEBUG5 - s_mTraceCount["Direct trace"]++; + s_mTraceCount[__FUNCTION__": direct trace"]++; #endif #ifdef SPLASH_DEBUG4 G::LineStorage.emplace_back(std::pair(vOld, trace.endpos), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 0)); @@ -1189,9 +1046,9 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i if (n % Vars::Aimbot::Projectile::SplashTraceInterval.Value && n != iSimTime && !bArmTime) continue; - SDK::TraceHull(vStaticPos, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(vStaticPos, vNew, -m_tProjInfo.m_vHull, m_tProjInfo.m_vHull, nMask, &filter, &trace); #ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash trace"]++; + s_mTraceCount[__FUNCTION__": splash trace"]++; #endif #ifdef SPLASH_DEBUG4 G::LineStorage.emplace_back(std::pair(vStaticPos, trace.endpos), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 0)); @@ -1207,49 +1064,30 @@ bool CAimbotProjectile::TestAngle(const Vec3& vPoint, const Vec3& vAngles, int i bool bValid = bTarget && bTime; if (bValid && bSplash) { - bValid = (trace.endpos - vPoint).IsZero(0.01f) || SDK::VisPosWorld(nullptr, tTarget.m_pEntity, trace.endpos, vPoint, nMask); + CGameTrace eyeTrace = {}; + SDK::Trace(trace.endpos + m_tInfo.m_flNormalOffset * trace.plane.normal, tTarget.m_vPos + m_tInfo.m_vTargetEye, MASK_SHOT, &filter, &eyeTrace); + bValid = eyeTrace.fraction == 1.f; #ifdef SPLASH_DEBUG5 - s_mTraceCount["Splash vispos"]++; + s_mTraceCount[__FUNCTION__": splash eye trace"]++; #endif #ifdef SPLASH_DEBUG4 - G::LineStorage.emplace_back(std::pair(trace.endpos, vPoint), I::GlobalVars->curtime + 5.f, Color_t(0, 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 - if (bValid) - { - Vec3 vFrom = trace.endpos; - switch (pWeapon->GetWeaponID()) - { - case TF_WEAPON_ROCKETLAUNCHER: - case TF_WEAPON_ROCKETLAUNCHER_DIRECTHIT: - case TF_WEAPON_PARTICLE_CANNON: - vFrom += trace.plane.normal; - } - - CGameTrace eyeTrace = {}; - SDK::Trace(vFrom, tTarget.m_vPos + m_tInfo.m_vTargetEye, MASK_SHOT, &filter, &eyeTrace); - bValid = eyeTrace.fraction == 1.f; -#ifdef SPLASH_DEBUG5 - s_mTraceCount["Eye trace"]++; -#endif -#ifdef SPLASH_DEBUG4 - G::LineStorage.emplace_back(std::pair(vFrom, trace.endpos), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 255)); -#endif - } } #ifdef SPLASH_DEBUG4 - G::BoxStorage.pop_back(); if (bValid) - G::BoxStorage.emplace_back(vPoint, vHull * -1, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 255, 0), Color_t(0, 0, 0, 0)); + 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 (bTime) - G::BoxStorage.emplace_back(vPoint, vHull * -1, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 255), Color_t(0, 0, 0, 0)); + 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 * -1, vHull, Vec3(), I::GlobalVars->curtime + 5.f, Color_t(255, 0, 255), Color_t(0, 0, 0, 0)); + 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 (bSplash) { - G::BoxStorage.emplace_back(trace.endpos, Vec3(-1, -1, -1), Vec3(1, 1, 1), Vec3(), I::GlobalVars->curtime + 5.f, Color_t(0, 0, 0), Color_t(0, 0, 0, 0)); - G::BoxStorage.emplace_back(vPoint, Vec3(-1, -1, -1), Vec3(1, 1, 1), Vec3(), I::GlobalVars->curtime + 5.f, Color_t(255, 255, 255), Color_t(0, 0, 0, 0)); + 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)); } } #endif @@ -1331,9 +1169,8 @@ bool CAimbotProjectile::HandlePoint(const Vec3& vOrigin, int iSimTime, float flP bool bReturn = false; Vec3 vAngles; Aim(G::CurrentUserCmd->viewangles, { flPitch, flYaw, 0.f }, vAngles); - - const Vec3 vOriginal = m_tInfo.m_pTarget->m_vPos; m_tInfo.m_pTarget->m_vPos = vOrigin; + if (!m_tInfo.m_pProjectile ? TestAngle(vPoint, vAngles, iSimTime, bSplash) : TestAngle(m_tInfo.m_pProjectile, vPoint, vAngles, iSimTime, bSplash)) @@ -1357,7 +1194,6 @@ bool CAimbotProjectile::HandlePoint(const Vec3& vOrigin, int iSimTime, float flP } } } - m_tInfo.m_pTarget->m_vPos = vOriginal; if (bReturn) { @@ -1404,23 +1240,9 @@ bool CAimbotProjectile::HandleSplash(std::vector& vSplashHistory) { return a.m_flTimeTo < b.m_flTimeTo; }); - - float flSize = m_tInfo.m_pTarget->m_pEntity->GetSize().Length(); - int iPoints = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashPointsDirect.Value : Vars::Aimbot::Projectile::SplashPointsArc.Value; - auto vSpherePoints = ComputeSphere(m_tInfo.m_flRadius + flSize, iPoints); -#ifdef SPLASH_DEBUG3 - for (auto& [vPoint, _] : vSpherePoints) - G::BoxStorage.emplace_back(vSplashHistory.front().m_vOrigin + m_tInfo.m_vTargetEye + vPoint, Vec3(-1, -1, -1), Vec3(1, 1, 1), Vec3(), I::GlobalVars->curtime + 60.f, Color_t(0, 0, 0, 0), Vars::Colors::Local.Value); -#endif - - int iMulti = Vars::Aimbot::Projectile::SplashMode.Value; - static std::vector vSimplePoints = {}; - if (iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Single) - { - SetupSplashPoints(vSplashHistory.front().m_vOrigin, vSpherePoints, vSimplePoints); - if (vSimplePoints.empty()) - return false; - } + SetupSplashPoints(vSplashHistory.front().m_vOrigin, m_vSplashPoints); + if (m_vSplashPoints.empty()) + return false; float flLowestDistance = std::numeric_limits::max(); for (auto& tHistory : vSplashHistory) @@ -1429,10 +1251,7 @@ bool CAimbotProjectile::HandleSplash(std::vector& vSplashHistory) continue; std::vector vSplashPoints = {}; - if (iMulti == Vars::Aimbot::Projectile::SplashModeEnum::Multi) - vSplashPoints = GetSplashPoints(tHistory.m_vOrigin, vSpherePoints, tHistory.m_iSimtime); - else - vSplashPoints = GetSplashPointsSimple(tHistory.m_vOrigin, vSimplePoints, tHistory.m_iSimtime); + vSplashPoints = GetSplashPoints(tHistory.m_vOrigin, m_vSplashPoints, tHistory.m_iSimtime); for (auto& tPoint : vSplashPoints) { @@ -1475,15 +1294,19 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas m_tInfo.m_vOffset = m_tProjInfo.m_vPos - m_tInfo.m_vLocalEye; m_tInfo.m_vOffset.y *= -1; m_tInfo.m_flOffsetTime = m_tInfo.m_vOffset.Length() / m_tInfo.m_flVelocity; // silly - float flSize = tTarget.m_pEntity->GetSize().Length(); m_tInfo.m_flGravity = m_tProjInfo.m_flGravity; m_tInfo.m_iSplashCount = !m_tInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashCountDirect.Value : Vars::Aimbot::Projectile::SplashCountArc.Value; m_tInfo.m_flRadius = GetSplashRadius(pWeapon, pLocal); m_tInfo.m_flRadiusTime = m_tInfo.m_flRadius / m_tInfo.m_flVelocity; - m_tInfo.m_flBoundingTime = m_tInfo.m_flRadiusTime + flSize / m_tInfo.m_flVelocity; - - m_tInfo.m_iSplashMode = GetSplashMode(pWeapon); + m_tInfo.m_flBoundingTime = m_tInfo.m_flRadiusTime + tTarget.m_pEntity->GetSize().Length() / m_tInfo.m_flVelocity; m_tInfo.m_iArmTime = TIME_TO_TICKS(ArmTime(pWeapon)); + switch (pWeapon->GetWeaponID()) + { + case TF_WEAPON_ROCKETLAUNCHER: + case TF_WEAPON_ROCKETLAUNCHER_DIRECTHIT: + case TF_WEAPON_PARTICLE_CANNON: + m_tInfo.m_flNormalOffset = 1.f; + } @@ -1508,8 +1331,8 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas bool bDirectBreaks = true; if (iSplash) { - Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, false); - if (tSolution.m_iCalculated != CalculatedEnum::Bad) + 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); @@ -1536,12 +1359,12 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, i, tSolution); switch (tSolution.m_iCalculated) { - case CalculatedEnum::Good: + 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); [[fallthrough]]; - case CalculatedEnum::Bad: + case CalculateResultEnum::Bad: mDirectPoints.erase(iIndex); } } @@ -1577,7 +1400,6 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas if (bVisuals && bAny && (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a || Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a)) { - m_tInfo.m_vHull = m_tInfo.m_vHull.Max(1); float flProjectileTime = TICKS_TO_TIME(m_vProjectilePath.size()); float flTargetTime = m_tMoveStorage.m_bFailed ? flProjectileTime : TICKS_TO_TIME(m_vPlayerPath.size()); @@ -1593,9 +1415,9 @@ int CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBas if (bMain && bPoint) { if (Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a) - m_vBoxes.emplace_back(m_vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); + m_vBoxes.emplace_back(m_vTarget, Vec3::Get(-1), Vec3::Get(1), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); if (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a) - m_vBoxes.emplace_back(m_vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); + m_vBoxes.emplace_back(m_vTarget, Vec3::Get(-1), Vec3::Get(1), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); } } } @@ -1783,6 +1605,9 @@ bool CAimbotProjectile::RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser #endif #if defined(SPLASH_DEBUG1) || defined(SPLASH_DEBUG2) || defined(SPLASH_DEBUG3) || defined(SPLASH_DEBUG4) G::BoxStorage.clear(); +#endif +#if defined(SPLASH_DEBUG2) && defined(WORLD_DEBUG) + G::TriangleStorage.clear(); #endif for (auto& tTarget : vTargets) { @@ -1917,7 +1742,7 @@ void CAimbotProjectile::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* if (Vars::Aimbot::General::AimType.Value && !s_mTraceCount.empty()) { int iTraceCount = 0; - for (auto& [_, iTraces] : s_mTraceCount) + for (auto& iTraces : s_mTraceCount | std::views::values) iTraceCount += iTraces; SDK::Output("Traces", std::format("{}", iTraceCount).c_str()); for (auto& [sType, iTraces] : s_mTraceCount) @@ -1999,7 +1824,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 * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); + 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) return false; } @@ -2022,7 +1847,7 @@ bool CAimbotProjectile::TestAngle(CBaseEntity* pProjectile, const Vec3& vPoint, } if (!bSplash) - SDK::TraceHull(vOld, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(vOld, vNew, -m_tProjInfo.m_vHull, m_tProjInfo.m_vHull, nMask, &filter, &trace); else { static Vec3 vStaticPos = {}; @@ -2031,7 +1856,7 @@ bool CAimbotProjectile::TestAngle(CBaseEntity* pProjectile, const Vec3& vPoint, if (n % Vars::Aimbot::Projectile::SplashTraceInterval.Value && n != iSimTime) continue; - SDK::TraceHull(vStaticPos, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(vStaticPos, vNew, -m_tProjInfo.m_vHull, m_tProjInfo.m_vHull, nMask, &filter, &trace); vStaticPos = vNew; } if (trace.DidHit()) @@ -2115,7 +1940,7 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa F::ProjSim.RunTick(m_tProjInfo); Vec3 vNew = F::ProjSim.GetOrigin(); - SDK::TraceHull(vOld, vNew, m_tProjInfo.m_vHull * -1, m_tProjInfo.m_vHull, MASK_SOLID, &filter, &trace); + SDK::TraceHull(vOld, vNew, -m_tProjInfo.m_vHull, m_tProjInfo.m_vHull, MASK_SOLID, &filter, &trace); m_tProjInfo.m_vPos = trace.endpos; } m_tInfo.m_vLocalEye = m_tProjInfo.m_vPos; // just assume from the projectile without any offset, check validity later @@ -2156,8 +1981,8 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa bool bDirectBreaks = true; if (iSplash) { - Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, tTarget.m_vPos, i, tSolution, false); - if (tSolution.m_iCalculated != CalculatedEnum::Bad) + 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); @@ -2184,10 +2009,10 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa Solution_t tSolution; CalculateAngle(m_tInfo.m_vLocalEye, vPoint, i, tSolution); switch (tSolution.m_iCalculated) { - case CalculatedEnum::Good: + case CalculateResultEnum::Good: vDirectHistory.emplace_back(History_t(tTarget.m_vPos, i), tSolution.m_flPitch, tSolution.m_flYaw, tSolution.m_flTime, vPoint, iIndex); [[fallthrough]]; - case CalculatedEnum::Bad: + case CalculateResultEnum::Bad: mDirectPoints.erase(iIndex); } } @@ -2224,7 +2049,6 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa { if (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a || Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a) { - m_tInfo.m_vHull = m_tInfo.m_vHull.Max(1); float flProjectileTime = TICKS_TO_TIME(m_vProjectilePath.size()); float flTargetTime = m_tMoveStorage.m_bFailed ? flProjectileTime : TICKS_TO_TIME(m_vPlayerPath.size()); @@ -2240,9 +2064,9 @@ bool CAimbotProjectile::CanHit(Target_t& tTarget, CTFPlayer* pLocal, CTFWeaponBa if (bPoint) { if (Vars::Colors::BoundHitboxEdgeIgnoreZ.Value.a || Vars::Colors::BoundHitboxFaceIgnoreZ.Value.a) - m_vBoxes.emplace_back(m_vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); + m_vBoxes.emplace_back(m_vTarget, Vec3::Get(-1), Vec3::Get(1), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdgeIgnoreZ.Value, Vars::Colors::BoundHitboxFaceIgnoreZ.Value); if (Vars::Colors::BoundHitboxEdge.Value.a || Vars::Colors::BoundHitboxFace.Value.a) - m_vBoxes.emplace_back(m_vTarget, m_tInfo.m_vHull * -1, m_tInfo.m_vHull, Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); + m_vBoxes.emplace_back(m_vTarget, Vec3::Get(-1), Vec3::Get(1), Vec3(), I::GlobalVars->curtime + (Vars::Visuals::Simulation::Timed.Value ? flProjectileTime : Vars::Visuals::Hitbox::DrawDuration.Value), Vars::Colors::BoundHitboxEdge.Value, Vars::Colors::BoundHitboxFace.Value, true); } } } diff --git a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h index 592f81ae..8985a447 100644 --- a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h +++ b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.h @@ -5,8 +5,8 @@ #include "../../Simulation/MovementSimulation/MovementSimulation.h" #include "../../Simulation/ProjectileSimulation/ProjectileSimulation.h" -Enum(PointType, None = 0, Out = 1 << 0, In = 1 << 1, Out2 = 1 << 2, In2 = 1 << 3) -Enum(Calculated, Pending, Good, Time, Bad) +Enum(CalculateFlags, None = 0, TwoPass = 1 << 0, SetupClip = 1 << 1, AccountDrag = 1 << 2, Accuracy = TwoPass | SetupClip | AccountDrag) +Enum(CalculateResult, Pending, Good, Time, Bad) struct Info_t { @@ -19,7 +19,6 @@ struct Info_t Vec3 m_vTargetEye = {}; float m_flLatency = 0.f; - Vec3 m_vHull = {}; Vec3 m_vOffset = {}; Vec3 m_vAngFix = {}; @@ -30,8 +29,8 @@ struct Info_t float m_flBoundingTime = 0.f; float m_flOffsetTime = 0.f; int m_iSplashCount = 0; - int m_iSplashMode = 0; int m_iArmTime = 0; + float m_flNormalOffset = 0.f; }; struct Solution_t @@ -39,7 +38,7 @@ struct Solution_t float m_flPitch = 0.f; float m_flYaw = 0.f; float m_flTime = 0.f; - int m_iCalculated = CalculatedEnum::Pending; + int m_iCalculated = CalculateResultEnum::Pending; }; struct Point_t { @@ -69,11 +68,10 @@ class CAimbotProjectile { private: std::unordered_map GetDirectPoints(); - std::vector GetSplashPoints(Vec3 vOrigin, std::vector>& vSpherePoints, int iSimTime); - void SetupSplashPoints(Vec3& vPos, std::vector>& vSpherePoints, std::vector& vSimplePoints); - std::vector GetSplashPointsSimple(Vec3 vOrigin, std::vector& vSpherePoints, int iSimTime); + void SetupSplashPoints(Vec3& vOrigin, std::vector& vSplashPoints); + std::vector GetSplashPoints(Vec3 vOrigin, std::vector& vSplashPoints, int iSimTime); - void CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, bool bAccuracy = true, int iTolerance = -1); + void CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, int iSimTime, Solution_t& tOut, int 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); @@ -92,6 +90,7 @@ private: Info_t m_tInfo = {}; MoveStorage m_tMoveStorage = {}; ProjectileInfo m_tProjInfo = {}; + std::vector m_vSplashPoints = {}; bool m_bLastTickHeld = false; diff --git a/Amalgam/src/Features/Aimbot/AutoHeal/AutoHeal.cpp b/Amalgam/src/Features/Aimbot/AutoHeal/AutoHeal.cpp index 8c90e6f5..ce667c8e 100644 --- a/Amalgam/src/Features/Aimbot/AutoHeal/AutoHeal.cpp +++ b/Amalgam/src/Features/Aimbot/AutoHeal/AutoHeal.cpp @@ -295,16 +295,16 @@ void CAutoHeal::GetDangers(CTFPlayer* pTarget, bool bVaccinator, float& flBullet bool bClassic = nWeaponID == TF_WEAPON_SNIPERRIFLE_CLASSIC; bool bHeadshot = pWeapon->As()->GetRifleType() != RIFLE_JARATE; bool bPiss = SDK::AttribHookValue(0, "jarate_duration", pWeapon) > 0; - auto GetSniperDot = [](CBaseEntity* pEntity) -> CSniperDot* + auto fGetSniperDot = [](CBaseEntity* pEntity) -> CSniperDot* + { + for (auto pDot : H::Entities.GetGroup(EntityEnum::SniperDots)) { - for (auto pDot : H::Entities.GetGroup(EntityEnum::SniperDots)) - { - if (pDot->m_hOwnerEntity().Get() == pEntity) - return pDot->As(); - } - return nullptr; - }; - if (CSniperDot* pPlayerDot = GetSniperDot(pEntity)) + if (pDot->m_hOwnerEntity().Get() == pEntity) + return pDot->As(); + } + return nullptr; + }; + if (CSniperDot* pPlayerDot = fGetSniperDot(pEntity)) { float flChargeTime = std::max(SDK::AttribHookValue(3.f, "mult_sniper_charge_per_sec", pWeapon), 1.5f); flDamage = Math::RemapVal(TICKS_TO_TIME(I::ClientState->m_ClockDriftMgr.m_nServerTick) - pPlayerDot->m_flChargeStartTime() - 0.3f, 0.f, flChargeTime, 50.f, 150.f); @@ -596,9 +596,9 @@ void CAutoHeal::AutoVaccinator(CTFPlayer* pLocal, CWeaponMedigun* pWeapon, CUser for (auto pTarget : vTargets) GetDangers(pTarget, true, vResistDangers[MEDIGUN_BULLET_RESIST].first, vResistDangers[MEDIGUN_BLAST_RESIST].first, vResistDangers[MEDIGUN_FIRE_RESIST].first); std::sort(vResistDangers.begin(), vResistDangers.end(), [&](const std::pair& a, const std::pair& b) -> bool - { - return a.first > b.first; - }); + { + return a.first > b.first; + }); int iTargetResist = vResistDangers.front().second; float flTargetDanger = vResistDangers.front().first; diff --git a/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp b/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp index dedfca0d..899f3e8b 100644 --- a/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp +++ b/Amalgam/src/Features/Aimbot/AutoRocketJump/AutoRocketJump.cpp @@ -167,17 +167,17 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p if (!pLocal->IsOnGround() || pLocal->IsSwimming()) break; - auto WillHit = [](CTFPlayer* pLocal, const Vec3& vOrigin, const Vec3& vPoint) - { - const Vec3 vOriginal = pLocal->GetAbsOrigin(); - pLocal->SetAbsOrigin(vOrigin); - Vec3 vPos; pLocal->m_Collision()->CalcNearestPoint(vPoint, &vPos); - pLocal->SetAbsOrigin(vOriginal); + auto fWillHit = [](CTFPlayer* pLocal, const Vec3& vOrigin, const Vec3& vPoint) + { + const Vec3 vOriginal = pLocal->GetAbsOrigin(); + pLocal->SetAbsOrigin(vOrigin); + Vec3 vPos; pLocal->m_Collision()->CalcNearestPoint(vPoint, &vPos); + pLocal->SetAbsOrigin(vOriginal); - return vPoint.DistTo(vPos) < TF_ROCKET_RADIUS_FOR_RJS && SDK::VisPosWorld(pLocal, pLocal, vPoint, vOrigin + pLocal->m_vecViewOffset(), MASK_SHOT); - }; + return vPoint.DistTo(vPos) < TF_ROCKET_RADIUS_FOR_RJS && SDK::VisPosWorld(pLocal, pLocal, vPoint, vOrigin + pLocal->m_vecViewOffset(), MASK_SHOT); + }; - bWillHit = WillHit(pLocal, tMoveStorage.m_MoveData.m_vecAbsOrigin, trace.endpos + trace.plane.normal); + bWillHit = fWillHit(pLocal, tMoveStorage.m_MoveData.m_vecAbsOrigin, trace.endpos + trace.plane.normal); if (bWillHit) { m_iDelay = n; diff --git a/Amalgam/src/Features/Backtrack/Backtrack.cpp b/Amalgam/src/Features/Backtrack/Backtrack.cpp index 153e47da..6386804a 100644 --- a/Amalgam/src/Features/Backtrack/Backtrack.cpp +++ b/Amalgam/src/Features/Backtrack/Backtrack.cpp @@ -180,23 +180,23 @@ std::vector CBacktrack::GetValidRecords(std::vector& v { if (bDistance) std::sort(vReturn.begin(), vReturn.end(), [&](const TickRecord* a, const TickRecord* b) -> bool - { - if (Vars::Backtrack::PreferOnShot.Value && a->m_bOnShot != b->m_bOnShot) - return a->m_bOnShot > b->m_bOnShot; + { + if (Vars::Backtrack::PreferOnShot.Value && a->m_bOnShot != b->m_bOnShot) + return a->m_bOnShot > b->m_bOnShot; - return pLocal->m_vecOrigin().DistTo(a->m_vOrigin) < pLocal->m_vecOrigin().DistTo(b->m_vOrigin); - }); + return pLocal->m_vecOrigin().DistTo(a->m_vOrigin) < pLocal->m_vecOrigin().DistTo(b->m_vOrigin); + }); else { std::sort(vReturn.begin(), vReturn.end(), [&](const TickRecord* a, const TickRecord* b) -> bool - { - if (Vars::Backtrack::PreferOnShot.Value && a->m_bOnShot != b->m_bOnShot) - return a->m_bOnShot > b->m_bOnShot; + { + if (Vars::Backtrack::PreferOnShot.Value && a->m_bOnShot != b->m_bOnShot) + return a->m_bOnShot > b->m_bOnShot; - const float flADelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(a->m_flSimTime + flTimeMod)); - const float flBDelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(b->m_flSimTime + flTimeMod)); - return fabsf(flADelta) < fabsf(flBDelta); - }); + const float flADelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(a->m_flSimTime + flTimeMod)); + const float flBDelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(b->m_flSimTime + flTimeMod)); + return fabsf(flADelta) < fabsf(flBDelta); + }); } } @@ -352,41 +352,41 @@ void CBacktrack::AdjustPing(CNetChannel* pNetChan) { m_nOldInSequenceNr = pNetChan->m_nInSequenceNr, m_nOldInReliableState = pNetChan->m_nInReliableState; - auto Set = [&]() + auto fSet = [&]() + { + if (!Vars::Backtrack::Latency.Value) + return 0.f; + + auto pLocal = H::Entities.GetLocal(); + if (!pLocal || !pLocal->m_iClass()) + return 0.f; + + static auto host_timescale = H::ConVars.FindVar("host_timescale"); + float flTimescale = host_timescale->GetFloat(); + + static float flStaticReal = 0.f; + float flFake = GetWishFake(), flReal = TICKS_TO_TIME(pLocal->m_nTickBase() - m_nOldTickBase); + flStaticReal += (flReal + 5 * TICK_INTERVAL - flStaticReal) * 0.1f; + + int nInReliableState = pNetChan->m_nInReliableState, nInSequenceNr = pNetChan->m_nInSequenceNr; float flLatency = 0.f; + for (auto& cSequence : m_dSequences) { - if (!Vars::Backtrack::Latency.Value) - return 0.f; + nInReliableState = cSequence.m_nInReliableState; + nInSequenceNr = cSequence.m_nSequenceNr; + flLatency = (I::GlobalVars->realtime - cSequence.m_flTime) * flTimescale - TICK_INTERVAL; - auto pLocal = H::Entities.GetLocal(); - if (!pLocal || !pLocal->m_iClass()) - return 0.f; + if (flLatency > flFake || m_nLastInSequenceNr >= cSequence.m_nSequenceNr || flLatency > m_flMaxUnlag - flStaticReal) + break; + } + if (flLatency > 1.f) // hacky failsafe + return 0.f; - static auto host_timescale = H::ConVars.FindVar("host_timescale"); - float flTimescale = host_timescale->GetFloat(); + pNetChan->m_nInReliableState = nInReliableState; + pNetChan->m_nInSequenceNr = nInSequenceNr; + return flLatency; + }; - static float flStaticReal = 0.f; - float flFake = GetWishFake(), flReal = TICKS_TO_TIME(pLocal->m_nTickBase() - m_nOldTickBase); - flStaticReal += (flReal + 5 * TICK_INTERVAL - flStaticReal) * 0.1f; - - int nInReliableState = pNetChan->m_nInReliableState, nInSequenceNr = pNetChan->m_nInSequenceNr; float flLatency = 0.f; - for (auto& cSequence : m_dSequences) - { - nInReliableState = cSequence.m_nInReliableState; - nInSequenceNr = cSequence.m_nSequenceNr; - flLatency = (I::GlobalVars->realtime - cSequence.m_flTime) * flTimescale - TICK_INTERVAL; - - if (flLatency > flFake || m_nLastInSequenceNr >= cSequence.m_nSequenceNr || flLatency > m_flMaxUnlag - flStaticReal) - break; - } - if (flLatency > 1.f) // hacky failsafe - return 0.f; - - pNetChan->m_nInReliableState = nInReliableState; - pNetChan->m_nInSequenceNr = nInSequenceNr; - return flLatency; - }; - - auto flLatency = Set(); + auto flLatency = fSet(); m_nLastInSequenceNr = pNetChan->m_nInSequenceNr; if (Vars::Backtrack::Latency.Value || m_flFakeLatency) diff --git a/Amalgam/src/Features/Binds/Binds.cpp b/Amalgam/src/Features/Binds/Binds.cpp index c992f825..17fb439a 100644 --- a/Amalgam/src/Features/Binds/Binds.cpp +++ b/Amalgam/src/Features/Binds/Binds.cpp @@ -304,49 +304,49 @@ void CBinds::RemoveBind(int iBind, bool bForce) } std::vector vErases = {}; - std::function searchBinds = [&](int iIndex) + std::function fSearchBinds = [&](int iIndex) + { + for (int iBind = 0; iBind < m_vBinds.size(); iBind++) { - for (int iBind = 0; iBind < m_vBinds.size(); iBind++) - { - auto& tBind = m_vBinds[iBind]; - if (iIndex == tBind.m_iParent && iIndex != iBind) - searchBinds(iBind); - } - vErases.push_back(iIndex); - }; - auto removeBind = [&](int iIndex) + auto& tBind = m_vBinds[iBind]; + if (iIndex == tBind.m_iParent && iIndex != iBind) + fSearchBinds(iBind); + } + vErases.push_back(iIndex); + }; + auto fRemoveBind = [&](int iIndex) + { + if (iIndex < m_vBinds.size()) + m_vBinds.erase(std::next(m_vBinds.begin(), iIndex)); + for (auto& tBind : m_vBinds) { - if (iIndex < m_vBinds.size()) - m_vBinds.erase(std::next(m_vBinds.begin(), iIndex)); - for (auto& tBind : m_vBinds) - { - if (tBind.m_iParent != DEFAULT_BIND && tBind.m_iParent > iIndex) - tBind.m_iParent--; - } + if (tBind.m_iParent != DEFAULT_BIND && tBind.m_iParent > iIndex) + tBind.m_iParent--; + } - for (auto& pBase : G::Vars) - { - Remove(bool, iIndex) - else Remove(int, iIndex) - else Remove(float, iIndex) - else Remove(IntRange_t, iIndex) - else Remove(FloatRange_t, iIndex) - else Remove(std::string, iIndex) - else Remove(VA_LIST(std::vector>), iIndex) - else Remove(Color_t, iIndex) - else Remove(Gradient_t, iIndex) - else Remove(Vec3, iIndex) - else Remove(DragBox_t, iIndex) - else Remove(WindowBox_t, iIndex) - } - }; - searchBinds(iBind); - std::sort(vErases.begin(), vErases.end(), [&](const int a, const int b) -> bool + for (auto& pBase : G::Vars) { - return a > b; - }); + Remove(bool, iIndex) + else Remove(int, iIndex) + else Remove(float, iIndex) + else Remove(IntRange_t, iIndex) + else Remove(FloatRange_t, iIndex) + else Remove(std::string, iIndex) + else Remove(VA_LIST(std::vector>), iIndex) + else Remove(Color_t, iIndex) + else Remove(Gradient_t, iIndex) + else Remove(Vec3, iIndex) + else Remove(DragBox_t, iIndex) + else Remove(WindowBox_t, iIndex) + } + }; + fSearchBinds(iBind); + std::sort(vErases.begin(), vErases.end(), [&](const int a, const int b) -> bool + { + return a > b; + }); for (auto iIndex : vErases) - removeBind(iIndex); + fRemoveBind(iIndex); } int CBinds::GetParent(int iBind) @@ -417,8 +417,8 @@ void CBinds::Move(int i1, int i2) else if (tBind.m_iParent == i2) vBinds2.push_back(&tBind); } - std::for_each(vBinds1.begin(), vBinds1.end(), [&](auto pBind) { pBind->m_iParent = i2; }); - std::for_each(vBinds2.begin(), vBinds2.end(), [&](auto pBind) { pBind->m_iParent = i1; }); + for (auto pBind : vBinds1) pBind->m_iParent = i2; + for (auto pBind : vBinds2) pBind->m_iParent = i1; for (auto& pBase : G::Vars) { diff --git a/Amalgam/src/Features/Commands/Commands.h b/Amalgam/src/Features/Commands/Commands.h index a1a181ca..d8e643c2 100644 --- a/Amalgam/src/Features/Commands/Commands.h +++ b/Amalgam/src/Features/Commands/Commands.h @@ -2,7 +2,7 @@ #include "../../SDK/SDK.h" #include -using CommandCallback = std::function&)>; +using CommandCallback = const std::function&)>; class CCommands { diff --git a/Amalgam/src/Features/Configs/Configs.cpp b/Amalgam/src/Features/Configs/Configs.cpp index 37c98ef9..9113686d 100644 --- a/Amalgam/src/Features/Configs/Configs.cpp +++ b/Amalgam/src/Features/Configs/Configs.cpp @@ -142,7 +142,7 @@ template <> void CConfigs::LoadJson(const boost::property_tree::ptree& t, const if (auto tChild = t.get_child_optional(s)) { v.clear(); - for (auto& [_, tLayer] : *tChild) + for (auto& tLayer : *tChild | std::views::values) { if (auto o = tLayer.get_optional("Material")) { @@ -160,7 +160,7 @@ template <> void CConfigs::LoadJson(const boost::property_tree::ptree& t, const bool bValid = uHash != FNV1A::Hash32Const("None") && (uHash == FNV1A::Hash32Const("Original") || F::Materials.m_mMaterials.contains(uHash)); if (bValid) { - int i = 0; for (auto& [s, _] : v) + int i = 0; for (auto& s : v | std::views::keys) { auto uHash2 = FNV1A::Hash32(s.c_str()); if (uHash == uHash2) @@ -380,7 +380,7 @@ static inline void LoadMain(BaseVar*& pBase, boost::property_tree::ptree& tTree) pVar->Map = { { DEFAULT_BIND, pVar->Default } }; if (auto tMap = tTree.get_child_optional(pVar->Name())) { - for (auto& [sKey, _] : *tMap) + for (auto& sKey : *tMap | std::views::keys) { int iBind = std::stoi(sKey); if (iBind == DEFAULT_BIND || F::Binds.m_vBinds.size() > iBind && !(pVar->m_iFlags & NOBIND)) @@ -520,7 +520,7 @@ bool CConfigs::LoadConfig(const std::string& sConfigName, bool bNotify) if (auto tSub = tRead.get_child_optional("Binds")) { - for (const auto& [_, tChild] : *tSub) + for (const auto& tChild : *tSub | std::views::values) { Bind_t tBind = {}; LoadJson(tChild, "Name", tBind.m_sName); @@ -568,7 +568,7 @@ bool CConfigs::LoadConfig(const std::string& sConfigName, bool bNotify) if (auto tSub = tRead.get_child_optional("Groups")) { - for (auto& [_, tChild] : *tSub) + for (auto& tChild : *tSub | std::views::values) { Group_t tGroup = {}; LoadJson(tChild, "Name", tGroup.m_sName); @@ -744,7 +744,7 @@ bool CConfigs::LoadVisual(const std::string& sConfigName, bool bNotify) if (auto tSub = tRead.get_child_optional("Groups")) { - for (auto& [_, tChild] : *tSub) + for (auto& tChild : *tSub | std::views::values) { Group_t tGroup = {}; LoadJson(tChild, "Name", tGroup.m_sName); diff --git a/Amalgam/src/Features/CritHack/CritHack.cpp b/Amalgam/src/Features/CritHack/CritHack.cpp index 72a89dfe..c4c70205 100644 --- a/Amalgam/src/Features/CritHack/CritHack.cpp +++ b/Amalgam/src/Features/CritHack/CritHack.cpp @@ -380,31 +380,31 @@ void CCritHack::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd) int CCritHack::PredictCmdNum(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd) { - auto getCmdNum = [&](int iCommandNumber) - { - if (!pWeapon || !pLocal->IsAlive() || !I::EngineClient->IsInGame() || Vars::Misc::Game::AntiCheatCompatibility.Value - || pLocal->IsCritBoosted() || pWeapon->m_flCritTime() > I::GlobalVars->curtime || !WeaponCanCrit(pWeapon)) - return iCommandNumber; - - UpdateInfo(pLocal, pWeapon); - if (pWeapon->IsRapidFire() && I::GlobalVars->curtime < pWeapon->m_flLastRapidFireCritCheckTime() + 1.f) - return iCommandNumber; - - int iRequest = GetCritRequest(pCmd, pWeapon); - if (iRequest == CritRequestEnum::Any) - return iCommandNumber; - - if (int iCommand = GetCritCommand(pWeapon, iCommandNumber, iRequest == CritRequestEnum::Crit)) - return iCommand; + auto fGetCmdNum = [&](int iCommandNumber) + { + if (!pWeapon || !pLocal->IsAlive() || !I::EngineClient->IsInGame() || Vars::Misc::Game::AntiCheatCompatibility.Value + || pLocal->IsCritBoosted() || pWeapon->m_flCritTime() > I::GlobalVars->curtime || !WeaponCanCrit(pWeapon)) return iCommandNumber; - }; + + UpdateInfo(pLocal, pWeapon); + if (pWeapon->IsRapidFire() && I::GlobalVars->curtime < pWeapon->m_flLastRapidFireCritCheckTime() + 1.f) + return iCommandNumber; + + int iRequest = GetCritRequest(pCmd, pWeapon); + if (iRequest == CritRequestEnum::Any) + return iCommandNumber; + + if (int iCommand = GetCritCommand(pWeapon, iCommandNumber, iRequest == CritRequestEnum::Crit)) + return iCommand; + return iCommandNumber; + }; static int iCommandNumber = 0; // cache, don't constantly test static int iStaticCommand = 0; if (pCmd->command_number != iStaticCommand) { - iCommandNumber = getCmdNum(pCmd->command_number); + iCommandNumber = fGetCmdNum(pCmd->command_number); iStaticCommand = pCmd->command_number; } @@ -442,7 +442,7 @@ void CCritHack::Event(IGameEvent* pEvent, uint32_t uHash, CTFPlayer* pLocal) int iOldHealth = (tHistory.m_mHistory.contains(iHealth) ? tHistory.m_mHistory[iHealth].m_iOldHealth : tHistory.m_iNewHealth) % 32768; if (iHealth > iOldHealth) { - for (auto& [_, tOldHealth] : tHistory.m_mHistory) + for (auto& tOldHealth : tHistory.m_mHistory | std::views::values) { int iOldHealth2 = tOldHealth.m_iOldHealth % 32768; if (iOldHealth2 > iHealth) diff --git a/Amalgam/src/Features/ImGui/Menu/Components.h b/Amalgam/src/Features/ImGui/Menu/Components.h index 44285580..fd84739d 100644 --- a/Amalgam/src/Features/ImGui/Menu/Components.h +++ b/Amalgam/src/Features/ImGui/Menu/Components.h @@ -270,7 +270,7 @@ namespace ImGui 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()); } - inline void Divider(float flInset = H::Draw.Scale(), float flPrePadding = H::Draw.Scale(8), float flPostPadding = H::Draw.Scale(7), ImU32 uBorder = F::Render.Background2) + 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) { ImVec2 vSize = GetWindowSize(); ImVec2 vDrawPos = GetDrawPos() + ImVec2(0, GetCursorPosY()); @@ -2161,22 +2161,22 @@ namespace ImGui { // material stuff std::vector vMaterials; - for (auto& [_, mat] : F::Materials.m_mMaterials) + for (auto& tMaterial : F::Materials.m_mMaterials | std::views::values) { - if (FNV1A::Hash32(mat.m_sName.c_str()) != FNV1A::Hash32Const("None")) - vMaterials.push_back(mat); + if (FNV1A::Hash32(tMaterial.m_sName.c_str()) != FNV1A::Hash32Const("None")) + vMaterials.push_back(tMaterial); } std::sort(vMaterials.begin(), vMaterials.end(), [&](const auto& a, const auto& b) -> bool - { - // keep locked materials higher - if (a.m_bLocked && !b.m_bLocked) - return true; - if (!a.m_bLocked && b.m_bLocked) - return false; + { + // keep locked materials higher + if (a.m_bLocked && !b.m_bLocked) + return true; + if (!a.m_bLocked && b.m_bLocked) + return false; - return a.m_sName < b.m_sName; - }); + return a.m_sName < b.m_sName; + }); std::vector vEntries = { "Original" }; for (auto& pair : vMaterials) @@ -2465,15 +2465,15 @@ namespace ImGui std::vector vValues = {}; std::vector vStrings = {}; // prevent dangling pointers - for (auto& [_iBind, _] : var.Map) + for (auto& _iBind : var.Map | std::views::keys) { if (_iBind != DEFAULT_BIND) vValues.push_back(_iBind); } std::sort(vValues.begin(), vValues.end(), [&](const int a, const int b) -> bool - { - return a < b; - }); + { + return a < b; + }); for (auto _iBind : vValues) vStrings.push_back(std::format("{}## Bind{}", _iBind != DEFAULT_BIND && _iBind < F::Binds.m_vBinds.size() ? F::Binds.m_vBinds[_iBind].m_sName : sBind, _iBind)); for (auto& sEntry : vStrings) diff --git a/Amalgam/src/Features/ImGui/Menu/Menu.cpp b/Amalgam/src/Features/ImGui/Menu/Menu.cpp index cd9e374a..43048e48 100644 --- a/Amalgam/src/Features/ImGui/Menu/Menu.cpp +++ b/Amalgam/src/Features/ImGui/Menu/Menu.cpp @@ -10,6 +10,7 @@ #include "../../Visuals/Visuals.h" #include "../../Misc/Misc.h" #include "../../Output/Output.h" +#include "../../World/World.h" void CMenu::DrawMenu() { @@ -307,20 +308,27 @@ void CMenu::MenuAimbot(int iTab) Divider(); FText("Splash"); - Divider(); - FSlider(Vars::Aimbot::Projectile::SplashPointsDirect, FSliderEnum::Left); - FSlider(Vars::Aimbot::Projectile::SplashPointsArc, FSliderEnum::Right); + Divider(H::Draw.Scale(8), H::Draw.Scale(-1)); + FDropdown(Vars::Aimbot::Projectile::SplashMode); + PushTransparent(Vars::Aimbot::Projectile::SplashMode.Value != Vars::Aimbot::Projectile::SplashModeEnum::Trace); + { + FSlider(Vars::Aimbot::Projectile::SplashPointsDirect, FSliderEnum::Left); + FSlider(Vars::Aimbot::Projectile::SplashPointsArc, FSliderEnum::Right); + FSlider(Vars::Aimbot::Projectile::SplashRotateX, FSliderEnum::Left, Vars::Aimbot::Projectile::SplashRotateX[DEFAULT_BIND] < 0.f ? "random" : "%g"); + FSlider(Vars::Aimbot::Projectile::SplashRotateY, FSliderEnum::Right, Vars::Aimbot::Projectile::SplashRotateY[DEFAULT_BIND] < 0.f ? "random" : "%g"); + } + PopTransparent(); + PushTransparent(Vars::Aimbot::Projectile::SplashMode.Value != Vars::Aimbot::Projectile::SplashModeEnum::Face); + { + FSlider(Vars::Aimbot::Projectile::SplashDensityDirect, FSliderEnum::Left); + FSlider(Vars::Aimbot::Projectile::SplashDensityArc, FSliderEnum::Right); + FSlider(Vars::Aimbot::Projectile::SplashSamplesCutoff); + } + PopTransparent(); FSlider(Vars::Aimbot::Projectile::SplashCountDirect, FSliderEnum::Left); FSlider(Vars::Aimbot::Projectile::SplashCountArc, FSliderEnum::Right); - FSlider(Vars::Aimbot::Projectile::SplashRotateX, FSliderEnum::Left, Vars::Aimbot::Projectile::SplashRotateX[DEFAULT_BIND] < 0.f ? "random" : "%g"); - FSlider(Vars::Aimbot::Projectile::SplashRotateY, FSliderEnum::Right, Vars::Aimbot::Projectile::SplashRotateY[DEFAULT_BIND] < 0.f ? "random" : "%g"); FSlider(Vars::Aimbot::Projectile::SplashTraceInterval, FSliderEnum::Left); FSlider(Vars::Aimbot::Projectile::SplashNormalSkip, FSliderEnum::Right); - FDropdown(Vars::Aimbot::Projectile::SplashMode, FDropdownEnum::Left); - FDropdown(Vars::Aimbot::Projectile::RocketSplashMode, FDropdownEnum::Right, 0, &Hovered); FTooltip("Special splash type for rockets, more expensive", Hovered); - FToggle(Vars::Aimbot::Projectile::SplashGrates); - FSlider(Vars::Aimbot::Projectile::Out2NormalMin, FSliderEnum::Left); - FSlider(Vars::Aimbot::Projectile::Out2NormalMax, FSliderEnum::Right); Divider(); FText("Misc"); @@ -502,20 +510,20 @@ void CMenu::MenuVisuals(int iTab) SetCursorPosY(GetCursorPosY() - H::Draw.Scale(5)); PopStyleColor(); - auto positionToIndex = [](ImVec2 vPos) - { - int iIndex = floorf((vPos.y - GetCursorPosY() - H::Draw.Scale(4)) / H::Draw.Scale(36)) * 2 - + (vPos.x > GetWindowWidth() / 2 ? 1 : 0); - iIndex = std::clamp(iIndex, 0, int(F::Groups.m_vGroups.size() - 1)); - return iIndex; - }; + auto fPositionToIndex = [](ImVec2 vPos) + { + int iIndex = floorf((vPos.y - GetCursorPosY() - H::Draw.Scale(4)) / H::Draw.Scale(36)) * 2 + + (vPos.x > GetWindowWidth() / 2 ? 1 : 0); + iIndex = std::clamp(iIndex, 0, int(F::Groups.m_vGroups.size() - 1)); + return iIndex; + }; static int iDragging = -1; if (!IsMouseDown(ImGuiMouseButton_Left)) iDragging = -1; else if (iDragging != -1) { - int iTo = positionToIndex(GetMousePos() - GetDrawPos()); + int iTo = fPositionToIndex(GetMousePos() - GetDrawPos()); if (iDragging != iTo) { F::Groups.Move(iDragging, iTo); @@ -624,7 +632,7 @@ void CMenu::MenuVisuals(int iTab) if (Section("Conditions")) { FDropdown("Conditions", &tGroup.m_iConditions, { "Enemy", "Team", "BLU", "RED", "##Divider", "Local", "Friends", "Party", "Priority", "Target", "##Divider", "Dormant" }, {}, FDropdownEnum::Multi); - Divider(H::Draw.Scale(), H::Draw.Scale(8), -H::Draw.Scale()); + Divider(H::Draw.Scale(8), H::Draw.Scale(-1)); PushTransparent(!(tGroup.m_iTargets & TargetsEnum::Players)); { FDropdown("Players", &tGroup.m_iPlayers, { "Scout", "Soldier", "Pyro", "Demoman", "Heavy", "Engineer", "Medic", "Sniper", "Spy", "##Divider", "Invulnerable", "Crits", "Invisible", "Disguise", "Hurt" }, {}, FDropdownEnum::Multi, 0, "All"); @@ -1292,310 +1300,310 @@ void CMenu::MenuLogs(int iTab) } } - auto getTeamColor = [&](int iTeam, bool bAlive) + auto fGetTeamColor = [&](int iTeam, bool bAlive) + { + switch (iTeam) { - switch (iTeam) - { - case 3: return Color_t(100, 150, 200, bAlive ? 255 : 127).Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha); - case 2: return Color_t(255, 100, 100, bAlive ? 255 : 127).Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha); - } - return Color_t(127, 127, 127, 255).Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha); - }; - auto drawPlayer = [&](const ListPlayer& tPlayer, int x, int y) + case 3: return Color_t(100, 150, 200, bAlive ? 255 : 127).Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha); + case 2: return Color_t(255, 100, 100, bAlive ? 255 : 127).Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha); + } + return Color_t(127, 127, 127, 255).Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha); + }; + auto fDrawPlayer = [&](const ListPlayer& tPlayer, int x, int y) + { + ImVec2 vOriginalPos = { !x ? GetStyle().WindowPadding.x : GetWindowWidth() / 2 + GetStyle().WindowPadding.x / 2, H::Draw.Scale(35 + 36 * y) }; + + // background + float flWidth = GetWindowWidth() / 2 - GetStyle().WindowPadding.x * 1.5f; + float flHeight = H::Draw.Scale(28); + ImColor tColor = ColorToVec(fGetTeamColor(tPlayer.m_iTeam, tPlayer.m_bAlive)); + ImVec2 vDrawPos = GetDrawPos() + vOriginalPos; + GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, tColor, H::Draw.Scale(4)); + + // text + icons + int lOffset = H::Draw.Scale(10); + if (tPlayer.m_bLocal || F::Spectate.GetTarget(true) == tPlayer.m_iUserID || tPlayer.m_bFriend || tPlayer.m_bParty) { - ImVec2 vOriginalPos = { !x ? GetStyle().WindowPadding.x : GetWindowWidth() / 2 + GetStyle().WindowPadding.x / 2, H::Draw.Scale(35 + 36 * y) }; + lOffset += H::Draw.Scale(19); + SetCursorPos({ vOriginalPos.x + H::Draw.Scale(7), vOriginalPos.y + H::Draw.Scale(6) }); + if (tPlayer.m_bLocal) + IconImage(ICON_MD_PERSON); + else if (F::Spectate.GetTarget(true) == tPlayer.m_iUserID) + IconImage(ICON_MD_VISIBILITY); + else if (tPlayer.m_bFriend) + IconImage(ICON_MD_GROUP); + else if (tPlayer.m_bParty) + IconImage(ICON_MD_GROUPS); + } + SetCursorPos({ vOriginalPos.x + lOffset, vOriginalPos.y + H::Draw.Scale(7) }); + auto sName = TruncateText(tPlayer.m_sName, flWidth / 2 - lOffset); + FText(sName.c_str()); + lOffset += FCalcTextSize(sName.c_str()).x + H::Draw.Scale(8); - // background - float flWidth = GetWindowWidth() / 2 - GetStyle().WindowPadding.x * 1.5f; - float flHeight = H::Draw.Scale(28); - ImColor tColor = ColorToVec(getTeamColor(tPlayer.m_iTeam, tPlayer.m_bAlive)); - ImVec2 vDrawPos = GetDrawPos() + vOriginalPos; - GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, tColor, H::Draw.Scale(4)); + // buttons + bool bPopup = false; - // text + icons - int lOffset = H::Draw.Scale(10); - if (tPlayer.m_bLocal || F::Spectate.GetTarget(true) == tPlayer.m_iUserID || tPlayer.m_bFriend || tPlayer.m_bParty) + if (!tPlayer.m_bFake) + { + // tag bar + SetCursorPos({ vOriginalPos.x + lOffset, vOriginalPos.y }); + if (BeginChild(std::format("TagBar{}", tPlayer.m_iUserID).c_str(), { flWidth - lOffset - H::Draw.Scale(4), flHeight }, ImGuiWindowFlags_None, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoBackground)) { - lOffset += H::Draw.Scale(19); - SetCursorPos({ vOriginalPos.x + H::Draw.Scale(7), vOriginalPos.y + H::Draw.Scale(6) }); - if (tPlayer.m_bLocal) - IconImage(ICON_MD_PERSON); - else if (F::Spectate.GetTarget(true) == tPlayer.m_iUserID) - IconImage(ICON_MD_VISIBILITY); - else if (tPlayer.m_bFriend) - IconImage(ICON_MD_GROUP); - else if (tPlayer.m_bParty) - IconImage(ICON_MD_GROUPS); - } - SetCursorPos({ vOriginalPos.x + lOffset, vOriginalPos.y + H::Draw.Scale(7) }); - auto sName = TruncateText(tPlayer.m_sName, flWidth / 2 - lOffset); - FText(sName.c_str()); - lOffset += FCalcTextSize(sName.c_str()).x + H::Draw.Scale(8); + std::vector vLabels = {}; + std::vector> vTags = {}; + if (int iParty = tPlayer.m_iParty) + { + auto pTag = &F::PlayerUtils.m_vTags[F::PlayerUtils.TagToIndex(PARTY_TAG)]; + if (!--iParty) + vTags.emplace_back(pTag, 0); + else + vLabels.emplace_back(std::format("{}: {}", pTag->m_sName, iParty), pTag->m_tColor.HueShift(iParty * 360.f / iPartyCount)); + } + if (tPlayer.m_bF2P) + { + auto pTag = &F::PlayerUtils.m_vTags[F::PlayerUtils.TagToIndex(F2P_TAG)]; + vTags.emplace_back(pTag, 0); + } + for (auto& iID : F::PlayerUtils.GetPlayerTags(tPlayer.m_uAccountID)) + { + if (auto pTag = F::PlayerUtils.GetTag(iID)) + vTags.emplace_back(pTag, iID); + } - // buttons - bool bPopup = false; + PushFont(F::Render.FontSmall); + const auto vDrawPos = GetDrawPos(); + float flTagOffset = 0; + auto fDrawTag = [&](PriorityLabel_t& tTag, int iID) + { + ImColor tTagColor = ColorToVec(tTag.m_tColor); + float flTagWidth = FCalcTextSize(tTag.m_sName.c_str()).x + H::Draw.Scale(!iID ? 10 : 25); + float flTagHeight = H::Draw.Scale(20); + ImVec2 vTagPos = { flTagOffset, H::Draw.Scale(4) }; + + GetWindowDrawList()->AddRectFilled(vDrawPos + vTagPos, { vDrawPos.x + vTagPos.x + flTagWidth, vDrawPos.y + vTagPos.y + flTagHeight }, tTagColor, H::Draw.Scale(4)); + SetCursorPos({ vTagPos.x + H::Draw.Scale(5), vTagPos.y + H::Draw.Scale(3) }); + TextColored(VecToColor(tColor).Blend(tTag.m_tColor).IsColorBright() ? ImVec4(0, 0, 0, 1) : ImVec4(1, 1, 1, 1), tTag.m_sName.c_str()); + if (iID) + { + SetCursorPos({ vTagPos.x + flTagWidth - H::Draw.Scale(22), vTagPos.y - H::Draw.Scale(2) }); + if (IconButton(ICON_MD_CANCEL)) + F::PlayerUtils.RemoveTag(tPlayer.m_uAccountID, iID, true, tPlayer.m_sName.c_str()); + } + + flTagOffset += flTagWidth + H::Draw.Scale(4); + }; + + for (auto& tTag : vLabels) + fDrawTag(tTag, 0); + for (auto& [pTag, iID] : vTags) + fDrawTag(*pTag, iID); + PopFont(); + } EndChild(); + + bPopup = IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right); + } + SetCursorPos(vOriginalPos); + Button(std::format("##{}", tPlayer.m_iUserID).c_str(), { flWidth, flHeight }); + bPopup |= IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right); + + // popups + if (bPopup) + OpenPopup(std::format("RightClicked{}", tPlayer.m_iUserID).c_str()); + + if (FBeginPopup(std::format("RightClicked{}", tPlayer.m_iUserID).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), H::Draw.Scale(8) }); if (!tPlayer.m_bFake) { - // tag bar - SetCursorPos({ vOriginalPos.x + lOffset, vOriginalPos.y }); - if (BeginChild(std::format("TagBar{}", tPlayer.m_iUserID).c_str(), { flWidth - lOffset - H::Draw.Scale(4), flHeight }, ImGuiWindowFlags_None, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoBackground)) - { - std::vector vLabels = {}; - std::vector> vTags = {}; - if (int iParty = tPlayer.m_iParty) - { - auto pTag = &F::PlayerUtils.m_vTags[F::PlayerUtils.TagToIndex(PARTY_TAG)]; - if (!--iParty) - vTags.emplace_back(pTag, 0); - else - vLabels.emplace_back(std::format("{}: {}", pTag->m_sName, iParty), pTag->m_tColor.HueShift(iParty * 360.f / iPartyCount)); - } - if (tPlayer.m_bF2P) - { - auto pTag = &F::PlayerUtils.m_vTags[F::PlayerUtils.TagToIndex(F2P_TAG)]; - vTags.emplace_back(pTag, 0); - } - for (auto& iID : F::PlayerUtils.GetPlayerTags(tPlayer.m_uAccountID)) - { - if (auto pTag = F::PlayerUtils.GetTag(iID)) - vTags.emplace_back(pTag, iID); - } - - PushFont(F::Render.FontSmall); - const auto vDrawPos = GetDrawPos(); - float flTagOffset = 0; - auto drawTag = [&](PriorityLabel_t& tTag, int iID) - { - ImColor tTagColor = ColorToVec(tTag.m_tColor); - float flTagWidth = FCalcTextSize(tTag.m_sName.c_str()).x + H::Draw.Scale(!iID ? 10 : 25); - float flTagHeight = H::Draw.Scale(20); - ImVec2 vTagPos = { flTagOffset, H::Draw.Scale(4) }; - - GetWindowDrawList()->AddRectFilled(vDrawPos + vTagPos, { vDrawPos.x + vTagPos.x + flTagWidth, vDrawPos.y + vTagPos.y + flTagHeight }, tTagColor, H::Draw.Scale(4)); - SetCursorPos({ vTagPos.x + H::Draw.Scale(5), vTagPos.y + H::Draw.Scale(3) }); - TextColored(VecToColor(tColor).Blend(tTag.m_tColor).IsColorBright() ? ImVec4(0, 0, 0, 1) : ImVec4(1, 1, 1, 1), tTag.m_sName.c_str()); - if (iID) - { - SetCursorPos({ vTagPos.x + flTagWidth - H::Draw.Scale(22), vTagPos.y - H::Draw.Scale(2) }); - if (IconButton(ICON_MD_CANCEL)) - F::PlayerUtils.RemoveTag(tPlayer.m_uAccountID, iID, true, tPlayer.m_sName.c_str()); - } - - flTagOffset += flTagWidth + H::Draw.Scale(4); - }; - - for (auto& tTag : vLabels) - drawTag(tTag, 0); - for (auto& [pTag, iID] : vTags) - drawTag(*pTag, iID); - PopFont(); - } EndChild(); - - bPopup = IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right); + if (FSelectable("Profile")) + I::SteamFriends->ActivateGameOverlayToUser("steamid", CSteamID(tPlayer.m_uAccountID, k_EUniversePublic, k_EAccountTypeIndividual)); + if (FSelectable("History")) + I::SteamFriends->ActivateGameOverlayToWebPage(std::format("https://steamhistory.net/id/{}", CSteamID(tPlayer.m_uAccountID, k_EUniversePublic, k_EAccountTypeIndividual).ConvertToUint64()).c_str()); } - SetCursorPos(vOriginalPos); - Button(std::format("##{}", tPlayer.m_iUserID).c_str(), { flWidth, flHeight }); - bPopup |= IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right); - // popups - if (bPopup) - OpenPopup(std::format("RightClicked{}", tPlayer.m_iUserID).c_str()); + if (FSelectable(F::Spectate.GetTarget(true) == tPlayer.m_iUserID ? "Unspectate" : "Spectate")) + F::Spectate.SetTarget(tPlayer.m_iUserID); - if (FBeginPopup(std::format("RightClicked{}", tPlayer.m_iUserID).c_str())) + if (!I::EngineClient->IsPlayingDemo() && FBeginMenu("Votekick")) { - PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), H::Draw.Scale(8) }); + if (FSelectable("No reason")) + I::ClientState->SendStringCmd(std::format("callvote Kick \"{} other\"", tPlayer.m_iUserID).c_str()); + if (FSelectable("Cheating")) + I::ClientState->SendStringCmd(std::format("callvote Kick \"{} cheating\"", tPlayer.m_iUserID).c_str()); + if (FSelectable("Idle")) + I::ClientState->SendStringCmd(std::format("callvote Kick \"{} idle\"", tPlayer.m_iUserID).c_str()); + if (FSelectable("Scamming")) + I::ClientState->SendStringCmd(std::format("callvote Kick \"{} scamming\"", tPlayer.m_iUserID).c_str()); - if (!tPlayer.m_bFake) + ImGui::EndMenu(); + } + + if (!tPlayer.m_bFake) + { + if (FBeginMenu("Add tag")) { - if (FSelectable("Profile")) - I::SteamFriends->ActivateGameOverlayToUser("steamid", CSteamID(tPlayer.m_uAccountID, k_EUniversePublic, k_EAccountTypeIndividual)); - if (FSelectable("History")) - I::SteamFriends->ActivateGameOverlayToWebPage(std::format("https://steamhistory.net/id/{}", CSteamID(tPlayer.m_uAccountID, k_EUniversePublic, k_EAccountTypeIndividual).ConvertToUint64()).c_str()); - } + for (auto it = F::PlayerUtils.m_vTags.begin(); it != F::PlayerUtils.m_vTags.end(); it++) + { + int iID = std::distance(F::PlayerUtils.m_vTags.begin(), it); + auto& tTag = *it; + if (!tTag.m_bAssignable || F::PlayerUtils.HasTag(tPlayer.m_uAccountID, iID)) + continue; - if (FSelectable(F::Spectate.GetTarget(true) == tPlayer.m_iUserID ? "Unspectate" : "Spectate")) - F::Spectate.SetTarget(tPlayer.m_iUserID); - - if (!I::EngineClient->IsPlayingDemo() && FBeginMenu("Votekick")) - { - if (FSelectable("No reason")) - I::ClientState->SendStringCmd(std::format("callvote Kick \"{} other\"", tPlayer.m_iUserID).c_str()); - if (FSelectable("Cheating")) - I::ClientState->SendStringCmd(std::format("callvote Kick \"{} cheating\"", tPlayer.m_iUserID).c_str()); - if (FSelectable("Idle")) - I::ClientState->SendStringCmd(std::format("callvote Kick \"{} idle\"", tPlayer.m_iUserID).c_str()); - if (FSelectable("Scamming")) - I::ClientState->SendStringCmd(std::format("callvote Kick \"{} scamming\"", tPlayer.m_iUserID).c_str()); + auto imColor = ColorToVec(tTag.m_tColor); + PushStyleColor(ImGuiCol_Text, imColor); + imColor.x /= 3; imColor.y /= 3; imColor.z /= 3; + if (FSelectable(tTag.m_sName.c_str(), imColor)) + F::PlayerUtils.AddTag(tPlayer.m_uAccountID, iID, true, tPlayer.m_sName.c_str()); + PopStyleColor(); + } ImGui::EndMenu(); } - - if (!tPlayer.m_bFake) + if (FBeginMenu("Alias")) { - if (FBeginMenu("Add tag")) + bool bHasAlias = F::PlayerUtils.m_mPlayerAliases.contains(tPlayer.m_uAccountID); + static std::string sInput = ""; + + bool bEnter = FInputText("Alias...", sInput, H::Draw.Scale(150), ImGuiInputTextFlags_EnterReturnsTrue); + if (!IsItemFocused()) + sInput = bHasAlias ? F::PlayerUtils.m_mPlayerAliases[tPlayer.m_uAccountID] : ""; + if (bEnter) { - for (auto it = F::PlayerUtils.m_vTags.begin(); it != F::PlayerUtils.m_vTags.end(); it++) + if (sInput.empty() && bHasAlias) { - int iID = std::distance(F::PlayerUtils.m_vTags.begin(), it); - auto& tTag = *it; - if (!tTag.m_bAssignable || F::PlayerUtils.HasTag(tPlayer.m_uAccountID, iID)) - continue; + F::Output.AliasChanged(tPlayer.m_sName.c_str(), "Removed", F::PlayerUtils.m_mPlayerAliases[tPlayer.m_uAccountID].c_str()); - auto imColor = ColorToVec(tTag.m_tColor); - PushStyleColor(ImGuiCol_Text, imColor); - imColor.x /= 3; imColor.y /= 3; imColor.z /= 3; - if (FSelectable(tTag.m_sName.c_str(), imColor)) - F::PlayerUtils.AddTag(tPlayer.m_uAccountID, iID, true, tPlayer.m_sName.c_str()); - PopStyleColor(); + F::PlayerUtils.m_mPlayerAliases.erase(tPlayer.m_uAccountID); + F::PlayerUtils.m_bSave = true; } - - ImGui::EndMenu(); - } - if (FBeginMenu("Alias")) - { - bool bHasAlias = F::PlayerUtils.m_mPlayerAliases.contains(tPlayer.m_uAccountID); - static std::string sInput = ""; - - bool bEnter = FInputText("Alias...", sInput, H::Draw.Scale(150), ImGuiInputTextFlags_EnterReturnsTrue); - if (!IsItemFocused()) - sInput = bHasAlias ? F::PlayerUtils.m_mPlayerAliases[tPlayer.m_uAccountID] : ""; - if (bEnter) + else if (!sInput.empty()) { - if (sInput.empty() && bHasAlias) - { - F::Output.AliasChanged(tPlayer.m_sName.c_str(), "Removed", F::PlayerUtils.m_mPlayerAliases[tPlayer.m_uAccountID].c_str()); + F::PlayerUtils.m_mPlayerAliases[tPlayer.m_uAccountID] = sInput; + F::PlayerUtils.m_bSave = true; - F::PlayerUtils.m_mPlayerAliases.erase(tPlayer.m_uAccountID); - F::PlayerUtils.m_bSave = true; - } - else if (!sInput.empty()) - { - F::PlayerUtils.m_mPlayerAliases[tPlayer.m_uAccountID] = sInput; - F::PlayerUtils.m_bSave = true; - - F::Output.AliasChanged(tPlayer.m_sName.c_str(), bHasAlias ? "Changed" : "Added", sInput.c_str()); - } + F::Output.AliasChanged(tPlayer.m_sName.c_str(), bHasAlias ? "Changed" : "Added", sInput.c_str()); } - - ImGui::EndMenu(); } + + ImGui::EndMenu(); } - - if (Vars::Resolver::Enabled.Value && !tPlayer.m_bLocal && !I::EngineClient->IsPlayingDemo()) - { - if (FBeginMenu("Set yaw")) - { - static std::vector> vYaws = { - { "Auto", 0.f }, - { "Forward", 0.f }, - { "Left", 90.f }, - { "Right", -90.f }, - { "Backwards", 180.f } - }; - for (auto& [sYaw, flValue] : vYaws) - { - if (FSelectable(sYaw)) - { - switch (FNV1A::Hash32(sYaw)) - { - case FNV1A::Hash32Const("Auto"): - F::Resolver.SetYaw(tPlayer.m_iUserID, 0.f, true); - break; - default: - F::Resolver.SetYaw(tPlayer.m_iUserID, flValue); - } - } - } - - ImGui::EndMenu(); - } - if (FBeginMenu("Set pitch")) - { - static std::vector> vPitches = { - { "Auto", 0.f }, - { "Up", -90.f }, - { "Down", 90.f }, - { "Zero", 0.f }, - { "Inverse", 0.f } - }; - for (auto& [sPitch, flValue] : vPitches) - { - if (FSelectable(sPitch)) - { - switch (FNV1A::Hash32(sPitch)) - { - case FNV1A::Hash32Const("Auto"): - F::Resolver.SetPitch(tPlayer.m_iUserID, 0.f, false, true); - break; - case FNV1A::Hash32Const("Inverse"): - F::Resolver.SetPitch(tPlayer.m_iUserID, 0.f, true); - break; - default: - F::Resolver.SetPitch(tPlayer.m_iUserID, flValue); - } - } - } - - ImGui::EndMenu(); - } - if (FBeginMenu("Set view")) - { - static std::vector> vPitches = { - { "Offset from static view", true }, - { "Offset from view to local", false } - }; - for (auto& [sPitch, bValue] : vPitches) - { - if (FSelectable(sPitch)) - F::Resolver.SetView(tPlayer.m_iUserID, bValue); - } - - ImGui::EndMenu(); - } - if (FBeginMenu("Set minwalk")) - { - static std::vector> vPitches = { - { "Minwalk on", true }, - { "Minwalk off", false } - }; - for (auto& [sPitch, bValue] : vPitches) - { - if (FSelectable(sPitch)) - F::Resolver.SetMinwalk(tPlayer.m_iUserID, bValue); - } - - ImGui::EndMenu(); - } - } - - if (mParties.contains(tPlayer.m_iParty)) - { - Divider(H::Draw.Scale(), H::Draw.Scale(1), 0); - - TextColored(F::Render.Inactive.Value, "Partied:"); - for (auto& pPlayer2 : mParties[tPlayer.m_iParty]) - TextColored(F::Render.Inactive.Value, pPlayer2->m_sName.c_str()); - } - - if (tPlayer.m_iLevel != -2) - { - Divider(H::Draw.Scale(), H::Draw.Scale(1), 0); - - std::string sLevel = "T? L?"; - if (tPlayer.m_iLevel != -1) - { - int iTier = std::max(std::ceil(tPlayer.m_iLevel / 150.f), 1.f); - int iLevel = ((tPlayer.m_iLevel - 1) % 150) + 1; - sLevel = std::format("T{} L{}", iTier, iLevel); - } - TextColored(F::Render.Inactive.Value, sLevel.c_str()); - } - - PopStyleVar(); - EndPopup(); } - }; + + if (Vars::Resolver::Enabled.Value && !tPlayer.m_bLocal && !I::EngineClient->IsPlayingDemo()) + { + if (FBeginMenu("Set yaw")) + { + static std::vector> vYaws = { + { "Auto", 0.f }, + { "Forward", 0.f }, + { "Left", 90.f }, + { "Right", -90.f }, + { "Backwards", 180.f } + }; + for (auto& [sYaw, flValue] : vYaws) + { + if (FSelectable(sYaw)) + { + switch (FNV1A::Hash32(sYaw)) + { + case FNV1A::Hash32Const("Auto"): + F::Resolver.SetYaw(tPlayer.m_iUserID, 0.f, true); + break; + default: + F::Resolver.SetYaw(tPlayer.m_iUserID, flValue); + } + } + } + + ImGui::EndMenu(); + } + if (FBeginMenu("Set pitch")) + { + static std::vector> vPitches = { + { "Auto", 0.f }, + { "Up", -90.f }, + { "Down", 90.f }, + { "Zero", 0.f }, + { "Inverse", 0.f } + }; + for (auto& [sPitch, flValue] : vPitches) + { + if (FSelectable(sPitch)) + { + switch (FNV1A::Hash32(sPitch)) + { + case FNV1A::Hash32Const("Auto"): + F::Resolver.SetPitch(tPlayer.m_iUserID, 0.f, false, true); + break; + case FNV1A::Hash32Const("Inverse"): + F::Resolver.SetPitch(tPlayer.m_iUserID, 0.f, true); + break; + default: + F::Resolver.SetPitch(tPlayer.m_iUserID, flValue); + } + } + } + + ImGui::EndMenu(); + } + if (FBeginMenu("Set view")) + { + static std::vector> vPitches = { + { "Offset from static view", true }, + { "Offset from view to local", false } + }; + for (auto& [sPitch, bValue] : vPitches) + { + if (FSelectable(sPitch)) + F::Resolver.SetView(tPlayer.m_iUserID, bValue); + } + + ImGui::EndMenu(); + } + if (FBeginMenu("Set minwalk")) + { + static std::vector> vPitches = { + { "Minwalk on", true }, + { "Minwalk off", false } + }; + for (auto& [sPitch, bValue] : vPitches) + { + if (FSelectable(sPitch)) + F::Resolver.SetMinwalk(tPlayer.m_iUserID, bValue); + } + + ImGui::EndMenu(); + } + } + + if (mParties.contains(tPlayer.m_iParty)) + { + Divider(H::Draw.Scale(1), 0); + + TextColored(F::Render.Inactive.Value, "Partied:"); + for (auto& pPlayer2 : mParties[tPlayer.m_iParty]) + TextColored(F::Render.Inactive.Value, pPlayer2->m_sName.c_str()); + } + + if (tPlayer.m_iLevel != -2) + { + Divider(H::Draw.Scale(1), 0); + + std::string sLevel = "T? L?"; + if (tPlayer.m_iLevel != -1) + { + int iTier = std::max(ceilf(tPlayer.m_iLevel / 150.f), 1.f); + int iLevel = ((tPlayer.m_iLevel - 1) % 150) + 1; + sLevel = std::format("T{} L{}", iTier, iLevel); + } + TextColored(F::Render.Inactive.Value, sLevel.c_str()); + } + + PopStyleVar(); + EndPopup(); + } + }; // display players std::vector vBlu, vRed, vOther; @@ -1612,12 +1620,12 @@ void CMenu::MenuLogs(int iTab) int iBlu = 0, iRed = 0; for (size_t i = 0; i < vBlu.size(); i++) { - drawPlayer(vBlu[i], 0, int(i)); + fDrawPlayer(vBlu[i], 0, int(i)); iBlu++; } for (size_t i = 0; i < vRed.size(); i++) { - drawPlayer(vRed[i], 1, int(i)); + fDrawPlayer(vRed[i], 1, int(i)); iRed++; } if (vOther.empty()) @@ -1628,7 +1636,7 @@ void CMenu::MenuLogs(int iTab) { size_t iMax = std::max(iBlu, iRed); for (size_t i = 0; i < vOther.size(); i++) - drawPlayer(vOther[i], i % 2, int(iMax + i / 2)); + fDrawPlayer(vOther[i], i % 2, int(iMax + i / 2)); } } else @@ -1707,156 +1715,156 @@ void CMenu::MenuLogs(int iTab) } } EndChild(); - auto drawTag = [](std::vector::iterator it, PriorityLabel_t& _tTag, int y) + auto fDrawTag = [](std::vector::iterator it, PriorityLabel_t& _tTag, int y) + { + int _iID = std::distance(F::PlayerUtils.m_vTags.begin(), it); + + ImVec2 vOriginalPos = { !_tTag.m_bLabel ? GetStyle().WindowPadding.x : GetWindowWidth() * 2 / 3 + GetStyle().WindowPadding.x / 2, H::Draw.Scale(96 + 36 * y) }; + + // background + float flWidth = GetWindowWidth() * (_tTag.m_bLabel ? 1.f / 3 : 2.f / 3) - GetStyle().WindowPadding.x * 1.5f; + float flHeight = H::Draw.Scale(28); + ImColor tColor = ColorToVec(_tTag.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha)); + ImVec2 vDrawPos = GetDrawPos() + vOriginalPos; + if (iID != _iID) + GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, tColor, H::Draw.Scale(4)); + else { - int _iID = std::distance(F::PlayerUtils.m_vTags.begin(), it); + ImColor tColor2 = { tColor.Value.x * 1.1f, tColor.Value.y * 1.1f, tColor.Value.z * 1.1f, tColor.Value.w }; + GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, tColor2, H::Draw.Scale(4)); - ImVec2 vOriginalPos = { !_tTag.m_bLabel ? GetStyle().WindowPadding.x : GetWindowWidth() * 2 / 3 + GetStyle().WindowPadding.x / 2, H::Draw.Scale(96 + 36 * y) }; + tColor2 = ColorToVec(_tTag.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.25f, LerpEnum::NoAlpha)); + float flInset = H::Draw.Scale(0.5f) - 0.5f; + GetWindowDrawList()->AddRect({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x - flInset + flWidth, vDrawPos.y - flInset + flHeight }, tColor2, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale()); + } - // background - float flWidth = GetWindowWidth() * (_tTag.m_bLabel ? 1.f / 3 : 2.f / 3) - GetStyle().WindowPadding.x * 1.5f; - float flHeight = H::Draw.Scale(28); - ImColor tColor = ColorToVec(_tTag.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha)); - ImVec2 vDrawPos = GetDrawPos() + vOriginalPos; - if (iID != _iID) - GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, tColor, H::Draw.Scale(4)); - else + // text + SetCursorPos({ vOriginalPos.x + H::Draw.Scale(9), vOriginalPos.y + H::Draw.Scale(7) }); + FText(TruncateText(_tTag.m_sName, _tTag.m_bLabel ? flWidth - H::Draw.Scale(38) : flWidth / 2 - H::Draw.Scale(20)).c_str()); + + if (!_tTag.m_bLabel) + { + SetCursorPos({ vOriginalPos.x + flWidth / 2, vOriginalPos.y + H::Draw.Scale(7) }); + FText(std::format("{}", _tTag.m_iPriority).c_str()); + } + + // buttons / icons + bool bDelete = false; + if (!_tTag.m_bLocked) + { + SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(26), vOriginalPos.y + H::Draw.Scale(2) }); + bDelete = IconButton(ICON_MD_DELETE); + } + else + { + SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(22), vOriginalPos.y + H::Draw.Scale(6) }); + switch (F::PlayerUtils.IndexToTag(_iID)) { - ImColor tColor2 = { tColor.Value.x * 1.1f, tColor.Value.y * 1.1f, tColor.Value.z * 1.1f, tColor.Value.w }; - GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, tColor2, H::Draw.Scale(4)); - - tColor2 = ColorToVec(_tTag.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.25f, LerpEnum::NoAlpha)); - float flInset = H::Draw.Scale(0.5f) - 0.5f; - GetWindowDrawList()->AddRect({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x - flInset + flWidth, vDrawPos.y - flInset + flHeight }, tColor2, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale()); + //case DEFAULT_TAG: // no image + case IGNORED_TAG: IconImage(ICON_MD_DO_NOT_DISTURB); break; + case CHEATER_TAG: IconImage(ICON_MD_FLAG); break; + case FRIEND_TAG: IconImage(ICON_MD_GROUP); break; + case PARTY_TAG: IconImage(ICON_MD_GROUPS); break; + case F2P_TAG: IconImage(ICON_MD_MONEY_OFF); break; } + } - // text - SetCursorPos({ vOriginalPos.x + H::Draw.Scale(9), vOriginalPos.y + H::Draw.Scale(7) }); - FText(TruncateText(_tTag.m_sName, _tTag.m_bLabel ? flWidth - H::Draw.Scale(38) : flWidth / 2 - H::Draw.Scale(20)).c_str()); + SetCursorPos(vOriginalPos); + bool bClicked = Button(std::format("##{}", _tTag.m_sName).c_str(), { flWidth, flHeight }); + bool bPopup = IsItemClicked(ImGuiMouseButton_Right); - if (!_tTag.m_bLabel) - { - SetCursorPos({ vOriginalPos.x + flWidth / 2, vOriginalPos.y + H::Draw.Scale(7) }); - FText(std::format("{}", _tTag.m_iPriority).c_str()); - } + if (bClicked) + { + iID = _iID; + tTag.m_sName = _tTag.m_sName; + tTag.m_tColor = _tTag.m_tColor; + tTag.m_iPriority = _tTag.m_iPriority; + tTag.m_bLabel = _tTag.m_bLabel; + } + else if (bPopup) + OpenPopup(std::format("RightClicked{}", _iID).c_str()); + else if (bDelete) + OpenPopup(std::format("DeleteTag{}", _iID).c_str()); + + if (FBeginPopup(std::format("RightClicked{}", _iID).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), 0 }); + + auto& _tTag2 = *it; + bool bSave = false; - // buttons / icons - bool bDelete = false; - if (!_tTag.m_bLocked) { - SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(26), vOriginalPos.y + H::Draw.Scale(2) }); - bDelete = IconButton(ICON_MD_DELETE); - } - else - { - SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(22), vOriginalPos.y + H::Draw.Scale(6) }); - switch (F::PlayerUtils.IndexToTag(_iID)) + static std::string sInput = ""; + + bool bEnter = FInputText("Name...", sInput, H::Draw.Scale(284), ImGuiInputTextFlags_EnterReturnsTrue); + if (!IsItemFocused()) + sInput = _tTag2.m_sName; + if (bEnter) { - //case DEFAULT_TAG: // no image - case IGNORED_TAG: IconImage(ICON_MD_DO_NOT_DISTURB); break; - case CHEATER_TAG: IconImage(ICON_MD_FLAG); break; - case FRIEND_TAG: IconImage(ICON_MD_GROUP); break; - case PARTY_TAG: IconImage(ICON_MD_GROUPS); break; - case F2P_TAG: IconImage(ICON_MD_MONEY_OFF); break; - } - } - - SetCursorPos(vOriginalPos); - bool bClicked = Button(std::format("##{}", _tTag.m_sName).c_str(), { flWidth, flHeight }); - bool bPopup = IsItemClicked(ImGuiMouseButton_Right); - - if (bClicked) - { - iID = _iID; - tTag.m_sName = _tTag.m_sName; - tTag.m_tColor = _tTag.m_tColor; - tTag.m_iPriority = _tTag.m_iPriority; - tTag.m_bLabel = _tTag.m_bLabel; - } - else if (bPopup) - OpenPopup(std::format("RightClicked{}", _iID).c_str()); - else if (bDelete) - OpenPopup(std::format("DeleteTag{}", _iID).c_str()); - - if (FBeginPopup(std::format("RightClicked{}", _iID).c_str())) - { - PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), 0 }); - - auto& _tTag2 = *it; - bool bSave = false; - - { - static std::string sInput = ""; - - bool bEnter = FInputText("Name...", sInput, H::Draw.Scale(284), ImGuiInputTextFlags_EnterReturnsTrue); - if (!IsItemFocused()) - sInput = _tTag2.m_sName; - if (bEnter) - { - _tTag2.m_sName = sInput; - bSave = true; - } - } - - PushDisabled(_iID == DEFAULT_TAG || _iID == IGNORED_TAG); - { - int iLabel = Disabled ? 0 : _tTag2.m_bLabel; - if (FDropdown("Type##", &iLabel, { "Priority", "Label" })) - bSave = true; - _tTag2.m_bLabel = iLabel; - if (Disabled) - _tTag2.m_bLabel = false; - } - PopDisabled(); - if (FSlider("Priority##", &_tTag2.m_iPriority, -10, 10)) + _tTag2.m_sName = sInput; bSave = true; - - if (bSave) - F::PlayerUtils.m_bSave = true; - - PopStyleVar(); - EndPopup(); + } } - else if (FBeginPopupModal(std::format("DeleteTag{}", _iID).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + + PushDisabled(_iID == DEFAULT_TAG || _iID == IGNORED_TAG); { - FText(std::format("Do you really want to delete '{}'?", _tTag.m_sName).c_str()); + int iLabel = Disabled ? 0 : _tTag2.m_bLabel; + if (FDropdown("Type##", &iLabel, { "Priority", "Label" })) + bSave = true; + _tTag2.m_bLabel = iLabel; + if (Disabled) + _tTag2.m_bLabel = false; + } + PopDisabled(); + if (FSlider("Priority##", &_tTag2.m_iPriority, -10, 10)) + bSave = true; - if (FButton("Yes", FButtonEnum::Left)) + if (bSave) + F::PlayerUtils.m_bSave = true; + + PopStyleVar(); + EndPopup(); + } + else if (FBeginPopupModal(std::format("DeleteTag{}", _iID).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + FText(std::format("Do you really want to delete '{}'?", _tTag.m_sName).c_str()); + + if (FButton("Yes", FButtonEnum::Left)) + { + F::PlayerUtils.m_vTags.erase(it); + F::PlayerUtils.m_bSave = F::PlayerUtils.m_bSave = true; + + for (auto& vTags : F::PlayerUtils.m_mPlayerTags | std::views::values) { - F::PlayerUtils.m_vTags.erase(it); - F::PlayerUtils.m_bSave = F::PlayerUtils.m_bSave = true; - - for (auto& [_, vTags] : F::PlayerUtils.m_mPlayerTags) + for (auto it = vTags.begin(); it != vTags.end();) { - for (auto it = vTags.begin(); it != vTags.end();) + if (_iID == *it) + vTags.erase(it); + else { - if (_iID == *it) - vTags.erase(it); - else - { - if (_iID < *it) - (*it)--; - it++; - } + if (_iID < *it) + (*it)--; + it++; } } - - if (iID == _iID) - { - iID = -1; - tTag = {}; - } - else if (iID > _iID) - iID--; - - CloseCurrentPopup(); } - if (FButton("No", FButtonEnum::Right | FButtonEnum::SameLine)) - CloseCurrentPopup(); - EndPopup(); + if (iID == _iID) + { + iID = -1; + tTag = {}; + } + else if (iID > _iID) + iID--; + + CloseCurrentPopup(); } - }; + if (FButton("No", FButtonEnum::Right | FButtonEnum::SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + }; PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); SetCursorPos({ H::Draw.Scale(13), H::Draw.Scale(80) }); FText("Priorities"); @@ -1875,38 +1883,38 @@ void CMenu::MenuLogs(int iTab) } std::sort(vPriorities.begin(), vPriorities.end(), [&](const auto& a, const auto& b) -> bool - { - // override for default tag - if (std::distance(F::PlayerUtils.m_vTags.begin(), a.first) == DEFAULT_TAG) - return true; - if (std::distance(F::PlayerUtils.m_vTags.begin(), b.first) == DEFAULT_TAG) - return false; + { + // override for default tag + if (std::distance(F::PlayerUtils.m_vTags.begin(), a.first) == DEFAULT_TAG) + return true; + if (std::distance(F::PlayerUtils.m_vTags.begin(), b.first) == DEFAULT_TAG) + return false; - // sort by priority if unequal - if (a.second.m_iPriority != b.second.m_iPriority) - return a.second.m_iPriority > b.second.m_iPriority; + // sort by priority if unequal + if (a.second.m_iPriority != b.second.m_iPriority) + return a.second.m_iPriority > b.second.m_iPriority; - return a.second.m_sName < b.second.m_sName; - }); + return a.second.m_sName < b.second.m_sName; + }); std::sort(vLabels.begin(), vLabels.end(), [&](const auto& a, const auto& b) -> bool - { - // sort by priority if unequal - if (a.second.m_iPriority != b.second.m_iPriority) - return a.second.m_iPriority > b.second.m_iPriority; + { + // sort by priority if unequal + if (a.second.m_iPriority != b.second.m_iPriority) + return a.second.m_iPriority > b.second.m_iPriority; - return a.second.m_sName < b.second.m_sName; - }); + return a.second.m_sName < b.second.m_sName; + }); // display tags int iPriorities = 0, iLabels = 0; for (auto& pair : vPriorities) { - drawTag(pair.first, pair.second, iPriorities); + fDrawTag(pair.first, pair.second, iPriorities); iPriorities++; } for (auto& pair : vLabels) { - drawTag(pair.first, pair.second, iLabels); + fDrawTag(pair.first, pair.second, iLabels); iLabels++; } SetCursorPos({ 0, H::Draw.Scale(60 + 36 * std::max(iPriorities, iLabels)) }); DebugDummy({ 0, H::Draw.Scale(28) }); @@ -1995,7 +2003,7 @@ void CMenu::MenuLogs(int iTab) for (auto& [sName, tChild] : *tSub) { uint32_t uAccountID = std::stoul(sName); - for (auto& [_, tTag] : tChild) + for (auto& tTag : tChild | std::views::values) { const std::string& sTag = tTag.data(); @@ -2340,153 +2348,153 @@ void CMenu::MenuSettings(int iTab) switch (iCurrentType) */ - auto drawConfigs = [](std::string& sStaticName, bool bVisual = false) + auto fDrawConfigs = [](std::string& sStaticName, bool bVisual = false) + { + auto& sPath = !bVisual ? F::Configs.m_sConfigPath : F::Configs.m_sVisualsPath; + auto& sConfig = !bVisual ? F::Configs.m_sCurrentConfig : F::Configs.m_sCurrentVisuals; + auto sType = !bVisual ? "Config" : "Visual"; + bool bNoSave = GetAsyncKeyState(VK_SHIFT) & 0x8000; + + FSDropdown("Name", &sStaticName, {}, FSDropdownEnum::AutoUpdate, -H::Draw.Unscale(FCalcTextSize("CREATE").x + FCalcTextSize("FOLDER").x) - 72); + PushDisabled(sStaticName.empty()); { - auto& sPath = !bVisual ? F::Configs.m_sConfigPath : F::Configs.m_sVisualsPath; - auto& sConfig = !bVisual ? F::Configs.m_sCurrentConfig : F::Configs.m_sCurrentVisuals; - auto sType = !bVisual ? "Config" : "Visual"; - bool bNoSave = GetAsyncKeyState(VK_SHIFT) & 0x8000; - - FSDropdown("Name", &sStaticName, {}, FSDropdownEnum::AutoUpdate, -H::Draw.Unscale(FCalcTextSize("CREATE").x + FCalcTextSize("FOLDER").x) - 72); - PushDisabled(sStaticName.empty()); + if (FButton("Create", FButtonEnum::Fit | FButtonEnum::SameLine, { 0, 40 })) { - if (FButton("Create", FButtonEnum::Fit | FButtonEnum::SameLine, { 0, 40 })) - { - if (!std::filesystem::exists(sPath + sStaticName)) - { - if (!bVisual) - F::Configs.SaveConfig(sStaticName); - else - F::Configs.SaveVisual(sStaticName); - } - sStaticName.clear(); - } - } - PopDisabled(); - if (FButton("Folder", FButtonEnum::Fit | FButtonEnum::SameLine, { 0, 40 })) - ShellExecuteA(NULL, NULL, sPath.c_str(), NULL, NULL, SW_SHOWNORMAL); - vRowSizes.clear(); - - std::vector> vConfigs = {}; - bool bDefaultFound = false; - for (auto& tEntry : std::filesystem::directory_iterator(sPath)) - { - if (!tEntry.is_regular_file() || tEntry.path().extension() != F::Configs.m_sConfigExtension) - continue; - - std::string sName = tEntry.path().filename().string(); - sName.erase(sName.end() - F::Configs.m_sConfigExtension.size(), sName.end()); - if (FNV1A::Hash32(sName.c_str()) == FNV1A::Hash32Const("default")) - bDefaultFound = true; - - vConfigs.emplace_back(tEntry, sName); - } - if (!bVisual) - { - if (!bDefaultFound) - F::Configs.SaveConfig("default"); - std::sort(vConfigs.begin(), vConfigs.end(), [&](const auto& a, const auto& b) -> bool - { - // override for default config - if (FNV1A::Hash32(a.second.c_str()) == FNV1A::Hash32Const("default")) - return true; - if (FNV1A::Hash32(b.second.c_str()) == FNV1A::Hash32Const("default")) - return false; - - return a.second < b.second; - }); - } - - for (auto& [entry, sConfigName] : vConfigs) - { - bool bCurrentConfig = FNV1A::Hash32(sConfigName.c_str()) == FNV1A::Hash32(sConfig.c_str()); - ImVec2 vOriginalPos = GetCursorPos(); - - SetCursorPos({ vOriginalPos.x + H::Draw.Scale(2), vOriginalPos.y + H::Draw.Scale(9) }); - bool bLoad = IconButton(bCurrentConfig ? ICON_MD_REFRESH : ICON_MD_DOWNLOAD); - FTooltip(ICON_MD_ADD ICON_MD_FILE_UPLOAD_OFF, bNoSave && IsItemHovered(), 300.f, F::Render.IconFont); - - SetCursorPos({ H::Draw.Scale(43), vOriginalPos.y + H::Draw.Scale(14) }); - TextColored(bCurrentConfig ? F::Render.Active.Value : F::Render.Inactive.Value, TruncateText(sConfigName, GetWindowWidth() - GetStyle().WindowPadding.x * 2 - H::Draw.Scale(80)).c_str()); - - int iOffset = 9; - SetCursorPos({ GetWindowWidth() - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(9) }); - bool bDelete = IconButton(ICON_MD_DELETE); - - SetCursorPos({ GetWindowWidth() - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(9) }); - bool bSave = IconButton(ICON_MD_SAVE); - FTooltip(ICON_MD_ADD ICON_MD_FILE_DOWNLOAD_OFF, bNoSave && IsItemHovered(), 300.f, F::Render.IconFont); - - if (bLoad) + if (!std::filesystem::exists(sPath + sStaticName)) { if (!bVisual) - F::Configs.LoadConfig(sConfigName); + F::Configs.SaveConfig(sStaticName); else - F::Configs.LoadVisual(sConfigName); + F::Configs.SaveVisual(sStaticName); } - else if (bSave) + sStaticName.clear(); + } + } + PopDisabled(); + if (FButton("Folder", FButtonEnum::Fit | FButtonEnum::SameLine, { 0, 40 })) + ShellExecuteA(NULL, NULL, sPath.c_str(), NULL, NULL, SW_SHOWNORMAL); + vRowSizes.clear(); + + std::vector> vConfigs = {}; + bool bDefaultFound = false; + for (auto& tEntry : std::filesystem::directory_iterator(sPath)) + { + if (!tEntry.is_regular_file() || tEntry.path().extension() != F::Configs.m_sConfigExtension) + continue; + + std::string sName = tEntry.path().filename().string(); + sName.erase(sName.end() - F::Configs.m_sConfigExtension.size(), sName.end()); + if (FNV1A::Hash32(sName.c_str()) == FNV1A::Hash32Const("default")) + bDefaultFound = true; + + vConfigs.emplace_back(tEntry, sName); + } + if (!bVisual) + { + if (!bDefaultFound) + F::Configs.SaveConfig("default"); + std::sort(vConfigs.begin(), vConfigs.end(), [&](const auto& a, const auto& b) -> bool + { + // override for default config + if (FNV1A::Hash32(a.second.c_str()) == FNV1A::Hash32Const("default")) + return true; + if (FNV1A::Hash32(b.second.c_str()) == FNV1A::Hash32Const("default")) + return false; + + return a.second < b.second; + }); + } + + for (auto& [entry, sConfigName] : vConfigs) + { + bool bCurrentConfig = FNV1A::Hash32(sConfigName.c_str()) == FNV1A::Hash32(sConfig.c_str()); + ImVec2 vOriginalPos = GetCursorPos(); + + SetCursorPos({ vOriginalPos.x + H::Draw.Scale(2), vOriginalPos.y + H::Draw.Scale(9) }); + bool bLoad = IconButton(bCurrentConfig ? ICON_MD_REFRESH : ICON_MD_DOWNLOAD); + FTooltip(ICON_MD_ADD ICON_MD_FILE_UPLOAD_OFF, bNoSave && IsItemHovered(), 300.f, F::Render.IconFont); + + SetCursorPos({ H::Draw.Scale(43), vOriginalPos.y + H::Draw.Scale(14) }); + TextColored(bCurrentConfig ? F::Render.Active.Value : F::Render.Inactive.Value, TruncateText(sConfigName, GetWindowWidth() - GetStyle().WindowPadding.x * 2 - H::Draw.Scale(80)).c_str()); + + int iOffset = 9; + SetCursorPos({ GetWindowWidth() - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(9) }); + bool bDelete = IconButton(ICON_MD_DELETE); + + SetCursorPos({ GetWindowWidth() - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(9) }); + bool bSave = IconButton(ICON_MD_SAVE); + FTooltip(ICON_MD_ADD ICON_MD_FILE_DOWNLOAD_OFF, bNoSave && IsItemHovered(), 300.f, F::Render.IconFont); + + if (bLoad) + { + if (!bVisual) + F::Configs.LoadConfig(sConfigName); + else + F::Configs.LoadVisual(sConfigName); + } + else if (bSave) + { + if (!bCurrentConfig || !bVisual && !F::Configs.m_sCurrentVisuals.empty()) + OpenPopup(std::format("Save{}{}", sType, sConfigName).c_str()); + else if (!bVisual) + F::Configs.SaveConfig(sConfigName); + else + F::Configs.SaveVisual(sConfigName); + } + else if (bDelete) + OpenPopup(std::format("Remove{}{}", sType, sConfigName).c_str()); + + if (FBeginPopupModal(std::format("Save{}{}", sType, sConfigName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + FText(std::format("Do you really want to override '{}'?", sConfigName).c_str()); + + if (FButton("Yes, override", FButtonEnum::Left)) { - if (!bCurrentConfig || !bVisual && !F::Configs.m_sCurrentVisuals.empty()) - OpenPopup(std::format("Save{}{}", sType, sConfigName).c_str()); - else if (!bVisual) + if (!bVisual) F::Configs.SaveConfig(sConfigName); else F::Configs.SaveVisual(sConfigName); + CloseCurrentPopup(); } - else if (bDelete) - OpenPopup(std::format("Remove{}{}", sType, sConfigName).c_str()); + if (FButton("No", FButtonEnum::Right | FButtonEnum::SameLine)) + CloseCurrentPopup(); - if (FBeginPopupModal(std::format("Save{}{}", sType, sConfigName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - FText(std::format("Do you really want to override '{}'?", sConfigName).c_str()); - - if (FButton("Yes, override", FButtonEnum::Left)) - { - if (!bVisual) - F::Configs.SaveConfig(sConfigName); - else - F::Configs.SaveVisual(sConfigName); - CloseCurrentPopup(); - } - if (FButton("No", FButtonEnum::Right | FButtonEnum::SameLine)) - CloseCurrentPopup(); - - EndPopup(); - } - else if (FBeginPopupModal(std::format("Remove{}{}", sType, sConfigName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - FText(std::format("Do you really want to remove '{}'?", sConfigName).c_str()); - - PushDisabled(!bVisual && FNV1A::Hash32(sConfigName.c_str()) == FNV1A::Hash32Const("default")); - { - if (FButton("Yes, delete", FButtonEnum::Fit)) - { - if (!bVisual) - F::Configs.DeleteConfig(sConfigName); - else - F::Configs.DeleteVisual(sConfigName); - CloseCurrentPopup(); - } - } - PopDisabled(); - if (FButton("Yes, reset", FButtonEnum::Fit | FButtonEnum::SameLine)) - { - if (!bVisual) - F::Configs.ResetConfig(sConfigName); - else - F::Configs.ResetVisual(sConfigName); - CloseCurrentPopup(); - } - if (FButton("No", FButtonEnum::Fit | FButtonEnum::SameLine)) - CloseCurrentPopup(); - - EndPopup(); - } - - SetCursorPos(vOriginalPos); DebugDummy({ 0, H::Draw.Scale(28) }); + EndPopup(); } - DebugDummy({ 0, H::Draw.Scale(7) }); - }; + else if (FBeginPopupModal(std::format("Remove{}{}", sType, sConfigName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + FText(std::format("Do you really want to remove '{}'?", sConfigName).c_str()); + + PushDisabled(!bVisual && FNV1A::Hash32(sConfigName.c_str()) == FNV1A::Hash32Const("default")); + { + if (FButton("Yes, delete", FButtonEnum::Fit)) + { + if (!bVisual) + F::Configs.DeleteConfig(sConfigName); + else + F::Configs.DeleteVisual(sConfigName); + CloseCurrentPopup(); + } + } + PopDisabled(); + if (FButton("Yes, reset", FButtonEnum::Fit | FButtonEnum::SameLine)) + { + if (!bVisual) + F::Configs.ResetConfig(sConfigName); + else + F::Configs.ResetVisual(sConfigName); + CloseCurrentPopup(); + } + if (FButton("No", FButtonEnum::Fit | FButtonEnum::SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + + SetCursorPos(vOriginalPos); DebugDummy({ 0, H::Draw.Scale(28) }); + } + DebugDummy({ 0, H::Draw.Scale(7) }); + }; /* Column 1 */ TableNextColumn(); @@ -2494,7 +2502,7 @@ void CMenu::MenuSettings(int iTab) { static std::string sStaticName; - drawConfigs(sStaticName); + fDrawConfigs(sStaticName); } EndSection(); PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); SetCursorPosX(GetCursorPosX() + GetStyle().WindowPadding.x); @@ -2509,7 +2517,7 @@ void CMenu::MenuSettings(int iTab) { static std::string sStaticName; - drawConfigs(sStaticName, true); + fDrawConfigs(sStaticName, true); } EndSection(); EndTable(); @@ -2609,46 +2617,46 @@ void CMenu::MenuSettings(int iTab) SetCursorPosY(GetCursorPosY() - H::Draw.Scale(5)); PopStyleColor(); - auto numberToIndex = [](int iNumber, int iLayer) + auto fNumberToIndex = [](int iNumber, int iLayer) + { + int iIndex = -1, i = -1; + + std::unordered_map mBinds = {}; + std::function fGetBinds = [&](int iParent) { - int iIndex = -1, i = -1; + for (int _iBind = 0; _iBind < F::Binds.m_vBinds.size(); _iBind++) + { + auto& _tBind = F::Binds.m_vBinds[_iBind]; + if (iParent != _tBind.m_iParent || mBinds.contains(_iBind)) + continue; - std::unordered_map mBinds = {}; - std::function getBinds = [&](int iParent) - { - for (int _iBind = 0; _iBind < F::Binds.m_vBinds.size(); _iBind++) - { - auto& _tBind = F::Binds.m_vBinds[_iBind]; - if (iParent != _tBind.m_iParent || mBinds.contains(_iBind)) - continue; + mBinds[_iBind]; - mBinds[_iBind]; - - i++; - //if (iParent == iLayer && iNumber >= i) - if (iIndex == -1 && iParent == iLayer && iNumber <= i) - iIndex = _iBind; - getBinds(_iBind); - } - }; - getBinds(DEFAULT_BIND); - - return iIndex; - }; - auto positionToIndex = [&](ImVec2 vPos, int iLayer = DEFAULT_BIND) - { - int iIndex = floorf((vPos.y - GetCursorPosY() - H::Draw.Scale(4)) / H::Draw.Scale(36)); - iIndex = std::clamp(iIndex, 0, int(F::Binds.m_vBinds.size() - 1)); - iIndex = numberToIndex(iIndex, iLayer); - return iIndex; + i++; + //if (iParent == iLayer && iNumber >= i) + if (iIndex == -1 && iParent == iLayer && iNumber <= i) + iIndex = _iBind; + fGetBinds(_iBind); + } }; + fGetBinds(DEFAULT_BIND); + + return iIndex; + }; + auto fPositionToIndex = [&](ImVec2 vPos, int iLayer = DEFAULT_BIND) + { + int iIndex = floorf((vPos.y - GetCursorPosY() - H::Draw.Scale(4)) / H::Draw.Scale(36)); + iIndex = std::clamp(iIndex, 0, int(F::Binds.m_vBinds.size() - 1)); + iIndex = fNumberToIndex(iIndex, iLayer); + return iIndex; + }; static int iDragging = -1, iLayer = DEFAULT_BIND; if (!IsMouseDown(ImGuiMouseButton_Left)) iDragging = -1; else if (iDragging != -1) { - int iTo = positionToIndex(GetMousePos() - GetDrawPos(), iLayer); + int iTo = fPositionToIndex(GetMousePos() - GetDrawPos(), iLayer); if (iTo != -1 && iDragging != iTo) { F::Binds.Move(iDragging, iTo); @@ -2657,241 +2665,241 @@ void CMenu::MenuSettings(int iTab) } std::unordered_map mBinds = {}; - std::function getBinds = [&](int iParent, int x) + std::function fGetBinds = [&](int iParent, int x) + { + for (int _iBind = 0; _iBind < F::Binds.m_vBinds.size(); _iBind++) { - for (int _iBind = 0; _iBind < F::Binds.m_vBinds.size(); _iBind++) + auto& _tBind = F::Binds.m_vBinds[_iBind]; + if (iParent != DEFAULT_BIND - 1 && iParent != _tBind.m_iParent || mBinds.contains(_iBind)) + continue; + + mBinds[_iBind]; + + std::string sType; std::string sInfo; + switch (_tBind.m_iType) { - auto& _tBind = F::Binds.m_vBinds[_iBind]; - if (iParent != DEFAULT_BIND - 1 && iParent != _tBind.m_iParent || mBinds.contains(_iBind)) - continue; - - mBinds[_iBind]; - - std::string sType; std::string sInfo; - switch (_tBind.m_iType) + case BindEnum::Key: + switch (_tBind.m_iInfo) { - case BindEnum::Key: + case BindEnum::KeyEnum::Hold: { sType = "hold"; break; } + case BindEnum::KeyEnum::Toggle: { sType = "toggle"; break; } + case BindEnum::KeyEnum::DoubleClick: { sType = "double"; break; } + } + sInfo = VK2STR(_tBind.m_iKey); + break; + case BindEnum::Class: + sType = "class"; + switch (_tBind.m_iInfo) + { + case BindEnum::ClassEnum::Scout: { sInfo = "scout"; break; } + case BindEnum::ClassEnum::Soldier: { sInfo = "soldier"; break; } + case BindEnum::ClassEnum::Pyro: { sInfo = "pyro"; break; } + case BindEnum::ClassEnum::Demoman: { sInfo = "demoman"; break; } + case BindEnum::ClassEnum::Heavy: { sInfo = "heavy"; break; } + case BindEnum::ClassEnum::Engineer: { sInfo = "engineer"; break; } + case BindEnum::ClassEnum::Medic: { sInfo = "medic"; break; } + case BindEnum::ClassEnum::Sniper: { sInfo = "sniper"; break; } + case BindEnum::ClassEnum::Spy: { sInfo = "spy"; break; } + } + break; + case BindEnum::WeaponType: + sType = "weapon"; + switch (_tBind.m_iInfo) + { + case BindEnum::WeaponTypeEnum::Hitscan: { sInfo = "hitscan"; break; } + case BindEnum::WeaponTypeEnum::Projectile: { sInfo = "projectile"; break; } + case BindEnum::WeaponTypeEnum::Melee: { sInfo = "melee"; break; } + case BindEnum::WeaponTypeEnum::Throwable: { sInfo = "throwable"; break; } + } + break; + case BindEnum::ItemSlot: + sType = "slot"; + sInfo = std::format("{}", _tBind.m_iInfo + 1); + break; + case BindEnum::Misc: + switch (_tBind.m_iInfo) + { + case BindEnum::MiscEnum::Spectated: + case BindEnum::MiscEnum::SpectatedFirst: + case BindEnum::MiscEnum::SpectatedThird: + sType = "spectated"; switch (_tBind.m_iInfo) { - case BindEnum::KeyEnum::Hold: { sType = "hold"; break; } - case BindEnum::KeyEnum::Toggle: { sType = "toggle"; break; } - case BindEnum::KeyEnum::DoubleClick: { sType = "double"; break; } - } - sInfo = VK2STR(_tBind.m_iKey); - break; - case BindEnum::Class: - sType = "class"; - switch (_tBind.m_iInfo) - { - case BindEnum::ClassEnum::Scout: { sInfo = "scout"; break; } - case BindEnum::ClassEnum::Soldier: { sInfo = "soldier"; break; } - case BindEnum::ClassEnum::Pyro: { sInfo = "pyro"; break; } - case BindEnum::ClassEnum::Demoman: { sInfo = "demoman"; break; } - case BindEnum::ClassEnum::Heavy: { sInfo = "heavy"; break; } - case BindEnum::ClassEnum::Engineer: { sInfo = "engineer"; break; } - case BindEnum::ClassEnum::Medic: { sInfo = "medic"; break; } - case BindEnum::ClassEnum::Sniper: { sInfo = "sniper"; break; } - case BindEnum::ClassEnum::Spy: { sInfo = "spy"; break; } + case BindEnum::MiscEnum::Spectated: { sInfo = "any"; break; } + case BindEnum::MiscEnum::SpectatedFirst: { sInfo = "1st"; break; } + case BindEnum::MiscEnum::SpectatedThird: { sInfo = "3rd"; break; } } break; - case BindEnum::WeaponType: - sType = "weapon"; + case BindEnum::MiscEnum::Zoomed: + case BindEnum::MiscEnum::Aiming: + sType = "cond"; switch (_tBind.m_iInfo) { - case BindEnum::WeaponTypeEnum::Hitscan: { sInfo = "hitscan"; break; } - case BindEnum::WeaponTypeEnum::Projectile: { sInfo = "projectile"; break; } - case BindEnum::WeaponTypeEnum::Melee: { sInfo = "melee"; break; } - case BindEnum::WeaponTypeEnum::Throwable: { sInfo = "throwable"; break; } - } - break; - case BindEnum::ItemSlot: - sType = "slot"; - sInfo = std::format("{}", _tBind.m_iInfo + 1); - break; - case BindEnum::Misc: - switch (_tBind.m_iInfo) - { - case BindEnum::MiscEnum::Spectated: - case BindEnum::MiscEnum::SpectatedFirst: - case BindEnum::MiscEnum::SpectatedThird: - sType = "spectated"; - switch (_tBind.m_iInfo) - { - case BindEnum::MiscEnum::Spectated: { sInfo = "any"; break; } - case BindEnum::MiscEnum::SpectatedFirst: { sInfo = "1st"; break; } - case BindEnum::MiscEnum::SpectatedThird: { sInfo = "3rd"; break; } - } - break; - case BindEnum::MiscEnum::Zoomed: - case BindEnum::MiscEnum::Aiming: - sType = "cond"; - switch (_tBind.m_iInfo) - { - case BindEnum::MiscEnum::Zoomed: { sInfo = "zoomed"; break; } - case BindEnum::MiscEnum::Aiming: { sInfo = "aiming"; break; } - } - break; + case BindEnum::MiscEnum::Zoomed: { sInfo = "zoomed"; break; } + case BindEnum::MiscEnum::Aiming: { sInfo = "aiming"; break; } } break; } - if (_tBind.m_bNot && (_tBind.m_iType != BindEnum::Key || _tBind.m_iInfo == BindEnum::KeyEnum::Hold)) - sType = std::format("not {}", sType); + break; + } + if (_tBind.m_bNot && (_tBind.m_iType != BindEnum::Key || _tBind.m_iInfo == BindEnum::KeyEnum::Hold)) + sType = std::format("not {}", sType); - ImVec2 vOriginalPos = { H::Draw.Scale(8) + H::Draw.Scale(28) * std::min(x, 3), GetCursorPosY() + H::Draw.Scale(8) }; + ImVec2 vOriginalPos = { H::Draw.Scale(8) + H::Draw.Scale(28) * std::min(x, 3), GetCursorPosY() + H::Draw.Scale(8) }; - // background - float flWidth = GetWindowWidth() - GetStyle().WindowPadding.x * 2 - H::Draw.Scale(28) * std::min(x, 3); - float flHeight = H::Draw.Scale(28); - ImVec2 vDrawPos = GetDrawPos() + vOriginalPos; - if (iBind != _iBind) - GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, F::Render.Background1p5, H::Draw.Scale(4)); + // background + float flWidth = GetWindowWidth() - GetStyle().WindowPadding.x * 2 - H::Draw.Scale(28) * std::min(x, 3); + float flHeight = H::Draw.Scale(28); + ImVec2 vDrawPos = GetDrawPos() + vOriginalPos; + if (iBind != _iBind) + GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, F::Render.Background1p5, H::Draw.Scale(4)); + else + { + ImColor tColor = F::Render.Background1p5L; + GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, tColor, H::Draw.Scale(4)); + + tColor = ColorToVec((VecToColor(F::Render.Background1p5)).Lerp({ 127, 127, 127 }, 1.f / 9, LerpEnum::NoAlpha)); + float flInset = H::Draw.Scale(0.5f) - 0.5f; + GetWindowDrawList()->AddRect({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x - flInset + flWidth, vDrawPos.y - flInset + flHeight }, tColor, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale()); + } + + // text + if (x > 3) + { // don't indent too much + auto sText = std::format("-> {}", x); + SetCursorPos({ vOriginalPos.x - FCalcTextSize(sText.c_str()).x - H::Draw.Scale(10), vOriginalPos.y + H::Draw.Scale(7) }); + FText(sText.c_str()); + } + + float flTextWidth = flWidth - H::Draw.Scale(127); + PushTransparent(!F::Binds.WillBeEnabled(_iBind), true); + + SetCursorPos({ vOriginalPos.x + H::Draw.Scale(9), vOriginalPos.y + H::Draw.Scale(7) }); + FText(TruncateText(_tBind.m_sName, flTextWidth * (1.f / 3) - H::Draw.Scale(20)).c_str()); + + SetCursorPos({ vOriginalPos.x + flTextWidth * (1.f / 3), vOriginalPos.y + H::Draw.Scale(7) }); + FText(sType.c_str()); + + SetCursorPos({ vOriginalPos.x + flTextWidth * (2.f / 3), vOriginalPos.y + H::Draw.Scale(7) }); + FText(sInfo.c_str()); + + // buttons + int iOffset = 1; + + SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); + bool bDelete = IconButton(ICON_MD_DELETE); + + SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); + if (IconButton(ICON_MD_EDIT)) + CurrentBind = CurrentBind != _iBind ? _iBind : DEFAULT_BIND; + + SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); + if (IconButton(!_tBind.m_bNot ? ICON_MD_CODE : ICON_MD_CODE_OFF)) + _tBind.m_bNot = !_tBind.m_bNot; + + PushTransparent(Transparent || _tBind.m_iVisibility == BindVisibilityEnum::Hidden, true); + SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); + if (IconButton(_tBind.m_iVisibility == BindVisibilityEnum::Always ? ICON_MD_VISIBILITY : ICON_MD_VISIBILITY_OFF)) + _tBind.m_iVisibility = (_tBind.m_iVisibility + 1) % 3; + PopTransparent(1, 1); + + SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); + if (IconButton(_tBind.m_bEnabled ? ICON_MD_TOGGLE_ON : ICON_MD_TOGGLE_OFF)) + _tBind.m_bEnabled = !_tBind.m_bEnabled; + + SetCursorPos(vOriginalPos); + bool bClicked = Button(std::format("##{}", _iBind).c_str(), { flWidth, flHeight }); + bool bPopup = IsItemClicked(ImGuiMouseButton_Right); + + PopTransparent(1, 1); + + if (bClicked) + { + if (!bParent) + { + iBind = _iBind; + tBind = _tBind; + } else { - ImColor tColor = F::Render.Background1p5L; - GetWindowDrawList()->AddRectFilled(vDrawPos, { vDrawPos.x + flWidth, vDrawPos.y + flHeight }, tColor, H::Draw.Scale(4)); + bParent = false; + tBind.m_iParent = _iBind; - tColor = ColorToVec((VecToColor(F::Render.Background1p5)).Lerp({ 127, 127, 127 }, 1.f / 9, LerpEnum::NoAlpha)); - float flInset = H::Draw.Scale(0.5f) - 0.5f; - GetWindowDrawList()->AddRect({ vDrawPos.x + flInset, vDrawPos.y + flInset }, { vDrawPos.x - flInset + flWidth, vDrawPos.y - flInset + flHeight }, tColor, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale()); - } - - // text - if (x > 3) - { // don't indent too much - auto sText = std::format("-> {}", x); - SetCursorPos({ vOriginalPos.x - FCalcTextSize(sText.c_str()).x - H::Draw.Scale(10), vOriginalPos.y + H::Draw.Scale(7) }); - FText(sText.c_str()); - } - - float flTextWidth = flWidth - H::Draw.Scale(127); - PushTransparent(!F::Binds.WillBeEnabled(_iBind), true); - - SetCursorPos({ vOriginalPos.x + H::Draw.Scale(9), vOriginalPos.y + H::Draw.Scale(7) }); - FText(TruncateText(_tBind.m_sName, flTextWidth * (1.f / 3) - H::Draw.Scale(20)).c_str()); - - SetCursorPos({ vOriginalPos.x + flTextWidth * (1.f / 3), vOriginalPos.y + H::Draw.Scale(7) }); - FText(sType.c_str()); - - SetCursorPos({ vOriginalPos.x + flTextWidth * (2.f / 3), vOriginalPos.y + H::Draw.Scale(7) }); - FText(sInfo.c_str()); - - // buttons - int iOffset = 1; - - SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); - bool bDelete = IconButton(ICON_MD_DELETE); - - SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); - if (IconButton(ICON_MD_EDIT)) - CurrentBind = CurrentBind != _iBind ? _iBind : DEFAULT_BIND; - - SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); - if (IconButton(!_tBind.m_bNot ? ICON_MD_CODE : ICON_MD_CODE_OFF)) - _tBind.m_bNot = !_tBind.m_bNot; - - PushTransparent(Transparent || _tBind.m_iVisibility == BindVisibilityEnum::Hidden, true); - SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); - if (IconButton(_tBind.m_iVisibility == BindVisibilityEnum::Always ? ICON_MD_VISIBILITY : ICON_MD_VISIBILITY_OFF)) - _tBind.m_iVisibility = (_tBind.m_iVisibility + 1) % 3; - PopTransparent(1, 1); - - SetCursorPos({ vOriginalPos.x + flWidth - H::Draw.Scale(iOffset += 25), vOriginalPos.y + H::Draw.Scale(2) }); - if (IconButton(_tBind.m_bEnabled ? ICON_MD_TOGGLE_ON : ICON_MD_TOGGLE_OFF)) - _tBind.m_bEnabled = !_tBind.m_bEnabled; - - SetCursorPos(vOriginalPos); - bool bClicked = Button(std::format("##{}", _iBind).c_str(), { flWidth, flHeight }); - bool bPopup = IsItemClicked(ImGuiMouseButton_Right); - - PopTransparent(1, 1); - - if (bClicked) - { - if (!bParent) + // make sure bind can't be parented to itself or any of its children + int _iBind2 = _iBind; + Bind_t _tBind2; + while (F::Binds.GetBind(_iBind2, &_tBind2)) { - iBind = _iBind; - tBind = _tBind; - } - else - { - bParent = false; - tBind.m_iParent = _iBind; - - // make sure bind can't be parented to itself or any of its children - int _iBind2 = _iBind; - Bind_t _tBind2; - while (F::Binds.GetBind(_iBind2, &_tBind2)) - { - if (_iBind2 == iBind) - tBind.m_iParent = DEFAULT_BIND; - _iBind2 = _tBind2.m_iParent; - } + if (_iBind2 == iBind) + tBind.m_iParent = DEFAULT_BIND; + _iBind2 = _tBind2.m_iParent; } } - else if (bPopup) - OpenPopup(std::format("RightClicked{}", _iBind).c_str()); - else if (iDragging == -1 && IsItemHovered() && IsMouseDown(ImGuiMouseButton_Left)) - iDragging = _iBind, iLayer = iParent; - else if (bDelete) - { - if (U::KeyHandler.Down(VK_SHIFT)) // allow user to quickly remove binds - F::Binds.RemoveBind(_iBind); - else - OpenPopup(std::format("DeleteBind{}", _iBind).c_str()); - } - - if (FBeginPopup(std::format("RightClicked{}", _iBind).c_str())) - { - PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), 0 }); - - { - static std::string sInput = ""; - - bool bEnter = FInputText("Name...", sInput, H::Draw.Scale(284), ImGuiInputTextFlags_EnterReturnsTrue); - if (!IsItemFocused()) - sInput = _tBind.m_sName; - if (bEnter) - _tBind.m_sName = sInput; - } - - FDropdown("Type", &_tBind.m_iType, { "Key", "Class", "Weapon type", "Item slot", "Misc" }, {}, FDropdownEnum::Left); - switch (_tBind.m_iType) - { - case BindEnum::Key: FDropdown("Behavior", &_tBind.m_iInfo, { "Hold", "Toggle", "Double click" }, {}, FDropdownEnum::Right); break; - case BindEnum::Class: FDropdown("Class", &_tBind.m_iInfo, { "Scout", "Soldier", "Pyro", "Demoman", "Heavy", "Engineer", "Medic", "Sniper", "Spy" }, {}, FDropdownEnum::Right); break; - case BindEnum::WeaponType: FDropdown("Weapon type", &_tBind.m_iInfo, { "Hitscan", "Projectile", "Melee", "Throwable" }, {}, FDropdownEnum::Right); break; - case BindEnum::ItemSlot: FDropdown("Item slot", &_tBind.m_iInfo, { "1", "2", "3", "4", "5", "6", "7", "8", "9" }, {}, FDropdownEnum::Right); break; - case BindEnum::Misc: FDropdown("Misc", &_tBind.m_iInfo, { "Spectated", "Spectated 1st", "Spectated 3rd", "##Divider", "Zoomed", "Aiming" }, {}, FDropdownEnum::Right); break; - } - if (_tBind.m_iType == BindEnum::Key) - FKeybind("Key", _tBind.m_iKey); - - PopStyleVar(); - EndPopup(); - } - else if (FBeginPopupModal(std::format("DeleteBind{}", _iBind).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - FText(std::format("Do you really want to delete '{}'{}?", _tBind.m_sName, F::Binds.HasChildren(_iBind) ? " and all of its children" : "").c_str()); - - if (FButton("Yes", FButtonEnum::Left)) - { - F::Binds.RemoveBind(_iBind); - CloseCurrentPopup(); - - iBind = DEFAULT_BIND; - tBind = {}; - } - if (FButton("No", FButtonEnum::Right | FButtonEnum::SameLine)) - CloseCurrentPopup(); - - EndPopup(); - } - - if (iParent != DEFAULT_BIND - 1) - getBinds(_iBind, x + 1); } - }; - getBinds(DEFAULT_BIND, 0); + else if (bPopup) + OpenPopup(std::format("RightClicked{}", _iBind).c_str()); + else if (iDragging == -1 && IsItemHovered() && IsMouseDown(ImGuiMouseButton_Left)) + iDragging = _iBind, iLayer = iParent; + else if (bDelete) + { + if (U::KeyHandler.Down(VK_SHIFT)) // allow user to quickly remove binds + F::Binds.RemoveBind(_iBind); + else + OpenPopup(std::format("DeleteBind{}", _iBind).c_str()); + } + + if (FBeginPopup(std::format("RightClicked{}", _iBind).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), 0 }); + + { + static std::string sInput = ""; + + bool bEnter = FInputText("Name...", sInput, H::Draw.Scale(284), ImGuiInputTextFlags_EnterReturnsTrue); + if (!IsItemFocused()) + sInput = _tBind.m_sName; + if (bEnter) + _tBind.m_sName = sInput; + } + + FDropdown("Type", &_tBind.m_iType, { "Key", "Class", "Weapon type", "Item slot", "Misc" }, {}, FDropdownEnum::Left); + switch (_tBind.m_iType) + { + case BindEnum::Key: FDropdown("Behavior", &_tBind.m_iInfo, { "Hold", "Toggle", "Double click" }, {}, FDropdownEnum::Right); break; + case BindEnum::Class: FDropdown("Class", &_tBind.m_iInfo, { "Scout", "Soldier", "Pyro", "Demoman", "Heavy", "Engineer", "Medic", "Sniper", "Spy" }, {}, FDropdownEnum::Right); break; + case BindEnum::WeaponType: FDropdown("Weapon type", &_tBind.m_iInfo, { "Hitscan", "Projectile", "Melee", "Throwable" }, {}, FDropdownEnum::Right); break; + case BindEnum::ItemSlot: FDropdown("Item slot", &_tBind.m_iInfo, { "1", "2", "3", "4", "5", "6", "7", "8", "9" }, {}, FDropdownEnum::Right); break; + case BindEnum::Misc: FDropdown("Misc", &_tBind.m_iInfo, { "Spectated", "Spectated 1st", "Spectated 3rd", "##Divider", "Zoomed", "Aiming" }, {}, FDropdownEnum::Right); break; + } + if (_tBind.m_iType == BindEnum::Key) + FKeybind("Key", _tBind.m_iKey); + + PopStyleVar(); + EndPopup(); + } + else if (FBeginPopupModal(std::format("DeleteBind{}", _iBind).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + FText(std::format("Do you really want to delete '{}'{}?", _tBind.m_sName, F::Binds.HasChildren(_iBind) ? " and all of its children" : "").c_str()); + + if (FButton("Yes", FButtonEnum::Left)) + { + F::Binds.RemoveBind(_iBind); + CloseCurrentPopup(); + + iBind = DEFAULT_BIND; + tBind = {}; + } + if (FButton("No", FButtonEnum::Right | FButtonEnum::SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + + if (iParent != DEFAULT_BIND - 1) + fGetBinds(_iBind, x + 1); + } + }; + fGetBinds(DEFAULT_BIND, 0); // this should ideally never happen, but failsafe if (F::Binds.m_vBinds.size() > mBinds.size()) @@ -2902,7 +2910,7 @@ void CMenu::MenuSettings(int iTab) SetCursorPosY(GetCursorPosY() - H::Draw.Scale(5)); PopStyleColor(); - getBinds(DEFAULT_BIND - 1, 0); + fGetBinds(DEFAULT_BIND - 1, 0); } if (bParent == 2) // dumb @@ -2953,25 +2961,25 @@ void CMenu::MenuSettings(int iTab) ShellExecuteA(NULL, NULL, F::Configs.m_sMaterialsPath.c_str(), NULL, NULL, SW_SHOWNORMAL); std::vector vMaterials; - for (auto& [_, mat] : F::Materials.m_mMaterials) - vMaterials.push_back(mat); + for (auto& tMaterial : F::Materials.m_mMaterials | std::views::values) + vMaterials.push_back(tMaterial); std::sort(vMaterials.begin(), vMaterials.end(), [&](const auto& a, const auto& b) -> bool - { - // override for none material - if (FNV1A::Hash32(a.m_sName.c_str()) == FNV1A::Hash32Const("None")) - return true; - if (FNV1A::Hash32(b.m_sName.c_str()) == FNV1A::Hash32Const("None")) - return false; + { + // override for none material + if (FNV1A::Hash32(a.m_sName.c_str()) == FNV1A::Hash32Const("None")) + return true; + if (FNV1A::Hash32(b.m_sName.c_str()) == FNV1A::Hash32Const("None")) + return false; - // keep locked materials higher - if (a.m_bLocked && !b.m_bLocked) - return true; - if (!a.m_bLocked && b.m_bLocked) - return false; + // keep locked materials higher + if (a.m_bLocked && !b.m_bLocked) + return true; + if (!a.m_bLocked && b.m_bLocked) + return false; - return a.m_sName < b.m_sName; - }); + return a.m_sName < b.m_sName; + }); for (auto& tMaterial : vMaterials) { @@ -3100,7 +3108,7 @@ void CMenu::MenuSettings(int iTab) I::EngineClient->ClientCmd_Unrestricted("retry"); if (FButton("Console", FButtonEnum::Left)) I::EngineClient->ClientCmd_Unrestricted("toggleconsole"); - if (FButton("Fix materials", FButtonEnum::Right | FButtonEnum::SameLine) && F::Materials.m_bLoaded) + if (FButton("Reload materials", FButtonEnum::Right | FButtonEnum::SameLine) && F::Materials.m_bLoaded) F::Materials.ReloadMaterials(); if (!I::EngineClient->IsConnected()) @@ -3159,6 +3167,36 @@ void CMenu::MenuSettings(int iTab) for (auto& tBox : G::BoxStorage) tBox.m_flTime = I::GlobalVars->curtime + 60.f; } + if (FButton("Restore spheres", FButtonEnum::Right | FButtonEnum::SameLine)) + { + for (auto& tSphere : G::SphereStorage) + tSphere.m_flTime = I::GlobalVars->curtime + 60.f; + } + if (FButton("Restore swept", FButtonEnum::Left)) + { + for (auto& tSwept : G::SweptStorage) + tSwept.m_flTime = I::GlobalVars->curtime + 60.f; + } + if (FButton("Restore triangles", FButtonEnum::Right | FButtonEnum::SameLine)) + { + for (auto& tTriangle : G::TriangleStorage) + tTriangle.m_flTime = I::GlobalVars->curtime + 60.f; + } + if (FButton("Restore visuals", FButtonEnum::Left)) + { + for (auto& tLine : G::LineStorage) + tLine.m_flTime = I::GlobalVars->curtime + 60.f; + for (auto& tPath : G::PathStorage) + tPath.m_flTime = I::GlobalVars->curtime + 60.f; + for (auto& tBox : G::BoxStorage) + tBox.m_flTime = I::GlobalVars->curtime + 60.f; + for (auto& tSphere : G::SphereStorage) + tSphere.m_flTime = I::GlobalVars->curtime + 60.f; + for (auto& tSwept : G::SweptStorage) + tSwept.m_flTime = I::GlobalVars->curtime + 60.f; + for (auto& tTriangle : G::TriangleStorage) + tTriangle.m_flTime = I::GlobalVars->curtime + 60.f; + } if (FButton("Clear visuals", FButtonEnum::Right | FButtonEnum::SameLine)) { G::LineStorage.clear(); @@ -3166,6 +3204,7 @@ void CMenu::MenuSettings(int iTab) G::BoxStorage.clear(); G::SphereStorage.clear(); G::SweptStorage.clear(); + G::TriangleStorage.clear(); } } EndSection(); } @@ -3192,6 +3231,13 @@ void CMenu::MenuSettings(int iTab) } EndSection(); } */ +#ifdef WORLD_DEBUG + if (Section("World")) + { + FDropdown(Vars::World::Faces, FDropdownEnum::Left); + FDropdown(Vars::World::Draw, FDropdownEnum::Right); + } EndSection(); +#endif #ifdef DEBUG_HOOKS if (Section("Hooks", 8)) { @@ -3556,94 +3602,94 @@ void CMenu::DrawBinds() return; std::vector vInfo; - std::function getBinds = [&](int iParent) + std::function fGetBinds = [&](int iParent) + { + for (int iBind = 0; iBind < F::Binds.m_vBinds.size(); iBind++) { - for (int iBind = 0; iBind < F::Binds.m_vBinds.size(); iBind++) - { - auto& tBind = F::Binds.m_vBinds[iBind]; - if (iParent != tBind.m_iParent || !tBind.m_bEnabled && !m_bIsOpen) - continue; + auto& tBind = F::Binds.m_vBinds[iBind]; + if (iParent != tBind.m_iParent || !tBind.m_bEnabled && !m_bIsOpen) + continue; - if (tBind.m_iVisibility == BindVisibilityEnum::Always || tBind.m_iVisibility == BindVisibilityEnum::WhileActive && tBind.m_bActive || m_bIsOpen) + if (tBind.m_iVisibility == BindVisibilityEnum::Always || tBind.m_iVisibility == BindVisibilityEnum::WhileActive && tBind.m_bActive || m_bIsOpen) + { + std::string sType; std::string sInfo; + switch (tBind.m_iType) { - std::string sType; std::string sInfo; - switch (tBind.m_iType) + case BindEnum::Key: + switch (tBind.m_iInfo) { - case BindEnum::Key: + case BindEnum::KeyEnum::Hold: { sType = "hold"; break; } + case BindEnum::KeyEnum::Toggle: { sType = "toggle"; break; } + case BindEnum::KeyEnum::DoubleClick: { sType = "double"; break; } + } + sInfo = VK2STR(tBind.m_iKey); + break; + case BindEnum::Class: + sType = "class"; + switch (tBind.m_iInfo) + { + case BindEnum::ClassEnum::Scout: { sInfo = "scout"; break; } + case BindEnum::ClassEnum::Soldier: { sInfo = "soldier"; break; } + case BindEnum::ClassEnum::Pyro: { sInfo = "pyro"; break; } + case BindEnum::ClassEnum::Demoman: { sInfo = "demoman"; break; } + case BindEnum::ClassEnum::Heavy: { sInfo = "heavy"; break; } + case BindEnum::ClassEnum::Engineer: { sInfo = "engineer"; break; } + case BindEnum::ClassEnum::Medic: { sInfo = "medic"; break; } + case BindEnum::ClassEnum::Sniper: { sInfo = "sniper"; break; } + case BindEnum::ClassEnum::Spy: { sInfo = "spy"; break; } + } + break; + case BindEnum::WeaponType: + sType = "weapon"; + switch (tBind.m_iInfo) + { + case BindEnum::WeaponTypeEnum::Hitscan: { sInfo = "hitscan"; break; } + case BindEnum::WeaponTypeEnum::Projectile: { sInfo = "projectile"; break; } + case BindEnum::WeaponTypeEnum::Melee: { sInfo = "melee"; break; } + case BindEnum::WeaponTypeEnum::Throwable: { sInfo = "throwable"; break; } + } + break; + case BindEnum::ItemSlot: + sType = "slot"; + sInfo = std::format("{}", tBind.m_iInfo + 1); + break; + case BindEnum::Misc: + switch (tBind.m_iInfo) + { + case BindEnum::MiscEnum::Spectated: + case BindEnum::MiscEnum::SpectatedFirst: + case BindEnum::MiscEnum::SpectatedThird: + sType = "spectated"; switch (tBind.m_iInfo) { - case BindEnum::KeyEnum::Hold: { sType = "hold"; break; } - case BindEnum::KeyEnum::Toggle: { sType = "toggle"; break; } - case BindEnum::KeyEnum::DoubleClick: { sType = "double"; break; } - } - sInfo = VK2STR(tBind.m_iKey); - break; - case BindEnum::Class: - sType = "class"; - switch (tBind.m_iInfo) - { - case BindEnum::ClassEnum::Scout: { sInfo = "scout"; break; } - case BindEnum::ClassEnum::Soldier: { sInfo = "soldier"; break; } - case BindEnum::ClassEnum::Pyro: { sInfo = "pyro"; break; } - case BindEnum::ClassEnum::Demoman: { sInfo = "demoman"; break; } - case BindEnum::ClassEnum::Heavy: { sInfo = "heavy"; break; } - case BindEnum::ClassEnum::Engineer: { sInfo = "engineer"; break; } - case BindEnum::ClassEnum::Medic: { sInfo = "medic"; break; } - case BindEnum::ClassEnum::Sniper: { sInfo = "sniper"; break; } - case BindEnum::ClassEnum::Spy: { sInfo = "spy"; break; } + case BindEnum::MiscEnum::Spectated: { sInfo = "any"; break; } + case BindEnum::MiscEnum::SpectatedFirst: { sInfo = "1st"; break; } + case BindEnum::MiscEnum::SpectatedThird: { sInfo = "3rd"; break; } } break; - case BindEnum::WeaponType: - sType = "weapon"; + case BindEnum::MiscEnum::Zoomed: + case BindEnum::MiscEnum::Aiming: + sType = "cond"; switch (tBind.m_iInfo) { - case BindEnum::WeaponTypeEnum::Hitscan: { sInfo = "hitscan"; break; } - case BindEnum::WeaponTypeEnum::Projectile: { sInfo = "projectile"; break; } - case BindEnum::WeaponTypeEnum::Melee: { sInfo = "melee"; break; } - case BindEnum::WeaponTypeEnum::Throwable: { sInfo = "throwable"; break; } - } - break; - case BindEnum::ItemSlot: - sType = "slot"; - sInfo = std::format("{}", tBind.m_iInfo + 1); - break; - case BindEnum::Misc: - switch (tBind.m_iInfo) - { - case BindEnum::MiscEnum::Spectated: - case BindEnum::MiscEnum::SpectatedFirst: - case BindEnum::MiscEnum::SpectatedThird: - sType = "spectated"; - switch (tBind.m_iInfo) - { - case BindEnum::MiscEnum::Spectated: { sInfo = "any"; break; } - case BindEnum::MiscEnum::SpectatedFirst: { sInfo = "1st"; break; } - case BindEnum::MiscEnum::SpectatedThird: { sInfo = "3rd"; break; } - } - break; - case BindEnum::MiscEnum::Zoomed: - case BindEnum::MiscEnum::Aiming: - sType = "cond"; - switch (tBind.m_iInfo) - { - case BindEnum::MiscEnum::Zoomed: { sInfo = "zoomed"; break; } - case BindEnum::MiscEnum::Aiming: { sInfo = "aiming"; break; } - } - break; + case BindEnum::MiscEnum::Zoomed: { sInfo = "zoomed"; break; } + case BindEnum::MiscEnum::Aiming: { sInfo = "aiming"; break; } } break; } - if (tBind.m_bNot && (tBind.m_iType != BindEnum::Key || tBind.m_iInfo == BindEnum::KeyEnum::Hold)) - sInfo = std::format("not {}", sInfo); - - vInfo.emplace_back(tBind.m_sName.c_str(), sType, sInfo, iBind, tBind); + break; } + if (tBind.m_bNot && (tBind.m_iType != BindEnum::Key || tBind.m_iInfo == BindEnum::KeyEnum::Hold)) + sInfo = std::format("not {}", sInfo); - if (tBind.m_bActive || m_bIsOpen) - getBinds(iBind); + vInfo.emplace_back(tBind.m_sName.c_str(), sType, sInfo, iBind, tBind); } - }; - getBinds(DEFAULT_BIND); + + if (tBind.m_bActive || m_bIsOpen) + fGetBinds(iBind); + } + }; + fGetBinds(DEFAULT_BIND); if (vInfo.empty()) return; diff --git a/Amalgam/src/Features/ImGui/Render.cpp b/Amalgam/src/Features/ImGui/Render.cpp index 14b3e237..b9b2c93f 100644 --- a/Amalgam/src/Features/ImGui/Render.cpp +++ b/Amalgam/src/Features/ImGui/Render.cpp @@ -49,20 +49,20 @@ void CRender::LoadColors() { using namespace ImGui; - auto ColorToVec = [](Color_t tColor) -> ImColor - { - return { tColor.r / 255.f, tColor.g / 255.f, tColor.b / 255.f, tColor.a / 255.f }; - }; + auto fColorToVec = [](Color_t tColor) -> ImColor + { + return { tColor.r / 255.f, tColor.g / 255.f, tColor.b / 255.f, tColor.a / 255.f }; + }; - Accent = ColorToVec(Vars::Menu::Theme::Accent.Value); - Background0 = ColorToVec(Vars::Menu::Theme::Background.Value); - Background0p5 = ColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 0.5f / 9, LerpEnum::NoAlpha)); - Background1 = ColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 1.f / 9, LerpEnum::NoAlpha)); - Background1p5 = ColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 1.5f / 9, LerpEnum::NoAlpha)); + Accent = fColorToVec(Vars::Menu::Theme::Accent.Value); + Background0 = fColorToVec(Vars::Menu::Theme::Background.Value); + Background0p5 = fColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 0.5f / 9, LerpEnum::NoAlpha)); + Background1 = fColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 1.f / 9, LerpEnum::NoAlpha)); + Background1p5 = fColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 1.5f / 9, LerpEnum::NoAlpha)); Background1p5L = { Background1p5.Value.x * 1.1f, Background1p5.Value.y * 1.1f, Background1p5.Value.z * 1.1f, Background1p5.Value.w }; - Background2 = ColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 2.f / 9, LerpEnum::NoAlpha)); - Inactive = ColorToVec(Vars::Menu::Theme::Inactive.Value); - Active = ColorToVec(Vars::Menu::Theme::Active.Value); + Background2 = fColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 2.f / 9, LerpEnum::NoAlpha)); + Inactive = fColorToVec(Vars::Menu::Theme::Inactive.Value); + Active = fColorToVec(Vars::Menu::Theme::Active.Value); ImVec4* colors = GetStyle().Colors; colors[ImGuiCol_Border] = Background2; diff --git a/Amalgam/src/Features/Misc/Misc.cpp b/Amalgam/src/Features/Misc/Misc.cpp index dd437fb1..0bcc7cc9 100644 --- a/Amalgam/src/Features/Misc/Misc.cpp +++ b/Amalgam/src/Features/Misc/Misc.cpp @@ -346,7 +346,7 @@ void CMisc::FastMovement(CTFPlayer* pLocal, CUserCmd* pCmd) return; Vec3 vMove = { pCmd->forwardmove, pCmd->sidemove, 0.f }; - Vec3 vAngMoveReverse = Math::VectorAngles(vMove * -1.f); + Vec3 vAngMoveReverse = Math::VectorAngles(-vMove); pCmd->forwardmove = -vMove.Length(); pCmd->sidemove = 0.f; pCmd->viewangles.y = fmodf(pCmd->viewangles.y - vAngMoveReverse.y, 360.f); @@ -463,9 +463,9 @@ int CMisc::AntiBackstab(CTFPlayer* pLocal, CUserCmd* pCmd, bool bSendPacket) return 0; std::sort(vTargets.begin(), vTargets.end(), [&](const auto& a, const auto& b) -> bool - { - return pLocal->GetCenter().DistTo(a.first) < pLocal->GetCenter().DistTo(b.first); - }); + { + return pLocal->GetCenter().DistTo(a.first) < pLocal->GetCenter().DistTo(b.first); + }); auto& pTargetPos = vTargets.front(); switch (Vars::Misc::Automation::AntiBackstab.Value) @@ -486,28 +486,28 @@ int CMisc::AntiBackstab(CTFPlayer* pLocal, CUserCmd* pCmd, bool bSendPacket) // if the closest spy is a cheater, assume auto stab is being used, otherwise don't do anything if target is in front if (!bCheater) { - auto TargetIsBehind = [&]() - { - const float flCompDist = PLAYER_ORIGIN_COMPRESSION / 2; - const float flSqCompDist = 0.0884f; + auto fTargetIsBehind = [&]() + { + const float flCompDist = PLAYER_ORIGIN_COMPRESSION / 2; + const float flSqCompDist = 0.0884f; - Vec3 vToTarget = (pLocal->m_vecOrigin() - pTargetPos.first).To2D(); - const float flDist = vToTarget.Normalize(); - if (flDist < flSqCompDist) - return true; + Vec3 vToTarget = (pLocal->m_vecOrigin() - pTargetPos.first).To2D(); + const float flDist = vToTarget.Normalize(); + if (flDist < flSqCompDist) + return true; - const float flExtra = 2.f * flCompDist / flDist; // account for origin compression - float flPosVsTargetViewMinDot = 0.f - 0.0031f - flExtra; + const float flExtra = 2.f * flCompDist / flDist; // account for origin compression + float flPosVsTargetViewMinDot = 0.f - 0.0031f - flExtra; - Vec3 vTargetForward; Math::AngleVectors(pCmd->viewangles, &vTargetForward); - vTargetForward.Normalize2D(); + Vec3 vTargetForward; Math::AngleVectors(pCmd->viewangles, &vTargetForward); + vTargetForward.Normalize2D(); - const float flPosVsTargetViewDot = vToTarget.Dot(vTargetForward); // Behind? + const float flPosVsTargetViewDot = vToTarget.Dot(vTargetForward); // Behind? - return flPosVsTargetViewDot > flPosVsTargetViewMinDot; - }; + return flPosVsTargetViewDot > flPosVsTargetViewMinDot; + }; - if (!TargetIsBehind()) + if (!fTargetIsBehind()) return 0; } diff --git a/Amalgam/src/Features/PacketManip/FakeLag/FakeLag.cpp b/Amalgam/src/Features/PacketManip/FakeLag/FakeLag.cpp index 1a948ff4..3027ee55 100644 --- a/Amalgam/src/Features/PacketManip/FakeLag/FakeLag.cpp +++ b/Amalgam/src/Features/PacketManip/FakeLag/FakeLag.cpp @@ -92,7 +92,7 @@ void CFakeLag::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd, bo { case Vars::Fakelag::FakelagEnum::Off: m_iGoal = 0; break; case Vars::Fakelag::FakelagEnum::Plain: m_iGoal = Vars::Fakelag::PlainTicks.Value; break; - case Vars::Fakelag::FakelagEnum::Random: m_iGoal = SDK::StdRandomInt(Vars::Fakelag::RandomTicks.Value.Min, Vars::Fakelag::RandomTicks.Value.Max); break; + case Vars::Fakelag::FakelagEnum::Random: m_iGoal = SDK::RandomInt(Vars::Fakelag::RandomTicks.Value.Min, Vars::Fakelag::RandomTicks.Value.Max); break; case Vars::Fakelag::FakelagEnum::Adaptive: m_iGoal = 22; break; } } diff --git a/Amalgam/src/Features/Players/PlayerCore.cpp b/Amalgam/src/Features/Players/PlayerCore.cpp index 6641dd3e..1a23d00a 100644 --- a/Amalgam/src/Features/Players/PlayerCore.cpp +++ b/Amalgam/src/Features/Players/PlayerCore.cpp @@ -138,7 +138,7 @@ void CPlayerlistCore::LoadPlayerlist() for (auto& [sName, tChild] : *tSub) { uint32_t uAccountID = std::stoul(sName); - for (auto& [_, tTag] : tChild) + for (auto& tTag : tChild | std::views::values) { const std::string& sTag = tTag.data(); diff --git a/Amalgam/src/Features/Players/PlayerUtils.cpp b/Amalgam/src/Features/Players/PlayerUtils.cpp index 49ccf4da..270a14eb 100644 --- a/Amalgam/src/Features/Players/PlayerUtils.cpp +++ b/Amalgam/src/Features/Players/PlayerUtils.cpp @@ -279,13 +279,13 @@ PriorityLabel_t* CPlayerlistUtils::GetSignificantTag(uint32_t uAccountID, int iM return nullptr; std::sort(vTags.begin(), vTags.end(), [&](const PriorityLabel_t* a, const PriorityLabel_t* b) -> bool - { - // sort by priority if unequal - if (a->m_iPriority != b->m_iPriority) - return a->m_iPriority > b->m_iPriority; + { + // sort by priority if unequal + if (a->m_iPriority != b->m_iPriority) + return a->m_iPriority > b->m_iPriority; - return a->m_sName < b->m_sName; - }); + return a->m_sName < b->m_sName; + }); return vTags.front(); } PriorityLabel_t* CPlayerlistUtils::GetSignificantTag(int iIndex, int iMode) diff --git a/Amalgam/src/Features/Resolver/Resolver.cpp b/Amalgam/src/Features/Resolver/Resolver.cpp index 9867fcab..d9e0ed72 100644 --- a/Amalgam/src/Features/Resolver/Resolver.cpp +++ b/Amalgam/src/Features/Resolver/Resolver.cpp @@ -125,38 +125,38 @@ void CResolver::CreateMove() if (!pResource) return; - auto getPlayerClosestToFOV = [&]() + auto fGetPlayerClosestToFOV = [&]() + { + CTFPlayer* pClosest = nullptr; + float flMinFOV = 180.f; + + const Vec3 vLocalPos = F::Ticks.GetShootPos(); + const Vec3 vLocalAngles = I::EngineClient->GetViewAngles(); + + for (auto& pEntity : H::Entities.GetGroup(EntityEnum::PlayerAll)) { - CTFPlayer* pClosest = nullptr; - float flMinFOV = 180.f; + if (pEntity->entindex() == I::EngineClient->GetLocalPlayer()) + continue; - const Vec3 vLocalPos = F::Ticks.GetShootPos(); - const Vec3 vLocalAngles = I::EngineClient->GetViewAngles(); + Vec3 vCurPos = pEntity->GetCenter(); + Vec3 vCurAngleTo = Math::CalcAngle(vLocalPos, vCurPos); + float flCurFOVTo = Math::CalcFov(vLocalAngles, vCurAngleTo); - for (auto& pEntity : H::Entities.GetGroup(EntityEnum::PlayerAll)) + if (flCurFOVTo < flMinFOV) { - if (pEntity->entindex() == I::EngineClient->GetLocalPlayer()) - continue; - - Vec3 vCurPos = pEntity->GetCenter(); - Vec3 vCurAngleTo = Math::CalcAngle(vLocalPos, vCurPos); - float flCurFOVTo = Math::CalcFov(vLocalAngles, vCurAngleTo); - - if (flCurFOVTo < flMinFOV) - { - pClosest = pEntity->As(); - flMinFOV = flCurFOVTo; - } + pClosest = pEntity->As(); + flMinFOV = flCurFOVTo; } + } - return pClosest; - }; + return pClosest; + }; if (Vars::Resolver::CycleYaw.Value) { if (SDK::PlatFloatTime() > m_flLastYawCycle + 0.5f) { - if (auto pTarget = getPlayerClosestToFOV()) + if (auto pTarget = fGetPlayerClosestToFOV()) { int iUserID = pResource->m_iUserID(pTarget->entindex()); auto& tData = m_mResolverData[iUserID]; @@ -178,7 +178,7 @@ void CResolver::CreateMove() { if (SDK::PlatFloatTime() > m_flLastPitchCycle + 0.5f) { - if (auto pTarget = getPlayerClosestToFOV()) + if (auto pTarget = fGetPlayerClosestToFOV()) { int iUserID = pResource->m_iUserID(pTarget->entindex()); auto& tData = m_mResolverData[iUserID]; @@ -208,7 +208,7 @@ void CResolver::CreateMove() { if (SDK::PlatFloatTime() > m_flLastMinwalkCycle + 0.5f) { - if (auto pTarget = getPlayerClosestToFOV()) + if (auto pTarget = fGetPlayerClosestToFOV()) { int iUserID = pResource->m_iUserID(pTarget->entindex()); auto& tData = m_mResolverData[iUserID]; @@ -230,7 +230,7 @@ void CResolver::CreateMove() { if (SDK::PlatFloatTime() > m_flLastViewCycle + 0.5f) { - if (auto pTarget = getPlayerClosestToFOV()) + if (auto pTarget = fGetPlayerClosestToFOV()) { int iUserID = pResource->m_iUserID(pTarget->entindex()); auto& tData = m_mResolverData[iUserID]; diff --git a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp index 2eb95ef0..41b873b8 100644 --- a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp +++ b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp @@ -579,7 +579,7 @@ void CMovementSimulation::RestoreBounds(CTFPlayer* pPlayer) } } -void CMovementSimulation::RunTick(MoveStorage& tMoveStorage, bool bPath, std::function* pCallback) +void CMovementSimulation::RunTick(MoveStorage& tMoveStorage, bool bPath, RunTickCallback* pCallback) { if (tMoveStorage.m_bFailed || !tMoveStorage.m_pPlayer || !tMoveStorage.m_pPlayer->IsPlayer()) return; @@ -649,7 +649,7 @@ void CMovementSimulation::RunTick(MoveStorage& tMoveStorage, bool bPath, std::fu RestoreBounds(tMoveStorage.m_pPlayer); } -void CMovementSimulation::RunTick(MoveStorage& tMoveStorage, bool bPath, std::function fCallback) +void CMovementSimulation::RunTick(MoveStorage& tMoveStorage, bool bPath, RunTickCallback fCallback) { RunTick(tMoveStorage, bPath, &fCallback); } diff --git a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h index 33777876..5735ddfc 100644 --- a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h +++ b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.h @@ -4,6 +4,8 @@ Enum(Move, Ground, Air, Swim) +using RunTickCallback = const std::function; + struct MoveStorage { CTFPlayer* m_pPlayer = nullptr; @@ -61,8 +63,8 @@ public: bool Initialize(CBaseEntity* pEntity, MoveStorage& tMoveStorage, bool bHitchance = true, bool bStrafe = true); bool SetDuck(MoveStorage& tMoveStorage, bool bDuck); - void RunTick(MoveStorage& tMoveStorage, bool bPath = true, std::function* pCallback = nullptr); - void RunTick(MoveStorage& tMoveStorage, bool bPath, std::function fCallback); + void RunTick(MoveStorage& tMoveStorage, bool bPath = true, RunTickCallback* pCallback = nullptr); + void RunTick(MoveStorage& tMoveStorage, bool bPath, RunTickCallback fCallback); void Restore(MoveStorage& tMoveStorage); float GetPredictedDelta(CBaseEntity* pEntity); diff --git a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp index bf958bdd..0ff8e22a 100644 --- a/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp +++ b/Amalgam/src/Features/Simulation/ProjectileSimulation/ProjectileSimulation.cpp @@ -316,10 +316,9 @@ bool CProjectileSimulation::GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, Vec3 vStart = bInterp ? pPlayer->GetEyePosition() : pPlayer->GetShootPos(); Vec3 vEnd = tProjInfo.m_vPos; - SDK::TraceHull(vStart, vEnd, tProjInfo.m_vHull * -1.f, tProjInfo.m_vHull, MASK_SOLID, &filter, &trace); + SDK::TraceHull(vStart, vEnd, -tProjInfo.m_vHull, tProjInfo.m_vHull, MASK_SOLID, &filter, &trace); tProjInfo.m_vPos = trace.endpos; - - return true; + return !trace.allsolid; } void CProjectileSimulation::GetInfo(CBaseEntity* pProjectile, ProjectileInfo& tProjInfo) diff --git a/Amalgam/src/Features/Visuals/Chams/Chams.cpp b/Amalgam/src/Features/Visuals/Chams/Chams.cpp index 3de733bf..49a3a953 100644 --- a/Amalgam/src/Features/Visuals/Chams/Chams.cpp +++ b/Amalgam/src/Features/Visuals/Chams/Chams.cpp @@ -180,23 +180,23 @@ void CChams::RenderBacktrack(const DrawModelState_t& pState, const ModelRenderIn pRenderContext->DepthRange(0.f, m_iFlags & BacktrackEnum::IgnoreZ ? 0.2f : 1.f); - auto drawModel = [&](Vec3& vOrigin, const DrawModelState_t& pState, const ModelRenderInfo_t& pInfo, matrix3x4* pBoneToWorld, float flBlend) - { - if (!SDK::IsOnScreen(pEntity, vOrigin)) - return; + auto fDrawModel = [&](Vec3& vOrigin, const DrawModelState_t& pState, const ModelRenderInfo_t& pInfo, matrix3x4* pBoneToWorld, float flBlend) + { + if (!SDK::IsOnScreen(pEntity, vOrigin)) + return; - float flOriginalBlend = I::RenderView->GetBlend(); - I::RenderView->SetBlend(flBlend * flOriginalBlend); - static auto IVModelRender_DrawModelExecute = U::Hooks.m_mHooks["IVModelRender_DrawModelExecute"]; - IVModelRender_DrawModelExecute->Call(I::ModelRender, pState, pInfo, pBoneToWorld); - I::RenderView->SetBlend(flOriginalBlend); - }; + float flOriginalBlend = I::RenderView->GetBlend(); + I::RenderView->SetBlend(flBlend * flOriginalBlend); + static auto IVModelRender_DrawModelExecute = U::Hooks.m_mHooks["IVModelRender_DrawModelExecute"]; + IVModelRender_DrawModelExecute->Call(I::ModelRender, pState, pInfo, pBoneToWorld); + I::RenderView->SetBlend(flOriginalBlend); + }; if (!bDrawLast && !bDrawFirst) { for (auto pRecord : vRecords) { if (float flBlend = Math::RemapVal(pEntity->GetAbsOrigin().DistTo(pRecord->m_vOrigin), 1.f, 24.f, 0.f, 1.f)) - drawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); + fDrawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); } } else @@ -205,13 +205,13 @@ void CChams::RenderBacktrack(const DrawModelState_t& pState, const ModelRenderIn { auto pRecord = vRecords.back(); if (float flBlend = Math::RemapVal(pEntity->GetAbsOrigin().DistTo(pRecord->m_vOrigin), 1.f, 24.f, 0.f, 1.f)) - drawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); + fDrawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); } if (bDrawFirst) { auto pRecord = vRecords.front(); if (float flBlend = Math::RemapVal(pEntity->GetAbsOrigin().DistTo(pRecord->m_vOrigin), 1.f, 24.f, 0.f, 1.f)) - drawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); + fDrawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); } } diff --git a/Amalgam/src/Features/Visuals/ESP/ESP.cpp b/Amalgam/src/Features/Visuals/ESP/ESP.cpp index 684db52f..7f87ddfe 100644 --- a/Amalgam/src/Features/Visuals/ESP/ESP.cpp +++ b/Amalgam/src/Features/Visuals/ESP/ESP.cpp @@ -87,13 +87,13 @@ static inline void StorePlayer(CTFPlayer* pPlayer, CTFPlayer* pLocal, Group_t* p if (!vTags.empty()) { std::sort(vTags.begin(), vTags.end(), [&](const auto a, const auto b) -> bool - { - // sort by priority if unequal - if (std::get<2>(a) != std::get<2>(b)) - return std::get<2>(a) > std::get<2>(b); + { + // sort by priority if unequal + if (std::get<2>(a) != std::get<2>(b)) + return std::get<2>(a) > std::get<2>(b); - return std::get<0>(a) < std::get<0>(b); - }); + return std::get<0>(a) < std::get<0>(b); + }); for (auto& [sName, tColor, _] : vTags) tCache.m_vText.emplace_back(ALIGN_TOPRIGHT, sName, tColor, tColor.IsColorDark() ? Color_t(255, 255, 255) : Color_t(0, 0, 0)); @@ -337,16 +337,16 @@ static inline void StorePlayer(CTFPlayer* pPlayer, CTFPlayer* pLocal, Group_t* p } else { - auto GetSniperDot = [](CBaseEntity* pEntity) -> CSniperDot* + auto fGetSniperDot = [](CBaseEntity* pEntity) -> CSniperDot* + { + for (auto pDot : H::Entities.GetGroup(EntityEnum::SniperDots)) { - for (auto pDot : H::Entities.GetGroup(EntityEnum::SniperDots)) - { - if (pDot->m_hOwnerEntity().Get() == pEntity) - return pDot->As(); - } - return nullptr; - }; - if (CSniperDot* pPlayerDot = GetSniperDot(pPlayer)) + if (pDot->m_hOwnerEntity().Get() == pEntity) + return pDot->As(); + } + return nullptr; + }; + if (CSniperDot* pPlayerDot = fGetSniperDot(pPlayer)) { float flChargeTime = std::max(SDK::AttribHookValue(3.f, "mult_sniper_charge_per_sec", pWeapon), 1.5f); tCache.m_vText.emplace_back(ALIGN_TOPRIGHT, std::format("Charging {:.0f}%", Math::RemapVal(TICKS_TO_TIME(I::ClientState->m_ClockDriftMgr.m_nServerTick) - pPlayerDot->m_flChargeStartTime() - 0.3f, 0.f, flChargeTime, 0.f, 100.f)), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value); @@ -803,27 +803,27 @@ void CESP::DrawPlayers() for (auto& [iMode, flPercent, tColor, tOverfill, bAdjust] : tCache.m_vBars) { - auto drawBar = [&](int x, int y, int w, int h, EAlign eAlign = ALIGN_LEFT) + auto fDrawBar = [&](int x, int y, int w, int h, EAlign eAlign = ALIGN_LEFT) + { + if (flPercent > 1.f) { - if (flPercent > 1.f) - { - H::Draw.FillRectPercent(x, y, w, h, 1.f, tColor, { 0, 0, 0, 255 }, eAlign, bAdjust); - H::Draw.FillRectPercent(x, y, w, h, flPercent - 1.f, tOverfill, { 0, 0, 0, 0 }, eAlign, bAdjust); - } - else - H::Draw.FillRectPercent(x, y, w, h, flPercent, tColor, { 0, 0, 0, 255 }, eAlign, bAdjust); - }; + H::Draw.FillRectPercent(x, y, w, h, 1.f, tColor, { 0, 0, 0, 255 }, eAlign, bAdjust); + H::Draw.FillRectPercent(x, y, w, h, flPercent - 1.f, tOverfill, { 0, 0, 0, 0 }, eAlign, bAdjust); + } + else + H::Draw.FillRectPercent(x, y, w, h, flPercent, tColor, { 0, 0, 0, 255 }, eAlign, bAdjust); + }; int iSpace = H::Draw.Scale(4); int iThickness = H::Draw.Scale(2, Scale_Round); switch (iMode) { case ALIGN_LEFT: - drawBar(x - iSpace - iThickness - lOffset, y, iThickness, h, ALIGN_BOTTOM); + fDrawBar(x - iSpace - iThickness - lOffset, y, iThickness, h, ALIGN_BOTTOM); lOffset += iSpace + iThickness; break; case ALIGN_BOTTOM: - drawBar(x, y + h + iSpace + bOffset, w, iThickness); + fDrawBar(x, y + h + iSpace + bOffset, w, iThickness); bOffset += iSpace + iThickness; break; } @@ -906,27 +906,27 @@ void CESP::DrawBuildings() H::Draw.LineRectOutline(x, y, w, h, tCache.m_tColor, { 0, 0, 0, 255 }); for (auto& [iMode, flPercent, tColor, tOverfill, bAdjust] : tCache.m_vBars) { - auto drawBar = [&](int x, int y, int w, int h, EAlign eAlign = ALIGN_LEFT) + auto fDrawBar = [&](int x, int y, int w, int h, EAlign eAlign = ALIGN_LEFT) + { + if (flPercent > 1.f) { - if (flPercent > 1.f) - { - H::Draw.FillRectPercent(x, y, w, h, 1.f, tColor, { 0, 0, 0, 255 }, eAlign, bAdjust); - H::Draw.FillRectPercent(x, y, w, h, flPercent - 1.f, tOverfill, { 0, 0, 0, 0 }, eAlign, bAdjust); - } - else - H::Draw.FillRectPercent(x, y, w, h, flPercent, tColor, { 0, 0, 0, 255 }, eAlign, bAdjust); - }; + H::Draw.FillRectPercent(x, y, w, h, 1.f, tColor, { 0, 0, 0, 255 }, eAlign, bAdjust); + H::Draw.FillRectPercent(x, y, w, h, flPercent - 1.f, tOverfill, { 0, 0, 0, 0 }, eAlign, bAdjust); + } + else + H::Draw.FillRectPercent(x, y, w, h, flPercent, tColor, { 0, 0, 0, 255 }, eAlign, bAdjust); + }; int iSpace = H::Draw.Scale(4); int iThickness = H::Draw.Scale(2, Scale_Round); switch (iMode) { case ALIGN_LEFT: - drawBar(x - iSpace - iThickness - lOffset, y, iThickness, h, ALIGN_BOTTOM); + fDrawBar(x - iSpace - iThickness - lOffset, y, iThickness, h, ALIGN_BOTTOM); lOffset += iSpace + iThickness; break; case ALIGN_BOTTOM: - drawBar(x, y + h + iSpace + bOffset, w, iThickness); + fDrawBar(x, y + h + iSpace + bOffset, w, iThickness); bOffset += iSpace + iThickness; break; } diff --git a/Amalgam/src/Features/Visuals/Glow/Glow.cpp b/Amalgam/src/Features/Visuals/Glow/Glow.cpp index d14df396..2fda5d7f 100644 --- a/Amalgam/src/Features/Visuals/Glow/Glow.cpp +++ b/Amalgam/src/Features/Visuals/Glow/Glow.cpp @@ -223,23 +223,23 @@ void CGlow::RenderBacktrack(const DrawModelState_t& pState, const ModelRenderInf bool bDrawLast = m_iFlags & BacktrackEnum::Last; bool bDrawFirst = m_iFlags & BacktrackEnum::First; - auto drawModel = [&](Vec3& vOrigin, const DrawModelState_t& pState, const ModelRenderInfo_t& pInfo, matrix3x4* pBoneToWorld, float flBlend) - { - if (!SDK::IsOnScreen(pEntity, vOrigin)) - return; + auto fDrawModel = [&](Vec3& vOrigin, const DrawModelState_t& pState, const ModelRenderInfo_t& pInfo, matrix3x4* pBoneToWorld, float flBlend) + { + if (!SDK::IsOnScreen(pEntity, vOrigin)) + return; - //float flOriginalBlend = I::RenderView->GetBlend(); - //I::RenderView->SetBlend(flBlend * flOriginalBlend); - static auto IVModelRender_DrawModelExecute = U::Hooks.m_mHooks["IVModelRender_DrawModelExecute"]; - IVModelRender_DrawModelExecute->Call(I::ModelRender, pState, pInfo, pBoneToWorld); - //I::RenderView->SetBlend(flOriginalBlend); - }; + //float flOriginalBlend = I::RenderView->GetBlend(); + //I::RenderView->SetBlend(flBlend * flOriginalBlend); + static auto IVModelRender_DrawModelExecute = U::Hooks.m_mHooks["IVModelRender_DrawModelExecute"]; + IVModelRender_DrawModelExecute->Call(I::ModelRender, pState, pInfo, pBoneToWorld); + //I::RenderView->SetBlend(flOriginalBlend); + }; if (!bDrawLast && !bDrawFirst) { for (auto pRecord : vRecords) { if (float flBlend = Math::RemapVal(pEntity->GetAbsOrigin().DistTo(pRecord->m_vOrigin), 1.f, 24.f, 0.f, 1.f)) - drawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); + fDrawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); } } else @@ -248,13 +248,13 @@ void CGlow::RenderBacktrack(const DrawModelState_t& pState, const ModelRenderInf { auto pRecord = vRecords.back(); if (float flBlend = Math::RemapVal(pEntity->GetAbsOrigin().DistTo(pRecord->m_vOrigin), 1.f, 24.f, 0.f, 1.f)) - drawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); + fDrawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); } if (bDrawFirst) { auto pRecord = vRecords.front(); if (float flBlend = Math::RemapVal(pEntity->GetAbsOrigin().DistTo(pRecord->m_vOrigin), 1.f, 24.f, 0.f, 1.f)) - drawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); + fDrawModel(pRecord->m_vOrigin, pState, pInfo, pRecord->m_aBones, flBlend); } } } diff --git a/Amalgam/src/Features/Visuals/Materials/Materials.cpp b/Amalgam/src/Features/Visuals/Materials/Materials.cpp index 2eaedcf3..c2b5a554 100644 --- a/Amalgam/src/Features/Visuals/Materials/Materials.cpp +++ b/Amalgam/src/Features/Visuals/Materials/Materials.cpp @@ -179,7 +179,7 @@ void CMaterials::LoadMaterials() StoreStruct(sName, sVMT); } // create materials - for (auto& [_, tMaterial] : m_mMaterials) + for (auto& tMaterial : m_mMaterials | std::views::values) { KeyValues* kv = new KeyValues(tMaterial.m_sName.c_str()); if (!kv->LoadFromBuffer(tMaterial.m_sName.c_str(), tMaterial.m_sVMT.c_str())) @@ -234,7 +234,7 @@ void CMaterials::UnloadMaterials() { m_bLoaded = false; - for (auto& [_, tMaterial] : m_mMaterials) + for (auto& tMaterial : m_mMaterials | std::views::values) Remove(tMaterial.m_pMaterial); m_mMaterials.clear(); m_mMatList.clear(); @@ -365,28 +365,28 @@ void CMaterials::RemoveMaterial(const char* sName) std::filesystem::remove(F::Configs.m_sMaterialsPath + sName + ".vmt"); - auto removeFromVal = [&](std::vector>& val) + auto fRemoveFromVal = [&](std::vector>& val) + { + for (auto it = val.begin(); it != val.end();) { - for (auto it = val.begin(); it != val.end();) - { - if (FNV1A::Hash32(it->first.c_str()) == uHash) - it = val.erase(it); - else - ++it; - } - }; - auto removeFromVar = [&](ConfigVar>>& var) + if (FNV1A::Hash32(it->first.c_str()) == uHash) + it = val.erase(it); + else + ++it; + } + }; + auto fRemoveFromVar = [&](ConfigVar>>& var) + { + for (auto& [iBind, vVal] : var.Map) { - for (auto& [iBind, vVal] : var.Map) - { - removeFromVal(vVal); - } - }; + fRemoveFromVal(vVal); + } + }; for (auto& tGroup : F::Groups.m_vGroups) { - removeFromVal(tGroup.m_tChams.Visible); - removeFromVal(tGroup.m_tChams.Occluded); - removeFromVal(tGroup.m_vBacktrackChams); + fRemoveFromVal(tGroup.m_tChams.Visible); + fRemoveFromVal(tGroup.m_tChams.Occluded); + fRemoveFromVal(tGroup.m_vBacktrackChams); } } diff --git a/Amalgam/src/Features/Visuals/Visuals.cpp b/Amalgam/src/Features/Visuals/Visuals.cpp index 24f96501..8e99aba1 100644 --- a/Amalgam/src/Features/Visuals/Visuals.cpp +++ b/Amalgam/src/Features/Visuals/Visuals.cpp @@ -10,6 +10,7 @@ #include "../Players/PlayerUtils.h" #include "../Spectate/Spectate.h" #include "Groups/Groups.h" +#include "../World/World.h" MAKE_SIGNATURE(UTIL_PlayerByIndex, "server.dll", "48 83 EC ? 8B D1 85 C9 7E ? 48 8B 05", 0x0); MAKE_SIGNATURE(CBaseAnimating_DrawServerHitboxes, "server.dll", "44 88 44 24 ? 53 48 81 EC", 0x0); @@ -81,7 +82,7 @@ void CVisuals::ProjectileTrace(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const F::ProjSim.SetupTrace(filter, nMask, pWeapon, 0, bInterp); Vec3* pNormal = nullptr; - SDK::TraceHull(F::ProjSim.GetOrigin(), F::ProjSim.GetOrigin(), tProjInfo.m_vHull * -1, tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(F::ProjSim.GetOrigin(), F::ProjSim.GetOrigin(), -tProjInfo.m_vHull, tProjInfo.m_vHull, nMask, &filter, &trace); if (trace.startsolid) return; @@ -92,7 +93,7 @@ void CVisuals::ProjectileTrace(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const F::ProjSim.RunTick(tProjInfo); Vec3 New = F::ProjSim.GetOrigin(); - SDK::TraceHull(Old, New, tProjInfo.m_vHull * -1, tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(Old, New, -tProjInfo.m_vHull, tProjInfo.m_vHull, nMask, &filter, &trace); F::ProjSim.SetupTrace(filter, nMask, pWeapon, n, bInterp); if (trace.DidHit()) { @@ -173,8 +174,8 @@ void CVisuals::ProjectileTrace(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const const Vec3 vSize = { 1.f, flSize, flSize }; Vec3 vAngles = Math::VectorAngles(*pNormal); - H::Draw.RenderWireframeBox(trace.endpos, vSize * -1, vSize, vAngles, Vars::Colors::TrajectoryPathIgnoreZ.Value); - H::Draw.RenderWireframeBox(trace.endpos, vSize * -1, vSize, vAngles, Vars::Colors::TrajectoryPath.Value, true); + H::Draw.RenderWireframeBox(trace.endpos, -vSize, vSize, vAngles, Vars::Colors::TrajectoryPathIgnoreZ.Value); + H::Draw.RenderWireframeBox(trace.endpos, -vSize, vSize, vAngles, Vars::Colors::TrajectoryPath.Value, true); } if (flRadius) @@ -210,9 +211,9 @@ void CVisuals::ProjectileTrace(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const Vec3 vAngles = Math::VectorAngles(*pNormal); if (Vars::Colors::ShotPathIgnoreZ.Value.a) - G::BoxStorage.emplace_back(trace.endpos, vSize * -1, vSize, vAngles, I::GlobalVars->curtime + TICKS_TO_TIME(tProjInfo.m_vPath.size()) + F::Backtrack.GetReal(), Vars::Colors::ShotPathIgnoreZ.Value, Color_t(0, 0, 0, 0)); + G::BoxStorage.emplace_back(trace.endpos, -vSize, vSize, vAngles, I::GlobalVars->curtime + TICKS_TO_TIME(tProjInfo.m_vPath.size()) + F::Backtrack.GetReal(), Vars::Colors::ShotPathIgnoreZ.Value, Color_t(0, 0, 0, 0)); if (Vars::Colors::ShotPath.Value.a) - G::BoxStorage.emplace_back(trace.endpos, vSize * -1, vSize, vAngles, I::GlobalVars->curtime + TICKS_TO_TIME(tProjInfo.m_vPath.size()) + F::Backtrack.GetReal(), Vars::Colors::ShotPath.Value, Color_t(0, 0, 0, 0), true); + G::BoxStorage.emplace_back(trace.endpos, -vSize, vSize, vAngles, I::GlobalVars->curtime + TICKS_TO_TIME(tProjInfo.m_vPath.size()) + F::Backtrack.GetReal(), Vars::Colors::ShotPath.Value, Color_t(0, 0, 0, 0), true); } if (flRadius) @@ -519,6 +520,13 @@ void CVisuals::DrawEffects() H::Draw.RenderWireframeSweptBox(tSwept.m_paOrigin.first, tSwept.m_paOrigin.second, tSwept.m_vMins, tSwept.m_vMaxs, tSwept.m_vAngles, tSwept.m_tColor, tSwept.m_bZBuffer); } + for (auto& tTriangle : G::TriangleStorage) + { + if (tTriangle.m_flTime < I::GlobalVars->curtime) + continue; + + H::Draw.RenderTriangle(tTriangle.m_aOrigin[0], tTriangle.m_aOrigin[1], tTriangle.m_aOrigin[2], tTriangle.m_tColor, tTriangle.m_bZBuffer); + } if (auto& tPath = F::Aimbot.m_tPath; tPath.m_flTime) { H::Draw.RenderPath(tPath.m_vPath, Vars::Colors::RealPath.Value, true, tPath.m_iStyle, tPath.m_flTime); @@ -689,7 +697,7 @@ void CVisuals::FOV(CTFPlayer* pLocal, CViewSetup* pView) } } - F::Aimbot.m_flFOV = pView->fov; + G::FOV = pView->fov; if (pLocal->IsAlive()) { pLocal->m_iFOV() = pView->fov; @@ -829,6 +837,7 @@ void CVisuals::Event(IGameEvent* pEvent, uint32_t uHash) G::PathStorage.clear(); G::SphereStorage.clear(); G::SweptStorage.clear(); + G::TriangleStorage.clear(); } } } @@ -917,7 +926,7 @@ void CVisuals::Store() F::ProjSim.RunTick(tProjInfo); Vec3 New = F::ProjSim.GetOrigin(); - SDK::TraceHull(Old, New, tProjInfo.m_vHull * -1, tProjInfo.m_vHull, nMask, &filter, &trace); + SDK::TraceHull(Old, New, -tProjInfo.m_vHull, tProjInfo.m_vHull, nMask, &filter, &trace); if (trace.DidHit()) { tProjectile.m_vNormal = trace.plane.normal; @@ -982,7 +991,7 @@ void CVisuals::Tick() tPath.m_flTime = std::min(tPath.m_flTime + 1.f, 0.f); } - for (auto& [_, tProjectile] : m_mProjectiles) + for (auto& tProjectile : m_mProjectiles | std::views::values) { if (tProjectile.m_flTime < 0.f) tProjectile.m_flTime = std::min(tProjectile.m_flTime + 1.f, 0.f); @@ -1116,6 +1125,20 @@ void CVisuals::RestoreWorldModulation() ApplyModulation({ 255, 255, 255, 255 }, true); } +#ifdef WORLD_DEBUG +class CEntityEnumerator : public IPartitionEnumerator +{ +public: + IterationRetval_t EnumElement(IHandleEntity* pHandleEntity) + { + m_vEntities.push_back(pHandleEntity); + return ITERATION_CONTINUE; + } + + std::vector m_vEntities = {}; +}; +#endif + void CVisuals::CreateMove(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) { if (Vars::Visuals::Simulation::ShotPath.Value && G::Attacking == 1 && !F::Aimbot.m_bRan) @@ -1159,4 +1182,44 @@ void CVisuals::CreateMove(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) r_aspectratio->SetValue(flNewRatio); DrawHitboxes(2); + +#ifdef WORLD_DEBUG + if (auto pLocal = H::Entities.GetLocal(); Vars::World::Faces.Value && pLocal && I::Input->CAM_IsThirdPerson()) + { + //float flRadius = 146.f + pLocal->GetSize().Length() / 2; + //Vec3 vOrigin = pLocal->GetCenter(); + //Vec3 vMins = vOrigin - flRadius; + //Vec3 vMaxs = vOrigin + flRadius; + Vec3 vOrigin = pLocal->m_vecOrigin(); + Vec3 vMins = vOrigin + pLocal->m_vecMins(); + Vec3 vMaxs = vOrigin + pLocal->m_vecMaxs(); + + G::LineStorage.clear(); G::BoxStorage.clear(); G::TriangleStorage.clear(); + G::BoxStorage.emplace_back(Vec3(), vMins, vMaxs, Vec3(), I::GlobalVars->curtime + 60.f, Color_t(255, 255, 255), Color_t(0, 0, 0, 0), true); + //G::BoxStorage.emplace_back(pLocal->m_vecOrigin(), pLocal->m_vecMins(), pLocal->m_vecMaxs(), Vec3(), I::GlobalVars->curtime + 60.f, Color_t(255, 255, 255), Color_t(0, 0, 0, 0), true); + + CTraceFilterWorldAndPropsOnly filter = {}; + std::vector vFaces = F::World.GetFacesInAABB(vMins, vMaxs, MASK_SOLID, &filter, Vars::World::Faces.Value); + SDK::Output("Faces", std::format("{}", vFaces.size()).c_str(), {}, OUTPUT_CONSOLE); + + if (Vars::World::Draw.Value) + { + for (auto& tFace : vFaces) + { + 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]; + + Vec3 vDir21 = vVertex2 - vVertex1, vDir31 = vVertex3 - vVertex1; + float flArea = vDir21.Cross(vDir31).Length() / 2; + + SDK::Output("Area", std::format("{}", flArea).c_str()); + } + */ + } + } + } +#endif } \ No newline at end of file diff --git a/Amalgam/src/Features/World/World.cpp b/Amalgam/src/Features/World/World.cpp new file mode 100644 index 00000000..71d1d0d5 --- /dev/null +++ b/Amalgam/src/Features/World/World.cpp @@ -0,0 +1,536 @@ +#include "../World/World.h" + +#include + +class CEntityEnumerator : public IPartitionEnumerator +{ +public: + IterationRetval_t EnumElement(IHandleEntity* pHandleEntity) + { + m_vEntities.push_back(pHandleEntity); + return ITERATION_CONTINUE; + } + + std::vector m_vEntities = {}; +}; + +void CWorld::SetVerticesValidCallback(VerticesValidCallback* pCallback) +{ + m_pVerticesValidCallback = pCallback ? pCallback : &s_fVerticesValid; +} + +void CWorld::SetBoundsValidCallback(BoundsValidCallback* pCallback) +{ + m_pBoundsValidCallback = pCallback ? pCallback : &s_fBoundsValid; +} + +void CWorld::SetNormalValidCallback(NormalValidCallback* pCallback) +{ + m_pNormalValidCallback = pCallback ? pCallback : &s_fNormalValid; +} + +bool CWorld::FaceValid(const std::vector& vVertices, const Vec3* pNormal, const Vec3* pMins, const Vec3* pMaxs) +{ + if (!(*m_pVerticesValidCallback)(vVertices)) + return false; + + if (pMins && pMaxs && !(*m_pBoundsValidCallback)(vVertices, *pMins, *pMaxs)) + return false; + + if (pNormal && !(*m_pNormalValidCallback)(vVertices, *pNormal)) + return false; + + return true; +} + + + +static CPhysConvex* s_aConvexes[1024]; +static inline void GetFacesForConvex(CPhysConvex* pConvex, std::vector& vFaces, float flResize = 0.f, int8_t iType = FaceTypeEnum::None) +{ + CPolyhedron* pPolyhedron = I::PhysicsCollision->PolyhedronFromConvex(pConvex, true); + if (!pPolyhedron) + return; + + if (!flResize) + { + std::vector, Vec3>> vTemp = {}; + for (int iPolygon = 0; iPolygon < pPolyhedron->iPolygonCount; iPolygon++) + { + Polyhedron_IndexedPolygon_t* pPolygon = &pPolyhedron->pPolygons[iPolygon]; + + std::vector* pVertices = nullptr; + for (auto& [vVertices, vNormal] : vTemp) + { + if (pPolygon->polyNormal.Dot(vNormal) > 1 - CALC_EPSILON) + { + pVertices = &vVertices; + break; + } + } + if (!pVertices) + { + vTemp.emplace_back(std::vector(), pPolygon->polyNormal); + pVertices = &vTemp.back().first; + } + + for (int iLineRef = 0; iLineRef < pPolygon->iIndexCount; iLineRef++) + { + Polyhedron_IndexedLineReference_t* pLineReference = &pPolyhedron->pIndices[pPolygon->iFirstIndex + iLineRef]; + Polyhedron_IndexedLine_t* pLine = &pPolyhedron->pLines[pLineReference->iLineIndex]; + int iVertex = pLine->iPointIndices[pLineReference->iEndPointIndex]; + if (std::find(pVertices->begin(), pVertices->end(), iVertex) == pVertices->end()) + pVertices->push_back(iVertex); + } + } + + for (auto& [vIndices, vNormal] : vTemp) + { + if (vIndices.size() < 3) + continue; + + std::vector vVertices = {}; + for (auto& iVertex : vIndices) + vVertices.push_back(pPolyhedron->pVertices[iVertex]); + + if (vVertices.size() > 3) + { + Vec3 vCenter = std::reduce(vVertices.begin(), vVertices.end()) / vVertices.size(); + Vec3 vDir1 = (vVertices.front() - vCenter).Normalized(); + Vec3 vDir2 = vDir1.Cross(vNormal); + std::sort(vVertices.begin(), vVertices.end(), [&](const Vec3& a, const Vec3& b) -> bool + { + return atan2f(vDir2.Dot(a - vCenter), vDir1.Dot(a - vCenter)) < atan2f(vDir2.Dot(b - vCenter), vDir1.Dot(b - vCenter)); + }); + } + + vFaces.emplace_back(vVertices, vNormal, iType); + } + } + else + { // rough approximation, not too sure why this is needed in the first place + std::vector vPlanes = {}; vPlanes.reserve(pPolyhedron->iPolygonCount); + for (int iPolygon = 0; iPolygon < pPolyhedron->iPolygonCount; iPolygon++) + { + Polyhedron_IndexedPolygon_t* pPolygon = &pPolyhedron->pPolygons[iPolygon]; + + if (pPolygon->iIndexCount) + { + Polyhedron_IndexedLineReference_t* pLineReference = &pPolyhedron->pIndices[pPolygon->iFirstIndex]; + Polyhedron_IndexedLine_t* pLine = &pPolyhedron->pLines[pLineReference->iLineIndex]; + Vec3& vVertex = pPolyhedron->pVertices[pLine->iPointIndices[pLineReference->iEndPointIndex]]; + vPlanes.emplace_back(pPolygon->polyNormal, pPolygon->polyNormal.Dot(vVertex + flResize * pPolygon->polyNormal)); + } + } + + if (CPhysConvex* pConvex2 = I::PhysicsCollision->ConvexFromPlanes(reinterpret_cast(vPlanes.data()), int(vPlanes.size()), 0.f)) + { + GetFacesForConvex(pConvex2, vFaces); + I::PhysicsCollision->ConvexFree(pConvex2); + } + } + + pPolyhedron->Release(); +} + +static inline void GetFacesForCollision(CPhysCollide* pCollision, std::vector& vFaces, float flResize = 0.f, int8_t iType = FaceTypeEnum::None) +{ + int iConvexes = I::PhysicsCollision->GetConvexesUsedInCollideable(pCollision, s_aConvexes, sizeof(s_aConvexes) / sizeof(CPhysConvex*)); + for (int iConvex = 0; iConvex < iConvexes; iConvex++) + GetFacesForConvex(s_aConvexes[iConvex], vFaces, flResize, iType); + + /* + Vec3* pVertices; int iVertices = I::PhysicsCollision->CreateDebugMesh(pCollision, &pVertices); iVertices -= iVertices % 3; + for (int iVertex = 0; iVertex < iVertices; iVertex += 3) + { + std::vector vVertices = { pVertices[iVertex], pVertices[iVertex + 1], pVertices[iVertex + 2] }; + Vec3 vNormal = (vVertices[0] - vVertices[2]).Cross(vVertices[0] - vVertices[1]).Normalized(); + + vFaces.emplace_back(vVertices, vNormal, iType); + } + I::PhysicsCollision->DestroyDebugMesh(iVertices, pVertices); + */ +} + +void CWorld::Cache() +{ + if (!m_iNeedsCache) + return; + + CacheBoxBrushes(); + CachePlaneBrushes(); + CacheProps(); + CacheEntities(); +} + +void CWorld::CacheBoxBrushes() +{ + if (!(m_iNeedsCache & FaceTypeEnum::BoxBrush)) + return; + + SDK::Output(__FUNCTION__, "Cache start", {}, OUTPUT_DEBUG); + + m_iNeedsCache &= ~FaceTypeEnum::BoxBrush; + + for (int iBrush = 0; iBrush < I::BSPData->numbrushes; iBrush++) + { + cbrush_t* pBrush = &I::BSPData->map_brushes[iBrush]; + if (!pBrush->IsBox()) + continue; + + cboxbrush_t* pBoxBrush = &I::BSPData->map_boxbrushes[pBrush->GetBox()]; + + Vec3 aVertices[8]; + for (int i = 0; i != 8; i++) + { + aVertices[i].x = i & (1 << 0) ? pBoxBrush->maxs.x : pBoxBrush->mins.x; + aVertices[i].y = i & (1 << 1) ? pBoxBrush->maxs.y : pBoxBrush->mins.y; + aVertices[i].z = i & (1 << 2) ? pBoxBrush->maxs.z : pBoxBrush->mins.z; + } + Vec3 aNormals[6] = { + { 1, 0, 0 }, + { -1, 0, 0 }, + { 0, 1, 0 }, + { 0, -1, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 } + }; + + for (int i = 0; i < 6; i++) + { + if (I::BSPData->map_surfaces[pBoxBrush->surfaceIndex[i]].flags & SURF_SKY) + continue; + + std::vector vVertices; + switch (i) + { + case 0: vVertices = { aVertices[1], aVertices[5], aVertices[7], aVertices[3] }; break; + case 1: vVertices = { aVertices[2], aVertices[6], aVertices[4], aVertices[0] }; break; + case 2: vVertices = { aVertices[3], aVertices[7], aVertices[6], aVertices[2] }; break; + case 3: vVertices = { aVertices[0], aVertices[4], aVertices[5], aVertices[1] }; break; + case 4: vVertices = { aVertices[6], aVertices[7], aVertices[5], aVertices[4] }; break; + case 5: vVertices = { aVertices[0], aVertices[1], aVertices[3], aVertices[2] }; break; + } + Vec3& vNormal = aNormals[i]; + + m_mFaceCache[pBrush].emplace_back(vVertices, vNormal, FaceTypeEnum::BoxBrush); + } + } + + SDK::Output(__FUNCTION__, "Cache finish", {}, OUTPUT_DEBUG); +} + +void CWorld::CachePlaneBrushes() +{ + if (!(m_iNeedsCache & FaceTypeEnum::PlaneBrush)) + return; + + SDK::Output(__FUNCTION__, "Cache start", {}, OUTPUT_DEBUG); + + m_iNeedsCache &= ~FaceTypeEnum::PlaneBrush; + + for (int iBrush = 0; iBrush < I::BSPData->numbrushes; iBrush++) + { + cbrush_t* pBrush = &I::BSPData->map_brushes[iBrush]; + if (pBrush->IsBox()) + continue; + + std::vector vPlanes = {}; vPlanes.reserve(pBrush->numsides); + for (int iSide = 0; iSide != pBrush->numsides; iSide++) + { + cbrushside_t* pBrushSide = &I::BSPData->map_brushsides[pBrush->firstbrushside + iSide]; + if (I::BSPData->map_surfaces[pBrushSide->surfaceIndex].flags & SURF_SKY) + continue; + + cplane_t* pPlane = pBrushSide->plane; + vPlanes.emplace_back(pPlane->normal, pPlane->dist); + } + CPhysConvex* pConvex = I::PhysicsCollision->ConvexFromPlanes(reinterpret_cast(vPlanes.data()), int(vPlanes.size()), 0.f); + if (!pConvex) + continue; + + GetFacesForConvex(pConvex, m_mFaceCache[pBrush], 0.f, FaceTypeEnum::PlaneBrush); + I::PhysicsCollision->ConvexFree(pConvex); + } + + SDK::Output(__FUNCTION__, "Cache finish", {}, OUTPUT_DEBUG); +} + +void CWorld::CacheProps() +{ + if (!(m_iNeedsCache & FaceTypeEnum::Prop)) + return; + + SDK::Output(__FUNCTION__, "Cache start", {}, OUTPUT_DEBUG); + + m_iNeedsCache &= ~FaceTypeEnum::Prop; + + CUtlVector vProps; I::StaticPropMgr->GetAllStaticProps(&vProps); + for (int i = 0; i < vProps.Count(); i++) + { + vcollide_t* pCollide = I::ModelInfoClient->GetVCollide(vProps[i]->GetCollisionModel()); + if (!pCollide || m_mFaceCache.contains(pCollide)) + continue; + + for (int iSolid = 0; iSolid < pCollide->solidCount; iSolid++) + { + CPhysCollide* pCollision = pCollide->solids[iSolid]; + if (!pCollision) + continue; + + GetFacesForCollision(pCollision, m_mFaceCache[pCollide], 0.f, FaceTypeEnum::Prop); + } + } + + SDK::Output(__FUNCTION__, "Cache finish", {}, OUTPUT_DEBUG); +} + +void CWorld::CacheEntities() +{ + if (!(m_iNeedsCache & FaceTypeEnum::Entity)) + return; + + SDK::Output(__FUNCTION__, "Cache start", {}, OUTPUT_DEBUG); + + m_iNeedsCache &= ~FaceTypeEnum::Entity; + + for (int iCModel = 0; iCModel < I::BSPData->numcmodels; iCModel++) + { + cmodel_t* pCModel = &I::BSPData->map_cmodels[iCModel]; + vcollide_t* pCollide = &pCModel->vcollisionData; + + for (int iSolid = 0; iSolid < pCollide->solidCount; iSolid++) + { + CPhysCollide* pCollision = pCollide->solids[iSolid]; + if (!pCollision) + continue; + + GetFacesForCollision(pCollision, m_mFaceCache[pCollide], 0.5f, FaceTypeEnum::Entity); + } + } + + SDK::Output(__FUNCTION__, "Cache finish", {}, OUTPUT_DEBUG); +} + + + +void CWorld::Uncache() +{ + if (m_iNeedsCache == FaceTypeEnum::Cache) + return; + + m_mFaceCache.clear(); + + m_iNeedsCache = FaceTypeEnum::Cache; +} + +void CWorld::UncacheBoxBrushes() +{ + if (m_iNeedsCache & FaceTypeEnum::BoxBrush) + return; + + for (auto& [pKey, vFaces] : m_mFaceCache) + { + if (vFaces.front().m_iType == FaceTypeEnum::BoxBrush) + m_mFaceCache.erase(pKey); + } + + m_iNeedsCache |= FaceTypeEnum::BoxBrush; +} + +void CWorld::UncachePlaneBrushes() +{ + if (m_iNeedsCache & FaceTypeEnum::PlaneBrush) + return; + + for (auto& [pKey, vFaces] : m_mFaceCache) + { + if (vFaces.front().m_iType == FaceTypeEnum::PlaneBrush) + m_mFaceCache.erase(pKey); + } + + m_iNeedsCache |= FaceTypeEnum::PlaneBrush; +} + +void CWorld::UncacheProps() +{ + if (m_iNeedsCache & FaceTypeEnum::Prop) + return; + + for (auto& [pKey, vFaces] : m_mFaceCache) + { + if (vFaces.front().m_iType == FaceTypeEnum::Prop) + m_mFaceCache.erase(pKey); + } + + m_iNeedsCache |= FaceTypeEnum::Prop; +} + +void CWorld::UncacheEntities() +{ + if (m_iNeedsCache & FaceTypeEnum::Entity) + return; + + for (auto& [pKey, vFaces] : m_mFaceCache) + { + if (vFaces.front().m_iType == FaceTypeEnum::Entity) + m_mFaceCache.erase(pKey); + } + + m_iNeedsCache |= FaceTypeEnum::Entity; +} + + + +std::vector CWorld::GetFacesInAABB(const Vec3& vMins, const Vec3& vMaxs, int iMask, ITraceFilter* pFilter, int iFlags) +{ + Cache(); + + std::vector vFaces; + + if (iFlags & (FaceTypeEnum::BoxBrush | FaceTypeEnum::PlaneBrush)) + { + CUtlVector vBrushes; I::EngineTrace->GetBrushesInAABB(vMins, vMaxs, &vBrushes, iMask); + for (int iBrush = 0; iBrush < vBrushes.Count(); iBrush++) + { + cbrush_t* pBrush = &I::BSPData->map_brushes[vBrushes[iBrush]]; + if (!m_mFaceCache.contains(pBrush)) + continue; + + bool bBox = pBrush->IsBox(); + if (!(iFlags & (bBox ? FaceTypeEnum::BoxBrush : FaceTypeEnum::PlaneBrush))) + continue; + + auto& vCache = m_mFaceCache[pBrush]; + if (bBox) + { + for (auto& tFace : vCache) + { + if (FaceValid(tFace.m_vVertices, &tFace.m_vNormal, &vMins, &vMaxs)) + { + vFaces.push_back(tFace); + for (auto& vVertex : vFaces.back().m_vVertices) + vVertex = vVertex.Clamp(vMins, vMaxs); + } + } + } + else + { + for (auto& tFace : vCache) + { + if (FaceValid(tFace.m_vVertices, &tFace.m_vNormal, &vMins, &vMaxs)) + vFaces.push_back(tFace); + } + } + } + } + + if (iFlags & FaceTypeEnum::Displacement && *I::DispCollTrees) + { + for (int iDisplacement = 0; iDisplacement < *I::DispCollTreeCount; iDisplacement++) + { + CDispCollTree* pDispTree = &(*I::DispCollTrees)[iDisplacement]; + if (!Math::IsBoxIntersectingBox(vMins, vMaxs, pDispTree->m_mins, pDispTree->m_maxs)) + continue; + + int iFaces = pDispTree->GetFaceCount(); + for (int iFace = 0; iFace < iFaces; iFace++) + { + CDispCollTri* pTri = &pDispTree->m_aTris[iFace]; + + std::vector vVertices = { pDispTree->m_aVerts[pTri->GetVert(0)], pDispTree->m_aVerts[pTri->GetVert(1)], pDispTree->m_aVerts[pTri->GetVert(2)] }; + + if (FaceValid(vVertices, &pTri->m_vecNormal, &vMins, &vMaxs)) + vFaces.emplace_back(vVertices, pTri->m_vecNormal, FaceTypeEnum::Displacement); + } + } + } + + if (iFlags & (FaceTypeEnum::Entity | FaceTypeEnum::Prop)) + { + CEntityEnumerator tEnumerator; I::SpatialPartition->EnumerateElementsInBox(I::EngineTrace->SpatialPartitionMask(), vMins, vMaxs, false, &tEnumerator); + for (auto pHandleEntity : tEnumerator.m_vEntities) + { + if (!pFilter->ShouldHitEntity(pHandleEntity, iMask)) + continue; + + bool bProp = I::StaticPropMgr->IsStaticProp(pHandleEntity); + if (!(iFlags & (bProp ? FaceTypeEnum::Prop : FaceTypeEnum::Entity))) + continue; + + ICollideable* pCollideable = nullptr; + if (!I::StaticPropMgr->IsStaticProp(pHandleEntity)) + { + CBaseEntity* pEntity = reinterpret_cast(pHandleEntity); + if (!pEntity->GetAbsVelocity().IsZero()) + continue; + + pCollideable = pEntity->GetCollideable(); + } + else + pCollideable = I::StaticPropMgr->GetStaticProp(pHandleEntity); + if (!pCollideable || !pCollideable->IsSolid()) + continue; + + vcollide_t* pCollide = I::ModelInfoClient->GetVCollide(pCollideable->GetCollisionModel()); + if (!m_mFaceCache.contains(pCollide)) + continue; + + auto& vCache = m_mFaceCache[pCollide]; + for (auto& tFace : vCache) + { + std::vector vVertices = tFace.m_vVertices; + Vec3 vNormal = tFace.m_vNormal; + if (!pCollideable->GetCollisionAngles()) + { + for (auto& vVertex : vVertices) + vVertex += pCollideable->GetCollisionOrigin(); + } + else + { + for (auto& vVertex : vVertices) + vVertex = Math::VectorTransform(vVertex, pCollideable->CollisionToWorldTransform()); + vNormal = (vVertices[0] - vVertices[2]).Cross(vVertices[0] - vVertices[1]).Normalized(); + } + + if (FaceValid(vVertices, &vNormal, &vMins, &vMaxs)) + vFaces.emplace_back(vVertices, vNormal, tFace.m_iType); + } + } + } + + return vFaces; +} + +#ifdef WORLD_DEBUG +void CWorld::DrawFace(const Face_t& tFace, int iFlags) +{ + if (iFlags & (DrawTypeEnum::Points | DrawTypeEnum::Edges)) + { + for (int i = 0; i < tFace.m_vVertices.size(); i++) + { + const Vec3& vVertex1 = tFace.m_vVertices[i], &vVertex2 = tFace.m_vVertices[(i + 1) % tFace.m_vVertices.size()]; + + if (iFlags & DrawTypeEnum::Points) + G::BoxStorage.emplace_back(vVertex1, Vec3::Get(1), Vec3::Get(1), Vec3(0, 0, 0), I::GlobalVars->curtime + 60.f, Color_t(255, 0, 0), Color_t(0, 0, 0, 0), true); + if (iFlags & DrawTypeEnum::Edges) + G::LineStorage.emplace_back(std::pair(vVertex1, vVertex2), I::GlobalVars->curtime + 60.f, Color_t(255, 0, 0), true); + } + } + + if (iFlags & DrawTypeEnum::Faces) + { + 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]; + G::TriangleStorage.emplace_back(std::array({ vVertex1, vVertex2, vVertex3 }), I::GlobalVars->curtime + 60.f, Color_t(255, 0, 0, 50), true); + } + } + + if (iFlags & DrawTypeEnum::Normals) + { + G::LineStorage.emplace_back(std::pair(tFace.m_vVertices[0], tFace.m_vVertices[0] + tFace.m_vNormal * 10), I::GlobalVars->curtime + 60.f, Color_t(255, 255, 0), true); + G::BoxStorage.emplace_back(tFace.m_vVertices[0] + tFace.m_vNormal * 10, Vec3::Get(-1), Vec3::Get(1), Vec3(), I::GlobalVars->curtime + 60.f, Color_t(255, 255, 0), Color_t(0, 0, 0, 0), true); + } +} +#endif \ No newline at end of file diff --git a/Amalgam/src/Features/World/World.h b/Amalgam/src/Features/World/World.h new file mode 100644 index 00000000..1e08dce8 --- /dev/null +++ b/Amalgam/src/Features/World/World.h @@ -0,0 +1,100 @@ +#pragma once +#include "../../SDK/SDK.h" +#include + +#define DIST_EPSILON 0.03125f +#define CALC_EPSILON 0.001f + +//#define WORLD_DEBUG + +Enum(FaceType, None = 0, BoxBrush = 1 << 0, PlaneBrush = 1 << 1, Displacement = 1 << 2, Prop = 1 << 3, Entity = 1 << 4, All = BoxBrush | PlaneBrush | Displacement | Prop | Entity, Cache = BoxBrush | PlaneBrush | Prop | Entity) +#ifdef WORLD_DEBUG +Enum(DrawType, Points = 1 << 0, Edges = 1 << 1, Faces = 1 << 2, Normals = 1 << 3) + +namespace Vars { + NAMESPACE_BEGIN(World) + CVarValues(Faces, "Faces", 0b11111, NOSAVE | DEBUGVAR | DROPDOWN_MULTI, nullptr, + "BoxBrush", "PlaneBrush", "Displacement", "Prop", "Entity"); + CVarValues(Draw, "Draw", 0b0110, NOSAVE | DEBUGVAR | DROPDOWN_MULTI, nullptr, + "Points", "Edges", "Faces", "Normals"); + NAMESPACE_END(World) +} +#endif + +using VerticesValidCallback = const std::function&)>; +using BoundsValidCallback = const std::function&, const Vec3&, const Vec3&)>; +using NormalValidCallback = const std::function&, const Vec3&)>; + +struct Plane_t +{ + Vec3 m_vNormal; + float m_flDist; +}; + +struct Face_t +{ + std::vector m_vVertices; + Vec3 m_vNormal; + int8_t m_iType; +}; + +static VerticesValidCallback s_fVerticesValid = [](const std::vector& vVertices) +{ + return vVertices.size() >= 3; +}; + +static BoundsValidCallback s_fBoundsValid = [](const std::vector& vVertices, const Vec3& vMins, const Vec3& vMaxs) +{ + Vec3 vVerticeMins = Vec3::GetMax(), vVerticeMaxs = Vec3::GetMin(); + for (auto& vVertex : vVertices) + vVerticeMins = vVerticeMins.Min(vVertex), vVerticeMaxs = vVerticeMaxs.Max(vVertex); + return Math::IsBoxIntersectingBox(vVerticeMins, vVerticeMaxs, vMins, vMaxs); +}; + +static NormalValidCallback s_fNormalValid = [](const std::vector& vVertices, const Vec3& vNormal) +{ +#ifdef WORLD_DEBUG + Vec3 vAngles = I::EngineClient->GetViewAngles(); + Vec3 vForward; Math::AngleVectors(vAngles, &vForward); + return vForward.Dot(vNormal) < 0; +#else + return true; +#endif +}; + +class CWorld +{ +private: + bool FaceValid(const std::vector& vVertices, const Vec3* pNormal, const Vec3* pMins = nullptr, const Vec3* pMaxs = nullptr); + + VerticesValidCallback* m_pVerticesValidCallback = &s_fVerticesValid; + BoundsValidCallback* m_pBoundsValidCallback = &s_fBoundsValid; + NormalValidCallback* m_pNormalValidCallback = &s_fNormalValid; + + int m_iNeedsCache = FaceTypeEnum::Cache; + std::unordered_map> m_mFaceCache = {}; + +public: + void Cache(); + void CacheBoxBrushes(); + void CachePlaneBrushes(); + void CacheProps(); + void CacheEntities(); + void Uncache(); + void UncacheBoxBrushes(); + void UncachePlaneBrushes(); + void UncacheProps(); + void UncacheEntities(); + + std::vector GetFacesInAABB(const Vec3& vMins, const Vec3& vMaxs, int iMask = MASK_SOLID, ITraceFilter* pFilter = nullptr, int iFlags = FaceTypeEnum::All); + + void SetVerticesValidCallback(VerticesValidCallback* pCallback = nullptr); + void SetBoundsValidCallback(BoundsValidCallback* pCallback = nullptr); + void SetNormalValidCallback(NormalValidCallback* pCallback = nullptr); + +#ifdef WORLD_DEBUG + void DrawFace(const Face_t& tFace, int iFlags = DrawTypeEnum::Points | DrawTypeEnum::Edges | DrawTypeEnum::Faces | DrawTypeEnum::Normals); +#endif +}; + +ADD_FEATURE(CWorld, World); \ No newline at end of file diff --git a/Amalgam/src/Hooks/CModelLoader_Map_LoadModel.cpp b/Amalgam/src/Hooks/CModelLoader_Map_LoadModel.cpp new file mode 100644 index 00000000..a4da3105 --- /dev/null +++ b/Amalgam/src/Hooks/CModelLoader_Map_LoadModel.cpp @@ -0,0 +1,39 @@ +#include "../SDK/SDK.h" + +#include "../Features/World/World.h" + +MAKE_SIGNATURE(CModelLoader_Map_LoadModel, "engine.dll", "48 8B C4 48 89 58 ? 48 89 50 ? 48 89 48 ? 55 56 57 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? FF 05", 0x0); +MAKE_SIGNATURE(CStaticPropMgr_LevelInit, "engine.dll", "40 57 48 81 EC ? ? ? ? 80 B9", 0x0); +MAKE_SIGNATURE(CM_FreeMap, "engine.dll", "48 8D 0D ? ? ? ? E9 ? ? ? ? CC CC CC CC 48 89 5C 24 ? 57 48 83 EC ? 45 33 C9", 0x0); + +MAKE_HOOK(CModelLoader_Map_LoadModel, S::CModelLoader_Map_LoadModel(), void, + void* rcx, model_t* mod) +{ + DEBUG_RETURN(CModelLoader_Map_LoadModel, rcx, mod); + + CALL_ORIGINAL(rcx, mod); + + F::World.CacheBoxBrushes(); + F::World.CachePlaneBrushes(); + F::World.CacheEntities(); +} + +MAKE_HOOK(CStaticPropMgr_LevelInit, S::CStaticPropMgr_LevelInit(), void, + void* rcx) +{ + DEBUG_RETURN(CStaticPropMgr_LevelInit, rcx); + + CALL_ORIGINAL(rcx); + + F::World.CacheProps(); +} + +MAKE_HOOK(CM_FreeMap, S::CM_FreeMap(), void, + ) +{ + DEBUG_RETURN(CM_FreeMap); + + CALL_ORIGINAL(); + + F::World.Uncache(); +} \ No newline at end of file diff --git a/Amalgam/src/Hooks/COPRenderSprites_Render.cpp b/Amalgam/src/Hooks/COPRenderSprites_Render.cpp index 000e1648..befe1b95 100644 --- a/Amalgam/src/Hooks/COPRenderSprites_Render.cpp +++ b/Amalgam/src/Hooks/COPRenderSprites_Render.cpp @@ -1,6 +1,6 @@ #include "../SDK/SDK.h" -#include "../SDK/Definitions/Misc/UtlObjectReference.h" +#include "../SDK/Definitions/Misc/CUtlObjectReference.h" MAKE_SIGNATURE(COPRenderSprites_Render, "client.dll", "48 89 54 24 ? 55 53 57 41 55 41 56", 0x0); MAKE_SIGNATURE(COPRenderSprites_RenderSpriteCard, "client.dll", "48 8B C4 48 89 58 ? 57 41 54", 0x0); diff --git a/Amalgam/src/Hooks/CSoundEmitterSystem_EmitSound.cpp b/Amalgam/src/Hooks/CSoundEmitterSystem_EmitSound.cpp index e6d0f488..ca4f9fdf 100644 --- a/Amalgam/src/Hooks/CSoundEmitterSystem_EmitSound.cpp +++ b/Amalgam/src/Hooks/CSoundEmitterSystem_EmitSound.cpp @@ -72,25 +72,25 @@ struct EmitSound_t EmitSound_t(const CSoundParameters& src); - int m_nChannel; + int m_nChannel; char const* m_pSoundName; - float m_flVolume; - int m_SoundLevel; - int m_nFlags; - int m_nPitch; - int m_nSpecialDSP; + float m_flVolume; + int m_SoundLevel; + int m_nFlags; + int m_nPitch; + int m_nSpecialDSP; const Vector* m_pOrigin; - float m_flSoundTime; ///< NOT DURATION, but rather, some absolute time in the future until which this sound should be delayed + float m_flSoundTime; ///< NOT DURATION, but rather, some absolute time in the future until which this sound should be delayed float* m_pflSoundDuration; - bool m_bEmitCloseCaption; - bool m_bWarnOnMissingCloseCaption; - bool m_bWarnOnDirectWaveReference; - int m_nSpeakerEntity; - mutable CUtlVector< Vector > m_UtlVecSoundOrigin; ///< Actual sound origin(s) (can be multiple if sound routed through speaker entity(ies) ) - mutable short m_hSoundScriptHandle; + bool m_bEmitCloseCaption; + bool m_bWarnOnMissingCloseCaption; + bool m_bWarnOnDirectWaveReference; + int m_nSpeakerEntity; + mutable CUtlVector m_UtlVecSoundOrigin; ///< Actual sound origin(s) (can be multiple if sound routed through speaker entity(ies) ) + mutable short m_hSoundScriptHandle; }; -const static std::vector s_vFootsteps = { "footstep", "flesh_impact_hard", "body_medium_impact_soft", "glass_sheet_step", "rubber_tire_impact_soft", "plastic_box_impact_soft", "plastic_barrel_impact_soft", "cardboard_box_impact_soft", "ceiling_tile_step" }; +const static std::vector s_vFootsteps = { "footstep", "flesh_impact_hard", "body_medium_impact_soft", "ceiling_tile_step", "glass_sheet_step", "rubber_tire_impact_soft", "plastic_box_impact_soft", "plastic_barrel_impact_soft", "cardboard_box_impact_soft", "glass_impact_soft" }; const static std::vector s_vNoisemaker = { "items\\halloween", "items\\football_manager", "items\\japan_fundraiser", "items\\samurai\\tf_samurai_noisemaker", "items\\summer", "misc\\happy_birthday_tf", "misc\\jingle_bells" }; const static std::vector s_vFryingPan = { "pan_" }; const static std::vector s_vWater = { "ambient_mp3\\water\\water_splash", "slosh", "wade" }; @@ -102,29 +102,29 @@ static inline bool ShouldBlockSound(const char* pSound) std::string sSound = pSound; std::transform(sSound.begin(), sSound.end(), sSound.begin(), ::tolower); - auto CheckSound = [&](const std::vector& vSounds, int iFlag = -1) + auto fCheckSound = [&](const std::vector& vSounds, int iFlag = -1) + { + if (Vars::Misc::Sound::Block.Value & iFlag) { - if (/*iFlag == -1 ||*/ Vars::Misc::Sound::Block.Value & iFlag) + for (auto& sNoise : vSounds) { - for (auto& sNoise : vSounds) - { - if (sSound.find(sNoise) != std::string::npos) - return true; - } + if (sSound.find(sNoise) != std::string::npos) + return true; } - return false; - }; + } + return false; + }; - if (CheckSound(s_vFootsteps, Vars::Misc::Sound::BlockEnum::Footsteps)) + if (fCheckSound(s_vFootsteps, Vars::Misc::Sound::BlockEnum::Footsteps)) return true; - if (CheckSound(s_vNoisemaker, Vars::Misc::Sound::BlockEnum::Noisemaker)) + if (fCheckSound(s_vNoisemaker, Vars::Misc::Sound::BlockEnum::Noisemaker)) return true; - if (CheckSound(s_vFryingPan, Vars::Misc::Sound::BlockEnum::FryingPan)) + if (fCheckSound(s_vFryingPan, Vars::Misc::Sound::BlockEnum::FryingPan)) return true; - if (CheckSound(s_vWater, Vars::Misc::Sound::BlockEnum::Water)) + if (fCheckSound(s_vWater, Vars::Misc::Sound::BlockEnum::Water)) return true; return false; diff --git a/Amalgam/src/Hooks/CStaticPropMgr_ComputePropOpacity.cpp b/Amalgam/src/Hooks/CStaticPropMgr_ComputePropOpacity.cpp index 7eaf5840..31179809 100644 --- a/Amalgam/src/Hooks/CStaticPropMgr_ComputePropOpacity.cpp +++ b/Amalgam/src/Hooks/CStaticPropMgr_ComputePropOpacity.cpp @@ -2,42 +2,6 @@ MAKE_SIGNATURE(CStaticPropMgr_ComputePropOpacity, "engine.dll", "48 89 5C 24 ? 48 89 7C 24 ? 41 54 41 56 41 57 48 83 EC ? 48 8B 05", 0x0); -class CStaticProp -{ -public: - byte pad[20]; - Vector m_Origin; - QAngle m_Angles; - model_t* m_pModel; - SpatialPartitionHandle_t m_Partition; - ModelInstanceHandle_t m_ModelInstance; - unsigned char m_Alpha; - unsigned char m_nSolidType; - unsigned char m_Skin; - unsigned char m_Flags; - unsigned short m_FirstLeaf; - unsigned short m_LeafCount; - CBaseHandle m_EntHandle; // FIXME: Do I need client + server handles? - ClientRenderHandle_t m_RenderHandle; - unsigned short m_FadeIndex; // Index into the m_StaticPropFade dictionary - float m_flForcedFadeScale; - - // bbox is the same for both GetBounds and GetRenderBounds since static props never move. - // GetRenderBounds is interpolated data, and GetBounds is last networked. - Vector m_RenderBBoxMin; - Vector m_RenderBBoxMax; - matrix3x4 m_ModelToWorld; - float m_flRadius; - - Vector m_WorldRenderBBoxMin; - Vector m_WorldRenderBBoxMax; - - // FIXME: This sucks. Need to store the lighting origin off - // because the time at which the static props are unserialized - // doesn't necessarily match the time at which we can initialize the light cache - Vector m_LightingOrigin; -}; - MAKE_HOOK(CStaticPropMgr_ComputePropOpacity, S::CStaticPropMgr_ComputePropOpacity(), void, void* rcx, CStaticProp* pProp) { diff --git a/Amalgam/src/Hooks/CTFPlayerShared_InCond.cpp b/Amalgam/src/Hooks/CTFPlayerShared_InCond.cpp index 6b3fdc1f..83ce2f6c 100644 --- a/Amalgam/src/Hooks/CTFPlayerShared_InCond.cpp +++ b/Amalgam/src/Hooks/CTFPlayerShared_InCond.cpp @@ -21,13 +21,13 @@ MAKE_HOOK(CTFPlayerShared_InCond, S::CTFPlayerShared_InCond(), bool, const auto dwKart1 = S::CTFPlayer_CreateMove_InCondKart_Call(); const auto dwKart2 = S::CTFInput_ApplyMouse_InCond_Call(); - auto GetOuter = [&rcx]() -> CBaseEntity* - { - static const auto iShared = U::NetVars.GetNetVar("CTFPlayer", "m_Shared"); - static const auto iBombHeadStage = U::NetVars.GetNetVar("CTFPlayer", "m_nHalloweenBombHeadStage"); - static const auto iOffset = iBombHeadStage - iShared + 0x4; - return *reinterpret_cast(uintptr_t(rcx) + iOffset); - }; + auto fGetOuter = [&rcx]() -> CBaseEntity* + { + static const auto iShared = U::NetVars.GetNetVar("CTFPlayer", "m_Shared"); + static const auto iBombHeadStage = U::NetVars.GetNetVar("CTFPlayer", "m_nHalloweenBombHeadStage"); + static const auto iOffset = iBombHeadStage - iShared + 0x4; + return *reinterpret_cast(uintptr_t(rcx) + iOffset); + }; switch (nCond) { @@ -36,13 +36,13 @@ MAKE_HOOK(CTFPlayerShared_InCond, S::CTFPlayerShared_InCond(), bool, return false; break; case TF_COND_DISGUISED: - if (Vars::Visuals::Removals::Disguises.Value && H::Entities.GetLocal() != GetOuter()) + if (Vars::Visuals::Removals::Disguises.Value && H::Entities.GetLocal() != fGetOuter()) return false; break; case TF_COND_TAUNTING: if (dwRetAddr == dwTaunt && Vars::Misc::Automation::TauntControl.Value) return false; - if (Vars::Visuals::Removals::Taunts.Value && H::Entities.GetLocal() != GetOuter()) + if (Vars::Visuals::Removals::Taunts.Value && H::Entities.GetLocal() != fGetOuter()) return false; break; case TF_COND_HALLOWEEN_KART: diff --git a/Amalgam/src/Hooks/CTFPlayer_GetMinFOV.cpp b/Amalgam/src/Hooks/CTFPlayer_GetMinFOV.cpp index 44108101..d931700d 100644 --- a/Amalgam/src/Hooks/CTFPlayer_GetMinFOV.cpp +++ b/Amalgam/src/Hooks/CTFPlayer_GetMinFOV.cpp @@ -1,6 +1,7 @@ #include "../SDK/SDK.h" MAKE_SIGNATURE(CTFPlayer_GetMinFOV, "client.dll", "F3 0F 10 05 ? ? ? ? C3 CC CC CC CC CC CC CC 48 8B 81 ? ? ? ? 8B D2", 0x0); +MAKE_SIGNATURE(CBasePlayer_GetFOV, "client.dll", "40 53 48 83 EC ? 48 8B D9 0F 29 74 24 ? 48 8B 0D ? ? ? ? 48 8B 01", 0x0); MAKE_HOOK(CTFPlayer_GetMinFOV, S::CTFPlayer_GetMinFOV(), float, /*void* rcx*/) @@ -8,4 +9,20 @@ MAKE_HOOK(CTFPlayer_GetMinFOV, S::CTFPlayer_GetMinFOV(), float, DEBUG_RETURN(CTFPlayer_GetMinFOV, /*rcx*/); return 0.f; +} + +MAKE_HOOK(CBasePlayer_GetFOV, S::CBasePlayer_GetFOV(), float, + void* rcx) +{ + DEBUG_RETURN(CTFPlayer_GetMinFOV, rcx); + + auto pPlayer = reinterpret_cast(rcx); + if (pPlayer->entindex() != I::EngineClient->GetLocalPlayer()) + return CALL_ORIGINAL(rcx); + + int iOriginalFOV = pPlayer->m_iFOV(); + pPlayer->m_iFOV() = ceilf(G::FOV); + float flReturn = CALL_ORIGINAL(rcx); + pPlayer->m_iFOV() = iOriginalFOV; + return ceilf(flReturn); } \ No newline at end of file diff --git a/Amalgam/src/Hooks/IEngineTrace_TraceRay.cpp b/Amalgam/src/Hooks/IEngineTrace_TraceRay.cpp index d813220d..341dfe99 100644 --- a/Amalgam/src/Hooks/IEngineTrace_TraceRay.cpp +++ b/Amalgam/src/Hooks/IEngineTrace_TraceRay.cpp @@ -1,50 +1,10 @@ #include "../SDK/SDK.h" -#include - -MAKE_SIGNATURE(CM_BoxTrace, "engine.dll", "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 45 0F B6 F1", 0x0); -MAKE_SIGNATURE(CM_ClipBoxToBrush_True, "engine.dll", "48 89 5C 24 ? 57 48 81 EC ? ? ? ? 44 0F B7 42", 0x0); -MAKE_SIGNATURE(CM_ClipBoxToBrush_False, "engine.dll", "48 8B C4 48 89 58 ? 57 48 81 EC ? ? ? ? 44 0F B7 42", 0x0); -MAKE_SIGNATURE(CEngineTrace_ClipTraceToTrace, "engine.dll", "48 89 5C 24 ? 57 48 83 EC ? 80 7A ? ? 49 8B D8", 0x0); - -#define MAX_CHECK_COUNT_DEPTH 2 -typedef uint32 TraceCounter_t; -typedef CUtlVector 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]; -}; - -static bool s_bNoSkip = false; -static std::optional s_bStartSolid = std::nullopt; - MAKE_HOOK(IEngineTrace_TraceRay, U::Memory.GetVirtual(I::EngineTrace, 4), void, void* rcx, const Ray_t& ray, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace) { DEBUG_RETURN(IEngineTrace_TraceRay, rcx, ray, fMask, pTraceFilter, pTrace); - s_bNoSkip = fMask & CONTENTS_NOSKIP; - CALL_ORIGINAL(rcx, ray, fMask, pTraceFilter, pTrace); #ifdef DEBUG_TRACES if (Vars::Debug::VisualizeTraces.Value) @@ -54,74 +14,9 @@ MAKE_HOOK(IEngineTrace_TraceRay, U::Memory.GetVirtual(I::EngineTrace, 4), void, G::LineStorage.emplace_back(std::pair(vStart, vEnd), I::GlobalVars->curtime + 0.015f, Color_t(0, 0, 255), bool(GetAsyncKeyState(VK_MENU) & 0x8000)); if (!ray.m_IsRay) { - G::BoxStorage.emplace_back(ray.m_Start, ray.m_Extents * -1, ray.m_Extents, Vec3(), I::GlobalVars->curtime + 0.015f, Color_t(0, 0, 255), Color_t(0, 0, 0, 0), bool(GetAsyncKeyState(VK_MENU) & 0x8000)); - G::BoxStorage.emplace_back(vEnd - ray.m_StartOffset, ray.m_Extents * -1, ray.m_Extents, Vec3(), I::GlobalVars->curtime + 0.015f, Color_t(0, 0, 255), Color_t(0, 0, 0, 0), bool(GetAsyncKeyState(VK_MENU) & 0x8000)); + G::BoxStorage.emplace_back(ray.m_Start, -ray.m_Extents, ray.m_Extents, Vec3(), I::GlobalVars->curtime + 0.015f, Color_t(0, 0, 255), Color_t(0, 0, 0, 0), bool(GetAsyncKeyState(VK_MENU) & 0x8000)); + G::BoxStorage.emplace_back(vEnd - ray.m_StartOffset, -ray.m_Extents, ray.m_Extents, Vec3(), I::GlobalVars->curtime + 0.015f, Color_t(0, 0, 255), Color_t(0, 0, 0, 0), bool(GetAsyncKeyState(VK_MENU) & 0x8000)); } } #endif - - if (s_bStartSolid) - pTrace->startsolid = s_bStartSolid.value(), s_bStartSolid = std::nullopt; - - s_bNoSkip = false; -} - -MAKE_HOOK(CM_BoxTrace, S::CM_BoxTrace(), void, - const Ray_t& ray, int headnode, int brushmask, bool computeEndpt, trace_t& tr) -{ - CALL_ORIGINAL(ray, headnode, brushmask, computeEndpt, tr); - - if (s_bStartSolid) - tr.startsolid = s_bStartSolid.value(), s_bStartSolid = std::nullopt; - if (s_bNoSkip) - s_bStartSolid = tr.startsolid, tr.startsolid = false; -} - -MAKE_HOOK(CM_ClipBoxToBrush_True, S::CM_ClipBoxToBrush_True(), void, - TraceInfo_t* pTraceInfo, void* brush) -{ - DEBUG_RETURN(CM_ClipBoxToBrush_True, pTraceInfo, brush); - - if (s_bStartSolid) - pTraceInfo->m_trace.startsolid = s_bStartSolid.value(), s_bStartSolid = std::nullopt; - - CALL_ORIGINAL(pTraceInfo, brush); - - if (s_bNoSkip) - { - s_bStartSolid = pTraceInfo->m_trace.startsolid, pTraceInfo->m_trace.startsolid = false; - if (!s_bStartSolid.value() && !pTraceInfo->m_trace.fractionleftsolid && pTraceInfo->m_trace.fraction != 1.f) - pTraceInfo->m_trace.fractionleftsolid = pTraceInfo->m_trace.fraction - FLT_EPSILON; - } -} - -MAKE_HOOK(CM_ClipBoxToBrush_False, S::CM_ClipBoxToBrush_False(), void, - TraceInfo_t* pTraceInfo, void* brush) -{ - DEBUG_RETURN(CM_ClipBoxToBrush_False, pTraceInfo, brush); - - if (s_bStartSolid) - pTraceInfo->m_trace.startsolid = s_bStartSolid.value(), s_bStartSolid = std::nullopt; - - CALL_ORIGINAL(pTraceInfo, brush); - - if (s_bNoSkip) - { - s_bStartSolid = pTraceInfo->m_trace.startsolid, pTraceInfo->m_trace.startsolid = false; - if (!s_bStartSolid.value() && !pTraceInfo->m_trace.fractionleftsolid && pTraceInfo->m_trace.fraction != 1.f) - pTraceInfo->m_trace.fractionleftsolid = pTraceInfo->m_trace.fraction - FLT_EPSILON; - } -} - -MAKE_HOOK(CEngineTrace_ClipTraceToTrace, S::CEngineTrace_ClipTraceToTrace(), bool, - void* rcx, trace_t& clipTrace, trace_t* pFinalTrace) -{ - DEBUG_RETURN(CEngineTrace_ClipTraceToTrace, rcx, clipTrace, pFinalTrace); - - if (s_bStartSolid) - pFinalTrace->startsolid = s_bStartSolid.value(), s_bStartSolid = std::nullopt; - if (s_bNoSkip && (!clipTrace.fraction || clipTrace.fraction < pFinalTrace->fractionleftsolid)) - return false; - - return CALL_ORIGINAL(rcx, clipTrace, pFinalTrace); } \ No newline at end of file diff --git a/Amalgam/src/Hooks/IMaterialSystem_FindTexture.cpp b/Amalgam/src/Hooks/IMaterialSystem_FindTexture.cpp index d04c9bca..81000efb 100644 --- a/Amalgam/src/Hooks/IMaterialSystem_FindTexture.cpp +++ b/Amalgam/src/Hooks/IMaterialSystem_FindTexture.cpp @@ -10,21 +10,21 @@ MAKE_HOOK(IMaterialSystem_FindTexture, U::Memory.GetVirtual(I::MaterialSystem, 7 auto uHash = FNV1A::Hash32(Vars::Visuals::World::WorldTexture.Value.c_str()); if (uHash == FNV1A::Hash32Const("Flat")) { - auto overrideTexture = [&]() - { - if (!pReturn || pReturn->IsTranslucent() || !pTextureName || !pTextureGroupName) - return; + auto fOverrideTexture = [&]() + { + if (!pReturn || pReturn->IsTranslucent() || !pTextureName || !pTextureGroupName) + return; - std::string_view sName = pTextureName; - std::string_view sGroup = pTextureGroupName; - if (!sGroup.starts_with(TEXTURE_GROUP_WORLD)) - return; + std::string_view sName = pTextureName; + std::string_view sGroup = pTextureGroupName; + if (!sGroup.starts_with(TEXTURE_GROUP_WORLD)) + return; - Vec3 vColor; pReturn->GetLowResColorSample(0.5f, 0.5f, &vColor.x); - Color_t tColor = { byte(vColor.x * 255), byte(vColor.y * 255), byte(vColor.z * 255), 255 }; - pReturn = I::MaterialSystem->CreateTextureFromBits(1, 1, 1, IMAGE_FORMAT_RGBA8888, 4, &tColor.r); - }; - overrideTexture(); + Vec3 vColor; pReturn->GetLowResColorSample(0.5f, 0.5f, &vColor.x); + Color_t tColor = { byte(vColor.x * 255), byte(vColor.y * 255), byte(vColor.z * 255), 255 }; + pReturn = I::MaterialSystem->CreateTextureFromBits(1, 1, 1, IMAGE_FORMAT_RGBA8888, 4, &tColor.r); + }; + fOverrideTexture(); } return pReturn; diff --git a/Amalgam/src/SDK/Definitions/Classes.h b/Amalgam/src/SDK/Definitions/Classes.h index 83493dbb..86f1b8ab 100644 --- a/Amalgam/src/SDK/Definitions/Classes.h +++ b/Amalgam/src/SDK/Definitions/Classes.h @@ -10,13 +10,16 @@ #include "Main/CBasePlayer.h" #include "Main/CBaseProjectile.h" #include "Main/CCaptureFlag.h" +#include "Main/CCollisionProperty.h" #include "Main/CEconDefinition.h" #include "Main/CEconEntity.h" #include "Main/CEconWearable.h" #include "Main/CEntitySphereQuery.h" +#include "Main/CGameTrace.h" #include "Main/CMultiPlayerAnimState.h" #include "Main/CPredictionCopy.h" #include "Main/CSniperDot.h" +#include "Main/CStaticProp.h" #include "Main/CTFPlayer.h" #include "Main/CTFPlayerResource.h" #include "Main/CTFWeaponBase.h" @@ -34,4 +37,5 @@ #include "Main/ITexture.h" #include "Main/KeyValues.h" #include "Main/MD5.h" -#include "Main/PlayerStats.h" \ No newline at end of file +#include "Main/PlayerStats.h" +#include "Main/Ray.h" \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Definitions.h b/Amalgam/src/SDK/Definitions/Definitions.h index 3c500cfe..f9cee149 100644 --- a/Amalgam/src/SDK/Definitions/Definitions.h +++ b/Amalgam/src/SDK/Definitions/Definitions.h @@ -1215,11 +1215,6 @@ enum class CBaseEntity; -struct CUtlString -{ - char* m_pString; -}; - struct FireBulletsInfo_t { int m_iShots; diff --git a/Amalgam/src/SDK/Definitions/Interfaces.h b/Amalgam/src/SDK/Definitions/Interfaces.h index 7c71fff1..bbf52629 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces.h +++ b/Amalgam/src/SDK/Definitions/Interfaces.h @@ -4,9 +4,12 @@ #include "Interfaces/CClientModeShared.h" #include "Interfaces/CClientState.h" +#include "Interfaces/CCollisionBSPData.h" +#include "Interfaces/CDispCollTree.h" #include "Interfaces/CGlobalVarsBase.h" #include "Interfaces/CHLClient.h" #include "Interfaces/CHLTVCamera.h" +#include "Interfaces/CStaticPropMgr.h" #include "Interfaces/CTFGameRules.h" #include "Interfaces/CTFGCClientSystem.h" #include "Interfaces/CThirdPersonManager.h" @@ -26,6 +29,7 @@ #include "Interfaces/IMemAlloc.h" #include "Interfaces/IMoveHelper.h" #include "Interfaces/IPanel.h" +#include "Interfaces/ISpatialPartition.h" #include "Interfaces/IStudioRender.h" #include "Interfaces/IUniformRandomStream.h" #include "Interfaces/IVEngineClient.h" @@ -37,6 +41,7 @@ #include "Interfaces/SteamInterfaces.h" #include "Interfaces/ViewRenderBeams.h" #include "Interfaces/VPhysics.h" +#include "Interfaces/WorldBrushData.h" #include MAKE_INTERFACE_SIGNATURE(IDirect3DDevice9, DirectXDevice, "shaderapidx9.dll, shaderapivk.dll", "48 8B 0D ? ? ? ? 48 8B 01 FF 50 ? 8B F8", 0x0, 1) diff --git a/Amalgam/src/SDK/Definitions/Interfaces/CClientState.h b/Amalgam/src/SDK/Definitions/Interfaces/CClientState.h index 731a1339..d959de78 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/CClientState.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/CClientState.h @@ -1,12 +1,16 @@ #pragma once #include "Interface.h" -#include "../Main/INetChannel.h" #include "../Misc/ClientClass.h" #include "../Misc/ServerClass.h" +#include "../Misc/CUtlVector.h" +#include "../Misc/CUtlString.h" #include "../Definitions.h" MAKE_SIGNATURE(CBaseClientState_SendStringCmd, "engine.dll", "48 81 EC ? ? ? ? 48 8B 49", 0x0); +#define MAX_OSPATH 260 // max length of a filesystem pathname + +class INetChannel; class IChangeFrameList; class PackedEntity diff --git a/Amalgam/src/SDK/Definitions/Interfaces/CCollisionBSPData.h b/Amalgam/src/SDK/Definitions/Interfaces/CCollisionBSPData.h new file mode 100644 index 00000000..326b6e24 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Interfaces/CCollisionBSPData.h @@ -0,0 +1,52 @@ +#pragma once +#include "Interface.h" +#include "../Main/CModel.h" +#include "../Misc/CRangeValidatedArray.h" +#include "../Misc/CDiscardableArray.h" + +#define MAX_QPATH 96 + +class CCollisionBSPData +{ +public: + cnode_t* map_rootnode; + char map_name[MAX_QPATH]; + static csurface_t nullsurface; + int numbrushsides; + CRangeValidatedArray map_brushsides; + int numboxbrushes; + CRangeValidatedArray map_boxbrushes; + int numplanes; + CRangeValidatedArray map_planes; + int numnodes; + CRangeValidatedArray map_nodes; + int numleafs; + CRangeValidatedArray map_leafs; + int emptyleaf, solidleaf; + int numleafbrushes; + CRangeValidatedArray map_leafbrushes; + int numcmodels; + CRangeValidatedArray map_cmodels; + int numbrushes; + CRangeValidatedArray map_brushes; + int numdisplist; + CRangeValidatedArray map_dispList; + int numvisibility; + dvis_t* map_vis; + int numentitychars; + CDiscardableArray map_entitystring; + int numareas; + CRangeValidatedArray map_areas; + int numareaportals; + CRangeValidatedArray map_areaportals; + int numclusters; + char* map_nullname; + int numtextures; + char* map_texturenames; + CRangeValidatedArray map_surfaces; + int floodvalid; + int numportalopen; + CRangeValidatedArray portalopen; +}; + +MAKE_INTERFACE_SIGNATURE(CCollisionBSPData, BSPData, "engine.dll", "48 8D 15 ? ? ? ? 4C 03 05", 0x0, 0); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Interfaces/CDispCollTree.h b/Amalgam/src/SDK/Definitions/Interfaces/CDispCollTree.h new file mode 100644 index 00000000..730b4e1c --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Interfaces/CDispCollTree.h @@ -0,0 +1,114 @@ +#pragma once +#include "../Misc/CUtlVector.h" +#include "../Types.h" + +typedef __m128 fltx4; + +class __declspec(align(16)) FourVectors +{ +public: + fltx4 x, y, z; +}; + +template +class CDispVector : public CUtlVector> +{ + +}; + +class CDispCollTri +{ +public: + inline void SetVert(int iPos, int iVert) { m_TriData[iPos].m_Index.uiVert = iVert; } + inline int GetVert(int iPos) const { return m_TriData[iPos].m_Index.uiVert; } + inline void SetMin(int iAxis, int iMin) { m_TriData[iAxis].m_Index.uiMin = iMin; } + inline int GetMin(int iAxis) const { return m_TriData[iAxis].m_Index.uiMin; } + inline void SetMax(int iAxis, int iMax) { m_TriData[iAxis].m_Index.uiMax = iMax; } + inline int GetMax(int iAxis) const { return m_TriData[iAxis].m_Index.uiMax; } + + struct index_t + { + union + { + struct + { + unsigned short uiVert : 9; + unsigned short uiMin : 2; + unsigned short uiMax : 2; + } m_Index; + unsigned short m_IndexDummy; + }; + }; + + index_t m_TriData[3]; + unsigned short m_ucSignBits : 3; + unsigned short m_ucPlaneType : 3; + unsigned short m_uiFlags : 5; + Vector m_vecNormal; + float m_flDist; +}; + +class CDispCollNode +{ +public: + FourVectors m_mins; + FourVectors m_maxs; +}; + +class CDispCollLeaf +{ +public: + short m_tris[2]; +}; + +#pragma pack(1) +class CDispCollTriCache +{ +public: + unsigned short m_iCrossX[3]; + unsigned short m_iCrossY[3]; + unsigned short m_iCrossZ[3]; +}; +#pragma pack() + +class CDispCollHelper +{ +public: + + float m_flStartFrac; + float m_flEndFrac; + Vector m_vecImpactNormal; + float m_flImpactDist; +}; + +class CDispCollTree +{ +public: + inline int GetWidth(void) const { return ((1 << m_nPower) + 1); } + inline int GetHeight(void) const { return ((1 << m_nPower) + 1); } + inline int GetSize(void) const { return ((1 << m_nPower) + 1) * ((1 << m_nPower) + 1); } + inline int GetFaceCount(void) const { return ((1 << m_nPower) * (1 << m_nPower) * 2); } + + byte pad0[8]; + Vector m_mins; + int m_iCounter; + Vector m_maxs; + int m_nContents; + void* m_hCache; + int m_nPower; + int m_nFlags; + Vector m_vecSurfPoints[4]; + Vector m_vecStabDir; + short m_nSurfaceProps[2]; + CUtlVector m_aVerts; + CDispVector m_aTris; + CDispVector m_nodes; + CDispVector m_leaves; + CUtlVector m_aTrisCache; + CUtlVector m_aEdgePlanes; + CDispCollHelper m_Helper; + unsigned int m_nSize; +}; + +MAKE_INTERFACE_SIGNATURE(CDispCollTree*, DispCollTrees, "engine.dll", "48 89 05 ? ? ? ? E8 ? ? ? ? 48 8B D0", 0x0, 0, false); +MAKE_INTERFACE_SIGNATURE(int, DispCollTreeCount, "engine.dll", "44 89 35 ? ? ? ? E8", 0x0, 0, false); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Interfaces/CHLClient.h b/Amalgam/src/SDK/Definitions/Interfaces/CHLClient.h index fc3979b3..bb4b0975 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/CHLClient.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/CHLClient.h @@ -1,31 +1,37 @@ #pragma once #include "Interface.h" -#include "../Main/UtlVector.h" #include "../Misc/BaseTypes.h" -#include "../Misc/bitbuf.h" -#include "../Misc/ButtonCode.h" -#include "../Misc/ChecksumCRC.h" #include "../Misc/ClientClass.h" +#include "../Misc/bitbuf.h" +#include "../Misc/CUtlVector.h" +#include "../Misc/ButtonCode.h" #include "../Misc/CViewSetup.h" -#include "../Misc/Datamap.h" -#include "../Misc/Modes.h" -#include "../Definitions.h" #include -struct vrect_t; -struct cmodel_t; -struct ScreenFade_t; -struct ScreenShake_t; -class CEngineSprite; class CGlobalVarsBase; +class CEngineSprite; class CSaveRestoreData; -struct datamap_t; -struct typedescription_t; class CStandardRecvProxies; class IFileList; class CRenamedRecvTableInfo; class CMouthInfo; class IConVar; +struct vrect_t; +struct ScreenFade_t; +struct datamap_t; +struct typedescription_t; + +enum ClientFrameStage_t +{ + FRAME_UNDEFINED = -1, + FRAME_START, + FRAME_NET_UPDATE_START, + FRAME_NET_UPDATE_POSTDATAUPDATE_START, + FRAME_NET_UPDATE_POSTDATAUPDATE_END, + FRAME_NET_UPDATE_END, + FRAME_RENDER_START, + FRAME_RENDER_END +}; typedef struct _XUSER_DATA { @@ -62,18 +68,6 @@ typedef struct _XUSER_CONTEXT DWORD dwValue; } XUSER_CONTEXT, * PXUSER_CONTEXT; -enum ClientFrameStage_t -{ - FRAME_UNDEFINED = -1, - FRAME_START, - FRAME_NET_UPDATE_START, - FRAME_NET_UPDATE_POSTDATAUPDATE_START, - FRAME_NET_UPDATE_POSTDATAUPDATE_END, - FRAME_NET_UPDATE_END, - FRAME_RENDER_START, - FRAME_RENDER_END -}; - class IBaseClientDLL { public: diff --git a/Amalgam/src/SDK/Definitions/Interfaces/CHLTVCamera.h b/Amalgam/src/SDK/Definitions/Interfaces/CHLTVCamera.h index 548e8a93..c4a9aa5c 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/CHLTVCamera.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/CHLTVCamera.h @@ -5,21 +5,21 @@ class CHLTVCamera : CGameEventListener { public: - int m_nCameraMode; // current camera mode - int m_iCameraMan; // camera man entindex or 0 - Vector m_vCamOrigin; //current camera origin - QAngle m_aCamAngle; //current camera angle - int m_iTraget1; // first tracked target or 0 - int m_iTraget2; // second tracked target or 0 - float m_flFOV; // current FOV - float m_flOffset; // z-offset from target origin - float m_flDistance; // distance to traget origin+offset - float m_flLastDistance; // too smooth distance - float m_flTheta; // view angle horizontal - float m_flPhi; // view angle vertical - float m_flInertia; // camera inertia 0..100 + int m_nCameraMode; + int m_iCameraMan; + Vector m_vCamOrigin; + QAngle m_aCamAngle; + int m_iTraget1; + int m_iTraget2; + float m_flFOV; + float m_flOffset; + float m_flDistance; + float m_flLastDistance; + float m_flTheta; + float m_flPhi; + float m_flInertia; float m_flLastAngleUpdateTime; - bool m_bEntityPacketReceived; // true after a new packet was received + bool m_bEntityPacketReceived; int m_nNumSpectators; char m_szTitleText[64]; CUserCmd m_LastCmd; diff --git a/Amalgam/src/SDK/Definitions/Interfaces/CStaticPropMgr.h b/Amalgam/src/SDK/Definitions/Interfaces/CStaticPropMgr.h new file mode 100644 index 00000000..20d25842 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Interfaces/CStaticPropMgr.h @@ -0,0 +1,130 @@ +#pragma once +#include "../Main/CStaticProp.h" +#include "../Main/CGameTrace.h" +#include "../Misc/CUtlVector.h" + +class IPhysicsEnvironment; +class IVPhysicsKeyHandler; +typedef unsigned short MDLHandle_t; +typedef struct LightCacheHandle_t__* LightCacheHandle_t; + +struct StaticPropLeafLump_t +{ + unsigned short m_Leaf; +}; + +class IStaticPropMgrEngine +{ +public: + virtual bool Init() = 0; + virtual void Shutdown() = 0; + virtual void LevelInit() = 0; + virtual void LevelInitClient() = 0; + virtual void LevelShutdownClient() = 0; + virtual void LevelShutdown() = 0; + virtual void RecomputeStaticLighting() = 0; + virtual bool IsPropInPVS(IHandleEntity* pHandleEntity, const byte* pVis) const = 0; + virtual ICollideable* GetStaticProp(IHandleEntity* pHandleEntity) = 0; + virtual LightCacheHandle_t GetLightCacheHandleForStaticProp(IHandleEntity* pHandleEntity) = 0; + virtual bool IsStaticProp(IHandleEntity* pHandleEntity) const = 0; + virtual bool IsStaticProp(CBaseHandle handle) const = 0; + virtual int GetStaticPropIndex(IHandleEntity* pHandleEntity) const = 0; + virtual bool PropHasBakedLightingDisabled(IHandleEntity* pHandleEntity) const = 0; +}; + +class IStaticPropMgr +{ +public: + virtual void CreateVPhysicsRepresentations(IPhysicsEnvironment* physenv, IVPhysicsKeyHandler* pDefaults, void* pGameData) = 0; + virtual void TraceRayAgainstStaticProp(const Ray_t& ray, int staticPropIndex, trace_t& tr) = 0; + virtual bool IsStaticProp(IHandleEntity* pHandleEntity) const = 0; + virtual bool IsStaticProp(CBaseHandle handle) const = 0; + virtual ICollideable* GetStaticPropByIndex(int propIndex) = 0; +}; + +class IStaticPropMgrClient : public IStaticPropMgr +{ +public: + virtual void ComputePropOpacity(const Vector & viewOrigin, float factor) = 0; + virtual void AddDecalToStaticProp(const Vector& rayStart, const Vector& rayEnd, int staticPropIndex, int decalIndex, bool doTrace, trace_t& tr) = 0; + virtual void AddShadowToStaticProp(unsigned short shadowHandle, IClientRenderable* pRenderable) = 0; + virtual void RemoveAllShadowsFromStaticProp(IClientRenderable* pRenderable) = 0; + virtual void GetStaticPropMaterialColorAndLighting(trace_t* pTrace, int staticPropIndex, Vector& lighting, Vector& matColor) = 0; + virtual void GetAllStaticProps(CUtlVector* pOutput) = 0; + virtual void GetAllStaticPropsInAABB(const Vector& vMins, const Vector& vMaxs, CUtlVector* pOutput) = 0; + virtual void GetAllStaticPropsInOBB(const Vector& ptOrigin, const Vector& vExtent1, const Vector& vExtent2, const Vector& vExtent3, CUtlVector* pOutput) = 0; + virtual void DrawStaticProps(IClientRenderable** pProps, int count, bool bShadowDepth, bool drawVCollideWireframe) = 0; + virtual void AddColorDecalToStaticProp(Vector const& rayStart, Vector const& rayEnd, int staticPropIndex, int decalIndex, bool doTrace, trace_t& tr, bool bUseColor, Color_t cColor) = 0; +}; + +class IStaticPropMgrServer : public IStaticPropMgr +{ +public: + virtual void GetAllStaticProps(CUtlVector* pOutput) = 0; + virtual void GetAllStaticPropsInAABB(const Vector& vMins, const Vector& vMaxs, CUtlVector* pOutput) = 0; + virtual void GetAllStaticPropsInOBB(const Vector& ptOrigin, const Vector& vExtent1, const Vector& vExtent2, const Vector& vExtent3, CUtlVector* pOutput) = 0; +}; + +class CStaticPropMgr : public IStaticPropMgrEngine, public IStaticPropMgrClient, public IStaticPropMgrServer +{ +public: + virtual ~CStaticPropMgr() = 0; + virtual bool Init() = 0; + virtual void Shutdown() = 0; + virtual void LevelInit() = 0; + virtual void LevelInitClient() = 0; + virtual void LevelShutdown() = 0; + virtual void LevelShutdownClient() = 0; + virtual bool IsPropInPVS(IHandleEntity* pHandleEntity, const byte* pVis) const = 0; + virtual ICollideable* GetStaticProp(IHandleEntity* pHandleEntity) = 0; + virtual void RecomputeStaticLighting() = 0; + virtual LightCacheHandle_t GetLightCacheHandleForStaticProp(IHandleEntity* pHandleEntity) = 0; + virtual bool IsStaticProp(IHandleEntity* pHandleEntity) const = 0; + virtual bool IsStaticProp(CBaseHandle handle) const = 0; + virtual int GetStaticPropIndex(IHandleEntity* pHandleEntity) const = 0; + virtual ICollideable* GetStaticPropByIndex(int propIndex) = 0; + virtual void ComputePropOpacity(const Vector& viewOrigin, float factor) = 0; + virtual void TraceRayAgainstStaticProp(const Ray_t& ray, int staticPropIndex, trace_t& tr) = 0; + virtual void AddDecalToStaticProp(Vector const& rayStart, Vector const& rayEnd, int staticPropIndex, int decalIndex, bool doTrace, trace_t& tr) = 0; + virtual void AddColorDecalToStaticProp(Vector const& rayStart, Vector const& rayEnd, int staticPropIndex, int decalIndex, bool doTrace, trace_t& tr, bool bUseColor, Color_t cColor) = 0; + virtual void AddShadowToStaticProp(unsigned short shadowHandle, IClientRenderable* pRenderable) = 0; + virtual void RemoveAllShadowsFromStaticProp(IClientRenderable* pRenderable) = 0; + virtual void GetStaticPropMaterialColorAndLighting(trace_t* pTrace, int staticPropIndex, Vector& lighting, Vector& matColor) = 0; + virtual void CreateVPhysicsRepresentations(IPhysicsEnvironment* physenv, IVPhysicsKeyHandler* pDefaults, void* pGameData) = 0; + virtual void GetAllStaticProps(CUtlVector* pOutput) = 0; + virtual void GetAllStaticPropsInAABB(const Vector& vMins, const Vector& vMaxs, CUtlVector* pOutput) = 0; + virtual void GetAllStaticPropsInOBB(const Vector& ptOrigin, const Vector& vExtent1, const Vector& vExtent2, const Vector& vExtent3, CUtlVector* pOutput) = 0; + virtual bool PropHasBakedLightingDisabled(IHandleEntity* pHandleEntity) const = 0; + + struct StaticPropDict_t + { + model_t* m_pModel; + MDLHandle_t m_hMDL; + }; + struct StaticPropFade_t + { + int m_Model; + union + { + float m_MinDistSq; + float m_MaxScreenWidth; + }; + union + { + float m_MaxDistSq; + float m_MinScreenWidth; + }; + float m_FalloffFactor; + }; + + CUtlVector m_StaticPropDict; + CUtlVector m_StaticProps; + CUtlVector m_StaticPropLeaves; + CUtlVector m_StaticPropFade; + bool m_bLevelInitialized; + bool m_bClientInitialized; + Vector m_vecLastViewOrigin; + float m_flLastViewFactor; +}; + +MAKE_INTERFACE_SIGNATURE(CStaticPropMgr, StaticPropMgr, "engine.dll", "48 8D 05 ? ? ? ? C3 CC CC CC CC CC CC CC CC 48 89 5C 24 ? 48 89 74 24 ? 57 48 81 EC ? ? ? ? 41 8B C0", 0x0, 0); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Interfaces/CThirdPersonManager.h b/Amalgam/src/SDK/Definitions/Interfaces/CThirdPersonManager.h index 3b5caf28..906c31be 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/CThirdPersonManager.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/CThirdPersonManager.h @@ -21,5 +21,4 @@ public: float m_flUpLerpTime; }; - MAKE_INTERFACE_SIGNATURE(CThirdPersonManager, ThirdPersonManager, "client.dll", "48 8D 0D ? ? ? ? 0F 29 BC 24", 0x0, 0); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Interfaces/ICVar.h b/Amalgam/src/SDK/Definitions/Interfaces/ICVar.h index 9797ba18..6edaa515 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/ICVar.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/ICVar.h @@ -5,7 +5,6 @@ class ConCommandBase; class ConCommand; - typedef int CVarDLLIdentifier_t; class IConsoleDisplayFunc diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IEngineTrace.h b/Amalgam/src/SDK/Definitions/Interfaces/IEngineTrace.h index 661193ab..64dfdfe9 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IEngineTrace.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IEngineTrace.h @@ -1,16 +1,15 @@ #pragma once #include "Interface.h" -#include "../Main/CBaseHandle.h" -#include "../Main/UtlVector.h" #include "../Main/CModel.h" +#include "../Misc/CUtlVector.h" #include "../Types.h" class CGameTrace; -typedef CGameTrace trace_t; +class IHandleEntity; class ICollideable; class CTraceListData; class CPhysCollide; -struct cplane_t; +typedef CGameTrace trace_t; enum TraceType_t { @@ -20,6 +19,14 @@ enum TraceType_t TRACE_EVERYTHING_FILTER_PROPS }; +enum +{ + TRACE_STAT_COUNTER_TRACERAY = 0, + TRACE_STAT_COUNTER_POINTCONTENTS, + TRACE_STAT_COUNTER_ENUMERATE, + NUM_TRACE_STAT_COUNTER +}; + class ITraceFilter { public: @@ -36,8 +43,8 @@ public: class IEngineTrace { public: - virtual int GetPointContents(const Vector& vecAbsPosition, IHandleEntity** ppEntity = NULL) = 0; - virtual int GetPointContents_Collideable(ICollideable* pCollide, const Vector& vecAbsPosition) = 0; + virtual int GetPointContents(const Vector& vecAbsPosition, IHandleEntity** ppEntity = NULL) = 0; + virtual int GetPointContents_Collideable(ICollideable* pCollide, const Vector& vecAbsPosition) = 0; virtual void ClipRayToEntity(const Ray_t& ray, unsigned int fMask, IHandleEntity* pEnt, trace_t* pTrace) = 0; virtual void ClipRayToCollideable(const Ray_t& ray, unsigned int fMask, ICollideable* pCollide, trace_t* pTrace) = 0; virtual void TraceRay(const Ray_t& ray, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace) = 0; @@ -56,4 +63,35 @@ public: virtual int GetLeafContainingPoint(const Vector& ptTest) = 0; }; -MAKE_INTERFACE_VERSION(IEngineTrace, EngineTrace, "engine.dll", "EngineTraceClient003"); \ No newline at end of file +class CEngineTrace : public IEngineTrace +{ +public: + virtual int GetPointContents(const Vector& vecAbsPosition, IHandleEntity** ppEntity = NULL) = 0; + virtual int GetPointContents_Collideable(ICollideable* pCollide, const Vector& vecAbsPosition) = 0; + virtual void ClipRayToEntity(const Ray_t& ray, unsigned int fMask, IHandleEntity* pEntity, trace_t* pTrace) = 0; + virtual void TraceRay(const Ray_t& ray, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace) = 0; + virtual void SetupLeafAndEntityListRay(const Ray_t& ray, CTraceListData& traceData) = 0; + virtual void SetupLeafAndEntityListBox(const Vector& vecBoxMin, const Vector& vecBoxMax, CTraceListData& traceData) = 0; + virtual void TraceRayAgainstLeafAndEntityList(const Ray_t& ray, CTraceListData& traceData, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace) = 0; + virtual void SweepCollideable(ICollideable* pCollide, const Vector& vecAbsStart, const Vector& vecAbsEnd, const QAngle& vecAngles, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace) = 0; + virtual void EnumerateEntities(const Ray_t& ray, bool triggers, IEntityEnumerator* pEnumerator) = 0; + virtual void EnumerateEntities(const Vector& vecAbsMins, const Vector& vecAbsMaxs, IEntityEnumerator* pEnumerator) = 0; + virtual void HandleEntityToCollideable(IHandleEntity* pHandleEntity, ICollideable** ppCollide, const char** ppDebugName) = 0; + virtual ICollideable* GetWorldCollideable() = 0; + virtual void ClipRayToCollideable(const Ray_t& ray, unsigned int fMask, ICollideable* pEntity, trace_t* pTrace) = 0; + virtual int GetStatByIndex(int index, bool bClear) = 0; + virtual void GetBrushesInAABB(const Vector& vMins, const Vector& vMaxs, CUtlVector* pOutput, int iContentsMask = 0xFFFFFFFF) = 0; + virtual CPhysCollide* GetCollidableFromDisplacementsInAABB(const Vector& vMins, const Vector& vMaxs) = 0; + virtual bool GetBrushInfo(int iBrush, CUtlVector* pPlanesOut, int* pContentsOut) = 0; + virtual bool PointOutsideWorld(const Vector& ptTest) = 0; + virtual int GetLeafContainingPoint(const Vector& ptTest) = 0; + virtual void SetTraceEntity(ICollideable* pCollideable, trace_t* pTrace) = 0; + virtual ICollideable* GetCollideable(IHandleEntity* pEntity) = 0; + virtual int SpatialPartitionMask() const = 0; + virtual int SpatialPartitionTriggerMask() const = 0; + + int m_traceStatCounters[NUM_TRACE_STAT_COUNTER]; + const matrix3x4* m_pRootMoveParent; +}; + +MAKE_INTERFACE_VERSION(CEngineTrace, EngineTrace, "engine.dll", "EngineTraceClient003"); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IFileSystem.h b/Amalgam/src/SDK/Definitions/Interfaces/IFileSystem.h index 000201e6..b3ce4c82 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IFileSystem.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IFileSystem.h @@ -2,13 +2,25 @@ #include "../Misc/IAppSystem.h" #include "../Main/MD5.h" +class CUtlBuffer; +class CSysModule; +class IThreadPool; +class KeyValues; +class IAsyncFileFetch; +class IPureServerWhitelist; +class IFileList; +class CUnverifiedFileHash; +class CMemoryFileBacking; +struct FileAsyncRequest_t; +struct FileSystemStatistics; +struct FileHash_t; +struct FSAsyncControl_t__ { int unused; }; typedef struct FSAsyncControl_t__* FSAsyncControl_t; +struct FSAsyncFile_t__ { int unused; }; typedef struct FSAsyncFile_t__* FSAsyncFile_t; typedef void* FileHandle_t; typedef void* (*FSAllocFunc_t)(const char* pszFilename, unsigned nBytes); typedef uint32_t PathTypeQuery_t; typedef int FileFindHandle_t; typedef void* FileNameHandle_t; -struct FSAsyncControl_t__ { int unused; }; typedef struct FSAsyncControl_t__* FSAsyncControl_t; -struct FSAsyncFile_t__ { int unused; }; typedef struct FSAsyncFile_t__* FSAsyncFile_t; typedef int WaitForResourcesHandle_t; typedef void (*FileSystemLoggingFunc_t)(const char* fileName, const char* accessType); typedef void (*FSDirtyDiskReportFunc_t)(); @@ -20,22 +32,26 @@ enum FileSystemSeek_t FILESYSTEM_SEEK_CURRENT = SEEK_CUR, FILESYSTEM_SEEK_TAIL = SEEK_END, }; + enum FilesystemMountRetval_t { FILESYSTEM_MOUNT_OK = 0, FILESYSTEM_MOUNT_FAILED, }; + enum SearchPathAdd_t { PATH_ADD_TO_HEAD, PATH_ADD_TO_TAIL, }; + enum PathTypeFilter_t { FILTER_NONE = 0, FILTER_CULLPACK = 1, FILTER_CULLNONPACK = 2, }; + enum FSAsyncStatus_t { FSASYNC_ERR_NOT_MINE = -8, @@ -52,6 +68,7 @@ enum FSAsyncStatus_t FSASYNC_STATUS_ABORTED, FSASYNC_STATUS_UNSERVICED, }; + enum FileWarningLevel_t { FILESYSTEM_WARNING = -1, @@ -63,12 +80,14 @@ enum FileWarningLevel_t FILESYSTEM_WARNING_REPORTALLACCESSES_READWRITE, FILESYSTEM_WARNING_REPORTALLACCESSES_ASYNC, }; + enum DVDMode_t { DVDMODE_OFF = 0, DVDMODE_STRICT = 1, DVDMODE_DEV = 2, }; + enum EPureServerFileClass { ePureServerFileClass_Unknown = -1, @@ -76,12 +95,14 @@ enum EPureServerFileClass ePureServerFileClass_AnyTrusted, ePureServerFileClass_CheckHash, }; + enum ECacheCRCType { k_eCacheCRCType_SingleFile, k_eCacheCRCType_Directory, k_eCacheCRCType_Directory_Recursive }; + enum EFileCRCStatus { k_eFileCRCStatus_CantOpenFile, @@ -89,18 +110,6 @@ enum EFileCRCStatus k_eFileCRCStatus_FileInVPK }; -struct FileAsyncRequest_t; -struct FileSystemStatistics; -struct FileHash_t; -class CUtlBuffer; -class CSysModule; -class IThreadPool; -class KeyValues; -class IAsyncFileFetch; -class IPureServerWhitelist; -class IFileList; -class CUnverifiedFileHash; -class CMemoryFileBacking; typedef void (*FSAsyncCallbackFunc_t)(const FileAsyncRequest_t& request, int nBytesRead, FSAsyncStatus_t err); class IBaseFileSystem diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IGameEvents.h b/Amalgam/src/SDK/Definitions/Interfaces/IGameEvents.h index 0e638240..af017a2c 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IGameEvents.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IGameEvents.h @@ -53,8 +53,6 @@ public: virtual IGameEvent* UnserializeEvent(bf_read* buf) = 0; }; -MAKE_INTERFACE_VERSION(IGameEventManager2, GameEventManager, "engine.dll", "GAMEEVENTSMANAGER002"); - class IGameEventListener { public: @@ -77,4 +75,6 @@ public: virtual bool FireEventClientOnly(KeyValues* event) = 0; virtual bool SerializeKeyValues(KeyValues* event, bf_write* buf, CGameEvent* eventtype = nullptr) = 0; virtual KeyValues* UnserializeKeyValue(bf_read* msg) = 0; -}; \ No newline at end of file +}; + +MAKE_INTERFACE_VERSION(IGameEventManager2, GameEventManager, "engine.dll", "GAMEEVENTSMANAGER002"); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IGameMovement.h b/Amalgam/src/SDK/Definitions/Interfaces/IGameMovement.h index 3c29e75c..c7e6851d 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IGameMovement.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IGameMovement.h @@ -1,7 +1,9 @@ #pragma once -#include "IMoveHelper.h" +#include "../Main/CBaseHandle.h" +#include "../Types.h" class CTFPlayer; +class CBasePlayer; class CMoveData { @@ -33,8 +35,6 @@ public: Vector m_vecAbsOrigin; }; -class CBasePlayer; - class IGameMovement { public: diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IInput.h b/Amalgam/src/SDK/Definitions/Interfaces/IInput.h index bcfa3b74..2c702982 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IInput.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IInput.h @@ -1,5 +1,6 @@ #pragma once #include "Interface.h" +#include "../Main/CUserCmd.h" #include "../Misc/bitbuf.h" #include "../Misc/IClientMode.h" #include "../Misc/ChecksumCRC.h" diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IKeyValuesSystem.h b/Amalgam/src/SDK/Definitions/Interfaces/IKeyValuesSystem.h index cd5b5df7..63c3c374 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IKeyValuesSystem.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IKeyValuesSystem.h @@ -1,9 +1,9 @@ #pragma once #include "Interface.h" -typedef int HKeySymbol; class IBaseFileSystem; class KeyValues; +typedef int HKeySymbol; class IKeyValuesSystem { diff --git a/Amalgam/src/SDK/Definitions/Interfaces/ILocalize.h b/Amalgam/src/SDK/Definitions/Interfaces/ILocalize.h index 16850c0c..aba0619d 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/ILocalize.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/ILocalize.h @@ -1,9 +1,8 @@ #pragma once #include "Interface.h" -typedef unsigned long StringIndex_t; - class KeyValues; +typedef unsigned long StringIndex_t; class ILocalize { diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IMatSystemSurface.h b/Amalgam/src/SDK/Definitions/Interfaces/IMatSystemSurface.h index ea688dd0..8fba5dac 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IMatSystemSurface.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IMatSystemSurface.h @@ -9,7 +9,6 @@ class VMatrix; class IMaterial; class ITexture; struct InputEvent_t; - typedef void (*GetMouseCallback_t)(int& x, int& y); typedef void (*SetMouseCallback_t)(int x, int y); typedef void (*PlaySoundFunc_t)(const char* pFileName); diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IMaterialSystem.h b/Amalgam/src/SDK/Definitions/Interfaces/IMaterialSystem.h index 74572e56..1a1bf87e 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IMaterialSystem.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IMaterialSystem.h @@ -14,27 +14,45 @@ #define OO_OVERBRIGHT ( 1.0f / 2.0f ) #define GAMMA 2.2f #define TEXGAMMA 2.2f +#define ABSOLUTE_MINIMUM_DXLEVEL 80 +#define MATERIAL_MORPH_DECAL ( (IMorph*)1 ) +#define CREATERENDERTARGETFLAGS_HDR 0x00000001 +#define CREATERENDERTARGETFLAGS_AUTOMIPMAP 0x00000002 +#define CREATERENDERTARGETFLAGS_UNFILTERABLE_OK 0x00000004 +#define CREATERENDERTARGETFLAGS_NOEDRAM 0x00000008 +#define CREATERENDERTARGETFLAGS_TEMP 0x00000010 +#define MAX_FB_TEXTURES 4 +#define INVALID_OCCLUSION_QUERY_OBJECT_HANDLE ( (OcclusionQueryObjectHandle_t)0 ) class IMaterial; class IMesh; class IVertexBuffer; class IIndexBuffer; -struct MaterialSystem_Config_t; class ITexture; class ITextureCompositor; -struct MaterialSystemHardwareIdentifier_t; class KeyValues; class IShader; class IVertexTexture; class IMorph; class IMatRenderContext; class ICallQueue; -struct MorphWeight_t; class IFileList; - +class IMaterialProxyFactory; +class ITexture; +class IMaterialSystemHardwareConfig; +class CShadowMgr; +struct MaterialSystem_Config_t; +struct MaterialSystemHardwareIdentifier_t; +struct MorphWeight_t; typedef uint64 VertexFormat_t; - -#define ABSOLUTE_MINIMUM_DXLEVEL 80 +typedef void (*MaterialBufferReleaseFunc_t)(); +typedef void (*MaterialBufferRestoreFunc_t)(int nChangeFlags); +typedef void (*ModeChangeCallbackFunc_t)(void); +typedef int VertexBufferHandle_t; +typedef unsigned short MaterialHandle_t; +typedef unsigned int MorphFormat_t; +using OcclusionQueryObjectHandle_t = void*; +using MaterialLock_t = void*; enum ShaderParamType_t { @@ -71,9 +89,6 @@ enum MaterialMatrixMode_t NUM_TEXTURE_TRANSFORMS = MATERIAL_TEXTURE7 - MATERIAL_TEXTURE0 + 1 }; -const int NUM_MODEL_TRANSFORMS = 53; -const int MATERIAL_MODEL_MAX = MATERIAL_MODEL + NUM_MODEL_TRANSFORMS; - enum MaterialPrimitiveType_t { MATERIAL_POINTS = 0x0, @@ -144,8 +159,6 @@ enum MaterialNonInteractiveMode_t MATERIAL_NON_INTERACTIVE_MODE_COUNT }; -#define MATERIAL_MORPH_DECAL ( (IMorph*)1 ) - enum MaterialThreadMode_t { MATERIAL_SINGLE_THREADED, @@ -166,12 +179,6 @@ enum MaterialFindContext_t MATERIAL_FINDCONTEXT_ISONAMODEL }; -#define CREATERENDERTARGETFLAGS_HDR 0x00000001 -#define CREATERENDERTARGETFLAGS_AUTOMIPMAP 0x00000002 -#define CREATERENDERTARGETFLAGS_UNFILTERABLE_OK 0x00000004 -#define CREATERENDERTARGETFLAGS_NOEDRAM 0x00000008 -#define CREATERENDERTARGETFLAGS_TEMP 0x00000010 - enum StencilOperation_t { STENCILOPERATION_KEEP = 1, @@ -207,8 +214,6 @@ enum MorphFormatFlags_t MORPH_SIDE = 0x0010 }; -typedef unsigned int MorphFormat_t; - enum StandardLightmap_t { MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE = -1, @@ -216,19 +221,59 @@ enum StandardLightmap_t MATERIAL_SYSTEM_LIGHTMAP_PAGE_USER_DEFINED = -3 }; +enum +{ + MATERIAL_ADAPTER_NAME_LENGTH = 512 +}; + +enum MaterialInitFlags_t +{ + MATERIAL_INIT_ALLOCATE_FULLSCREEN_TEXTURE = 0x2, + MATERIAL_INIT_REFERENCE_RASTERIZER = 0x4 +}; + +enum MaterialRenderTargetDepth_t +{ + MATERIAL_RT_DEPTH_SHARED = 0x0, + MATERIAL_RT_DEPTH_SEPARATE = 0x1, + MATERIAL_RT_DEPTH_NONE = 0x2, + MATERIAL_RT_DEPTH_ONLY = 0x3 +}; + +enum RestoreChangeFlags_t +{ + MATERIAL_RESTORE_VERTEX_FORMAT_CHANGED = 0x1 +}; + +enum RenderTargetSizeMode_t +{ + RT_SIZE_NO_CHANGE = 0, + RT_SIZE_DEFAULT = 1, + RT_SIZE_PICMIP = 2, + RT_SIZE_HDR = 3, + RT_SIZE_FULL_FRAME_BUFFER = 4, + RT_SIZE_OFFSCREEN = 5, + RT_SIZE_FULL_FRAME_BUFFER_ROUNDED_UP = 6, + RT_SIZE_REPLAY_SCREENSHOT = 7, + RT_SIZE_LITERAL = 8, + RT_SIZE_LITERAL_PICMIP = 9 +}; + +enum RenderBackend_t +{ + RENDER_BACKEND_UNKNOWN, + RENDER_BACKEND_D3D9, + RENDER_BACKEND_TOGL, + RENDER_BACKEND_VULKAN, + RENDER_BACKEND_NULL, +}; + struct MaterialSystem_SortInfo_t { IMaterial* material; int lightmapPageID; }; -#define MAX_FB_TEXTURES 4 - -enum -{ - MATERIAL_ADAPTER_NAME_LENGTH = 512 -}; - struct MaterialAdapterInfo_t { char m_pDriverName[MATERIAL_ADAPTER_NAME_LENGTH]; @@ -290,64 +335,8 @@ public: virtual int GetRefCount() const = 0; }; -enum MaterialInitFlags_t -{ - MATERIAL_INIT_ALLOCATE_FULLSCREEN_TEXTURE = 0x2, - MATERIAL_INIT_REFERENCE_RASTERIZER = 0x4 -}; - -enum MaterialRenderTargetDepth_t -{ - MATERIAL_RT_DEPTH_SHARED = 0x0, - MATERIAL_RT_DEPTH_SEPARATE = 0x1, - MATERIAL_RT_DEPTH_NONE = 0x2, - MATERIAL_RT_DEPTH_ONLY = 0x3 -}; - -enum RestoreChangeFlags_t -{ - MATERIAL_RESTORE_VERTEX_FORMAT_CHANGED = 0x1 -}; - -enum RenderTargetSizeMode_t -{ - RT_SIZE_NO_CHANGE = 0, - RT_SIZE_DEFAULT = 1, - RT_SIZE_PICMIP = 2, - RT_SIZE_HDR = 3, - RT_SIZE_FULL_FRAME_BUFFER = 4, - RT_SIZE_OFFSCREEN = 5, - RT_SIZE_FULL_FRAME_BUFFER_ROUNDED_UP = 6, - RT_SIZE_REPLAY_SCREENSHOT = 7, - RT_SIZE_LITERAL = 8, - RT_SIZE_LITERAL_PICMIP = 9 -}; - -enum RenderBackend_t -{ - RENDER_BACKEND_UNKNOWN, - RENDER_BACKEND_D3D9, - RENDER_BACKEND_TOGL, - RENDER_BACKEND_VULKAN, - RENDER_BACKEND_NULL, -}; - -typedef void (*MaterialBufferReleaseFunc_t)(); -typedef void (*MaterialBufferRestoreFunc_t)(int nChangeFlags); -typedef void (*ModeChangeCallbackFunc_t)(void); - -typedef int VertexBufferHandle_t; -typedef unsigned short MaterialHandle_t; - -using OcclusionQueryObjectHandle_t = void*; -#define INVALID_OCCLUSION_QUERY_OBJECT_HANDLE ( (OcclusionQueryObjectHandle_t)0 ) - -class IMaterialProxyFactory; -class ITexture; -class IMaterialSystemHardwareConfig; -class CShadowMgr; - -using MaterialLock_t = void*; +const int NUM_MODEL_TRANSFORMS = 53; +const int MATERIAL_MODEL_MAX = MATERIAL_MODEL + NUM_MODEL_TRANSFORMS; class IMaterialSystem : public IAppSystem { @@ -489,8 +478,6 @@ public: virtual void ResumeTextureStreaming() = 0; }; -MAKE_INTERFACE_VERSION(IMaterialSystem, MaterialSystem, "materialsystem.dll", "VMaterialSystem082"); - class IMatRenderContext : public IRefCounted { public: @@ -733,4 +720,6 @@ struct ShaderStencilState_t pRenderContext->SetStencilTestMask(m_nTestMask); pRenderContext->SetStencilWriteMask(m_nWriteMask); } -}; \ No newline at end of file +}; + +MAKE_INTERFACE_VERSION(IMaterialSystem, MaterialSystem, "materialsystem.dll", "VMaterialSystem082"); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IMemAlloc.h b/Amalgam/src/SDK/Definitions/Interfaces/IMemAlloc.h index 026fbc0f..d93157f8 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IMemAlloc.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IMemAlloc.h @@ -2,8 +2,8 @@ #include "Interface.h" #include "../Misc/BaseTypes.h" -typedef size_t(*MemAllocFailHandler_t)(size_t); class IVirtualMemorySection; +typedef size_t(*MemAllocFailHandler_t)(size_t); struct GenericMemoryStat_t { diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IMoveHelper.h b/Amalgam/src/SDK/Definitions/Interfaces/IMoveHelper.h index 05b21ac0..48f22d0b 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IMoveHelper.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IMoveHelper.h @@ -2,16 +2,13 @@ #include "Interface.h" #include "../Main/CBaseHandle.h" #include "../Definitions.h" -#include "../Types.h" + +#define INVALID_ENTITY_HANDLE INVALID_EHANDLE_INDEX class CGameTrace; class IPhysicsSurfaceProps; enum PLAYER_ANIM; -typedef CBaseHandle EntityHandle_t; - -#define INVALID_ENTITY_HANDLE INVALID_EHANDLE_INDEX - class IMoveHelper { public: diff --git a/Amalgam/src/SDK/Definitions/Misc/ISpatialPartition.h b/Amalgam/src/SDK/Definitions/Interfaces/ISpatialPartition.h similarity index 97% rename from Amalgam/src/SDK/Definitions/Misc/ISpatialPartition.h rename to Amalgam/src/SDK/Definitions/Interfaces/ISpatialPartition.h index bc06d828..3c764ad6 100644 --- a/Amalgam/src/SDK/Definitions/Misc/ISpatialPartition.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/ISpatialPartition.h @@ -1,24 +1,27 @@ #pragma once +#include "Interface.h" #include "../Definitions.h" -#include "../Types.h" - -struct Ray_t; -class IHandleEntity; #define PARTITION_ALL_CLIENT_EDICTS (PARTITION_CLIENT_NON_STATIC_EDICTS | PARTITION_CLIENT_STATIC_PROPS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_SOLID_EDICTS) - #define PARTITION_CLIENT_GAME_EDICTS (PARTITION_ALL_CLIENT_EDICTS & ~PARTITION_CLIENT_STATIC_PROPS) #define PARTITION_SERVER_GAME_EDICTS (PARTITION_ENGINE_SOLID_EDICTS|PARTITION_ENGINE_TRIGGER_EDICTS|PARTITION_ENGINE_NON_STATIC_EDICTS) +class IHandleEntity; +struct Ray_t; +typedef unsigned short SpatialPartitionHandle_t; +typedef int SpatialPartitionListMask_t; +typedef int SpatialTempHandle_t; + enum IterationRetval_t { ITERATION_CONTINUE = 0, ITERATION_STOP }; -typedef unsigned short SpatialPartitionHandle_t; -typedef int SpatialPartitionListMask_t; -typedef int SpatialTempHandle_t; +enum +{ + PARTITION_INVALID_HANDLE = (SpatialPartitionHandle_t)~0 +}; class IPartitionEnumerator { @@ -34,11 +37,6 @@ public: virtual void OnPostQuery(SpatialPartitionListMask_t listMask) = 0; }; -enum -{ - PARTITION_INVALID_HANDLE = (SpatialPartitionHandle_t)~0 -}; - class ISpatialPartition { public: @@ -103,4 +101,6 @@ public: virtual void RenderObjectsAlongRay(const Ray_t& ray, float flTime) = 0; virtual void ReportStats(const char* pFileName) = 0; virtual void InstallQueryCallback(IPartitionQueryCallback* pCallback) = 0; -}; \ No newline at end of file +}; + +MAKE_INTERFACE_VERSION(ISpatialPartition, SpatialPartition, "engine.dll", "SpatialPartition001"); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IStudioRender.h b/Amalgam/src/SDK/Definitions/Interfaces/IStudioRender.h index f36784b4..6f66621e 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IStudioRender.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IStudioRender.h @@ -1,25 +1,72 @@ #pragma once -#include "IMaterialSystem.h" #include "../Main/IMaterial.h" -#include "../Misc/IMDLCache.h" #include "../Misc/Studio.h" -#include "../Main/UtlVector.h" +#include "../Misc/CUtlVector.h" #include "../Types.h" +#define STUDIORENDER_DECAL_INVALID ( (StudioDecalHandle_t)0 ) +#define VERTEX_TEXCOORD0_2D ( ( (uint64) 2 ) << ( TEX_COORD_SIZE_BIT + ( 3*0 ) ) ) +#define MAX_DRAW_MODEL_INFO_MATERIALS 8 + +class IMaterialSystem; +class IMesh; +class IPooledVBAllocator; struct studiohdr_t; struct studiomeshdata_t; struct LightDesc_t; -class IMaterial; struct studiohwdata_t; struct Ray_t; -class IMaterialSystem; -class IMesh; struct vertexFileHeader_t; struct FlashlightState_t; struct FileHeader_t; -class IPooledVBAllocator; - +typedef unsigned short MDLHandle_t; typedef void (*StudioRender_Printf_t)(const char* fmt, ...); +using StudioDecalHandle_t = void*; + +enum +{ + ADDDECAL_TO_ALL_LODS = -1 +}; + +enum +{ + STUDIORENDER_DRAW_ENTIRE_MODEL = 0, + STUDIORENDER_DRAW_OPAQUE_ONLY = 0x01, + STUDIORENDER_DRAW_TRANSLUCENT_ONLY = 0x02, + STUDIORENDER_DRAW_GROUP_MASK = 0x03, + STUDIORENDER_DRAW_NO_FLEXES = 0x04, + STUDIORENDER_DRAW_STATIC_LIGHTING = 0x08, + STUDIORENDER_DRAW_ACCURATETIME = 0x10, + STUDIORENDER_DRAW_NO_SHADOWS = 0x20, + STUDIORENDER_DRAW_GET_PERF_STATS = 0x40, + STUDIORENDER_DRAW_WIREFRAME = 0x80, + STUDIORENDER_DRAW_ITEM_BLINK = 0x100, + STUDIORENDER_SHADOWDEPTHTEXTURE = 0x200, + STUDIORENDER_SSAODEPTHTEXTURE = 0x1000, + STUDIORENDER_GENERATE_STATS = 0x8000 +}; + +enum MaterialVertexFormat_t +{ + MATERIAL_VERTEX_FORMAT_MODEL_SKINNED = (VertexFormat_t)VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_BONEWEIGHT(2) | VERTEX_BONE_INDEX | VERTEX_USERDATA_SIZE(4), + MATERIAL_VERTEX_FORMAT_MODEL_SKINNED_DX7 = (VertexFormat_t)VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_BONEWEIGHT(2) | VERTEX_BONE_INDEX, + MATERIAL_VERTEX_FORMAT_MODEL = (VertexFormat_t)VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_USERDATA_SIZE(4), + MATERIAL_VERTEX_FORMAT_MODEL_DX7 = (VertexFormat_t)VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D, + MATERIAL_VERTEX_FORMAT_COLOR = (VertexFormat_t)VERTEX_SPECULAR +}; + +enum OverrideType_t +{ + OVERRIDE_NORMAL = 0, + OVERRIDE_BUILD_SHADOWS, + OVERRIDE_DEPTH_WRITE, + OVERRIDE_SSAO_DEPTH_WRITE +}; + +enum +{ + USESHADOWLOD = -2 +}; struct StudioRenderConfig_t { @@ -49,58 +96,6 @@ struct StudioRenderConfig_t int m_nReserved[4]; }; -using StudioDecalHandle_t = void*; -#define STUDIORENDER_DECAL_INVALID ( (StudioDecalHandle_t)0 ) - -enum -{ - ADDDECAL_TO_ALL_LODS = -1 -}; - -enum -{ - STUDIORENDER_DRAW_ENTIRE_MODEL = 0, - STUDIORENDER_DRAW_OPAQUE_ONLY = 0x01, - STUDIORENDER_DRAW_TRANSLUCENT_ONLY = 0x02, - STUDIORENDER_DRAW_GROUP_MASK = 0x03, - STUDIORENDER_DRAW_NO_FLEXES = 0x04, - STUDIORENDER_DRAW_STATIC_LIGHTING = 0x08, - STUDIORENDER_DRAW_ACCURATETIME = 0x10, - STUDIORENDER_DRAW_NO_SHADOWS = 0x20, - STUDIORENDER_DRAW_GET_PERF_STATS = 0x40, - STUDIORENDER_DRAW_WIREFRAME = 0x80, - STUDIORENDER_DRAW_ITEM_BLINK = 0x100, - STUDIORENDER_SHADOWDEPTHTEXTURE = 0x200, - STUDIORENDER_SSAODEPTHTEXTURE = 0x1000, - STUDIORENDER_GENERATE_STATS = 0x8000 -}; - -#define VERTEX_TEXCOORD0_2D ( ( (uint64) 2 ) << ( TEX_COORD_SIZE_BIT + ( 3*0 ) ) ) - -enum MaterialVertexFormat_t -{ - MATERIAL_VERTEX_FORMAT_MODEL_SKINNED = (VertexFormat_t)VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_BONEWEIGHT(2) | VERTEX_BONE_INDEX | VERTEX_USERDATA_SIZE(4), - MATERIAL_VERTEX_FORMAT_MODEL_SKINNED_DX7 = (VertexFormat_t)VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_BONEWEIGHT(2) | VERTEX_BONE_INDEX, - MATERIAL_VERTEX_FORMAT_MODEL = (VertexFormat_t)VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_USERDATA_SIZE(4), - MATERIAL_VERTEX_FORMAT_MODEL_DX7 = (VertexFormat_t)VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D, - MATERIAL_VERTEX_FORMAT_COLOR = (VertexFormat_t)VERTEX_SPECULAR -}; - -enum OverrideType_t -{ - OVERRIDE_NORMAL = 0, - OVERRIDE_BUILD_SHADOWS, - OVERRIDE_DEPTH_WRITE, - OVERRIDE_SSAO_DEPTH_WRITE -}; - -enum -{ - USESHADOWLOD = -2 -}; - -#define MAX_DRAW_MODEL_INFO_MATERIALS 8 - struct DrawModelResults_t { int m_ActualTriCount; diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IVEngineClient.h b/Amalgam/src/SDK/Definitions/Interfaces/IVEngineClient.h index ebdc65fd..ebb1c2e0 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IVEngineClient.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IVEngineClient.h @@ -1,17 +1,11 @@ #pragma once #include "Interface.h" -#include "../Main/UtlVector.h" #include "../Misc/BaseTypes.h" -#include "../Misc/bitbuf.h" -#include "../Misc/ButtonCode.h" #include "../Misc/ChecksumCRC.h" -#include "../Misc/ClientClass.h" -#include "../Misc/CViewSetup.h" -#include "../Misc/Datamap.h" +#include "../Misc/ButtonCode.h" #include "../Misc/Modes.h" #include "../Definitions.h" -struct model_t; class CSentence; class IMaterial; class CAudioSource; @@ -20,10 +14,18 @@ class ISpatialQuery; class IMaterialSystem; class CPhysCollide; class INetChannelInfo; -struct client_textmessage_t; class IAchievementMgr; class CGamestatsData; class KeyValues; +struct model_t; +struct client_textmessage_t; + +enum SkyboxVisibility_t +{ + SKYBOX_NOT_VISIBLE = 0, + SKYBOX_3DSKYBOX_VISIBLE, + SKYBOX_2DSKYBOX_VISIBLE, +}; typedef struct player_info_s { @@ -46,13 +48,6 @@ struct AudioState_t bool m_bIsUnderwater; }; -enum SkyboxVisibility_t -{ - SKYBOX_NOT_VISIBLE = 0, - SKYBOX_3DSKYBOX_VISIBLE, - SKYBOX_2DSKYBOX_VISIBLE, -}; - struct OcclusionParams_t { float m_flMaxOccludeeArea; diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IVModelInfo.h b/Amalgam/src/SDK/Definitions/Interfaces/IVModelInfo.h index 3de3cbaa..c04c9576 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IVModelInfo.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IVModelInfo.h @@ -4,19 +4,19 @@ class IMaterial; class KeyValues; -struct vcollide_t; -struct model_t; class CGameTrace; -struct cplane_t; -typedef CGameTrace trace_t; -struct studiohdr_t; -struct virtualmodel_t; -typedef unsigned char byte; -struct virtualterrainparams_t; class CPhysCollide; -typedef unsigned short MDLHandle_t; class CUtlBuffer; class IClientRenderable; +struct vcollide_t; +struct model_t; +struct cplane_t; +struct studiohdr_t; +struct virtualmodel_t; +struct virtualterrainparams_t; +typedef CGameTrace trace_t; +typedef unsigned char byte; +typedef unsigned short MDLHandle_t; class IModelLoadCallback { diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IVModelRender.h b/Amalgam/src/SDK/Definitions/Interfaces/IVModelRender.h index f9c92443..abbdcde3 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IVModelRender.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IVModelRender.h @@ -5,7 +5,13 @@ class IClientRenderable; struct model_t; -using LightCacheHandle_t = void*; +typedef unsigned short ModelInstanceHandle_t; +typedef struct LightCacheHandle_t__* LightCacheHandle_t; + +enum +{ + MODEL_INSTANCE_INVALID = (ModelInstanceHandle_t)~0 +}; struct DrawModelState_t { @@ -18,13 +24,6 @@ struct DrawModelState_t int m_lod; }; -typedef unsigned short ModelInstanceHandle_t; - -enum -{ - MODEL_INSTANCE_INVALID = (ModelInstanceHandle_t)~0 -}; - struct ModelRenderInfo_t { Vector origin; @@ -55,19 +54,7 @@ struct StaticPropRenderInfo_t class IVModelRender { public: - virtual int DrawModel(int flags, - IClientRenderable* pRenderable, - ModelInstanceHandle_t instance, - int entity_index, - const model_t* model, - Vector const& origin, - QAngle const& angles, - int skin, - int body, - int hitboxset, - const matrix3x4* modelToWorld = NULL, - const matrix3x4* pLightingOffset = NULL) = 0; - + virtual int DrawModel(int flags, IClientRenderable* pRenderable, ModelInstanceHandle_t instance, int entity_index, const model_t* model, Vector const& origin, QAngle const& angles, int skin, int body, int hitboxset, const matrix3x4* modelToWorld = NULL, const matrix3x4* pLightingOffset = NULL) = 0; virtual void ForcedMaterialOverride(IMaterial* newMaterial, OverrideType_t nOverrideType = OVERRIDE_NORMAL) = 0; virtual void SetViewTarget(const CStudioHdr* pStudioHdr, int nBodyIndex, const Vector& target) = 0; virtual ModelInstanceHandle_t CreateInstance(IClientRenderable* pRenderable, LightCacheHandle_t* pCache = NULL) = 0; diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IVRenderView.h b/Amalgam/src/SDK/Definitions/Interfaces/IVRenderView.h index 5f33d0bd..01fc390a 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IVRenderView.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IVRenderView.h @@ -5,6 +5,8 @@ #include "../Misc/VPlane.h" #include "../Definitions.h" +#define MAX_VIS_LEAVES 32 + class IClientRenderable; class IClientEntity; class CViewSetup; @@ -54,7 +56,6 @@ enum ERenderDepthMode }; typedef VPlane Frustum[FRUSTUM_NUMPLANES]; - typedef unsigned short LeafIndex_t; typedef short LeafFogVolume_t; @@ -117,8 +118,6 @@ public: virtual bool RenderBrushModelSurface(IClientEntity* pBaseEntity, IBrushSurface* pBrushSurface) = 0; }; -#define MAX_VIS_LEAVES 32 - enum DrawBrushModelMode_t { DBM_DRAW_ALL = 0, diff --git a/Amalgam/src/SDK/Definitions/Interfaces/IViewRender.h b/Amalgam/src/SDK/Definitions/Interfaces/IViewRender.h index 2ea389c7..fc0eb8cb 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/IViewRender.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/IViewRender.h @@ -3,40 +3,32 @@ class CViewSetup; class CBaseEntity; -struct vrect_t; -struct WriteReplayScreenshotParams_t; class IReplayScreenshotSystem; class ITexture; class IMaterial; +struct vrect_t; +struct WriteReplayScreenshotParams_t; enum DrawFlags_t { DF_RENDER_REFRACTION = 0x1, DF_RENDER_REFLECTION = 0x2, - DF_CLIP_Z = 0x4, DF_CLIP_BELOW = 0x8, - DF_RENDER_UNDERWATER = 0x10, DF_RENDER_ABOVEWATER = 0x20, DF_RENDER_WATER = 0x40, - DF_SSAO_DEPTH_PASS = 0x100, DF_WATERHEIGHT = 0x200, DF_DRAW_SSAO = 0x400, DF_DRAWSKYBOX = 0x800, - DF_FUDGE_UP = 0x1000, - DF_DRAW_ENTITITES = 0x2000, DF_UNUSED3 = 0x4000, - DF_UNUSED4 = 0x8000, - DF_UNUSED5 = 0x10000, DF_SAVEGAMESCREENSHOT = 0x20000, DF_CLIP_SKYBOX = 0x40000, - DF_SHADOW_DEPTH_MAP = 0x100000 }; @@ -46,7 +38,7 @@ enum ClearFlags_t VIEW_CLEAR_DEPTH = 0x2, VIEW_CLEAR_FULL_TARGET = 0x4, VIEW_NO_DRAW = 0x8, - VIEW_CLEAR_OBEY_STENCIL = 0x10, // Draws a quad allowing stencil test to clear through portals + VIEW_CLEAR_OBEY_STENCIL = 0x10, VIEW_CLEAR_STENCIL = 0x20, }; @@ -58,86 +50,43 @@ enum RenderViewInfo_t RENDERVIEW_SUPPRESSMONITORRENDERING = (1 << 2), }; -//----------------------------------------------------------------------------- -// Purpose: View setup and rendering -//----------------------------------------------------------------------------- class IViewRender { public: - // SETUP - // Initialize view renderer - virtual void Init(void) = 0; - - // Clear any systems between levels - virtual void LevelInit(void) = 0; - virtual void LevelShutdown(void) = 0; - - // Shutdown - virtual void Shutdown(void) = 0; - - // RENDERING - // Called right before simulation. It must setup the view model origins and angles here so - // the correct attachment points can be used during simulation. - virtual void OnRenderStart() = 0; - - // Called to render the entire scene - virtual void Render(vrect_t* rect) = 0; - - // Called to render just a particular setup ( for timerefresh and envmap creation ) - virtual void RenderView(const CViewSetup& view, int nClearFlags, int whatToDraw) = 0; - - // What are we currently rendering? Returns a combination of DF_ flags. + virtual void Init(void) = 0; + virtual void LevelInit(void) = 0; + virtual void LevelShutdown(void) = 0; + virtual void Shutdown(void) = 0; + virtual void OnRenderStart() = 0; + virtual void Render(vrect_t* rect) = 0; + virtual void RenderView(const CViewSetup& view, int nClearFlags, int whatToDraw) = 0; virtual int GetDrawFlags() = 0; - - // MISC - // Start and stop pitch drifting logic - virtual void StartPitchDrift(void) = 0; - virtual void StopPitchDrift(void) = 0; - - // This can only be called during rendering (while within RenderView). + virtual void StartPitchDrift(void) = 0; + virtual void StopPitchDrift(void) = 0; virtual void* GetFrustum() = 0; - - virtual bool ShouldDrawBrushModels(void) = 0; - + virtual bool ShouldDrawBrushModels(void) = 0; virtual const CViewSetup* GetPlayerViewSetup(void) const = 0; virtual const CViewSetup* GetViewSetup(void) const = 0; - - virtual void DisableVis(void) = 0; - - virtual int BuildWorldListsNumber() const = 0; - - virtual void SetCheapWaterStartDistance(float flCheapWaterStartDistance) = 0; - virtual void SetCheapWaterEndDistance(float flCheapWaterEndDistance) = 0; - - virtual void GetWaterLODParams(float& flCheapWaterStartDistance, float& flCheapWaterEndDistance) = 0; - - virtual void DriftPitch(void) = 0; - - virtual void SetScreenOverlayMaterial(IMaterial* pMaterial) = 0; + virtual void DisableVis(void) = 0; + virtual int BuildWorldListsNumber() const = 0; + virtual void SetCheapWaterStartDistance(float flCheapWaterStartDistance) = 0; + virtual void SetCheapWaterEndDistance(float flCheapWaterEndDistance) = 0; + virtual void GetWaterLODParams(float& flCheapWaterStartDistance, float& flCheapWaterEndDistance) = 0; + virtual void DriftPitch(void) = 0; + virtual void SetScreenOverlayMaterial(IMaterial* pMaterial) = 0; virtual IMaterial* GetScreenOverlayMaterial() = 0; - - virtual void WriteSaveGameScreenshot(const char* pFilename) = 0; - virtual void WriteSaveGameScreenshotOfSize(const char* pFilename, int width, int height, bool bCreatePowerOf2Padded = false, bool bWriteVTF = false) = 0; - - virtual void WriteReplayScreenshot(WriteReplayScreenshotParams_t& params) = 0; - virtual void UpdateReplayScreenshotCache() = 0; - - // Draws another rendering over the top of the screen - virtual void QueueOverlayRenderView(const CViewSetup& view, int nClearFlags, int whatToDraw) = 0; - - // Returns znear and zfar - virtual float GetZNear() = 0; - virtual float GetZFar() = 0; - - virtual void GetScreenFadeDistances(float* min, float* max) = 0; - + virtual void WriteSaveGameScreenshot(const char* pFilename) = 0; + virtual void WriteSaveGameScreenshotOfSize(const char* pFilename, int width, int height, bool bCreatePowerOf2Padded = false, bool bWriteVTF = false) = 0; + virtual void WriteReplayScreenshot(WriteReplayScreenshotParams_t& params) = 0; + virtual void UpdateReplayScreenshotCache() = 0; + virtual void QueueOverlayRenderView(const CViewSetup& view, int nClearFlags, int whatToDraw) = 0; + virtual float GetZNear() = 0; + virtual float GetZFar() = 0; + virtual void GetScreenFadeDistances(float* min, float* max) = 0; virtual CBaseEntity* GetCurrentlyDrawingEntity() = 0; - virtual void SetCurrentlyDrawingEntity(CBaseEntity* pEnt) = 0; - - virtual bool UpdateShadowDepthTexture(ITexture* pRenderTarget, ITexture* pDepthTexture, const CViewSetup& shadowView) = 0; - - virtual void FreezeFrame(float flFreezeTime) = 0; - + virtual void SetCurrentlyDrawingEntity(CBaseEntity* pEnt) = 0; + virtual bool UpdateShadowDepthTexture(ITexture* pRenderTarget, ITexture* pDepthTexture, const CViewSetup& shadowView) = 0; + virtual void FreezeFrame(float flFreezeTime) = 0; virtual IReplayScreenshotSystem* GetReplayScreenshotSystem() = 0; }; diff --git a/Amalgam/src/SDK/Definitions/Interfaces/Prediction.h b/Amalgam/src/SDK/Definitions/Interfaces/Prediction.h index 5a2abb1b..c8b5af5c 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/Prediction.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/Prediction.h @@ -1,12 +1,12 @@ #pragma once -#include "IMoveHelper.h" #include "../Misc/IPrediction.h" MAKE_SIGNATURE(CPrediction_RestoreEntityToPredictedFrame, "client.dll", "40 55 48 83 EC ? 8B EA", 0x0); -class CMoveData; -class CUserCmd; class CBasePlayer; +class CUserCmd; +class CMoveData; +class IMoveHelper; class CPrediction : public IPrediction { diff --git a/Amalgam/src/SDK/Definitions/Interfaces/VPhysics.h b/Amalgam/src/SDK/Definitions/Interfaces/VPhysics.h index 1c52a87a..87f2b5af 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/VPhysics.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/VPhysics.h @@ -6,8 +6,62 @@ #define k_flMaxAngularVelocity 360.0f * 10.0f #define DEFAULT_MIN_FRICTION_MASS 10.0f #define DEFAULT_MAX_FRICTION_MASS 2500.0f +#define LEAFMAP_HAS_CUBEMAP 0x0001 +#define LEAFMAP_HAS_SINGLE_VERTEX_SPAN 0x0002 +#define LEAFMAP_HAS_MULTIPLE_VERTEX_SPANS 0x0004 +#define METERS_PER_INCH (0.0254f) +#define CUBIC_METERS_PER_CUBIC_INCH (METERS_PER_INCH*METERS_PER_INCH*METERS_PER_INCH) +#define POUNDS_PER_KG (2.2f) +#define KG_PER_POUND (1.0f/POUNDS_PER_KG) +#define lbs2kg(x) ((x)*KG_PER_POUND) +#define kg2lbs(x) ((x)*POUNDS_PER_KG) +const float VPHYSICS_MIN_MASS = 0.1f; +const float VPHYSICS_MAX_MASS = 5e4f; + +class IPhysicsShadowController; +class IPhysicsSurfaceProps; +class IPhysicsConstraint; +class IPhysicsConstraintGroup; +class IPhysicsFluidController; +class IPhysicsSpring; +class IPhysicsVehicleController; +class IConvexInfo; +class IPhysicsObjectPairHash; +class IPhysicsCollisionSet; +class IPhysicsPlayerController; +class IPhysicsFrictionSnapshot; +class CGameTrace; +class ISave; +class IRestore; +class CPhysConvex; +class CPhysPolysoup; +class IVPhysicsKeyParser; +class CPackedPhysicsDescription; +class CPhysicsEventHandler; +class CPhysicsSimObject; +class IPhysicsMotionController; +struct Ray_t; struct vcollide_t; +struct constraint_ragdollparams_t; +struct constraint_hingeparams_t; +struct constraint_fixedparams_t; +struct constraint_ballsocketparams_t; +struct constraint_slidingparams_t; +struct constraint_pulleyparams_t; +struct constraint_lengthparams_t; +struct constraint_groupparams_t; +struct vehicleparams_t; +struct fluidparams_t; +struct springparams_t; +struct debugcollide_t; +struct physics_stats_t; +struct virtualmeshparams_t; +struct physsaveparams_t; +struct physrestoreparams_t; +struct physprerestoreparams_t; +struct convertconvexparams_t; +typedef CGameTrace trace_t; enum { @@ -17,36 +71,37 @@ enum COLLIDE_VIRTUAL = 3, }; -class IPhysCollide +enum PhysInterfaceId_t { -public: - virtual ~IPhysCollide() {} - //virtual void AddReference() = 0; - //virtual void ReleaseReference() = 0; - - // get a surface manager - virtual void* CreateSurfaceManager(short&) const = 0; - virtual void GetAllLedges(void* ledges) const = 0; - virtual unsigned int GetSerializationSize() const = 0; - virtual unsigned int SerializeToBuffer(char* pDest, bool bSwap = false) const = 0; - virtual int GetVCollideIndex() const = 0; - virtual Vec3 GetMassCenter() const = 0; - virtual void SetMassCenter(const Vec3& massCenter) = 0; - virtual Vec3 GetOrthographicAreas() const = 0; - virtual void SetOrthographicAreas(const Vec3& areas) = 0; - virtual float GetSphereRadius() const = 0; - virtual void OutputDebugInfo() const = 0; + PIID_UNKNOWN, + PIID_IPHYSICSOBJECT, + PIID_IPHYSICSFLUIDCONTROLLER, + PIID_IPHYSICSSPRING, + PIID_IPHYSICSCONSTRAINTGROUP, + PIID_IPHYSICSCONSTRAINT, + PIID_IPHYSICSSHADOWCONTROLLER, + PIID_IPHYSICSPLAYERCONTROLLER, + PIID_IPHYSICSMOTIONCONTROLLER, + PIID_IPHYSICSVEHICLECONTROLLER, + PIID_IPHYSICSGAMETRACE, + PIID_NUM_TYPES +}; + +enum PhysicsTraceType_t +{ + VPHYSICS_TRACE_EVERYTHING = 0, + VPHYSICS_TRACE_STATIC_ONLY, + VPHYSICS_TRACE_MOVING_ONLY, + VPHYSICS_TRACE_TRIGGERS_ONLY, + VPHYSICS_TRACE_STATIC_AND_MOVING, }; -#define LEAFMAP_HAS_CUBEMAP 0x0001 -#define LEAFMAP_HAS_SINGLE_VERTEX_SPAN 0x0002 -#define LEAFMAP_HAS_MULTIPLE_VERTEX_SPANS 0x0004 struct leafmap_t { void* pLeaf; unsigned short vertCount; - byte flags; - byte spanCount; + byte flags; + byte spanCount; unsigned short startVert[8]; void SetHasCubemap() @@ -107,57 +162,176 @@ struct leafmap_t inline bool HasRLESpans() const { return (flags & LEAFMAP_HAS_MULTIPLE_VERTEX_SPANS) ? true : false; } }; - struct collidemap_t { - int leafCount; - leafmap_t leafmap[1]; + int leafCount; + leafmap_t leafmap[1]; +}; + +struct objectparams_t +{ + Vec3* massCenterOverride; + float mass; + float inertia; + float damping; + float rotdamping; + float rotInertiaLimit; + const char* pName; + void* pGameData; + float volume; + float dragCoefficient; + bool enableCollisions; +}; + +struct physics_performanceparams_t +{ + int maxCollisionsPerObjectPerTimestep; + int maxCollisionChecksPerTimestep; + float maxVelocity; + float maxAngularVelocity; + float lookAheadTimeObjectsVsWorld; + float lookAheadTimeObjectsVsObject; + float minFrictionMass; + float maxFrictionMass; + + void Defaults() + { + maxCollisionsPerObjectPerTimestep = 6; + maxCollisionChecksPerTimestep = 250; + maxVelocity = k_flMaxVelocity; + maxAngularVelocity = k_flMaxAngularVelocity; + lookAheadTimeObjectsVsWorld = 1.0f; + lookAheadTimeObjectsVsObject = 0.5f; + minFrictionMass = DEFAULT_MIN_FRICTION_MASS; + maxFrictionMass = DEFAULT_MAX_FRICTION_MASS; + } +}; + +struct truncatedcone_t +{ + Vec3 origin; + Vec3 normal; + float h; + float theta; +}; + +struct hlshadowcontrol_params_t +{ + Vec3 targetPosition; + QAngle targetRotation; + float maxAngular; + float maxDampAngular; + float maxSpeed; + float maxDampSpeed; + float dampFactor; + float teleportDistance; +}; + +struct Polyhedron_IndexedLine_t +{ + unsigned short iPointIndices[2]; +}; + +struct Polyhedron_IndexedLineReference_t +{ + unsigned short iLineIndex; + unsigned char iEndPointIndex; +}; + +struct Polyhedron_IndexedPolygon_t +{ + unsigned short iFirstIndex; + unsigned short iIndexCount; + Vector polyNormal; +}; + +class CPolyhedron +{ +public: + Vector* pVertices; + Polyhedron_IndexedLine_t* pLines; + Polyhedron_IndexedLineReference_t* pIndices; + Polyhedron_IndexedPolygon_t* pPolygons; + + unsigned short iVertexCount; + unsigned short iLineCount; + unsigned short iIndexCount; + unsigned short iPolygonCount; + + virtual ~CPolyhedron(void) = 0; + virtual void Release(void) = 0; + + Vector Center(void) + { + if (!iVertexCount) + return Vec3(); + + Vector vAABBMin, vAABBMax; + vAABBMin = vAABBMax = pVertices[0]; + for (int i = 1; i != iVertexCount; i++) + { + Vector& vPoint = pVertices[i]; + if (vPoint.x < vAABBMin.x) + vAABBMin.x = vPoint.x; + if (vPoint.y < vAABBMin.y) + vAABBMin.y = vPoint.y; + if (vPoint.z < vAABBMin.z) + vAABBMin.z = vPoint.z; + + if (vPoint.x > vAABBMax.x) + vAABBMax.x = vPoint.x; + if (vPoint.y > vAABBMax.y) + vAABBMax.y = vPoint.y; + if (vPoint.z > vAABBMax.z) + vAABBMax.z = vPoint.z; + } + return (vAABBMin + vAABBMax) / 2; + } +}; + +class ICollisionQuery +{ +public: + virtual ~ICollisionQuery() {} + virtual int ConvexCount(void) = 0; + virtual int TriangleCount(int convexIndex) = 0; + virtual unsigned int GetGameData(int convexIndex) = 0; + virtual void GetTriangleVerts(int convexIndex, int triangleIndex, Vec3* verts) = 0; + virtual void SetTriangleVerts(int convexIndex, int triangleIndex, const Vec3* verts) = 0; + virtual int GetTriangleMaterialIndex(int convexIndex, int triangleIndex) = 0; + virtual void SetTriangleMaterialIndex(int convexIndex, int triangleIndex, int index7bits) = 0; +}; + +class IPhysCollide +{ +public: + virtual ~IPhysCollide() {} + //virtual void AddReference() = 0; + //virtual void ReleaseReference() = 0; + virtual void* CreateSurfaceManager(short&) const = 0; + virtual void GetAllLedges(void* ledges) const = 0; + virtual unsigned int GetSerializationSize() const = 0; + virtual unsigned int SerializeToBuffer(char* pDest, bool bSwap = false) const = 0; + virtual int GetVCollideIndex() const = 0; + virtual Vec3 GetMassCenter() const = 0; + virtual void SetMassCenter(const Vec3& massCenter) = 0; + virtual Vec3 GetOrthographicAreas() const = 0; + virtual void SetOrthographicAreas(const Vec3& areas) = 0; + virtual float GetSphereRadius() const = 0; + virtual void OutputDebugInfo() const = 0; }; class CPhysCollide : public IPhysCollide { public: - static CPhysCollide* UnserializeFromBuffer(const char* pBuffer, unsigned int size, int index, bool swap = false); - virtual const void* GetCompactSurface() const { return NULL; } - virtual Vec3 GetOrthographicAreas() const { return Vec3(1, 1, 1); } - virtual float GetSphereRadius() const { return 0; } - virtual void ComputeOrthographicAreas(float epsilon) {} - virtual void SetOrthographicAreas(const Vec3& areas) {} - virtual const collidemap_t* GetCollideMap() const { return NULL; } + virtual const void* GetCompactSurface() const = 0; + virtual Vec3 GetOrthographicAreas() const = 0; + virtual float GetSphereRadius() const = 0; + virtual void ComputeOrthographicAreas(float epsilon) = 0; + virtual void SetOrthographicAreas(const Vec3& areas) = 0; + virtual const collidemap_t* GetCollideMap() const = 0; }; -// ------------------------------------------------------------------------------------ -// UNITS: -// ------------------------------------------------------------------------------------ -// NOTE: Coordinates are in HL units. 1 unit == 1 inch. X is east (forward), Y is north (left), Z is up (up) -// QAngle are pitch (around y), Yaw (around Z), Roll (around X) -// AngularImpulse are exponetial maps (an axis in HL units scaled by a "twist" angle in degrees) -// They can be transformed like normals/covectors and added linearly -// mass is kg, volume is in^3, acceleration is in/s^2, velocity is in/s - -// density is kg/m^3 (water ~= 998 at room temperature) -// preferably, these would be in kg/in^3, but the range of those numbers makes them not very human readable -// having water be about 1000 is really convenient for data entry. -// Since volume is in in^3 and density is in kg/m^3: -// density = (mass / volume) * CUBIC_METERS_PER_CUBIC_INCH -// Force is applied using impulses (kg*in/s) -// Torque is applied using impulses (kg*degrees/s) -// ------------------------------------------------------------------------------------ - -#define METERS_PER_INCH (0.0254f) -#define CUBIC_METERS_PER_CUBIC_INCH (METERS_PER_INCH*METERS_PER_INCH*METERS_PER_INCH) -// 2.2 lbs / kg -#define POUNDS_PER_KG (2.2f) -#define KG_PER_POUND (1.0f/POUNDS_PER_KG) - -// convert from pounds to kg -#define lbs2kg(x) ((x)*KG_PER_POUND) -#define kg2lbs(x) ((x)*POUNDS_PER_KG) - -const float VPHYSICS_MIN_MASS = 0.1f; -const float VPHYSICS_MAX_MASS = 5e4f; - -class IPhysicsShadowController; class IPhysicsObject { public: @@ -231,150 +405,45 @@ public: virtual void SetShadow(float maxSpeed, float maxAngularSpeed, bool allowPhysicsMovement, bool allowPhysicsRotation) = 0; virtual void UpdateShadow(const Vec3& targetPosition, const QAngle& targetAngles, bool tempDisableGravity, float timeOffset) = 0; virtual int GetShadowPosition(Vec3* position, QAngle* angles) const = 0; - virtual /*IPhysicsShadowController*/void* GetShadowController(void) const = 0; + virtual IPhysicsShadowController* GetShadowController(void) const = 0; virtual void RemoveShadowController() = 0; - virtual float ComputeShadowControl(/*const hlshadowcontrol_params_t &*/void* params, float secondsToArrival, float dt) = 0; + virtual float ComputeShadowControl(const hlshadowcontrol_params_t& params, float secondsToArrival, float dt) = 0; virtual const CPhysCollide* GetCollide(void) const = 0; virtual const char* GetName() const = 0; virtual void BecomeTrigger() = 0; virtual void RemoveTrigger() = 0; virtual void BecomeHinged(int localAxis) = 0; virtual void RemoveHinged() = 0; - virtual /*IPhysicsFrictionSnapshot*/void* CreateFrictionSnapshot() = 0; - virtual void DestroyFrictionSnapshot(/*IPhysicsFrictionSnapshot*/void* pSnapshot) = 0; + virtual IPhysicsFrictionSnapshot* CreateFrictionSnapshot() = 0; + virtual void DestroyFrictionSnapshot(IPhysicsFrictionSnapshot* pSnapshot) = 0; virtual void OutputDebugInfo() const = 0; void* m_pGameData; void* m_pObject; const CPhysCollide* m_pCollide; IPhysicsShadowController* m_pShadow; - - Vec3 m_dragBasis; - Vec3 m_angDragBasis; - - // these 5 should pack into a short - // pack new bools here - bool m_shadowTempGravityDisable : 5; - bool m_hasTouchedDynamic : 1; - bool m_asleepSinceCreation : 1; - bool m_forceSilentDelete : 1; - unsigned char m_sleepState : 2; - unsigned char m_hingedAxis : 3; - unsigned char m_collideType : 3; - unsigned short m_gameIndex; - -private: - unsigned short m_materialIndex; - unsigned short m_activeIndex; - - unsigned short m_callbacks; - unsigned short m_gameFlags; - unsigned int m_contentsMask; - - float m_volume; - float m_buoyancyRatio; - float m_dragCoefficient; - float m_angDragCoefficient; -}; -class IPhysicsEnvironment; -class IPhysicsSurfaceProps; -class IPhysicsConstraint; -class IPhysicsConstraintGroup; -class IPhysicsFluidController; -class IPhysicsSpring; -class IPhysicsVehicleController; -class IConvexInfo; -class IPhysicsObjectPairHash; -class IPhysicsCollisionSet; -class IPhysicsPlayerController; -class IPhysicsFrictionSnapshot; - -struct Ray_t; -struct constraint_ragdollparams_t; -struct constraint_hingeparams_t; -struct constraint_fixedparams_t; -struct constraint_ballsocketparams_t; -struct constraint_slidingparams_t; -struct constraint_pulleyparams_t; -struct constraint_lengthparams_t; -struct constraint_groupparams_t; - -struct vehicleparams_t; - -struct fluidparams_t; -struct springparams_t; -struct objectparams_t -{ - Vec3* massCenterOverride; - float mass; - float inertia; - float damping; - float rotdamping; - float rotInertiaLimit; - const char* pName; // used only for debugging - void* pGameData; - float volume; - float dragCoefficient; - bool enableCollisions; -}; -struct debugcollide_t; -class CGameTrace; -typedef CGameTrace trace_t; -struct physics_stats_t; -struct physics_performanceparams_t -{ - int maxCollisionsPerObjectPerTimestep; // object will be frozen after this many collisions (visual hitching vs. CPU cost) - int maxCollisionChecksPerTimestep; // objects may penetrate after this many collision checks (can be extended in AdditionalCollisionChecksThisTick) - float maxVelocity; // limit world space linear velocity to this (in / s) - float maxAngularVelocity; // limit world space angular velocity to this (degrees / s) - float lookAheadTimeObjectsVsWorld; // predict collisions this far (seconds) into the future - float lookAheadTimeObjectsVsObject; // predict collisions this far (seconds) into the future - float minFrictionMass; // min mass for friction solves (constrains dynamic range of mass to improve stability) - float maxFrictionMass; // mas mass for friction solves - - void Defaults() - { - maxCollisionsPerObjectPerTimestep = 6; - maxCollisionChecksPerTimestep = 250; - maxVelocity = k_flMaxVelocity; - maxAngularVelocity = k_flMaxAngularVelocity; - lookAheadTimeObjectsVsWorld = 1.0f; - lookAheadTimeObjectsVsObject = 0.5f; - minFrictionMass = DEFAULT_MIN_FRICTION_MASS; - maxFrictionMass = DEFAULT_MAX_FRICTION_MASS; - } -}; -struct virtualmeshparams_t; - -//enum PhysInterfaceId_t; -struct physsaveparams_t; -struct physrestoreparams_t; -struct physprerestoreparams_t; - -enum PhysInterfaceId_t -{ - PIID_UNKNOWN, - PIID_IPHYSICSOBJECT, - PIID_IPHYSICSFLUIDCONTROLLER, - PIID_IPHYSICSSPRING, - PIID_IPHYSICSCONSTRAINTGROUP, - PIID_IPHYSICSCONSTRAINT, - PIID_IPHYSICSSHADOWCONTROLLER, - PIID_IPHYSICSPLAYERCONTROLLER, - PIID_IPHYSICSMOTIONCONTROLLER, - PIID_IPHYSICSVEHICLECONTROLLER, - PIID_IPHYSICSGAMETRACE, - - PIID_NUM_TYPES + Vec3 m_dragBasis; + Vec3 m_angDragBasis; + bool m_shadowTempGravityDisable : 5; + bool m_hasTouchedDynamic : 1; + bool m_asleepSinceCreation : 1; + bool m_forceSilentDelete : 1; + unsigned char m_sleepState : 2; + unsigned char m_hingedAxis : 3; + unsigned char m_collideType : 3; + unsigned short m_gameIndex; + unsigned short m_materialIndex; + unsigned short m_activeIndex; + unsigned short m_callbacks; + unsigned short m_gameFlags; + unsigned int m_contentsMask; + float m_volume; + float m_buoyancyRatio; + float m_dragCoefficient; + float m_angDragCoefficient; }; - -class ISave; -class IRestore; - - -#define VPHYSICS_DEBUG_OVERLAY_INTERFACE_VERSION "VPhysicsDebugOverlay001" - +// "VPhysicsDebugOverlay001" class IVPhysicsDebugOverlay { public: @@ -389,340 +458,92 @@ public: virtual void AddTextOverlayRGB(const Vec3& origin, int line_offset, float duration, float r, float g, float b, float alpha, const char* format, ...) = 0; }; -class IPhysics : public IAppSystem -{ -public: - virtual IPhysicsEnvironment* CreateEnvironment(void) = 0; - virtual void DestroyEnvironment(IPhysicsEnvironment*) = 0; - virtual IPhysicsEnvironment* GetActiveEnvironmentByIndex(int index) = 0; - - // Creates a fast hash of pairs of objects - // Useful for maintaining a table of object relationships like pairs that do not collide. - virtual IPhysicsObjectPairHash* CreateObjectPairHash() = 0; - virtual void DestroyObjectPairHash(IPhysicsObjectPairHash* pHash) = 0; - - // holds a cache of these by id. So you can get by id to search for the previously created set - // UNDONE: Sets are currently limited to 32 elements. More elements will return NULL in create. - // NOTE: id is not allowed to be zero. - virtual IPhysicsCollisionSet* FindOrCreateCollisionSet(unsigned int id, int maxElementCount) = 0; - virtual IPhysicsCollisionSet* FindCollisionSet(unsigned int id) = 0; - virtual void DestroyAllCollisionSets() = 0; -}; - - -// CPhysConvex is a single convex solid -class CPhysConvex; -// CPhysPolysoup is an abstract triangle soup mesh -class CPhysPolysoup; -class ICollisionQuery; -class IVPhysicsKeyParser; -struct convertconvexparams_t; -class CPackedPhysicsDescription; - -class CPolyhedron; - -// UNDONE: Find a better place for this? Should be in collisionutils, but it's needs VPHYSICS' solver. -struct truncatedcone_t -{ - Vec3 origin; - Vec3 normal; - float h; // height of the cone (hl units) - float theta; // cone angle (degrees) -}; - - -#define VPHYSICS_COLLISION_INTERFACE_VERSION "VPhysicsCollision007" - -class IPhysicsCollision -{ -public: - virtual ~IPhysicsCollision(void) {} - - // produce a convex element from verts (convex hull around verts) - virtual CPhysConvex* ConvexFromVerts(Vec3** pVerts, int vertCount) = 0; - // produce a convex element from planes (csg of planes) - virtual CPhysConvex* ConvexFromPlanes(float* pPlanes, int planeCount, float mergeDistance) = 0; - // calculate volume of a convex element - virtual float ConvexVolume(CPhysConvex* pConvex) = 0; - - virtual float ConvexSurfaceArea(CPhysConvex* pConvex) = 0; - // store game-specific data in a convex solid - virtual void SetConvexGameData(CPhysConvex* pConvex, unsigned int gameData) = 0; - // If not converted, free the convex elements with this call - virtual void ConvexFree(CPhysConvex* pConvex) = 0; - virtual CPhysConvex* BBoxToConvex(const Vec3& mins, const Vec3& maxs) = 0; - // produce a convex element from a convex polyhedron - virtual CPhysConvex* ConvexFromConvexPolyhedron(const CPolyhedron& ConvexPolyhedron) = 0; - // produce a set of convex triangles from a convex polygon, normal is assumed to be on the side with forward point ordering, which should be clockwise, output will need to be able to hold exactly (iPointCount-2) convexes - virtual void ConvexesFromConvexPolygon(const Vec3& vPolyNormal, const Vec3* pPoints, int iPointCount, CPhysConvex** pOutput) = 0; - - // concave objects - // create a triangle soup - virtual CPhysPolysoup* PolysoupCreate(void) = 0; - // destroy the container and memory - virtual void PolysoupDestroy(CPhysPolysoup* pSoup) = 0; - // add a triangle to the soup - virtual void PolysoupAddTriangle(CPhysPolysoup* pSoup, const Vec3& a, const Vec3& b, const Vec3& c, int materialIndex7bits) = 0; - // convert the convex into a compiled collision model - virtual CPhysCollide* ConvertPolysoupToCollide(CPhysPolysoup* pSoup, bool useMOPP) = 0; - - // Convert an array of convex elements to a compiled collision model (this deletes the convex elements) - virtual CPhysCollide* ConvertConvexToCollide(CPhysConvex** pConvex, int convexCount) = 0; - virtual CPhysCollide* ConvertConvexToCollideParams(CPhysConvex** pConvex, int convexCount, const convertconvexparams_t& convertParams) = 0; - // Free a collide that was created with ConvertConvexToCollide() - virtual void DestroyCollide(CPhysCollide* pCollide) = 0; - - // Get the memory size in bytes of the collision model for serialization - virtual int CollideSize(CPhysCollide* pCollide) = 0; - // serialize the collide to a block of memory - virtual int CollideWrite(char* pDest, CPhysCollide* pCollide, bool bSwap = false) = 0; - // unserialize the collide from a block of memory - virtual CPhysCollide* UnserializeCollide(char* pBuffer, int size, int index) = 0; - - // compute the volume of a collide - virtual float CollideVolume(CPhysCollide* pCollide) = 0; - // compute surface area for tools - virtual float CollideSurfaceArea(CPhysCollide* pCollide) = 0; - - // Get the support map for a collide in the given direction - virtual Vec3 CollideGetExtent(const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, const Vec3& direction) = 0; - - // Get an AABB for an oriented collision model - virtual void CollideGetAABB(Vec3* pMins, Vec3* pMaxs, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles) = 0; - - virtual void CollideGetMassCenter(CPhysCollide* pCollide, Vec3* pOutMassCenter) = 0; - virtual void CollideSetMassCenter(CPhysCollide* pCollide, const Vec3& massCenter) = 0; - // get the approximate cross-sectional area projected orthographically on the bbox of the collide - // NOTE: These are fractional areas - unitless. Basically this is the fraction of the OBB on each axis that - // would be visible if the object were rendered orthographically. - // NOTE: This has been precomputed when the collide was built or this function will return 1,1,1 - virtual Vec3 CollideGetOrthographicAreas(const CPhysCollide* pCollide) = 0; - virtual void CollideSetOrthographicAreas(CPhysCollide* pCollide, const Vec3& areas) = 0; - - // query the vcollide index in the physics model for the instance - virtual int CollideIndex(const CPhysCollide* pCollide) = 0; - - // Convert a bbox to a collide - virtual CPhysCollide* BBoxToCollide(const Vec3& mins, const Vec3& maxs) = 0; - virtual int GetConvexesUsedInCollideable(const CPhysCollide* pCollideable, CPhysConvex** pOutputArray, int iOutputArrayLimit) = 0; - - - // Trace an AABB against a collide - virtual void TraceBox(const Vec3& start, const Vec3& end, const Vec3& mins, const Vec3& maxs, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, trace_t* ptr) = 0; - virtual void TraceBox(const Ray_t& ray, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, trace_t* ptr) = 0; - virtual void TraceBox(const Ray_t& ray, unsigned int contentsMask, IConvexInfo* pConvexInfo, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, trace_t* ptr) = 0; - - // Trace one collide against another - virtual void TraceCollide(const Vec3& start, const Vec3& end, const CPhysCollide* pSweepCollide, const QAngle& sweepAngles, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, trace_t* ptr) = 0; - - // relatively slow test for box vs. truncated cone - virtual bool IsBoxIntersectingCone(const Vec3& boxAbsMins, const Vec3& boxAbsMaxs, const truncatedcone_t& cone) = 0; - - // loads a set of solids into a vcollide_t - virtual void VCollideLoad(vcollide_t* pOutput, int solidCount, const char* pBuffer, int size, bool swap = false) = 0; - // destroyts the set of solids created by VCollideLoad - virtual void VCollideUnload(vcollide_t* pVCollide) = 0; - - // begins parsing a vcollide. NOTE: This keeps pointers to the text - // If you free the text and call members of IVPhysicsKeyParser, it will crash - virtual IVPhysicsKeyParser* VPhysicsKeyParserCreate(const char* pKeyData) = 0; - // Free the parser created by VPhysicsKeyParserCreate - virtual void VPhysicsKeyParserDestroy(IVPhysicsKeyParser* pParser) = 0; - - // creates a list of verts from a collision mesh - virtual int CreateDebugMesh(CPhysCollide const* pCollisionModel, Vec3** outVerts) = 0; - // destroy the list of verts created by CreateDebugMesh - virtual void DestroyDebugMesh(int vertCount, Vec3* outVerts) = 0; - - // create a queryable version of the collision model - virtual ICollisionQuery* CreateQueryModel(CPhysCollide* pCollide) = 0; - // destroy the queryable version - virtual void DestroyQueryModel(ICollisionQuery* pQuery) = 0; - - virtual IPhysicsCollision* ThreadContextCreate(void) = 0; - virtual void ThreadContextDestroy(IPhysicsCollision* pThreadContex) = 0; - - virtual CPhysCollide* CreateVirtualMesh(const virtualmeshparams_t& params) = 0; - virtual bool SupportsVirtualMesh() = 0; - - - virtual bool GetBBoxCacheSize(int* pCachedSize, int* pCachedCount) = 0; - - - // extracts a polyhedron that defines a CPhysConvex's shape - virtual CPolyhedron* PolyhedronFromConvex(CPhysConvex* const pConvex, bool bUseTempPolyhedron) = 0; - - // dumps info about the collide to Msg() - virtual void OutputDebugInfo(const CPhysCollide* pCollide) = 0; - virtual unsigned int ReadStat(int statID) = 0; -}; - -MAKE_INTERFACE_VERSION(IPhysicsCollision, PhysicsCollision, "vphysics.dll", "VPhysicsCollision007"); - -// this can be used to post-process a collision model -class ICollisionQuery -{ -public: - virtual ~ICollisionQuery() {} - // number of convex pieces in the whole solid - virtual int ConvexCount(void) = 0; - // triangle count for this convex piece - virtual int TriangleCount(int convexIndex) = 0; - // get the stored game data - virtual unsigned int GetGameData(int convexIndex) = 0; - // Gets the triangle's verts to an array - virtual void GetTriangleVerts(int convexIndex, int triangleIndex, Vec3* verts) = 0; - - // UNDONE: This doesn't work!!! - virtual void SetTriangleVerts(int convexIndex, int triangleIndex, const Vec3* verts) = 0; - - // returns the 7-bit material index - virtual int GetTriangleMaterialIndex(int convexIndex, int triangleIndex) = 0; - // sets a 7-bit material index for this triangle - virtual void SetTriangleMaterialIndex(int convexIndex, int triangleIndex, int index7bits) = 0; -}; - -//----------------------------------------------------------------------------- -// Purpose: Ray traces from game engine. -//----------------------------------------------------------------------------- class IPhysicsGameTrace { public: virtual void VehicleTraceRay(const Ray_t& ray, void* pVehicle, trace_t* pTrace) = 0; - virtual void VehicleTraceRayWithWater(const Ray_t& ray, void* pVehicle, trace_t* pTrace) = 0; + virtual void VehicleTraceRayWithWater(const Ray_t& ray, void* pVehicle, trace_t* pTrace) = 0; virtual bool VehiclePointInWater(const Vec3& vecPoint) = 0; }; -// The caller should implement this to return contents masks per convex on a collide class IConvexInfo { public: virtual unsigned int GetContents(int convexGameData) = 0; }; -class CPhysicsEventHandler; class IPhysicsCollisionData { public: - virtual void GetSurfaceNormal(Vec3& out) = 0; // normal points toward second object (object index 1) - virtual void GetContactPoint(Vec3& out) = 0; // contact point of collision (in world space) - virtual void GetContactSpeed(Vec3& out) = 0; // speed of surface 1 relative to surface 0 (in world space) + virtual void GetSurfaceNormal(Vec3& out) = 0; + virtual void GetContactPoint(Vec3& out) = 0; + virtual void GetContactSpeed(Vec3& out) = 0; }; - struct vcollisionevent_t { IPhysicsObject* pObjects[2]; - int surfaceProps[2]; - bool isCollision; - bool isShadowCollision; - float deltaCollisionTime; - - float collisionSpeed; // only valid at postCollision - IPhysicsCollisionData* pInternalData; // may change pre/post collision + int surfaceProps[2]; + bool isCollision; + bool isShadowCollision; + float deltaCollisionTime; + float collisionSpeed; + IPhysicsCollisionData* pInternalData; }; class IPhysicsCollisionEvent { public: - // returns the two objects that collided, time between last collision of these objects - // and an opaque data block of collision information - // NOTE: PreCollision/PostCollision ALWAYS come in matched pairs!!! virtual void PreCollision(vcollisionevent_t* pEvent) = 0; virtual void PostCollision(vcollisionevent_t* pEvent) = 0; - - // This is a scrape event. The object has scraped across another object consuming the indicated energy virtual void Friction(IPhysicsObject* pObject, float energy, int surfaceProps, int surfacePropsHit, IPhysicsCollisionData* pData) = 0; - virtual void StartTouch(IPhysicsObject* pObject1, IPhysicsObject* pObject2, IPhysicsCollisionData* pTouchData) = 0; virtual void EndTouch(IPhysicsObject* pObject1, IPhysicsObject* pObject2, IPhysicsCollisionData* pTouchData) = 0; - virtual void FluidStartTouch(IPhysicsObject* pObject, IPhysicsFluidController* pFluid) = 0; virtual void FluidEndTouch(IPhysicsObject* pObject, IPhysicsFluidController* pFluid) = 0; - virtual void PostSimulationFrame() = 0; - virtual void ObjectEnterTrigger(IPhysicsObject* pTrigger, IPhysicsObject* pObject) {} virtual void ObjectLeaveTrigger(IPhysicsObject* pTrigger, IPhysicsObject* pObject) {} }; - class IPhysicsObjectEvent { public: - // these can be used to optimize out queries on sleeping objects - // Called when an object is woken after sleeping virtual void ObjectWake(IPhysicsObject* pObject) = 0; - // called when an object goes to sleep (no longer simulating) virtual void ObjectSleep(IPhysicsObject* pObject) = 0; }; class IPhysicsConstraintEvent { public: - // the constraint is now inactive, the game code is required to delete it or re-activate it. virtual void ConstraintBroken(IPhysicsConstraint*) = 0; }; -struct hlshadowcontrol_params_t -{ - Vec3 targetPosition; - QAngle targetRotation; - float maxAngular; - float maxDampAngular; - float maxSpeed; - float maxDampSpeed; - float dampFactor; - float teleportDistance; -}; - -// UNDONE: At some point allow this to be parameterized using hlshadowcontrol_params_t. -// All of the infrastructure is in place to do that. - class IPhysicsShadowController { public: virtual ~IPhysicsShadowController(void) {} - virtual void Update(const Vec3& position, const QAngle& angles, float timeOffset) = 0; virtual void MaxSpeed(float maxSpeed, float maxAngularSpeed) = 0; virtual void StepUp(float height) = 0; - - // If the teleport distance is non-zero, the object will be teleported to - // the target location when the error exceeds this quantity. virtual void SetTeleportDistance(float teleportDistance) = 0; virtual bool AllowsTranslation() = 0; virtual bool AllowsRotation() = 0; - - // There are two classes of shadow objects: - // 1) Game physics controlled, shadow follows game physics (this is the default) - // 2) Physically controlled - shadow position is a target, but the game hasn't guaranteed that the space can be occupied by this object virtual void SetPhysicallyControlled(bool isPhysicallyControlled) = 0; virtual bool IsPhysicallyControlled() = 0; virtual void GetLastImpulse(Vec3* pOut) = 0; virtual void UseShadowMaterial(bool bUseShadowMaterial) = 0; virtual void ObjectMaterialChanged(int materialIndex) = 0; - - - //Basically get the last inputs to IPhysicsShadowController::Update(), returns last input to timeOffset in Update() virtual float GetTargetPosition(Vec3* pPositionOut, QAngle* pAnglesOut) = 0; - virtual float GetTeleportDistance(void) = 0; virtual void GetMaxSpeed(float* pMaxSpeedOut, float* pMaxAngularSpeedOut) = 0; }; -class CPhysicsSimObject; -class IPhysicsMotionController; - -// Callback for simulation class IMotionEvent { public: - // These constants instruct the simulator as to how to apply the values copied to linear & angular - // GLOBAL/LOCAL refer to the coordinate system of the values, whereas acceleration/force determine whether or not - // mass is divided out (forces must be divided by mass to compute acceleration) enum simresult_e { SIM_NOTHING = 0, SIM_LOCAL_ACCELERATION, SIM_LOCAL_FORCE, SIM_GLOBAL_ACCELERATION, SIM_GLOBAL_FORCE }; - virtual simresult_e Simulate(IPhysicsMotionController* pController, IPhysicsObject* pObject, float deltaTime, Vec3& linear, Vec3& angular) = 0; + virtual simresult_e Simulate(IPhysicsMotionController* pController, IPhysicsObject* pObject, float deltaTime, Vec3& linear, Vec3& angular) = 0; }; class IPhysicsMotionController @@ -732,16 +553,10 @@ public: virtual void SetEventHandler(IMotionEvent* handler) = 0; virtual void AttachObject(IPhysicsObject* pObject, bool checkIfAlreadyAttached) = 0; virtual void DetachObject(IPhysicsObject* pObject) = 0; - - // returns the number of objects currently attached to the controller virtual int CountObjects(void) = 0; - // NOTE: pObjectList is an array with at least CountObjects() allocated virtual void GetObjects(IPhysicsObject** pObjectList) = 0; - // detaches all attached objects virtual void ClearObjects(void) = 0; - // wakes up all attached objects virtual void WakeObjects(void) = 0; - enum priority_t { LOW_PRIORITY = 0, @@ -751,82 +566,41 @@ public: virtual void SetPriority(priority_t priority) = 0; }; -// ------------------- -// Collision filter function. Return 0 if objects should not be tested for collisions, nonzero otherwise -// Install with IPhysicsEnvironment::SetCollisionFilter() -// ------------------- class IPhysicsCollisionSolver { public: virtual int ShouldCollide(IPhysicsObject* pObj0, IPhysicsObject* pObj1, void* pGameData0, void* pGameData1) = 0; virtual int ShouldSolvePenetration(IPhysicsObject* pObj0, IPhysicsObject* pObj1, void* pGameData0, void* pGameData1, float dt) = 0; - - // pObject has already done the max number of collisions this tick, should we freeze it to save CPU? virtual bool ShouldFreezeObject(IPhysicsObject* pObject) = 0; - - // The system has already done too many collision checks, performance will suffer. - // How many more should it do? virtual int AdditionalCollisionChecksThisTick(int currentChecksDone) = 0; - - // This list of objects is in a connected contact graph that is too large to solve quickly - // return true to freeze the system, false to solve it virtual bool ShouldFreezeContacts(IPhysicsObject** pObjectList, int objectCount) = 0; }; -enum PhysicsTraceType_t -{ - VPHYSICS_TRACE_EVERYTHING = 0, - VPHYSICS_TRACE_STATIC_ONLY, - VPHYSICS_TRACE_MOVING_ONLY, - VPHYSICS_TRACE_TRIGGERS_ONLY, - VPHYSICS_TRACE_STATIC_AND_MOVING, -}; - class IPhysicsTraceFilter { public: virtual bool ShouldHitObject(IPhysicsObject* pObject, int contentsMask) = 0; - virtual PhysicsTraceType_t GetTraceType() const = 0; + virtual PhysicsTraceType_t GetTraceType() const = 0; }; class IPhysicsEnvironment { public: virtual ~IPhysicsEnvironment(void) {} - virtual void SetDebugOverlay(CreateInterfaceFn debugOverlayFactory) = 0; virtual IVPhysicsDebugOverlay* GetDebugOverlay(void) = 0; - - // gravity is a 3-vector in in/s^2 - virtual void SetGravity(const Vec3& gravityVector) = 0; - virtual void GetGravity(Vec3* pGravityVector) const = 0; - - // air density is in kg / m^3 (water is 1000) - // This controls drag, air that is more dense has more drag. - virtual void SetAirDensity(float density) = 0; - virtual float GetAirDensity(void) const = 0; - - // object creation - // create a polygonal object. pCollisionModel was created by the physics builder DLL in a pre-process. + virtual void SetGravity(const Vec3& gravityVector) = 0; + virtual void GetGravity(Vec3* pGravityVector) const = 0; + virtual void SetAirDensity(float density) = 0; + virtual float GetAirDensity(void) const = 0; virtual IPhysicsObject* CreatePolyObject(const CPhysCollide* pCollisionModel, int materialIndex, const Vec3& position, const QAngle& angles, objectparams_t* pParams) = 0; - // same as above, but this one cannot move or rotate (infinite mass/inertia) virtual IPhysicsObject* CreatePolyObjectStatic(const CPhysCollide* pCollisionModel, int materialIndex, const Vec3& position, const QAngle& angles, objectparams_t* pParams) = 0; - // Create a perfectly spherical object virtual IPhysicsObject* CreateSphereObject(float radius, int materialIndex, const Vec3& position, const QAngle& angles, objectparams_t* pParams, bool isStatic) = 0; - // destroy an object created with CreatePolyObject() or CreatePolyObjectStatic() virtual void DestroyObject(IPhysicsObject*) = 0; - - // Create a polygonal fluid body out of the specified collision model - // This object will affect any other objects that collide with the collision model virtual IPhysicsFluidController* CreateFluidController(IPhysicsObject* pFluidObject, fluidparams_t* pParams) = 0; - // Destroy an object created with CreateFluidController() virtual void DestroyFluidController(IPhysicsFluidController*) = 0; - - // Create a simulated spring that connects 2 objects virtual IPhysicsSpring* CreateSpring(IPhysicsObject* pObjectStart, IPhysicsObject* pObjectEnd, springparams_t* pParams) = 0; virtual void DestroySpring(IPhysicsSpring*) = 0; - - // Create a constraint in the space of pReferenceObject which is attached by the constraint to pAttachedObject virtual IPhysicsConstraint* CreateRagdollConstraint(IPhysicsObject* pReferenceObject, IPhysicsObject* pAttachedObject, IPhysicsConstraintGroup* pGroup, const constraint_ragdollparams_t& ragdoll) = 0; virtual IPhysicsConstraint* CreateHingeConstraint(IPhysicsObject* pReferenceObject, IPhysicsObject* pAttachedObject, IPhysicsConstraintGroup* pGroup, const constraint_hingeparams_t& hinge) = 0; virtual IPhysicsConstraint* CreateFixedConstraint(IPhysicsObject* pReferenceObject, IPhysicsObject* pAttachedObject, IPhysicsConstraintGroup* pGroup, const constraint_fixedparams_t& fixed) = 0; @@ -834,87 +608,122 @@ public: virtual IPhysicsConstraint* CreateBallsocketConstraint(IPhysicsObject* pReferenceObject, IPhysicsObject* pAttachedObject, IPhysicsConstraintGroup* pGroup, const constraint_ballsocketparams_t& ballsocket) = 0; virtual IPhysicsConstraint* CreatePulleyConstraint(IPhysicsObject* pReferenceObject, IPhysicsObject* pAttachedObject, IPhysicsConstraintGroup* pGroup, const constraint_pulleyparams_t& pulley) = 0; virtual IPhysicsConstraint* CreateLengthConstraint(IPhysicsObject* pReferenceObject, IPhysicsObject* pAttachedObject, IPhysicsConstraintGroup* pGroup, const constraint_lengthparams_t& length) = 0; - virtual void DestroyConstraint(IPhysicsConstraint*) = 0; - virtual IPhysicsConstraintGroup* CreateConstraintGroup(const constraint_groupparams_t& groupParams) = 0; virtual void DestroyConstraintGroup(IPhysicsConstraintGroup* pGroup) = 0; - virtual IPhysicsShadowController* CreateShadowController(IPhysicsObject* pObject, bool allowTranslation, bool allowRotation) = 0; - virtual void DestroyShadowController(IPhysicsShadowController*) = 0; - + virtual void DestroyShadowController(IPhysicsShadowController*) = 0; virtual IPhysicsPlayerController* CreatePlayerController(IPhysicsObject* pObject) = 0; - virtual void DestroyPlayerController(IPhysicsPlayerController*) = 0; - + virtual void DestroyPlayerController(IPhysicsPlayerController*) = 0; virtual IPhysicsMotionController* CreateMotionController(IMotionEvent* pHandler) = 0; - virtual void DestroyMotionController(IPhysicsMotionController* pController) = 0; - + virtual void DestroyMotionController(IPhysicsMotionController* pController) = 0; virtual IPhysicsVehicleController* CreateVehicleController(IPhysicsObject* pVehicleBodyObject, const vehicleparams_t& params, unsigned int nVehicleType, IPhysicsGameTrace* pGameTrace) = 0; - virtual void DestroyVehicleController(IPhysicsVehicleController*) = 0; - - // install a function to filter collisions/penentration - virtual void SetCollisionSolver(IPhysicsCollisionSolver* pSolver) = 0; - - // run the simulator for deltaTime seconds - virtual void Simulate(float deltaTime) = 0; - // true if currently running the simulator (i.e. in a callback during physenv->Simulate()) - virtual bool IsInSimulation() const = 0; - - // Manage the timestep (period) of the simulator. The main functions are all integrated with - // this period as dt. - virtual float GetSimulationTimestep() const = 0; - virtual void SetSimulationTimestep(float timestep) = 0; - - // returns the current simulation clock's value. This is an absolute time. - virtual float GetSimulationTime() const = 0; - virtual void ResetSimulationClock() = 0; - // returns the current simulation clock's value at the next frame. This is an absolute time. - virtual float GetNextFrameTime(void) const = 0; - - // Collision callbacks (game code collision response) - virtual void SetCollisionEventHandler(IPhysicsCollisionEvent* pCollisionEvents) = 0; - virtual void SetObjectEventHandler(IPhysicsObjectEvent* pObjectEvents) = 0; - virtual void SetConstraintEventHandler(IPhysicsConstraintEvent* pConstraintEvents) = 0; - - virtual void SetQuickDelete(bool bQuick) = 0; - - virtual int GetActiveObjectCount() const = 0; - virtual void GetActiveObjects(IPhysicsObject** pOutputObjectList) const = 0; + virtual void DestroyVehicleController(IPhysicsVehicleController*) = 0; + virtual void SetCollisionSolver(IPhysicsCollisionSolver* pSolver) = 0; + virtual void Simulate(float deltaTime) = 0; + virtual bool IsInSimulation() const = 0; + virtual float GetSimulationTimestep() const = 0; + virtual void SetSimulationTimestep(float timestep) = 0; + virtual float GetSimulationTime() const = 0; + virtual void ResetSimulationClock() = 0; + virtual float GetNextFrameTime(void) const = 0; + virtual void SetCollisionEventHandler(IPhysicsCollisionEvent* pCollisionEvents) = 0; + virtual void SetObjectEventHandler(IPhysicsObjectEvent* pObjectEvents) = 0; + virtual void SetConstraintEventHandler(IPhysicsConstraintEvent* pConstraintEvents) = 0; + virtual void SetQuickDelete(bool bQuick) = 0; + virtual int GetActiveObjectCount() const = 0; + virtual void GetActiveObjects(IPhysicsObject** pOutputObjectList) const = 0; virtual const IPhysicsObject** GetObjectList(int* pOutputObjectCount) const = 0; - virtual bool TransferObject(IPhysicsObject* pObject, IPhysicsEnvironment* pDestinationEnvironment) = 0; - - virtual void CleanupDeleteList(void) = 0; - virtual void EnableDeleteQueue(bool enable) = 0; - - // Save/Restore methods - virtual bool Save(const physsaveparams_t& params) = 0; - virtual void PreRestore(const physprerestoreparams_t& params) = 0; - virtual bool Restore(const physrestoreparams_t& params) = 0; - virtual void PostRestore() = 0; - - // Debugging: + virtual bool TransferObject(IPhysicsObject* pObject, IPhysicsEnvironment* pDestinationEnvironment) = 0; + virtual void CleanupDeleteList(void) = 0; + virtual void EnableDeleteQueue(bool enable) = 0; + virtual bool Save(const physsaveparams_t& params) = 0; + virtual void PreRestore(const physprerestoreparams_t& params) = 0; + virtual bool Restore(const physrestoreparams_t& params) = 0; + virtual void PostRestore() = 0; virtual bool IsCollisionModelUsed(CPhysCollide* pCollide) const = 0; - - // Physics world version of the enginetrace API: virtual void TraceRay(const Ray_t& ray, unsigned int fMask, IPhysicsTraceFilter* pTraceFilter, trace_t* pTrace) = 0; - virtual void SweepCollideable(const CPhysCollide* pCollide, const Vec3& vecAbsStart, const Vec3& vecAbsEnd, - const QAngle& vecAngles, unsigned int fMask, IPhysicsTraceFilter* pTraceFilter, trace_t* pTrace) = 0; - - // performance tuning + virtual void SweepCollideable(const CPhysCollide* pCollide, const Vec3& vecAbsStart, const Vec3& vecAbsEnd, const QAngle& vecAngles, unsigned int fMask, IPhysicsTraceFilter* pTraceFilter, trace_t* pTrace) = 0; virtual void GetPerformanceSettings(physics_performanceparams_t* pOutput) const = 0; virtual void SetPerformanceSettings(const physics_performanceparams_t* pSettings) = 0; - - // perf/cost statistics virtual void ReadStats(physics_stats_t* pOutput) = 0; virtual void ClearStats() = 0; - - virtual unsigned int GetObjectSerializeSize(IPhysicsObject* pObject) const = 0; - virtual void SerializeObjectToBuffer(IPhysicsObject* pObject, unsigned char* pBuffer, unsigned int bufferSize) = 0; + virtual unsigned int GetObjectSerializeSize(IPhysicsObject* pObject) const = 0; + virtual void SerializeObjectToBuffer(IPhysicsObject* pObject, unsigned char* pBuffer, unsigned int bufferSize) = 0; virtual IPhysicsObject* UnserializeObjectFromBuffer(void* pGameData, unsigned char* pBuffer, unsigned int bufferSize, bool enableCollisions) = 0; - - virtual void EnableConstraintNotify(bool bEnable) = 0; virtual void DebugCheckContacts(void) = 0; }; +class IPhysicsCollision +{ +public: + virtual ~IPhysicsCollision(void) {} + virtual CPhysConvex* ConvexFromVerts(Vec3** pVerts, int vertCount) = 0; + virtual CPhysConvex* ConvexFromPlanes(float* pPlanes, int planeCount, float mergeDistance) = 0; + virtual float ConvexVolume(CPhysConvex* pConvex) = 0; + virtual float ConvexSurfaceArea(CPhysConvex* pConvex) = 0; + virtual void SetConvexGameData(CPhysConvex* pConvex, unsigned int gameData) = 0; + virtual void ConvexFree(CPhysConvex* pConvex) = 0; + virtual CPhysConvex* BBoxToConvex(const Vec3& mins, const Vec3& maxs) = 0; + virtual CPhysConvex* ConvexFromConvexPolyhedron(const CPolyhedron& ConvexPolyhedron) = 0; + virtual void ConvexesFromConvexPolygon(const Vec3& vPolyNormal, const Vec3* pPoints, int iPointCount, CPhysConvex** pOutput) = 0; + virtual CPhysPolysoup* PolysoupCreate(void) = 0; + virtual void PolysoupDestroy(CPhysPolysoup* pSoup) = 0; + virtual void PolysoupAddTriangle(CPhysPolysoup* pSoup, const Vec3& a, const Vec3& b, const Vec3& c, int materialIndex7bits) = 0; + virtual CPhysCollide* ConvertPolysoupToCollide(CPhysPolysoup* pSoup, bool useMOPP) = 0; + virtual CPhysCollide* ConvertConvexToCollide(CPhysConvex** pConvex, int convexCount) = 0; + virtual CPhysCollide* ConvertConvexToCollideParams(CPhysConvex** pConvex, int convexCount, const convertconvexparams_t& convertParams) = 0; + virtual void DestroyCollide(CPhysCollide* pCollide) = 0; + virtual int CollideSize(CPhysCollide* pCollide) = 0; + virtual int CollideWrite(char* pDest, CPhysCollide* pCollide, bool bSwap = false) = 0; + virtual CPhysCollide* UnserializeCollide(char* pBuffer, int size, int index) = 0; + virtual float CollideVolume(CPhysCollide* pCollide) = 0; + virtual float CollideSurfaceArea(CPhysCollide* pCollide) = 0; + virtual Vec3 CollideGetExtent(const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, const Vec3& direction) = 0; + virtual void CollideGetAABB(Vec3* pMins, Vec3* pMaxs, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles) = 0; + virtual void CollideGetMassCenter(CPhysCollide* pCollide, Vec3* pOutMassCenter) = 0; + virtual void CollideSetMassCenter(CPhysCollide* pCollide, const Vec3& massCenter) = 0; + virtual Vec3 CollideGetOrthographicAreas(const CPhysCollide* pCollide) = 0; + virtual void CollideSetOrthographicAreas(CPhysCollide* pCollide, const Vec3& areas) = 0; + virtual int CollideIndex(const CPhysCollide* pCollide) = 0; + virtual CPhysCollide* BBoxToCollide(const Vec3& mins, const Vec3& maxs) = 0; + virtual int GetConvexesUsedInCollideable(const CPhysCollide* pCollideable, CPhysConvex** pOutputArray, int iOutputArrayLimit) = 0; + virtual void TraceBox(const Vec3& start, const Vec3& end, const Vec3& mins, const Vec3& maxs, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, trace_t* ptr) = 0; + virtual void TraceBox(const Ray_t& ray, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, trace_t* ptr) = 0; + virtual void TraceBox(const Ray_t& ray, unsigned int contentsMask, IConvexInfo* pConvexInfo, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, trace_t* ptr) = 0; + virtual void TraceCollide(const Vec3& start, const Vec3& end, const CPhysCollide* pSweepCollide, const QAngle& sweepAngles, const CPhysCollide* pCollide, const Vec3& collideOrigin, const QAngle& collideAngles, trace_t* ptr) = 0; + virtual bool IsBoxIntersectingCone(const Vec3& boxAbsMins, const Vec3& boxAbsMaxs, const truncatedcone_t& cone) = 0; + virtual void VCollideLoad(vcollide_t* pOutput, int solidCount, const char* pBuffer, int size, bool swap = false) = 0; + virtual void VCollideUnload(vcollide_t* pVCollide) = 0; + virtual IVPhysicsKeyParser* VPhysicsKeyParserCreate(const char* pKeyData) = 0; + virtual void VPhysicsKeyParserDestroy(IVPhysicsKeyParser* pParser) = 0; + virtual int CreateDebugMesh(CPhysCollide const* pCollisionModel, Vec3** outVerts) = 0; + virtual void DestroyDebugMesh(int vertCount, Vec3* outVerts) = 0; + virtual ICollisionQuery* CreateQueryModel(CPhysCollide* pCollide) = 0; + virtual void DestroyQueryModel(ICollisionQuery* pQuery) = 0; + virtual IPhysicsCollision* ThreadContextCreate(void) = 0; + virtual void ThreadContextDestroy(IPhysicsCollision* pThreadContex) = 0; + virtual CPhysCollide* CreateVirtualMesh(const virtualmeshparams_t& params) = 0; + virtual bool SupportsVirtualMesh() = 0; + virtual bool GetBBoxCacheSize(int* pCachedSize, int* pCachedCount) = 0; + virtual CPolyhedron* PolyhedronFromConvex(CPhysConvex* const pConvex, bool bUseTempPolyhedron) = 0; + virtual void OutputDebugInfo(const CPhysCollide* pCollide) = 0; + virtual unsigned int ReadStat(int statID) = 0; +}; + +class IPhysics : public IAppSystem +{ +public: + virtual IPhysicsEnvironment* CreateEnvironment(void) = 0; + virtual void DestroyEnvironment(IPhysicsEnvironment*) = 0; + virtual IPhysicsEnvironment* GetActiveEnvironmentByIndex(int index) = 0; + virtual IPhysicsObjectPairHash* CreateObjectPairHash() = 0; + virtual void DestroyObjectPairHash(IPhysicsObjectPairHash* pHash) = 0; + virtual IPhysicsCollisionSet* FindOrCreateCollisionSet(unsigned int id, int maxElementCount) = 0; + virtual IPhysicsCollisionSet* FindCollisionSet(unsigned int id) = 0; + virtual void DestroyAllCollisionSets() = 0; +}; + +MAKE_INTERFACE_VERSION(IPhysicsCollision, PhysicsCollision, "vphysics.dll", "VPhysicsCollision007"); MAKE_INTERFACE_VERSION(IPhysics, Physics, "vphysics.dll", "VPhysics031"); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Interfaces/ViewRenderBeams.h b/Amalgam/src/SDK/Definitions/Interfaces/ViewRenderBeams.h index 72c51775..7bd2b6f3 100644 --- a/Amalgam/src/SDK/Definitions/Interfaces/ViewRenderBeams.h +++ b/Amalgam/src/SDK/Definitions/Interfaces/ViewRenderBeams.h @@ -5,6 +5,28 @@ class CBaseEntity; class CTraceFilter; +enum +{ + FBEAM_STARTENTITY = 0x00000001, + FBEAM_ENDENTITY = 0x00000002, + FBEAM_FADEIN = 0x00000004, + FBEAM_FADEOUT = 0x00000008, + FBEAM_SINENOISE = 0x00000010, + FBEAM_SOLID = 0x00000020, + FBEAM_SHADEIN = 0x00000040, + FBEAM_SHADEOUT = 0x00000080, + FBEAM_ONLYNOISEONCE = 0x00000100, + FBEAM_NOTILE = 0x00000200, + FBEAM_USE_HITBOXES = 0x00000400, + FBEAM_STARTVISIBLE = 0x00000800, + FBEAM_ENDVISIBLE = 0x00001000, + FBEAM_ISACTIVE = 0x00002000, + FBEAM_FOREVER = 0x00004000, + FBEAM_HALOBEAM = 0x00008000, + FBEAM_REVERSED = 0x00010000, + NUM_BEAM_FLAGS = 17 +}; + struct BeamTrail_t { BeamTrail_t* next; @@ -57,28 +79,6 @@ struct Beam_t float m_flHDRColorScale; }; -enum -{ - FBEAM_STARTENTITY = 0x00000001, - FBEAM_ENDENTITY = 0x00000002, - FBEAM_FADEIN = 0x00000004, - FBEAM_FADEOUT = 0x00000008, - FBEAM_SINENOISE = 0x00000010, - FBEAM_SOLID = 0x00000020, - FBEAM_SHADEIN = 0x00000040, - FBEAM_SHADEOUT = 0x00000080, - FBEAM_ONLYNOISEONCE = 0x00000100, // Only calculate our noise once - FBEAM_NOTILE = 0x00000200, - FBEAM_USE_HITBOXES = 0x00000400, // Attachment indices represent hitbox indices instead when this is set. - FBEAM_STARTVISIBLE = 0x00000800, // Has this client actually seen this beam's start entity yet? - FBEAM_ENDVISIBLE = 0x00001000, // Has this client actually seen this beam's end entity yet? - FBEAM_ISACTIVE = 0x00002000, - FBEAM_FOREVER = 0x00004000, - FBEAM_HALOBEAM = 0x00008000, // When drawing a beam with a halo, don't ignore the segments and endwidth - FBEAM_REVERSED = 0x00010000, - NUM_BEAM_FLAGS = 17 // KEEP THIS UPDATED! -}; - struct BeamInfo_t { int m_nType; @@ -131,16 +131,10 @@ public: virtual void InitBeams(void) = 0; virtual void ShutdownBeams(void) = 0; virtual void ClearBeams(void) = 0; - - // Updates the state of the temp ent beams virtual void UpdateTempEntBeams() = 0; - virtual void DrawBeam(CBaseEntity* pbeam, CTraceFilter* pEntityBeamTraceFilter = NULL) = 0; virtual void DrawBeam(Beam_t* pbeam) = 0; - virtual void KillDeadBeams(CBaseEntity* pEnt) = 0; - - // New interfaces! virtual Beam_t* CreateBeamEnts(BeamInfo_t& beamInfo) = 0; virtual Beam_t* CreateBeamEntPoint(BeamInfo_t& beamInfo) = 0; virtual Beam_t* CreateBeamPoints(BeamInfo_t& beamInfo) = 0; @@ -148,11 +142,8 @@ public: virtual Beam_t* CreateBeamRingPoint(BeamInfo_t& beamInfo) = 0; virtual Beam_t* CreateBeamCirclePoints(BeamInfo_t& beamInfo) = 0; virtual Beam_t* CreateBeamFollow(BeamInfo_t& beamInfo) = 0; - virtual void FreeBeam(Beam_t* pBeam) = 0; virtual void UpdateBeamInfo(Beam_t* pBeam, BeamInfo_t& beamInfo) = 0; - - // These will go away! virtual void CreateBeamEnts(int startEnt, int endEnt, int modelIndex, int haloIndex, float haloScale, float life, float width, float m_nEndWidth, float m_nFadeLength, float amplitude, float brightness, float speed, int startFrame, diff --git a/Amalgam/src/SDK/Definitions/Interfaces/WorldBrushData.h b/Amalgam/src/SDK/Definitions/Interfaces/WorldBrushData.h new file mode 100644 index 00000000..410e94c2 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Interfaces/WorldBrushData.h @@ -0,0 +1,5 @@ +#pragma once +#include "Interface.h" +#include "../Main/CModel.h" + +MAKE_INTERFACE_SIGNATURE(worldbrushdata_t, WorldBrushData, "engine.dll", "48 8D 05 ? ? ? ? 48 89 05 ? ? ? ? 48 8B 5C 24 ? 48 83 C4", 0x0, 0); \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/CBaseAnimating.h b/Amalgam/src/SDK/Definitions/Main/CBaseAnimating.h index e38c02ff..e7347c4d 100644 --- a/Amalgam/src/SDK/Definitions/Main/CBaseAnimating.h +++ b/Amalgam/src/SDK/Definitions/Main/CBaseAnimating.h @@ -1,6 +1,7 @@ #pragma once #include "CBaseEntity.h" -#include "../Misc/Studio.h" + +class CStudioHdr; MAKE_SIGNATURE(CBaseAnimating_FrameAdvance, "client.dll", "48 89 5C 24 ? 48 89 6C 24 ? 57 48 81 EC ? ? ? ? 44 0F 29 54 24", 0x0); MAKE_SIGNATURE(CBaseAnimating_GetBonePosition, "client.dll", "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 8B DA 49 8B F1", 0x0); diff --git a/Amalgam/src/SDK/Definitions/Main/CBaseEntity.h b/Amalgam/src/SDK/Definitions/Main/CBaseEntity.h index ae5d3f62..9b1fa0d5 100644 --- a/Amalgam/src/SDK/Definitions/Main/CBaseEntity.h +++ b/Amalgam/src/SDK/Definitions/Main/CBaseEntity.h @@ -1,10 +1,8 @@ #pragma once #include "CBaseHandle.h" #include "IClientEntity.h" -#include "CCollisionProperty.h" -#include "CParticleProperty.h" -#include "../Main/UtlVector.h" #include "../Misc/CInterpolatedVar.h" +#include "../Misc/CUtlVector.h" #include "../Definitions.h" #include "../../../Utils/Memory/Memory.h" #include "../../../Utils/Signatures/Signatures.h" @@ -29,6 +27,8 @@ typedef CHandle EHANDLE; #define MULTIPLAYER_BACKUP 90 class IInterpolatedVar; +class CCollisionProperty; +class CParticleProperty; class VarMapEntry_t { diff --git a/Amalgam/src/SDK/Definitions/Main/CBaseHandle.h b/Amalgam/src/SDK/Definitions/Main/CBaseHandle.h index 6f04c765..a3586559 100644 --- a/Amalgam/src/SDK/Definitions/Main/CBaseHandle.h +++ b/Amalgam/src/SDK/Definitions/Main/CBaseHandle.h @@ -241,4 +241,6 @@ template T* CHandle::operator ->() const { return Get(); -} \ No newline at end of file +} + +typedef CBaseHandle EntityHandle_t; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/CBasePlayer.h b/Amalgam/src/SDK/Definitions/Main/CBasePlayer.h index ad706aa9..0de2d9bc 100644 --- a/Amalgam/src/SDK/Definitions/Main/CBasePlayer.h +++ b/Amalgam/src/SDK/Definitions/Main/CBasePlayer.h @@ -1,7 +1,8 @@ #pragma once #include "CBaseCombatCharacter.h" #include "CEconWearable.h" -#include "CUserCmd.h" + +class CUserCmd; MAKE_SIGNATURE(CBasePlayer_GetAmmoCount, "client.dll", "48 89 5C 24 ? 57 48 83 EC ? 48 63 DA 48 8B F9 83 FB", 0x0); diff --git a/Amalgam/src/SDK/Definitions/Main/CBaseTrace.h b/Amalgam/src/SDK/Definitions/Main/CBaseTrace.h index a60c3c05..bca72350 100644 --- a/Amalgam/src/SDK/Definitions/Main/CBaseTrace.h +++ b/Amalgam/src/SDK/Definitions/Main/CBaseTrace.h @@ -1,5 +1,5 @@ #pragma once -#include "../Types.h" +#include "CModel.h" #define DISPSURF_FLAG_SURFACE (1<<0) #define DISPSURF_FLAG_WALKABLE (1<<1) @@ -7,15 +7,6 @@ #define DISPSURF_FLAG_SURFPROP1 (1<<3) #define DISPSURF_FLAG_SURFPROP2 (1<<4) -struct cplane_t -{ - Vector normal{}; - float dist{}; - byte type{}; - byte signbits{}; - byte pad[2]{}; -}; - #define CPLANE_NORMAL_X 0 #define CPLANE_NORMAL_Y 4 #define CPLANE_NORMAL_Z 8 diff --git a/Amalgam/src/SDK/Definitions/Main/CCollisionProperty.h b/Amalgam/src/SDK/Definitions/Main/CCollisionProperty.h index 946d2c38..106eb514 100644 --- a/Amalgam/src/SDK/Definitions/Main/CCollisionProperty.h +++ b/Amalgam/src/SDK/Definitions/Main/CCollisionProperty.h @@ -1,37 +1,11 @@ #pragma once -#include "CGameTrace.h" -#include "../Types.h" +#include "ICollideable.h" #include "../../../Utils/Signatures/Signatures.h" MAKE_SIGNATURE(CCollisionProperty_SetCollisionBounds, "client.dll", "48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 81 EC ? ? ? ? F3 0F 10 0A", 0x0); MAKE_SIGNATURE(CCollisionProperty_CalcNearestPoint, "client.dll", "48 89 5C 24 ? 57 48 83 EC ? 49 8B D8 48 8B F9 4C 8D 44 24", 0x0); -struct model_t; - -class ICollideable -{ -public: - virtual void* GetEntityHandle() = 0; - virtual const Vec3& OBBMinsPreScaled() const = 0; - virtual const Vec3& OBBMaxsPreScaled() const = 0; - virtual const Vec3& OBBMins() const = 0; - virtual const Vec3& OBBMaxs() const = 0; - virtual void WorldSpaceTriggerBounds(Vec3* pVecWorldMins, Vec3* pVecWorldMaxs) const = 0; - virtual bool TestCollision(const Ray_t& ray, unsigned int fContentsMask, CGameTrace& tr) = 0; - virtual bool TestHitboxes(const Ray_t& ray, unsigned int fContentsMask, CGameTrace& tr) = 0; - virtual int GetCollisionModelIndex() = 0; - virtual const model_t* GetCollisionModel() = 0; - virtual const Vec3& GetCollisionOrigin() const = 0; - virtual const Vec3& GetCollisionAngles() const = 0; - virtual const matrix3x4& CollisionToWorldTransform() const = 0; - virtual SolidType_t GetSolid() const = 0; - virtual int GetSolidFlags() const = 0; - virtual void* GetIClientUnknown() = 0; - virtual int GetCollisionGroup() const = 0; - virtual void WorldSpaceSurroundingBounds(Vec3* pVecMins, Vec3* pVecMaxs) = 0; - virtual bool ShouldTouchTrigger(int triggerSolidFlags) const = 0; - virtual const matrix3x4* GetRootParentToWorldTransform() const = 0; -}; +typedef unsigned short SpatialPartitionHandle_t; class CCollisionProperty : public ICollideable { diff --git a/Amalgam/src/SDK/Definitions/Main/CEconDefinition.h b/Amalgam/src/SDK/Definitions/Main/CEconDefinition.h index dd786b8b..a410a435 100644 --- a/Amalgam/src/SDK/Definitions/Main/CEconDefinition.h +++ b/Amalgam/src/SDK/Definitions/Main/CEconDefinition.h @@ -1,7 +1,8 @@ #pragma once -#include "KeyValues.h" #include "../Steam/SteamClientPublic.h" +class KeyValues; + class CEconNotification { public: diff --git a/Amalgam/src/SDK/Definitions/Main/CEntitySphereQuery.h b/Amalgam/src/SDK/Definitions/Main/CEntitySphereQuery.h index 7eeacee1..237a9405 100644 --- a/Amalgam/src/SDK/Definitions/Main/CEntitySphereQuery.h +++ b/Amalgam/src/SDK/Definitions/Main/CEntitySphereQuery.h @@ -1,20 +1,23 @@ #pragma once #include "../Definitions.h" -#include "CBaseEntity.h" - -#define MAX_SPHERE_QUERY 512 +#include "../../../Utils/Signatures/Signatures.h" +#pragma warning (push) #pragma warning (disable : 26495) MAKE_SIGNATURE(CEntitySphereQuery, "client.dll", "40 53 48 83 EC ? 48 8B D9 C7 44 24 ? ? ? ? ? 33 C9", 0x0); -//credits to KGB +#define MAX_SPHERE_QUERY 512 + +class CBaseEntity; + +// credits to KGB class CEntitySphereQuery { public: CEntitySphereQuery(const Vec3& center, const float radius, const int flagMask = 0, const int partitionMask = PARTITION_CLIENT_NON_STATIC_EDICTS) { - S::CEntitySphereQuery.Call(this, std::ref(center), radius, flagMask, partitionMask); + S::CEntitySphereQuery.Call(this, std::ref(center), radius, flagMask, partitionMask); } inline CBaseEntity* GetCurrentEntity() @@ -30,4 +33,6 @@ public: private: int m_nListIndex, m_nListCount; CBaseEntity* m_pList[MAX_SPHERE_QUERY]; -}; \ No newline at end of file +}; + +#pragma warning (pop) \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/CGameTrace.h b/Amalgam/src/SDK/Definitions/Main/CGameTrace.h index 620a8482..4902d2c1 100644 --- a/Amalgam/src/SDK/Definitions/Main/CGameTrace.h +++ b/Amalgam/src/SDK/Definitions/Main/CGameTrace.h @@ -1,8 +1,5 @@ #pragma once -#include "CModel.h" -#include "UtlVector.h" -#include "IHandleEntity.h" -#include "../Misc/ISpatialPartition.h" +#include "CBaseTrace.h" class CBaseEntity; diff --git a/Amalgam/src/SDK/Definitions/Main/CMapLoadHelper.h b/Amalgam/src/SDK/Definitions/Main/CMapLoadHelper.h new file mode 100644 index 00000000..67e77233 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Main/CMapLoadHelper.h @@ -0,0 +1,120 @@ +#pragma once +#include "../../../Utils/Signatures/Signatures.h" +#include + +MAKE_SIGNATURE(CMapLoadHelper, "engine.dll", "40 53 56 41 56 41 57", 0x0); +MAKE_SIGNATURE(_CMapLoadHelper, "engine.dll", "40 53 48 83 EC ? 48 8B D9 48 8B 49 ? 48 85 C9 74 ? E8 ? ? ? ? 48 8B 53", 0x0); +MAKE_SIGNATURE(CMapLoadHelper_Init, "engine.dll", "48 89 5C 24 ? 57 48 83 EC ? 8B 05 ? ? ? ? 48 8B DA", 0x0); +MAKE_SIGNATURE(CMapLoadHelper_Shutdown, "engine.dll", "48 83 EC ? 8B 05 ? ? ? ? FF C8", 0x0); + +#define HEADER_LUMPS 64 + +struct model_t; +using byte = unsigned char; + +enum +{ + LUMP_ENTITIES = 0, + LUMP_PLANES = 1, + LUMP_TEXDATA = 2, + LUMP_VERTEXES = 3, + LUMP_VISIBILITY = 4, + LUMP_NODES = 5, + LUMP_TEXINFO = 6, + LUMP_FACES = 7, + LUMP_LIGHTING = 8, + LUMP_OCCLUSION = 9, + LUMP_LEAFS = 10, + LUMP_FACEIDS = 11, + LUMP_EDGES = 12, + LUMP_SURFEDGES = 13, + LUMP_MODELS = 14, + LUMP_WORLDLIGHTS = 15, + LUMP_LEAFFACES = 16, + LUMP_LEAFBRUSHES = 17, + LUMP_BRUSHES = 18, + LUMP_BRUSHSIDES = 19, + LUMP_AREAS = 20, + LUMP_AREAPORTALS = 21, + LUMP_UNUSED0 = 22, + LUMP_UNUSED1 = 23, + LUMP_UNUSED2 = 24, + LUMP_UNUSED3 = 25, + LUMP_DISPINFO = 26, + LUMP_ORIGINALFACES = 27, + LUMP_PHYSDISP = 28, + LUMP_PHYSCOLLIDE = 29, + LUMP_VERTNORMALS = 30, + LUMP_VERTNORMALINDICES = 31, + LUMP_DISP_LIGHTMAP_ALPHAS = 32, + LUMP_DISP_VERTS = 33, + LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS = 34, + LUMP_GAME_LUMP = 35, + LUMP_LEAFWATERDATA = 36, + LUMP_PRIMITIVES = 37, + LUMP_PRIMVERTS = 38, + LUMP_PRIMINDICES = 39, + LUMP_PAKFILE = 40, + LUMP_CLIPPORTALVERTS = 41, + LUMP_CUBEMAPS = 42, + LUMP_TEXDATA_STRING_DATA = 43, + LUMP_TEXDATA_STRING_TABLE = 44, + LUMP_OVERLAYS = 45, + LUMP_LEAFMINDISTTOWATER = 46, + LUMP_FACE_MACRO_TEXTURE_INFO = 47, + LUMP_DISP_TRIS = 48, + LUMP_PHYSCOLLIDESURFACE = 49, + LUMP_WATEROVERLAYS = 50, + LUMP_LEAF_AMBIENT_INDEX_HDR = 51, + LUMP_LEAF_AMBIENT_INDEX = 52, + LUMP_LIGHTING_HDR = 53, + LUMP_WORLDLIGHTS_HDR = 54, + LUMP_LEAF_AMBIENT_LIGHTING_HDR = 55, + LUMP_LEAF_AMBIENT_LIGHTING = 56, + LUMP_XZIPPAKFILE = 57, + LUMP_FACES_HDR = 58, + LUMP_MAP_FLAGS = 59, + LUMP_OVERLAY_FADES = 60, +}; + +class CMapLoadHelper +{ +public: + CMapLoadHelper(int lumpToLoad) + { + S::CMapLoadHelper.Call(this, lumpToLoad); + } + ~CMapLoadHelper(void) + { + S::_CMapLoadHelper.Call(this); + } + + byte* LumpBase() { return m_pData; } + int LumpSize() { return m_nLumpSize; } + int LumpOffset() { return m_nLumpOffset; }; + int LumpVersion() const { return m_nLumpVersion; }; + //const char* GetMapName() { return s_szMapName; } + //char* GetLoadName(); + //struct worldbrushdata_t* GetMap(); + + // Global setup/shutdown + static SIGNATURE_ARGS(Init, void, CMapLoadHelper, (model_t* pMapModel, const char* loadname), pMapModel, loadname); + static SIGNATURE(Shutdown, void, CMapLoadHelper); + //static void InitFromMemory(model_t* pMapModel, const void* pData, int nDataSize); + //static int GetRefCount(); + //static void FreeLightingLump(); + //static int LumpSize(int lumpId); + //static int LumpOffset(int lumpId); + //void LoadLumpElement(int nElemIndex, int nElemSize, void* pData); + //void LoadLumpData(int offset, int size, void* pData); + +public: + int m_nLumpSize; + int m_nLumpOffset; + int m_nLumpVersion; + byte* m_pRawData; + byte* m_pData; + byte* m_pUncompressedData; + int m_nLumpID; + char m_szLumpFilename[MAX_PATH]; +}; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/CModel.h b/Amalgam/src/SDK/Definitions/Main/CModel.h index 5d4d8067..9c50280c 100644 --- a/Amalgam/src/SDK/Definitions/Main/CModel.h +++ b/Amalgam/src/SDK/Definitions/Main/CModel.h @@ -1,97 +1,532 @@ #pragma once -#include "CBaseTrace.h" -#include "CBaseHandle.h" +#include "Ray.h" #include "../Misc/BSPFlags.h" #include "../Misc/VCollide.h" - -struct edict_t; -struct model_t; +#include "../Misc/CUtlString.h" #define AREA_SOLID 1 #define AREA_TRIGGERS 2 +#define NUMSIDES_BOXBRUSH 0xFFFF +#define MAXLIGHTMAPS 4 -struct cmodel_t +#define SURFDRAW_NOLIGHT 0x00000001 +#define SURFDRAW_NODE 0x00000002 +#define SURFDRAW_SKY 0x00000004 +#define SURFDRAW_BUMPLIGHT 0x00000008 +#define SURFDRAW_NODRAW 0x00000010 +#define SURFDRAW_TRANS 0x00000020 +#define SURFDRAW_PLANEBACK 0x00000040 +#define SURFDRAW_DYNAMIC 0x00000080 +#define SURFDRAW_TANGENTSPACE 0x00000100 +#define SURFDRAW_NOCULL 0x00000200 +#define SURFDRAW_HASLIGHTSYTLES 0x00000400 +#define SURFDRAW_HAS_DISP 0x00000800 +#define SURFDRAW_ALPHATEST 0x00001000 +#define SURFDRAW_NOSHADOWS 0x00002000 +#define SURFDRAW_NODECALS 0x00004000 +#define SURFDRAW_HAS_PRIMS 0x00008000 +#define SURFDRAW_WATERSURFACE 0x00010000 +#define SURFDRAW_UNDERWATER 0x00020000 +#define SURFDRAW_ABOVEWATER 0x00040000 +#define SURFDRAW_HASDLIGHT 0x00080000 +#define SURFDRAW_DLIGHTPASS 0x00100000 +#define SURFDRAW_UNUSED2 0x00200000 +#define SURFDRAW_VERTCOUNT_MASK 0xFF000000 +#define SURFDRAW_SORTGROUP_MASK 0x00C00000 + +#define SURFDRAW_VERTCOUNT_SHIFT 24 +#define SURFDRAW_SORTGROUP_SHIFT 22 + +class IMaterial; +class ITexture; +class CEngineSprite; +class IDispInfo; +struct cplane_t; +struct edict_t; +struct model_t; +typedef unsigned short WorldDecalHandle_t; +typedef unsigned short ShadowDecalHandle_t; +typedef unsigned short OverlayFragmentHandle_t; +typedef void* FileNameHandle_t; +typedef unsigned short MDLHandle_t; +typedef void* HDISPINFOARRAY; +typedef void*/*CCubeMap*/ lightzbuffer_t; + +enum modtype_t +{ + mod_bad = 0, + mod_brush, + mod_sprite, + mod_studio +}; + +enum emittype_t +{ + emit_surface, + emit_point, + emit_spotlight, + emit_skylight, + emit_quakelight, + emit_skyambient, +}; + +struct ColorRGBExp32 +{ + byte r, g, b; + signed char exponent; +}; + +struct CompressedLightCube +{ + ColorRGBExp32 m_Color[6]; +}; + +struct darea_t +{ + int numareaportals; + int firstareaportal; +}; + +struct dareaportal_t +{ + unsigned short m_PortalKey; + unsigned short otherarea; + unsigned short m_FirstClipPortalVert; + unsigned short m_nClipPortalVerts; + int planenum; +}; + +struct dvis_t +{ + int numclusters; + int bitofs[8][2]; +}; + +struct doccluderdata_t +{ + int flags; + int firstpoly; + int polycount; + Vector mins; + Vector maxs; + int area; +}; + +struct doccluderpolydata_t +{ + int firstvertexindex; + int vertexcount; + int planenum; +}; + +struct dvertex_t +{ + Vector point; +}; + +struct dedge_t +{ + unsigned short v[2]; +}; + +struct dface_t +{ + unsigned short planenum; + byte side; + byte onNode; + int firstedge; + short numedges; + short texinfo; + //union + //{ + short dispinfo; + short surfaceFogVolumeID; + //}; + byte styles[MAXLIGHTMAPS]; + int lightofs; + float area; + int m_LightmapTextureMinsInLuxels[2]; + int m_LightmapTextureSizeInLuxels[2]; + int origFace; + unsigned short m_NumPrims; + unsigned short firstPrimID; + unsigned int smoothingGroups; +}; + +struct dbrush_t +{ + int firstside; + int numsides; + int contents; +}; + +struct dbrushside_t +{ + unsigned short planenum; + short texinfo; + short dispinfo; + short bevel; +}; + +struct dworldlight_t { - Vector mins, maxs; Vector origin; - int headnode; - vcollide_t vcollisionData; + Vector intensity; + Vector normal; + int cluster; + emittype_t type; + int style; + float stopdot; + float stopdot2; + float exponent; + float radius; + float constant_attn; + float linear_attn; + float quadratic_attn; + int flags; + int texinfo; + int owner; +}; + +struct dleafambientindex_t +{ + unsigned short ambientSampleCount; + unsigned short firstAmbientSample; +}; +typedef dleafambientindex_t mleafambientindex_t; + +struct dleafambientlighting_t +{ + CompressedLightCube cube; + byte x; + byte y; + byte z; + byte pad; +}; +typedef dleafambientlighting_t mleafambientlighting_t; + +struct mnode_t +{ + int contents; + int visframe; + mnode_t* parent; + short area; + short flags; + VectorAligned m_vecCenter; + VectorAligned m_vecHalfDiagonal; + cplane_t* plane; + mnode_t* children[2]; + unsigned short firstsurface; + unsigned short numsurfaces; +}; + +struct mleaf_t +{ + int contents; + int visframe; + mnode_t* parent; + short area; + short flags; + VectorAligned m_vecCenter; + VectorAligned m_vecHalfDiagonal; + short cluster; + short leafWaterDataID; + unsigned short firstmarksurface; + unsigned short nummarksurfaces; + short nummarknodesurfaces; + short unused; + unsigned short dispListStart; + unsigned short dispCount; +}; + +struct mleafwaterdata_t +{ + float surfaceZ; + float minZ; + short surfaceTexInfoID; + short firstLeafIndex; +}; + +struct mvertex_t +{ + Vector position; +}; + +struct msurface1_t +{ + int textureMins[2]; + short textureExtents[2]; + struct + { + unsigned short numPrims; + unsigned short firstPrimID; + } prims; +}; + +#pragma pack(1) +struct msurface2_t +{ + unsigned int flags; + //unsigned char vertCount; + //unsigned char sortGroup; + cplane_t* plane; + int firstvertindex; + WorldDecalHandle_t decals; + ShadowDecalHandle_t m_ShadowDecals; + OverlayFragmentHandle_t m_nFirstOverlayFragment; + short materialSortID; + unsigned short vertBufferIndex; + unsigned short m_bDynamicShadowsEnabled : 1; + unsigned short texinfo : 15; + IDispInfo* pDispInfo; + int visframe; + byte pad[24]; +}; +#pragma pack() +typedef msurface2_t* SurfaceHandle_t; + +struct msurfacelighting_t +{ + short m_LightmapMins[2]; + short m_LightmapExtents[2]; + short m_OffsetIntoLightmapPage[2]; + int m_nLastComputedFrame; + int m_fDLightBits; + int m_nDLightFrame; + unsigned char m_nStyles[MAXLIGHTMAPS]; + ColorRGBExp32* m_pSamples; +}; + +#pragma pack(1) +struct msurfacenormal_t +{ + unsigned int firstvertnormal; + //unsigned short firstvertnormal; + //short fogVolumeID; +}; +#pragma pack() + +struct mtexinfo_t +{ + Vector4D textureVecsTexelsPerWorldUnits[2]; + Vector4D lightmapVecsLuxelsPerWorldUnits[2]; + float luxelsPerWorldUnit; + float worldUnitsPerLuxel; + unsigned short flags; + unsigned short texinfoFlags; + IMaterial* material; +}; + +struct mprimitive_t +{ + int type; + unsigned short firstIndex; + unsigned short indexCount; + unsigned short firstVert; + unsigned short vertCount; +}; + +struct mprimvert_t +{ + Vector pos; + float texCoord[2]; + float lightCoord[2]; +}; + +struct mcubemapsample_t +{ + Vector origin; + ITexture* pTexture; + unsigned char size; +}; + +struct cleaf_t +{ + int contents; + short cluster; + short area : 9; + short flags : 7; + unsigned short firstleafbrush; + unsigned short numleafbrushes; + unsigned short dispListStart; + unsigned short dispCount; +}; + +struct carea_t +{ + int numareaportals; + int firstareaportal; + int floodnum; + int floodvalid; +}; + +struct cplane_t +{ + Vector normal{}; + float dist{}; + byte type{}; + byte signbits{}; + byte pad[2]{}; }; struct csurface_t { const char* name; short surfaceProps; - unsigned short flags; + unsigned short flags; }; -class __declspec(align(16))VectorAligned : public Vec3 +struct cnode_t { -public: - inline VectorAligned(void) { }; - - inline VectorAligned(float x, float y, float z) { - Set(x, y, z); - } - - explicit VectorAligned(const Vec3& othr) { - Set(othr.x, othr.y, othr.z); - } - - VectorAligned& operator=(const Vec3& othr) { - Set(othr.x, othr.y, othr.z); - return *this; - } - - float w = 0.0f; + cplane_t* plane; + int children[2]; }; -struct Ray_t +struct cbrush_t { - VectorAligned m_Start{}; - VectorAligned m_Delta{}; - VectorAligned m_StartOffset{}; - VectorAligned m_Extents{}; - bool m_IsRay{}; - bool m_IsSwept{}; + int contents; + unsigned short numsides; + unsigned short firstbrushside; - void Init(Vector const& start, Vector const& end) + inline int GetBox() const { return firstbrushside; } + inline void SetBox(int boxID) { - m_Delta = end - start; - m_IsSwept = m_Delta.LengthSqr() != 0; - m_Extents.Set(); - m_IsRay = true; - m_StartOffset.Set(); - m_Start = start; + numsides = NUMSIDES_BOXBRUSH; + firstbrushside = boxID; } + inline bool IsBox() const { return numsides == NUMSIDES_BOXBRUSH ? true : false; } +}; - void Init(Vector const& start, Vector const& end, Vector const& mins, Vector const& maxs) - { - m_Delta = end - start; - m_IsSwept = m_Delta.LengthSqr() != 0; - m_Extents = maxs - mins; - m_Extents *= 0.5f; - m_IsRay = m_Extents.LengthSqr() == 0; - m_StartOffset = mins + maxs; - m_StartOffset *= 0.5f; - m_Start = start + m_StartOffset; - m_StartOffset *= -1.0f; - } +struct cboxbrush_t +{ + VectorAligned mins; + VectorAligned maxs; + unsigned short surfaceIndex[6]; + unsigned short pad2[2]; +}; - Vector InvDelta() const +struct cbrushside_t +{ + cplane_t* plane; + unsigned short surfaceIndex; + unsigned short bBevel; +}; + +struct cmodel_t +{ + Vector mins, maxs; + Vector origin; + int headnode; + vcollide_t vcollisionData; +}; + +struct worldbrushdata_t +{ + int numsubmodels; + int numplanes; + cplane_t* planes; + int numleafs; + mleaf_t* leafs; + int numleafwaterdata; + mleafwaterdata_t* leafwaterdata; + int numvertexes; + mvertex_t* vertexes; + int numoccluders; + doccluderdata_t* occluders; + int numoccluderpolys; + doccluderpolydata_t* occluderpolys; + int numoccludervertindices; + int* occludervertindices; + int numvertnormalindices; + unsigned short* vertnormalindices; + int numvertnormals; + Vector* vertnormals; + int numnodes; + mnode_t* nodes; + unsigned short* m_LeafMinDistToWater; + int numtexinfo; + mtexinfo_t* texinfo; + int numtexdata; + csurface_t* texdata; + int numDispInfos; + HDISPINFOARRAY hDispInfos; + //int numOrigSurfaces; + //msurface_t *pOrigSurfaces; + int numsurfaces; + msurface1_t* surfaces1; + msurface2_t* surfaces2; + msurfacelighting_t* surfacelighting; + msurfacenormal_t* surfacenormals; + bool unloadedlightmaps; + int numvertindices; + unsigned short* vertindices; + int nummarksurfaces; + SurfaceHandle_t* marksurfaces; + ColorRGBExp32* lightdata; + int numworldlights; + dworldlight_t* worldlights; + lightzbuffer_t* shadowzbuffers; + int numprimitives; + mprimitive_t* primitives; + int numprimverts; + mprimvert_t* primverts; + int numprimindices; + unsigned short* primindices; + int m_nAreas; + darea_t* m_pAreas; + int m_nAreaPortals; + dareaportal_t* m_pAreaPortals; + int m_nClipPortalVerts; + Vector* m_pClipPortalVerts; + mcubemapsample_t* m_pCubemapSamples; + int m_nCubemapSamples; + int m_nDispInfoReferences; + unsigned short* m_pDispInfoReferences; + mleafambientindex_t* m_pLeafAmbient; + mleafambientlighting_t* m_pAmbientSamples; +#if 0 + int numportals; + mportal_t* portals; + int numclusters; + mcluster_t* clusters; + int numportalverts; + unsigned short* portalverts; + int numclusterportals; + unsigned short* clusterportals; +#endif +}; + +struct brushdata_t +{ + worldbrushdata_t* pShared; + int firstmodelsurface, nummodelsurfaces; + unsigned short renderHandle; + unsigned short firstnode; +}; + +struct spritedata_t +{ + int numframes; + int width; + int height; + CEngineSprite* sprite; +}; + +struct model_t +{ + FileNameHandle_t fnHandle; + CUtlString strName; + int nLoadFlags; + int nServerCount; + IMaterial** ppMaterials; + modtype_t type; + int flags; + Vector mins, maxs; + float radius; + union { - Vector vecInvDelta; - for (int iAxis = 0; iAxis < 3; ++iAxis) - { - if (m_Delta[iAxis] != 0.0f) - { - vecInvDelta[iAxis] = 1.0f / m_Delta[iAxis]; - } - else - { - vecInvDelta[iAxis] = 3.402823e+38f; - } - } - return vecInvDelta; - } + brushdata_t brush; + MDLHandle_t studio; + spritedata_t sprite; + }; }; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/CMultiPlayerAnimState.h b/Amalgam/src/SDK/Definitions/Main/CMultiPlayerAnimState.h index 8921e308..122f5c5f 100644 --- a/Amalgam/src/SDK/Definitions/Main/CMultiPlayerAnimState.h +++ b/Amalgam/src/SDK/Definitions/Main/CMultiPlayerAnimState.h @@ -1,8 +1,14 @@ #pragma once -#include "CBasePlayer.h" +#include "CBaseHandle.h" #include "../Misc/Activity.h" +#include "../Misc/CUtlVector.h" #include "../Misc/CRangeCheckedVar.h" #include "../Misc/CInterpolatedVar.h" +#include "../Types.h" + +class CBaseEntity; +class CBasePlayer; +class CStudioHdr; class CAnimationLayer { diff --git a/Amalgam/src/SDK/Definitions/Main/CParticleProperty.h b/Amalgam/src/SDK/Definitions/Main/CParticleProperty.h index 60596d82..6ed4dca3 100644 --- a/Amalgam/src/SDK/Definitions/Main/CParticleProperty.h +++ b/Amalgam/src/SDK/Definitions/Main/CParticleProperty.h @@ -1,5 +1,5 @@ #pragma once -#include "UtlVector.h" +#include "../Misc/CUtlVector.h" class CBaseEntity; struct ParticleEffectList_t; diff --git a/Amalgam/src/SDK/Definitions/Main/CPlayerResource.h b/Amalgam/src/SDK/Definitions/Main/CPlayerResource.h index f2ade70f..26aabe70 100644 --- a/Amalgam/src/SDK/Definitions/Main/CPlayerResource.h +++ b/Amalgam/src/SDK/Definitions/Main/CPlayerResource.h @@ -1,7 +1,6 @@ #pragma once #include "CBaseEntity.h" #include "../Misc/IGameResources.h" -#include "../Misc/String.h" #define PLAYER_UNCONNECTED_NAME "unconnected" #define PLAYER_ERROR_NAME "ERRORNAME" diff --git a/Amalgam/src/SDK/Definitions/Main/CPredictionCopy.h b/Amalgam/src/SDK/Definitions/Main/CPredictionCopy.h index 17a34c94..3d0b1f14 100644 --- a/Amalgam/src/SDK/Definitions/Main/CPredictionCopy.h +++ b/Amalgam/src/SDK/Definitions/Main/CPredictionCopy.h @@ -2,6 +2,9 @@ #include "../Misc/Datamap.h" #include "../../../Utils/Signatures/Signatures.h" +#pragma warning (push) +#pragma warning (disable : 26495) + MAKE_SIGNATURE(CPredictionCopy_TransferData, "client.dll", "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 8B 3D", 0x0); #define PC_DATA_PACKED true @@ -78,4 +81,6 @@ public: typedescription_t* m_pWatchField; char const* m_pOperation; -}; \ No newline at end of file +}; + +#pragma warning (pop) \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/CStaticProp.h b/Amalgam/src/SDK/Definitions/Main/CStaticProp.h new file mode 100644 index 00000000..0ada7e03 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Main/CStaticProp.h @@ -0,0 +1,108 @@ +#pragma once +#include "IClientUnknown.h" +#include "IClientRenderable.h" +#include "ICollideable.h" +#include "CBaseHandle.h" + +typedef unsigned short SpatialPartitionHandle_t; + +class CStaticProp : public IClientUnknown, public IClientRenderable, public ICollideable +{ +public: + virtual void SetRefEHandle(const CBaseHandle& handle) = 0; + virtual const CBaseHandle& GetRefEHandle() const = 0; + virtual IClientUnknown* GetIClientUnknown() = 0; + virtual ICollideable* GetCollideable() = 0; + virtual IClientNetworkable* GetClientNetworkable() = 0; + virtual IClientRenderable* GetClientRenderable() = 0; + virtual IClientEntity* GetIClientEntity() = 0; + virtual CBaseEntity* GetBaseEntity() = 0; + virtual IClientThinkable* GetClientThinkable() = 0; + virtual const Vector& OBBMinsPreScaled() const = 0; + virtual const Vector& OBBMaxsPreScaled() const = 0; + virtual const Vector& OBBMins() const = 0; + virtual const Vector& OBBMaxs() const = 0; + virtual bool TestCollision(const Ray_t& ray, unsigned int fContentsMask, trace_t& tr) = 0; + virtual bool TestHitboxes(const Ray_t& ray, unsigned int fContentsMask, trace_t& tr) = 0; + virtual int GetCollisionModelIndex() = 0; + virtual const model_t* GetCollisionModel() = 0; + virtual const Vector& GetCollisionOrigin() const = 0; + virtual const QAngle& GetCollisionAngles() const = 0; + virtual const matrix3x4& CollisionToWorldTransform() const = 0; + virtual SolidType_t GetSolid() const = 0; + virtual int GetSolidFlags() const = 0; + virtual IHandleEntity* GetEntityHandle() = 0; + virtual int GetCollisionGroup() const = 0; + virtual void WorldSpaceTriggerBounds(Vector* pVecWorldMins, Vector* pVecWorldMaxs) const = 0; + virtual void WorldSpaceSurroundingBounds(Vector* pVecWorldMins, Vector* pVecWorldMaxs) = 0; + virtual bool ShouldTouchTrigger(int triggerSolidFlags) const = 0; + virtual const matrix3x4* GetRootParentToWorldTransform() const = 0; + virtual int GetBody() = 0; + virtual int GetSkin() = 0; + virtual const Vector& GetRenderOrigin() = 0; + virtual const QAngle& GetRenderAngles() = 0; + virtual bool ShouldDraw() = 0; + virtual bool IsTransparent(void) = 0; + virtual bool IsTwoPass(void) = 0; + virtual void OnThreadedDrawSetup() = 0; + virtual const model_t* GetModel() = 0; + virtual int DrawModel(int flags) = 0; + virtual void ComputeFxBlend() = 0; + virtual int GetFxBlend() = 0; + virtual void GetColorModulation(float* color) = 0; + virtual bool LODTest() = 0; + virtual bool SetupBones(matrix3x4* pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime) = 0; + virtual void SetupWeights(const matrix3x4* pBoneToWorld, int nFlexWeightCount, float* pFlexWeights, float* pFlexDelayedWeights) = 0; + virtual bool UsesFlexDelayedWeights() = 0; + virtual void DoAnimationEvents(void) = 0; + virtual IPVSNotify* GetPVSNotifyInterface() = 0; + virtual void GetRenderBounds(Vector& mins, Vector& maxs) = 0; + virtual void GetRenderBoundsWorldspace(Vector& mins, Vector& maxs) = 0; + virtual bool ShouldCacheRenderInfo() = 0; + virtual bool ShouldReceiveProjectedTextures(int flags) = 0; + virtual bool GetShadowCastDistance(float* pDist, ShadowType_t shadowType) const = 0; + virtual bool GetShadowCastDirection(Vector* pDirection, ShadowType_t shadowType) const = 0; + virtual bool UsesPowerOfTwoFrameBufferTexture() = 0; + virtual bool UsesFullFrameBufferTexture() = 0; + virtual ClientShadowHandle_t GetShadowHandle() = 0; + virtual ClientRenderHandle_t& RenderHandle() = 0; + virtual void RecordToolMessage() = 0; + virtual void GetShadowRenderBounds(Vector& mins, Vector& maxs, ShadowType_t shadowType) = 0; + virtual bool IsShadowDirty() = 0; + virtual void MarkShadowDirty(bool bDirty) = 0; + virtual IClientRenderable* GetShadowParent() = 0; + virtual IClientRenderable* FirstShadowChild() = 0; + virtual IClientRenderable* NextShadowPeer() = 0; + virtual ShadowType_t ShadowCastType() = 0; + virtual void CreateModelInstance() = 0; + virtual ModelInstanceHandle_t GetModelInstance() = 0; + virtual int LookupAttachment(const char* pAttachmentName) = 0; + virtual bool GetAttachment(int number, Vector& origin, QAngle& angles) = 0; + virtual bool GetAttachment(int number, matrix3x4& matrix) = 0; + virtual bool IgnoresZBuffer(void) const = 0; + virtual float* GetRenderClipPlane(void) = 0; + virtual const matrix3x4& RenderableToWorldTransform() = 0; + + Vector m_Origin; + QAngle m_Angles; + model_t* m_pModel; + SpatialPartitionHandle_t m_Partition; + ModelInstanceHandle_t m_ModelInstance; + unsigned char m_Alpha; + unsigned char m_nSolidType; + unsigned char m_Skin; + unsigned char m_Flags; + unsigned short m_FirstLeaf; + unsigned short m_LeafCount; + CBaseHandle m_EntHandle; + ClientRenderHandle_t m_RenderHandle; + unsigned short m_FadeIndex; + float m_flForcedFadeScale; + Vector m_RenderBBoxMin; + Vector m_RenderBBoxMax; + matrix3x4 m_ModelToWorld; + float m_flRadius; + Vector m_WorldRenderBBoxMin; + Vector m_WorldRenderBBoxMax; + Vector m_LightingOrigin; +}; diff --git a/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.cpp b/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.cpp index 87e3447b..30879a81 100644 --- a/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.cpp +++ b/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.cpp @@ -202,28 +202,28 @@ int CTFSniperRifle::GetRifleType() float CTFSniperRifle::GetHeadshotMult(CTFPlayer* pTarget) { - auto GetMainMult = [&]() - { - auto pOwner = m_hOwnerEntity()->As(); - if (pOwner && pOwner->IsCritBoosted()) - return 3.f; - - if (GetRifleType() == RIFLE_JARATE) - { - if (SDK::AttribHookValue(0, "jarate_duration", this) > 0) - return 1.36f; - - if (pOwner && pOwner->IsMiniCritBoosted() - || pTarget && (pTarget->InCond(TF_COND_URINE) || pTarget->InCond(TF_COND_MARKEDFORDEATH))) - return 1.36f; - - return 1.f; - } - + auto fGetMainMult = [&]() + { + auto pOwner = m_hOwnerEntity()->As(); + if (pOwner && pOwner->IsCritBoosted()) return 3.f; - }; - float flMult = SDK::AttribHookValue(GetMainMult(), "mult_dmg", this); + if (GetRifleType() == RIFLE_JARATE) + { + if (SDK::AttribHookValue(0, "jarate_duration", this) > 0) + return 1.36f; + + if (pOwner && pOwner->IsMiniCritBoosted() + || pTarget && (pTarget->InCond(TF_COND_URINE) || pTarget->InCond(TF_COND_MARKEDFORDEATH))) + return 1.36f; + + return 1.f; + } + + return 3.f; + }; + + float flMult = SDK::AttribHookValue(fGetMainMult(), "mult_dmg", this); if (m_flChargedDamage() == 150.f) flMult = SDK::AttribHookValue(flMult, "sniper_full_charge_damage_bonus", this); return flMult; @@ -231,20 +231,20 @@ float CTFSniperRifle::GetHeadshotMult(CTFPlayer* pTarget) float CTFSniperRifle::GetBodyshotMult(CTFPlayer* pTarget) { - auto GetMainMult = [&]() - { - auto pOwner = m_hOwnerEntity()->As(); - if (pOwner && pOwner->IsCritBoosted()) - return 3.f; + auto fGetMainMult = [&]() + { + auto pOwner = m_hOwnerEntity()->As(); + if (pOwner && pOwner->IsCritBoosted()) + return 3.f; - if (pOwner && pOwner->IsMiniCritBoosted() - || pTarget && (pTarget->InCond(TF_COND_URINE) || pTarget->InCond(TF_COND_MARKEDFORDEATH))) - return 1.36f; + if (pOwner && pOwner->IsMiniCritBoosted() + || pTarget && (pTarget->InCond(TF_COND_URINE) || pTarget->InCond(TF_COND_MARKEDFORDEATH))) + return 1.36f; - return 1.f; - }; + return 1.f; + }; - float flMult = SDK::AttribHookValue(GetMainMult(), "mult_dmg", this); + float flMult = SDK::AttribHookValue(fGetMainMult(), "mult_dmg", this); flMult = SDK::AttribHookValue(flMult, "bodyshot_damage_modify", this); if (m_flChargedDamage() == 150.f) flMult = SDK::AttribHookValue(flMult, "sniper_full_charge_damage_bonus", this); diff --git a/Amalgam/src/SDK/Definitions/Main/IAchievementMgr.h b/Amalgam/src/SDK/Definitions/Main/IAchievementMgr.h index 29338da1..31a898af 100644 --- a/Amalgam/src/SDK/Definitions/Main/IAchievementMgr.h +++ b/Amalgam/src/SDK/Definitions/Main/IAchievementMgr.h @@ -1,8 +1,7 @@ +#pragma once + #ifndef IACHIEVEMENTMGR_H #define IACHIEVEMENTMGR_H -#ifdef _WIN32 -#pragma once -#endif class CBaseAchievement; diff --git a/Amalgam/src/SDK/Definitions/Main/IClientNetworkable.h b/Amalgam/src/SDK/Definitions/Main/IClientNetworkable.h index 525880cf..3f3e91b1 100644 --- a/Amalgam/src/SDK/Definitions/Main/IClientNetworkable.h +++ b/Amalgam/src/SDK/Definitions/Main/IClientNetworkable.h @@ -1,11 +1,9 @@ #pragma once #include "IClientUnknown.h" -#include "../Misc/bitbuf.h" #include "../Misc/ClientClass.h" +#include "../Misc/bitbuf.h" #include "../Definitions.h" -class IClientEntity; - enum ShouldTransmitState_t { SHOULDTRANSMIT_START = 0, diff --git a/Amalgam/src/SDK/Definitions/Main/IClientRenderable.h b/Amalgam/src/SDK/Definitions/Main/IClientRenderable.h index 6f05507d..4ace44c4 100644 --- a/Amalgam/src/SDK/Definitions/Main/IClientRenderable.h +++ b/Amalgam/src/SDK/Definitions/Main/IClientRenderable.h @@ -42,9 +42,9 @@ public: virtual ClientRenderHandle_t& RenderHandle() = 0; virtual const model_t* GetModel() const = 0; virtual int DrawModel(int flags) = 0; - virtual int GetBody() = 0; + virtual int GetBody() = 0; virtual void ComputeFxBlend() = 0; - virtual int GetFxBlend(void) = 0; + virtual int GetFxBlend(void) = 0; virtual void GetColorModulation(float* color) = 0; virtual bool LODTest() = 0; virtual bool SetupBones(matrix3x4* pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime) = 0; @@ -67,7 +67,7 @@ public: virtual ModelInstanceHandle_t GetModelInstance() = 0; virtual const matrix3x4& RenderableToWorldTransform() = 0; virtual int LookupAttachment(const char* pAttachmentName) = 0; - virtual bool GetAttachment(int number, Vector& origin, QAngle& angles) = 0; + virtual bool GetAttachment(int number, Vector& origin, QAngle& angles) = 0; virtual bool GetAttachment(int number, matrix3x4& matrix) = 0; virtual float* GetRenderClipPlane(void) = 0; virtual int GetSkin() = 0; diff --git a/Amalgam/src/SDK/Definitions/Main/ICollideable.h b/Amalgam/src/SDK/Definitions/Main/ICollideable.h new file mode 100644 index 00000000..7892d1c5 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Main/ICollideable.h @@ -0,0 +1,37 @@ +#pragma once +#include "CGameTrace.h" +#include "../Definitions.h" + +class IHandleEntity; +class IClientUnknown; +struct model_t; + +class ICollideable +{ +public: + virtual IHandleEntity* GetEntityHandle() = 0; + virtual const Vector& OBBMinsPreScaled() const = 0; + virtual const Vector& OBBMaxsPreScaled() const = 0; + virtual const Vector& OBBMins() const = 0; + virtual const Vector& OBBMaxs() const = 0; + virtual void WorldSpaceTriggerBounds(Vector* pVecWorldMins, Vector* pVecWorldMaxs) const = 0; + virtual bool TestCollision(const Ray_t& ray, unsigned int fContentsMask, trace_t& tr) = 0; + virtual bool TestHitboxes(const Ray_t& ray, unsigned int fContentsMask, trace_t& tr) = 0; + virtual int GetCollisionModelIndex() = 0; + virtual const model_t* GetCollisionModel() = 0; + virtual const Vector& GetCollisionOrigin() const = 0; + virtual const QAngle& GetCollisionAngles() const = 0; + virtual const matrix3x4& CollisionToWorldTransform() const = 0; + virtual SolidType_t GetSolid() const = 0; + virtual int GetSolidFlags() const = 0; + virtual IClientUnknown* GetIClientUnknown() = 0; + virtual int GetCollisionGroup() const = 0; + virtual void WorldSpaceSurroundingBounds(Vector* pVecMins, Vector* pVecMaxs) = 0; + virtual bool ShouldTouchTrigger(int triggerSolidFlags) const = 0; + virtual const matrix3x4* GetRootParentToWorldTransform() const = 0; + + inline bool IsSolid() + { + return GetSolid() != SOLID_NONE && !(GetSolidFlags() & FSOLID_NOT_SOLID); + } +}; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/IDispInfo.h b/Amalgam/src/SDK/Definitions/Main/IDispInfo.h new file mode 100644 index 00000000..9057cc46 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Main/IDispInfo.h @@ -0,0 +1,50 @@ +#pragma once +#include "../Main/CModel.h" + +class SurfInfo; +struct decal_t; +typedef unsigned short DispDecalHandle_t; +typedef unsigned short DispShadowHandle_t; +typedef unsigned short ShadowHandle_t; + +class GetIntersectingSurfaces_Struct +{ +public: + model_t* m_pModel; + const Vector* m_pCenter; + const byte* m_pCenterPVS; + float m_Radius; + bool m_bOnlyVisible; + SurfInfo* m_pInfos; + int m_nMaxInfos; + int m_nSetInfos; +}; + +struct RayDispOutput_t +{ + short ndxVerts[4]; + float u, v; + float dist; +}; + +class IDispInfo +{ +public: + virtual ~IDispInfo() = 0; + virtual void GetIntersectingSurfaces(GetIntersectingSurfaces_Struct* pStruct) = 0; + virtual void RenderWireframeInLightmapPage(int pageId) = 0; + virtual void GetBoundingBox(Vector& bbMin, Vector& bbMax) = 0; + virtual void SetParent(SurfaceHandle_t surfID) = 0; + virtual SurfaceHandle_t GetParent() = 0; + virtual void AddDynamicLights(struct dlight_t* pLights, unsigned int lightMask) = 0; + virtual unsigned int ComputeDynamicLightMask(struct dlight_t* pLights) = 0; + virtual DispDecalHandle_t NotifyAddDecal(decal_t* pDecal, float flSize) = 0; + virtual void NotifyRemoveDecal(DispDecalHandle_t h) = 0; + virtual DispShadowHandle_t AddShadowDecal(ShadowHandle_t shadowHandle) = 0; + virtual void RemoveShadowDecal(DispShadowHandle_t handle) = 0; + virtual bool ComputeShadowFragments(DispShadowHandle_t h, int& vertexCount, int& indexCount) = 0; + virtual bool GetTag() = 0; + virtual void SetTag() = 0; + virtual bool TestRay(Ray_t const& ray, float start, float end, float& dist, Vector2D* lightmapUV, Vector2D* textureUV) = 0; + virtual void ComputeLightmapAndTextureCoordinate(RayDispOutput_t const& uv, Vector2D* luv, Vector2D* tuv) = 0; +}; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/IMaterial.h b/Amalgam/src/SDK/Definitions/Main/IMaterial.h index ef80f4aa..297452ca 100644 --- a/Amalgam/src/SDK/Definitions/Main/IMaterial.h +++ b/Amalgam/src/SDK/Definitions/Main/IMaterial.h @@ -1,9 +1,4 @@ #pragma once -#include "../Interfaces/IMaterialSystem.h" - -class IMaterialVar; -class ITexture; -class IMaterialProxy; #define VERTEX_POSITION 0x0001 #define VERTEX_NORMAL 0x0002 @@ -25,11 +20,15 @@ class IMaterialProxy; #define USER_DATA_SIZE_MASK ( 0x7 << USER_DATA_SIZE_BIT ) #define VERTEX_FORMAT_FIELD_MASK 0x0FF #define VERTEX_FORMAT_UNKNOWN 0 - #define VERTEX_BONEWEIGHT( _n ) ((_n) << VERTEX_BONE_WEIGHT_BIT) #define VERTEX_USERDATA_SIZE( _n ) ((_n) << USER_DATA_SIZE_BIT) #define VERTEX_TEXCOORD_MASK( _coord ) (( 0x7ULL ) << ( TEX_COORD_SIZE_BIT + 3 * (_coord) )) +class IMaterialVar; +class ITexture; +class IMaterialProxy; +typedef unsigned int MorphFormat_t; + enum VertexElement_t { VERTEX_ELEMENT_NONE = -1, diff --git a/Amalgam/src/SDK/Definitions/Main/INetChannel.h b/Amalgam/src/SDK/Definitions/Main/INetChannel.h index 3c3dfa83..5db41f49 100644 --- a/Amalgam/src/SDK/Definitions/Main/INetChannel.h +++ b/Amalgam/src/SDK/Definitions/Main/INetChannel.h @@ -1,5 +1,6 @@ #pragma once #include "NetChannel.h" +#include "INetworkSystem.h" #include "INetChannelInfo.h" #include "INetMessage.h" @@ -60,8 +61,8 @@ public: class CNetChannel : public INetChannel { public: - virtual ConnectionStatus_t GetConnectionState(); - virtual const netadr_t& GetRemoteAddress(void) const; + virtual ConnectionStatus_t GetConnectionState() = 0; + virtual const netadr_t& GetRemoteAddress(void) const = 0; ConnectionStatus_t m_ConnectionState; int m_nOutSequenceNr; diff --git a/Amalgam/src/SDK/Definitions/Main/INetMessage.h b/Amalgam/src/SDK/Definitions/Main/INetMessage.h index adde4f32..f374809e 100644 --- a/Amalgam/src/SDK/Definitions/Main/INetMessage.h +++ b/Amalgam/src/SDK/Definitions/Main/INetMessage.h @@ -1,6 +1,6 @@ #pragma once #include "../Misc/bitbuf.h" -#include "../Main/UtlVector.h" +#include "../Misc/CUtlVector.h" #include "../Types.h" #define MAX_OSPATH 260 // max length of a filesystem pathname diff --git a/Amalgam/src/SDK/Definitions/Main/INetworkMessage.h b/Amalgam/src/SDK/Definitions/Main/INetworkMessage.h index 9b7ecdfb..4cb84e47 100644 --- a/Amalgam/src/SDK/Definitions/Main/INetworkMessage.h +++ b/Amalgam/src/SDK/Definitions/Main/INetworkMessage.h @@ -1,5 +1,4 @@ #pragma once -#include "INetMessage.h" class INetChannel; diff --git a/Amalgam/src/SDK/Definitions/Main/INetworkSystem.h b/Amalgam/src/SDK/Definitions/Main/INetworkSystem.h index ea48d924..20577146 100644 --- a/Amalgam/src/SDK/Definitions/Main/INetworkSystem.h +++ b/Amalgam/src/SDK/Definitions/Main/INetworkSystem.h @@ -1,7 +1,6 @@ #pragma once #include "INetworkMessage.h" #include "../Misc/IAppSystem.h" -#include "../Misc/NetAdr.h" enum { diff --git a/Amalgam/src/SDK/Definitions/Main/MD5.cpp b/Amalgam/src/SDK/Definitions/Main/MD5.cpp index 8839acb4..30fe168d 100644 --- a/Amalgam/src/SDK/Definitions/Main/MD5.cpp +++ b/Amalgam/src/SDK/Definitions/Main/MD5.cpp @@ -1,4 +1,5 @@ #include "MD5.h" + #include #define F1(x, y, z) (z ^ (x & (y ^ z))) diff --git a/Amalgam/src/SDK/Definitions/Main/NetChannel.h b/Amalgam/src/SDK/Definitions/Main/NetChannel.h index 51eea1c9..0aaa4843 100644 --- a/Amalgam/src/SDK/Definitions/Main/NetChannel.h +++ b/Amalgam/src/SDK/Definitions/Main/NetChannel.h @@ -1,8 +1,5 @@ #pragma once -#include "INetworkSystem.h" -#include "UtlVector.h" -#include "../Misc/bitbuf.h" -#include "../Misc/BaseTypes.h" +#include "../Misc/NetAdr.h" enum { diff --git a/Amalgam/src/SDK/Definitions/Main/PlayerStats.h b/Amalgam/src/SDK/Definitions/Main/PlayerStats.h index a56e43ef..217d5bf3 100644 --- a/Amalgam/src/SDK/Definitions/Main/PlayerStats.h +++ b/Amalgam/src/SDK/Definitions/Main/PlayerStats.h @@ -1,6 +1,6 @@ #pragma once -#include "../Definitions.h" #include "../Misc/BaseTypes.h" +#include "../Definitions.h" #ifndef ARRAYSIZE #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) diff --git a/Amalgam/src/SDK/Definitions/Main/Ray.h b/Amalgam/src/SDK/Definitions/Main/Ray.h new file mode 100644 index 00000000..3b9d1c3e --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Main/Ray.h @@ -0,0 +1,76 @@ +#pragma once +#include "../Types.h" + +class __declspec(align(16))VectorAligned : public Vec3 +{ +public: + inline VectorAligned(void) {}; + + inline VectorAligned(float x, float y, float z) + { + Set(x, y, z); + } + + explicit VectorAligned(const Vec3& othr) + { + Set(othr.x, othr.y, othr.z); + } + + VectorAligned& operator=(const Vec3& othr) + { + Set(othr.x, othr.y, othr.z); + return *this; + } + + float w = 0.0f; +}; + +struct Ray_t +{ + VectorAligned m_Start{}; + VectorAligned m_Delta{}; + VectorAligned m_StartOffset{}; + VectorAligned m_Extents{}; + bool m_IsRay{}; + bool m_IsSwept{}; + + void Init(Vector const& start, Vector const& end) + { + m_Delta = end - start; + m_IsSwept = m_Delta.LengthSqr() != 0; + m_Extents.Set(); + m_IsRay = true; + m_StartOffset.Set(); + m_Start = start; + } + + void Init(Vector const& start, Vector const& end, Vector const& mins, Vector const& maxs) + { + m_Delta = end - start; + m_IsSwept = m_Delta.LengthSqr() != 0; + m_Extents = maxs - mins; + m_Extents *= 0.5f; + m_IsRay = m_Extents.LengthSqr() == 0; + m_StartOffset = mins + maxs; + m_StartOffset *= 0.5f; + m_Start = start + m_StartOffset; + m_StartOffset *= -1.0f; + } + + Vector InvDelta() const + { + Vector vecInvDelta; + for (int iAxis = 0; iAxis < 3; ++iAxis) + { + if (m_Delta[iAxis] != 0.0f) + { + vecInvDelta[iAxis] = 1.0f / m_Delta[iAxis]; + } + else + { + vecInvDelta[iAxis] = 3.402823e+38f; + } + } + return vecInvDelta; + } +}; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/UtlVector.h b/Amalgam/src/SDK/Definitions/Main/UtlVector.h deleted file mode 100644 index b7825104..00000000 --- a/Amalgam/src/SDK/Definitions/Main/UtlVector.h +++ /dev/null @@ -1,752 +0,0 @@ -#pragma once -#include -#include - -#pragma warning (push) -#pragma warning (disable : 4100) -#pragma warning (disable : 4514) -#pragma warning (disable : 26495) - -template -inline void Construct(T* pMemory) { - ::new(pMemory) T; -} - -template -inline void CopyConstruct(T* pMemory, T const& src) { - ::new(pMemory) T(src); -} - -template -inline void Destruct(T* pMemory) { - pMemory->~T(); -} - -//----------------------------------------------------------------------------- -// The CUtlMemory class: -// A growable memory class which doubles in size by default. -//----------------------------------------------------------------------------- -template< class T > -class CUtlMemory { -public: - // constructor, destructor - CUtlMemory(int nGrowSize = 0, int nInitSize = 0); - CUtlMemory(T* pMemory, int numElements); - ~CUtlMemory(); - - // element access - T& operator[](int i); - T const& operator[](int i) const; - T& Element(int i); - T const& Element(int i) const; - - // Can we use this index? - bool IsIdxValid(int i) const; - - // Gets the base address (can change when adding elements!) - T* Base(); - T const* Base() const; - - // Attaches the buffer to external memory.... - void SetExternalBuffer(T* pMemory, int numElements); - - // Size - int NumAllocated() const; - int Count() const; - - // Grows the memory, so that at least allocated + num elements are allocated - void Grow(int num = 1); - - // Memory deallocation - void Purge(); - - // is the memory externally allocated? - bool IsExternallyAllocated() const; - - // Set the size by which the memory grows - void SetGrowSize(int size); - -private: - enum { - EXTERNAL_BUFFER_MARKER = -1, - }; - - T* m_pMemory; - int m_nAllocationCount; - int m_nGrowSize; -}; - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- -template< class T > -CUtlMemory::CUtlMemory(int nGrowSize, int nInitAllocationCount) : m_pMemory(0), -m_nAllocationCount(nInitAllocationCount), m_nGrowSize(nGrowSize) { - //Assert((nGrowSize >= 0) && (nGrowSize != EXTERNAL_BUFFER_MARKER)); - if (m_nAllocationCount) { - m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T)); - } -} - -template< class T > -CUtlMemory::CUtlMemory(T* pMemory, int numElements) : m_pMemory(pMemory), -m_nAllocationCount(numElements) { - // Special marker indicating externally supplied memory - m_nGrowSize = EXTERNAL_BUFFER_MARKER; -} - -template< class T > -CUtlMemory::~CUtlMemory() { - Purge(); -} - - -//----------------------------------------------------------------------------- -// Attaches the buffer to external memory.... -//----------------------------------------------------------------------------- -template< class T > -void CUtlMemory::SetExternalBuffer(T* pMemory, int numElements) { - // Blow away any existing allocated memory - Purge(); - - m_pMemory = pMemory; - m_nAllocationCount = numElements; - - // Indicate that we don't own the memory - m_nGrowSize = EXTERNAL_BUFFER_MARKER; -} - - -//----------------------------------------------------------------------------- -// element access -//----------------------------------------------------------------------------- -template< class T > -inline T& CUtlMemory::operator[](int i) { - //Assert(IsIdxValid(i)); - return m_pMemory[i]; -} - -template< class T > -inline T const& CUtlMemory::operator[](int i) const { - //Assert(IsIdxValid(i)); - return m_pMemory[i]; -} - -template< class T > -inline T& CUtlMemory::Element(int i) { - //Assert(IsIdxValid(i)); - return m_pMemory[i]; -} - -template< class T > -inline T const& CUtlMemory::Element(int i) const { - //Assert(IsIdxValid(i)); - return m_pMemory[i]; -} - - -//----------------------------------------------------------------------------- -// is the memory externally allocated? -//----------------------------------------------------------------------------- -template< class T > -bool CUtlMemory::IsExternallyAllocated() const { - return m_nGrowSize == EXTERNAL_BUFFER_MARKER; -} - - -template< class T > -void CUtlMemory::SetGrowSize(int nSize) { - //Assert((nSize >= 0) && (nSize != EXTERNAL_BUFFER_MARKER)); - m_nGrowSize = nSize; -} - - -//----------------------------------------------------------------------------- -// Gets the base address (can change when adding elements!) -//----------------------------------------------------------------------------- -template< class T > -inline T* CUtlMemory::Base() { - return m_pMemory; -} - -template< class T > -inline T const* CUtlMemory::Base() const { - return m_pMemory; -} - - -//----------------------------------------------------------------------------- -// Size -//----------------------------------------------------------------------------- -template< class T > -inline int CUtlMemory::NumAllocated() const { - return m_nAllocationCount; -} - -template< class T > -inline int CUtlMemory::Count() const { - return m_nAllocationCount; -} - - -//----------------------------------------------------------------------------- -// Is element index valid? -//----------------------------------------------------------------------------- -template< class T > -inline bool CUtlMemory::IsIdxValid(int i) const { - return (i >= 0) && (i < m_nAllocationCount); -} - -#pragma warning (push) -#pragma warning (disable : 6308) - -//----------------------------------------------------------------------------- -// Grows the memory -//----------------------------------------------------------------------------- -template< class T > -void CUtlMemory::Grow(int num) { - assert(num > 0); - - if (IsExternallyAllocated()) { - // Can't grow a buffer whose memory was externally allocated - assert(0); - return; - } - - // Make sure we have at least numallocated + num allocations. - // Use the grow rules specified for this memory (in m_nGrowSize) - int nAllocationRequested = m_nAllocationCount + num; - while (m_nAllocationCount < nAllocationRequested) { - if (m_nAllocationCount != 0) { - if (m_nGrowSize) { - m_nAllocationCount += m_nGrowSize; - } - else { - m_nAllocationCount += m_nAllocationCount; - } - } - else { - // Compute an allocation which is at least as big as a cache line... - m_nAllocationCount = (31 + sizeof(T)) / sizeof(T); - assert(m_nAllocationCount != 0); - } - } - - if (m_pMemory) { - m_pMemory = (T*)realloc(m_pMemory, m_nAllocationCount * sizeof(T)); - } - else { - m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T)); - } -} - -#pragma warning (pop) - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- -template< class T > -void CUtlMemory::Purge() { - if (!IsExternallyAllocated()) { - if (m_pMemory) { - free((void*)m_pMemory); - m_pMemory = 0; - } - m_nAllocationCount = 0; - } -} - -template -class CUtlVector { -public: - typedef T ElemType_t; - - // constructor, destructor - CUtlVector(int growSize = 0, int initSize = 0); - CUtlVector(T* pMemory, int numElements); - ~CUtlVector(); - - // Copy the array. - CUtlVector& operator=(const CUtlVector& other); - - // element access - T& operator[](int i); - T const& operator[](int i) const; - T& Element(int i); - T const& Element(int i) const; - - // Gets the base address (can change when adding elements!) - T* Base(); - T const* Base() const; - - // Returns the number of elements in the vector - // SIZE IS DEPRECATED! - int Count() const; - int Size() const; // don't use me! - - // Is element index valid? - bool IsValidIndex(int i) const; - static int InvalidIndex(void); - - // Adds an element, uses default constructor - int AddToHead(); - int AddToTail(); - int InsertBefore(int elem); - int InsertAfter(int elem); - - // Adds an element, uses copy constructor - int AddToHead(T const& src); - int AddToTail(T const& src); - int InsertBefore(int elem, T const& src); - int InsertAfter(int elem, T const& src); - - // Adds multiple elements, uses default constructor - int AddMultipleToHead(int num); - int AddMultipleToTail(int num, const T* pToCopy = NULL); - int InsertMultipleBefore(int elem, int num, const T* pToCopy = NULL); // If pToCopy is set, then it's an array of length 'num' and - int InsertMultipleAfter(int elem, int num); - - // Calls RemoveAll() then AddMultipleToTail. - void SetSize(int size); - void SetCount(int count); - - // Calls SetSize and copies each element. - void CopyArray(T const* pArray, int size); - - // Add the specified array to the tail. - int AddVectorToTail(CUtlVector const& src); - - // Finds an element (element needs operator== defined) - int Find(T const& src) const; - - bool HasElement(T const& src); - - // Makes sure we have at least this many elements - void EnsureCount(int num); - - // Element removal - void FastRemove(int elem); // doesn't preserve order - void Remove(int elem); // preserves order, shifts elements - void FindAndRemove(T const& src); // removes first occurrence of src, preserves order, shifts elements - void RemoveMultiple(int elem, int num); // preserves order, shifts elements - void RemoveAll(); // doesn't deallocate memory - - // Memory deallocation - void Purge(); - - // Purges the list and calls delete on each element in it. - void PurgeAndDeleteElements(); - - // Set the size by which it grows when it needs to allocate more memory. - void SetGrowSize(int size); - - // Can't copy this unless we explicitly do it! - CUtlVector(CUtlVector const& vec) { - assert(0); - } - -protected: - // Grows the vector - void GrowVector(int num = 1); - - // Shifts elements.... - void ShiftElementsRight(int elem, int num = 1); - void ShiftElementsLeft(int elem, int num = 1); - - // For easier access to the elements through the debugger - void ResetDbgInfo(); - - CUtlMemory m_Memory; - int m_Size; - - // For easier access to the elements through the debugger - // it's in release builds so this can be used in libraries correctly - T* m_pElements; -}; - -//----------------------------------------------------------------------------- -// For easier access to the elements through the debugger -//----------------------------------------------------------------------------- - -template< class T > -inline void CUtlVector::ResetDbgInfo() { - m_pElements = m_Memory.Base(); -} - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template< class T > -inline CUtlVector::CUtlVector(int growSize, int initSize) : - m_Memory(growSize, initSize), m_Size(0) { - ResetDbgInfo(); -} - -template< class T > -inline CUtlVector::CUtlVector(T* pMemory, int numElements) : - m_Memory(pMemory, numElements), m_Size(0) { - ResetDbgInfo(); -} - -template< class T > -inline CUtlVector::~CUtlVector() { - Purge(); -} - -template -inline CUtlVector& CUtlVector::operator=(const CUtlVector& other) { - CopyArray(other.Base(), other.Count()); - return *this; -} - -//----------------------------------------------------------------------------- -// element access -//----------------------------------------------------------------------------- - -template< class T > -inline T& CUtlVector::operator[](int i) { - assert(IsValidIndex(i)); - return m_Memory[i]; -} - -template< class T > -inline T const& CUtlVector::operator[](int i) const { - assert(IsValidIndex(i)); - return m_Memory[i]; -} - -template< class T > -inline T& CUtlVector::Element(int i) { - assert(IsValidIndex(i)); - return m_Memory[i]; -} - -template< class T > -inline T const& CUtlVector::Element(int i) const { - assert(IsValidIndex(i)); - return m_Memory[i]; -} - -//----------------------------------------------------------------------------- -// Gets the base address (can change when adding elements!) -//----------------------------------------------------------------------------- - -template< class T > -inline T* CUtlVector::Base() { - return m_Memory.Base(); -} - -template< class T > -inline T const* CUtlVector::Base() const { - return m_Memory.Base(); -} - -//----------------------------------------------------------------------------- -// Count -//----------------------------------------------------------------------------- - -template< class T > -inline int CUtlVector::Size() const { - return m_Size; -} - -template< class T > -inline int CUtlVector::Count() const { - return m_Size; -} - -//----------------------------------------------------------------------------- -// Is element index valid? -//----------------------------------------------------------------------------- - -template< class T > -inline bool CUtlVector::IsValidIndex(int i) const { - return (i >= 0) && (i < m_Size); -} - -//----------------------------------------------------------------------------- -// Returns in invalid index -//----------------------------------------------------------------------------- -template< class T > -inline int CUtlVector::InvalidIndex(void) { - return -1; -} - -//----------------------------------------------------------------------------- -// Grows the vector -//----------------------------------------------------------------------------- -template< class T > -void CUtlVector::GrowVector(int num) { - if (m_Size + num - 1 >= m_Memory.NumAllocated()) { - m_Memory.Grow(m_Size + num - m_Memory.NumAllocated()); - } - - m_Size += num; - ResetDbgInfo(); -} - -//----------------------------------------------------------------------------- -// Makes sure we have at least this many elements -//----------------------------------------------------------------------------- -template< class T > -void CUtlVector::EnsureCount(int num) { - if (Count() < num) - AddMultipleToTail(num - Count()); -} - -//----------------------------------------------------------------------------- -// Shifts elements -//----------------------------------------------------------------------------- -template< class T > -void CUtlVector::ShiftElementsRight(int elem, int num) { - assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0)); - int numToMove = m_Size - elem - num; - if ((numToMove > 0) && (num > 0)) - memmove(&Element(elem + num), &Element(elem), numToMove * sizeof(T)); -} - -template< class T > -void CUtlVector::ShiftElementsLeft(int elem, int num) { - assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0)); - int numToMove = m_Size - elem - num; - if ((numToMove > 0) && (num > 0)) { - memmove(&Element(elem), &Element(elem + num), numToMove * sizeof(T)); - -#ifdef _DEBUG - memset(&Element(m_Size - num), 0xDD, num * sizeof(T)); -#endif - } -} - -//----------------------------------------------------------------------------- -// Adds an element, uses default constructor -//----------------------------------------------------------------------------- - -template< class T > -inline int CUtlVector::AddToHead() { - return InsertBefore(0); -} - -template< class T > -inline int CUtlVector::AddToTail() { - return InsertBefore(m_Size); -} - -template< class T > -inline int CUtlVector::InsertAfter(int elem) { - return InsertBefore(elem + 1); -} - -template< class T > -int CUtlVector::InsertBefore(int elem) { - // Can insert at the end - assert((elem == Count()) || IsValidIndex(elem)); - - GrowVector(); - ShiftElementsRight(elem); - Construct(&Element(elem)); - return elem; -} - -//----------------------------------------------------------------------------- -// Adds an element, uses copy constructor -//----------------------------------------------------------------------------- - -template< class T > -inline int CUtlVector::AddToHead(T const& src) { - return InsertBefore(0, src); -} - -template< class T > -inline int CUtlVector::AddToTail(T const& src) { - return InsertBefore(m_Size, src); -} - -template< class T > -inline int CUtlVector::InsertAfter(int elem, T const& src) { - return InsertBefore(elem + 1, src); -} - -template< class T > -int CUtlVector::InsertBefore(int elem, T const& src) { - // Can insert at the end - assert((elem == Count()) || IsValidIndex(elem)); - - GrowVector(); - ShiftElementsRight(elem); - CopyConstruct(&Element(elem), src); - return elem; -} - - -//----------------------------------------------------------------------------- -// Adds multiple elements, uses default constructor -//----------------------------------------------------------------------------- - -template< class T > -inline int CUtlVector::AddMultipleToHead(int num) { - return InsertMultipleBefore(0, num); -} - -template< class T > -inline int CUtlVector::AddMultipleToTail(int num, const T* pToCopy) { - return InsertMultipleBefore(m_Size, num, pToCopy); -} - -template< class T > -int CUtlVector::InsertMultipleAfter(int elem, int num) { - return InsertMultipleBefore(elem + 1, num); -} - - -template< class T > -void CUtlVector::SetCount(int count) { - RemoveAll(); - AddMultipleToTail(count); -} - -template< class T > -inline void CUtlVector::SetSize(int size) { - SetCount(size); -} - -template< class T > -void CUtlVector::CopyArray(T const* pArray, int size) { - SetSize(size); - for (int i = 0; i < size; i++) - (*this)[i] = pArray[i]; -} - -template< class T > -int CUtlVector::AddVectorToTail(CUtlVector const& src) { - int base = Count(); - - // Make space. - AddMultipleToTail(src.Count()); - - // Copy the elements. - for (int i = 0; i < src.Count(); i++) - (*this)[base + i] = src[i]; - - return base; -} - -template< class T > -inline int CUtlVector::InsertMultipleBefore(int elem, int num, const T* pToInsert) { - if (num == 0) - return elem; - - // Can insert at the end - assert((elem == Count()) || IsValidIndex(elem)); - - GrowVector(num); - ShiftElementsRight(elem, num); - - // Invoke default constructors - for (int i = 0; i < num; ++i) - Construct(&Element(elem + i)); - - // Copy stuff in? - if (pToInsert) { - for (int i = 0; i < num; i++) { - Element(elem + i) = pToInsert[i]; - } - } - - return elem; -} - -//----------------------------------------------------------------------------- -// Finds an element (element needs operator== defined) -//----------------------------------------------------------------------------- -template< class T > -int CUtlVector::Find(T const& src) const { - for (int i = 0; i < Count(); ++i) { - if (Element(i) == src) - return i; - } - return -1; -} - -template< class T > -bool CUtlVector::HasElement(T const& src) { - return (Find(src) >= 0); -} - -//----------------------------------------------------------------------------- -// Element removal -//----------------------------------------------------------------------------- - -template< class T > -void CUtlVector::FastRemove(int elem) { - assert(IsValidIndex(elem)); - - Destruct(&Element(elem)); - if (m_Size > 0) { - Q_memcpy(&Element(elem), &Element(m_Size - 1), sizeof(T)); - --m_Size; - } -} - -template< class T > -void CUtlVector::Remove(int elem) { - Destruct(&Element(elem)); - ShiftElementsLeft(elem); - --m_Size; -} - -template< class T > -void CUtlVector::FindAndRemove(T const& src) { - int elem = Find(src); - if (elem != -1) { - Remove(elem); - } -} - -template< class T > -void CUtlVector::RemoveMultiple(int elem, int num) { - assert(IsValidIndex(elem)); - assert(elem + num <= Count()); - - for (int i = elem + num; --i >= elem;) - Destruct(&Element(i)); - - ShiftElementsLeft(elem, num); - m_Size -= num; -} - -template< class T > -void CUtlVector::RemoveAll() { - for (int i = m_Size; --i >= 0;) - Destruct(&Element(i)); - - m_Size = 0; -} - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- - -template< class T > -void CUtlVector::Purge() { - RemoveAll(); - m_Memory.Purge(); - ResetDbgInfo(); -} - -template -inline void CUtlVector::PurgeAndDeleteElements() { - for (int i = 0; i < m_Size; i++) - delete Element(i); - - Purge(); -} - -template< class T > -void CUtlVector::SetGrowSize(int size) { - m_Memory.SetGrowSize(size); -} - -#pragma warning (pop) \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/BSPFlags.h b/Amalgam/src/SDK/Definitions/Misc/BSPFlags.h index 3199dff9..afaaedd1 100644 --- a/Amalgam/src/SDK/Definitions/Misc/BSPFlags.h +++ b/Amalgam/src/SDK/Definitions/Misc/BSPFlags.h @@ -55,8 +55,6 @@ #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_NOSKIP 0x80000000 // don't skip entities or displacements when starting in solid - // 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 diff --git a/Amalgam/src/SDK/Definitions/Misc/CByteSwap.cpp b/Amalgam/src/SDK/Definitions/Misc/CByteSwap.cpp new file mode 100644 index 00000000..77cc6ba6 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CByteSwap.cpp @@ -0,0 +1,82 @@ +#include "CByteSwap.h" + +//----------------------------------------------------------------------------- +// Copy a single field from the input buffer to the output buffer, swapping the bytes if necessary +//----------------------------------------------------------------------------- +void CByteswap::SwapFieldToTargetEndian(void* pOutputBuffer, void* pData, typedescription_t* pField) +{ + switch (pField->fieldType) + { + case FIELD_CHARACTER: + SwapBufferToTargetEndian((char*)pOutputBuffer, (char*)pData, pField->fieldSize); + break; + + case FIELD_BOOLEAN: + SwapBufferToTargetEndian((bool*)pOutputBuffer, (bool*)pData, pField->fieldSize); + break; + + case FIELD_SHORT: + SwapBufferToTargetEndian((short*)pOutputBuffer, (short*)pData, pField->fieldSize); + break; + + case FIELD_FLOAT: + SwapBufferToTargetEndian((uint*)pOutputBuffer, (uint*)pData, pField->fieldSize); + break; + + case FIELD_INTEGER: + SwapBufferToTargetEndian((int*)pOutputBuffer, (int*)pData, pField->fieldSize); + break; + + case FIELD_VECTOR: + SwapBufferToTargetEndian((uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 3); + break; + + case FIELD_VECTOR2D: + SwapBufferToTargetEndian((uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 2); + break; + + case FIELD_QUATERNION: + SwapBufferToTargetEndian((uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 4); + break; + + case FIELD_EMBEDDED: + { + typedescription_t* pEmbed = pField->td->dataDesc; + for (int i = 0; i < pField->fieldSize; ++i) + { + SwapFieldsToTargetEndian((byte*)pOutputBuffer + pEmbed->fieldOffset[TD_OFFSET_NORMAL], + (byte*)pData + pEmbed->fieldOffset[TD_OFFSET_NORMAL], + pField->td); + + pOutputBuffer = (byte*)pOutputBuffer + pField->fieldSizeInBytes; + pData = (byte*)pData + pField->fieldSizeInBytes; + } + } + break; + + //default: + //assert(0); + } +} + +//----------------------------------------------------------------------------- +// Write a block of fields. Works a bit like the saverestore code. +//----------------------------------------------------------------------------- +void CByteswap::SwapFieldsToTargetEndian(void* pOutputBuffer, void* pBaseData, datamap_t* pDataMap) +{ + // deal with base class first + if (pDataMap->baseMap) + { + SwapFieldsToTargetEndian(pOutputBuffer, pBaseData, pDataMap->baseMap); + } + + typedescription_t* pFields = pDataMap->dataDesc; + int fieldCount = pDataMap->dataNumFields; + for (int i = 0; i < fieldCount; ++i) + { + typedescription_t* pField = &pFields[i]; + SwapFieldToTargetEndian((BYTE*)pOutputBuffer + pField->fieldOffset[TD_OFFSET_NORMAL], + (BYTE*)pBaseData + pField->fieldOffset[TD_OFFSET_NORMAL], + pField); + } +} \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/CByteSwap.h b/Amalgam/src/SDK/Definitions/Misc/CByteSwap.h new file mode 100644 index 00000000..483a4911 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CByteSwap.h @@ -0,0 +1,239 @@ +#pragma once +#include "Datamap.h" +#include "BaseTypes.h" +#include +#include + +class CByteswap +{ +public: + CByteswap() + { + // Default behavior sets the target endian to match the machine native endian (no swap). + SetTargetBigEndian(IsMachineBigEndian()); + } + + //----------------------------------------------------------------------------- + // Write a single field. + //----------------------------------------------------------------------------- + void SwapFieldToTargetEndian(void* pOutputBuffer, void* pData, typedescription_t* pField); + + //----------------------------------------------------------------------------- + // Write a block of fields. Works a bit like the saverestore code. + //----------------------------------------------------------------------------- + void SwapFieldsToTargetEndian(void* pOutputBuffer, void* pBaseData, datamap_t* pDataMap); + + // Swaps fields for the templated type to the output buffer. + template inline void SwapFieldsToTargetEndian(T* pOutputBuffer, void* pBaseData, unsigned int objectCount = 1) + { + for (unsigned int i = 0; i < objectCount; ++i, ++pOutputBuffer) + { + SwapFieldsToTargetEndian((void*)pOutputBuffer, pBaseData, &T::m_DataMap); + pBaseData = (byte*)pBaseData + sizeof(T); + } + } + + // Swaps fields for the templated type in place. + template inline void SwapFieldsToTargetEndian(T* pOutputBuffer, unsigned int objectCount = 1) + { + SwapFieldsToTargetEndian(pOutputBuffer, (void*)pOutputBuffer, objectCount); + } + + //----------------------------------------------------------------------------- + // True if the current machine is detected as big endian. + // (Endienness is effectively detected at compile time when optimizations are + // enabled) + //----------------------------------------------------------------------------- + static bool IsMachineBigEndian() + { + short nIsBigEndian = 1; + + // if we are big endian, the first byte will be a 0, if little endian, it will be a one. + return (bool)(0 == *(char*)&nIsBigEndian); + } + + //----------------------------------------------------------------------------- + // Sets the target byte ordering we are swapping to or from. + // + // Braindead Endian Reference: + // x86 is LITTLE Endian + // PowerPC is BIG Endian + //----------------------------------------------------------------------------- + inline void SetTargetBigEndian(bool bigEndian) + { + m_bBigEndian = bigEndian; + m_bSwapBytes = IsMachineBigEndian() != bigEndian; + } + + // Changes target endian + inline void FlipTargetEndian(void) + { + m_bSwapBytes = !m_bSwapBytes; + m_bBigEndian = !m_bBigEndian; + } + + // Forces byte swapping state, regardless of endianess + inline void ActivateByteSwapping(bool bActivate) + { + SetTargetBigEndian(IsMachineBigEndian() != bActivate); + } + + //----------------------------------------------------------------------------- + // Returns true if the target machine is the same as this one in endianness. + // + // Used to determine when a byteswap needs to take place. + //----------------------------------------------------------------------------- + inline bool IsSwappingBytes(void) // Are bytes being swapped? + { + return m_bSwapBytes; + } + + inline bool IsTargetBigEndian(void) // What is the current target endian? + { + return m_bBigEndian; + } + + //----------------------------------------------------------------------------- + // IsByteSwapped() + // + // When supplied with a chunk of input data and a constant or magic number + // (in native format) determines the endienness of the current machine in + // relation to the given input data. + // + // Returns: + // 1 if input is the same as nativeConstant. + // 0 if input is byteswapped relative to nativeConstant. + // -1 if input is not the same as nativeConstant and not byteswapped either. + // + // ( This is useful for detecting byteswapping in magic numbers in structure + // headers for example. ) + //----------------------------------------------------------------------------- + template inline int SourceIsNativeEndian(T input, T nativeConstant) + { + // If it's the same, it isn't byteswapped: + if (input == nativeConstant) + return 1; + + int output; + LowLevelByteSwap(&output, &input); + if (output == nativeConstant) + return 0; + + assert(0); // if we get here, input is neither a swapped nor unswapped version of nativeConstant. + return -1; + } + + //----------------------------------------------------------------------------- + // Swaps an input buffer full of type T into the given output buffer. + // + // Swaps [count] items from the inputBuffer to the outputBuffer. + // If inputBuffer is omitted or NULL, then it is assumed to be the same as + // outputBuffer - effectively swapping the contents of the buffer in place. + //----------------------------------------------------------------------------- + template inline void SwapBuffer(T* outputBuffer, T* inputBuffer = NULL, int count = 1) + { + assert(count >= 0); + assert(outputBuffer); + + // Fail gracefully in release: + if (count <= 0 || !outputBuffer) + return; + + // Optimization for the case when we are swapping in place. + if (inputBuffer == NULL) + { + inputBuffer = outputBuffer; + } + + // Swap everything in the buffer: + for (int i = 0; i < count; i++) + { + LowLevelByteSwap(&outputBuffer[i], &inputBuffer[i]); + } + } + + //----------------------------------------------------------------------------- + // Swaps an input buffer full of type T into the given output buffer. + // + // Swaps [count] items from the inputBuffer to the outputBuffer. + // If inputBuffer is omitted or NULL, then it is assumed to be the same as + // outputBuffer - effectively swapping the contents of the buffer in place. + //----------------------------------------------------------------------------- + template inline void SwapBufferToTargetEndian(T* outputBuffer, T* inputBuffer = NULL, int count = 1) + { + assert(count >= 0); + assert(outputBuffer); + + // Fail gracefully in release: + if (count <= 0 || !outputBuffer) + return; + + // Optimization for the case when we are swapping in place. + if (inputBuffer == NULL) + { + inputBuffer = outputBuffer; + } + + // Are we already the correct endienness? ( or are we swapping 1 byte items? ) + if (!m_bSwapBytes || (sizeof(T) == 1)) + { + // If we were just going to swap in place then return. + if (!inputBuffer) + return; + + // Otherwise copy the inputBuffer to the outputBuffer: + memcpy(outputBuffer, inputBuffer, count * sizeof(T)); + return; + + } + + // Swap everything in the buffer: + for (int i = 0; i < count; i++) + { + LowLevelByteSwap(&outputBuffer[i], &inputBuffer[i]); + } + } + +private: + //----------------------------------------------------------------------------- + // The lowest level byte swapping workhorse of doom. output always contains the + // swapped version of input. ( Doesn't compare machine to target endianness ) + //----------------------------------------------------------------------------- + template static void LowLevelByteSwap(T* output, T* input) + { + T temp = *output; +#if defined( _X360 ) + // Intrinsics need the source type to be fixed-point + DWORD* word = (DWORD*)input; + switch (sizeof(T)) + { + case 8: + { + __storewordbytereverse(*word, 0, &temp); + __storewordbytereverse(*(word + 1), 4, &temp); + } + break; + + case 4: + __storewordbytereverse(*word, 0, &temp); + break; + + case 2: + __storeshortbytereverse(*input, 0, &temp); + break; + + default: + //Assert("Invalid size in CByteswap::LowLevelByteSwap" && 0); + } +#else + for (size_t i = 0; i < sizeof(T); i++) + { + ((unsigned char*)&temp)[i] = ((unsigned char*)input)[sizeof(T) - (i + 1)]; + } +#endif + memcpy(output, &temp, sizeof(T)); + } + + unsigned int m_bSwapBytes : 1; + unsigned int m_bBigEndian : 1; +}; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/CDiscardableArray.h b/Amalgam/src/SDK/Definitions/Misc/CDiscardableArray.h new file mode 100644 index 00000000..615c65fc --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CDiscardableArray.h @@ -0,0 +1,68 @@ +#pragma once +#include "CUtlBuffer.h" +#include "../Interfaces/IFileSystem.h" + +//----------------------------------------------------------------------------- +// A dumpable version of RangeValidatedArray +//----------------------------------------------------------------------------- +template +class CDiscardableArray +{ +public: + CDiscardableArray() + { + m_nCount = 0; + m_nOffset = -1; + memset(m_pFilename, 0, sizeof(m_pFilename)); + } + + ~CDiscardableArray() + { + } + + void Init(char* pFilename, int nOffset, int nCount, void* pData = NULL) + { + if (m_buf.TellPut()) + { + m_buf.Purge(); + } + + m_nCount = nCount; + strcpy_s(m_pFilename, pFilename); + m_nOffset = nOffset; + + // can preload as required + if (pData) + { + m_buf.Put(pData, nCount); + } + } + + // Either get or load the array as needed: + T* Get() + { + if (!m_buf.TellPut()) + { + if (!I::FileSystem->ReadFile(m_pFilename, NULL, m_buf, sizeof(T) * m_nCount, m_nOffset)) + { + return NULL; + } + } + + return (T*)m_buf.PeekGet(); + } + + void Discard() + { + // TODO(johns): Neutered -- Tear this class out. This can no longer be discarded with transparently compressed + // BSPs. This is on the range of 500k of memory, and is probably overly complex for the savings in + // the current era. + // m_buf.Purge(); + } + +protected: + int m_nCount; + CUtlBuffer m_buf; + char m_pFilename[256]; + int m_nOffset; +}; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/CRangeValidatedArray.h b/Amalgam/src/SDK/Definitions/Misc/CRangeValidatedArray.h new file mode 100644 index 00000000..a429d77f --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CRangeValidatedArray.h @@ -0,0 +1,63 @@ +#pragma once + +#define DBGFLAG_ASSERT + +template +class CRangeValidatedArray +{ +public: + void Attach(int nCount, T* pData); + void Detach(); + + T& operator[](int i); + const T& operator[](int i) const; + + T* Base(); + +private: + T* m_pArray; + +#ifdef DBGFLAG_ASSERT + int m_nCount; +#endif +}; + +template +inline T& CRangeValidatedArray::operator[](int i) +{ + //Assert((i >= 0) && (i < m_nCount)); + return m_pArray[i]; +} + +template +inline const T& CRangeValidatedArray::operator[](int i) const +{ + //Assert((i >= 0) && (i < m_nCount)); + return m_pArray[i]; +} + +template +inline void CRangeValidatedArray::Attach(int nCount, T* pData) +{ + m_pArray = pData; + +#ifdef DBGFLAG_ASSERT + m_nCount = nCount; +#endif +} + +template +inline void CRangeValidatedArray::Detach() +{ + m_pArray = NULL; + +#ifdef DBGFLAG_ASSERT + m_nCount = 0; +#endif +} + +template +inline T* CRangeValidatedArray::Base() +{ + return m_pArray; +} \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/SmartPtr.h b/Amalgam/src/SDK/Definitions/Misc/CSmartPtr.h similarity index 96% rename from Amalgam/src/SDK/Definitions/Misc/SmartPtr.h rename to Amalgam/src/SDK/Definitions/Misc/CSmartPtr.h index 466ca0bc..5535d2a4 100644 --- a/Amalgam/src/SDK/Definitions/Misc/SmartPtr.h +++ b/Amalgam/src/SDK/Definitions/Misc/CSmartPtr.h @@ -1,16 +1,7 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// +#pragma once #ifndef SMARTPTR_H #define SMARTPTR_H -#ifdef _WIN32 -#pragma once -#endif - class CRefCountAccessor { @@ -275,5 +266,4 @@ private: T m_valPop; }; - -#endif // SMARTPTR_H +#endif // SMARTPTR_H \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/CUtlBuffer.cpp b/Amalgam/src/SDK/Definitions/Misc/CUtlBuffer.cpp new file mode 100644 index 00000000..2b9db1d0 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CUtlBuffer.cpp @@ -0,0 +1,1684 @@ +#include "CUtlBuffer.h" + +#pragma warning (disable:4267) + +static int FastToLower(char c) +{ + int i = (unsigned char)c; + if (i < 0x80) + { + // Brutally fast branchless ASCII tolower(): + i += (((('A' - 1) - i) & (i - ('Z' + 1))) >> 26) & 0x20; + } + else + { + i += isupper(i) ? 0x20 : 0; + } + return i; +} + +static char const* strnistr(char const* pStr, char const* pSearch, int n) +{ + //AssertValidStringPtr(pStr); + //AssertValidStringPtr(pSearch); + + if (!pStr || !pSearch) + return 0; + + char const* pLetter = pStr; + + // Check the entire string + while (*pLetter != 0) + { + if (n <= 0) + return 0; + + // Skip over non-matches + if (FastToLower(*pLetter) == FastToLower(*pSearch)) + { + int n1 = n - 1; + + // Check for match + char const* pMatch = pLetter + 1; + char const* pTest = pSearch + 1; + while (*pTest != 0) + { + if (n1 <= 0) + return 0; + + // We've run off the end; don't bother. + if (*pMatch == 0) + return 0; + + if (FastToLower(*pMatch) != FastToLower(*pTest)) + break; + + ++pMatch; + ++pTest; + --n1; + } + + // Found a match! + if (*pTest == 0) + return pLetter; + } + + ++pLetter; + --n; + } + + return 0; +} + +static const char* strnchr(const char* pStr, char c, int n) +{ + char const* pLetter = pStr; + char const* pLast = pStr + n; + + // Check the entire string + while ((pLetter < pLast) && (*pLetter != 0)) + { + if (*pLetter == c) + return pLetter; + ++pLetter; + } + return NULL; +} + +//----------------------------------------------------------------------------- +// constructors +//----------------------------------------------------------------------------- +CUtlBuffer::CUtlBuffer(int growSize, int initSize, int nFlags) : + m_Error(0) +{ + m_Memory.Init(growSize, initSize); + m_Get = 0; + m_Put = 0; + m_nTab = 0; + m_nOffset = 0; + m_Flags = nFlags; + if ((initSize != 0) && !IsReadOnly()) + { + m_nMaxPut = -1; + AddNullTermination(); + } + else + { + m_nMaxPut = 0; + } + SetOverflowFuncs(&CUtlBuffer::GetOverflow, &CUtlBuffer::PutOverflow); +} + +CUtlBuffer::CUtlBuffer(const void* pBuffer, int nSize, int nFlags) : + m_Memory((unsigned char*)pBuffer, nSize), m_Error(0) +{ + //Assert(nSize != 0); + + m_Get = 0; + m_Put = 0; + m_nTab = 0; + m_nOffset = 0; + m_Flags = nFlags; + if (IsReadOnly()) + { + m_nMaxPut = nSize; + } + else + { + m_nMaxPut = -1; + AddNullTermination(); + } + SetOverflowFuncs(&CUtlBuffer::GetOverflow, &CUtlBuffer::PutOverflow); +} + + +//----------------------------------------------------------------------------- +// Modifies the buffer to be binary or text; Blows away the buffer and the CONTAINS_CRLF value. +//----------------------------------------------------------------------------- +void CUtlBuffer::SetBufferType(bool bIsText, bool bContainsCRLF) +{ +#ifdef _DEBUG + // If the buffer is empty, there is no opportunity for this stuff to fail + if (TellMaxPut() != 0) + { + if (IsText()) + { + if (bIsText) + { + //Assert(ContainsCRLF() == bContainsCRLF); + } + else + { + //Assert(ContainsCRLF()); + } + } + else + { + if (bIsText) + { + //Assert(bContainsCRLF); + } + } + } +#endif + + if (bIsText) + { + m_Flags |= TEXT_BUFFER; + } + else + { + m_Flags &= ~TEXT_BUFFER; + } + if (bContainsCRLF) + { + m_Flags |= CONTAINS_CRLF; + } + else + { + m_Flags &= ~CONTAINS_CRLF; + } +} + + +//----------------------------------------------------------------------------- +// Attaches the buffer to external memory.... +//----------------------------------------------------------------------------- +void CUtlBuffer::SetExternalBuffer(void* pMemory, int nSize, int nInitialPut, int nFlags) +{ + m_Memory.SetExternalBuffer((unsigned char*)pMemory, nSize); + + // Reset all indices; we just changed memory + m_Get = 0; + m_Put = nInitialPut; + m_nTab = 0; + m_Error = 0; + m_nOffset = 0; + m_Flags = nFlags; + m_nMaxPut = -1; + AddNullTermination(); +} + +//----------------------------------------------------------------------------- +// Assumes an external buffer but manages its deletion +//----------------------------------------------------------------------------- +void CUtlBuffer::AssumeMemory(void* pMemory, int nSize, int nInitialPut, int nFlags) +{ + m_Memory.AssumeMemory((unsigned char*)pMemory, nSize); + + // Reset all indices; we just changed memory + m_Get = 0; + m_Put = nInitialPut; + m_nTab = 0; + m_Error = 0; + m_nOffset = 0; + m_Flags = nFlags; + m_nMaxPut = -1; + AddNullTermination(); +} + +//----------------------------------------------------------------------------- +// Makes sure we've got at least this much memory +//----------------------------------------------------------------------------- +void CUtlBuffer::EnsureCapacity(int num) +{ + // Add one extra for the null termination + num += 1; + if (m_Memory.IsExternallyAllocated()) + { + if (IsGrowable() && (m_Memory.NumAllocated() < num)) + { + m_Memory.ConvertToGrowableMemory(0); + } + else + { + num -= 1; + } + } + + m_Memory.EnsureCapacity(num); +} + + +//----------------------------------------------------------------------------- +// Base get method from which all others derive +//----------------------------------------------------------------------------- +void CUtlBuffer::Get(void* pMem, int size) +{ + if (size > 0 && CheckGet(size)) + { + int Index = m_Get - m_nOffset; + //Assert(m_Memory.IsIdxValid(Index) && m_Memory.IsIdxValid(Index + size - 1)); + + memcpy(pMem, &m_Memory[Index], size); + m_Get += size; + } +} + + +//----------------------------------------------------------------------------- +// This will get at least 1 byte and up to nSize bytes. +// It will return the number of bytes actually read. +//----------------------------------------------------------------------------- +int CUtlBuffer::GetUpTo(void* pMem, int nSize) +{ + if (CheckArbitraryPeekGet(0, nSize)) + { + int Index = m_Get - m_nOffset; + //Assert(m_Memory.IsIdxValid(Index) && m_Memory.IsIdxValid(Index + nSize - 1)); + + memcpy(pMem, &m_Memory[Index], nSize); + m_Get += nSize; + return nSize; + } + return 0; +} + + +//----------------------------------------------------------------------------- +// Eats whitespace +//----------------------------------------------------------------------------- +void CUtlBuffer::EatWhiteSpace() +{ + if (IsText() && IsValid()) + { + while (CheckGet(sizeof(char))) + { + if (!isspace(*(const unsigned char*)PeekGet())) + break; + m_Get += sizeof(char); + } + } +} + + +//----------------------------------------------------------------------------- +// Eats C++ style comments +//----------------------------------------------------------------------------- +bool CUtlBuffer::EatCPPComment() +{ + if (IsText() && IsValid()) + { + // If we don't have a a c++ style comment next, we're done + const char* pPeek = (const char*)PeekGet(2 * sizeof(char), 0); + if (!pPeek || (pPeek[0] != '/') || (pPeek[1] != '/')) + return false; + + // Deal with c++ style comments + m_Get += 2; + + // read complete line + for (char c = GetChar(); IsValid(); c = GetChar()) + { + if (c == '\n') + break; + } + return true; + } + return false; +} + + +//----------------------------------------------------------------------------- +// Peeks how much whitespace to eat +//----------------------------------------------------------------------------- +int CUtlBuffer::PeekWhiteSpace(int nOffset) +{ + if (!IsText() || !IsValid()) + return 0; + + while (CheckPeekGet(nOffset, sizeof(char))) + { + if (!isspace(*(unsigned char*)PeekGet(nOffset))) + break; + nOffset += sizeof(char); + } + + return nOffset; +} + + +//----------------------------------------------------------------------------- +// Peek size of sting to come, check memory bound +//----------------------------------------------------------------------------- +int CUtlBuffer::PeekStringLength() +{ + if (!IsValid()) + return 0; + + // Eat preceeding whitespace + int nOffset = 0; + if (IsText()) + { + nOffset = PeekWhiteSpace(nOffset); + } + + int nStartingOffset = nOffset; + + do + { + int nPeekAmount = 128; + + // NOTE: Add 1 for the terminating zero! + if (!CheckArbitraryPeekGet(nOffset, nPeekAmount)) + { + if (nOffset == nStartingOffset) + return 0; + return nOffset - nStartingOffset + 1; + } + + const char* pTest = (const char*)PeekGet(nOffset); + + if (!IsText()) + { + for (int i = 0; i < nPeekAmount; ++i) + { + // The +1 here is so we eat the terminating 0 + if (pTest[i] == 0) + return (i + nOffset - nStartingOffset + 1); + } + } + else + { + for (int i = 0; i < nPeekAmount; ++i) + { + // The +1 here is so we eat the terminating 0 + if (isspace((unsigned char)pTest[i]) || (pTest[i] == 0)) + return (i + nOffset - nStartingOffset + 1); + } + } + + nOffset += nPeekAmount; + + } while (true); +} + + +//----------------------------------------------------------------------------- +// Peek size of line to come, check memory bound +//----------------------------------------------------------------------------- +int CUtlBuffer::PeekLineLength() +{ + if (!IsValid()) + return 0; + + int nOffset = 0; + int nStartingOffset = nOffset; + + do + { + int nPeekAmount = 128; + + // NOTE: Add 1 for the terminating zero! + if (!CheckArbitraryPeekGet(nOffset, nPeekAmount)) + { + if (nOffset == nStartingOffset) + return 0; + return nOffset - nStartingOffset + 1; + } + + const char* pTest = (const char*)PeekGet(nOffset); + + for (int i = 0; i < nPeekAmount; ++i) + { + // The +2 here is so we eat the terminating '\n' and 0 + if (pTest[i] == '\n' || pTest[i] == '\r') + return (i + nOffset - nStartingOffset + 2); + // The +1 here is so we eat the terminating 0 + if (pTest[i] == 0) + return (i + nOffset - nStartingOffset + 1); + } + + nOffset += nPeekAmount; + + } while (true); +} + + +//----------------------------------------------------------------------------- +// Does the next bytes of the buffer match a pattern? +//----------------------------------------------------------------------------- +bool CUtlBuffer::PeekStringMatch(int nOffset, const char* pString, int nLen) +{ + if (!CheckPeekGet(nOffset, nLen)) + return false; + return !strncmp((const char*)PeekGet(nOffset), pString, nLen); +} + + +//----------------------------------------------------------------------------- +// This version of PeekStringLength converts \" to \\ and " to \, etc. +// It also reads a " at the beginning and end of the string +//----------------------------------------------------------------------------- +int CUtlBuffer::PeekDelimitedStringLength(CUtlCharConversion* pConv, bool bActualSize) +{ + if (!IsText() || !pConv) + return PeekStringLength(); + + // Eat preceeding whitespace + int nOffset = 0; + if (IsText()) + { + nOffset = PeekWhiteSpace(nOffset); + } + + if (!PeekStringMatch(nOffset, pConv->GetDelimiter(), pConv->GetDelimiterLength())) + return 0; + + // Try to read ending ", but don't accept \" + int nActualStart = nOffset; + nOffset += pConv->GetDelimiterLength(); + int nLen = 1; // Starts at 1 for the '\0' termination + + do + { + if (PeekStringMatch(nOffset, pConv->GetDelimiter(), pConv->GetDelimiterLength())) + break; + + if (!CheckPeekGet(nOffset, 1)) + break; + + char c = *(const char*)PeekGet(nOffset); + ++nLen; + ++nOffset; + if (c == pConv->GetEscapeChar()) + { + int nLength = pConv->MaxConversionLength(); + if (!CheckArbitraryPeekGet(nOffset, nLength)) + break; + + pConv->FindConversion((const char*)PeekGet(nOffset), &nLength); + nOffset += nLength; + } + } while (true); + + return bActualSize ? nLen : nOffset - nActualStart + pConv->GetDelimiterLength() + 1; +} + + +//----------------------------------------------------------------------------- +// Reads a null-terminated string +//----------------------------------------------------------------------------- +void CUtlBuffer::GetStringInternal(char* pString, size_t maxLenInChars) +{ + if (!IsValid()) + { + *pString = 0; + return; + } + + // This can legitimately be zero if we were told that the buffer is zero length, and + // we're asking to duplicate the buffer, so let that pass, too. + //Assert(maxLenInChars != 0 || PeekStringLength() == 0); + + if (maxLenInChars == 0) + { + return; + } + + // Remember, this *includes* the null character + // It will be 0, however, if the buffer is empty. + int nLen = PeekStringLength(); + + if (IsText()) + { + EatWhiteSpace(); + } + + if (nLen <= 0) + { + *pString = 0; + m_Error |= GET_OVERFLOW; + return; + } + + const size_t nCharsToRead = Min((size_t)nLen, maxLenInChars) - 1; + + Get(pString, nCharsToRead); + pString[nCharsToRead] = 0; + + if ((size_t)nLen > (nCharsToRead + 1)) + { + SeekGet(SEEK_CURRENT, nLen - (nCharsToRead + 1)); + } + + // Read the terminating NULL in binary formats + if (!IsText()) + { + //VerifyEquals(GetChar(), 0); + } +} + + +//----------------------------------------------------------------------------- +// Reads up to and including the first \n +//----------------------------------------------------------------------------- +void CUtlBuffer::GetLine(char* pLine, int nMaxChars) +{ + //Assert(IsText() && !ContainsCRLF()); + + if (!IsValid()) + { + *pLine = 0; + return; + } + + if (nMaxChars == 0) + { + nMaxChars = INT_MAX; + } + + // Remember, this *includes* the null character + // It will be 0, however, if the buffer is empty. + int nLen = PeekLineLength(); + if (nLen == 0) + { + *pLine = 0; + m_Error |= GET_OVERFLOW; + return; + } + + // Strip off the terminating NULL + if (nLen <= nMaxChars) + { + Get(pLine, nLen - 1); + pLine[nLen - 1] = 0; + } + else + { + Get(pLine, nMaxChars - 1); + pLine[nMaxChars - 1] = 0; + SeekGet(SEEK_CURRENT, nLen - 1 - nMaxChars); + } +} + + +//----------------------------------------------------------------------------- +// This version of GetString converts \ to \\ and " to \", etc. +// It also places " at the beginning and end of the string +//----------------------------------------------------------------------------- +char CUtlBuffer::GetDelimitedCharInternal(CUtlCharConversion* pConv) +{ + char c = GetChar(); + if (c == pConv->GetEscapeChar()) + { + int nLength = pConv->MaxConversionLength(); + if (!CheckArbitraryPeekGet(0, nLength)) + return '\0'; + + c = pConv->FindConversion((const char*)PeekGet(), &nLength); + SeekGet(SEEK_CURRENT, nLength); + } + + return c; +} + +char CUtlBuffer::GetDelimitedChar(CUtlCharConversion* pConv) +{ + if (!IsText() || !pConv) + return GetChar(); + return GetDelimitedCharInternal(pConv); +} + +void CUtlBuffer::GetDelimitedString(CUtlCharConversion* pConv, char* pString, int nMaxChars) +{ + if (!IsText() || !pConv) + { + GetStringInternal(pString, nMaxChars); + return; + } + + if (!IsValid()) + { + *pString = 0; + return; + } + + if (nMaxChars == 0) + { + nMaxChars = INT_MAX; + } + + EatWhiteSpace(); + if (!PeekStringMatch(0, pConv->GetDelimiter(), pConv->GetDelimiterLength())) + return; + + // Pull off the starting delimiter + SeekGet(SEEK_CURRENT, pConv->GetDelimiterLength()); + + int nRead = 0; + while (IsValid()) + { + if (PeekStringMatch(0, pConv->GetDelimiter(), pConv->GetDelimiterLength())) + { + SeekGet(SEEK_CURRENT, pConv->GetDelimiterLength()); + break; + } + + char c = GetDelimitedCharInternal(pConv); + + if (nRead < nMaxChars) + { + pString[nRead] = c; + ++nRead; + } + } + + if (nRead >= nMaxChars) + { + nRead = nMaxChars - 1; + } + pString[nRead] = '\0'; +} + + +//----------------------------------------------------------------------------- +// Checks if a get is ok +//----------------------------------------------------------------------------- +bool CUtlBuffer::CheckGet(int nSize) +{ + if (m_Error & GET_OVERFLOW) + return false; + + if (TellMaxPut() < m_Get + nSize) + { + m_Error |= GET_OVERFLOW; + return false; + } + + if ((m_Get < m_nOffset) || (m_Memory.NumAllocated() < m_Get - m_nOffset + nSize)) + { + if (!OnGetOverflow(nSize)) + { + m_Error |= GET_OVERFLOW; + return false; + } + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Checks if a peek get is ok +//----------------------------------------------------------------------------- +bool CUtlBuffer::CheckPeekGet(int nOffset, int nSize) +{ + if (m_Error & GET_OVERFLOW) + return false; + + // Checking for peek can't set the overflow flag + bool bOk = CheckGet(nOffset + nSize); + m_Error &= ~GET_OVERFLOW; + return bOk; +} + + +//----------------------------------------------------------------------------- +// Call this to peek arbitrarily long into memory. It doesn't fail unless +// it can't read *anything* new +//----------------------------------------------------------------------------- +bool CUtlBuffer::CheckArbitraryPeekGet(int nOffset, int& nIncrement) +{ + if (TellGet() + nOffset >= TellMaxPut()) + { + nIncrement = 0; + return false; + } + + if (TellGet() + nOffset + nIncrement > TellMaxPut()) + { + nIncrement = TellMaxPut() - TellGet() - nOffset; + } + + // NOTE: CheckPeekGet could modify TellMaxPut for streaming files + // We have to call TellMaxPut again here + CheckPeekGet(nOffset, nIncrement); + int nMaxGet = TellMaxPut() - TellGet(); + if (nMaxGet < nIncrement) + { + nIncrement = nMaxGet; + } + return (nIncrement != 0); +} + + +//----------------------------------------------------------------------------- +// Peek part of the butt +//----------------------------------------------------------------------------- +const void* CUtlBuffer::PeekGet(int nMaxSize, int nOffset) +{ + if (!CheckPeekGet(nOffset, nMaxSize)) + return NULL; + + int Index = m_Get + nOffset - m_nOffset; + //Assert(m_Memory.IsIdxValid(Index) && m_Memory.IsIdxValid(Index + nMaxSize - 1)); + + return &m_Memory[Index]; +} + + +//----------------------------------------------------------------------------- +// Change where I'm reading +//----------------------------------------------------------------------------- +void CUtlBuffer::SeekGet(SeekType_t type, int offset) +{ + switch (type) + { + case SEEK_HEAD: + m_Get = offset; + break; + + case SEEK_CURRENT: + m_Get += offset; + break; + + case SEEK_TAIL: + m_Get = m_nMaxPut - offset; + break; + } + + if (m_Get > m_nMaxPut) + { + m_Error |= GET_OVERFLOW; + } + else + { + m_Error &= ~GET_OVERFLOW; + if (m_Get < m_nOffset || m_Get >= m_nOffset + Size()) + { + OnGetOverflow(-1); + } + } +} + + +//----------------------------------------------------------------------------- +// Parse... +//----------------------------------------------------------------------------- + +#pragma warning ( disable : 4706 ) + +int CUtlBuffer::VaScanf(const char* pFmt, va_list list) +{ + //Assert(pFmt); + if (m_Error || !IsText()) + return 0; + + int numScanned = 0; + int nLength; + char c; + char* pEnd; + while ((c = *pFmt++)) + { + // Stop if we hit the end of the buffer + if (m_Get >= TellMaxPut()) + { + m_Error |= GET_OVERFLOW; + break; + } + + switch (c) + { + case ' ': + // eat all whitespace + EatWhiteSpace(); + break; + + case '%': + { + // Conversion character... try to convert baby! + char type = *pFmt++; + if (type == 0) + return numScanned; + + switch (type) + { + case 'c': + { + char* ch = va_arg(list, char*); + if (CheckPeekGet(0, sizeof(char))) + { + *ch = *(const char*)PeekGet(); + ++m_Get; + } + else + { + *ch = 0; + return numScanned; + } + } + break; + + case 'i': + case 'd': + { + int* i = va_arg(list, int*); + + // NOTE: This is not bullet-proof; it assumes numbers are < 128 characters + nLength = 128; + if (!CheckArbitraryPeekGet(0, nLength)) + { + *i = 0; + return numScanned; + } + + *i = strtol((char*)PeekGet(), &pEnd, 10); + int nBytesRead = (int)(pEnd - (char*)PeekGet()); + if (nBytesRead == 0) + return numScanned; + m_Get += nBytesRead; + } + break; + + case 'x': + { + int* i = va_arg(list, int*); + + // NOTE: This is not bullet-proof; it assumes numbers are < 128 characters + nLength = 128; + if (!CheckArbitraryPeekGet(0, nLength)) + { + *i = 0; + return numScanned; + } + + *i = strtol((char*)PeekGet(), &pEnd, 16); + int nBytesRead = (int)(pEnd - (char*)PeekGet()); + if (nBytesRead == 0) + return numScanned; + m_Get += nBytesRead; + } + break; + + case 'u': + { + unsigned int* u = va_arg(list, unsigned int*); + + // NOTE: This is not bullet-proof; it assumes numbers are < 128 characters + nLength = 128; + if (!CheckArbitraryPeekGet(0, nLength)) + { + *u = 0; + return numScanned; + } + + *u = strtoul((char*)PeekGet(), &pEnd, 10); + int nBytesRead = (int)(pEnd - (char*)PeekGet()); + if (nBytesRead == 0) + return numScanned; + m_Get += nBytesRead; + } + break; + + case 'f': + { + float* f = va_arg(list, float*); + + // NOTE: This is not bullet-proof; it assumes numbers are < 128 characters + nLength = 128; + if (!CheckArbitraryPeekGet(0, nLength)) + { + *f = 0.0f; + return numScanned; + } + + *f = (float)strtod((char*)PeekGet(), &pEnd); + int nBytesRead = (int)(pEnd - (char*)PeekGet()); + if (nBytesRead == 0) + return numScanned; + m_Get += nBytesRead; + } + break; + + case 's': + { + char* s = va_arg(list, char*); + GetStringInternal(s, 256); + } + break; + + default: + { + // unimplemented scanf type + //Assert(0); + return numScanned; + } + break; + } + + ++numScanned; + } + break; + + default: + { + // Here we have to match the format string character + // against what's in the buffer or we're done. + if (!CheckPeekGet(0, sizeof(char))) + return numScanned; + + if (c != *(const char*)PeekGet()) + return numScanned; + + ++m_Get; + } + } + } + return numScanned; +} + +#pragma warning ( default : 4706 ) + +int CUtlBuffer::Scanf(const char* pFmt, ...) +{ + va_list args; + + va_start(args, pFmt); + int count = VaScanf(pFmt, args); + va_end(args); + + return count; +} + +//----------------------------------------------------------------------------- +// Advance the get index until after the particular string is found +// Do not eat whitespace before starting. Return false if it failed +//----------------------------------------------------------------------------- +bool CUtlBuffer::GetToken(const char* pToken) +{ + //Assert(pToken); + + // Look for the token + int nLen = strlen(pToken); + + int nSizeToCheck = Size() - TellGet() - m_nOffset; + + int nGet = TellGet(); + do + { + int nMaxSize = TellMaxPut() - TellGet(); + if (nMaxSize < nSizeToCheck) + { + nSizeToCheck = nMaxSize; + } + if (nLen > nSizeToCheck) + break; + + if (!CheckPeekGet(0, nSizeToCheck)) + break; + + const char* pBufStart = (const char*)PeekGet(); + const char* pFoundEnd = strnistr(pBufStart, pToken, nSizeToCheck); + if (pFoundEnd) + { + size_t nOffset = (size_t)pFoundEnd - (size_t)pBufStart; + SeekGet(CUtlBuffer::SEEK_CURRENT, nOffset + nLen); + return true; + } + + SeekGet(CUtlBuffer::SEEK_CURRENT, nSizeToCheck - nLen - 1); + nSizeToCheck = Size() - (nLen - 1); + + } while (true); + + SeekGet(CUtlBuffer::SEEK_HEAD, nGet); + return false; +} + + +//----------------------------------------------------------------------------- +// (For text buffers only) +// Parse a token from the buffer: +// Grab all text that lies between a starting delimiter + ending delimiter +// (skipping whitespace that leads + trails both delimiters). +// Note the delimiter checks are case-insensitive. +// If successful, the get index is advanced and the function returns true, +// otherwise the index is not advanced and the function returns false. +//----------------------------------------------------------------------------- +bool CUtlBuffer::ParseToken(const char* pStartingDelim, const char* pEndingDelim, char* pString, int nMaxLen) +{ + int nCharsToCopy = 0; + int nCurrentGet = 0; + + size_t nEndingDelimLen; + + // Starting delimiter is optional + char emptyBuf = '\0'; + if (!pStartingDelim) + { + pStartingDelim = &emptyBuf; + } + + // Ending delimiter is not + //Assert(pEndingDelim && pEndingDelim[0]); + nEndingDelimLen = strlen(pEndingDelim); + + int nStartGet = TellGet(); + char nCurrChar; + int nTokenStart = -1; + EatWhiteSpace(); + while (*pStartingDelim) + { + nCurrChar = *pStartingDelim++; + if (!isspace((unsigned char)nCurrChar)) + { + if (tolower(GetChar()) != tolower(nCurrChar)) + goto parseFailed; + } + else + { + EatWhiteSpace(); + } + } + + EatWhiteSpace(); + nTokenStart = TellGet(); + if (!GetToken(pEndingDelim)) + goto parseFailed; + + nCurrentGet = TellGet(); + nCharsToCopy = (nCurrentGet - nEndingDelimLen) - nTokenStart; + if (nCharsToCopy >= nMaxLen) + { + nCharsToCopy = nMaxLen - 1; + } + + if (nCharsToCopy > 0) + { + SeekGet(CUtlBuffer::SEEK_HEAD, nTokenStart); + Get(pString, nCharsToCopy); + if (!IsValid()) + goto parseFailed; + + // Eat trailing whitespace + for (; nCharsToCopy > 0; --nCharsToCopy) + { + if (!isspace((unsigned char)pString[nCharsToCopy - 1])) + break; + } + } + pString[nCharsToCopy] = '\0'; + + // Advance the Get index + SeekGet(CUtlBuffer::SEEK_HEAD, nCurrentGet); + return true; + +parseFailed: + // Revert the get index + SeekGet(SEEK_HEAD, nStartGet); + pString[0] = '\0'; + return false; +} + + +//----------------------------------------------------------------------------- +// Parses the next token, given a set of character breaks to stop at +//----------------------------------------------------------------------------- +int CUtlBuffer::ParseToken(characterset_t* pBreaks, char* pTokenBuf, int nMaxLen, bool bParseComments) +{ + //Assert(nMaxLen > 0); + pTokenBuf[0] = 0; + + // skip whitespace + comments + while (true) + { + if (!IsValid()) + return -1; + EatWhiteSpace(); + if (bParseComments) + { + if (!EatCPPComment()) + break; + } + else + { + break; + } + } + + char c = GetChar(); + + // End of buffer + if (c == 0) + return -1; + + // handle quoted strings specially + if (c == '\"') + { + int nLen = 0; + while (IsValid()) + { + c = GetChar(); + if (c == '\"' || !c) + { + pTokenBuf[nLen] = 0; + return nLen; + } + pTokenBuf[nLen] = c; + if (++nLen == nMaxLen) + { + pTokenBuf[nLen - 1] = 0; + return nMaxLen; + } + } + + // In this case, we hit the end of the buffer before hitting the end qoute + pTokenBuf[nLen] = 0; + return nLen; + } + + // parse single characters + if (IN_CHARACTERSET(*pBreaks, c)) + { + pTokenBuf[0] = c; + pTokenBuf[1] = 0; + return 1; + } + + // parse a regular word + int nLen = 0; + while (true) + { + pTokenBuf[nLen] = c; + if (++nLen == nMaxLen) + { + pTokenBuf[nLen - 1] = 0; + return nMaxLen; + } + c = GetChar(); + if (!IsValid()) + break; + + if (IN_CHARACTERSET(*pBreaks, c) || c == '\"' || c <= ' ') + { + SeekGet(SEEK_CURRENT, -1); + break; + } + } + + pTokenBuf[nLen] = 0; + return nLen; +} + + + +//----------------------------------------------------------------------------- +// Serialization +//----------------------------------------------------------------------------- +void CUtlBuffer::Put(const void* pMem, int size) +{ + if (size && CheckPut(size)) + { + int Index = m_Put - m_nOffset; + //Assert(m_Memory.IsIdxValid(Index) && m_Memory.IsIdxValid(Index + size - 1)); + if (Index >= 0) + { + memcpy(&m_Memory[Index], pMem, size); + m_Put += size; + + AddNullTermination(); + } + } +} + + +//----------------------------------------------------------------------------- +// Writes a null-terminated string +//----------------------------------------------------------------------------- +void CUtlBuffer::PutString(const char* pString) +{ + if (!IsText()) + { + if (pString) + { + // Not text? append a null at the end. + size_t nLen = strlen(pString) + 1; + Put(pString, nLen * sizeof(char)); + return; + } + else + { + PutTypeBin(0); + } + } + else if (pString) + { + int nTabCount = (m_Flags & AUTO_TABS_DISABLED) ? 0 : m_nTab; + if (nTabCount > 0) + { + if (WasLastCharacterCR()) + { + PutTabs(); + } + + const char* pEndl = strchr(pString, '\n'); + while (pEndl) + { + size_t nSize = (size_t)pEndl - (size_t)pString + sizeof(char); + Put(pString, nSize); + pString = pEndl + 1; + if (*pString) + { + PutTabs(); + pEndl = strchr(pString, '\n'); + } + else + { + pEndl = NULL; + } + } + } + size_t nLen = strlen(pString); + if (nLen) + { + Put(pString, nLen * sizeof(char)); + } + } +} + + +//----------------------------------------------------------------------------- +// This version of PutString converts \ to \\ and " to \", etc. +// It also places " at the beginning and end of the string +//----------------------------------------------------------------------------- +inline void CUtlBuffer::PutDelimitedCharInternal(CUtlCharConversion* pConv, char c) +{ + int l = pConv->GetConversionLength(c); + if (l == 0) + { + PutChar(c); + } + else + { + PutChar(pConv->GetEscapeChar()); + Put(pConv->GetConversionString(c), l); + } +} + +void CUtlBuffer::PutDelimitedChar(CUtlCharConversion* pConv, char c) +{ + if (!IsText() || !pConv) + { + PutChar(c); + return; + } + + PutDelimitedCharInternal(pConv, c); +} + +void CUtlBuffer::PutDelimitedString(CUtlCharConversion* pConv, const char* pString) +{ + if (!IsText() || !pConv) + { + PutString(pString); + return; + } + + if (WasLastCharacterCR()) + { + PutTabs(); + } + Put(pConv->GetDelimiter(), pConv->GetDelimiterLength()); + + int nLen = pString ? strlen(pString) : 0; + for (int i = 0; i < nLen; ++i) + { + PutDelimitedCharInternal(pConv, pString[i]); + } + + if (WasLastCharacterCR()) + { + PutTabs(); + } + Put(pConv->GetDelimiter(), pConv->GetDelimiterLength()); +} + + +void CUtlBuffer::VaPrintf(const char* pFmt, va_list list) +{ + char temp[2048]; +#ifdef DBGFLAG_ASSERT + int nLen = +#endif + vsnprintf(temp, sizeof(temp), pFmt, list); + //Assert(nLen < 2048); + PutString(temp); +} + +void CUtlBuffer::Printf(const char* pFmt, ...) +{ + va_list args; + + va_start(args, pFmt); + VaPrintf(pFmt, args); + va_end(args); +} + + +//----------------------------------------------------------------------------- +// Calls the overflow functions +//----------------------------------------------------------------------------- +void CUtlBuffer::SetOverflowFuncs(UtlBufferOverflowFunc_t getFunc, UtlBufferOverflowFunc_t putFunc) +{ + m_GetOverflowFunc = getFunc; + m_PutOverflowFunc = putFunc; +} + + +//----------------------------------------------------------------------------- +// Calls the overflow functions +//----------------------------------------------------------------------------- +bool CUtlBuffer::OnPutOverflow(int nSize) +{ + return (this->*m_PutOverflowFunc)(nSize); +} + +bool CUtlBuffer::OnGetOverflow(int nSize) +{ + return (this->*m_GetOverflowFunc)(nSize); +} + + +//----------------------------------------------------------------------------- +// Checks if a put is ok +//----------------------------------------------------------------------------- +bool CUtlBuffer::PutOverflow(int nSize) +{ + if (m_Memory.IsExternallyAllocated()) + { + if (!IsGrowable()) + return false; + + m_Memory.ConvertToGrowableMemory(0); + } + + while (Size() < m_Put - m_nOffset + nSize) + { + m_Memory.Grow(); + } + + return true; +} + +bool CUtlBuffer::GetOverflow(int nSize) +{ + return false; +} + + +//----------------------------------------------------------------------------- +// Checks if a put is ok +//----------------------------------------------------------------------------- +bool CUtlBuffer::CheckPut(int nSize) +{ + if ((m_Error & PUT_OVERFLOW) || IsReadOnly()) + return false; + + if ((m_Put < m_nOffset) || (m_Memory.NumAllocated() < m_Put - m_nOffset + nSize)) + { + if (!OnPutOverflow(nSize)) + { + m_Error |= PUT_OVERFLOW; + return false; + } + } + return true; +} + +void CUtlBuffer::SeekPut(SeekType_t type, int offset) +{ + int nNextPut = m_Put; + switch (type) + { + case SEEK_HEAD: + nNextPut = offset; + break; + + case SEEK_CURRENT: + nNextPut += offset; + break; + + case SEEK_TAIL: + nNextPut = m_nMaxPut - offset; + break; + } + + // Force a write of the data + // FIXME: We could make this more optimal potentially by writing out + // the entire buffer if you seek outside the current range + + // NOTE: This call will write and will also seek the file to nNextPut. + OnPutOverflow(-nNextPut - 1); + m_Put = nNextPut; + + AddNullTermination(); +} + + +void CUtlBuffer::ActivateByteSwapping(bool bActivate) +{ + m_Byteswap.ActivateByteSwapping(bActivate); +} + +void CUtlBuffer::SetBigEndian(bool bigEndian) +{ + m_Byteswap.SetTargetBigEndian(bigEndian); +} + +bool CUtlBuffer::IsBigEndian(void) +{ + return m_Byteswap.IsTargetBigEndian(); +} + + +//----------------------------------------------------------------------------- +// null terminate the buffer +//----------------------------------------------------------------------------- +void CUtlBuffer::AddNullTermination(void) +{ + if (m_Put > m_nMaxPut) + { + if (!IsReadOnly() && ((m_Error & PUT_OVERFLOW) == 0)) + { + // Add null termination value + if (CheckPut(1)) + { + int Index = m_Put - m_nOffset; + //Assert(m_Memory.IsIdxValid(Index)); + if (Index >= 0) + { + m_Memory[Index] = 0; + } + } + else + { + // Restore the overflow state, it was valid before... + m_Error &= ~PUT_OVERFLOW; + } + } + m_nMaxPut = m_Put; + } +} + + +//----------------------------------------------------------------------------- +// Converts a buffer from a CRLF buffer to a CR buffer (and back) +// Returns false if no conversion was necessary (and outBuf is left untouched) +// If the conversion occurs, outBuf will be cleared. +//----------------------------------------------------------------------------- +bool CUtlBuffer::ConvertCRLF(CUtlBuffer& outBuf) +{ + if (!IsText() || !outBuf.IsText()) + return false; + + if (ContainsCRLF() == outBuf.ContainsCRLF()) + return false; + + int nInCount = TellMaxPut(); + + outBuf.Purge(); + outBuf.EnsureCapacity(nInCount); + + bool bFromCRLF = ContainsCRLF(); + + // Start reading from the beginning + int nGet = TellGet(); + int nPut = TellPut(); + int nGetDelta = 0; + int nPutDelta = 0; + + const char* pBase = (const char*)Base(); + int nCurrGet = 0; + while (nCurrGet < nInCount) + { + const char* pCurr = &pBase[nCurrGet]; + if (bFromCRLF) + { + const char* pNext = strnistr(pCurr, "\r\n", nInCount - nCurrGet); + if (!pNext) + { + outBuf.Put(pCurr, nInCount - nCurrGet); + break; + } + + int nBytes = (size_t)pNext - (size_t)pCurr; + outBuf.Put(pCurr, nBytes); + outBuf.PutChar('\n'); + nCurrGet += nBytes + 2; + if (nGet >= nCurrGet - 1) + { + --nGetDelta; + } + if (nPut >= nCurrGet - 1) + { + --nPutDelta; + } + } + else + { + const char* pNext = strnchr(pCurr, '\n', nInCount - nCurrGet); + if (!pNext) + { + outBuf.Put(pCurr, nInCount - nCurrGet); + break; + } + + int nBytes = (size_t)pNext - (size_t)pCurr; + outBuf.Put(pCurr, nBytes); + outBuf.PutChar('\r'); + outBuf.PutChar('\n'); + nCurrGet += nBytes + 1; + if (nGet >= nCurrGet) + { + ++nGetDelta; + } + if (nPut >= nCurrGet) + { + ++nPutDelta; + } + } + } + + //Assert(nPut + nPutDelta <= outBuf.TellMaxPut()); + + outBuf.SeekGet(SEEK_HEAD, nGet + nGetDelta); + outBuf.SeekPut(SEEK_HEAD, nPut + nPutDelta); + + return true; +} + +//----------------------------------------------------------------------------- +// Fast swap +//----------------------------------------------------------------------------- +void CUtlBuffer::Swap(CUtlBuffer& buf) +{ + std::swap(m_Get, buf.m_Get); + std::swap(m_Put, buf.m_Put); + std::swap(m_nMaxPut, buf.m_nMaxPut); + std::swap(m_Error, buf.m_Error); + m_Memory.Swap(buf.m_Memory); +} + + +//----------------------------------------------------------------------------- +// Fast swap w/ a CUtlMemory. +//----------------------------------------------------------------------------- +void CUtlBuffer::Swap(CUtlMemory& mem) +{ + m_Get = 0; + m_Put = mem.Count(); + m_nMaxPut = mem.Count(); + m_Error = 0; + m_Memory.Swap(mem); +} + +//--------------------------------------------------------------------------- +// Implementation of CUtlInplaceBuffer +//--------------------------------------------------------------------------- + +CUtlInplaceBuffer::CUtlInplaceBuffer(int growSize /* = 0 */, int initSize /* = 0 */, int nFlags /* = 0 */) : + CUtlBuffer(growSize, initSize, nFlags) +{ +} + +bool CUtlInplaceBuffer::InplaceGetLinePtr(char** ppszInBufferPtr, int* pnLineLength) +{ + //Assert(IsText() && !ContainsCRLF()); + + int nLineLen = PeekLineLength(); + if (nLineLen <= 1) + { + SeekGet(SEEK_TAIL, 0); + return false; + } + + --nLineLen; // because it accounts for putting a terminating null-character + + char* pszLine = (char*) const_cast(PeekGet()); + SeekGet(SEEK_CURRENT, nLineLen); + + // Set the out args + if (ppszInBufferPtr) + *ppszInBufferPtr = pszLine; + + if (pnLineLength) + *pnLineLength = nLineLen; + + return true; +} + +char* CUtlInplaceBuffer::InplaceGetLinePtr(void) +{ + char* pszLine = NULL; + int nLineLen = 0; + + if (InplaceGetLinePtr(&pszLine, &nLineLen)) + { + //Assert(nLineLen >= 1); + + switch (pszLine[nLineLen - 1]) + { + case '\n': + case '\r': + pszLine[nLineLen - 1] = 0; + if (--nLineLen) + { + switch (pszLine[nLineLen - 1]) + { + case '\n': + case '\r': + pszLine[nLineLen - 1] = 0; + break; + } + } + break; + + default: + //Assert(pszLine[nLineLen] == 0); + break; + } + } + + return pszLine; +} \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/CUtlBuffer.h b/Amalgam/src/SDK/Definitions/Misc/CUtlBuffer.h new file mode 100644 index 00000000..a41ea509 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CUtlBuffer.h @@ -0,0 +1,987 @@ +#pragma once +#include "CUtlMemory.h" +#include "CUtlCharConversion.h" +#include "CByteSwap.h" +#include "BaseTypes.h" +#include "../Types.h" + +#define FORCEINLINE __forceinline +#define IN_CHARACTERSET( SetBuffer, character ) ((SetBuffer).set[ (unsigned char) (character) ]) + +struct characterset_t +{ + char set[256]; +}; + +class CUtlBuffer +{ +public: + enum SeekType_t + { + SEEK_HEAD = 0, + SEEK_CURRENT, + SEEK_TAIL + }; + + // flags + enum BufferFlags_t + { + TEXT_BUFFER = 0x1, // Describes how get + put work (as strings, or binary) + EXTERNAL_GROWABLE = 0x2, // This is used w/ external buffers and causes the utlbuf to switch to reallocatable memory if an overflow happens when Putting. + CONTAINS_CRLF = 0x4, // For text buffers only, does this contain \n or \n\r? + READ_ONLY = 0x8, // For external buffers; prevents null termination from happening. + AUTO_TABS_DISABLED = 0x10, // Used to disable/enable push/pop tabs + }; + + // Overflow functions when a get or put overflows + typedef bool (CUtlBuffer::* UtlBufferOverflowFunc_t)(int nSize); + + // Constructors for growable + external buffers for serialization/unserialization + CUtlBuffer(int growSize = 0, int initSize = 0, int nFlags = 0); + CUtlBuffer(const void* pBuffer, int size, int nFlags = 0); + // This one isn't actually defined so that we catch contructors that are trying to pass a bool in as the third param. + CUtlBuffer(const void* pBuffer, int size, bool crap); + + unsigned char GetFlags() const; + + // NOTE: This will assert if you attempt to recast it in a way that + // is not compatible. The only valid conversion is binary-> text w/CRLF + void SetBufferType(bool bIsText, bool bContainsCRLF); + + // Makes sure we've got at least this much memory + void EnsureCapacity(int num); + + // Attaches the buffer to external memory.... + void SetExternalBuffer(void* pMemory, int nSize, int nInitialPut, int nFlags = 0); + bool IsExternallyAllocated() const; + // Takes ownership of the passed memory, including freeing it when this buffer is destroyed. + void AssumeMemory(void* pMemory, int nSize, int nInitialPut, int nFlags = 0); + + // copies data from another buffer + void CopyBuffer(const CUtlBuffer& buffer); + void CopyBuffer(const void* pubData, int cubData); + + void Swap(CUtlBuffer& buf); + void Swap(CUtlMemory& mem); + + FORCEINLINE void ActivateByteSwappingIfBigEndian(void) + { + + } + + + // Controls endian-ness of binary utlbufs - default matches the current platform + void ActivateByteSwapping(bool bActivate); + void SetBigEndian(bool bigEndian); + bool IsBigEndian(void); + + // Resets the buffer; but doesn't free memory + void Clear(); + + // Clears out the buffer; frees memory + void Purge(); + + // Read stuff out. + // Binary mode: it'll just read the bits directly in, and characters will be + // read for strings until a null character is reached. + // Text mode: it'll parse the file, turning text #s into real numbers. + // GetString will read a string until a space is reached + char GetChar(); + unsigned char GetUnsignedChar(); + short GetShort(); + unsigned short GetUnsignedShort(); + int GetInt(); + int64 GetInt64(); + int GetIntHex(); + unsigned int GetUnsignedInt(); + float GetFloat(); + double GetDouble(); + template void GetString(char(&pString)[maxLenInChars]) + { + GetStringInternal(pString, maxLenInChars); + } + + void GetStringManualCharCount(char* pString, size_t maxLenInChars) + { + GetStringInternal(pString, maxLenInChars); + } + + void Get(void* pMem, int size); + void GetLine(char* pLine, int nMaxChars = 0); + + // Used for getting objects that have a byteswap datadesc defined + template void GetObjects(T* dest, int count = 1); + + // This will get at least 1 byte and up to nSize bytes. + // It will return the number of bytes actually read. + int GetUpTo(void* pMem, int nSize); + + // This version of GetString converts \" to \\ and " to \, etc. + // It also reads a " at the beginning and end of the string + void GetDelimitedString(CUtlCharConversion* pConv, char* pString, int nMaxChars = 0); + char GetDelimitedChar(CUtlCharConversion* pConv); + + // This will return the # of characters of the string about to be read out + // NOTE: The count will *include* the terminating 0!! + // In binary mode, it's the number of characters until the next 0 + // In text mode, it's the number of characters until the next space. + int PeekStringLength(); + + // This version of PeekStringLength converts \" to \\ and " to \, etc. + // It also reads a " at the beginning and end of the string + // NOTE: The count will *include* the terminating 0!! + // In binary mode, it's the number of characters until the next 0 + // In text mode, it's the number of characters between "s (checking for \") + // Specifying false for bActualSize will return the pre-translated number of characters + // including the delimiters and the escape characters. So, \n counts as 2 characters when bActualSize == false + // and only 1 character when bActualSize == true + int PeekDelimitedStringLength(CUtlCharConversion* pConv, bool bActualSize = true); + + // Just like scanf, but doesn't work in binary mode + int Scanf(const char* pFmt, ...); + int VaScanf(const char* pFmt, va_list list); + + // Eats white space, advances Get index + void EatWhiteSpace(); + + // Eats C++ style comments + bool EatCPPComment(); + + // (For text buffers only) + // Parse a token from the buffer: + // Grab all text that lies between a starting delimiter + ending delimiter + // (skipping whitespace that leads + trails both delimiters). + // If successful, the get index is advanced and the function returns true, + // otherwise the index is not advanced and the function returns false. + bool ParseToken(const char* pStartingDelim, const char* pEndingDelim, char* pString, int nMaxLen); + + // Advance the get index until after the particular string is found + // Do not eat whitespace before starting. Return false if it failed + // String test is case-insensitive. + bool GetToken(const char* pToken); + + // Parses the next token, given a set of character breaks to stop at + // Returns the length of the token parsed in bytes (-1 if none parsed) + int ParseToken(characterset_t* pBreaks, char* pTokenBuf, int nMaxLen, bool bParseComments = true); + + // Write stuff in + // Binary mode: it'll just write the bits directly in, and strings will be + // written with a null terminating character + // Text mode: it'll convert the numbers to text versions + // PutString will not write a terminating character + void PutChar(char c); + void PutUnsignedChar(unsigned char uc); + void PutUint64(uint64 ub); + void PutInt16(int16 s16); + void PutShort(short s); + void PutUnsignedShort(unsigned short us); + void PutInt(int i); + void PutInt64(int64 i); + void PutUnsignedInt(unsigned int u); + void PutFloat(float f); + void PutDouble(double d); + void PutString(const char* pString); + void Put(const void* pMem, int size); + + // Used for putting objects that have a byteswap datadesc defined + template void PutObjects(T* src, int count = 1); + + // This version of PutString converts \ to \\ and " to \", etc. + // It also places " at the beginning and end of the string + void PutDelimitedString(CUtlCharConversion* pConv, const char* pString); + void PutDelimitedChar(CUtlCharConversion* pConv, char c); + + // Just like printf, writes a terminating zero in binary mode + void Printf(const char* pFmt, ...); + void VaPrintf(const char* pFmt, va_list list); + + // What am I writing (put)/reading (get)? + void* PeekPut(int offset = 0); + const void* PeekGet(int offset = 0) const; + const void* PeekGet(int nMaxSize, int nOffset); + + // Where am I writing (put)/reading (get)? + int TellPut() const; + int TellGet() const; + + // What's the most I've ever written? + int TellMaxPut() const; + + // How many bytes remain to be read? + // NOTE: This is not accurate for streaming text files; it overshoots + int GetBytesRemaining() const; + + // Change where I'm writing (put)/reading (get) + void SeekPut(SeekType_t type, int offset); + void SeekGet(SeekType_t type, int offset); + + // Buffer base + const void* Base() const; + void* Base(); + // Returns the base as a const char*, only valid in text mode. + const char* String() const; + + // memory allocation size, does *not* reflect size written or read, + // use TellPut or TellGet for that + int Size() const; + + // Am I a text buffer? + bool IsText() const; + + // Can I grow if I'm externally allocated? + bool IsGrowable() const; + + // Am I valid? (overflow or underflow error), Once invalid it stays invalid + bool IsValid() const; + + // Do I contain carriage return/linefeeds? + bool ContainsCRLF() const; + + // Am I read-only + bool IsReadOnly() const; + + // Converts a buffer from a CRLF buffer to a CR buffer (and back) + // Returns false if no conversion was necessary (and outBuf is left untouched) + // If the conversion occurs, outBuf will be cleared. + bool ConvertCRLF(CUtlBuffer& outBuf); + + // Push/pop pretty-printing tabs + void PushTab(); + void PopTab(); + + // Temporarily disables pretty print + void EnableTabs(bool bEnable); + +protected: + // error flags + enum + { + PUT_OVERFLOW = 0x1, + GET_OVERFLOW = 0x2, + MAX_ERROR_FLAG = GET_OVERFLOW, + }; + + void SetOverflowFuncs(UtlBufferOverflowFunc_t getFunc, UtlBufferOverflowFunc_t putFunc); + + bool OnPutOverflow(int nSize); + bool OnGetOverflow(int nSize); + +protected: + // Checks if a get/put is ok + bool CheckPut(int size); + bool CheckGet(int size); + + void AddNullTermination(); + + // Methods to help with pretty-printing + bool WasLastCharacterCR(); + void PutTabs(); + + // Help with delimited stuff + char GetDelimitedCharInternal(CUtlCharConversion* pConv); + void PutDelimitedCharInternal(CUtlCharConversion* pConv, char c); + + // Default overflow funcs + bool PutOverflow(int nSize); + bool GetOverflow(int nSize); + + // Does the next bytes of the buffer match a pattern? + bool PeekStringMatch(int nOffset, const char* pString, int nLen); + + // Peek size of line to come, check memory bound + int PeekLineLength(); + + // How much whitespace should I skip? + int PeekWhiteSpace(int nOffset); + + // Checks if a peek get is ok + bool CheckPeekGet(int nOffset, int nSize); + + // Call this to peek arbitrarily long into memory. It doesn't fail unless + // it can't read *anything* new + bool CheckArbitraryPeekGet(int nOffset, int& nIncrement); + void GetStringInternal(char* pString, size_t maxLenInChars); + + template void GetType(T& dest, const char* pszFmt); + template void GetTypeBin(T& dest); + template void GetObject(T* src); + + template void PutType(T src, const char* pszFmt); + template void PutTypeBin(T src); + template void PutObject(T* src); + + CUtlMemory m_Memory; + int m_Get; + int m_Put; + + unsigned char m_Error; + unsigned char m_Flags; + unsigned char m_Reserved; +#if defined( _X360 ) + unsigned char pad; +#endif + + int m_nTab; + int m_nMaxPut; + int m_nOffset; + + UtlBufferOverflowFunc_t m_GetOverflowFunc; + UtlBufferOverflowFunc_t m_PutOverflowFunc; + + CByteswap m_Byteswap; +}; + +// Stream style output operators for CUtlBuffer +inline CUtlBuffer& operator<<(CUtlBuffer& b, char v) +{ + b.PutChar(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, unsigned char v) +{ + b.PutUnsignedChar(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, short v) +{ + b.PutShort(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, unsigned short v) +{ + b.PutUnsignedShort(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, int v) +{ + b.PutInt(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, unsigned int v) +{ + b.PutUnsignedInt(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, float v) +{ + b.PutFloat(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, double v) +{ + b.PutDouble(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, const char* pv) +{ + b.PutString(pv); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, const Vector& v) +{ + b << v.x << " " << v.y << " " << v.z; + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, const Vector2D& v) +{ + b << v.x << " " << v.y; + return b; +} + + +class CUtlInplaceBuffer : public CUtlBuffer +{ +public: + CUtlInplaceBuffer(int growSize = 0, int initSize = 0, int nFlags = 0); + + // + // Routines returning buffer-inplace-pointers + // +public: + // + // Upon success, determines the line length, fills out the pointer to the + // beginning of the line and the line length, advances the "get" pointer + // offset by the line length and returns "true". + // + // If end of file is reached or upon error returns "false". + // + // Note: the returned length of the line is at least one character because the + // trailing newline characters are also included as part of the line. + // + // Note: the pointer returned points into the local memory of this buffer, in + // case the buffer gets relocated or destroyed the pointer becomes invalid. + // + // e.g.: ------------- + // + // char *pszLine; + // int nLineLen; + // while ( pUtlInplaceBuffer->InplaceGetLinePtr( &pszLine, &nLineLen ) ) + // { + // ... + // } + // + // ------------- + // + // @param ppszInBufferPtr on return points into this buffer at start of line + // @param pnLineLength on return holds num bytes accessible via (*ppszInBufferPtr) + // + // @returns true if line was successfully read + // false when EOF is reached or error occurs + // + bool InplaceGetLinePtr( /* out */ char** ppszInBufferPtr, /* out */ int* pnLineLength); + + // + // Determines the line length, advances the "get" pointer offset by the line length, + // replaces the newline character with null-terminator and returns the initial pointer + // to now null-terminated line. + // + // If end of file is reached or upon error returns NULL. + // + // Note: the pointer returned points into the local memory of this buffer, in + // case the buffer gets relocated or destroyed the pointer becomes invalid. + // + // e.g.: ------------- + // + // while ( char *pszLine = pUtlInplaceBuffer->InplaceGetLinePtr() ) + // { + // ... + // } + // + // ------------- + // + // @returns ptr-to-zero-terminated-line if line was successfully read and buffer modified + // NULL when EOF is reached or error occurs + // + char* InplaceGetLinePtr(void); +}; + +//----------------------------------------------------------------------------- +// Where am I reading? +//----------------------------------------------------------------------------- +inline int CUtlBuffer::TellGet() const +{ + return m_Get; +} + + +//----------------------------------------------------------------------------- +// How many bytes remain to be read? +//----------------------------------------------------------------------------- +inline int CUtlBuffer::GetBytesRemaining() const +{ + return m_nMaxPut - TellGet(); +} + + +//----------------------------------------------------------------------------- +// What am I reading? +//----------------------------------------------------------------------------- +inline const void* CUtlBuffer::PeekGet(int offset) const +{ + return &m_Memory[m_Get + offset - m_nOffset]; +} + + +//----------------------------------------------------------------------------- +// Unserialization +//----------------------------------------------------------------------------- + +template +inline void CUtlBuffer::GetObject(T* dest) +{ + if (CheckGet(sizeof(T))) + { + if (!m_Byteswap.IsSwappingBytes() || (sizeof(T) == 1)) + { + *dest = *(T*)PeekGet(); + } + else + { + m_Byteswap.SwapFieldsToTargetEndian(dest, (T*)PeekGet()); + } + m_Get += sizeof(T); + } + else + { + Q_memset(dest, 0, sizeof(T)); + } +} + + +template +inline void CUtlBuffer::GetObjects(T* dest, int count) +{ + for (int i = 0; i < count; ++i, ++dest) + { + GetObject(dest); + } +} + + +template +inline void CUtlBuffer::GetTypeBin(T& dest) +{ + if (CheckGet(sizeof(T))) + { + if (!m_Byteswap.IsSwappingBytes() || (sizeof(T) == 1)) + { + dest = *(T*)PeekGet(); + } + else + { + m_Byteswap.SwapBufferToTargetEndian(&dest, (T*)PeekGet()); + } + m_Get += sizeof(T); + } + else + { + dest = 0; + } +} + +template <> +inline void CUtlBuffer::GetTypeBin< float >(float& dest) +{ + if (CheckGet(sizeof(float))) + { + uintptr_t pData = (uintptr_t)PeekGet(); + { + // aligned read + dest = *(float*)pData; + } + if (m_Byteswap.IsSwappingBytes()) + { + m_Byteswap.SwapBufferToTargetEndian< float >(&dest, &dest); + } + m_Get += sizeof(float); + } + else + { + dest = 0; + } +} + +template +inline void CUtlBuffer::GetType(T& dest, const char* pszFmt) +{ + if (!IsText()) + { + GetTypeBin(dest); + } + else + { + dest = 0; + Scanf(pszFmt, &dest); + } +} + +inline char CUtlBuffer::GetChar() +{ + char c; + GetType(c, "%c"); + return c; +} + +inline unsigned char CUtlBuffer::GetUnsignedChar() +{ + unsigned char c; + GetType(c, "%u"); + return c; +} + +inline short CUtlBuffer::GetShort() +{ + short s; + GetType(s, "%d"); + return s; +} + +inline unsigned short CUtlBuffer::GetUnsignedShort() +{ + unsigned short s; + GetType(s, "%u"); + return s; +} + +inline int CUtlBuffer::GetInt() +{ + int i; + GetType(i, "%d"); + return i; +} + +inline int64 CUtlBuffer::GetInt64() +{ + int64 i; + GetType(i, "%lld"); + return i; +} + +inline int CUtlBuffer::GetIntHex() +{ + int i; + GetType(i, "%x"); + return i; +} + +inline unsigned int CUtlBuffer::GetUnsignedInt() +{ + unsigned int u; + GetType(u, "%u"); + return u; +} + +inline float CUtlBuffer::GetFloat() +{ + float f; + GetType(f, "%f"); + return f; +} + +inline double CUtlBuffer::GetDouble() +{ + double d; + GetType(d, "%f"); + return d; +} + + +//----------------------------------------------------------------------------- +// Where am I writing? +//----------------------------------------------------------------------------- +inline unsigned char CUtlBuffer::GetFlags() const +{ + return m_Flags; +} + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +inline bool CUtlBuffer::IsExternallyAllocated() const +{ + return m_Memory.IsExternallyAllocated(); +} + + +//----------------------------------------------------------------------------- +// Where am I writing? +//----------------------------------------------------------------------------- +inline int CUtlBuffer::TellPut() const +{ + return m_Put; +} + + +//----------------------------------------------------------------------------- +// What's the most I've ever written? +//----------------------------------------------------------------------------- +inline int CUtlBuffer::TellMaxPut() const +{ + return m_nMaxPut; +} + + +//----------------------------------------------------------------------------- +// What am I reading? +//----------------------------------------------------------------------------- +inline void* CUtlBuffer::PeekPut(int offset) +{ + return &m_Memory[m_Put + offset - m_nOffset]; +} + + +//----------------------------------------------------------------------------- +// Various put methods +//----------------------------------------------------------------------------- + +template +inline void CUtlBuffer::PutObject(T* src) +{ + if (CheckPut(sizeof(T))) + { + if (!m_Byteswap.IsSwappingBytes() || (sizeof(T) == 1)) + { + *(T*)PeekPut() = *src; + } + else + { + m_Byteswap.SwapFieldsToTargetEndian((T*)PeekPut(), src); + } + m_Put += sizeof(T); + AddNullTermination(); + } +} + + +template +inline void CUtlBuffer::PutObjects(T* src, int count) +{ + for (int i = 0; i < count; ++i, ++src) + { + PutObject(src); + } +} + + +template +inline void CUtlBuffer::PutTypeBin(T src) +{ + if (CheckPut(sizeof(T))) + { + if (!m_Byteswap.IsSwappingBytes() || (sizeof(T) == 1)) + { + *(T*)PeekPut() = src; + } + else + { + m_Byteswap.SwapBufferToTargetEndian((T*)PeekPut(), &src); + } + m_Put += sizeof(T); + AddNullTermination(); + } +} + +template +inline void CUtlBuffer::PutType(T src, const char* pszFmt) +{ + if (!IsText()) + { + PutTypeBin(src); + } + else + { + Printf(pszFmt, src); + } +} + +//----------------------------------------------------------------------------- +// Methods to help with pretty-printing +//----------------------------------------------------------------------------- +inline bool CUtlBuffer::WasLastCharacterCR() +{ + if (!IsText() || (TellPut() == 0)) + return false; + return (*(const char*)PeekPut(-1) == '\n'); +} + +inline void CUtlBuffer::PutTabs() +{ + int nTabCount = (m_Flags & AUTO_TABS_DISABLED) ? 0 : m_nTab; + for (int i = nTabCount; --i >= 0; ) + { + PutTypeBin('\t'); + } +} + + +//----------------------------------------------------------------------------- +// Push/pop pretty-printing tabs +//----------------------------------------------------------------------------- +inline void CUtlBuffer::PushTab() +{ + ++m_nTab; +} + +inline void CUtlBuffer::PopTab() +{ + if (--m_nTab < 0) + { + m_nTab = 0; + } +} + + +//----------------------------------------------------------------------------- +// Temporarily disables pretty print +//----------------------------------------------------------------------------- +inline void CUtlBuffer::EnableTabs(bool bEnable) +{ + if (bEnable) + { + m_Flags &= ~AUTO_TABS_DISABLED; + } + else + { + m_Flags |= AUTO_TABS_DISABLED; + } +} + +inline void CUtlBuffer::PutChar(char c) +{ + if (WasLastCharacterCR()) + { + PutTabs(); + } + + PutTypeBin(c); +} + +inline void CUtlBuffer::PutUnsignedChar(unsigned char c) +{ + PutType(c, "%u"); +} + +inline void CUtlBuffer::PutUint64(uint64 ub) +{ + PutType(ub, "%llu"); +} + +inline void CUtlBuffer::PutInt16(int16 s16) +{ + PutType(s16, "%d"); +} + +inline void CUtlBuffer::PutShort(short s) +{ + PutType(s, "%d"); +} + +inline void CUtlBuffer::PutUnsignedShort(unsigned short s) +{ + PutType(s, "%u"); +} + +inline void CUtlBuffer::PutInt(int i) +{ + PutType(i, "%d"); +} + +inline void CUtlBuffer::PutInt64(int64 i) +{ + PutType(i, "%llu"); +} + +inline void CUtlBuffer::PutUnsignedInt(unsigned int u) +{ + PutType(u, "%u"); +} + +inline void CUtlBuffer::PutFloat(float f) +{ + PutType(f, "%f"); +} + +inline void CUtlBuffer::PutDouble(double d) +{ + PutType(d, "%f"); +} + + +//----------------------------------------------------------------------------- +// Am I a text buffer? +//----------------------------------------------------------------------------- +inline bool CUtlBuffer::IsText() const +{ + return (m_Flags & TEXT_BUFFER) != 0; +} + + +//----------------------------------------------------------------------------- +// Can I grow if I'm externally allocated? +//----------------------------------------------------------------------------- +inline bool CUtlBuffer::IsGrowable() const +{ + return (m_Flags & EXTERNAL_GROWABLE) != 0; +} + + +//----------------------------------------------------------------------------- +// Am I valid? (overflow or underflow error), Once invalid it stays invalid +//----------------------------------------------------------------------------- +inline bool CUtlBuffer::IsValid() const +{ + return m_Error == 0; +} + + +//----------------------------------------------------------------------------- +// Do I contain carriage return/linefeeds? +//----------------------------------------------------------------------------- +inline bool CUtlBuffer::ContainsCRLF() const +{ + return IsText() && ((m_Flags & CONTAINS_CRLF) != 0); +} + + +//----------------------------------------------------------------------------- +// Am I read-only +//----------------------------------------------------------------------------- +inline bool CUtlBuffer::IsReadOnly() const +{ + return (m_Flags & READ_ONLY) != 0; +} + + +//----------------------------------------------------------------------------- +// Buffer base and size +//----------------------------------------------------------------------------- +inline const void* CUtlBuffer::Base() const +{ + return m_Memory.Base(); +} + +inline void* CUtlBuffer::Base() +{ + return m_Memory.Base(); +} + +// Returns the base as a const char*, only valid in text mode. +inline const char* CUtlBuffer::String() const +{ + //Assert(IsText()); + return reinterpret_cast(m_Memory.Base()); +} + +inline int CUtlBuffer::Size() const +{ + return m_Memory.NumAllocated(); +} + + +//----------------------------------------------------------------------------- +// Clears out the buffer; frees memory +//----------------------------------------------------------------------------- +inline void CUtlBuffer::Clear() +{ + m_Get = 0; + m_Put = 0; + m_Error = 0; + m_nOffset = 0; + m_nMaxPut = -1; + AddNullTermination(); +} + +inline void CUtlBuffer::Purge() +{ + m_Get = 0; + m_Put = 0; + m_nOffset = 0; + m_nMaxPut = 0; + m_Error = 0; + m_Memory.Purge(); +} + +inline void CUtlBuffer::CopyBuffer(const CUtlBuffer& buffer) +{ + CopyBuffer(buffer.Base(), buffer.TellPut()); +} + +inline void CUtlBuffer::CopyBuffer(const void* pubData, int cubData) +{ + Clear(); + if (cubData) + { + Put(pubData, cubData); + } +} \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/CUtlCharConversion.cpp b/Amalgam/src/SDK/Definitions/Misc/CUtlCharConversion.cpp new file mode 100644 index 00000000..c43bbd08 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CUtlCharConversion.cpp @@ -0,0 +1,89 @@ +#include "CUtlCharConversion.h" + +#include + +#pragma warning (disable:4267) + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CUtlCharConversion::CUtlCharConversion(char nEscapeChar, const char* pDelimiter, int nCount, ConversionArray_t* pArray) +{ + m_nEscapeChar = nEscapeChar; + m_pDelimiter = pDelimiter; + m_nCount = nCount; + m_nDelimiterLength = strlen(pDelimiter); + m_nMaxConversionLength = 0; + + memset(m_pReplacements, 0, sizeof(m_pReplacements)); + + for (int i = 0; i < nCount; ++i) + { + m_pList[i] = pArray[i].m_nActualChar; + ConversionInfo_t& info = m_pReplacements[(unsigned char)m_pList[i]]; + //Assert(info.m_pReplacementString == 0); + info.m_pReplacementString = pArray[i].m_pReplacementString; + info.m_nLength = strlen(info.m_pReplacementString); + if (info.m_nLength > m_nMaxConversionLength) + { + m_nMaxConversionLength = info.m_nLength; + } + } +} + + +//----------------------------------------------------------------------------- +// Escape character + delimiter +//----------------------------------------------------------------------------- +char CUtlCharConversion::GetEscapeChar() const +{ + return m_nEscapeChar; +} + +const char* CUtlCharConversion::GetDelimiter() const +{ + return m_pDelimiter; +} + +int CUtlCharConversion::GetDelimiterLength() const +{ + return m_nDelimiterLength; +} + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +const char* CUtlCharConversion::GetConversionString(char c) const +{ + return m_pReplacements[(unsigned char)c].m_pReplacementString; +} + +int CUtlCharConversion::GetConversionLength(char c) const +{ + return m_pReplacements[(unsigned char)c].m_nLength; +} + +int CUtlCharConversion::MaxConversionLength() const +{ + return m_nMaxConversionLength; +} + + +//----------------------------------------------------------------------------- +// Finds a conversion for the passed-in string, returns length +//----------------------------------------------------------------------------- +char CUtlCharConversion::FindConversion(const char* pString, int* pLength) +{ + for (int i = 0; i < m_nCount; ++i) + { + if (!strcmp(pString, m_pReplacements[(unsigned char)m_pList[i]].m_pReplacementString)) + { + *pLength = m_pReplacements[(unsigned char)m_pList[i]].m_nLength; + return m_pList[i]; + } + } + + *pLength = 0; + return '\0'; +} \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/CUtlCharConversion.h b/Amalgam/src/SDK/Definitions/Misc/CUtlCharConversion.h new file mode 100644 index 00000000..4c27219b --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CUtlCharConversion.h @@ -0,0 +1,38 @@ +#pragma once + +class CUtlCharConversion +{ +public: + struct ConversionArray_t + { + char m_nActualChar; + const char* m_pReplacementString; + }; + + CUtlCharConversion(char nEscapeChar, const char* pDelimiter, int nCount, ConversionArray_t* pArray); + char GetEscapeChar() const; + const char* GetDelimiter() const; + int GetDelimiterLength() const; + + const char* GetConversionString(char c) const; + int GetConversionLength(char c) const; + int MaxConversionLength() const; + + // Finds a conversion for the passed-in string, returns length + virtual char FindConversion(const char* pString, int* pLength); + +protected: + struct ConversionInfo_t + { + int m_nLength; + const char* m_pReplacementString; + }; + + char m_nEscapeChar; + const char* m_pDelimiter; + int m_nDelimiterLength; + int m_nCount; + int m_nMaxConversionLength; + char m_pList[256]; + ConversionInfo_t m_pReplacements[256]; +}; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/UtlIntrusiveList.h b/Amalgam/src/SDK/Definitions/Misc/CUtlIntrusiveList.h similarity index 89% rename from Amalgam/src/SDK/Definitions/Misc/UtlIntrusiveList.h rename to Amalgam/src/SDK/Definitions/Misc/CUtlIntrusiveList.h index 90427ff2..8ecdcc04 100644 --- a/Amalgam/src/SDK/Definitions/Misc/UtlIntrusiveList.h +++ b/Amalgam/src/SDK/Definitions/Misc/CUtlIntrusiveList.h @@ -1,42 +1,8 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Intrusive linked list templates, both for singly and doubly linked lists -// -// $Revision: $ -// $NoKeywords: $ -//===========================================================================// +#pragma once #ifndef UTILINTRUSIVELIST_H #define UTILINTRUSIVELIST_H -#ifdef _WIN32 -#pragma once -#endif - - - -// -// These templates are used for intrusive linked list classes. Intrusive linked list templates -// force the structs and classes contained within them to have their own m_pNext, (optionally), -// m_pPrev, and other fields contained within. All memory management is up to the caller and their -// classes. No data will ever be copied. Nodes can only exist on one list at a time, because of -// only having on m_Next field, and manipulating the list while walking it requires that care on -// the part of the caller. All accessing and searching functions work by passing and returning -// pointers. -// -// -// -// naming and field conventions: -// functions referring to a DList are for doubly linked lists. nodes must have m_pHead and -// m_pPrev pointer fields. -// Functions using Priority require an m_Priority field, which must be comparable. -// -// Some functions are mean for use with lists which maintain both a head and tail pointer -// in order to support fast adding to the end. - - -/// validates that the doubly linked list has the proper structure, pointer-wise - namespace IntrusiveList { #ifdef SUPERSLOW_DEBUG_VERSION @@ -44,17 +10,17 @@ namespace IntrusiveList { if (head) { - Assert(head->m_pPrev == 0); + //Assert(head->m_pPrev == 0); } while (head) { if (head->m_pNext) { - Assert(head->m_pNext->m_pPrev == head); + //Assert(head->m_pNext->m_pPrev == head); } if (head->m_pPrev) { - Assert(head->m_pPrev->m_pNext == head); + //Assert(head->m_pPrev->m_pNext == head); } head = head->m_pNext; } @@ -75,15 +41,15 @@ namespace IntrusiveList T* p = which->m_pPrev; T* pp = p->m_pPrev; T* n = which->m_pNext; - Assert(p->m_pNext == which); + //Assert(p->m_pNext == which); if (n) { - Assert(n->m_pPrev == which); + //Assert(n->m_pPrev == which); n->m_pPrev = p; } if (pp) { - Assert(pp->m_pNext == p); + //Assert(pp->m_pNext == p); pp->m_pNext = which; } else @@ -105,11 +71,11 @@ namespace IntrusiveList { if (which->m_pPrev) { - Assert(which->m_pPrev->m_pNext == which); + //Assert(which->m_pPrev->m_pNext == which); which->m_pPrev->m_pNext = which->m_pNext; if (which->m_pNext) { - Assert(which->m_pNext->m_pPrev == which); + //Assert(which->m_pNext->m_pPrev == which); which->m_pNext->m_pPrev = which->m_pPrev; } } @@ -120,7 +86,7 @@ namespace IntrusiveList head = which->m_pNext; if (head) { - Assert(head->m_pPrev == which); + //Assert(head->m_pPrev == which); head->m_pPrev = 0; } } @@ -191,7 +157,7 @@ namespace IntrusiveList { if (!tailptr) { - Assert(!head); + //Assert(!head); which->m_pPrev = which->m_pNext = 0; tailptr = head = which; } @@ -214,11 +180,11 @@ namespace IntrusiveList } if (which->m_pPrev) { - Assert(which->m_pPrev->m_pNext == which); + //Assert(which->m_pPrev->m_pNext == which); which->m_pPrev->m_pNext = which->m_pNext; if (which->m_pNext) { - Assert(which->m_pNext->m_pPrev == which); + //Assert(which->m_pNext->m_pPrev == which); which->m_pNext->m_pPrev = which->m_pPrev; } } @@ -229,7 +195,7 @@ namespace IntrusiveList head = which->m_pNext; if (head) { - Assert(head->m_pPrev == which); + //Assert(head->m_pPrev == which); head->m_pPrev = 0; } } @@ -249,11 +215,11 @@ namespace IntrusiveList } if (which->m_pPrev) { - Assert(which->m_pPrev->m_pNext == which); + //Assert(which->m_pPrev->m_pNext == which); which->m_pPrev->m_pNext = which->m_pNext; if (which->m_pNext) { - Assert(which->m_pNext->m_pPrev == which); + //Assert(which->m_pNext->m_pPrev == which); which->m_pNext->m_pPrev = which->m_pPrev; } } @@ -264,7 +230,7 @@ namespace IntrusiveList head = which->m_pNext; if (head) { - Assert(head->m_pPrev == which); + //Assert(head->m_pPrev == which); head->m_pPrev = 0; } } @@ -486,7 +452,7 @@ namespace IntrusiveList // the head and tail pointer can be modified by this routine. template void AddToEndWithTail(T*& head, T*& tail, V* node) { - Assert((head && tail) || ((!head) && (!tail))); + //Assert((head && tail) || ((!head) && (!tail))); node->m_pNext = 0; if (!head) { diff --git a/Amalgam/src/SDK/Definitions/Misc/CUtlMemory.h b/Amalgam/src/SDK/Definitions/Misc/CUtlMemory.h new file mode 100644 index 00000000..3a88bba4 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CUtlMemory.h @@ -0,0 +1,1060 @@ +#pragma once +#include "../Interfaces/IMemAlloc.h" + +#pragma warning (push) +#pragma warning (disable:4100) +#pragma warning (disable:4514) + +#ifdef UTLMEMORY_TRACK +#define UTLMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "Sum of all UtlMemory", 0, m_nAllocationCount * sizeof(T), m_nAllocationCount * sizeof(T), 0 ) +#define UTLMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "Sum of all UtlMemory", 0, m_nAllocationCount * sizeof(T), m_nAllocationCount * sizeof(T), 0 ) +#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( typeid(*this).name() ) +#define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name()) +#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__) +#else +#define UTLMEMORY_TRACK_ALLOC() ((void)0) +#define UTLMEMORY_TRACK_FREE() ((void)0) +#define MEM_ALLOC_CREDIT_CLASS() ((void)0) +#define MEM_ALLOC_CLASSNAME(type) ((void)0) +#define MEM_ALLOC_CREDIT() ((void)0) +#endif + +//----------------------------------------------------------------------------- +// The CUtlMemory class: +// A growable memory class which doubles in size by default. +//----------------------------------------------------------------------------- +template< class T, class I = int > +class CUtlMemory +{ +public: + // constructor, destructor + CUtlMemory(int nGrowSize = 0, int nInitSize = 0); + CUtlMemory(T* pMemory, int numElements); + CUtlMemory(const T* pMemory, int numElements); + ~CUtlMemory(); + + // Set the size by which the memory grows + void Init(int nGrowSize = 0, int nInitSize = 0); + + class Iterator_t + { + public: + Iterator_t(I i) : index(i) {} + I index; + + bool operator==(const Iterator_t it) const { return index == it.index; } + bool operator!=(const Iterator_t it) const { return index != it.index; } + }; + Iterator_t First() const { return Iterator_t(IsIdxValid(0) ? 0 : InvalidIndex()); } + Iterator_t Next(const Iterator_t& it) const { return Iterator_t(IsIdxValid(it.index + 1) ? it.index + 1 : InvalidIndex()); } + I GetIndex(const Iterator_t& it) const { return it.index; } + bool IsIdxAfter(I i, const Iterator_t& it) const { return i > it.index; } + bool IsValidIterator(const Iterator_t& it) const { return IsIdxValid(it.index); } + Iterator_t InvalidIterator() const { return Iterator_t(InvalidIndex()); } + + // element access + T& operator[](I i); + const T& operator[](I i) const; + T& Element(I i); + const T& Element(I i) const; + + // Can we use this index? + bool IsIdxValid(I i) const; + + // Specify the invalid ('null') index that we'll only return on failure + static const I INVALID_INDEX = (I)-1; // For use with COMPILE_TIME_ASSERT + static I InvalidIndex() { return INVALID_INDEX; } + + // Gets the base address (can change when adding elements!) + T* Base(); + const T* Base() const; + + // Attaches the buffer to external memory.... + void SetExternalBuffer(T* pMemory, int numElements); + void SetExternalBuffer(const T* pMemory, int numElements); + // Takes ownership of the passed memory, including freeing it when this buffer is destroyed. + void AssumeMemory(T* pMemory, int nSize); + + // Fast swap + void Swap(CUtlMemory< T, I >& mem); + + // Switches the buffer from an external memory buffer to a reallocatable buffer + // Will copy the current contents of the external buffer to the reallocatable buffer + void ConvertToGrowableMemory(int nGrowSize); + + // Size + int NumAllocated() const; + int Count() const; + + // Grows the memory, so that at least allocated + num elements are allocated + void Grow(int num = 1); + + // Makes sure we've got at least this much memory + void EnsureCapacity(int num); + + // Memory deallocation + void Purge(); + + // Purge all but the given number of elements + void Purge(int numElements); + + // is the memory externally allocated? + bool IsExternallyAllocated() const; + + // is the memory read only? + bool IsReadOnly() const; + + // Set the size by which the memory grows + void SetGrowSize(int size); + +protected: + void ValidateGrowSize() + { +#ifdef _X360 + if (m_nGrowSize && m_nGrowSize != EXTERNAL_BUFFER_MARKER) + { + // Max grow size at 128 bytes on XBOX + const int MAX_GROW = 128; + if (m_nGrowSize * sizeof(T) > MAX_GROW) + { + m_nGrowSize = max(1, MAX_GROW / sizeof(T)); + } + } +#endif + } + + enum + { + EXTERNAL_BUFFER_MARKER = -1, + EXTERNAL_CONST_BUFFER_MARKER = -2, + }; + + T* m_pMemory; + int m_nAllocationCount; + int m_nGrowSize; +}; + + +//----------------------------------------------------------------------------- +// The CUtlMemory class: +// A growable memory class which doubles in size by default. +//----------------------------------------------------------------------------- +template< class T, size_t SIZE, class I = int > +class CUtlMemoryFixedGrowable : public CUtlMemory< T, I > +{ + typedef CUtlMemory< T, I > BaseClass; + +public: + CUtlMemoryFixedGrowable(int nGrowSize = 0, int nInitSize = SIZE) : BaseClass(m_pFixedMemory, SIZE) + { + //Assert(nInitSize == 0 || nInitSize == SIZE); + m_nMallocGrowSize = nGrowSize; + } + + void Grow(int nCount = 1) + { + if (this->IsExternallyAllocated()) + { + this->ConvertToGrowableMemory(m_nMallocGrowSize); + } + BaseClass::Grow(nCount); + } + + void EnsureCapacity(int num) + { + if (CUtlMemory::m_nAllocationCount >= num) + return; + + if (this->IsExternallyAllocated()) + { + // Can't grow a buffer whose memory was externally allocated + this->ConvertToGrowableMemory(m_nMallocGrowSize); + } + + BaseClass::EnsureCapacity(num); + } + +private: + int m_nMallocGrowSize; + T m_pFixedMemory[SIZE]; +}; + +//----------------------------------------------------------------------------- +// The CUtlMemoryFixed class: +// A fixed memory class +//----------------------------------------------------------------------------- +template< typename T, size_t SIZE, int nAlignment = 0 > +class CUtlMemoryFixed +{ +public: + // constructor, destructor + CUtlMemoryFixed(int nGrowSize = 0, int nInitSize = 0) { /*Assert(nInitSize == 0 || nInitSize == SIZE);*/ } + CUtlMemoryFixed(T* pMemory, int numElements) { /*Assert(0);*/ } + + // Can we use this index? + // Use unsigned math to improve performance + bool IsIdxValid(int i) const { return (size_t)i < SIZE; } + + // Specify the invalid ('null') index that we'll only return on failure + static const int INVALID_INDEX = -1; // For use with COMPILE_TIME_ASSERT + static int InvalidIndex() { return INVALID_INDEX; } + + // Gets the base address + T* Base() { if (nAlignment == 0) return (T*)(&m_Memory[0]); else return (T*)AlignValue(&m_Memory[0], nAlignment); } + const T* Base() const { if (nAlignment == 0) return (T*)(&m_Memory[0]); else return (T*)AlignValue(&m_Memory[0], nAlignment); } + + // element access + // Use unsigned math and inlined checks to improve performance. + T& operator[](int i) { /*Assert((size_t)i < SIZE);*/ return Base()[i]; } + const T& operator[](int i) const { /*Assert((size_t)i < SIZE);*/ return Base()[i]; } + T& Element(int i) { /*Assert((size_t)i < SIZE);*/ return Base()[i]; } + const T& Element(int i) const { /*Assert((size_t)i < SIZE);*/ return Base()[i]; } + + // Attaches the buffer to external memory.... + void SetExternalBuffer(T* pMemory, int numElements) { /*Assert(0);*/ } + + // Size + int NumAllocated() const { return SIZE; } + int Count() const { return SIZE; } + + // Grows the memory, so that at least allocated + num elements are allocated + void Grow(int num = 1) { /*Assert(0);*/ } + + // Makes sure we've got at least this much memory + void EnsureCapacity(int num) { /*Assert(num <= SIZE);*/ } + + // Memory deallocation + void Purge() {} + + // Purge all but the given number of elements (NOT IMPLEMENTED IN CUtlMemoryFixed) + void Purge(int numElements) { /*Assert(0);*/ } + + // is the memory externally allocated? + bool IsExternallyAllocated() const { return false; } + + // Set the size by which the memory grows + void SetGrowSize(int size) {} + + class Iterator_t + { + public: + Iterator_t(int i) : index(i) {} + int index; + bool operator==(const Iterator_t it) const { return index == it.index; } + bool operator!=(const Iterator_t it) const { return index != it.index; } + }; + Iterator_t First() const { return Iterator_t(IsIdxValid(0) ? 0 : InvalidIndex()); } + Iterator_t Next(const Iterator_t& it) const { return Iterator_t(IsIdxValid(it.index + 1) ? it.index + 1 : InvalidIndex()); } + int GetIndex(const Iterator_t& it) const { return it.index; } + bool IsIdxAfter(int i, const Iterator_t& it) const { return i > it.index; } + bool IsValidIterator(const Iterator_t& it) const { return IsIdxValid(it.index); } + Iterator_t InvalidIterator() const { return Iterator_t(InvalidIndex()); } + +private: + char m_Memory[SIZE * sizeof(T) + nAlignment]; +}; + +#if defined(POSIX) +// From Chris Green: Memory is a little fuzzy but I believe this class did +// something fishy with respect to msize and alignment that was OK under our +// allocator, the glibc allocator, etc but not the valgrind one (which has no +// padding because it detects all forms of head/tail overwrite, including +// writing 1 byte past a 1 byte allocation). +#define REMEMBER_ALLOC_SIZE_FOR_VALGRIND 1 +#endif + +//----------------------------------------------------------------------------- +// The CUtlMemoryConservative class: +// A dynamic memory class that tries to minimize overhead (itself small, no custom grow factor) +//----------------------------------------------------------------------------- +template< typename T > +class CUtlMemoryConservative +{ + +public: + // constructor, destructor + CUtlMemoryConservative(int nGrowSize = 0, int nInitSize = 0) : m_pMemory(NULL) + { +#ifdef REMEMBER_ALLOC_SIZE_FOR_VALGRIND + m_nCurAllocSize = 0; +#endif + + } + CUtlMemoryConservative(T* pMemory, int numElements) { /*Assert(0);*/ } + ~CUtlMemoryConservative() { if (m_pMemory) free(m_pMemory); } + + // Can we use this index? +#if _DEBUG + bool IsIdxValid(int i) const { return (i >= 0); } +#else + bool IsIdxValid(int i) const { return (i >= 0 && i < NumAllocated()); } +#endif + static int InvalidIndex() { return -1; } + + // Gets the base address + T* Base() { return m_pMemory; } + const T* Base() const { return m_pMemory; } + + // element access + T& operator[](int i) { /*Assert(IsIdxValid(i));*/ return Base()[i]; } + const T& operator[](int i) const { /*Assert(IsIdxValid(i));*/ return Base()[i]; } + T& Element(int i) { /*Assert(IsIdxValid(i));*/ return Base()[i]; } + const T& Element(int i) const { /*Assert(IsIdxValid(i));*/ return Base()[i]; } + + // Attaches the buffer to external memory.... + void SetExternalBuffer(T* pMemory, int numElements) { /*Assert(0);*/ } + + // Size + FORCEINLINE void RememberAllocSize(size_t sz) + { +#ifdef REMEMBER_ALLOC_SIZE_FOR_VALGRIND + m_nCurAllocSize = sz; +#endif + } + + size_t AllocSize(void) const + { +#ifdef REMEMBER_ALLOC_SIZE_FOR_VALGRIND + return m_nCurAllocSize; +#else + return (m_pMemory) ? I::MemAlloc->GetSize(m_pMemory) : 0; +#endif + } + + int NumAllocated() const + { + return AllocSize() / sizeof(T); + } + int Count() const + { + return NumAllocated(); + } + + FORCEINLINE void ReAlloc(size_t sz) + { + m_pMemory = (T*)realloc(m_pMemory, sz); + RememberAllocSize(sz); + } + // Grows the memory, so that at least allocated + num elements are allocated + void Grow(int num = 1) + { + int nCurN = NumAllocated(); + ReAlloc((nCurN + num) * sizeof(T)); + } + + // Makes sure we've got at least this much memory + void EnsureCapacity(int num) + { + size_t nSize = sizeof(T) * MAX(num, Count()); + ReAlloc(nSize); + } + + // Memory deallocation + void Purge() + { + free(m_pMemory); + RememberAllocSize(0); + m_pMemory = NULL; + } + + // Purge all but the given number of elements + void Purge(int numElements) { ReAlloc(numElements * sizeof(T)); } + + // is the memory externally allocated? + bool IsExternallyAllocated() const { return false; } + + // Set the size by which the memory grows + void SetGrowSize(int size) {} + + class Iterator_t + { + public: + Iterator_t(int i, int _limit) : index(i), limit(_limit) {} + int index; + int limit; + bool operator==(const Iterator_t it) const { return index == it.index; } + bool operator!=(const Iterator_t it) const { return index != it.index; } + }; + Iterator_t First() const { int limit = NumAllocated(); return Iterator_t(limit ? 0 : InvalidIndex(), limit); } + Iterator_t Next(const Iterator_t& it) const { return Iterator_t((it.index + 1 < it.limit) ? it.index + 1 : InvalidIndex(), it.limit); } + int GetIndex(const Iterator_t& it) const { return it.index; } + bool IsIdxAfter(int i, const Iterator_t& it) const { return i > it.index; } + bool IsValidIterator(const Iterator_t& it) const { return IsIdxValid(it.index) && (it.index < it.limit); } + Iterator_t InvalidIterator() const { return Iterator_t(InvalidIndex(), 0); } + +private: + T* m_pMemory; +#ifdef REMEMBER_ALLOC_SIZE_FOR_VALGRIND + size_t m_nCurAllocSize; +#endif + +}; + + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- + +template< class T, class I > +CUtlMemory::CUtlMemory(int nGrowSize, int nInitAllocationCount) : m_pMemory(0), +m_nAllocationCount(nInitAllocationCount), m_nGrowSize(nGrowSize) +{ + ValidateGrowSize(); + //Assert(nGrowSize >= 0); + if (m_nAllocationCount) + { + UTLMEMORY_TRACK_ALLOC(); + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T)); + } +} + +template< class T, class I > +CUtlMemory::CUtlMemory(T* pMemory, int numElements) : m_pMemory(pMemory), +m_nAllocationCount(numElements) +{ + // Special marker indicating externally supplied modifyable memory + m_nGrowSize = EXTERNAL_BUFFER_MARKER; +} + +template< class T, class I > +CUtlMemory::CUtlMemory(const T* pMemory, int numElements) : m_pMemory((T*)pMemory), +m_nAllocationCount(numElements) +{ + // Special marker indicating externally supplied modifyable memory + m_nGrowSize = EXTERNAL_CONST_BUFFER_MARKER; +} + +template< class T, class I > +CUtlMemory::~CUtlMemory() +{ + Purge(); +} + +template< class T, class I > +void CUtlMemory::Init(int nGrowSize /*= 0*/, int nInitSize /*= 0*/) +{ + Purge(); + + m_nGrowSize = nGrowSize; + m_nAllocationCount = nInitSize; + ValidateGrowSize(); + //Assert(nGrowSize >= 0); + if (m_nAllocationCount) + { + UTLMEMORY_TRACK_ALLOC(); + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T)); + } +} + +//----------------------------------------------------------------------------- +// Fast swap +//----------------------------------------------------------------------------- +template< class T, class I > +void CUtlMemory::Swap(CUtlMemory& mem) +{ + std::swap(m_nGrowSize, mem.m_nGrowSize); + std::swap(m_pMemory, mem.m_pMemory); + std::swap(m_nAllocationCount, mem.m_nAllocationCount); +} + + +//----------------------------------------------------------------------------- +// Switches the buffer from an external memory buffer to a reallocatable buffer +//----------------------------------------------------------------------------- +template< class T, class I > +void CUtlMemory::ConvertToGrowableMemory(int nGrowSize) +{ + if (!IsExternallyAllocated()) + return; + + m_nGrowSize = nGrowSize; + if (m_nAllocationCount) + { + UTLMEMORY_TRACK_ALLOC(); + MEM_ALLOC_CREDIT_CLASS(); + + int nNumBytes = m_nAllocationCount * sizeof(T); + T* pMemory = (T*)malloc(nNumBytes); + memcpy((void*)pMemory, (void*)m_pMemory, nNumBytes); + m_pMemory = pMemory; + } + else + { + m_pMemory = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Attaches the buffer to external memory.... +//----------------------------------------------------------------------------- +template< class T, class I > +void CUtlMemory::SetExternalBuffer(T* pMemory, int numElements) +{ + // Blow away any existing allocated memory + Purge(); + + m_pMemory = pMemory; + m_nAllocationCount = numElements; + + // Indicate that we don't own the memory + m_nGrowSize = EXTERNAL_BUFFER_MARKER; +} + +template< class T, class I > +void CUtlMemory::SetExternalBuffer(const T* pMemory, int numElements) +{ + // Blow away any existing allocated memory + Purge(); + + m_pMemory = const_cast(pMemory); + m_nAllocationCount = numElements; + + // Indicate that we don't own the memory + m_nGrowSize = EXTERNAL_CONST_BUFFER_MARKER; +} + +template< class T, class I > +void CUtlMemory::AssumeMemory(T* pMemory, int numElements) +{ + // Blow away any existing allocated memory + Purge(); + + // Simply take the pointer but don't mark us as external + m_pMemory = pMemory; + m_nAllocationCount = numElements; +} + + +//----------------------------------------------------------------------------- +// element access +//----------------------------------------------------------------------------- +template< class T, class I > +inline T& CUtlMemory::operator[](I i) +{ + // Avoid function calls in the asserts to improve debug build performance + //Assert(m_nGrowSize != EXTERNAL_CONST_BUFFER_MARKER); //Assert( !IsReadOnly() ); + //Assert((uint32)i < (uint32)m_nAllocationCount); + return m_pMemory[(uint32)i]; +} + +template< class T, class I > +inline const T& CUtlMemory::operator[](I i) const +{ + // Avoid function calls in the asserts to improve debug build performance + //Assert((uint32)i < (uint32)m_nAllocationCount); + return m_pMemory[(uint32)i]; +} + +template< class T, class I > +inline T& CUtlMemory::Element(I i) +{ + // Avoid function calls in the asserts to improve debug build performance + //Assert(m_nGrowSize != EXTERNAL_CONST_BUFFER_MARKER); //Assert( !IsReadOnly() ); + //Assert((uint32)i < (uint32)m_nAllocationCount); + return m_pMemory[(uint32)i]; +} + +template< class T, class I > +inline const T& CUtlMemory::Element(I i) const +{ + // Avoid function calls in the asserts to improve debug build performance + //Assert((uint32)i < (uint32)m_nAllocationCount); + return m_pMemory[(uint32)i]; +} + + +//----------------------------------------------------------------------------- +// is the memory externally allocated? +//----------------------------------------------------------------------------- +template< class T, class I > +bool CUtlMemory::IsExternallyAllocated() const +{ + return (m_nGrowSize < 0); +} + + +//----------------------------------------------------------------------------- +// is the memory read only? +//----------------------------------------------------------------------------- +template< class T, class I > +bool CUtlMemory::IsReadOnly() const +{ + return (m_nGrowSize == EXTERNAL_CONST_BUFFER_MARKER); +} + + +template< class T, class I > +void CUtlMemory::SetGrowSize(int nSize) +{ + //Assert(!IsExternallyAllocated()); + //Assert(nSize >= 0); + m_nGrowSize = nSize; + ValidateGrowSize(); +} + + +//----------------------------------------------------------------------------- +// Gets the base address (can change when adding elements!) +//----------------------------------------------------------------------------- +template< class T, class I > +inline T* CUtlMemory::Base() +{ + //Assert(!IsReadOnly()); + return m_pMemory; +} + +template< class T, class I > +inline const T* CUtlMemory::Base() const +{ + return m_pMemory; +} + + +//----------------------------------------------------------------------------- +// Size +//----------------------------------------------------------------------------- +template< class T, class I > +inline int CUtlMemory::NumAllocated() const +{ + return m_nAllocationCount; +} + +template< class T, class I > +inline int CUtlMemory::Count() const +{ + return m_nAllocationCount; +} + + +//----------------------------------------------------------------------------- +// Is element index valid? +//----------------------------------------------------------------------------- +template< class T, class I > +inline bool CUtlMemory::IsIdxValid(I i) const +{ + // If we always cast 'i' and 'm_nAllocationCount' to unsigned then we can + // do our range checking with a single comparison instead of two. This gives + // a modest speedup in debug builds. + return (uint32)i < (uint32)m_nAllocationCount; +} + +//----------------------------------------------------------------------------- +// Grows the memory +//----------------------------------------------------------------------------- +inline int UtlMemory_CalcNewAllocationCount(int nAllocationCount, int nGrowSize, int nNewSize, int nBytesItem) +{ + if (nGrowSize) + { + nAllocationCount = ((1 + ((nNewSize - 1) / nGrowSize)) * nGrowSize); + } + else + { + if (!nAllocationCount) + { + // Compute an allocation which is at least as big as a cache line... + nAllocationCount = (31 + nBytesItem) / nBytesItem; + } + + while (nAllocationCount < nNewSize) + { +#ifndef _X360 + nAllocationCount *= 2; +#else + int nNewAllocationCount = (nAllocationCount * 9) / 8; // 12.5 % + if (nNewAllocationCount > nAllocationCount) + nAllocationCount = nNewAllocationCount; + else + nAllocationCount *= 2; +#endif + } + } + + return nAllocationCount; +} + +template< class T, class I > +void CUtlMemory::Grow(int num) +{ + //Assert(num > 0); + + if (IsExternallyAllocated()) + { + // Can't grow a buffer whose memory was externally allocated + //Assert(0); + return; + } + + // Make sure we have at least numallocated + num allocations. + // Use the grow rules specified for this memory (in m_nGrowSize) + int nAllocationRequested = m_nAllocationCount + num; + + UTLMEMORY_TRACK_FREE(); + + int nNewAllocationCount = UtlMemory_CalcNewAllocationCount(m_nAllocationCount, m_nGrowSize, nAllocationRequested, sizeof(T)); + + // if m_nAllocationRequested wraps index type I, recalculate + if ((int)(I)nNewAllocationCount < nAllocationRequested) + { + if ((int)(I)nNewAllocationCount == 0 && (int)(I)(nNewAllocationCount - 1) >= nAllocationRequested) + { + --nNewAllocationCount; // deal w/ the common case of m_nAllocationCount == MAX_USHORT + 1 + } + else + { + if ((int)(I)nAllocationRequested != nAllocationRequested) + { + // we've been asked to grow memory to a size s.t. the index type can't address the requested amount of memory + //Assert(0); + return; + } + while ((int)(I)nNewAllocationCount < nAllocationRequested) + { + nNewAllocationCount = (nNewAllocationCount + nAllocationRequested) / 2; + } + } + } + + m_nAllocationCount = nNewAllocationCount; + + UTLMEMORY_TRACK_ALLOC(); + + if (m_pMemory) + { + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory = (T*)realloc(m_pMemory, m_nAllocationCount * sizeof(T)); + //Assert(m_pMemory); + } + else + { + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T)); + //Assert(m_pMemory); + } +} + + +//----------------------------------------------------------------------------- +// Makes sure we've got at least this much memory +//----------------------------------------------------------------------------- +template< class T, class I > +inline void CUtlMemory::EnsureCapacity(int num) +{ + if (m_nAllocationCount >= num) + return; + + if (IsExternallyAllocated()) + { + // Can't grow a buffer whose memory was externally allocated + //Assert(0); + return; + } + + UTLMEMORY_TRACK_FREE(); + + m_nAllocationCount = num; + + UTLMEMORY_TRACK_ALLOC(); + + if (m_pMemory) + { + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory = (T*)realloc(m_pMemory, m_nAllocationCount * sizeof(T)); + } + else + { + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T)); + } +} + + +//----------------------------------------------------------------------------- +// Memory deallocation +//----------------------------------------------------------------------------- +template< class T, class I > +void CUtlMemory::Purge() +{ + if (!IsExternallyAllocated()) + { + if (m_pMemory) + { + UTLMEMORY_TRACK_FREE(); + free((void*)m_pMemory); + m_pMemory = 0; + } + m_nAllocationCount = 0; + } +} + +template< class T, class I > +void CUtlMemory::Purge(int numElements) +{ + //Assert(numElements >= 0); + + if (numElements > m_nAllocationCount) + { + // Ensure this isn't a grow request in disguise. + //Assert(numElements <= m_nAllocationCount); + return; + } + + // If we have zero elements, simply do a purge: + if (numElements == 0) + { + Purge(); + return; + } + + if (IsExternallyAllocated()) + { + // Can't shrink a buffer whose memory was externally allocated, fail silently like purge + return; + } + + // If the number of elements is the same as the allocation count, we are done. + if (numElements == m_nAllocationCount) + { + return; + } + + + if (!m_pMemory) + { + // Allocation count is non zero, but memory is null. + //Assert(m_pMemory); + return; + } + + UTLMEMORY_TRACK_FREE(); + + m_nAllocationCount = numElements; + + UTLMEMORY_TRACK_ALLOC(); + + // Allocation count > 0, shrink it down. + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory = (T*)realloc(m_pMemory, m_nAllocationCount * sizeof(T)); +} + +//----------------------------------------------------------------------------- +// The CUtlMemory class: +// A growable memory class which doubles in size by default. +//----------------------------------------------------------------------------- +template< class T, int nAlignment > +class CUtlMemoryAligned : public CUtlMemory +{ +public: + // constructor, destructor + CUtlMemoryAligned(int nGrowSize = 0, int nInitSize = 0); + CUtlMemoryAligned(T* pMemory, int numElements); + CUtlMemoryAligned(const T* pMemory, int numElements); + ~CUtlMemoryAligned(); + + // Attaches the buffer to external memory.... + void SetExternalBuffer(T* pMemory, int numElements); + void SetExternalBuffer(const T* pMemory, int numElements); + + // Grows the memory, so that at least allocated + num elements are allocated + void Grow(int num = 1); + + // Makes sure we've got at least this much memory + void EnsureCapacity(int num); + + // Memory deallocation + void Purge(); + + // Purge all but the given number of elements (NOT IMPLEMENTED IN CUtlMemoryAligned) + void Purge(int numElements) { /*Assert(0);*/ } + +private: + void* Align(const void* pAddr); +}; + + +//----------------------------------------------------------------------------- +// Aligns a pointer +//----------------------------------------------------------------------------- +template< class T, int nAlignment > +void* CUtlMemoryAligned::Align(const void* pAddr) +{ + size_t nAlignmentMask = nAlignment - 1; + return (void*)(((size_t)pAddr + nAlignmentMask) & (~nAlignmentMask)); +} + + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +template< class T, int nAlignment > +CUtlMemoryAligned::CUtlMemoryAligned(int nGrowSize, int nInitAllocationCount) +{ + CUtlMemory::m_pMemory = 0; + CUtlMemory::m_nAllocationCount = nInitAllocationCount; + CUtlMemory::m_nGrowSize = nGrowSize; + this->ValidateGrowSize(); + + // Alignment must be a power of two + COMPILE_TIME_ASSERT((nAlignment & (nAlignment - 1)) == 0); + //Assert((nGrowSize >= 0) && (nGrowSize != CUtlMemory::EXTERNAL_BUFFER_MARKER)); + if (CUtlMemory::m_nAllocationCount) + { + UTLMEMORY_TRACK_ALLOC(); + MEM_ALLOC_CREDIT_CLASS(); + CUtlMemory::m_pMemory = (T*)_aligned_malloc(nInitAllocationCount * sizeof(T), nAlignment); + } +} + +template< class T, int nAlignment > +CUtlMemoryAligned::CUtlMemoryAligned(T* pMemory, int numElements) +{ + // Special marker indicating externally supplied memory + CUtlMemory::m_nGrowSize = CUtlMemory::EXTERNAL_BUFFER_MARKER; + + CUtlMemory::m_pMemory = (T*)Align(pMemory); + CUtlMemory::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory::m_pMemory) / sizeof(T); +} + +template< class T, int nAlignment > +CUtlMemoryAligned::CUtlMemoryAligned(const T* pMemory, int numElements) +{ + // Special marker indicating externally supplied memory + CUtlMemory::m_nGrowSize = CUtlMemory::EXTERNAL_CONST_BUFFER_MARKER; + + CUtlMemory::m_pMemory = (T*)Align(pMemory); + CUtlMemory::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory::m_pMemory) / sizeof(T); +} + +template< class T, int nAlignment > +CUtlMemoryAligned::~CUtlMemoryAligned() +{ + Purge(); +} + + +//----------------------------------------------------------------------------- +// Attaches the buffer to external memory.... +//----------------------------------------------------------------------------- +template< class T, int nAlignment > +void CUtlMemoryAligned::SetExternalBuffer(T* pMemory, int numElements) +{ + // Blow away any existing allocated memory + Purge(); + + CUtlMemory::m_pMemory = (T*)Align(pMemory); + CUtlMemory::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory::m_pMemory) / sizeof(T); + + // Indicate that we don't own the memory + CUtlMemory::m_nGrowSize = CUtlMemory::EXTERNAL_BUFFER_MARKER; +} + +template< class T, int nAlignment > +void CUtlMemoryAligned::SetExternalBuffer(const T* pMemory, int numElements) +{ + // Blow away any existing allocated memory + Purge(); + + CUtlMemory::m_pMemory = (T*)Align(pMemory); + CUtlMemory::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory::m_pMemory) / sizeof(T); + + // Indicate that we don't own the memory + CUtlMemory::m_nGrowSize = CUtlMemory::EXTERNAL_CONST_BUFFER_MARKER; +} + + +//----------------------------------------------------------------------------- +// Grows the memory +//----------------------------------------------------------------------------- +template< class T, int nAlignment > +void CUtlMemoryAligned::Grow(int num) +{ + //Assert(num > 0); + + if (this->IsExternallyAllocated()) + { + // Can't grow a buffer whose memory was externally allocated + //Assert(0); + return; + } + + UTLMEMORY_TRACK_FREE(); + + // Make sure we have at least numallocated + num allocations. + // Use the grow rules specified for this memory (in m_nGrowSize) + int nAllocationRequested = CUtlMemory::m_nAllocationCount + num; + + CUtlMemory::m_nAllocationCount = UtlMemory_CalcNewAllocationCount(CUtlMemory::m_nAllocationCount, CUtlMemory::m_nGrowSize, nAllocationRequested, sizeof(T)); + + UTLMEMORY_TRACK_ALLOC(); + + if (CUtlMemory::m_pMemory) + { + MEM_ALLOC_CREDIT_CLASS(); + CUtlMemory::m_pMemory = (T*)MemAlloc_ReallocAligned(CUtlMemory::m_pMemory, CUtlMemory::m_nAllocationCount * sizeof(T), nAlignment); + //Assert(CUtlMemory::m_pMemory); + } + else + { + MEM_ALLOC_CREDIT_CLASS(); + CUtlMemory::m_pMemory = (T*)MemAlloc_AllocAligned(CUtlMemory::m_nAllocationCount * sizeof(T), nAlignment); + //Assert(CUtlMemory::m_pMemory); + } +} + + +//----------------------------------------------------------------------------- +// Makes sure we've got at least this much memory +//----------------------------------------------------------------------------- +template< class T, int nAlignment > +inline void CUtlMemoryAligned::EnsureCapacity(int num) +{ + if (CUtlMemory::m_nAllocationCount >= num) + return; + + if (this->IsExternallyAllocated()) + { + // Can't grow a buffer whose memory was externally allocated + //Assert(0); + return; + } + + UTLMEMORY_TRACK_FREE(); + + CUtlMemory::m_nAllocationCount = num; + + UTLMEMORY_TRACK_ALLOC(); + + if (CUtlMemory::m_pMemory) + { + MEM_ALLOC_CREDIT_CLASS(); + CUtlMemory::m_pMemory = (T*)MemAlloc_ReallocAligned(CUtlMemory::m_pMemory, CUtlMemory::m_nAllocationCount * sizeof(T), nAlignment); + } + else + { + MEM_ALLOC_CREDIT_CLASS(); + CUtlMemory::m_pMemory = (T*)MemAlloc_AllocAligned(CUtlMemory::m_nAllocationCount * sizeof(T), nAlignment); + } +} + + +//----------------------------------------------------------------------------- +// Memory deallocation +//----------------------------------------------------------------------------- +template< class T, int nAlignment > +void CUtlMemoryAligned::Purge() +{ + if (!this->IsExternallyAllocated()) + { + if (CUtlMemory::m_pMemory) + { + UTLMEMORY_TRACK_FREE(); + MemAlloc_FreeAligned(CUtlMemory::m_pMemory); + CUtlMemory::m_pMemory = 0; + } + CUtlMemory::m_nAllocationCount = 0; + } +} + +#pragma warning (pop) \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/UtlObjectReference.h b/Amalgam/src/SDK/Definitions/Misc/CUtlObjectReference.h similarity index 68% rename from Amalgam/src/SDK/Definitions/Misc/UtlObjectReference.h rename to Amalgam/src/SDK/Definitions/Misc/CUtlObjectReference.h index 1eb87bf4..60585128 100644 --- a/Amalgam/src/SDK/Definitions/Misc/UtlObjectReference.h +++ b/Amalgam/src/SDK/Definitions/Misc/CUtlObjectReference.h @@ -1,35 +1,9 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// $Revision: $ -// $NoKeywords: $ -//===========================================================================// +#pragma once +#include "CUtlIntrusiveList.h" #ifndef UTLOBJECTREFERENCE_H #define UTLOBJECTREFERENCE_H -#ifdef _WIN32 -#pragma once -#endif - -#include "UtlIntrusiveList.h" - - - -// Purpose: class for keeping track of all the references that exist to an object. When the object -// being referenced is freed, all of the references pointing at it will become null. -// -// To Use: -// Add a DECLARE_REFERENCED_CLASS to the class that you want to use CutlReferences with. -// Replace pointers to that class with CUtlReferences. -// Check these references for null in appropriate places. -// -// NOTE : You can still happily use pointers instead of references where you want to - these -// pointers will not magically become null like references would, but if you know no one is going -// to delete the underlying object during a partcular section of code, it doesn't -// matter. Basically, CUtlReferences don't rely on every use of an object using one. - - - template class CUtlReference { public: @@ -155,5 +129,4 @@ public: CUtlReferenceList< _className > m_References; \ template friend class CUtlReference; - -#endif +#endif \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/CUtlString.h b/Amalgam/src/SDK/Definitions/Misc/CUtlString.h new file mode 100644 index 00000000..4d0c4bf4 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CUtlString.h @@ -0,0 +1,6 @@ +#pragma once + +struct CUtlString +{ + char* m_pString; +}; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/CUtlVector.h b/Amalgam/src/SDK/Definitions/Misc/CUtlVector.h new file mode 100644 index 00000000..5f529e04 --- /dev/null +++ b/Amalgam/src/SDK/Definitions/Misc/CUtlVector.h @@ -0,0 +1,569 @@ +#pragma once +#include "CUtlMemory.h" +#include +#include + +#pragma warning (push) +#pragma warning (disable : 4100) +#pragma warning (disable : 4514) +#pragma warning (disable : 26495) + +template +inline void Construct(T* pMemory) +{ + ::new(pMemory) T; +} + +template +inline void CopyConstruct(T* pMemory, T const& src) +{ + ::new(pMemory) T(src); +} + +template +inline void Destruct(T* pMemory) +{ + pMemory->~T(); +} + +template> +class CUtlVector +{ +public: + typedef T ElemType_t; + + // constructor, destructor + CUtlVector(int growSize = 0, int initSize = 0); + CUtlVector(T* pMemory, int numElements); + ~CUtlVector(); + + // Copy the array. + CUtlVector& operator=(const CUtlVector& other); + + // element access + T& operator[](int i); + T const& operator[](int i) const; + T& Element(int i); + T const& Element(int i) const; + + // Gets the base address (can change when adding elements!) + T* Base(); + T const* Base() const; + + // Returns the number of elements in the vector + // SIZE IS DEPRECATED! + int Count() const; + int Size() const; // don't use me! + + // Is element index valid? + bool IsValidIndex(int i) const; + static int InvalidIndex(void); + + // Adds an element, uses default constructor + int AddToHead(); + int AddToTail(); + int InsertBefore(int elem); + int InsertAfter(int elem); + + // Adds an element, uses copy constructor + int AddToHead(T const& src); + int AddToTail(T const& src); + int InsertBefore(int elem, T const& src); + int InsertAfter(int elem, T const& src); + + // Adds multiple elements, uses default constructor + int AddMultipleToHead(int num); + int AddMultipleToTail(int num, const T* pToCopy = NULL); + int InsertMultipleBefore(int elem, int num, const T* pToCopy = NULL); // If pToCopy is set, then it's an array of length 'num' and + int InsertMultipleAfter(int elem, int num); + + // Calls RemoveAll() then AddMultipleToTail. + void SetSize(int size); + void SetCount(int count); + + // Calls SetSize and copies each element. + void CopyArray(T const* pArray, int size); + + // Add the specified array to the tail. + int AddVectorToTail(CUtlVector const& src); + + // Finds an element (element needs operator== defined) + int Find(T const& src) const; + + bool HasElement(T const& src); + + // Makes sure we have at least this many elements + void EnsureCount(int num); + + // Element removal + void FastRemove(int elem); // doesn't preserve order + void Remove(int elem); // preserves order, shifts elements + void FindAndRemove(T const& src); // removes first occurrence of src, preserves order, shifts elements + void RemoveMultiple(int elem, int num); // preserves order, shifts elements + void RemoveAll(); // doesn't deallocate memory + + // Memory deallocation + void Purge(); + + // Purges the list and calls delete on each element in it. + void PurgeAndDeleteElements(); + + // Set the size by which it grows when it needs to allocate more memory. + void SetGrowSize(int size); + + // Can't copy this unless we explicitly do it! + CUtlVector(CUtlVector const& vec) + { + assert(0); + } + +protected: + // Grows the vector + void GrowVector(int num = 1); + + // Shifts elements.... + void ShiftElementsRight(int elem, int num = 1); + void ShiftElementsLeft(int elem, int num = 1); + + // For easier access to the elements through the debugger + void ResetDbgInfo(); + + A m_Memory; + int m_Size; + + // For easier access to the elements through the debugger + // it's in release builds so this can be used in libraries correctly + T* m_pElements; +}; + +//----------------------------------------------------------------------------- +// For easier access to the elements through the debugger +//----------------------------------------------------------------------------- + +template< class T, class A > +inline void CUtlVector::ResetDbgInfo() +{ + m_pElements = m_Memory.Base(); +} + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- + +template< class T, class A > +inline CUtlVector::CUtlVector(int growSize, int initSize) : m_Memory(growSize, initSize), m_Size(0) +{ + ResetDbgInfo(); +} + +template< class T, class A > +inline CUtlVector::CUtlVector(T* pMemory, int numElements) : m_Memory(pMemory, numElements), m_Size(0) +{ + ResetDbgInfo(); +} + +template< class T, class A > +inline CUtlVector::~CUtlVector() +{ + Purge(); +} + +template< class T, class A > +inline CUtlVector& CUtlVector::operator=(const CUtlVector& other) +{ + CopyArray(other.Base(), other.Count()); + return *this; +} + +//----------------------------------------------------------------------------- +// element access +//----------------------------------------------------------------------------- + +template< class T, class A > +inline T& CUtlVector::operator[](int i) +{ + assert(IsValidIndex(i)); + return m_Memory[i]; +} + +template< class T, class A > +inline T const& CUtlVector::operator[](int i) const +{ + assert(IsValidIndex(i)); + return m_Memory[i]; +} + +template< class T, class A > +inline T& CUtlVector::Element(int i) +{ + assert(IsValidIndex(i)); + return m_Memory[i]; +} + +template< class T, class A > +inline T const& CUtlVector::Element(int i) const +{ + assert(IsValidIndex(i)); + return m_Memory[i]; +} + +//----------------------------------------------------------------------------- +// Gets the base address (can change when adding elements!) +//----------------------------------------------------------------------------- + +template< class T, class A > +inline T* CUtlVector::Base() +{ + return m_Memory.Base(); +} + +template< class T, class A > +inline T const* CUtlVector::Base() const +{ + return m_Memory.Base(); +} + +//----------------------------------------------------------------------------- +// Count +//----------------------------------------------------------------------------- + +template< class T, class A > +inline int CUtlVector::Size() const +{ + return m_Size; +} + +template< class T, class A > +inline int CUtlVector::Count() const +{ + return m_Size; +} + +//----------------------------------------------------------------------------- +// Is element index valid? +//----------------------------------------------------------------------------- + +template< class T, class A > +inline bool CUtlVector::IsValidIndex(int i) const +{ + return (i >= 0) && (i < m_Size); +} + +//----------------------------------------------------------------------------- +// Returns in invalid index +//----------------------------------------------------------------------------- +template< class T, class A > +inline int CUtlVector::InvalidIndex(void) +{ + return -1; +} + +//----------------------------------------------------------------------------- +// Grows the vector +//----------------------------------------------------------------------------- +template< class T, class A > +void CUtlVector::GrowVector(int num) +{ + if (m_Size + num - 1 >= m_Memory.NumAllocated()) + m_Memory.Grow(m_Size + num - m_Memory.NumAllocated()); + + m_Size += num; + ResetDbgInfo(); +} + +//----------------------------------------------------------------------------- +// Makes sure we have at least this many elements +//----------------------------------------------------------------------------- +template< class T, class A > +void CUtlVector::EnsureCount(int num) +{ + if (Count() < num) + AddMultipleToTail(num - Count()); +} + +//----------------------------------------------------------------------------- +// Shifts elements +//----------------------------------------------------------------------------- +template< class T, class A > +void CUtlVector::ShiftElementsRight(int elem, int num) +{ + assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0)); + int numToMove = m_Size - elem - num; + if ((numToMove > 0) && (num > 0)) + memmove(&Element(elem + num), &Element(elem), numToMove * sizeof(T)); +} + +template< class T, class A > +void CUtlVector::ShiftElementsLeft(int elem, int num) +{ + assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0)); + int numToMove = m_Size - elem - num; + if ((numToMove > 0) && (num > 0)) + { + memmove(&Element(elem), &Element(elem + num), numToMove * sizeof(T)); + +#ifdef _DEBUG + memset(&Element(m_Size - num), 0xDD, num * sizeof(T)); +#endif + } +} + +//----------------------------------------------------------------------------- +// Adds an element, uses default constructor +//----------------------------------------------------------------------------- + +template< class T, class A > +inline int CUtlVector::AddToHead() +{ + return InsertBefore(0); +} + +template< class T, class A > +inline int CUtlVector::AddToTail() +{ + return InsertBefore(m_Size); +} + +template< class T, class A > +inline int CUtlVector::InsertAfter(int elem) +{ + return InsertBefore(elem + 1); +} + +template< class T, class A > +int CUtlVector::InsertBefore(int elem) +{ + // Can insert at the end + assert((elem == Count()) || IsValidIndex(elem)); + + GrowVector(); + ShiftElementsRight(elem); + Construct(&Element(elem)); + return elem; +} + +//----------------------------------------------------------------------------- +// Adds an element, uses copy constructor +//----------------------------------------------------------------------------- + +template< class T, class A > +inline int CUtlVector::AddToHead(T const& src) +{ + return InsertBefore(0, src); +} + +template< class T, class A > +inline int CUtlVector::AddToTail(T const& src) +{ + return InsertBefore(m_Size, src); +} + +template< class T, class A > +inline int CUtlVector::InsertAfter(int elem, T const& src) +{ + return InsertBefore(elem + 1, src); +} + +template< class T, class A > +int CUtlVector::InsertBefore(int elem, T const& src) +{ + // Can insert at the end + assert((elem == Count()) || IsValidIndex(elem)); + + GrowVector(); + ShiftElementsRight(elem); + CopyConstruct(&Element(elem), src); + return elem; +} + + +//----------------------------------------------------------------------------- +// Adds multiple elements, uses default constructor +//----------------------------------------------------------------------------- + +template< class T, class A > +inline int CUtlVector::AddMultipleToHead(int num) +{ + return InsertMultipleBefore(0, num); +} + +template< class T, class A > +inline int CUtlVector::AddMultipleToTail(int num, const T* pToCopy) +{ + return InsertMultipleBefore(m_Size, num, pToCopy); +} + +template< class T, class A > +int CUtlVector::InsertMultipleAfter(int elem, int num) +{ + return InsertMultipleBefore(elem + 1, num); +} + + +template< class T, class A > +void CUtlVector::SetCount(int count) +{ + RemoveAll(); + AddMultipleToTail(count); +} + +template< class T, class A > +inline void CUtlVector::SetSize(int size) +{ + SetCount(size); +} + +template< class T, class A > +void CUtlVector::CopyArray(T const* pArray, int size) +{ + SetSize(size); + for (int i = 0; i < size; i++) + (*this)[i] = pArray[i]; +} + +template< class T, class A > +int CUtlVector::AddVectorToTail(CUtlVector const& src) +{ + int base = Count(); + + // Make space. + AddMultipleToTail(src.Count()); + + // Copy the elements. + for (int i = 0; i < src.Count(); i++) + (*this)[base + i] = src[i]; + + return base; +} + +template< class T, class A > +inline int CUtlVector::InsertMultipleBefore(int elem, int num, const T* pToInsert) +{ + if (num == 0) + return elem; + + // Can insert at the end + assert((elem == Count()) || IsValidIndex(elem)); + + GrowVector(num); + ShiftElementsRight(elem, num); + + // Invoke default constructors + for (int i = 0; i < num; ++i) + Construct(&Element(elem + i)); + + // Copy stuff in? + if (pToInsert) + { + for (int i = 0; i < num; i++) + { + Element(elem + i) = pToInsert[i]; + } + } + + return elem; +} + +//----------------------------------------------------------------------------- +// Finds an element (element needs operator== defined) +//----------------------------------------------------------------------------- +template< class T, class A > +int CUtlVector::Find(T const& src) const +{ + for (int i = 0; i < Count(); ++i) + { + if (Element(i) == src) + return i; + } + return -1; +} + +template< class T, class A > +bool CUtlVector::HasElement(T const& src) +{ + return (Find(src) >= 0); +} + +//----------------------------------------------------------------------------- +// Element removal +//----------------------------------------------------------------------------- + +template< class T, class A > +void CUtlVector::FastRemove(int elem) +{ + assert(IsValidIndex(elem)); + + Destruct(&Element(elem)); + if (m_Size > 0) + { + Q_memcpy(&Element(elem), &Element(m_Size - 1), sizeof(T)); + --m_Size; + } +} + +template< class T, class A > +void CUtlVector::Remove(int elem) +{ + Destruct(&Element(elem)); + ShiftElementsLeft(elem); + --m_Size; +} + +template< class T, class A > +void CUtlVector::FindAndRemove(T const& src) +{ + int elem = Find(src); + if (elem != -1) + Remove(elem); +} + +template< class T, class A > +void CUtlVector::RemoveMultiple(int elem, int num) +{ + assert(IsValidIndex(elem)); + assert(elem + num <= Count()); + + for (int i = elem + num; --i >= elem;) + Destruct(&Element(i)); + + ShiftElementsLeft(elem, num); + m_Size -= num; +} + +template< class T, class A > +void CUtlVector::RemoveAll() +{ + for (int i = m_Size; --i >= 0;) + Destruct(&Element(i)); + + m_Size = 0; +} + +//----------------------------------------------------------------------------- +// Memory deallocation +//----------------------------------------------------------------------------- + +template< class T, class A > +void CUtlVector::Purge() +{ + RemoveAll(); + m_Memory.Purge(); + ResetDbgInfo(); +} + +template< class T, class A > +inline void CUtlVector::PurgeAndDeleteElements() +{ + for (int i = 0; i < m_Size; i++) + delete Element(i); + + Purge(); +} + +template< class T, class A > +void CUtlVector::SetGrowSize(int size) +{ + m_Memory.SetGrowSize(size); +} + +#pragma warning (pop) \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/ChecksumCRC.cpp b/Amalgam/src/SDK/Definitions/Misc/ChecksumCRC.cpp index c1ecb21f..02afdcf4 100644 --- a/Amalgam/src/SDK/Definitions/Misc/ChecksumCRC.cpp +++ b/Amalgam/src/SDK/Definitions/Misc/ChecksumCRC.cpp @@ -1,10 +1,5 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Generic CRC functions -// -//=============================================================================// - #include "ChecksumCRC.h" + #include #define CRC32_INIT_VALUE 0xFFFFFFFFUL diff --git a/Amalgam/src/SDK/Definitions/Misc/ConVar.h b/Amalgam/src/SDK/Definitions/Misc/ConVar.h index de372aba..5c547b4f 100644 --- a/Amalgam/src/SDK/Definitions/Misc/ConVar.h +++ b/Amalgam/src/SDK/Definitions/Misc/ConVar.h @@ -1,12 +1,25 @@ #pragma once #include "IConVar.h" -#include "../Main/UtlVector.h" +#include "CUtlVector.h" +#include "CUtlString.h" + +#define COMMAND_COMPLETION_MAXITEMS 64 +#define COMMAND_COMPLETION_ITEM_LENGTH 64 class ConVar; class CCommand; class ConCommand; class ConCommandBase; struct characterset_t; +typedef void (*FnCommandCallbackVoid_t)(void); +typedef void (*FnCommandCallback_t)(const CCommand& command); +typedef int (*FnCommandCompletionCallback)(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); + +enum +{ + COMMAND_MAX_ARGC = 64, + COMMAND_MAX_LENGTH = 512 +}; class IConCommandBaseAccessor { @@ -14,14 +27,6 @@ public: virtual bool RegisterConCommandBase(ConCommandBase* pVar) = 0; }; -typedef void (*FnCommandCallbackVoid_t)(void); -typedef void (*FnCommandCallback_t)(const CCommand& command); - -#define COMMAND_COMPLETION_MAXITEMS 64 -#define COMMAND_COMPLETION_ITEM_LENGTH 64 - -typedef int (*FnCommandCompletionCallback)(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); - class ICommandCallback { public: @@ -31,7 +36,7 @@ public: class ICommandCompletionCallback { public: - virtual int CommandCompletionCallback(const char* pPartial, CUtlVector< /*CUtlString*/ void* >& commands) = 0; + virtual int CommandCompletionCallback(const char* pPartial, CUtlVector& commands) = 0; }; class ConCommandBase @@ -60,12 +65,6 @@ protected: static IConCommandBaseAccessor* s_pAccessor; }; -enum -{ - COMMAND_MAX_ARGC = 64, - COMMAND_MAX_LENGTH = 512 -}; - class CCommand { public: @@ -114,7 +113,7 @@ class ConCommand : public ConCommandBase public: virtual ~ConCommand(void) = 0; virtual bool IsCommand(void) const = 0; - virtual int AutoCompleteSuggest(const char* partial, CUtlVector< /*CUtlString*/ void* >& commands) = 0; + virtual int AutoCompleteSuggest(const char* partial, CUtlVector& commands) = 0; virtual bool CanAutoComplete(void) = 0; virtual void Dispatch(const CCommand& command) = 0; diff --git a/Amalgam/src/SDK/Definitions/Misc/Cursor.h b/Amalgam/src/SDK/Definitions/Misc/Cursor.h index fd98eff6..6eefa4b1 100644 --- a/Amalgam/src/SDK/Definitions/Misc/Cursor.h +++ b/Amalgam/src/SDK/Definitions/Misc/Cursor.h @@ -1,5 +1,4 @@ #pragma once -#include "VGUI.h" enum CursorCode { diff --git a/Amalgam/src/SDK/Definitions/Misc/Datamap.h b/Amalgam/src/SDK/Definitions/Misc/Datamap.h index 9dd132d4..a6244842 100644 --- a/Amalgam/src/SDK/Definitions/Misc/Datamap.h +++ b/Amalgam/src/SDK/Definitions/Misc/Datamap.h @@ -79,13 +79,9 @@ public: #define FTYPEDESC_VIEW_NEVER 0x8000 #define TD_MSECTOLERANCE 0.001f -struct typedescription_t; class ISaveRestoreOps; - -typedef void (*inputfunc_t)(inputdata_t& data); - struct datamap_t; -struct typedescription_t; +typedef void (*inputfunc_t)(inputdata_t& data); enum { diff --git a/Amalgam/src/SDK/Definitions/Misc/IClientMode.h b/Amalgam/src/SDK/Definitions/Misc/IClientMode.h index b509b039..d4df6cd1 100644 --- a/Amalgam/src/SDK/Definitions/Misc/IClientMode.h +++ b/Amalgam/src/SDK/Definitions/Misc/IClientMode.h @@ -1,11 +1,11 @@ #pragma once #include "VGUI.h" #include "ButtonCode.h" -#include "../Main/CUserCmd.h" class CViewSetup; class CBaseEntity; class CBasePlayer; +class CUserCmd; class Panel; class AnimationController; class KeyValues; diff --git a/Amalgam/src/SDK/Definitions/Misc/IColorCorrectionSystem.h b/Amalgam/src/SDK/Definitions/Misc/IColorCorrectionSystem.h index 36ded3b3..cb61f23a 100644 --- a/Amalgam/src/SDK/Definitions/Misc/IColorCorrectionSystem.h +++ b/Amalgam/src/SDK/Definitions/Misc/IColorCorrectionSystem.h @@ -2,8 +2,8 @@ #include "ImageFormat.h" #include "BaseTypes.h" -typedef unsigned int ColorCorrectionHandle_t; struct ShaderColorCorrectionInfo_t; +typedef unsigned int ColorCorrectionHandle_t; class IColorCorrectionSystem { diff --git a/Amalgam/src/SDK/Definitions/Misc/IConVar.h b/Amalgam/src/SDK/Definitions/Misc/IConVar.h index c6881c67..5cd1b1a9 100644 --- a/Amalgam/src/SDK/Definitions/Misc/IConVar.h +++ b/Amalgam/src/SDK/Definitions/Misc/IConVar.h @@ -1,8 +1,5 @@ #pragma once -class IConVar; -class CCommand; - #define FCVAR_NONE 0 #define FCVAR_UNREGISTERED (1<<0) #define FCVAR_DEVELOPMENTONLY (1<<1) @@ -35,6 +32,8 @@ class CCommand; #define FCVAR_ALLOWED_IN_COMPETITIVE (1<<18) #define FCVAR_MATERIAL_THREAD_MASK ( FCVAR_RELOAD_MATERIALS | FCVAR_RELOAD_TEXTURES | FCVAR_MATERIAL_SYSTEM_THREAD ) +class IConVar; +class CCommand; typedef void (*FnChangeCallback_t)(IConVar* var, const char* pOldValue, float flOldValue); class IConVar diff --git a/Amalgam/src/SDK/Definitions/Misc/IImage.h b/Amalgam/src/SDK/Definitions/Misc/IImage.h index 1ee7ed37..20171809 100644 --- a/Amalgam/src/SDK/Definitions/Misc/IImage.h +++ b/Amalgam/src/SDK/Definitions/Misc/IImage.h @@ -1,5 +1,4 @@ #pragma once -#include "VGUI.h" #include "../Types.h" typedef unsigned long HTexture; diff --git a/Amalgam/src/SDK/Definitions/Misc/IMDLCache.h b/Amalgam/src/SDK/Definitions/Misc/IMDLCache.h index f75019f9..04e7ace0 100644 --- a/Amalgam/src/SDK/Definitions/Misc/IMDLCache.h +++ b/Amalgam/src/SDK/Definitions/Misc/IMDLCache.h @@ -7,7 +7,6 @@ struct vcollide_t; struct virtualmodel_t; struct vertexFileHeader_t; struct FileHeader_t; - typedef unsigned short MDLHandle_t; enum @@ -26,13 +25,6 @@ enum MDLCacheDataType_t MDLCACHE_DECODEDANIMBLOCK }; -class IMDLCacheNotify -{ -public: - virtual void OnDataLoaded(MDLCacheDataType_t type, MDLHandle_t handle) = 0; - virtual void OnDataUnloaded(MDLCacheDataType_t type, MDLHandle_t handle) = 0; -}; - enum MDLCacheFlush_t { MDLCACHE_FLUSH_STUDIOHDR = 0x01, @@ -46,6 +38,13 @@ enum MDLCacheFlush_t MDLCACHE_FLUSH_ALL = 0xFFFFFFFF }; +class IMDLCacheNotify +{ +public: + virtual void OnDataLoaded(MDLCacheDataType_t type, MDLHandle_t handle) = 0; + virtual void OnDataUnloaded(MDLCacheDataType_t type, MDLHandle_t handle) = 0; +}; + class IMDLCache : public IAppSystem { public: diff --git a/Amalgam/src/SDK/Definitions/Misc/IMatchGroupDescription.h b/Amalgam/src/SDK/Definitions/Misc/IMatchGroupDescription.h index fa7860f0..813f4dd6 100644 --- a/Amalgam/src/SDK/Definitions/Misc/IMatchGroupDescription.h +++ b/Amalgam/src/SDK/Definitions/Misc/IMatchGroupDescription.h @@ -1,7 +1,8 @@ #pragma once #include "ConVar.h" +#include "CUtlVector.h" +#include "CUtlString.h" #include "../Interfaces/IVEngineClient.h" -#include "../Main/UtlVector.h" #include "../Steam/SteamClientPublic.h" #include "../Definitions.h" #include "../../../Utils/Signatures/Signatures.h" diff --git a/Amalgam/src/SDK/Definitions/Misc/IMaterialSystemHardwareConfig.h b/Amalgam/src/SDK/Definitions/Misc/IMaterialSystemHardwareConfig.h index 4331af4d..9df11f0e 100644 --- a/Amalgam/src/SDK/Definitions/Misc/IMaterialSystemHardwareConfig.h +++ b/Amalgam/src/SDK/Definitions/Misc/IMaterialSystemHardwareConfig.h @@ -1,5 +1,7 @@ #pragma once +#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) virtual ret_type method const = 0; + enum HDRType_t { HDR_TYPE_NONE, @@ -14,8 +16,6 @@ enum VertexCompressionType_t VERTEX_COMPRESSION_ON = 1 }; -#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) virtual ret_type method const = 0; - class IMaterialSystemHardwareConfig { public: diff --git a/Amalgam/src/SDK/Definitions/Misc/ISurface.h b/Amalgam/src/SDK/Definitions/Misc/ISurface.h index ec85ff76..5e6c7ebd 100644 --- a/Amalgam/src/SDK/Definitions/Misc/ISurface.h +++ b/Amalgam/src/SDK/Definitions/Misc/ISurface.h @@ -1,5 +1,6 @@ #pragma once #include "IAppSystem.h" +#include "VGUI.h" #include "IHTML.h" #include "ImageFormat.h" #include "IVguiMatInfo.h" diff --git a/Amalgam/src/SDK/Definitions/Misc/ImageFormat.h b/Amalgam/src/SDK/Definitions/Misc/ImageFormat.h index ce7eb6ef..9237a1f5 100644 --- a/Amalgam/src/SDK/Definitions/Misc/ImageFormat.h +++ b/Amalgam/src/SDK/Definitions/Misc/ImageFormat.h @@ -1,12 +1,12 @@ #pragma once +//typedef enum _D3DFORMAT D3DFORMAT; + enum NormalDecodeMode_t { NORMAL_DECODE_NONE = 0 }; -//typedef enum _D3DFORMAT D3DFORMAT; - enum ImageFormat { IMAGE_FORMAT_UNKNOWN = -1, diff --git a/Amalgam/src/SDK/Definitions/Misc/InputEnums.h b/Amalgam/src/SDK/Definitions/Misc/InputEnums.h index cb81e362..ab5dc3e1 100644 --- a/Amalgam/src/SDK/Definitions/Misc/InputEnums.h +++ b/Amalgam/src/SDK/Definitions/Misc/InputEnums.h @@ -43,15 +43,6 @@ enum InputEventType_t IE_FirstAppEvent = 2000 }; -struct InputEvent_t -{ - int m_nType = 0; - int m_nTick = 0; - int m_nData = 0; - int m_nData2 = 0; - int m_nData3 = 0; -}; - typedef enum { SK_NULL, @@ -141,4 +132,13 @@ enum JoystickType_t INPUT_TYPE_GENERIC_JOYSTICK = 0, INPUT_TYPE_X360, INPUT_TYPE_STEAMCONTROLLER +}; + +struct InputEvent_t +{ + int m_nType = 0; + int m_nTick = 0; + int m_nData = 0; + int m_nData2 = 0; + int m_nData3 = 0; }; \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Misc/Studio.h b/Amalgam/src/SDK/Definitions/Misc/Studio.h index a2127926..e9879008 100644 --- a/Amalgam/src/SDK/Definitions/Misc/Studio.h +++ b/Amalgam/src/SDK/Definitions/Misc/Studio.h @@ -1,8 +1,8 @@ #pragma once +#include "CUtlVector.h" #include "BaseTypes.h" #include "Datamap.h" #include "LocalFlexController.h" -#include "../Main/UtlVector.h" #include "../Types.h" #define STUDIO_ENABLE_PERF_COUNTERS diff --git a/Amalgam/src/SDK/Definitions/Misc/VPlane.h b/Amalgam/src/SDK/Definitions/Misc/VPlane.h index 74ce5b63..ac618a61 100644 --- a/Amalgam/src/SDK/Definitions/Misc/VPlane.h +++ b/Amalgam/src/SDK/Definitions/Misc/VPlane.h @@ -2,14 +2,13 @@ #include "BaseTypes.h" #include "../Types.h" -typedef int SideType; - #define SIDE_FRONT 0 #define SIDE_BACK 1 #define SIDE_ON 2 - #define VP_EPSILON 0.01f +typedef int SideType; + class VPlane { public: diff --git a/Amalgam/src/SDK/Definitions/Misc/VTF.h b/Amalgam/src/SDK/Definitions/Misc/VTF.h index d7d7e72f..99e656a1 100644 --- a/Amalgam/src/SDK/Definitions/Misc/VTF.h +++ b/Amalgam/src/SDK/Definitions/Misc/VTF.h @@ -2,9 +2,12 @@ #include "BaseTypes.h" #include "ImageFormat.h" +#define STREAMING_START_MIPMAP 3 +#define IMAGE_FORMAT_DEFAULT ((ImageFormat)-2) + class CUtlBuffer; -struct Rect_t; class IFileSystem; +struct Rect_t; enum CompiledVtfFlags { @@ -48,7 +51,6 @@ enum VersionedVtfFlags VERSIONED_VTF_FLAGS_MASK_7_3 = ~0xD1780400 }; - struct VtfProcessingOptions { uint32 cbSize; @@ -99,9 +101,6 @@ enum LookDir_t LOOK_DOWN_NEGZ }; -#define STREAMING_START_MIPMAP 3 -#define IMAGE_FORMAT_DEFAULT ((ImageFormat)-2) - class IVTFTexture { public: diff --git a/Amalgam/src/SDK/Definitions/Misc/bitbuf.cpp b/Amalgam/src/SDK/Definitions/Misc/bitbuf.cpp index be975afa..4ffff1f5 100644 --- a/Amalgam/src/SDK/Definitions/Misc/bitbuf.cpp +++ b/Amalgam/src/SDK/Definitions/Misc/bitbuf.cpp @@ -1,5 +1,6 @@ #include "bitbuf.h" +#include #include "../Types.h" inline void Q_memcpy(void* dest, const void* src, int count) @@ -84,17 +85,6 @@ void bf_write::StartWriting(void* pData, int nBytes, int iStartBit, int nBits) m_bOverflow = false; } -#include "bitbuf.h" -#include - -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - // FIXME: Can't use this until we get multithreaded allocations in tier0 working for tools // This is used by VVIS and fails to link // NOTE: This must be the last file included!!! diff --git a/Amalgam/src/SDK/Definitions/Misc/bitbuf.h b/Amalgam/src/SDK/Definitions/Misc/bitbuf.h index 363b773c..a76d0d21 100644 --- a/Amalgam/src/SDK/Definitions/Misc/bitbuf.h +++ b/Amalgam/src/SDK/Definitions/Misc/bitbuf.h @@ -1,12 +1,11 @@ #pragma once +#include +#include #pragma warning (disable : 4244) #pragma warning (disable : 4002) class Vec3; -#include -#include - #define nullAssert assert #if _DEBUG diff --git a/Amalgam/src/SDK/Definitions/Misc/bitvec.h b/Amalgam/src/SDK/Definitions/Misc/bitvec.h index de5aad9e..7303d7b9 100644 --- a/Amalgam/src/SDK/Definitions/Misc/bitvec.h +++ b/Amalgam/src/SDK/Definitions/Misc/bitvec.h @@ -1,25 +1,12 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//===========================================================================// +#pragma once +#include "BaseTypes.h" +#include #ifndef BITVEC_H #define BITVEC_H -#ifdef _WIN32 -#pragma once -#endif - -#include -#include -#include "BaseTypes.h" - #define FORCEINLINE_TEMPLATE __forceinline #define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred ) #define Plat_FastMemset memset - -// Pad a number so it lies on an N byte boundary. -// So PAD_NUMBER(0,4) is 0 and PAD_NUMBER(1,4) is 4 #define PAD_NUMBER(number, boundary) \ ( ((number) + ((boundary)-1)) / (boundary) ) * (boundary) @@ -302,7 +289,7 @@ protected: CVarBitVecBase& operator=(const CVarBitVecBase& from); ~CVarBitVecBase(void); - void ValidateOperand(const CVarBitVecBase& operand) const { ((void)0) /*Assert(GetNumBits() == operand.GetNumBits())*/; } + void ValidateOperand(const CVarBitVecBase& operand) const { /*Assert(GetNumBits() == operand.GetNumBits());*/ } unsigned GetEndMask() const { return ::GetEndMask(GetNumBits()); } @@ -376,7 +363,7 @@ public: protected: CFixedBitVecBase() {} - CFixedBitVecBase(int numBits) { ((void)0) /*Assert(numBits == NUM_BITS)*/; } // doesn't make sense, really. Supported to simplify templates & allow easy replacement of variable + CFixedBitVecBase(int numBits) { /*Assert(numBits == NUM_BITS);*/ } // doesn't make sense, really. Supported to simplify templates & allow easy replacement of variable void ValidateOperand(const CFixedBitVecBase& operand) const { } // no need, compiler does so statically diff --git a/Amalgam/src/SDK/Definitions/Misc/dt_common.h b/Amalgam/src/SDK/Definitions/Misc/dt_common.h index 11a897aa..fd5c71c7 100644 --- a/Amalgam/src/SDK/Definitions/Misc/dt_common.h +++ b/Amalgam/src/SDK/Definitions/Misc/dt_common.h @@ -1,19 +1,10 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// +#pragma once +#include +//#include #pragma warning (push) #pragma warning (disable : 26495) -#pragma once - -//#include -#include - // Max number of properties in a datatable and its children. #define MAX_DATATABLES 1024 // must be a power of 2. #define MAX_DATATABLE_PROPS 4096 diff --git a/Amalgam/src/SDK/Definitions/Misc/dt_recv.h b/Amalgam/src/SDK/Definitions/Misc/dt_recv.h index 8b7cd4f9..27b10305 100644 --- a/Amalgam/src/SDK/Definitions/Misc/dt_recv.h +++ b/Amalgam/src/SDK/Definitions/Misc/dt_recv.h @@ -1,20 +1,8 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// +#pragma once +#include "dt_common.h" #ifndef DATATABLE_RECV_H #define DATATABLE_RECV_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "dt_common.h" - #define ADDRESSPROXY_NONE -1 class RecvTable; diff --git a/Amalgam/src/SDK/Definitions/Misc/dt_send.h b/Amalgam/src/SDK/Definitions/Misc/dt_send.h index d75b000b..04a59b68 100644 --- a/Amalgam/src/SDK/Definitions/Misc/dt_send.h +++ b/Amalgam/src/SDK/Definitions/Misc/dt_send.h @@ -1,21 +1,9 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef DATATABLE_SEND_H -#define DATATABLE_SEND_H - -#ifdef _WIN32 #pragma once -#endif - #include "dt_common.h" #include "bitvec.h" +#ifndef DATATABLE_SEND_H +#define DATATABLE_SEND_H #define ABSOLUTE_PLAYER_LIMIT 255 #define SP_MODEL_INDEX_BITS 13 diff --git a/Amalgam/src/SDK/Definitions/Types.h b/Amalgam/src/SDK/Definitions/Types.h index 1a380055..1483571d 100644 --- a/Amalgam/src/SDK/Definitions/Types.h +++ b/Amalgam/src/SDK/Definitions/Types.h @@ -1,9 +1,13 @@ #pragma once #include -#include -#include #include #include +#include +#include +#include +#include +#include +#include #define PI 3.14159265358979323846 #define M_RADPI 57.295779513082 @@ -12,8 +16,39 @@ #pragma warning (disable : 26495) +namespace Math +{ + inline float DeltaAngle(const float flAngleA, const float flAngleB) + { + float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f); + return flOut += flOut < 0 ? 180.f : -180.f; + } + + inline float ShortDist(const float flAngleA, const float flAngleB) + { + const float flDelta = fmodf((flAngleA - flAngleB), 360.f); + return fmodf(2 * flDelta, 360.f) - flDelta; + } +} + class Vec2 { +public: + static inline Vec2 Get(float v = 0.f) + { + return { v, v }; + } + + static inline Vec2 GetMin() + { + return Get(-FLT_MAX); + } + + static inline Vec2 GetMax() + { + return Get(FLT_MAX); + } + public: float x = 0.f, y = 0.f; @@ -138,21 +173,46 @@ public: return Vec2(x + v, y + v); } + inline friend Vec2 operator+(float l, const Vec2& r) + { + return Vec2(l + r.x, l + r.y); + } + inline Vec2 operator-(float v) const { return Vec2(x - v, y - v); } + inline friend Vec2 operator-(float l, const Vec2& r) + { + return Vec2(l - r.x, l - r.y); + } + inline Vec2 operator*(float v) const { return Vec2(x * v, y * v); } + inline friend Vec2 operator*(float l, const Vec2& r) + { + return Vec2(l * r.x, l * r.y); + } + inline Vec2 operator/(float v) const { return Vec2(x / v, y / v); } + inline friend Vec2 operator/(float l, const Vec2& r) + { + return Vec2(l / r.x, l / r.y); + } + + inline Vec2 operator-() const + { + return Vec2(-x, -y); + } + inline void Set(float X = 0.f, float Y = 0.f) { x = X; y = Y; @@ -210,44 +270,22 @@ public: inline Vec2 DeltaAngle(const Vec2& v) const { - auto deltaAngle = [](const float flAngleA, const float flAngleB) - { - float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f); - return flOut += flOut < 0 ? 180.f : -180.f; - }; - - return { deltaAngle(x, v.x), deltaAngle(y, v.y) }; + return { Math::DeltaAngle(x, v.x), Math::DeltaAngle(y, v.y) }; } inline Vec2 DeltaAngle(float v) const { - auto deltaAngle = [](const float flAngleA, const float flAngleB) - { - float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f); - return flOut += flOut < 0 ? 180.f : -180.f; - }; - - return { deltaAngle(x, v), deltaAngle(y, v) }; + return { Math::DeltaAngle(x, v), Math::DeltaAngle(y, v) }; } inline Vec2 LerpAngle(const Vec2& v, float t) const { - auto shortDist = [](const float flAngleA, const float flAngleB) - { - const float flDelta = fmodf((flAngleA - flAngleB), 360.f); - return fmodf(2 * flDelta, 360.f) - flDelta; - }; - return { x - shortDist(x, v.x) * t, y - shortDist(y, v.y) * t }; + return { x - Math::ShortDist(x, v.x) * t, y - Math::ShortDist(y, v.y) * t }; } inline Vec2 LerpAngle(float v, float t) const { - auto shortDist = [](const float flAngleA, const float flAngleB) - { - const float flDelta = fmodf((flAngleA - flAngleB), 360.f); - return fmodf(2 * flDelta, 360.f) - flDelta; - }; - return { x - shortDist(x, v) * t, y - shortDist(y, v) * t }; + return { x - Math::ShortDist(x, v) * t, y - Math::ShortDist(y, v) * t }; } inline float Length(void) const @@ -290,6 +328,22 @@ using Vector2D = Vec2; class Vec3 { +public: + static inline Vec3 Get(float v = 0.f) + { + return { v, v, v }; + } + + static inline Vec3 GetMin() + { + return Get(-FLT_MAX); + } + + static inline Vec3 GetMax() + { + return Get(FLT_MAX); + } + public: float x = 0.f, y = 0.f, z = 0.f; @@ -419,21 +473,46 @@ public: return Vec3(x + v, y + v, z + v); } + inline friend Vec3 operator+(float l, const Vec3& r) + { + return Vec3(l + r.x, l + r.y, l + r.z); + } + inline Vec3 operator-(float v) const { return Vec3(x - v, y - v, z - v); } + inline friend Vec3 operator-(float l, const Vec3& r) + { + return Vec3(l - r.x, l - r.y, l - r.z); + } + inline Vec3 operator*(float v) const { return Vec3(x * v, y * v, z * v); } + inline friend Vec3 operator*(float l, const Vec3& r) + { + return Vec3(l * r.x, l * r.y, l * r.z); + } + inline Vec3 operator/(float v) const { return Vec3(x / v, y / v, z / v); } + inline friend Vec3 operator/(float l, const Vec3& r) + { + return Vec3(l / r.x, l / r.y, l / r.z); + } + + inline Vec3 operator-() const + { + return Vec3(-x, -y, -z); + } + inline void Set(float X = 0.f, float Y = 0.f, float Z = 0.f) { x = X; y = Y; z = Z; @@ -444,6 +523,16 @@ public: return { x, y }; } + inline float Min() const + { + return std::min(x, std::min(y, z)); + } + + inline float Max() const + { + return std::max(x, std::max(y, z)); + } + inline Vec3 Min(const Vec3& v) const { return Vec3(std::min(x, v.x), std::min(y, v.y), std::min(z, v.z)); @@ -459,16 +548,6 @@ public: return Max(v1).Min(v2); } - inline float Min() const - { - return std::min(x, std::min(y, z)); - } - - inline float Max() const - { - return std::max(x, std::max(y, z)); - } - inline Vec3 Min(float v) const { return Vec3(std::min(x, v), std::min(y, v), std::min(z, v)); @@ -496,44 +575,22 @@ public: inline Vec3 DeltaAngle(const Vec3& v) const { - auto deltaAngle = [](const float flAngleA, const float flAngleB) - { - float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f); - return flOut += flOut < 0 ? 180.f : -180.f; - }; - - return { deltaAngle(x, v.x), deltaAngle(y, v.y), deltaAngle(z, v.z) }; + return { Math::DeltaAngle(x, v.x), Math::DeltaAngle(y, v.y), Math::DeltaAngle(z, v.z) }; } inline Vec3 DeltaAngle(float v) const { - auto deltaAngle = [](const float flAngleA, const float flAngleB) - { - float flOut = fmodf((flAngleA - flAngleB) + 180.f, 360.f); - return flOut += flOut < 0 ? 180.f : -180.f; - }; - - return { deltaAngle(x, v), deltaAngle(y, v), deltaAngle(z, v) }; + return { Math::DeltaAngle(x, v), Math::DeltaAngle(y, v), Math::DeltaAngle(z, v) }; } inline Vec3 LerpAngle(const Vec3& v, float t) const { - auto shortDist = [](const float flAngleA, const float flAngleB) - { - const float flDelta = fmodf((flAngleA - flAngleB), 360.f); - return fmodf(2 * flDelta, 360.f) - flDelta; - }; - return { x - shortDist(x, v.x) * t, y - shortDist(y, v.y) * t, z - shortDist(z, v.z) * t }; + return { x - Math::ShortDist(x, v.x) * t, y - Math::ShortDist(y, v.y) * t, z - Math::ShortDist(z, v.z) * t }; } inline Vec3 LerpAngle(float v, float t) const { - auto shortDist = [](const float flAngleA, const float flAngleB) - { - const float flDelta = fmodf((flAngleA - flAngleB), 360.f); - return fmodf(2 * flDelta, 360.f) - flDelta; - }; - return { x - shortDist(x, v) * t, y - shortDist(y, v) * t, z - shortDist(z, v) * t }; + return { x - Math::ShortDist(x, v) * t, y - Math::ShortDist(y, v) * t, z - Math::ShortDist(z, v) * t }; } inline float Length(void) const @@ -648,7 +705,7 @@ public: inline Vec3 FromAngle() const noexcept { return { cos(DEG2RAD(x)) * cos(DEG2RAD(y)), - cos(DEG2RAD(x))* sin(DEG2RAD(y)), + cos(DEG2RAD(x)) * sin(DEG2RAD(y)), -sin(DEG2RAD(x)) }; } }; @@ -904,7 +961,7 @@ struct Color_t flV = flR * 100; } - inline Color_t HueShift(float flShift) + inline Color_t HueShift(float flShift) const { float flH, flS, flV; GetHSV(flH, flS, flV); Color_t tOut; tOut.SetHSV(fmodf(flH + flShift, 360.f), flS, flV, a); diff --git a/Amalgam/src/SDK/Globals.h b/Amalgam/src/SDK/Globals.h index bd2faba7..657d2c7b 100644 --- a/Amalgam/src/SDK/Globals.h +++ b/Amalgam/src/SDK/Globals.h @@ -58,6 +58,14 @@ struct DrawSwept_t bool m_bZBuffer = false; }; +struct DrawTriangle_t +{ + std::array m_aOrigin; + float m_flTime; + Color_t m_tColor; + bool m_bZBuffer = false; +}; + struct AimTarget_t { int m_iEntIndex = 0; @@ -83,6 +91,7 @@ namespace G inline bool CanHeadshot = false; inline int Throwing = false; inline float Lerp = 0.015f; + inline float FOV = 90.f; inline EWeaponType PrimaryWeaponType = {}, SecondaryWeaponType = {}; @@ -107,6 +116,7 @@ namespace G inline std::vector BoxStorage = {}; inline std::vector SphereStorage = {}; inline std::vector SweptStorage = {}; + inline std::vector TriangleStorage = {}; inline int& RandomSeed() { diff --git a/Amalgam/src/SDK/Helpers/ConVars/ConVars.cpp b/Amalgam/src/SDK/Helpers/ConVars/ConVars.cpp index cfe0aa26..a88664ff 100644 --- a/Amalgam/src/SDK/Helpers/ConVars/ConVars.cpp +++ b/Amalgam/src/SDK/Helpers/ConVars/ConVars.cpp @@ -1,6 +1,7 @@ #include "ConVars.h" #include "../../Definitions/Interfaces/ICVar.h" +#include "../../../Utils/Hash/FNV1A.h" bool CConVars::Unlock() { diff --git a/Amalgam/src/SDK/Helpers/ConVars/ConVars.h b/Amalgam/src/SDK/Helpers/ConVars/ConVars.h index 16774b6e..62e5bb9d 100644 --- a/Amalgam/src/SDK/Helpers/ConVars/ConVars.h +++ b/Amalgam/src/SDK/Helpers/ConVars/ConVars.h @@ -1,7 +1,6 @@ #pragma once #include "../../Definitions/Misc/ConVar.h" #include "../../../Utils/Macros/Macros.h" -#include "../../../Utils/Hash/FNV1A.h" #include class CConVars diff --git a/Amalgam/src/SDK/Helpers/Draw/Draw.cpp b/Amalgam/src/SDK/Helpers/Draw/Draw.cpp index b5ba9fb2..395d3f54 100644 --- a/Amalgam/src/SDK/Helpers/Draw/Draw.cpp +++ b/Amalgam/src/SDK/Helpers/Draw/Draw.cpp @@ -4,8 +4,6 @@ #include "../../Definitions/Interfaces.h" #include "../../../Utils/Math/Math.h" #include "../../../Utils/Timer/Timer.h" -#include -#include MAKE_SIGNATURE(CHudBaseDeathNotice_GetIcon, "client.dll", "40 53 48 81 EC ? ? ? ? 48 8B DA", 0x0); MAKE_SIGNATURE(RenderLine, "engine.dll", "48 89 5C 24 ? 48 89 74 24 ? 44 89 44 24", 0x0); diff --git a/Amalgam/src/SDK/Helpers/Draw/Draw.h b/Amalgam/src/SDK/Helpers/Draw/Draw.h index a85be508..769481b2 100644 --- a/Amalgam/src/SDK/Helpers/Draw/Draw.h +++ b/Amalgam/src/SDK/Helpers/Draw/Draw.h @@ -1,7 +1,9 @@ #pragma once #include "../Fonts/Fonts.h" +#include "../../Definitions/Misc/ISurface.h" #include "../../Definitions/Definitions.h" #include "../../Vars.h" +#include "../../../Utils/Signatures/Signatures.h" MAKE_SIGNATURE(InitializeStandardMaterials, "engine.dll", "48 83 EC ? 80 3D ? ? ? ? ? 0F 85 ? ? ? ? 48 89 5C 24 ? B9 ? ? ? ? 48 89 7C 24 ? C6 05", 0x0); MAKE_SIGNATURE(Wireframe, "engine.dll", "48 89 05 ? ? ? ? E8 ? ? ? ? 48 85 C0 74 ? 48 8D 15 ? ? ? ? 48 8B C8 E8 ? ? ? ? 48 8B F8 EB ? 48 8B FB 41 B8 ? ? ? ? 48 8D 15 ? ? ? ? 48 8B CF E8 ? ? ? ? 41 B8 ? ? ? ? 48 8D 15 ? ? ? ? 48 8B CF E8 ? ? ? ? 41 B8", 0x0); @@ -9,6 +11,8 @@ MAKE_SIGNATURE(WireframeIgnoreZ, "engine.dll", "48 89 05 ? ? ? ? E8 ? ? ? ? 48 8 MAKE_SIGNATURE(VertexColor, "engine.dll", "48 89 05 ? ? ? ? E8 ? ? ? ? 48 8B 7C 24", 0x0); MAKE_SIGNATURE(VertexColorIgnoreZ, "engine.dll", "48 89 05 ? ? ? ? 48 83 C4 ? C3 CC CC CC CC CC CC CC CC CC 48 8B C4", 0x0); +class IMaterial; + enum EAlign { ALIGN_TOPLEFT, diff --git a/Amalgam/src/SDK/Helpers/Fonts/Fonts.cpp b/Amalgam/src/SDK/Helpers/Fonts/Fonts.cpp index 99d3b6d7..33d7871d 100644 --- a/Amalgam/src/SDK/Helpers/Fonts/Fonts.cpp +++ b/Amalgam/src/SDK/Helpers/Fonts/Fonts.cpp @@ -1,11 +1,14 @@ #include "Fonts.h" +#include "../../Definitions/Interfaces/IMatSystemSurface.h" +#include + void CFonts::Reload(float flDPI) { m_mFonts[FONT_ESP] = { "Verdana", int(12.f * flDPI), FONTFLAG_ANTIALIAS, 0 }; m_mFonts[FONT_INDICATORS] = { "Verdana", int(13.f * flDPI), FONTFLAG_ANTIALIAS, 0 }; - for (auto& [_, fFont] : m_mFonts) + for (auto& fFont : m_mFonts | std::views::values) { if (fFont.m_dwFont = I::MatSystemSurface->CreateFont()) I::MatSystemSurface->SetFontGlyphSet(fFont.m_dwFont, fFont.m_szName, fFont.m_nTall, fFont.m_nWeight, 0, 0, fFont.m_nFlags); diff --git a/Amalgam/src/SDK/Helpers/Fonts/Fonts.h b/Amalgam/src/SDK/Helpers/Fonts/Fonts.h index ce877ffb..95a1646d 100644 --- a/Amalgam/src/SDK/Helpers/Fonts/Fonts.h +++ b/Amalgam/src/SDK/Helpers/Fonts/Fonts.h @@ -1,6 +1,5 @@ #pragma once #include "../../../Utils/Macros/Macros.h" -#include "../../Definitions/Interfaces/IMatSystemSurface.h" #include enum EFonts diff --git a/Amalgam/src/SDK/Helpers/Particles/Particles.h b/Amalgam/src/SDK/Helpers/Particles/Particles.h index f5483caa..1ab7b762 100644 --- a/Amalgam/src/SDK/Helpers/Particles/Particles.h +++ b/Amalgam/src/SDK/Helpers/Particles/Particles.h @@ -13,11 +13,8 @@ enum ParticleAttachment_t PATTACH_CUSTOMORIGIN, // Create at a custom origin, but don't follow PATTACH_POINT, // Create on attachment point, but don't follow PATTACH_POINT_FOLLOW, // Create on attachment point, and update to follow the entity - PATTACH_WORLDORIGIN, // Used for control points that don't attach to an entity - PATTACH_ROOTBONE_FOLLOW, // Create at the root bone of the entity, and update to follow - MAX_PATTACH_TYPES, }; diff --git a/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.cpp b/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.cpp index d3be477b..01fcf244 100644 --- a/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.cpp +++ b/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.cpp @@ -2,12 +2,12 @@ #include "../../SDK.h" -bool CTraceFilterHitscan::ShouldHitEntity(IHandleEntity* pServerEntity, int nContentsMask) +bool CTraceFilterHitscan::ShouldHitEntity(IHandleEntity* pHandleEntity, int nContentsMask) { - if (!pServerEntity || pServerEntity == pSkip) + if (!pHandleEntity || pHandleEntity == pSkip) return false; - auto pEntity = reinterpret_cast(pServerEntity); + auto pEntity = reinterpret_cast(pHandleEntity); if (iTeam == -1) iTeam = pSkip ? pSkip->m_iTeamNum() : 0; if (iType != SKIP_CHECK && !vWeapons.empty()) { @@ -43,12 +43,12 @@ TraceType_t CTraceFilterHitscan::GetTraceType() const return TRACE_EVERYTHING; } -bool CTraceFilterCollideable::ShouldHitEntity(IHandleEntity* pServerEntity, int nContentsMask) +bool CTraceFilterCollideable::ShouldHitEntity(IHandleEntity* pHandleEntity, int nContentsMask) { - if (!pServerEntity || pServerEntity == pSkip) + if (!pHandleEntity || pHandleEntity == pSkip) return false; - auto pEntity = reinterpret_cast(pServerEntity); + auto pEntity = reinterpret_cast(pHandleEntity); if (iTeam == -1) iTeam = pSkip ? pSkip->m_iTeamNum() : 0; if (iType != SKIP_CHECK && !vWeapons.empty()) { @@ -109,14 +109,14 @@ TraceType_t CTraceFilterCollideable::GetTraceType() const return TRACE_EVERYTHING; } -bool CTraceFilterWorldAndPropsOnly::ShouldHitEntity(IHandleEntity* pServerEntity, int nContentsMask) +bool CTraceFilterWorldAndPropsOnly::ShouldHitEntity(IHandleEntity* pHandleEntity, int nContentsMask) { - if (!pServerEntity || pServerEntity == pSkip) + if (!pHandleEntity || pHandleEntity == pSkip) return false; - if (pServerEntity->GetRefEHandle().GetSerialNumber() == (1 << 15)) - return pServerEntity->GetRefEHandle().GetEntryIndex() != iTeam; // just use team variable since cliententitylist can give us nullptrs for some props for whatever reason + if (pHandleEntity->GetRefEHandle().GetSerialNumber() == (1 << 15)) + return pHandleEntity->GetRefEHandle().GetEntryIndex() != iTeam; // just use team variable since cliententitylist can give us nullptrs for some props for whatever reason - auto pEntity = reinterpret_cast(pServerEntity); + auto pEntity = reinterpret_cast(pHandleEntity); if (iTeam == -1) iTeam = pSkip ? pSkip->m_iTeamNum() : 0; switch (pEntity->GetClassID()) diff --git a/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.h b/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.h index fdc97702..9badcbb5 100644 --- a/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.h +++ b/Amalgam/src/SDK/Helpers/TraceFilters/TraceFilters.h @@ -1,5 +1,8 @@ #pragma once #include "../../Definitions/Interfaces/IEngineTrace.h" +#include "../../Definitions/Definitions.h" + +class CBaseEntity; enum { @@ -29,7 +32,7 @@ enum class CTraceFilterHitscan : public ITraceFilter { public: - bool ShouldHitEntity(IHandleEntity* pServerEntity, int nContentsMask) override; + bool ShouldHitEntity(IHandleEntity* pHandleEntity, int nContentsMask) override; TraceType_t GetTraceType() const override; CBaseEntity* pSkip = nullptr; @@ -43,7 +46,7 @@ public: class CTraceFilterCollideable : public ITraceFilter { public: - bool ShouldHitEntity(IHandleEntity* pServerEntity, int nContentsMask) override; + bool ShouldHitEntity(IHandleEntity* pHandleEntity, int nContentsMask) override; TraceType_t GetTraceType() const override; CBaseEntity* pSkip = nullptr; @@ -60,7 +63,7 @@ public: class CTraceFilterWorldAndPropsOnly : public ITraceFilter { public: - bool ShouldHitEntity(IHandleEntity* pServerEntity, int nContentsMask) override; + bool ShouldHitEntity(IHandleEntity* pHandleEntity, int nContentsMask) override; TraceType_t GetTraceType() const override; CBaseEntity* pSkip = nullptr; diff --git a/Amalgam/src/SDK/SDK.cpp b/Amalgam/src/SDK/SDK.cpp index 9de2b3f6..186687ca 100644 --- a/Amalgam/src/SDK/SDK.cpp +++ b/Amalgam/src/SDK/SDK.cpp @@ -162,20 +162,17 @@ double SDK::PlatFloatTime() return Plat_FloatTime(); } +static std::random_device s_tRandomDevice; +static std::mt19937 s_tEngine(s_tRandomDevice()); int SDK::StdRandomInt(int iMin, int iMax) { - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> distr(iMin, iMax); - return distr(gen); + std::uniform_int_distribution iDistribution(iMin, iMax); + return iDistribution(s_tEngine); } - float SDK::StdRandomFloat(float flMin, float flMax) { - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_real_distribution distr(flMin, flMax); - return distr(gen); + std::uniform_real_distribution flDistribution(flMin, flMax); + return flDistribution(s_tEngine); } int SDK::SeedFileLineHash(int iSeed, const char* sName, int iAdditionalSeed) @@ -195,19 +192,16 @@ int SDK::SharedRandomInt(unsigned iSeed, const char* sName, int iMinVal, int iMa I::UniformRandomStream->SetSeed(iSeed2); return I::UniformRandomStream->RandomInt(iMinVal, iMaxVal); } - void SDK::RandomSeed(int iSeed) { static auto RandomSeed = U::Memory.GetModuleExport("vstdlib.dll", "RandomSeed"); RandomSeed(iSeed); } - int SDK::RandomInt(int iMinVal, int iMaxVal) { static auto RandomInt = U::Memory.GetModuleExport("vstdlib.dll", "RandomInt"); return RandomInt(iMinVal, iMaxVal); } - float SDK::RandomFloat(float flMinVal, float flMaxVal) { static auto RandomFloat = U::Memory.GetModuleExport("vstdlib.dll", "RandomFloat"); @@ -720,7 +714,7 @@ void SDK::FixMovement(CUserCmd* pCmd, const Vec3& vCurAngle, const Vec3& vTarget bool bCurOOB = fabsf(Math::NormalizeAngle(vCurAngle.x)) > 90.f; bool bTargetOOB = fabsf(Math::NormalizeAngle(vTargetAngle.x)) > 90.f; - Vec3 vMove = { pCmd->forwardmove, pCmd->sidemove * (bCurOOB ? -1 : 1), pCmd->upmove }; + Vec3 vMove = { pCmd->forwardmove, pCmd->sidemove * (bCurOOB ? -1 : 1), pCmd->upmove}; float flSpeed = vMove.Length2D(); Vec3 vMoveAng = Math::VectorAngles(vMove); @@ -748,7 +742,7 @@ bool SDK::StopMovement(CTFPlayer* pLocal, CUserCmd* pCmd) if (G::Attacking != 1) { - float flDirection = Math::VectorAngles(pLocal->m_vecVelocity() * -1).y; + float flDirection = Math::VectorAngles(-pLocal->m_vecVelocity()).y; pCmd->viewangles = { 90, flDirection, 0 }; pCmd->sidemove = 0; pCmd->forwardmove = 0; return true; diff --git a/Amalgam/src/SDK/SDK.h b/Amalgam/src/SDK/SDK.h index cbcca0a6..477663d9 100644 --- a/Amalgam/src/SDK/SDK.h +++ b/Amalgam/src/SDK/SDK.h @@ -68,9 +68,9 @@ #define OUTPUT_CHAT 1 << 4 #define OUTPUT_PARTY 1 << 5 -template int sign(T val) +template inline int sign(T t) { - return (val > T(0)) - (val < T(0)); + return (t > T(0)) - (t < T(0)); } inline float fnmodf(float flX, float flY) @@ -97,8 +97,8 @@ namespace SDK bool IsGameWindowInFocus(); double PlatFloatTime(); - int StdRandomInt(int iMin, int iMax); - float StdRandomFloat(float flMin, float flMax); + int StdRandomInt(int iMin = 0, int iMax = VALVE_RAND_MAX); + float StdRandomFloat(float flMin = 0.f, float flMax = 1.f); int SeedFileLineHash(int iSeed, const char* sName, int iAdditionalSeed); int SharedRandomInt(unsigned iSeed, const char* sName, int iMinVal, int iMaxVal, int iAdditionalSeed); diff --git a/Amalgam/src/SDK/Vars.h b/Amalgam/src/SDK/Vars.h index 5f9a0a44..26e9499d 100644 --- a/Amalgam/src/SDK/Vars.h +++ b/Amalgam/src/SDK/Vars.h @@ -2,8 +2,6 @@ #include "../SDK/Definitions/Types.h" #include "../Utils/Macros/Macros.h" #include -#include -#include #include #define DEFAULT_BIND -1 @@ -360,23 +358,20 @@ NAMESPACE_BEGIN(Vars) CVar(HuntsmanPullPoint, "Huntsman pull point", false, NOSAVE | DEBUGVAR); CVar(HuntsmanPullNoZ, "Pull no Z", false, NOSAVE | DEBUGVAR); + CVarEnum(SplashMode, "Splash mode", 0, NOSAVE | DEBUGVAR, nullptr, + VA_LIST("Trace", "Face"), + Trace, Face); CVar(SplashPointsDirect, "Splash points direct", 100, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 0, 400, 5); CVar(SplashPointsArc, "Splash points arc", 100, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 0, 400, 5); - CVar(SplashCountDirect, "Splash count direct", 100, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 1, 400, 5); - CVar(SplashCountArc, "Splash count arc", 5, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 1, 400, 5); CVar(SplashRotateX, "Splash Rx", -1.f, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, -1.f, 360.f); CVar(SplashRotateY, "Splash Ry", -1.f, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, -1.f, 360.f); + CVar(SplashDensityDirect, "Splash density direct", 40.f, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 0.f, 100.f, 1.f); + CVar(SplashDensityArc, "Splash density arc", 40.f, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 0.f, 100.f, 1.f); + CVar(SplashSamplesCutoff, "Splash samples cutoff", 0.0000001f, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 0.f, 0.000001f, 0.00000001f); + CVar(SplashCountDirect, "Splash count direct", 100, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 1, 400, 5); + CVar(SplashCountArc, "Splash count arc", 5, NOSAVE | DEBUGVAR | SLIDER_MIN | SLIDER_PRECISION, 1, 400, 5); CVar(SplashTraceInterval, "Splash trace interval", 10, NOSAVE | DEBUGVAR, 1, 10); CVar(SplashNormalSkip, "Splash normal skip", 1, NOSAVE | DEBUGVAR | SLIDER_MIN, 1, 10); - CVarEnum(SplashMode, "Splash mode", 0, NOSAVE | DEBUGVAR, nullptr, - VA_LIST("Multi", "Single"), - Multi, Single); - CVarEnum(RocketSplashMode, "Rocket splash mode", 0, NOSAVE | DEBUGVAR, nullptr, - VA_LIST("Regular", "Special light", "Special heavy"), - Regular, SpecialLight, SpecialHeavy); - CVar(SplashGrates, "Splash grates", true, NOSAVE | DEBUGVAR); - CVar(Out2NormalMin, "Out2 normal min", -0.7f, NOSAVE | DEBUGVAR | SLIDER_CLAMP | SLIDER_PRECISION, -1.f, 1.f, 0.1f); - CVar(Out2NormalMax, "Out2 normal max", 0.7f, NOSAVE | DEBUGVAR | SLIDER_CLAMP | SLIDER_PRECISION, -1.f, 1.f, 0.1f); CVar(DeltaCount, "Delta count", 5, NOSAVE | DEBUGVAR, 1, 5); CVarEnum(DeltaMode, "Delta mode", 0, NOSAVE | DEBUGVAR, nullptr, diff --git a/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp b/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp index 4e85f72f..462a6fd1 100644 --- a/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp +++ b/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp @@ -80,7 +80,7 @@ static inline std::deque StackTrace(PCONTEXT pContext) } { - uintptr_t dwOffset = 0; + DWORD64 dwOffset = 0; char buf[sizeof(IMAGEHLP_SYMBOL64) + 255]; auto symbol = PIMAGEHLP_SYMBOL64(buf); symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64) + 255; diff --git a/Amalgam/src/Utils/Interfaces/Interfaces.cpp b/Amalgam/src/Utils/Interfaces/Interfaces.cpp index ca80a794..1a132019 100644 --- a/Amalgam/src/Utils/Interfaces/Interfaces.cpp +++ b/Amalgam/src/Utils/Interfaces/Interfaces.cpp @@ -10,7 +10,7 @@ #pragma warning (disable: 4172) -InterfaceInit_t::InterfaceInit_t(void** pPtr, const char* sDLL, const char* sName, int8_t nType, int8_t nOffset, int8_t nDereferenceCount) +InterfaceInit_t::InterfaceInit_t(void** pPtr, const char* sDLL, const char* sName, int8_t nType, int8_t nOffset, int8_t nDereferenceCount, bool bNullCheck) { m_pPtr = pPtr; m_sDLL = sDLL; @@ -18,6 +18,7 @@ InterfaceInit_t::InterfaceInit_t(void** pPtr, const char* sDLL, const char* sNam m_nType = nType; m_nOffset = nOffset; m_nDereferenceCount = nDereferenceCount; + m_bNullCheck = bNullCheck; U::Interfaces.AddInterface(this); } @@ -85,15 +86,14 @@ bool CInterfaces::Initialize() *Interface->m_pPtr = *reinterpret_cast(*Interface->m_pPtr); } - if (!*Interface->m_pPtr) + if (Interface->m_bNullCheck && !*Interface->m_pPtr) { U::Core.AppendFailText(std::format("CInterfaces::Initialize() failed to initialize:\n {}\n {}", sModule, Interface->m_sName).c_str()); m_bFailed = true; } } - if (!H::Interfaces.Initialize()) - m_bFailed = true; // Initialize any null interfaces + m_bFailed = !H::Interfaces.Initialize() || m_bFailed; // initialize any null interfaces return !m_bFailed; } \ No newline at end of file diff --git a/Amalgam/src/Utils/Interfaces/Interfaces.h b/Amalgam/src/Utils/Interfaces/Interfaces.h index 1ab73df1..096c90aa 100644 --- a/Amalgam/src/Utils/Interfaces/Interfaces.h +++ b/Amalgam/src/Utils/Interfaces/Interfaces.h @@ -10,26 +10,27 @@ struct InterfaceInit_t int8_t m_nType; // 0: find interface, 1: get export, 2: sig scan int8_t m_nOffset; int8_t m_nDereferenceCount; + bool m_bNullCheck; - InterfaceInit_t(void** pPtr, const char* sDLL, const char* sName, int8_t nType, int8_t nOffset = 0, int8_t nDereferenceCount = 0); + InterfaceInit_t(void** pPtr, const char* sDLL, const char* sName, int8_t nType, int8_t nOffset = 0, int8_t nDereferenceCount = 0, bool bNullCheck = true); }; -#define MAKE_INTERFACE_VERSION(type, symbol, dll, version) namespace I { inline type *symbol = nullptr; } \ +#define MAKE_INTERFACE_VERSION(type, symbol, dll, version, ...) namespace I { inline type *symbol = nullptr; } \ namespace MAKE_INTERFACE_SCOPE \ {\ - inline InterfaceInit_t symbol##InterfaceInit_t(reinterpret_cast(&I::symbol), dll, version, 0); \ + inline InterfaceInit_t symbol##InterfaceInit_t(reinterpret_cast(&I::symbol), dll, version, 0, __VA_ARGS__); \ } -#define MAKE_INTERFACE_EXPORT(type, symbol, dll, name, deref) namespace I { inline type *symbol = nullptr; } \ +#define MAKE_INTERFACE_EXPORT(type, symbol, dll, name, deref, ...) namespace I { inline type *symbol = nullptr; } \ namespace MAKE_INTERFACE_SCOPE \ {\ - inline InterfaceInit_t symbol##InterfaceInit_t(reinterpret_cast(&I::symbol), dll, name, 1, 0, deref); \ + inline InterfaceInit_t symbol##InterfaceInit_t(reinterpret_cast(&I::symbol), dll, name, 1, 0, deref, __VA_ARGS__); \ } -#define MAKE_INTERFACE_SIGNATURE(type, symbol, dll, signature, offset, deref) namespace I { inline type *symbol = nullptr; } \ +#define MAKE_INTERFACE_SIGNATURE(type, symbol, dll, signature, offset, deref, ...) namespace I { inline type *symbol = nullptr; } \ namespace MAKE_INTERFACE_SCOPE \ {\ - inline InterfaceInit_t symbol##InterfaceInit_t(reinterpret_cast(&I::symbol), dll, signature, 2, offset, deref); \ + inline InterfaceInit_t symbol##InterfaceInit_t(reinterpret_cast(&I::symbol), dll, signature, 2, offset, deref, __VA_ARGS__); \ } #define MAKE_INTERFACE_NULL(type, symbol) namespace I { inline type *symbol = nullptr; } diff --git a/Amalgam/src/Utils/Math/Math.h b/Amalgam/src/Utils/Math/Math.h index 6594ca1b..ca052bdc 100644 --- a/Amalgam/src/Utils/Math/Math.h +++ b/Amalgam/src/Utils/Math/Math.h @@ -1,11 +1,8 @@ #pragma once - #include "../../SDK/Definitions/Types.h" - #include #include #include -#include #undef min #undef max @@ -14,7 +11,7 @@ #pragma warning (disable : 26451) #pragma warning (disable : 4244) -#define floatCompare(x, y) (fabsf(x - y) <= FLT_EPSILON * fmaxf(1.f, fmaxf(fabsf(x), fabsf(y)))) +#define FLT_COMPARE(x, y) (fabsf(x - y) <= FLT_EPSILON * fmaxf(1.f, fmaxf(fabsf(x), fabsf(y)))) namespace Math { @@ -197,9 +194,9 @@ namespace Math return flResult; } - inline Vec3 RotatePoint(Vec3 vPoint, Vec3 vOrigin, Vec3 vAngles) + inline Vec3 RotatePoint(const Vec3& vPoint, const Vec3& vOrigin, const Vec3& vAngles) { - vPoint -= vOrigin; + Vec3 vOffset = vPoint - vOrigin; float sp, sy, sr, cp, cy, cr; SinCos(DEG2RAD(vAngles.x), &sp, &cp); @@ -222,7 +219,23 @@ namespace Math cp * cr }; - return Vec3(vX.Dot(vPoint), vY.Dot(vPoint), vZ.Dot(vPoint)) + vOrigin; + return Vec3(vX.Dot(vOffset), vY.Dot(vOffset), vZ.Dot(vOffset)) + vOrigin; + } + + inline bool IsBoxIntersectingBox(const Vec3& vMins1, const Vec3& vMaxs1, const Vec3& vMins2, const Vec3& vMaxs2) + { + if ((vMins1.x > vMaxs2.x) || (vMaxs1.x < vMins2.x)) + return false; + if ((vMins1.y > vMaxs2.y) || (vMaxs1.y < vMins2.y)) + return false; + if ((vMins1.z > vMaxs2.z) || (vMaxs1.z < vMins2.z)) + return false; + return true; + } + + inline bool IsPointIntersectingBox(const Vec3& vPoint, const Vec3& vMins, const Vec3& vMaxs) + { + return IsBoxIntersectingBox(vPoint, vPoint, vMins, vMaxs); } inline void VectorTransform(const Vec3& vIn, const matrix3x4& mMatrix, Vec3& vOut) @@ -231,6 +244,29 @@ namespace Math vOut[i] = vIn.Dot(mMatrix[i]) + mMatrix[i][3]; } + inline Vec3 VectorTransform(const Vec3& vIn, const matrix3x4& mMatrix) + { + Vec3 vOut; + VectorTransform(vIn, mMatrix, vOut); + return vOut; + } + + inline void VectorITransform(const Vec3& vIn, const matrix3x4& mMatrix, Vec3& vOut) + { + Vec3 vMatrixT; + for (auto i = 0; i < 3; i++) + vMatrixT[i] = vIn[i] - mMatrix[i][3]; + for (auto i = 0; i < 3; i++) + vOut[i] = vMatrixT[0] * mMatrix[0][i] + vMatrixT[1] * mMatrix[1][i] + vMatrixT[2] * mMatrix[2][i]; + } + + inline Vec3 VectorITransform(const Vec3& vIn, const matrix3x4& mMatrix) + { + Vec3 vOut; + VectorITransform(vIn, mMatrix, vOut); + return vOut; + } + inline void MatrixSetColumn(const Vec3& vIn, int iColumn, matrix3x4& mOut) { mOut[0][iColumn] = vIn.x; @@ -291,6 +327,13 @@ namespace Math } } + inline Vec3 MatrixAngles(const matrix3x4& mMatrix) + { + Vec3 vOut; + MatrixAngles(mMatrix, vOut); + return vOut; + } + inline bool RayToOBB(const Vec3& vOrigin, const Vec3& vDirection, const Vec3& vMins, const Vec3& vMaxs, const matrix3x4& mMatrix, float flScale = 1.f) { if (!flScale) @@ -311,7 +354,7 @@ namespace Math for (int i = 0; i < 3; ++i) { - if (floatCompare(f[i], 0.f)) + if (FLT_COMPARE(f[i], 0.f)) { if (-e[i] + vMins[i] * flScale > 0.f || -e[i] + vMaxs[i] * flScale < 0.f) return false; @@ -332,11 +375,18 @@ namespace Math return true; } - inline void VectorRotate(Vec3& vIn, const matrix3x4& mIn, Vec3& vOut) + inline void VectorRotate(const Vec3& vIn, const matrix3x4& mMatrix, Vec3& vOut) { - vOut.x = vIn.Dot(mIn[0]); - vOut.y = vIn.Dot(mIn[1]); - vOut.z = vIn.Dot(mIn[2]); + vOut.x = vIn.Dot(mMatrix[0]); + vOut.y = vIn.Dot(mMatrix[1]); + vOut.z = vIn.Dot(mMatrix[2]); + } + + inline Vec3 VectorRotate(const Vec3& vIn, const matrix3x4& mMatrix) + { + Vec3 vOut; + VectorRotate(vIn, mMatrix, vOut); + return vOut; } inline void MatrixCopy(const matrix3x4& mIn, matrix3x4& mOut) @@ -354,6 +404,13 @@ namespace Math vOrigin.y = mMatrix[1][3]; vOrigin.z = mMatrix[2][3]; } + + inline Vec3 GetMatrixOrigin(const matrix3x4& mMatrix) + { + Vec3 vOut; + GetMatrixOrigin(mMatrix, vOut); + return vOut; + } inline void ConcatTransforms(const matrix3x4& mIn1, const matrix3x4& mIn2, matrix3x4& mOut) { diff --git a/Amalgam/src/Utils/Memory/Memory.h b/Amalgam/src/Utils/Memory/Memory.h index ed2fdc74..a02c1517 100644 --- a/Amalgam/src/Utils/Memory/Memory.h +++ b/Amalgam/src/Utils/Memory/Memory.h @@ -19,14 +19,20 @@ public: inline void* GetVirtual(void* p, size_t i) { - auto vTable = *static_cast(p); + auto vTable = *reinterpret_cast(p); + return vTable[i]; + } + + inline void* GetVirtual(uintptr_t u, size_t i) + { + auto vTable = *reinterpret_cast(u); return vTable[i]; } template inline T CallVirtual(void* p, Args... args) const { - auto vTable = *static_cast(p); + auto vTable = *reinterpret_cast(p); return reinterpret_cast(vTable[I])(p, args...); } @@ -34,7 +40,7 @@ public: inline T CallVirtual(uintptr_t u, Args... args) const { auto p = reinterpret_cast(u); - auto vTable = *static_cast(p); + auto vTable = *reinterpret_cast(p); return reinterpret_cast(vTable[I])(p, args...); }