From 7042c6e64607cb8da32693adc924a57e7d10bc2c Mon Sep 17 00:00:00 2001 From: ang-xd Date: Sun, 9 Feb 2025 16:42:09 -0500 Subject: [PATCH] New events & extensions --- MiraAPI.Example/ExampleEventHandlers.cs | 26 ++++++---- .../Events/Vanilla/AdminButtonClickEvent.cs | 24 ---------- .../{ => Gameplay}/AfterMurderEvent.cs | 2 +- .../{ => Gameplay}/BeforeMurderEvent.cs | 2 +- .../Events/Vanilla/Gameplay/GameEndEvent.cs | 21 ++++++++ .../{Player => Gameplay}/IntroBeginEvent.cs | 6 +-- .../Vanilla/{ => Map}/CloseDoorsEvent.cs | 2 +- .../Vanilla/{ => Map}/UpdateSystemEvent.cs | 2 +- .../Vanilla/Player/CompleteTaskEvent.cs | 28 +++++++++++ .../Events/Vanilla/Player/PlayerDeathEvent.cs | 28 +++++++++++ .../Events/Vanilla/Player/PlayerJoinEvent.cs | 23 +++++++++ .../Events/Vanilla/Player/PlayerLeaveEvent.cs | 30 ++++++++++++ .../Vanilla/SabotageButtonClickEvent.cs | 24 ---------- .../Vanilla/{ => Usables}/EnterVentEvent.cs | 2 +- .../Vanilla/{ => Usables}/ExitVentEvent.cs | 2 +- MiraAPI/Events/Vanilla/UseButtonClickEvent.cs | 24 ---------- .../Events/Vanilla/VentButtonClickEvent.cs | 21 -------- MiraAPI/Hud/CustomActionButton.cs | 9 ++++ MiraAPI/Networking/CustomMurderRpc.cs | 9 ++-- MiraAPI/Patches/AmongUsClientSyncPatch.cs | 19 +++++++- MiraAPI/Patches/Events/EndGamePatches.cs | 20 ++++++++ .../Patches/Events/HudButtonEventPatches.cs | 48 ------------------- .../Patches/Events/KillAnimationPatches.cs | 25 ++++++++++ .../Patches/Events/SabotageEventPatches.cs | 2 +- MiraAPI/Patches/Events/VentEventPatches.cs | 2 +- MiraAPI/Patches/IntroCutscenePatches.cs | 2 +- MiraAPI/Patches/PlayerControlPatches.cs | 42 +++++++++++++++- MiraAPI/PluginLoading/MiraPluginManager.cs | 10 ++-- MiraAPI/Utilities/Extensions.cs | 26 ++++++++++ 29 files changed, 305 insertions(+), 176 deletions(-) delete mode 100644 MiraAPI/Events/Vanilla/AdminButtonClickEvent.cs rename MiraAPI/Events/Vanilla/{ => Gameplay}/AfterMurderEvent.cs (94%) rename MiraAPI/Events/Vanilla/{ => Gameplay}/BeforeMurderEvent.cs (94%) create mode 100644 MiraAPI/Events/Vanilla/Gameplay/GameEndEvent.cs rename MiraAPI/Events/Vanilla/{Player => Gameplay}/IntroBeginEvent.cs (79%) rename MiraAPI/Events/Vanilla/{ => Map}/CloseDoorsEvent.cs (92%) rename MiraAPI/Events/Vanilla/{ => Map}/UpdateSystemEvent.cs (96%) create mode 100644 MiraAPI/Events/Vanilla/Player/CompleteTaskEvent.cs create mode 100644 MiraAPI/Events/Vanilla/Player/PlayerDeathEvent.cs create mode 100644 MiraAPI/Events/Vanilla/Player/PlayerJoinEvent.cs create mode 100644 MiraAPI/Events/Vanilla/Player/PlayerLeaveEvent.cs delete mode 100644 MiraAPI/Events/Vanilla/SabotageButtonClickEvent.cs rename MiraAPI/Events/Vanilla/{ => Usables}/EnterVentEvent.cs (94%) rename MiraAPI/Events/Vanilla/{ => Usables}/ExitVentEvent.cs (94%) delete mode 100644 MiraAPI/Events/Vanilla/UseButtonClickEvent.cs delete mode 100644 MiraAPI/Events/Vanilla/VentButtonClickEvent.cs create mode 100644 MiraAPI/Patches/Events/EndGamePatches.cs delete mode 100644 MiraAPI/Patches/Events/HudButtonEventPatches.cs create mode 100644 MiraAPI/Patches/Events/KillAnimationPatches.cs diff --git a/MiraAPI.Example/ExampleEventHandlers.cs b/MiraAPI.Example/ExampleEventHandlers.cs index 9d18bc1..e196b28 100644 --- a/MiraAPI.Example/ExampleEventHandlers.cs +++ b/MiraAPI.Example/ExampleEventHandlers.cs @@ -1,7 +1,8 @@ using MiraAPI.Events; using MiraAPI.Events.Mira; -using MiraAPI.Events.Vanilla; -using MiraAPI.Events.Vanilla.Usables; +using MiraAPI.Events.Vanilla.Gameplay; +using MiraAPI.Events.Vanilla.Map; +using MiraAPI.Events.Vanilla.Player; using MiraAPI.Example.Buttons.Freezer; using Reactor.Utilities; @@ -15,16 +16,21 @@ public static class ExampleEventHandlers MiraEventManager.RegisterEventHandler>(FreezeButtonClickHandler, 1); MiraEventManager.RegisterEventHandler>(FreezeButtonCancelledHandler); MiraEventManager.RegisterEventHandler(UpdateSystemEventHandler); - MiraEventManager.RegisterEventHandler(PlayerControlCanUse); - MiraEventManager.RegisterEventHandler(PlayerControlUse); - } - public static void PlayerControlCanUse(PlayerCanUseEvent @event) - { - } + MiraEventManager.RegisterEventHandler(@event => + { + Logger.Info($"{@event.Source.Data.PlayerName} is about to kill {@event.Target.Data.PlayerName}"); + }); - public static void PlayerControlUse(PlayerUseEvent @event) - { + MiraEventManager.RegisterEventHandler(@event => + { + Logger.Info($"{@event.Source.Data.PlayerName} has killed {@event.Target.Data.PlayerName}"); + }); + + MiraEventManager.RegisterEventHandler(@event => + { + Logger.Info($"{@event.Player.Data.PlayerName} completed {@event.Task.TaskType.ToString()}"); + }); } public static void UpdateSystemEventHandler(UpdateSystemEvent @event) diff --git a/MiraAPI/Events/Vanilla/AdminButtonClickEvent.cs b/MiraAPI/Events/Vanilla/AdminButtonClickEvent.cs deleted file mode 100644 index de02bb9..0000000 --- a/MiraAPI/Events/Vanilla/AdminButtonClickEvent.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace MiraAPI.Events.Vanilla; - -/// -/// Button click event for from Vanilla Among Us. -/// -[Obsolete("This class is deprecated. Use PlayerUseEvent instead.")] -public class AdminButtonClickEvent : MiraCancelableEvent -{ - /// - /// Gets the instance of that was clicked. - /// - public AdminButton Button { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The AdminButton. - public AdminButtonClickEvent(AdminButton button) - { - Button = button; - } -} diff --git a/MiraAPI/Events/Vanilla/AfterMurderEvent.cs b/MiraAPI/Events/Vanilla/Gameplay/AfterMurderEvent.cs similarity index 94% rename from MiraAPI/Events/Vanilla/AfterMurderEvent.cs rename to MiraAPI/Events/Vanilla/Gameplay/AfterMurderEvent.cs index a425cd2..fcf9df4 100644 --- a/MiraAPI/Events/Vanilla/AfterMurderEvent.cs +++ b/MiraAPI/Events/Vanilla/Gameplay/AfterMurderEvent.cs @@ -1,4 +1,4 @@ -namespace MiraAPI.Events.Vanilla; +namespace MiraAPI.Events.Vanilla.Gameplay; /// /// Event that is invoked after a player is murdered. Only called after a successful murder. This event is not cancelable. diff --git a/MiraAPI/Events/Vanilla/BeforeMurderEvent.cs b/MiraAPI/Events/Vanilla/Gameplay/BeforeMurderEvent.cs similarity index 94% rename from MiraAPI/Events/Vanilla/BeforeMurderEvent.cs rename to MiraAPI/Events/Vanilla/Gameplay/BeforeMurderEvent.cs index f4f2be3..82694f7 100644 --- a/MiraAPI/Events/Vanilla/BeforeMurderEvent.cs +++ b/MiraAPI/Events/Vanilla/Gameplay/BeforeMurderEvent.cs @@ -1,4 +1,4 @@ -namespace MiraAPI.Events.Vanilla; +namespace MiraAPI.Events.Vanilla.Gameplay; /// /// Event that is invoked before a player is murdered. This event is cancelable. diff --git a/MiraAPI/Events/Vanilla/Gameplay/GameEndEvent.cs b/MiraAPI/Events/Vanilla/Gameplay/GameEndEvent.cs new file mode 100644 index 0000000..1f06533 --- /dev/null +++ b/MiraAPI/Events/Vanilla/Gameplay/GameEndEvent.cs @@ -0,0 +1,21 @@ +namespace MiraAPI.Events.Vanilla.Gameplay; + +/// +/// The event that is invoked when the end game screen is shown. Non cancelable. +/// +public class GameEndEvent : MiraEvent +{ + /// + /// Gets the instance of the EndGameManager. + /// + public EndGameManager EndGameManager { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The instance of the EndGameManager. + public GameEndEvent(EndGameManager manager) + { + EndGameManager = manager; + } +} diff --git a/MiraAPI/Events/Vanilla/Player/IntroBeginEvent.cs b/MiraAPI/Events/Vanilla/Gameplay/IntroBeginEvent.cs similarity index 79% rename from MiraAPI/Events/Vanilla/Player/IntroBeginEvent.cs rename to MiraAPI/Events/Vanilla/Gameplay/IntroBeginEvent.cs index 817f6e7..5d5e8d8 100644 --- a/MiraAPI/Events/Vanilla/Player/IntroBeginEvent.cs +++ b/MiraAPI/Events/Vanilla/Gameplay/IntroBeginEvent.cs @@ -1,7 +1,7 @@ -namespace MiraAPI.Events.Vanilla.Meeting; +namespace MiraAPI.Events.Vanilla.Gameplay; /// -/// The event that is invoked when the intro cutscene is shown. Non cancellable. +/// The event that is invoked when the intro cutscene is shown. Non cancelable. /// public class IntroBeginEvent : MiraEvent { @@ -13,7 +13,7 @@ public class IntroBeginEvent : MiraEvent /// /// Initializes a new instance of the class. /// - /// The exile controller. + /// The intro cutscene. public IntroBeginEvent(IntroCutscene introCutscene) { IntroCutscene = introCutscene; diff --git a/MiraAPI/Events/Vanilla/CloseDoorsEvent.cs b/MiraAPI/Events/Vanilla/Map/CloseDoorsEvent.cs similarity index 92% rename from MiraAPI/Events/Vanilla/CloseDoorsEvent.cs rename to MiraAPI/Events/Vanilla/Map/CloseDoorsEvent.cs index 8d0b9bf..86f2bfd 100644 --- a/MiraAPI/Events/Vanilla/CloseDoorsEvent.cs +++ b/MiraAPI/Events/Vanilla/Map/CloseDoorsEvent.cs @@ -1,4 +1,4 @@ -namespace MiraAPI.Events.Vanilla; +namespace MiraAPI.Events.Vanilla.Map; /// /// Event fired when a player closes the doors in a room. diff --git a/MiraAPI/Events/Vanilla/UpdateSystemEvent.cs b/MiraAPI/Events/Vanilla/Map/UpdateSystemEvent.cs similarity index 96% rename from MiraAPI/Events/Vanilla/UpdateSystemEvent.cs rename to MiraAPI/Events/Vanilla/Map/UpdateSystemEvent.cs index 1ac8bda..6b6d907 100644 --- a/MiraAPI/Events/Vanilla/UpdateSystemEvent.cs +++ b/MiraAPI/Events/Vanilla/Map/UpdateSystemEvent.cs @@ -1,4 +1,4 @@ -namespace MiraAPI.Events.Vanilla; +namespace MiraAPI.Events.Vanilla.Map; /// /// Cancelable event that is invoked before a system is updated. Usually used for sabotage events. diff --git a/MiraAPI/Events/Vanilla/Player/CompleteTaskEvent.cs b/MiraAPI/Events/Vanilla/Player/CompleteTaskEvent.cs new file mode 100644 index 0000000..31fd9d4 --- /dev/null +++ b/MiraAPI/Events/Vanilla/Player/CompleteTaskEvent.cs @@ -0,0 +1,28 @@ +namespace MiraAPI.Events.Vanilla.Player; + +/// +/// The event that is invoked when a player completes a task. Non cancelable. +/// +public class CompleteTaskEvent : MiraEvent +{ + /// + /// Gets the instance of the . + /// + public PlayerControl Player { get; } + + /// + /// Gets the instance of the that the player completed. + /// + public PlayerTask Task { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The player who completed the task. + /// The task that the player completed. + public CompleteTaskEvent(PlayerControl player, PlayerTask task) + { + Player = player; + Task = task; + } +} diff --git a/MiraAPI/Events/Vanilla/Player/PlayerDeathEvent.cs b/MiraAPI/Events/Vanilla/Player/PlayerDeathEvent.cs new file mode 100644 index 0000000..e787b13 --- /dev/null +++ b/MiraAPI/Events/Vanilla/Player/PlayerDeathEvent.cs @@ -0,0 +1,28 @@ +namespace MiraAPI.Events.Vanilla.Player; + +/// +/// Event that is invoked when a player dies. Non cancelable. +/// +public class PlayerDeathEvent : MiraEvent +{ + /// + /// Gets the player who died. + /// + public PlayerControl Player { get; } + + /// + /// Gets the reason the player died. + /// + public DeathReason DeathReason { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The player who died. + /// The reason the player died. + public PlayerDeathEvent(PlayerControl player, DeathReason reason) + { + Player = player; + DeathReason = reason; + } +} diff --git a/MiraAPI/Events/Vanilla/Player/PlayerJoinEvent.cs b/MiraAPI/Events/Vanilla/Player/PlayerJoinEvent.cs new file mode 100644 index 0000000..ba9bfb5 --- /dev/null +++ b/MiraAPI/Events/Vanilla/Player/PlayerJoinEvent.cs @@ -0,0 +1,23 @@ +using InnerNet; + +namespace MiraAPI.Events.Vanilla.Player; + +/// +/// Event that is invoked when a player joins the lobby. Non cancelable. +/// +public class PlayerJoinEvent : MiraEvent +{ + /// + /// Gets the player who joined. + /// + public ClientData ClientData { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The data of the player who joined. + public PlayerJoinEvent(ClientData data) + { + ClientData = data; + } +} diff --git a/MiraAPI/Events/Vanilla/Player/PlayerLeaveEvent.cs b/MiraAPI/Events/Vanilla/Player/PlayerLeaveEvent.cs new file mode 100644 index 0000000..4607305 --- /dev/null +++ b/MiraAPI/Events/Vanilla/Player/PlayerLeaveEvent.cs @@ -0,0 +1,30 @@ +using InnerNet; + +namespace MiraAPI.Events.Vanilla.Player; + +/// +/// Event that is invoked when a player leaves the game. Non cancelable. +/// +public class PlayerLeaveEvent : MiraEvent +{ + /// + /// Gets the player who left. + /// + public ClientData ClientData { get; } + + /// + /// Gets the reason why the player left. + /// + public DisconnectReasons Reason { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The data of the player who left. + /// The reason why the player left. + public PlayerLeaveEvent(ClientData data, DisconnectReasons reason) + { + ClientData = data; + Reason = reason; + } +} diff --git a/MiraAPI/Events/Vanilla/SabotageButtonClickEvent.cs b/MiraAPI/Events/Vanilla/SabotageButtonClickEvent.cs deleted file mode 100644 index 9d3d2ba..0000000 --- a/MiraAPI/Events/Vanilla/SabotageButtonClickEvent.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace MiraAPI.Events.Vanilla; - -/// -/// Button click event for from Vanilla Among Us. -/// -[Obsolete("This class is deprecated. Use PlayerOpenSabotageEvent instead.")] -public class SabotageButtonClickEvent : MiraCancelableEvent -{ - /// - /// Gets the instance of that was clicked. - /// - public SabotageButton Button { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The SabotageButton. - public SabotageButtonClickEvent(SabotageButton button) - { - Button = button; - } -} diff --git a/MiraAPI/Events/Vanilla/EnterVentEvent.cs b/MiraAPI/Events/Vanilla/Usables/EnterVentEvent.cs similarity index 94% rename from MiraAPI/Events/Vanilla/EnterVentEvent.cs rename to MiraAPI/Events/Vanilla/Usables/EnterVentEvent.cs index 63e872c..ce3b3ca 100644 --- a/MiraAPI/Events/Vanilla/EnterVentEvent.cs +++ b/MiraAPI/Events/Vanilla/Usables/EnterVentEvent.cs @@ -1,4 +1,4 @@ -namespace MiraAPI.Events.Vanilla; +namespace MiraAPI.Events.Vanilla.Usables; /// /// Event that is invoked when a player enters a vent. This event is cancelable. diff --git a/MiraAPI/Events/Vanilla/ExitVentEvent.cs b/MiraAPI/Events/Vanilla/Usables/ExitVentEvent.cs similarity index 94% rename from MiraAPI/Events/Vanilla/ExitVentEvent.cs rename to MiraAPI/Events/Vanilla/Usables/ExitVentEvent.cs index 1269b8a..351411f 100644 --- a/MiraAPI/Events/Vanilla/ExitVentEvent.cs +++ b/MiraAPI/Events/Vanilla/Usables/ExitVentEvent.cs @@ -1,4 +1,4 @@ -namespace MiraAPI.Events.Vanilla; +namespace MiraAPI.Events.Vanilla.Usables; /// /// Event that is invoked when a player exits a vent. This event is cancelable. diff --git a/MiraAPI/Events/Vanilla/UseButtonClickEvent.cs b/MiraAPI/Events/Vanilla/UseButtonClickEvent.cs deleted file mode 100644 index 8b859fb..0000000 --- a/MiraAPI/Events/Vanilla/UseButtonClickEvent.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace MiraAPI.Events.Vanilla; - -/// -/// Button click event for from Vanilla Among Us. -/// -[Obsolete("This class is deprecated. Use PlayerUseEvent instead.")] -public class UseButtonClickEvent : MiraCancelableEvent -{ - /// - /// Gets the instance of that was clicked. - /// - public UseButton Button { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The UseButton. - public UseButtonClickEvent(UseButton button) - { - Button = button; - } -} diff --git a/MiraAPI/Events/Vanilla/VentButtonClickEvent.cs b/MiraAPI/Events/Vanilla/VentButtonClickEvent.cs deleted file mode 100644 index a46601f..0000000 --- a/MiraAPI/Events/Vanilla/VentButtonClickEvent.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace MiraAPI.Events.Vanilla; - -/// -/// Button click event for from Vanilla Among Us. -/// -public class VentButtonClickEvent : MiraCancelableEvent -{ - /// - /// Gets the instance of that was clicked. - /// - public VentButton Button { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The VentButton. - public VentButtonClickEvent(VentButton button) - { - Button = button; - } -} diff --git a/MiraAPI/Hud/CustomActionButton.cs b/MiraAPI/Hud/CustomActionButton.cs index fcefc95..f37f2eb 100644 --- a/MiraAPI/Hud/CustomActionButton.cs +++ b/MiraAPI/Hud/CustomActionButton.cs @@ -445,4 +445,13 @@ public abstract class CustomActionButton : CustomActionButton where T : MonoB return base.CanUse() && Target != null; } + + /// + /// Use this to reset the button's target after used. + /// + public virtual void ResetTarget() + { + Target = null; + SetOutline(false); + } } diff --git a/MiraAPI/Networking/CustomMurderRpc.cs b/MiraAPI/Networking/CustomMurderRpc.cs index e28ddf2..252ac91 100644 --- a/MiraAPI/Networking/CustomMurderRpc.cs +++ b/MiraAPI/Networking/CustomMurderRpc.cs @@ -1,14 +1,14 @@ -using System.Collections; -using System.Linq; -using AmongUs.GameOptions; +using AmongUs.GameOptions; using Assets.CoreScripts; using BepInEx.Unity.IL2CPP.Utils; using MiraAPI.Events; -using MiraAPI.Events.Vanilla; +using MiraAPI.Events.Vanilla.Gameplay; using Reactor.Networking.Attributes; using Reactor.Networking.Rpc; using Reactor.Utilities; using Reactor.Utilities.Extensions; +using System.Collections; +using System.Linq; using UnityEngine; namespace MiraAPI.Networking; @@ -84,7 +84,6 @@ public static class CustomMurderRpc bool playKillSound = true) { source.isKilling = false; - Logger.Error($"{source.PlayerId} trying to murder {target.PlayerId}"); var data = target.Data; if (resultFlags.HasFlag(MurderResultFlags.FailedError)) { diff --git a/MiraAPI/Patches/AmongUsClientSyncPatch.cs b/MiraAPI/Patches/AmongUsClientSyncPatch.cs index 3034b42..4a76283 100644 --- a/MiraAPI/Patches/AmongUsClientSyncPatch.cs +++ b/MiraAPI/Patches/AmongUsClientSyncPatch.cs @@ -1,5 +1,7 @@ using HarmonyLib; using InnerNet; +using MiraAPI.Events; +using MiraAPI.Events.Vanilla.Player; using MiraAPI.GameOptions; using MiraAPI.Modifiers; using MiraAPI.Roles; @@ -9,11 +11,16 @@ namespace MiraAPI.Patches; /// /// Sync all options, role settings, and modifiers to the player when they join the game. /// -[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.CreatePlayer))] +[HarmonyPatch(typeof(AmongUsClient))] public static class AmongUsClientSyncPatch { - public static void Postfix(ClientData clientData) + [HarmonyPostfix] + [HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.CreatePlayer))] + public static void CreatePlayerPatch(ClientData clientData) { + var joinEvent = new PlayerJoinEvent(clientData); + MiraEventManager.InvokeEvent(joinEvent); + if (!AmongUsClient.Instance.AmHost) { return; @@ -28,4 +35,12 @@ public static class AmongUsClientSyncPatch CustomRoleManager.SyncAllRoleSettings(clientData.Id); ModifierManager.SyncAllModifiers(clientData.Id); } + + [HarmonyPostfix] + [HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnPlayerLeft))] + public static void PlayerLeftPatch(ClientData data, DisconnectReasons reason) + { + var leftEvent = new PlayerLeaveEvent(data, reason); + MiraEventManager.InvokeEvent(leftEvent); + } } diff --git a/MiraAPI/Patches/Events/EndGamePatches.cs b/MiraAPI/Patches/Events/EndGamePatches.cs new file mode 100644 index 0000000..4f7118b --- /dev/null +++ b/MiraAPI/Patches/Events/EndGamePatches.cs @@ -0,0 +1,20 @@ +using HarmonyLib; +using MiraAPI.Events; +using MiraAPI.Events.Vanilla.Gameplay; + +namespace MiraAPI.Patches.Events; + +/// +/// Patch for trigging the GameEndEvent. +/// +[HarmonyPatch] +public static class EndGamePatches +{ + [HarmonyPostfix] + [HarmonyPatch(typeof(EndGameManager), nameof(EndGameManager.SetEverythingUp))] + public static void SetEverythingUpPatch(EndGameManager __instance) + { + var @event = new GameEndEvent(__instance); + MiraEventManager.InvokeEvent(@event); + } +} diff --git a/MiraAPI/Patches/Events/HudButtonEventPatches.cs b/MiraAPI/Patches/Events/HudButtonEventPatches.cs deleted file mode 100644 index 42dde11..0000000 --- a/MiraAPI/Patches/Events/HudButtonEventPatches.cs +++ /dev/null @@ -1,48 +0,0 @@ -using HarmonyLib; -using MiraAPI.Events; -using MiraAPI.Events.Vanilla; - -namespace MiraAPI.Patches.Events; - -/// -/// Patch for button related MiraEvents. -/// -[HarmonyPatch] -public static class HudButtonEventPatches -{ - [HarmonyPrefix] - [HarmonyPatch(typeof(AdminButton), nameof(AdminButton.DoClick))] - public static bool AdminButtonDoClickPrefix(AdminButton __instance) - { - var @event = new AdminButtonClickEvent(__instance); - MiraEventManager.InvokeEvent(@event); - return !@event.IsCancelled; - } - - [HarmonyPrefix] - [HarmonyPatch(typeof(SabotageButton), nameof(SabotageButton.DoClick))] - public static bool SabotageButtonDoClickPrefix(SabotageButton __instance) - { - var @event = new SabotageButtonClickEvent(__instance); - MiraEventManager.InvokeEvent(@event); - return !@event.IsCancelled; - } - - [HarmonyPrefix] - [HarmonyPatch(typeof(UseButton), nameof(UseButton.DoClick))] - public static bool UseButtonDoClickPrefix(UseButton __instance) - { - var @event = new UseButtonClickEvent(__instance); - MiraEventManager.InvokeEvent(@event); - return !@event.IsCancelled; - } - - [HarmonyPrefix] - [HarmonyPatch(typeof(VentButton), nameof(VentButton.DoClick))] - public static bool VentButtonDoClickPrefix(VentButton __instance) - { - var @event = new VentButtonClickEvent(__instance); - MiraEventManager.InvokeEvent(@event); - return !@event.IsCancelled; - } -} diff --git a/MiraAPI/Patches/Events/KillAnimationPatches.cs b/MiraAPI/Patches/Events/KillAnimationPatches.cs new file mode 100644 index 0000000..13b4cff --- /dev/null +++ b/MiraAPI/Patches/Events/KillAnimationPatches.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using MiraAPI.Events; +using MiraAPI.Events.Vanilla.Gameplay; + +namespace MiraAPI.Patches; + +/// +/// General patches for the KillAnimation class. +/// +[HarmonyPatch] +public static class KillAnimationPatches +{ + /// + /// Used to trigger the . + /// + /// The killer. + /// The target. + [HarmonyPostfix] + [HarmonyPatch(typeof(KillAnimation), nameof(KillAnimation.CoPerformKill))] + public static void KillAnimPostfix(PlayerControl source, PlayerControl target) + { + var afterMurderEvent = new AfterMurderEvent(source, target); + MiraEventManager.InvokeEvent(afterMurderEvent); + } +} diff --git a/MiraAPI/Patches/Events/SabotageEventPatches.cs b/MiraAPI/Patches/Events/SabotageEventPatches.cs index b8a1fd2..4f04d7e 100644 --- a/MiraAPI/Patches/Events/SabotageEventPatches.cs +++ b/MiraAPI/Patches/Events/SabotageEventPatches.cs @@ -1,6 +1,6 @@ using HarmonyLib; using MiraAPI.Events; -using MiraAPI.Events.Vanilla; +using MiraAPI.Events.Vanilla.Map; namespace MiraAPI.Patches.Events; diff --git a/MiraAPI/Patches/Events/VentEventPatches.cs b/MiraAPI/Patches/Events/VentEventPatches.cs index e8e5661..0b1b1cd 100644 --- a/MiraAPI/Patches/Events/VentEventPatches.cs +++ b/MiraAPI/Patches/Events/VentEventPatches.cs @@ -1,6 +1,6 @@ using HarmonyLib; using MiraAPI.Events; -using MiraAPI.Events.Vanilla; +using MiraAPI.Events.Vanilla.Usables; using System.Linq; namespace MiraAPI.Patches.Events; diff --git a/MiraAPI/Patches/IntroCutscenePatches.cs b/MiraAPI/Patches/IntroCutscenePatches.cs index 03cc403..297ce94 100644 --- a/MiraAPI/Patches/IntroCutscenePatches.cs +++ b/MiraAPI/Patches/IntroCutscenePatches.cs @@ -1,6 +1,6 @@ using HarmonyLib; using MiraAPI.Events; -using MiraAPI.Events.Vanilla.Meeting; +using MiraAPI.Events.Vanilla.Gameplay; using MiraAPI.Roles; using MiraAPI.Utilities; using UnityEngine; diff --git a/MiraAPI/Patches/PlayerControlPatches.cs b/MiraAPI/Patches/PlayerControlPatches.cs index bc98a51..c7918fe 100644 --- a/MiraAPI/Patches/PlayerControlPatches.cs +++ b/MiraAPI/Patches/PlayerControlPatches.cs @@ -1,8 +1,12 @@ using HarmonyLib; +using MiraAPI.Events; +using MiraAPI.Events.Vanilla.Gameplay; +using MiraAPI.Events.Vanilla.Player; using MiraAPI.Hud; using MiraAPI.Modifiers; using MiraAPI.Roles; using Reactor.Utilities.Extensions; +using System.Linq; namespace MiraAPI.Patches; @@ -36,14 +40,50 @@ public static class PlayerControlPatches [HarmonyPatch(nameof(PlayerControl.Die))] public static void PlayerControlDiePostfix(PlayerControl __instance, DeathReason reason) { + var deathEvent = new PlayerDeathEvent(__instance, reason); + MiraEventManager.InvokeEvent(deathEvent); + var modifiersComponent = __instance.GetComponent(); if (modifiersComponent) { - modifiersComponent.ActiveModifiers.ForEach(x=>x.OnDeath(reason)); + modifiersComponent.ActiveModifiers.ForEach(x => x.OnDeath(reason)); } } + /// + /// Used to trigger the . + /// + /// PlayerControl instance. + /// The task id. + [HarmonyPostfix] + [HarmonyPatch(nameof(PlayerControl.CompleteTask))] + public static void PlayerCompleteTaskPostfix(PlayerControl __instance, uint idx) + { + var playerTask = __instance.myTasks.ToArray().First(playerTask => playerTask.Id == idx); + if (playerTask != null) + { + var completeTaskEvent = new CompleteTaskEvent(__instance, playerTask); + MiraEventManager.InvokeEvent(completeTaskEvent); + } + } + + /// + /// Used to trigger the . + /// + /// The source player. + /// The target. + /// Whether the kill succeeded. + [HarmonyPrefix] + [HarmonyPatch(nameof(PlayerControl.RpcMurderPlayer))] + public static void PlayerControlMurderPrefix(PlayerControl __instance, PlayerControl target, ref bool didSucceed) + { + var beforeMurderEvent = new BeforeMurderEvent(__instance, target); + MiraEventManager.InvokeEvent(beforeMurderEvent); + + didSucceed = beforeMurderEvent.IsCancelled; + } + /// /// FixedUpdate handler for custom roles and custom buttons. /// diff --git a/MiraAPI/PluginLoading/MiraPluginManager.cs b/MiraAPI/PluginLoading/MiraPluginManager.cs index acb6ebe..25d3065 100644 --- a/MiraAPI/PluginLoading/MiraPluginManager.cs +++ b/MiraAPI/PluginLoading/MiraPluginManager.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using BepInEx.Unity.IL2CPP; +using BepInEx.Unity.IL2CPP; using MiraAPI.Colors; using MiraAPI.Events; using MiraAPI.GameOptions; @@ -13,6 +9,10 @@ using MiraAPI.Roles; using MiraAPI.Utilities; using Reactor.Networking; using Reactor.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; namespace MiraAPI.PluginLoading; diff --git a/MiraAPI/Utilities/Extensions.cs b/MiraAPI/Utilities/Extensions.cs index 636601b..d694c85 100644 --- a/MiraAPI/Utilities/Extensions.cs +++ b/MiraAPI/Utilities/Extensions.cs @@ -346,6 +346,16 @@ public static class Extensions .Find(component => component && !component.Reported); } + /// + /// Get all living players. + /// + /// A list of alive players. + public static List GetAlivePlayers() + { + return PlayerControl.AllPlayerControls.ToArray().Where(x => !x.Data.IsDead).ToList(); + } + + /// /// Finds the nearest object of a specified type to a player. It will only work if the object has a collider. /// @@ -393,4 +403,20 @@ public static class Extensions return predicate != null ? filteredPlayers.Find(predicate) : filteredPlayers.FirstOrDefault(); } + + private static readonly int _outline = Shader.PropertyToID("_Outline"); + private static readonly int _outlineColor = Shader.PropertyToID("_OutlineColor"); + private static readonly int _addColor = Shader.PropertyToID("_AddColor"); + + /// + /// Fixed version of Reactor's SetOutline. + /// + /// The renderer you want to update the outline for. + /// The outline color. + public static void UpdateOutline(this Renderer renderer, Color? color) + { + renderer.material.SetFloat(_outline, color.HasValue ? 1 : 0); + renderer.material.SetColor(_outlineColor, color.HasValue ? color.Value : Color.clear); + renderer.material.SetColor(_addColor, color.HasValue ? color.Value : Color.clear); + } }