From bf103d6e2f99d0f544027940ff7d805879e68524 Mon Sep 17 00:00:00 2001 From: rei-2 <174158077+rei-2@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:48:54 -0400 Subject: [PATCH] misc changes and fixes fix dormancy bug relating to dead to spawned players reverse average yaw upon landing in movesim add usererror assert in fdropdown for arg mismatch --- .../AimbotProjectile/AimbotProjectile.cpp | 2 +- Amalgam/src/Features/ImGui/Menu/Components.h | 87 +++++++++---------- Amalgam/src/Features/ImGui/Menu/Menu.cpp | 49 ++++------- .../MovementSimulation/MovementSimulation.cpp | 19 ++-- Amalgam/src/SDK/Helpers/Entities/Entities.cpp | 13 +-- Amalgam/src/SDK/SDK.cpp | 13 +-- Amalgam/src/SDK/SDK.h | 1 + .../ExceptionHandler/ExceptionHandler.cpp | 19 ++-- 8 files changed, 93 insertions(+), 110 deletions(-) diff --git a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp index fbfec735..0587e790 100644 --- a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp @@ -551,7 +551,7 @@ static inline void HandleFace(Face_t& tFace, std::vector& vPoints, floa // don't particularly like the hacky random epsilons int iFaceClosest = SDK::StdRandomInt(iSamples < 2 ? 0 : iSamples < 4 ? 1 : 2, iSamples < 2 ? 1 : 2); //int iEdgeClosest = SDK::StdRandomInt(iSamples < 8 ? 0 : iSamples < 16 ? 1 : 2, iSamples < 8 ? 1 : 2); // eats up a bit too much performance for my liking - int iEdgeRandom = SDK::StdRandomInt(iSamples < 8 ? 0 : iSamples < 16 ? 1 : 2, iSamples < 3 ? 0 : iSamples < 12 ? 1 : 2); + int iEdgeRandom = SDK::StdRandomInt(iSamples < 8 ? 0 : iSamples < 16 ? 1 : 2, iSamples < 3 && iFaceClosest ? 0 : iSamples < 12 ? 1 : 2); iEdgeRandom += iFaceClosest; //iEdgeClosest += iFaceClosest, iEdgeRandom += iEdgeClosest; //, iSamples += iEdgeRandom; #ifdef SPLASH_DEBUG2 Color_t tColor = { byte(SDK::StdRandomInt(0, 255)), byte(SDK::StdRandomInt(0, 255)), byte(SDK::StdRandomInt(0, 255)) }; diff --git a/Amalgam/src/Features/ImGui/Menu/Components.h b/Amalgam/src/Features/ImGui/Menu/Components.h index d6b00e23..fcc2080d 100644 --- a/Amalgam/src/Features/ImGui/Menu/Components.h +++ b/Amalgam/src/Features/ImGui/Menu/Components.h @@ -358,24 +358,14 @@ namespace ImGui return sText; } - inline std::string TruncateText(const std::string& sText, int iPixels, ImFont* pFont = nullptr, const char* sEnd = "...", size_t* pLength = nullptr) + inline std::string TruncateText(const std::string& sText, int iPixels, ImFont* pFont = nullptr, const char* sEnd = "...", int iMin = 0, int* pLength = nullptr) { - if (sText.empty()) - return ""; - else if (FCalcTextSize(sText.c_str(), pFont).x < iPixels) // no unnecessary truncation + if (sText.empty() || FCalcTextSize(sText.c_str(), pFont).x < iPixels) // no unnecessary truncation return sText; std::string sTruncated = ""; - size_t i = 0; - while (FCalcTextSize(std::format("{}{}{}", sTruncated, sText[i + 1], sEnd).c_str(), pFont).x < iPixels) - { + int i = 0; while (i < iMin || i < sText.length() && FCalcTextSize(std::format("{}{}{}", sTruncated, sText[i], sEnd).c_str(), pFont).x < iPixels) sTruncated += sText[i++]; - if (i >= sText.length()) - { - i = 0; - break; - } - } if (i) sTruncated += sEnd; if (pLength) @@ -384,11 +374,15 @@ namespace ImGui return sTruncated; } - inline std::deque WrapText(const std::string& sText, int iPixels, ImFont* pFont = nullptr) + inline std::vector WrapText(const std::string& sText, std::vector vPixels, ImFont* pFont = nullptr) { - if (sText.empty()) - return { "" }; - else if (FCalcTextSize(sText.c_str(), pFont).x < iPixels) // no unnecessary wrapping + if (vPixels.empty()) + { + IM_ASSERT_USER_ERROR(0, "WrapText() vPixels empty."); + return {}; + } + + if (sText.empty() || sText.find("\n") == std::string::npos && FCalcTextSize(sText.c_str(), pFont).x < vPixels.front()) // no unnecessary wrapping return { sText }; std::vector vWords = { "" }; @@ -400,44 +394,44 @@ namespace ImGui vWords.back().push_back(iChar); } - std::deque vWrapped = { "" }; - int iWord = 0; - for (auto& sWord : vWords) + std::vector vWrapped = { "" }; + int iWord = 0; for (auto& sWord : vWords) { begin: if (sWord.empty()) continue; - auto sSeparator = iWord ? std::string(1, sWord[0]) : ""; - if (sWord[0] == ' ' || sWord[0] == '\n' || sWord[0] == '\t') - sWord.erase(0, 1); - if (sSeparator != "\n" && FCalcTextSize(std::format("{}{}{}", vWrapped.back(), sSeparator, sWord).c_str(), pFont).x < iPixels) + int iPixels = vPixels[std::min(vWrapped.size(), vPixels.size()) - 1]; + bool bForce = sWord[0] == '\n'; + if (!bForce && FCalcTextSize(std::format("{}{}", vWrapped.back(), sWord).c_str(), pFont).x < iPixels) { - vWrapped.back() += std::format("{}{}", sSeparator, sWord); + vWrapped.back() += sWord; iWord++; } else { - bool bContinue = false, bFirstWord = !iWord; iWord = 0; - if (bFirstWord) + if (sWord[0] == ' ' || sWord[0] == '\t' || bForce) + sWord.erase(0, 1); + + if (!iWord && !bForce) { - size_t i = 0; - vWrapped.back() += TruncateText(sWord, iPixels, pFont, "-", &i); - if (!i) // i don't know why it fucking does this, but i don't care enough to fix it - bContinue = true; - else - sWord = sWord.substr(i, sWord.length() - i); + int i = 0; vWrapped.back() += TruncateText(sWord, iPixels, pFont, "-", 1, &i); + sWord = sWord.substr(i, sWord.length() - i); } - if (vWrapped.back().empty()) - break; // don't do the same thing over and over - vWrapped.push_back(""); - if (!bContinue) + if (!sWord.empty() || bForce) + { + vWrapped.push_back(""); iWord = 0; goto begin; + } } } return vWrapped; } + inline std::vector WrapText(const std::string& sText, int iPixels, ImFont* pFont = nullptr) + { + return WrapText(sText, std::vector({ iPixels }), pFont); + } inline void FTooltip(const char* sTooltip, bool bCondition = IsItemHovered(), float flWrapWidth = 300, ImFont* pFont = F::Render.FontSmall, ImVec2* pPosOverride = nullptr, ImVec2* pSizeOverride = nullptr) { @@ -449,7 +443,7 @@ namespace ImGui ImVec2 vPos = pPosOverride ? *pPosOverride : !pRowSizes->empty() ? pRowSizes->back().m_vPos : ImVec2((GetItemRectMin().x + GetItemRectMax().x) / 2, GetItemRectMax().y); ImVec2 vSize = pSizeOverride ? *pSizeOverride : !pRowSizes->empty() ? pRowSizes->back().m_vSize : ImVec2(); - std::deque vWraps = WrapText(sTooltip, H::Draw.Scale(flWrapWidth)); + auto vWraps = WrapText(sTooltip, H::Draw.Scale(flWrapWidth)); ImVec2 vText = { 0, H::Draw.Scale(9) }; for (auto& sText : vWraps) { @@ -1473,11 +1467,6 @@ namespace ImGui { bool bReturn = false; - if (Transparent || Disabled) - PushStyleVar(ImGuiStyleVar_Alpha, 0.5f); - - bool bTitle = sLabel[0] != '#'; - if (vValues.empty()) { int i = 0; for (auto& sEntry : vEntries) @@ -1489,6 +1478,16 @@ namespace ImGui i++; } } + if (vValues.size() != std::count_if(vEntries.begin(), vEntries.end(), [](auto sEntry) { return FNV1A::Hash32(sEntry) != FNV1A::Hash32Const("##Divider"); })) + { + IM_ASSERT_USER_ERROR(0, "FDropdown() vValues size mismatch to vEntries."); + return bReturn; + } + + if (Transparent || Disabled) + PushStyleVar(ImGuiStyleVar_Alpha, 0.5f); + + bool bTitle = sLabel[0] != '#'; if (!(iFlags & FDropdownEnum::NoSanitization) && !vValues.empty()) { @@ -2003,7 +2002,7 @@ namespace ImGui vIconOffset += { flIconOffset, flIconOffset }; } - std::deque vWrapped; + std::vector vWrapped; int iWraps = 0; if (iFlags & (FColorPickerEnum::Left | FColorPickerEnum::Right | FColorPickerEnum::Full)) { diff --git a/Amalgam/src/Features/ImGui/Menu/Menu.cpp b/Amalgam/src/Features/ImGui/Menu/Menu.cpp index 1efae35d..2ddb9aa0 100644 --- a/Amalgam/src/Features/ImGui/Menu/Menu.cpp +++ b/Amalgam/src/Features/ImGui/Menu/Menu.cpp @@ -2434,47 +2434,30 @@ void CMenu::MenuLogs(int iTab) size_t iLines = 1; float flWidth = GetWindowWidth() - GetStyle().WindowPadding.x * 2; - if (tOutput.m_sFunction != "") + if (!tOutput.m_sFunction.empty()) { float flTitleWidth = 0.f; - PushStyleColor(ImGuiCol_Text, ColorToVec(tOutput.tAccent)); - auto vWrapped = WrapText(tOutput.m_sFunction, flWidth); - for (size_t i = 0; i < vWrapped.size(); i++) + if (!vWrapped.empty()) { - FText(vWrapped[i].c_str()); - if (i == vWrapped.size() - 1) - flTitleWidth = FCalcTextSize(vWrapped[i].c_str()).x + H::Draw.Scale(4); + PushStyleColor(ImGuiCol_Text, ColorToVec(tOutput.tAccent)); + + for (auto& sText : vWrapped) + FText(sText.c_str()); + iLines = vWrapped.size(); + flTitleWidth = FCalcTextSize(vWrapped.back().c_str()).x + H::Draw.Scale(4); + + PopStyleColor(); } - iLines = vWrapped.size(); - PopStyleColor(); - - vWrapped = WrapText(tOutput.m_sLog, flWidth - flTitleWidth); + vWrapped = WrapText(tOutput.m_sLog, { int(flWidth - flTitleWidth), int(flWidth) }); if (!vWrapped.empty()) { SameLine(flTitleWidth + GetStyle().WindowPadding.x); - FText(vWrapped.front().c_str()); - - if (vWrapped.size() > 1) - { - std::string sLog = ""; - for (size_t i = 1; i < vWrapped.size(); i++) - { - sLog += vWrapped[i].c_str(); - if (i != vWrapped.size() - 1) - sLog += " "; - } - vWrapped = WrapText(sLog, flWidth); - for (size_t i = 0; i < vWrapped.size(); i++) - { - FText(vWrapped[i].c_str()); - if (i == vWrapped.size() - 1) - flTitleWidth = FCalcTextSize(vWrapped[i].c_str()).x + H::Draw.Scale(4); - } - iLines += vWrapped.size(); - } + for (auto& sText : vWrapped) + FText(sText.c_str()); + iLines += vWrapped.size() - 1; } } else @@ -2482,8 +2465,8 @@ void CMenu::MenuLogs(int iTab) PushStyleColor(ImGuiCol_Text, ColorToVec(tOutput.tAccent)); auto vWrapped = WrapText(tOutput.m_sLog, flWidth); - for (size_t i = 0; i < vWrapped.size(); i++) - FText(vWrapped[i].c_str()); + for (auto& sText : vWrapped) + FText(sText.c_str()); iLines = vWrapped.size(); PopStyleColor(); diff --git a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp index a155a214..6010da1b 100644 --- a/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp +++ b/Amalgam/src/Features/Simulation/MovementSimulation/MovementSimulation.cpp @@ -697,14 +697,19 @@ void CMovementSimulation::RunTick(MoveStorage& tMoveStorage, bool bPath, RunTick if (tMoveStorage.m_flAverageYaw) tMoveStorage.m_MoveData.m_vecViewAngles.y -= flCorrection; - else if (tMoveStorage.m_bDirectMove && !bLastbDirectMove - && !tMoveStorage.m_MoveData.m_flForwardMove && !tMoveStorage.m_MoveData.m_flSideMove - && tMoveStorage.m_MoveData.m_vecVelocity.Length2D() > tMoveStorage.m_MoveData.m_flMaxSpeed * 0.015f) + + if (tMoveStorage.m_bDirectMove && !bLastbDirectMove) { - Vec3 vDirection = tMoveStorage.m_MoveData.m_vecVelocity.Normalized2D() * 520.f; - G::DummyCmd.forwardmove = vDirection.x, G::DummyCmd.sidemove = -vDirection.y; - SDK::FixMovement(&G::DummyCmd, {}, tMoveStorage.m_MoveData.m_vecViewAngles); - tMoveStorage.m_MoveData.m_flForwardMove = G::DummyCmd.forwardmove, tMoveStorage.m_MoveData.m_flSideMove = G::DummyCmd.sidemove; + if (tMoveStorage.m_flAverageYaw) + tMoveStorage.m_flAverageYaw *= -1; + else if (!tMoveStorage.m_MoveData.m_flForwardMove && !tMoveStorage.m_MoveData.m_flSideMove + && tMoveStorage.m_MoveData.m_vecVelocity.Length2D() > tMoveStorage.m_MoveData.m_flMaxSpeed * 0.015f) + { + Vec3 vDirection = tMoveStorage.m_MoveData.m_vecVelocity.Normalized2D() * 520.f; + G::DummyCmd.forwardmove = vDirection.x, G::DummyCmd.sidemove = -vDirection.y; + SDK::FixMovement(&G::DummyCmd, {}, tMoveStorage.m_MoveData.m_vecViewAngles); + tMoveStorage.m_MoveData.m_flForwardMove = G::DummyCmd.forwardmove, tMoveStorage.m_MoveData.m_flSideMove = G::DummyCmd.sidemove; + } } RestoreBounds(tMoveStorage.m_pPlayer); diff --git a/Amalgam/src/SDK/Helpers/Entities/Entities.cpp b/Amalgam/src/SDK/Helpers/Entities/Entities.cpp index 10ea54a3..81ac948e 100644 --- a/Amalgam/src/SDK/Helpers/Entities/Entities.cpp +++ b/Amalgam/src/SDK/Helpers/Entities/Entities.cpp @@ -359,13 +359,10 @@ void CEntities::ManualNetwork(const StartSoundParams_t& params) case ETFClassID::CTFPlayer: pEntity->As()->m_vecVelocity() = (params.origin - pEntity->m_vecOrigin()) / std::min(I::GlobalVars->curtime - s_mDormancy[n].m_flLastUpdate, 1.f); pEntity->SetAbsVelocity(pEntity->As()->m_vecVelocity()); SetAvgVelocity(pEntity->entindex(), pEntity->As()->m_vecVelocity()); - s_mDormancy[n] = { params.origin, I::GlobalVars->curtime }; - break; - case ETFClassID::CObjectSentrygun: - case ETFClassID::CObjectDispenser: - case ETFClassID::CObjectTeleporter: - s_mDormancy[n] = { params.origin, I::GlobalVars->curtime }; } + pEntity->SetAbsOrigin(pEntity->m_vecOrigin() = params.origin); + + s_mDormancy[n] = { params.origin, I::GlobalVars->curtime }; } bool CEntities::ManageDormancy(CBaseEntity* pEntity) { @@ -399,9 +396,7 @@ bool CEntities::ManageDormancy(CBaseEntity* pEntity) if (s_mDormancy.contains(n)) { auto& tDormancy = s_mDormancy[n]; - if (tDormancy.m_flLastUpdate + flDuration > I::GlobalVars->curtime) - pEntity->SetAbsOrigin(pEntity->m_vecOrigin() = tDormancy.m_vLocation); - else + if (tDormancy.m_flLastUpdate + flDuration < I::GlobalVars->curtime || pEntity->IsPlayer() && !pEntity->As()->IsAlive()) s_mDormancy.erase(n); } } diff --git a/Amalgam/src/SDK/SDK.cpp b/Amalgam/src/SDK/SDK.cpp index 43b7b1e7..201077ac 100644 --- a/Amalgam/src/SDK/SDK.cpp +++ b/Amalgam/src/SDK/SDK.cpp @@ -564,8 +564,6 @@ int SDK::IsAttacking(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd* switch (pWeapon->GetWeaponID()) { - case TF_WEAPON_COMPOUND_BOW: - return !(pCmd->buttons & IN_ATTACK) && pWeapon->As()->m_flChargeBeginTime() > 0.f; case TF_WEAPON_PIPEBOMBLAUNCHER: case TF_WEAPON_STICKY_BALL_LAUNCHER: case TF_WEAPON_GRENADE_STICKY_BALL: @@ -586,17 +584,16 @@ int SDK::IsAttacking(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd* } case TF_WEAPON_SNIPERRIFLE_CLASSIC: return !(pCmd->buttons & IN_ATTACK) && pWeapon->As()->m_flChargedDamage() > 0.f; + case TF_WEAPON_COMPOUND_BOW: + return !(pCmd->buttons & IN_ATTACK) && pWeapon->As()->m_flChargeBeginTime() > 0.f; case TF_WEAPON_PARTICLE_CANNON: - { - float flChargeBeginTime = pWeapon->As()->m_flChargeBeginTime(); - if (flChargeBeginTime > 0) + if (float flChargeBeginTime = pWeapon->As()->m_flChargeBeginTime(); flChargeBeginTime > 0) { float flTotalChargeTime = flTickBase - flChargeBeginTime; if (flTotalChargeTime >= TF_PARTICLE_MAX_CHARGE_TIME) return 1; } break; - } case TF_WEAPON_CLEAVER: // we can randomly use attack2 to fire case TF_WEAPON_JAR: case TF_WEAPON_JAR_MILK: @@ -664,6 +661,10 @@ int SDK::IsAttacking(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd* if (G::CanSecondaryAttack && pCmd->buttons & IN_ATTACK2) return 1; break; + case TF_WEAPON_MEDIGUN: + if (pWeapon->As()->m_bHealing()) + return false; + break; } switch (pWeapon->m_iItemDefinitionIndex()) diff --git a/Amalgam/src/SDK/SDK.h b/Amalgam/src/SDK/SDK.h index 47de7d0f..3b5870e5 100644 --- a/Amalgam/src/SDK/SDK.h +++ b/Amalgam/src/SDK/SDK.h @@ -62,6 +62,7 @@ #define VK_Y 0x59 #define VK_Z 0x5A +#define OUTPUT_NONE 0 #define OUTPUT_CONSOLE 1 << 0 #define OUTPUT_DEBUG 1 << 1 #define OUTPUT_TOAST 1 << 2 diff --git a/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp b/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp index 7e415d54..e6333a29 100644 --- a/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp +++ b/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp @@ -10,7 +10,8 @@ #include #pragma comment(lib, "imagehlp.lib") -#define STATUS_RUNTIME_ERROR ((DWORD)0xE06D7363) +#define STATUS_RUNTIME_ERROR ((DWORD )0xE06D7363L) +#define DBG_THREAD_NAMING ((DWORD )0x406D1388L) struct Frame_t { @@ -24,7 +25,6 @@ struct Frame_t static PVOID s_pHandle; static LPVOID s_lpParam; -static std::unordered_mapset s_mAddresses = {}; static int s_iExceptions = 0; static inline std::deque StackTrace(PCONTEXT pContext) @@ -103,16 +103,15 @@ static LONG APIENTRY ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) case STATUS_ACCESS_VIOLATION: sError = "ACCESS VIOLATION"; break; case STATUS_STACK_OVERFLOW: sError = "STACK OVERFLOW"; break; case STATUS_HEAP_CORRUPTION: sError = "HEAP CORRUPTION"; break; - case STATUS_RUNTIME_ERROR: sError = "RUNTIME ERROR"; break; + case STATUS_RUNTIME_ERROR: + case EXCEPTION_BREAKPOINT: case DBG_PRINTEXCEPTION_C: - case DBG_PRINTEXCEPTION_WIDE_C: return EXCEPTION_EXECUTE_HANDLER; + case DBG_PRINTEXCEPTION_WIDE_C: + case DBG_THREAD_NAMING: return EXCEPTION_CONTINUE_SEARCH; } - if (s_mAddresses.contains(ExceptionInfo->ExceptionRecord->ExceptionAddress) - || !Vars::Debug::CrashLogging.Value - || s_iExceptions && GetAsyncKeyState(VK_SHIFT) & 0x8000 && GetAsyncKeyState(VK_RETURN) & 0x8000) - return EXCEPTION_EXECUTE_HANDLER; - s_mAddresses[ExceptionInfo->ExceptionRecord->ExceptionAddress]; + if (!Vars::Debug::CrashLogging.Value) + return EXCEPTION_CONTINUE_SEARCH; std::stringstream ssErrorStream; ssErrorStream << std::format("Error: {} (0x{:X}) ({})\n", sError, ExceptionInfo->ExceptionRecord->ExceptionCode, ++s_iExceptions); @@ -179,7 +178,7 @@ static LONG APIENTRY ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) SDK::Output("Unhandled exception", ssErrorStream.str().c_str(), {}, OUTPUT_DEBUG, MB_OK | MB_ICONERROR); } - return EXCEPTION_EXECUTE_HANDLER; + return EXCEPTION_CONTINUE_SEARCH; } void CExceptionHandler::Initialize(LPVOID lpParam)