diff --git a/MiraAPI/Events/Vanilla/Gameplay/BeforeGameEndEvent.cs b/MiraAPI/Events/Vanilla/Gameplay/BeforeGameEndEvent.cs
new file mode 100644
index 0000000..0a70a1d
--- /dev/null
+++ b/MiraAPI/Events/Vanilla/Gameplay/BeforeGameEndEvent.cs
@@ -0,0 +1,21 @@
+namespace MiraAPI.Events.Vanilla.Gameplay;
+
+///
+/// Invoked before RpcEndGame is called, allowing cancellation of the game end entirely.
+///
+public class BeforeGameEndEvent : MiraCancelableEvent
+{
+ ///
+ /// Gets the reason for the game end.
+ ///
+ public GameOverReason Reason { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The reason for the game end.
+ public BeforeGameEndEvent(GameOverReason reason)
+ {
+ Reason = reason;
+ }
+}
diff --git a/MiraAPI/Patches/Events/EndGamePatches.cs b/MiraAPI/Patches/Events/EndGamePatches.cs
index 2c04d6b..558c468 100644
--- a/MiraAPI/Patches/Events/EndGamePatches.cs
+++ b/MiraAPI/Patches/Events/EndGamePatches.cs
@@ -5,29 +5,44 @@ using MiraAPI.GameEnd;
namespace MiraAPI.Patches.Events;
-[HarmonyPatch(typeof(EndGameManager), nameof(EndGameManager.SetEverythingUp))]
internal static class EndGamePatches
{
- public static bool Prefix(EndGameManager __instance)
+ [HarmonyPatch(typeof(GameManager), nameof(GameManager.RpcEndGame))]
+ public static class GameManagerPatches
{
- if (CustomGameOver.Instance is not { } gameOver)
+ public static bool Prefix(GameOverReason endReason)
{
- return true;
- }
+ var @event = new BeforeGameEndEvent(endReason);
+ MiraEventManager.InvokeEvent(@event);
- var result = gameOver.BeforeEndGameSetup(__instance);
- return result;
+ return !@event.IsCancelled;
+ }
}
- public static void Postfix(EndGameManager __instance)
+ [HarmonyPatch(typeof(EndGameManager), nameof(EndGameManager.SetEverythingUp))]
+ public static class EndGameManagerPatches
{
- if (CustomGameOver.Instance is { } gameOver)
+ public static bool Prefix(EndGameManager __instance)
{
- gameOver.AfterEndGameSetup(__instance);
- CustomGameOver.Instance = null;
+ if (CustomGameOver.Instance is not { } gameOver)
+ {
+ return true;
+ }
+
+ var result = gameOver.BeforeEndGameSetup(__instance);
+ return result;
}
- var @event = new GameEndEvent(__instance);
- MiraEventManager.InvokeEvent(@event);
+ public static void Postfix(EndGameManager __instance)
+ {
+ if (CustomGameOver.Instance is { } gameOver)
+ {
+ gameOver.AfterEndGameSetup(__instance);
+ CustomGameOver.Instance = null;
+ }
+
+ var @event = new GameEndEvent(__instance);
+ MiraEventManager.InvokeEvent(@event);
+ }
}
}