From af6958bba12e0c4e8f81a0f48e7a60a5fbc1547b Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 24 Nov 2022 15:30:06 +0000 Subject: [PATCH] [Script]: Add IsSprinting & more --- src/Components/Modules/Bots.cpp | 10 +- src/Components/Modules/GSC/Script.cpp | 163 +++++++++++----------- src/Components/Modules/GSC/Script.hpp | 25 +++- src/Components/Modules/PlayerMovement.cpp | 22 ++- src/Components/Modules/PlayerMovement.hpp | 2 + src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 3 + src/Game/Structs.hpp | 34 ++--- 8 files changed, 157 insertions(+), 103 deletions(-) diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index 2b7132f8..2dfe290e 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -111,9 +111,15 @@ namespace Components } } - void Bots::GScr_isTestClient(Game::scr_entref_t entref) + void Bots::GScr_isTestClient(const Game::scr_entref_t entref) { - const auto* ent = Game::GetPlayerEntity(entref); + const auto* ent = Game::GetEntity(entref); + if (!ent->client) + { + Game::Scr_Error("isTestClient: entity must be a player entity"); + return; + } + Game::Scr_AddBool(Game::SV_IsTestClient(ent->s.number) != 0); } diff --git a/src/Components/Modules/GSC/Script.cpp b/src/Components/Modules/GSC/Script.cpp index 9de55849..ae4e6723 100644 --- a/src/Components/Modules/GSC/Script.cpp +++ b/src/Components/Modules/GSC/Script.cpp @@ -15,8 +15,8 @@ namespace Components std::unordered_map Script::ReplacedFunctions; const char* Script::ReplacedPos = nullptr; - std::vector Script::ScriptMainHandles; - std::vector Script::ScriptInitHandles; + std::unordered_map Script::ScriptMainHandles; + std::unordered_map Script::ScriptInitHandles; void Script::ShowDeprecationWarning() { @@ -28,16 +28,16 @@ namespace Components void Script::FunctionError() { - const auto* funcName = Game::SL_ConvertToString(Script::FunctionName); + const auto* funcName = Game::SL_ConvertToString(FunctionName); Game::Scr_ShutdownAllocNode(); Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "\n"); Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "******* script compile error *******\n"); - Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Error: unknown function {} in {}\n", funcName, Script::ScriptName); + Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Error: unknown function {} in {}\n", funcName, ScriptName); Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "************************************\n"); - Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\nunknown function {}\n{}\n\n", funcName, Script::ScriptName); + Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\nunknown function {}\n{}\n\n", funcName, ScriptName); } __declspec(naked) void Script::StoreFunctionNameStub() @@ -45,7 +45,7 @@ namespace Components __asm { mov eax, [esp - 8h] - mov Script::FunctionName, ax + mov FunctionName, ax sub esp, 0Ch push 0 @@ -87,12 +87,12 @@ namespace Components void Script::StoreScriptName(const char* name) { - Script::ScriptNameStack.push_back(Script::ScriptName); - Script::ScriptName = name; + ScriptNameStack.push_back(ScriptName); + ScriptName = name; - if (!Utils::String::EndsWith(Script::ScriptName, ".gsc")) + if (!Utils::String::EndsWith(ScriptName, ".gsc")) { - Script::ScriptName.append(".gsc"); + ScriptName.append(".gsc"); } } @@ -105,7 +105,7 @@ namespace Components lea ecx, [esp + 30h] push ecx - call Script::StoreScriptName + call StoreScriptName add esp, 4h popad @@ -120,8 +120,8 @@ namespace Components void Script::RestoreScriptName() { - Script::ScriptName = Script::ScriptNameStack.back(); - Script::ScriptNameStack.pop_back(); + ScriptName = ScriptNameStack.back(); + ScriptNameStack.pop_back(); } __declspec(naked) void Script::RestoreScriptNameStub() @@ -129,7 +129,7 @@ namespace Components __asm { pushad - call Script::RestoreScriptName + call RestoreScriptName popad mov ds:1CDEAA8h, ebp @@ -205,17 +205,19 @@ namespace Components Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "\n"); Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "******* script compile error *******\n"); Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Error: {} ", msgbuf); - Script::PrintSourcePos(Script::ScriptName.data(), offset); + PrintSourcePos(ScriptName.data(), offset); Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "************************************\n\n"); - Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\n{}\n{}\n(see console for actual details)\n", msgbuf, Script::ScriptName); + Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\n{}\n{}\n(see console for actual details)\n", msgbuf, ScriptName); } void Script::Scr_LoadGameType_Stub() { - for (const auto& handle : Script::ScriptMainHandles) + for (const auto& handle : ScriptMainHandles) { - const auto id = Game::Scr_ExecThread(handle, 0); + Logger::Print("Executing '{}::main'\n", handle.first.data()); + + const auto id = Game::Scr_ExecThread(handle.second, 0); Game::Scr_FreeThread(static_cast(id)); } @@ -224,9 +226,11 @@ namespace Components void Script::Scr_StartupGameType_Stub() { - for (const auto& handle : Script::ScriptInitHandles) + for (const auto& handle : ScriptInitHandles) { - const auto id = Game::Scr_ExecThread(handle, 0); + Logger::Print("Executing '{}::init'\n", handle.first.data()); + + const auto id = Game::Scr_ExecThread(handle.second, 0); Game::Scr_FreeThread(static_cast(id)); } @@ -237,8 +241,8 @@ namespace Components void Script::GScr_LoadGameTypeScript_Stub() { // Clear handles (from previous GSC loading session) - Script::ScriptMainHandles.clear(); - Script::ScriptInitHandles.clear(); + ScriptMainHandles.clear(); + ScriptInitHandles.clear(); char path[MAX_PATH]{}; @@ -262,18 +266,17 @@ namespace Components } Logger::Print("Script {}.gsc loaded successfully.\n", path); - Logger::Debug("Finding script handle main or init..."); const auto initHandle = Game::Scr_GetFunctionHandle(path, "init"); if (initHandle != 0) { - Script::ScriptInitHandles.push_back(initHandle); + ScriptInitHandles.insert_or_assign(path, initHandle); } const auto mainHandle = Game::Scr_GetFunctionHandle(path, "main"); if (mainHandle != 0) { - Script::ScriptMainHandles.push_back(mainHandle); + ScriptMainHandles.insert_or_assign(path, mainHandle); } // Allow scripts with no handles @@ -285,7 +288,7 @@ namespace Components void Script::AddFunction(const std::string& name, Game::BuiltinFunction func, bool type) { - Script::ScriptFunction toAdd; + ScriptFunction toAdd; toAdd.actionFunc = func; toAdd.type = type; @@ -294,7 +297,7 @@ namespace Components void Script::AddMethod(const std::string& name, Game::BuiltinMethod func, bool type) { - Script::ScriptMethod toAdd; + ScriptMethod toAdd; toAdd.actionFunc = func; toAdd.type = type; @@ -306,7 +309,7 @@ namespace Components if (pName != nullptr) { // If no function was found let's call game's function - if (const auto itr = Script::CustomScrFunctions.find(Utils::String::ToLower(*pName)); itr != Script::CustomScrFunctions.end()) + if (const auto itr = CustomScrFunctions.find(Utils::String::ToLower(*pName)); itr != CustomScrFunctions.end()) { *type = itr->second.type; return itr->second.actionFunc; @@ -314,7 +317,7 @@ namespace Components } else { - for (const auto& [name, builtin] : Script::CustomScrFunctions) + for (const auto& [name, builtin] : CustomScrFunctions) { Game::Scr_RegisterFunction(reinterpret_cast(builtin.actionFunc), name.data()); } @@ -328,7 +331,7 @@ namespace Components if (pName != nullptr) { // If no method was found let's call game's function - if (const auto itr = Script::CustomScrMethods.find(Utils::String::ToLower(*pName)); itr != Script::CustomScrMethods.end()) + if (const auto itr = CustomScrMethods.find(Utils::String::ToLower(*pName)); itr != CustomScrMethods.end()) { *type = itr->second.type; return itr->second.actionFunc; @@ -336,7 +339,7 @@ namespace Components } else { - for (const auto& [name, builtin] : Script::CustomScrMethods) + for (const auto& [name, builtin] : CustomScrMethods) { Game::Scr_RegisterFunction(reinterpret_cast(builtin.actionFunc), name.data()); } @@ -347,7 +350,7 @@ namespace Components void Script::StoreScriptBaseProgramNum() { - Script::ScriptBaseProgramNum.insert_or_assign(Utils::Hook::Get(0x1CFEEF8), Script::ScriptName); + ScriptBaseProgramNum.insert_or_assign(Utils::Hook::Get(0x1CFEEF8), ScriptName); } void Script::Scr_PrintPrevCodePos(int scriptPos) @@ -355,7 +358,7 @@ namespace Components auto bestCodePos = -1, nextCodePos = -1, offset = -1; std::string file; - for (const auto& [key, value] : Script::ScriptBaseProgramNum) + for (const auto& [key, value] : ScriptBaseProgramNum) { const auto codePos = key; @@ -388,7 +391,7 @@ namespace Components __asm { push esi - call Script::Scr_PrintPrevCodePos + call Scr_PrintPrevCodePos add esp, 4h pop esi @@ -402,7 +405,7 @@ namespace Components { // execute our hook pushad - call Script::StoreScriptBaseProgramNum + call StoreScriptBaseProgramNum popad // execute overwritten code caused by the jump hook @@ -452,9 +455,9 @@ namespace Components void Script::GetReplacedPos(const char* pos) { - if (Script::ReplacedFunctions.contains(pos)) + if (ReplacedFunctions.contains(pos)) { - Script::ReplacedPos = Script::ReplacedFunctions[pos]; + ReplacedPos = ReplacedFunctions[pos]; } } @@ -466,12 +469,12 @@ namespace Components return; } - if (Script::ReplacedFunctions.contains(what)) + if (ReplacedFunctions.contains(what)) { Logger::Warning(Game::CON_CHANNEL_SCRIPT, "ReplacedFunctions already contains codePosValue for a function\n"); } - Script::ReplacedFunctions[what] = with; + ReplacedFunctions[what] = with; } __declspec(naked) void Script::VMExecuteInternalStub() @@ -481,12 +484,12 @@ namespace Components pushad push edx - call Script::GetReplacedPos + call GetReplacedPos pop edx popad - cmp Script::ReplacedPos, 0 + cmp ReplacedPos, 0 jne SetPos movzx eax, byte ptr [edx] @@ -509,8 +512,8 @@ namespace Components retn SetPos: - mov edx, Script::ReplacedPos - mov Script::ReplacedPos, 0 + mov edx, ReplacedPos + mov ReplacedPos, 0 movzx eax, byte ptr [edx] inc edx @@ -521,7 +524,7 @@ namespace Components Game::client_t* Script::GetClient(const Game::gentity_t* ent) { - assert(ent != nullptr); + assert(ent); if (ent->client == nullptr) { @@ -529,7 +532,7 @@ namespace Components return nullptr; } - if (ent->s.number >= *Game::svs_clientCount) + if (static_cast(ent->s.number) >= Game::MAX_CLIENTS) { Game::Scr_ObjectError(Utils::String::VA("Entity %i is out of bounds", ent->s.number)); return nullptr; @@ -540,7 +543,7 @@ namespace Components void Script::AddFunctions() { - Script::AddFunction("ReplaceFunc", [] // gsc: ReplaceFunc(, ) + AddFunction("ReplaceFunc", [] // gsc: ReplaceFunc(, ) { if (Game::Scr_GetNumParam() != 2) { @@ -548,14 +551,14 @@ namespace Components return; } - const auto what = Script::GetCodePosForParam(0); - const auto with = Script::GetCodePosForParam(1); + const auto what = GetCodePosForParam(0); + const auto with = GetCodePosForParam(1); - Script::SetReplacedPos(what, with); + SetReplacedPos(what, with); }); // System time - Script::AddFunction("GetSystemMilliseconds", [] // gsc: GetSystemMilliseconds() + AddFunction("GetSystemMilliseconds", [] // gsc: GetSystemMilliseconds() { SYSTEMTIME time; GetSystemTime(&time); @@ -564,7 +567,7 @@ namespace Components }); // Executes command to the console - Script::AddFunction("Exec", [] // gsc: Exec() + AddFunction("Exec", [] // gsc: Exec() { const auto str = Game::Scr_GetString(0); @@ -578,7 +581,7 @@ namespace Components }); // Allow printing to the console even when developer is 0 - Script::AddFunction("PrintConsole", [] // gsc: PrintConsole() + AddFunction("PrintConsole", [] // gsc: PrintConsole() { for (std::size_t i = 0; i < Game::Scr_GetNumParam(); ++i) { @@ -595,9 +598,9 @@ namespace Components }); // PlayerCmd_AreControlsFrozen GSC function from Black Ops 2 - Script::AddMethod("AreControlsFrozen", [](Game::scr_entref_t entref) // Usage: self AreControlsFrozen(); + AddMethod("AreControlsFrozen", [](Game::scr_entref_t entref) // Usage: self AreControlsFrozen(); { - const auto* ent = Game::GetPlayerEntity(entref); + const auto* ent = Scr_GetPlayerEntity(entref); Game::Scr_AddBool((ent->client->flags & Game::PLAYER_FLAG_FROZEN) != 0); }); @@ -605,34 +608,34 @@ namespace Components Script::Script() { - Utils::Hook(0x612DB0, Script::StoreFunctionNameStub, HOOK_JUMP).install()->quick(); - Utils::Hook(0x427E71, Script::RestoreScriptNameStub, HOOK_JUMP).install()->quick(); - Utils::Hook(0x427DBC, Script::StoreScriptNameStub, HOOK_JUMP).install()->quick(); - Utils::Hook(0x426C2D, Script::StoreScriptBaseProgramNumStub, HOOK_JUMP).install()->quick(); - Utils::Hook(0x42281B, Script::Scr_PrintPrevCodePosStub, HOOK_JUMP).install()->quick(); + Utils::Hook(0x612DB0, StoreFunctionNameStub, HOOK_JUMP).install()->quick(); + Utils::Hook(0x427E71, RestoreScriptNameStub, HOOK_JUMP).install()->quick(); + Utils::Hook(0x427DBC, StoreScriptNameStub, HOOK_JUMP).install()->quick(); + Utils::Hook(0x426C2D, StoreScriptBaseProgramNumStub, HOOK_JUMP).install()->quick(); + Utils::Hook(0x42281B, Scr_PrintPrevCodePosStub, HOOK_JUMP).install()->quick(); - Utils::Hook(0x61E3AD, Script::RuntimeError, HOOK_CALL).install()->quick(); - Utils::Hook(0x621976, Script::RuntimeError, HOOK_CALL).install()->quick(); - Utils::Hook(0x62246E, Script::RuntimeError, HOOK_CALL).install()->quick(); + Utils::Hook(0x61E3AD, RuntimeError, HOOK_CALL).install()->quick(); + Utils::Hook(0x621976, RuntimeError, HOOK_CALL).install()->quick(); + Utils::Hook(0x62246E, RuntimeError, HOOK_CALL).install()->quick(); // Skip check in GScr_CheckAllowedToSetPersistentData to prevent log spam in RuntimeError. // On IW5 the function is entirely nullsubbed - Utils::Hook::Set(0x5F8DBF, 0xEB); + Utils::Hook::Set(0x5F8DBF, 0xEB); - Utils::Hook(0x612E8D, Script::FunctionError, HOOK_CALL).install()->quick(); - Utils::Hook(0x612EA2, Script::FunctionError, HOOK_CALL).install()->quick(); - Utils::Hook(0x434260, Script::CompileError, HOOK_JUMP).install()->quick(); + Utils::Hook(0x612E8D, FunctionError, HOOK_CALL).install()->quick(); + Utils::Hook(0x612EA2, FunctionError, HOOK_CALL).install()->quick(); + Utils::Hook(0x434260, CompileError, HOOK_JUMP).install()->quick(); - Utils::Hook(0x48EFFE, Script::Scr_LoadGameType_Stub, HOOK_CALL).install()->quick(); - Utils::Hook(0x48F008, Script::Scr_StartupGameType_Stub, HOOK_CALL).install()->quick(); - Utils::Hook(0x45D44A, Script::GScr_LoadGameTypeScript_Stub, HOOK_CALL).install()->quick(); + Utils::Hook(0x48EFFE, Scr_LoadGameType_Stub, HOOK_CALL).install()->quick(); + Utils::Hook(0x48F008, Scr_StartupGameType_Stub, HOOK_CALL).install()->quick(); + Utils::Hook(0x45D44A, GScr_LoadGameTypeScript_Stub, HOOK_CALL).install()->quick(); // Fetch custom functions - Utils::Hook(0x44E72E, Script::BuiltIn_GetFunctionStub, HOOK_CALL).install()->quick(); // Scr_GetFunction - Utils::Hook(0x4EC8DD, Script::BuiltIn_GetMethodStub, HOOK_CALL).install()->quick(); // Scr_GetMethod + Utils::Hook(0x44E72E, BuiltIn_GetFunctionStub, HOOK_CALL).install()->quick(); // Scr_GetFunction + Utils::Hook(0x4EC8DD, BuiltIn_GetMethodStub, HOOK_CALL).install()->quick(); // Scr_GetMethod - Utils::Hook(0x5F41A3, Script::SetExpFogStub, HOOK_CALL).install()->quick(); + Utils::Hook(0x5F41A3, SetExpFogStub, HOOK_CALL).install()->quick(); - Utils::Hook(0x61E92E, Script::VMExecuteInternalStub, HOOK_JUMP).install()->quick(); + Utils::Hook(0x61E92E, VMExecuteInternalStub, HOOK_JUMP).install()->quick(); Utils::Hook::Nop(0x61E933, 1); Scheduler::Loop([] @@ -642,9 +645,9 @@ namespace Components const auto nowMs = Game::Sys_Milliseconds(); - if (Script::LastFrameTime != -1) + if (LastFrameTime != -1) { - const auto timeTaken = (nowMs - Script::LastFrameTime) * static_cast((*Game::com_timescale)->current.value); + const auto timeTaken = (nowMs - LastFrameTime) * static_cast((*Game::com_timescale)->current.value); if (timeTaken >= 500) { @@ -652,11 +655,11 @@ namespace Components } } - Script::LastFrameTime = nowMs; + LastFrameTime = nowMs; }, Scheduler::Pipeline::SERVER); #ifdef _DEBUG - Script::AddFunction("DebugBox", [] + AddFunction("DebugBox", [] { const auto* message = Game::Scr_GetString(0); @@ -666,14 +669,14 @@ namespace Components } MessageBoxA(nullptr, message, "DEBUG", MB_OK); - }, 1); + }, true); #endif - Script::AddFunctions(); + AddFunctions(); Events::OnVMShutdown([] { - Script::ReplacedFunctions.clear(); + ReplacedFunctions.clear(); }); } } diff --git a/src/Components/Modules/GSC/Script.hpp b/src/Components/Modules/GSC/Script.hpp index d80f952e..bf850257 100644 --- a/src/Components/Modules/GSC/Script.hpp +++ b/src/Components/Modules/GSC/Script.hpp @@ -16,6 +16,27 @@ namespace Components static void ShowDeprecationWarning(); + // Probably a macro 'originally' but this is fine + static Game::gentity_s* Scr_GetPlayerEntity(Game::scr_entref_t entref) + { + if (entref.classnum != 0) + { + Game::Scr_ObjectError("not an entity"); + return nullptr; + } + + assert(entref.entnum < Game::MAX_GENTITIES); + + auto* ent = &Game::g_entities[entref.entnum]; + if (ent->client == nullptr) + { + Game::Scr_ObjectError(Utils::String::VA("entity %i is not a player", entref.entnum)); + return nullptr; + } + + return ent; + } + private: struct ScriptFunction { @@ -38,8 +59,8 @@ namespace Components static std::unordered_map ScriptBaseProgramNum; static int LastFrameTime; - static std::vector ScriptMainHandles; - static std::vector ScriptInitHandles; + static std::unordered_map ScriptMainHandles; + static std::unordered_map ScriptInitHandles; static std::unordered_map ReplacedFunctions; static const char* ReplacedPos; diff --git a/src/Components/Modules/PlayerMovement.cpp b/src/Components/Modules/PlayerMovement.cpp index 9bf88dd7..05aeb8b5 100644 --- a/src/Components/Modules/PlayerMovement.cpp +++ b/src/Components/Modules/PlayerMovement.cpp @@ -1,4 +1,5 @@ #include +#include "GSC/Script.hpp" namespace Components { @@ -106,13 +107,13 @@ namespace Components // Bounce push 0x4B1B34 - retn + ret noBounce: // Original game code cmp dword ptr [esp + 0x24], 0 push 0x4B1B48 - retn + ret } } @@ -186,6 +187,18 @@ namespace Components } } + void PlayerMovement::GScr_IsSprinting(const Game::scr_entref_t entref) + { + const auto* client = Game::GetEntity(entref)->client; + if (!client) + { + Game::Scr_Error("IsSprinting can only be called on a player"); + return; + } + + Game::Scr_AddBool(Game::PM_IsSprinting(&client->ps)); + } + const Game::dvar_t* PlayerMovement::Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value, float min, float max, unsigned __int16 /*flags*/, const char* description) { @@ -233,6 +246,9 @@ namespace Components PlayerMovement::PlayerMovement() { + AssertOffset(Game::playerState_s, eFlags, 0xB0); + AssertOffset(Game::playerState_s, pm_flags, 0xC); + Scheduler::Once([] { static const char* bg_bouncesValues[] = @@ -273,6 +289,8 @@ namespace Components Utils::Hook(0x45A5BF, CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity Utils::Hook(0x5A0CAD, CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity + Script::AddMethod("IsSprinting", GScr_IsSprinting); + RegisterMovementDvars(); } } diff --git a/src/Components/Modules/PlayerMovement.hpp b/src/Components/Modules/PlayerMovement.hpp index c99ee59f..5977ef44 100644 --- a/src/Components/Modules/PlayerMovement.hpp +++ b/src/Components/Modules/PlayerMovement.hpp @@ -41,6 +41,8 @@ namespace Components static int StuckInClient_Hk(Game::gentity_s* self); static void CM_TransformedCapsuleTrace_Hk(Game::trace_t* results, const float* start, const float* end, const Game::Bounds* bounds, const Game::Bounds* capsule, int contents, const float* origin, const float* angles); + static void GScr_IsSprinting(Game::scr_entref_t entref); + static const Game::dvar_t* Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value, float min, float max, unsigned __int16 flags, const char* description); static void RegisterMovementDvars(); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 8a6e33c4..6f9c2c1d 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -233,6 +233,7 @@ namespace Game PM_Trace_t PM_Trace = PM_Trace_t(0x441F60); PM_GetEffectiveStance_t PM_GetEffectiveStance = PM_GetEffectiveStance_t(0x412540); PM_UpdateLean_t PM_UpdateLean = PM_UpdateLean_t(0x43DED0); + PM_IsSprinting_t PM_IsSprinting = PM_IsSprinting_t(0x4B3830); IN_RecenterMouse_t IN_RecenterMouse = IN_RecenterMouse_t(0x463D80); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 6c52b815..1c12835c 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -524,6 +524,9 @@ namespace Game typedef void(*PM_UpdateLean_t)(playerState_s* ps, float msec, usercmd_s* cmd, void(*capsuleTrace)(trace_t*, const float*, const float*, const Bounds*, int, int)); extern PM_UpdateLean_t PM_UpdateLean; + typedef bool(*PM_IsSprinting_t)(const playerState_s* ps); + extern PM_IsSprinting_t PM_IsSprinting; + typedef void(*IN_RecenterMouse_t)(); extern IN_RecenterMouse_t IN_RecenterMouse; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index df84c4f9..c87612a2 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -1679,23 +1679,23 @@ namespace Game enum usercmdButtonBits { - CMD_BUTTON_ATTACK = 0x1, - CMD_BUTTON_SPRINT = 0x2, - CMD_BUTTON_MELEE = 0x4, - CMD_BUTTON_ACTIVATE = 0x8, - CMD_BUTTON_RELOAD = 0x10, - CMD_BUTTON_USE_RELOAD = 0x20, - CMD_BUTTON_LEAN_LEFT = 0x40, - CMD_BUTTON_LEAN_RIGHT = 0x80, - CMD_BUTTON_PRONE = 0x100, - CMD_BUTTON_CROUCH = 0x200, - CMD_BUTTON_UP = 0x400, - CMD_BUTTON_ADS = 0x800, - CMD_BUTTON_DOWN = 0x1000, - CMD_BUTTON_BREATH = 0x2000, - CMD_BUTTON_FRAG = 0x4000, - CMD_BUTTON_OFFHAND_SECONDARY = 0x8000, - CMD_BUTTON_THROW = 0x80000 + CMD_BUTTON_ATTACK = 1 << 0, + CMD_BUTTON_SPRINT = 1 << 1, + CMD_BUTTON_MELEE = 1 << 2, + CMD_BUTTON_ACTIVATE = 1 << 3, + CMD_BUTTON_RELOAD = 1 << 4, + CMD_BUTTON_USE_RELOAD = 1 << 5, + CMD_BUTTON_LEAN_LEFT = 1 << 6, + CMD_BUTTON_LEAN_RIGHT = 1 << 7, + CMD_BUTTON_PRONE = 1 << 8, + CMD_BUTTON_CROUCH = 1 << 9, + CMD_BUTTON_UP = 1 << 10, + CMD_BUTTON_ADS = 1 << 11, + CMD_BUTTON_DOWN = 1 << 12, + CMD_BUTTON_BREATH = 1 << 13, + CMD_BUTTON_FRAG = 1 << 14, + CMD_BUTTON_OFFHAND_SECONDARY = 1 << 15, + CMD_BUTTON_THROW = 1 << 19, }; #pragma pack(push, 4)