using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using HarmonyLib; using Il2Cpp; using Il2CppFishNet; using Il2CppFishNet.Connection; using Il2CppFishNet.Managing; using Il2CppFishNet.Managing.Object; using Il2CppFishNet.Object; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne; using Il2CppScheduleOne.AvatarFramework; using Il2CppScheduleOne.Building; using Il2CppScheduleOne.Core.Items.Framework; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Dialogue; using Il2CppScheduleOne.Employees; using Il2CppScheduleOne.EntityFramework; using Il2CppScheduleOne.GameTime; using Il2CppScheduleOne.Heatmap; using Il2CppScheduleOne.Interaction; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Lighting; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.ObjectScripts; using Il2CppScheduleOne.Persistence; using Il2CppScheduleOne.Persistence.Datas; using Il2CppScheduleOne.Persistence.Loaders; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Product; using Il2CppScheduleOne.Property; using Il2CppScheduleOne.Storage; using Il2CppScheduleOne.Tiles; using Il2CppScheduleOne.UI; using Il2CppScheduleOne.UI.Management; using Il2CppScheduleOne.Variables; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using S1API.AssetBundles; using S1API.Economy; using S1API.Entities; using S1API.Entities.Customer; using S1API.Entities.Relation; using S1API.GameTime; using S1API.Internal.Abstraction; using S1API.Items; using S1API.Leveling; using S1API.Map; using S1API.Map.Buildings; using S1API.Products; using S1API.Quests; using S1API.Quests.Constants; using S1API.Saveables; using SidewalkEconomy; using SidewalkEconomy.Controllers; using SidewalkEconomy.Helpers; using SidewalkEconomy.Saveables; using UnityEngine; using UnityEngine.AI; using UnityEngine.Events; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(SidewalkEconomyMod), "SidewalkEconomy", "1.0.1", "SirTidez", null)] [assembly: MelonColor(1, 0, 0, 255)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("SidewalkEconomy-IL2CPP")] [assembly: AssemblyConfiguration("Debug IL2CPP")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+de42324db45c550550d20429a0fc34e385f32488")] [assembly: AssemblyProduct("SidewalkEconomy-IL2CPP")] [assembly: AssemblyTitle("SidewalkEconomy-IL2CPP")] [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.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = 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 SidewalkEconomy { public static class BuildInfo { public const string Name = "SidewalkEconomy"; public const string Description = "Allows placing buildable items anywhere on the map"; public const string Author = "SirTidez"; public const string Version = "1.0.1"; } public class SidewalkEconomyMod : MelonMod { [CompilerGenerated] private sealed class d__61 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SidewalkEconomyMod <>4__this; private int 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__61(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; ModLogger.Info("CheckTentSpawnOnSceneLoad: Started waiting for tent prefab..."); 5__1 = 0; goto IL_0074; case 1: <>1__state = -1; goto IL_0074; case 2: { <>1__state = -1; ModLogger.Info($"CheckTentSpawnOnSceneLoad: Tent prefab loaded after {5__1} attempts - performing initial level check"); <>4__this.OnDayPass(); ModLogger.Info("CheckTentSpawnOnSceneLoad: OnDayPass() called"); return false; } IL_0074: if (!EnsureTentPrefabReady(5__1 > 0) && 5__1 < 100) { 5__1++; <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } if (!EnsureTentPrefabReady(logReload: true)) { ModLogger.Warn("Tent prefab not loaded after waiting - cannot perform initial level check"); return false; } <>2__current = (object)new WaitForSeconds(1.5f); <>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__59 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SidewalkEconomyMod <>4__this; private float 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__59(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; 5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (TentOwnershipSaveable.Instance == null || !TentOwnershipSaveable.Instance.IsReady) { if (Time.time - 5__1 > 10f) { ModLogger.Warn("Timed out waiting for tent ownership saveable"); return false; } <>2__current = null; <>1__state = 1; return true; } TentOwnershipManager.SetTentOwned(owned: true); ModLogger.Info("Tent ownership set to player"); 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__65 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SidewalkEconomyMod <>4__this; private WrappedAssetBundle 5__1; private string[] 5__2; private string[] <>s__3; private int <>s__4; private string 5__5; private Exception 5__6; private Exception 5__7; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__65(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__2 = null; <>s__3 = null; 5__5 = null; 5__6 = null; 5__7 = null; <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; try { ModLogger.Debug("Loading assetbundle assets..."); if (CachedAssetBundle == null) { ModLogger.Debug("Loading assetbundle..."); CachedAssetBundle = AssetBundleUtils.LoadAssetBundle("SidewalkEconomy.sidewalkeconomy"); if (CachedAssetBundle == null) { ModLogger.Error("Failed to load assetbundle"); return false; } ModLogger.Debug("✓ Assetbundle loaded successfully"); } 5__1 = CachedAssetBundle; try { ModLogger.Info("=== Listing all assets in assetbundle ==="); 5__2 = 5__1.GetAllAssetNames(); ModLogger.Info($"Total assets in bundle: {5__2.Length}"); <>s__3 = 5__2; for (<>s__4 = 0; <>s__4 < <>s__3.Length; <>s__4++) { 5__5 = <>s__3[<>s__4]; ModLogger.Info(" - " + 5__5); 5__5 = null; } <>s__3 = null; ModLogger.Info("=== End of asset list ==="); 5__2 = null; } catch (Exception ex) { 5__6 = ex; ModLogger.Warn("Failed to list assets: " + 5__6.Message); ModLogger.Warn("Stack trace: " + 5__6.StackTrace); } ModLogger.Debug("Loading sleepingbag prefab: assets/sidewalk economy/sleepingbag.prefab"); SleepingBagPrefab = 5__1.LoadAsset("assets/sidewalk economy/sleepingbag.prefab"); if ((Object)(object)SleepingBagPrefab == (Object)null) { ModLogger.Warn("Failed to load sleepingbag prefab 'assets/sidewalk economy/sleepingbag.prefab' from assetbundle"); } else { ModLogger.Info("✓ Sleepingbag prefab loaded: " + ((Object)SleepingBagPrefab).name); ShaderUtils.FixShadersOnGameObject(SleepingBagPrefab); } ModLogger.Debug("Loading tent prefab: assets/sidewalk economy/tent.prefab"); TentPrefab = 5__1.LoadAsset("assets/sidewalk economy/tent.prefab"); if ((Object)(object)TentPrefab == (Object)null) { ModLogger.Warn("Failed to load tent prefab 'assets/sidewalk economy/tent.prefab' from assetbundle"); } else { _tentPrefabLoadedOnce = true; ModLogger.Info("✓ Tent prefab loaded: " + ((Object)TentPrefab).name); ShaderUtils.FixShadersOnGameObject(TentPrefab); } ModLogger.Info("Assetbundle assets loaded successfully"); PrefabControllerInstaller.InstallControllers(SleepingBagPrefab, TentPrefab); ModLogger.Info("Scheduling custom buildable item registration..."); MelonCoroutines.Start(ItemRegistrationManager.RegisterCustomItemsWhenReady()); ModLogger.Info("Requesting initial world spawns..."); WorldSpawnManager.SpawnInitialShelters(SleepingBagPrefab, TentPrefab); 5__1 = null; } catch (Exception ex) { 5__7 = ex; ModLogger.Error("[MainMod] Failed to load assetbundle assets: " + 5__7.Message); ModLogger.Error("Stack trace: " + 5__7.StackTrace); } 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__63 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private SaveManager 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__63(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (!Singleton.InstanceExists) { <>2__current = null; <>1__state = 1; return true; } if (_saveListenerRegistered) { return false; } 5__1 = Singleton.Instance; if ((Object)(object)5__1 == (Object)null) { return false; } if (_saveStartHandler == null) { _saveStartHandler = OnGameSaveStarted; } 5__1.onSaveStart.AddListener(UnityAction.op_Implicit(_saveStartHandler)); _saveListenerRegistered = true; ModLogger.Debug("Registered outside buildable save listener"); 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__60 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SidewalkEconomyMod <>4__this; private Exception 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__60(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (_dayPassEventSubscribed) { return false; } <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 2; return true; case 2: <>1__state = -1; try { ModLogger.Debug("Subscribing to S1API TimeManager.OnDayPass event"); TimeManager.OnDayPass = (Action)Delegate.Combine(TimeManager.OnDayPass, new Action(<>4__this.OnDayPass)); _dayPassEventSubscribed = true; ModLogger.Info("Subscribed to day pass event - tent will spawn when player reaches Peddler rank"); } catch (Exception ex) { 5__1 = ex; ModLogger.Error("Failed to subscribe to day pass event: " + 5__1.Message); ModLogger.Error("Stack trace: " + 5__1.StackTrace); } 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(); } } private const float SyntheticPropertyRenameDistance = 30f; private const int SyntheticPropertyNameMaxLength = 48; private const float SyntheticIdleEditDistance = 40f; private const float SyntheticIdleYawStep = 5f; private static Harmony HarmonyInstance; private static bool _tentSpawned; private static bool _tentPrefabLoadedOnce; private static bool _dayPassEventSubscribed; private static bool _saveListenerRegistered; private static Action _saveStartHandler; private bool _showSyntheticPropertyRenameWindow; private bool _focusSyntheticPropertyNameInput; private string _syntheticPropertyNameInput = string.Empty; private string _syntheticPropertyRenameError = string.Empty; private Rect _syntheticPropertyRenameWindowRect = new Rect(24f, 24f, 420f, 180f); private Property _selectedSyntheticProperty; private bool _isSyntheticIdleEditMode; private Property _syntheticIdleEditProperty; private Vector3 _syntheticIdleEditPosition; private float _syntheticIdleEditYaw; private bool _syntheticIdleEditValid; private string _syntheticIdleEditStatus = string.Empty; private GameObject _syntheticIdleEditGizmo; private Renderer _syntheticIdleEditGizmoBaseRenderer; private Renderer _syntheticIdleEditGizmoArrowRenderer; public static WrappedAssetBundle? CachedAssetBundle { get; private set; } public static GameObject? SleepingBagPrefab { get; private set; } public static GameObject? TentPrefab { get; private set; } public override void OnInitializeMelon() { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown ModSettings.Initialize(); ModLogger.SetDebugEnabled(ModSettings.EnableDebugLogging); GameTimeManager.Instance.Initialize(); ModLogger.Info("Build-anywhere systems initialized"); new TentOwnershipSaveable(); new TentStorageSaveable(); SyntheticGridSaveable syntheticGridSaveable = new SyntheticGridSaveable(); OutsideBuildablesSaveable outsideBuildablesSaveable = new OutsideBuildablesSaveable(); SyntheticGridManager.Initialize(); if (_saveStartHandler == null) { _saveStartHandler = OnGameSaveStarted; } ModLogger.Info("SidewalkEconomy initialized"); ModLogger.Debug("This will only show in debug mode"); ModLogger.Debug($"[MainMod] EnableOutsidePlacement: {ModSettings.EnableOutsidePlacement}"); ModLogger.Debug($"[MainMod] EnableDebugLogging: {ModSettings.EnableDebugLogging}"); HarmonyInstance = new Harmony("SidewalkEconomy"); ModLogger.Debug("[MainMod] Applying Harmony patches..."); ModLogger.Debug("[MainMod] Patching BuildUpdate_Grid.CheckIntersections"); HarmonyInstance.PatchAll(); ModLogger.Debug("Harmony patches applied"); try { MethodInfo method = typeof(BuildUpdate_Grid).GetMethod("CheckIntersections", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); ModLogger.Debug($"[MainMod] CheckIntersections method found: {method != null}"); if (!(method != null)) { return; } Patches patchInfo = Harmony.GetPatchInfo((MethodBase)method); ModLogger.Debug($"[MainMod] CheckIntersections patches: {(patchInfo?.Postfixes?.Count).GetValueOrDefault()} postfix(es)"); if (patchInfo?.Postfixes == null || patchInfo.Postfixes.Count <= 0) { return; } foreach (Patch postfix in patchInfo.Postfixes) { ModLogger.Debug("[MainMod] - Postfix: " + postfix.owner); } } catch (Exception value) { ModLogger.Warn($"[MainMod] Error verifying patches: {value}"); } } public override void OnDeinitializeMelon() { ExitSyntheticIdleEditMode(); if (_saveListenerRegistered && Singleton.InstanceExists) { try { if (_saveStartHandler != null) { Singleton.Instance.onSaveStart.RemoveListener(UnityAction.op_Implicit(_saveStartHandler)); } _saveListenerRegistered = false; ModLogger.Debug("Unregistered outside buildable save listener"); } catch (Exception ex) { ModLogger.Warn("Failed to unregister save listener: " + ex.Message); } } if (_dayPassEventSubscribed) { try { TimeManager.OnDayPass = (Action)Delegate.Remove(TimeManager.OnDayPass, new Action(OnDayPass)); _dayPassEventSubscribed = false; ModLogger.Debug("Unsubscribed from S1API TimeManager day pass event"); } catch (Exception ex2) { ModLogger.Debug("Failed to unsubscribe from day pass event: " + ex2.Message); } } Harmony harmonyInstance = HarmonyInstance; if (harmonyInstance != null) { harmonyInstance.UnpatchSelf(); } ModLogger.Debug("Harmony patches removed"); GameTimeManager.Instance.Shutdown(); } public override void OnUpdate() { HandleSyntheticIdleEditHotkey(); UpdateSyntheticIdleEditMode(); HandleSyntheticPropertyRenameHotkey(); } public override void OnGUI() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (_isSyntheticIdleEditMode) { DrawSyntheticIdleEditOverlay(); } if (_showSyntheticPropertyRenameWindow) { GUILayout.BeginArea(_syntheticPropertyRenameWindowRect, "Rename Synthetic Property", GUI.skin.window); DrawSyntheticPropertyRenameWindowContents(); GUILayout.EndArea(); } } private void HandleTeleportHotkeys() { //IL_000e: 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) if (Input.GetKeyDown((KeyCode)91)) { TeleportPlayer(Constants.WorldSpawns.TENT_POSITION, "Tent"); } if (Input.GetKeyDown((KeyCode)112)) { TeleportPlayer(Constants.WorldSpawns.SLEEPING_BAG_POSITION, "Sleeping Bag"); } } private void HandleSyntheticPropertyRenameHotkey() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (!ModSettings.EnableOutsidePlacement || _showSyntheticPropertyRenameWindow || _isSyntheticIdleEditMode || !IsAltHeld() || !Input.GetKeyDown((KeyCode)114)) { return; } Player local = Player.Local; if ((Object)(object)local == (Object)null) { ModLogger.Warn("Cannot rename synthetic property: player not found"); return; } Property nearestSyntheticProperty = SyntheticGridManager.GetNearestSyntheticProperty(((Component)local).transform.position, 30f); if ((Object)(object)nearestSyntheticProperty == (Object)null) { ModLogger.Warn("No synthetic property found nearby. Move closer and press Alt+R."); return; } _selectedSyntheticProperty = nearestSyntheticProperty; _syntheticPropertyNameInput = nearestSyntheticProperty.PropertyName ?? string.Empty; _syntheticPropertyRenameError = string.Empty; _showSyntheticPropertyRenameWindow = true; _focusSyntheticPropertyNameInput = true; } private void DrawSyntheticPropertyRenameWindowContents() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 Event current = Event.current; if ((int)current.type == 4) { if ((int)current.keyCode == 27) { CloseSyntheticPropertyRenameWindow(); current.Use(); return; } if ((int)current.keyCode == 13 || (int)current.keyCode == 271) { ApplySyntheticPropertyRename(); current.Use(); return; } } GUILayout.BeginVertical((Il2CppReferenceArray)null); GUILayout.Label("Set a custom name for this synthetic property.", (Il2CppReferenceArray)null); GUILayout.Label("This name is used internally for save data and troubleshooting.", (Il2CppReferenceArray)null); GUILayout.Space(6f); GUI.SetNextControlName("SyntheticPropertyNameInput"); _syntheticPropertyNameInput = GUILayout.TextField(_syntheticPropertyNameInput ?? string.Empty, 48, Array.Empty()); if (_focusSyntheticPropertyNameInput) { GUI.FocusControl("SyntheticPropertyNameInput"); _focusSyntheticPropertyNameInput = false; } if (!string.IsNullOrWhiteSpace(_syntheticPropertyRenameError)) { GUILayout.Label(_syntheticPropertyRenameError, (Il2CppReferenceArray)null); } GUILayout.FlexibleSpace(); GUILayout.BeginHorizontal((Il2CppReferenceArray)null); if (GUILayout.Button("Save", (Il2CppReferenceArray)null)) { ApplySyntheticPropertyRename(); } if (GUILayout.Button("Cancel", (Il2CppReferenceArray)null)) { CloseSyntheticPropertyRenameWindow(); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private void ApplySyntheticPropertyRename() { if ((Object)(object)_selectedSyntheticProperty == (Object)null) { _syntheticPropertyRenameError = "No synthetic property selected."; return; } string text = (_syntheticPropertyNameInput ?? string.Empty).Trim(); if (string.IsNullOrWhiteSpace(text)) { _syntheticPropertyRenameError = "Property name cannot be empty."; return; } if (!SyntheticGridManager.TryRenameSyntheticProperty(_selectedSyntheticProperty, text, out var failureReason)) { _syntheticPropertyRenameError = (string.IsNullOrWhiteSpace(failureReason) ? "Failed to rename synthetic property." : failureReason); return; } ModLogger.Info("Renamed synthetic property to '" + text + "'"); CloseSyntheticPropertyRenameWindow(); } private void CloseSyntheticPropertyRenameWindow() { _showSyntheticPropertyRenameWindow = false; _focusSyntheticPropertyNameInput = false; _syntheticPropertyRenameError = string.Empty; _selectedSyntheticProperty = null; } private void HandleSyntheticIdleEditHotkey() { if (!SyntheticGridManager.AreSyntheticEmployeesEnabled()) { if (_isSyntheticIdleEditMode) { ExitSyntheticIdleEditMode(); } if (IsAltHeld() && Input.GetKeyDown((KeyCode)105)) { ModLogger.Warn("Synthetic property employees are disabled in this version."); } } else if (ModSettings.EnableOutsidePlacement && !_showSyntheticPropertyRenameWindow && IsAltHeld() && Input.GetKeyDown((KeyCode)105)) { if (_isSyntheticIdleEditMode) { ExitSyntheticIdleEditMode(); } else { EnterSyntheticIdleEditMode(); } } } private void EnterSyntheticIdleEditMode() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (!SyntheticGridManager.AreSyntheticEmployeesEnabled()) { return; } Player local = Player.Local; if ((Object)(object)local == (Object)null) { ModLogger.Warn("Cannot enter synthetic idle edit mode: player not found"); return; } Property nearestSyntheticProperty = SyntheticGridManager.GetNearestSyntheticProperty(((Component)local).transform.position, 40f); if ((Object)(object)nearestSyntheticProperty == (Object)null) { ModLogger.Warn("No synthetic property found nearby. Move closer and press Alt+I."); return; } _syntheticIdleEditProperty = nearestSyntheticProperty; if (!SyntheticGridManager.TryGetManualIdlePoint(nearestSyntheticProperty, out _syntheticIdleEditPosition, out _syntheticIdleEditYaw)) { _syntheticIdleEditPosition = (((Object)(object)nearestSyntheticProperty.NPCSpawnPoint != (Object)null) ? nearestSyntheticProperty.NPCSpawnPoint.position : ((Component)local).transform.position); _syntheticIdleEditYaw = ((Component)local).transform.eulerAngles.y; } _isSyntheticIdleEditMode = true; _syntheticIdleEditStatus = "Idle edit mode active."; EnsureSyntheticIdleEditGizmo(); UpdateSyntheticIdleEditGizmo(); } private void ExitSyntheticIdleEditMode() { _isSyntheticIdleEditMode = false; _syntheticIdleEditProperty = null; _syntheticIdleEditStatus = string.Empty; if ((Object)(object)_syntheticIdleEditGizmo != (Object)null) { Object.Destroy((Object)(object)_syntheticIdleEditGizmo); _syntheticIdleEditGizmo = null; _syntheticIdleEditGizmoBaseRenderer = null; _syntheticIdleEditGizmoArrowRenderer = null; } } private void UpdateSyntheticIdleEditMode() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) if (!SyntheticGridManager.AreSyntheticEmployeesEnabled()) { if (_isSyntheticIdleEditMode) { ExitSyntheticIdleEditMode(); } } else { if (!_isSyntheticIdleEditMode) { return; } if ((Object)(object)_syntheticIdleEditProperty == (Object)null) { ExitSyntheticIdleEditMode(); return; } if (Input.GetKeyDown((KeyCode)27)) { ExitSyntheticIdleEditMode(); return; } bool flag = false; if (Input.GetKeyDown((KeyCode)113)) { _syntheticIdleEditYaw -= 5f; flag = true; } if (Input.GetKeyDown((KeyCode)101)) { _syntheticIdleEditYaw += 5f; flag = true; } if (Input.GetMouseButtonDown(0) && TryGetIdleEditAimPoint(out var point)) { _syntheticIdleEditPosition = point; flag = true; } if (Input.GetKeyDown((KeyCode)8) || Input.GetKeyDown((KeyCode)127)) { SyntheticGridManager.ClearManualIdlePoint(_syntheticIdleEditProperty); _syntheticIdleEditStatus = "Cleared manual idle marker. Hiring is now disabled until a marker is placed."; UpdateSyntheticIdleEditGizmo(); return; } if (flag) { if (SyntheticGridManager.TrySetManualIdlePoint(_syntheticIdleEditProperty, _syntheticIdleEditPosition, _syntheticIdleEditYaw, out var failureReason)) { _syntheticIdleEditStatus = "Idle marker updated."; } else { _syntheticIdleEditStatus = (string.IsNullOrWhiteSpace(failureReason) ? "Idle marker is invalid. Move it to clear navmesh." : failureReason); } } UpdateSyntheticIdleEditGizmo(); } } private bool TryGetIdleEditAimPoint(out Vector3 point) { //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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return false; } Ray val = main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f)); RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val, ref val2, 500f, -1, (QueryTriggerInteraction)1)) { point = ((RaycastHit)(ref val2)).point; return true; } point = ((Component)main).transform.position + ((Component)main).transform.forward * 4f; return true; } private void EnsureSyntheticIdleEditGizmo() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_syntheticIdleEditGizmo != (Object)null)) { _syntheticIdleEditGizmo = new GameObject("SyntheticIdleEditGizmo"); GameObject val = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)val).name = "Base"; val.transform.SetParent(_syntheticIdleEditGizmo.transform, false); val.transform.localScale = new Vector3(0.35f, 0.05f, 0.35f); val.transform.localPosition = Vector3.zero; _syntheticIdleEditGizmoBaseRenderer = val.GetComponent(); Collider component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; } GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val2).name = "Forward"; val2.transform.SetParent(_syntheticIdleEditGizmo.transform, false); val2.transform.localScale = new Vector3(0.08f, 0.08f, 0.5f); val2.transform.localPosition = new Vector3(0f, 0.1f, 0.25f); _syntheticIdleEditGizmoArrowRenderer = val2.GetComponent(); Collider component2 = val2.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.enabled = false; } } } private void UpdateSyntheticIdleEditGizmo() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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) if (!_isSyntheticIdleEditMode || (Object)(object)_syntheticIdleEditProperty == (Object)null) { return; } EnsureSyntheticIdleEditGizmo(); if ((Object)(object)_syntheticIdleEditGizmo == (Object)null) { return; } _syntheticIdleEditYaw = Mathf.Repeat(_syntheticIdleEditYaw, 360f); if (SyntheticGridManager.TryValidateEmployeeIdlePoint(_syntheticIdleEditProperty, _syntheticIdleEditPosition, out var resolvedPosition, out var failureReason)) { _syntheticIdleEditValid = true; _syntheticIdleEditPosition = resolvedPosition; if (string.IsNullOrWhiteSpace(_syntheticIdleEditStatus) || _syntheticIdleEditStatus.Contains("invalid", StringComparison.OrdinalIgnoreCase)) { _syntheticIdleEditStatus = "Idle marker is valid."; } } else { _syntheticIdleEditValid = false; if (!string.IsNullOrWhiteSpace(failureReason)) { _syntheticIdleEditStatus = failureReason; } } _syntheticIdleEditGizmo.transform.position = _syntheticIdleEditPosition + Vector3.up * 0.03f; _syntheticIdleEditGizmo.transform.rotation = Quaternion.Euler(0f, _syntheticIdleEditYaw, 0f); Color color = (_syntheticIdleEditValid ? new Color(0.2f, 0.9f, 0.3f, 0.95f) : new Color(0.95f, 0.25f, 0.25f, 0.95f)); if ((Object)(object)_syntheticIdleEditGizmoBaseRenderer != (Object)null) { _syntheticIdleEditGizmoBaseRenderer.material.color = color; } if ((Object)(object)_syntheticIdleEditGizmoArrowRenderer != (Object)null) { _syntheticIdleEditGizmoArrowRenderer.material.color = color; } } private void DrawSyntheticIdleEditOverlay() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (SyntheticGridManager.AreSyntheticEmployeesEnabled() && _isSyntheticIdleEditMode && !((Object)(object)_syntheticIdleEditProperty == (Object)null)) { GUILayout.BeginArea(new Rect(24f, 214f, 520f, 150f), "Synthetic Idle Edit", GUI.skin.window); GUILayout.Label("Property: " + _syntheticIdleEditProperty.PropertyName, (Il2CppReferenceArray)null); GUILayout.Label($"Point: {_syntheticIdleEditPosition.x:F2}, {_syntheticIdleEditPosition.y:F2}, {_syntheticIdleEditPosition.z:F2} | Yaw: {_syntheticIdleEditYaw:F1}", (Il2CppReferenceArray)null); GUILayout.Label(_syntheticIdleEditValid ? "Status: Valid" : "Status: Invalid", (Il2CppReferenceArray)null); if (!string.IsNullOrWhiteSpace(_syntheticIdleEditStatus)) { GUILayout.Label(_syntheticIdleEditStatus, (Il2CppReferenceArray)null); } GUILayout.Label("Controls: LMB place marker | Q/E rotate | Delete clear | Alt+I or Esc exit", (Il2CppReferenceArray)null); GUILayout.EndArea(); } } private static bool IsAltHeld() { return Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); } private void TeleportPlayer(Vector3 position, string label) { //IL_0031: 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) Player local = Player.Local; if ((Object)(object)local == (Object)null) { ModLogger.Warn("Teleport skipped - player not found (" + label + ")"); return; } ((Component)local).transform.position = position; ModLogger.Info($"Teleported player to {label} at {position}"); } private void OnDayPass() { //IL_006e: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Invalid comparison between Unknown and I4 //IL_009b: Unknown result type (might be due to invalid IL or missing references) ModLogger.Info("OnDayPass: Called"); try { if (_tentSpawned && !IsTentPresent()) { _tentSpawned = false; ModLogger.Warn("Tent spawn flag was set but tent is missing in scene. Retrying spawn."); } if (_tentSpawned) { ModLogger.Debug("OnDayPass: Tent already spawned, skipping"); return; } if (!EnsureTentPrefabReady(logReload: true)) { ModLogger.Debug("OnDayPass: Tent prefab not loaded yet"); return; } Rank rank = LevelManager.Rank; if ((int)rank >= 2) { ModLogger.Info($"Player reached {rank} - spawning tent!"); if (WorldSpawnManager.SpawnTent(TentPrefab)) { EnsureTentOwned(); _tentSpawned = true; } else { ModLogger.Warn("Tent spawn attempt did not succeed; will retry on next trigger."); } } } catch (Exception ex) { ModLogger.Error("OnDayPass error: " + ex.Message); } } private static bool IsTentPresent() { return (Object)(object)GameObject.Find("SidewalkEconomy_Tent_Spawn") != (Object)null; } private void EnsureTentOwned() { if (!TentOwnershipManager.IsTentOwned()) { TentOwnershipManager.SetTentOwned(owned: true); if (!TentOwnershipManager.IsTentOwned()) { MelonCoroutines.Start(EnsureTentOwnedWhenReady()); } else { ModLogger.Info("Tent ownership set to player"); } } } [IteratorStateMachine(typeof(d__59))] private IEnumerator EnsureTentOwnedWhenReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__59(0) { <>4__this = this }; } [IteratorStateMachine(typeof(d__60))] private IEnumerator SubscribeToDayPassEvent() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__60(0) { <>4__this = this }; } [IteratorStateMachine(typeof(d__61))] private IEnumerator CheckTentSpawnOnSceneLoad() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__61(0) { <>4__this = this }; } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { ExitSyntheticIdleEditMode(); ModLogger.Debug("Scene loaded: " + sceneName); if (sceneName == "Main") { _tentSpawned = IsTentPresent(); ModLogger.Debug($"Tent present on scene load: {_tentSpawned}"); ModLogger.Debug("Main scene loaded"); MelonCoroutines.Start(LoadAssetBundleAssets()); MelonCoroutines.Start(SubscribeToDayPassEvent()); MelonCoroutines.Start(Utils.WaitForNetwork(CheckTentSpawnOnSceneLoad())); MelonCoroutines.Start(RegisterSaveListener()); } } [IteratorStateMachine(typeof(d__63))] private static IEnumerator RegisterSaveListener() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__63(0); } private static void OnGameSaveStarted() { if (OutsideBuildablesSaveable.Instance == null) { ModLogger.Warn("Outside buildables saveable not ready; skipping capture"); } else { OutsideBuildablesSaveable.Instance.CaptureFromWorld(); } SyntheticGridManager.CaptureForSave(); TentStorageEntity.FlushAllForSave(); } [IteratorStateMachine(typeof(d__65))] private IEnumerator LoadAssetBundleAssets() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__65(0) { <>4__this = this }; } private static bool EnsureTentPrefabReady(bool logReload) { if ((Object)(object)TentPrefab != (Object)null) { return true; } if (CachedAssetBundle == null || !_tentPrefabLoadedOnce) { return false; } try { TentPrefab = CachedAssetBundle.LoadAsset("assets/sidewalk economy/tent.prefab"); if ((Object)(object)TentPrefab != (Object)null) { if (logReload) { ModLogger.Debug("Rehydrated tent prefab reference from cached assetbundle"); } ShaderUtils.FixShadersOnGameObject(TentPrefab); return true; } } catch (Exception ex) { if (logReload) { ModLogger.Warn("Failed to rehydrate tent prefab from cached assetbundle: " + ex.Message); } } return false; } } public static class ModSettings { private static MelonPreferences_Category _category; private static MelonPreferences_Entry _enableDebugLogging; private static MelonPreferences_Entry _enableOutsidePlacement; public static bool EnableDebugLogging { get { return _enableDebugLogging?.Value ?? false; } set { if (_enableDebugLogging != null) { _enableDebugLogging.Value = value; MelonPreferences.Save(); } } } public static bool EnableOutsidePlacement { get { return _enableOutsidePlacement?.Value ?? true; } set { if (_enableOutsidePlacement != null) { _enableOutsidePlacement.Value = value; MelonPreferences.Save(); } } } public static void Initialize() { _category = MelonPreferences.CreateCategory("SidewalkEconomy", "SidewalkEconomy"); _enableDebugLogging = _category.CreateEntry("EnableDebugLogging", false, "Enable Debug Logging", "When enabled, detailed debug messages will be logged to the console.", false, false, (ValueValidator)null, (string)null); _enableOutsidePlacement = _category.CreateEntry("EnableOutsidePlacement", true, "Enable Outside Placement", "Enables or disables the ability to place buildable items anywhere on the map. When enabled, players can place items outside of approved building zones.", false, false, (ValueValidator)null, (string)null); MelonPreferences.Save(); } } } namespace SidewalkEconomy.Saveables { public sealed class OutsideBuildablesSaveable : Saveable { private sealed class OutsideBuildableRecordWithOrder { public OutsideBuildableRecord Record { get; set; } public int LoadOrder { get; set; } } private sealed class PendingRestoreRecord { public OutsideBuildableRecord Record { get; set; } public int SourceIndex { get; set; } public int Attempts { get; set; } public string LastDeferredReason { get; set; } } private enum RestoreOutcome { Restored, Deferred, PermanentFailure } private enum BuildableCaptureState { Valid, Transient, Invalid } [CompilerGenerated] private sealed class d__15 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public OutsideBuildablesSaveable <>4__this; private LoadManager 5__1; private List 5__2; private int 5__3; private int 5__4; private int 5__5; private bool 5__6; private int 5__7; private List 5__8; private List.Enumerator <>s__9; private PendingRestoreRecord 5__10; private RestoreOutcome 5__11; private string 5__12; private RestoreOutcome <>s__13; private List.Enumerator <>s__14; private PendingRestoreRecord 5__15; private string 5__16; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 4) { try { } finally { <>m__Finally1(); } } 5__1 = null; 5__2 = null; 5__8 = null; <>s__9 = default(List.Enumerator); 5__10 = null; 5__12 = null; <>s__14 = default(List.Enumerator); 5__15 = null; 5__16 = null; <>1__state = -2; } private bool MoveNext() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Expected O, but got Unknown try { Scene activeScene; switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!InstanceFinder.IsServer) { ModLogger.Debug("Outside buildable restore skipped - not server"); return false; } goto IL_008d; case 1: <>1__state = -1; goto IL_008d; case 2: <>1__state = -1; goto IL_00c9; case 3: <>1__state = -1; goto IL_00f7; case 4: <>1__state = -3; 5__12 = null; 5__10 = null; goto IL_03e7; case 5: { <>1__state = -1; goto IL_0475; } IL_048f: if (5__5 > 6 || 5__2.Count <= 0) { break; } 5__6 = false; 5__7 = 5__2.Count; 5__8 = new List(); ModLogger.Info((5__5 == 1) ? $"Restoring {5__7} outside buildable(s)..." : $"Retrying {5__7} deferred outside buildable restore(s) (pass {5__5}/{6})"); <>s__9 = 5__2.GetEnumerator(); <>1__state = -3; goto IL_03e7; IL_008d: activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name != "Main") { <>2__current = null; <>1__state = 1; return true; } goto IL_00c9; IL_00c9: if (!NetworkSingleton.InstanceExists) { <>2__current = null; <>1__state = 2; return true; } goto IL_00f7; IL_00f7: if ((Object)(object)Singleton.Instance == (Object)null) { <>2__current = null; <>1__state = 3; return true; } 5__1 = Singleton.Instance; 5__2 = <>4__this._records.Select((OutsideBuildableRecord record, int index) => new PendingRestoreRecord { Record = record, SourceIndex = index + 1 }).ToList(); 5__3 = 0; 5__4 = 0; 5__5 = 1; goto IL_048f; IL_0475: 5__8 = null; 5__5++; goto IL_048f; IL_03e7: if (<>s__9.MoveNext()) { 5__10 = <>s__9.Current; 5__10.Attempts++; 5__11 = TryRestoreRecord(5__1, 5__10, out 5__12); RestoreOutcome restoreOutcome = 5__11; <>s__13 = restoreOutcome; switch (<>s__13) { case RestoreOutcome.Restored: 5__6 = true; 5__3++; break; case RestoreOutcome.Deferred: if (!string.Equals(5__10.LastDeferredReason, 5__12, StringComparison.Ordinal)) { ModLogger.Warn("Deferring restore for " + DescribeRecord(5__10.Record, 5__10.SourceIndex) + ": " + 5__12); 5__10.LastDeferredReason = 5__12; } 5__8.Add(5__10); break; case RestoreOutcome.PermanentFailure: 5__4++; ModLogger.Warn("Failed to restore " + DescribeRecord(5__10.Record, 5__10.SourceIndex) + ": " + 5__12); break; } <>2__current = null; <>1__state = 4; return true; } <>m__Finally1(); <>s__9 = default(List.Enumerator); 5__2 = 5__8; if (5__2.Count == 0) { break; } if (5__5 < 6) { <>2__current = (object)new WaitForSeconds(5__6 ? 0.25f : 1f); <>1__state = 5; return true; } goto IL_0475; } <>s__14 = 5__2.GetEnumerator(); try { while (<>s__14.MoveNext()) { 5__15 = <>s__14.Current; 5__4++; 5__16 = (string.IsNullOrWhiteSpace(5__15.LastDeferredReason) ? "dependencies never reached a ready state" : 5__15.LastDeferredReason); ModLogger.Warn($"Giving up on deferred restore for {DescribeRecord(5__15.Record, 5__15.SourceIndex)} after {5__15.Attempts} attempt(s): {5__16}"); 5__16 = null; 5__15 = null; } } finally { ((IDisposable)<>s__14).Dispose(); } <>s__14 = default(List.Enumerator); ModLogger.Info($"Outside buildables restore complete ({5__3} restored, {5__4} unresolved)"); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__9).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const int RestoreRetryAttempts = 3; private const int MaxDeferredRestorePasses = 6; private const float DeferredRestoreRetryDelaySeconds = 1f; [SaveableField("outside_buildables")] private List _records = new List(); public static OutsideBuildablesSaveable Instance { get; private set; } public override SaveableLoadOrder LoadOrder => (SaveableLoadOrder)1; public OutsideBuildablesSaveable() { Instance = this; } public IReadOnlyList GetRecords() { return _records; } public void SetRecords(List records) { _records = records ?? new List(); } public void CaptureFromWorld() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!InstanceFinder.IsServer) { ModLogger.Debug("Outside buildable capture skipped - not server"); return; } Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name != "Main") { ModLogger.Debug("Outside buildable capture skipped - not in Main scene"); return; } List list = CloneRecords(_records); int num = 0; int num2 = 0; foreach (Property item in Property.Properties.AsEnumerable()) { if ((Object)(object)item == (Object)null || (Object)(object)InjectedComponentHelper.GetInjectedComponent((Component)(object)item) == (Object)null) { continue; } if (!TryGetPropertyGridGuids(item, out var gridGuids)) { ModLogger.Warn("Preserving outside buildable snapshot for property '" + item.PropertyCode + "' because no grid GUIDs were available"); num2++; continue; } List list2 = new List(); List list3 = new List(); string text = string.Empty; foreach (BuildableItem item2 in item.BuildableItems.AsEnumerable().ToList()) { string reason; bool pruneFromProperty; switch (EvaluateBuildableCaptureState(item, item2, out reason, out pruneFromProperty)) { case BuildableCaptureState.Transient: text = reason; break; case BuildableCaptureState.Invalid: ModLogger.Warn("Skipping outside buildable capture for " + DescribeBuildable(item2) + ": " + reason); if (pruneFromProperty && (Object)(object)item2 != (Object)null) { list2.Add(item2); } continue; default: { DynamicSaveData val = null; try { val = item2.GetSaveData(); } catch (Exception ex) { text = "save data capture failed for " + DescribeBuildable(item2) + ": " + ex.Message; break; } if (val == null) { text = "save data was null for " + DescribeBuildable(item2); break; } OutsideBuildableRecord record2 = CreateRecord(val); list3.Add(new OutsideBuildableRecordWithOrder { Record = record2, LoadOrder = GetLoadOrder(val.BaseData) }); continue; } } break; } if (!string.IsNullOrWhiteSpace(text)) { ModLogger.Warn("Preserving outside buildable snapshot for property '" + item.PropertyCode + "' because " + text); num2++; continue; } RemoveRecordsForGridGuids(list, gridGuids); list.AddRange(from item in list3 orderby item.LoadOrder select item.Record); num++; PruneInvalidBuildables(item, list2); } _records = list.OrderBy((OutsideBuildableRecord record) => GetLoadOrder(record?.BaseData)).ToList(); ModLogger.Info($"Captured {_records.Count} outside buildable(s) for save across {num} stable property snapshot(s); preserved {num2} property snapshot(s)"); } protected override void OnLoaded() { ModLogger.Info($"Outside buildables loaded ({_records?.Count ?? 0} record(s))"); if (_records != null && _records.Count != 0) { MelonCoroutines.Start(Utils.WaitForPlayer(RestoreRoutine())); } } [IteratorStateMachine(typeof(d__15))] private IEnumerator RestoreRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(0) { <>4__this = this }; } private static DynamicSaveData BuildDynamicSaveData(OutsideBuildableRecord record) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0006: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown DynamicSaveData val = new DynamicSaveData(new SaveData()) { DataType = (record.DataType ?? string.Empty), BaseData = (record.BaseData ?? string.Empty) }; val.AdditionalDatas.Clear(); if (record.AdditionalDatas != null) { foreach (AdditionalDataRecord additionalData in record.AdditionalDatas) { if (additionalData != null) { val.AdditionalDatas.Add(new AdditionalData { Name = (additionalData.Name ?? string.Empty), Contents = (additionalData.Contents ?? string.Empty) }); } } } return val; } private static OutsideBuildableRecord CreateRecord(DynamicSaveData saveData) { return new OutsideBuildableRecord { DataType = ((SaveData)saveData).DataType, BaseData = saveData.BaseData, AdditionalDatas = ConvertAdditionalDatas(saveData.AdditionalDatas.AsEnumerable()) }; } private static List ConvertAdditionalDatas(IEnumerable additionalDatas) { List list = new List(); if (additionalDatas == null) { return list; } foreach (AdditionalData additionalData in additionalDatas) { if (additionalData != null) { list.Add(new AdditionalDataRecord { Name = (additionalData.Name ?? string.Empty), Contents = (additionalData.Contents ?? string.Empty) }); } } return list; } private static bool TryGetGridGuid(string baseDataJson, out Guid guid) { guid = default(Guid); if (string.IsNullOrEmpty(baseDataJson)) { return false; } try { GridItemData val = JsonUtility.FromJson(baseDataJson); if (val != null && !string.IsNullOrEmpty(val.GridGUID) && Guid.TryParse(val.GridGUID, out guid)) { return true; } } catch (Exception value) { ModLogger.Warn($"Failed to read grid GUID from base data: {value}"); } return false; } private static bool TryGetBuildableGuid(string baseDataJson, out Guid guid) { guid = default(Guid); if (string.IsNullOrEmpty(baseDataJson)) { return false; } try { BuildableItemData val = JsonUtility.FromJson(baseDataJson); if (val != null && !string.IsNullOrEmpty(val.GUID) && Guid.TryParse(val.GUID, out guid)) { return true; } } catch (Exception value) { ModLogger.Warn($"Failed to read buildable GUID from base data: {value}"); } return false; } private static T GetObjectByGuid(Guid guid) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) return GUIDManager.GetObject(new Guid(guid.ToString())); } private static bool TryParseProceduralGridItemData(string baseDataJson, out ProceduralGridItemData proceduralData) { proceduralData = null; if (string.IsNullOrEmpty(baseDataJson)) { return false; } try { proceduralData = JsonUtility.FromJson(baseDataJson); if (proceduralData == null || proceduralData.FootprintMatches == null || ((Il2CppArrayBase)(object)proceduralData.FootprintMatches).Length == 0) { proceduralData = null; return false; } return true; } catch { proceduralData = null; return false; } } private static bool AreProceduralDependenciesReady(ProceduralGridItemData proceduralData, out string reason) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0115: 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_0132: Expected O, but got Unknown reason = string.Empty; if (proceduralData == null || proceduralData.FootprintMatches == null || ((Il2CppArrayBase)(object)proceduralData.FootprintMatches).Length == 0) { reason = "procedural footprint match data is missing"; return false; } for (int i = 0; i < ((Il2CppArrayBase)(object)proceduralData.FootprintMatches).Length; i++) { FootprintMatchData val = ((Il2CppArrayBase)(object)proceduralData.FootprintMatches)[i]; if (!Guid.TryParse(val.TileOwnerGUID, out var result)) { reason = $"invalid tile owner GUID at footprint index {i}"; return false; } BuildableItem objectByGuid = GetObjectByGuid(result); if ((Object)(object)objectByGuid == (Object)null || objectByGuid.IsDestroyed || (Object)(object)((NetworkBehaviour)objectByGuid).NetworkObject == (Object)null) { reason = "tile owner " + val.TileOwnerGUID + " is missing"; return false; } CoordinateProceduralTilePair val2 = new CoordinateProceduralTilePair { coord = new Coordinate(Mathf.RoundToInt(val.FootprintCoordinate.x), Mathf.RoundToInt(val.FootprintCoordinate.y)), tileParent = ((NetworkBehaviour)objectByGuid).NetworkObject, tileIndex = val.TileIndex }; ProceduralTile tile; try { tile = val2.tile; } catch { reason = $"tile lookup failed for owner {val.TileOwnerGUID} at index {val.TileIndex}"; return false; } if ((Object)(object)tile == (Object)null) { reason = $"tile lookup returned null for owner {val.TileOwnerGUID} at index {val.TileIndex}"; return false; } if ((Object)(object)tile.MatchedFootprintTile == (Object)null) { reason = $"tile {val.TileIndex} on owner {val.TileOwnerGUID} is not matched to a footprint tile"; return false; } if ((Object)(object)tile.MatchedFootprintTile.MatchedStandardTile == (Object)null) { reason = $"tile {val.TileIndex} on owner {val.TileOwnerGUID} has no matched standard tile"; return false; } if ((Object)(object)tile.MatchedFootprintTile.MatchedStandardTile.LightExposureNode == (Object)null) { reason = $"tile {val.TileIndex} on owner {val.TileOwnerGUID} has no light exposure node"; return false; } } return true; } private static int GetLoadOrder(string baseDataJson) { if (string.IsNullOrEmpty(baseDataJson)) { return 0; } try { BuildableItemData val = JsonUtility.FromJson(baseDataJson); return (val != null) ? val.LoadOrder : 0; } catch (Exception value) { ModLogger.Warn($"Failed to read load order from base data: {value}"); } return 0; } private static BuildableCaptureState EvaluateBuildableCaptureState(Property property, BuildableItem buildable, out string reason, out bool pruneFromProperty) { reason = string.Empty; pruneFromProperty = false; if ((Object)(object)buildable == (Object)null) { reason = "buildable was null"; return BuildableCaptureState.Invalid; } if ((Object)(object)((Component)buildable).gameObject == (Object)null) { reason = "buildable game object missing"; pruneFromProperty = true; return BuildableCaptureState.Invalid; } if (buildable.IsDestroyed) { reason = "buildable is destroyed"; pruneFromProperty = true; return BuildableCaptureState.Invalid; } if (buildable.isGhost) { reason = "buildable is still ghost-only"; return BuildableCaptureState.Transient; } if (!buildable.Initialized) { reason = "buildable was never initialized"; return BuildableCaptureState.Transient; } if ((Object)(object)buildable.ParentProperty == (Object)null) { reason = "buildable parent property is missing"; pruneFromProperty = true; return BuildableCaptureState.Invalid; } if ((Object)(object)buildable.ParentProperty != (Object)(object)property) { reason = "buildable belongs to a different property"; pruneFromProperty = true; return BuildableCaptureState.Invalid; } GridItem val = (GridItem)(object)((buildable is GridItem) ? buildable : null); if (val != null && (Object)(object)val.OwnerGrid == (Object)null) { reason = "grid item owner grid is missing"; return BuildableCaptureState.Transient; } Pot val2 = (Pot)(object)((buildable is Pot) ? buildable : null); if (val2 != null && val2.Configuration == null) { reason = "pot configuration is missing"; return BuildableCaptureState.Transient; } return BuildableCaptureState.Valid; } private static void PruneInvalidBuildables(Property property, List invalidBuildables) { if ((Object)(object)property == (Object)null || property.BuildableItems == null) { return; } if (invalidBuildables == null) { invalidBuildables = new List(); } int num = 0; for (int num2 = property.BuildableItems.Count - 1; num2 >= 0; num2--) { if ((Object)(object)property.BuildableItems[num2] == (Object)null) { property.BuildableItems.RemoveAt(num2); num++; } } foreach (BuildableItem item in invalidBuildables.Distinct().ToList()) { if (!((Object)(object)item == (Object)null) && property.BuildableItems.Remove(item)) { num++; } } if (num > 0) { ModLogger.Warn($"Pruned {num} invalid outside buildable(s) from property '{property.PropertyCode}'"); } } private static string DescribeBuildable(BuildableItem buildable) { //IL_0047: 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) if ((Object)(object)buildable == (Object)null) { return ""; } string text = (((Object)(object)((Component)buildable).gameObject != (Object)null) ? ((Object)((Component)buildable).gameObject).name : ((object)buildable).GetType().Name); string text2 = "no-guid"; try { Guid gUID = buildable.GUID; string text3 = ((object)(Guid)(ref gUID)).ToString(); if (!string.IsNullOrWhiteSpace(text3) && !text3.Equals("00000000-0000-0000-0000-000000000000", StringComparison.Ordinal)) { text2 = text3; } } catch { } return text + " (" + text2 + ")"; } private static RestoreOutcome TryRestoreRecord(LoadManager loadManager, PendingRestoreRecord pendingRecord, out string reason) { reason = string.Empty; if (pendingRecord?.Record == null) { reason = "record was null"; return RestoreOutcome.PermanentFailure; } OutsideBuildableRecord record = pendingRecord.Record; if (string.IsNullOrEmpty(record.BaseData)) { reason = "record had empty base data"; return RestoreOutcome.PermanentFailure; } DynamicSaveData val = BuildDynamicSaveData(record); if (string.IsNullOrEmpty(((SaveData)val).DataType)) { reason = "record was missing data type"; return RestoreOutcome.PermanentFailure; } if (!TryGetBuildableGuid(val.BaseData, out var guid)) { reason = "record had invalid buildable GUID"; return RestoreOutcome.PermanentFailure; } if (TryGetGridGuid(val.BaseData, out var guid2) && (Object)(object)GetObjectByGuid(guid2) == (Object)null) { reason = $"grid {guid2} is not ready"; return RestoreOutcome.Deferred; } BuildableItemLoader objectLoader = loadManager.GetObjectLoader(((SaveData)val).DataType); if (objectLoader == null) { reason = "object loader for " + ((SaveData)val).DataType + " is not ready"; return RestoreOutcome.Deferred; } if (TryParseProceduralGridItemData(val.BaseData, out var proceduralData) && !AreProceduralDependenciesReady(proceduralData, out var reason2)) { reason = "procedural dependencies are not ready: " + reason2; return RestoreOutcome.Deferred; } try { objectLoader.Load(val); ModLogger.Info($"Restored outside buildable {((SaveData)val).DataType} ({guid})"); return RestoreOutcome.Restored; } catch (Exception ex) { reason = ((SaveData)val).DataType + " restore threw: " + ex.Message; return (pendingRecord.Attempts < 3) ? RestoreOutcome.Deferred : RestoreOutcome.PermanentFailure; } } private static List CloneRecords(IEnumerable records) { List list = new List(); if (records == null) { return list; } foreach (OutsideBuildableRecord record in records) { if (record != null) { list.Add(new OutsideBuildableRecord { DataType = record.DataType, BaseData = record.BaseData, AdditionalDatas = ((record.AdditionalDatas != null) ? record.AdditionalDatas.Select((AdditionalDataRecord additional) => new AdditionalDataRecord { Name = (additional?.Name ?? string.Empty), Contents = (additional?.Contents ?? string.Empty) }).ToList() : new List()) }); } } return list; } private static bool TryGetPropertyGridGuids(Property property, out HashSet gridGuids) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) gridGuids = new HashSet(); if (((property != null) ? property.Grids : null) == null) { return false; } foreach (Grid item in property.Grids.AsEnumerable()) { if ((Object)(object)item == (Object)null) { continue; } try { Guid gUID = item.GUID; string input = ((object)(Guid)(ref gUID)).ToString(); if (Guid.TryParse(input, out var result) && result != Guid.Empty) { gridGuids.Add(result); } } catch { } } return gridGuids.Count > 0; } private static void RemoveRecordsForGridGuids(List records, HashSet gridGuids) { if (records == null || records.Count == 0 || gridGuids == null || gridGuids.Count == 0) { return; } for (int num = records.Count - 1; num >= 0; num--) { OutsideBuildableRecord outsideBuildableRecord = records[num]; Guid guid; if (outsideBuildableRecord == null) { records.RemoveAt(num); } else if (TryGetGridGuid(outsideBuildableRecord.BaseData, out guid) && gridGuids.Contains(guid)) { records.RemoveAt(num); } } } private static string DescribeRecord(OutsideBuildableRecord record, int sourceIndex) { if (record == null) { return $"outside buildable record #{sourceIndex}"; } string text = ((!string.IsNullOrWhiteSpace(record.DataType)) ? record.DataType : $"record #{sourceIndex}"); if (TryGetBuildableGuid(record.BaseData, out var guid)) { return $"{text} ({guid})"; } return text; } } public sealed class OutsideBuildableRecord { public string DataType { get; set; } public string BaseData { get; set; } public List AdditionalDatas { get; set; } = new List(); } public sealed class AdditionalDataRecord { public string Name { get; set; } public string Contents { get; set; } } public sealed class SyntheticGridSaveable : Saveable { [SaveableField("synthetic_grids")] private List _records = new List(); public static SyntheticGridSaveable Instance { get; private set; } public SyntheticGridSaveable() { Instance = this; } public IReadOnlyList GetRecords() { return _records; } public void SetRecords(List records) { _records = records ?? new List(); } protected override void OnLoaded() { if (SyntheticGridManager.TryMigrateLegacySyntheticGridRecords(_records, out var migratedRecords, out var mergedPropertiesCount, out var mergedRecordCount)) { _records = migratedRecords; ModLogger.Warn($"Migrated legacy synthetic properties: merged {mergedRecordCount} record(s) across {mergedPropertiesCount} nearby cluster(s). Changes will persist on the next save."); } SyntheticGridManager.RestoreFromSave(_records); } } public sealed class SyntheticGridRecord { public string PropertyCode { get; set; } public string PropertyName { get; set; } public string GridGuid { get; set; } public Vector3 Origin { get; set; } public int MinX { get; set; } public int MaxX { get; set; } public int MinY { get; set; } public int MaxY { get; set; } public bool HasManualIdlePoint { get; set; } public Vector3 ManualIdlePointPosition { get; set; } public float ManualIdlePointYaw { get; set; } } public sealed class TentOwnershipSaveable : Saveable { private bool _isReady = false; [SaveableField("tent_owned")] private bool _tentOwned = false; [SaveableField("quest_completed")] private bool _questCompleted = false; [SaveableField("npc_relocated")] private bool _npcRelocated = false; public static TentOwnershipSaveable Instance { get; private set; } public override SaveableLoadOrder LoadOrder => (SaveableLoadOrder)1; public bool IsTentOwned => _tentOwned; public bool IsQuestCompleted => _questCompleted; public bool IsNPCRelocated => _npcRelocated; public bool IsReady => _isReady; public TentOwnershipSaveable() { Instance = this; } protected override void OnCreated() { _isReady = true; } protected override void OnLoaded() { _isReady = true; } public void SetTentOwned(bool owned) { _tentOwned = owned; } public void SetQuestCompleted(bool completed) { _questCompleted = completed; if (completed) { _tentOwned = true; } } public void SetNPCRelocated(bool relocated) { _npcRelocated = relocated; } } public sealed class TentStorageSaveable : Saveable { private bool _isReady; [SaveableField("tent_storage_items")] private List _items = new List(); public static TentStorageSaveable Instance { get; private set; } public override SaveableLoadOrder LoadOrder => (SaveableLoadOrder)1; public bool IsReady => _isReady; public TentStorageSaveable() { Instance = this; } public IReadOnlyList GetItems() { return _items; } public void SetItems(List items) { _items = items ?? new List(); } protected override void OnCreated() { _isReady = true; ModLogger.Info("Tent storage saveable created"); } protected override void OnLoaded() { _isReady = true; ModLogger.Info($"Tent storage loaded ({_items?.Count ?? 0} item(s))"); } protected override void OnSaved() { ModLogger.Info($"Tent storage saved ({_items?.Count ?? 0} item(s))"); } } public sealed class TentStoredItem { public string ItemId { get; set; } public int Quantity { get; set; } } } namespace SidewalkEconomy.Quests { public sealed class TentInheritanceQuest : Quest { private const string QUEST_ID = "reginald_tent_inheritance_quest"; [SaveableField("rewardGranted")] private bool _rewardGranted = false; [SaveableField("requiredItems")] private Dictionary _requiredItems = new Dictionary(); private QuestEntry _itemEntry; private QuestEntry _returnEntry; public IReadOnlyDictionary RequiredItems => _requiredItems; protected override string Title => "New Beginnings"; protected override string Description => ""; protected override bool AutoBegin => false; protected override void OnCreated() { ((Registerable)this).OnCreated(); if (base.QuestEntries.Count == 0) { if (_requiredItems.Count == 0) { _requiredItems["growtent"] = 1; _requiredItems["ogkushseed"] = 3; } _itemEntry = ((Quest)this).AddEntry("Bring " + PrintRequiredItems() + " for Reggie", (Vector3?)null); _itemEntry.Begin(); _returnEntry = ((Quest)this).AddEntry("Return to Reggie with the supplies", (Vector3?)null); _returnEntry.SetState((QuestState)0); } else { if (base.QuestEntries.Count >= 1) { _itemEntry = base.QuestEntries[0]; } if (base.QuestEntries.Count >= 2) { _returnEntry = base.QuestEntries[1]; } } } public string PrintRequiredItems() { return string.Join(", ", _requiredItems.Select(delegate(KeyValuePair entry) { string key = entry.Key; int value = entry.Value; ItemDefinition itemDefinition = ItemManager.GetItemDefinition(key); string value2 = ((itemDefinition != null) ? itemDefinition.Name : null) ?? ("Unknown Item (" + key + ")"); return $"{value} {value2}"; })); } public void SetRequiredItems(Dictionary requiredItems) { if (requiredItems == null) { ModLogger.Warn("Required items cannot be null. Quest setup aborted."); } else { _requiredItems = requiredItems; } } } } namespace SidewalkEconomy.NPCs { public sealed class ReginaldIterson : NPC { [Serializable] private class PersistedData { public bool QuestCompleted = false; public bool NPCRelocated = false; } [SaveableField("ReginaldItersonData")] private PersistedData _data = new PersistedData(); public override bool IsPhysical => true; public ReginaldIterson() : base("reginald_iterson", "Reginald", "Iterson", (Sprite)null) { } protected override void ConfigurePrefab(NPCPrefabBuilder builder) { //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_0053: Unknown result type (might be due to invalid IL or missing references) Vector3 val = CalculateSpawnPosition(); Building val2 = Building.Get(); Building val3 = Building.Get(); Building val4 = Building.Get(); builder.WithIdentity("reginald_iterson", "Reginald", "Iterson").WithAppearanceDefaults((Action)delegate(AvatarDefaultsBuilder av) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) av.Gender = 0f; av.Height = 1f; av.Weight = 0.1f; av.SkinColor = new Color32((byte)211, (byte)181, (byte)143, byte.MaxValue); av.LeftEyeLidColor = new Color(0.827f, 0.71f, 0.561f); av.RightEyeLidColor = new Color(0.827f, 0.71f, 0.561f); av.EyeBallTint = new Color(1f, 1f, 1f); av.HairColor = new Color(0.176f, 0.125f, 0.075f); av.HairPath = "Avatar/Hair/closebuzzcut/CloseBuzzCut"; av.EyeballMaterialIdentifier = "Default"; av.PupilDilation = 0.5f; av.EyebrowScale = 1f; av.EyebrowThickness = 1f; av.EyebrowRestingHeight = -0.75f; av.EyebrowRestingAngle = 0.3f; av.LeftEye = (0.5f, 0.35f); av.RightEye = (0.555f, 0.35f); av.WithFaceLayer("Avatar/Layers/Face/Face_Agape", new Color(1f, 1f, 1f)); av.WithFaceLayer("Avatar/Layers/Face/FacialHair_Stubble", new Color(0f, 0f, 0f)); av.WithFaceLayer("Avatar/Layers/Face/FacialHair_Goatee", new Color(0.325f, 0.282f, 0.192f)); av.WithBodyLayer("Avatar/Layers/Top/ChestHair1", new Color(0.318f, 0.294f, 0.2f)); av.WithBodyLayer("Avatar/Layers/Bottom/CargoPants", new Color(0.125f, 0.125f, 0.125f)); av.WithBodyLayer("Avatar/Layers/Bottom/MaleUnderwear", new Color(1f, 1f, 1f)); av.WithBodyLayer("Avatar/Layers/Top/FlannelButtonUp", new Color(0.541f, 0f, 0f)); av.WithAccessoryLayer("Avatar/Accessories/Chest/OpenVest/OpenVest", new Color(0.592f, 0.569f, 0.341f)); av.WithAccessoryLayer("Avatar/Accessories/Head/Cap/Cap", new Color(0.384f, 0.369f, 0.216f)); }).WithSpawnPosition(val) .EnsureCustomer() .WithCustomerDefaults((Action)delegate(CustomerDataBuilder cd) { cd.WithSpending(400f, 900f).WithOrdersPerWeek(1, 4).WithPreferredOrderDay((Day)6) .WithOrderTime(900) .WithStandards((CustomerStandard)1) .WithMutualRelationRequirement(2.5f, 4f) .AllowDirectApproach(true) .WithCallPoliceChance(0.7f) .WithDependence(0.15f, 1f) .WithAffinities((IEnumerable>)new(DrugType, float)[2] { ((DrugType)0, 0.5f), ((DrugType)4, 0.5f) }); }) .WithRelationshipDefaults((Action)delegate(NPCRelationshipDataBuilder r) { r.WithDelta(1f).SetUnlocked(false).SetUnlockType((UnlockType)1) .WithConnectionsById(new string[1] { "kyle_cooley" }); }) .WithInventoryDefaults((Action)delegate(RandomInventoryItemsBuilder inv) { inv.WithStartupItems(new string[2] { "machete", "donut" }).WithRandomCash(50, 500); }); } private Vector3 CalculateSpawnPosition() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Vector3 tENT_POSITION = Constants.WorldSpawns.TENT_POSITION; return new Vector3(500f, 0f, 500f); } protected override void OnLoaded() { ((Saveable)this).OnLoaded(); } protected override void OnCreated() { ((NPC)this).OnCreated(); ((NPC)this).Appearance.Build(); ((NPC)this).Schedule.Enable(); ((NPC)this).Region = (Region)0; SetupDialogue(); ((NPC)this).RequiresRegionUnlocked = false; ((NPC)this).Region = (Region)0; ((NPC)this).Aggressiveness = 0f; } private void SetupDialogue() { } } } namespace SidewalkEconomy.Helpers { public static class AssetBundleUtils { private static readonly SidewalkEconomyMod mod = MelonAssembly.FindMelonInstance(); private static readonly MelonAssembly melonAssembly = ((MelonBase)mod).MelonAssembly; private static readonly Assembly modAssembly = melonAssembly.Assembly; private static Dictionary _bundleCache = new Dictionary(); public static WrappedAssetBundle LoadAssetBundle(string bundleFileName) { try { if (_bundleCache.TryGetValue(bundleFileName, out var value)) { if (value != null) { ModLogger.Debug("Using cached asset bundle: " + bundleFileName); return value; } _bundleCache.Remove(bundleFileName); } string text = (bundleFileName.Contains(".") ? bundleFileName : (modAssembly.GetName().Name + "." + bundleFileName)); ModLogger.Debug("Loading asset bundle from embedded resource: " + text); WrappedAssetBundle assetBundleFromStream = AssetLoader.GetAssetBundleFromStream(text, modAssembly); if (assetBundleFromStream == null) { if (modAssembly != null) { string[] manifestResourceNames = modAssembly.GetManifestResourceNames(); ModLogger.Error($"Failed to load AssetBundle from resource: '{text}'. Make sure the bundle file '{bundleFileName}' is set as 'EmbeddedResource' in your .csproj file."); ModLogger.Error($"Available embedded resources ({manifestResourceNames.Length}):"); string[] array = manifestResourceNames; foreach (string text2 in array) { ModLogger.Error(" - " + text2); } } else { ModLogger.Error($"Failed to load AssetBundle from resource: '{text}'. Make sure the bundle file '{bundleFileName}' is set as 'EmbeddedResource' in your .csproj file."); } return null; } _bundleCache[bundleFileName] = assetBundleFromStream; ModLogger.Debug("✓ Successfully loaded and cached asset bundle: " + bundleFileName); return assetBundleFromStream; } catch (Exception ex) { ModLogger.Error("Failed to load AssetBundle '" + bundleFileName + "': " + ex.Message); ModLogger.Error("Stack trace: " + ex.StackTrace); return null; } } public static WrappedAssetBundle GetLoadedAssetBundle(string asset_name_flag) { if (_bundleCache.TryGetValue(asset_name_flag, out var value)) { if (value != null) { return value; } _bundleCache.Remove(asset_name_flag); } IEnumerable allLoadedAssetBundles = AssetBundle.GetAllLoadedAssetBundles(); AssetBundle[] array = ConvertIl2CppEnumerableToArray(allLoadedAssetBundles); try { AssetBundle[] array2 = array; foreach (AssetBundle val in array2) { if (!((Object)(object)val == (Object)null) && val.Contains(asset_name_flag)) { string name = ((Object)val).name; if (_bundleCache.TryGetValue(name, out var value2)) { return value2; } ModLogger.Debug("Found bundle '" + name + "' but it's not in cache as WrappedAssetBundle"); } } string text = ""; AssetBundle[] array3 = array; foreach (AssetBundle val2 in array3) { if (!((Object)(object)val2 == (Object)null)) { try { string[] array4 = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)val2.GetAllAssetNames()); string value3 = string.Join("\n\r -", array4); text += $"{((Object)val2).name}({array4.Length} assets):{value3}\n"; } catch { text = text + ((Object)val2).name + "(error getting asset names)\n"; } } } ModLogger.Error($"Asset '{asset_name_flag}' not found in {array.Length} bundle(s).\n{text}"); return null; } catch (Exception ex) { ModLogger.Error("Failed to get loaded AssetBundle: " + ex.Message); ModLogger.Error("Stack trace: " + ex.StackTrace); return null; } } public static GameObject LoadAssetFromBundle(string asset_name) { WrappedAssetBundle loadedAssetBundle = GetLoadedAssetBundle(asset_name); if (loadedAssetBundle == null) { ModLogger.Error("Cannot load asset '" + asset_name + "': bundle not found"); return null; } try { return loadedAssetBundle.LoadAsset(asset_name); } catch (Exception ex) { ModLogger.Error("Failed to load asset '" + asset_name + "' from bundle: " + ex.Message); return null; } } public static void ClearBundleCache(string bundleFileName = null) { if (bundleFileName == null) { _bundleCache.Clear(); ModLogger.Debug("Cleared entire asset bundle cache"); } else if (_bundleCache.Remove(bundleFileName)) { ModLogger.Debug("Removed " + bundleFileName + " from asset bundle cache"); } } private static AssetBundle[] ConvertIl2CppEnumerableToArray(object il2cppEnumerable) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown if (il2cppEnumerable == null) { return Array.Empty(); } List list = new List(); foreach (AssetBundle item in (IEnumerable)il2cppEnumerable) { AssetBundle val = item; if ((Object)(object)val != (Object)null) { list.Add(val); } } return list.ToArray(); } } internal static class BuildModeRecovery { private const float OutsidePlacementHeartbeatWindowSeconds = 0.35f; private static float _outsidePlacementHeartbeatExpiry; internal static void ReportOutsidePlacementHeartbeat() { _outsidePlacementHeartbeatExpiry = Time.unscaledTime + 0.35f; } internal static bool OwnsOutsidePlacementFlow() { return Time.unscaledTime <= _outsidePlacementHeartbeatExpiry && IsBuildModeActive(); } internal static bool IsBuildModeActive() { if (!NetworkSingleton.InstanceExists) { _outsidePlacementHeartbeatExpiry = 0f; return false; } BuildManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { _outsidePlacementHeartbeatExpiry = 0f; return false; } if (instance.isBuilding) { return true; } return (Object)(object)GetCurrentBuildHandler(instance) != (Object)null; } internal static bool TryExitBuildMode(string reason, bool force) { if (!NetworkSingleton.InstanceExists) { _outsidePlacementHeartbeatExpiry = 0f; return false; } BuildManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { return false; } GameObject currentBuildHandler = GetCurrentBuildHandler(instance); bool isBuilding = instance.isBuilding; if (!force && !isBuilding && (Object)(object)currentBuildHandler == (Object)null) { _outsidePlacementHeartbeatExpiry = 0f; return false; } try { if (isBuilding && (Object)(object)currentBuildHandler != (Object)null && (Object)(object)currentBuildHandler.GetComponent() != (Object)null) { instance.StopBuilding(); if (!IsBuildModeStillActive(instance)) { _outsidePlacementHeartbeatExpiry = 0f; ModLogger.Debug("Build mode exited: " + reason); return true; } ModLogger.Warn("BuildManager.StopBuilding did not fully clear build mode (" + reason + "); escalating to forced reset"); } } catch (Exception value) { ModLogger.Warn($"BuildManager.StopBuilding failed during recovery ({reason}): {value}"); } ForceResetBuildMode(instance, currentBuildHandler, reason); return true; } private static GameObject GetCurrentBuildHandler(BuildManager buildManager) { return ((Object)(object)buildManager != (Object)null) ? buildManager.currentBuildHandler : null; } private static void ForceResetBuildMode(BuildManager buildManager, GameObject handler, string reason) { try { if ((Object)(object)handler != (Object)null) { BuildStop_Base component = handler.GetComponent(); if ((Object)(object)component != (Object)null) { component.Stop_Building(); } else { Object.Destroy((Object)(object)handler); } } TrySetPropertyValue(buildManager, "isBuilding", value: false); TrySetPropertyValue(buildManager, "currentBuildHandler", null); if (Singleton.InstanceExists) { Singleton.Instance.UnloadModule(); } if (Singleton.InstanceExists) { Singleton.Instance.SetAllHeatmapsActive(false); } if (PlayerSingleton.InstanceExists && Singleton.InstanceExists && PlayerSingleton.Instance.activeUIElementCount == 0) { Singleton.Instance.SetCrosshairVisible(true); } _outsidePlacementHeartbeatExpiry = 0f; if (IsBuildModeStillActive(buildManager)) { ModLogger.Warn("Forced build mode reset completed with residual active state: " + reason); } else { ModLogger.Warn("Forced build mode reset: " + reason); } } catch (Exception value) { ModLogger.Error($"Forced build mode reset failed ({reason}): {value}"); } } private static bool IsBuildModeStillActive(BuildManager buildManager) { return (Object)(object)buildManager != (Object)null && (buildManager.isBuilding || (Object)(object)GetCurrentBuildHandler(buildManager) != (Object)null); } private static bool TrySetPropertyValue(BuildManager buildManager, string propertyName, T value) { if ((Object)(object)buildManager == (Object)null) { return false; } PropertyInfo property = typeof(BuildManager).GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)property == null || !property.CanWrite) { return false; } try { property.SetValue(buildManager, value, null); return true; } catch { return false; } } } public static class Constants { public static class AssetBundle { public const string ASSETBUNDLE_NAME = "SidewalkEconomy.sidewalkeconomy"; public const string ASSETBUNDLE_FILE_NAME = "sidewalkeconomy"; public const string SLEEPINGBAG_PREFAB_NAME = "assets/sidewalk economy/sleepingbag.prefab"; public const string TENT_PREFAB_NAME = "assets/sidewalk economy/tent.prefab"; } public static class CustomItems { public const string TENT_ID = "sidewalkeconomy.tent"; public const string SLEEPINGBAG_ID = "sidewalkeconomy.sleepingbag"; public const string TENT_NAME = "Sidewalk Tent"; public const string SLEEPINGBAG_NAME = "Sleeping Bag"; public const string TENT_DESCRIPTION = "A portable shelter for outdoor living. Provides basic protection from the elements."; public const string SLEEPINGBAG_DESCRIPTION = "A warm sleeping bag for rough nights on the streets."; public const string CATEGORY = "Survival Gear"; public const int TENT_PRICE = 150; public const int SLEEPINGBAG_PRICE = 75; public const ushort TENT_PREFAB_ID = 9001; public const ushort SLEEPINGBAG_PREFAB_ID = 9002; public const string TENT_ICON_PATH = "SidewalkEconomy.Icons.tent.png"; public const string SLEEPINGBAG_ICON_PATH = "SidewalkEconomy.Icons.sleepingbag.png"; } public static class WorldSpawns { public const string SLEEPING_BAG_SPAWN_NAME = "SidewalkEconomy_SleepingBag_Spawn"; public const string TENT_SPAWN_NAME = "SidewalkEconomy_Tent_Spawn"; public const string TENT_STORAGE_ANCHOR_NAME = "SidewalkEconomy_TentStorage"; public static readonly Vector3 SLEEPING_BAG_POSITION = new Vector3(-90.5f, -3.85f, 69.728f); public static readonly Vector3 SLEEPING_BAG_ROTATION_EULER = Vector3.zero; public static readonly Vector3 TENT_POSITION = new Vector3(10f, 0.65f, -76f); public static readonly Vector3 TENT_ROTATION_EULER = new Vector3(0f, 180f, 0f); public static readonly Vector3 MARCUS_RELOCATE_POSITION = new Vector3(25f, 0.65f, -60f); public static readonly Vector3 MARCUS_RELOCATE_ROTATION_EULER = new Vector3(0f, 90f, 0f); public const float TENT_ENTRANCE_ANGLE_DEGREES = 30f; public const float TENT_ENTRANCE_YAW_OFFSET_DEGREES = 20f; public static readonly Vector3 TENT_SLEEP_OFFSET = new Vector3(0f, 0.9f, 1.35f); public static readonly Vector3 TENT_SLEEP_COLLIDER_SIZE = new Vector3(1.1f, 1.4f, 0.75f); public static readonly Vector3 TENT_STORAGE_OFFSET = new Vector3(1.25f, 0f, 0f); public static readonly Vector3 TENT_STORAGE_COLLIDER_SIZE = new Vector3(0.6f, 1f, 0.6f); } public static class NPCs { public const string MARCUS_ID = "reginald_iterson"; public const string MARCUS_FIRST_NAME = "Reginald"; public const string MARCUS_LAST_NAME = "Iterson"; } public static class Quests { public const string TENT_INHERITANCE_ID = "tent_inheritance_quest"; public const string TENT_INHERITANCE_TITLE = "New Beginnings"; public const string TENT_INHERITANCE_GROW_TENT_ID = "growtent"; public const string TENT_INHERITANCE_GROW_TENT_NAME = "Grow Tent"; public const int TENT_INHERITANCE_GROW_TENT_AMOUNT = 1; public const string TENT_INHERITANCE_OG_KUSH_SEED_ID = "ogkushseed"; public const string TENT_INHERITANCE_OG_KUSH_SEED_NAME = "OG Kush Seeds"; public const int TENT_INHERITANCE_OG_KUSH_SEED_AMOUNT = 3; } } public sealed class GameTimeManager { [CompilerGenerated] private sealed class d__30 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GameTimeManager <>4__this; private float 5__1; private int 5__2; private float 5__3; private int 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__30(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } 5__1 = <>4__this.GetCurrentGameTimeInMinutes(); 5__2 = Mathf.FloorToInt(GameMinutesToGameDays(5__1)) + 1; 5__3 = 5__1 % 1440f; 5__4 = Mathf.FloorToInt(5__3 / 60f); 5__5 = Mathf.FloorToInt(5__3 % 60f); if (5__2 != <>4__this._currentGameDay) { <>4__this._currentGameDay = 5__2; <>4__this.OnGameDayChanged?.Invoke(<>4__this._currentGameDay); } if (5__4 != <>4__this._currentGameHour) { <>4__this._currentGameHour = 5__4; <>4__this.OnGameHourChanged?.Invoke(<>4__this._currentGameHour); } if (5__5 != <>4__this._currentGameMinute) { <>4__this._currentGameMinute = 5__5; <>4__this.OnGameMinuteChanged?.Invoke(<>4__this._currentGameMinute); } <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; 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(); } } private static GameTimeManager _instance; public const float REAL_SECONDS_PER_GAME_MINUTE = 1f; public const float GAME_SECONDS_PER_GAME_MINUTE = 60f; public const float GAME_MINUTES_PER_GAME_HOUR = 60f; public const float GAME_HOURS_PER_GAME_DAY = 24f; private int _currentGameDay = 1; private int _currentGameHour; private int _currentGameMinute; private bool _isInitialized; private object _updateCoroutine; public static GameTimeManager Instance => _instance ?? (_instance = new GameTimeManager()); public event Action OnGameHourChanged; public event Action OnGameMinuteChanged; public event Action OnGameDayChanged; public void Initialize() { if (!_isInitialized) { _isInitialized = true; _updateCoroutine = MelonCoroutines.Start(UpdateGameTime()); } } public float GetCurrentGameTimeInMinutes() { return Time.time / 1f; } public int GetCurrentGameHour() { return _currentGameHour; } public int GetCurrentGameMinute() { return _currentGameMinute; } public int GetCurrentGameDay() { return _currentGameDay; } public static float GameMinutesToGameHours(float gameMinutes) { return gameMinutes / 60f; } public static float GameHoursToGameMinutes(float gameHours) { return gameHours * 60f; } public static float GameDaysToGameMinutes(float gameDays) { return gameDays * 24f * 60f; } public static float GameMinutesToGameDays(float gameMinutes) { return gameMinutes / 1440f; } [IteratorStateMachine(typeof(d__30))] private IEnumerator UpdateGameTime() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__30(0) { <>4__this = this }; } public void Shutdown() { if (!_isInitialized) { return; } object updateCoroutine = _updateCoroutine; _updateCoroutine = null; if (updateCoroutine != null) { try { MelonCoroutines.Stop(updateCoroutine); } catch (Exception ex) { ModLogger.Debug("GameTimeManager coroutine stop skipped during shutdown: " + ex.Message); } } _isInitialized = false; } } internal static class InjectedComponentHelper { internal static T GetInjectedComponent(GameObject gameObject) where T : Component { if ((Object)(object)gameObject == (Object)null) { return default(T); } EnsureTypeRegistered(); Component component = gameObject.GetComponent(Il2CppType.Of()); return ((Object)(object)component != (Object)null) ? ((Il2CppObjectBase)component).Cast() : default(T); } internal static T GetInjectedComponent(Component component) where T : Component { return ((Object)(object)component != (Object)null) ? GetInjectedComponent(component.gameObject) : default(T); } internal static T GetInjectedComponentInParent(Component component) where T : Component { if ((Object)(object)component == (Object)null) { return default(T); } EnsureTypeRegistered(); Component componentInParent = component.GetComponentInParent(Il2CppType.Of()); return ((Object)(object)componentInParent != (Object)null) ? ((Il2CppObjectBase)componentInParent).Cast() : default(T); } internal static T AddInjectedComponent(GameObject gameObject) where T : Component { if ((Object)(object)gameObject == (Object)null) { return default(T); } EnsureTypeRegistered(); Component val = gameObject.AddComponent(Il2CppType.Of()); return ((Object)(object)val != (Object)null) ? ((Il2CppObjectBase)val).Cast() : default(T); } private static void EnsureTypeRegistered() where T : class { if (!ClassInjector.IsTypeRegisteredInIl2Cpp()) { ClassInjector.RegisterTypeInIl2Cpp(); ModLogger.Debug("Registered injected IL2CPP type: " + typeof(T).FullName); } } } public static class ItemRegistrationManager { [CompilerGenerated] private sealed class d__4 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private int 5__1; private Registry 5__2; private string 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__4(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; <>1__state = -2; } private bool MoveNext() { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown bool result; try { switch (<>1__state) { default: result = false; goto end_IL_0000; case 0: <>1__state = -1; if (!_isRegistered && !_registrationInProgress) { _registrationInProgress = true; <>1__state = -3; 5__1 = 1; break; } result = false; goto end_IL_0000; case 1: <>1__state = -3; 5__2 = null; 5__3 = null; 5__1++; break; } if (5__1 <= 20 && !_isRegistered) { if (!TryGetReadyRegistry(out 5__2, out 5__3)) { if (5__1 == 1 || 5__1 == 20 || 5__1 % 5 == 0) { ModLogger.Debug($"Custom item registration waiting for registry readiness: {5__3} (attempt {5__1}/{20})"); } goto IL_012e; } if (!TryRegisterCustomItems(5__2)) { goto IL_012e; } result = false; <>m__Finally1(); } else { if (!_isRegistered) { ModLogger.Error("Custom item registration did not complete before retry budget was exhausted"); } <>m__Finally1(); result = false; } goto end_IL_0000; IL_012e: <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; result = true; end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; _registrationInProgress = false; } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static bool _isRegistered; private static bool _registrationInProgress; private const int MaxRegistrationAttempts = 20; private const float RegistrationRetryDelaySeconds = 0.5f; [IteratorStateMachine(typeof(d__4))] public static IEnumerator RegisterCustomItemsWhenReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__4(0); } public static void RegisterCustomItems() { Registry registry; string reason; if (_isRegistered) { ModLogger.Warn("Custom items already registered - skipping duplicate registration"); } else if (!TryGetReadyRegistry(out registry, out reason)) { ModLogger.Warn("Item registry is not ready - skipping immediate registration attempt: " + reason); } else { TryRegisterCustomItems(registry); } } private static bool TryRegisterCustomItems(Registry registry) { try { ModLogger.Info("Starting custom item registration..."); if ((Object)(object)SidewalkEconomyMod.TentPrefab == (Object)null) { ModLogger.Error("Tent prefab is null - cannot register tent item"); return false; } if ((Object)(object)SidewalkEconomyMod.SleepingBagPrefab == (Object)null) { ModLogger.Error("Sleeping bag prefab is null - cannot register sleeping bag item"); return false; } ModLogger.Debug("Setting up network components..."); if (!NetworkPrefabManager.SetupNetworkPrefab(SidewalkEconomyMod.TentPrefab, 9001)) { ModLogger.Error("Failed to setup tent network prefab"); return false; } if (!NetworkPrefabManager.SetupNetworkPrefab(SidewalkEconomyMod.SleepingBagPrefab, 9002)) { ModLogger.Error("Failed to setup sleeping bag network prefab"); return false; } bool flag = EnsureItemRegistered(registry, "sidewalkeconomy.tent", "Sidewalk Tent", "A portable shelter for outdoor living. Provides basic protection from the elements.", 150, "SidewalkEconomy.Icons.tent.png", SidewalkEconomyMod.TentPrefab); bool flag2 = EnsureItemRegistered(registry, "sidewalkeconomy.sleepingbag", "Sleeping Bag", "A warm sleeping bag for rough nights on the streets.", 75, "SidewalkEconomy.Icons.sleepingbag.png", SidewalkEconomyMod.SleepingBagPrefab); _isRegistered = flag && flag2; if (_isRegistered) { ModLogger.Info("✓ All custom items registered successfully"); } else { ModLogger.Warn("Custom item registration is incomplete; unresolved items will retry on the next registration pass"); } try { if ((Object)(object)registry != (Object)null && registry.ItemRegistry != null) { ModLogger.Debug($"Current ItemRegistry count: {registry.ItemRegistry.Count}"); int num = 0; Enumerator enumerator = registry.ItemRegistry.GetEnumerator(); while (enumerator.MoveNext()) { ItemRegister current = enumerator.Current; if (num >= 5) { break; } string obj = ((object)current.Definition)?.GetType().Name; ItemDefinition definition = current.Definition; ModLogger.Debug(" Sample item: " + obj + " - " + ((definition != null) ? ((Object)definition).name : null)); num++; } } } catch (Exception ex) { ModLogger.Warn("Could not log ItemRegistry contents: " + ex.Message); } return _isRegistered; } catch (Exception ex2) { ModLogger.Error("Failed to register custom items: " + ex2.Message); ModLogger.Error("Stack trace: " + ex2.StackTrace); return false; } } private static bool TryGetReadyRegistry(out Registry registry, out string reason) { registry = Singleton.Instance; if ((Object)(object)registry == (Object)null) { reason = "Registry.Instance is null"; return false; } if (registry.ItemRegistry == null) { reason = "Registry.ItemRegistry is null"; return false; } reason = string.Empty; return true; } private static bool EnsureItemRegistered(Registry registry, string itemId, string itemName, string description, int price, string iconResourcePath, GameObject builtItemPrefab) { if (IsItemRegistered(registry, itemId)) { ModLogger.Debug(itemId + " is already present in the registry"); return true; } ModLogger.Debug("Creating buildable item definition for " + itemName + "..."); BuildableItemDefinition val = CreateBuildableItemDefinition(itemId, itemName, description, price, iconResourcePath, builtItemPrefab); if ((Object)(object)val == (Object)null) { return false; } return RegisterWithGame(registry, val); } private static BuildableItemDefinition CreateBuildableItemDefinition(string itemId, string itemName, string description, int price, string iconResourcePath, GameObject builtItemPrefab) { try { BuildableItemDefinition val = ScriptableObject.CreateInstance(); if ((Object)(object)val == (Object)null) { ModLogger.Error("Failed to create BuildableItemDefinition for " + itemName); return null; } SetFieldValue(val, "ID", itemId); SetFieldValue(val, "_name", itemName); SetFieldValue(val, "Name", itemName); SetFieldValue(val, "name", itemName); SetFieldValue(val, "Description", description); SetFieldValue(val, "_description", description); SetFieldValue(val, "Category", "Survival Gear"); SetFieldValue(val, "_category", "Survival Gear"); SetFieldValue(val, "Price", price); SetFieldValue(val, "_price", price); SetFieldValue(val, "Cost", price); SetFieldValue(val, "_cost", price); Sprite val2 = LoadIconFromResource(iconResourcePath); if ((Object)(object)val2 != (Object)null) { SetFieldValue(val, "Icon", val2); SetFieldValue(val, "_icon", val2); ModLogger.Debug("✓ Icon loaded for " + itemName); } else { ModLogger.Warn("Could not load icon for " + itemName + " from " + iconResourcePath); } BuildableItem val3 = builtItemPrefab.GetComponent(); if ((Object)(object)val3 == (Object)null) { ModLogger.Debug("Adding BuildableItem component to " + itemName + " prefab"); val3 = builtItemPrefab.AddComponent(); } SetFieldValue(val, "BuiltItem", val3); SetFieldValue(val, "_builtItem", val3); SetFieldValue(val, "Stackable", false); SetFieldValue(val, "_stackable", false); SetFieldValue(val, "MaxStack", 1); SetFieldValue(val, "_maxStack", 1); SetFieldValue(val, "BuildSoundType", 0); SetFieldValue(val, "_buildSoundType", 0); ModLogger.Debug("✓ Created BuildableItemDefinition for " + itemName); return val; } catch (Exception ex) { ModLogger.Error("Failed to create BuildableItemDefinition for " + itemName + ": " + ex.Message); ModLogger.Error("Stack trace: " + ex.StackTrace); return null; } } private static Sprite LoadIconFromResource(string resourcePath) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); using Stream stream = executingAssembly.GetManifestResourceStream(resourcePath); if (stream == null) { ModLogger.Error("Could not find embedded resource: " + resourcePath); ModLogger.Debug("Available resources:"); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { ModLogger.Debug(" - " + text); } return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2); IL2CPP.il2cpp_gc_disable(); ImageConversion.LoadImage(val, Il2CppStructArray.op_Implicit(array)); IL2CPP.il2cpp_gc_enable(); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } catch (Exception ex) { ModLogger.Error("Failed to load icon from " + resourcePath + ": " + ex.Message); ModLogger.Error("Stack trace: " + ex.StackTrace); return null; } } private static bool RegisterWithGame(Registry registry, BuildableItemDefinition definition) { try { if ((Object)(object)registry == (Object)null || registry.ItemRegistry == null) { ModLogger.Error("Item registry is unavailable - cannot register items"); return false; } if (IsItemRegistered(registry, ((BaseItemDefinition)definition).ID)) { ModLogger.Debug(((BaseItemDefinition)definition).ID + " already exists in ItemRegistry"); return true; } try { registry.AddToRegistry((ItemDefinition)(object)definition); } catch (Exception ex) { ModLogger.Warn("Direct registry add failed for " + ((BaseItemDefinition)definition).ID + ": " + ex.Message); if (!TryRegisterWithFallbackItemRegister(registry, definition)) { return false; } } if (!IsItemRegistered(registry, ((BaseItemDefinition)definition).ID)) { ModLogger.Warn("Registry add did not make " + ((BaseItemDefinition)definition).ID + " discoverable by item ID"); return false; } ModLogger.Info("✓ Registered custom item " + ((BaseItemDefinition)definition).ID); return true; } catch (Exception ex2) { ModLogger.Error("Failed to register " + ((Object)definition).name + " with game: " + ex2.Message); ModLogger.Error("Stack trace: " + ex2.StackTrace); return false; } } private static Type FindItemRegisterType() { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); Assembly[] array = assemblies; foreach (Assembly assembly in array) { if (assembly.FullName.StartsWith("System") || assembly.FullName.StartsWith("Unity") || assembly.FullName.StartsWith("mscorlib")) { continue; } try { Type type = (assembly.GetType("ScheduleOne.Registry", throwOnError: false) ?? assembly.GetType("Il2CppScheduleOne.Registry", throwOnError: false))?.GetNestedType("ItemRegister", BindingFlags.Public | BindingFlags.NonPublic); if (type != null) { return type; } } catch (Exception) { } } } catch (Exception ex2) { ModLogger.Error("Error finding ItemRegister type: " + ex2.Message); } return null; } private static bool TryRegisterWithFallbackItemRegister(Registry registry, BuildableItemDefinition definition) { try { Type type = ((object)registry).GetType().GetNestedType("ItemRegister", BindingFlags.Public | BindingFlags.NonPublic) ?? FindItemRegisterType(); if (type == null) { ModLogger.Warn("Fallback registration type was not found for " + ((BaseItemDefinition)definition).ID); return false; } object obj = Activator.CreateInstance(type, nonPublic: true); if (obj == null) { ModLogger.Warn("Fallback registration object could not be created for " + ((BaseItemDefinition)definition).ID); return false; } SetFieldValue(obj, "name", ((Object)definition).name); SetFieldValue(obj, "ID", ((BaseItemDefinition)definition).ID); SetFieldValue(obj, "Definition", definition); MethodInfo method = ((object)registry.ItemRegistry).GetType().GetMethod("Add"); if (method == null) { ModLogger.Warn("Fallback registry add method was not found for " + ((BaseItemDefinition)definition).ID); return false; } method.Invoke(registry.ItemRegistry, new object[1] { obj }); ((object)registry).GetType().GetMethod("AddToItemDictionary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(registry, new object[1] { obj }); return true; } catch (Exception ex) { ModLogger.Error("Fallback item register creation failed for " + ((BaseItemDefinition)definition).ID + ": " + ex.Message); ModLogger.Error("Stack trace: " + ex.StackTrace); return false; } } private static bool IsItemRegistered(Registry registry, string itemId) { if ((Object)(object)registry == (Object)null || string.IsNullOrWhiteSpace(itemId)) { return false; } try { if (Registry.ItemExists(itemId)) { return true; } return (Object)(object)Registry.GetItem(itemId) != (Object)null; } catch (Exception ex) { ModLogger.Warn("Failed to verify registry entry for " + itemId + ": " + ex.Message); return false; } } private static void SetFieldValue(object obj, string fieldName, object value) { try { Type type = obj.GetType(); PropertyInfo property = type.GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(obj, value); return; } FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(obj, value); } } catch (Exception) { } } } public static class MelonLoggerExtensions { public static void Debug(this Instance logger, string message, bool stacktrace = true) { ModLogger.Debug(message); } } public static class ModLogger { private static bool _debugEnabled; public static bool IsDebugEnabled => _debugEnabled; public static void SetDebugEnabled(bool enabled) { _debugEnabled = enabled; if (enabled) { Info("Debug logging enabled"); } } public static void Info(string message) { MelonLogger.Msg(message); } public static void Debug(string message) { if (_debugEnabled) { MelonLogger.Msg("[DEBUG] " + message); } } public static void Error(string message) { MelonLogger.Error("[ERROR] " + message); } public static void Error(string message, Exception exception) { MelonLogger.Error("[ERROR] " + message + ": " + exception.Message); MelonLogger.Error("Stack trace: " + exception.StackTrace); } public static void Warn(string message) { MelonLogger.Warning(message); } public static void SystemDebug(string message) { if (_debugEnabled) { MelonLogger.Msg("[SYSTEM] " + message); } } public static void UIDebug(string message) { if (_debugEnabled) { MelonLogger.Msg("[UI] " + message); } } public static void NetworkDebug(string message) { if (_debugEnabled) { MelonLogger.Msg("[NETWORK] " + message); } } public static void LogInitialized() { Info("SidewalkEconomy v1.0.1 initialized successfully"); } public static void LogInitializing() { Info("SidewalkEconomy v1.0.1 initializing..."); } } public static class NetworkPrefabManager { public static bool SetupNetworkPrefab(GameObject prefab, ushort prefabId) { if ((Object)(object)prefab == (Object)null) { ModLogger.Error("Cannot setup network prefab: prefab is null"); return false; } try { ModLogger.Debug($"Setting up NetworkObject for {((Object)prefab).name} (ID: {prefabId})"); NetworkObject val = prefab.GetComponent(); if ((Object)(object)val == (Object)null) { ModLogger.Debug("Adding NetworkObject component to " + ((Object)prefab).name); val = prefab.AddComponent(); } else { ModLogger.Debug("NetworkObject already exists on " + ((Object)prefab).name); } ModLogger.Debug("✓ NetworkObject component ready for " + ((Object)prefab).name); return RegisterWithFishNet(prefab, val); } catch (Exception ex) { ModLogger.Error("Failed to setup NetworkObject for " + ((Object)prefab).name + ": " + ex.Message); ModLogger.Error("Stack trace: " + ex.StackTrace); return false; } } private static bool RegisterWithFishNet(GameObject prefab, NetworkObject networkObject) { try { NetworkManager networkManager = InstanceFinder.NetworkManager; if ((Object)(object)networkManager == (Object)null) { ModLogger.Warn("NetworkManager not found - prefab " + ((Object)prefab).name + " may not sync properly"); ModLogger.Warn("This is expected if called before network initialization"); return true; } PrefabObjects spawnablePrefabs = networkManager.SpawnablePrefabs; if ((Object)(object)spawnablePrefabs == (Object)null) { ModLogger.Warn("SpawnablePrefabs collection not found on NetworkManager"); return true; } ModLogger.Debug("✓ " + ((Object)prefab).name + " has NetworkObject - FishNet will handle spawning automatically"); ModLogger.Debug(" (Manual prefab pool registration not required - game handles this)"); return true; } catch (Exception ex) { ModLogger.Error("Failed to register " + ((Object)prefab).name + " with FishNet: " + ex.Message); ModLogger.Error("Stack trace: " + ex.StackTrace); return false; } } public static bool VerifyNetworkSetup(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { ModLogger.Error("Cannot verify null prefab"); return false; } NetworkObject component = prefab.GetComponent(); if ((Object)(object)component == (Object)null) { ModLogger.Error(((Object)prefab).name + " is missing NetworkObject component"); return false; } if (component.PrefabId == 0) { ModLogger.Error(((Object)prefab).name + " has invalid PrefabId (0)"); return false; } ModLogger.Debug($"✓ {((Object)prefab).name} network setup verified (PrefabId: {component.PrefabId})"); return true; } } public static class PrefabControllerInstaller { public static void InstallControllers(GameObject sleepingBagPrefab, GameObject tentPrefab) { if ((Object)(object)sleepingBagPrefab == (Object)null) { ModLogger.Warn("Sleeping bag prefab missing - controller install skipped"); } else if ((Object)(object)InjectedComponentHelper.GetInjectedComponent(sleepingBagPrefab) == (Object)null) { InjectedComponentHelper.AddInjectedComponent(sleepingBagPrefab); ModLogger.Debug("SleepingBagController attached to sleeping bag prefab"); } if ((Object)(object)tentPrefab == (Object)null) { ModLogger.Warn("Tent prefab missing - controller install skipped"); } else if ((Object)(object)InjectedComponentHelper.GetInjectedComponent(tentPrefab) == (Object)null) { InjectedComponentHelper.AddInjectedComponent(tentPrefab); ModLogger.Debug("TentController attached to tent prefab"); } } } public static class ShaderUtils { private static Dictionary _shaderCache = new Dictionary(); private static Dictionary _shaderMapping = new Dictionary(); public static int FixShadersOnGameObject(GameObject rootObject, bool logProgress = true) { if ((Object)(object)rootObject == (Object)null) { ModLogger.Error("Cannot fix shaders: rootObject is null"); return 0; } int num = 0; List allComponentsInChildrenRecursive = GetAllComponentsInChildrenRecursive(rootObject); if (logProgress) { ModLogger.Debug($"Fixing URP shaders on {allComponentsInChildrenRecursive.Count} renderer(s) in '{((Object)rootObject).name}'"); } foreach (Renderer item in allComponentsInChildrenRecursive) { if ((Object)(object)item == (Object)null) { continue; } Il2CppReferenceArray materials = item.materials; for (int i = 0; i < ((Il2CppArrayBase)(object)materials).Length; i++) { Material val = ((Il2CppArrayBase)(object)materials)[i]; if ((Object)(object)val == (Object)null) { continue; } Shader shader = val.shader; if ((Object)(object)shader == (Object)null) { continue; } Shader val2 = FindURPShader(((Object)shader).name); if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)shader) { val.shader = val2; num++; if (logProgress) { ModLogger.Debug($"Fixed shader on '{((Object)item).name}': '{((Object)shader).name}' -> '{((Object)val2).name}'"); } } else if ((Object)(object)val2 == (Object)null && logProgress) { ModLogger.Warn($"Could not find URP shader for '{((Object)shader).name}' on '{((Object)item).name}'"); } } } if (logProgress) { ModLogger.Debug($"✓ Fixed {num} material shader(s) on '{((Object)rootObject).name}'"); } return num; } public static Shader FindURPShader(string shaderName) { if (string.IsNullOrEmpty(shaderName)) { return null; } if (_shaderCache.TryGetValue(shaderName, out var value)) { if ((Object)(object)value != (Object)null) { return value; } _shaderCache.Remove(shaderName); } if (_shaderMapping.TryGetValue(shaderName, out var value2)) { Shader val = FindURPShader(value2); if ((Object)(object)val != (Object)null) { _shaderCache[shaderName] = val; return val; } } Shader val2 = Shader.Find(shaderName); if ((Object)(object)val2 != (Object)null && IsURPShader(val2)) { _shaderCache[shaderName] = val2; return val2; } Shader val3 = null; foreach (Shader item in Resources.FindObjectsOfTypeAll()) { if (!((Object)(object)item == (Object)null)) { if (((Object)item).name == shaderName && IsURPShader(item)) { _shaderCache[shaderName] = item; return item; } if ((Object)(object)val3 == (Object)null && IsURPShader(item) && (((Object)item).name.Contains(shaderName) || shaderName.Contains(((Object)item).name))) { val3 = item; } } } if ((Object)(object)val3 == (Object)null) { val3 = TryCommonURPShaderPatterns(shaderName); } if ((Object)(object)val3 != (Object)null) { _shaderCache[shaderName] = val3; return val3; } _shaderCache[shaderName] = null; return null; } private static bool IsURPShader(Shader shader) { if ((Object)(object)shader == (Object)null || string.IsNullOrEmpty(((Object)shader).name)) { return false; } string name = ((Object)shader).name; return name.Contains("Universal Render Pipeline") || name.Contains("UniversalRP") || name.Contains("URP") || name.StartsWith("Shader Graphs/"); } private static Shader TryCommonURPShaderPatterns(string originalShaderName) { string[] array = new string[8] { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit", "Universal Render Pipeline/Unlit", "Universal Render Pipeline/Baked Lit", "Universal Render Pipeline/Terrain/Lit", "Universal Render Pipeline/Particles/Lit", "Universal Render Pipeline/Particles/Simple Lit", "Universal Render Pipeline/Particles/Unlit" }; string text = originalShaderName.ToLower(); if (text.Contains("lit") && !text.Contains("unlit")) { string[] array2 = new string[2] { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit" }; foreach (string text2 in array2) { Shader val = Shader.Find(text2); if ((Object)(object)val != (Object)null) { return val; } } } else if (text.Contains("unlit")) { Shader val2 = Shader.Find("Universal Render Pipeline/Unlit"); if ((Object)(object)val2 != (Object)null) { return val2; } } else if (text.Contains("particle")) { string[] array3 = new string[2] { "Universal Render Pipeline/Particles/Lit", "Universal Render Pipeline/Particles/Unlit" }; foreach (string text3 in array3) { Shader val3 = Shader.Find(text3); if ((Object)(object)val3 != (Object)null) { return val3; } } } else if (text.Contains("terrain")) { Shader val4 = Shader.Find("Universal Render Pipeline/Terrain/Lit"); if ((Object)(object)val4 != (Object)null) { return val4; } } string[] array4 = array; foreach (string text4 in array4) { Shader val5 = Shader.Find(text4); if ((Object)(object)val5 != (Object)null) { return val5; } } return null; } public static void AddShaderMapping(string bundleShaderName, string gameShaderName) { _shaderMapping[bundleShaderName] = gameShaderName; ModLogger.Debug($"Added shader mapping: '{bundleShaderName}' -> '{gameShaderName}'"); } private static List GetAllComponentsInChildrenRecursive(GameObject obj) where T : Component { List list = new List(); if ((Object)(object)obj == (Object)null) { return list; } T[] array = Il2CppArrayBase.op_Implicit(obj.GetComponents()); if (array.Length != 0) { list.AddRange(array); } for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); list.AddRange(GetAllComponentsInChildrenRecursive(((Component)child).gameObject)); } return list; } } public static class SleepUtils { public static bool CanSleep(out string noSleepReason) { noSleepReason = string.Empty; TimeManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null || !instance.IsCurrentTimeWithinRange(1800, 400)) { noSleepReason = "Can't sleep before " + TimeManager.Get12HourTime(1800f, true); return false; } Player local = Player.Local; if ((Object)(object)local == (Object)null) { ModLogger.Warn("Player not found while checking sleep conditions"); return true; } ProductItemInstance consumedProduct = local.ConsumedProduct; if (consumedProduct == null) { return true; } object propertyValue = GetPropertyValue(consumedProduct, "Definition"); if (!(GetPropertyValue(propertyValue, "Properties") is IEnumerable properties)) { return true; } if (HasEffectType(properties, "Energizing")) { noSleepReason = "Can't sleep while energized!"; return false; } if (HasEffectType(properties, "Athletic")) { noSleepReason = "Can't sleep while athletic!"; return false; } return true; } private static bool HasEffectType(IEnumerable properties, string effectTypeName) { foreach (object property in properties) { if (property == null || !(property.GetType().Name == effectTypeName)) { continue; } return true; } return false; } private static object GetPropertyValue(object instance, string propertyName) { return instance?.GetType().GetProperty(propertyName)?.GetValue(instance); } } internal static class SyntheticGridManager { private struct ManualIdlePointConfig { public Vector3 Position; public float YawDegrees; } private sealed class SyntheticGridInfo { public Property Property; public Grid Grid; public string PropertyCode; public string GridGuid; public Vector3 Origin; public int MinX; public int MaxX; public int MinY; public int MaxY; public HashSet TileCoords; public Dictionary CoordinateToTile; public List Tiles; public List CoordinateTilePairs; public bool BoundsInitialized; } private readonly struct GridCoord : IEquatable { public int X { get; } public int Y { get; } public GridCoord(int x, int y) { X = x; Y = y; } public bool Equals(GridCoord other) { return X == other.X && Y == other.Y; } public override bool Equals(object obj) { return obj is GridCoord other && Equals(other); } public override int GetHashCode() { return (X * 397) ^ Y; } } private const float MergeSearchRadius = 25f; private const float PlacementFallbackBoundsRadius = 1.5f; private const float PlacementBoundsMargin = 0.75f; private const float LegacyMigrationClusterDistance = 25f; private const int PaddingTiles = 1; private const float TileSize = 0.5f; private const float TileColliderHeight = 0.1f; private const float TileGroundOffset = 0.02f; private const float GroundRaycastHeight = 75f; private const float GroundRaycastDepth = 150f; private const float SyntheticTileAmbientExposure = 1f; private const string RootName = "SidewalkEconomy_SyntheticRoot"; private const string PreviewPropertyCode = "sidewalkeconomy_preview"; private const string PreviewPropertyName = "SidewalkEconomy Placement Preview"; private const string PreviewGridGuid = "00000000-0000-0000-0000-000000000001"; private const bool EnableSyntheticEmployees = false; private const string DefaultSyntheticPropertyNamePrefix = "Synthetic Property "; private const float EmployeeNavMeshSampleDistance = 2.5f; private const float EmployeeIdleClearanceRadius = 0.35f; private const float EmployeeIdleClearanceHeight = 1.8f; private const float EmployeeIdleProbeBaseHeight = 0.2f; private const float ManualIdleNavMeshSampleDistance = 4f; private static readonly List Grids = new List(); private static readonly Dictionary ManualIdlePointsByPropertyCode = new Dictionary(StringComparer.Ordinal); private static readonly Dictionary PreviewTileObjects = new Dictionary(); private static readonly HashSet PreviewActiveCoords = new HashSet(); private static readonly RaycastHit[] GroundRaycastHits = (RaycastHit[])(object)new RaycastHit[64]; private static GameObject _root; private static SyntheticGridInfo _previewInfo; private static int _tileLayer = -1; public static void Initialize() { EnsureRoot(); } public static bool HasAnyTileIntersections(GridItem buildable) { if ((Object)(object)buildable == (Object)null || buildable.CoordinateFootprintTilePairs == null) { return false; } for (int i = 0; i < buildable.CoordinateFootprintTilePairs.Count; i++) { FootprintTile footprintTile = buildable.CoordinateFootprintTilePairs[i].footprintTile; TileDetector val = (((Object)(object)footprintTile != (Object)null) ? footprintTile.tileDetector : null); if ((Object)(object)val != (Object)null && val.intersectedTiles != null && val.intersectedTiles.Count > 0) { return true; } } return false; } public static bool EnsureGridForPlacement(Vector3 placementPosition, Vector3 originFootprintPosition, GridItem buildable = null) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) EnsureRoot(); SyntheticGridInfo syntheticGridInfo = FindGridNearPosition(placementPosition, 25f); bool flag = false; if (syntheticGridInfo == null) { syntheticGridInfo = CreateSyntheticGrid(originFootprintPosition); Grids.Add(syntheticGridInfo); flag = true; } flag |= ExtendGridBounds(syntheticGridInfo, GetPlacementGridBounds(buildable, placementPosition), (buildable != null) ? ((Component)buildable).transform : null); if (flag) { ConfigureSyntheticPropertyEmployeeAccess(syntheticGridInfo.Property); } return flag; } public static bool EnsurePreviewGridForPlacement(Vector3 placementPosition, Vector3 originFootprintPosition, GridItem buildable = null) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) EnsureRoot(); SyntheticGridInfo syntheticGridInfo = EnsurePreviewGrid(originFootprintPosition); if (syntheticGridInfo == null) { return false; } syntheticGridInfo.Origin = originFootprintPosition; if ((Object)(object)syntheticGridInfo.Property != (Object)null) { ((Component)syntheticGridInfo.Property).transform.position = originFootprintPosition; ((Component)syntheticGridInfo.Property).gameObject.SetActive(true); } if ((Object)(object)syntheticGridInfo.Grid != (Object)null) { ((Component)syntheticGridInfo.Grid).transform.position = originFootprintPosition; ((Component)syntheticGridInfo.Grid).gameObject.SetActive(true); } Bounds placementGridBounds = GetPlacementGridBounds(buildable, placementPosition); GetBoundsForWorld(syntheticGridInfo.Grid, ((Bounds)(ref placementGridBounds)).min, ((Bounds)(ref placementGridBounds)).max, out var minX, out var maxX, out var minY, out var maxY); minX--; maxX++; minY--; maxY++; return UpdatePreviewTiles(syntheticGridInfo, minX, maxX, minY, maxY, (buildable != null) ? ((Component)buildable).transform : null); } public static void HidePreviewGrid() { if ((Object)(object)_previewInfo?.Property != (Object)null) { ((Component)_previewInfo.Property).gameObject.SetActive(false); } } public static bool PromotePreviewGridForPlacement(Vector3 placementPosition, Vector3 originFootprintPosition, GridItem buildable = null) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) EnsureRoot(); if (FindGridNearPosition(placementPosition, 25f) != null) { HidePreviewGrid(); return EnsureGridForPlacement(placementPosition, originFootprintPosition, buildable); } if ((Object)(object)_previewInfo?.Grid == (Object)null || (Object)(object)_previewInfo.Property == (Object)null || PreviewActiveCoords.Count == 0) { HidePreviewGrid(); return EnsureGridForPlacement(placementPosition, originFootprintPosition, buildable); } SyntheticGridInfo previewInfo = _previewInfo; DestroyInactivePreviewTiles(previewInfo); RemovePreviewTileMarkers(); string text = Guid.NewGuid().ToString(); string text2 = "synthetic_" + text; string propertyName = "Synthetic Property " + text.Substring(0, 8); previewInfo.PropertyCode = text2; previewInfo.GridGuid = text; previewInfo.Origin = originFootprintPosition; ((Component)previewInfo.Property).transform.position = originFootprintPosition; ((Component)previewInfo.Property).gameObject.SetActive(true); ((Component)previewInfo.Grid).transform.position = originFootprintPosition; ((Component)previewInfo.Grid).gameObject.SetActive(true); SetPropertyField(previewInfo.Property, "propertyCode", text2); SetSyntheticPropertyDisplayName(previewInfo.Property, propertyName); EnsureWorldspaceUIContainer(previewInfo.Property, propertyName); EnsureEmployeeAnchors(previewInfo.Property); SetGridParentProperty(previewInfo.Grid, previewInfo.Property); SetGridGuid(previewInfo.Grid, text); RegisterSyntheticProperty(previewInfo.Property); RegisterGrid(previewInfo.Property, previewInfo.Grid); Grids.Add(previewInfo); RenameGridObjectsForProperty(previewInfo.Property, propertyName); UpdateInfoBoundsFromTileCoords(previewInfo); ConfigureSyntheticPropertyEmployeeAccess(previewInfo.Property); _previewInfo = null; PreviewTileObjects.Clear(); PreviewActiveCoords.Clear(); return true; } public static bool HasPreviewTileIntersections(GridItem buildable) { if ((Object)(object)buildable == (Object)null || buildable.CoordinateFootprintTilePairs == null) { return false; } for (int i = 0; i < buildable.CoordinateFootprintTilePairs.Count; i++) { FootprintTile footprintTile = buildable.CoordinateFootprintTilePairs[i].footprintTile; TileDetector val = (((Object)(object)footprintTile != (Object)null) ? footprintTile.tileDetector : null); if (((val != null) ? val.intersectedTiles : null) == null) { continue; } for (int j = 0; j < val.intersectedTiles.Count; j++) { Tile val2 = val.intersectedTiles[j]; if ((Object)(object)val2 != (Object)null && (Object)(object)InjectedComponentHelper.GetInjectedComponentInParent((Component)(object)val2) != (Object)null) { return true; } } } return false; } public static void CaptureForSave() { SyncSavedRecords(); } internal static bool AreSyntheticEmployeesEnabled() { return false; } internal static bool IsSyntheticProperty(Property property) { return (Object)(object)property != (Object)null && (Object)(object)InjectedComponentHelper.GetInjectedComponent((Component)(object)property) != (Object)null; } internal static bool IsSyntheticPropertyIdentifier(string identifier) { if (string.IsNullOrWhiteSpace(identifier)) { return false; } if (Property.Properties == null) { return false; } foreach (Property item in Property.Properties.AsEnumerable()) { if (!IsSyntheticProperty(item) || (!string.Equals(item.PropertyCode, identifier, StringComparison.Ordinal) && !string.Equals(item.PropertyName, identifier, StringComparison.Ordinal))) { continue; } return true; } return false; } internal static Property GetNearestSyntheticProperty(Vector3 position, float maxDistance) { //IL_0048: 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_003f: Unknown result type (might be due to invalid IL or missing references) SyntheticGridInfo syntheticGridInfo = null; float num = maxDistance; for (int i = 0; i < Grids.Count; i++) { SyntheticGridInfo syntheticGridInfo2 = Grids[i]; if (syntheticGridInfo2 != null && !((Object)(object)syntheticGridInfo2.Property == (Object)null)) { float num2 = (syntheticGridInfo2.BoundsInitialized ? DistanceToBoundsXZ(syntheticGridInfo2, position) : Vector3.Distance(syntheticGridInfo2.Origin, position)); if (num2 <= num) { num = num2; syntheticGridInfo = syntheticGridInfo2; } } } return syntheticGridInfo?.Property; } internal static bool TryRenameSyntheticProperty(Property property, string newPropertyName, out string failureReason) { failureReason = string.Empty; if ((Object)(object)property == (Object)null) { failureReason = "No synthetic property selected."; return false; } string text = (newPropertyName ?? string.Empty).Trim(); if (string.IsNullOrWhiteSpace(text)) { failureReason = "Property name cannot be empty."; return false; } if (FindGridByProperty(property) == null) { failureReason = "Synthetic property backing data was not found."; return false; } SetSyntheticPropertyDisplayName(property, text); RenameGridObjectsForProperty(property, text); SyncSavedRecords(); return true; } internal static bool TryGetManualIdlePoint(Property property, out Vector3 position, out float yawDegrees) { //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) position = Vector3.zero; yawDegrees = 0f; bool flag = true; return false; } internal static bool TrySetManualIdlePoint(Property property, Vector3 position, float yawDegrees, out string failureReason) { failureReason = "Synthetic property employees are currently disabled."; bool flag = true; return false; } internal static void ClearManualIdlePoint(Property property) { bool flag = true; } internal static bool TryValidateEmployeeIdlePoint(Property property, Vector3 desiredPosition, out Vector3 resolvedPosition, out string failureReason) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) resolvedPosition = desiredPosition; failureReason = "Synthetic property employees are currently disabled."; bool flag = true; return false; } internal static bool EnsureEmployeeHiringConfigured(Property property, out string failureReason) { failureReason = string.Empty; if ((Object)(object)property == (Object)null) { failureReason = "Property was not found."; return false; } if ((Object)(object)InjectedComponentHelper.GetInjectedComponent((Component)(object)property) == (Object)null) { return true; } bool flag = true; ConfigureSyntheticPropertyEmployeeAccess(property); failureReason = "Employees are disabled on synthetic properties in this version."; return false; } internal static bool TryMigrateLegacySyntheticGridRecords(IReadOnlyList records, out List migratedRecords, out int mergedPropertiesCount, out int mergedRecordCount) { //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) migratedRecords = new List(); mergedPropertiesCount = 0; mergedRecordCount = 0; if (records == null || records.Count == 0) { return false; } for (int i = 0; i < records.Count; i++) { migratedRecords.Add(CloneRecord(records[i])); } bool result = false; bool[] array = new bool[migratedRecords.Count]; for (int j = 0; j < migratedRecords.Count; j++) { if (array[j] || migratedRecords[j] == null) { continue; } List list = new List(); Queue queue = new Queue(); queue.Enqueue(j); array[j] = true; while (queue.Count > 0) { int num = queue.Dequeue(); list.Add(num); for (int k = 0; k < migratedRecords.Count; k++) { if (!array[k] && migratedRecords[k] != null && GetRecordBoundsDistanceXZ(migratedRecords[num], migratedRecords[k]) <= 25f) { array[k] = true; queue.Enqueue(k); } } } if (list.Count <= 1) { continue; } int num2 = SelectCanonicalRecordIndex(list, migratedRecords); if (num2 < 0) { continue; } string propertyCode = migratedRecords[num2].PropertyCode; string text = migratedRecords[num2].PropertyName; if (string.IsNullOrWhiteSpace(propertyCode)) { continue; } if (string.IsNullOrWhiteSpace(text)) { text = BuildDefaultSyntheticPropertyName(propertyCode); } bool flag = migratedRecords[num2].HasManualIdlePoint; Vector3 manualIdlePointPosition = migratedRecords[num2].ManualIdlePointPosition; float manualIdlePointYaw = migratedRecords[num2].ManualIdlePointYaw; if (!flag) { for (int l = 0; l < list.Count; l++) { SyntheticGridRecord syntheticGridRecord = migratedRecords[list[l]]; if (syntheticGridRecord != null && syntheticGridRecord.HasManualIdlePoint) { flag = true; manualIdlePointPosition = syntheticGridRecord.ManualIdlePointPosition; manualIdlePointYaw = syntheticGridRecord.ManualIdlePointYaw; break; } } } int num3 = 0; for (int m = 0; m < list.Count; m++) { int index = list[m]; SyntheticGridRecord syntheticGridRecord2 = migratedRecords[index]; if (syntheticGridRecord2 == null) { continue; } bool flag2 = false; if (!string.Equals(syntheticGridRecord2.PropertyCode, propertyCode, StringComparison.Ordinal)) { syntheticGridRecord2.PropertyCode = propertyCode; flag2 = true; } if (!string.Equals(syntheticGridRecord2.PropertyName, text, StringComparison.Ordinal)) { syntheticGridRecord2.PropertyName = text; flag2 = true; } if (syntheticGridRecord2.HasManualIdlePoint != flag) { syntheticGridRecord2.HasManualIdlePoint = flag; flag2 = true; } if (flag) { if (syntheticGridRecord2.ManualIdlePointPosition != manualIdlePointPosition) { syntheticGridRecord2.ManualIdlePointPosition = manualIdlePointPosition; flag2 = true; } if (!Mathf.Approximately(syntheticGridRecord2.ManualIdlePointYaw, manualIdlePointYaw)) { syntheticGridRecord2.ManualIdlePointYaw = manualIdlePointYaw; flag2 = true; } } if (flag2) { num3++; } } if (num3 > 0) { result = true; mergedPropertiesCount++; mergedRecordCount += num3; } } return result; } public static void RestoreFromSave(IReadOnlyList records) { //IL_009f: 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) EnsureRoot(); ClearExistingSyntheticObjects(); Grids.Clear(); ManualIdlePointsByPropertyCode.Clear(); if (records == null || records.Count == 0) { return; } Dictionary dictionary = new Dictionary(StringComparer.Ordinal); for (int i = 0; i < records.Count; i++) { SyntheticGridRecord syntheticGridRecord = records[i]; if (syntheticGridRecord != null && !string.IsNullOrWhiteSpace(syntheticGridRecord.PropertyCode) && !string.IsNullOrWhiteSpace(syntheticGridRecord.GridGuid)) { bool flag = false; if (!dictionary.TryGetValue(syntheticGridRecord.PropertyCode, out var value)) { value = CreateSyntheticProperty(syntheticGridRecord.Origin, syntheticGridRecord.PropertyCode, syntheticGridRecord.PropertyName); dictionary[syntheticGridRecord.PropertyCode] = value; } else if (IsDefaultSyntheticPropertyName(value.PropertyName) && !IsDefaultSyntheticPropertyName(syntheticGridRecord.PropertyName)) { SetSyntheticPropertyDisplayName(value, syntheticGridRecord.PropertyName); RenameGridObjectsForProperty(value, value.PropertyName); } SyntheticGridInfo syntheticGridInfo = CreateSyntheticGridForProperty(value, syntheticGridRecord.Origin, syntheticGridRecord.PropertyCode, syntheticGridRecord.GridGuid); syntheticGridInfo.MinX = syntheticGridRecord.MinX; syntheticGridInfo.MaxX = syntheticGridRecord.MaxX; syntheticGridInfo.MinY = syntheticGridRecord.MinY; syntheticGridInfo.MaxY = syntheticGridRecord.MaxY; syntheticGridInfo.BoundsInitialized = true; EnsureTilesForBounds(syntheticGridInfo, syntheticGridRecord.MinX, syntheticGridRecord.MaxX, syntheticGridRecord.MinY, syntheticGridRecord.MaxY, null); Grids.Add(syntheticGridInfo); } } foreach (Property value2 in dictionary.Values) { ConfigureSyntheticPropertyEmployeeAccess(value2); } } private static void EnsureRoot() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (!((Object)(object)_root != (Object)null)) { _tileLayer = LayerMask.NameToLayer("Tile"); _root = new GameObject("SidewalkEconomy_SyntheticRoot"); Object.DontDestroyOnLoad((Object)(object)_root); } } private static void ClearExistingSyntheticObjects() { if ((Object)(object)_root == (Object)null) { return; } for (int num = _root.transform.childCount - 1; num >= 0; num--) { Transform child = _root.transform.GetChild(num); if ((Object)(object)child != (Object)null) { Property component = ((Component)child).GetComponent(); if ((Object)(object)component != (Object)null) { Property.Properties.Remove(component); Property.OwnedProperties.Remove(component); Property.UnownedProperties.Remove(component); } Object.Destroy((Object)(object)((Component)child).gameObject); } } _previewInfo = null; PreviewTileObjects.Clear(); PreviewActiveCoords.Clear(); } private static SyntheticGridInfo CreateSyntheticGrid(Vector3 originFootprintPosition) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) string text = Guid.NewGuid().ToString(); string propertyCode = "synthetic_" + text; string propertyName = "Synthetic Property " + text.Substring(0, 8); return CreateSyntheticGrid(originFootprintPosition, propertyCode, propertyName, text); } private static SyntheticGridInfo CreateSyntheticGrid(Vector3 originFootprintPosition, string propertyCode, string propertyName, string gridGuid) { //IL_0001: 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) Property property = CreateSyntheticProperty(originFootprintPosition, propertyCode, propertyName); return CreateSyntheticGridForProperty(property, originFootprintPosition, propertyCode, gridGuid); } private static SyntheticGridInfo EnsurePreviewGrid(Vector3 originFootprintPosition) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_previewInfo?.Grid != (Object)null) { return _previewInfo; } GameObject val = new GameObject("SidewalkEconomy Placement Preview"); val.transform.SetParent(_root.transform, false); val.transform.position = originFootprintPosition; InjectedComponentHelper.AddInjectedComponent(val); Property val2 = val.AddComponent(); GameObject val3 = new GameObject("SidewalkEconomy Placement Preview_Container"); val3.transform.SetParent(val.transform, false); PropertyContentsContainer val4 = val3.AddComponent(); SetPropertyField(val2, "propertyCode", "sidewalkeconomy_preview"); SetSyntheticPropertyDisplayName(val2, "SidewalkEconomy Placement Preview"); SetPropertyAutoValue(val2, "IsOwned", true); SetPropertyAutoValue(val2, "AmbientTemperature", 20f); SetPropertyField(val2, "ContentCullingEnabled", false); val2.EmployeeCapacity = 0; val2.IsContentCulled = false; val2.Container = val4; val4.SetProperty(val2); _previewInfo = CreateSyntheticGridForProperty(val2, originFootprintPosition, "sidewalkeconomy_preview", "00000000-0000-0000-0000-000000000001"); val.SetActive(false); return _previewInfo; } private static Property CreateSyntheticProperty(Vector3 originFootprintPosition, string propertyCode, string propertyName) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown string text = (string.IsNullOrWhiteSpace(propertyName) ? BuildDefaultSyntheticPropertyName(propertyCode) : propertyName); GameObject val = new GameObject(text); val.transform.SetParent(_root.transform, false); val.transform.position = originFootprintPosition; InjectedComponentHelper.AddInjectedComponent(val); Property val2 = val.AddComponent(); GameObject val3 = new GameObject(text + "_Container"); val3.transform.SetParent(val.transform, false); PropertyContentsContainer val4 = val3.AddComponent(); SetPropertyField(val2, "propertyCode", propertyCode); SetSyntheticPropertyDisplayName(val2, text); SetPropertyAutoValue(val2, "IsOwned", true); SetPropertyAutoValue(val2, "AmbientTemperature", 20f); SetPropertyField(val2, "ContentCullingEnabled", false); val2.EmployeeCapacity = 0; val2.IsContentCulled = false; val2.Container = val4; val4.SetProperty(val2); EnsureWorldspaceUIContainer(val2, text); EnsureEmployeeAnchors(val2); RegisterSyntheticProperty(val2); return val2; } private static SyntheticGridInfo CreateSyntheticGridForProperty(Property property, Vector3 originFootprintPosition, string propertyCode, string gridGuid) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0076: 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) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) string text = (((Object)(object)property != (Object)null) ? property.PropertyName : propertyCode); Transform val = (((Object)(object)((property != null) ? property.Container : null) != (Object)null) ? ((Component)property.Container).transform : (((Object)(object)property != (Object)null) ? ((Component)property).transform : _root.transform)); GameObject val2 = new GameObject(text + "_Grid"); val2.transform.SetParent(val, false); val2.transform.position = originFootprintPosition; val2.transform.rotation = Quaternion.identity; InjectedComponentHelper.AddInjectedComponent(val2); Grid grid = val2.AddComponent(); SyntheticGridInfo syntheticGridInfo = new SyntheticGridInfo { Property = property, Grid = grid, PropertyCode = propertyCode, GridGuid = gridGuid, Origin = originFootprintPosition }; SetGridParentProperty(grid, property); InitializeGridCollections(syntheticGridInfo); SetGridGuid(grid, gridGuid); RegisterGrid(property, grid); return syntheticGridInfo; } private static SyntheticGridInfo FindGridNearPosition(Vector3 position, float maxDistance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) SyntheticGridInfo result = null; float num = maxDistance; for (int i = 0; i < Grids.Count; i++) { SyntheticGridInfo syntheticGridInfo = Grids[i]; if (syntheticGridInfo != null) { float num2 = DistanceToBoundsXZ(syntheticGridInfo, position); if (num2 <= num) { num = num2; result = syntheticGridInfo; } } } return result; } private static SyntheticGridInfo FindGridByProperty(Property property) { if ((Object)(object)property == (Object)null) { return null; } for (int i = 0; i < Grids.Count; i++) { SyntheticGridInfo syntheticGridInfo = Grids[i]; if (syntheticGridInfo != null && (Object)(object)syntheticGridInfo.Property == (Object)(object)property) { return syntheticGridInfo; } } return null; } private static void SetSyntheticPropertyDisplayName(Property property, string propertyName) { if (!((Object)(object)property == (Object)null)) { string text = (string.IsNullOrWhiteSpace(propertyName) ? property.PropertyCode : propertyName.Trim()); SetPropertyField(property, "propertyName", text); ((Object)((Component)property).gameObject).name = text; if ((Object)(object)property.Container != (Object)null) { ((Object)((Component)property.Container).gameObject).name = text + "_Container"; } if ((Object)(object)property.WorldspaceUIContainer != (Object)null) { ((Object)((Component)property.WorldspaceUIContainer).gameObject).name = text + " Worldspace UI Container"; } } } private static void RenameGridObjectsForProperty(Property property, string propertyName) { if ((Object)(object)property == (Object)null) { return; } int num = 1; for (int i = 0; i < Grids.Count; i++) { SyntheticGridInfo syntheticGridInfo = Grids[i]; if (!((Object)(object)syntheticGridInfo?.Property != (Object)(object)property) && !((Object)(object)syntheticGridInfo.Grid == (Object)null)) { string text = ((num == 1) ? string.Empty : $"_{num}"); ((Object)((Component)syntheticGridInfo.Grid).gameObject).name = propertyName + "_Grid" + text; num++; } } } private static SyntheticGridRecord CloneRecord(SyntheticGridRecord record) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (record == null) { return null; } return new SyntheticGridRecord { PropertyCode = record.PropertyCode, PropertyName = record.PropertyName, GridGuid = record.GridGuid, Origin = record.Origin, MinX = record.MinX, MaxX = record.MaxX, MinY = record.MinY, MaxY = record.MaxY, HasManualIdlePoint = record.HasManualIdlePoint, ManualIdlePointPosition = record.ManualIdlePointPosition, ManualIdlePointYaw = record.ManualIdlePointYaw }; } private static int SelectCanonicalRecordIndex(List cluster, List records) { if (cluster == null || records == null || cluster.Count == 0) { return -1; } for (int i = 0; i < cluster.Count; i++) { int num = cluster[i]; if (num >= 0 && num < records.Count && records[num] != null && !IsDefaultSyntheticPropertyName(records[num].PropertyName)) { return num; } } return cluster[0]; } private static bool IsDefaultSyntheticPropertyName(string propertyName) { return string.IsNullOrWhiteSpace(propertyName) || propertyName.StartsWith("Synthetic Property ", StringComparison.OrdinalIgnoreCase); } private static string BuildDefaultSyntheticPropertyName(string propertyCode) { if (!string.IsNullOrWhiteSpace(propertyCode)) { string text = propertyCode; if (text.StartsWith("synthetic_", StringComparison.OrdinalIgnoreCase) && text.Length > "synthetic_".Length) { text = text.Substring("synthetic_".Length); } string text2 = ((text.Length > 8) ? text.Substring(0, 8) : text); return "Synthetic Property " + text2; } return "Synthetic Property Unknown"; } private static float GetRecordBoundsDistanceXZ(SyntheticGridRecord a, SyntheticGridRecord b) { GetRecordBounds(a, out var minX, out var maxX, out var minZ, out var maxZ); GetRecordBounds(b, out var minX2, out var maxX2, out var minZ2, out var maxZ2); float num = Math.Max(minX - maxX2, minX2 - maxX); if (num < 0f) { num = 0f; } float num2 = Math.Max(minZ - maxZ2, minZ2 - maxZ); if (num2 < 0f) { num2 = 0f; } return Mathf.Sqrt(num * num + num2 * num2); } private static void GetRecordBounds(SyntheticGridRecord record, out float minX, out float maxX, out float minZ, out float maxZ) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (record == null) { minX = (maxX = (minZ = (maxZ = 0f))); return; } float val = record.Origin.x + (float)record.MinX * 0.5f; float val2 = record.Origin.x + (float)record.MaxX * 0.5f; float val3 = record.Origin.z + (float)record.MinY * 0.5f; float val4 = record.Origin.z + (float)record.MaxY * 0.5f; minX = Math.Min(val, val2); maxX = Math.Max(val, val2); minZ = Math.Min(val3, val4); maxZ = Math.Max(val3, val4); } private static bool ExtendGridBounds(SyntheticGridInfo info, Bounds placementBounds, Transform ignoredRoot) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) Vector3 min = ((Bounds)(ref placementBounds)).min; Vector3 max = ((Bounds)(ref placementBounds)).max; GetBoundsForWorld(info.Grid, min, max, out var minX, out var maxX, out var minY, out var maxY); minX--; maxX++; minY--; maxY++; if (!info.BoundsInitialized) { info.MinX = minX; info.MaxX = maxX; info.MinY = minY; info.MaxY = maxY; info.BoundsInitialized = true; EnsureTilesForBounds(info, info.MinX, info.MaxX, info.MinY, info.MaxY, ignoredRoot); return true; } int minX2 = info.MinX; int maxX2 = info.MaxX; int minY2 = info.MinY; int maxY2 = info.MaxY; int num = Math.Min(minX2, minX); int num2 = Math.Max(maxX2, maxX); int num3 = Math.Min(minY2, minY); int num4 = Math.Max(maxY2, maxY); if (num == minX2 && num2 == maxX2 && num3 == minY2 && num4 == maxY2) { return false; } info.MinX = num; info.MaxX = num2; info.MinY = num3; info.MaxY = num4; EnsureTilesForExpandedBounds(info, minX2, maxX2, minY2, maxY2, num, num2, num3, num4, ignoredRoot); return true; } private static Bounds GetPlacementGridBounds(GridItem buildable, Vector3 placementPosition) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (TryGetBuildableFootprintBounds(buildable, out var bounds)) { ((Bounds)(ref bounds)).Expand(new Vector3(1.5f, 0f, 1.5f)); return bounds; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(3f, 0f, 3f); return new Bounds(placementPosition, val); } private static bool TryGetBuildableFootprintBounds(GridItem buildable, out Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); bool initialized = false; if (((buildable != null) ? buildable.CoordinateFootprintTilePairs : null) != null) { for (int i = 0; i < buildable.CoordinateFootprintTilePairs.Count; i++) { FootprintTile footprintTile = buildable.CoordinateFootprintTilePairs[i].footprintTile; if (!((Object)(object)footprintTile == (Object)null)) { ExpandBounds(ref bounds, ref initialized, ((Component)footprintTile).transform.position); } } } if (!initialized && (Object)(object)((buildable != null) ? ((BuildableItem)buildable).BoundingCollider : null) != (Object)null) { bounds = ((Collider)((BuildableItem)buildable).BoundingCollider).bounds; initialized = true; } if (!initialized && (Object)(object)buildable != (Object)null) { bounds = new Bounds(((Component)buildable).transform.position, new Vector3(0.5f, 0.5f, 0.5f)); initialized = true; } return initialized; } private static void ExpandBounds(ref Bounds bounds, ref bool initialized, Vector3 point) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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) if (!initialized) { bounds = new Bounds(point, Vector3.zero); initialized = true; } else { ((Bounds)(ref bounds)).Encapsulate(point); } } private static void EnsureTilesForBounds(SyntheticGridInfo info, int minX, int maxX, int minY, int maxY, Transform ignoredRoot) { if (info == null) { return; } for (int i = minX; i <= maxX; i++) { for (int j = minY; j <= maxY; j++) { GridCoord gridCoord = new GridCoord(i, j); if (!info.TileCoords.Contains(gridCoord)) { CreateTile(info, i, j, gridCoord, ignoredRoot); } } } } private static void EnsureTilesForExpandedBounds(SyntheticGridInfo info, int oldMinX, int oldMaxX, int oldMinY, int oldMaxY, int expandedMinX, int expandedMaxX, int expandedMinY, int expandedMaxY, Transform ignoredRoot) { if (expandedMinX < oldMinX) { EnsureTilesForBounds(info, expandedMinX, oldMinX - 1, expandedMinY, expandedMaxY, ignoredRoot); } if (expandedMaxX > oldMaxX) { EnsureTilesForBounds(info, oldMaxX + 1, expandedMaxX, expandedMinY, expandedMaxY, ignoredRoot); } if (expandedMinY < oldMinY) { EnsureTilesForBounds(info, oldMinX, oldMaxX, expandedMinY, oldMinY - 1, ignoredRoot); } if (expandedMaxY > oldMaxY) { EnsureTilesForBounds(info, oldMinX, oldMaxX, oldMaxY + 1, expandedMaxY, ignoredRoot); } } private static void DestroyInactivePreviewTiles(SyntheticGridInfo info) { List list = new List(); foreach (KeyValuePair previewTileObject in PreviewTileObjects) { if (!PreviewActiveCoords.Contains(previewTileObject.Key)) { list.Add(previewTileObject.Key); GameObject value = previewTileObject.Value; if (!((Object)(object)value == (Object)null)) { Tile component = value.GetComponent(); RemoveTileFromGrid(info, previewTileObject.Key, component); Object.Destroy((Object)(object)value); } } } for (int i = 0; i < list.Count; i++) { PreviewTileObjects.Remove(list[i]); } } private static void RemovePreviewTileMarkers() { foreach (KeyValuePair previewTileObject in PreviewTileObjects) { GameObject value = previewTileObject.Value; if (!((Object)(object)value == (Object)null)) { SyntheticPreviewTileMarker injectedComponent = InjectedComponentHelper.GetInjectedComponent(value); if ((Object)(object)injectedComponent != (Object)null) { Object.Destroy((Object)(object)injectedComponent); } } } } private static void UpdateInfoBoundsFromTileCoords(SyntheticGridInfo info) { if (info == null || info.TileCoords == null || info.TileCoords.Count == 0) { return; } bool flag = false; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; foreach (GridCoord tileCoord in info.TileCoords) { if (!flag) { num = tileCoord.X; num2 = tileCoord.X; num3 = tileCoord.Y; num4 = tileCoord.Y; flag = true; } else { num = Math.Min(num, tileCoord.X); num2 = Math.Max(num2, tileCoord.X); num3 = Math.Min(num3, tileCoord.Y); num4 = Math.Max(num4, tileCoord.Y); } } info.MinX = num; info.MaxX = num2; info.MinY = num3; info.MaxY = num4; info.BoundsInitialized = true; } private static bool UpdatePreviewTiles(SyntheticGridInfo info, int minX, int maxX, int minY, int maxY, Transform ignoredRoot) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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) if ((Object)(object)info?.Grid == (Object)null) { return false; } bool result = false; PreviewActiveCoords.Clear(); for (int i = minX; i <= maxX; i++) { for (int j = minY; j <= maxY; j++) { GridCoord gridCoord = new GridCoord(i, j); PreviewActiveCoords.Add(gridCoord); if (!PreviewTileObjects.TryGetValue(gridCoord, out var value) || (Object)(object)value == (Object)null) { Tile val = CreateTile(info, i, j, gridCoord, ignoredRoot); value = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null); if ((Object)(object)value == (Object)null) { continue; } InjectedComponentHelper.AddInjectedComponent(value); PreviewTileObjects[gridCoord] = value; result = true; } Vector3 terrainAlignedTilePosition = GetTerrainAlignedTilePosition(info.Grid, i, j, ignoredRoot); Vector3 val2 = value.transform.position - terrainAlignedTilePosition; if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { value.transform.position = terrainAlignedTilePosition; result = true; } if (!value.activeSelf) { value.SetActive(true); result = true; } } } foreach (KeyValuePair previewTileObject in PreviewTileObjects) { if (!PreviewActiveCoords.Contains(previewTileObject.Key) && (Object)(object)previewTileObject.Value != (Object)null && previewTileObject.Value.activeSelf) { previewTileObject.Value.SetActive(false); result = true; } } return result; } private static Tile CreateTile(SyntheticGridInfo info, int x, int y, GridCoord coordKey, Transform ignoredRoot) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown GameObject val = new GameObject($"SyntheticTile_{x}_{y}"); val.transform.SetParent(((Component)info.Grid).transform, false); val.transform.position = GetTerrainAlignedTilePosition(info.Grid, x, y, ignoredRoot); val.layer = ((_tileLayer >= 0) ? _tileLayer : 0); InjectedComponentHelper.AddInjectedComponent(val); BoxCollider val2 = val.AddComponent(); val2.size = new Vector3(0.5f, 0.1f, 0.5f); val2.center = Vector3.zero; ((Collider)val2).isTrigger = true; Tile val3 = val.AddComponent(); val3.InitializePropertyTile(x, y, 1000f, info.Grid); LightExposureNode val4 = val.AddComponent(); val4.ambientExposure = 1f; val3.LightExposureNode = val4; float num = (((Object)(object)info.Property != (Object)null) ? info.Property.AmbientTemperature : 20f); SetFieldValue(val3, "_cosmeticTileTemperature", num); SetFieldValue(val3, "_tileTemperature", num); info.TileCoords.Add(coordKey); AddTileToGrid(info, new Coordinate(x, y), val3); return val3; } private static void AddTileToGrid(SyntheticGridInfo info, Coordinate coord, Tile tile) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown info.CoordinateToTile.Add(coord, tile); info.Tiles.Add(tile); CoordinateTilePair val = new CoordinateTilePair(); val.coord = coord; val.tile = tile; info.CoordinateTilePairs.Add(val); } private static void RemoveTileFromGrid(SyntheticGridInfo info, GridCoord coordKey, Tile tile) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (info == null) { return; } info.TileCoords?.Remove(coordKey); Coordinate val = new Coordinate(coordKey.X, coordKey.Y); info.CoordinateToTile?.Remove(val); if ((Object)(object)tile != (Object)null) { info.Tiles?.Remove(tile); } if (info.CoordinateTilePairs == null) { return; } for (int num = info.CoordinateTilePairs.Count - 1; num >= 0; num--) { if (((Object)info.CoordinateTilePairs[num].coord).Equals((Object)(object)val)) { info.CoordinateTilePairs.RemoveAt(num); } } } private static void RegisterSyntheticProperty(Property property) { if (!Property.Properties.Contains(property)) { Property.Properties.Add(property); } Property.OwnedProperties.Remove(property); Property.UnownedProperties.Remove(property); } private static void RegisterGrid(Property property, Grid grid) { if (property.Grids != null && !property.Grids.Contains(grid)) { property.Grids.Add(grid); } } private static void ConfigureSyntheticPropertyEmployeeAccess(Property property) { if (!((Object)(object)property == (Object)null)) { EnsureEmployeeAnchors(property); bool flag = true; DisableEmployeeHiring(property); } } private static void EnsureEmployeeAnchors(Property property) { if (!((Object)(object)property == (Object)null)) { if ((Object)(object)property.EmployeeContainer == (Object)null) { property.EmployeeContainer = EnsureNamedChild(((Component)property).transform, "Employees"); } if ((Object)(object)property.NPCSpawnPoint == (Object)null) { property.NPCSpawnPoint = EnsureNamedChild(property.EmployeeContainer, "NPCSpawnPoint"); } if ((Object)(object)property.SpawnPoint == (Object)null) { property.SpawnPoint = EnsureNamedChild(property.EmployeeContainer, "SpawnPoint"); } if ((Object)(object)property.InteriorSpawnPoint == (Object)null) { property.InteriorSpawnPoint = EnsureNamedChild(property.EmployeeContainer, "InteriorSpawnPoint"); } if (property.EmployeeIdlePoints == null) { property.EmployeeIdlePoints = Il2CppReferenceArray.op_Implicit(Array.Empty()); } } } private static Transform EnsureEmployeeIdlePointAnchor(Property property, Vector3 position, float yawDegrees) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)property == (Object)null) { return null; } Transform parent = (((Object)(object)property.EmployeeContainer != (Object)null) ? property.EmployeeContainer : ((Component)property).transform); Transform val = FindChildByName(parent, "IdlePoint_01"); if ((Object)(object)val == (Object)null) { val = EnsureNamedChild(parent, "IdlePoint_01"); } val.position = position; val.rotation = Quaternion.Euler(0f, NormalizeYaw(yawDegrees), 0f); return val; } private static bool TryGetManualIdleConfig(string propertyCode, out ManualIdlePointConfig manualConfig) { manualConfig = default(ManualIdlePointConfig); if (string.IsNullOrWhiteSpace(propertyCode)) { return false; } return ManualIdlePointsByPropertyCode.TryGetValue(propertyCode, out manualConfig); } private static bool TryProjectToValidNavMeshPoint(Vector3 candidate, out Vector3 navPoint) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryProjectToValidNavMeshPoint(candidate, 2.5f, out navPoint); } private static bool TryProjectToValidNavMeshPoint(Vector3 candidate, float sampleDistance, out Vector3 navPoint) { //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_001d: 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) //IL_003b: Unknown result type (might be due to invalid IL or missing references) navPoint = Vector3.zero; float num = ((sampleDistance > 0.05f) ? sampleDistance : 2.5f); NavMeshHit val = default(NavMeshHit); if (!NavMesh.SamplePosition(candidate, ref val, num, -1)) { return false; } navPoint = ((NavMeshHit)(ref val)).position; return true; } private static bool IsEmployeeSpaceOccupied(Vector3 point, Property property) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = point + Vector3.up * 0.2f; Vector3 val2 = val + Vector3.up * 1.8f; Il2CppReferenceArray val3 = Physics.OverlapCapsule(val, val2, 0.35f, -1, (QueryTriggerInteraction)1); Transform val4 = (((Object)(object)property != (Object)null) ? ((Component)property).transform : null); for (int i = 0; i < ((Il2CppArrayBase)(object)val3).Length; i++) { Collider val5 = ((Il2CppArrayBase)(object)val3)[i]; if (!((Object)(object)val5 == (Object)null) && val5.enabled && (!((Object)(object)val4 != (Object)null) || !((Component)val5).transform.IsChildOf(val4)) && !(val5 is TerrainCollider) && !((Object)(object)InjectedComponentHelper.GetInjectedComponentInParent((Component)(object)val5) != (Object)null) && !((Object)(object)((Component)val5).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val5).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val5).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val5).GetComponentInParent() == (Object)null)) { return true; } } return false; } private static void ApplyEmployeePoint(Property property, Vector3 position, float yawDegrees) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) float num = NormalizeYaw(yawDegrees); Quaternion rotation = Quaternion.Euler(0f, num, 0f); if ((Object)(object)property.NPCSpawnPoint != (Object)null) { property.NPCSpawnPoint.position = position; property.NPCSpawnPoint.rotation = rotation; } if ((Object)(object)property.SpawnPoint != (Object)null) { property.SpawnPoint.position = position; property.SpawnPoint.rotation = rotation; } if ((Object)(object)property.InteriorSpawnPoint != (Object)null) { property.InteriorSpawnPoint.position = position; property.InteriorSpawnPoint.rotation = rotation; } Transform val = EnsureEmployeeIdlePointAnchor(property, position, num); property.EmployeeIdlePoints = Il2CppReferenceArray.op_Implicit((Transform[])((!((Object)(object)val != (Object)null)) ? ((Array)Array.Empty()) : ((Array)new Transform[1] { val }))); property.EmployeeCapacity = ((Il2CppArrayBase)(object)property.EmployeeIdlePoints).Length; } private static void DisableEmployeeHiring(Property property) { if (!((Object)(object)property == (Object)null)) { property.EmployeeCapacity = 0; property.EmployeeIdlePoints = Il2CppReferenceArray.op_Implicit(Array.Empty()); } } private static Transform EnsureNamedChild(Transform parent, string childName) { //IL_0057: 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_0078: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)parent == (Object)null) { parent = (((Object)(object)_root != (Object)null) ? _root.transform : null); } if ((Object)(object)parent == (Object)null) { return null; } Transform val = FindChildByName(parent, childName); if ((Object)(object)val != (Object)null) { return val; } Transform transform = new GameObject(childName).transform; transform.SetParent(parent, false); transform.localPosition = Vector3.zero; transform.localRotation = Quaternion.identity; return transform; } private static Transform FindChildByName(Transform parent, string childName) { if ((Object)(object)parent == (Object)null || string.IsNullOrWhiteSpace(childName)) { return null; } for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if ((Object)(object)child != (Object)null && string.Equals(((Object)child).name, childName, StringComparison.Ordinal)) { return child; } } return null; } private static void InitializeGridCollections(SyntheticGridInfo info) { info.Tiles = new List(); info.CoordinateTilePairs = new List(); info.CoordinateToTile = new Dictionary(); info.TileCoords = new HashSet(); info.Grid.Tiles = info.Tiles; info.Grid.CoordinateTilePairs = info.CoordinateTilePairs; SetGridCoordinateMap(info.Grid, info.CoordinateToTile); } private static void SetGridGuid(Grid grid, string gridGuid) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (Guid.TryParse(gridGuid, out var result)) { Guid gUID = default(Guid); ((Guid)(ref gUID))..ctor(result.ToString()); grid.SetGUID(gUID); } } private static void EnsureWorldspaceUIContainer(Property property, string propertyName) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown GameObject val = new GameObject(propertyName + " Worldspace UI Container"); RectTransform val2 = val.AddComponent(); if (Singleton.InstanceExists) { ((Transform)val2).SetParent(((Component)Singleton.Instance.Canvas).transform, false); } else { ((Transform)val2).SetParent(((Component)property).transform, false); } ((Component)val2).gameObject.SetActive(false); SetPropertyAutoValue(property, "WorldspaceUIContainer", val2); } private static float DistanceToBoundsXZ(SyntheticGridInfo info, Vector3 position) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_004d: 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) //IL_0066: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (!info.BoundsInitialized) { return float.MaxValue; } Vector3 val = GridToWorld(info.Grid, info.MinX, info.MinY); Vector3 val2 = GridToWorld(info.Grid, info.MaxX, info.MaxY); float val3 = Math.Max(val.x - position.x, 0f); val3 = Math.Max(val3, position.x - val2.x); float val4 = Math.Max(val.z - position.z, 0f); val4 = Math.Max(val4, position.z - val2.z); return Mathf.Sqrt(val3 * val3 + val4 * val4); } private static void GetBoundsForWorld(Grid grid, Vector3 minWorld, Vector3 maxWorld, out int minX, out int maxX, out int minY, out int maxY) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)grid).transform.InverseTransformPoint(minWorld); Vector3 val2 = ((Component)grid).transform.InverseTransformPoint(maxWorld); minX = Mathf.FloorToInt(val.x / 0.5f); maxX = Mathf.CeilToInt(val2.x / 0.5f); minY = Mathf.FloorToInt(val.z / 0.5f); maxY = Mathf.CeilToInt(val2.z / 0.5f); } private static Vector3 GridToWorld(Grid grid, int x, int y) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) return ((Component)grid).transform.TransformPoint(new Vector3((float)x * 0.5f, 0f, (float)y * 0.5f)); } private static Vector3 GetTerrainAlignedTilePosition(Grid grid, int x, int y, Transform ignoredRoot) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0030: 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) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) Vector3 val = GridToWorld(grid, x, y); RaycastHit groundHit; return (Vector3)(TrySampleGround(val, ignoredRoot, out groundHit) ? new Vector3(val.x, ((RaycastHit)(ref groundHit)).point.y + 0.02f, val.z) : val); } private static bool TrySampleGround(Vector3 position, Transform ignoredRoot, out RaycastHit groundHit) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (TrySampleColliderGround(position, ignoredRoot, out groundHit)) { return true; } return TrySampleTerrain(position, out groundHit); } private static bool TrySampleColliderGround(Vector3 position, Transform ignoredRoot, out RaycastHit groundHit) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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) //IL_0091: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(position.x, position.y + 75f, position.z); int num = Physics.RaycastNonAlloc(val, Vector3.down, Il2CppStructArray.op_Implicit(GroundRaycastHits), 225f, -1, (QueryTriggerInteraction)1); groundHit = default(RaycastHit); float num2 = float.MaxValue; for (int i = 0; i < num; i++) { RaycastHit val2 = GroundRaycastHits[i]; if (IsGroundSampleCollider(((RaycastHit)(ref val2)).collider, ignoredRoot) && ((RaycastHit)(ref val2)).distance < num2) { num2 = ((RaycastHit)(ref val2)).distance; groundHit = val2; } } return num2 < float.MaxValue; } private static bool TrySampleTerrain(Vector3 position, out RaycastHit groundHit) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) groundHit = default(RaycastHit); Il2CppReferenceArray activeTerrains = Terrain.activeTerrains; if (activeTerrains == null || ((Il2CppArrayBase)(object)activeTerrains).Length == 0) { return false; } Terrain val = null; float num = float.MaxValue; float num2 = 0f; for (int i = 0; i < ((Il2CppArrayBase)(object)activeTerrains).Length; i++) { Terrain val2 = ((Il2CppArrayBase)(object)activeTerrains)[i]; TerrainData val3 = (((Object)(object)val2 != (Object)null) ? val2.terrainData : null); if ((Object)(object)val3 == (Object)null) { continue; } Vector3 position2 = ((Component)val2).transform.position; Vector3 size = val3.size; if (!(position.x < position2.x) && !(position.x > position2.x + size.x) && !(position.z < position2.z) && !(position.z > position2.z + size.z)) { float num3 = val2.SampleHeight(position) + position2.y; float num4 = Mathf.Abs(position.y - num3); if (num4 < num) { val = val2; num = num4; num2 = num3; } } } if ((Object)(object)val == (Object)null) { return false; } Vector3 val4 = position - ((Component)val).transform.position; Vector3 size2 = val.terrainData.size; float num5 = Mathf.Clamp01(val4.x / size2.x); float num6 = Mathf.Clamp01(val4.z / size2.z); ((RaycastHit)(ref groundHit)).point = new Vector3(position.x, num2, position.z); ((RaycastHit)(ref groundHit)).normal = val.terrainData.GetInterpolatedNormal(num5, num6); return true; } private static bool IsGroundSampleCollider(Collider collider, Transform ignoredRoot) { if ((Object)(object)collider == (Object)null || !collider.enabled) { return false; } if ((Object)(object)ignoredRoot != (Object)null && ((Component)collider).transform.IsChildOf(ignoredRoot)) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } if ((Object)(object)InjectedComponentHelper.GetInjectedComponentInParent((Component)(object)collider) != (Object)null) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } return true; } private static float NormalizeYaw(float yawDegrees) { float num = yawDegrees % 360f; if (num < 0f) { num += 360f; } return num; } private static void SetGridParentProperty(Grid grid, Property property) { SetFieldValue(grid, "_parentProperty", property); } private static void SetGridCoordinateMap(Grid grid, object map) { SetFieldValue(grid, "_coordinateToTile", map); } private static void SetPropertyField(Property property, string fieldName, object value) { SetFieldValue(property, fieldName, value); } private static void SetPropertyAutoValue(Property property, string propertyName, object value) { SetPropertyValue(property, propertyName, value); } private static void SetFieldValue(object target, string fieldName, object value) { SetMemberValue(target, fieldName, value); } private static void SetPropertyValue(object target, string propertyName, object value) { SetMemberValue(target, propertyName, value); } private static void SetMemberValue(object target, string memberName, object value) { if (target == null) { return; } Type type = target.GetType(); PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(target, value); return; } FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(target, value); } else { type.GetField("<" + memberName + ">k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(target, value); } } private static void SyncSavedRecords() { SyntheticGridSaveable.Instance?.SetRecords(BuildRecords()); } private static List BuildRecords() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) List list = new List(); for (int i = 0; i < Grids.Count; i++) { SyntheticGridInfo syntheticGridInfo = Grids[i]; if (syntheticGridInfo != null && syntheticGridInfo.BoundsInitialized && HasPlacedBuildables(syntheticGridInfo)) { bool flag = ManualIdlePointsByPropertyCode.TryGetValue(syntheticGridInfo.PropertyCode, out var value); bool flag2 = true; flag = false; list.Add(new SyntheticGridRecord { PropertyCode = syntheticGridInfo.PropertyCode, PropertyName = (((Object)(object)syntheticGridInfo.Property != (Object)null) ? syntheticGridInfo.Property.PropertyName : syntheticGridInfo.PropertyCode), GridGuid = syntheticGridInfo.GridGuid, Origin = syntheticGridInfo.Origin, MinX = syntheticGridInfo.MinX, MaxX = syntheticGridInfo.MaxX, MinY = syntheticGridInfo.MinY, MaxY = syntheticGridInfo.MaxY, HasManualIdlePoint = flag, ManualIdlePointPosition = (flag ? value.Position : Vector3.zero), ManualIdlePointYaw = (flag ? value.YawDegrees : 0f) }); } } return list; } private static bool HasPlacedBuildables(SyntheticGridInfo info) { object obj; if (info == null) { obj = null; } else { Property property = info.Property; obj = ((property != null) ? property.BuildableItems : null); } List val = (List)obj; if (val == null) { return false; } foreach (BuildableItem item in val.AsEnumerable()) { if ((Object)(object)item != (Object)null) { return true; } } return false; } } internal sealed class SyntheticPropertyMarker : MonoBehaviour { } internal sealed class SyntheticGridMarker : MonoBehaviour { } internal sealed class SyntheticTileMarker : MonoBehaviour { } internal sealed class SyntheticPreviewTileMarker : MonoBehaviour { } public static class TentOwnershipManager { public static bool IsTentOwned() { return TentOwnershipSaveable.Instance?.IsTentOwned ?? false; } public static bool IsQuestCompleted() { return TentOwnershipSaveable.Instance?.IsQuestCompleted ?? false; } public static bool IsNPCRelocated() { return TentOwnershipSaveable.Instance?.IsNPCRelocated ?? false; } public static void SetTentOwned(bool owned) { TentOwnershipSaveable.Instance?.SetTentOwned(owned); } public static void SetQuestCompleted(bool completed) { TentOwnershipSaveable.Instance?.SetQuestCompleted(completed); } public static void SetNPCRelocated(bool relocated) { TentOwnershipSaveable.Instance?.SetNPCRelocated(relocated); } public static string GetInteractionBlockedMessage() { return "This tent belongs to someone..."; } } public static class Il2CppListExtensions { public static IEnumerable AsEnumerable(this List list) { return list ?? new List(); } public static List ToIl2CppList(this IEnumerable source) { List val = new List(); foreach (T item in source) { val.Add(item); } return val; } public static List ConvertToList(List il2CppList) { List list = new List(); T[] collection = Il2CppArrayBase.op_Implicit(il2CppList.ToArray()); list.AddRange(collection); return list; } public static IEnumerable AsEnumerable(this List list) { IEnumerable result; if (list != null) { result = ((IEnumerable)list._items).Take(list._size); } else { IEnumerable enumerable = Array.Empty(); result = enumerable; } return result; } } public static class Utils { [CompilerGenerated] private sealed class d__5 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__5(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; break; case 1: <>1__state = -1; break; } if (!InstanceFinder.IsServer && !InstanceFinder.IsClient) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); 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__7 : IEnumerator, IEnumerator, IDisposable where T : notnull, NetworkSingleton { private int <>1__state; private object <>2__current; public IEnumerator coroutine; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__7(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; goto IL_0044; case 1: <>1__state = -1; goto IL_0044; case 2: { <>1__state = -1; return false; } IL_0044: if (!NetworkSingleton.InstanceExists) { <>2__current = null; <>1__state = 1; return true; } <>2__current = coroutine; <>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__6 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public object obj; public float timeout; public Action onTimeout; public Action onFinish; private float 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(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; 5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (obj == null) { if (!float.IsNaN(timeout) && Time.time - 5__1 > timeout) { onTimeout?.Invoke(); return false; } <>2__current = null; <>1__state = 1; return true; } onFinish?.Invoke(); 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__4 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__4(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; break; case 1: <>1__state = -1; break; } if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); 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 static T FindObjectByName(string objectName) where T : Object { try { foreach (T item in Resources.FindObjectsOfTypeAll()) { if (((Object)item).name != objectName) { continue; } ModLogger.Debug($"Found {typeof(T).Name} '{objectName}' directly in loaded objects"); return item; } return default(T); } catch (Exception ex) { ModLogger.Error($"Error finding {typeof(T).Name} '{objectName}': {ex.Message}"); return default(T); } } public static List GetAllComponentsInChildrenRecursive(GameObject obj) where T : Component { List list = new List(); if ((Object)(object)obj == (Object)null) { return list; } T[] array = Il2CppArrayBase.op_Implicit(obj.GetComponents()); if (array.Length != 0) { list.AddRange(array); } for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); list.AddRange(GetAllComponentsInChildrenRecursive(((Component)child).gameObject)); } return list; } public static bool Is(object obj, out T result) where T : Object { Object val = (Object)((obj is Object) ? obj : null); if (val != null) { Type val2 = Il2CppType.Of(); Type il2CppType = val.GetIl2CppType(); if (val2.IsAssignableFrom(il2CppType)) { result = ((Il2CppObjectBase)val).TryCast(); return result != null; } } result = default(T); return false; } public static List GetAllStorableItemDefinitions() { List list = Il2CppListExtensions.ConvertToList(Singleton.Instance.ItemRegistry); List list2 = new List(); foreach (ItemRegister item in list) { if (Utils.Is((object)item.Definition, out StorableItemDefinition result)) { list2.Add(result); } else { ModLogger.Warn("Definition " + ((object)item.Definition)?.GetType().FullName + " is not a StorableItemDefinition"); } } return list2.ToList(); } [IteratorStateMachine(typeof(d__4))] public static IEnumerator WaitForPlayer(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__4(0) { routine = routine }; } [IteratorStateMachine(typeof(d__5))] public static IEnumerator WaitForNetwork(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__5(0) { routine = routine }; } [IteratorStateMachine(typeof(d__6))] public static IEnumerator WaitForNotNull(object? obj, float timeout = float.NaN, Action onTimeout = null, Action onFinish = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(0) { obj = obj, timeout = timeout, onTimeout = onTimeout, onFinish = onFinish }; } [IteratorStateMachine(typeof(d__7<>))] public static IEnumerator WaitForNetworkSingleton(IEnumerator coroutine) where T : NetworkSingleton { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(0) { coroutine = coroutine }; } } public static class WorldSpawnManager { [CompilerGenerated] private sealed class d__7 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GameObject instance; public Vector3 targetPosition; private Il2CppArrayBase 5__1; private Il2CppArrayBase 5__2; private Il2CppArrayBase 5__3; private string 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__2 = null; 5__3 = null; 5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)instance == (Object)null) { ModLogger.Warn("Spawn confirmation failed - instance destroyed"); return false; } instance.transform.position = targetPosition; instance.SetActive(true); ForceEnableRenderers(instance); 5__1 = instance.GetComponentsInChildren(true); 5__2 = instance.GetComponentsInChildren(true); 5__3 = instance.GetComponentsInChildren(true); 5__4 = ((5__1.Length > 0) ? $"bounds={5__1[0].bounds}" : "bounds=none"); ModLogger.Debug($"Spawn confirm: {((Object)instance).name} pos={instance.transform.position} active={instance.activeInHierarchy} renderers={5__1.Length} meshes={5__2.Length} skinned={5__3.Length} {5__4}"); 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(); } } private static bool _spawned; public static void SpawnInitialShelters(GameObject sleepingBagPrefab, GameObject tentPrefab) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (name != "Main") { ModLogger.Debug("World spawn skipped - active scene is '" + name + "'"); return; } if ((Object)(object)sleepingBagPrefab == (Object)null) { ModLogger.Warn("Sleeping bag prefab missing - world spawn skipped"); return; } ModLogger.Info("Spawning initial sleeping bag..."); bool value = (_spawned = SpawnIfMissing("SidewalkEconomy_SleepingBag_Spawn", sleepingBagPrefab, Constants.WorldSpawns.SLEEPING_BAG_POSITION, Constants.WorldSpawns.SLEEPING_BAG_ROTATION_EULER)); ModLogger.Debug($"Spawn results - sleeping bag: {value}"); ModLogger.Info("Tent will spawn when player reaches Peddler rank or higher"); } public static bool SpawnTent(GameObject tentPrefab) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (name != "Main") { ModLogger.Debug("Tent spawn skipped - active scene is '" + name + "'"); return false; } if ((Object)(object)tentPrefab == (Object)null) { ModLogger.Warn("Tent prefab missing - tent spawn skipped"); return false; } ModLogger.Info("Spawning tent..."); bool flag = SpawnIfMissing("SidewalkEconomy_Tent_Spawn", tentPrefab, Constants.WorldSpawns.TENT_POSITION, Constants.WorldSpawns.TENT_ROTATION_EULER); ModLogger.Debug($"Tent spawn result: {flag}"); return flag; } private static bool SpawnIfMissing(string name, GameObject prefab, Vector3 position, Vector3? rotationEuler) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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) GameObject val = GameObject.Find(name); if ((Object)(object)val != (Object)null) { ApplySpawnTransform(val, prefab, position, rotationEuler); val.SetActive(true); ForceEnableRenderers(val); ShaderUtils.FixShadersOnGameObject(val); ModLogger.Debug("Spawn corrected - already present: " + name); return true; } GameObject val2 = Object.Instantiate(prefab, position, prefab.transform.rotation); ((Object)val2).name = name; ApplySpawnTransform(val2, prefab, position, rotationEuler); SetLayerRecursive(val2, 0); val2.SetActive(true); ForceEnableRenderers(val2); ShaderUtils.FixShadersOnGameObject(val2); ModLogger.Debug($"Spawned {name} at {position} (active: {val2.activeInHierarchy}, scale: {val2.transform.localScale})"); MelonCoroutines.Start(ConfirmSpawn(val2, position)); return true; } private static void ApplySpawnTransform(GameObject instance, GameObject prefab, Vector3 position, Vector3? rotationEuler) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) instance.transform.position = position; instance.transform.localScale = prefab.transform.localScale; Quaternion rotation = prefab.transform.rotation; if (rotationEuler.HasValue) { rotation = Quaternion.Euler(((Quaternion)(ref rotation)).eulerAngles + rotationEuler.Value); } instance.transform.rotation = rotation; } private static void ForceEnableRenderers(GameObject instance) { Il2CppArrayBase componentsInChildren = instance.GetComponentsInChildren(true); foreach (Renderer item in componentsInChildren) { item.enabled = true; } } private static void SetLayerRecursive(GameObject root, int layer) { if (!((Object)(object)root == (Object)null)) { root.layer = layer; for (int i = 0; i < root.transform.childCount; i++) { SetLayerRecursive(((Component)root.transform.GetChild(i)).gameObject, layer); } } } [IteratorStateMachine(typeof(d__7))] private static IEnumerator ConfirmSpawn(GameObject instance, Vector3 targetPosition) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(0) { instance = instance, targetPosition = targetPosition }; } } } namespace SidewalkEconomy.HarmonyPatches { [HarmonyPatch(typeof(Input), "GetMouseButtonDown", new Type[] { typeof(int) })] internal static class BuildSecondaryClickDownFilterPatch { private static bool Prefix(int button, ref bool __result) { if (button != 1 || !ShouldFilterSecondaryClick()) { return true; } __result = false; return false; } private static bool ShouldFilterSecondaryClick() { if (!ModSettings.EnableOutsidePlacement) { return false; } if (!BuildModeRecovery.OwnsOutsidePlacementFlow()) { return false; } bool flag = Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); return !flag; } } [HarmonyPatch(typeof(Input), "GetMouseButton", new Type[] { typeof(int) })] internal static class BuildSecondaryClickHoldFilterPatch { private static bool Prefix(int button, ref bool __result) { if (button != 1 || !ShouldFilterSecondaryClick()) { return true; } __result = false; return false; } private static bool ShouldFilterSecondaryClick() { if (!ModSettings.EnableOutsidePlacement) { return false; } if (!BuildModeRecovery.OwnsOutsidePlacementFlow()) { return false; } bool flag = Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); return !flag; } } [HarmonyPatch(typeof(BuildUpdate_Grid), "CheckIntersections")] internal static class BuildUpdateGridCheckPatch { private const float OverlapBoundsInset = 0.01f; private const float BlockingPenetrationThreshold = 0.01f; private const float SupportSurfaceClearance = 0.25f; private const float SupportSurfacePadding = 0.05f; private const float SupportRaycastHeight = 2f; private const float SupportRaycastDepth = 4f; private const float MinSupportNormalY = 0.55f; private static readonly RaycastHit[] SupportRaycastHits = (RaycastHit[])(object)new RaycastHit[32]; private static readonly PropertyInfo ValidPositionProperty = AccessTools.Property(typeof(BuildUpdate_Grid), "_validPosition"); private static void Postfix(BuildUpdate_Grid __instance) { if (ModSettings.EnableOutsidePlacement && !((Object)(object)__instance == (Object)null)) { GridItem buildableItemClass = __instance.BuildableItemClass; if (!((Object)(object)buildableItemClass == (Object)null) && IsPlacementValid(__instance) && SyntheticGridManager.HasAnyTileIntersections(buildableItemClass) && HasBlockingWorldIntersection(buildableItemClass)) { SetPlacementValid(__instance, value: false); } } } private static bool HasBlockingWorldIntersection(GridItem buildable) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)buildable == (Object)null) { return false; } List placementColliders = GetPlacementColliders(buildable); for (int i = 0; i < placementColliders.Count; i++) { Collider val = placementColliders[i]; Collider[] potentialOverlaps = GetPotentialOverlaps(val); foreach (Collider val2 in potentialOverlaps) { if (IsBlockingCollider(buildable, val, val2) && CollidersPenetrate(val, val2)) { return true; } } } List placementBounds = GetPlacementBounds(buildable); for (int k = 0; k < placementBounds.Count; k++) { Bounds val3 = placementBounds[k]; Il2CppReferenceArray val4 = Physics.OverlapBox(((Bounds)(ref val3)).center, GetBoundsHalfExtents(val3), Quaternion.identity, -1, (QueryTriggerInteraction)1); for (int l = 0; l < ((Il2CppArrayBase)(object)val4).Length; l++) { Collider val5 = ((Il2CppArrayBase)(object)val4)[l]; if (IsBlockingCollider(buildable, null, val5, val3)) { Bounds bounds = val5.bounds; if (((Bounds)(ref bounds)).Intersects(val3)) { return true; } } } } return false; } private static List GetPlacementColliders(GridItem buildable) { List allComponentsInChildrenRecursive = Utils.GetAllComponentsInChildrenRecursive(((Component)buildable).gameObject); List list = new List(allComponentsInChildrenRecursive.Count); for (int i = 0; i < allComponentsInChildrenRecursive.Count; i++) { Collider val = allComponentsInChildrenRecursive[i]; if (!((Object)(object)val == (Object)null) && val.enabled && ((Component)val).gameObject.activeInHierarchy && !((Object)(object)((Component)val).GetComponentInParent() != (Object)null)) { list.Add(val); } } return list; } private static Collider[] GetPotentialOverlaps(Collider collider) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) BoxCollider val = (BoxCollider)(object)((collider is BoxCollider) ? collider : null); if (val != null) { Vector3 boxHalfExtents = GetBoxHalfExtents(val); Vector3 val2 = ((Component)val).transform.TransformPoint(val.center); return Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)Physics.OverlapBox(val2, boxHalfExtents, ((Component)val).transform.rotation, -1, (QueryTriggerInteraction)1)); } SphereCollider val3 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null); if (val3 != null) { float sphereRadius = GetSphereRadius(val3); Vector3 val4 = ((Component)val3).transform.TransformPoint(val3.center); return Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)Physics.OverlapSphere(val4, sphereRadius, -1, (QueryTriggerInteraction)1)); } CapsuleCollider val5 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null); if (val5 != null) { GetCapsuleGeometry(val5, out var point, out var point2, out var radius); return Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)Physics.OverlapCapsule(point, point2, radius, -1, (QueryTriggerInteraction)1)); } Bounds bounds = collider.bounds; Vector3 val6 = default(Vector3); ((Vector3)(ref val6))..ctor(Mathf.Max(((Bounds)(ref bounds)).extents.x - 0.01f, 0.01f), Mathf.Max(((Bounds)(ref bounds)).extents.y - 0.01f, 0.01f), Mathf.Max(((Bounds)(ref bounds)).extents.z - 0.01f, 0.01f)); return Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)Physics.OverlapBox(((Bounds)(ref bounds)).center, val6, Quaternion.identity, -1, (QueryTriggerInteraction)1)); } private static List GetPlacementBounds(GridItem buildable) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) List allComponentsInChildrenRecursive = Utils.GetAllComponentsInChildrenRecursive(((Component)buildable).gameObject); List list = new List(allComponentsInChildrenRecursive.Count); for (int i = 0; i < allComponentsInChildrenRecursive.Count; i++) { Renderer val = allComponentsInChildrenRecursive[i]; if (!((Object)(object)val == (Object)null) && val.enabled && ((Component)val).gameObject.activeInHierarchy && !((Object)(object)((Component)val).GetComponentInParent() != (Object)null)) { Bounds bounds = val.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 0f)) { list.Add(bounds); } } } if (list.Count == 0 && (Object)(object)((BuildableItem)buildable).BoundingCollider != (Object)null) { list.Add(((Collider)((BuildableItem)buildable).BoundingCollider).bounds); } return list; } private static Vector3 GetBoundsHalfExtents(Bounds bounds) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Mathf.Max(((Bounds)(ref bounds)).extents.x - 0.01f, 0.01f), Mathf.Max(((Bounds)(ref bounds)).extents.y - 0.01f, 0.01f), Mathf.Max(((Bounds)(ref bounds)).extents.z - 0.01f, 0.01f)); } private static Vector3 GetBoxHalfExtents(BoxCollider collider) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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) Vector3 lossyScale = ((Component)collider).transform.lossyScale; float num = Mathf.Max(Mathf.Abs(collider.size.x * lossyScale.x) * 0.5f - 0.01f, 0.01f); float num2 = Mathf.Max(Mathf.Abs(collider.size.y * lossyScale.y) * 0.5f - 0.01f, 0.01f); float num3 = Mathf.Max(Mathf.Abs(collider.size.z * lossyScale.z) * 0.5f - 0.01f, 0.01f); return new Vector3(num, num2, num3); } private static float GetSphereRadius(SphereCollider collider) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Vector3 lossyScale = ((Component)collider).transform.lossyScale; float num = Mathf.Max(new float[3] { Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z) }); return Mathf.Max(collider.radius * num - 0.01f, 0.01f); } private static void GetCapsuleGeometry(CapsuleCollider collider, out Vector3 point0, out Vector3 point1, out float radius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) Vector3 lossyScale = ((Component)collider).transform.lossyScale; Vector3 val = ((Component)collider).transform.TransformPoint(collider.center); Vector3 val2; float num; float num2; switch (collider.direction) { case 0: val2 = ((Component)collider).transform.right; num = Mathf.Abs(lossyScale.x); num2 = Mathf.Max(Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z)); break; case 2: val2 = ((Component)collider).transform.forward; num = Mathf.Abs(lossyScale.z); num2 = Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.y)); break; default: val2 = ((Component)collider).transform.up; num = Mathf.Abs(lossyScale.y); num2 = Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.z)); break; } radius = Mathf.Max(collider.radius * num2 - 0.01f, 0.01f); float num3 = Mathf.Max(collider.height * num * 0.5f - radius, 0f); Vector3 val3 = val2 * num3; point0 = val + val3; point1 = val - val3; } private static bool CollidersPenetrate(Collider selfCollider, Collider otherCollider) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)selfCollider == (Object)null || (Object)(object)otherCollider == (Object)null) { return false; } Vector3 val = default(Vector3); float num = default(float); if (Physics.ComputePenetration(selfCollider, ((Component)selfCollider).transform.position, ((Component)selfCollider).transform.rotation, otherCollider, ((Component)otherCollider).transform.position, ((Component)otherCollider).transform.rotation, ref val, ref num)) { return num > 0.01f; } int result; if (selfCollider is MeshCollider) { Bounds bounds = selfCollider.bounds; result = (((Bounds)(ref bounds)).Intersects(otherCollider.bounds) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } private static bool IsBlockingCollider(GridItem buildable, Collider selfCollider, Collider collider, Bounds? placementBounds = null) { if ((Object)(object)collider == (Object)null || !collider.enabled || (Object)(object)collider == (Object)(object)selfCollider) { return false; } if ((Object)(object)buildable != (Object)null && ((Component)collider).transform.IsChildOf(((Component)buildable).transform)) { return false; } if (collider is TerrainCollider) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } if ((Object)(object)InjectedComponentHelper.GetInjectedComponentInParent((Component)(object)collider) != (Object)null) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } if (IsPlacementSupportSurface(buildable, selfCollider, placementBounds, collider)) { return false; } return true; } private static bool IsPlacementSupportSurface(GridItem buildable, Collider selfCollider, Bounds? placementBounds, Collider collider) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)collider == (Object)null || (Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return false; } Bounds? val = placementBounds; Bounds val3; if (!val.HasValue) { if (selfCollider == null) { Bounds? obj; if (buildable == null) { obj = null; } else { BoxCollider boundingCollider = ((BuildableItem)buildable).BoundingCollider; obj = ((boundingCollider != null) ? new Bounds?(((Collider)boundingCollider).bounds) : null); } Bounds? val2 = obj; val3 = val2.GetValueOrDefault(); } else { val3 = selfCollider.bounds; } } else { val3 = val.GetValueOrDefault(); } Bounds val4 = val3; Vector3 size = ((Bounds)(ref val4)).size; if (((Vector3)(ref size)).sqrMagnitude <= 0f) { return false; } float placementSupportY = GetPlacementSupportY(buildable, val4); Bounds bounds = collider.bounds; if (OverlapsHorizontally(val4, bounds) && ((Bounds)(ref bounds)).max.y <= placementSupportY + 0.25f) { return true; } return HasSupportRayHit(collider, val4, placementSupportY); } private static float GetPlacementSupportY(GridItem buildable, Bounds bounds) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) FootprintTile val = ((buildable != null) ? buildable.OriginFootprint : null); return ((Object)(object)val != (Object)null) ? ((Component)val).transform.position.y : ((Bounds)(ref bounds)).min.y; } private static bool OverlapsHorizontally(Bounds placementBounds, Bounds colliderBounds) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) return ((Bounds)(ref placementBounds)).min.x <= ((Bounds)(ref colliderBounds)).max.x + 0.05f && ((Bounds)(ref placementBounds)).max.x >= ((Bounds)(ref colliderBounds)).min.x - 0.05f && ((Bounds)(ref placementBounds)).min.z <= ((Bounds)(ref colliderBounds)).max.z + 0.05f && ((Bounds)(ref placementBounds)).max.z >= ((Bounds)(ref colliderBounds)).min.z - 0.05f; } private static bool HasSupportRayHit(Collider candidate, Bounds bounds, float supportY) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) Vector3 min = ((Bounds)(ref bounds)).min; Vector3 max = ((Bounds)(ref bounds)).max; Vector3 center = ((Bounds)(ref bounds)).center; return SupportRayHitsCandidate(candidate, center.x, center.z, supportY) || SupportRayHitsCandidate(candidate, min.x + 0.05f, min.z + 0.05f, supportY) || SupportRayHitsCandidate(candidate, min.x + 0.05f, max.z - 0.05f, supportY) || SupportRayHitsCandidate(candidate, max.x - 0.05f, min.z + 0.05f, supportY) || SupportRayHitsCandidate(candidate, max.x - 0.05f, max.z - 0.05f, supportY); } private static bool SupportRayHitsCandidate(Collider candidate, float x, float z, float supportY) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(x, supportY + 2f, z); int num = Physics.RaycastNonAlloc(val, Vector3.down, Il2CppStructArray.op_Implicit(SupportRaycastHits), 6f, -1, (QueryTriggerInteraction)1); for (int i = 0; i < num; i++) { RaycastHit val2 = SupportRaycastHits[i]; if (!((Object)(object)((RaycastHit)(ref val2)).collider != (Object)(object)candidate) && !(((RaycastHit)(ref val2)).normal.y < 0.55f) && ((RaycastHit)(ref val2)).point.y <= supportY + 0.25f) { return true; } } return false; } private static bool IsPlacementValid(BuildUpdate_Grid buildUpdate) { if ((Object)(object)buildUpdate == (Object)null) { return false; } if (ValidPositionProperty?.GetValue(buildUpdate, null) is bool result) { return result; } if (((object)buildUpdate).GetType().GetProperty("_validPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(buildUpdate, null) is bool result2) { return result2; } object obj = ((object)buildUpdate).GetType().GetField("_validPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(buildUpdate); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static void SetPlacementValid(BuildUpdate_Grid buildUpdate, bool value) { if ((Object)(object)buildUpdate == (Object)null) { return; } PropertyInfo validPositionProperty = ValidPositionProperty; if ((object)validPositionProperty != null && validPositionProperty.CanWrite) { ValidPositionProperty.SetValue(buildUpdate, value, null); return; } PropertyInfo property = ((object)buildUpdate).GetType().GetProperty("_validPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)property != null && property.CanWrite) { property.SetValue(buildUpdate, value, null); } else { ((object)buildUpdate).GetType().GetField("_validPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(buildUpdate, value); } } } [HarmonyPatch(typeof(BuildUpdate_Grid), "Update")] internal static class BuildUpdateGridPlacePatch { private const float PreviewPrimeMoveThresholdSqr = 0.0625f; private const float PreviewPrimeRetryInterval = 0.15f; private static readonly PropertyInfo ValidPositionProperty = AccessTools.Property(typeof(BuildUpdate_Grid), "_validPosition"); private static readonly MethodInfo CheckIntersectionsMethod = AccessTools.Method(typeof(BuildUpdate_Grid), "CheckIntersections", (Type[])null, (Type[])null); private static readonly MethodInfo PlaceMethod = AccessTools.Method(typeof(BuildUpdate_Grid), "Place", (Type[])null, (Type[])null); private static BuildUpdate_Grid _lastPrimeBuildUpdate; private static GridItem _lastPrimeBuildable; private static Vector3 _lastPrimePosition; private static float _nextPrimeTime; private static void Prefix(BuildUpdate_Grid __instance) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (!ModSettings.EnableOutsidePlacement || (Object)(object)__instance == (Object)null) { return; } if (!NetworkSingleton.InstanceExists || (Object)(object)NetworkSingleton.Instance == (Object)null || !NetworkSingleton.Instance.isBuilding) { SyntheticGridManager.HidePreviewGrid(); } else { if (!GameInput.GetButtonDown((ButtonCode)0)) { return; } GridItem buildableItemClass = __instance.BuildableItemClass; if (!((Object)(object)buildableItemClass == (Object)null) && IsPlacementValid(__instance) && SyntheticGridManager.HasPreviewTileIntersections(buildableItemClass) && !((Object)(object)Player.Local == (Object)null) && !Player.Local.IsRagdolled && !Player.Local.IsArrested) { try { GetPlacementContext(__instance, buildableItemClass, out var placementPosition, out var originPosition); SyntheticGridManager.PromotePreviewGridForPlacement(placementPosition, originPosition, buildableItemClass); Physics.SyncTransforms(); buildableItemClass.CalculateFootprintTileIntersections(); CheckIntersectionsMethod?.Invoke(__instance, null); } catch (Exception value) { ModLogger.Warn($"Build preview commit failed: {value}"); } } } } private static void Postfix(BuildUpdate_Grid __instance) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) if (!ModSettings.EnableOutsidePlacement) { SyntheticGridManager.HidePreviewGrid(); return; } if ((Object)(object)__instance == (Object)null) { SyntheticGridManager.HidePreviewGrid(); return; } if (GameInput.GetButtonDown((ButtonCode)1) && IsAltPressed() && NetworkSingleton.InstanceExists && (Object)(object)NetworkSingleton.Instance != (Object)null && NetworkSingleton.Instance.isBuilding) { BuildModeRecovery.TryExitBuildMode("alt+secondary click cancel", force: false); return; } if (!NetworkSingleton.InstanceExists || (Object)(object)NetworkSingleton.Instance == (Object)null || !NetworkSingleton.Instance.isBuilding) { SyntheticGridManager.HidePreviewGrid(); return; } GridItem buildableItemClass = __instance.BuildableItemClass; if ((Object)(object)buildableItemClass == (Object)null) { SyntheticGridManager.HidePreviewGrid(); return; } GetPlacementContext(__instance, buildableItemClass, out var placementPosition, out var originPosition); if (!IsPlacementValid(__instance)) { TryPrimeSyntheticGrid(__instance, buildableItemClass, placementPosition, originPosition); } BuildModeRecovery.ReportOutsidePlacementHeartbeat(); if (!GameInput.GetButtonDown((ButtonCode)0)) { return; } if ((Object)(object)Player.Local == (Object)null || Player.Local.IsRagdolled || Player.Local.IsArrested) { BuildModeRecovery.TryExitBuildMode("invalid player state during placement", force: true); } else { if (IsPlacementValid(__instance)) { return; } try { if (SyntheticGridManager.HasPreviewTileIntersections(buildableItemClass) ? SyntheticGridManager.PromotePreviewGridForPlacement(placementPosition, originPosition, buildableItemClass) : SyntheticGridManager.EnsureGridForPlacement(placementPosition, originPosition, buildableItemClass)) { Physics.SyncTransforms(); } buildableItemClass.CalculateFootprintTileIntersections(); CheckIntersectionsMethod?.Invoke(__instance, null); if (IsPlacementValid(__instance)) { PlaceMethod?.Invoke(__instance, null); } } catch (Exception value) { ModLogger.Warn($"Build placement recovery triggered after placement failure: {value}"); BuildModeRecovery.TryExitBuildMode("placement exception", force: true); } } } private static void GetPlacementContext(BuildUpdate_Grid buildUpdate, GridItem buildable, out Vector3 placementPosition, out Vector3 originPosition) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) GameObject val = ((buildUpdate != null) ? buildUpdate.GhostModel : null); placementPosition = (((Object)(object)val != (Object)null) ? val.transform.position : ((Component)buildable).transform.position); FootprintTile val2 = ((buildable != null) ? buildable.OriginFootprint : null); originPosition = (((Object)(object)val2 != (Object)null) ? ((Component)val2).transform.position : placementPosition); } private static bool IsAltPressed() { return Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); } private static void TryPrimeSyntheticGrid(BuildUpdate_Grid buildUpdate, GridItem buildable, Vector3 placementPosition, Vector3 originPosition) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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) try { if (ShouldPrimeSyntheticGrid(buildUpdate, buildable, placementPosition)) { if (SyntheticGridManager.EnsurePreviewGridForPlacement(placementPosition, originPosition, buildable)) { Physics.SyncTransforms(); } buildable.CalculateFootprintTileIntersections(); CheckIntersectionsMethod?.Invoke(buildUpdate, null); } } catch (Exception value) { ModLogger.Warn($"Build grid priming failed: {value}"); } } private static bool ShouldPrimeSyntheticGrid(BuildUpdate_Grid buildUpdate, GridItem buildable, Vector3 placementPosition) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)buildUpdate != (Object)(object)_lastPrimeBuildUpdate || (Object)(object)buildable != (Object)(object)_lastPrimeBuildable) { _lastPrimeBuildUpdate = buildUpdate; _lastPrimeBuildable = buildable; _lastPrimePosition = placementPosition; _nextPrimeTime = Time.unscaledTime + 0.15f; return true; } Vector3 val = placementPosition - _lastPrimePosition; bool flag = ((Vector3)(ref val)).sqrMagnitude >= 0.0625f; bool flag2 = Time.unscaledTime >= _nextPrimeTime; if (!flag && !flag2) { return false; } if (!flag && SyntheticGridManager.HasAnyTileIntersections(buildable)) { _nextPrimeTime = Time.unscaledTime + 0.15f; return false; } _lastPrimePosition = placementPosition; _nextPrimeTime = Time.unscaledTime + 0.15f; return true; } private static bool IsPlacementValid(BuildUpdate_Grid buildUpdate) { if ((Object)(object)buildUpdate == (Object)null) { return false; } if (ValidPositionProperty?.GetValue(buildUpdate, null) is bool result) { return result; } if (((object)buildUpdate).GetType().GetProperty("_validPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(buildUpdate, null) is bool result2) { return result2; } object obj = ((object)buildUpdate).GetType().GetField("_validPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(buildUpdate); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } [HarmonyPatch] internal static class GrowLightSafetyPatch { private static readonly MethodInfo ProceduralGridItemDestroyMethod = AccessTools.Method(typeof(ProceduralGridItem), "Destroy", (Type[])null, (Type[])null); [HarmonyPatch(typeof(GrowLight), "InitializeProceduralGridItem")] [HarmonyFinalizer] private static Exception InitializeProceduralGridItemFinalizer(GrowLight __instance, Exception __exception) { if (__exception == null) { return null; } if (!(__exception is NullReferenceException)) { return __exception; } try { ApplySafeLightStateAndSources(__instance); ModLogger.Warn("Recovered GrowLight initialization from missing procedural tile dependencies"); return null; } catch (Exception value) { ModLogger.Warn($"GrowLight initialization fallback failed: {value}"); return __exception; } } [HarmonyPatch(typeof(GrowLight), "Destroy")] [HarmonyFinalizer] private static Exception DestroyFinalizer(GrowLight __instance, Exception __exception) { if (__exception == null) { return null; } if (!(__exception is NullReferenceException)) { return __exception; } try { ProceduralGridItemDestroyMethod?.Invoke(__instance, null); ModLogger.Warn("Recovered GrowLight destroy from missing procedural tile dependencies"); return null; } catch (Exception value) { ModLogger.Warn($"GrowLight destroy fallback failed: {value}"); return __exception; } } private static void ApplySafeLightStateAndSources(GrowLight growLight) { if ((Object)(object)growLight == (Object)null || ((BuildableItem)growLight).isGhost) { return; } if ((Object)(object)growLight.usableLightSource != (Object)null) { growLight.usableLightSource.isEmitting = true; } if ((Object)(object)growLight.Light != (Object)null) { growLight.Light.isOn = true; } if ((Object)(object)growLight.usableLightSource == (Object)null || ((ProceduralGridItem)growLight).footprintTileMatches == null) { return; } for (int i = 0; i < ((ProceduralGridItem)growLight).footprintTileMatches.Count; i++) { ProceduralTile tile; try { tile = ((ProceduralGridItem)growLight).footprintTileMatches[i].tile; } catch { continue; } object obj2; if (tile == null) { obj2 = null; } else { FootprintTile matchedFootprintTile = tile.MatchedFootprintTile; if (matchedFootprintTile == null) { obj2 = null; } else { Tile matchedStandardTile = matchedFootprintTile.MatchedStandardTile; obj2 = ((matchedStandardTile != null) ? matchedStandardTile.LightExposureNode : null); } } LightExposureNode val = (LightExposureNode)obj2; if ((Object)(object)val != (Object)null) { val.AddSource(growLight.usableLightSource, 1f); } } } } [HarmonyPatch(typeof(Player))] internal static class PlayerBuildModeCleanupPatch { [HarmonyPostfix] [HarmonyPatch("OnDied")] private static void OnDiedPostfix(Player __instance) { TryCleanup(__instance, "player death"); } [HarmonyPostfix] [HarmonyPatch("OnRevived")] private static void OnRevivedPostfix(Player __instance) { TryCleanup(__instance, "player revive"); } private static void TryCleanup(Player player, string reason) { if (!((Object)(object)player == (Object)null) && !((Object)(object)Player.Local == (Object)null) && !((Object)(object)player != (Object)(object)Player.Local)) { BuildModeRecovery.TryExitBuildMode(reason, force: true); } } } [HarmonyPatch(typeof(StorageEntity))] public static class StorageEntityPatch { [HarmonyPrefix] [HarmonyPatch("SetStoredInstance")] public static bool SetStoredInstance_Prefix(StorageEntity __instance, NetworkConnection conn, int itemSlotIndex, ItemInstance instance) { if (__instance is TentStorageEntity) { if (itemSlotIndex >= 0 && itemSlotIndex < __instance.ItemSlots.Count) { __instance.ItemSlots[itemSlotIndex].SetStoredItem(instance, true); } return false; } return true; } [HarmonyPrefix] [HarmonyPatch("SetItemSlotQuantity")] public static bool SetItemSlotQuantity_Prefix(StorageEntity __instance, int itemSlotIndex, int quantity) { if (__instance is TentStorageEntity) { if (itemSlotIndex >= 0 && itemSlotIndex < __instance.ItemSlots.Count && __instance.ItemSlots[itemSlotIndex] != null) { __instance.ItemSlots[itemSlotIndex].SetQuantity(quantity, true); } return false; } return true; } [HarmonyPrefix] [HarmonyPatch("Open")] public static bool Open_Prefix(StorageEntity __instance) { TentStorageEntity tentStorageEntity = __instance as TentStorageEntity; if ((Object)(object)tentStorageEntity == (Object)null) { return true; } try { if (!tentStorageEntity.TryOpenLocalStorage()) { ModLogger.Warn("TentStorage: local open blocked"); } } catch (Exception ex) { ModLogger.Error("TentStorage: local open failed: " + ex.Message + "\n" + ex.StackTrace); } return false; } [HarmonyPrefix] [HarmonyPatch("Close")] public static bool Close_Prefix(StorageEntity __instance) { TentStorageEntity tentStorageEntity = __instance as TentStorageEntity; if ((Object)(object)tentStorageEntity == (Object)null) { return true; } try { tentStorageEntity.CloseLocalStorage(); } catch (Exception ex) { ModLogger.Error("TentStorage: local close failed: " + ex.Message + "\n" + ex.StackTrace); StorageMenu instance = Singleton.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.OpenedStorageEntity == (Object)(object)__instance) { instance.CloseMenu(); } } return false; } } internal static class SyntheticAwakePatch { [HarmonyPatch(typeof(Property), "Awake")] [HarmonyPrefix] private static bool PropertyAwakePrefix(Property __instance) { return (Object)(object)__instance == (Object)null || (Object)(object)InjectedComponentHelper.GetInjectedComponent((Component)(object)__instance) == (Object)null; } [HarmonyPatch(typeof(Grid), "Awake")] [HarmonyPrefix] private static bool GridAwakePrefix(Grid __instance) { return (Object)(object)__instance == (Object)null || (Object)(object)InjectedComponentHelper.GetInjectedComponent((Component)(object)__instance) == (Object)null; } [HarmonyPatch(typeof(Tile), "Awake")] [HarmonyPrefix] private static bool TileAwakePrefix(Tile __instance) { return (Object)(object)__instance == (Object)null || (Object)(object)InjectedComponentHelper.GetInjectedComponent((Component)(object)__instance) == (Object)null; } } internal static class SyntheticPropertyEmployeeCompatibilityPatch { [HarmonyPatch(typeof(Property), "GetUnassignedBeds")] [HarmonyPrefix] private static bool GetUnassignedBedsPrefix(Property __instance, ref List __result) { if ((Object)(object)__instance == (Object)null || (Object)(object)InjectedComponentHelper.GetInjectedComponent((Component)(object)__instance) == (Object)null) { return true; } __result = new List(); return false; } [HarmonyPatch(typeof(DialogueController_Fixer), "ModifyChoiceList")] [HarmonyPostfix] private static void FixerModifyChoiceListPostfix(string dialogueLabel, ref List existingChoices) { if (SyntheticGridManager.AreSyntheticEmployeesEnabled() || existingChoices == null) { return; } PropertyManager val = (Singleton.InstanceExists ? Singleton.Instance : null); for (int num = existingChoices.Count - 1; num >= 0; num--) { DialogueChoiceData val2 = existingChoices[num]; if (val2 != null && !string.IsNullOrWhiteSpace(val2.ChoiceLabel)) { Property property = (((Object)(object)val != (Object)null) ? val.GetProperty(val2.ChoiceLabel) : null); if (SyntheticGridManager.IsSyntheticProperty(property) || SyntheticGridManager.IsSyntheticPropertyIdentifier(val2.ChoiceLabel)) { existingChoices.RemoveAt(num); } } } } [HarmonyPatch(typeof(DialogueController_Fixer), "Confirm")] [HarmonyPrefix] private static bool ConfirmPrefix(DialogueController_Fixer __instance) { Property memberValue = GetMemberValue(__instance, new string[1] { "selectedProperty" }); if ((Object)(object)memberValue == (Object)null || (Object)(object)InjectedComponentHelper.GetInjectedComponent((Component)(object)memberValue) == (Object)null) { return true; } if (TryValidateSyntheticEmployeeHire(memberValue, requireServerAuthority: true, out var failureReason)) { return true; } string text = (string.IsNullOrWhiteSpace(failureReason) ? "Synthetic employee hiring is unavailable for this property." : failureReason); ModLogger.Warn("Blocked synthetic employee hire for '" + memberValue.PropertyName + "': " + text); NPC memberValue2 = GetMemberValue(__instance, new string[1] { "npc" }); if (memberValue2 != null && (Object)(object)memberValue2.DialogueHandler != (Object)null) { memberValue2.DialogueHandler.ShowWorldspaceDialogue(text, 5f); } return false; } [HarmonyPatch(typeof(EmployeeManager), "CreateNewEmployee")] [HarmonyPrefix] private static bool CreateNewEmployeePrefix(EmployeeManager __instance, Property property, EEmployeeType type) { //IL_011d: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)property == (Object)null || (Object)(object)InjectedComponentHelper.GetInjectedComponent((Component)(object)property) == (Object)null) { return true; } if (!TryValidateSyntheticEmployeeHire(property, requireServerAuthority: true, out var failureReason)) { ModLogger.Warn("Skipping synthetic employee create for '" + property.PropertyName + "': " + failureReason); return false; } bool flag = 0.67f > Random.Range(0f, 1f); if (NetworkSingleton.InstanceExists) { float value = NetworkSingleton.Instance.GetValue("LifetimeEmployeesRecruited"); NetworkSingleton.Instance.SetVariableValue("LifetimeEmployeesRecruited", (value + 1f).ToString(), true); } string text = default(string); string text2 = default(string); __instance.GenerateRandomName(flag, ref text, ref text2); string text3 = text.ToLower() + "_" + text2.ToLower(); int num = default(int); AvatarSettings val = default(AvatarSettings); __instance.GetRandomAppearance(flag, ref num, ref val); string text4 = Guid.NewGuid().ToString(); Vector3 val2 = (((Object)(object)property.NPCSpawnPoint != (Object)null) ? property.NPCSpawnPoint.position : ((Component)property).transform.position); Quaternion val3 = (((Object)(object)property.NPCSpawnPoint != (Object)null) ? property.NPCSpawnPoint.rotation : Quaternion.identity); Employee val4 = __instance.CreateEmployee_Server(property, type, text, text2, text3, flag, num, val2, val3, text4); if ((Object)(object)val4 == (Object)null) { ModLogger.Warn("Synthetic employee creation returned null for property '" + property.PropertyName + "'"); } return false; } private static bool TryValidateSyntheticEmployeeHire(Property property, bool requireServerAuthority, out string failureReason) { failureReason = string.Empty; if ((Object)(object)property == (Object)null) { failureReason = "Synthetic property was not found."; return false; } if (!SyntheticGridManager.AreSyntheticEmployeesEnabled()) { failureReason = "Employees are disabled on synthetic properties in this version."; return false; } if (requireServerAuthority && !InstanceFinder.IsServer) { failureReason = "Synthetic employee hiring must be performed by the host/server."; return false; } if (!SyntheticGridManager.EnsureEmployeeHiringConfigured(property, out failureReason)) { failureReason = (string.IsNullOrWhiteSpace(failureReason) ? "Synthetic property employee configuration is invalid." : failureReason); return false; } return true; } private static T GetMemberValue(object target, params string[] candidateNames) where T : class { if (target == null || candidateNames == null || candidateNames.Length == 0) { return null; } Type type = target.GetType(); foreach (string name in candidateNames) { if (type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(target, null) is T result) { return result; } if (type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(target) is T result2) { return result2; } } return null; } } } namespace SidewalkEconomy.Controllers { public sealed class SleepingBagController : MonoBehaviour { private void Awake() { SleepingSpotController sleepingSpotController = InjectedComponentHelper.GetInjectedComponent((Component)(object)this); if ((Object)(object)sleepingSpotController == (Object)null) { sleepingSpotController = InjectedComponentHelper.AddInjectedComponent(((Component)this).gameObject); } sleepingSpotController.Configure("Sleeping Bag", ((Component)this).transform); } } public sealed class SleepingSpotController : MonoBehaviour { private string _sleepDisplayName = "Sleeping Spot"; private Transform _sleepPosition; private InteractableObject _interactableObject; private NetworkObject _networkObject; private bool _isInitialized; public void Configure(string displayName, Transform sleepPosition = null) { if (!string.IsNullOrWhiteSpace(displayName)) { _sleepDisplayName = displayName; } if ((Object)(object)sleepPosition != (Object)null) { _sleepPosition = sleepPosition; } if (_isInitialized) { RefreshInteractable(); } } private void Awake() { Initialize(); } private void Initialize() { if (!_isInitialized) { _networkObject = ((Component)this).GetComponent(); if ((Object)(object)_networkObject == (Object)null) { _networkObject = ((Component)this).GetComponentInParent(); } if ((Object)(object)_sleepPosition == (Object)null) { _sleepPosition = ((Component)this).transform; } _interactableObject = ((Component)this).GetComponent(); if ((Object)(object)_interactableObject == (Object)null) { Component val = ((Component)this).gameObject.AddComponent(Il2CppType.Of()); _interactableObject = ((Il2CppObjectBase)val).Cast(); } _interactableObject.MaxInteractionRange = 5f; _interactableObject.SetInteractionType((EInteractionType)0); ((Behaviour)_interactableObject).enabled = true; RefreshInteractable(); _interactableObject.onHovered.AddListener(UnityAction.op_Implicit((Action)OnHovered)); _interactableObject.onInteractStart.AddListener(UnityAction.op_Implicit((Action)OnInteractStart)); _isInitialized = true; ModLogger.Debug("Initialized sleep interaction for " + _sleepDisplayName); } } private void RefreshInteractable() { if (!((Object)(object)_interactableObject == (Object)null)) { _interactableObject.SetMessage("Sleep"); _interactableObject.SetInteractableState((EInteractableState)0); } } private void OnHovered() { if (!((Object)(object)_interactableObject == (Object)null)) { if (SleepUtils.CanSleep(out var noSleepReason)) { _interactableObject.SetInteractableState((EInteractableState)0); _interactableObject.SetMessage("Sleep"); } else { _interactableObject.SetInteractableState((EInteractableState)1); _interactableObject.SetMessage(noSleepReason); } } } private void OnInteractStart() { if (!SleepUtils.CanSleep(out var noSleepReason)) { ModLogger.Debug(_sleepDisplayName + ": sleep blocked - " + noSleepReason); return; } Player local = Player.Local; if ((Object)(object)local == (Object)null) { ModLogger.Warn(_sleepDisplayName + ": player not found - cannot start sleep"); return; } local.CurrentBed = _networkObject; try { Singleton.Instance.SetIsOpen(true); } catch (Exception ex) { ModLogger.Error(_sleepDisplayName + ": failed to open sleep canvas: " + ex.Message); } } } public sealed class TentController : MonoBehaviour { private const string SleepHotspotName = "SidewalkEconomy_TentSleepHotspot"; private const string StorageHotspotName = "SidewalkEconomy_TentStorageHotspot"; private TentStorageStation _storageStation; private NetworkObject _networkObject; private InteractableObject _storageInteractable; private bool _storageHoverListenerRegistered; private bool _storageInteractListenerRegistered; private void Awake() { _networkObject = ((Component)this).GetComponent(); EnsureStorageStation(); DisableLegacyRootInteraction(); EnsureSleepHotspot(); EnsureStorageHotspot(); LogInteractionSetup(); } private void EnsureStorageStation() { _storageStation = InjectedComponentHelper.GetInjectedComponent((Component)(object)this); if ((Object)(object)_storageStation == (Object)null) { _storageStation = InjectedComponentHelper.AddInjectedComponent(((Component)this).gameObject); } _storageStation.Configure(useInteractable: false); } private void DisableLegacyRootInteraction() { InteractableObject component = ((Component)this).GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } if ((Object)(object)((Component)this).GetComponent() == (Object)null) { Collider component2 = ((Component)this).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.enabled = false; } } } private void EnsureSleepHotspot() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) GameObject orCreateHotspot = GetOrCreateHotspot("SidewalkEconomy_TentSleepHotspot", Constants.WorldSpawns.TENT_SLEEP_OFFSET, Constants.WorldSpawns.TENT_SLEEP_COLLIDER_SIZE); if (!((Object)(object)orCreateHotspot == (Object)null)) { SleepingSpotController sleepingSpotController = InjectedComponentHelper.GetInjectedComponent(orCreateHotspot); if ((Object)(object)sleepingSpotController == (Object)null) { sleepingSpotController = InjectedComponentHelper.AddInjectedComponent(orCreateHotspot); } sleepingSpotController?.Configure("Sleep", ((Component)this).transform); } } private void EnsureStorageHotspot() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) GameObject orCreateHotspot = GetOrCreateHotspot("SidewalkEconomy_TentStorageHotspot", Constants.WorldSpawns.TENT_STORAGE_OFFSET, Constants.WorldSpawns.TENT_STORAGE_COLLIDER_SIZE); if (!((Object)(object)orCreateHotspot == (Object)null)) { _storageInteractable = orCreateHotspot.GetComponent(); if ((Object)(object)_storageInteractable == (Object)null) { Component val = orCreateHotspot.AddComponent(Il2CppType.Of()); _storageInteractable = ((Il2CppObjectBase)val).Cast(); } _storageInteractable.MaxInteractionRange = 3f; _storageInteractable.SetInteractionType((EInteractionType)0); _storageInteractable.SetInteractableState((EInteractableState)0); _storageInteractable.SetMessage("Storage"); ((Behaviour)_storageInteractable).enabled = true; if (!_storageHoverListenerRegistered) { _storageInteractable.onHovered.AddListener(UnityAction.op_Implicit((Action)OnStorageHovered)); _storageHoverListenerRegistered = true; } if (!_storageInteractListenerRegistered) { _storageInteractable.onInteractStart.AddListener(UnityAction.op_Implicit((Action)OnStorageInteractStart)); _storageInteractListenerRegistered = true; } } } private GameObject GetOrCreateHotspot(string hotspotName, Vector3 localPosition, Vector3 colliderSize) { //IL_0018: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)this).transform.Find(hotspotName); GameObject val2 = (GameObject)(((Object)(object)val != (Object)null) ? ((object)((Component)val).gameObject) : ((object)new GameObject(hotspotName))); if ((Object)(object)val2.transform.parent != (Object)(object)((Component)this).transform) { val2.transform.SetParent(((Component)this).transform, false); } val2.transform.localPosition = localPosition; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; val2.layer = GetInteractionLayer(); BoxCollider val3 = val2.GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = val2.AddComponent(); } ((Collider)val3).isTrigger = false; val3.size = colliderSize; val3.center = Vector3.zero; ((Collider)val3).enabled = true; return val2; } private int GetInteractionLayer() { //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) if (Singleton.InstanceExists && (Object)(object)Singleton.Instance != (Object)null) { LayerMask interaction_SearchMask = Singleton.Instance.Interaction_SearchMask; int value = ((LayerMask)(ref interaction_SearchMask)).value; int num = 1 << ((Component)this).gameObject.layer; if ((value & num) != 0) { return ((Component)this).gameObject.layer; } for (int i = 0; i < 32; i++) { if ((value & (1 << i)) != 0) { return i; } } } return ((Component)this).gameObject.layer; } private void OnStorageHovered() { if (!((Object)(object)_storageInteractable == (Object)null)) { if (!TentOwnershipManager.IsTentOwned()) { _storageInteractable.SetInteractableState((EInteractableState)1); _storageInteractable.SetMessage(TentOwnershipManager.GetInteractionBlockedMessage()); } else { _storageInteractable.SetInteractableState((EInteractableState)0); _storageInteractable.SetMessage("Storage"); } } } private void OnStorageInteractStart() { if (!TentOwnershipManager.IsTentOwned()) { ModLogger.Debug("Tent storage interaction blocked - not owned by player"); } else if ((Object)(object)_storageStation == (Object)null) { ModLogger.Warn("Storage station missing - cannot open storage"); } else { _storageStation.OpenStorage(); } } private void LogInteractionSetup() { ModLogger.Info($"Tent interaction hotspots ready (network object: {(Object)(object)_networkObject != (Object)null}, storage station: {(Object)(object)_storageStation != (Object)null})"); } private void OnDestroy() { if (!((Object)(object)_storageInteractable == (Object)null)) { if (_storageHoverListenerRegistered) { _storageInteractable.onHovered.RemoveListener(UnityAction.op_Implicit((Action)OnStorageHovered)); _storageHoverListenerRegistered = false; } if (_storageInteractListenerRegistered) { _storageInteractable.onInteractStart.RemoveListener(UnityAction.op_Implicit((Action)OnStorageInteractStart)); _storageInteractListenerRegistered = false; } } } } public sealed class TentStorageEntity : StorageEntity { private enum StorageLifecycleState { Uninitialized, Ready, Opening, Open, Closing } [CompilerGenerated] private sealed class d__26 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public int saveSequence; public TentStorageEntity <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; case 1: <>1__state = -1; if (saveSequence != <>4__this._saveSequence) { return false; } <>4__this._saveQueued = false; <>4__this.SaveContents(); 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(); } } private static readonly List Instances = new List(); private bool _hasLoadedFromSave; private bool _suppressSave; private bool _saveQueued; private int _saveSequence; private bool _storageMenuCloseListenerRegistered; private StorageLifecycleState _lifecycleState = StorageLifecycleState.Uninitialized; public TentStorageEntity(IntPtr ptr) : base(ptr) { } public override void Awake() { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown if (!Instances.Contains(this)) { Instances.Add(this); } ((StorageEntity)this).StorageEntityName = "Tent Storage"; ((StorageEntity)this).StorageEntitySubtitle = "Store personal items"; ((StorageEntity)this).SlotCount = 12; ((StorageEntity)this).AccessSettings = (EAccessSettings)1; ((StorageEntity)this).MaxAccessDistance = 3f; ((StorageEntity)this).DisplayRowCount = 3; ((StorageEntity)this).Awake(); NetworkObject val = ((Component)this).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)this).gameObject.AddComponent(); } try { ((Behaviour)val).enabled = true; } catch (Exception ex) { ModLogger.Warn("NetworkObject setup: " + ex.Message); } if (((StorageEntity)this).ItemSlots == null) { ((StorageEntity)this).ItemSlots = new List(); } while (((StorageEntity)this).ItemSlots.Count < ((StorageEntity)this).SlotCount) { ItemSlot val2 = new ItemSlot(((StorageEntity)this).SlotsAreFilterable); val2.onItemDataChanged += Action.op_Implicit((Action)((StorageEntity)this).ContentsChanged); val2.onItemDataChanged += Action.op_Implicit((Action)HandleItemDataChanged); val2.SetSlotOwner(((Il2CppObjectBase)this).Cast()); ((StorageEntity)this).ItemSlots.Add(val2); } _lifecycleState = StorageLifecycleState.Ready; } public static void FlushAllForSave() { for (int num = Instances.Count - 1; num >= 0; num--) { TentStorageEntity tentStorageEntity = Instances[num]; if ((Object)(object)tentStorageEntity == (Object)null) { Instances.RemoveAt(num); } else { tentStorageEntity.FlushPendingSave(); } } } public void PrepareForOpen() { LoadFromSaveIfNeeded(); } internal bool TryOpenLocalStorage() { if (!((StorageEntity)this).CanBeOpened()) { return false; } if (_lifecycleState == StorageLifecycleState.Open || _lifecycleState == StorageLifecycleState.Opening) { ModLogger.Debug("TentStorage: open request ignored because storage is already active"); return (Object)(object)((StorageEntity)this).CurrentPlayerAccessor == (Object)(object)Player.Local; } if (_lifecycleState == StorageLifecycleState.Closing) { ModLogger.Warn("TentStorage: open request ignored while storage is closing"); return false; } Player local = Player.Local; if ((Object)(object)local == (Object)null) { return false; } StorageMenu instance = Singleton.Instance; if ((Object)(object)instance == (Object)null) { return false; } EnsureStorageMenuCloseListener(instance); _lifecycleState = StorageLifecycleState.Opening; try { instance.Open(((Il2CppObjectBase)this).Cast(), ((StorageEntity)this).StorageEntityName, ((StorageEntity)this).StorageEntitySubtitle); Player currentPlayerAccessor = ((StorageEntity)this).CurrentPlayerAccessor; ((StorageEntity)this).CurrentPlayerAccessor = local; if ((Object)(object)currentPlayerAccessor == (Object)null && (Object)(object)((StorageEntity)this).CurrentPlayerAccessor != (Object)null) { ((StorageEntity)this).OnOpened(); } _lifecycleState = StorageLifecycleState.Open; return true; } catch { _lifecycleState = StorageLifecycleState.Ready; throw; } } internal void CloseLocalStorage() { if (_lifecycleState != StorageLifecycleState.Ready || !((Object)(object)((StorageEntity)this).CurrentPlayerAccessor == (Object)null)) { _lifecycleState = StorageLifecycleState.Closing; StorageMenu instance = Singleton.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.OpenedStorageEntity == (Object)(object)this) { instance.CloseMenu(); } else { FinalizeLocalClose("manual close without active storage menu"); } } } private void EnsureStorageMenuCloseListener(StorageMenu storageMenu) { if (!_storageMenuCloseListenerRegistered) { storageMenu.onClosed.AddListener(UnityAction.op_Implicit((Action)HandleStorageMenuClosed)); _storageMenuCloseListenerRegistered = true; } } private void RemoveStorageMenuCloseListener() { if (_storageMenuCloseListenerRegistered) { StorageMenu instance = Singleton.Instance; if ((Object)(object)instance == (Object)null) { _storageMenuCloseListenerRegistered = false; return; } instance.onClosed.RemoveListener(UnityAction.op_Implicit((Action)HandleStorageMenuClosed)); _storageMenuCloseListenerRegistered = false; } } private void HandleStorageMenuClosed() { if (_lifecycleState != StorageLifecycleState.Ready || !((Object)(object)((StorageEntity)this).CurrentPlayerAccessor == (Object)null)) { FinalizeLocalClose("storage menu closed"); } } public override bool CanBeOpened() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) Player local = Player.Local; if ((Object)(object)local == (Object)null) { return false; } if ((Object)(object)((StorageEntity)this).CurrentPlayerAccessor != (Object)null && (Object)(object)((StorageEntity)this).CurrentPlayerAccessor != (Object)(object)local) { return false; } float num = Vector3.Distance(((Component)local).transform.position, ((Component)this).transform.position); if (num > ((StorageEntity)this).MaxAccessDistance) { return false; } return true; } public override void OnOpened() { ((StorageEntity)this).OnOpened(); _lifecycleState = StorageLifecycleState.Open; Player currentPlayerAccessor = ((StorageEntity)this).CurrentPlayerAccessor; ModLogger.Debug("TentStorage: Opened by " + (((currentPlayerAccessor != null) ? ((Object)currentPlayerAccessor).name : null) ?? "unknown")); } public override void OnClosed() { ((StorageEntity)this).OnClosed(); SaveContents(); ModLogger.Debug("TentStorage: Closed"); } private void LoadFromSaveIfNeeded() { if (_hasLoadedFromSave) { return; } TentStorageSaveable instance = TentStorageSaveable.Instance; if (instance == null || !instance.IsReady) { return; } IReadOnlyList items = instance.GetItems(); if (items == null || items.Count == 0) { _hasLoadedFromSave = true; return; } _suppressSave = true; try { ((StorageEntity)this).ClearContents(); foreach (TentStoredItem item2 in items) { if (item2 == null || string.IsNullOrWhiteSpace(item2.ItemId) || item2.Quantity <= 0) { continue; } ItemDefinition item = Registry.GetItem(item2.ItemId); if (!((Object)(object)item == (Object)null)) { ItemInstance defaultInstance = item.GetDefaultInstance(item2.Quantity); if (defaultInstance != null) { ((StorageEntity)this).InsertItem(defaultInstance, false); } } } } finally { _suppressSave = false; } _hasLoadedFromSave = true; } private void SaveContents() { TentStorageSaveable instance = TentStorageSaveable.Instance; if (instance == null || !instance.IsReady) { return; } List list = new List(); Enumerator enumerator = ((StorageEntity)this).ItemSlots.GetEnumerator(); while (enumerator.MoveNext()) { ItemSlot current = enumerator.Current; if (((current != null) ? current.ItemInstance : null) != null) { string itemId = GetItemId(current.ItemInstance); if (!string.IsNullOrEmpty(itemId) && !(itemId == "unknown")) { int itemQuantity = GetItemQuantity(current, current.ItemInstance); list.Add(new TentStoredItem { ItemId = itemId, Quantity = itemQuantity }); } } } instance.SetItems(list); } private static string GetItemId(ItemInstance itemInstance) { if ((Object)(object)((itemInstance != null) ? itemInstance.Definition : null) != (Object)null && !string.IsNullOrEmpty(((BaseItemDefinition)itemInstance.Definition).ID)) { return ((BaseItemDefinition)itemInstance.Definition).ID; } return "unknown"; } private static int GetItemQuantity(ItemSlot slot, ItemInstance itemInstance) { if (slot != null && slot.Quantity > 0) { return slot.Quantity; } if (itemInstance != null && ((BaseItemInstance)itemInstance).Quantity > 0) { return ((BaseItemInstance)itemInstance).Quantity; } return 1; } private void HandleItemDataChanged() { if (!_suppressSave && _lifecycleState != StorageLifecycleState.Opening && _lifecycleState != StorageLifecycleState.Closing) { QueueDelayedSave(); } } private void QueueDelayedSave() { if (!_saveQueued) { _saveQueued = true; MelonCoroutines.Start(DelayedSaveContents(++_saveSequence)); } } [IteratorStateMachine(typeof(d__26))] private IEnumerator DelayedSaveContents(int saveSequence) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__26(0) { <>4__this = this, saveSequence = saveSequence }; } private void OnApplicationQuit() { if (_lifecycleState == StorageLifecycleState.Open) { _lifecycleState = StorageLifecycleState.Ready; } FlushPendingSave(); } public override void OnDestroy() { Instances.Remove(this); RemoveStorageMenuCloseListener(); FlushPendingSave(); ((StorageEntity)this).OnDestroy(); } private void FlushPendingSave() { if (!_suppressSave && _hasLoadedFromSave && _lifecycleState != StorageLifecycleState.Opening) { _saveSequence++; _saveQueued = false; SaveContents(); } } private void FinalizeLocalClose(string reason) { bool flag = (Object)(object)((StorageEntity)this).CurrentPlayerAccessor != (Object)null; ((StorageEntity)this).CurrentPlayerAccessor = null; _lifecycleState = StorageLifecycleState.Ready; if (flag) { _saveSequence++; _saveQueued = false; ((StorageEntity)this).OnClosed(); } ModLogger.Debug("TentStorage: close finalized (" + reason + ")"); } } public sealed class TentStorageStation : MonoBehaviour { private InteractableObject _interactableObject; private TentStorageEntity _storageEntity; private bool _useInteractable; private bool _hasInteractStartListener; private Component _storageInteractable; private void Awake() { SetupStorage(); } public void Configure(bool useInteractable) { _useInteractable = useInteractable; if (!_useInteractable) { RemoveInteractStartListener(); DisableStorageInteractable(); return; } EnsureStorageInteractable(); EnsureInteractableObject(); ConfigureInteractableObject(); AddInteractStartListener(); } public void OpenStorage() { if ((Object)(object)_storageEntity == (Object)null) { ModLogger.Warn("Storage entity missing - cannot open"); return; } try { _storageEntity.PrepareForOpen(); if (!((StorageEntity)_storageEntity).CanBeOpened()) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(39, 2); defaultInterpolatedStringHandler.AppendLiteral("Cannot open storage (Player: "); Player currentPlayerAccessor = ((StorageEntity)_storageEntity).CurrentPlayerAccessor; defaultInterpolatedStringHandler.AppendFormatted(((currentPlayerAccessor != null) ? ((Object)currentPlayerAccessor).name : null) ?? "null"); defaultInterpolatedStringHandler.AppendLiteral(", Slots: "); defaultInterpolatedStringHandler.AppendFormatted(((StorageEntity)_storageEntity).ItemSlots?.Count ?? 0); defaultInterpolatedStringHandler.AppendLiteral(")"); ModLogger.Warn(defaultInterpolatedStringHandler.ToStringAndClear()); } else if (_storageEntity.TryOpenLocalStorage()) { ModLogger.Debug("Tent storage opened successfully"); } else { ModLogger.Warn("Tent storage local open failed"); } } catch (Exception ex) { ModLogger.Error("Storage open failed: " + ex.Message + "\n" + ex.StackTrace); } } private void SetupStorage() { _storageEntity = InjectedComponentHelper.GetInjectedComponent((Component)(object)this); if ((Object)(object)_storageEntity == (Object)null) { _storageEntity = InjectedComponentHelper.AddInjectedComponent(((Component)this).gameObject); } if (_useInteractable) { EnsureStorageInteractable(); EnsureInteractableObject(); ConfigureInteractableObject(); AddInteractStartListener(); } } private void OnInteractStart() { OpenStorage(); } private void EnsureStorageInteractable() { string storageInteractableTypeName = GetStorageInteractableTypeName(); if (storageInteractableTypeName == null) { return; } Type type = Type.GetType(storageInteractableTypeName); if (!(type == null)) { Type val = Il2CppType.From(type); _storageInteractable = ((Component)this).GetComponent(val); if ((Object)(object)_storageInteractable == (Object)null) { _storageInteractable = ((Component)this).gameObject.AddComponent(val); } ConfigureStorageInteractable(); Component storageInteractable = _storageInteractable; Behaviour val2 = (Behaviour)(object)((storageInteractable is Behaviour) ? storageInteractable : null); if (val2 != null) { val2.enabled = true; } } } private void EnsureInteractableObject() { _interactableObject = ((Component)this).GetComponent(); if ((Object)(object)_interactableObject == (Object)null) { Component val = ((Component)this).gameObject.AddComponent(Il2CppType.Of()); _interactableObject = ((Il2CppObjectBase)val).Cast(); } } private void ConfigureInteractableObject() { if (!((Object)(object)_interactableObject == (Object)null)) { _interactableObject.MaxInteractionRange = 3f; _interactableObject.SetMessage("Storage"); _interactableObject.SetInteractionType((EInteractionType)0); _interactableObject.SetInteractableState((EInteractableState)0); } } private void AddInteractStartListener() { if (!_hasInteractStartListener && !((Object)(object)_interactableObject == (Object)null)) { _interactableObject.onInteractStart.AddListener(UnityAction.op_Implicit((Action)OnInteractStart)); _hasInteractStartListener = true; } } private void RemoveInteractStartListener() { if (_hasInteractStartListener && !((Object)(object)_interactableObject == (Object)null)) { _interactableObject.onInteractStart.RemoveListener(UnityAction.op_Implicit((Action)OnInteractStart)); _hasInteractStartListener = false; } } private void DisableStorageInteractable() { if ((Object)(object)_storageInteractable != (Object)null) { Component storageInteractable = _storageInteractable; Behaviour val = (Behaviour)(object)((storageInteractable is Behaviour) ? storageInteractable : null); if (val != null) { val.enabled = false; } return; } string storageInteractableTypeName = GetStorageInteractableTypeName(); if (storageInteractableTypeName == null) { return; } Type type = Type.GetType(storageInteractableTypeName); if (!(type == null)) { _storageInteractable = ((Component)this).GetComponent(Il2CppType.From(type)); Component storageInteractable2 = _storageInteractable; Behaviour val2 = (Behaviour)(object)((storageInteractable2 is Behaviour) ? storageInteractable2 : null); if (val2 != null) { val2.enabled = false; } } } private static string GetStorageInteractableTypeName() { return "Il2CppScheduleOne.Storage.StorageEntityInteractable, Assembly-CSharp"; } private void ConfigureStorageInteractable() { if ((Object)(object)_storageInteractable == (Object)null || (Object)(object)_storageEntity == (Object)null) { return; } Type type = ((object)_storageInteractable).GetType(); PropertyInfo propertyInfo = type.GetProperty("storageEntity") ?? type.GetProperty("StorageEntity"); if (propertyInfo != null && propertyInfo.CanWrite) { propertyInfo.SetValue(_storageInteractable, _storageEntity); } else { (type.GetField("storageEntity") ?? type.GetField("StorageEntity"))?.SetValue(_storageInteractable, _storageEntity); } EnsureInteractableObject(); ConfigureInteractableObject(); InteractableObject interactableObject = _interactableObject; if (!((Object)(object)interactableObject == (Object)null)) { PropertyInfo propertyInfo2 = type.GetProperty("intObj") ?? type.GetProperty("IntObj"); if (propertyInfo2 != null && propertyInfo2.CanWrite) { propertyInfo2.SetValue(_storageInteractable, interactableObject); } else { (type.GetField("intObj") ?? type.GetField("IntObj"))?.SetValue(_storageInteractable, interactableObject); } } } private void OnDestroy() { RemoveInteractStartListener(); } } }