From eba329c7b854c0bd5edce5c74e5ce93ab3ecb5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20H=C3=A0n=20Minh=20Khang?= Date: Wed, 24 Aug 2022 22:42:14 -0400 Subject: [PATCH] Necromancing CS1.6 support from cs branch (#322) * Added bxt_anglespeed_cap to override yaw and pitch lock in CS1.6 * re-add speedscaling * copy pasting already existing code for already solved problem * am I doing this correctly to revert a change?? * stylistic change and rebase * Get the variables a bit outside to switch between games' physics * Necromancing stamina/fuser2 HUD * 100% more conditional and organizing stuffs * Working prediction and logging stamina in BXT TAS status * Moving the stamina HUD to the top center * add duck tap slow * update PM_PlayerMove pattern * changes probably will be requested * initial rebase * fix oppsies --- BunnymodXT/cvars.cpp | 10 +++ BunnymodXT/cvars.hpp | 5 ++ BunnymodXT/hud_custom.cpp | 30 ++++++- BunnymodXT/hud_custom.hpp | 3 +- BunnymodXT/modules/ClientDLL.cpp | 133 +++++++++++++++++++++++++++++++ BunnymodXT/modules/ClientDLL.hpp | 10 +++ BunnymodXT/modules/HwDLL.cpp | 42 +++++++--- BunnymodXT/modules/HwDLL.hpp | 2 +- BunnymodXT/patterns.hpp | 24 +++++- BunnymodXT/triangle_drawing.cpp | 6 +- hlstrafe | 2 +- 11 files changed, 249 insertions(+), 18 deletions(-) diff --git a/BunnymodXT/cvars.cpp b/BunnymodXT/cvars.cpp index a58f7f2e..b2133751 100644 --- a/BunnymodXT/cvars.cpp +++ b/BunnymodXT/cvars.cpp @@ -157,6 +157,9 @@ namespace CVars CVarWrapper bxt_hud_entities("bxt_hud_entities", "0"); CVarWrapper bxt_hud_entities_offset("bxt_hud_entities_offset", ""); CVarWrapper bxt_hud_entities_anchor("bxt_hud_entities_anchor", "0 0"); + CVarWrapper bxt_hud_stamina("bxt_hud_stamina", "0"); + CVarWrapper bxt_hud_stamina_offset("bxt_hud_stamina_offset", ""); + CVarWrapper bxt_hud_stamina_anchor("bxt_hud_stamina_anchor", "0.5 0"); CVarWrapper bxt_cross("bxt_cross", "0"); CVarWrapper bxt_cross_color("bxt_cross_color", ""); CVarWrapper bxt_cross_alpha("bxt_cross_alpha", ""); @@ -177,6 +180,8 @@ namespace CVars CVarWrapper bxt_viewmodel_bob_angled("bxt_viewmodel_bob_angled", "0"); CVarWrapper bxt_show_bullets("bxt_show_bullets", "0"); CVarWrapper bxt_show_bullets_enemy("bxt_show_bullets_enemy", "0"); + CVarWrapper bxt_anglespeed_cap("bxt_anglespeed_cap", "1"); + CVarWrapper bxt_speed_scaling("bxt_speed_scaling", "1"); const std::vector allCVars = { @@ -188,6 +193,8 @@ namespace CVars &_bxt_tas_script_generation, &bxt_taslog_filename, &bxt_autopause, + &bxt_anglespeed_cap, + &bxt_speed_scaling, &bxt_interprocess_enable, &bxt_fade_remove, &bxt_skybox_remove, @@ -327,6 +334,9 @@ namespace CVars &bxt_hud_entities, &bxt_hud_entities_offset, &bxt_hud_entities_anchor, + &bxt_hud_stamina, + &bxt_hud_stamina_offset, + &bxt_hud_stamina_anchor, &bxt_cross, &bxt_cross_color, &bxt_cross_alpha, diff --git a/BunnymodXT/cvars.hpp b/BunnymodXT/cvars.hpp index 96bae181..22a42147 100644 --- a/BunnymodXT/cvars.hpp +++ b/BunnymodXT/cvars.hpp @@ -188,6 +188,8 @@ namespace CVars // Clientside CVars extern CVarWrapper cl_righthand; + extern CVarWrapper bxt_anglespeed_cap; + extern CVarWrapper bxt_speed_scaling; extern CVarWrapper bxt_disable_hud; extern CVarWrapper bxt_disable_nightvision_sprite; extern CVarWrapper bxt_autojump_prediction; @@ -270,6 +272,9 @@ namespace CVars extern CVarWrapper bxt_hud_entities; extern CVarWrapper bxt_hud_entities_offset; extern CVarWrapper bxt_hud_entities_anchor; + extern CVarWrapper bxt_hud_stamina; + extern CVarWrapper bxt_hud_stamina_offset; + extern CVarWrapper bxt_hud_stamina_anchor; extern CVarWrapper bxt_cross; extern CVarWrapper bxt_cross_color; extern CVarWrapper bxt_cross_alpha; diff --git a/BunnymodXT/hud_custom.cpp b/BunnymodXT/hud_custom.cpp index cbb35ed1..e04ad120 100644 --- a/BunnymodXT/hud_custom.cpp +++ b/BunnymodXT/hud_custom.cpp @@ -81,6 +81,8 @@ namespace CustomHud float realyaw; float health; float armor; + + float stamina; }; static FrameBulkStatus frame_bulk_status; static bool frame_bulk_selected; @@ -421,7 +423,7 @@ namespace CustomHud void GetAccurateInfo() { - receivedAccurateInfo = HwDLL::GetInstance().TryGettingAccurateInfo(player.origin, player.velocity, player.health, player.armorvalue, player.waterlevel); + receivedAccurateInfo = HwDLL::GetInstance().TryGettingAccurateInfo(player.origin, player.velocity, player.health, player.armorvalue, player.waterlevel, player.stamina); HwDLL::GetInstance().GetViewangles(player.viewangles); } @@ -1429,6 +1431,27 @@ namespace CustomHud } } + void DrawStamina(float flTime) + { + if (CVars::bxt_hud_stamina.GetBool()) + { + int x, y; + GetPosition(CVars::bxt_hud_stamina_offset, CVars::bxt_hud_stamina_anchor, &x, &y, -75, si.iCharHeight * 4); + + std::ostringstream out; + out.setf(std::ios::fixed); + out.precision(precision); + out << "Stamina: "; + + if (frame_bulk_selected) + out << frame_bulk_status.stamina; + else + out << player.stamina; + + DrawString(x, y, out.str().c_str()); + } + } + void Init() { SpriteList = nullptr; @@ -1528,6 +1551,7 @@ namespace CustomHud DrawTASEditorStatus(); DrawEntities(flTime); DrawCrosshair(flTime); + DrawStamina(flTime); receivedAccurateInfo = false; frame_bulk_selected = false; @@ -1650,7 +1674,7 @@ namespace CustomHud return si; } - void UpdateTASEditorStatus(const HLTAS::Frame& frame_bulk, const float& player_vel, const float& player_zvel, const float& player_zpos, const float& player_realyaw, const float& player_health, const float& player_armor) + void UpdateTASEditorStatus(const HLTAS::Frame& frame_bulk, const float& player_vel, const float& player_zvel, const float& player_zpos, const float& player_realyaw, const float& player_health, const float& player_armor, const float& player_stamina) { frame_bulk_selected = true; frame_bulk_status = FrameBulkStatus{}; @@ -1708,5 +1732,7 @@ namespace CustomHud frame_bulk_status.health = player_health; frame_bulk_status.armor = player_armor; + + frame_bulk_status.stamina = player_stamina; } } diff --git a/BunnymodXT/hud_custom.hpp b/BunnymodXT/hud_custom.hpp index b9ece4d7..6ee6268c 100644 --- a/BunnymodXT/hud_custom.hpp +++ b/BunnymodXT/hud_custom.hpp @@ -12,6 +12,7 @@ namespace CustomHud float health; float armorvalue; int waterlevel; + float stamina; } playerinfo; void Init(); @@ -34,5 +35,5 @@ namespace CustomHud const SCREENINFO& GetScreenInfo(); - void UpdateTASEditorStatus(const HLTAS::Frame& frame_bulk, const float& player_vel, const float& player_zvel, const float& player_zpos, const float& player_realyaw, const float& player_health, const float& player_armor); + void UpdateTASEditorStatus(const HLTAS::Frame& frame_bulk, const float& player_vel, const float& player_zvel, const float& player_zpos, const float& player_realyaw, const float& player_health, const float& player_armor, const float& player_stamina); }; diff --git a/BunnymodXT/modules/ClientDLL.cpp b/BunnymodXT/modules/ClientDLL.cpp index 8e509300..d9d99337 100644 --- a/BunnymodXT/modules/ClientDLL.cpp +++ b/BunnymodXT/modules/ClientDLL.cpp @@ -298,6 +298,10 @@ void ClientDLL::Clear() last_viewup = Vector(); last_viewright = Vector(); last_buttons = 0; + pCS_AngleSpeedCap = 0; + pCS_AngleSpeedCap_Linux = 0; + pCS_SpeedScaling = 0; + pCS_SpeedScaling_Linux = 0; } void ClientDLL::FindStuff() @@ -419,6 +423,18 @@ void ClientDLL::FindStuff() } }); + auto fCS_AngleSpeedCap = FindAsync( + pCS_AngleSpeedCap, + patterns::client::CS_AngleSpeedCap); + auto fCS_AngleSpeedCap_Linux = FindAsync( + pCS_AngleSpeedCap_Linux, + patterns::client::CS_AngleSpeedCap_Linux); + auto fCS_SpeedScaling = FindAsync( + pCS_SpeedScaling, + patterns::client::CS_SpeedScaling); + auto fCS_SpeedScaling_Linux = FindAsync( + pCS_SpeedScaling_Linux, + patterns::client::CS_SpeedScaling_Linux); auto fEV_GetDefaultShellInfo = FindAsync(ORIG_EV_GetDefaultShellInfo, patterns::client::EV_GetDefaultShellInfo); auto fCStudioModelRenderer__StudioSetupBones = FindAsync( ORIG_CStudioModelRenderer__StudioSetupBones, @@ -726,6 +742,34 @@ void ClientDLL::FindStuff() } } } + + { + auto pattern = fCS_AngleSpeedCap.get(); + if (pCS_AngleSpeedCap) { + EngineDevMsg("[client dll] Found the angle speed cap pattern at %p (using the %s pattern).\n", pCS_AngleSpeedCap, pattern->name()); + } else { + if (pCS_AngleSpeedCap_Linux) { + pattern = fCS_AngleSpeedCap_Linux.get(); + EngineDevMsg("[client dll] Found the angle speed cap pattern [Linux] at %p (using the %s pattern).\n", pCS_AngleSpeedCap_Linux, pattern->name()); + } else { + EngineDevWarning("[client dll] Could not find angle speed cap pattern.\n"); + } + } + } + + { + auto pattern = fCS_SpeedScaling.get(); + if (pCS_SpeedScaling) { + EngineDevMsg("[client dll] Found the speed scaling pattern at %p (using the %s pattern).\n", pCS_SpeedScaling, pattern->name()); + } else { + if (pCS_SpeedScaling_Linux) { + pattern = fCS_SpeedScaling_Linux.get(); + EngineDevMsg("[client dll] Found the speed scaling pattern [Linux] at %p (using the %s pattern).\n", pCS_SpeedScaling_Linux, pattern->name()); + } else { + EngineDevWarning("[client dll] Could not find the speed scaling pattern.\n"); + } + } + } } bool ClientDLL::FindHUDFunctions() @@ -869,6 +913,9 @@ void ClientDLL::RegisterCVarsAndCommands() REG(bxt_cross_bottom_line); REG(bxt_cross_left_line); REG(bxt_cross_right_line); + REG(bxt_hud_stamina); + REG(bxt_hud_stamina_offset); + REG(bxt_hud_stamina_anchor); } if (ORIG_HUD_Redraw) { @@ -887,6 +934,14 @@ void ClientDLL::RegisterCVarsAndCommands() if (ORIG_CHudFlashlight__drawNightVision_Linux || ORIG_CHudFlashlight__drawNightVision || ORIG_CHud__DrawHudNightVision_Linux || ORIG_CHud__DrawHudNightVision ) { REG(bxt_disable_nightvision_sprite); } + + if (pCS_AngleSpeedCap || pCS_AngleSpeedCap_Linux) { + REG(bxt_anglespeed_cap); + } + + if (pCS_SpeedScaling || pCS_SpeedScaling_Linux) { + REG(bxt_speed_scaling); + } #undef REG } @@ -947,6 +1002,84 @@ bool ClientDLL::DoesGameDirMatch(const char *game) return !std::strcmp(gameDir, game); } +void ClientDLL::SetAngleSpeedCap(bool capped) +{ + if (!pCS_AngleSpeedCap && !pCS_AngleSpeedCap_Linux) { + return; + } + + if (capped) { // restore the bytes + if (pCS_AngleSpeedCap + && *reinterpret_cast(pCS_AngleSpeedCap + 5) == 0xEB + && *reinterpret_cast(pCS_AngleSpeedCap + 37) == 0xEB + && *reinterpret_cast(pCS_AngleSpeedCap + 328) == 0xEB + && *reinterpret_cast(pCS_AngleSpeedCap + 360) == 0xEB) + { + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap + 5), 1, reinterpret_cast("\x7B")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap + 37), 1, reinterpret_cast("\x7A")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap + 328), 1, reinterpret_cast("\x7B")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap + 360), 1, reinterpret_cast("\x7A")); + } + else if (pCS_AngleSpeedCap_Linux + && *reinterpret_cast(pCS_AngleSpeedCap_Linux + 79) == 0xD8 + && *reinterpret_cast(pCS_AngleSpeedCap_Linux + 1089) == 0xD8 + && *reinterpret_cast(pCS_AngleSpeedCap_Linux + 359) == 0xD8 + && *reinterpret_cast(pCS_AngleSpeedCap_Linux + 801) == 0xD8) + { + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap_Linux + 79), 1, reinterpret_cast("\xD9")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap_Linux + 1089), 1, reinterpret_cast("\xD9")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap_Linux + 359), 1, reinterpret_cast("\xD9")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap_Linux + 801), 1, reinterpret_cast("\xD9")); + } + } else { + if (pCS_AngleSpeedCap + && *reinterpret_cast(pCS_AngleSpeedCap + 5) == 0x7B + && *reinterpret_cast(pCS_AngleSpeedCap + 37) == 0x7A + && *reinterpret_cast(pCS_AngleSpeedCap + 328) == 0x7B + && *reinterpret_cast(pCS_AngleSpeedCap + 360) == 0x7A) + { + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap + 5), 1, reinterpret_cast("\xEB")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap + 37), 1, reinterpret_cast("\xEB")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap + 328), 1, reinterpret_cast("\xEB")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap + 360), 1, reinterpret_cast("\xEB")); + } + else if (pCS_AngleSpeedCap_Linux + && *reinterpret_cast(pCS_AngleSpeedCap_Linux + 79) == 0xD9 + && *reinterpret_cast(pCS_AngleSpeedCap_Linux + 1089) == 0xD9 + && *reinterpret_cast(pCS_AngleSpeedCap_Linux + 359) == 0xD9 + && *reinterpret_cast(pCS_AngleSpeedCap_Linux + 801) == 0xD9) + { + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap_Linux + 79), 1, reinterpret_cast("\xD8")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap_Linux + 1089), 1, reinterpret_cast("\xD8")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap_Linux + 359), 1, reinterpret_cast("\xD8")); + MemUtils::ReplaceBytes(reinterpret_cast(pCS_AngleSpeedCap_Linux + 801), 1, reinterpret_cast("\xD8")); + } + } +} + +void ClientDLL::SetSpeedScaling(bool scaled) +{ + if (!pCS_SpeedScaling && !pCS_SpeedScaling_Linux) { + return; + } + + if (scaled) { + if (pCS_SpeedScaling && *reinterpret_cast(pCS_SpeedScaling + 19) == 0xEB) + MemUtils::ReplaceBytes(reinterpret_cast(pCS_SpeedScaling + 19), 1, reinterpret_cast("\x75")); + else if (pCS_SpeedScaling_Linux + && *reinterpret_cast(pCS_SpeedScaling_Linux + 2) == 0xE9 + && *reinterpret_cast(pCS_SpeedScaling_Linux + 3) == 0x62) + MemUtils::ReplaceBytes(reinterpret_cast(pCS_SpeedScaling_Linux + 2), 4, reinterpret_cast("\x0F\x86\x61\xFE")); + } else { + if (pCS_SpeedScaling && *reinterpret_cast(pCS_SpeedScaling + 19) == 0x75) + MemUtils::ReplaceBytes(reinterpret_cast(pCS_SpeedScaling + 19), 1, reinterpret_cast("\xEB")); + else if (pCS_SpeedScaling_Linux + && *reinterpret_cast(pCS_SpeedScaling_Linux + 2) == 0x0F + && *reinterpret_cast(pCS_SpeedScaling_Linux + 3) == 0x86) + MemUtils::ReplaceBytes(reinterpret_cast(pCS_SpeedScaling_Linux + 2), 4, reinterpret_cast("\xE9\x62\xFE\xFF")); + } +} + HOOK_DEF_0(ClientDLL, void, __cdecl, PM_Jump) { auto pmove = reinterpret_cast(*ppmove); diff --git a/BunnymodXT/modules/ClientDLL.hpp b/BunnymodXT/modules/ClientDLL.hpp index 47497f41..05f03259 100644 --- a/BunnymodXT/modules/ClientDLL.hpp +++ b/BunnymodXT/modules/ClientDLL.hpp @@ -94,6 +94,10 @@ class ClientDLL : public IHookableNameFilter Vector AnglesToForward(const Vector &angles); + void SetAngleSpeedCap(bool capped); + + void SetSpeedScaling(bool scaled); + private: ClientDLL() : IHookableNameFilter({ L"client.dll", L"client.so" }) {}; ClientDLL(const ClientDLL&); @@ -118,6 +122,12 @@ class ClientDLL : public IHookableNameFilter ptrdiff_t pBhopcapWindows; byte originalBhopcapInsn[6]; + ptrdiff_t pCS_AngleSpeedCap; + ptrdiff_t pCS_AngleSpeedCap_Linux; + + ptrdiff_t pCS_SpeedScaling; + ptrdiff_t pCS_SpeedScaling_Linux; + bool cantJumpNextTime; unsigned SeedsQueued; diff --git a/BunnymodXT/modules/HwDLL.cpp b/BunnymodXT/modules/HwDLL.cpp index 35433ff8..a7cf4fcc 100644 --- a/BunnymodXT/modules/HwDLL.cpp +++ b/BunnymodXT/modules/HwDLL.cpp @@ -3981,6 +3981,7 @@ void HwDLL::InsertCommands() player.Ducking = (pl->v.flags & FL_DUCKING) != 0; player.InDuckAnimation = (pl->v.bInDuck != 0); player.DuckTime = static_cast(pl->v.flDuckTime); + player.StaminaTime = pl->v.fuser2; if (ORIG_PF_GetPhysicsKeyValue) { auto slj = std::atoi(ORIG_PF_GetPhysicsKeyValue(pl, "slj")); @@ -4564,6 +4565,7 @@ void HwDLL::InsertCommands() player.Ducking = (pl->v.flags & FL_DUCKING) != 0; player.InDuckAnimation = (pl->v.bInDuck != 0); player.DuckTime = static_cast(pl->v.flDuckTime); + player.StaminaTime = pl->v.fuser2; if (ORIG_PF_GetPhysicsKeyValue) { auto slj = std::atoi(ORIG_PF_GetPhysicsKeyValue(pl, "slj")); @@ -4693,6 +4695,7 @@ HLStrafe::PlayerData HwDLL::GetPlayerData() player.Ducking = (pl->v.flags & FL_DUCKING) != 0; player.InDuckAnimation = (pl->v.bInDuck != 0); player.DuckTime = static_cast(pl->v.flDuckTime); + player.StaminaTime = pl->v.fuser2; if (ORIG_PF_GetPhysicsKeyValue) { auto slj = std::atoi(ORIG_PF_GetPhysicsKeyValue(pl, "slj")); @@ -4750,16 +4753,6 @@ HLStrafe::MovementVars HwDLL::GetMovementVars() FindCVarsIfNeeded(); vars.Frametime = GetFrameTime(); vars.Maxvelocity = CVars::sv_maxvelocity.GetFloat(); - - static bool is_paranoia = cl.DoesGameDirMatch("paranoia"); - - if (is_paranoia) - vars.Maxspeed = cl.pEngfuncs->GetClientMaxspeed() * CVars::sv_maxspeed.GetFloat() / 100.0f; // GetMaxSpeed is factor here - else if (cl.pEngfuncs && (cl.pEngfuncs->GetClientMaxspeed() > 0.0f) && (CVars::sv_maxspeed.GetFloat() > cl.pEngfuncs->GetClientMaxspeed())) - vars.Maxspeed = cl.pEngfuncs->GetClientMaxspeed(); // Get true maxspeed in CS games & other mods (Poke646 e.g.) - else - vars.Maxspeed = CVars::sv_maxspeed.GetFloat(); - vars.Stopspeed = CVars::sv_stopspeed.GetFloat(); vars.Friction = CVars::sv_friction.GetFloat(); vars.Edgefriction = CVars::edgefriction.GetFloat(); @@ -4770,6 +4763,28 @@ HLStrafe::MovementVars HwDLL::GetMovementVars() vars.Bounce = CVars::sv_bounce.GetFloat(); vars.Bhopcap = CVars::bxt_bhopcap.GetBool(); + static bool is_paranoia = cl.DoesGameDirMatch("paranoia"); + static bool is_cstrike = cl.DoesGameDirMatch("cstrike"); + + if (is_cstrike) { + vars.Maxspeed = cl.pEngfuncs->GetClientMaxspeed(); + vars.BhopcapMultiplier = 0.8f; + vars.BhopcapMaxspeedScale = 1.2f; + vars.HasStamina = true; + vars.DuckTapSlow = true; + } else { + if (is_paranoia) + vars.Maxspeed = cl.pEngfuncs->GetClientMaxspeed() * CVars::sv_maxspeed.GetFloat() / 100.0f; // GetMaxSpeed is factor here + else if (cl.pEngfuncs && (cl.pEngfuncs->GetClientMaxspeed() > 0.0f) && (CVars::sv_maxspeed.GetFloat() > cl.pEngfuncs->GetClientMaxspeed())) + vars.Maxspeed = cl.pEngfuncs->GetClientMaxspeed(); // Get true maxspeed in other mods (Poke646 e.g.) + else + vars.Maxspeed = CVars::sv_maxspeed.GetFloat(); + + vars.BhopcapMultiplier = 0.65f; + vars.BhopcapMaxspeedScale = 1.7f; + vars.UseSlow = true; + } + if (svs->num_clients >= 1) { edict_t *pl = GetPlayerEdict(); if (pl) { @@ -5056,6 +5071,10 @@ HOOK_DEF_0(HwDLL, void, __cdecl, Cbuf_Execute) } insideCbuf_Execute = false; + ClientDLL::GetInstance().SetAngleSpeedCap(CVars::bxt_anglespeed_cap.GetBool()); + + ClientDLL::GetInstance().SetSpeedScaling(CVars::bxt_speed_scaling.GetBool()); + RuntimeData::SaveStored(); if (CVars::_bxt_taslog.GetBool()) { @@ -5078,7 +5097,7 @@ void HwDLL::SetPlayerVelocity(float velocity[3]) player.Velocity[2] = velocity[2]; } -bool HwDLL::TryGettingAccurateInfo(float origin[3], float velocity[3], float& health, float& armorvalue, int& waterlevel) +bool HwDLL::TryGettingAccurateInfo(float origin[3], float velocity[3], float& health, float& armorvalue, int& waterlevel, float& stamina) { if (!svs || svs->num_clients < 1) return false; @@ -5096,6 +5115,7 @@ bool HwDLL::TryGettingAccurateInfo(float origin[3], float velocity[3], float& he health = pl->v.health; armorvalue = pl->v.armorvalue; waterlevel = pl->v.waterlevel; + stamina = pl->v.fuser2; return true; } diff --git a/BunnymodXT/modules/HwDLL.hpp b/BunnymodXT/modules/HwDLL.hpp index 941796ab..ffd63c6a 100644 --- a/BunnymodXT/modules/HwDLL.hpp +++ b/BunnymodXT/modules/HwDLL.hpp @@ -162,7 +162,7 @@ class HwDLL : public IHookableNameFilterOrdered void SetPlayerOrigin(float origin[3]); void SetPlayerVelocity(float velocity[3]); - bool TryGettingAccurateInfo(float origin[3], float velocity[3], float& health, float& armorvalue, int& waterlevel); + bool TryGettingAccurateInfo(float origin[3], float velocity[3], float& health, float& armorvalue, int& waterlevel, float& stamina); void GetViewangles(float* va); void SetViewangles(float* va); diff --git a/BunnymodXT/patterns.hpp b/BunnymodXT/patterns.hpp index 83ba1028..41e4eeb1 100644 --- a/BunnymodXT/patterns.hpp +++ b/BunnymodXT/patterns.hpp @@ -916,6 +916,26 @@ namespace patterns "TWHL-Tower-2", "55 8B EC 83 EC 14 D9 05 ?? ?? ?? ?? 56 8B F1" ); + + PATTERNS(CS_AngleSpeedCap, + "CS-SteamPipe", + "DF E0 F6 C4 05 7B 10 D9 41 0C D8 1D ?? ?? ?? ?? DF E0 F6 C4 05 7A 1D D9 41 0C D8 1D ?? ?? ?? ?? DF E0 F6 C4 05 7A 08 D9 05 ?? ?? ?? ?? EB 0B D9 41 0C EB 06 D9 05" + ); + + PATTERNS(CS_AngleSpeedCap_Linux, + "CS-SteamPipe", + "57 56 53 83 EC 30 F6 05 ?? ?? ?? ?? 01" + ); + + PATTERNS(CS_SpeedScaling, + "CS-SteamPipe", + "D9 FA DD DB DD D8 DD D8 D8 54 24 18 DF E0 25 00 41 00 00 75 1C D8 7C 24 18 D9 C0 D8 4E 10 D9 5E 10 D9 C0 D8 4E 14 D9 5E 14 D8 4E 18 D9 5E 18 EB 02" + ); + + PATTERNS(CS_SpeedScaling_Linux, + "CS-SteamPipe", + "DB E9 0F 86 ?? ?? ?? ?? DE F9 D9 43 ??" + ); } namespace shared @@ -990,7 +1010,9 @@ namespace patterns "CSCZDS", "A1 ?? ?? ?? ?? 8B 4C 24 04 55 56 57 33 ED 33 ?? 89 48 04 E8 ?? ?? ?? ?? 8B 15 ?? ?? ?? ?? 33 C9 89 AA 8C 54 04 00 A1 ?? ?? ?? ?? 8A 88 5A 54 04 00 89", "Cthulhu", - "A1 ?? ?? ?? ?? 8B 4C 24 04 53 55 57 33 DB 33 FF 89 48 04 E8 ?? ?? ?? ?? 8B 15 ?? ?? ?? ?? 33 C9 89 9A 8C 54 04 00 A1 ?? ?? ?? ?? 8A 88 5A 54 04 00 89" + "A1 ?? ?? ?? ?? 8B 4C 24 04 53 55 57 33 DB 33 FF 89 48 04 E8 ?? ?? ?? ?? 8B 15 ?? ?? ?? ?? 33 C9 89 9A 8C 54 04 00 A1 ?? ?? ?? ?? 8A 88 5A 54 04 00 89", + "CS-SteamPipe", + "83 EC 10 A1 ?? ?? ?? ?? 8B 4C 24 ??" ); PATTERNS(PM_ClipVelocity, diff --git a/BunnymodXT/triangle_drawing.cpp b/BunnymodXT/triangle_drawing.cpp index bacdc999..19add6c3 100644 --- a/BunnymodXT/triangle_drawing.cpp +++ b/BunnymodXT/triangle_drawing.cpp @@ -1684,6 +1684,8 @@ namespace TriangleDrawing float current_player_health = 0; float current_player_armor = 0; + float current_player_stamina = 0; + if (input.player_datas.size() > closest_edge_frame) { auto& current_player_data = input.player_datas[closest_edge_frame]; auto& current_player_vels = current_player_data.Velocity; @@ -1695,6 +1697,8 @@ namespace TriangleDrawing current_player_health = input.player_health_datas[closest_edge_frame]; current_player_armor = input.player_armor_datas[closest_edge_frame]; + + current_player_stamina = current_player_data.StaminaTime; } // Update the HUD status before any changes, since that's the state that was visualized earlier. @@ -1702,7 +1706,7 @@ namespace TriangleDrawing frame_bulk, current_player_vel, current_player_zvel, current_player_zpos, current_player_realyaw, - current_player_health, current_player_armor); + current_player_health, current_player_armor, current_player_stamina); if (left_pressed) { auto mouse_diff = mouse - left_pressed_at; diff --git a/hlstrafe b/hlstrafe index e4dc33b7..717e3ece 160000 --- a/hlstrafe +++ b/hlstrafe @@ -1 +1 @@ -Subproject commit e4dc33b7c65ec832488c68a7c25b3c6f3a2d6806 +Subproject commit 717e3ece9b69524fe1bcc542b5d132ecad406e55