diff --git a/FullAuto.cs b/FullAuto.cs index 4ae2c6e..8623087 100644 --- a/FullAuto.cs +++ b/FullAuto.cs @@ -46,18 +46,17 @@ public class FullAuto : SonsMod private void OnUpdate() { + CheckFireInputPatch.UpdateTrigger(); + if (!Enabled || !GameState.IsPlayerControllable || !CheckFireInputPatch.HoldingGun) return; - if (Mode == FireMode.Burst && Input.GetMouseButtonDown(0)) - CheckFireInputPatch.StartBurst(); - if (Input.GetMouseButtonDown(2)) { Mode = Mode switch { - FireMode.Auto => FireMode.Burst, - FireMode.Burst => FireMode.Semi, + FireMode.Auto => FireMode.Semi, + FireMode.Semi => FireMode.Burst, _ => FireMode.Auto }; CheckFireInputPatch.CancelBurst(); @@ -122,9 +121,9 @@ public class FullAuto : SonsMod { return Mode switch { - FireMode.Auto => "Full-Auto", + FireMode.Auto => "Full-automatic", FireMode.Burst => "3-Round Burst", - _ => "Semi-Automatic" + _ => "Semi-automatic" }; } @@ -179,6 +178,7 @@ internal static class CheckFireInputPatch { private const int MaxShotsPerFrame = 4; private const int BurstSize = 3; + private const float ReleaseTime = 0.05f; private static readonly HashSet Guns = new() { @@ -189,10 +189,13 @@ internal static class CheckFireInputPatch }; private static readonly Dictionary Allowed = new(); + private static readonly Dictionary FireDelays = new(); private static readonly HashSet Reported = new(); private static float _nextShot; private static int _burstLeft; private static float _lastGunTime = -1f; + private static bool _triggerDown; + private static float _releasedFor; private static bool _loggedHook; internal static bool HoldingGun => _lastGunTime >= 0f && Time.time - _lastGunTime < 0.25f; @@ -202,7 +205,26 @@ internal static class CheckFireInputPatch _burstLeft = 0; } - internal static void StartBurst() + internal static void UpdateTrigger() + { + if (Input.GetMouseButton(0)) + { + _releasedFor = 0f; + if (_triggerDown) + return; + + _triggerDown = true; + if (FullAuto.Enabled && FullAuto.Mode == FireMode.Burst && HoldingGun && GameState.IsPlayerControllable) + StartBurst(); + return; + } + + _releasedFor += Time.unscaledDeltaTime; + if (_releasedFor >= ReleaseTime) + _triggerDown = false; + } + + private static void StartBurst() { if (_burstLeft > 0) return; @@ -234,13 +256,24 @@ internal static class CheckFireInputPatch if (FullAuto.Mode == FireMode.Semi) return true; + var held = Input.GetMouseButton(0); + if (!GameState.IsPlayerControllable) { CancelBurst(); - return true; + return !held; } - var held = Input.GetMouseButton(0); + if (__instance._isReloading || __instance.IsReloading()) + return Stop(); + + var weapon = __instance.GetRangedWeapon(); + if (!weapon) + return Stop(); + + var ammo = weapon.GetAmmo(); + if (ammo == null || ammo.GetRemainingAmmo() <= 0) + return Stop(); if (FullAuto.Mode == FireMode.Burst) { @@ -252,20 +285,9 @@ internal static class CheckFireInputPatch return true; } - if (__instance._isReloading || __instance.IsReloading()) - return Stop(); - if (__instance._mustAimToFire && !__instance.IsAiming) return Stop(); - var weapon = __instance.GetRangedWeapon(); - if (!weapon) - return Stop(); - - var ammo = weapon.GetAmmo(); - if (ammo == null || ammo.GetRemainingAmmo() <= 0) - return Stop(); - var now = Time.time; var interval = 60f / FullAuto.Rpm; @@ -287,6 +309,9 @@ internal static class CheckFireInputPatch shots++; } + if (FireDelays.TryGetValue(__instance.Pointer, out var delay)) + __instance._fireDelay = delay; + return false; } @@ -332,6 +357,8 @@ internal static class CheckFireInputPatch var name = controller.GetIl2CppType().Name; allowed = Guns.Contains(name); Allowed[ptr] = allowed; + if (allowed) + FireDelays[ptr] = controller._fireDelay; RLog.Msg($"FullAuto {name}: {(allowed ? "full-auto" : "ignored")}"); return allowed; } diff --git a/README.md b/README.md index 73223a2..7d36568 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,11 @@ With a gun equipped, click the middle mouse button to cycle fire modes: | Mode | Behavior | | --- | --- | -| Full-auto | Fires while the button is held | -| 3-round burst | Fires 3 shots per click | -| Semi-auto | Normal game behavior, one shot per click | +| Full-automatic | Fires while the button is held | +| Semi-automatic | Normal game behavior, one shot per click | +| 3-Round Burst | Fires 3 shots, then release and press again for the next 3 | -The mod starts in full-auto every time the game loads. +The mod starts in full-automatic every time the game loads. Press F1 to open the console, then use these commands: