diff --git a/MiraAPI.Example/ExampleEventHandlers.cs b/MiraAPI.Example/ExampleEventHandlers.cs index 94f90ed..20c0def 100644 --- a/MiraAPI.Example/ExampleEventHandlers.cs +++ b/MiraAPI.Example/ExampleEventHandlers.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Globalization; +using System.Linq; using MiraAPI.Events; using MiraAPI.Events.Mira; using MiraAPI.Events.Vanilla.Gameplay; @@ -17,7 +18,7 @@ public static class ExampleEventHandlers { public static void Initialize() { - // You can register event handlers with the MiraEventManager class. + // You can register event handlers with the MiraEventManager class var handle = MiraEventManager.RegisterEventHandler(@event => { Logger.Info($"{@event.Source.Data.PlayerName} is about to kill {@event.Target.Data.PlayerName}"); @@ -37,6 +38,21 @@ public static class ExampleEventHandlers MiraEventManager.UnregisterEventHandler(handle); } + // If you want to check vanilla buttons, use something like this! + [RegisterEvent] + public static void VanillaButtonClickHandler(VanillaButtonClickEvent @event) + { + Logger.Info($"{@event.Button.buttonLabelText.text} is being used!"); + if (@event.PlayerTarget != null) + { + Logger.Info($"{@event.PlayerTarget.Data.PlayerName} is being targeted!"); + } + else if (@event.VentTarget != null) + { + Logger.Info($"Vent with id {@event.VentTarget.Id.ToString(CultureInfo.InvariantCulture)} is being targeted!"); + } + } + // If you want to add extra votes to a player, do something like this. [RegisterEvent] public static void StartMeetingEvent(StartMeetingEvent _) diff --git a/MiraAPI/Events/Vanilla/Gameplay/VanillaButtonCancelledEvent.cs b/MiraAPI/Events/Vanilla/Gameplay/VanillaButtonCancelledEvent.cs new file mode 100644 index 0000000..4265a3a --- /dev/null +++ b/MiraAPI/Events/Vanilla/Gameplay/VanillaButtonCancelledEvent.cs @@ -0,0 +1,44 @@ +using MiraAPI.Hud; + +namespace MiraAPI.Events.Vanilla.Gameplay; + +/// +/// Invoked when a Vanilla Button click is cancelled. Do not use for custom buttons. +/// +/// The Vanilla Button type. +public sealed class VanillaButtonCancelledEvent : MiraEvent where T : AbilityButton +{ + /// + /// Gets Vanilla Button whose click was cancelled. + /// + public T Button { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The Mira Button whose click was cancelled. + public VanillaButtonCancelledEvent(T button) + { + Button = button; + } +} + +/// +/// Invoked when a Vanilla Button click is cancelled. Do not use for custom buttons. +/// +public sealed class VanillaButtonCancelledEvent : MiraEvent +{ + /// + /// Gets Vanilla Button whose click was cancelled. + /// + public AbilityButton Button { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The Vanilla Button whose click was cancelled. + public VanillaButtonCancelledEvent(AbilityButton button) + { + Button = button; + } +} diff --git a/MiraAPI/Events/Vanilla/Gameplay/VanillaButtonClickEvent.cs b/MiraAPI/Events/Vanilla/Gameplay/VanillaButtonClickEvent.cs new file mode 100644 index 0000000..3da499b --- /dev/null +++ b/MiraAPI/Events/Vanilla/Gameplay/VanillaButtonClickEvent.cs @@ -0,0 +1,65 @@ +using MiraAPI.Hud; + +namespace MiraAPI.Events.Vanilla.Gameplay; + +/// +/// Button click event for Vanilla Buttons only. Do not use for custom buttons. +/// +/// The Vanilla Button type. +public sealed class VanillaButtonClickEvent : MiraCancelableEvent where T : AbilityButton +{ + /// + /// Gets Vanilla Button that was clicked. + /// + public T Button { get; } + + /// + /// Gets the generic click event that is invoked before this button-specific event. + /// + public VanillaButtonClickEvent GenericClickEvent { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The Mira Button that was clicked. + /// The generic click event invoked before button-specific events. + public VanillaButtonClickEvent(T button, VanillaButtonClickEvent genericClickEvent) + { + GenericClickEvent = genericClickEvent; + Button = button; + } +} + +/// +/// Button click event for Vanilla Buttons only. Do not use for custom buttons. +/// +public sealed class VanillaButtonClickEvent : MiraCancelableEvent +{ + /// + /// Gets Vanilla Button that was clicked. + /// + public AbilityButton Button { get; } + + /// + /// Gets the target player, if any, of the Vanilla Button that was clicked. + /// + public PlayerControl? PlayerTarget { get; } + + /// + /// Gets the target vent, if any, of the Vanilla Button that was clicked. + /// + public Vent? VentTarget { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The Vanilla Button that was clicked. + /// The Player target, if any. + /// The Vent target, if any. + public VanillaButtonClickEvent(AbilityButton button, PlayerControl? playerTarget = null, Vent? ventTarget = null) + { + Button = button; + PlayerTarget = playerTarget; + VentTarget = ventTarget; + } +} diff --git a/MiraAPI/Patches/Events/VanillaButtonPatches.cs b/MiraAPI/Patches/Events/VanillaButtonPatches.cs new file mode 100644 index 0000000..278de09 --- /dev/null +++ b/MiraAPI/Patches/Events/VanillaButtonPatches.cs @@ -0,0 +1,75 @@ +using System.Linq; +using AmongUs.GameOptions; +using HarmonyLib; +using MiraAPI.Events; +using MiraAPI.Events.Vanilla.Gameplay; +using MiraAPI.Events.Vanilla.Usables; + +namespace MiraAPI.Patches.Events; + +/// +/// Patches to invoke vent related MiraEvents. +/// +[HarmonyPatch] +public static class VanillaButtonPatches +{ + [HarmonyPrefix] + [HarmonyPatch(typeof(AbilityButton), nameof(AbilityButton.DoClick))] + public static bool DoClickPrefix(AbilityButton __instance) + { + // Invoke the generic button click event. + PlayerControl? playerTarget = null; + Vent? ventTarget = null; + var role = PlayerControl.LocalPlayer.Data.Role; + if (role.Role is RoleTypes.Tracker) + { + playerTarget = role.Cast().currentTarget; + } + else if (role.Role is RoleTypes.GuardianAngel) + { + playerTarget = role.Cast().currentTarget; + } + else if (role.Role is RoleTypes.Engineer) + { + ventTarget = role.Cast().currentTarget; + } + var genericEvent = new VanillaButtonClickEvent(__instance, playerTarget, ventTarget); + MiraEventManager.InvokeEvent(genericEvent); + if (genericEvent.IsCancelled) + { + MiraEventManager.InvokeEvent(new VanillaButtonCancelledEvent(__instance)); + } + + if (!genericEvent.IsCancelled) + { + return true; + } + + return false; + } + [HarmonyPrefix] + [HarmonyPatch(typeof(SecondaryAbilityButton), nameof(SecondaryAbilityButton.DoClick))] + public static bool SecondaryDoClickPrefix(AbilityButton __instance) + { + // Invoke the generic button click event. + PlayerControl? playerTarget = null; + var role = PlayerControl.LocalPlayer.Data.Role; + if (role.Role is RoleTypes.Detective) + { + playerTarget = role.Cast().currentTarget; + } + var genericEvent = new VanillaButtonClickEvent(__instance, playerTarget); + MiraEventManager.InvokeEvent(genericEvent); + if (genericEvent.IsCancelled) + { + MiraEventManager.InvokeEvent(new VanillaButtonCancelledEvent(__instance)); + } + + if (!genericEvent.IsCancelled) + { + return true; + } + + return false; + } +}