Decompiled source of PersistentScene v1.0.0
Mods/PersistentScene.dll
Decompiled a day 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 Il2CppCysharp.Threading.Tasks; 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 LabFusion.Data; using LabFusion.Data.Serializables; using LabFusion.Entities; using LabFusion.Marrow.Messages; using LabFusion.Network; using LabFusion.Player; using LabFusion.RPC; using MelonLoader; using Microsoft.CodeAnalysis; using PersistentScene; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(Core), "PersistentScene", "1.0.0", "CAitStudio", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonOptionalDependencies(new string[] { "LabFusion" })] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("PersistentScene")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PersistentScene")] [assembly: AssemblyTitle("PersistentScene")] [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 PersistentScene { public class Core : MelonMod { [CompilerGenerated] private sealed class <>c__DisplayClass69_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 <>c__DisplayClass95_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 <ApplyNpcWorldPosePass>d__111 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public Core <>4__this; public List<Poolee> made; private Stopwatch <stopwatch>5__2; private int <i>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ApplyNpcWorldPosePass>d__111(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Core core = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__2.Restart(); goto IL_00f1; } <>1__state = -1; <stopwatch>5__2 = Stopwatch.StartNew(); <i>5__3 = 0; goto IL_0103; IL_0103: if (<i>5__3 < save.Objects.Count && <i>5__3 < made.Count) { if (!save.Objects[<i>5__3].HasAIBrain) { HealthRecord health = save.Objects[<i>5__3].Health; if (health == null || !health.IsDead.GetValueOrDefault()) { goto IL_00b5; } } core.ApplySavedTransforms(made[<i>5__3], save.Objects[<i>5__3], restoreWorldPose: true, keepRigidbodiesFrozen: true); goto IL_00b5; } return false; IL_00f1: <i>5__3++; goto IL_0103; IL_00b5: if (<stopwatch>5__2.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } goto IL_00f1; } 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__85 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private Stopwatch <stopwatch>5__2; private Poolee[] <>7__wrap2; private int <>7__wrap3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DespawnExistingPooleesTimeSliced>d__85(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__2 = null; <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Core core = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__2.Restart(); goto IL_00e2; } <>1__state = -1; <stopwatch>5__2 = Stopwatch.StartNew(); <>7__wrap2 = core.PooleesNow(); <>7__wrap3 = 0; goto IL_00f0; IL_00e2: <>7__wrap3++; goto IL_00f0; IL_00f0: if (<>7__wrap3 < <>7__wrap2.Length) { Poolee val = <>7__wrap2[<>7__wrap3]; if (core.CanClearPoolee(val)) { SpawnableCrate spawnableCrate = val.SpawnableCrate; object value; if (spawnableCrate == null) { value = null; } else { Barcode barcode = ((Scannable)spawnableCrate).Barcode; value = ((barcode != null) ? barcode.ID : null); } if (!string.IsNullOrWhiteSpace((string?)value)) { try { val.Despawn(); core.Dirty(); } catch { Object.Destroy((Object)(object)((Component)val).gameObject); core.Dirty(); } if (<stopwatch>5__2.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } } goto IL_00e2; } <>7__wrap2 = null; 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 <DespawnIgnoredPooleesTimeSliced>d__86 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private Stopwatch <stopwatch>5__2; private Poolee[] <>7__wrap2; private int <>7__wrap3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DespawnIgnoredPooleesTimeSliced>d__86(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__2 = null; <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Core core = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__2.Restart(); goto IL_0100; } <>1__state = -1; <stopwatch>5__2 = Stopwatch.StartNew(); <>7__wrap2 = core.PooleesNow(); <>7__wrap3 = 0; goto IL_010e; IL_0100: <>7__wrap3++; goto IL_010e; IL_010e: if (<>7__wrap3 < <>7__wrap2.Length) { Poolee val = <>7__wrap2[<>7__wrap3]; if (!((Object)(object)val == (Object)null)) { SpawnableCrate spawnableCrate = val.SpawnableCrate; if (!(((spawnableCrate != null) ? ((Scannable)spawnableCrate).Barcode : null) == (Barcode)null)) { string iD = ((Scannable)val.SpawnableCrate).Barcode.ID; if (IsSpentCasing(val, iD) || IsLooseEmptyMagazine(val)) { try { val.Despawn(); core.Dirty(); } catch { Object.Destroy((Object)(object)((Component)val).gameObject); core.Dirty(); } if (<stopwatch>5__2.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } } } goto IL_0100; } <>7__wrap2 = null; 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 <FixSaveQuitPopup>d__151 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FixSaveQuitPopup>d__151(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown int num = <>1__state; Core CS$<>8__locals0 = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: { <>1__state = -1; Button val = CS$<>8__locals0.FindYesButton(); if (!((Object)(object)val == (Object)null)) { CS$<>8__locals0.RetitlePopup(((Component)val).gameObject); val.onClick = new ButtonClickedEvent(); ((UnityEvent)val.onClick).AddListener(UnityAction.op_Implicit((Action)delegate { if (!CS$<>8__locals0.SaveCurrentLevel("SaveAndQuit")) { ((MelonBase)CS$<>8__locals0).LoggerInstance.Warning("falied to save,pls try again"); } else { CS$<>8__locals0._quitSaved = true; Application.Quit(); } })); return false; } <i>5__2++; break; } } if (<i>5__2 < 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__78 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; public Action<Constrainer> onResolved; private Constrainer <made>5__2; private Task<Poolee> <spawnTask>5__3; private float <timeoutAt>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetOrSpawnConstrainer>d__78(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <made>5__2 = null; <spawnTask>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; Core core = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if ((Object)(object)core._dummyConstrainer != (Object)null && !((Il2CppObjectBase)core._dummyConstrainer).WasCollected) { onResolved?.Invoke(core._dummyConstrainer); return false; } <made>5__2 = null; <spawnTask>5__3 = null; try { string barcode = Barcodes.Get(SceneSaveBarcode.CONSTRAINER); <spawnTask>5__3 = SpawnBits.SpawnAsync(barcode, new Vector3(1000f, 1000f, 1000f), Quaternion.identity, Vector3.one); } catch (Exception ex) { ((MelonBase)core).LoggerInstance.Warning("Could not spawn dummy constrainer: " + ex.Message); } <timeoutAt>5__4 = Time.realtimeSinceStartup + 12f; break; case 1: <>1__state = -1; break; } if (<spawnTask>5__3 != null && !<spawnTask>5__3.IsCompleted && Time.realtimeSinceStartup < <timeoutAt>5__4) { <>2__current = null; <>1__state = 1; return true; } if (<spawnTask>5__3 != null && <spawnTask>5__3.IsCompletedSuccessfully) { Poolee result = <spawnTask>5__3.Result; if ((Object)(object)result != (Object)null) { SuppressDummyVisualEffects(((Component)result).gameObject); <made>5__2 = ((Component)result).GetComponent<Constrainer>() ?? ((Component)result).GetComponentInChildren<Constrainer>(true); } } core._dummyConstrainer = <made>5__2 ?? Object.FindObjectOfType<Constrainer>(); if ((Object)(object)core._dummyConstrainer != (Object)null) { SuppressDummyVisualEffects(((Component)core._dummyConstrainer).gameObject); } onResolved?.Invoke(core._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__133 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float seconds; public Dictionary<Rigidbody, bool> frozen; private float <endTime>5__2; private float <nextReassertTime>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <HoldKinematicLoadWindow>d__133(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__2 = Time.realtimeSinceStartup + seconds; <nextReassertTime>5__3 = 0f; break; case 1: <>1__state = -1; break; } if (Time.realtimeSinceStartup < <endTime>5__2) { if (Time.realtimeSinceStartup >= <nextReassertTime>5__3) { ReassertFrozenRigidbodies(frozen); <nextReassertTime>5__3 = 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__255 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerPoseRecord pose; public Core <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <KeepPlayerThere>d__255(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown int num = <>1__state; Core core = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (pose == null) { return false; } break; case 1: { <>1__state = -1; RigManager val = TryGetRigManager(); if ((Object)(object)val != (Object)null && (Object)(object)val.remapHeptaRig != (Object)null) { HoldPlayerThere(val, pose, 0.18f); } <>2__current = null; <>1__state = 2; return true; } case 2: <>1__state = -1; break; } if (core._holdPlayer && core._loadingNow) { RigManager val = TryGetRigManager(); if ((Object)(object)val != (Object)null && (Object)(object)val.remapHeptaRig != (Object)null) { HoldPlayerThere(val, 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__95 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; public string path; public bool automatic; private <>c__DisplayClass95_0 <>8__1; private SceneSaveFile <save>5__2; private bool <interceptedAutoLoad>5__3; private bool <movePlayer>5__4; private Dictionary<Rigidbody, bool> <frozen>5__5; private List<Poolee> <made>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadCurrentLevelSave>d__95(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 22u) { try { } finally { <>m__Finally1(); } } <>8__1 = null; <save>5__2 = null; <frozen>5__5 = null; <made>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Expected O, but got Unknown //IL_04b9: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Expected O, but got Unknown //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Expected O, but got Unknown try { int num = <>1__state; Core core = <>4__this; bool[] array; List<int> spawnOrder; switch (num) { default: return false; case 0: <>1__state = -1; if (!core._config.ModEnabled) { core._blockDefaultCrateSpawners = false; core._skipSceneSpawnerRouteForLoad = false; return false; } if (!FusionCompat.CanTouchScene) { core._blockDefaultCrateSpawners = false; core._skipSceneSpawnerRouteForLoad = false; ((MelonBase)core).LoggerInstance.Msg("Fusion client detected, skipping load."); return false; } if (core._loadingNow) { return false; } try { <save>5__2 = LoadSaveFile(path); } catch (Exception value) { ((MelonBase)core).LoggerInstance.Error($"Load failed: {value}"); return false; } if (<save>5__2 == null || <save>5__2.LevelBarcode != core._levelBarcode) { core._blockDefaultCrateSpawners = false; ((MelonBase)core).LoggerInstance.Warning("Save file does not match current level, skipping: " + path); return false; } EnsureSaveIds(<save>5__2); core.CleanSave(<save>5__2); if (core.IsBlacklisted(core._levelBarcode) || core.IsBlacklisted(<save>5__2.LevelBarcode)) { core._blockDefaultCrateSpawners = false; ((MelonBase)core).LoggerInstance.Msg("Skipping load for blacklisted level: " + core._levelBarcode); return false; } core._loadingNow = true; <>1__state = -3; <>8__1 = new <>c__DisplayClass95_0(); <interceptedAutoLoad>5__3 = automatic && core._blockDefaultCrateSpawners; core._skipSceneSpawnerRouteForLoad = <interceptedAutoLoad>5__3; NotifySaveLoadStarted(); <>2__current = (object)new WaitForSecondsRealtime(GetLoadDelay(automatic)); <>1__state = 1; return true; case 1: <>1__state = -3; <>2__current = RestorePlayerAmmoWhenReady(<save>5__2.PlayerAmmo); <>1__state = 2; return true; case 2: <>1__state = -3; <>2__current = core.RestorePlayerInventoryWhenReady(<save>5__2.PlayerInventory); <>1__state = 3; return true; case 3: <>1__state = -3; <movePlayer>5__4 = core._config.SavePlayerLocation && <save>5__2.PlayerPose != null; if (<movePlayer>5__4) { core._holdPlayer = true; MelonCoroutines.Start(core.KeepPlayerThere(<save>5__2.PlayerPose)); <>2__current = core.MovePlayerWhenReady(<save>5__2.PlayerPose); <>1__state = 4; return true; } goto IL_0314; case 4: <>1__state = -3; goto IL_0314; case 5: <>1__state = -3; <>2__current = core.DespawnExistingPooleesTimeSliced(); <>1__state = 6; return true; case 6: <>1__state = -3; goto IL_037e; case 7: <>1__state = -3; <>2__current = (object)new WaitForSecondsRealtime(0.05f); <>1__state = 8; return true; case 8: <>1__state = -3; <>2__current = core.ApplyNpcWorldPosePass(<save>5__2, <made>5__6); <>1__state = 9; return true; case 9: <>1__state = -3; <>2__current = (object)new WaitForSecondsRealtime(0.1f); <>1__state = 10; return true; case 10: <>1__state = -3; <>2__current = core.ApplyNpcWorldPosePass(<save>5__2, <made>5__6); <>1__state = 11; return true; case 11: <>1__state = -3; <>2__current = RestoreSavedRigidbodyStatesTimeSliced(<save>5__2, <made>5__6, <frozen>5__5, keepKinematic: true); <>1__state = 12; return true; case 12: <>1__state = -3; core.RegrabLoadedRigidbodies(<save>5__2, <made>5__6, <frozen>5__5); ((MelonBase)core).LoggerInstance.Msg($"Holding loaded rigidbodies kinematic for {2f:0.#} seconds."); <>2__current = HoldKinematicLoadWindow(2f, <frozen>5__5); <>1__state = 13; return true; case 13: <>1__state = -3; <>2__current = core.ApplyNpcWorldPosePass(<save>5__2, <made>5__6); <>1__state = 14; return true; case 14: <>1__state = -3; core.RegrabLoadedRigidbodies(<save>5__2, <made>5__6, <frozen>5__5); <>2__current = RestoreSavedRigidbodyStatesTimeSliced(<save>5__2, <made>5__6, <frozen>5__5, keepKinematic: true); <>1__state = 15; return true; case 15: <>1__state = -3; <>8__1.constrainer = null; <>2__current = core.GetOrSpawnConstrainer(delegate(Constrainer constrainerInstance) { <>8__1.constrainer = constrainerInstance; }); <>1__state = 16; return true; case 16: <>1__state = -3; <>8__1.joints = 0; <>2__current = core.RestoreConstraintsWithRetryTimeSliced(<save>5__2, <made>5__6, <>8__1.constrainer, delegate(int got) { <>8__1.joints = got; }); <>1__state = 17; return true; case 17: <>1__state = -3; <>2__current = core.RestoreNpcHealthTimeSliced(<save>5__2, <made>5__6); <>1__state = 18; return true; case 18: <>1__state = -3; <>2__current = core.RestoreSceneLogicStates(<save>5__2); <>1__state = 19; return true; case 19: <>1__state = -3; <>2__current = RestoreSavedRigidbodyStatesTimeSliced(<save>5__2, <made>5__6, <frozen>5__5, keepKinematic: false); <>1__state = 20; return true; case 20: <>1__state = -3; <>2__current = core.StabilizeDeadNpcPosesTimeSliced(<save>5__2, <made>5__6); <>1__state = 21; return true; case 21: <>1__state = -3; UnfreezeRemainingRigidbodies(<frozen>5__5); if (<movePlayer>5__4) { core._holdPlayer = false; <>2__current = null; <>1__state = 22; return true; } break; case 22: <>1__state = -3; <>2__current = core.PutPlayerBackAfterLoad(<save>5__2.PlayerPose); <>1__state = 23; return true; case 23: { <>1__state = -3; break; } IL_037e: core._blockDefaultCrateSpawners = false; <frozen>5__5 = new Dictionary<Rigidbody, bool>(UnityObjectComparer<Rigidbody>.Instance); <made>5__6 = Enumerable.Repeat<Poolee>(null, <save>5__2.Objects.Count).ToList(); array = new bool[<save>5__2.Objects.Count]; spawnOrder = GetSpawnOrder(<save>5__2); foreach (int item in Enumerable.Range(0, <save>5__2.Objects.Count).Except(spawnOrder)) { array[item] = true; } <>2__current = core.SpawnSavedObjectsOneAtATime(<save>5__2, <made>5__6, array, <frozen>5__5, spawnOrder); <>1__state = 7; return true; IL_0314: if (!<interceptedAutoLoad>5__3) { core.MarkExistingDeletedPoolees(<save>5__2); <>2__current = core.DespawnIgnoredPooleesTimeSliced(); <>1__state = 5; return true; } ((MelonBase)core).LoggerInstance.Msg("Skipped scene spawnable scan/clear because default CrateSpawners were blocked for this auto-load."); goto IL_037e; } <save>5__2.SupportedVersion = "1.0.0"; WriteSaveOver(path, <save>5__2); NotifySaveLoadFinished(<made>5__6.Count, <>8__1.joints); ((MelonBase)core).LoggerInstance.Msg($"Loaded {<made>5__6.Count} saved spawnables and got {<>8__1.joints}/{<save>5__2.Constraints.Count} constraints for {core._levelBarcode}."); <>8__1 = null; <frozen>5__5 = null; <made>5__6 = 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; Core core = <>4__this; core._blockDefaultCrateSpawners = false; core._skipSceneSpawnerRouteForLoad = false; core._holdPlayer = false; core._loadingNow = false; } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <MovePlayerWhenReady>d__254 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerPoseRecord pose; public bool rotatePlayer; private int <i>5__2; private RigManager <rigManager>5__3; private int <repeat>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <MovePlayerWhenReady>d__254(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <rigManager>5__3 = 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__2 = 0; goto IL_0102; case 1: <>1__state = -1; <repeat>5__4++; goto IL_00c9; case 2: { <>1__state = -1; <rigManager>5__3 = null; <i>5__2++; goto IL_0102; } IL_00c9: if (<repeat>5__4 < 8) { HoldPlayerThere(<rigManager>5__3, pose, 0.18f); <>2__current = null; <>1__state = 1; return true; } return false; IL_0102: if (<i>5__2 < 180) { <rigManager>5__3 = TryGetRigManager(); if ((Object)(object)<rigManager>5__3 != (Object)null && (Object)(object)<rigManager>5__3.remapHeptaRig != (Object)null) { TeleportPlayerToPose(<rigManager>5__3, pose, 0.18f, rotatePlayer); <repeat>5__4 = 0; goto IL_00c9; } <>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__256 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerPoseRecord pose; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PutPlayerBackAfterLoad>d__256(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 (pose == null) { return false; } <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < 10) { RigManager val = TryGetRigManager(); if ((Object)(object)val != (Object)null && (Object)(object)val.remapHeptaRig != (Object)null) { HoldPlayerThere(val, 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 <RefreshSaveQuitSoon>d__147 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RefreshSaveQuitSoon>d__147(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Core core = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < 30) { core.MakeSaveQuitButton(); if ((Object)(object)core._saveQuitObj != (Object)null && !((Il2CppObjectBase)core._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__70 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Constrainer constrainer; public Action<int> onDone; public HashSet<int> doneJoints; public SceneSaveFile save; public Core <>4__this; public List<Poolee> made; private int <got>5__2; private Stopwatch <stopwatch>5__3; private int <i>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreConstraintsTimeSliced>d__70(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__3 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Core core = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__3.Restart(); goto IL_015a; } <>1__state = -1; if ((Object)(object)constrainer == (Object)null) { onDone?.Invoke(doneJoints?.Count ?? 0); return false; } <got>5__2 = doneJoints?.Count ?? 0; <stopwatch>5__3 = Stopwatch.StartNew(); <i>5__4 = 0; goto IL_016a; IL_015a: <i>5__4++; goto IL_016a; IL_016a: if (<i>5__4 < save.Constraints.Count) { if (doneJoints == null || !doneJoints.Contains(<i>5__4)) { ConstraintRecord record = save.Constraints[<i>5__4]; try { if (core.RestoreConstraint(record, save, made, constrainer)) { <got>5__2++; doneJoints?.Add(<i>5__4); } } catch (Exception ex) { ((MelonBase)core).LoggerInstance.Warning("Failed to restore constraint: " + ex.Message); } if (<stopwatch>5__3.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } goto IL_015a; } onDone?.Invoke(<got>5__2); 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 <RestoreConstraintsWithRetryTimeSliced>d__69 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Constrainer constrainer; private <>c__DisplayClass69_0 <>8__1; public Core <>4__this; public SceneSaveFile save; public List<Poolee> made; public Action<int> onDone; 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__69(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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown int num = <>1__state; Core core = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass69_0(); <>8__1.constrainer = constrainer; <doneJoints>5__2 = new HashSet<int>(); <>8__1.got = 0; <pass>5__3 = 0; goto IL_017d; case 1: <>1__state = -1; goto IL_0095; case 2: <>1__state = -1; goto IL_0104; case 3: { <>1__state = -1; <pass>5__3++; goto IL_017d; } IL_017d: 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_0095; IL_0095: if ((Object)(object)<>8__1.constrainer == (Object)null || ((Il2CppObjectBase)<>8__1.constrainer).WasCollected) { <>2__current = core.GetOrSpawnConstrainer(delegate(Constrainer constrainerInstance) { <>8__1.constrainer = constrainerInstance; }); <>1__state = 2; return true; } goto IL_0104; IL_0104: <>2__current = core.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)core).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__112 : 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__2; private int <i>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreNpcHealthTimeSliced>d__112(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <stopwatch>5__2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Core core = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <stopwatch>5__2.Restart(); goto IL_00cf; } <>1__state = -1; <stopwatch>5__2 = Stopwatch.StartNew(); <i>5__3 = 0; goto IL_00e1; IL_00cf: <i>5__3++; goto IL_00e1; IL_00e1: if (<i>5__3 < save.Objects.Count && <i>5__3 < made.Count) { SavedObject savedObject = save.Objects[<i>5__3]; if (savedObject?.Health != null && !((Object)(object)made[<i>5__3] == (Object)null)) { core.RestoreHealth(made[<i>5__3], savedObject.Health); if (<stopwatch>5__2.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } goto IL_00cf; } 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 <RestorePlayerAmmoWhenReady>d__118 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerAmmoRecord ammo; private AmmoInventory <inv>5__2; private int <i>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestorePlayerAmmoWhenReady>d__118(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <inv>5__2 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (ammo == null) { return false; } <inv>5__2 = null; <i>5__3 = 0; break; case 1: <>1__state = -1; <i>5__3++; break; } if (<i>5__3 < 180) { <inv>5__2 = AmmoInventory.Instance; if (!((Object)(object)<inv>5__2 != (Object)null)) { <>2__current = null; <>1__state = 1; return true; } } if ((Object)(object)<inv>5__2 == (Object)null) { return false; } try { <inv>5__2.ClearAmmo(); <inv>5__2.AddCartridge(<inv>5__2.lightAmmoGroup, Math.Max(0, ammo.LightAmmo)); <inv>5__2.AddCartridge(<inv>5__2.mediumAmmoGroup, Math.Max(0, ammo.MediumAmmo)); <inv>5__2.AddCartridge(<inv>5__2.heavyAmmoGroup, Math.Max(0, ammo.HeavyAmmo)); } catch { } 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 <RestorePlayerInventoryWhenReady>d__119 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerInventoryRecord inv; public Core <>4__this; private RigManager <rig>5__2; private int <restored>5__3; private int <i>5__4; private List<PlayerInventoryItemRecord>.Enumerator <>7__wrap4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestorePlayerInventoryWhenReady>d__119(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 2) { try { } finally { <>m__Finally1(); } } <rig>5__2 = null; <>7__wrap4 = default(List<PlayerInventoryItemRecord>.Enumerator); <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; Core core = <>4__this; RigManager obj3; object obj4; switch (num) { default: return false; case 0: <>1__state = -1; if (inv?.Items == null || inv.Items.Count == 0) { return false; } <rig>5__2 = null; <i>5__4 = 0; goto IL_00c2; case 1: <>1__state = -1; <i>5__4++; goto IL_00c2; case 2: { <>1__state = -3; <restored>5__3++; break; } IL_00c2: if (<i>5__4 < 180) { <rig>5__2 = TryGetRigManager(); RigManager obj = <rig>5__2; object obj2; if (obj == null) { obj2 = null; } else { Inventory inventory = obj.inventory; obj2 = ((inventory != null) ? inventory.bodySlots : null); } if (obj2 == null) { <>2__current = null; <>1__state = 1; return true; } } obj3 = <rig>5__2; if (obj3 == null) { obj4 = null; } else { Inventory inventory2 = obj3.inventory; obj4 = ((inventory2 != null) ? inventory2.bodySlots : null); } if (obj4 == null) { return false; } <restored>5__3 = 0; <>7__wrap4 = inv.Items.GetEnumerator(); <>1__state = -3; break; } while (<>7__wrap4.MoveNext()) { PlayerInventoryItemRecord current = <>7__wrap4.Current; if (current != null && !string.IsNullOrWhiteSpace(current.SlotName) && !string.IsNullOrWhiteSpace(current.Barcode)) { SlotContainer obj5 = FindBodySlot(<rig>5__2, current.SlotName); InventorySlotReceiver val = ((obj5 != null) ? obj5.inventorySlotReceiver : null); if (!((Object)(object)val == (Object)null)) { <>2__current = core.SpawnInventoryItem(val, current); <>1__state = 2; return true; } } } <>m__Finally1(); <>7__wrap4 = default(List<PlayerInventoryItemRecord>.Enumerator); if (<restored>5__3 > 0) { ((MelonBase)core).LoggerInstance.Msg($"Restored {<restored>5__3} inventory slot items."); } 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)<>7__wrap4).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RestoreSavedRigidbodyStatesTimeSliced>d__132 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public List<Poolee> made; public SceneSaveFile save; public bool keepKinematic; public Dictionary<Rigidbody, bool> frozen; private Stopwatch <stopwatch>5__2; private int <i>5__3; private Poolee <poolee>5__4; private bool <keepDeadNpcFrozen>5__5; private bool <rootOnly>5__6; private List<TransformRecord>.Enumerator <>7__wrap6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreSavedRigidbodyStatesTimeSliced>d__132(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__2 = null; <poolee>5__4 = null; <>7__wrap6 = default(List<TransformRecord>.Enumerator); <>1__state = -2; } private bool MoveNext() { //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021e: 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__2.Restart(); goto IL_0268; } <>1__state = -1; <stopwatch>5__2 = Stopwatch.StartNew(); <i>5__3 = 0; goto IL_02a3; IL_02a3: if (<i>5__3 < save.Objects.Count && <i>5__3 < made.Count) { <poolee>5__4 = made[<i>5__3]; SavedObject savedObject = save.Objects[<i>5__3]; if (!((Object)(object)<poolee>5__4 == (Object)null) && savedObject != null) { <keepDeadNpcFrozen>5__5 = IsDeadNpcObject(savedObject); <rootOnly>5__6 = OnlyRootPoseForThis(savedObject); <>7__wrap6 = savedObject.Transforms.GetEnumerator(); <>1__state = -3; goto IL_0268; } goto IL_0291; } return false; IL_0291: <i>5__3++; goto IL_02a3; IL_0268: while (<>7__wrap6.MoveNext()) { TransformRecord current = <>7__wrap6.Current; if ((<rootOnly>5__6 && !RootRecord(current)) || current.Rigidbody == null) { continue; } Transform val = ResolveBySiblingPath(((Component)<poolee>5__4).transform, current.SiblingPath); if ((Object)(object)val == (Object)null) { val = ResolveRelativePath(((Component)<poolee>5__4).transform, current.Path); } if ((Object)(object)val == (Object)null) { continue; } Rigidbody component = ((Component)val).GetComponent<Rigidbody>(); if ((Object)(object)component == (Object)null) { continue; } component.isKinematic = (keepKinematic | <keepDeadNpcFrozen>5__5) || current.Rigidbody.IsKinematic; component.useGravity = current.Rigidbody.UseGravity; Vector3 val2 = current.Rigidbody.Velocity.ToUnity(); Vector3 val3 = current.Rigidbody.AngularVelocity.ToUnity(); component.velocity = ((keepKinematic | <keepDeadNpcFrozen>5__5) ? Vector3.zero : val2); component.angularVelocity = ((keepKinematic | <keepDeadNpcFrozen>5__5) ? Vector3.zero : val3); if (keepKinematic) { ClearRigidbodyMotion(component); } else { frozen.Remove(component); if (!<keepDeadNpcFrozen>5__5 && !current.Rigidbody.IsKinematic) { component.WakeUp(); component.velocity = val2; component.angularVelocity = val3; } } if (<stopwatch>5__2.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap6 = default(List<TransformRecord>.Enumerator); <poolee>5__4 = null; goto IL_0291; } 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)<>7__wrap6).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RestoreSceneLogicStates>d__292 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public Core <>4__this; private Dictionary<string, Transform> <pathCache>5__2; private Stopwatch <clock>5__3; private int <ok>5__4; private List<SceneLogicRecord>.Enumerator <>7__wrap4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreSceneLogicStates>d__292(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(); } } <pathCache>5__2 = null; <clock>5__3 = null; <>7__wrap4 = default(List<SceneLogicRecord>.Enumerator); <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; Core core = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (save?.SceneLogic == null || save.SceneLogic.Count == 0) { return false; } <pathCache>5__2 = new Dictionary<string, Transform>(StringComparer.Ordinal); <clock>5__3 = Stopwatch.StartNew(); <ok>5__4 = 0; <>7__wrap4 = save.SceneLogic.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; <clock>5__3.Restart(); break; } while (<>7__wrap4.MoveNext()) { SceneLogicRecord current = <>7__wrap4.Current; if (core.RestoreSceneLogicRecord(current, <pathCache>5__2)) { <ok>5__4++; } if (<clock>5__3.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap4 = default(List<SceneLogicRecord>.Enumerator); if (<ok>5__4 > 0) { ((MelonBase)core).LoggerInstance.Msg($"Restored {<ok>5__4}/{save.SceneLogic.Count} scene logic states."); } 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)<>7__wrap4).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SimpleMembers>d__303 : IEnumerable<MemberInfo>, IEnumerable, IEnumerator<MemberInfo>, IEnumerator, IDisposable { private int <>1__state; private MemberInfo <>2__current; private int <>l__initialThreadId; private Type type; public Type <>3__type; private BindingFlags <flags>5__2; private FieldInfo[] <>7__wrap2; private int <>7__wrap3; private PropertyInfo[] <>7__wrap4; MemberInfo IEnumerator<MemberInfo>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SimpleMembers>d__303(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>7__wrap2 = null; <>7__wrap4 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <flags>5__2 = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; <>7__wrap2 = type.GetFields(<flags>5__2); <>7__wrap3 = 0; goto IL_008a; case 1: <>1__state = -1; goto IL_007c; case 2: { <>1__state = -1; goto IL_010c; } IL_008a: if (<>7__wrap3 < <>7__wrap2.Length) { FieldInfo fieldInfo = <>7__wrap2[<>7__wrap3]; if (SimpleType(fieldInfo.FieldType)) { <>2__current = fieldInfo; <>1__state = 1; return true; } goto IL_007c; } <>7__wrap2 = null; <>7__wrap4 = type.GetProperties(<flags>5__2); <>7__wrap3 = 0; goto IL_011a; IL_007c: <>7__wrap3++; goto IL_008a; IL_011a: if (<>7__wrap3 < <>7__wrap4.Length) { PropertyInfo propertyInfo = <>7__wrap4[<>7__wrap3]; if (propertyInfo.GetIndexParameters().Length == 0 && propertyInfo.CanRead && propertyInfo.CanWrite && SimpleType(propertyInfo.PropertyType)) { <>2__current = propertyInfo; <>1__state = 2; return true; } goto IL_010c; } <>7__wrap4 = null; return false; IL_010c: <>7__wrap3++; goto IL_011a; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<MemberInfo> IEnumerable<MemberInfo>.GetEnumerator() { <SimpleMembers>d__303 <SimpleMembers>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <SimpleMembers>d__ = this; } else { <SimpleMembers>d__ = new <SimpleMembers>d__303(0); } <SimpleMembers>d__.type = <>3__type; return <SimpleMembers>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<MemberInfo>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <SpawnInventoryItem>d__120 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public InventorySlotReceiver receiver; public PlayerInventoryItemRecord item; public Core <>4__this; private float <timeout>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnInventoryItem>d__120(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown int num = <>1__state; Core core = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if ((Object)(object)receiver == (Object)null || item == null) { return false; } try { if ((Object)(object)receiver._slottedWeapon != (Object)null) { receiver.DespawnContents(); } } catch { } try { receiver.SpawnInSlotAsync(new Barcode(item.Barcode)); } catch (Exception ex) { ((MelonBase)core).LoggerInstance.Warning("Could not spawn inventory item " + item.Barcode + ": " + ex.Message); } <timeout>5__2 = Time.realtimeSinceStartup + 2f; goto IL_00dc; case 1: <>1__state = -1; goto IL_00dc; case 2: { <>1__state = -1; _ = (Object)(object)FindPooleeInReceiver(receiver) == (Object)null; return false; } IL_00dc: if ((Object)(object)receiver._slottedWeapon == (Object)null && Time.realtimeSinceStartup < <timeout>5__2) { <>2__current = null; <>1__state = 1; return true; } <>2__current = null; <>1__state = 2; return true; } } 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__107 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public int i; public SceneSaveFile save; public bool[] done; public Dictionary<int, Task<Poolee>> running; public bool retry; public Core <>4__this; public List<int> slow; public List<Poolee> made; public Dictionary<Rigidbody, bool> frozen; private Task<Poolee> <task>5__2; private float <timeoutAt>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnOneSavedObject>d__107(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <task>5__2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Core core = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (i < 0 || i >= save.Objects.Count || done[i]) { return false; } <task>5__2 = null; running.TryGetValue(i, out <task>5__2); if (<task>5__2 == null || <task>5__2.IsFaulted || (retry && <task>5__2.IsCompleted && (Object)(object)<task>5__2.Result == (Object)null)) { <task>5__2 = core.SpawnSavedObject(save.Objects[i]); running[i] = <task>5__2; } <timeoutAt>5__3 = Time.realtimeSinceStartup + 1f; break; case 1: <>1__state = -1; break; } if (!<task>5__2.IsCompleted && Time.realtimeSinceStartup < <timeoutAt>5__3) { <>2__current = null; <>1__state = 1; return true; } if (!<task>5__2.IsCompleted) { if (!retry) { slow?.Add(i); } else { ((MelonBase)core).LoggerInstance.Warning("Still waiting on slow spawnable after retry: " + save.Objects[i].Barcode); } return false; } if (<task>5__2.IsFaulted) { ((MelonBase)core).LoggerInstance.Warning("Failed to spawn " + save.Objects[i].Barcode + ": " + <task>5__2.Exception?.GetBaseException().Message); done[i] = true; return false; } Poolee result = <task>5__2.Result; if ((Object)(object)result == (Object)null) { if (!retry) { slow?.Add(i); } else { ((MelonBase)core).LoggerInstance.Warning("Spawn returned null for " + save.Objects[i].Barcode); done[i] = true; } return false; } made[i] = result; core.RememberLoadedSaveId(result, save.Objects[i]); TouchLoadedPoolee(result, save.Objects[i], frozen); core.RestoreObjectState(result, 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__105 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public List<int> order; public SceneSaveFile save; public bool[] done; public Core <>4__this; public List<Poolee> made; public Dictionary<Rigidbody, bool> frozen; private Dictionary<int, Task<Poolee>> <running>5__2; private Dictionary<int, float> <started>5__3; private List<int> <active>5__4; private List<int> <slow>5__5; private Queue<int> <todo>5__6; private Queue<int> <retry>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnSavedObjectsOneAtATime>d__105(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <running>5__2 = null; <started>5__3 = null; <active>5__4 = null; <slow>5__5 = null; <todo>5__6 = null; <retry>5__7 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Core core = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <running>5__2 = new Dictionary<int, Task<Poolee>>(); <started>5__3 = new Dictionary<int, float>(); <active>5__4 = new List<int>(); <slow>5__5 = new List<int>(); <todo>5__6 = new Queue<int>(order); goto IL_0149; case 1: <>1__state = -1; goto IL_0149; case 2: { <>1__state = -1; break; } IL_0149: while (<todo>5__6.Count > 0 || <active>5__4.Count > 0) { while (<todo>5__6.Count > 0 && <active>5__4.Count < 6) { int num2 = <todo>5__6.Dequeue(); if (num2 >= 0 && num2 < save.Objects.Count && !done[num2]) { Task<Poolee> value = core.SpawnSavedObject(save.Objects[num2]); <running>5__2[num2] = value; <started>5__3[num2] = Time.realtimeSinceStartup; <active>5__4.Add(num2); } } if (!core.PumpSpawnQueue(save, made, done, frozen, <running>5__2, <started>5__3, <active>5__4, <slow>5__5, retry: false)) { <>2__current = null; <>1__state = 1; return true; } } if (<slow>5__5.Count <= 0) { return false; } ((MelonBase)core).LoggerInstance.Msg($"Retrying {<slow>5__5.Count} slow spawnables after the first pass."); <retry>5__7 = new Queue<int>(<slow>5__5); <slow>5__5.Clear(); break; } while (<retry>5__7.Count > 0 || <active>5__4.Count > 0) { while (<retry>5__7.Count > 0 && <active>5__4.Count < 6) { int num3 = <retry>5__7.Dequeue(); if (num3 >= 0 && num3 < save.Objects.Count && !done[num3]) { if (!<running>5__2.TryGetValue(num3, out var value2) || value2.IsFaulted || (value2.IsCompleted && (Object)(object)value2.Result == (Object)null)) { value2 = core.SpawnSavedObject(save.Objects[num3]); <running>5__2[num3] = value2; } <started>5__3[num3] = Time.realtimeSinceStartup; <active>5__4.Add(num3); } } if (!core.PumpSpawnQueue(save, made, done, frozen, <running>5__2, <started>5__3, <active>5__4, null, retry: true)) { <>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 <StabilizeDeadNpcPosesTimeSliced>d__135 : 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__2; private int <pass>5__3; private Stopwatch <stopwatch>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__135(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <releaseStopwatch>5__2 = null; <stopwatch>5__4 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Core core = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <pass>5__3 = 0; goto IL_0184; case 1: <>1__state = -1; <stopwatch>5__4.Restart(); goto IL_010d; case 2: <>1__state = -1; <stopwatch>5__4 = null; <pass>5__3++; goto IL_0184; case 3: { <>1__state = -1; <releaseStopwatch>5__2.Restart(); goto IL_0249; } IL_0184: if (<pass>5__3 < 10) { <stopwatch>5__4 = Stopwatch.StartNew(); <i>5__5 = 0; goto IL_011d; } <releaseStopwatch>5__2 = Stopwatch.StartNew(); <pass>5__3 = 0; goto IL_0259; IL_010d: <i>5__5++; goto IL_011d; IL_0259: if (<pass>5__3 >= save.Objects.Count || <pass>5__3 >= made.Count) { break; } if (IsDeadNpcObject(save.Objects[<pass>5__3]) && !((Object)(object)made[<pass>5__3] == (Object)null)) { ReleaseDeadNpcRigidbodies(made[<pass>5__3], save.Objects[<pass>5__3]); if (<releaseStopwatch>5__2.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 3; return true; } } goto IL_0249; IL_0249: <pass>5__3++; goto IL_0259; IL_011d: if (<i>5__5 < save.Objects.Count && <i>5__5 < made.Count) { if (IsDeadNpcObject(save.Objects[<i>5__5]) && !((Object)(object)made[<i>5__5] == (Object)null)) { core.ApplySavedTransforms(made[<i>5__5], save.Objects[<i>5__5], restoreWorldPose: true, keepRigidbodiesFrozen: true); ClearPooleeRigidbodyMotion(made[<i>5__5]); if (<stopwatch>5__4.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } goto IL_010d; } 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 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 double RestoreBudgetMs = 4.5; private const float SpawnItemTimeoutSeconds = 1f; private const int PcSpawnBatchSize = 6; private const float ZoneMissingPreserveDistance = 12f; private const float CrateSpawnerMatchDistance = 4f; private const float CrateSpawnerDeleteMatchDistance = 25f; private const float LoadKinematicHoldSeconds = 2f; 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 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 _setting; 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 bool _blockDefaultCrateSpawners; private bool _skipSceneSpawnerRouteForLoad; 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 static Transform _constraintDummyTransform; private bool _holdPlayer; 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 const string holodeckRecordType = "PersistentScene.GameControl_Holodeck"; private static readonly string[] logicHints = new string[15] { "ButtonController", "Il2CppSLZ.Marrow.Circuits", "Il2CppSLZ.Marrow.VoidLogic", "VoidLogic", "RPCBool", "RPCFloat", "RPCInt", "RPCString", "RPCVector3", "RPCVariable", "MaterialDecorator", "MaterialSwitch", "MaterialSwitcher", "MaterialSelector", "MaterialSelect" }; private static readonly string[] logicBoolNames = new string[27] { "_charged", "charged", "Charged", "_toggleCharged", "toggleCharged", "ToggleCharged", "_isOn", "isOn", "IsOn", "_isActive", "isActive", "IsActive", "_active", "active", "Active", "_enabled", "enabled", "Enabled", "_value", "value", "Value", "_boolValue", "boolValue", "BoolValue", "_state", "state", "State" }; private static readonly string[] logicFloatNames = new string[16] { "_value", "value", "Value", "_floatValue", "floatValue", "FloatValue", "_lastSensorValue", "lastSensorValue", "_sensorValue", "sensorValue", "_charge", "charge", "_input", "inputValue", "_output", "outputValue" }; private static readonly string[] logicIntNames = new string[17] { "_value", "value", "Value", "_intValue", "intValue", "IntValue", "_state", "state", "State", "_index", "index", "_currentIndex", "currentIndex", "_selection", "selection", "_setting", "setting" }; private static readonly string[] logicStringNames = new string[8] { "_value", "value", "Value", "_stringValue", "stringValue", "StringValue", "_text", "text" }; private static readonly string[] logicVectorNames = new string[6] { "_value", "value", "Value", "_vector3Value", "vector3Value", "Vector3Value" }; private static double restoreBudget => 4.5; internal static Core Current { get; private set; } public override void OnInitializeMelon() { Current = this; _homeDir = SaveRoot(); _saveFolder = Path.Combine(_homeDir, "PersistentScene_SaveFiles"); _cfg = Path.Combine(_saveFolder, "config.json"); Directory.CreateDirectory(_saveFolder); LoadConfig(); SpawnBits.Init(((MelonBase)this).HarmonyInstance); CrateSpawnerAwakeBlocker.Init(((MelonBase)this).HarmonyInstance); PooleeHooks.Init(((MelonBase)this).HarmonyInstance); JointBits.Init(((MelonBase)this).HarmonyInstance); NpcBits.Init(((MelonBase)this).HarmonyInstance); HolodeckBits.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() { string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); return Path.Combine(folderPath, "AppData", "LocalLow", "Stress Level Zero", "BONELAB", "Saves"); } public override void OnSceneWasInitialized(int buildIndex, string sceneName) { if (_config.ModEnabled && !_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 && _config.ModEnabled) { 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) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (!_config.ModEnabled) { _blockDefaultCrateSpawners = false; _skipSceneSpawnerRouteForLoad = false; } else if (!_savedThisTrip && _inLevel && !string.IsNullOrWhiteSpace(_levelBarcode)) { SaveCurrentLevel("level loading"); _savedThisTrip = true; } _blockDefaultCrateSpawners = _config.ModEnabled && ShouldBlockDefaultSpawns(nextLevel); _skipSceneSpawnerRouteForLoad = false; if (_blockDefaultCrateSpawners) { ((MelonBase)this).LoggerInstance.Msg("Blocking default CrateSpawner Awake for saved level: " + nextLevel.barcode); } ClearRuntimeJunk(); _savedIds.Clear(); _loadedIds.Clear(); _deletedIds.Clear(); _deadPtrs.Clear(); _inLevel = false; KillSaveQuitButton(); } private void OnLevelLoaded(LevelInfo info) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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 (!_config.ModEnabled) { _blockDefaultCrateSpawners = false; ((MelonBase)this).LoggerInstance.Msg("Mod disabled, skipping load."); return; } if (FusionCompat.ClientInRoom) { _blockDefaultCrateSpawners = false; ((MelonBase)this).LoggerInstance.Msg("Fusion client detected, host will handle PersistentScene load."); return; } if (IsBlacklisted(_levelBarcode)) { _blockDefaultCrateSpawners = false; ForgetLast(); ((MelonBase)this).LoggerInstance.Msg("Level is blacklisted, skipping load: " + _levelBarcode); return; } RememberLevel(info); string savePath = GetSavePath(_levelBarcode); if (string.IsNullOrWhiteSpace(savePath) || !Directory.Exists(savePath)) { _blockDefaultCrateSpawners = false; ((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(); _blockDefaultCrateSpawners = false; _skipSceneSpawnerRouteForLoad = false; _savedIds.Clear(); _loadedIds.Clear(); _deletedIds.Clear(); _deadPtrs.Clear(); _inLevel = false; _levelTitle = null; _savedThisTrip = false; KillSaveQuitButton(); } internal void SaveBeforeSceneStreamerLoad(string reason) { if (_config.ModEnabled && !_savedThisTrip && _inLevel && !string.IsNullOrWhiteSpace(_levelBarcode) && SaveCurrentLevel(reason)) { _savedThisTrip = true; } } private static void ClearRuntimeJunk() { SpawnBits.Clear(); NpcBits.Clear(); JointBits.Clear(); HolodeckBits.Clear(); } private bool ShouldBlockDefaultSpawns(LevelInfo nextLevel) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!_config.ModEnabled) { return false; } if (FusionCompat.ClientInRoom) { return false; } string barcode = nextLevel.barcode; if (string.IsNullOrWhiteSpace(barcode)) { return false; } if (IsBlacklisted(barcode)) { return false; } string savePath = GetSavePath(barcode, nextLevel.title); if (string.IsNullOrWhiteSpace(savePath) || !Directory.Exists(savePath)) { return false; } SceneSaveFile sceneSaveFile = ReadSaveMaybe(savePath); if (sceneSaveFile != null) { return string.Equals(sceneSaveFile.LevelBarcode, barcode, StringComparison.Ordinal); } return false; } internal bool ShouldBlockCrateSpawnerAwake(CrateSpawner spawner) { if (!_blockDefaultCrateSpawners || (Object)(object)spawner == (Object)null) { return false; } if ((Object)(object)((Component)spawner).GetComponentInParent<Poolee>() != (Object)null) { return false; } if ((Object)(object)((Component)spawner).GetComponentInParent<RigManager>() != (Object)null) { return false; } if ((Object)(object)((Component)spawner).GetComponentInParent<UIRig>() != (Object)null) { return false; } return true; } [IteratorStateMachine(typeof(<RestoreConstraintsWithRetryTimeSliced>d__69))] private IEnumerator RestoreConstraintsWithRetryTimeSliced(SceneSaveFile save, List<Poolee> made, Constrainer constrainer, Action<int> onDone) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RestoreConstraintsWithRetryTimeSliced>d__69(0) { <>4__this = this, save = save, made = made, constrainer = constrainer, onDone = onDone }; } [IteratorStateMachine(typeof(<RestoreConstraintsTimeSliced>d__70))] private IEnumerator RestoreConstraintsTimeSliced(SceneSaveFile save, List<Poolee> made, Constrainer constrainer, HashSet<int> doneJoints, Action<int> onDone) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RestoreConstraintsTimeSliced>d__70(0) { <>4__this = this, save = save, made = made, constrainer = constrainer, doneJoints = doneJoints, onDone = onDone }; } private bool RestoreConstraint(ConstraintRecord record, SceneSaveFile save, List<Poolee> made, Constrainer constrainer) { //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) Transform val = ResolveConstraintTransform(record.FirstObjectIndex, record.FirstPath, record.FirstSiblingPath, save, made); Transform val2 = ResolveConstraintTransform(record.SecondObjectIndex, record.SecondPath, record.SecondSiblingPath, save, made); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { ((MelonBase)this).LoggerInstance.Warning($"Constraint endpoint missing: {record.FirstObjectIndex}:{record.FirstSiblingPath ?? record.FirstPath} -> {record.SecondObjectIndex}:{record.SecondSiblingPath ?? record.SecondPath}"); return false; } Vector3 val3 = record.FirstPoint.ToUnity(); Vector3 val4 = record.SecondPoint.ToUnity(); Vector3 val5 = record.FirstNormal.ToUnity(); Vector3 val6 = record.SecondNormal.ToUnity(); if (val5 == Vector3.zero) { val5 = Vector3.up; } if (val6 == Vector3.zero) { val6 = Vector3.up; } bool flag = record.HasFirstTargetPose; bool flag2 = record.HasSecondTargetPose; Vector3 val7 = record.FirstTargetPosition.ToUnity(); Quaternion val8 = Quaternion.Euler(record.FirstTargetRotation.ToUnity()); Vector3 val9 = record.SecondTargetPosition.ToUnity(); Quaternion val10 = Quaternion.Euler(record.SecondTargetRotation.ToUnity()); bool flag3 = record.FirstObjectIndex >= 0; bool flag4 = record.SecondObjectIndex >= 0; if (record.FirstObjectIndex < 0) { val.position = val3; val.rotation = Quaternion.identity; } if (record.SecondObjectIndex < 0) { val2.position = val4; val2.rotation = Quaternion.identity; } MarrowBody val11 = FindBodyForConstraint(val); MarrowBody val12 = FindBodyForConstraint(val2); if ((Object)(object)val11 == (Object)null && (Object)(object)val12 == (Object)null) { ((MelonBase)this).LoggerInstance.Warning("Constraint bodies missing: " + ((Object)val).name + " -> " + ((Object)val2).name); return false; } if ((Object)(object)val11 == (Object)null) { Transform obj = val2; val2 = val; val = obj; MarrowBody obj2 = val12; val12 = val11; val11 = obj2; Vector3 val13 = val4; val4 = val3; val3 = val13; Vector3 val14 = val6; val6 = val5; val5 = val14; bool num = flag2; flag2 = flag; flag = num; Vector3 val15 = val9; val9 = val7; val7 = val15; Quaternion val16 = val10; val10 = val8; val8 = val16; bool num2 = flag4; flag4 = flag3; flag3 = num2; } if (!Enum.TryParse<ConstraintMode>(record.Mode, out ConstraintMode result)) { result = (ConstraintMode)1; } Vector3 position = val.position; Quaternion rotation = val.rotation; Vector3 position2 = val2.position; Quaternion rotation2 = val2.rotation; bool flag5 = flag3 && flag; bool flag6 = flag4 && flag2; try { if (flag) { val.SetPositionAndRotation(val7, val8); } if (flag2) { val2.SetPositionAndRotation(val9, val10); } constrainer.mode = result; constrainer._gO1 = ((Component)val).gameObject; constrainer._gO2 = ((Component)val2).gameObject; constrainer._mb1 = val11; constrainer._mb2 = val12; constrainer._point1 = val3; constrainer._point2 = val4; constrainer._normal1 = val5; constrainer._normal2 = val6; constrainer.PrimaryButtonUp(); FusionCompat.SendConstraint(((Component)val).gameObject, ((Component)val2).gameObject, result, val3, val4, val5, val6, flag ? val7 : val.position, flag ? val8 : val.rotation, flag2 ? val9 : val2.position, flag2 ? val10 : val2.rotation); } finally { if (flag5 && (Object)(object)val != (Object)null) { val.SetPositionAndRotation(position, rotation); } if (flag6 && (Object)(object)val2 != (Object)null) { val2.SetPositionAndRotation(position2, rotation2); } } return true; } private static MarrowBody FindBodyForConstraint(Transform transform) { if ((Object)(object)transform == (Object)null) { return null; } MarrowBody val = MarrowBody.Cache.Get(((Component)transform).gameObject); if (val == null) { val = ((Component)transform).GetComponent<MarrowBody>(); } if (val == null) { val = ((Component)transform).GetComponentInParent<MarrowBody>(); } if (val == null) { val = ((Component)transform).GetComponentInChildren<MarrowBody>(true); } if ((Object)(object)val == (Object)null) { Rigidbody val2 = ((Component)transform).GetComponent<Rigidbody>() ?? ((Component)transform).GetComponentInParent<Rigidbody>() ?? ((Component)transform).GetComponentInChildren<Rigidbody>(true); if ((Object)(object)val2 != (Object)null) { val = MarrowBody.Cache.Get(((Component)val2).gameObject) ?? ((Component)val2).GetComponent<MarrowBody>() ?? ((Component)val2).GetComponentInParent<MarrowBody>(); } } return val; } private Transform ResolveConstraintTransform(int objectIndex, string relativePath, string siblingPath, SceneSaveFile save, List<Poolee> made) { if (objectIndex < 0 || objectIndex >= made.Count) { object obj; if (string.IsNullOrWhiteSpace(relativePath)) { obj = null; } else { GameObject obj2 = GameObject.Find(relativePath); obj = ((obj2 != null) ? obj2.transform : null); } if (obj == null) { obj = GetConstraintDummyTransform(); } return (Transform)obj; } if ((Object)(object)made[objectIndex] == (Object)null && save?.Objects != null && objectIndex < save.Objects.Count) { Poolee val = FindLoadedPooleeForSavedObject(save.Objects[objectIndex]); if ((Object)(object)val != (Object)null) { made[objectIndex] = val; } } if ((Object)(object)made[objectIndex] == (Object)null) { return GetConstraintDummyTransform(); } Transform transform = ((Component)made[objectIndex]).transform; Transform val2 = ResolveBySiblingPath(transform, siblingPath); if ((Object)(object)val2 != (Object)null) { return val2; } return ResolveRelativePath(transform, relativePath); } private static Transform GetConstraintDummyTransform() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if ((Object)(object)_constraintDummyTransform == (Object)null) { GameObject val = new GameObject("SceneSave Constraint Dummy"); Object.DontDestroyOnLoad((Object)val); _constraintDummyTransform = val.transform; } return _constraintDummyTransform; } private static Transform ResolveRelativePath(Transform root, string relativePath) { if ((Object)(object)root == (Object)null) { return null; } if (string.IsNullOrEmpty(relativePath)) { return root; } Transform val = root; string[] array = relativePath.Split('/'); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { Transform val2 = val.Find(text); if ((Object)(object)val2 == (Object)null) { return null; } val = val2; } } return val; } private static Transform ResolveBySiblingPath(Transform root, string siblingPath) { if ((Object)(object)root == (Object)null || string.IsNullOrWhiteSpace(siblingPath)) { return null; } Transform val = root; string[] array = siblingPath.Split('/'); for (int i = 0; i < array.Length; i++) { if (!int.TryParse(array[i], out var result) || result < 0 || result >= v