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 <>9__0; public Action <>9__1; internal void b__0(Constrainer constrainerInstance) { constrainer = constrainerInstance; } internal void b__1(int count) { got = count; } } [CompilerGenerated] private sealed class <>c__DisplayClass95_0 { public Constrainer constrainer; public int joints; internal void b__0(Constrainer constrainerInstance) { constrainer = constrainerInstance; } internal void b__1(int got) { joints = got; } } [CompilerGenerated] private sealed class d__111 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public Core <>4__this; public List made; private Stopwatch 5__2; private int 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__111(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 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; 5__2.Restart(); goto IL_00f1; } <>1__state = -1; 5__2 = Stopwatch.StartNew(); 5__3 = 0; goto IL_0103; IL_0103: if (5__3 < save.Objects.Count && 5__3 < made.Count) { if (!save.Objects[5__3].HasAIBrain) { HealthRecord health = save.Objects[5__3].Health; if (health == null || !health.IsDead.GetValueOrDefault()) { goto IL_00b5; } } core.ApplySavedTransforms(made[5__3], save.Objects[5__3], restoreWorldPose: true, keepRigidbodiesFrozen: true); goto IL_00b5; } return false; IL_00f1: 5__3++; goto IL_0103; IL_00b5: if (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 d__85 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private Stopwatch 5__2; private Poolee[] <>7__wrap2; private int <>7__wrap3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__85(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 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; 5__2.Restart(); goto IL_00e2; } <>1__state = -1; 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 (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 d__86 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private Stopwatch 5__2; private Poolee[] <>7__wrap2; private int <>7__wrap3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__86(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 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; 5__2.Restart(); goto IL_0100; } <>1__state = -1; 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 (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 d__151 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; 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; } 5__2++; break; } } if (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 d__78 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; public Action onResolved; private Constrainer 5__2; private Task 5__3; private float 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__78(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 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; } 5__2 = null; 5__3 = null; try { string barcode = Barcodes.Get(SceneSaveBarcode.CONSTRAINER); 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); } 5__4 = Time.realtimeSinceStartup + 12f; break; case 1: <>1__state = -1; break; } if (5__3 != null && !5__3.IsCompleted && Time.realtimeSinceStartup < 5__4) { <>2__current = null; <>1__state = 1; return true; } if (5__3 != null && 5__3.IsCompletedSuccessfully) { Poolee result = 5__3.Result; if ((Object)(object)result != (Object)null) { SuppressDummyVisualEffects(((Component)result).gameObject); 5__2 = ((Component)result).GetComponent() ?? ((Component)result).GetComponentInChildren(true); } } core._dummyConstrainer = 5__2 ?? Object.FindObjectOfType(); 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 d__133 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float seconds; public Dictionary frozen; private float 5__2; private float 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; } 5__2 = Time.realtimeSinceStartup + seconds; 5__3 = 0f; break; case 1: <>1__state = -1; break; } if (Time.realtimeSinceStartup < 5__2) { if (Time.realtimeSinceStartup >= 5__3) { ReassertFrozenRigidbodies(frozen); 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 d__255 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerPoseRecord pose; public Core <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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 d__95 : IEnumerator, 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 5__2; private bool 5__3; private bool 5__4; private Dictionary 5__5; private List 5__6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; 5__2 = null; 5__5 = null; 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 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 { 5__2 = LoadSaveFile(path); } catch (Exception value) { ((MelonBase)core).LoggerInstance.Error($"Load failed: {value}"); return false; } if (5__2 == null || 5__2.LevelBarcode != core._levelBarcode) { core._blockDefaultCrateSpawners = false; ((MelonBase)core).LoggerInstance.Warning("Save file does not match current level, skipping: " + path); return false; } EnsureSaveIds(5__2); core.CleanSave(5__2); if (core.IsBlacklisted(core._levelBarcode) || core.IsBlacklisted(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(); 5__3 = automatic && core._blockDefaultCrateSpawners; core._skipSceneSpawnerRouteForLoad = 5__3; NotifySaveLoadStarted(); <>2__current = (object)new WaitForSecondsRealtime(GetLoadDelay(automatic)); <>1__state = 1; return true; case 1: <>1__state = -3; <>2__current = RestorePlayerAmmoWhenReady(5__2.PlayerAmmo); <>1__state = 2; return true; case 2: <>1__state = -3; <>2__current = core.RestorePlayerInventoryWhenReady(5__2.PlayerInventory); <>1__state = 3; return true; case 3: <>1__state = -3; 5__4 = core._config.SavePlayerLocation && 5__2.PlayerPose != null; if (5__4) { core._holdPlayer = true; MelonCoroutines.Start(core.KeepPlayerThere(5__2.PlayerPose)); <>2__current = core.MovePlayerWhenReady(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(5__2, 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(5__2, 5__6); <>1__state = 11; return true; case 11: <>1__state = -3; <>2__current = RestoreSavedRigidbodyStatesTimeSliced(5__2, 5__6, 5__5, keepKinematic: true); <>1__state = 12; return true; case 12: <>1__state = -3; core.RegrabLoadedRigidbodies(5__2, 5__6, 5__5); ((MelonBase)core).LoggerInstance.Msg($"Holding loaded rigidbodies kinematic for {2f:0.#} seconds."); <>2__current = HoldKinematicLoadWindow(2f, 5__5); <>1__state = 13; return true; case 13: <>1__state = -3; <>2__current = core.ApplyNpcWorldPosePass(5__2, 5__6); <>1__state = 14; return true; case 14: <>1__state = -3; core.RegrabLoadedRigidbodies(5__2, 5__6, 5__5); <>2__current = RestoreSavedRigidbodyStatesTimeSliced(5__2, 5__6, 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(5__2, 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(5__2, 5__6); <>1__state = 18; return true; case 18: <>1__state = -3; <>2__current = core.RestoreSceneLogicStates(5__2); <>1__state = 19; return true; case 19: <>1__state = -3; <>2__current = RestoreSavedRigidbodyStatesTimeSliced(5__2, 5__6, 5__5, keepKinematic: false); <>1__state = 20; return true; case 20: <>1__state = -3; <>2__current = core.StabilizeDeadNpcPosesTimeSliced(5__2, 5__6); <>1__state = 21; return true; case 21: <>1__state = -3; UnfreezeRemainingRigidbodies(5__5); if (5__4) { core._holdPlayer = false; <>2__current = null; <>1__state = 22; return true; } break; case 22: <>1__state = -3; <>2__current = core.PutPlayerBackAfterLoad(5__2.PlayerPose); <>1__state = 23; return true; case 23: { <>1__state = -3; break; } IL_037e: core._blockDefaultCrateSpawners = false; 5__5 = new Dictionary(UnityObjectComparer.Instance); 5__6 = Enumerable.Repeat(null, 5__2.Objects.Count).ToList(); array = new bool[5__2.Objects.Count]; spawnOrder = GetSpawnOrder(5__2); foreach (int item in Enumerable.Range(0, 5__2.Objects.Count).Except(spawnOrder)) { array[item] = true; } <>2__current = core.SpawnSavedObjectsOneAtATime(5__2, 5__6, array, 5__5, spawnOrder); <>1__state = 7; return true; IL_0314: if (!5__3) { core.MarkExistingDeletedPoolees(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; } 5__2.SupportedVersion = "1.0.0"; WriteSaveOver(path, 5__2); NotifySaveLoadFinished(5__6.Count, <>8__1.joints); ((MelonBase)core).LoggerInstance.Msg($"Loaded {5__6.Count} saved spawnables and got {<>8__1.joints}/{5__2.Constraints.Count} constraints for {core._levelBarcode}."); <>8__1 = null; 5__5 = null; 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 d__254 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerPoseRecord pose; public bool rotatePlayer; private int 5__2; private RigManager 5__3; private int 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__254(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 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; } 5__2 = 0; goto IL_0102; case 1: <>1__state = -1; 5__4++; goto IL_00c9; case 2: { <>1__state = -1; 5__3 = null; 5__2++; goto IL_0102; } IL_00c9: if (5__4 < 8) { HoldPlayerThere(5__3, pose, 0.18f); <>2__current = null; <>1__state = 1; return true; } return false; IL_0102: if (5__2 < 180) { 5__3 = TryGetRigManager(); if ((Object)(object)5__3 != (Object)null && (Object)(object)5__3.remapHeptaRig != (Object)null) { TeleportPlayerToPose(5__3, pose, 0.18f, rotatePlayer); 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 d__256 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerPoseRecord pose; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; } 5__2 = 0; break; case 1: <>1__state = -1; 5__2++; break; } if (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 d__147 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; 5__2 = 0; break; case 1: <>1__state = -1; 5__2++; break; } if (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 d__70 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Constrainer constrainer; public Action onDone; public HashSet doneJoints; public SceneSaveFile save; public Core <>4__this; public List made; private int 5__2; private Stopwatch 5__3; private int 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__70(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 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; 5__3.Restart(); goto IL_015a; } <>1__state = -1; if ((Object)(object)constrainer == (Object)null) { onDone?.Invoke(doneJoints?.Count ?? 0); return false; } 5__2 = doneJoints?.Count ?? 0; 5__3 = Stopwatch.StartNew(); 5__4 = 0; goto IL_016a; IL_015a: 5__4++; goto IL_016a; IL_016a: if (5__4 < save.Constraints.Count) { if (doneJoints == null || !doneJoints.Contains(5__4)) { ConstraintRecord record = save.Constraints[5__4]; try { if (core.RestoreConstraint(record, save, made, constrainer)) { 5__2++; doneJoints?.Add(5__4); } } catch (Exception ex) { ((MelonBase)core).LoggerInstance.Warning("Failed to restore constraint: " + ex.Message); } if (5__3.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } goto IL_015a; } onDone?.Invoke(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 d__69 : IEnumerator, 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 made; public Action onDone; private HashSet 5__2; private int 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__69(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 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; 5__2 = new HashSet(); <>8__1.got = 0; 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; 5__3++; goto IL_017d; } IL_017d: if (5__3 >= 3 || <>8__1.got >= save.Constraints.Count) { break; } if (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, 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 d__112 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List made; public Core <>4__this; private Stopwatch 5__2; private int 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__112(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 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; 5__2.Restart(); goto IL_00cf; } <>1__state = -1; 5__2 = Stopwatch.StartNew(); 5__3 = 0; goto IL_00e1; IL_00cf: 5__3++; goto IL_00e1; IL_00e1: if (5__3 < save.Objects.Count && 5__3 < made.Count) { SavedObject savedObject = save.Objects[5__3]; if (savedObject?.Health != null && !((Object)(object)made[5__3] == (Object)null)) { core.RestoreHealth(made[5__3], savedObject.Health); if (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 d__118 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerAmmoRecord ammo; private AmmoInventory 5__2; private int 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__118(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 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; } 5__2 = null; 5__3 = 0; break; case 1: <>1__state = -1; 5__3++; break; } if (5__3 < 180) { 5__2 = AmmoInventory.Instance; if (!((Object)(object)5__2 != (Object)null)) { <>2__current = null; <>1__state = 1; return true; } } if ((Object)(object)5__2 == (Object)null) { return false; } try { 5__2.ClearAmmo(); 5__2.AddCartridge(5__2.lightAmmoGroup, Math.Max(0, ammo.LightAmmo)); 5__2.AddCartridge(5__2.mediumAmmoGroup, Math.Max(0, ammo.MediumAmmo)); 5__2.AddCartridge(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 d__119 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerInventoryRecord inv; public Core <>4__this; private RigManager 5__2; private int 5__3; private int 5__4; private List.Enumerator <>7__wrap4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__2 = null; <>7__wrap4 = default(List.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; } 5__2 = null; 5__4 = 0; goto IL_00c2; case 1: <>1__state = -1; 5__4++; goto IL_00c2; case 2: { <>1__state = -3; 5__3++; break; } IL_00c2: if (5__4 < 180) { 5__2 = TryGetRigManager(); RigManager obj = 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 = 5__2; if (obj3 == null) { obj4 = null; } else { Inventory inventory2 = obj3.inventory; obj4 = ((inventory2 != null) ? inventory2.bodySlots : null); } if (obj4 == null) { return false; } 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(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.Enumerator); if (5__3 > 0) { ((MelonBase)core).LoggerInstance.Msg($"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 d__132 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public List made; public SceneSaveFile save; public bool keepKinematic; public Dictionary frozen; private Stopwatch 5__2; private int 5__3; private Poolee 5__4; private bool 5__5; private bool 5__6; private List.Enumerator <>7__wrap6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__2 = null; 5__4 = null; <>7__wrap6 = default(List.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; 5__2.Restart(); goto IL_0268; } <>1__state = -1; 5__2 = Stopwatch.StartNew(); 5__3 = 0; goto IL_02a3; IL_02a3: if (5__3 < save.Objects.Count && 5__3 < made.Count) { 5__4 = made[5__3]; SavedObject savedObject = save.Objects[5__3]; if (!((Object)(object)5__4 == (Object)null) && savedObject != null) { 5__5 = IsDeadNpcObject(savedObject); 5__6 = OnlyRootPoseForThis(savedObject); <>7__wrap6 = savedObject.Transforms.GetEnumerator(); <>1__state = -3; goto IL_0268; } goto IL_0291; } return false; IL_0291: 5__3++; goto IL_02a3; IL_0268: while (<>7__wrap6.MoveNext()) { TransformRecord current = <>7__wrap6.Current; if ((5__6 && !RootRecord(current)) || current.Rigidbody == null) { continue; } Transform val = ResolveBySiblingPath(((Component)5__4).transform, current.SiblingPath); if ((Object)(object)val == (Object)null) { val = ResolveRelativePath(((Component)5__4).transform, current.Path); } if ((Object)(object)val == (Object)null) { continue; } Rigidbody component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { continue; } component.isKinematic = (keepKinematic | 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 | 5__5) ? Vector3.zero : val2); component.angularVelocity = ((keepKinematic | 5__5) ? Vector3.zero : val3); if (keepKinematic) { ClearRigidbodyMotion(component); } else { frozen.Remove(component); if (!5__5 && !current.Rigidbody.IsKinematic) { component.WakeUp(); component.velocity = val2; component.angularVelocity = val3; } } if (5__2.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap6 = default(List.Enumerator); 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 d__292 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public Core <>4__this; private Dictionary 5__2; private Stopwatch 5__3; private int 5__4; private List.Enumerator <>7__wrap4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__2 = null; 5__3 = null; <>7__wrap4 = default(List.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; } 5__2 = new Dictionary(StringComparer.Ordinal); 5__3 = Stopwatch.StartNew(); 5__4 = 0; <>7__wrap4 = save.SceneLogic.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; 5__3.Restart(); break; } while (<>7__wrap4.MoveNext()) { SceneLogicRecord current = <>7__wrap4.Current; if (core.RestoreSceneLogicRecord(current, 5__2)) { 5__4++; } if (5__3.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap4 = default(List.Enumerator); if (5__4 > 0) { ((MelonBase)core).LoggerInstance.Msg($"Restored {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 d__303 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private MemberInfo <>2__current; private int <>l__initialThreadId; private Type type; public Type <>3__type; private BindingFlags 5__2; private FieldInfo[] <>7__wrap2; private int <>7__wrap3; private PropertyInfo[] <>7__wrap4; MemberInfo IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; 5__2 = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; <>7__wrap2 = type.GetFields(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(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 IEnumerable.GetEnumerator() { d__303 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__303(0); } d__.type = <>3__type; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [CompilerGenerated] private sealed class d__120 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public InventorySlotReceiver receiver; public PlayerInventoryItemRecord item; public Core <>4__this; private float 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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); } 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 < 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 d__107 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public int i; public SceneSaveFile save; public bool[] done; public Dictionary> running; public bool retry; public Core <>4__this; public List slow; public List made; public Dictionary frozen; private Task 5__2; private float 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__107(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 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; } 5__2 = null; running.TryGetValue(i, out 5__2); if (5__2 == null || 5__2.IsFaulted || (retry && 5__2.IsCompleted && (Object)(object)5__2.Result == (Object)null)) { 5__2 = core.SpawnSavedObject(save.Objects[i]); running[i] = 5__2; } 5__3 = Time.realtimeSinceStartup + 1f; break; case 1: <>1__state = -1; break; } if (!5__2.IsCompleted && Time.realtimeSinceStartup < 5__3) { <>2__current = null; <>1__state = 1; return true; } if (!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 (5__2.IsFaulted) { ((MelonBase)core).LoggerInstance.Warning("Failed to spawn " + save.Objects[i].Barcode + ": " + 5__2.Exception?.GetBaseException().Message); done[i] = true; return false; } Poolee result = 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 d__105 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public List order; public SceneSaveFile save; public bool[] done; public Core <>4__this; public List made; public Dictionary frozen; private Dictionary> 5__2; private Dictionary 5__3; private List 5__4; private List 5__5; private Queue 5__6; private Queue 5__7; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__105(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; 5__4 = null; 5__5 = null; 5__6 = null; 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; 5__2 = new Dictionary>(); 5__3 = new Dictionary(); 5__4 = new List(); 5__5 = new List(); 5__6 = new Queue(order); goto IL_0149; case 1: <>1__state = -1; goto IL_0149; case 2: { <>1__state = -1; break; } IL_0149: while (5__6.Count > 0 || 5__4.Count > 0) { while (5__6.Count > 0 && 5__4.Count < 6) { int num2 = 5__6.Dequeue(); if (num2 >= 0 && num2 < save.Objects.Count && !done[num2]) { Task value = core.SpawnSavedObject(save.Objects[num2]); 5__2[num2] = value; 5__3[num2] = Time.realtimeSinceStartup; 5__4.Add(num2); } } if (!core.PumpSpawnQueue(save, made, done, frozen, 5__2, 5__3, 5__4, 5__5, retry: false)) { <>2__current = null; <>1__state = 1; return true; } } if (5__5.Count <= 0) { return false; } ((MelonBase)core).LoggerInstance.Msg($"Retrying {5__5.Count} slow spawnables after the first pass."); 5__7 = new Queue(5__5); 5__5.Clear(); break; } while (5__7.Count > 0 || 5__4.Count > 0) { while (5__7.Count > 0 && 5__4.Count < 6) { int num3 = 5__7.Dequeue(); if (num3 >= 0 && num3 < save.Objects.Count && !done[num3]) { if (!5__2.TryGetValue(num3, out var value2) || value2.IsFaulted || (value2.IsCompleted && (Object)(object)value2.Result == (Object)null)) { value2 = core.SpawnSavedObject(save.Objects[num3]); 5__2[num3] = value2; } 5__3[num3] = Time.realtimeSinceStartup; 5__4.Add(num3); } } if (!core.PumpSpawnQueue(save, made, done, frozen, 5__2, 5__3, 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 d__135 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SceneSaveFile save; public List made; public Core <>4__this; private Stopwatch 5__2; private int 5__3; private Stopwatch 5__4; private int 5__5; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__135(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 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; 5__3 = 0; goto IL_0184; case 1: <>1__state = -1; 5__4.Restart(); goto IL_010d; case 2: <>1__state = -1; 5__4 = null; 5__3++; goto IL_0184; case 3: { <>1__state = -1; 5__2.Restart(); goto IL_0249; } IL_0184: if (5__3 < 10) { 5__4 = Stopwatch.StartNew(); 5__5 = 0; goto IL_011d; } 5__2 = Stopwatch.StartNew(); 5__3 = 0; goto IL_0259; IL_010d: 5__5++; goto IL_011d; IL_0259: if (5__3 >= save.Objects.Count || 5__3 >= made.Count) { break; } if (IsDeadNpcObject(save.Objects[5__3]) && !((Object)(object)made[5__3] == (Object)null)) { ReleaseDeadNpcRigidbodies(made[5__3], save.Objects[5__3]); if (5__2.Elapsed.TotalMilliseconds >= restoreBudget) { <>2__current = null; <>1__state = 3; return true; } } goto IL_0249; IL_0249: 5__3++; goto IL_0259; IL_011d: if (5__5 < save.Objects.Count && 5__5 < made.Count) { if (IsDeadNpcObject(save.Objects[5__5]) && !((Object)(object)made[5__5] == (Object)null)) { core.ApplySavedTransforms(made[5__5], save.Objects[5__5], restoreWorldPose: true, keepRigidbodiesFrozen: true); ClearPooleeRigidbodyMotion(made[5__5]); if (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 dontSaveThese = new HashSet(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 _savedIds = new Dictionary(); private readonly Dictionary _loadedIds = new Dictionary(StringComparer.Ordinal); private readonly HashSet _deletedIds = new HashSet(StringComparer.Ordinal); private readonly HashSet _deadPtrs = new HashSet(); 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() != (Object)null) { return false; } if ((Object)(object)((Component)spawner).GetComponentInParent() != (Object)null) { return false; } if ((Object)(object)((Component)spawner).GetComponentInParent() != (Object)null) { return false; } return true; } [IteratorStateMachine(typeof(d__69))] private IEnumerator RestoreConstraintsWithRetryTimeSliced(SceneSaveFile save, List made, Constrainer constrainer, Action onDone) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__69(0) { <>4__this = this, save = save, made = made, constrainer = constrainer, onDone = onDone }; } [IteratorStateMachine(typeof(d__70))] private IEnumerator RestoreConstraintsTimeSliced(SceneSaveFile save, List made, Constrainer constrainer, HashSet doneJoints, Action onDone) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__70(0) { <>4__this = this, save = save, made = made, constrainer = constrainer, doneJoints = doneJoints, onDone = onDone }; } private bool RestoreConstraint(ConstraintRecord record, SceneSaveFile save, List 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(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(); } if (val == null) { val = ((Component)transform).GetComponentInParent(); } if (val == null) { val = ((Component)transform).GetComponentInChildren(true); } if ((Object)(object)val == (Object)null) { Rigidbody val2 = ((Component)transform).GetComponent() ?? ((Component)transform).GetComponentInParent() ?? ((Component)transform).GetComponentInChildren(true); if ((Object)(object)val2 != (Object)null) { val = MarrowBody.Cache.Get(((Component)val2).gameObject) ?? ((Component)val2).GetComponent() ?? ((Component)val2).GetComponentInParent(); } } return val; } private Transform ResolveConstraintTransform(int objectIndex, string relativePath, string siblingPath, SceneSaveFile save, List 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 >= val.childCount) { return null; } val = val.GetChild(result); } return val; } [IteratorStateMachine(typeof(d__78))] private IEnumerator GetOrSpawnConstrainer(Action onResolved) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__78(0) { <>4__this = this, onResolved = onResolved }; } private static void SuppressDummyVisualEffects(GameObject root) { if ((Object)(object)root == (Object)null) { return; } foreach (ParticleSystem componentsInChild in root.GetComponentsInChildren(true)) { componentsInChild.emission.enabled = false; componentsInChild.Stop(true, (ParticleSystemStopBehavior)0); } } private HealthRecord CaptureHealth(Poolee poolee) { AIBrain componentInChildren = ((Component)poolee).GetComponentInChildren(true); object obj; if (componentInChildren == null) { obj = null; } else { BehaviourBaseNav behaviour = componentInChildren.behaviour; obj = ((behaviour != null) ? behaviour.health : null); } SubBehaviourHealth val = (SubBehaviourHealth)obj; if ((Object)(object)componentInChildren == (Object)null && val == null) { return null; } NpcRuntimeState state = NpcBits.GetState(componentInChildren, val); if (val == null) { HealthRecord healthRecord = new HealthRecord(); healthRecord.IsDead = state.IsDead || TryReadBoolMember(componentInChildren, "_isDead", "isDead").GetValueOrDefault(); healthRecord.AppliedDamage = ((state.DamageTaken > 0f) ? new float?(state.DamageTaken) : null); return healthRecord; } float? num = TryReadFloatMember(val, "curr_Health", "currentHealth", "_health", "health"); float? maxHealth = TryReadFloatMember(val, "max_Health", "maxHealth"); bool? isDead = TryReadBoolMember(componentInChildren, "_isDead", "isDead") ?? TryReadBoolMember(val, "_isDead", "isDead"); if (state.IsDead || num <= 0f) { isDead = true; } return new HealthRecord { CurrentHealth = num, MaxHealth = maxHealth, IsDead = isDead, AppliedDamage = ((state.DamageTaken > 0f) ? new float?(state.DamageTaken) : null) }; } private DestructibleRecord CaptureDestructible(Poolee poolee) { ObjectDestructible componentInChildren = ((Component)poolee).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { return null; } return new DestructibleRecord { Health = componentInChildren._health, MaxHealth = componentInChildren.maxHealth, IsDead = componentInChildren._isDead }; } private void RestoreHealth(Poolee poolee, HealthRecord record) { //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_0164: Expected O, but got Unknown //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_011d: Expected O, but got Unknown if (record == null) { return; } AIBrain componentInChildren = ((Component)poolee).GetComponentInChildren(true); object obj; if (componentInChildren == null) { obj = null; } else { BehaviourBaseNav behaviour = componentInChildren.behaviour; obj = ((behaviour != null) ? behaviour.health : null); } SubBehaviourHealth val = (SubBehaviourHealth)obj; if (val == null) { return; } if (record.MaxHealth.HasValue) { TryWriteFloatMember(val, record.MaxHealth.Value, "max_Health", "maxHealth"); } if (record.IsDead.GetValueOrDefault()) { KillNpc(componentInChildren, val); } else if (record.CurrentHealth.HasValue) { if (!TryWriteFloatMember(val, record.CurrentHealth.Value, "curr_Health", "currentHealth", "_health", "health")) { float valueOrDefault = record.MaxHealth.GetValueOrDefault(100f); float num = Mathf.Max(0f, valueOrDefault - record.CurrentHealth.Value); if (num > 0f) { val.TakeDamage(1, new Attack { damage = num }); } } } else if (record.AppliedDamage.HasValue && record.AppliedDamage.Value > 0f) { val.TakeDamage(1, new Attack { damage = record.AppliedDamage.Value }); } } private static void KillNpc(AIBrain brain, SubBehaviourHealth health) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown try { health.TakeDamage(1, new Attack { damage = 999999f }); } catch { } try { if (brain != null) { brain.OnDeath(); } } catch { } } private void RestoreDestructible(Poolee poolee, DestructibleRecord record) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (record == null) { return; } ObjectDestructible componentInChildren = ((Component)poolee).GetComponentInChildren(true); if (!((Object)(object)componentInChildren == (Object)null)) { componentInChildren.maxHealth = record.MaxHealth; componentInChildren._health = record.Health; if (record.IsDead && !componentInChildren._isDead) { componentInChildren.TakeDamage(Vector3.up, componentInChildren._health + 1f, false, (AttackType)64); } else { componentInChildren._isDead = record.IsDead; } } } [IteratorStateMachine(typeof(d__85))] private IEnumerator DespawnExistingPooleesTimeSliced() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__85(0) { <>4__this = this }; } [IteratorStateMachine(typeof(d__86))] private IEnumerator DespawnIgnoredPooleesTimeSliced() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__86(0) { <>4__this = this }; } private static void WalkHierarchy(Transform root, List transforms) { transforms.Add(root); for (int i = 0; i < root.childCount; i++) { Transform child = root.GetChild(i); if (!ShouldIgnoreTransform(child)) { WalkHierarchy(child, transforms); } } } private static bool ShouldIgnoreTransform(Transform transform) { string name = ((Object)transform).name; if (!name.StartsWith("jPt", StringComparison.Ordinal)) { return name.StartsWith("SavingBounds", StringComparison.Ordinal); } return true; } private static string GetRelativePath(Transform root, Transform transform) { if ((Object)(object)root == (Object)(object)transform) { return string.Empty; } List list = new List(); Transform val = transform; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list); } private static string GetSiblingPath(Transform root, Transform transform) { if ((Object)(object)root == (Object)null || (Object)(object)transform == (Object)null) { return null; } List list = new List(); Transform val = transform; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { list.Add(val.GetSiblingIndex()); val = val.parent; } if ((Object)(object)val != (Object)(object)root) { return null; } list.Reverse(); return string.Join("/", list); } private static Transform NormalizeConstraintTransform(Transform transform) { if ((Object)(object)transform != (Object)null && ((Object)transform).name.StartsWith("jPt", StringComparison.Ordinal) && (Object)(object)transform.parent != (Object)null) { return transform.parent; } return transform; } private static Poolee GetPooleeUpwards(Transform transform) { if ((Object)(object)transform != (Object)null) { Poolee val = Poolee.Cache.Get(((Component)transform.root).gameObject); if ((Object)(object)val != (Object)null) { return val; } } while ((Object)(object)transform != (Object)null) { Poolee val2 = Poolee.Cache.Get(((Component)transform).gameObject); if ((Object)(object)val2 != (Object)null) { return val2; } transform = transform.parent; } return null; } private static bool IsProbablyMenuOrSystemObject(Transform transform) { while ((Object)(object)transform != (Object)null) { string name = ((Object)transform).name; if (name.Contains("BoneMenu", StringComparison.OrdinalIgnoreCase) || name.Contains("UIRig", StringComparison.OrdinalIgnoreCase) || name.Contains("PopUpMenu", StringComparison.OrdinalIgnoreCase) || name.Contains("PreferencesPanel", StringComparison.OrdinalIgnoreCase) || name.Contains("QuickMenu", StringComparison.OrdinalIgnoreCase) || name.Contains("SceneSave Dummy", StringComparison.OrdinalIgnoreCase) || name.Contains("SSBL Dummy", StringComparison.OrdinalIgnoreCase)) { return true; } transform = transform.parent; } return false; } [IteratorStateMachine(typeof(d__95))] private IEnumerator LoadCurrentLevelSave(string path, bool automatic = false) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__95(0) { <>4__this = this, path = path, automatic = automatic }; } private static float GetLoadDelay(bool automatic) { if (!automatic) { return 0.05f; } return 1.25f; } private static SceneSaveFile LoadSaveFile(string path) { return ReadSaveMaybe(path); } private static List GetSpawnOrder(SceneSaveFile save) { return (from i in Enumerable.Range(0, save.Objects.Count) where CanLoadSavedObject(save.Objects[i]) select i).OrderBy(delegate(int i) { if (!save.Objects[i].HasAIBrain) { HealthRecord health = save.Objects[i].Health; if (health == null || !health.IsDead.GetValueOrDefault()) { return 1; } } return 0; }).ThenBy((int i) => save.Objects[i].Transforms?.Count ?? 0).ThenBy((int i) => i) .ToList(); } private static float? TryReadFloatMember(object target, params string[] names) { foreach (string name in names) { object obj = TryReadMember(target, name); if (obj is float) { return (float)obj; } if (obj is int num) { return num; } } return null; } private static bool? TryReadBoolMember(object target, params string[] names) { foreach (string name in names) { object obj = TryReadMember(target, name); if (obj is bool) { return (bool)obj; } } return null; } private static int? TryReadIntMember(object target, params string[] names) { foreach (string name in names) { object obj = TryReadMember(target, name); if (obj is int) { return (int)obj; } if (obj is byte) { return (byte)obj; } if (obj is short) { return (short)obj; } if (obj is long num) { return (int)((num > int.MaxValue) ? int.MaxValue : ((num < int.MinValue) ? int.MinValue : num)); } } return null; } private static object TryReadMember(object target, string name) { if (target == null) { return null; } Type type = target.GetType(); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(target); } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanRead) { return property.GetValue(target); } return null; } private static bool TryWriteFloatMember(object target, float value, params string[] names) { foreach (string name in names) { if (TryWriteMember(target, name, value)) { return true; } } return false; } private static bool TryWriteMember(object target, string name, object value) { if (target == null) { return false; } Type type = target.GetType(); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(target, value); return true; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(target, value); return true; } return false; } [IteratorStateMachine(typeof(d__105))] private IEnumerator SpawnSavedObjectsOneAtATime(SceneSaveFile save, List made, bool[] done, Dictionary frozen, List order) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__105(0) { <>4__this = this, save = save, made = made, done = done, frozen = frozen, order = order }; } private bool PumpSpawnQueue(SceneSaveFile save, List made, bool[] done, Dictionary frozen, Dictionary> running, Dictionary started, List active, List slow, bool retry) { bool result = false; for (int num = active.Count - 1; num >= 0; num--) { int num2 = active[num]; if (!running.TryGetValue(num2, out var value)) { active.RemoveAt(num); result = true; } else if (!value.IsCompleted) { if (started.TryGetValue(num2, out var value2) && Time.realtimeSinceStartup - value2 >= 1f) { active.RemoveAt(num); if (!retry) { slow?.Add(num2); } else { ((MelonBase)this).LoggerInstance.Warning("Still waiting on slow spawnable after retry: " + save.Objects[num2].Barcode); } result = true; } } else { active.RemoveAt(num); started.Remove(num2); if (value.IsFaulted) { ((MelonBase)this).LoggerInstance.Warning("Failed to spawn " + save.Objects[num2].Barcode + ": " + value.Exception?.GetBaseException().Message); done[num2] = true; result = true; } else { Poolee result2 = value.Result; if ((Object)(object)result2 == (Object)null) { if (!retry) { slow?.Add(num2); } else { ((MelonBase)this).LoggerInstance.Warning("Spawn returned null for " + save.Objects[num2].Barcode); done[num2] = true; } result = true; } else { made[num2] = result2; RememberLoadedSaveId(result2, save.Objects[num2]); TouchLoadedPoolee(result2, save.Objects[num2], frozen); RestoreObjectState(result2, save.Objects[num2], keepRigidbodiesFrozen: true); done[num2] = true; result = true; } } } } return result; } [IteratorStateMachine(typeof(d__107))] private IEnumerator SpawnOneSavedObject(SceneSaveFile save, List made, bool[] done, Dictionary frozen, Dictionary> running, List slow, int i, bool retry) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__107(0) { <>4__this = this, save = save, made = made, done = done, frozen = frozen, running = running, slow = slow, i = i, retry = retry }; } private void MarkExistingDeletedPoolees(SceneSaveFile save) { if (save?.DeletedSaveIds == null || save.DeletedSaveIds.Count == 0) { return; } HashSet hashSet = save.DeletedSaveIds.Where((string id) => !string.IsNullOrWhiteSpace(id)).ToHashSet(StringComparer.Ordinal); if (hashSet.Count == 0) { return; } CrateSpawner[] spawners = SpawnersNow(); int num = 0; Poolee[] array = PooleesNow(); foreach (Poolee val in array) { if (!((Object)(object)val == (Object)null) && !((Il2CppObjectBase)val).WasCollected && IsDeletedPoolee(val, save.LevelBarcode, spawners, hashSet)) { _deadPtrs.Add(((Il2CppObjectBase)val).Pointer); num++; } } if (num > 0) { ((MelonBase)this).LoggerInstance.Msg($"Marked {num} existing scene poolees as deleted before loading the save."); } } private static void TouchLoadedPoolee(Poolee poolee, SavedObject thing, Dictionary frozen) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)poolee == (Object)null) && thing != null) { ((Component)poolee).transform.position = thing.Position.ToUnity(); ((Component)poolee).transform.rotation = Quaternion.Euler(thing.Rotation.ToUnity()); ((Component)poolee).transform.localScale = thing.Scale.ToUnity(); FreezePooleeRigidbodies(poolee, frozen); ClearPooleeRigidbodyMotion(poolee); } } private void RememberLoadedSaveId(Poolee poolee, SavedObject thing) { if (!((Object)(object)poolee == (Object)null) && thing != null && !string.IsNullOrWhiteSpace(thing.SaveId)) { _savedIds[((Il2CppObjectBase)poolee).Pointer] = thing.SaveId; _loadedIds[thing.SaveId] = poolee; } } [IteratorStateMachine(typeof(d__111))] private IEnumerator ApplyNpcWorldPosePass(SceneSaveFile save, List made) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__111(0) { <>4__this = this, save = save, made = made }; } [IteratorStateMachine(typeof(d__112))] private IEnumerator RestoreNpcHealthTimeSliced(SceneSaveFile save, List made) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__112(0) { <>4__this = this, save = save, made = made }; } private async Task SpawnSavedObject(SavedObject thing) { _ = 2; try { Poolee val = await SpawnSavedObjectFromSceneCrateSpawner(thing); if ((Object)(object)val != (Object)null) { ((Component)val).transform.localScale = thing.Scale.ToUnity(); return val; } Vector3 val2 = thing.Position.ToUnity(); Quaternion val3 = Quaternion.Euler(thing.Rotation.ToUnity()); Vector3 scale = thing.Scale.ToUnity(); val = ((!FusionCompat.InRoom || !FusionCompat.Hosting) ? (await SpawnBits.SpawnAsync(thing.Barcode, val2, val3, scale)) : (await FusionCompat.SpawnSceneThing(thing.Barcode, val2, val3, scale))); if ((Object)(object)val != (Object)null) { ((Component)val).transform.localScale = thing.Scale.ToUnity(); } return val; } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Warning("Failed to spawn " + thing.Barcode + ": " + ex.Message); return null; } } private Task SpawnSavedObjectFromSceneCrateSpawner(SavedObject thing) { TaskCompletionSource tcs = new TaskCompletionSource(); if (_skipSceneSpawnerRouteForLoad) { tcs.TrySetResult(null); return tcs.Task; } if (thing == null || (!IsSceneSpawnerSavedObject(thing) && !LooksLikeSceneSpawnerSaveId(thing.SaveId))) { tcs.TrySetResult(null); return tcs.Task; } CrateSpawner spawner = FindSceneCrateSpawner(thing); if ((Object)(object)spawner == (Object)null) { tcs.TrySetResult(null); return tcs.Task; } try { UniTask val = spawner.SpawnSpawnableAsync(false); Awaiter awaiter = val.GetAwaiter(); awaiter.OnCompleted(Action.op_Implicit((Action)delegate { //IL_0041: Unknown result type (might be due to invalid IL or missing references) try { Poolee result = awaiter.GetResult(); if ((Object)(object)result != (Object)null) { tcs.TrySetResult(result); } else { tcs.TrySetResult(FindRecentlySpawnedScenePoolee(thing, ((Component)spawner).transform.position)); } } catch (Exception ex2) { ((MelonBase)this).LoggerInstance.Warning("Scene CrateSpawner spawn failed for " + thing.Name + ": " + ex2.Message); tcs.TrySetResult(null); } })); } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Warning("Scene CrateSpawner spawn failed for " + thing.Name + ": " + ex.Message); tcs.TrySetResult(null); } return tcs.Task; } private CrateSpawner FindSceneCrateSpawner(SavedObject thing) { if (thing == null || string.IsNullOrWhiteSpace(thing.Barcode)) { return null; } string text = ((!string.IsNullOrWhiteSpace(thing.SceneSpawnerId)) ? thing.SceneSpawnerId : thing.SaveId); if (string.IsNullOrWhiteSpace(text)) { return null; } CrateSpawner[] array = SpawnersNow(); foreach (CrateSpawner val in array) { if (TryGetCrateSpawnerBarcode(val, out var barcode) && string.Equals(barcode, thing.Barcode, StringComparison.Ordinal)) { string sceneCrateSpawnerSaveId = GetSceneCrateSpawnerSaveId(_levelBarcode, val, barcode); if (string.Equals(sceneCrateSpawnerSaveId, text, StringComparison.Ordinal) || string.Equals(sceneCrateSpawnerSaveId, thing.SaveId, StringComparison.Ordinal)) { return val; } } } return null; } private Poolee FindRecentlySpawnedScenePoolee(SavedObject thing, Vector3 spawnerPosition) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (thing == null || string.IsNullOrWhiteSpace(thing.Barcode)) { return null; } Poolee result = null; float num = float.PositiveInfinity; Poolee[] array = PooleesNow(); foreach (Poolee val in array) { if ((Object)(object)val == (Object)null || ((Il2CppObjectBase)val).WasCollected) { continue; } SpawnableCrate spawnableCrate = val.SpawnableCrate; if (!(((spawnableCrate != null) ? ((Scannable)spawnableCrate).Barcode : null) == (Barcode)null) && string.Equals(((Scannable)val.SpawnableCrate).Barcode.ID, thing.Barcode, StringComparison.Ordinal)) { float num2 = Vector3.Distance(((Component)val).transform.position, spawnerPosition); if (num2 < num) { result = val; num = num2; } } } if (!(num <= 4f)) { return null; } return result; } private void RestoreObjectState(Poolee poolee, SavedObject thing, bool keepRigidbodiesFrozen = false) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)poolee == (Object)null) && !((Il2CppObjectBase)poolee).WasCollected) { ApplySavedTransforms(poolee, thing, restoreWorldPose: false, keepRigidbodiesFrozen); if (thing.HasAIBrain) { ((Component)poolee).transform.position = thing.Position.ToUnity(); ((Component)poolee).transform.rotation = Quaternion.Euler(thing.Rotation.ToUnity()); } RestoreHealth(poolee, thing.Health); RestoreDestructible(poolee, thing.Destructible); } } [IteratorStateMachine(typeof(d__118))] private static IEnumerator RestorePlayerAmmoWhenReady(PlayerAmmoRecord ammo) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__118(0) { ammo = ammo }; } [IteratorStateMachine(typeof(d__119))] private IEnumerator RestorePlayerInventoryWhenReady(PlayerInventoryRecord inv) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__119(0) { <>4__this = this, inv = inv }; } [IteratorStateMachine(typeof(d__120))] private IEnumerator SpawnInventoryItem(InventorySlotReceiver receiver, PlayerInventoryItemRecord item) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__120(0) { <>4__this = this, receiver = receiver, item = item }; } private static SlotContainer FindBodySlot(RigManager rig, string slotName) { object obj; if (rig == null) { obj = null; } else { Inventory inventory = rig.inventory; obj = ((inventory != null) ? inventory.bodySlots : null); } if (obj == null) { return null; } foreach (SlotContainer item in (Il2CppArrayBase)(object)rig.inventory.bodySlots) { if ((Object)(object)item != (Object)null && ((Object)((Component)item).gameObject).name == slotName) { return item; } } return null; } private static Poolee FindPooleeInReceiver(InventorySlotReceiver receiver) { try { if ((Object)(object)receiver == (Object)null || (Object)(object)receiver._slottedWeapon == (Object)null) { return null; } InteractableHost interactableHost = receiver._slottedWeapon.interactableHost; object obj = TryReadMember(TryReadMember(interactableHost, "marrowEntity"), "_poolee"); Poolee val = (Poolee)((obj is Poolee) ? obj : null); if ((Object)(object)val != (Object)null) { return val; } GameObject val2 = (((Object)(object)interactableHost == (Object)null) ? null : ((Component)interactableHost).gameObject); return ((Object)(object)val2 == (Object)null) ? null : val2.GetComponentInParent(); } catch { return null; } } private void ApplySavedTransforms(Poolee poolee, SavedObject thing, bool restoreWorldPose, bool keepRigidbodiesFrozen = false) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)poolee == (Object)null || thing == null) { return; } bool flag = OnlyRootPoseForThis(thing); Dictionary dictionary = null; foreach (TransformRecord transform in thing.Transforms) { if (flag && !RootRecord(transform)) { continue; } Transform value = ResolveBySiblingPath(((Component)poolee).transform, transform.SiblingPath); if ((Object)(object)value == (Object)null) { if (dictionary == null) { dictionary = BuildRuntimeTransformMap(((Component)poolee).transform); } if (!dictionary.TryGetValue(transform.Path, out value)) { continue; } } value.localPosition = transform.LocalPosition.ToUnity(); value.localRotation = Quaternion.Euler(transform.LocalRotation.ToUnity()); value.localScale = transform.LocalScale.ToUnity(); bool flag2 = restoreWorldPose && transform.HasWorldPose && !string.IsNullOrEmpty(transform.SiblingPath); if (flag2) { value.position = transform.WorldPosition.ToUnity(); value.rotation = Quaternion.Euler(transform.WorldRotation.ToUnity()); } PutSmallObjectStateBack(value, transform); if (transform.Rigidbody == null) { continue; } Rigidbody component = ((Component)value).GetComponent(); if (!((Object)(object)component == (Object)null)) { if (flag2) { component.position = transform.WorldPosition.ToUnity(); component.rotation = Quaternion.Euler(transform.WorldRotation.ToUnity()); } component.isKinematic = keepRigidbodiesFrozen || transform.Rigidbody.IsKinematic; component.useGravity = transform.Rigidbody.UseGravity; component.velocity = transform.Rigidbody.Velocity.ToUnity(); component.angularVelocity = transform.Rigidbody.AngularVelocity.ToUnity(); } } } private static void PutSmallObjectStateBack(Transform transform, TransformRecord record) { if ((Object)(object)transform == (Object)null || record == null) { return; } if (record.ComponentToggles != null && record.ComponentToggles.Count > 0) { foreach (ComponentToggleRecord componentToggle in record.ComponentToggles) { if (DontGrabTinyState(componentToggle.TypeName)) { continue; } Component val = FindSavedComponent(transform, componentToggle.TypeName, componentToggle.TypeSlot); if ((Object)(object)val == (Object)null) { continue; } try { Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if (val2 != null) { val2.enabled = componentToggle.Enabled; continue; } Renderer val3 = (Renderer)(object)((val is Renderer) ? val : null); if (val3 != null) { val3.enabled = componentToggle.Enabled; continue; } Collider val4 = (Collider)(object)((val is Collider) ? val : null); if (val4 != null) { val4.enabled = componentToggle.Enabled; } } catch { } } } if (record.ComponentBools != null && record.ComponentBools.Count > 0) { foreach (ComponentBoolRecord componentBool in record.ComponentBools) { if (string.IsNullOrWhiteSpace(componentBool.Name) || DontGrabTinyState(componentBool.TypeName)) { continue; } Component val5 = FindSavedComponent(transform, componentBool.TypeName, componentBool.TypeSlot); if (!((Object)(object)val5 == (Object)null)) { try { TryWriteMember(val5, componentBool.Name, componentBool.Value); } catch { } } } } if (record.ComponentFloats != null && record.ComponentFloats.Count > 0) { foreach (ComponentFloatRecord componentFloat in record.ComponentFloats) { if (string.IsNullOrWhiteSpace(componentFloat.Name) || DontGrabTinyState(componentFloat.TypeName)) { continue; } Component val6 = FindSavedComponent(transform, componentFloat.TypeName, componentFloat.TypeSlot); if (!((Object)(object)val6 == (Object)null)) { try { TryWriteMember(val6, componentFloat.Name, componentFloat.Value); } catch { } } } } try { if (((Component)transform).gameObject.activeSelf != record.ActiveSelf) { ((Component)transform).gameObject.SetActive(record.ActiveSelf); } } catch { } } private static Component FindSavedComponent(Transform transform, string typeName, int slot) { if ((Object)(object)transform == (Object)null || string.IsNullOrWhiteSpace(typeName)) { return null; } Component[] array; try { array = Il2CppArrayBase.op_Implicit(((Component)transform).GetComponents()); } catch { return null; } int num = 0; Component[] array2 = array; foreach (Component val in array2) { if (!((Object)(object)val == (Object)null) && string.Equals(GetCompName(val), typeName, StringComparison.Ordinal)) { if (num == slot) { return val; } num++; } } return null; } private static bool DontGrabTinyState(Component comp, string typeName) { if ((Object)(object)comp == (Object)null) { return true; } if (comp is Transform) { return true; } return DontGrabTinyState(typeName); } private static bool DontGrabTinyState(string typeName) { if (string.IsNullOrWhiteSpace(typeName)) { return true; } if (typeName == "UnityEngine.Transform") { return true; } if (typeName == "UnityEngine.RectTransform") { return true; } return false; } private static Dictionary BuildRuntimeTransformMap(Transform root) { Dictionary dictionary = new Dictionary(StringComparer.Ordinal); List list = new List(); WalkHierarchy(root, list); foreach (Transform item in list) { dictionary[GetRelativePath(root, item)] = item; } return dictionary; } private static void FreezePooleeRigidbodies(Poolee poolee, Dictionary frozen) { if ((Object)(object)poolee == (Object)null) { return; } foreach (Rigidbody componentsInChild in ((Component)poolee).GetComponentsInChildren(true)) { if (!((Object)(object)componentsInChild == (Object)null) && !frozen.ContainsKey(componentsInChild)) { frozen[componentsInChild] = componentsInChild.isKinematic; componentsInChild.isKinematic = true; } } } private void RegrabLoadedRigidbodies(SceneSaveFile save, List made, Dictionary frozen) { if (save == null || frozen == null) { return; } if (made != null) { for (int i = 0; i < made.Count; i++) { if ((Object)(object)made[i] == (Object)null && save.Objects != null && i < save.Objects.Count) { made[i] = FindLoadedPooleeForSavedObject(save.Objects[i]); } FreezePooleeRigidbodies(made[i], frozen); } } HashSet hashSet = (from obj in save.Objects?.Where((SavedObject obj) => obj != null && !string.IsNullOrWhiteSpace(obj.SaveId)) select obj.SaveId).ToHashSet(StringComparer.Ordinal) ?? new HashSet(StringComparer.Ordinal); if (hashSet.Count == 0) { return; } Poolee[] array = PooleesNow(); foreach (Poolee val in array) { if (!((Object)(object)val == (Object)null) && !((Il2CppObjectBase)val).WasCollected && _savedIds.TryGetValue(((Il2CppObjectBase)val).Pointer, out var value) && hashSet.Contains(value)) { FreezePooleeRigidbodies(val, frozen); } } } private Poolee FindLoadedPooleeForSavedObject(SavedObject obj) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) if (obj == null) { return null; } Poolee[] array; if (!string.IsNullOrWhiteSpace(obj.SaveId)) { if (_loadedIds.TryGetValue(obj.SaveId, out var value)) { if ((Object)(object)value != (Object)null && !((Il2CppObjectBase)value).WasCollected) { return value; } _loadedIds.Remove(obj.SaveId); } array = PooleesNow(); foreach (Poolee val in array) { if (!((Object)(object)val == (Object)null) && !((Il2CppObjectBase)val).WasCollected && _savedIds.TryGetValue(((Il2CppObjectBase)val).Pointer, out var value2) && string.Equals(value2, obj.SaveId, StringComparison.Ordinal)) { _loadedIds[obj.SaveId] = val; return val; } } } if (string.IsNullOrWhiteSpace(obj.Barcode)) { return null; } Vector3 val2 = obj.Position.ToUnity(); Poolee val3 = null; float num = 3f; array = PooleesNow(); foreach (Poolee val4 in array) { if ((Object)(object)val4 == (Object)null || ((Il2CppObjectBase)val4).WasCollected) { continue; } SpawnableCrate spawnableCrate = val4.SpawnableCrate; if (!(((spawnableCrate != null) ? ((Scannable)spawnableCrate).Barcode : null) == (Barcode)null) && string.Equals(((Scannable)val4.SpawnableCrate).Barcode.ID, obj.Barcode, StringComparison.Ordinal)) { float num2 = Vector3.Distance(((Component)val4).transform.position, val2); if (!(num2 > num)) { val3 = val4; num = num2; } } } if ((Object)(object)val3 != (Object)null && !string.IsNullOrWhiteSpace(obj.SaveId)) { _savedIds[((Il2CppObjectBase)val3).Pointer] = obj.SaveId; _loadedIds[obj.SaveId] = val3; } return val3; } [IteratorStateMachine(typeof(d__132))] private static IEnumerator RestoreSavedRigidbodyStatesTimeSliced(SceneSaveFile save, List made, Dictionary frozen, bool keepKinematic) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__132(0) { save = save, made = made, frozen = frozen, keepKinematic = keepKinematic }; } [IteratorStateMachine(typeof(d__133))] private static IEnumerator HoldKinematicLoadWindow(float seconds, Dictionary frozen) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__133(0) { seconds = seconds, frozen = frozen }; } private static void ReassertFrozenRigidbodies(Dictionary frozen) { if (frozen == null) { return; } foreach (Rigidbody item in frozen.Keys.ToList()) { if ((Object)(object)item == (Object)null) { frozen.Remove(item); continue; } item.isKinematic = true; ClearRigidbodyMotion(item); } } [IteratorStateMachine(typeof(d__135))] private IEnumerator StabilizeDeadNpcPosesTimeSliced(SceneSaveFile save, List made) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__135(0) { <>4__this = this, save = save, made = made }; } private static bool IsDeadNpcObject(SavedObject obj) { if (obj != null && obj.HasAIBrain) { return obj.Health?.IsDead.GetValueOrDefault() ?? false; } return false; } private static void ClearPooleeRigidbodyMotion(Poolee poolee) { if ((Object)(object)poolee == (Object)null) { return; } foreach (Rigidbody componentsInChild in ((Component)poolee).GetComponentsInChildren(true)) { ClearRigidbodyMotion(componentsInChild); } } private static void ClearRigidbodyMotion(Rigidbody rb) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rb == (Object)null)) { rb.velocity = Vector3.zero; rb.angularVelocity = Vector3.zero; rb.Sleep(); } } private static void ReleaseDeadNpcRigidbodies(Poolee poolee, SavedObject obj) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) foreach (TransformRecord transform in obj.Transforms) { if (transform.Rigidbody == null) { continue; } Transform val = ResolveBySiblingPath(((Component)poolee).transform, transform.SiblingPath); if ((Object)(object)val == (Object)null) { val = ResolveRelativePath(((Component)poolee).transform, transform.Path); } if (!((Object)(object)val == (Object)null)) { Rigidbody component = ((Component)val).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.position = transform.WorldPosition.ToUnity(); component.rotation = Quaternion.Euler(transform.WorldRotation.ToUnity()); component.isKinematic = transform.Rigidbody.IsKinematic; component.useGravity = transform.Rigidbody.UseGravity; ClearRigidbodyMotion(component); } } } } private static void UnfreezeRemainingRigidbodies(Dictionary frozen) { KeyValuePair[] array = frozen.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair keyValuePair = array[i]; if ((Object)(object)keyValuePair.Key != (Object)null) { keyValuePair.Key.isKinematic = keyValuePair.Value; } } frozen.Clear(); } private static void NotifySaveLoadStarted() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Loading Save"), Message = NotificationText.op_Implicit("Asynchronously loading saved spawnables. Please wait."), Type = (NotificationType)0, ShowTitleOnPopup = true, PopupLength = 3f }); } private static void NotifySaveLoadFinished(int spawnables, int constraints) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Save Loaded Successfully:"), Message = NotificationText.op_Implicit($"Loaded {spawnables} spawnables, {constraints} constraints."), Type = (NotificationType)3, ShowTitleOnPopup = true, PopupLength = 5f }); } private static void ShowModVersion() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown Notifier.Send(new Notification { Title = NotificationText.op_Implicit("PersistentScene"), Message = NotificationText.op_Implicit("Mod Version: 1.0.0"), Type = (NotificationType)0, ShowTitleOnPopup = true, PopupLength = 5f }); } private void OnUIRigCreated() { MakeSaveQuitButton(); } [IteratorStateMachine(typeof(d__147))] private IEnumerator RefreshSaveQuitSoon() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__147(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(((Component)val).gameObject, parent, false); ((Object)val3).name = "button_SaveAndQuit"; val3.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex()); _saveQuitObj = val3; _saveQuitBtn = val3.GetComponent