Decompiled source of Scene Save v1.0.0
Mods/SceneSave.dll
Decompiled 4 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Threading.Tasks; using BoneLib; using BoneLib.BoneMenu; using BoneLib.BoneMenu.UI; using BoneLib.Notifications; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Bonelab; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.AI; using Il2CppSLZ.Marrow.Combat; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Interaction; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.PuppetMasta; using Il2CppSLZ.Marrow.SceneStreaming; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using SceneSave; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Core), "SceneSave", "1.0.0", "CAitStudio", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("SceneSave")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SceneSave")] [assembly: AssemblyTitle("SceneSave")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SceneSave { public class Core : MelonMod { [CompilerGenerated] private sealed class <>c__DisplayClass172_0 { public Constrainer constrainer; public int joints; internal void <LoadCurrentLevelSave>b__0(Constrainer constrainerInstance) { constrainer = constrainerInstance; } internal void <LoadCurrentLevelSave>b__1(int got) { joints = got; } } [CompilerGenerated] private sealed class <>c__DisplayClass175_0 { public Constrainer constrainer; public int joints; internal void <LoadCurrentLevelSaveQuest>b__0(Constrainer constrainerInstance) { constrainer = constrainerInstance; } internal void <LoadCurrentLevelSaveQuest>b__1(int got) { joints = got; } } [CompilerGenerated] private sealed class <>c__DisplayClass211_0 { public Constrainer constrainer; public int got; public Action<Constrainer> <>9__0; public Action<int> <>9__1; internal void <RestoreConstraintsWithRetryTimeSliced>b__0(Constrainer constrainerInstance) { constrainer = constrainerInstance; } internal void <RestoreConstraintsWithRetryTimeSliced>b__1(int count) { got = count; } } [CompilerGenerated] private sealed class <ApplyNpcWorldPosePass>d__188 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public Core <>4__this; private Stopwatch <stopwatch>5__1; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ApplyNpcWorldPosePass>d__188(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__1 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__1.Restart(); goto IL_010a; } <>1__state = -1; <stopwatch>5__1 = Stopwatch.StartNew(); <i>5__2 = 0; goto IL_011d; IL_011d: if (<i>5__2 < save.Objects.Count && <i>5__2 < made.Count) { if (!save.Objects[<i>5__2].HasAIBrain) { HealthRecord health = save.Objects[<i>5__2].Health; if (health == null || !health.IsDead.GetValueOrDefault()) { goto IL_00c3; } } <>4__this.ApplySavedTransforms(made[<i>5__2], save.Objects[<i>5__2], restoreWorldPose: true, keepRigidbodiesFrozen: true); goto IL_00c3; } return false; IL_010a: <i>5__2++; goto IL_011d; IL_00c3: if (<stopwatch>5__1.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } goto IL_010a; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <DespawnExistingPooleesTimeSliced>d__227 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private Stopwatch <stopwatch>5__1; private Poolee[] <>s__2; private int <>s__3; private Poolee <poolee>5__4; private string <barcode>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DespawnExistingPooleesTimeSliced>d__227(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__1 = null; <>s__2 = null; <poolee>5__4 = null; <barcode>5__5 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__1.Restart(); goto IL_0140; } <>1__state = -1; <stopwatch>5__1 = Stopwatch.StartNew(); <>s__2 = <>4__this.PooleesNow(); <>s__3 = 0; goto IL_015d; IL_015d: if (<>s__3 < <>s__2.Length) { <poolee>5__4 = <>s__2[<>s__3]; if (<>4__this.CanClearPoolee(<poolee>5__4)) { SpawnableCrate spawnableCrate = <poolee>5__4.SpawnableCrate; object obj; if (spawnableCrate == null) { obj = null; } else { Barcode barcode = ((Scannable)spawnableCrate).Barcode; obj = ((barcode != null) ? barcode.ID : null); } <barcode>5__5 = (string)obj; if (!string.IsNullOrWhiteSpace(<barcode>5__5)) { try { <poolee>5__4.Despawn(); <>4__this.Dirty(); } catch { Object.Destroy((Object)(object)((Component)<poolee>5__4).gameObject); <>4__this.Dirty(); } if (<stopwatch>5__1.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } goto IL_0140; } } goto IL_014f; } <>s__2 = null; return false; IL_014f: <>s__3++; goto IL_015d; IL_0140: <barcode>5__5 = null; <poolee>5__4 = null; goto IL_014f; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <DespawnIgnoredPooleesTimeSliced>d__228 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private Stopwatch <stopwatch>5__1; private Poolee[] <>s__2; private int <>s__3; private Poolee <poolee>5__4; private string <barcode>5__5; private bool <ignored>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DespawnIgnoredPooleesTimeSliced>d__228(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__1 = null; <>s__2 = null; <poolee>5__4 = null; <barcode>5__5 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__1.Restart(); goto IL_0171; } <>1__state = -1; <stopwatch>5__1 = Stopwatch.StartNew(); <>s__2 = <>4__this.PooleesNow(); <>s__3 = 0; goto IL_018e; IL_018e: if (<>s__3 < <>s__2.Length) { <poolee>5__4 = <>s__2[<>s__3]; if (!((Object)(object)<poolee>5__4 == (Object)null)) { SpawnableCrate spawnableCrate = <poolee>5__4.SpawnableCrate; if (!(((spawnableCrate != null) ? ((Scannable)spawnableCrate).Barcode : null) == (Barcode)null)) { <barcode>5__5 = ((Scannable)<poolee>5__4.SpawnableCrate).Barcode.ID; <ignored>5__6 = IsSpentCasing(<poolee>5__4, <barcode>5__5) || IsLooseEmptyMagazine(<poolee>5__4); if (<ignored>5__6) { try { <poolee>5__4.Despawn(); <>4__this.Dirty(); } catch { Object.Destroy((Object)(object)((Component)<poolee>5__4).gameObject); <>4__this.Dirty(); } if (<stopwatch>5__1.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } goto IL_0171; } } } goto IL_0180; } <>s__2 = null; return false; IL_0180: <>s__3++; goto IL_018e; IL_0171: <barcode>5__5 = null; <poolee>5__4 = null; goto IL_0180; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <FixSaveQuitPopup>d__79 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private int <i>5__1; private Button <confirm>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FixSaveQuitPopup>d__79(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <confirm>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <i>5__1 = 0; break; case 1: <>1__state = -1; <confirm>5__2 = <>4__this.FindYesButton(); if (!((Object)(object)<confirm>5__2 == (Object)null)) { <>4__this.RetitlePopup(((Component)<confirm>5__2).gameObject); <confirm>5__2.onClick = new ButtonClickedEvent(); ((UnityEvent)<confirm>5__2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate { if (!<>4__this.SaveCurrentLevel("SaveAndQuit")) { ((MelonBase)<>4__this).LoggerInstance.Warning("falied to save,pls try again"); } else { <>4__this._quitSaved = true; Application.Quit(); } })); return false; } <i>5__1++; break; } if (<i>5__1 < 60) { <>2__current = null; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <GetOrSpawnConstrainer>d__220 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Action<Constrainer> onResolved; public Core <>4__this; private Constrainer <made>5__1; private Task<Poolee> <spawnTask>5__2; private float <timeoutAt>5__3; private string <barcode>5__4; private Exception <ex>5__5; private Poolee <poolee>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetOrSpawnConstrainer>d__220(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <made>5__1 = null; <spawnTask>5__2 = null; <barcode>5__4 = null; <ex>5__5 = null; <poolee>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; if ((Object)(object)<>4__this._dummyConstrainer != (Object)null && !((Il2CppObjectBase)<>4__this._dummyConstrainer).WasCollected) { onResolved?.Invoke(<>4__this._dummyConstrainer); return false; } <made>5__1 = null; <spawnTask>5__2 = null; try { <barcode>5__4 = Barcodes.Get(SceneSaveBarcode.CONSTRAINER); <spawnTask>5__2 = SpawnBits.SpawnAsync(<barcode>5__4, new Vector3(1000f, 1000f, 1000f), Quaternion.identity, Vector3.one); <barcode>5__4 = null; } catch (Exception ex) { <ex>5__5 = ex; ((MelonBase)<>4__this).LoggerInstance.Warning("Could not spawn dummy constrainer: " + <ex>5__5.Message); } <timeoutAt>5__3 = Time.realtimeSinceStartup + 12f; break; case 1: <>1__state = -1; break; } if (<spawnTask>5__2 != null && !<spawnTask>5__2.IsCompleted && Time.realtimeSinceStartup < <timeoutAt>5__3) { <>2__current = null; <>1__state = 1; return true; } if (<spawnTask>5__2 != null && <spawnTask>5__2.IsCompletedSuccessfully) { <poolee>5__6 = <spawnTask>5__2.Result; if ((Object)(object)<poolee>5__6 != (Object)null) { SuppressDummyVisualEffects(((Component)<poolee>5__6).gameObject); <made>5__1 = ((Component)<poolee>5__6).GetComponent<Constrainer>() ?? ((Component)<poolee>5__6).GetComponentInChildren<Constrainer>(true); } <poolee>5__6 = null; } <>4__this._dummyConstrainer = <made>5__1 ?? Object.FindObjectOfType<Constrainer>(); if ((Object)(object)<>4__this._dummyConstrainer != (Object)null) { SuppressDummyVisualEffects(((Component)<>4__this._dummyConstrainer).gameObject); } onResolved?.Invoke(<>4__this._dummyConstrainer); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <HoldKinematicLoadWindow>d__203 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float seconds; public Dictionary<Rigidbody, bool> frozen; private float <endTime>5__1; private float <nextReassertTime>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <HoldKinematicLoadWindow>d__203(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (seconds <= 0f) { return false; } <endTime>5__1 = Time.realtimeSinceStartup + seconds; <nextReassertTime>5__2 = 0f; break; case 1: <>1__state = -1; break; } if (Time.realtimeSinceStartup < <endTime>5__1) { if (Time.realtimeSinceStartup >= <nextReassertTime>5__2) { ReassertFrozenRigidbodies(frozen); <nextReassertTime>5__2 = Time.realtimeSinceStartup + 0.25f; } try { Physics.SyncTransforms(); } catch { } <>2__current = null; <>1__state = 1; return true; } ReassertFrozenRigidbodies(frozen); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <KeepPlayerThere>d__143 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerPoseRecord pose; public Core <>4__this; private RigManager <rigManager>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <KeepPlayerThere>d__143(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <rigManager>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (pose == null) { return false; } break; case 1: <>1__state = -1; <rigManager>5__1 = TryGetRigManager(); if ((Object)(object)<rigManager>5__1 != (Object)null && (Object)(object)<rigManager>5__1.remapHeptaRig != (Object)null) { HoldPlayerThere(<rigManager>5__1, pose, 0.18f); } <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; <rigManager>5__1 = null; break; } if (<>4__this._holdPlayer && <>4__this._loadingNow) { <rigManager>5__1 = TryGetRigManager(); if ((Object)(object)<rigManager>5__1 != (Object)null && (Object)(object)<rigManager>5__1.remapHeptaRig != (Object)null) { HoldPlayerThere(<rigManager>5__1, pose, 0.18f); } <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadCurrentLevelSave>d__172 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string path; public bool automatic; public Core <>4__this; private SceneSaveFile <save>5__1; private Exception <ex>5__2; private <>c__DisplayClass172_0 <>8__3; private bool <movePlayer>5__4; private Dictionary<Rigidbody, bool> <frozen>5__5; private List<Poolee> <made>5__6; private bool[] <done>5__7; private List<int> <order>5__8; private IEnumerator<int> <>s__9; private int <i>5__10; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadCurrentLevelSave>d__172(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 2) <= 20u) { try { } finally { <>m__Finally1(); } } <save>5__1 = null; <ex>5__2 = null; <>8__3 = null; <frozen>5__5 = null; <made>5__6 = null; <done>5__7 = null; <order>5__8 = null; <>s__9 = null; <>1__state = -2; } private bool MoveNext() { //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Expected O, but got Unknown //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0549: Expected O, but got Unknown //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (<>4__this._loadingNow) { return false; } if (onQuest) { <>2__current = <>4__this.LoadCurrentLevelSaveQuest(path, automatic); <>1__state = 1; return true; } try { <save>5__1 = LoadSaveFileQuest(path); } catch (Exception ex) { <ex>5__2 = ex; ((MelonBase)<>4__this).LoggerInstance.Error($"Load failed: {<ex>5__2}"); return false; } if (<save>5__1 == null || <save>5__1.LevelBarcode != <>4__this._levelBarcode) { ((MelonBase)<>4__this).LoggerInstance.Warning("Save file does not match current level, skipping: " + path); return false; } EnsureSaveIds(<save>5__1); <>4__this.CleanSave(<save>5__1); if (<>4__this.IsBlacklisted(<>4__this._levelBarcode) || <>4__this.IsBlacklisted(<save>5__1.LevelBarcode)) { ((MelonBase)<>4__this).LoggerInstance.Msg("Skipping load for blacklisted level: " + <>4__this._levelBarcode); return false; } <>4__this._loadingNow = true; <>1__state = -3; <>8__3 = new <>c__DisplayClass172_0(); NotifySaveLoadStarted(); <>2__current = (object)new WaitForSecondsRealtime(GetLoadDelay(automatic)); <>1__state = 2; return true; case 1: <>1__state = -1; return false; case 2: <>1__state = -3; <movePlayer>5__4 = <>4__this._config.SavePlayerLocation && <save>5__1.PlayerPose != null; if (<movePlayer>5__4) { <>4__this._holdPlayer = true; MelonCoroutines.Start(<>4__this.KeepPlayerThere(<save>5__1.PlayerPose)); <>2__current = <>4__this.MovePlayerWhenReady(<save>5__1.PlayerPose); <>1__state = 3; return true; } goto IL_0363; case 3: <>1__state = -3; goto IL_0363; case 4: <>1__state = -3; <>2__current = <>4__this.DespawnExistingPooleesTimeSliced(); <>1__state = 5; return true; case 5: <>1__state = -3; <frozen>5__5 = new Dictionary<Rigidbody, bool>(UnityObjectComparer<Rigidbody>.Instance); <made>5__6 = Enumerable.Repeat<Poolee>(null, <save>5__1.Objects.Count).ToList(); <done>5__7 = new bool[<save>5__1.Objects.Count]; <order>5__8 = GetSpawnOrder(<save>5__1); <>s__9 = Enumerable.Range(0, <save>5__1.Objects.Count).Except(<order>5__8).GetEnumerator(); try { while (<>s__9.MoveNext()) { <i>5__10 = <>s__9.Current; <done>5__7[<i>5__10] = true; } } finally { if (<>s__9 != null) { <>s__9.Dispose(); } } <>s__9 = null; <>2__current = <>4__this.SpawnSavedObjectsOneAtATime(<save>5__1, <made>5__6, <done>5__7, <frozen>5__5, <order>5__8); <>1__state = 6; return true; case 6: <>1__state = -3; <>2__current = (object)new WaitForSecondsRealtime(0.05f); <>1__state = 7; return true; case 7: <>1__state = -3; <>2__current = <>4__this.ApplyNpcWorldPosePass(<save>5__1, <made>5__6); <>1__state = 8; return true; case 8: <>1__state = -3; <>2__current = (object)new WaitForSecondsRealtime(0.1f); <>1__state = 9; return true; case 9: <>1__state = -3; <>2__current = <>4__this.ApplyNpcWorldPosePass(<save>5__1, <made>5__6); <>1__state = 10; return true; case 10: <>1__state = -3; <>2__current = RestoreSavedRigidbodyStatesTimeSliced(<save>5__1, <made>5__6, <frozen>5__5, keepKinematic: true); <>1__state = 11; return true; case 11: <>1__state = -3; <>4__this.RegrabLoadedRigidbodies(<save>5__1, <made>5__6, <frozen>5__5); ((MelonBase)<>4__this).LoggerInstance.Msg($"Holding loaded rigidbodies kinematic for {3.5f:0.#} seconds."); <>2__current = HoldKinematicLoadWindow(3.5f, <frozen>5__5); <>1__state = 12; return true; case 12: <>1__state = -3; <>2__current = <>4__this.ApplyNpcWorldPosePass(<save>5__1, <made>5__6); <>1__state = 13; return true; case 13: <>1__state = -3; <>4__this.RegrabLoadedRigidbodies(<save>5__1, <made>5__6, <frozen>5__5); <>2__current = RestoreSavedRigidbodyStatesTimeSliced(<save>5__1, <made>5__6, <frozen>5__5, keepKinematic: true); <>1__state = 14; return true; case 14: <>1__state = -3; <>8__3.constrainer = null; <>2__current = <>4__this.GetOrSpawnConstrainer(delegate(Constrainer constrainerInstance) { <>8__3.constrainer = constrainerInstance; }); <>1__state = 15; return true; case 15: <>1__state = -3; <>8__3.joints = 0; <>2__current = <>4__this.RestoreConstraintsWithRetryTimeSliced(<save>5__1, <made>5__6, <>8__3.constrainer, delegate(int got) { <>8__3.joints = got; }); <>1__state = 16; return true; case 16: <>1__state = -3; <>2__current = <>4__this.RestoreNpcHealthTimeSliced(<save>5__1, <made>5__6); <>1__state = 17; return true; case 17: <>1__state = -3; <>2__current = RestoreSavedRigidbodyStatesTimeSliced(<save>5__1, <made>5__6, <frozen>5__5, keepKinematic: false); <>1__state = 18; return true; case 18: <>1__state = -3; <>2__current = <>4__this.StabilizeDeadNpcPosesTimeSliced(<save>5__1, <made>5__6); <>1__state = 19; return true; case 19: <>1__state = -3; UnfreezeRemainingRigidbodies(<frozen>5__5); if (<movePlayer>5__4) { <>4__this._holdPlayer = false; <>2__current = null; <>1__state = 20; return true; } break; case 20: <>1__state = -3; <>2__current = <>4__this.MovePlayerWhenReady(<save>5__1.PlayerPose); <>1__state = 21; return true; case 21: <>1__state = -3; <>2__current = <>4__this.PutPlayerBackAfterLoad(<save>5__1.PlayerPose); <>1__state = 22; return true; case 22: { <>1__state = -3; break; } IL_0363: <>4__this.MarkExistingDeletedPoolees(<save>5__1); <>2__current = <>4__this.DespawnIgnoredPooleesTimeSliced(); <>1__state = 4; return true; } NotifySaveLoadFinished(<made>5__6.Count, <>8__3.joints); ((MelonBase)<>4__this).LoggerInstance.Msg($"Loaded {<made>5__6.Count} saved spawnables and got {<>8__3.joints}/{<save>5__1.Constraints.Count} constraints for {<>4__this._levelBarcode}."); <>8__3 = null; <frozen>5__5 = null; <made>5__6 = null; <done>5__7 = null; <order>5__8 = null; <>m__Finally1(); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; <>4__this._holdPlayer = false; <>4__this._loadingNow = false; } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadCurrentLevelSaveQuest>d__175 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string path; public bool automatic; public Core <>4__this; private SceneSaveFile <save>5__1; private Exception <ex>5__2; private <>c__DisplayClass175_0 <>8__3; private bool <movePlayer>5__4; private Dictionary<Rigidbody, bool> <frozen>5__5; private List<Poolee> <made>5__6; private bool[] <madeFlags>5__7; private List<int> <order>5__8; private IEnumerator<int> <>s__9; private int <i>5__10; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadCurrentLevelSaveQuest>d__175(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 2) <= 25u) { try { } finally { <>m__Finally1(); } } <save>5__1 = null; <ex>5__2 = null; <>8__3 = null; <frozen>5__5 = null; <made>5__6 = null; <madeFlags>5__7 = null; <order>5__8 = null; <>s__9 = null; <>1__state = -2; } private bool MoveNext() { //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0549: Expected O, but got Unknown //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05de: Expected O, but got Unknown //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (string.IsNullOrWhiteSpace(path) || !File.Exists(path)) { return false; } if (automatic) { <>2__current = <>4__this.QuestAutoLoadWait(); <>1__state = 1; return true; } goto IL_0177; case 1: <>1__state = -1; goto IL_0177; case 2: <>1__state = -3; goto IL_030e; case 3: <>1__state = -3; <>2__current = <>4__this.QuestBreather(0.2f); <>1__state = 4; return true; case 4: <>1__state = -3; <>2__current = <>4__this.DespawnExistingPooleesTimeSliced(); <>1__state = 5; return true; case 5: <>1__state = -3; <>2__current = <>4__this.QuestBreather(0.45f, collect: true); <>1__state = 6; return true; case 6: <>1__state = -3; <frozen>5__5 = new Dictionary<Rigidbody, bool>(UnityObjectComparer<Rigidbody>.Instance); <made>5__6 = Enumerable.Repeat<Poolee>(null, <save>5__1.Objects.Count).ToList(); <madeFlags>5__7 = new bool[<save>5__1.Objects.Count]; <order>5__8 = GetSpawnOrder(<save>5__1); <>s__9 = Enumerable.Range(0, <save>5__1.Objects.Count).Except(<order>5__8).GetEnumerator(); try { while (<>s__9.MoveNext()) { <i>5__10 = <>s__9.Current; <madeFlags>5__7[<i>5__10] = true; } } finally { if (<>s__9 != null) { <>s__9.Dispose(); } } <>s__9 = null; <>2__current = <>4__this.SpawnSavedObjectsQuest(<save>5__1, <made>5__6, <madeFlags>5__7, <frozen>5__5, <order>5__8); <>1__state = 7; return true; case 7: <>1__state = -3; <>2__current = <>4__this.QuestBreather(0.45f, collect: true); <>1__state = 8; return true; case 8: <>1__state = -3; <>2__current = (object)new WaitForSecondsRealtime(0.125f); <>1__state = 9; return true; case 9: <>1__state = -3; <>2__current = <>4__this.RestoreQuestObjectStates(<save>5__1, <made>5__6, <frozen>5__5); <>1__state = 10; return true; case 10: <>1__state = -3; <>2__current = <>4__this.ApplyNpcWorldPosePass(<save>5__1, <made>5__6); <>1__state = 11; return true; case 11: <>1__state = -3; <>2__current = (object)new WaitForSecondsRealtime(0.125f); <>1__state = 12; return true; case 12: <>1__state = -3; <>2__current = <>4__this.ApplyNpcWorldPosePass(<save>5__1, <made>5__6); <>1__state = 13; return true; case 13: <>1__state = -3; <>2__current = RestoreSavedRigidbodyStatesTimeSliced(<save>5__1, <made>5__6, <frozen>5__5, keepKinematic: true); <>1__state = 14; return true; case 14: <>1__state = -3; <>4__this.RegrabLoadedRigidbodies(<save>5__1, <made>5__6, <frozen>5__5); ((MelonBase)<>4__this).LoggerInstance.Msg($"Quest holding loaded rigidbodies kinematic for {3.5f:0.#} seconds."); <>2__current = HoldKinematicLoadWindow(3.5f, <frozen>5__5); <>1__state = 15; return true; case 15: <>1__state = -3; <>2__current = <>4__this.QuestBreather(0.25f); <>1__state = 16; return true; case 16: <>1__state = -3; <>2__current = <>4__this.ApplyNpcWorldPosePass(<save>5__1, <made>5__6); <>1__state = 17; return true; case 17: <>1__state = -3; <>4__this.RegrabLoadedRigidbodies(<save>5__1, <made>5__6, <frozen>5__5); <>2__current = RestoreSavedRigidbodyStatesTimeSliced(<save>5__1, <made>5__6, <frozen>5__5, keepKinematic: true); <>1__state = 18; return true; case 18: <>1__state = -3; <>8__3.constrainer = null; <>2__current = <>4__this.GetOrSpawnConstrainer(delegate(Constrainer constrainerInstance) { <>8__3.constrainer = constrainerInstance; }); <>1__state = 19; return true; case 19: <>1__state = -3; <>8__3.joints = 0; <>2__current = <>4__this.RestoreConstraintsWithRetryTimeSliced(<save>5__1, <made>5__6, <>8__3.constrainer, delegate(int got) { <>8__3.joints = got; }); <>1__state = 20; return true; case 20: <>1__state = -3; <>2__current = <>4__this.QuestBreather(0.2f); <>1__state = 21; return true; case 21: <>1__state = -3; <>2__current = <>4__this.RestoreNpcHealthTimeSliced(<save>5__1, <made>5__6); <>1__state = 22; return true; case 22: <>1__state = -3; <>2__current = RestoreSavedRigidbodyStatesTimeSliced(<save>5__1, <made>5__6, <frozen>5__5, keepKinematic: false); <>1__state = 23; return true; case 23: <>1__state = -3; <>2__current = <>4__this.StabilizeDeadNpcPosesTimeSliced(<save>5__1, <made>5__6); <>1__state = 24; return true; case 24: <>1__state = -3; UnfreezeRemainingRigidbodies(<frozen>5__5); if (<movePlayer>5__4) { <>2__current = null; <>1__state = 25; return true; } break; case 25: <>1__state = -3; <>2__current = <>4__this.MovePlayerWhenReady(<save>5__1.PlayerPose); <>1__state = 26; return true; case 26: <>1__state = -3; <>2__current = <>4__this.PutPlayerBackAfterLoad(<save>5__1.PlayerPose); <>1__state = 27; return true; case 27: { <>1__state = -3; break; } IL_0177: try { <save>5__1 = LoadSaveFileQuest(path); } catch (Exception ex) { <ex>5__2 = ex; ((MelonBase)<>4__this).LoggerInstance.Error($"Quest load failed while reading save: {<ex>5__2}"); return false; } if (<save>5__1 == null || <save>5__1.LevelBarcode != <>4__this._levelBarcode) { ((MelonBase)<>4__this).LoggerInstance.Warning("Quest save file does not match current level, skipping: " + path); return false; } EnsureSaveIds(<save>5__1); <>4__this.CleanSave(<save>5__1); if (<>4__this.IsBlacklisted(<>4__this._levelBarcode) || <>4__this.IsBlacklisted(<save>5__1.LevelBarcode)) { ((MelonBase)<>4__this).LoggerInstance.Msg("Quest load skipped for blacklisted level: " + <>4__this._levelBarcode); return false; } <>4__this._loadingNow = true; <>1__state = -3; <>8__3 = new <>c__DisplayClass175_0(); NotifySaveLoadStarted(); if (!automatic) { <>2__current = (object)new WaitForSecondsRealtime(0.05f); <>1__state = 2; return true; } goto IL_030e; IL_030e: <movePlayer>5__4 = <>4__this._config.SavePlayerLocation && <save>5__1.PlayerPose != null; <>4__this.MarkExistingDeletedPoolees(<save>5__1); <>2__current = <>4__this.DespawnIgnoredPooleesTimeSliced(); <>1__state = 3; return true; } NotifySaveLoadFinished(<made>5__6.Count, <>8__3.joints); ((MelonBase)<>4__this).LoggerInstance.Msg($"Quest loaded {<made>5__6.Count} saved spawnables and got {<>8__3.joints}/{<save>5__1.Constraints.Count} constraints for {<>4__this._levelBarcode}."); <>8__3 = null; <frozen>5__5 = null; <made>5__6 = null; <madeFlags>5__7 = null; <order>5__8 = null; <>m__Finally1(); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; <>4__this._holdPlayer = false; <>4__this._loadingNow = false; } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <MovePlayerWhenReady>d__142 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerPoseRecord pose; public Core <>4__this; private int <i>5__1; private RigManager <rigManager>5__2; private int <repeat>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <MovePlayerWhenReady>d__142(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <rigManager>5__2 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (pose == null) { return false; } <i>5__1 = 0; goto IL_011f; case 1: <>1__state = -1; <repeat>5__3++; goto IL_00df; case 2: { <>1__state = -1; <rigManager>5__2 = null; <i>5__1++; goto IL_011f; } IL_00df: if (<repeat>5__3 < 8) { HoldPlayerThere(<rigManager>5__2, pose, 0.18f); <>2__current = null; <>1__state = 1; return true; } return false; IL_011f: if (<i>5__1 < 180) { <rigManager>5__2 = TryGetRigManager(); if ((Object)(object)<rigManager>5__2 != (Object)null && (Object)(object)<rigManager>5__2.remapHeptaRig != (Object)null) { TeleportPlayerToPose(<rigManager>5__2, pose, 0.18f); <repeat>5__3 = 0; goto IL_00df; } <>2__current = null; <>1__state = 2; return true; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PutPlayerBackAfterLoad>d__144 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerPoseRecord pose; public Core <>4__this; private int <i>5__1; private RigManager <rigManager>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PutPlayerBackAfterLoad>d__144(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <rigManager>5__2 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (pose == null) { return false; } <i>5__1 = 0; break; case 1: <>1__state = -1; <rigManager>5__2 = null; <i>5__1++; break; } if (<i>5__1 < 10) { <rigManager>5__2 = TryGetRigManager(); if ((Object)(object)<rigManager>5__2 != (Object)null && (Object)(object)<rigManager>5__2.remapHeptaRig != (Object)null) { HoldPlayerThere(<rigManager>5__2, pose, 0.04f); } <>2__current = null; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <QuestAutoLoadWait>d__176 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <QuestAutoLoadWait>d__176(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; NotifyQuestAutoLoadSoon(); <>2__current = (object)new WaitForSecondsRealtime(5f); <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <QuestBreather>d__186 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float seconds; public bool collect; public Core <>4__this; private AsyncOperation <op>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <QuestBreather>d__186(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <op>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!onQuest) { return false; } if (collect) { GC.Collect(); <op>5__1 = Resources.UnloadUnusedAssets(); goto IL_007a; } goto IL_009f; case 1: <>1__state = -1; goto IL_007a; case 2: <>1__state = -1; break; case 3: { <>1__state = -1; break; } IL_007a: if (<op>5__1 != null && !<op>5__1.isDone) { <>2__current = null; <>1__state = 1; return true; } <op>5__1 = null; goto IL_009f; IL_009f: if (seconds > 0f) { <>2__current = (object)new WaitForSecondsRealtime(seconds); <>1__state = 2; return true; } <>2__current = null; <>1__state = 3; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RefreshSaveQuitSoon>d__75 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private int <i>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RefreshSaveQuitSoon>d__75(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <i>5__1 = 0; break; case 1: <>1__state = -1; <i>5__1++; break; } if (<i>5__1 < 30) { <>4__this.MakeSaveQuitButton(); if ((Object)(object)<>4__this._saveQuitObj != (Object)null && !((Il2CppObjectBase)<>4__this._saveQuitObj).WasCollected) { return false; } <>2__current = null; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RestoreConstraintsTimeSliced>d__212 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public Constrainer constrainer; public HashSet<int> doneJoints; public Action<int> onDone; public Core <>4__this; private int <got>5__1; private Stopwatch <stopwatch>5__2; private int <i>5__3; private ConstraintRecord <record>5__4; private Exception <ex>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreConstraintsTimeSliced>d__212(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__2 = null; <record>5__4 = null; <ex>5__5 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__2.Restart(); goto IL_019f; } <>1__state = -1; if ((Object)(object)constrainer == (Object)null) { onDone?.Invoke(doneJoints?.Count ?? 0); return false; } <got>5__1 = doneJoints?.Count ?? 0; <stopwatch>5__2 = Stopwatch.StartNew(); <i>5__3 = 0; goto IL_01b9; IL_01b9: if (<i>5__3 < save.Constraints.Count) { if (doneJoints != null && doneJoints.Contains(<i>5__3)) { goto IL_01a7; } <record>5__4 = save.Constraints[<i>5__3]; try { if (<>4__this.RestoreConstraint(<record>5__4, save, made, constrainer)) { <got>5__1++; doneJoints?.Add(<i>5__3); } } catch (Exception ex) { <ex>5__5 = ex; ((MelonBase)<>4__this).LoggerInstance.Warning("Failed to restore constraint: " + <ex>5__5.Message); } if (<stopwatch>5__2.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } goto IL_019f; } onDone?.Invoke(<got>5__1); return false; IL_01a7: <i>5__3++; goto IL_01b9; IL_019f: <record>5__4 = null; goto IL_01a7; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RestoreConstraintsWithRetryTimeSliced>d__211 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public Constrainer constrainer; public Action<int> onDone; public Core <>4__this; private <>c__DisplayClass211_0 <>8__1; private HashSet<int> <doneJoints>5__2; private int <pass>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreConstraintsWithRetryTimeSliced>d__211(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <doneJoints>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass211_0(); <>8__1.constrainer = constrainer; <doneJoints>5__2 = new HashSet<int>(); <>8__1.got = 0; <pass>5__3 = 0; goto IL_019e; case 1: <>1__state = -1; goto IL_00a4; case 2: <>1__state = -1; goto IL_011d; case 3: { <>1__state = -1; <pass>5__3++; goto IL_019e; } IL_019e: if (<pass>5__3 >= 3 || <>8__1.got >= save.Constraints.Count) { break; } if (<pass>5__3 > 0) { <>2__current = (object)new WaitForSecondsRealtime(0.35f); <>1__state = 1; return true; } goto IL_00a4; IL_00a4: if ((Object)(object)<>8__1.constrainer == (Object)null || ((Il2CppObjectBase)<>8__1.constrainer).WasCollected) { <>2__current = <>4__this.GetOrSpawnConstrainer(delegate(Constrainer constrainerInstance) { <>8__1.constrainer = constrainerInstance; }); <>1__state = 2; return true; } goto IL_011d; IL_011d: <>2__current = <>4__this.RestoreConstraintsTimeSliced(save, made, <>8__1.constrainer, <doneJoints>5__2, delegate(int count) { <>8__1.got = count; }); <>1__state = 3; return true; } if (<>8__1.got < save.Constraints.Count) { ((MelonBase)<>4__this).LoggerInstance.Warning($"Restored {<>8__1.got}/{save.Constraints.Count} constraints after delayed retry."); } onDone?.Invoke(<>8__1.got); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RestoreNpcHealthTimeSliced>d__189 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public Core <>4__this; private Stopwatch <stopwatch>5__1; private int <i>5__2; private SavedObject <thing>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreNpcHealthTimeSliced>d__189(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__1 = null; <thing>5__3 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__1.Restart(); goto IL_00f9; } <>1__state = -1; <stopwatch>5__1 = Stopwatch.StartNew(); <i>5__2 = 0; goto IL_0113; IL_0113: if (<i>5__2 < save.Objects.Count && <i>5__2 < made.Count) { <thing>5__3 = save.Objects[<i>5__2]; if (<thing>5__3?.Health == null || (Object)(object)made[<i>5__2] == (Object)null) { goto IL_0101; } <>4__this.RestoreHealth(made[<i>5__2], <thing>5__3.Health); if (<stopwatch>5__1.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } goto IL_00f9; } return false; IL_0101: <i>5__2++; goto IL_0113; IL_00f9: <thing>5__3 = null; goto IL_0101; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RestoreQuestObjectStates>d__182 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public Dictionary<Rigidbody, bool> frozen; public Core <>4__this; private Stopwatch <stopwatch>5__1; private int <i>5__2; private Poolee <poolee>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreQuestObjectStates>d__182(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__1 = null; <poolee>5__3 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__1.Restart(); goto IL_00fc; } <>1__state = -1; <stopwatch>5__1 = Stopwatch.StartNew(); <i>5__2 = 0; goto IL_0116; IL_0116: if (<i>5__2 < save.Objects.Count && <i>5__2 < made.Count) { <poolee>5__3 = made[<i>5__2]; if ((Object)(object)<poolee>5__3 == (Object)null || ((Il2CppObjectBase)<poolee>5__3).WasCollected) { goto IL_0104; } <>4__this.RestoreObjectState(<poolee>5__3, save.Objects[<i>5__2], keepRigidbodiesFrozen: true); FreezePooleeRigidbodies(<poolee>5__3, frozen); if (<stopwatch>5__1.Elapsed.TotalMilliseconds >= 3.0) { <>2__current = null; <>1__state = 1; return true; } goto IL_00fc; } return false; IL_0104: <i>5__2++; goto IL_0116; IL_00fc: <poolee>5__3 = null; goto IL_0104; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RestoreSavedRigidbodyStatesTimeSliced>d__202 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public Dictionary<Rigidbody, bool> frozen; public bool keepKinematic; private Stopwatch <stopwatch>5__1; private int <i>5__2; private Poolee <poolee>5__3; private SavedObject <obj>5__4; private bool <keepDeadNpcFrozen>5__5; private List<TransformRecord>.Enumerator <>s__6; private TransformRecord <record>5__7; private Transform <transform>5__8; private Rigidbody <rb>5__9; private Vector3 <velocity>5__10; private Vector3 <angularVelocity>5__11; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreSavedRigidbodyStatesTimeSliced>d__202(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <stopwatch>5__1 = null; <poolee>5__3 = null; <obj>5__4 = null; <>s__6 = default(List<TransformRecord>.Enumerator); <record>5__7 = null; <transform>5__8 = null; <rb>5__9 = null; <>1__state = -2; } private bool MoveNext() { //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -3; <stopwatch>5__1.Restart(); goto IL_0334; } <>1__state = -1; <stopwatch>5__1 = Stopwatch.StartNew(); <i>5__2 = 0; goto IL_038e; IL_0187: <rb>5__9.isKinematic = (keepKinematic | <keepDeadNpcFrozen>5__5) || <record>5__7.Rigidbody.IsKinematic; <rb>5__9.useGravity = <record>5__7.Rigidbody.UseGravity; <velocity>5__10 = <record>5__7.Rigidbody.Velocity.ToUnity(); <angularVelocity>5__11 = <record>5__7.Rigidbody.AngularVelocity.ToUnity(); <rb>5__9.velocity = ((keepKinematic | <keepDeadNpcFrozen>5__5) ? Vector3.zero : <velocity>5__10); <rb>5__9.angularVelocity = ((keepKinematic | <keepDeadNpcFrozen>5__5) ? Vector3.zero : <angularVelocity>5__11); if (keepKinematic) { ClearRigidbodyMotion(<rb>5__9); } else { frozen.Remove(<rb>5__9); if (!<keepDeadNpcFrozen>5__5 && !<record>5__7.Rigidbody.IsKinematic) { <rb>5__9.WakeUp(); <rb>5__9.velocity = <velocity>5__10; <rb>5__9.angularVelocity = <angularVelocity>5__11; } } if (<stopwatch>5__1.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } goto IL_0334; IL_037c: <i>5__2++; goto IL_038e; IL_0334: <transform>5__8 = null; <rb>5__9 = null; <record>5__7 = null; goto IL_034a; IL_034a: while (<>s__6.MoveNext()) { <record>5__7 = <>s__6.Current; if (<record>5__7.Rigidbody == null) { continue; } <transform>5__8 = ResolveBySiblingPath(((Component)<poolee>5__3).transform, <record>5__7.SiblingPath); if ((Object)(object)<transform>5__8 == (Object)null) { <transform>5__8 = ResolveRelativePath(((Component)<poolee>5__3).transform, <record>5__7.Path); } if ((Object)(object)<transform>5__8 == (Object)null) { continue; } <rb>5__9 = ((Component)<transform>5__8).GetComponent<Rigidbody>(); if ((Object)(object)<rb>5__9 == (Object)null) { continue; } goto IL_0187; } <>m__Finally1(); <>s__6 = default(List<TransformRecord>.Enumerator); <poolee>5__3 = null; <obj>5__4 = null; goto IL_037c; IL_038e: if (<i>5__2 < save.Objects.Count && <i>5__2 < made.Count) { <poolee>5__3 = made[<i>5__2]; <obj>5__4 = save.Objects[<i>5__2]; if ((Object)(object)<poolee>5__3 == (Object)null || <obj>5__4 == null) { goto IL_037c; } <keepDeadNpcFrozen>5__5 = IsDeadNpcObject(<obj>5__4); <>s__6 = <obj>5__4.Transforms.GetEnumerator(); <>1__state = -3; goto IL_034a; } return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__6).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SpawnOneQuest>d__181 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SavedObject thing; public List<Poolee> made; public bool[] madeFlags; public Dictionary<Rigidbody, bool> frozen; public List<int> slow; public int i; public bool retry; public Core <>4__this; private Task<Poolee> <task>5__1; private float <waitForIt>5__2; private float <timeoutAt>5__3; private Poolee <poolee>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnOneQuest>d__181(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <task>5__1 = null; <poolee>5__4 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (thing == null || i < 0 || i >= madeFlags.Length || madeFlags[i]) { return false; } <task>5__1 = <>4__this.SpawnSavedObject(thing); <waitForIt>5__2 = (retry ? 16f : 8f); <timeoutAt>5__3 = Time.realtimeSinceStartup + <waitForIt>5__2; break; case 1: <>1__state = -1; break; } if (!<task>5__1.IsCompleted && Time.realtimeSinceStartup < <timeoutAt>5__3) { <>2__current = null; <>1__state = 1; return true; } if (!<task>5__1.IsCompleted) { if (!retry) { slow?.Add(i); } else { ((MelonBase)<>4__this).LoggerInstance.Warning("Quest skipped slow spawnable after waiting: " + thing.Barcode); } return false; } if (<task>5__1.IsFaulted) { ((MelonBase)<>4__this).LoggerInstance.Warning("Failed to spawn " + thing.Barcode + ": " + <task>5__1.Exception?.GetBaseException().Message); madeFlags[i] = true; return false; } <poolee>5__4 = <task>5__1.Result; if ((Object)(object)<poolee>5__4 == (Object)null) { if (!retry) { slow?.Add(i); } else { madeFlags[i] = true; } return false; } made[i] = <poolee>5__4; <>4__this.RememberLoadedSaveId(<poolee>5__4, thing); TouchLoadedPoolee(<poolee>5__4, thing, frozen); madeFlags[i] = true; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SpawnOneSavedObject>d__183 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public bool[] done; public Dictionary<Rigidbody, bool> frozen; public Dictionary<int, Task<Poolee>> running; public List<int> slow; public int i; public bool retry; public Core <>4__this; private Task<Poolee> <task>5__1; private float <timeoutAt>5__2; private Poolee <poolee>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnOneSavedObject>d__183(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <task>5__1 = null; <poolee>5__3 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (i < 0 || i >= save.Objects.Count || done[i]) { return false; } <task>5__1 = null; running.TryGetValue(i, out <task>5__1); if (<task>5__1 == null || <task>5__1.IsFaulted || (retry && <task>5__1.IsCompleted && (Object)(object)<task>5__1.Result == (Object)null)) { <task>5__1 = <>4__this.SpawnSavedObject(save.Objects[i]); running[i] = <task>5__1; } <timeoutAt>5__2 = Time.realtimeSinceStartup + 1f; break; case 1: <>1__state = -1; break; } if (!<task>5__1.IsCompleted && Time.realtimeSinceStartup < <timeoutAt>5__2) { <>2__current = null; <>1__state = 1; return true; } if (!<task>5__1.IsCompleted) { if (!retry) { slow?.Add(i); } else { ((MelonBase)<>4__this).LoggerInstance.Warning("Still waiting on slow spawnable after retry: " + save.Objects[i].Barcode); } return false; } if (<task>5__1.IsFaulted) { ((MelonBase)<>4__this).LoggerInstance.Warning("Failed to spawn " + save.Objects[i].Barcode + ": " + <task>5__1.Exception?.GetBaseException().Message); done[i] = true; return false; } <poolee>5__3 = <task>5__1.Result; if ((Object)(object)<poolee>5__3 == (Object)null) { if (!retry) { slow?.Add(i); } else { ((MelonBase)<>4__this).LoggerInstance.Warning("Spawn returned null for " + save.Objects[i].Barcode); done[i] = true; } return false; } made[i] = <poolee>5__3; <>4__this.RememberLoadedSaveId(<poolee>5__3, save.Objects[i]); TouchLoadedPoolee(<poolee>5__3, save.Objects[i], frozen); <>4__this.RestoreObjectState(<poolee>5__3, save.Objects[i], keepRigidbodiesFrozen: true); done[i] = true; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SpawnSavedObjectsOneAtATime>d__179 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public bool[] done; public Dictionary<Rigidbody, bool> frozen; public List<int> order; public Core <>4__this; private Dictionary<int, Task<Poolee>> <running>5__1; private List<int> <slow>5__2; private List<int>.Enumerator <>s__3; private int <i>5__4; private int[] <>s__5; private int <>s__6; private int <i>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnSavedObjectsOneAtATime>d__179(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <running>5__1 = null; <slow>5__2 = null; <>s__3 = default(List<int>.Enumerator); <>s__5 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <running>5__1 = new Dictionary<int, Task<Poolee>>(); <slow>5__2 = new List<int>(); <>s__3 = order.GetEnumerator(); <>1__state = -3; goto IL_00cb; case 1: <>1__state = -3; goto IL_00cb; case 2: { <>1__state = -1; <>s__6++; break; } IL_00cb: if (<>s__3.MoveNext()) { <i>5__4 = <>s__3.Current; <>2__current = <>4__this.SpawnOneSavedObject(save, made, done, frozen, <running>5__1, <slow>5__2, <i>5__4, retry: false); <>1__state = 1; return true; } <>m__Finally1(); <>s__3 = default(List<int>.Enumerator); if (<slow>5__2.Count <= 0) { return false; } ((MelonBase)<>4__this).LoggerInstance.Msg($"Retrying {<slow>5__2.Count} slow spawnables after the first pass."); <>s__5 = <slow>5__2.ToArray(); <>s__6 = 0; break; } if (<>s__6 < <>s__5.Length) { <i>5__7 = <>s__5[<>s__6]; <>2__current = <>4__this.SpawnOneSavedObject(save, made, done, frozen, <running>5__1, null, <i>5__7, retry: true); <>1__state = 2; return true; } <>s__5 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__3).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SpawnSavedObjectsQuest>d__180 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public bool[] madeFlags; public Dictionary<Rigidbody, bool> frozen; public List<int> order; public Core <>4__this; private List<int> <slow>5__1; private List<int>.Enumerator <>s__2; private int <i>5__3; private SavedObject <thing>5__4; private int[] <>s__5; private int <>s__6; private int <i>5__7; private SavedObject <thing>5__8; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnSavedObjectsQuest>d__180(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 2u) { try { } finally { <>m__Finally1(); } } <slow>5__1 = null; <>s__2 = default(List<int>.Enumerator); <thing>5__4 = null; <>s__5 = null; <thing>5__8 = null; <>1__state = -2; } private bool MoveNext() { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <slow>5__1 = new List<int>(); <>s__2 = order.GetEnumerator(); <>1__state = -3; goto IL_0152; case 1: <>1__state = -3; <>2__current = <>4__this.SpawnOneQuest(<thing>5__4, made, madeFlags, frozen, <slow>5__1, <i>5__3, retry: false); <>1__state = 2; return true; case 2: <>1__state = -3; <>2__current = (object)new WaitForSecondsRealtime(0.12f); <>1__state = 3; return true; case 3: <>1__state = -3; <thing>5__4 = null; goto IL_0152; case 4: <>1__state = -1; <>s__5 = <slow>5__1.ToArray(); <>s__6 = 0; break; case 5: <>1__state = -1; <>2__current = <>4__this.SpawnOneQuest(<thing>5__8, made, madeFlags, frozen, null, <i>5__7, retry: true); <>1__state = 6; return true; case 6: <>1__state = -1; <>2__current = (object)new WaitForSecondsRealtime(0.24f); <>1__state = 7; return true; case 7: { <>1__state = -1; <thing>5__8 = null; <>s__6++; break; } IL_0152: if (<>s__2.MoveNext()) { <i>5__3 = <>s__2.Current; <thing>5__4 = save.Objects[<i>5__3]; <>2__current = null; <>1__state = 1; return true; } <>m__Finally1(); <>s__2 = default(List<int>.Enumerator); if (<slow>5__1.Count <= 0) { return false; } ((MelonBase)<>4__this).LoggerInstance.Msg($"Quest retry pass for {<slow>5__1.Count} slow spawnables."); <>2__current = <>4__this.QuestBreather(0.45f, collect: true); <>1__state = 4; return true; } if (<>s__6 < <>s__5.Length) { <i>5__7 = <>s__5[<>s__6]; <thing>5__8 = save.Objects[<i>5__7]; <>2__current = null; <>1__state = 5; return true; } <>s__5 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__2).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <StabilizeDeadNpcPosesTimeSliced>d__205 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List<Poolee> made; public Core <>4__this; private Stopwatch <releaseStopwatch>5__1; private int <pass>5__2; private Stopwatch <stopwatch>5__3; private int <i>5__4; private int <i>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <StabilizeDeadNpcPosesTimeSliced>d__205(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <releaseStopwatch>5__1 = null; <stopwatch>5__3 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <pass>5__2 = 0; goto IL_01bc; case 1: <>1__state = -1; <stopwatch>5__3.Restart(); goto IL_0132; case 2: <>1__state = -1; <stopwatch>5__3 = null; <pass>5__2++; goto IL_01bc; case 3: { <>1__state = -1; <releaseStopwatch>5__1.Restart(); goto IL_029c; } IL_01bc: if (<pass>5__2 < 10) { <stopwatch>5__3 = Stopwatch.StartNew(); <i>5__4 = 0; goto IL_0144; } <releaseStopwatch>5__1 = Stopwatch.StartNew(); <i>5__5 = 0; goto IL_02ae; IL_0132: <i>5__4++; goto IL_0144; IL_02ae: if (<i>5__5 >= save.Objects.Count || <i>5__5 >= made.Count) { break; } if (IsDeadNpcObject(save.Objects[<i>5__5]) && !((Object)(object)made[<i>5__5] == (Object)null)) { ReleaseDeadNpcRigidbodies(made[<i>5__5], save.Objects[<i>5__5]); if (<releaseStopwatch>5__1.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 3; return true; } } goto IL_029c; IL_029c: <i>5__5++; goto IL_02ae; IL_0144: if (<i>5__4 < save.Objects.Count && <i>5__4 < made.Count) { if (IsDeadNpcObject(save.Objects[<i>5__4]) && !((Object)(object)made[<i>5__4] == (Object)null)) { <>4__this.ApplySavedTransforms(made[<i>5__4], save.Objects[<i>5__4], restoreWorldPose: true, keepRigidbodiesFrozen: true); ClearPooleeRigidbodyMotion(made[<i>5__4]); if (<stopwatch>5__3.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } goto IL_0132; } try { Physics.SyncTransforms(); } catch { } <>2__current = null; <>1__state = 2; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string ModVersion = "1.0.0"; private const string SaveExtension = ".json"; private const string ConfigFileName = "config.json"; private const string DefaultPlayerRigBarcode = "SLZ.BONELAB.Core.DefaultPlayerRig"; private const string BlankRigBarcode = "SLZ.BONELAB.Core.Spawnable.RigManagerBlank"; private const float SystemObjectDistance = 500f; private const float LoadInitialDelaySeconds = 0.05f; private const float AutoLoadInitialDelaySeconds = 1.25f; private const float QuestAutoLoadInitialDelaySeconds = 5f; private const double RestoreBudgetMs = 4.5; private const double QuestTimeSliceMs = 3.0; private const float SpawnItemTimeoutSeconds = 1f; private const float ZoneMissingPreserveDistance = 12f; private const float CrateSpawnerMatchDistance = 4f; private const float CrateSpawnerDeleteMatchDistance = 25f; private const float LoadKinematicHoldSeconds = 3.5f; private const float PlayerLoadLift = 0.18f; private const float PlayerLoadSettleLift = 0.04f; private const string MainMenuBarcode = "c2534c5a-80e1-4a29-93ca-f3254d656e75"; private const string VoidG114Barcode = "fa534c5a868247138f50c62e424c4144.Level.VoidG114"; private const float QuestSpawnWaitSeconds = 8f; private const float QuestSpawnRetryWaitSeconds = 16f; private const float QuestSpawnGapSeconds = 0.12f; private const float QuestBigBreathSeconds = 0.45f; private static readonly (string Name, string Barcode)[] defaultBlacklist = new(string, string)[24] { ("00-MainMenu", "c2534c5a-80e1-4a29-93ca-f3254d656e75"), ("01-Descent", "c2534c5a-4197-4879-8cd3-4a695363656e"), ("03-LongRun", "c2534c5a-56a6-40ab-a8ce-23074c657665"), ("04-MineDive", "c2534c5a-54df-470b-baaf-741f4c657665"), ("05-BigAnomaly", "c2534c5a-7601-4443-bdfe-7f235363656e"), ("06-StreetPuncher", "SLZ.BONELAB.Content.Level.LevelStreetPunch"), ("07-SprintBridge", "SLZ.BONELAB.Content.Level.SprintBridge04"), ("08-MagmaGate", "SLZ.BONELAB.Content.Level.SceneMagmaGate"), ("09-Moonbase", "SLZ.BONELAB.Content.Level.MoonBase"), ("10-MonogonMotorway", "SLZ.BONELAB.Content.Level.LevelKartRace"), ("11-PillarClimb", "c2534c5a-c056-4883-ac79-e051426f6964"), ("12-BigAnomaly2", "SLZ.BONELAB.Content.Level.LevelBigAnomalyB"), ("13-Ascent", "c2534c5a-db71-49cf-b694-24584c657665"), ("14-Home", "SLZ.BONELAB.Content.Level.LevelOutro"), ("NeonTrial", "c2534c5a-4f3b-480e-ad2f-69175363656e"), ("DropPit", "c2534c5a-de61-4df9-8f6c-416954726547"), ("TunnelTipper", "c2534c5a-c180-40e0-b2b7-325c5363656e"), ("FantasyArena", "fa534c5a868247138f50c62e424c4144.Level.LevelArenaMin"), ("ContainerYard", "c2534c5a-162f-4661-a04d-975d5363656e"), ("DungeonWarrior", "c2534c5a-5c2f-4eef-a851-66214c657665"), ("Rooftops", "c2534c5a-c6ac-48b4-9c5f-b5cd5363656e"), ("NeonParkour", "fa534c5a83ee4ec6bd641fec424c4142.Level.SceneparkourDistrictLogic"), ("LoadDefault", "fa534c5a83ee4ec6bd641fec424c4142.Level.DefaultLoad"), ("LoadMod", "SLZ.BONELAB.CORE.Level.LevelModLevelLoad") }; private static readonly HashSet<string> dontSaveThese = new HashSet<string>(StringComparer.Ordinal) { "Lakatrazz.FusionContent.Spawnable.AchievementBoard", "Lakatrazz.FusionContent.Spawnable.BitMart", "Lakatrazz.FusionContent.Spawnable.InfoBoard" }; private static readonly JsonSerializerOptions jsonOpts = new JsonSerializerOptions { WriteIndented = true, IncludeFields = false }; private string _homeDir; private string _saveFolder; private string _cfg; private SceneSaveConfig _config = new SceneSaveConfig(); private Page _page; private Page _savePage; private Page _banPage; private Page _manual; private string _levelBarcode; private string _levelTitle; private Constrainer _dummyConstrainer; private bool _inLevel; private bool _savingNow; private bool _loadingNow; private bool _savedThisTrip; private bool _quitSaved; private bool _jumpTried; private Action _quitHook; private Poolee[] _poolCache; private float _poolCacheAt = -999f; private CrateSpawner[] _spawnerCache; private float _spawnerCacheAt = -999f; private readonly Dictionary<IntPtr, string> _savedIds = new Dictionary<IntPtr, string>(); private readonly Dictionary<string, Poolee> _loadedIds = new Dictionary<string, Poolee>(StringComparer.Ordinal); private readonly HashSet<string> _deletedIds = new HashSet<string>(StringComparer.Ordinal); private readonly HashSet<IntPtr> _deadPtrs = new HashSet<IntPtr>(); private GameObject _saveQuitObj; private Button _saveQuitBtn; private static readonly string[] switchyBoolNames = new string[26] { "isOn", "_isOn", "m_isOn", "IsOn", "on", "_on", "m_On", "isToggled", "_isToggled", "toggled", "_toggled", "isActivated", "_isActivated", "activated", "_activated", "isActive", "_isActive", "m_IsActive", "powered", "_powered", "isPowered", "_isPowered", "lightOn", "_lightOn", "flashlightOn", "_flashlightOn" }; private static readonly string[] switchyFloatNames = new string[3] { "intensity", "_intensity", "m_Intensity" }; private bool _holdPlayer; private static Transform _constraintDummyTransform; private static bool onQuest => HelperMethods.IsAndroid(); private static double restoreBudget => onQuest ? 3.0 : 4.5; internal static Core Current { get; private set; } public override void OnInitializeMelon() { Current = this; _homeDir = Path.Combine(SaveRoot(), "SceneSave"); _saveFolder = Path.Combine(_homeDir, "SaveFiles"); _cfg = Path.Combine(_homeDir, "config.json"); Directory.CreateDirectory(_homeDir); Directory.CreateDirectory(_saveFolder); LoadConfig(); SpawnBits.Init(((MelonBase)this).HarmonyInstance); PooleeHooks.Init(((MelonBase)this).HarmonyInstance); JointBits.Init(((MelonBase)this).HarmonyInstance); NpcBits.Init(((MelonBase)this).HarmonyInstance); LevelHooks.Init(((MelonBase)this).HarmonyInstance); BuildBoneMenu(); Hooking.OnLevelLoading += OnLevelLoading; Hooking.OnLevelLoaded += OnLevelLoaded; Hooking.OnLevelUnloaded += OnLevelUnloaded; Hooking.OnUIRigCreated += OnUIRigCreated; _quitHook = OnUnityQuitting; Application.quitting += Action.op_Implicit(_quitHook); ((MelonBase)this).LoggerInstance.Msg("Initialized. Saves: " + _saveFolder); } private static string SaveRoot() { if (onQuest) { return MelonEnvironment.UserDataDirectory; } return MelonEnvironment.MelonBaseDirectory; } public override void OnSceneWasInitialized(int buildIndex, string sceneName) { if (!_jumpTried && !string.IsNullOrWhiteSpace(sceneName) && sceneName.Contains("BOOTSTRAP", StringComparison.OrdinalIgnoreCase)) { _jumpTried = true; if (HasLastLevelToOpen()) { AssetWarehouse.OnReady(Action.op_Implicit((Action)StartupJump)); } } } public override void OnDeinitializeMelon() { if (!_quitSaved) { SaveOnTheWayOut("melon shutdown"); } if (_quitHook != null) { Application.quitting -= Action.op_Implicit(_quitHook); _quitHook = null; } Hooking.OnUIRigCreated -= OnUIRigCreated; if (Current == this) { Current = null; } } public override void OnApplicationQuit() { SaveOnTheWayOut("application quit"); } private void OnUnityQuitting() { SaveOnTheWayOut("unity quitting"); } private void OnLevelLoading(LevelInfo nextLevel) { if (!_savedThisTrip && _inLevel && !string.IsNullOrWhiteSpace(_levelBarcode)) { SaveCurrentLevel("level loading"); _savedThisTrip = true; } ClearRuntimeJunk(); _savedIds.Clear(); _loadedIds.Clear(); _deletedIds.Clear(); _deadPtrs.Clear(); _inLevel = false; KillSaveQuitButton(); } private void OnLevelLoaded(LevelInfo info) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) ClearRuntimeJunk(); _savedIds.Clear(); _loadedIds.Clear(); _deletedIds.Clear(); _deadPtrs.Clear(); _levelBarcode = info.barcode; _levelTitle = info.title; _inLevel = true; _savedThisTrip = false; _quitSaved = false; DropFindCache(); RefreshBoneMenu(); MelonCoroutines.Start(RefreshSaveQuitSoon()); if (IsBlacklisted(_levelBarcode)) { ForgetLast(); ((MelonBase)this).LoggerInstance.Msg("Level is blacklisted, skipping load: " + _levelBarcode); return; } RememberLevel(info); string savePath = GetSavePath(_levelBarcode); if (string.IsNullOrWhiteSpace(savePath)) { ((MelonBase)this).LoggerInstance.Msg("No save for level: " + _levelBarcode); } else { MelonCoroutines.Start(LoadCurrentLevelSave(savePath, automatic: true)); } } private void OnLevelUnloaded() { if (!_savedThisTrip && _inLevel && !string.IsNullOrWhiteSpace(_levelBarcode)) { ((MelonBase)this).LoggerInstance.Warning("Skipping late level-unloaded save; the scene is already tearing down."); } ClearRuntimeJunk(); DropFindCache(); _savedIds.Clear(); _loadedIds.Clear(); _deletedIds.Clear(); _deadPtrs.Clear(); _inLevel = false; _levelTitle = null; _savedThisTrip = false; KillSaveQuitButton(); } internal void SaveBeforeSceneStreamerLoad(string reason) { if (!_savedThisTrip && _inLevel && !string.IsNullOrWhiteSpace(_levelBarcode) && SaveCurrentLevel(reason)) { _savedThisTrip = true; } } private static void ClearRuntimeJunk() { SpawnBits.Clear(); NpcBits.Clear(); JointBits.Clear(); } private void OnUIRigCreated() { MakeSaveQuitButton(); } [IteratorStateMachine(typeof(<RefreshSaveQuitSoon>d__75))] private IEnumerator RefreshSaveQuitSoon() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RefreshSaveQuitSoon>d__75(0) { <>4__this = this }; } private void MakeSaveQuitButton() { if (!ShowSaveQuit()) { KillSaveQuitButton(); } else { if ((Object)(object)_saveQuitObj != (Object)null && !((Il2CppObjectBase)_saveQuitObj).WasCollected) { return; } Button val = FindRealQuitButton(); if ((Object)(object)val == (Object)null) { return; } Transform parent = ((Component)val).transform.parent; if (!((Object)(object)parent == (Object)null)) { Transform val2 = parent.Find("button_SaveAndQuit"); if ((Object)(object)val2 != (Object)null) { ((Object)val2).name = "button_SaveAndQuit_old"; Object.Destroy((Object)(object)((Component)val2).gameObject); } GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent, false); ((Object)val3).name = "button_SaveAndQuit"; val3.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex()); _saveQuitObj = val3; _saveQuitBtn = val3.GetComponent<Button>(); HookSaveQuitButton(); PutButtonText(val3, "Save & Quit"); } } } private void HookSaveQuitButton() { if (!((Object)(object)_saveQuitBtn == (Object)null)) { ((UnityEvent)_saveQuitBtn.onClick).AddListener(UnityAction.op_Implicit((Action)OnSaveQuitButtonPressed)); } } private void OnSaveQuitButtonPressed() { if (ShowSaveQuit()) { MelonCoroutines.Start(FixSaveQuitPopup()); } } [IteratorStateMachine(typeof(<FixSaveQuitPopup>d__79))] private IEnumerator FixSaveQuitPopup() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FixSaveQuitPopup>d__79(0) { <>4__this = this }; } private Button FindYesButton() { UIRig uIRig = Player.UIRig; object obj; if (uIRig == null) { obj = null; } else { PopUpMenuView popUpMenu = uIRig.popUpMenu; obj = ((popUpMenu != null) ? popUpMenu.preferencesPanelView : null); } PreferencesPanelView val = (PreferencesPanelView)obj; if ((Object)(object)val == (Object)null) { return null; } Button result = null; foreach (Button componentsInChild in ((Component)val).GetComponentsInChildren<Button>(true)) { if ((Object)(object)componentsInChild == (Object)null || !((Component)componentsInChild).gameObject.activeInHierarchy || ((Object)(object)_saveQuitBtn != (Object)null && (Object)(object)componentsInChild == (Object)(object)_saveQuitBtn) || (Object)(object)componentsInChild == (Object)(object)FindRealQuitButton() || InOptionsGrid(((Component)componentsInChild).transform)) { continue; } string text = ButtonText(((Component)componentsInChild).gameObject); string name = ((Object)componentsInChild).name ?? string.Empty; if (!LooksNoish(name, text) && LooksYesish(name, text)) { result = componentsInChild; if (text.Contains("yes", StringComparison.OrdinalIgnoreCase) || text.Contains("confirm", StringComparison.OrdinalIgnoreCase) || text.Contains("main menu", StringComparison.OrdinalIgnoreCase)) { return componentsInChild; } } } return result; } private static bool InOptionsGrid(Transform t) { while ((Object)(object)t != (Object)null) { string a = ((Object)t).name ?? string.Empty; if (string.Equals(a, "grid_Options", StringComparison.OrdinalIgnoreCase)) { return true; } if (string.Equals(a, "page_OPTIONS", StringComparison.OrdinalIgnoreCase)) { return true; } t = t.parent; } return false; } private static bool LooksYesish(string name, string text) { string text2 = name + " " + text; return text2.Contains("confirm", StringComparison.OrdinalIgnoreCase) || text2.Contains("accept", StringComparison.OrdinalIgnoreCase) || text2.Contains("yes", StringComparison.OrdinalIgnoreCase) || text2.Contains("ok", StringComparison.OrdinalIgnoreCase) || text2.Contains("main menu", StringComparison.OrdinalIgnoreCase); } private static bool LooksNoish(string name, string text) { string text2 = name + " " + text; return text2.Contains("cancel", StringComparison.OrdinalIgnoreCase) || text2.Contains("deny", StringComparison.OrdinalIgnoreCase) || text2.Contains("no", StringComparison.OrdinalIgnoreCase) || text2.Contains("back", StringComparison.OrdinalIgnoreCase) || text2.Contains("close", StringComparison.OrdinalIgnoreCase); } private void RetitlePopup(GameObject confirmButton) { Transform val = ((confirmButton != null) ? confirmButton.transform : null); for (int i = 0; i < 4; i++) { if (!((Object)(object)((val != null) ? val.parent : null) != (Object)null)) { break; } val = val.parent; } if ((Object)(object)val == (Object)null) { return; } foreach (TMP_Text componentsInChild in ((Component)val).GetComponentsInChildren<TMP_Text>(true)) { if (!((Object)(object)componentsInChild == (Object)null) && !IsButtonChild(componentsInChild.transform)) { string text = componentsInChild.text ?? string.Empty; if (text.Contains("main menu", StringComparison.OrdinalIgnoreCase) || text.Contains("return", StringComparison.OrdinalIgnoreCase) || text.Contains("quit", StringComparison.OrdinalIgnoreCase)) { componentsInChild.text = "Save and Quit?"; } } } } private static bool IsButtonChild(Transform t) { while ((Object)(object)t != (Object)null) { if ((Object)(object)((Component)t).GetComponent<Button>() != (Object)null) { return true; } t = t.parent; } return false; } private Button FindRealQuitButton() { try { UIRig uIRig = Player.UIRig; object obj; if (uIRig == null) { obj = null; } else { PopUpMenuView popUpMenu = uIRig.popUpMenu; obj = ((popUpMenu != null) ? popUpMenu.preferencesPanelView : null); } PreferencesPanelView val = (PreferencesPanelView)obj; if ((Object)(object)val == (Object)null) { return null; } Transform val2 = ((Component)val).transform.Find("page_OPTIONS/grid_Options"); if ((Object)(object)val2 == (Object)null && val.pages != null) { GameObject val3 = ((Il2CppArrayBase<GameObject>)(object)val.pages)[val.defaultPage]; val2 = ((val3 != null) ? val3.transform.Find("grid_Options") : null); } Transform val4 = ((val2 != null) ? val2.Find("button_Quit") : null); if ((Object)(object)val4 != (Object)null) { return ((Component)val4).GetComponent<Button>(); } Transform val5 = val2 ?? ((Component)val).transform; Button[] array = Il2CppArrayBase<Button>.op_Implicit(((Component)val5).GetComponentsInChildren<Button>(true)); Button[] array2 = array; foreach (Button val6 in array2) { if (!((Object)(object)val6 == (Object)null)) { GameObject gameObject = ((Component)val6).gameObject; if (!((Object)(object)gameObject == (Object)null) && !string.Equals(((Object)gameObject).name, "button_SaveAndQuit", StringComparison.OrdinalIgnoreCase) && (((Object)gameObject).name.Contains("button_Quit", StringComparison.OrdinalIgnoreCase) || ((Object)gameObject).name.Contains("Quit", StringComparison.OrdinalIgnoreCase) || ButtonSays(gameObject, "Main Menu"))) { return val6; } } } } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Warning("Could not find native quit button: " + ex.Message); } return null; } private bool ButtonSays(GameObject button, string text) { if ((Object)(object)button == (Object)null) { return false; } foreach (TMP_Text componentsInChild in button.GetComponentsInChildren<TMP_Text>(true)) { if ((Object)(object)componentsInChild != (Object)null && string.Equals(componentsInChild.text, text, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private void KillSaveQuitButton() { if (!((Object)(object)_saveQuitObj == (Object)null) && !((Il2CppObjectBase)_saveQuitObj).WasCollected) { Object.Destroy((Object)(object)_saveQuitObj); _saveQuitObj = null; _saveQuitBtn = null; } } private bool ShowSaveQuit() { if (!_inLevel || string.IsNullOrWhiteSpace(_levelBarcode)) { return false; } if (string.Equals(_levelBarcode, "c2534c5a-80e1-4a29-93ca-f3254d656e75", StringComparison.Ordinal)) { return false; } if (string.Equals(_levelBarcode, "fa534c5a868247138f50c62e424c4144.Level.VoidG114", StringComparison.Ordinal)) { return false; } return true; } private static string ButtonText(GameObject button) { if ((Object)(object)button == (Object)null) { return string.Empty; } return string.Join(" ", from label in (IEnumerable<TMP_Text>)button.GetComponentsInChildren<TMP_Text>(true) where (Object)(object)label != (Object)null && !string.IsNullOrWhiteSpace(label.text) select label.text); } private static void PutButtonText(GameObject button, string text) { if ((Object)(object)button == (Object)null) { return; } foreach (TMP_Text componentsInChild in button.GetComponentsInChildren<TMP_Text>(true)) { if ((Object)(object)componentsInChild != (Object)null) { componentsInChild.text = text; } } } private bool SaveCurrentLevel(string reason) { if (onQuest) { return SaveCurrentLevelQuest(reason); } if (_savingNow) { return false; } if (_loadingNow) { return false; } if (!_inLevel) { return false; } if (string.IsNullOrWhiteSpace(_levelBarcode)) { return false; } if (IsBlacklisted(_levelBarcode)) { ((MelonBase)this).LoggerInstance.Msg("Skipping save for blacklisted level: " + _levelBarcode); return true; } try { _savingNow = true; RememberLevel(_levelBarcode, _levelTitle); string savePath = GetSavePath(_levelBarcode); SceneSaveFile oldSave = ReadSaveMaybe(savePath); SceneSaveFile sceneSaveFile = PackScene(_levelBarcode, oldSave); KeepOtherZoneStuff(sceneSaveFile, oldSave); KeepOldConstraints(sceneSaveFile, oldSave); DropBadConstraints(sceneSaveFile); CleanSave(sceneSaveFile); DropBadConstraints(sceneSaveFile); WriteSaveOver(savePath, sceneSaveFile); ((MelonBase)this).LoggerInstance.Msg($"Saved {sceneSaveFile.Objects.Count} spawnables, {sceneSaveFile.Constraints.Count} constraints ({reason})."); RefreshBoneMenu(); return true; } catch (Exception value) { ((MelonBase)this).LoggerInstance.Error($"Save failed: {value}"); return false; } finally { _savingNow = false; } } private bool SaveCurrentLevelQuest(string reason) { if (_savingNow) { return false; } if (_lo