diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 03ee1317..7c64416a 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -106,6 +106,7 @@ namespace Components Loader::Register(new ClientCommand()); Loader::Register(new ScriptExtension()); Loader::Register(new RawMouse()); + Loader::Register(new Bullet()); Loader::Pregame = false; } diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 12dd197e..12ffb1ff 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -137,3 +137,4 @@ namespace Components #include "Modules/Gamepad.hpp" #include "Modules/ScriptExtension.hpp" #include "Modules/RawMouse.hpp" +#include "Modules/Bullet.hpp" diff --git a/src/Components/Modules/Bullet.cpp b/src/Components/Modules/Bullet.cpp new file mode 100644 index 00000000..c07476d7 --- /dev/null +++ b/src/Components/Modules/Bullet.cpp @@ -0,0 +1,60 @@ +#include + +namespace Components +{ + Dvar::Var Bullet::BGSurfacePenetration; + Game::dvar_t* Bullet::BGBulletRange; + + float Bullet::BG_GetSurfacePenetrationDepthStub(const Game::WeaponDef* weapDef, int surfaceType) + { + assert(weapDef != nullptr); + assert(weapDef->penetrateType != Game::PenetrateType::PENETRATE_TYPE_NONE); + assert(weapDef->penetrateType < Game::PenetrateType::PENETRATE_TYPE_COUNT); + assert(static_cast(surfaceType) < Game::materialSurfType_t::SURF_TYPE_COUNT); + + const auto penetrationDepth = BGSurfacePenetration.get(); + if (penetrationDepth > 0.0f) + { + // Custom depth + return penetrationDepth; + } + + // Game's code + if (surfaceType != Game::materialSurfType_t::SURF_TYPE_DEFAULT) + { + return (*Game::penetrationDepthTable)[weapDef->penetrateType][surfaceType]; + } + + return 0.0f; + } + + __declspec(naked) void Bullet::Bullet_FireStub() + { + __asm + { + push eax + mov eax, BGBulletRange + fld dword ptr [eax + 0x10] // dvar_t.current.value + pop eax + + push 0x440346 + retn + } + } + + Bullet::Bullet() + { + Dvar::OnInit([] + { + BGSurfacePenetration = Dvar::Register("bg_surfacePenetration", 0.0f, + 0.0f, std::numeric_limits::max(), Game::dvar_flag::DVAR_CODINFO, + "Set to a value greater than 0 to override the surface penetration depth"); + BGBulletRange = Game::Dvar_RegisterFloat("bg_bulletRange", 8192.0f, + 0.0f, std::numeric_limits::max(), Game::dvar_flag::DVAR_CODINFO, + "Max range used when calculating the bullet end position"); + }); + + Utils::Hook(0x4F6980, BG_GetSurfacePenetrationDepthStub, HOOK_JUMP).install()->quick(); + Utils::Hook(0x440340, Bullet_FireStub, HOOK_JUMP).install()->quick(); + } +} diff --git a/src/Components/Modules/Bullet.hpp b/src/Components/Modules/Bullet.hpp new file mode 100644 index 00000000..c1626205 --- /dev/null +++ b/src/Components/Modules/Bullet.hpp @@ -0,0 +1,19 @@ +#pragma once + +namespace Components +{ + class Bullet : public Component + { + public: + Bullet(); + + private: + static Dvar::Var BGSurfacePenetration; + // Can't use Var class inside assembly stubs + static Game::dvar_t* BGBulletRange; + + static float BG_GetSurfacePenetrationDepthStub(const Game::WeaponDef* weapDef, int surfaceType); + + static void Bullet_FireStub(); + }; +} diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 3f95f023..5fb7505a 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -193,7 +193,7 @@ namespace Game Load_snd_alias_list_nameArray_t Load_snd_alias_list_nameArray = Load_snd_alias_list_nameArray_t(0x4499F0); Menus_CloseAll_t Menus_CloseAll = Menus_CloseAll_t(0x4BA5B0); - Menus_CloseRequest_t Menus_CloseRequest = Menus_CloseRequest_t(0x430D50); + Menus_CloseRequest_t Menus_CloseRequest = Menus_CloseRequest_t(0x430D50); Menus_OpenByName_t Menus_OpenByName = Menus_OpenByName_t(0x4CCE60); Menus_FindByName_t Menus_FindByName = Menus_FindByName_t(0x487240); Menu_IsVisible_t Menu_IsVisible = Menu_IsVisible_t(0x4D77D0); @@ -550,6 +550,8 @@ namespace Game level_locals_t* level = reinterpret_cast(0x1A831A8); + float(*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT] = reinterpret_cast(0x7C4878); + WinMouseVars_t* s_wmv = reinterpret_cast(0x649D640); int* window_center_x = reinterpret_cast(0x649D638); @@ -1593,7 +1595,7 @@ namespace Game __declspec(naked) void AimAssist_UpdateAdsLerp(const AimInput* /*aimInput*/) { - __asm + __asm { mov eax, [esp + 0x4] mov ebx, 0x569AA0 diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index b11f32a5..4369bbad 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -477,8 +477,8 @@ namespace Game typedef void(__cdecl * Menus_CloseAll_t)(UiContext* dc); extern Menus_CloseAll_t Menus_CloseAll; - typedef void(__cdecl * Menus_CloseRequest_t)(UiContext *dc, menuDef_t* menu); - extern Menus_CloseRequest_t Menus_CloseRequest; + typedef void(__cdecl * Menus_CloseRequest_t)(UiContext* dc, menuDef_t* menu); + extern Menus_CloseRequest_t Menus_CloseRequest; typedef int(__cdecl * Menus_OpenByName_t)(UiContext* dc, const char* p); extern Menus_OpenByName_t Menus_OpenByName; @@ -1148,6 +1148,8 @@ namespace Game extern level_locals_t* level; + extern float(*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT]; + extern WinMouseVars_t* s_wmv; extern int* window_center_x; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 944f0572..e0eb5dcc 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -96,6 +96,43 @@ namespace Game ASSET_TYPE_INVALID = -1, }; + enum materialSurfType_t + { + SURF_TYPE_DEFAULT, + SURF_TYPE_BARK, + SURF_TYPE_BRICK, + SURF_TYPE_CARPET, + SURF_TYPE_CLOTH, + SURF_TYPE_CONCRETE, + SURF_TYPE_DIRT, + SURF_TYPE_FLESH, + SURF_TYPE_FOLIAGE, + SURF_TYPE_GLASS, + SURF_TYPE_GRASS, + SURF_TYPE_GRAVEL, + SURF_TYPE_ICE, + SURF_TYPE_METAL, + SURF_TYPE_MUD, + SURF_TYPE_PAPER, + SURF_TYPE_PLASTER, + SURF_TYPE_ROCK, + SURF_TYPE_SAND, + SURF_TYPE_SNOW, + SURF_TYPE_WATER, + SURF_TYPE_WOOD, + SURF_TYPE_ASPHALT, + SURF_TYPE_CERAMIC, + SURF_TYPE_PLASTIC, + SURF_TYPE_RUBBER, + SURF_TYPE_CUSHION, + SURF_TYPE_FRUIT, + SURF_TYPE_PAINTED_METAL, + SURF_TYPE_RIOT_SHIELD, + SURF_TYPE_SLUSH, + + SURF_TYPE_COUNT + }; + enum dvar_flag : unsigned __int16 { DVAR_NONE = 0x0, // No flags