From 4ee39b510f550601f93ec6cf5352e62d6a6d4c44 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 19 Jan 2022 00:49:50 +0000 Subject: [PATCH] Refactor bounces --- src/Components/Modules/Movement.cpp | 86 +++++++++++++++++++++++++++ src/Components/Modules/Movement.hpp | 10 ++++ src/Components/Modules/QuickPatch.cpp | 32 ---------- src/Components/Modules/QuickPatch.hpp | 3 - 4 files changed, 96 insertions(+), 35 deletions(-) diff --git a/src/Components/Modules/Movement.cpp b/src/Components/Modules/Movement.cpp index e3d42e72..70fdb608 100644 --- a/src/Components/Modules/Movement.cpp +++ b/src/Components/Modules/Movement.cpp @@ -8,6 +8,8 @@ namespace Components Dvar::Var Movement::PlayerSpectateSpeedScale; Dvar::Var Movement::CGUfoScaler; Dvar::Var Movement::CGNoclipScaler; + Dvar::Var Movement::BGBouncesAllAngles; + Game::dvar_t* Movement::BGBounces; float Movement::PM_CmdScaleForStance(const Game::pmove_s* pm) { @@ -153,6 +155,71 @@ namespace Components } } + __declspec(naked) void Movement::PM_StepSlideMoveStub() + { + __asm + { + // Check the value of BGEnableBounces + push ecx + push eax + + mov eax, Movement::BGBounces + mov ecx, dword ptr [eax + 0x10] + test ecx, ecx + + pop eax + pop ecx + + // Do not bounce if BGEnableBounces is 0 + jle noBounce + + // Bounce + push 0x4B1B34 + retn + + noBounce: + // Original code + cmp dword ptr [esp + 0x24], 0 + push 0x4B1B48 + retn + } + } + + void Movement::PM_ProjectVelocityStub(const float* velIn, const float* normal, float* velOut) + { + auto lengthSquared2D = velIn[0] * velIn[0] + velIn[1] * velIn[1]; + + if (std::fabsf(normal[2]) < 0.001f || lengthSquared2D == 0.0) + { + velOut[0] = velIn[0]; + velOut[1] = velIn[1]; + velOut[2] = velIn[2]; + return; + } + + auto newZ = velIn[0] * normal[0] + velIn[1] * normal[1]; + newZ = -newZ / normal[2]; + auto lengthScale = std::sqrtf((velIn[2] * velIn[2] + lengthSquared2D) + / (newZ * newZ + lengthSquared2D)); + + if (Movement::BGBouncesAllAngles.get() + || (lengthScale < 1.f || newZ < 0.f || velIn[2] > 0.f)) + { + velOut[0] = velIn[0] * lengthScale; + velOut[1] = velIn[1] * lengthScale; + velOut[2] = newZ * lengthScale; + } + } + + // Double bounces + void Movement::Jump_ClearStateHk(Game::playerState_s* ps) + { + if (Movement::BGBounces->current.integer == Movement::DOUBLE) + return; + + Game::Jump_ClearState(ps); + } + Game::dvar_t* Movement::Dvar_RegisterLastStandSpeedScale(const char* name, float value, float min, float max, int, const char* desc) { @@ -175,6 +242,14 @@ namespace Components { Dvar::OnInit([] { + static const char* bg_enableBouncesValues[] = + { + "disabled", + "enabled", + "double", + nullptr + }; + Movement::PlayerDuckedSpeedScale = Dvar::Register("player_duckedSpeedScale", 0.65f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, "The scale applied to the player speed when ducking"); @@ -191,6 +266,12 @@ namespace Components Movement::CGNoclipScaler = Dvar::Register("cg_noclip_scaler", 3.0f, 0.001f, 1000.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, "The speed at which noclip camera moves"); + + Movement::BGBounces = Game::Dvar_RegisterEnum("bg_bounces", + bg_enableBouncesValues, Movement::DISABLED, Game::DVAR_FLAG_REPLICATED, "Bounce glitch settings"); + + Movement::BGBouncesAllAngles = Dvar::Register("bg_bouncesAllAngles", + false, Game::DVAR_FLAG_REPLICATED, "Force bounce from all angles"); }); // Hook PM_CmdScaleForStance in PM_CmdScale_Walk @@ -208,6 +289,11 @@ namespace Components // Hook PM_MoveScale so we can add custom speed scale for Ufo and Noclip Utils::Hook(0x56F845, Movement::PM_MoveScaleStub, HOOK_CALL).install()->quick(); Utils::Hook(0x56FABD, Movement::PM_MoveScaleStub, HOOK_CALL).install()->quick(); + + Utils::Hook(0x4B1B2D, Movement::PM_StepSlideMoveStub, HOOK_JUMP).install()->quick(); + Utils::Hook(0x57383E, Movement::Jump_ClearStateHk, HOOK_CALL).install()->quick(); + + Utils::Hook(0x4B1B97, Movement::PM_ProjectVelocityStub, HOOK_CALL).install()->quick(); } Movement::~Movement() diff --git a/src/Components/Modules/Movement.hpp b/src/Components/Modules/Movement.hpp index 09678e37..791dfedc 100644 --- a/src/Components/Modules/Movement.hpp +++ b/src/Components/Modules/Movement.hpp @@ -9,12 +9,17 @@ namespace Components ~Movement(); private: + enum BouncesSettings { DISABLED, ENABLED, DOUBLE }; + static Dvar::Var PlayerDuckedSpeedScale; static Dvar::Var PlayerLastStandCrawlSpeedScale; static Dvar::Var PlayerProneSpeedScale; static Dvar::Var PlayerSpectateSpeedScale; static Dvar::Var CGUfoScaler; static Dvar::Var CGNoclipScaler; + static Dvar::Var BGBouncesAllAngles; + // Can't use Var class inside assembly stubs + static Game::dvar_t* BGBounces; static float PM_CmdScaleForStance(const Game::pmove_s* move); static void PM_CmdScaleForStanceStub(); @@ -22,6 +27,11 @@ namespace Components static float PM_MoveScale(Game::playerState_s* ps, float forwardmove, float rightmove, float upmove); static void PM_MoveScaleStub(); + // Bounce logic + static void PM_StepSlideMoveStub(); + static void PM_ProjectVelocityStub(const float* velIn, const float* normal, float* velOut); + static void Jump_ClearStateHk(Game::playerState_s* ps); + static Game::dvar_t* Dvar_RegisterLastStandSpeedScale(const char* name, float value, float min, float max, int flags, const char* desc); static Game::dvar_t* Dvar_RegisterSpectateSpeedScale(const char* name, float value, float min, float max, int flags, const char* desc); }; diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index edaafa42..c327a79b 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -239,34 +239,6 @@ namespace Components } } - Game::dvar_t* QuickPatch::sv_enableBounces; - __declspec(naked) void QuickPatch::BounceStub() - { - __asm - { - // check the value of sv_enableBounces - push eax; - mov eax, sv_enableBounces; - cmp byte ptr[eax + 16], 1; - pop eax; - - // always bounce if sv_enableBounces is set to 1 - je bounce; - - // original code - cmp dword ptr[esp + 24h], 0; - jnz dontBounce; - - bounce: - push 0x004B1B34; - retn; - - dontBounce: - push 0x004B1B48; - retn; - } - } - Game::dvar_t* QuickPatch::Dvar_RegisterAspectRatioDvar(const char* name, char**, int defaultVal, int flags, const char* description) { static const char* r_aspectRatioEnum[] = @@ -457,10 +429,6 @@ namespace Components // Hook escape handling on open console to change behaviour to close the console instead of only canceling autocomplete Utils::Hook(0x4F66A3, CL_KeyEvent_ConsoleEscape_Stub, HOOK_JUMP).install()->quick(); - // bounce dvar - sv_enableBounces = Game::Dvar_RegisterBool("sv_enableBounces", false, Game::DVAR_FLAG_REPLICATED, "Enables bouncing on the server"); - Utils::Hook(0x4B1B2D, QuickPatch::BounceStub, HOOK_JUMP).install()->quick(); - // Intermission time dvar Game::Dvar_RegisterFloat("scr_intermissionTime", 10, 0, 120, Game::DVAR_FLAG_REPLICATED | Game::DVAR_FLAG_DEDISAVED, "Time in seconds before match server loads the next map"); diff --git a/src/Components/Modules/QuickPatch.hpp b/src/Components/Modules/QuickPatch.hpp index 6b13a5a1..197f9bc8 100644 --- a/src/Components/Modules/QuickPatch.hpp +++ b/src/Components/Modules/QuickPatch.hpp @@ -31,9 +31,6 @@ namespace Components static bool InvalidNameCheck(char* dest, const char* source, int size); static void InvalidNameStub(); - static Game::dvar_t* sv_enableBounces; - static void BounceStub(); - static Dvar::Var r_customAspectRatio; static Game::dvar_t* Dvar_RegisterAspectRatioDvar(const char* name, char** enumValues, int defaultVal, int flags, const char* description); static void SetAspectRatioStub();