From 0f3a2adedab337622b8733d2cf5c34e7bf842fe1 Mon Sep 17 00:00:00 2001 From: rei-2 <174158077+rei-2@users.noreply.github.com> Date: Sat, 14 Mar 2026 17:45:35 -0400 Subject: [PATCH] add face splash currently off by default, can be enabled in debug vars under projectile points on faces currently generated completely randomly injecting midgame and using face splash will freeze the game temporarily to cache faces --- Amalgam/Amalgam.vcxproj | 33 +- Amalgam/Amalgam.vcxproj.filters | 33 +- Amalgam/cpp.hint | 20 +- Amalgam/src/Features/Aimbot/Aimbot.cpp | 2 +- Amalgam/src/Features/Aimbot/Aimbot.h | 1 - .../Aimbot/AimbotGlobal/AimbotGlobal.cpp | 12 +- .../Aimbot/AimbotHitscan/AimbotHitscan.cpp | 34 +- .../Aimbot/AimbotMelee/AimbotMelee.cpp | 32 +- .../AimbotProjectile/AimbotProjectile.cpp | 802 +++---- .../AimbotProjectile/AimbotProjectile.h | 17 +- .../src/Features/Aimbot/AutoHeal/AutoHeal.cpp | 24 +- .../Aimbot/AutoRocketJump/AutoRocketJump.cpp | 18 +- Amalgam/src/Features/Backtrack/Backtrack.cpp | 86 +- Amalgam/src/Features/Binds/Binds.cpp | 80 +- Amalgam/src/Features/Commands/Commands.h | 2 +- Amalgam/src/Features/Configs/Configs.cpp | 12 +- Amalgam/src/Features/CritHack/CritHack.cpp | 38 +- Amalgam/src/Features/ImGui/Menu/Components.h | 32 +- Amalgam/src/Features/ImGui/Menu/Menu.cpp | 1872 +++++++++-------- Amalgam/src/Features/ImGui/Render.cpp | 24 +- Amalgam/src/Features/Misc/Misc.cpp | 40 +- .../Features/PacketManip/FakeLag/FakeLag.cpp | 2 +- Amalgam/src/Features/Players/PlayerCore.cpp | 2 +- Amalgam/src/Features/Players/PlayerUtils.cpp | 12 +- Amalgam/src/Features/Resolver/Resolver.cpp | 48 +- .../MovementSimulation/MovementSimulation.cpp | 4 +- .../MovementSimulation/MovementSimulation.h | 6 +- .../ProjectileSimulation.cpp | 5 +- Amalgam/src/Features/Visuals/Chams/Chams.cpp | 26 +- Amalgam/src/Features/Visuals/ESP/ESP.cpp | 74 +- Amalgam/src/Features/Visuals/Glow/Glow.cpp | 26 +- .../Features/Visuals/Materials/Materials.cpp | 40 +- Amalgam/src/Features/Visuals/Visuals.cpp | 81 +- Amalgam/src/Features/World/World.cpp | 536 +++++ Amalgam/src/Features/World/World.h | 100 + .../src/Hooks/CModelLoader_Map_LoadModel.cpp | 39 + Amalgam/src/Hooks/COPRenderSprites_Render.cpp | 2 +- .../Hooks/CSoundEmitterSystem_EmitSound.cpp | 54 +- .../CStaticPropMgr_ComputePropOpacity.cpp | 36 - Amalgam/src/Hooks/CTFPlayerShared_InCond.cpp | 18 +- Amalgam/src/Hooks/CTFPlayer_GetMinFOV.cpp | 17 + Amalgam/src/Hooks/IEngineTrace_TraceRay.cpp | 109 +- .../src/Hooks/IMaterialSystem_FindTexture.cpp | 26 +- Amalgam/src/SDK/Definitions/Classes.h | 6 +- Amalgam/src/SDK/Definitions/Definitions.h | 5 - Amalgam/src/SDK/Definitions/Interfaces.h | 5 + .../SDK/Definitions/Interfaces/CClientState.h | 6 +- .../Interfaces/CCollisionBSPData.h | 52 + .../Definitions/Interfaces/CDispCollTree.h | 114 + .../SDK/Definitions/Interfaces/CHLClient.h | 46 +- .../SDK/Definitions/Interfaces/CHLTVCamera.h | 28 +- .../Definitions/Interfaces/CStaticPropMgr.h | 130 ++ .../Interfaces/CThirdPersonManager.h | 1 - .../src/SDK/Definitions/Interfaces/ICVar.h | 1 - .../SDK/Definitions/Interfaces/IEngineTrace.h | 52 +- .../SDK/Definitions/Interfaces/IFileSystem.h | 37 +- .../SDK/Definitions/Interfaces/IGameEvents.h | 6 +- .../Definitions/Interfaces/IGameMovement.h | 6 +- .../src/SDK/Definitions/Interfaces/IInput.h | 1 + .../Definitions/Interfaces/IKeyValuesSystem.h | 2 +- .../SDK/Definitions/Interfaces/ILocalize.h | 3 +- .../Interfaces/IMatSystemSurface.h | 1 - .../Definitions/Interfaces/IMaterialSystem.h | 163 +- .../SDK/Definitions/Interfaces/IMemAlloc.h | 2 +- .../SDK/Definitions/Interfaces/IMoveHelper.h | 7 +- .../{Misc => Interfaces}/ISpatialPartition.h | 28 +- .../Definitions/Interfaces/IStudioRender.h | 115 +- .../Definitions/Interfaces/IVEngineClient.h | 25 +- .../SDK/Definitions/Interfaces/IVModelInfo.h | 18 +- .../Definitions/Interfaces/IVModelRender.h | 29 +- .../SDK/Definitions/Interfaces/IVRenderView.h | 5 +- .../SDK/Definitions/Interfaces/IViewRender.h | 113 +- .../SDK/Definitions/Interfaces/Prediction.h | 6 +- .../src/SDK/Definitions/Interfaces/VPhysics.h | 947 ++++----- .../Definitions/Interfaces/ViewRenderBeams.h | 53 +- .../Definitions/Interfaces/WorldBrushData.h | 5 + .../src/SDK/Definitions/Main/CBaseAnimating.h | 3 +- .../src/SDK/Definitions/Main/CBaseEntity.h | 6 +- .../src/SDK/Definitions/Main/CBaseHandle.h | 4 +- .../src/SDK/Definitions/Main/CBasePlayer.h | 3 +- Amalgam/src/SDK/Definitions/Main/CBaseTrace.h | 11 +- .../SDK/Definitions/Main/CCollisionProperty.h | 30 +- .../SDK/Definitions/Main/CEconDefinition.h | 3 +- .../SDK/Definitions/Main/CEntitySphereQuery.h | 17 +- Amalgam/src/SDK/Definitions/Main/CGameTrace.h | 5 +- .../src/SDK/Definitions/Main/CMapLoadHelper.h | 120 ++ Amalgam/src/SDK/Definitions/Main/CModel.h | 573 ++++- .../Definitions/Main/CMultiPlayerAnimState.h | 8 +- .../SDK/Definitions/Main/CParticleProperty.h | 2 +- .../SDK/Definitions/Main/CPlayerResource.h | 1 - .../SDK/Definitions/Main/CPredictionCopy.h | 7 +- .../src/SDK/Definitions/Main/CStaticProp.h | 108 + .../SDK/Definitions/Main/CTFWeaponBase.cpp | 62 +- .../SDK/Definitions/Main/IAchievementMgr.h | 5 +- .../SDK/Definitions/Main/IClientNetworkable.h | 4 +- .../SDK/Definitions/Main/IClientRenderable.h | 6 +- .../src/SDK/Definitions/Main/ICollideable.h | 37 + Amalgam/src/SDK/Definitions/Main/IDispInfo.h | 50 + Amalgam/src/SDK/Definitions/Main/IMaterial.h | 11 +- .../src/SDK/Definitions/Main/INetChannel.h | 5 +- .../src/SDK/Definitions/Main/INetMessage.h | 2 +- .../SDK/Definitions/Main/INetworkMessage.h | 1 - .../src/SDK/Definitions/Main/INetworkSystem.h | 1 - Amalgam/src/SDK/Definitions/Main/MD5.cpp | 1 + Amalgam/src/SDK/Definitions/Main/NetChannel.h | 5 +- .../src/SDK/Definitions/Main/PlayerStats.h | 2 +- Amalgam/src/SDK/Definitions/Main/Ray.h | 76 + Amalgam/src/SDK/Definitions/Main/UtlVector.h | 752 ------- Amalgam/src/SDK/Definitions/Misc/BSPFlags.h | 2 - .../src/SDK/Definitions/Misc/CByteSwap.cpp | 82 + Amalgam/src/SDK/Definitions/Misc/CByteSwap.h | 239 +++ .../SDK/Definitions/Misc/CDiscardableArray.h | 68 + .../Definitions/Misc/CRangeValidatedArray.h | 63 + .../Misc/{SmartPtr.h => CSmartPtr.h} | 14 +- .../src/SDK/Definitions/Misc/CUtlBuffer.cpp | 1684 +++++++++++++++ Amalgam/src/SDK/Definitions/Misc/CUtlBuffer.h | 987 +++++++++ .../Definitions/Misc/CUtlCharConversion.cpp | 89 + .../SDK/Definitions/Misc/CUtlCharConversion.h | 38 + ...UtlIntrusiveList.h => CUtlIntrusiveList.h} | 70 +- Amalgam/src/SDK/Definitions/Misc/CUtlMemory.h | 1060 ++++++++++ ...bjectReference.h => CUtlObjectReference.h} | 33 +- Amalgam/src/SDK/Definitions/Misc/CUtlString.h | 6 + Amalgam/src/SDK/Definitions/Misc/CUtlVector.h | 569 +++++ .../src/SDK/Definitions/Misc/ChecksumCRC.cpp | 7 +- Amalgam/src/SDK/Definitions/Misc/ConVar.h | 33 +- Amalgam/src/SDK/Definitions/Misc/Cursor.h | 1 - Amalgam/src/SDK/Definitions/Misc/Datamap.h | 6 +- .../src/SDK/Definitions/Misc/IClientMode.h | 2 +- .../Definitions/Misc/IColorCorrectionSystem.h | 2 +- Amalgam/src/SDK/Definitions/Misc/IConVar.h | 5 +- Amalgam/src/SDK/Definitions/Misc/IImage.h | 1 - Amalgam/src/SDK/Definitions/Misc/IMDLCache.h | 15 +- .../Definitions/Misc/IMatchGroupDescription.h | 3 +- .../Misc/IMaterialSystemHardwareConfig.h | 4 +- Amalgam/src/SDK/Definitions/Misc/ISurface.h | 1 + .../src/SDK/Definitions/Misc/ImageFormat.h | 4 +- Amalgam/src/SDK/Definitions/Misc/InputEnums.h | 18 +- Amalgam/src/SDK/Definitions/Misc/Studio.h | 2 +- Amalgam/src/SDK/Definitions/Misc/VPlane.h | 5 +- Amalgam/src/SDK/Definitions/Misc/VTF.h | 9 +- Amalgam/src/SDK/Definitions/Misc/bitbuf.cpp | 12 +- Amalgam/src/SDK/Definitions/Misc/bitbuf.h | 5 +- Amalgam/src/SDK/Definitions/Misc/bitvec.h | 23 +- Amalgam/src/SDK/Definitions/Misc/dt_common.h | 15 +- Amalgam/src/SDK/Definitions/Misc/dt_recv.h | 16 +- Amalgam/src/SDK/Definitions/Misc/dt_send.h | 16 +- Amalgam/src/SDK/Definitions/Types.h | 189 +- Amalgam/src/SDK/Globals.h | 10 + Amalgam/src/SDK/Helpers/ConVars/ConVars.cpp | 1 + Amalgam/src/SDK/Helpers/ConVars/ConVars.h | 1 - Amalgam/src/SDK/Helpers/Draw/Draw.cpp | 2 - Amalgam/src/SDK/Helpers/Draw/Draw.h | 4 + Amalgam/src/SDK/Helpers/Fonts/Fonts.cpp | 5 +- Amalgam/src/SDK/Helpers/Fonts/Fonts.h | 1 - Amalgam/src/SDK/Helpers/Particles/Particles.h | 3 - .../SDK/Helpers/TraceFilters/TraceFilters.cpp | 22 +- .../SDK/Helpers/TraceFilters/TraceFilters.h | 9 +- Amalgam/src/SDK/SDK.cpp | 22 +- Amalgam/src/SDK/SDK.h | 8 +- Amalgam/src/SDK/Vars.h | 21 +- .../ExceptionHandler/ExceptionHandler.cpp | 2 +- Amalgam/src/Utils/Interfaces/Interfaces.cpp | 8 +- Amalgam/src/Utils/Interfaces/Interfaces.h | 15 +- Amalgam/src/Utils/Math/Math.h | 81 +- Amalgam/src/Utils/Memory/Memory.h | 12 +- 165 files changed, 9767 insertions(+), 4274 deletions(-) create mode 100644 Amalgam/src/Features/World/World.cpp create mode 100644 Amalgam/src/Features/World/World.h create mode 100644 Amalgam/src/Hooks/CModelLoader_Map_LoadModel.cpp create mode 100644 Amalgam/src/SDK/Definitions/Interfaces/CCollisionBSPData.h create mode 100644 Amalgam/src/SDK/Definitions/Interfaces/CDispCollTree.h create mode 100644 Amalgam/src/SDK/Definitions/Interfaces/CStaticPropMgr.h rename Amalgam/src/SDK/Definitions/{Misc => Interfaces}/ISpatialPartition.h (97%) create mode 100644 Amalgam/src/SDK/Definitions/Interfaces/WorldBrushData.h create mode 100644 Amalgam/src/SDK/Definitions/Main/CMapLoadHelper.h create mode 100644 Amalgam/src/SDK/Definitions/Main/CStaticProp.h create mode 100644 Amalgam/src/SDK/Definitions/Main/ICollideable.h create mode 100644 Amalgam/src/SDK/Definitions/Main/IDispInfo.h create mode 100644 Amalgam/src/SDK/Definitions/Main/Ray.h delete mode 100644 Amalgam/src/SDK/Definitions/Main/UtlVector.h create mode 100644 Amalgam/src/SDK/Definitions/Misc/CByteSwap.cpp create mode 100644 Amalgam/src/SDK/Definitions/Misc/CByteSwap.h create mode 100644 Amalgam/src/SDK/Definitions/Misc/CDiscardableArray.h create mode 100644 Amalgam/src/SDK/Definitions/Misc/CRangeValidatedArray.h rename Amalgam/src/SDK/Definitions/Misc/{SmartPtr.h => CSmartPtr.h} (96%) create mode 100644 Amalgam/src/SDK/Definitions/Misc/CUtlBuffer.cpp create mode 100644 Amalgam/src/SDK/Definitions/Misc/CUtlBuffer.h create mode 100644 Amalgam/src/SDK/Definitions/Misc/CUtlCharConversion.cpp create mode 100644 Amalgam/src/SDK/Definitions/Misc/CUtlCharConversion.h rename Amalgam/src/SDK/Definitions/Misc/{UtlIntrusiveList.h => CUtlIntrusiveList.h} (89%) create mode 100644 Amalgam/src/SDK/Definitions/Misc/CUtlMemory.h rename Amalgam/src/SDK/Definitions/Misc/{UtlObjectReference.h => CUtlObjectReference.h} (68%) create mode 100644 Amalgam/src/SDK/Definitions/Misc/CUtlString.h create mode 100644 Amalgam/src/SDK/Definitions/Misc/CUtlVector.h 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...); }