From 7489ecb7f8977d199d06812f4b2b8bb3f7ad43e2 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Sat, 1 Jun 2024 00:43:31 -0700 Subject: [PATCH 1/4] MAYBE fix eye softlock (and use owml methods instead of copied qsb ones) --- NewHorizons/Main.cs | 8 +++-- NewHorizons/Patches/RigidbodyPatches.cs | 2 +- NewHorizons/Utility/NewHorizonExtensions.cs | 34 --------------------- 3 files changed, 7 insertions(+), 37 deletions(-) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index df767fe70..0f8eebeaf 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -388,7 +388,9 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { IsWarpingBackToEye = false; OWTime.Pause(OWTime.PauseType.Loading); - LoadManager.LoadScene(OWScene.EyeOfTheUniverse); // LoadScene loads one frame later in Update. will this break since we unpause before that in the next line? + // fire OnStartSceneLoad so qsb and other mods are happy + ((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null)).DynamicInvoke(); + LoadManager.LoadSceneImmediate(OWScene.EyeOfTheUniverse); OWTime.Unpause(OWTime.PauseType.Loading); return; } @@ -936,11 +938,13 @@ public void ChangeCurrentStarSystem(string newStarSystem, bool warp = false, boo OWInput.ChangeInputMode(InputMode.None); // Hide unloading + // fire OnStartSceneLoad so qsb and other mods are happy + ((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null)).DynamicInvoke(); FadeHandler.FadeThen(1f, () => { // Slide reel unloading is tied to being removed from the sector, so we do that here to prevent a softlock Locator.GetPlayerSectorDetector().RemoveFromAllSectors(); - LoadManager.LoadScene(sceneToLoad); // this used to be LoadSceneImmediate, but that breaks with qsb. hopefully it doesnt break nh + LoadManager.LoadSceneImmediate(sceneToLoad); }); } } diff --git a/NewHorizons/Patches/RigidbodyPatches.cs b/NewHorizons/Patches/RigidbodyPatches.cs index 22ad16dc6..963a64069 100644 --- a/NewHorizons/Patches/RigidbodyPatches.cs +++ b/NewHorizons/Patches/RigidbodyPatches.cs @@ -1,5 +1,5 @@ using HarmonyLib; -using NewHorizons.Utility; +using OWML.Utils; using System.Collections.Generic; using UnityEngine; diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index 3ba29885c..7236af7ea 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -372,40 +372,6 @@ public static AnimationCurve ToAnimationCurve(this HeightDensityPair[] pairs) return curve; } - // From QSB - public static void RaiseEvent(this T instance, string eventName, params object[] args) - { - const BindingFlags flags = BindingFlags.Instance - | BindingFlags.Static - | BindingFlags.Public - | BindingFlags.NonPublic - | BindingFlags.DeclaredOnly; - if (typeof(T) - .GetField(eventName, flags)? - .GetValue(instance) is not MulticastDelegate multiDelegate) - { - return; - } - - multiDelegate.SafeInvoke(args); - } - - // From QSB - public static void SafeInvoke(this MulticastDelegate multicast, params object[] args) - { - foreach (var del in multicast.GetInvocationList()) - { - try - { - del.DynamicInvoke(args); - } - catch (TargetInvocationException ex) - { - NHLogger.LogError($"Error invoking delegate! {ex.InnerException}"); - } - } - } - public static List GetChildNodes(this XmlNode parentNode, string tagName) { return parentNode.ChildNodes.Cast().Where(node => node.LocalName == tagName).ToList(); From 1d41360c00ea4d3a704215af257c33c04f29fa99 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Sat, 1 Jun 2024 10:34:49 -0700 Subject: [PATCH 2/4] forgot to pass in the right arguments --- NewHorizons/Main.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 0f8eebeaf..b0dd6bf35 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -389,7 +389,7 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode) IsWarpingBackToEye = false; OWTime.Pause(OWTime.PauseType.Loading); // fire OnStartSceneLoad so qsb and other mods are happy - ((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null)).DynamicInvoke(); + ((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null)).DynamicInvoke(LoadManager.s_currentScene, LoadManager.s_loadingScene); LoadManager.LoadSceneImmediate(OWScene.EyeOfTheUniverse); OWTime.Unpause(OWTime.PauseType.Loading); return; @@ -939,7 +939,7 @@ public void ChangeCurrentStarSystem(string newStarSystem, bool warp = false, boo // Hide unloading // fire OnStartSceneLoad so qsb and other mods are happy - ((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null)).DynamicInvoke(); + ((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null)).DynamicInvoke(LoadManager.s_currentScene, LoadManager.s_loadingScene); FadeHandler.FadeThen(1f, () => { // Slide reel unloading is tied to being removed from the sector, so we do that here to prevent a softlock From 8ec148bb9a083a68737d785e6f56e443938ae67c Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Sat, 1 Jun 2024 12:16:16 -0700 Subject: [PATCH 3/4] do things as properly as i can --- NewHorizons/Main.cs | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index b0dd6bf35..3ea714ae3 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -387,11 +387,10 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode) else if (IsWarpingBackToEye) { IsWarpingBackToEye = false; - OWTime.Pause(OWTime.PauseType.Loading); - // fire OnStartSceneLoad so qsb and other mods are happy - ((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null)).DynamicInvoke(LoadManager.s_currentScene, LoadManager.s_loadingScene); + // OWTime.Pause(OWTime.PauseType.Loading); // loading already pauses + ManualOnStartSceneLoad(OWScene.EyeOfTheUniverse); LoadManager.LoadSceneImmediate(OWScene.EyeOfTheUniverse); - OWTime.Unpause(OWTime.PauseType.Loading); + // OWTime.Unpause(OWTime.PauseType.Loading); // changing active scenes already unpauses return; } @@ -629,6 +628,39 @@ public void EnableWarpDrive() HasWarpDrive = true; } + /// + /// sometimes we call LoadSceneImmediate, which doesnt do the required event firing for mods to be happy. + /// this method emulates that via copying parts of LoadManager. + /// + public static void ManualOnStartSceneLoad(OWScene scene) + { + LoadManager.s_loadSceneJob = new LoadManager.LoadSceneJob(); + LoadManager.s_loadSceneJob.sceneToLoad = scene; + LoadManager.s_loadSceneJob.fadeType = LoadManager.FadeType.None; + LoadManager.s_loadSceneJob.fadeLength = 0; + LoadManager.s_loadSceneJob.pauseDuringFade = true; + LoadManager.s_loadSceneJob.asyncOperation = false; + LoadManager.s_loadSceneJob.skipPreLoadMemoryDump = false; + LoadManager.s_loadSceneJob.skipVsyncChange = false; + + LoadManager.s_loadingScene = LoadManager.s_loadSceneJob.sceneToLoad; + LoadManager.s_fadeType = LoadManager.s_loadSceneJob.fadeType; + LoadManager.s_fadeStartTime = Time.unscaledTime; + LoadManager.s_fadeLength = LoadManager.s_loadSceneJob.fadeLength; + LoadManager.s_pauseDuringFade = LoadManager.s_loadSceneJob.pauseDuringFade; + LoadManager.s_skipVsyncChange = LoadManager.s_loadSceneJob.skipVsyncChange; + + // cant fire events from outside of class without reflection + ((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null)) + .DynamicInvoke(LoadManager.s_currentScene, LoadManager.s_loadingScene); + + if (LoadManager.s_pauseDuringFade) + { + OWTime.Pause(OWTime.PauseType.Loading); + } + + LoadManager.s_loadSceneJob = null; + } #region Load public void LoadStarSystemConfig(string starSystemName, StarSystemConfig starSystemConfig, string relativePath, IModBehaviour mod) @@ -938,8 +970,7 @@ public void ChangeCurrentStarSystem(string newStarSystem, bool warp = false, boo OWInput.ChangeInputMode(InputMode.None); // Hide unloading - // fire OnStartSceneLoad so qsb and other mods are happy - ((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null)).DynamicInvoke(LoadManager.s_currentScene, LoadManager.s_loadingScene); + ManualOnStartSceneLoad(sceneToLoad); FadeHandler.FadeThen(1f, () => { // Slide reel unloading is tied to being removed from the sector, so we do that here to prevent a softlock From 79ad86467f348021ed566bf52ea2a888ca95920d Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Sat, 1 Jun 2024 12:59:26 -0700 Subject: [PATCH 4/4] format --- NewHorizons/Main.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 3ea714ae3..7ca6e3224 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -389,7 +389,7 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode) IsWarpingBackToEye = false; // OWTime.Pause(OWTime.PauseType.Loading); // loading already pauses ManualOnStartSceneLoad(OWScene.EyeOfTheUniverse); - LoadManager.LoadSceneImmediate(OWScene.EyeOfTheUniverse); + LoadManager.LoadSceneImmediate(OWScene.EyeOfTheUniverse); // OWTime.Unpause(OWTime.PauseType.Loading); // changing active scenes already unpauses return; }