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
This commit is contained in:
rei-2
2026-06-17 15:48:54 -04:00
parent edafbf5b49
commit bf103d6e2f
8 changed files with 93 additions and 110 deletions
@@ -551,7 +551,7 @@ static inline void HandleFace(Face_t& tFace, std::vector<Setup_t>& 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)) };
+43 -44
View File
@@ -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<std::string> WrapText(const std::string& sText, int iPixels, ImFont* pFont = nullptr)
inline std::vector<std::string> WrapText(const std::string& sText, std::vector<int> 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<std::string> vWords = { "" };
@@ -400,44 +394,44 @@ namespace ImGui
vWords.back().push_back(iChar);
}
std::deque<std::string> vWrapped = { "" };
int iWord = 0;
for (auto& sWord : vWords)
std::vector<std::string> 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<std::string> WrapText(const std::string& sText, int iPixels, ImFont* pFont = nullptr)
{
return WrapText(sText, std::vector<int>({ 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<std::string> 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<std::string> vWrapped;
std::vector<std::string> vWrapped;
int iWraps = 0;
if (iFlags & (FColorPickerEnum::Left | FColorPickerEnum::Right | FColorPickerEnum::Full))
{
+16 -33
View File
@@ -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();
@@ -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);
@@ -359,13 +359,10 @@ void CEntities::ManualNetwork(const StartSoundParams_t& params)
case ETFClassID::CTFPlayer:
pEntity->As<CTFPlayer>()->m_vecVelocity() = (params.origin - pEntity->m_vecOrigin()) / std::min(I::GlobalVars->curtime - s_mDormancy[n].m_flLastUpdate, 1.f);
pEntity->SetAbsVelocity(pEntity->As<CTFPlayer>()->m_vecVelocity()); SetAvgVelocity(pEntity->entindex(), pEntity->As<CTFPlayer>()->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<CTFPlayer>()->IsAlive())
s_mDormancy.erase(n);
}
}
+7 -6
View File
@@ -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<CTFPipebombLauncher>()->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<CTFSniperRifle>()->m_flChargedDamage() > 0.f;
case TF_WEAPON_COMPOUND_BOW:
return !(pCmd->buttons & IN_ATTACK) && pWeapon->As<CTFPipebombLauncher>()->m_flChargeBeginTime() > 0.f;
case TF_WEAPON_PARTICLE_CANNON:
{
float flChargeBeginTime = pWeapon->As<CTFParticleCannon>()->m_flChargeBeginTime();
if (flChargeBeginTime > 0)
if (float flChargeBeginTime = pWeapon->As<CTFParticleCannon>()->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<CWeaponMedigun>()->m_bHealing())
return false;
break;
}
switch (pWeapon->m_iItemDefinitionIndex())
+1
View File
@@ -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
@@ -10,7 +10,8 @@
#include <format>
#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<LPVOID> s_mAddresses = {};
static int s_iExceptions = 0;
static inline std::deque<Frame_t> 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)