From 6ce2c6bdf65142bfc585995113e166f95d4c87e1 Mon Sep 17 00:00:00 2001 From: Justin Oros Date: Thu, 17 Sep 2026 09:05:38 -0700 Subject: [PATCH] Remember fire mode per gun across restarts --- FullAuto.cs | 58 ++++++++++++++++++++++++++++++++++++++++++----------- README.md | 23 ++++++++++++++++++--- 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/FullAuto.cs b/FullAuto.cs index 8813e8a..49655ea 100644 --- a/FullAuto.cs +++ b/FullAuto.cs @@ -28,7 +28,14 @@ public class FullAuto : SonsMod internal static bool Enabled = true; internal static float Rpm = 900f; - internal static FireMode Mode = FireMode.Auto; + internal static readonly Dictionary Modes = new(); + internal static string CurrentGun = ""; + + internal static FireMode Mode + { + get => Modes.TryGetValue(CurrentGun, out var mode) ? mode : FireMode.Auto; + set => Modes[CurrentGun] = value; + } internal static bool FastReload; internal static KeyCode FlashlightKey = KeyCode.F; internal static bool Verbose; @@ -71,8 +78,9 @@ public class FullAuto : SonsMod _ => FireMode.Auto }; CheckFireInputPatch.CancelBurst(); + Save(); ShowMode(); - RLog.Msg($"FullAuto mode: {ModeName()}"); + RLog.Msg($"FullAuto {CurrentGun} mode: {ModeName()}"); } } @@ -184,6 +192,8 @@ public class FullAuto : SonsMod FastReload = fast; else if (key == "flashlightkey" && Enum.TryParse(val, true, out var flashKey)) FlashlightKey = flashKey; + else if (key.StartsWith("mode.") && Enum.TryParse(val, true, out var gunMode)) + Modes[key.Substring(5)] = gunMode; } } catch (Exception e) @@ -196,7 +206,16 @@ public class FullAuto : SonsMod { try { - File.WriteAllText(_configPath, $"rpm={Rpm}\nfastreload={FastReload.ToString().ToLowerInvariant()}\nflashlightkey={FlashlightKey}\n"); + var sb = new System.Text.StringBuilder(); + sb.Append($"rpm={Rpm}\n"); + sb.Append($"fastreload={FastReload.ToString().ToLowerInvariant()}\n"); + sb.Append($"flashlightkey={FlashlightKey}\n"); + foreach (var gun in CheckFireInputPatch.GunKeys) + { + var mode = Modes.TryGetValue(gun, out var m) ? m : FireMode.Auto; + sb.Append($"mode.{gun}={mode.ToString().ToLowerInvariant()}\n"); + } + File.WriteAllText(_configPath, sb.ToString()); } catch (Exception e) { @@ -212,14 +231,18 @@ internal static class CheckFireInputPatch private const int BurstSize = 3; private const float ReleaseTime = 0.15f; - private static readonly HashSet Guns = new() + private static readonly Dictionary Guns = new() { - "CompactPistolWeaponController", - "RevolverWeaponController", - "ShotgunWeaponController", - "RifleAnimatorController" + { "CompactPistolWeaponController", "pistol" }, + { "RevolverWeaponController", "revolver" }, + { "ShotgunWeaponController", "shotgun" }, + { "RifleAnimatorController", "rifle" } }; + internal static IEnumerable GunKeys => Guns.Values; + + private static readonly Dictionary GunNames = new(); + private static readonly Dictionary Allowed = new(); private static readonly Dictionary FireDelays = new(); private static readonly HashSet Reported = new(); @@ -511,8 +534,17 @@ internal static class CheckFireInputPatch UpdateReloadSpeed(__instance, allowed); - if (allowed && FullAuto.Enabled && (!HoldingGun || ptr != _lastGunPtr)) - FullAuto.ShowMode(); + if (allowed && GunNames.TryGetValue(ptr, out var gunName)) + { + var switched = !HoldingGun || ptr != _lastGunPtr; + FullAuto.CurrentGun = gunName; + if (switched) + { + CancelBurst(); + if (FullAuto.Enabled) + FullAuto.ShowMode(); + } + } if (allowed) _lastGunPtr = ptr; @@ -628,12 +660,14 @@ internal static class CheckFireInputPatch return allowed; var name = controller.GetIl2CppType().Name; - allowed = Guns.Contains(name); + allowed = Guns.TryGetValue(name, out var gunKey); Allowed[ptr] = allowed; if (allowed) + { FireDelays[ptr] = controller._fireDelay; + GunNames[ptr] = gunKey; + } RLog.Msg($"FullAuto {name}: {(allowed ? "full-auto" : "ignored")}"); return allowed; } } - diff --git a/README.md b/README.md index 7863488..a90955a 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,11 @@ With a gun equipped, click the middle mouse button to cycle fire modes: | 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-automatic every time the game loads. +Each gun remembers its own fire mode, even after you restart the game. Guns +start in full-automatic until you change them. + +Press F to turn a flashlight attached to your gun or crossbow on or off. +The key can be changed with the `flashlightkey=` line in `UserData\FullAuto.txt`. Press F1 to open the console, then use these commands: @@ -73,13 +77,14 @@ Press F1 to open the console, then use these commands: | `fullauto` | Show current settings | | `fullauto on` | Enable | | `fullauto off` | Disable until the game restarts | -| `fullauto toggle` | Switch between on and off | | `fullauto rpm 1200` | Set the fire rate, 60 to 3000 rounds per minute | +| `fullauto fastreload on` | Reload guns twice as fast, `off` to turn it back off | | `fullauto debug` | Log every shot to `_RedLoader\Latest.log` | The default is 900 rpm. The rpm also sets how fast burst shots fire. -The rpm is saved to `UserData\FullAuto.txt` in your game folder. +The rpm, fast reload, flashlight key and each gun's fire mode are saved to +`UserData\FullAuto.txt` in your game folder. ## Supported weapons @@ -89,5 +94,17 @@ behavior. ## Building from source +Requires the .NET 8 SDK and RedLoader installed with its game assemblies +generated. +```powershell +.\build.ps1 -Install +``` +Use `-Package` to build `FullAuto.zip` for a release. Pass `-GameDir "path"` if +the game is not found automatically. + +## Troubleshooting + +Check `_RedLoader\Latest.log` in your game folder. FullAuto logs a line when it loads and a line for each weapon showing whether it is full-auto or +ignored.