Skip to content

Commit

Permalink
Fix eye softlock maybe (#874)
Browse files Browse the repository at this point in the history
## Bug fixes

- fix #865: dont softlock when at the eye (johncorby's fault) 
- fix #783: pause on load like base game does
  • Loading branch information
JohnCorby authored Jun 3, 2024
2 parents fb9e10f + 79ad864 commit 2fe4267
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 39 deletions.
43 changes: 39 additions & 4 deletions NewHorizons/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,10 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
else if (IsWarpingBackToEye)
{
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?
OWTime.Unpause(OWTime.PauseType.Loading);
// OWTime.Pause(OWTime.PauseType.Loading); // loading already pauses
ManualOnStartSceneLoad(OWScene.EyeOfTheUniverse);
LoadManager.LoadSceneImmediate(OWScene.EyeOfTheUniverse);
// OWTime.Unpause(OWTime.PauseType.Loading); // changing active scenes already unpauses
return;
}

Expand Down Expand Up @@ -627,6 +628,39 @@ public void EnableWarpDrive()
HasWarpDrive = true;
}

/// <summary>
/// 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.
/// </summary>
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)
Expand Down Expand Up @@ -936,11 +970,12 @@ public void ChangeCurrentStarSystem(string newStarSystem, bool warp = false, boo
OWInput.ChangeInputMode(InputMode.None);

// Hide unloading
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
Locator.GetPlayerSectorDetector().RemoveFromAllSectors();
LoadManager.LoadScene(sceneToLoad); // this used to be LoadSceneImmediate, but that breaks with qsb. hopefully it doesnt break nh
LoadManager.LoadSceneImmediate(sceneToLoad);
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion NewHorizons/Patches/RigidbodyPatches.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using HarmonyLib;
using NewHorizons.Utility;
using OWML.Utils;
using System.Collections.Generic;
using UnityEngine;

Expand Down
34 changes: 0 additions & 34 deletions NewHorizons/Utility/NewHorizonExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,40 +372,6 @@ public static AnimationCurve ToAnimationCurve(this HeightDensityPair[] pairs)
return curve;
}

// From QSB
public static void RaiseEvent<T>(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<XmlNode> GetChildNodes(this XmlNode parentNode, string tagName)
{
return parentNode.ChildNodes.Cast<XmlNode>().Where(node => node.LocalName == tagName).ToList();
Expand Down

0 comments on commit 2fe4267

Please sign in to comment.