diff --git a/MiraAPI/Events/Vanilla/Gameplay/IntroEndEvent.cs b/MiraAPI/Events/Vanilla/Gameplay/IntroEndEvent.cs new file mode 100644 index 0000000..b27bcec --- /dev/null +++ b/MiraAPI/Events/Vanilla/Gameplay/IntroEndEvent.cs @@ -0,0 +1,12 @@ +namespace MiraAPI.Events.Vanilla.Gameplay; + +/// +/// The event that is invoked when the intro cutscene has finished playing. +/// +public class IntroEndEvent(IntroCutscene introCutscene) : MiraEvent +{ + /// + /// Gets the instance of the IntroCutscene. + /// + public IntroCutscene IntroCutscene { get; } = introCutscene; +} diff --git a/MiraAPI/Events/Vanilla/Gameplay/RoundStartEvent.cs b/MiraAPI/Events/Vanilla/Gameplay/RoundStartEvent.cs new file mode 100644 index 0000000..a50fde5 --- /dev/null +++ b/MiraAPI/Events/Vanilla/Gameplay/RoundStartEvent.cs @@ -0,0 +1,21 @@ +namespace MiraAPI.Events.Vanilla.Gameplay; + +/// +/// Start Round event, invoked on IntroCutscene.OnDestroy and ExileController.WrapUp. +/// +public class RoundStartEvent : MiraEvent +{ + /// + /// Gets a value indicating whether the event was triggered by the IntroCutscene or ExileController. + /// + public bool TriggeredByIntro { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Whether the event was triggered by the intro or not. + public RoundStartEvent(bool triggeredByIntro) + { + TriggeredByIntro = triggeredByIntro; + } +} diff --git a/MiraAPI/Events/Vanilla/Meeting/EndMeetingEvent.cs b/MiraAPI/Events/Vanilla/Meeting/EndMeetingEvent.cs new file mode 100644 index 0000000..55cdae9 --- /dev/null +++ b/MiraAPI/Events/Vanilla/Meeting/EndMeetingEvent.cs @@ -0,0 +1,12 @@ +namespace MiraAPI.Events.Vanilla.Meeting; + +/// +/// The event that is invoked when the meeting has ended. +/// +public class EndMeetingEvent(MeetingHud meetingHud) : MiraEvent +{ + /// + /// Gets the MeetingHud instance. + /// + public MeetingHud MeetingHud { get; } = meetingHud; +} diff --git a/MiraAPI/Events/Vanilla/Meeting/Voting/VotingCompleteEvent.cs b/MiraAPI/Events/Vanilla/Meeting/Voting/VotingCompleteEvent.cs new file mode 100644 index 0000000..5f782bf --- /dev/null +++ b/MiraAPI/Events/Vanilla/Meeting/Voting/VotingCompleteEvent.cs @@ -0,0 +1,13 @@ +namespace MiraAPI.Events.Vanilla.Meeting.Voting; + +/// +/// The event that is invoked when the voting phase of a meeting is complete. +/// +/// The MeetingHud instance. +public class VotingCompleteEvent(MeetingHud meetingHud) : MiraEvent +{ + /// + /// Gets the MeetingHud instance. + /// + public MeetingHud MeetingHud { get; } = meetingHud; +} diff --git a/MiraAPI/Patches/IntroCutscenePatches.cs b/MiraAPI/Patches/IntroCutscenePatches.cs index fb6144a..d068f26 100644 --- a/MiraAPI/Patches/IntroCutscenePatches.cs +++ b/MiraAPI/Patches/IntroCutscenePatches.cs @@ -56,11 +56,11 @@ public static class IntroCutscenePatches } } - /* [HarmonyPostfix] [HarmonyPatch(nameof(IntroCutscene.OnDestroy))] - public static void GameBeginPatch() + public static void GameBeginPatch(IntroCutscene __instance) { - CustomGameModeManager.ActiveMode?.Initialize(); - }*/ + MiraEventManager.InvokeEvent(new IntroEndEvent(__instance)); + MiraEventManager.InvokeEvent(new RoundStartEvent(true)); + } } diff --git a/MiraAPI/Patches/Roles/EjectionPatches.cs b/MiraAPI/Patches/Roles/EjectionPatches.cs index 48d6abb..a7861df 100644 --- a/MiraAPI/Patches/Roles/EjectionPatches.cs +++ b/MiraAPI/Patches/Roles/EjectionPatches.cs @@ -1,5 +1,8 @@ -using HarmonyLib; +using System.Collections.Generic; +using System.Reflection; +using HarmonyLib; using MiraAPI.Events; +using MiraAPI.Events.Vanilla.Gameplay; using MiraAPI.Events.Vanilla.Meeting; using MiraAPI.Roles; @@ -31,4 +34,24 @@ public static class EjectionPatches __instance.completeString = role.GetCustomEjectionMessage(__instance.initData.networkedPlayer); } + + [HarmonyPatch] + internal static class WrapUpPatch + { + public static IEnumerable TargetMethods() + { + yield return AccessTools.Method(typeof(ExileController), nameof(ExileController.WrapUp)); + yield return AccessTools.Method(typeof(AirshipExileController), nameof(AirshipExileController.WrapUpAndSpawn)); + if (AccessTools.TypeByName("Submerged.ExileCutscene.SubmergedExileController") is { } type) + { + yield return AccessTools.Method(type, "WrapUpAndSpawn"); + } + } + + public static void Postfix() + { + var @event = new RoundStartEvent(false); + MiraEventManager.InvokeEvent(@event); + } + } } diff --git a/MiraAPI/Patches/Voting/MeetingHudPatches.cs b/MiraAPI/Patches/Voting/MeetingHudPatches.cs index 6070b1e..337a5f7 100644 --- a/MiraAPI/Patches/Voting/MeetingHudPatches.cs +++ b/MiraAPI/Patches/Voting/MeetingHudPatches.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Diagnostics.CodeAnalysis; +using System.Linq; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using MiraAPI.Events; @@ -10,6 +11,7 @@ using MiraAPI.Voting; namespace MiraAPI.Patches.Voting; [HarmonyPatch(typeof(MeetingHud))] +[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Harmony Convention")] internal static class MeetingHudPatches { [HarmonyPostfix] @@ -31,6 +33,20 @@ internal static class MeetingHudPatches MiraEventManager.InvokeEvent(@event); } + [HarmonyPostfix] + [HarmonyPatch(nameof(MeetingHud.OnDestroy))] + public static void MeetingHudOnDestroyPatch(MeetingHud __instance) + { + MiraEventManager.InvokeEvent(new EndMeetingEvent(__instance)); + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(MeetingHud.VotingComplete))] + public static void MeetingHudVotingCompletePatch(MeetingHud __instance) + { + MiraEventManager.InvokeEvent(new VotingCompleteEvent(__instance)); + } + [HarmonyPrefix] [HarmonyPatch(nameof(MeetingHud.Select))] public static bool SelectPatch(MeetingHud __instance, int suspectStateIdx)