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))
{