diff --git a/MiraAPI/Hud/CustomActionButton.cs b/MiraAPI/Hud/CustomActionButton.cs index b7d4085..6a886ba 100644 --- a/MiraAPI/Hud/CustomActionButton.cs +++ b/MiraAPI/Hud/CustomActionButton.cs @@ -8,6 +8,7 @@ using MiraAPI.Patches; using MiraAPI.Utilities; using MiraAPI.Utilities.Assets; using Reactor.Utilities; +using Rewired; using TMPro; using UnityEngine; using UnityEngine.Events; @@ -75,7 +76,7 @@ public abstract class CustomActionButton /// /// Gets the keybind for this button. If null, no keybind will be added. /// - public virtual MiraKeybind? Keybind => null; + public virtual BaseKeybind? Keybind => null; /// /// Gets the button's text outline color. @@ -494,7 +495,8 @@ public abstract class CustomActionButton { KeybindText.text = Keybind.CurrentKey.ToString(); KeybindIcon?.SetActive(ActiveInputManager.currentControlType == ActiveInputManager.InputType.Keyboard && - LocalSettingsTabSingleton.Instance.ShowKeybinds.Value); + LocalSettingsTabSingleton.Instance.ShowKeybinds.Value && + Keybind.CurrentKey != KeyboardKeyCode.None); } if (Timer >= 0) diff --git a/MiraAPI/Keybinds/BaseKeybind.cs b/MiraAPI/Keybinds/BaseKeybind.cs new file mode 100644 index 0000000..e4e6ac8 --- /dev/null +++ b/MiraAPI/Keybinds/BaseKeybind.cs @@ -0,0 +1,72 @@ +using System; +using Rewired; + +namespace MiraAPI.Keybinds; + +/// +/// Base keybind class. +/// +public class BaseKeybind +{ + /// + /// Gets the Rewired assinged for this keybind. + /// + public InputAction? RewiredInputAction { get; internal set; } + + /// + /// Gets the unique identifier for this keybind. Used in Rewired. + /// + public string Id { get; protected set; } + + /// + /// Gets the currently assigned keycode. + /// + public KeyboardKeyCode CurrentKey => KeybindUtils.GetKeycodeByKeybind(this); + + /// + /// Gets or sets the handler of the keybind. Invoked when the keybind is activated. + /// + protected Action Handler { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The unique identifier for this keybind. + public BaseKeybind(string id) + { + Id = id; + Handler = () => { }; + } + + public BaseKeybind() + { + Handler = () => { }; + } + + /// + /// Triggers the keybind, invoking its handler. + /// + public void Invoke() + { + Handler.Invoke(); + } + + /// + /// Adds an that will be invoked when the keybind is used. + /// + /// The to add. + public void OnActivate(Action action) + { + Handler += action; + } + + /// + /// Removes an that would be invoked when the keybind is used. + /// Not recommended to use - add checks in the method added in itself rather than removing it from the keybind. + /// + /// The to remove. + public void RemoveOnActivate(Action action) + { + Handler -= action; + } +} \ No newline at end of file diff --git a/MiraAPI/Keybinds/KeybindManager.cs b/MiraAPI/Keybinds/KeybindManager.cs index 57c87e7..ce212f0 100644 --- a/MiraAPI/Keybinds/KeybindManager.cs +++ b/MiraAPI/Keybinds/KeybindManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Il2CppInterop.Runtime.Attributes; using MiraAPI.Utilities; using Reactor.Utilities; using Rewired; @@ -17,6 +18,9 @@ public static class KeybindManager /// public static List Keybinds { get; } = new(); + [HideFromIl2Cpp] + internal static Dictionary VanillaKeybinds { get; set; } = []; + internal static void RewiredInit() { try diff --git a/MiraAPI/Keybinds/KeybindUtils.cs b/MiraAPI/Keybinds/KeybindUtils.cs index fbca1d6..f4371b3 100644 --- a/MiraAPI/Keybinds/KeybindUtils.cs +++ b/MiraAPI/Keybinds/KeybindUtils.cs @@ -18,11 +18,11 @@ public static class KeybindUtils /// /// The keybind to get the keycode from. /// The currently assigned keycode. - public static KeyboardKeyCode? GetKeycodeByKeybind(MiraKeybind keybind) + public static KeyboardKeyCode GetKeycodeByKeybind(BaseKeybind keybind) { if (keybind.RewiredInputAction == null) { - return null; + return KeyboardKeyCode.None; } return GetKeycodeByActionId(keybind.RewiredInputAction.id); @@ -34,10 +34,29 @@ public static class KeybindUtils /// The action ID. /// The keyboard keycode. public static KeyboardKeyCode GetKeycodeByActionId(int actionId) + { + return GetActionElementMap(actionId)?.keyboardKeyCode ?? KeyboardKeyCode.None; + } + + /// + /// Gets a by id with ReInput. + /// + /// The action ID. + /// The keyboard keycode. + public static ActionElementMap? GetActionElementMap(int actionId) { var player = ReInput.players.GetPlayer(0); - return player.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, actionId, false)? - .keyboardKeyCode ?? KeyboardKeyCode.None; + return player.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, actionId, false); + } + + /// + /// Gets an by id. + /// + /// The action identifier name. + /// The keyboard keycode. + public static InputAction? GetInputActionById(int id) + { + return RewiredInputManager?.userData?.GetActionById(id); } /// diff --git a/MiraAPI/Keybinds/MiraKeybind.cs b/MiraAPI/Keybinds/MiraKeybind.cs index 9007a0d..52d64a1 100644 --- a/MiraAPI/Keybinds/MiraKeybind.cs +++ b/MiraAPI/Keybinds/MiraKeybind.cs @@ -1,6 +1,4 @@ -using System; -using System.Globalization; -using Reactor.Utilities; +using System.Globalization; using Rewired; namespace MiraAPI.Keybinds; @@ -8,48 +6,28 @@ namespace MiraAPI.Keybinds; /// /// Represents a registered keybind. /// -public class MiraKeybind +public class MiraKeybind : BaseKeybind { /// /// Gets name of the keybind /// public string Name { get; } - /// - /// Gets the unique identifier for this keybind. Used in Rewired. - /// - public string Id { get; } - /// /// Gets the default keycode of this keybind. /// public KeyboardKeyCode DefaultKey { get; } /// - /// Gets a value indicating whether this keybind should be checked for conflicts with other exclusive keybinds using the same key. - /// - public bool Exclusive { get; } - - /// - /// Gets the modifier keys assinged to this keybind. + /// Gets the modifier keys assigned to this keybind. /// Due to Rewired limitations, there can only be 3 modifier keys. /// public ModifierKey[] ModifierKeys { get; } /// - /// Gets the Rewired assinged for this keybind. + /// Gets a value indicating whether this keybind should be checked for conflicts with other exclusive keybinds using the same key. /// - public InputAction? RewiredInputAction { get; internal set; } - - /// - /// Gets the currently assigned keycode. - /// - public KeyboardKeyCode CurrentKey => KeybindUtils.GetKeycodeByKeybind(this) ?? KeyboardKeyCode.None; - - /// - /// Gets or sets the handler of the keybind. Invoked when the keybind is activated. - /// - private Action Handler { get; set; } + public bool Exclusive { get; } internal string? SourcePluginName { get; set; } @@ -64,14 +42,12 @@ public class MiraKeybind string name, KeyboardKeyCode? defaultKeycode, ModifierKey[]? modifierKeys = null, - bool exclusive = true) + bool exclusive = true) : base(name.ToLower(CultureInfo.InvariantCulture).Replace(' ', '_')) { Name = name; - Id = name.ToLower(CultureInfo.InvariantCulture).Replace(' ', '_'); DefaultKey = defaultKeycode ?? KeyboardKeyCode.None; - ModifierKeys = modifierKeys ?? Array.Empty(); + ModifierKeys = modifierKeys ?? []; Exclusive = exclusive; - Handler = () => { }; } /// @@ -79,31 +55,4 @@ public class MiraKeybind { return $"{Name} ({Id})"; } - - /// - /// Triggers the keybind, invoking its handler. - /// - public void Invoke() - { - Handler.Invoke(); - } - - /// - /// Adds an that will be invoked when the keybind is used. - /// - /// The to add. - public void OnActivate(Action action) - { - Handler += action; - } - - /// - /// Removes an that would be invoked when the keybind is used. - /// Not recommended to use - add checks in the method added in itself rather than removing it from the keybind. - /// - /// The to remove. - public void RemoveOnActivate(Action action) - { - Handler -= action; - } } diff --git a/MiraAPI/Keybinds/VanillaKeybind.cs b/MiraAPI/Keybinds/VanillaKeybind.cs new file mode 100644 index 0000000..c04b83b --- /dev/null +++ b/MiraAPI/Keybinds/VanillaKeybind.cs @@ -0,0 +1,24 @@ +using Rewired; + +namespace MiraAPI.Keybinds; + +/// +/// Represents a vanilla keybind. +/// +public class VanillaKeybind : BaseKeybind +{ + /// + /// Gets the this keybind is binded to. + /// + public ActionButton? Button { get; internal set; } + + /// + /// Initializes a new instance of the class. + /// + /// The keybind id. + public VanillaKeybind(int id) + { + RewiredInputAction = KeybindUtils.GetInputActionById(id); + Id = RewiredInputAction?.name; + } +} diff --git a/MiraAPI/Keybinds/VanillaKeybindSingleton.cs b/MiraAPI/Keybinds/VanillaKeybindSingleton.cs new file mode 100644 index 0000000..980da77 --- /dev/null +++ b/MiraAPI/Keybinds/VanillaKeybindSingleton.cs @@ -0,0 +1,17 @@ +namespace MiraAPI.Keybinds; + +/// +/// Singleton for getting a vanilla keybind by . +/// +/// ActionButton type. +public static class VanillaKeybinding where T : ActionButton +{ + private static VanillaKeybind? _instance; + + /// + /// Gets the instance of the option group. + /// +#pragma warning disable CA1000 + public static VanillaKeybind Instance => _instance ??= KeybindManager.VanillaKeybinds[typeof(T)]; +#pragma warning restore CA1000 +} diff --git a/MiraAPI/Patches/HudManagerPatches.cs b/MiraAPI/Patches/HudManagerPatches.cs index 09ee13e..54e7fae 100644 --- a/MiraAPI/Patches/HudManagerPatches.cs +++ b/MiraAPI/Patches/HudManagerPatches.cs @@ -99,7 +99,6 @@ public static class HudManagerPatches gridArrange.Start(); gridArrange.ArrangeChilds(); - aspectPosition.AdjustPosition(); vanillaKeybindIcons = []; @@ -111,6 +110,7 @@ public static class HudManagerPatches { __instance.ReportButton.gameObject, 7 }, { __instance.ImpostorVentButton.gameObject, 50 }, { __instance.SabotageButton.gameObject, 4 }, + { __instance.AbilityButton.gameObject, 49 }, }; foreach (var kvp in vanillaButtons) @@ -125,6 +125,8 @@ public static class HudManagerPatches } var icon = Helpers.CreateKeybindIcon(buttonObj, key, keybindIconPos); vanillaKeybindIcons.Add(icon.transform.GetChild(0).GetComponent(), actionId); + var comp = buttonObj.GetComponent(); + KeybindManager.VanillaKeybinds[comp.GetType()].Button = comp; } } @@ -169,11 +171,10 @@ public static class HudManagerPatches LocalSettingsTabSingleton.Instance.ShowKeybinds.Value); } + var player = ReInput.players.GetPlayer(0); foreach (var entry in KeybindManager.Keybinds) { - var player = ReInput.players.GetPlayer(0); var keyboard = player.controllers.Keyboard; - bool modifierKeysPressed = entry.ModifierKeys.All(k => keyboard.GetModifierKey(k)) || entry.ModifierKeys.Length <= 0; if (player.GetButtonDown(entry.Id) && modifierKeysPressed) @@ -181,5 +182,12 @@ public static class HudManagerPatches entry.Invoke(); } } + foreach (var entry in KeybindManager.VanillaKeybinds.Values) + { + if (player.GetButtonDown(entry.Id)) + { + entry.Invoke(); + } + } } } diff --git a/MiraAPI/Patches/Keybinds/KeybindsPatch.cs b/MiraAPI/Patches/Keybinds/KeybindsPatch.cs index 1f60df0..c08a47f 100644 --- a/MiraAPI/Patches/Keybinds/KeybindsPatch.cs +++ b/MiraAPI/Patches/Keybinds/KeybindsPatch.cs @@ -1,5 +1,6 @@ using HarmonyLib; using MiraAPI.Keybinds; +using MonoMod.Utils; using Rewired; namespace MiraAPI.Patches.Keybinds; @@ -20,5 +21,16 @@ public static class KeybindMenuPatch KeybindUtils.RewiredInputManager = __instance; KeybindManager.RewiredInit(); _registered = true; + + // Set these here right after input manager initializes + KeybindManager.VanillaKeybinds = new() + { + { typeof(KillButton), new VanillaKeybind(8) }, + { typeof(UseButton), new VanillaKeybind(6) }, + { typeof(ReportButton), new VanillaKeybind(7) }, + { typeof(VentButton), new VanillaKeybind(50) }, + { typeof(SabotageButton), new VanillaKeybind(4) }, + { typeof(AbilityButton), new VanillaKeybind(49) }, + }; } }