From 3041d9f73c2bb945a8923583815aba6a5cf3c8b7 Mon Sep 17 00:00:00 2001 From: ivan tkachenko Date: Fri, 16 Jan 2026 18:21:33 +0200 Subject: [PATCH] Merge EnemyAI.OnDestroy patch with cleanups into existing Behaviour That Harmony patch predated MuzikaGromcheJesterNetworkBehaviour, but there is no need to have as a separate class, especially not with the subclass check hack. --- MuzikaGromche/Plugin.cs | 58 ++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/MuzikaGromche/Plugin.cs b/MuzikaGromche/Plugin.cs index 5629f50..a93325d 100644 --- a/MuzikaGromche/Plugin.cs +++ b/MuzikaGromche/Plugin.cs @@ -1186,7 +1186,6 @@ namespace MuzikaGromche Harmony = new Harmony(MyPluginInfo.PLUGIN_NAME); Harmony.PatchAll(typeof(GameNetworkManagerPatch)); Harmony.PatchAll(typeof(JesterPatch)); - Harmony.PatchAll(typeof(EnemyAIPatch)); Harmony.PatchAll(typeof(PoweredLightsAnimatorsPatch)); Harmony.PatchAll(typeof(AllPoweredLightsPatch)); Harmony.PatchAll(typeof(DiscoBallTilePatch)); @@ -3116,6 +3115,9 @@ namespace MuzikaGromche public override void OnDestroy() { Config.Volume.SettingChanged -= UpdateVolume; + + DeathScreenGameOverTextManager.Clear(); + Stop(); } private void UpdateVolume(object sender, EventArgs e) @@ -3247,6 +3249,30 @@ namespace MuzikaGromche Plugin.Log.LogDebug($"Play Intro: dspTime={AudioSettings.dspTime:N4}, intro.time={IntroAudioSource.time:N4}/{IntroAudioSource.clip.length:N4}, scheduled Loop={loopStartDspTime}"); } + public void Stop() + { + PoweredLightsBehaviour.Instance.ResetLightColor(); + DiscoBallManager.Disable(); + ScreenFiltersManager.Clear(); + + if (IntroAudioSource != null) + { + IntroAudioSource.Stop(); + IntroAudioSource.clip = null; + } + if (LoopAudioSource != null) + { + LoopAudioSource.Stop(); + LoopAudioSource.clip = null; + } + BeatTimeState = null; + + // Just in case if players have spawned multiple Jesters, + // Don't reset Config.CurrentTrack to null, + // so that the latest chosen track remains set. + CurrentTrack = null; + } + public void OverrideDeathScreenGameOverText() { if (CurrentTrack == null) @@ -3266,8 +3292,7 @@ namespace MuzikaGromche static void SetJesterInitialValuesPostfix(JesterAI __instance) { var behaviour = __instance.GetComponent(); - behaviour.IntroAudioSource.Stop(); - behaviour.LoopAudioSource.Stop(); + behaviour.Stop(); #if DEBUG // Almost instant follow timer @@ -3415,12 +3440,9 @@ namespace MuzikaGromche // transition away from state 2 ("poppedOut"), normally to state 0 if (__state.previousState == 2 && __instance.previousState != 2) { - PoweredLightsBehaviour.Instance.ResetLightColor(); - DiscoBallManager.Disable(); - ScreenFiltersManager.Clear(); + behaviour.Stop(); // Rotate track groups behaviour.ChooseTrack(); - behaviour.BeatTimeState = null; } // Manage the timeline: switch color of the lights according to the current playback/beat position. @@ -3472,26 +3494,4 @@ namespace MuzikaGromche } } } - - [HarmonyPatch(typeof(EnemyAI))] - static class EnemyAIPatch - { - // JesterAI class does not override abstract method OnDestroy, - // so we have to patch its superclass directly. - [HarmonyPatch(nameof(EnemyAI.OnDestroy))] - [HarmonyPrefix] - static void CleanUpOnDestroy(EnemyAI __instance) - { - if (__instance is JesterAI) - { - PoweredLightsBehaviour.Instance.ResetLightColor(); - DiscoBallManager.Disable(); - DeathScreenGameOverTextManager.Clear(); - ScreenFiltersManager.Clear(); - // Just in case if players have spawned multiple Jesters, - // Don't reset Config.CurrentTrack to null, - // so that the latest chosen track remains set. - } - } - } }