From 91f94208bc04caa9b51b8b5f203c634a8bfa3b24 Mon Sep 17 00:00:00 2001 From: 97saundersj Date: Wed, 17 Jun 2026 23:19:49 +0100 Subject: [PATCH 1/5] Add option to disable automatic reload when magazine is empty Introduced a new configuration setting 'DisableEmptyMagazineAutoReload' to prevent automatic reloading when firing with an empty magazine. Updated input handling to respect this setting and added a helper function to determine when to suppress firing to avoid unintended reloads. --- HaloCEVR/Game.cpp | 1 + HaloCEVR/Game.h | 1 + HaloCEVR/Helpers/Objects.cpp | 19 +++++++++++++++++++ HaloCEVR/Helpers/Objects.h | 3 +++ HaloCEVR/InputHandler.cpp | 22 ++++++++++++++++++++++ 5 files changed, 46 insertions(+) diff --git a/HaloCEVR/Game.cpp b/HaloCEVR/Game.cpp index 01ed133..3f44c0d 100644 --- a/HaloCEVR/Game.cpp +++ b/HaloCEVR/Game.cpp @@ -1086,6 +1086,7 @@ void Game::SetupConfigs() c_3DOFWeaponOffset = config.RegisterVector3("3DOFWeaponOffset", "This is a cosmetic setting for the position offset for the 3DOF weapon model. This has no impact on gameplay. (right, forward, up in metres). Use negative Z to lower the weapon", Vector3(0.0f, 0.0f, -0.08f)); c_3DOFWeaponSmoothingAmount = config.RegisterFloat("3DOFWeaponSmoothingAmount", "This is a cosmetic setting that controls the amount of smoothing applied to 3DOF weapon facing direction. This has no impact on gameplay. (0 is disabled, 2.0 is maximum, default is 1.5)", 1.5f); c_3DOFScopeScale = config.RegisterFloat("3DOFScopeScale", "Width of the scope view in metres (3DOF mode)", 7.f); + c_DisableEmptyMagazineAutoReload = config.RegisterBool("DisableEmptyMagazineAutoReload", "When true, holding fire with an empty magazine does not trigger the game's automatic reload; press Reload to reload. Uses primary weapon ammo only (dual wield off-hand may differ).", false); // Weapon holster settings c_EnableWeaponHolsters = config.RegisterBool("EnableWeaponHolsters", "When enabled Weapons can only be switched by using the 'SwitchWeapons' binding while the dominant hand is within distance of a holster", true); c_LeftShoulderHolsterActivationDistance = config.RegisterFloat("LeftShoulderHolsterDistance", "The 'size' of the left shoulder holster. This is the distance that the dominant hand needs to be from the holster to change weapons (<0 to disable)", 0.3f); diff --git a/HaloCEVR/Game.h b/HaloCEVR/Game.h index d52d093..25e5fc9 100644 --- a/HaloCEVR/Game.h +++ b/HaloCEVR/Game.h @@ -255,5 +255,6 @@ class Game Vector3Property* c_3DOFWeaponOffset = nullptr; FloatProperty* c_3DOFWeaponSmoothingAmount = nullptr; FloatProperty* c_3DOFScopeScale = nullptr; + BoolProperty* c_DisableEmptyMagazineAutoReload = nullptr; }; diff --git a/HaloCEVR/Helpers/Objects.cpp b/HaloCEVR/Helpers/Objects.cpp index 6f079c2..f622e8b 100644 --- a/HaloCEVR/Helpers/Objects.cpp +++ b/HaloCEVR/Helpers/Objects.cpp @@ -48,3 +48,22 @@ BaseDynamicObject* Helpers::GetLocalPlayer() return GetDynamicObject(playerID); } + +bool Helpers::ShouldSuppressFireToPreventEmptyMagReload() +{ + UnitDynamicObject* player = static_cast(GetLocalPlayer()); + if (!player) + { + return false; + } + + WeaponDynamicObject* weaponObj = static_cast(GetDynamicObject(player->weapon)); + if (!weaponObj) + { + return false; + } + + // weaponData[0] is the primary weapon; dual-wield off-hand may use weaponData[1] (not handled here). + const Weapon& w = weaponObj->weaponData[0]; + return w.ammo == 0 && w.reserveAmmo > 0; +} diff --git a/HaloCEVR/Helpers/Objects.h b/HaloCEVR/Helpers/Objects.h index f97c2f5..a62f39d 100644 --- a/HaloCEVR/Helpers/Objects.h +++ b/HaloCEVR/Helpers/Objects.h @@ -238,4 +238,7 @@ namespace Helpers BaseDynamicObject* GetDynamicObject(HaloID& ID); bool GetLocalPlayerID(HaloID& OutID); BaseDynamicObject* GetLocalPlayer(); + + // True when held weapon (weaponData[0]) has no rounds in mag but still has reserve — vanilla Halo starts a reload on held fire in this state. + bool ShouldSuppressFireToPreventEmptyMagReload(); } \ No newline at end of file diff --git a/HaloCEVR/InputHandler.cpp b/HaloCEVR/InputHandler.cpp index 71ead9c..e187a1a 100644 --- a/HaloCEVR/InputHandler.cpp +++ b/HaloCEVR/InputHandler.cpp @@ -4,6 +4,7 @@ #include "Helpers/Camera.h" #include "Helpers/Menus.h" #include "Helpers/Maths.h" +#include "Helpers/Objects.h" #define RegisterBoolInput(set, x) x = vr->RegisterBoolInput(set, #x); @@ -11,6 +12,23 @@ #define ApplyBoolInput(x) controls.##x = vr->GetBoolInput(x) ? 127 : 0; #define ApplyImpulseBoolInput(x) controls.##x = vr->GetBoolInput(x, bHasChanged) && bHasChanged ? 127 : 0; +template +static void MaybeSuppressEmptyMagAutoReload(T& controls) +{ + if (!Game::instance.c_DisableEmptyMagazineAutoReload || !Game::instance.c_DisableEmptyMagazineAutoReload->Value()) + { + return; + } + if (!controls.Fire || controls.Reload) + { + return; + } + if (Helpers::ShouldSuppressFireToPreventEmptyMagReload()) + { + controls.Fire = 0; + } +} + void InputHandler::RegisterInputs() { IVR* vr = Game::instance.GetVR(); @@ -92,6 +110,8 @@ void InputHandler::UpdateInputs(bool bInVehicle) ApplyImpulseBoolInput(Zoom); ApplyBoolInput(Reload); + MaybeSuppressEmptyMagAutoReload(controls); + Game::instance.bIsFiring = controls.Fire; } else @@ -111,6 +131,8 @@ void InputHandler::UpdateInputs(bool bInVehicle) ApplyImpulseBoolInput(Zoom); ApplyBoolInput(Reload); + MaybeSuppressEmptyMagAutoReload(controls); + Game::instance.bIsFiring = controls.Fire; } From 54a33bf11181649ab1e6e96d14ba9adc8a3b7a08 Mon Sep 17 00:00:00 2001 From: 97saundersj Date: Fri, 19 Jun 2026 17:56:39 +0100 Subject: [PATCH 2/5] Add functionality to block automatic reload based on input state --- HaloCEVR/Game.cpp | 5 +++++ HaloCEVR/Game.h | 1 + HaloCEVR/Hooking/Hooks.cpp | 7 +++++++ HaloCEVR/InputHandler.cpp | 18 ++++++++++++++++++ HaloCEVR/InputHandler.h | 3 +++ 5 files changed, 34 insertions(+) diff --git a/HaloCEVR/Game.cpp b/HaloCEVR/Game.cpp index 3f44c0d..06ccefa 100644 --- a/HaloCEVR/Game.cpp +++ b/HaloCEVR/Game.cpp @@ -859,6 +859,11 @@ bool Game::GetCalculatedHandPositions(Matrix4& controllerTransform, Vector3& dom return inputHandler.GetCalculatedHandPositions(controllerTransform, dominantHandPos, offHand); } +bool Game::ShouldBlockAutoReloadStart() const +{ + return inputHandler.ShouldBlockAutoReloadStart(); +} + void Game::ReloadStart(HaloID param1, short param2, bool param3) { VR_PROFILE_SCOPE(Game_ReloadStart); diff --git a/HaloCEVR/Game.h b/HaloCEVR/Game.h index 25e5fc9..76ad095 100644 --- a/HaloCEVR/Game.h +++ b/HaloCEVR/Game.h @@ -61,6 +61,7 @@ class Game bool GetCalculatedHandPositions(Matrix4& controllerTransform, Vector3& dominantHandPos, Vector3& offHand); void ReloadStart(HaloID param1, short param2, bool param3); void ReloadEnd(short param1, HaloID param2); + bool ShouldBlockAutoReloadStart() const; void UpdateInputs(); void CalculateSmoothedInput(); diff --git a/HaloCEVR/Hooking/Hooks.cpp b/HaloCEVR/Hooking/Hooks.cpp index 8634f82..1b42ec7 100644 --- a/HaloCEVR/Hooking/Hooks.cpp +++ b/HaloCEVR/Hooking/Hooks.cpp @@ -900,6 +900,13 @@ void Hooks::H_ReloadStart(HaloID param1, short param2, bool param3) { VR_PROFILE_SCOPE(Hooks_ReloadStart); + // Auto-reload is started inside the game (often when the last round fires), before VR + // controls are applied in H_HandleInputs. Clearing Controls.Fire alone is too late. + if (Game::instance.ShouldBlockAutoReloadStart()) + { + return; + } + ReloadStart.Original(param1, param2, param3); Game::instance.ReloadStart(param1, param2, param3); diff --git a/HaloCEVR/InputHandler.cpp b/HaloCEVR/InputHandler.cpp index e187a1a..3ded492 100644 --- a/HaloCEVR/InputHandler.cpp +++ b/HaloCEVR/InputHandler.cpp @@ -26,9 +26,27 @@ static void MaybeSuppressEmptyMagAutoReload(T& controls) if (Helpers::ShouldSuppressFireToPreventEmptyMagReload()) { controls.Fire = 0; + // Controls are written after HandleInputs.Original(); the game may also read InputData.firing. + Helpers::GetInputData().firing = 0.0f; } } +bool InputHandler::IsReloadPressed() const +{ + IVR* vr = Game::instance.GetVR(); + return vr && vr->GetBoolInput(Reload); +} + +bool InputHandler::ShouldBlockAutoReloadStart() const +{ + if (!Game::instance.c_DisableEmptyMagazineAutoReload || !Game::instance.c_DisableEmptyMagazineAutoReload->Value()) + { + return false; + } + + return !IsReloadPressed(); +} + void InputHandler::RegisterInputs() { IVR* vr = Game::instance.GetVR(); diff --git a/HaloCEVR/InputHandler.h b/HaloCEVR/InputHandler.h index 49c7fcd..ba4b2c7 100644 --- a/HaloCEVR/InputHandler.h +++ b/HaloCEVR/InputHandler.h @@ -15,6 +15,9 @@ class InputHandler bool GetCalculatedHandPositions(Matrix4& controllerTransform, Vector3& dominantHandPos, Vector3& offHand); void CalculateSmoothedInput(); + bool IsReloadPressed() const; + bool ShouldBlockAutoReloadStart() const; + Vector3 smoothedPosition = Vector3(0.0f, 0.0f, 0.0f); // Track previous yaw offset to detect snap turns for weapon position smoothing From 46d3de34d0f1dbe0325818667ed66489f5dadc2e Mon Sep 17 00:00:00 2001 From: 97saundersj Date: Fri, 19 Jun 2026 18:16:41 +0100 Subject: [PATCH 3/5] Refactor automatic reload handling and remove unused suppression function Updated the 'DisableEmptyMagazineAutoReload' configuration description for clarity. Removed the 'MaybeSuppressEmptyMagAutoReload' function and its references from the input handling logic, as it is no longer needed. This streamlines the code and improves maintainability. --- HaloCEVR/Game.cpp | 2 +- HaloCEVR/Helpers/Objects.cpp | 19 ------------------- HaloCEVR/Helpers/Objects.h | 3 --- HaloCEVR/InputHandler.cpp | 24 ------------------------ 4 files changed, 1 insertion(+), 47 deletions(-) diff --git a/HaloCEVR/Game.cpp b/HaloCEVR/Game.cpp index 06ccefa..f9ee31d 100644 --- a/HaloCEVR/Game.cpp +++ b/HaloCEVR/Game.cpp @@ -1091,7 +1091,7 @@ void Game::SetupConfigs() c_3DOFWeaponOffset = config.RegisterVector3("3DOFWeaponOffset", "This is a cosmetic setting for the position offset for the 3DOF weapon model. This has no impact on gameplay. (right, forward, up in metres). Use negative Z to lower the weapon", Vector3(0.0f, 0.0f, -0.08f)); c_3DOFWeaponSmoothingAmount = config.RegisterFloat("3DOFWeaponSmoothingAmount", "This is a cosmetic setting that controls the amount of smoothing applied to 3DOF weapon facing direction. This has no impact on gameplay. (0 is disabled, 2.0 is maximum, default is 1.5)", 1.5f); c_3DOFScopeScale = config.RegisterFloat("3DOFScopeScale", "Width of the scope view in metres (3DOF mode)", 7.f); - c_DisableEmptyMagazineAutoReload = config.RegisterBool("DisableEmptyMagazineAutoReload", "When true, holding fire with an empty magazine does not trigger the game's automatic reload; press Reload to reload. Uses primary weapon ammo only (dual wield off-hand may differ).", false); + c_DisableEmptyMagazineAutoReload = config.RegisterBool("DisableEmptyMagazineAutoReload", "When true, the game will not automatically reload on an empty magazine; press Reload to reload. Auto-reloads are blocked via the ReloadStart hook so dry-fire sounds still play.", false); // Weapon holster settings c_EnableWeaponHolsters = config.RegisterBool("EnableWeaponHolsters", "When enabled Weapons can only be switched by using the 'SwitchWeapons' binding while the dominant hand is within distance of a holster", true); c_LeftShoulderHolsterActivationDistance = config.RegisterFloat("LeftShoulderHolsterDistance", "The 'size' of the left shoulder holster. This is the distance that the dominant hand needs to be from the holster to change weapons (<0 to disable)", 0.3f); diff --git a/HaloCEVR/Helpers/Objects.cpp b/HaloCEVR/Helpers/Objects.cpp index f622e8b..6f079c2 100644 --- a/HaloCEVR/Helpers/Objects.cpp +++ b/HaloCEVR/Helpers/Objects.cpp @@ -48,22 +48,3 @@ BaseDynamicObject* Helpers::GetLocalPlayer() return GetDynamicObject(playerID); } - -bool Helpers::ShouldSuppressFireToPreventEmptyMagReload() -{ - UnitDynamicObject* player = static_cast(GetLocalPlayer()); - if (!player) - { - return false; - } - - WeaponDynamicObject* weaponObj = static_cast(GetDynamicObject(player->weapon)); - if (!weaponObj) - { - return false; - } - - // weaponData[0] is the primary weapon; dual-wield off-hand may use weaponData[1] (not handled here). - const Weapon& w = weaponObj->weaponData[0]; - return w.ammo == 0 && w.reserveAmmo > 0; -} diff --git a/HaloCEVR/Helpers/Objects.h b/HaloCEVR/Helpers/Objects.h index a62f39d..f97c2f5 100644 --- a/HaloCEVR/Helpers/Objects.h +++ b/HaloCEVR/Helpers/Objects.h @@ -238,7 +238,4 @@ namespace Helpers BaseDynamicObject* GetDynamicObject(HaloID& ID); bool GetLocalPlayerID(HaloID& OutID); BaseDynamicObject* GetLocalPlayer(); - - // True when held weapon (weaponData[0]) has no rounds in mag but still has reserve — vanilla Halo starts a reload on held fire in this state. - bool ShouldSuppressFireToPreventEmptyMagReload(); } \ No newline at end of file diff --git a/HaloCEVR/InputHandler.cpp b/HaloCEVR/InputHandler.cpp index 3ded492..51a175a 100644 --- a/HaloCEVR/InputHandler.cpp +++ b/HaloCEVR/InputHandler.cpp @@ -4,7 +4,6 @@ #include "Helpers/Camera.h" #include "Helpers/Menus.h" #include "Helpers/Maths.h" -#include "Helpers/Objects.h" #define RegisterBoolInput(set, x) x = vr->RegisterBoolInput(set, #x); @@ -12,25 +11,6 @@ #define ApplyBoolInput(x) controls.##x = vr->GetBoolInput(x) ? 127 : 0; #define ApplyImpulseBoolInput(x) controls.##x = vr->GetBoolInput(x, bHasChanged) && bHasChanged ? 127 : 0; -template -static void MaybeSuppressEmptyMagAutoReload(T& controls) -{ - if (!Game::instance.c_DisableEmptyMagazineAutoReload || !Game::instance.c_DisableEmptyMagazineAutoReload->Value()) - { - return; - } - if (!controls.Fire || controls.Reload) - { - return; - } - if (Helpers::ShouldSuppressFireToPreventEmptyMagReload()) - { - controls.Fire = 0; - // Controls are written after HandleInputs.Original(); the game may also read InputData.firing. - Helpers::GetInputData().firing = 0.0f; - } -} - bool InputHandler::IsReloadPressed() const { IVR* vr = Game::instance.GetVR(); @@ -128,8 +108,6 @@ void InputHandler::UpdateInputs(bool bInVehicle) ApplyImpulseBoolInput(Zoom); ApplyBoolInput(Reload); - MaybeSuppressEmptyMagAutoReload(controls); - Game::instance.bIsFiring = controls.Fire; } else @@ -149,8 +127,6 @@ void InputHandler::UpdateInputs(bool bInVehicle) ApplyImpulseBoolInput(Zoom); ApplyBoolInput(Reload); - MaybeSuppressEmptyMagAutoReload(controls); - Game::instance.bIsFiring = controls.Fire; } From 0090208fbd09c0740cd987716cb73c1bfcd1409e Mon Sep 17 00:00:00 2001 From: 97saundersj Date: Fri, 19 Jun 2026 23:11:39 +0100 Subject: [PATCH 4/5] Moved DisableEmptyMagazineAutoReload configuration option --- HaloCEVR/Game.cpp | 2 +- HaloCEVR/Game.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HaloCEVR/Game.cpp b/HaloCEVR/Game.cpp index f9ee31d..5abc23f 100644 --- a/HaloCEVR/Game.cpp +++ b/HaloCEVR/Game.cpp @@ -1074,6 +1074,7 @@ void Game::SetupConfigs() c_LeftHandMeleeSwingSpeed = config.RegisterFloat("LeftHandMeleeSwingSpeed", "Minimum vertical velocity of left hand required to initiate a melee attack in m/s (<0 to disable)", 2.5f); c_RightHandMeleeSwingSpeed = config.RegisterFloat("RightHandMeleeSwingSpeed", "Minimum vertical velocity of right hand required to initiate a melee attack in m/s (<0 to disable)", 2.5f); c_CrouchHeight = config.RegisterFloat("CrouchHeight", "Minimum height to duck by in metres to automatically trigger the crouch input in game (<0 to disable)", 0.15f); + c_DisableEmptyMagazineAutoReload = config.RegisterBool("DisableEmptyMagazineAutoReload", "When enabled, the game will not automatically reload when the magazine is empty. Press Reload to reload manually", false); // Hand settings c_ControllerOffset = config.RegisterVector3("ControllerOffset", "Offset from the controller's position used when calculating the in game hand position", Vector3(0.0f, 0.0f, 0.0f)); c_ControllerRotation = config.RegisterVector3("ControllerRotation", "Rotation added to the controller when calculating the in game hand rotation", Vector3(0.0f, 0.0f, 0.0f)); @@ -1091,7 +1092,6 @@ void Game::SetupConfigs() c_3DOFWeaponOffset = config.RegisterVector3("3DOFWeaponOffset", "This is a cosmetic setting for the position offset for the 3DOF weapon model. This has no impact on gameplay. (right, forward, up in metres). Use negative Z to lower the weapon", Vector3(0.0f, 0.0f, -0.08f)); c_3DOFWeaponSmoothingAmount = config.RegisterFloat("3DOFWeaponSmoothingAmount", "This is a cosmetic setting that controls the amount of smoothing applied to 3DOF weapon facing direction. This has no impact on gameplay. (0 is disabled, 2.0 is maximum, default is 1.5)", 1.5f); c_3DOFScopeScale = config.RegisterFloat("3DOFScopeScale", "Width of the scope view in metres (3DOF mode)", 7.f); - c_DisableEmptyMagazineAutoReload = config.RegisterBool("DisableEmptyMagazineAutoReload", "When true, the game will not automatically reload on an empty magazine; press Reload to reload. Auto-reloads are blocked via the ReloadStart hook so dry-fire sounds still play.", false); // Weapon holster settings c_EnableWeaponHolsters = config.RegisterBool("EnableWeaponHolsters", "When enabled Weapons can only be switched by using the 'SwitchWeapons' binding while the dominant hand is within distance of a holster", true); c_LeftShoulderHolsterActivationDistance = config.RegisterFloat("LeftShoulderHolsterDistance", "The 'size' of the left shoulder holster. This is the distance that the dominant hand needs to be from the holster to change weapons (<0 to disable)", 0.3f); diff --git a/HaloCEVR/Game.h b/HaloCEVR/Game.h index 76ad095..42de920 100644 --- a/HaloCEVR/Game.h +++ b/HaloCEVR/Game.h @@ -238,6 +238,7 @@ class Game FloatProperty* c_LeftHandMeleeSwingSpeed = nullptr; FloatProperty* c_RightHandMeleeSwingSpeed = nullptr; FloatProperty* c_CrouchHeight = nullptr; + BoolProperty* c_DisableEmptyMagazineAutoReload = nullptr; BoolProperty* c_ShowRoomCentre = nullptr; BoolProperty* c_ToggleGrip = nullptr; FloatProperty* c_TwoHandDistance = nullptr; @@ -256,6 +257,5 @@ class Game Vector3Property* c_3DOFWeaponOffset = nullptr; FloatProperty* c_3DOFWeaponSmoothingAmount = nullptr; FloatProperty* c_3DOFScopeScale = nullptr; - BoolProperty* c_DisableEmptyMagazineAutoReload = nullptr; }; From d6129e645db4d83478b9e42741c285fae659738d Mon Sep 17 00:00:00 2001 From: 97saundersj Date: Sun, 21 Jun 2026 22:57:20 +0100 Subject: [PATCH 5/5] Refactoring changes --- HaloCEVR/Game.cpp | 3 ++- HaloCEVR/Hooking/Hooks.cpp | 3 +-- HaloCEVR/InputHandler.cpp | 11 +++-------- HaloCEVR/InputHandler.h | 1 - 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/HaloCEVR/Game.cpp b/HaloCEVR/Game.cpp index 5abc23f..837ce2b 100644 --- a/HaloCEVR/Game.cpp +++ b/HaloCEVR/Game.cpp @@ -1074,7 +1074,6 @@ void Game::SetupConfigs() c_LeftHandMeleeSwingSpeed = config.RegisterFloat("LeftHandMeleeSwingSpeed", "Minimum vertical velocity of left hand required to initiate a melee attack in m/s (<0 to disable)", 2.5f); c_RightHandMeleeSwingSpeed = config.RegisterFloat("RightHandMeleeSwingSpeed", "Minimum vertical velocity of right hand required to initiate a melee attack in m/s (<0 to disable)", 2.5f); c_CrouchHeight = config.RegisterFloat("CrouchHeight", "Minimum height to duck by in metres to automatically trigger the crouch input in game (<0 to disable)", 0.15f); - c_DisableEmptyMagazineAutoReload = config.RegisterBool("DisableEmptyMagazineAutoReload", "When enabled, the game will not automatically reload when the magazine is empty. Press Reload to reload manually", false); // Hand settings c_ControllerOffset = config.RegisterVector3("ControllerOffset", "Offset from the controller's position used when calculating the in game hand position", Vector3(0.0f, 0.0f, 0.0f)); c_ControllerRotation = config.RegisterVector3("ControllerRotation", "Rotation added to the controller when calculating the in game hand rotation", Vector3(0.0f, 0.0f, 0.0f)); @@ -1098,6 +1097,8 @@ void Game::SetupConfigs() c_LeftShoulderHolsterOffset = config.RegisterVector3("LeftShoulderHolsterOffset", "The (foward, left, up) Offset of the left shoulder holster relative to the headset's location", Vector3(-0.15f, 0.25f, -0.25f)); c_RightShoulderHolsterActivationDistance = config.RegisterFloat("RightShoulderHolsterDistance", "The 'size' of the right shoulder holster. This is the distance that the dominant hand needs to be from the holster to change weapons (<0 to disable)", 0.3f); c_RightShoulderHolsterOffset = config.RegisterVector3("RightShoulderHolsterOffset", "The (foward, left, up) Offset of the right shoulder holster relative to the headset's location", Vector3(-0.15f, -0.25f, -0.25f)); + // Manual reload settings + c_DisableEmptyMagazineAutoReload = config.RegisterBool("DisableEmptyMagazineAutoReload", "When enabled, the game will not automatically reload when the magazine is empty. Press Reload to reload manually", false); // Misc settings c_ShowRoomCentre = config.RegisterBool("ShowRoomCentre", "Draw an indicator at your feet to show where the player character is actually positioned", true); c_d3d9Path = config.RegisterString("CustomD3D9Path", "If set first try to load d3d9.dll from the specified path instead of from system32", ""); diff --git a/HaloCEVR/Hooking/Hooks.cpp b/HaloCEVR/Hooking/Hooks.cpp index 1b42ec7..ba6158d 100644 --- a/HaloCEVR/Hooking/Hooks.cpp +++ b/HaloCEVR/Hooking/Hooks.cpp @@ -900,8 +900,7 @@ void Hooks::H_ReloadStart(HaloID param1, short param2, bool param3) { VR_PROFILE_SCOPE(Hooks_ReloadStart); - // Auto-reload is started inside the game (often when the last round fires), before VR - // controls are applied in H_HandleInputs. Clearing Controls.Fire alone is too late. + // Block auto-reload from starting. if (Game::instance.ShouldBlockAutoReloadStart()) { return; diff --git a/HaloCEVR/InputHandler.cpp b/HaloCEVR/InputHandler.cpp index 51a175a..b6bf153 100644 --- a/HaloCEVR/InputHandler.cpp +++ b/HaloCEVR/InputHandler.cpp @@ -11,20 +11,15 @@ #define ApplyBoolInput(x) controls.##x = vr->GetBoolInput(x) ? 127 : 0; #define ApplyImpulseBoolInput(x) controls.##x = vr->GetBoolInput(x, bHasChanged) && bHasChanged ? 127 : 0; -bool InputHandler::IsReloadPressed() const -{ - IVR* vr = Game::instance.GetVR(); - return vr && vr->GetBoolInput(Reload); -} - bool InputHandler::ShouldBlockAutoReloadStart() const { - if (!Game::instance.c_DisableEmptyMagazineAutoReload || !Game::instance.c_DisableEmptyMagazineAutoReload->Value()) + if (!Game::instance.c_DisableEmptyMagazineAutoReload->Value()) { return false; } - return !IsReloadPressed(); + IVR* vr = Game::instance.GetVR(); + return !vr->GetBoolInput(Reload); } void InputHandler::RegisterInputs() diff --git a/HaloCEVR/InputHandler.h b/HaloCEVR/InputHandler.h index ba4b2c7..cd560cf 100644 --- a/HaloCEVR/InputHandler.h +++ b/HaloCEVR/InputHandler.h @@ -15,7 +15,6 @@ class InputHandler bool GetCalculatedHandPositions(Matrix4& controllerTransform, Vector3& dominantHandPos, Vector3& offHand); void CalculateSmoothedInput(); - bool IsReloadPressed() const; bool ShouldBlockAutoReloadStart() const; Vector3 smoothedPosition = Vector3(0.0f, 0.0f, 0.0f);