From 22718a708cc28f47384e0dd98b80eb243d7f74b5 Mon Sep 17 00:00:00 2001 From: ang-xd Date: Thu, 6 Feb 2025 20:24:53 -0500 Subject: [PATCH] New events and more flexibility --- .../Events/Vanilla/Meeting/EjectionEvent.cs | 28 ++++++++ .../{ => Meeting}/StartMeetingEvent.cs | 4 +- .../Events/Vanilla/Player/IntroBeginEvent.cs | 21 ++++++ MiraAPI/Hud/CustomActionButton.cs | 70 +++++++++++++++---- MiraAPI/Hud/CustomButtonManager.cs | 8 +-- .../Patches/Events/StartMeetingEventPatch.cs | 2 +- MiraAPI/Patches/HudManagerPatches.cs | 19 +++-- MiraAPI/Patches/IntroCutscenePatches.cs | 10 +++ MiraAPI/Patches/Roles/EjectionPatches.cs | 9 +++ MiraAPI/Roles/ICustomRole.cs | 10 +-- 10 files changed, 151 insertions(+), 30 deletions(-) create mode 100644 MiraAPI/Events/Vanilla/Meeting/EjectionEvent.cs rename MiraAPI/Events/Vanilla/{ => Meeting}/StartMeetingEvent.cs (91%) create mode 100644 MiraAPI/Events/Vanilla/Player/IntroBeginEvent.cs diff --git a/MiraAPI/Events/Vanilla/Meeting/EjectionEvent.cs b/MiraAPI/Events/Vanilla/Meeting/EjectionEvent.cs new file mode 100644 index 0000000..31b08c1 --- /dev/null +++ b/MiraAPI/Events/Vanilla/Meeting/EjectionEvent.cs @@ -0,0 +1,28 @@ +namespace MiraAPI.Events.Vanilla.Meeting; + +/// +/// The event that is invoked when a player is ejected. +/// +public class EjectionEvent : MiraCancelableEvent +{ + /// + /// Gets the player that is being ejected. + /// + public PlayerControl? Player { get; } + + /// + /// Gets the instance of the ExileController. + /// + public ExileController ExileController { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The player who is being ejected. + /// The exile controller. + public EjectionEvent(PlayerControl player, ExileController controller) + { + Player = player; + ExileController = controller; + } +} diff --git a/MiraAPI/Events/Vanilla/StartMeetingEvent.cs b/MiraAPI/Events/Vanilla/Meeting/StartMeetingEvent.cs similarity index 91% rename from MiraAPI/Events/Vanilla/StartMeetingEvent.cs rename to MiraAPI/Events/Vanilla/Meeting/StartMeetingEvent.cs index 2e3d8c2..b988b2f 100644 --- a/MiraAPI/Events/Vanilla/StartMeetingEvent.cs +++ b/MiraAPI/Events/Vanilla/Meeting/StartMeetingEvent.cs @@ -1,7 +1,7 @@ -namespace MiraAPI.Events.Vanilla; +namespace MiraAPI.Events.Vanilla.Meeting; /// -/// The event that is invoked when a meeting is called +/// The event that is invoked when a meeting is called. /// public class StartMeetingEvent : MiraCancelableEvent { diff --git a/MiraAPI/Events/Vanilla/Player/IntroBeginEvent.cs b/MiraAPI/Events/Vanilla/Player/IntroBeginEvent.cs new file mode 100644 index 0000000..817f6e7 --- /dev/null +++ b/MiraAPI/Events/Vanilla/Player/IntroBeginEvent.cs @@ -0,0 +1,21 @@ +namespace MiraAPI.Events.Vanilla.Meeting; + +/// +/// The event that is invoked when the intro cutscene is shown. Non cancellable. +/// +public class IntroBeginEvent : MiraEvent +{ + /// + /// Gets the instance of the IntroCutscene. + /// + public IntroCutscene IntroCutscene { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The exile controller. + public IntroBeginEvent(IntroCutscene introCutscene) + { + IntroCutscene = introCutscene; + } +} diff --git a/MiraAPI/Hud/CustomActionButton.cs b/MiraAPI/Hud/CustomActionButton.cs index 3e47d59..fcefc95 100644 --- a/MiraAPI/Hud/CustomActionButton.cs +++ b/MiraAPI/Hud/CustomActionButton.cs @@ -1,7 +1,8 @@ -using System; -using MiraAPI.Events; +using MiraAPI.Events; using MiraAPI.Events.Mira; +using MiraAPI.Patches; using MiraAPI.Utilities.Assets; +using System; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; @@ -47,7 +48,7 @@ public abstract class CustomActionButton /// /// Gets the location of the button on the screen. /// - public virtual ButtonLocation Location => ButtonLocation.BottomLeft; + public virtual ButtonLocation Location { get; private set; } = ButtonLocation.BottomLeft; /// /// Gets a value indicating whether the button has an effect ability. @@ -79,7 +80,11 @@ public abstract class CustomActionButton /// protected ActionButton? Button { get; private set; } - internal void CreateButton(Transform parent) + /// + /// The method used to create the button. + /// + /// The parent of the button. + public virtual void CreateButton(Transform parent) { if (Button) { @@ -142,10 +147,49 @@ public abstract class CustomActionButton })); } + /// + /// Allows you to change the button's location. + /// + /// The new location. + /// Whether the button's position should change ingame. + public virtual void SetButtonLocation(ButtonLocation location, bool moveButton = true) + { + if (HudManager.Instance == null || Button == null) + { + return; + } + + this.Location = location; + + if (!moveButton) return; + + if (HudManagerPatches._bottomLeft == null || HudManagerPatches._bottomRight == null) + { + return; + } + + switch (location) + { + case ButtonLocation.BottomLeft: + var gridArrange = HudManagerPatches._bottomLeft.GetComponent(); + var aspectPosition = HudManagerPatches._bottomLeft.GetComponent(); + + Button.transform.SetParent(HudManagerPatches._bottomLeft.transform); + + gridArrange.Start(); + gridArrange.ArrangeChilds(); + aspectPosition.AdjustPosition(); + break; + case ButtonLocation.BottomRight: + Button.transform.SetParent(HudManagerPatches._bottomRight); + break; + } + } + /// /// A utility function to reset the cooldown and/or effect of the button. /// - public void ResetCooldownAndOrEffect() + public virtual void ResetCooldownAndOrEffect() { Timer = Cooldown; if (EffectActive) @@ -160,7 +204,7 @@ public abstract class CustomActionButton /// A utility function to override the sprite of the button. /// /// The new sprite to override with. - public void OverrideSprite(Sprite sprite) + public virtual void OverrideSprite(Sprite sprite) { if (Button != null) { @@ -172,7 +216,7 @@ public abstract class CustomActionButton /// A utility function to override the name of the button. /// /// The new name to override with. - public void OverrideName(string name) + public virtual void OverrideName(string name) { Button?.OverrideText(name); } @@ -181,7 +225,7 @@ public abstract class CustomActionButton /// Set the button's timer. /// /// The time you want to set to. - public void SetTimer(float time) + public virtual void SetTimer(float time) { Timer = Mathf.Clamp(time, -1, float.MaxValue); } @@ -190,7 +234,7 @@ public abstract class CustomActionButton /// Increase the button's timer. /// /// The amount you want to increase by. - public void IncreaseTimer(float amount) + public virtual void IncreaseTimer(float amount) { SetTimer(Timer + amount); } @@ -199,7 +243,7 @@ public abstract class CustomActionButton /// Decrease the button's timer. /// /// The amount you want to decrease by. - public void DecreaseTimer(float amount) + public virtual void DecreaseTimer(float amount) { SetTimer(Timer - amount); } @@ -208,7 +252,7 @@ public abstract class CustomActionButton /// Set the amount of uses this button has left. /// /// The amount you want to set to. - public void SetUses(int amount) + public virtual void SetUses(int amount) { UsesLeft = Mathf.Clamp(amount, 0, int.MaxValue); Button?.SetUsesRemaining(UsesLeft); @@ -218,7 +262,7 @@ public abstract class CustomActionButton /// Increase the amount of uses this button has left. /// /// The amount you want to increase by. Default: 1. - public void IncreaseUses(int amount = 1) + public virtual void IncreaseUses(int amount = 1) { SetUses(UsesLeft + amount); } @@ -227,7 +271,7 @@ public abstract class CustomActionButton /// Decrease the amount of uses this button has left. /// /// The amount you want to decrease by. Default: 1. - public void DecreaseUses(int amount = 1) + public virtual void DecreaseUses(int amount = 1) { SetUses(UsesLeft - amount); } diff --git a/MiraAPI/Hud/CustomButtonManager.cs b/MiraAPI/Hud/CustomButtonManager.cs index 398aa58..c66ae4d 100644 --- a/MiraAPI/Hud/CustomButtonManager.cs +++ b/MiraAPI/Hud/CustomButtonManager.cs @@ -1,9 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using MiraAPI.Events.Mira; +using MiraAPI.Events.Mira; using MiraAPI.PluginLoading; using Reactor.Utilities; +using System; +using System.Collections.Generic; +using System.Reflection; namespace MiraAPI.Hud; diff --git a/MiraAPI/Patches/Events/StartMeetingEventPatch.cs b/MiraAPI/Patches/Events/StartMeetingEventPatch.cs index 00f8ba4..2012b5d 100644 --- a/MiraAPI/Patches/Events/StartMeetingEventPatch.cs +++ b/MiraAPI/Patches/Events/StartMeetingEventPatch.cs @@ -1,6 +1,6 @@ using HarmonyLib; using MiraAPI.Events; -using MiraAPI.Events.Vanilla; +using MiraAPI.Events.Vanilla.Meeting; using MiraAPI.Utilities; namespace MiraAPI.Patches.Events; diff --git a/MiraAPI/Patches/HudManagerPatches.cs b/MiraAPI/Patches/HudManagerPatches.cs index 85d7750..fa057d4 100644 --- a/MiraAPI/Patches/HudManagerPatches.cs +++ b/MiraAPI/Patches/HudManagerPatches.cs @@ -13,7 +13,9 @@ namespace MiraAPI.Patches; public static class HudManagerPatches { // Custom buttons parent. - private static GameObject? _bottomLeft; + internal static GameObject? _bottomLeft; + internal static Transform? _bottomRight; + internal static Transform? _buttons; /* /// @@ -34,12 +36,19 @@ public static class HudManagerPatches [HarmonyPatch(nameof(HudManager.Start))] public static void StartPostfix(HudManager __instance) { - var buttons = __instance.transform.Find("Buttons"); - var bottomRight = buttons.Find("BottomRight"); + if (_buttons == null) + { + _buttons = __instance.transform.Find("Buttons"); + } + + if (_bottomRight == null) + { + _bottomRight = _buttons.Find("BottomRight"); + } if (_bottomLeft == null) { - _bottomLeft = Object.Instantiate(bottomRight.gameObject, buttons); + _bottomLeft = Object.Instantiate(_bottomRight.gameObject, _buttons); } foreach (var t in _bottomLeft.GetComponentsInChildren(true)) @@ -59,7 +68,7 @@ public static class HudManagerPatches var location = button.Location switch { ButtonLocation.BottomLeft => _bottomLeft.transform, - ButtonLocation.BottomRight => bottomRight, + ButtonLocation.BottomRight => _bottomRight, _ => null, }; diff --git a/MiraAPI/Patches/IntroCutscenePatches.cs b/MiraAPI/Patches/IntroCutscenePatches.cs index 2250d3d..03cc403 100644 --- a/MiraAPI/Patches/IntroCutscenePatches.cs +++ b/MiraAPI/Patches/IntroCutscenePatches.cs @@ -1,4 +1,6 @@ using HarmonyLib; +using MiraAPI.Events; +using MiraAPI.Events.Vanilla.Meeting; using MiraAPI.Roles; using MiraAPI.Utilities; using UnityEngine; @@ -20,6 +22,14 @@ public static class IntroCutscenePatches } }*/ + [HarmonyPostfix] + [HarmonyPatch(nameof(IntroCutscene.CoBegin))] + public static void IntroBeginPatch(IntroCutscene __instance) + { + var @event = new IntroBeginEvent(__instance); + MiraEventManager.InvokeEvent(@event); + } + [HarmonyPrefix] [HarmonyPatch(nameof(IntroCutscene.BeginCrewmate))] public static bool BeginCrewmatePatch(IntroCutscene __instance) diff --git a/MiraAPI/Patches/Roles/EjectionPatches.cs b/MiraAPI/Patches/Roles/EjectionPatches.cs index 9f85872..3acf228 100644 --- a/MiraAPI/Patches/Roles/EjectionPatches.cs +++ b/MiraAPI/Patches/Roles/EjectionPatches.cs @@ -1,4 +1,6 @@ using HarmonyLib; +using MiraAPI.Events; +using MiraAPI.Events.Vanilla.Meeting; using MiraAPI.Roles; namespace MiraAPI.Patches.Roles; @@ -13,6 +15,13 @@ public static class EjectionPatches [HarmonyPatch(nameof(ExileController.Begin))] public static void BeginPostfix(ExileController __instance) { + var @event = new EjectionEvent(__instance.initData.networkedPlayer.Object, __instance); + MiraEventManager.InvokeEvent(@event); + + if (@event.IsCancelled) + { + return; + } if (!__instance.initData.networkedPlayer || !__instance.initData.networkedPlayer.Role || __instance.initData.networkedPlayer.Role is not ICustomRole role) { diff --git a/MiraAPI/Roles/ICustomRole.cs b/MiraAPI/Roles/ICustomRole.cs index ba318b2..a28bed9 100644 --- a/MiraAPI/Roles/ICustomRole.cs +++ b/MiraAPI/Roles/ICustomRole.cs @@ -2,8 +2,8 @@ using MiraAPI.Modifiers; using MiraAPI.PluginLoading; using MiraAPI.Utilities; -using System.Text; using Reactor.Utilities; +using System.Text; using UnityEngine; namespace MiraAPI.Roles; @@ -63,7 +63,7 @@ public interface ICustomRole /// Gets the role chance option. /// /// The role chance option. - public int? GetChance() + public virtual int? GetChance() { if (!Configuration.CanModifyChance) { @@ -82,7 +82,7 @@ public interface ICustomRole /// Gets the role count option. /// /// The role count option. - public int? GetCount() + public virtual int? GetCount() { if (ParentMod.PluginConfig.TryGetEntry(NumConfigDefinition, out ConfigEntry entry)) { @@ -96,7 +96,7 @@ public interface ICustomRole /// Sets the role chance option. /// /// The chance between 0 and 100. - public void SetChance(int chance) + public virtual void SetChance(int chance) { if (!Configuration.CanModifyChance) { @@ -117,7 +117,7 @@ public interface ICustomRole /// Sets the role count option. /// /// The amount of this role between zero and its MaxRoleCount in the Configuration. - public void SetCount(int count) + public virtual void SetCount(int count) { if (ParentMod.PluginConfig.TryGetEntry(NumConfigDefinition, out ConfigEntry entry)) {