using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using I2.Loc; using Lamb.UI; using Lamb.UI.BuildMenu; using Pathfinding.ClipperLib; using Spine.Unity; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.U2D; using src.Extensions; [assembly: ComVisible(false)] [assembly: Guid("7e433b45-7d31-4eb4-9ec8-3f6f7cc9cfda")] [assembly: AssemblyFileVersion("0.3.51.0")] [assembly: AssemblyCopyright("")] [assembly: AssemblyProduct("EvenMoreSpace")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyCompany("")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyTrademark("")] [assembly: AssemblyTitle("EvenMoreSpace")] [assembly: AssemblyDescription("Extra Woolhaven base expansion for Cult of the Lamb.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyVersion("0.3.51.0")] namespace EvenMoreSpace; [BepInPlugin("com.cotl.evenmorespace", "EvenMoreSpace", "0.3.51")] public sealed class EvenMoreSpacePlugin : BaseUnityPlugin { public const string PluginGuid = "com.cotl.evenmorespace"; public const string PluginName = "EvenMoreSpace"; public const string PluginVersion = "0.3.51"; internal static EvenMoreSpacePlugin Instance; internal static ManualLogSource Log; internal static Harmony HarmonyInstance; private bool _expansionRuntimePatchesInstalled; private float _nextRuntimePatchCheck; private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00ca: 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_00ec: Expected O, but got Unknown //IL_00ec: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Expected O, but got Unknown //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Expected O, but got Unknown //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Expected O, but got Unknown //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Expected O, but got Unknown //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Expected O, but got Unknown //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Expected O, but got Unknown //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Expected O, but got Unknown //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Expected O, but got Unknown //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Expected O, but got Unknown //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Expected O, but got Unknown //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Expected O, but got Unknown //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Expected O, but got Unknown //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Expected O, but got Unknown //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Expected O, but got Unknown //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Expected O, but got Unknown //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Expected O, but got Unknown //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; EvenMoreSpaceConfig.Bind(((BaseUnityPlugin)this).Config); HarmonyInstance = new Harmony("com.cotl.evenmorespace"); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(Interaction_PurchaseLand), "Start", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PurchaseLandStartPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(Interaction_PurchaseLand), "OnInteract", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PurchaseLandInteractPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(DLCLandController), "ShowSlot", (Type[])null, (Type[])null), new HarmonyMethod(typeof(DLCLandShowSlotPatch), "Prefix", (Type[])null), new HarmonyMethod(typeof(DLCLandShowSlotPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(BiomeBaseManager), "ActivateRoom", new Type[1] { typeof(bool) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BiomeBaseActivateRoomPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(LocationManager), "PlaceStructures", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LocationPlaceStructuresPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(DataManager), "DeactivateWoolhavenDLC", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(WoolhavenDeactivationPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(DLCLandController), "CombineColliders", new Type[3] { typeof(Vector2[]), typeof(PolygonCollider2D), typeof(int) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(DLCLandCombineCollidersPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(PlacementRegion), "CreateFloodFill", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PlacementRegionCreateFloodFillPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(SaveAndLoad), "ResetSave", (Type[])null, (Type[])null), new HarmonyMethod(typeof(SaveAndLoadResetPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(SaveAndLoad), "DeleteSaveSlot", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(SaveAndLoadDeletePatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(LocationManager), "PlaceStructure", new Type[2] { typeof(StructuresData), typeof(GameObject) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(RemoteBuildStationPlacePatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(UIBuildMenuController), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RemoteBuildStationMenuPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(StructuresData), "LocalizedName", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(RemoteBuildStationNamePatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(StructuresData), "LocalizedDescription", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(RemoteBuildStationDescriptionPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); StructureManager.OnStructuresPlaced = (StructuresPlaced)Delegate.Combine((Delegate?)(object)StructureManager.OnStructuresPlaced, (Delegate?)new StructuresPlaced(EvenMoreSpaceState.ScheduleDelayedVisualRepair)); StructureManager.OnStructuresPlaced = (StructuresPlaced)Delegate.Combine((Delegate?)(object)StructureManager.OnStructuresPlaced, (Delegate?)new StructuresPlaced(BuildModePerformanceState.MarkGridDirty)); StructureManager.OnStructureAddedToGrid = (StructureChanged)Delegate.Combine((Delegate?)(object)StructureManager.OnStructureAddedToGrid, (Delegate?)new StructureChanged(BuildModePerformanceState.MarkGridDirty)); StructureManager.OnStructureMoved = (StructureChanged)Delegate.Combine((Delegate?)(object)StructureManager.OnStructureMoved, (Delegate?)new StructureChanged(BuildModePerformanceState.MarkGridDirty)); StructureManager.OnStructureRemoved = (StructureChanged)Delegate.Combine((Delegate?)(object)StructureManager.OnStructureRemoved, (Delegate?)new StructureChanged(BuildModePerformanceState.MarkGridDirty)); Log.LogInfo((object)("EvenMoreSpace loaded with the " + 20 + "-plot preset.")); RefreshExpansionRuntimePatches(); } private void Update() { if (!(Time.unscaledTime < _nextRuntimePatchCheck)) { _nextRuntimePatchCheck = Time.unscaledTime + 0.5f; RefreshExpansionRuntimePatches(); BuildModePerformanceState.CleanupInterruptedOverlay(); EvenMoreSpaceState.RefreshExpansionTrigger(); } } internal void RefreshExpansionRuntimePatches() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00b8: 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_00da: Expected O, but got Unknown //IL_00da: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Expected O, but got Unknown //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Expected O, but got Unknown //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Expected O, but got Unknown //IL_0347: Expected O, but got Unknown //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Expected O, but got Unknown //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Expected O, but got Unknown bool flag = EvenMoreSpaceState.HasActiveExpansion(); if (flag != _expansionRuntimePatchesInstalled && HarmonyInstance != null) { if (flag) { HarmonyInstance.Patch((MethodBase)AccessTools.PropertyGetter(typeof(PlacementRegion), "X_Constraints"), (HarmonyMethod)null, new HarmonyMethod(typeof(PlacementRegionConstraintsPatch), "XPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.PropertyGetter(typeof(PlacementRegion), "Y_Constraints"), (HarmonyMethod)null, new HarmonyMethod(typeof(PlacementRegionConstraintsPatch), "YPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(Structures_Ranch), "GetRanchingTiles", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RanchTileScanPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(RanchTileScanPatch), "Finalizer", (Type[])null), (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(Structures_Ranch), "GetValidRanchingTiles", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(RanchInnerScanPatch), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(Structures_Ranch), "WillHitFence", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(RanchInnerScanPatch), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(Interaction_Ranch), "CheckValidEnclosure", new Type[1] { typeof(StructuresData) }, (Type[])null), new HarmonyMethod(typeof(RanchValidationPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(Interaction_Ranch), "UpdateAllFences", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RanchFenceRefreshPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(PlacementRegion), "UpdateFenceablePositions", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RanchFencePlacementPositionsPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(PlacementRegion), "PlaceTiles", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BuildModePlaceTilesPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(PlacementRegion), "GetTile", new Type[1] { typeof(Vector3) }, (Type[])null), new HarmonyMethod(typeof(BuildModeGetTilePatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(PlacementRegion), "GetClosestTileAtWorldPosition", new Type[2] { typeof(Vector3), typeof(float) }, (Type[])null), new HarmonyMethod(typeof(BuildModeGetClosestTilePatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); PatchBuildMouseRuntimeMethods(); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(PlacementRegion), "UpdateTileAvailability", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BuildModeTileAvailabilityPatch), "Prefix", (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BuildModeTileAvailabilityPatch), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(PlacementRegion), "ClearTilesIE", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BuildModeClearTilesPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(PlacementRegion), "OnDestroy", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BuildModeRegionDestroyPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); PatchResourceTaskRuntimeMethods(); Log.LogInfo((object)"Enabled expanded-map build and ranch patches for an active extra-land save."); } else { UnpatchExpansionRuntimeMethods(); RanchPerformanceState.Reset(); BuildModePerformanceState.Reset(); Log.LogInfo((object)"Disabled expanded-map build and ranch patches because this save has no active extra land."); } _expansionRuntimePatchesInstalled = flag; } } private void PatchResourceTaskRuntimeMethods() { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown MethodBase methodBase = AccessTools.Method(typeof(Structures_Tree), "GetAvailableTasks", (Type[])null, (Type[])null); MethodBase methodBase2 = AccessTools.Method(typeof(Structures_Rubble), "GetAvailableTasks", (Type[])null, (Type[])null); MethodBase methodBase3 = AccessTools.Method(typeof(FollowerTask_ChopTrees), "OnDoingBegin", new Type[1] { typeof(Follower) }, (Type[])null); MethodBase methodBase4 = AccessTools.Method(typeof(FollowerTask_ClearRubble), "OnDoingBegin", new Type[1] { typeof(Follower) }, (Type[])null); MethodBase methodBase5 = AccessTools.Method(typeof(FollowerTask_ClearRubble), "UpdateDestination", new Type[1] { typeof(Follower) }, (Type[])null); try { if (methodBase != null) { HarmonyInstance.Patch(methodBase, new HarmonyMethod(typeof(ExpandedTreeTasksPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodBase2 != null) { HarmonyInstance.Patch(methodBase2, new HarmonyMethod(typeof(ExpandedRubbleTasksPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodBase3 != null) { HarmonyInstance.Patch(methodBase3, new HarmonyMethod(typeof(ExpandedChopTaskPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodBase4 != null) { HarmonyInstance.Patch(methodBase4, new HarmonyMethod(typeof(ExpandedRubbleTaskPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodBase5 != null) { HarmonyInstance.Patch(methodBase5, (HarmonyMethod)null, new HarmonyMethod(typeof(ExpandedRubbleDestinationPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception ex) { UnpatchRuntimeMethod(methodBase); UnpatchRuntimeMethod(methodBase2); UnpatchRuntimeMethod(methodBase3); UnpatchRuntimeMethod(methodBase4); UnpatchRuntimeMethod(methodBase5); Log.LogError((object)("Could not install expanded resource-task guards; they were disabled for this session: " + ex.Message)); } } private void PatchBuildMouseRuntimeMethods() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown MethodBase placementEnumeratorMoveNext = GetPlacementEnumeratorMoveNext("PlaceObject"); MethodBase placementEnumeratorMoveNext2 = GetPlacementEnumeratorMoveNext("PlaceObject_o"); HarmonyMethod val = new HarmonyMethod(typeof(BuildModeMouseCameraGatePatch), "Transpiler", (Type[])null); if (placementEnumeratorMoveNext != null) { HarmonyInstance.Patch(placementEnumeratorMoveNext, (HarmonyMethod)null, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null); } if (placementEnumeratorMoveNext2 != null) { HarmonyInstance.Patch(placementEnumeratorMoveNext2, (HarmonyMethod)null, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null); } } private static MethodBase GetPlacementEnumeratorMoveNext(string methodName) { MethodBase methodBase = AccessTools.Method(typeof(PlacementRegion), methodName, (Type[])null, (Type[])null); if (!(methodBase != null)) { return null; } return AccessTools.EnumeratorMoveNext(methodBase); } private void UnpatchExpansionRuntimeMethods() { UnpatchRuntimeMethod(AccessTools.PropertyGetter(typeof(PlacementRegion), "X_Constraints")); UnpatchRuntimeMethod(AccessTools.PropertyGetter(typeof(PlacementRegion), "Y_Constraints")); UnpatchRuntimeMethod(AccessTools.Method(typeof(Structures_Ranch), "GetRanchingTiles", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(Structures_Ranch), "GetValidRanchingTiles", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(Structures_Ranch), "WillHitFence", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(Interaction_Ranch), "CheckValidEnclosure", new Type[1] { typeof(StructuresData) }, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(Interaction_Ranch), "UpdateAllFences", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(PlacementRegion), "UpdateFenceablePositions", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(PlacementRegion), "PlaceTiles", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(PlacementRegion), "GetTile", new Type[1] { typeof(Vector3) }, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(PlacementRegion), "GetClosestTileAtWorldPosition", new Type[2] { typeof(Vector3), typeof(float) }, (Type[])null)); UnpatchRuntimeMethod(GetPlacementEnumeratorMoveNext("PlaceObject")); UnpatchRuntimeMethod(GetPlacementEnumeratorMoveNext("PlaceObject_o")); UnpatchRuntimeMethod(AccessTools.Method(typeof(PlacementRegion), "UpdateTileAvailability", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(PlacementRegion), "ClearTilesIE", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(PlacementRegion), "OnDestroy", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(Structures_Tree), "GetAvailableTasks", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(Structures_Rubble), "GetAvailableTasks", (Type[])null, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(FollowerTask_ChopTrees), "OnDoingBegin", new Type[1] { typeof(Follower) }, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(FollowerTask_ClearRubble), "OnDoingBegin", new Type[1] { typeof(Follower) }, (Type[])null)); UnpatchRuntimeMethod(AccessTools.Method(typeof(FollowerTask_ClearRubble), "UpdateDestination", new Type[1] { typeof(Follower) }, (Type[])null)); } private void UnpatchRuntimeMethod(MethodBase method) { if (method != null && HarmonyInstance != null) { HarmonyInstance.Unpatch(method, (HarmonyPatchType)0, "com.cotl.evenmorespace"); } } private void OnDestroy() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown StructureManager.OnStructuresPlaced = (StructuresPlaced)Delegate.Remove((Delegate?)(object)StructureManager.OnStructuresPlaced, (Delegate?)new StructuresPlaced(EvenMoreSpaceState.ScheduleDelayedVisualRepair)); StructureManager.OnStructuresPlaced = (StructuresPlaced)Delegate.Remove((Delegate?)(object)StructureManager.OnStructuresPlaced, (Delegate?)new StructuresPlaced(BuildModePerformanceState.MarkGridDirty)); StructureManager.OnStructureAddedToGrid = (StructureChanged)Delegate.Remove((Delegate?)(object)StructureManager.OnStructureAddedToGrid, (Delegate?)new StructureChanged(BuildModePerformanceState.MarkGridDirty)); StructureManager.OnStructureMoved = (StructureChanged)Delegate.Remove((Delegate?)(object)StructureManager.OnStructureMoved, (Delegate?)new StructureChanged(BuildModePerformanceState.MarkGridDirty)); StructureManager.OnStructureRemoved = (StructureChanged)Delegate.Remove((Delegate?)(object)StructureManager.OnStructureRemoved, (Delegate?)new StructureChanged(BuildModePerformanceState.MarkGridDirty)); if (_expansionRuntimePatchesInstalled) { UnpatchExpansionRuntimeMethods(); _expansionRuntimePatchesInstalled = false; } RanchPerformanceState.Reset(); BuildModePerformanceState.Reset(); EvenMoreSpaceState.ReleaseTransientDlcFreePresentation(); if (HarmonyInstance != null) { HarmonyInstance.UnpatchSelf(); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } internal static class EvenMoreSpaceConfig { internal const int PresetPlotLimit = 20; internal const int PresetStepLimit = 60; internal const int PresetMinimumTileCap = 40000; internal static ConfigEntry Enabled; internal static ConfigEntry MaxExtraSteps; internal static ConfigEntry MinimumTileCap; internal static ConfigEntry ExtraSegmentWeedCount; internal static ConfigEntry CreateGroundVisuals; internal static ConfigEntry ClearConnectorScenery; internal static ConfigEntry DuplicateConnectorBridge; internal static ConfigEntry DuplicateBackgroundDecor; internal static ConfigEntry MaxVisualClones; internal static ConfigEntry UseVanillaMoleCost; internal static ConfigEntry ExtraMoleCost; internal static ConfigEntry CostIncreasePerCompletedRow; internal static ConfigEntry EnableRemoteBuildStation; internal static ConfigEntry RanchEnclosureScanLimit; internal static ConfigEntry OptimizeExpandedBuildMode; internal static ConfigEntry BuildTileWindowRadius; internal static ConfigEntry DebugLogging; internal static void Bind(ConfigFile config) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Expected O, but got Unknown //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Expected O, but got Unknown Enabled = config.Bind("General", "Enabled", true, "Enable extra Woolhaven base expansion."); MaxExtraSteps = config.Bind("Expansion", "MaxExtraSteps", 60, new ConfigDescription("Maximum extra mole purchases for the installed " + 20 + "-plot edition. Each three purchases add one complete plot row.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 60), new object[0])); MinimumTileCap = config.Bind("Safety", "MinimumTileCap", 40000, new ConfigDescription("Maximum iterative placement-grid tiles available to an expanded base. The installed plot edition enforces its own safe minimum.", (AcceptableValueBase)(object)new AcceptableValueRange(5000, 250000), new object[0])); ExtraSegmentWeedCount = config.Bind("Population", "ExtraSegmentWeedCount", 36, new ConfigDescription("Target weed count for each new center segment; side segments use 75 percent. Existing populated segments are not changed.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 150), new object[0])); CreateGroundVisuals = config.Bind("Visuals", "CreateGroundVisuals", true, "Extend Woolhaven's own SpriteShape fill and border over purchased extra segments."); ClearConnectorScenery = config.Bind("Visuals", "ClearConnectorScenery", true, "Hide named trees, walls, bushes, and tall grass where generated center connectors open."); DuplicateConnectorBridge = config.Bind("Visuals", "DuplicateConnectorBridge", true, "Add a filtered set of vanilla SHOW DLC wall-cap sprites around each generated center walkway."); DuplicateBackgroundDecor = config.Bind("Visuals", "DuplicateBackgroundDecor", false, "Experimental collision-free scenery copies. Disabled by default so Woolhaven's existing fog/weather remains uncluttered."); MaxVisualClones = config.Bind("Visuals", "MaxVisualClones", 48, new ConfigDescription("Maximum cloned land visual objects to create.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 160), new object[0])); UseVanillaMoleCost = config.Bind("Mole Trigger", "UseVanillaMoleCost", true, "Use the final vanilla mole's resource cost for extra expansions."); ExtraMoleCost = config.Bind("Mole Trigger", "ExtraMoleCost", 150, new ConfigDescription("Resource cost when UseVanillaMoleCost is false.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 10000), new object[0])); CostIncreasePerCompletedRow = config.Bind("Mole Trigger", "CostIncreasePerCompletedRow", 25, new ConfigDescription("Amount added to each plot price after every completed three-plot row. Set to 0 for flat pricing.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 10000), new object[0])); EnableRemoteBuildStation = config.Bind("Remote Build Station", "Enabled", true, "Turn Woolhaven Small Statue 2 into a placeable Remote Construction Totem that opens the normal build menu."); RanchEnclosureScanLimit = config.Bind("Performance", "RanchEnclosureScanLimit", 128, new ConfigDescription("Maximum horizontal or vertical tiles checked by Woolhaven ranch enclosure searches while extra land is active.", (AcceptableValueBase)(object)new AcceptableValueRange(64, 512), new object[0])); OptimizeExpandedBuildMode = config.Bind("Performance", "OptimizeExpandedBuildMode", true, "Use a moving window of placement overlay tiles instead of creating and updating one overlay object for every expanded-map tile."); BuildTileWindowRadius = config.Bind("Performance", "BuildTileWindowRadius", 20, new ConfigDescription("Radius of the visible build-overlay window around the placement cursor. Increase only if placement squares disappear at unusually wide camera zooms.", (AcceptableValueBase)(object)new AcceptableValueRange(12, 40), new object[0])); DebugLogging = config.Bind("Debug", "DebugLogging", false, "Write verbose EvenMoreSpace logs."); } } internal static class BuildModePerformanceState { private sealed class WindowState { internal List Tiles; internal readonly Dictionary Lookup = new Dictionary(); internal Vector2Int Center; internal bool Initialized; internal int WindowVersion; internal int LastGridRevision = -1; internal int LastWindowVersion = -1; internal Vector2Int LastAvailabilityPosition; internal TYPES LastStructureType; internal bool HasAvailabilityPosition; } private sealed class GridPositionMembershipState { internal int Revision; internal int Count; internal HashSet Positions; } private static readonly FieldInfo TilesField = AccessTools.Field(typeof(PlacementRegion), "Tiles"); private static readonly FieldInfo TilesInitiatedField = AccessTools.Field(typeof(PlacementRegion), "tilesInitiated"); private static readonly FieldInfo PlacementObjectField = AccessTools.Field(typeof(PlacementRegion), "placementObject"); private static readonly FieldInfo CurrentTileField = AccessTools.Field(typeof(PlacementRegion), "CurrentTile"); private static readonly FieldInfo IsClearingTilesField = AccessTools.Field(typeof(PlacementRegion), "isClearingTiles"); private static readonly MethodInfo GetFromPoolMethod = AccessTools.Method(typeof(PlacementRegion), "GetFromPool", new Type[1] { typeof(GameObject) }, (Type[])null); private static readonly MethodInfo ReturnToPoolMethod = AccessTools.Method(typeof(PlacementRegion), "ReturnToPool", new Type[1] { typeof(GameObject) }, (Type[])null); private static readonly MethodInfo OnStructuresPlacedMethod = AccessTools.Method(typeof(PlacementRegion), "OnStructuresPlaced", (Type[])null, (Type[])null); private static readonly Dictionary Windows = new Dictionary(); private static readonly Dictionary, GridPositionMembershipState> GridPositionMembership = new Dictionary, GridPositionMembershipState>(); private static int _gridRevision; internal static bool IsSupported { get { if (TilesField != null && TilesInitiatedField != null && PlacementObjectField != null && CurrentTileField != null && IsClearingTilesField != null && GetFromPoolMethod != null && ReturnToPoolMethod != null) { return OnStructuresPlacedMethod != null; } return false; } } internal static bool ShouldOptimize(PlacementRegion region) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 if ((Object)(object)region != (Object)null && IsSupported && EvenMoreSpaceConfig.OptimizeExpandedBuildMode.Value && EvenMoreSpaceState.HasActiveExpansion() && (int)region.StructureType != 393 && (Object)(object)region.PlacementSquare != (Object)null && region.Grid != null) { return region.Grid.Count > 0; } return false; } internal static void MarkGridDirty() { _gridRevision++; GridPositionMembership.Clear(); } internal static void MarkGridDirty(StructuresData structure) { _gridRevision++; GridPositionMembership.Clear(); } internal static void ForgetRegion(PlacementRegion region) { if ((Object)(object)region != (Object)null) { ForceCleanupRegion(region); } } internal static void ClearOptimizedWindowIfPresent(PlacementRegion region) { if ((Object)(object)region != (Object)null && Windows.ContainsKey(((Object)region).GetInstanceID())) { ForceCleanupRegion(region); } } internal static void Reset() { if ((Object)(object)PlacementRegion.Instance != (Object)null && IsSupported) { ForceCleanupRegion(PlacementRegion.Instance); } Windows.Clear(); GridPositionMembership.Clear(); _gridRevision++; } internal static bool ContainsGridPosition(List positions, Vector2Int position) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (positions == null || positions.Count == 0) { return false; } if (!GridPositionMembership.TryGetValue(positions, out var value) || value == null || value.Revision != _gridRevision || value.Count != positions.Count) { GridPositionMembershipState gridPositionMembershipState = new GridPositionMembershipState(); gridPositionMembershipState.Revision = _gridRevision; gridPositionMembershipState.Count = positions.Count; gridPositionMembershipState.Positions = new HashSet(positions); value = gridPositionMembershipState; GridPositionMembership[positions] = value; } return value.Positions.Contains(position); } internal static void CleanupInterruptedOverlay() { PlacementRegion instance = PlacementRegion.Instance; if ((Object)(object)instance == (Object)null || !IsSupported || !EvenMoreSpaceState.HasActiveExpansion()) { return; } bool flag = (bool)TilesInitiatedField.GetValue(instance); object? value = PlacementObjectField.GetValue(instance); PlacementObject val = (PlacementObject)((value is PlacementObject) ? value : null); bool flag2 = Windows.ContainsKey(((Object)instance).GetInstanceID()); PlacementTile[] componentsInChildren = ((Component)instance).GetComponentsInChildren(true); bool flag3 = false; for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Component)componentsInChildren[i]).gameObject.activeSelf) { flag3 = true; break; } } if ((Object)(object)val == (Object)null && (flag2 || flag || flag3)) { ForceCleanupRegion(instance); } } internal unsafe static IEnumerator PlaceTilesWindow(PlacementRegion region) { if ((Object)(object)region == (Object)null || !IsSupported) { yield break; } if ((bool)TilesInitiatedField.GetValue(region)) { if (!Windows.TryGetValue(((Object)region).GetInstanceID(), out var value) || value == null || !value.Initialized || IsWindowHealthy(region, value)) { yield break; } ForceCleanupRegion(region); } if (TilesField.GetValue(region) is List { Count: >0 } list) { ReleasePlacementTiles(region, list); list.Clear(); } TilesInitiatedField.SetValue(region, true); List list2 = new List(); TilesField.SetValue(region, list2); WindowState windowState = new WindowState(); windowState.Tiles = list2; WindowState windowState2 = windowState; Windows[((Object)region).GetInstanceID()] = windowState2; object? value2 = PlacementObjectField.GetValue(region); PlacementObject val = (PlacementObject)((value2 is PlacementObject) ? value2 : null); Vector3 worldPosition = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : ((Component)region).transform.position); Vector2Int center = FindClosestGridPosition(region, worldPosition); foreach (Vector2Int item in EnumerateWindowPositions(center, GetWindowRadius())) { if (region.GetTileGridTile(item) != null) { AddPlacementTile(region, windowState2, item); } } windowState2.Center = center; if (windowState2.Tiles.Count == 0) { ForceCleanupRegion(region); EvenMoreSpaceState.DebugLog("Could not create any build overlay tiles for the expanded placement region."); yield break; } windowState2.Initialized = true; windowState2.WindowVersion++; OnStructuresPlacedMethod.Invoke(region, null); EvenMoreSpaceState.DebugLog("Created build overlay window with " + windowState2.Tiles.Count + " tiles around " + ((object)(*(Vector2Int*)(¢er))/*cast due to .constrained prefix*/).ToString() + "."); } internal static bool ShouldUseWindowClear(PlacementRegion region) { if ((Object)(object)region != (Object)null && IsSupported && Windows.TryGetValue(((Object)region).GetInstanceID(), out var value) && value != null) { return value.Initialized; } return false; } internal static IEnumerator ClearTilesWindow(PlacementRegion region) { if ((bool)IsClearingTilesField.GetValue(region)) { while ((Object)(object)region != (Object)null && (bool)IsClearingTilesField.GetValue(region)) { yield return null; } yield break; } IsClearingTilesField.SetValue(region, true); try { if (TilesField.GetValue(region) is List list) { ReleasePlacementTiles(region, new List(list)); list.Clear(); } } finally { ForceCleanupRegion(region); } } internal static bool TryGetTile(PlacementRegion region, Vector3 position, out PlacementTile tile) { //IL_0062: 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) tile = null; if (!EnsureWindow(region, out var state)) { return false; } int num = Mathf.RoundToInt(position.x); int num2 = Mathf.RoundToInt(position.y); if (Mathf.Abs(position.x - (float)num) > 0.001f || Mathf.Abs(position.y - (float)num2) > 0.001f) { return false; } Vector2Int val = default(Vector2Int); ((Vector2Int)(ref val))..ctor(num, num2); EnsureWindowContains(region, state, val); if (!state.Lookup.TryGetValue(val, out tile) || (Object)(object)tile == (Object)null || !((Component)tile).gameObject.activeSelf) { tile = null; return false; } return true; } internal static bool TryGetClosestTile(PlacementRegion region, Vector3 worldPosition, float maxDistance, out PlacementTile tile) { //IL_0015: 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_001d: 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_0028: 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) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_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_0071: 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) tile = null; if (!EnsureWindow(region, out var state)) { return false; } Vector3 val = ((Component)region).transform.InverseTransformPoint(worldPosition); if (!TryFindNearbyGridPosition(region, val, out var result)) { result = FindClosestGridPositionLocal(region, val); } if (region.GetTileGridTile(result) == null) { return false; } Vector3 val2 = new Vector3((float)((Vector2Int)(ref result)).x, (float)((Vector2Int)(ref result)).y) - val; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (maxDistance != -1f && sqrMagnitude >= maxDistance * maxDistance) { return false; } EnsureWindowContains(region, state, result); if (!state.Lookup.TryGetValue(result, out tile) || (Object)(object)tile == (Object)null || !((Component)tile).gameObject.activeSelf) { tile = null; return false; } return true; } internal static void ForceCleanupRegion(PlacementRegion region) { if ((Object)(object)region == (Object)null || !IsSupported) { return; } try { List list = TilesField.GetValue(region) as List; ReleasePlacementTiles(region, list); list?.Clear(); } catch (Exception ex) { EvenMoreSpaceState.DebugLog("Could not finish build-overlay cleanup: " + ex.Message); } finally { Windows.Remove(((Object)region).GetInstanceID()); TilesInitiatedField.SetValue(region, false); IsClearingTilesField.SetValue(region, false); } } private static void ReleasePlacementTiles(PlacementRegion region, IList tiles) { if ((Object)(object)region == (Object)null) { return; } HashSet hashSet = new HashSet(); if (tiles != null) { for (int i = 0; i < tiles.Count; i++) { if ((Object)(object)tiles[i] != (Object)null) { hashSet.Add(tiles[i]); } } } PlacementTile[] componentsInChildren = ((Component)region).GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)null && ((Object)((Component)componentsInChildren[j]).gameObject).name != "PathBrushPlusPreview") { hashSet.Add(componentsInChildren[j]); } } foreach (PlacementTile item in hashSet) { if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null) { continue; } if (((Component)item).gameObject.activeSelf || (Object)(object)((Component)item).transform.parent == (Object)(object)((Component)region).transform) { try { ReturnToPoolMethod.Invoke(region, new object[1] { ((Component)item).gameObject }); } catch (Exception ex) { ((Component)item).gameObject.SetActive(false); EvenMoreSpaceState.DebugLog("Could not return a build preview tile to the pool: " + ex.Message); } } else { ((Component)item).gameObject.SetActive(false); } } } internal static bool ShouldRefreshAvailability(PlacementRegion region) { //IL_0029: 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_0078: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //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_0046: 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 (!EnsureWindow(region, out var state)) { return true; } object? value = CurrentTileField.GetValue(region); PlacementTile val = (PlacementTile)((value is PlacementTile) ? value : null); if ((Object)(object)val == (Object)null) { return true; } Vector2Int gridPosition = val.GridPosition; if (state.HasAvailabilityPosition && state.LastAvailabilityPosition == gridPosition && state.LastStructureType == region.StructureType && state.LastGridRevision == _gridRevision && state.LastWindowVersion == state.WindowVersion) { return false; } state.HasAvailabilityPosition = true; state.LastAvailabilityPosition = gridPosition; state.LastStructureType = region.StructureType; state.LastGridRevision = _gridRevision; state.LastWindowVersion = state.WindowVersion; return true; } private static bool EnsureWindow(PlacementRegion region, out WindowState state) { state = null; if (!ShouldOptimize(region) || (bool)IsClearingTilesField.GetValue(region) || PlacementObjectField.GetValue(region) == null) { return false; } if (TryGetWindow(region, out state)) { return true; } if ((bool)TilesInitiatedField.GetValue(region)) { return false; } IEnumerator enumerator = PlaceTilesWindow(region); while (enumerator.MoveNext()) { } return TryGetWindow(region, out state); } private static bool TryGetWindow(PlacementRegion region, out WindowState state) { state = null; if (!ShouldOptimize(region) || !(bool)TilesInitiatedField.GetValue(region) || (bool)IsClearingTilesField.GetValue(region) || !Windows.TryGetValue(((Object)region).GetInstanceID(), out state) || !state.Initialized) { return false; } List objA = TilesField.GetValue(region) as List; if (!object.ReferenceEquals(objA, state.Tiles)) { ForceCleanupRegion(region); state = null; return false; } if (!IsWindowHealthy(region, state)) { ForceCleanupRegion(region); state = null; return false; } return true; } private static bool IsWindowHealthy(PlacementRegion region, WindowState state) { if ((Object)(object)region != (Object)null && state != null && state.Initialized && state.Tiles != null && state.Tiles.Count > 0 && state.Lookup.Count == state.Tiles.Count && (Object)(object)state.Tiles[0] != (Object)null && (Object)(object)((Component)state.Tiles[0]).gameObject != (Object)null) { return ((Component)state.Tiles[0]).gameObject.activeSelf; } return false; } private static void EnsureWindowContains(PlacementRegion region, WindowState state, Vector2Int position) { //IL_0056: 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_00aa: 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_00dd: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) int windowRadius = GetWindowRadius(); int num = Mathf.Max(4, windowRadius - 4); if ((Mathf.Abs(((Vector2Int)(ref position)).x - ((Vector2Int)(ref state.Center)).x) <= num && Mathf.Abs(((Vector2Int)(ref position)).y - ((Vector2Int)(ref state.Center)).y) <= num && state.Lookup.ContainsKey(position)) || region.GetTileGridTile(position) == null) { return; } int num2 = ((Vector2Int)(ref position)).x - windowRadius; int num3 = ((Vector2Int)(ref position)).x + windowRadius; int num4 = ((Vector2Int)(ref position)).y - windowRadius; int num5 = ((Vector2Int)(ref position)).y + windowRadius; List list = new List(); foreach (KeyValuePair item in state.Lookup) { Vector2Int key = item.Key; if (((Vector2Int)(ref key)).x < num2 || ((Vector2Int)(ref key)).x > num3 || ((Vector2Int)(ref key)).y < num4 || ((Vector2Int)(ref key)).y > num5) { list.Add(key); } } for (int i = 0; i < list.Count; i++) { PlacementTile val = state.Lookup[list[i]]; state.Lookup.Remove(list[i]); state.Tiles.Remove(val); ReturnToPoolMethod.Invoke(region, new object[1] { ((Component)val).gameObject }); } foreach (Vector2Int item2 in EnumerateWindowPositions(position, windowRadius)) { if (!state.Lookup.ContainsKey(item2) && region.GetTileGridTile(item2) != null) { AddPlacementTile(region, state, item2); } } state.Center = position; state.WindowVersion++; } private static void AddPlacementTile(PlacementRegion region, WindowState state, Vector2Int position) { //IL_0089: 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) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)region == (Object)null || state == null || (Object)(object)region.PlacementSquare == (Object)null) { return; } GameObject val; try { object? obj = GetFromPoolMethod.Invoke(region, new object[1] { region.PlacementSquare }); val = (GameObject)((obj is GameObject) ? obj : null); } catch (Exception ex) { EvenMoreSpaceState.DebugLog("Skipped expanded build tile because the placement pool was unavailable: " + ex.Message); return; } if (!((Object)(object)val == (Object)null)) { val.transform.SetParent(((Component)region).transform, false); val.transform.localPosition = new Vector3((float)((Vector2Int)(ref position)).x, (float)((Vector2Int)(ref position)).y); PlacementTile component = val.GetComponent(); if ((Object)(object)component == (Object)null) { ReturnToPoolMethod.Invoke(region, new object[1] { val }); return; } component.Position = new Vector3((float)((Vector2Int)(ref position)).x, (float)((Vector2Int)(ref position)).y); component.GridPosition = position; component.SetColor(Color.white, ((Component)component).transform.position); state.Tiles.Add(component); state.Lookup[position] = component; } } private static IEnumerable EnumerateWindowPositions(Vector2Int center, int radius) { //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) for (int y = ((Vector2Int)(ref center)).y - radius; y <= ((Vector2Int)(ref center)).y + radius; y++) { for (int x = ((Vector2Int)(ref center)).x - radius; x <= ((Vector2Int)(ref center)).x + radius; x++) { yield return new Vector2Int(x, y); } } } private static int GetWindowRadius() { return Mathf.Clamp(EvenMoreSpaceConfig.BuildTileWindowRadius.Value, 12, 40); } private static Vector2Int FindClosestGridPosition(PlacementRegion region, Vector3 worldPosition) { //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) return FindClosestGridPositionLocal(region, ((Component)region).transform.InverseTransformPoint(worldPosition)); } private static bool TryFindNearbyGridPosition(PlacementRegion region, Vector3 localPosition, out Vector2Int result) { //IL_0026: 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_0054: 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_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_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) Vector2Int val = default(Vector2Int); ((Vector2Int)(ref val))..ctor(Mathf.RoundToInt(localPosition.x), Mathf.RoundToInt(localPosition.y)); float num = float.MaxValue; result = val; bool result2 = false; Vector2Int val2 = default(Vector2Int); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { ((Vector2Int)(ref val2))..ctor(((Vector2Int)(ref val)).x + j, ((Vector2Int)(ref val)).y + i); if (region.GetTileGridTile(val2) != null) { Vector3 val3 = new Vector3((float)((Vector2Int)(ref val2)).x, (float)((Vector2Int)(ref val2)).y) - localPosition; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val2; result2 = true; } } } } return result2; } private static Vector2Int FindClosestGridPositionLocal(PlacementRegion region, Vector3 localPosition) { //IL_0001: 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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_004e: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) if (TryFindNearbyGridPosition(region, localPosition, out var result)) { return result; } Vector2Int result2 = Vector2Int.zero; float num = float.MaxValue; foreach (TileGridTile item in region.Grid) { Vector3 val = new Vector3((float)((Vector2Int)(ref item.Position)).x, (float)((Vector2Int)(ref item.Position)).y) - localPosition; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result2 = item.Position; } } return result2; } } internal static class RanchPerformanceState { internal struct TileScanState { internal int Depth; internal Structures_Ranch Ranch; internal HashSet FenceTiles; internal Dictionary, TileListMembershipState> TileListMembership; } internal sealed class TileListMembershipState { internal int Count; internal HashSet Tiles; } private sealed class ValidationThrottleState { internal float SuppressUntil; internal float LastValidationAt = -1f; } [ThreadStatic] private static int _scanDepth; [ThreadStatic] private static Structures_Ranch _scanRanch; [ThreadStatic] private static HashSet _scanFenceTiles; [ThreadStatic] private static Dictionary, TileListMembershipState> _scanTileListMembership; private static readonly Dictionary PendingValidations = new Dictionary(); private static readonly MethodInfo UpdateAllFencesMethod = AccessTools.Method(typeof(Interaction_Ranch), "UpdateAllFences", (Type[])null, (Type[])null); private static List _indestructibleRanchStructures; private static Interaction_Ranch _coalescedFenceRefreshExecutor; private static Coroutine _coalescedFenceRefreshCoroutine; private static bool _coalescedFenceRefreshScheduled; private static bool _coalescedFenceRefreshRunning; private static int _coalescedFenceRefreshRequestCount; internal static TileScanState EnterTileScan(Structures_Ranch ranch) { TileScanState result = new TileScanState { Depth = _scanDepth, Ranch = _scanRanch, FenceTiles = _scanFenceTiles, TileListMembership = _scanTileListMembership }; _scanDepth++; _scanRanch = ranch; _scanFenceTiles = new HashSet(); _scanTileListMembership = new Dictionary, TileListMembershipState>(); if (ranch != null && ranch.Fences != null) { for (int i = 0; i < ranch.Fences.Count; i++) { FenceData val = ranch.Fences[i]; if (val != null && val.Tile != null) { _scanFenceTiles.Add(val.Tile); } } } return result; } internal static void ExitTileScan(TileScanState previous) { _scanDepth = previous.Depth; _scanRanch = previous.Ranch; _scanFenceTiles = previous.FenceTiles; _scanTileListMembership = previous.TileListMembership; } internal static List GetIndestructibleRanchStructures() { if (_indestructibleRanchStructures == null) { _indestructibleRanchStructures = StructureManager.IndestructibleByRanchStructures; } return _indestructibleRanchStructures; } internal static bool ContainsFence(Structures_Ranch ranch, TileGridTile tile) { if (ranch == null || tile == null) { return false; } if (_scanDepth > 0 && _scanRanch == ranch && _scanFenceTiles != null) { return _scanFenceTiles.Contains(tile); } return ranch.ContainsFence(tile); } internal static bool ContainsTile(List tiles, TileGridTile tile) { if (_scanDepth <= 0 || _scanTileListMembership == null) { return tiles?.Contains(tile) ?? false; } if (tiles == null) { return false; } if (tiles.Count == 0) { _scanTileListMembership.Remove(tiles); return false; } if (!_scanTileListMembership.TryGetValue(tiles, out var value) || value == null || value.Tiles == null || tiles.Count < value.Count) { TileListMembershipState tileListMembershipState = new TileListMembershipState(); tileListMembershipState.Count = tiles.Count; tileListMembershipState.Tiles = new HashSet(tiles); value = tileListMembershipState; _scanTileListMembership[tiles] = value; } else if (tiles.Count > value.Count) { for (int i = value.Count; i < tiles.Count; i++) { if (tiles[i] != null) { value.Tiles.Add(tiles[i]); } } value.Count = tiles.Count; } return value.Tiles.Contains(tile); } internal static void LimitConstraint(ref Vector2 result) { //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) if (_scanDepth > 0 && EvenMoreSpaceState.HasActiveExpansion()) { int num = Mathf.Clamp(EvenMoreSpaceConfig.RanchEnclosureScanLimit.Value, 64, 512); float num2 = Mathf.Abs(result.x) + Mathf.Abs(result.y); if (!(num2 <= (float)num)) { float num3 = (float)num * 0.5f; result = new Vector2(0f - num3, num3); } } } internal static bool ShouldRunValidation(Interaction_Ranch ranch, StructuresData changedStructure) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ranch == (Object)null || !EvenMoreSpaceState.HasActiveExpansion()) { return true; } if (ranch.Brain == null || ((StructureBrain)ranch.Brain).Data == null) { return true; } int iD = ((StructureBrain)ranch.Brain).Data.ID; if (changedStructure != null && !StructureManager.RanchingStructures.Contains(changedStructure.Type)) { return true; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (!PendingValidations.TryGetValue(iD, out var value) || value == null) { value = new ValidationThrottleState(); PendingValidations[iD] = value; } if (changedStructure != null) { if (realtimeSinceStartup < value.SuppressUntil) { return false; } value.SuppressUntil = realtimeSinceStartup + 2f; value.LastValidationAt = -1f; return true; } if (realtimeSinceStartup < value.SuppressUntil && value.LastValidationAt >= 0f) { return false; } value.LastValidationAt = realtimeSinceStartup; if (realtimeSinceStartup >= value.SuppressUntil) { value.SuppressUntil = realtimeSinceStartup + 2f; } return true; } internal static bool ShouldRunFenceRefresh(Interaction_Ranch ranch) { if (_coalescedFenceRefreshRunning || !EvenMoreSpaceState.HasActiveExpansion() || UpdateAllFencesMethod == null || !HasMultipleActiveRanches()) { return true; } EvenMoreSpacePlugin instance = EvenMoreSpacePlugin.Instance; if ((Object)(object)instance == (Object)null) { return true; } if (IsUsableRanch(ranch)) { _coalescedFenceRefreshExecutor = ranch; } _coalescedFenceRefreshRequestCount++; if (!_coalescedFenceRefreshScheduled) { _coalescedFenceRefreshScheduled = true; _coalescedFenceRefreshCoroutine = ((MonoBehaviour)instance).StartCoroutine(RunCoalescedFenceRefresh()); } return false; } internal static bool RebuildFencePlacementPositions(PlacementRegion region, List fenceableGridPositions, List touchingRanchGridPositions) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0169: 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) if ((Object)(object)region == (Object)null || (int)region.StructureType != 393 || !EvenMoreSpaceState.HasActiveExpansion() || fenceableGridPositions == null || touchingRanchGridPositions == null) { return true; } long timestamp = Stopwatch.GetTimestamp(); try { List list = new List(); List list2 = new List(); HashSet seen = new HashSet(); HashSet seen2 = new HashSet(); List allStructuresOfType = StructureManager.GetAllStructuresOfType(); for (int i = 0; i < allStructuresOfType.Count; i++) { Structures_Ranch val = allStructuresOfType[i]; if (val != null) { AddUniqueTilePositions(val.GetRanchTiles(), list, seen); List surroundingRanchTiles = val.GetSurroundingRanchTiles(); AddUniqueTilePositions(surroundingRanchTiles, list, seen); AddUniqueTilePositions(surroundingRanchTiles, list2, seen2); } } int num = 0; if (allStructuresOfType.Count > 0) { List allStructuresOfType2 = StructureManager.GetAllStructuresOfType((TYPES)393, true, false); num = allStructuresOfType2.Count; for (int j = 0; j < allStructuresOfType2.Count; j++) { StructureBrain val2 = allStructuresOfType2[j]; if (val2 != null && val2.Data != null) { TileGridTile tileGridTile = region.GetTileGridTile(val2.Data.GridTilePosition); AddUniqueTilePosition(tileGridTile, list, seen); if (tileGridTile != null) { Vector2Int position = tileGridTile.Position; AddUniqueTilePosition(region.GetTileGridTile(new Vector2Int(((Vector2Int)(ref position)).x - 1, ((Vector2Int)(ref position)).y)), list, seen); AddUniqueTilePosition(region.GetTileGridTile(new Vector2Int(((Vector2Int)(ref position)).x, ((Vector2Int)(ref position)).y - 1)), list, seen); AddUniqueTilePosition(region.GetTileGridTile(new Vector2Int(((Vector2Int)(ref position)).x, ((Vector2Int)(ref position)).y + 1)), list, seen); AddUniqueTilePosition(region.GetTileGridTile(new Vector2Int(((Vector2Int)(ref position)).x + 1, ((Vector2Int)(ref position)).y)), list, seen); } } } } fenceableGridPositions.Clear(); fenceableGridPositions.AddRange(list); touchingRanchGridPositions.Clear(); touchingRanchGridPositions.AddRange(list2); double num2 = (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency; EvenMoreSpaceState.DebugLog("Rebuilt " + list.Count + " fence placement position(s) for " + allStructuresOfType.Count + " ranch(es) and " + num + " fence(s) in " + num2.ToString("0.00") + " ms."); return false; } catch (Exception ex) { if (EvenMoreSpacePlugin.Log != null) { EvenMoreSpacePlugin.Log.LogError((object)("Optimized ranch fence position rebuild failed; using the vanilla calculation: " + ex)); } return true; } } private static void AddUniqueTilePositions(List tiles, List positions, HashSet seen) { if (tiles != null) { for (int i = 0; i < tiles.Count; i++) { AddUniqueTilePosition(tiles[i], positions, seen); } } } private static void AddUniqueTilePosition(TileGridTile tile, List positions, HashSet seen) { //IL_0005: 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) if (tile != null && seen.Add(tile.Position)) { positions.Add(tile.Position); } } private static IEnumerator RunCoalescedFenceRefresh() { yield return null; _coalescedFenceRefreshCoroutine = null; _coalescedFenceRefreshScheduled = false; int requestCount = _coalescedFenceRefreshRequestCount; _coalescedFenceRefreshRequestCount = 0; Interaction_Ranch executor = FindFenceRefreshExecutor(); _coalescedFenceRefreshExecutor = null; if ((Object)(object)executor == (Object)null) { EvenMoreSpaceState.DebugLog("Skipped a coalesced ranch fence refresh because the ranch scene unloaded."); yield break; } long startedAt = Stopwatch.GetTimestamp(); _coalescedFenceRefreshRunning = true; try { UpdateAllFencesMethod.Invoke(executor, null); } catch (TargetInvocationException ex) { Exception ex2 = ex.InnerException ?? ex; if (EvenMoreSpacePlugin.Log != null) { EvenMoreSpacePlugin.Log.LogError((object)("Coalesced ranch fence refresh failed: " + ex2)); } } catch (Exception ex3) { if (EvenMoreSpacePlugin.Log != null) { EvenMoreSpacePlugin.Log.LogError((object)("Coalesced ranch fence refresh failed: " + ex3)); } } finally { _coalescedFenceRefreshRunning = false; } double elapsedMilliseconds = (double)(Stopwatch.GetTimestamp() - startedAt) * 1000.0 / (double)Stopwatch.Frequency; EvenMoreSpaceState.DebugLog("Coalesced " + requestCount + " ranch fence refresh request(s) into one pass (" + elapsedMilliseconds.ToString("0.00") + " ms)."); } private static bool HasMultipleActiveRanches() { int num = 0; List ranches = Interaction_Ranch.Ranches; if (ranches == null) { return false; } for (int i = 0; i < ranches.Count; i++) { if (IsUsableRanch(ranches[i]) && ++num > 1) { return true; } } return false; } private static Interaction_Ranch FindFenceRefreshExecutor() { if (IsUsableRanch(_coalescedFenceRefreshExecutor)) { return _coalescedFenceRefreshExecutor; } List ranches = Interaction_Ranch.Ranches; if (ranches != null) { for (int i = 0; i < ranches.Count; i++) { if (IsUsableRanch(ranches[i])) { return ranches[i]; } } } return null; } private static bool IsUsableRanch(Interaction_Ranch ranch) { if ((Object)(object)ranch != (Object)null && (Object)(object)((Component)ranch).gameObject != (Object)null && ((Component)ranch).gameObject.activeInHierarchy && ranch.Brain != null) { return ((StructureBrain)ranch.Brain).Data != null; } return false; } internal static void Reset() { EvenMoreSpacePlugin instance = EvenMoreSpacePlugin.Instance; if (_coalescedFenceRefreshCoroutine != null && (Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StopCoroutine(_coalescedFenceRefreshCoroutine); } _coalescedFenceRefreshExecutor = null; _coalescedFenceRefreshCoroutine = null; _coalescedFenceRefreshScheduled = false; _coalescedFenceRefreshRunning = false; _coalescedFenceRefreshRequestCount = 0; PendingValidations.Clear(); } } internal static class EvenMoreSpaceState { private struct SpriteShapePointSnapshot { internal Vector3 Position; internal Vector3 LeftTangent; internal Vector3 RightTangent; internal ShapeTangentMode TangentMode; internal float Height; internal int SpriteIndex; internal bool Corner; } private struct SuppressedGameObjectState { internal GameObject Target; internal bool ActiveSelf; } private const int FallbackVanillaMaxLandIndex = 2; private const int DlcFreePopulationRevision = 1; private const string CloneRootName = "EvenMoreSpace Visual Clones"; private const string GroundRootName = "EvenMoreSpace Ground"; private const string FreeGroundShapeRootName = "EvenMoreSpace DLC-Free Ground Shape"; private const string PersistentMoleName = "EvenMoreSpace Persistent Mole"; private const string FreeExpansionMarkerName = "EvenMoreSpace Base Expansion Cairn"; private const string BackgroundDecorRootName = "EvenMoreSpace Background Decor"; private const string ConnectorBridgeRootName = "EvenMoreSpace Connector Bridges"; private const string WoolhavenHoopRootPrefix = "Hoop_Pillar_Symbol_1"; private const long ClipperScale = 1000L; private const float SegmentJoinOverlap = 0.35f; private const float ConnectorClearWidth = 6f; private const float ConnectorClearHeight = 6f; private const float SuppressedConnectorBorderHeight = 0.01f; private const int MaxFirstConnectorSceneryRenderers = 1024; private const int MaxConnectorSceneryRenderersPerOpening = 128; private static bool _applying; private static bool _finalMoleHandoffScheduled; private static bool _populationBackfillScheduled; private static bool _delayedVisualRepairScheduled; private static bool _dlcFreeMoleHandoffScheduled; private static bool _moleTemplateWarningLogged; private static bool _prematureMoleHandoffRepairLogged; private static bool _hasDlcFreeMoleHandoffPosition; private static Vector3 _dlcFreeMoleHandoffPosition; private static int _extraStepsCacheSaveSlot = int.MinValue; private static int _extraStepsCacheMaximum = -1; private static int _extraStepsCacheValue; private static bool _extraStepsCacheValid; private static bool _majorDlcAuthenticationCacheValid; private static bool _majorDlcAuthenticationCacheValue; private static float _majorDlcAuthenticationCacheExpiresAt; private static int _stepsOverride = -1; private static PolygonCollider2D _lastExpansionCollider; private static Vector2[] _lastAddedSegmentLocalPath; private static Bounds _lastAddedSegmentWorldBounds; private static Interaction_PurchaseLand _persistentMole; private static FreeExpansionInteraction _freeExpansionMarker; private static GameObject _suppressedDlcEntranceBridge; private static GameObject _suppressedBaseExpansionSign; private static int _vanillaBaseMoleCost = -1; private static readonly List HiddenConnectorRenderers = new List(); private static SpriteShapeController _landSpriteShape; private static List _originalSpriteShapePoints; private static Texture2D _freeGroundTexture; private static Sprite _freeGroundSprite; private static Texture2D _freeMarkerTexture; private static Sprite _freeMarkerSprite; private static SpriteShapeController _freeBaseSpriteShape; private static List _originalFreeSpriteShapePoints; private static bool _freeBaseSpriteShapeExpanded; private static int _originalFreeSpriteShapeSortingOrder; private static bool _freeBaseSpriteShapeSortingCaptured; private static GameObject _freeGroundShapeRoot; private static GameObject _groundRoot; private static GameObject _backgroundDecorRoot; private static GameObject _connectorBridgeRoot; private static readonly List SuppressedDlcFreeScenery = new List(); internal static readonly FieldInfo LandSlotsField = AccessTools.Field(typeof(DLCLandController), "landSlots"); internal static readonly FieldInfo DLCLandEnabledField = AccessTools.Field(typeof(DLCLandController), "dlcLandEnabled"); internal static readonly FieldInfo DLCLandDisabledField = AccessTools.Field(typeof(DLCLandController), "dlcLandDisabled"); internal static readonly FieldInfo LandIndexField = AccessTools.Field(typeof(Interaction_PurchaseLand), "landIndex"); internal static readonly FieldInfo CostTypeField = AccessTools.Field(typeof(Interaction_PurchaseLand), "costType"); internal static readonly FieldInfo CostField = AccessTools.Field(typeof(Interaction_PurchaseLand), "cost"); internal static readonly FieldInfo SpineField = AccessTools.Field(typeof(Interaction_PurchaseLand), "spine"); internal static readonly FieldInfo IsRevealedField = AccessTools.Field(typeof(Interaction_PurchaseLand), "isRevealed"); internal static readonly FieldInfo IntroConvoField = AccessTools.Field(typeof(Interaction_PurchaseLand), "introConvo"); internal static readonly FieldInfo CameraTargetField = AccessTools.Field(typeof(Interaction_PurchaseLand), "cameraTarget"); internal static readonly FieldInfo PostBuildOffsetField = AccessTools.Field(typeof(Interaction_PurchaseLand), "postBuildOffset"); internal static readonly FieldInfo PlacementCachedColliderPointsField = AccessTools.Field(typeof(PlacementRegion), "cachedColliderPoints"); internal static readonly FieldInfo PlacementCountField = AccessTools.Field(typeof(PlacementRegion), "Count"); internal static readonly FieldInfo OnboardingDlcBridgeField = AccessTools.Field(typeof(Onboarding), "dlcBridge"); internal static readonly FieldInfo OnboardingBaseExpansionSignField = AccessTools.Field(typeof(Onboarding), "baseExpansionSign"); internal static bool LastFloodFillSucceeded { get; private set; } internal static bool LastGeometryExpansionSucceeded { get; private set; } internal static bool IsVanillaBaseExpansionEventActive() { if (!EvenMoreSpaceConfig.Enabled.Value || !IsWoolhavenActive()) { return false; } if (DataManager.Instance.OnboardedBaseExpansion || DataManager.Instance.LandPurchased >= 0) { return true; } int yngyaOffering = DataManager.Instance.YngyaOffering; if (yngyaOffering < 2) { return yngyaOffering < 0; } return true; } private static bool IsWoolhavenActive() { if (DataManager.Instance == null || !DataManager.Instance.MAJOR_DLC) { return false; } int yngyaOffering = DataManager.Instance.YngyaOffering; if (yngyaOffering >= 2 || yngyaOffering < 0) { return true; } if (!HasDlcFreeOrigin()) { if (!DataManager.Instance.OnboardedBaseExpansion) { return DataManager.Instance.LandPurchased >= 0; } return true; } return false; } private static bool IsFullWoolhavenWorldActive() { if (DataManager.Instance != null && DataManager.Instance.MAJOR_DLC) { return DataManager.Instance.YngyaOffering < 0; } return false; } private static string GetDlcFreeOriginKey(int saveSlot) { return "EvenMoreSpace.DlcFreeOrigin.SaveSlot." + GetCanonicalSaveSlot(saveSlot); } private static bool HasDlcFreeOrigin() { return PlayerPrefs.GetInt(GetDlcFreeOriginKey(SaveAndLoad.SAVE_SLOT), 0) == 1; } private static void MarkDlcFreeOrigin() { if (!HasDlcFreeOrigin()) { PlayerPrefs.SetInt(GetDlcFreeOriginKey(SaveAndLoad.SAVE_SLOT), 1); PlayerPrefs.Save(); } } private static bool HasDlcFreeProgressPendingHandoff() { if (IsWoolhavenActive() && GetExtraSteps() > 0 && !IsDlcFreeMoleRoute()) { if (!HasDlcFreeOrigin()) { return DataManager.Instance.LandPurchased < 0; } return true; } return false; } private static bool HasDlcFreeMoleRouteFlag() { return PlayerPrefs.GetInt(GetDlcFreeMoleRouteKey(SaveAndLoad.SAVE_SLOT), 0) == 1; } internal static bool IsDlcFreeMoleRoute() { if (IsWoolhavenActive() && GetExtraSteps() > 0) { return HasDlcFreeMoleRouteFlag(); } return false; } internal static bool IsReadyForExtraExpansion() { if (!EvenMoreSpaceConfig.Enabled.Value || DataManager.Instance == null) { return false; } if (IsDlcFreeMoleRoute()) { return true; } if (!IsVanillaBaseExpansionEventActive()) { return false; } return DataManager.Instance.LandPurchased >= GetVanillaMaxLandIndex(); } internal static bool IsDlcFreeExpansionAvailable() { if (!EvenMoreSpaceConfig.Enabled.Value || DataManager.Instance == null || IsWoolhavenActive()) { return false; } if ((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) { return (Object)(object)BiomeBaseManager.Instance.Room.Pieces[0] != (Object)null; } return false; } internal static bool UsesDlcFreeCustomGeometry() { if (!IsDlcFreeExpansionAvailable() && !IsDlcFreeMoleRoute()) { return HasDlcFreeProgressPendingHandoff(); } return true; } internal static bool ShouldSuppressVanillaLandSlotActivation() { if (EvenMoreSpaceConfig.Enabled.Value && GetExtraSteps() > 0 && HasDlcFreeOrigin()) { if (!UsesDlcFreeCustomGeometry()) { return HasDlcFreeMoleRouteFlag(); } return true; } return false; } private static bool IsBaseExpansionSceneReady() { if ((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0 && (Object)(object)BiomeBaseManager.Instance.Room.Pieces[0] != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room.Pieces[0].Collider != (Object)null && BiomeBaseManager.Instance.CachedColliderPoints != null && (Object)(object)DLCLandController.Instance != (Object)null) { return GetLandSlots() != null; } return false; } internal static bool EnsureDlcFreeCustomGeometry() { if (!UsesDlcFreeCustomGeometry() || GetExtraSteps() <= 0 || HasActiveExpansion()) { return true; } if (!IsBaseExpansionSceneReady()) { return false; } return ApplyExpansionToCurrentBase(rebuildPlacementGrid: false); } private static bool UsesVanillaDlcGeometry() { if (UsesDlcFreeCustomGeometry()) { return false; } if (!IsReadyForExtraExpansion() || (Object)(object)DLCLandController.Instance == (Object)null) { return false; } LandSlot[] landSlots = GetLandSlots(); if (landSlots != null) { return landSlots.Length > 0; } return false; } private static bool IsExpansionReadyForGeometry() { if (!IsReadyForExtraExpansion()) { return IsDlcFreeExpansionAvailable(); } return true; } internal static bool IsExtraMole(Interaction_PurchaseLand interaction) { if (IsDlcFreeExpansionAvailable() || !IsReadyForExtraExpansion() || (Object)(object)interaction == (Object)null) { return false; } return GetPrivateInt(LandIndexField, interaction, -999) >= GetVanillaMaxLandIndex(); } internal static bool IsFinalVanillaMolePurchase(Interaction_PurchaseLand interaction) { if (!EvenMoreSpaceConfig.Enabled.Value || IsDlcFreeExpansionAvailable() || !IsVanillaBaseExpansionEventActive() || (Object)(object)interaction == (Object)null || DataManager.Instance == null) { return false; } if (!HasAuthenticatedMajorDlc()) { return false; } int vanillaMaxLandIndex = GetVanillaMaxLandIndex(); int privateInt = GetPrivateInt(LandIndexField, interaction, -999); if (privateInt >= vanillaMaxLandIndex) { return DataManager.Instance.LandPurchased == vanillaMaxLandIndex - 1; } return false; } internal static void ScheduleFinalMoleHandoff(Interaction_PurchaseLand interaction) { if (!_finalMoleHandoffScheduled && IsFinalVanillaMolePurchase(interaction) && !((Object)(object)EvenMoreSpacePlugin.Instance == (Object)null)) { _finalMoleHandoffScheduled = true; ((MonoBehaviour)EvenMoreSpacePlugin.Instance).StartCoroutine(FinalMoleHandoff(interaction)); DebugLog("Scheduled final vanilla mole handoff."); } } private static IEnumerator FinalMoleHandoff(Interaction_PurchaseLand original) { int maxVanillaIndex = GetVanillaMaxLandIndex(); while ((Object)(object)original != (Object)null && DataManager.Instance != null && DataManager.Instance.LandPurchased < maxVanillaIndex) { yield return null; } if ((Object)(object)original == (Object)null || DataManager.Instance == null || DataManager.Instance.LandPurchased < maxVanillaIndex) { _finalMoleHandoffScheduled = false; yield break; } GameObject replacement = null; Exception cloneError = null; try { replacement = Object.Instantiate(((Component)original).gameObject, ((Component)original).transform.position, ((Component)original).transform.rotation); ((Object)replacement).name = ((Object)((Component)original).gameObject).name + " EvenMoreSpace"; replacement.SetActive(false); Interaction_PurchaseLand component = replacement.GetComponent(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException("The cloned mole has no purchase-land interaction."); } ((Behaviour)component).enabled = true; ((Interaction)component).Interactable = true; component.ForceShown = false; } catch (Exception ex) { cloneError = ex; } if (cloneError != null || (Object)(object)replacement == (Object)null) { if ((Object)(object)replacement != (Object)null) { Object.Destroy((Object)(object)replacement); } EvenMoreSpacePlugin.Log.LogError((object)("Could not preserve the final Woolhaven mole: " + cloneError)); _finalMoleHandoffScheduled = false; yield break; } while ((Object)(object)original != (Object)null) { yield return null; } yield return null; if ((Object)(object)replacement != (Object)null) { Interaction_PurchaseLand component2 = replacement.GetComponent(); ((Object)replacement).name = "EvenMoreSpace Persistent Mole"; replacement.SetActive(true); _persistentMole = component2; KeepFinalMoleAlive(component2); EvenMoreSpacePlugin.Log.LogInfo((object)"Final Woolhaven mole handoff complete; extra land purchases are now available."); } _finalMoleHandoffScheduled = false; } internal static int GetVanillaMaxLandIndex() { LandSlot[] landSlots = GetLandSlots(); if (landSlots != null && landSlots.Length > 0) { return landSlots.Length - 1; } return 2; } internal static LandSlot[] GetLandSlots() { if ((Object)(object)DLCLandController.Instance == (Object)null || LandSlotsField == null) { return null; } return LandSlotsField.GetValue(DLCLandController.Instance) as LandSlot[]; } internal static int GetExtraSteps() { int value = EvenMoreSpaceConfig.MaxExtraSteps.Value; int sAVE_SLOT = SaveAndLoad.SAVE_SLOT; if (_extraStepsCacheValid && _extraStepsCacheSaveSlot == sAVE_SLOT && _extraStepsCacheMaximum == value) { return Mathf.Clamp(_extraStepsCacheValue, 0, value); } string playerPrefsKey = GetPlayerPrefsKey(SaveAndLoad.SAVE_SLOT); int num = PlayerPrefs.GetInt(playerPrefsKey, 0); if (!PlayerPrefs.HasKey(playerPrefsKey) && SaveAndLoad.SAVE_SLOT >= 10) { string legacyPlayerPrefsKey = GetLegacyPlayerPrefsKey(SaveAndLoad.SAVE_SLOT); if (PlayerPrefs.HasKey(legacyPlayerPrefsKey)) { num = PlayerPrefs.GetInt(legacyPlayerPrefsKey, 0); PlayerPrefs.SetInt(playerPrefsKey, num); PlayerPrefs.DeleteKey(legacyPlayerPrefsKey); PlayerPrefs.Save(); } } if (num < 0) { num = 0; } if (num > value) { num = value; } _extraStepsCacheSaveSlot = sAVE_SLOT; _extraStepsCacheMaximum = value; _extraStepsCacheValue = num; _extraStepsCacheValid = true; return num; } internal static void SetExtraSteps(int steps) { int num = Mathf.Clamp(steps, 0, EvenMoreSpaceConfig.MaxExtraSteps.Value); PlayerPrefs.SetInt(GetPlayerPrefsKey(SaveAndLoad.SAVE_SLOT), num); PlayerPrefs.Save(); _extraStepsCacheSaveSlot = SaveAndLoad.SAVE_SLOT; _extraStepsCacheMaximum = EvenMoreSpaceConfig.MaxExtraSteps.Value; _extraStepsCacheValue = num; _extraStepsCacheValid = true; if ((Object)(object)EvenMoreSpacePlugin.Instance != (Object)null) { EvenMoreSpacePlugin.Instance.RefreshExpansionRuntimePatches(); } } internal static int GetEffectiveExtraSteps() { if (_stepsOverride < 0) { return GetExtraSteps(); } return _stepsOverride; } internal static bool HasActiveExpansion() { if (!EvenMoreSpaceConfig.Enabled.Value || GetEffectiveExtraSteps() <= 0) { return false; } if (IsExpansionReadyForGeometry() && LastGeometryExpansionSucceeded) { return (Object)(object)_lastExpansionCollider != (Object)null; } return false; } private static bool HasAuthenticatedMajorDlc() { if (DataManager.Instance == null || !DataManager.Instance.MAJOR_DLC) { return false; } float unscaledTime = Time.unscaledTime; if (!_majorDlcAuthenticationCacheValid || unscaledTime >= _majorDlcAuthenticationCacheExpiresAt) { _majorDlcAuthenticationCacheValue = GameManager.AuthenticateMajorDLC(); _majorDlcAuthenticationCacheExpiresAt = unscaledTime + 2f; _majorDlcAuthenticationCacheValid = true; } return _majorDlcAuthenticationCacheValue; } internal static bool IsAuthenticatedMajorDlc() { return HasAuthenticatedMajorDlc(); } internal static string GetPlayerPrefsKey(int saveSlot) { return "EvenMoreSpace.ExtraSteps.SaveSlot." + GetCanonicalSaveSlot(saveSlot); } private static string GetDlcFreeMoleRouteKey(int saveSlot) { return "EvenMoreSpace.DlcFreeMoleRoute.SaveSlot." + GetCanonicalSaveSlot(saveSlot); } private static void SetDlcFreeMoleRoute(bool enabled) { string dlcFreeMoleRouteKey = GetDlcFreeMoleRouteKey(SaveAndLoad.SAVE_SLOT); if (enabled) { PlayerPrefs.SetInt(dlcFreeMoleRouteKey, 1); } else { PlayerPrefs.DeleteKey(dlcFreeMoleRouteKey); } PlayerPrefs.Save(); } internal static void ClearSaveSlotState(int saveSlot) { int canonicalSaveSlot = GetCanonicalSaveSlot(saveSlot); PlayerPrefs.DeleteKey(GetPlayerPrefsKey(canonicalSaveSlot)); PlayerPrefs.DeleteKey(GetPopulatedStepsKey(canonicalSaveSlot)); PlayerPrefs.DeleteKey(GetPopulationRevisionKey(canonicalSaveSlot)); PlayerPrefs.DeleteKey(GetRightFirstRowsKey(canonicalSaveSlot)); PlayerPrefs.DeleteKey(GetRightFirstRowsHighKey(canonicalSaveSlot)); PlayerPrefs.DeleteKey(GetDlcFreeMoleRouteKey(canonicalSaveSlot)); PlayerPrefs.DeleteKey(GetDlcFreeOriginKey(canonicalSaveSlot)); PlayerPrefs.DeleteKey(GetLegacyPlayerPrefsKey(canonicalSaveSlot + 10)); PlayerPrefs.Save(); _extraStepsCacheValid = false; if ((Object)(object)EvenMoreSpacePlugin.Instance != (Object)null) { EvenMoreSpacePlugin.Instance.RefreshExpansionRuntimePatches(); } DebugLog("Cleared expansion state for save slot " + canonicalSaveSlot + "."); } private static int GetCanonicalSaveSlot(int saveSlot) { if (saveSlot < 10) { return saveSlot; } return saveSlot - 10; } private static string GetLegacyPlayerPrefsKey(int saveSlot) { return "EvenMoreSpace.ExtraSteps.SaveSlot." + saveSlot; } private static string GetPopulatedStepsKey(int saveSlot) { return "EvenMoreSpace.PopulatedSteps.SaveSlot." + GetCanonicalSaveSlot(saveSlot); } private static string GetPopulationRevisionKey(int saveSlot) { return "EvenMoreSpace.PopulationRevision.SaveSlot." + GetCanonicalSaveSlot(saveSlot); } private static string GetRightFirstRowsKey(int saveSlot) { return "EvenMoreSpace.RightFirstRows.SaveSlot." + GetCanonicalSaveSlot(saveSlot); } private static string GetRightFirstRowsHighKey(int saveSlot) { return "EvenMoreSpace.RightFirstRowsHigh.SaveSlot." + GetCanonicalSaveSlot(saveSlot); } private static int GetRightFirstRows() { return PlayerPrefs.GetInt(GetRightFirstRowsKey(SaveAndLoad.SAVE_SLOT), 0); } private static void SetRightFirstRows(int rows) { PlayerPrefs.SetInt(GetRightFirstRowsKey(SaveAndLoad.SAVE_SLOT), rows); PlayerPrefs.Save(); } private static int GetRightFirstRowsHigh() { return PlayerPrefs.GetInt(GetRightFirstRowsHighKey(SaveAndLoad.SAVE_SLOT), 0); } private static void SetRightFirstRowsHigh(int rows) { PlayerPrefs.SetInt(GetRightFirstRowsHighKey(SaveAndLoad.SAVE_SLOT), rows); PlayerPrefs.Save(); } private static bool IsRightFirstRow(int row) { switch (row) { default: return false; case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: return (GetRightFirstRowsHigh() & (1 << row - 30)) != 0; case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: return (GetRightFirstRows() & (1 << row)) != 0; } } private static void SetRightFirstRow(int row, bool rightFirst) { switch (row) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: { int rightFirstRows = GetRightFirstRows(); int num2 = 1 << row; SetRightFirstRows(rightFirst ? (rightFirstRows | num2) : (rightFirstRows & ~num2)); break; } case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: { int rightFirstRowsHigh = GetRightFirstRowsHigh(); int num = 1 << row - 30; SetRightFirstRowsHigh(rightFirst ? (rightFirstRowsHigh | num) : (rightFirstRowsHigh & ~num)); break; } } } private static int GetSegmentIndexForStep(int step, int slotCount) { if (step <= 0 || slotCount < 3) { if (step <= 0 || slotCount <= 0) { return 0; } return (step - 1) % slotCount; } int num = (step - 1) % 3; if (num == 0) { return 0; } bool flag = IsRightFirstRow((step - 1) / 3); if (num != 1) { if (!flag) { return 2; } return 1; } if (!flag) { return 1; } return 2; } private static int GetPopulatedSteps() { return Mathf.Clamp(PlayerPrefs.GetInt(GetPopulatedStepsKey(SaveAndLoad.SAVE_SLOT), 0), 0, GetExtraSteps()); } private static void SetPopulatedSteps(int steps) { PlayerPrefs.SetInt(GetPopulatedStepsKey(SaveAndLoad.SAVE_SLOT), Mathf.Clamp(steps, 0, GetExtraSteps())); PlayerPrefs.Save(); } private static int GetPopulationRevision() { return PlayerPrefs.GetInt(GetPopulationRevisionKey(SaveAndLoad.SAVE_SLOT), 0); } private static void SetPopulationRevision(int revision) { PlayerPrefs.SetInt(GetPopulationRevisionKey(SaveAndLoad.SAVE_SLOT), revision); PlayerPrefs.Save(); } private static void RefreshInteractionRegion(Interaction interaction) { //IL_0074: 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) if ((Object)(object)interaction == (Object)null) { return; } if (Interactor.InteractionRegions != null) { foreach (List value in Interactor.InteractionRegions.Values) { for (int num = value.Count - 1; num >= 0; num--) { if ((Object)(object)value[num] == (Object)(object)interaction) { value.RemoveAt(num); } } } } interaction.Position = ((Component)interaction).transform.position; Interactor.AddToRegion(interaction); } internal static void KeepFinalMoleAlive(Interaction_PurchaseLand interaction) { //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) //IL_00b7: 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_00ef: Unknown result type (might be due to invalid IL or missing references) if (!IsExtraMole(interaction)) { return; } if (GetExtraSteps() >= EvenMoreSpaceConfig.MaxExtraSteps.Value) { HideExtraMole(interaction); return; } Interaction_SimpleConversation val = (Interaction_SimpleConversation)((IntroConvoField != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); } SkeletonAnimation val2 = (SkeletonAnimation)((SpineField != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(true); SafePlayMoleAnimation(val2, "idle", "idle"); } ((Component)interaction).transform.SetParent((Transform)null, true); if (_hasDlcFreeMoleHandoffPosition) { ((Component)interaction).transform.position = _dlcFreeMoleHandoffPosition; _hasDlcFreeMoleHandoffPosition = false; } else { ((Component)interaction).transform.position = GetNextMolePosition(GetExtraSteps(), ((Component)interaction).transform.position); } ((Interaction)interaction).ActivatorOffset = Vector3.zero; ((Interaction)interaction).ActivateDistance = Mathf.Max(3f, ((Interaction)interaction).ActivateDistance); RefreshInteractionRegion((Interaction)(object)interaction); interaction.ForceShown = true; SetPrivateBool(IsRevealedField, interaction, value: true); ((Interaction)interaction).Interactable = true; UpdateMoleDisplayedCost(interaction, GetExtraSteps()); _persistentMole = interaction; DebugLog("Kept final mole interaction alive for extra expansion."); } private static void HideExtraMole(Interaction_PurchaseLand interaction) { if (!((Object)(object)interaction == (Object)null)) { ((Interaction)interaction).Interactable = false; interaction.ForceShown = false; _persistentMole = interaction; if ((Object)(object)EvenMoreSpacePlugin.Instance != (Object)null) { ((MonoBehaviour)EvenMoreSpacePlugin.Instance).StartCoroutine(DeactivateMoleNextFrame(((Component)interaction).gameObject)); } else { ((Component)interaction).gameObject.SetActive(false); } DebugLog("Hid the expansion mole because the configured plot limit was reached."); } } private static IEnumerator DeactivateMoleNextFrame(GameObject mole) { yield return null; if ((Object)(object)mole != (Object)null && GetExtraSteps() >= EvenMoreSpaceConfig.MaxExtraSteps.Value) { mole.SetActive(false); } } internal static void EnsureExtraMoleExists() { RemoteBuildStationFeature.EnsureUnlocked(); if (IsDlcFreeExpansionAvailable()) { EnsureDlcFreeExpansionMarker(); } else { if (!IsReadyForExtraExpansion() || _finalMoleHandoffScheduled || !IsBaseExpansionSceneReady()) { return; } if (GetExtraSteps() >= EvenMoreSpaceConfig.MaxExtraSteps.Value) { Interaction_PurchaseLand[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { if (IsExtraMole(array[i])) { HideExtraMole(array[i]); } } return; } if ((Object)(object)_persistentMole != (Object)null) { KeepFinalMoleAlive(_persistentMole); return; } Interaction_PurchaseLand[] array2 = Resources.FindObjectsOfTypeAll(); for (int j = 0; j < array2.Length; j++) { if ((Object)(object)array2[j] != (Object)null && ((Object)((Component)array2[j]).gameObject).name == "EvenMoreSpace Persistent Mole") { _persistentMole = array2[j]; KeepFinalMoleAlive(array2[j]); return; } } LandSlot[] landSlots = GetLandSlots(); if (landSlots == null || landSlots.Length < 2 || landSlots[^2] == null || (Object)(object)landSlots[^2].Land == (Object)null) { if (!_moleTemplateWarningLogged) { EvenMoreSpacePlugin.Log.LogError((object)"Could not find the vanilla final-mole land slot after the base scene finished loading."); _moleTemplateWarningLogged = true; } return; } Interaction_PurchaseLand componentInChildren = landSlots[^2].Land.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { if (!_moleTemplateWarningLogged) { EvenMoreSpacePlugin.Log.LogError((object)"Could not find the vanilla final-mole template after the base scene finished loading."); _moleTemplateWarningLogged = true; } return; } _moleTemplateWarningLogged = false; GameObject val = Object.Instantiate(((Component)componentInChildren).gameObject); ((Object)val).name = "EvenMoreSpace Persistent Mole"; val.transform.SetParent((Transform)null, true); val.SetActive(true); _persistentMole = val.GetComponent(); KeepFinalMoleAlive(_persistentMole); EvenMoreSpacePlugin.Log.LogInfo((object)"Restored the persistent Woolhaven expansion mole from the vanilla template."); } } internal static void ScheduleDlcFreeMoleHandoff() { //IL_003f: 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_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) if (!_dlcFreeMoleHandoffScheduled && HasDlcFreeProgressPendingHandoff() && !((Object)(object)EvenMoreSpacePlugin.Instance == (Object)null)) { if ((Object)(object)_freeExpansionMarker != (Object)null) { _dlcFreeMoleHandoffPosition = ((Component)_freeExpansionMarker).transform.position; } else { _dlcFreeMoleHandoffPosition = GetFreeExpansionFallbackPosition(); } _hasDlcFreeMoleHandoffPosition = true; _dlcFreeMoleHandoffScheduled = true; ((MonoBehaviour)EvenMoreSpacePlugin.Instance).StartCoroutine(DlcFreeMoleHandoff()); DebugLog("Scheduled the automatic DLC-free marker to Woolhaven mole handoff."); } } private static IEnumerator DlcFreeMoleHandoff() { int waited = 0; while (HasDlcFreeProgressPendingHandoff() && !IsBaseExpansionSceneReady()) { if (waited++ >= 300) { EvenMoreSpacePlugin.Log.LogError((object)"Could not complete the DLC-free expansion handoff because the base scene did not finish loading."); _hasDlcFreeMoleHandoffPosition = false; _dlcFreeMoleHandoffScheduled = false; yield break; } yield return null; } if (!HasDlcFreeProgressPendingHandoff()) { _hasDlcFreeMoleHandoffPosition = false; _dlcFreeMoleHandoffScheduled = false; yield break; } SetDlcFreeMoleRoute(enabled: true); DataManager.Instance.OnboardedBaseExpansion = true; DataManager.Instance.LandConvoProgress = 0; DataManager.Instance.LandResourcesGiven = 0; DataManager.Instance.LandPurchased = GetVanillaMaxLandIndex(); ObjectiveManager.CompleteCustomObjective((CustomQuestTypes)106, -1); ClearDlcFreeExpansionMarker(); if (ApplyExpansionToCurrentBase(rebuildPlacementGrid: false, GetExtraSteps(), geometryAlreadyApplied: true)) { EnsureExtraMoleExists(); EvenMoreSpacePlugin.Log.LogInfo((object)"Woolhaven activated; preserved the DLC-free terrain and handed future purchases to the vanilla mole."); } else { EvenMoreSpacePlugin.Log.LogWarning((object)"Woolhaven handoff state was saved, but custom terrain restoration will retry when the base scene is ready."); } _dlcFreeMoleHandoffScheduled = false; } private static void RepairPrematureDlcFreeMoleHandoff() { if (DataManager.Instance == null || !HasDlcFreeOrigin() || GetExtraSteps() <= 0 || !HasDlcFreeMoleRouteFlag() || IsWoolhavenActive()) { return; } SetDlcFreeMoleRoute(enabled: false); _dlcFreeMoleHandoffScheduled = false; _hasDlcFreeMoleHandoffPosition = false; if (DataManager.Instance.YngyaOffering >= 0 && DataManager.Instance.YngyaOffering < 2) { DataManager.Instance.LandPurchased = -1; DataManager.Instance.LandConvoProgress = 0; DataManager.Instance.LandResourcesGiven = 0; DataManager.Instance.OnboardedBaseExpansion = false; } if ((Object)(object)_persistentMole != (Object)null && ((Object)((Component)_persistentMole).gameObject).name == "EvenMoreSpace Persistent Mole") { ((Component)_persistentMole).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)_persistentMole).gameObject); } _persistentMole = null; Interaction_PurchaseLand[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && ((Object)((Component)array[i]).gameObject).name == "EvenMoreSpace Persistent Mole") { ((Component)array[i]).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)array[i]).gameObject); } } if (!_prematureMoleHandoffRepairLogged) { EvenMoreSpacePlugin.Log.LogInfo((object)"Repaired a premature DLC-free mole handoff; the expansion cairn will remain active until Yngya unlocks vanilla base expansion."); _prematureMoleHandoffRepairLogged = true; } } private static void UpdateDlcFreeOnboardingPresentation() { bool flag = EvenMoreSpaceConfig.Enabled.Value && DataManager.Instance != null && HasDlcFreeOrigin() && GetEffectiveExtraSteps() > 0; bool flag2 = flag && !IsFullWoolhavenWorldActive(); Onboarding instance = Onboarding.Instance; GameObject val = (GameObject)(((Object)(object)instance != (Object)null && OnboardingDlcBridgeField != null) ? /*isinst with value type is only supported in some contexts*/: null); Interaction_PurchaseLand val2 = (Interaction_PurchaseLand)(((Object)(object)instance != (Object)null && OnboardingBaseExpansionSignField != null) ? /*isinst with value type is only supported in some contexts*/: null); if (flag2) { if ((Object)(object)val != (Object)null) { _suppressedDlcEntranceBridge = val; if (val.activeSelf) { val.SetActive(false); } } } else if ((Object)(object)_suppressedDlcEntranceBridge != (Object)null) { bool active = DataManager.Instance != null && DataManager.Instance.OnboardedDLCEntrance; _suppressedDlcEntranceBridge.SetActive(active); _suppressedDlcEntranceBridge = null; } UpdateDlcFreeHoopSuppression(flag); if (flag2 && (Object)(object)val2 != (Object)null) { _suppressedBaseExpansionSign = ((Component)val2).gameObject; ((Interaction)val2).Interactable = false; val2.ForceShown = false; if (((Component)val2).gameObject.activeSelf) { ((Component)val2).gameObject.SetActive(false); } } else if ((Object)(object)_suppressedBaseExpansionSign != (Object)null) { bool flag3 = DataManager.Instance != null && DataManager.Instance.LandPurchased <= 0 && DataManager.Instance.OnboardedBaseExpansion; _suppressedBaseExpansionSign.SetActive(flag3); Interaction_PurchaseLand component = _suppressedBaseExpansionSign.GetComponent(); if ((Object)(object)component != (Object)null) { ((Interaction)component).Interactable = flag3; component.ForceShown = flag3; } _suppressedBaseExpansionSign = null; } } internal static void ReleaseTransientDlcFreePresentation() { UpdateDlcFreeHoopSuppression(suppress: false); if ((Object)(object)_suppressedDlcEntranceBridge != (Object)null) { bool active = DataManager.Instance != null && DataManager.Instance.OnboardedDLCEntrance; _suppressedDlcEntranceBridge.SetActive(active); _suppressedDlcEntranceBridge = null; } if ((Object)(object)_suppressedBaseExpansionSign != (Object)null) { bool flag = DataManager.Instance != null && DataManager.Instance.LandPurchased <= 0 && DataManager.Instance.OnboardedBaseExpansion; _suppressedBaseExpansionSign.SetActive(flag); Interaction_PurchaseLand component = _suppressedBaseExpansionSign.GetComponent(); if ((Object)(object)component != (Object)null) { ((Interaction)component).Interactable = flag; component.ForceShown = flag; } _suppressedBaseExpansionSign = null; } } private static void UpdateDlcFreeHoopSuppression(bool suppress) { if (!suppress) { for (int num = SuppressedDlcFreeScenery.Count - 1; num >= 0; num--) { SuppressedGameObjectState suppressedGameObjectState = SuppressedDlcFreeScenery[num]; if ((Object)(object)suppressedGameObjectState.Target != (Object)null) { suppressedGameObjectState.Target.SetActive(suppressedGameObjectState.ActiveSelf); } } SuppressedDlcFreeScenery.Clear(); return; } for (int num2 = SuppressedDlcFreeScenery.Count - 1; num2 >= 0; num2--) { GameObject target = SuppressedDlcFreeScenery[num2].Target; if ((Object)(object)target == (Object)null) { SuppressedDlcFreeScenery.RemoveAt(num2); } else if (target.activeSelf) { target.SetActive(false); } } if (SuppressedDlcFreeScenery.Count > 0 || (Object)(object)DLCLandController.Instance == (Object)null || DLCLandDisabledField == null || !(DLCLandDisabledField.GetValue(DLCLandController.Instance) is GameObject[] array)) { return; } int num3 = 0; foreach (GameObject val in array) { if ((Object)(object)val == (Object)null) { continue; } Transform[] componentsInChildren = val.GetComponentsInChildren(true); foreach (Transform val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || !((Object)val2).name.StartsWith("Hoop_Pillar_Symbol_1", StringComparison.Ordinal)) { continue; } GameObject gameObject = ((Component)val2).gameObject; bool flag = false; for (int k = 0; k < SuppressedDlcFreeScenery.Count; k++) { if ((Object)(object)SuppressedDlcFreeScenery[k].Target == (Object)(object)gameObject) { flag = true; break; } } if (!flag) { SuppressedDlcFreeScenery.Add(new SuppressedGameObjectState { Target = gameObject, ActiveSelf = gameObject.activeSelf }); gameObject.SetActive(false); num3++; } } } if (num3 > 0) { DebugLog("Suppressed " + num3 + " dormant Woolhaven wicker-hoop scenery root(s) on the DLC-free plots."); } } internal static void RefreshExpansionTrigger() { RepairPrematureDlcFreeMoleHandoff(); UpdateDlcFreeOnboardingPresentation(); if (!EvenMoreSpaceConfig.Enabled.Value) { RestoreConnectorScenery(); ClearDlcFreeExpansionMarker(); return; } if (HasDlcFreeProgressPendingHandoff()) { ScheduleDlcFreeMoleHandoff(); ClearDlcFreeExpansionMarker(); return; } if (IsDlcFreeExpansionAvailable()) { EnsureDlcFreeCustomGeometry(); EnsureDlcFreeExpansionMarker(); return; } if (IsDlcFreeMoleRoute()) { ClearDlcFreeExpansionMarker(); if (EnsureDlcFreeCustomGeometry()) { EnsureExtraMoleExists(); } return; } RestoreConnectorScenery(); ClearDlcFreeExpansionMarker(); if (IsReadyForExtraExpansion() && IsBaseExpansionSceneReady()) { EnsureExtraMoleExists(); } } private static void EnsureDlcFreeExpansionMarker() { //IL_0150: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown if (!IsDlcFreeExpansionAvailable() || GetExtraSteps() >= EvenMoreSpaceConfig.MaxExtraSteps.Value) { ClearDlcFreeExpansionMarker(); return; } MarkDlcFreeOrigin(); if ((Object)(object)_freeExpansionMarker == (Object)null) { GameObject val = GameObject.Find("EvenMoreSpace Base Expansion Cairn"); if ((Object)(object)val != (Object)null) { _freeExpansionMarker = val.GetComponent(); } } if ((Object)(object)_freeExpansionMarker == (Object)null) { GameObject val2 = new GameObject("EvenMoreSpace Base Expansion Cairn"); Transform val3 = (((Object)(object)BaseLocationManager.Instance != (Object)null) ? ((LocationManager)BaseLocationManager.Instance).StructureLayer : null); if ((Object)(object)val3 == (Object)null && (Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null) { val3 = ((Component)BiomeBaseManager.Instance.Room).transform; } if ((Object)(object)val3 != (Object)null) { val2.transform.SetParent(val3, true); } _freeExpansionMarker = val2.AddComponent(); ((Interaction)_freeExpansionMarker).ActivateDistance = 2.25f; ((Interaction)_freeExpansionMarker).PriorityWeight = 5f; ((Interaction)_freeExpansionMarker).IgnoreTutorial = true; ((Interaction)_freeExpansionMarker).Interactable = true; SpriteRenderer val4 = CreateFreeExpansionMarkerVisual(val2.transform); ((Interaction)_freeExpansionMarker).OutlineTarget = (((Object)(object)val4 != (Object)null) ? ((Component)val4).gameObject : val2); val2.SetActive(true); EvenMoreSpacePlugin.Log.LogInfo((object)"Created the base-game expansion cairn trigger."); } Vector3 freeExpansionFallbackPosition = GetFreeExpansionFallbackPosition(); ((Component)_freeExpansionMarker).transform.position = GetNextMolePosition(GetExtraSteps(), freeExpansionFallbackPosition); RefreshInteractionRegion((Interaction)(object)_freeExpansionMarker); ((Interaction)_freeExpansionMarker).Interactable = true; } private static void ClearDlcFreeExpansionMarker() { if ((Object)(object)_freeExpansionMarker != (Object)null) { Object.Destroy((Object)(object)((Component)_freeExpansionMarker).gameObject); _freeExpansionMarker = null; return; } GameObject val = GameObject.Find("EvenMoreSpace Base Expansion Cairn"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } internal static void PrepareExtraInteraction(Interaction_PurchaseLand interaction, StateMachine state) { if (!((Object)(object)interaction == (Object)null) && !((Object)(object)state == (Object)null)) { ((Interaction)interaction).state = state; PlayerFarming val = (((Interaction)interaction).playerFarming = ((Component)state).GetComponent()); if (((Interaction)interaction).SwitchMainPlayerOnInteract) { PlayerFarming.SetMainPlayer(state); } ((Interaction)interaction).EndIndicateHighlighted(val); if ((Object)(object)val != (Object)null && (Object)(object)val.playerWeapon != (Object)null) { val.playerWeapon.StopHeavyAttackRoutine(); } if (((Interaction)interaction).CallbackStart != null) { ((Interaction)interaction).CallbackStart.Invoke(); } } } internal static IEnumerator RunExtraMoleExpansion(Interaction_PurchaseLand interaction, StateMachine state) { int current = GetExtraSteps(); if (current >= EvenMoreSpaceConfig.MaxExtraSteps.Value) { ShakePlayer(state); EvenMoreSpacePlugin.Log.LogInfo((object)"Extra Woolhaven expansion is already at the configured max."); yield break; } ITEM_TYPE costType = GetPrivateCostType(interaction); int cost = GetMoleCostForStep(interaction, current); if (cost > 0 && Inventory.GetItemQuantity(costType) < cost) { ShakePlayer(state); yield break; } PrepareExtraInteraction(interaction, state); ((Interaction)interaction).Interactable = false; SkeletonAnimation spine = (SkeletonAnimation)((SpineField != null) ? /*isinst with value type is only supported in some contexts*/: null); GameManager gameManager = GameManager.GetInstance(); GameObject temporaryCameraTarget = null; bool conversationOpened = false; bool committed = false; int originalRightFirstRows = GetRightFirstRows(); int originalRightFirstRowsHigh = GetRightFirstRowsHigh(); bool directionChanged = false; try { if ((Object)(object)state != (Object)null) { state.CURRENT_STATE = (State)49; } if ((Object)(object)spine != (Object)null) { ((Component)spine).gameObject.SetActive(true); SafePlayMoleAnimation(spine, "dig_up", "idle"); } int desiredSteps = current + 1; if (current % 3 == 1) { int num = current / 3; bool flag = (Object)(object)state != (Object)null && ((Component)state).transform.position.x >= ((Component)interaction).transform.position.x; SetRightFirstRow(num, flag); directionChanged = true; EvenMoreSpacePlugin.Log.LogInfo((object)("Selected " + (flag ? "right" : "left") + " as the first wing for extra Woolhaven row " + (num + 1) + ".")); } if (!ApplyExpansionToCurrentBase(rebuildPlacementGrid: true, desiredSteps)) { ShakePlayer(state); EvenMoreSpacePlugin.Log.LogError((object)"Extra Woolhaven expansion was not charged because the map rebuild failed."); yield break; } GameObject fallbackCameraTarget = (GameObject)((CameraTargetField != null) ? /*isinst with value type is only supported in some contexts*/: null); temporaryCameraTarget = new GameObject("EvenMoreSpace Expansion Camera Target"); temporaryCameraTarget.transform.position = GetExpansionCameraPosition(((Object)(object)fallbackCameraTarget != (Object)null) ? fallbackCameraTarget.transform.position : ((Component)interaction).transform.position); GameObject cameraTarget = temporaryCameraTarget; if ((Object)(object)cameraTarget != (Object)null && (Object)(object)gameManager != (Object)null) { gameManager.OnConversationNew(true, true, (PlayerFarming)null); gameManager.OnConversationNext(cameraTarget, 15f); conversationOpened = true; } yield return (object)new WaitForSeconds(0.35f); PlayAudio("event:/dlc/env/gofernon/base_expand", ((Component)interaction).transform.position); if ((Object)(object)CameraManager.instance != (Object)null) { CameraManager.instance.ShakeCameraForDuration(0.4f, 0.55f, 2f, true); } bool resourcesDeducted = false; Exception commitError = null; try { if (cost > 0) { Inventory.ChangeItemQuantity(costType, -cost, 0); resourcesDeducted = true; } SetExtraSteps(desiredSteps); committed = true; PopulatePendingSegments(); } catch (Exception ex) { commitError = ex; } if (commitError != null) { if (resourcesDeducted) { Inventory.ChangeItemQuantity(costType, cost, 0); } SetExtraSteps(current); committed = false; ShakePlayer(state); EvenMoreSpacePlugin.Log.LogError((object)("Rolled back extra Woolhaven expansion after commit failure: " + commitError)); yield break; } ((Component)interaction).transform.position = GetNextMolePosition(desiredSteps, ((Component)interaction).transform.position); RefreshInteractionRegion((Interaction)(object)interaction); MovePlayersNear(((Component)interaction).transform.position); yield return (object)new WaitForSeconds(0.4f); if ((Object)(object)spine != (Object)null) { ((Component)spine).gameObject.SetActive(true); SafePlayMoleAnimation(spine, "idle", "idle"); } interaction.ForceShown = true; SetPrivateBool(IsRevealedField, interaction, value: true); } finally { if (!committed) { if (directionChanged) { SetRightFirstRows(originalRightFirstRows); SetRightFirstRowsHigh(originalRightFirstRowsHigh); } ApplyExpansionToCurrentBase(rebuildPlacementGrid: true, current); } if ((Object)(object)state != (Object)null && (int)state.CURRENT_STATE == 49) { state.CURRENT_STATE = (State)0; } if (conversationOpened && (Object)(object)gameManager != (Object)null) { gameManager.OnConversationEnd(true, true); } if ((Object)(object)temporaryCameraTarget != (Object)null) { Object.Destroy((Object)(object)temporaryCameraTarget); } ((Interaction)interaction).Interactable = true; KeepFinalMoleAlive(interaction); } if (committed) { EvenMoreSpacePlugin.Log.LogInfo((object)("Added extra Woolhaven expansion step " + GetExtraSteps() + ".")); } } internal static IEnumerator RunDlcFreeExpansion(FreeExpansionInteraction marker, StateMachine state) { int current = GetExtraSteps(); if ((Object)(object)marker == (Object)null || current >= EvenMoreSpaceConfig.MaxExtraSteps.Value) { ShakePlayer(state); yield break; } int cost = GetMoleCostForStep(null, current); if (cost > 0 && Inventory.GetItemQuantity((ITEM_TYPE)1) < cost) { ShakePlayer(state); yield break; } bool committed = false; bool resourcesDeducted = false; try { if ((Object)(object)state != (Object)null) { state.CURRENT_STATE = (State)49; } ((Interaction)marker).Interactable = false; int desiredSteps = current + 1; if (!ApplyExpansionToCurrentBase(rebuildPlacementGrid: true, desiredSteps)) { ShakePlayer(state); EvenMoreSpacePlugin.Log.LogError((object)"DLC-free expansion was not charged because the base rebuild failed."); yield break; } yield return (object)new WaitForSeconds(0.2f); PlayAudio("event:/ui/open_menu", ((Component)marker).transform.position); if ((Object)(object)CameraManager.instance != (Object)null) { CameraManager.instance.ShakeCameraForDuration(0.25f, 0.35f, 1.5f, true); } if (cost > 0) { Inventory.ChangeItemQuantity((ITEM_TYPE)1, -cost, 0); resourcesDeducted = true; } SetExtraSteps(desiredSteps); committed = true; PopulatePendingSegments(); ((Component)marker).transform.position = GetNextMolePosition(desiredSteps, ((Component)marker).transform.position); RefreshInteractionRegion((Interaction)(object)marker); MovePlayersNear(((Component)marker).transform.position); yield return (object)new WaitForSeconds(0.15f); } finally { if (!committed) { if (resourcesDeducted) { Inventory.ChangeItemQuantity((ITEM_TYPE)1, cost, 0); } SetExtraSteps(current); ApplyExpansionToCurrentBase(rebuildPlacementGrid: true, current); } if ((Object)(object)state != (Object)null && (int)state.CURRENT_STATE == 49) { state.CURRENT_STATE = (State)0; } if ((Object)(object)marker != (Object)null) { ((Interaction)marker).Interactable = true; } EnsureDlcFreeExpansionMarker(); } if (committed) { EvenMoreSpacePlugin.Log.LogInfo((object)("Added DLC-free base expansion step " + GetExtraSteps() + ".")); } } internal static bool ApplyExpansionToCurrentBase(bool rebuildPlacementGrid, int stepsOverride = -1, bool geometryAlreadyApplied = false) { if (_applying || !IsExpansionReadyForGeometry()) { return false; } _applying = true; int stepsOverride2 = _stepsOverride; _stepsOverride = stepsOverride; PolygonCollider2D collider = null; Vector2[] originalPath = null; bool flag = false; try { bool flag2 = UsesVanillaDlcGeometry(); if ((Object)(object)BiomeBaseManager.Instance == (Object)null || (Object)(object)BiomeBaseManager.Instance.Room == (Object)null || BiomeBaseManager.Instance.Room.Pieces == null || BiomeBaseManager.Instance.Room.Pieces.Count == 0 || (Object)(object)BiomeBaseManager.Instance.Room.Pieces[0] == (Object)null) { throw new InvalidOperationException("The base room is not ready."); } if (BiomeBaseManager.Instance.CachedColliderPoints == null) { throw new InvalidOperationException("The base collider cache is not ready."); } PolygonCollider2D val = BiomeBaseManager.Instance.Room.Pieces[0].Collider; if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("The base room collider is missing."); } collider = val; originalPath = val.GetPath(0); if (!geometryAlreadyApplied || !HasActiveExpansion() || !LastGeometryExpansionSucceeded || !((Object)(object)_lastExpansionCollider == (Object)(object)val)) { if (flag2) { int num = Mathf.Clamp(DataManager.Instance.LandPurchased, 0, GetVanillaMaxLandIndex()); val = DLCLandController.Instance.CombineColliders(BiomeBaseManager.Instance.CachedColliderPoints, val, num); } else { flag = true; RestoreBaseRoomCollider(val); val = ExpandCollider(val); } if (GetEffectiveExtraSteps() > 0 && !LastGeometryExpansionSucceeded) { throw new InvalidOperationException("The expanded room polygon could not be generated."); } BiomeBaseManager.Instance.Room.Pieces[0].Collider = val; BiomeBaseManager.Instance.Room.SetColliderAndUpdatePathfinding(); Physics2D.SyncTransforms(); if (!flag2 && HasActiveExpansion() && !ValidateCustomExpansionGeometry(val, GetEffectiveExtraSteps())) { throw new InvalidOperationException("The DLC-free room boundary did not contain every generated plot."); } } else { DebugLog("Reused the expanded collider and vanilla pathfinding pass during base load."); } if (!flag2 && (Object)(object)PlacementRegion.Instance != (Object)null) { SyncPlacementRegionCollider(val); } if (EvenMoreSpaceConfig.CreateGroundVisuals.Value) { if (flag2) { RestoreDlcFreeSpriteShape(); RebuildGroundVisual(val); } else { RebuildDlcFreeGroundVisual(val); } } else { ClearGroundVisual(); RestoreOriginalSpriteShape(); RestoreDlcFreeSpriteShape(); } if (flag2) { UpdateConnectorScenery(val); RebuildConnectorBridges(val); RebuildBackgroundDecor(val); } else { UpdateConnectorScenery(val); ClearBackgroundDecor(); RebuildConnectorBridges(val); } ClearVisualClones(); UpdateDlcFreeOnboardingPresentation(); if (rebuildPlacementGrid && (Object)(object)PlacementRegion.Instance != (Object)null) { PlacementRegion.Instance.CreateFloodFill(); if (PlacementRegion.Instance.Grid == null || PlacementRegion.Instance.Grid.Count == 0 || (HasActiveExpansion() && !LastFloodFillSucceeded)) { throw new InvalidOperationException("The placement grid rebuild did not complete."); } ReAddStructuresToPlacementGrid(); if (flag2) { Interaction_PurchaseLand.OccupyBridgeArea(); } } else if (rebuildPlacementGrid) { throw new InvalidOperationException("The placement region is not ready."); } Follower.Points = (Vector2[])(object)new Vector2[0]; return true; } catch (Exception ex) { if (flag) { RollbackCustomGeometry(collider, originalPath); } EvenMoreSpacePlugin.Log.LogError((object)("Failed while applying extra Woolhaven expansion: " + ex)); return false; } finally { _stepsOverride = stepsOverride2; _applying = false; } } internal static PolygonCollider2D ExpandCollider(PolygonCollider2D collider) { //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) int effectiveExtraSteps = GetEffectiveExtraSteps(); if (!IsBaseRoomCollider(collider) || effectiveExtraSteps <= 0 || !IsExpansionReadyForGeometry()) { LastGeometryExpansionSucceeded = true; return collider; } LastGeometryExpansionSucceeded = false; Vector2[] path = collider.GetPath(0); if (path == null || path.Length < 3) { return collider; } if (!TryBuildExpandedPath(((Component)collider).transform, path, effectiveExtraSteps, out var expandedPath, out var latestSegment, out var latestBounds)) { EvenMoreSpacePlugin.Log.LogError((object)"Could not repeat the vanilla Woolhaven land segments."); return collider; } collider.pathCount = 1; collider.SetPath(0, expandedPath); _lastExpansionCollider = collider; _lastAddedSegmentLocalPath = latestSegment; _lastAddedSegmentWorldBounds = latestBounds; LastGeometryExpansionSucceeded = true; DebugLog("Expanded collider with " + effectiveExtraSteps + " repeated vanilla segment(s) and " + expandedPath.Length + " boundary points."); return collider; } private static bool IsBaseRoomCollider(PolygonCollider2D collider) { if ((Object)(object)collider != (Object)null && (Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0 && (Object)(object)BiomeBaseManager.Instance.Room.Pieces[0] != (Object)null) { return (Object)(object)BiomeBaseManager.Instance.Room.Pieces[0].Collider == (Object)(object)collider; } return false; } private static void RestoreBaseRoomCollider(PolygonCollider2D collider) { //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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)collider == (Object)null) && !((Object)(object)BiomeBaseManager.Instance == (Object)null) && BiomeBaseManager.Instance.CachedColliderPoints != null) { collider.pathCount = 1; collider.SetPath(0, BiomeBaseManager.Instance.CachedColliderPoints); _lastExpansionCollider = null; _lastAddedSegmentLocalPath = null; _lastAddedSegmentWorldBounds = new Bounds(Vector3.zero, Vector3.zero); } } private static void SyncPlacementRegionCollider(PolygonCollider2D source) { //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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null || (Object)(object)PlacementRegion.Instance == (Object)null || (Object)(object)PlacementRegion.Instance.polygonCollider2D == (Object)null) { return; } PolygonCollider2D polygonCollider2D = PlacementRegion.Instance.polygonCollider2D; polygonCollider2D.pathCount = source.pathCount; for (int i = 0; i < source.pathCount; i++) { Vector2[] path = source.GetPath(i); Vector2[] array = (Vector2[])(object)new Vector2[path.Length]; for (int j = 0; j < path.Length; j++) { ref Vector2 reference = ref array[j]; reference = Vector2.op_Implicit(((Component)polygonCollider2D).transform.InverseTransformPoint(((Component)source).transform.TransformPoint(Vector2.op_Implicit(path[j])))); } polygonCollider2D.SetPath(i, array); } } private static bool ValidateCustomExpansionGeometry(PolygonCollider2D collider, int steps) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)collider == (Object)null || steps <= 0 || collider.pathCount <= 0) { return false; } Vector2[] path = collider.GetPath(0); if (path == null || path.Length < 3) { return false; } for (int i = 1; i <= steps; i++) { if (!TryGetTranslatedSegmentPath(i, ((Component)collider).transform, out var path2, out var worldBounds) || path2 == null || path2.Length < 3) { return false; } Vector2 point = Vector2.op_Implicit(((Component)collider).transform.InverseTransformPoint(((Bounds)(ref worldBounds)).center)); if (!IsPointInPolygon(point, path)) { EvenMoreSpacePlugin.Log.LogError((object)("DLC-free boundary validation rejected generated segment " + i + ".")); return false; } } return true; } private static void RollbackCustomGeometry(PolygonCollider2D collider, Vector2[] originalPath) { //IL_00b2: 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_00bc: 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) try { if ((Object)(object)collider != (Object)null && originalPath != null && originalPath.Length >= 3) { collider.pathCount = 1; collider.SetPath(0, originalPath); if ((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) { BiomeBaseManager.Instance.Room.Pieces[0].Collider = collider; BiomeBaseManager.Instance.Room.SetColliderAndUpdatePathfinding(); } SyncPlacementRegionCollider(collider); Physics2D.SyncTransforms(); } _lastExpansionCollider = null; _lastAddedSegmentLocalPath = null; _lastAddedSegmentWorldBounds = new Bounds(Vector3.zero, Vector3.zero); LastGeometryExpansionSucceeded = false; ClearGroundVisual(); RestoreDlcFreeSpriteShape(); } catch (Exception ex) { EvenMoreSpacePlugin.Log.LogError((object)("Could not roll back the failed DLC-free room rebuild: " + ex)); } } private static bool TryBuildExpandedPath(Transform target, IList basePath, int steps, out Vector2[] expandedPath, out Vector2[] latestSegment, out Bounds latestBounds) { //IL_0009: 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_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_0053: 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) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) expandedPath = null; latestSegment = null; latestBounds = new Bounds(Vector3.zero, Vector3.zero); if ((Object)(object)target == (Object)null || basePath == null || basePath.Count < 3) { return false; } List> list = new List>(); Vector2[] array = (Vector2[])(object)new Vector2[basePath.Count]; for (int i = 0; i < basePath.Count; i++) { ref Vector2 reference = ref array[i]; reference = basePath[i]; } list.Add(ToClipperPath(array)); for (int j = 1; j <= steps; j++) { if (!TryGetTranslatedSegmentPath(j, target, out var path, out var worldBounds)) { return false; } bool flag = false; if (!UsesVanillaDlcGeometry() && TryGetTranslatedDlcFreeFullTemplatePaths(j, target, out var paths, out var _)) { for (int k = 0; k < paths.Count; k++) { list.Add(ToClipperPath(paths[k])); } flag = paths.Count > 0; } if (!flag) { list.Add(ToClipperPath(path)); } latestSegment = path; latestBounds = worldBounds; } if (!TryUnionPaths(list, out var largest)) { return false; } expandedPath = FromClipperPath(largest); return expandedPath.Length >= 3; } private static bool TryGetTranslatedSegmentPath(int step, Transform target, out Vector2[] path, out Bounds worldBounds) { //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_000e: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_00ef: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) path = null; worldBounds = new Bounds(Vector3.zero, Vector3.zero); if (step <= 0 || (Object)(object)target == (Object)null) { return false; } if (!UsesVanillaDlcGeometry()) { return TryGetDlcFreeSegmentPath(step, target, out path, out worldBounds); } LandSlot[] landSlots = GetLandSlots(); if (landSlots == null || landSlots.Length == 0) { return false; } int segmentIndexForStep = GetSegmentIndexForStep(step, landSlots.Length); int num = (step - 1) / 3 + 1; PolygonCollider2D segmentCollider = landSlots[segmentIndexForStep].SegmentCollider; if ((Object)(object)segmentCollider == (Object)null || segmentCollider.pathCount == 0) { return false; } Vector2[] path2 = segmentCollider.GetPath(0); if (path2 == null || path2.Length < 3) { return false; } float num2 = GetVanillaRowOffset() * (float)num; path = (Vector2[])(object)new Vector2[path2.Length]; bool flag = false; for (int i = 0; i < path2.Length; i++) { Vector3 val = ((Component)segmentCollider).transform.TransformPoint(Vector2.op_Implicit(path2[i])); val.y += num2; ref Vector2 reference = ref path[i]; reference = Vector2.op_Implicit(target.InverseTransformPoint(val)); if (!flag) { worldBounds = new Bounds(val, Vector3.zero); flag = true; } else { ((Bounds)(ref worldBounds)).Encapsulate(val); } } return flag; } private static bool TryGetDlcFreeSegmentPath(int step, Transform target, out Vector2[] path, out Bounds worldBounds) { //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_000e: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) path = null; worldBounds = new Bounds(Vector3.zero, Vector3.zero); if (TryGetDlcFreeVanillaTemplatePath(step, target, out path, out worldBounds)) { return true; } PolygonCollider2D val = (((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) ? BiomeBaseManager.Instance.Room.Pieces[0].Collider : null); if ((Object)(object)val == (Object)null || BiomeBaseManager.Instance.CachedColliderPoints == null) { return false; } if (!TryGetCachedColliderWorldBounds(((Component)val).transform, out var bounds)) { return false; } float num = Mathf.Clamp(((Bounds)(ref bounds)).size.x * 0.78f, 16f, 32f); float num2 = Mathf.Clamp(((Bounds)(ref bounds)).size.y * 0.58f, 10f, 18f); float num3 = Mathf.Max(0.35f, 0.75f); int num4 = (step - 1) % 3; int num5 = (step - 1) / 3; bool flag = IsRightFirstRow(num5); float num6 = num - num3; float num7 = num4 switch { 1 => flag ? num6 : (0f - num6), 0 => 0f, _ => flag ? (0f - num6) : num6, }; float num8 = ((Bounds)(ref bounds)).min.y - (float)num5 * GetDlcFreeRowPitch(num2) + num3; float num9 = num8 - num2; float num10 = ((Bounds)(ref bounds)).center.x + num7; float num11 = num10 - num * 0.5f; float num12 = num10 + num * 0.5f; Vector3[] array = (Vector3[])(object)new Vector3[4] { new Vector3(num11, num9, 0f), new Vector3(num11, num8, 0f), new Vector3(num12, num8, 0f), new Vector3(num12, num9, 0f) }; path = (Vector2[])(object)new Vector2[array.Length]; for (int i = 0; i < array.Length; i++) { ref Vector2 reference = ref path[i]; reference = Vector2.op_Implicit(target.InverseTransformPoint(array[i])); } worldBounds = new Bounds(array[0], Vector3.zero); for (int j = 1; j < array.Length; j++) { ((Bounds)(ref worldBounds)).Encapsulate(array[j]); } return true; } private static float GetDlcFreeRowPitch(float fallbackHeight) { float num = 0f - GetVanillaRowOffset(); if (num >= 4f && num <= 48f) { return num; } return Mathf.Max(4f, fallbackHeight - Mathf.Max(0.35f, 0.75f)); } private static bool TryGetDlcFreeSegmentHorizontalOffset(int segmentIndex, out float offset) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0062: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) offset = 0f; if (segmentIndex == 0) { return true; } LandSlot[] landSlots = GetLandSlots(); if (landSlots == null || landSlots.Length < 3 || landSlots[0] == null || landSlots[segmentIndex] == null || (Object)(object)landSlots[0].SegmentCollider == (Object)null || (Object)(object)landSlots[segmentIndex].SegmentCollider == (Object)null) { return false; } Bounds colliderWorldBounds = GetColliderWorldBounds(landSlots[0].SegmentCollider); Bounds colliderWorldBounds2 = GetColliderWorldBounds(landSlots[segmentIndex].SegmentCollider); offset = ((Bounds)(ref colliderWorldBounds2)).center.x - ((Bounds)(ref colliderWorldBounds)).center.x; float num = Mathf.Max(64f, ((Bounds)(ref colliderWorldBounds2)).size.x * 4f); if (Mathf.Abs(offset) >= 0.5f) { return Mathf.Abs(offset) <= num; } return false; } private static bool TryGetTranslatedDlcFreeFullTemplatePaths(int step, Transform target, out List paths, out Bounds worldBounds) { //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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_009c: 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_00c2: 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) paths = new List(); worldBounds = new Bounds(Vector3.zero, Vector3.zero); if (step <= 0 || (Object)(object)target == (Object)null) { return false; } LandSlot[] landSlots = GetLandSlots(); if (landSlots == null || landSlots.Length < 3) { return false; } int segmentIndexForStep = GetSegmentIndexForStep(step, landSlots.Length); if (segmentIndexForStep < 0 || segmentIndexForStep >= landSlots.Length || landSlots[segmentIndexForStep] == null || (Object)(object)landSlots[segmentIndexForStep].FullCollider == (Object)null || landSlots[segmentIndexForStep].FullCollider.pathCount == 0) { return false; } PolygonCollider2D fullCollider = landSlots[segmentIndexForStep].FullCollider; Vector2[] path = fullCollider.GetPath(0); if (path == null || path.Length < 3) { return false; } Bounds colliderWorldBounds = GetColliderWorldBounds(fullCollider); if (((Bounds)(ref colliderWorldBounds)).size.x < 4f || ((Bounds)(ref colliderWorldBounds)).size.y < 4f || ((Bounds)(ref colliderWorldBounds)).size.x > 96f || ((Bounds)(ref colliderWorldBounds)).size.y > 48f) { return false; } PolygonCollider2D val = (((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) ? BiomeBaseManager.Instance.Room.Pieces[0].Collider : null); if ((Object)(object)val == (Object)null || !TryGetCachedColliderWorldBounds(((Component)val).transform, out var bounds)) { return false; } if (landSlots[0] == null || (Object)(object)landSlots[0].SegmentCollider == (Object)null) { return false; } Bounds colliderWorldBounds2 = GetColliderWorldBounds(landSlots[0].SegmentCollider); float num = Mathf.Max(0.35f, 0.75f); int num2 = (step - 1) / 3; float num3 = ((Bounds)(ref bounds)).min.y - (float)num2 * GetDlcFreeRowPitch(((Bounds)(ref colliderWorldBounds)).size.y) + num; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(((Bounds)(ref colliderWorldBounds2)).center.x, ((Bounds)(ref colliderWorldBounds)).max.y, 0f); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(((Bounds)(ref bounds)).center.x, num3, 0f); Vector3 val4 = val3 - val2; bool flag = false; for (int i = 0; i < fullCollider.pathCount; i++) { Vector2[] path2 = fullCollider.GetPath(i); if (path2 == null || path2.Length < 3) { continue; } Vector2[] array = (Vector2[])(object)new Vector2[path2.Length]; for (int j = 0; j < path2.Length; j++) { Vector3 val5 = ((Component)fullCollider).transform.TransformPoint(Vector2.op_Implicit(path2[j])) + val4; ref Vector2 reference = ref array[j]; reference = Vector2.op_Implicit(target.InverseTransformPoint(val5)); if (!flag) { worldBounds = new Bounds(val5, Vector3.zero); flag = true; } else { ((Bounds)(ref worldBounds)).Encapsulate(val5); } } paths.Add(array); } if (flag) { return paths.Count > 0; } return false; } private static bool TryGetDlcFreeVanillaTemplatePath(int step, Transform target, out Vector2[] path, out Bounds worldBounds) { //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_000e: 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_008f: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: 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) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) path = null; worldBounds = new Bounds(Vector3.zero, Vector3.zero); if (step <= 0 || (Object)(object)target == (Object)null) { return false; } LandSlot[] landSlots = GetLandSlots(); if (landSlots == null || landSlots.Length < 3) { return false; } int segmentIndexForStep = GetSegmentIndexForStep(step, landSlots.Length); if (segmentIndexForStep < 0 || segmentIndexForStep >= landSlots.Length || landSlots[segmentIndexForStep] == null || (Object)(object)landSlots[segmentIndexForStep].SegmentCollider == (Object)null || landSlots[segmentIndexForStep].SegmentCollider.pathCount == 0) { return false; } PolygonCollider2D segmentCollider = landSlots[segmentIndexForStep].SegmentCollider; Vector2[] path2 = segmentCollider.GetPath(0); if (path2 == null || path2.Length < 3) { return false; } Bounds colliderWorldBounds = GetColliderWorldBounds(segmentCollider); if (((Bounds)(ref colliderWorldBounds)).size.x < 4f || ((Bounds)(ref colliderWorldBounds)).size.y < 4f || ((Bounds)(ref colliderWorldBounds)).size.x > 48f || ((Bounds)(ref colliderWorldBounds)).size.y > 32f) { return false; } PolygonCollider2D val = (((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) ? BiomeBaseManager.Instance.Room.Pieces[0].Collider : null); if ((Object)(object)val == (Object)null || !TryGetCachedColliderWorldBounds(((Component)val).transform, out var bounds)) { return false; } float num = Mathf.Max(0.35f, 0.75f); int num2 = (step - 1) % 3; int num3 = (step - 1) / 3; float num4 = ((Bounds)(ref colliderWorldBounds)).size.x - num; if (!TryGetDlcFreeSegmentHorizontalOffset(segmentIndexForStep, out var offset)) { offset = ((num2 == 0) ? 0f : ((segmentIndexForStep == 1) ? (0f - num4) : num4)); } float num5 = ((Bounds)(ref bounds)).min.y - (float)num3 * GetDlcFreeRowPitch(((Bounds)(ref colliderWorldBounds)).size.y) + num; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(((Bounds)(ref bounds)).center.x + offset, num5 - ((Bounds)(ref colliderWorldBounds)).size.y * 0.5f, ((Bounds)(ref colliderWorldBounds)).center.z); Vector3 val3 = val2 - ((Bounds)(ref colliderWorldBounds)).center; path = (Vector2[])(object)new Vector2[path2.Length]; bool flag = false; for (int i = 0; i < path2.Length; i++) { Vector3 val4 = ((Component)segmentCollider).transform.TransformPoint(Vector2.op_Implicit(path2[i])) + val3; ref Vector2 reference = ref path[i]; reference = Vector2.op_Implicit(target.InverseTransformPoint(val4)); if (!flag) { worldBounds = new Bounds(val4, Vector3.zero); flag = true; } else { ((Bounds)(ref worldBounds)).Encapsulate(val4); } } return flag; } private static bool TryGetCachedColliderWorldBounds(Transform target, out Bounds bounds) { //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_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_0058: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_0074: 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_0094: 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) bounds = new Bounds(Vector3.zero, Vector3.zero); if ((Object)(object)target == (Object)null || (Object)(object)BiomeBaseManager.Instance == (Object)null || BiomeBaseManager.Instance.CachedColliderPoints == null || BiomeBaseManager.Instance.CachedColliderPoints.Length == 0) { return false; } Vector3 val = target.TransformPoint(Vector2.op_Implicit(BiomeBaseManager.Instance.CachedColliderPoints[0])); bounds = new Bounds(val, Vector3.zero); for (int i = 1; i < BiomeBaseManager.Instance.CachedColliderPoints.Length; i++) { ((Bounds)(ref bounds)).Encapsulate(target.TransformPoint(Vector2.op_Implicit(BiomeBaseManager.Instance.CachedColliderPoints[i]))); } return true; } private static float GetVanillaRowOffset() { //IL_0040: 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_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) //IL_005a: 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_0087: Unknown result type (might be due to invalid IL or missing references) LandSlot[] landSlots = GetLandSlots(); if (landSlots == null || landSlots.Length == 0 || (Object)(object)landSlots[0].SegmentCollider == (Object)null || (Object)(object)landSlots[^1].FullCollider == (Object)null) { return -23f; } Bounds colliderWorldBounds = GetColliderWorldBounds(landSlots[0].SegmentCollider); Bounds colliderWorldBounds2 = GetColliderWorldBounds(landSlots[^1].FullCollider); float num = ((Bounds)(ref colliderWorldBounds2)).min.y - ((Bounds)(ref colliderWorldBounds)).max.y + 0.35f; if (!(num < -4f)) { return 0f - Mathf.Max(4f, ((Bounds)(ref colliderWorldBounds)).size.y - 0.35f); } return num; } private static Bounds GetColliderWorldBounds(PolygonCollider2D collider) { //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_0081: 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_0042: 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_0060: 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_0050: Unknown result type (might be due to invalid IL or missing references) Bounds result = default(Bounds); ((Bounds)(ref result))..ctor(((Component)collider).transform.position, Vector3.zero); bool flag = false; for (int i = 0; i < collider.pathCount; i++) { Vector2[] path = collider.GetPath(i); for (int j = 0; j < path.Length; j++) { Vector3 val = ((Component)collider).transform.TransformPoint(Vector2.op_Implicit(path[j])); if (!flag) { ((Bounds)(ref result))..ctor(val, Vector3.zero); flag = true; } else { ((Bounds)(ref result)).Encapsulate(val); } } } return result; } private static bool TryUnionPaths(List> subjects, out List largest) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown largest = null; if (subjects == null || subjects.Count == 0 || subjects[0].Count < 3) { return false; } bool flag = Clipper.Orientation(subjects[0]); for (int i = 1; i < subjects.Count; i++) { if (Clipper.Orientation(subjects[i]) != flag) { subjects[i].Reverse(); } } Clipper val = new Clipper(0); val.StrictlySimple = true; ((ClipperBase)val).PreserveCollinear = true; ((ClipperBase)val).AddPaths(subjects, (PolyType)0, true); List> list = new List>(); if (!val.Execute((ClipType)1, list, (PolyFillType)1, (PolyFillType)1) || list.Count == 0) { return false; } largest = list[0]; double num = Math.Abs(GetClipperArea(largest)); for (int j = 1; j < list.Count; j++) { double num2 = Math.Abs(GetClipperArea(list[j])); if (num2 > num) { largest = list[j]; num = num2; } } largest = Clipper.CleanPolygon(largest, 1.0); if (largest == null || largest.Count < 3) { return false; } if (Clipper.Orientation(largest) != flag) { largest.Reverse(); } return true; } internal static Vector3 GetExpansionCameraPosition(Vector3 fallback) { //IL_0026: 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) //IL_002d: 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_0041: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_lastExpansionCollider == (Object)null)) { Vector3 size = ((Bounds)(ref _lastAddedSegmentWorldBounds)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 0.01f)) { Vector3 center = ((Bounds)(ref _lastAddedSegmentWorldBounds)).center; center.z = fallback.z; return center; } } return fallback; } private static Vector3 GetFreeExpansionFallbackPosition() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_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_00bc: 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) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) PolygonCollider2D val = (((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) ? BiomeBaseManager.Instance.Room.Pieces[0].Collider : null); Bounds bounds = new Bounds(Vector3.zero, Vector3.zero); if ((Object)(object)val != (Object)null && TryGetCachedColliderWorldBounds(((Component)val).transform, out bounds)) { return new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).min.y + 1.5f, 0f); } return Vector3.zero; } private static Vector3 GetNextMolePosition(int purchasedSteps, Vector3 fallback) { //IL_00ab: 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_00ef: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_014d: 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) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) Transform val2; if (!UsesVanillaDlcGeometry()) { PolygonCollider2D val = (((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) ? BiomeBaseManager.Instance.Room.Pieces[0].Collider : null); val2 = (((Object)(object)_lastExpansionCollider != (Object)null) ? ((Component)_lastExpansionCollider).transform : (((Object)(object)val != (Object)null) ? ((Component)val).transform : null)); } else { LandSlot[] landSlots = GetLandSlots(); if (landSlots == null || landSlots.Length == 0) { return fallback; } val2 = (((Object)(object)_lastExpansionCollider != (Object)null) ? ((Component)_lastExpansionCollider).transform : ((Component)landSlots[^1].FullCollider).transform); } if ((Object)(object)val2 == (Object)null) { return fallback; } Bounds worldBounds = new Bounds(Vector3.zero, Vector3.zero); int num = purchasedSteps % 3; bool flag = purchasedSteps >= EvenMoreSpaceConfig.MaxExtraSteps.Value; int step = ((num == 0 && !flag) ? (purchasedSteps + 1) : (purchasedSteps - num + 1)); if (flag && num == 0) { step = Mathf.Max(1, purchasedSteps - 2); num = 1; } if (!TryGetTranslatedSegmentPath(step, val2, out var _, out worldBounds)) { return fallback; } Vector3 center = ((Bounds)(ref worldBounds)).center; if (num == 0) { center.y = ((Bounds)(ref worldBounds)).max.y + 1.5f; } else { center.y = ((Bounds)(ref worldBounds)).center.y; } center.z = fallback.z; return center; } internal static void SchedulePopulationBackfill() { if (!_populationBackfillScheduled && !((Object)(object)EvenMoreSpacePlugin.Instance == (Object)null) && GetExtraSteps() > GetPopulatedSteps()) { _populationBackfillScheduled = true; ((MonoBehaviour)EvenMoreSpacePlugin.Instance).StartCoroutine(PopulationBackfillRoutine()); } } private static IEnumerator PopulationBackfillRoutine() { yield return null; try { PopulatePendingSegments(); } finally { _populationBackfillScheduled = false; } } private static void PopulatePendingSegments() { if ((Object)(object)PlacementRegion.Instance == (Object)null || PlacementRegion.Instance.structureBrain == null) { return; } int num = GetPopulatedSteps(); int extraSteps = GetExtraSteps(); if (!UsesVanillaDlcGeometry()) { if (GetPopulationRevision() < 1) { num = 0; SetPopulatedSteps(0); SetPopulationRevision(1); } for (int i = num + 1; i <= extraSteps && PopulateSegment(i); i++) { SetPopulatedSteps(i); } ScheduleDelayedVisualRepair(); } else { for (int j = num + 1; j <= extraSteps && PopulateSegment(j); j++) { SetPopulatedSteps(j); } if ((Object)(object)_lastExpansionCollider != (Object)null) { UpdateConnectorScenery(_lastExpansionCollider); } ScheduleDelayedVisualRepair(); } } internal static void ScheduleDelayedVisualRepair() { if (!_delayedVisualRepairScheduled && !((Object)(object)EvenMoreSpacePlugin.Instance == (Object)null) && HasActiveExpansion()) { _delayedVisualRepairScheduled = true; ((MonoBehaviour)EvenMoreSpacePlugin.Instance).StartCoroutine(DelayedVisualRepairRoutine()); } } private static IEnumerator DelayedVisualRepairRoutine() { yield return null; float[] delays = new float[3] { 0.5f, 1.5f, 3f }; for (int pass = 0; pass < delays.Length; pass++) { yield return (object)new WaitForSecondsRealtime(delays[pass]); try { PolygonCollider2D val = _lastExpansionCollider; if ((Object)(object)val == (Object)null && (Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) { val = BiomeBaseManager.Instance.Room.Pieces[0].Collider; } if ((Object)(object)val != (Object)null) { ForceBakeExpandedGround(); UpdateConnectorScenery(val); RebuildConnectorBridges(val); UpdateDlcFreeOnboardingPresentation(); } } catch (Exception ex) { EvenMoreSpacePlugin.Log.LogError((object)("Delayed connector visual repair pass " + (pass + 1).ToString() + " failed: " + ex)); } } _delayedVisualRepairScheduled = false; EvenMoreSpacePlugin.Log.LogInfo((object)"Completed delayed connector cleanup and wall-trim repair for the loaded expanded base."); } private static bool PopulateSegment(int step) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown LandSlot[] landSlots = GetLandSlots(); PolygonCollider2D val = (((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) ? BiomeBaseManager.Instance.Room.Pieces[0].Collider : null); if (landSlots == null || landSlots.Length == 0 || (Object)(object)val == (Object)null || (Object)(object)PlacementRegion.Instance == (Object)null || PlacementRegion.Instance.structureBrain == null) { return false; } int segmentIndexForStep = GetSegmentIndexForStep(step, landSlots.Length); if (segmentIndexForStep < 0 || segmentIndexForStep >= landSlots.Length || landSlots[segmentIndexForStep] == null) { return false; } GameObject val2 = new GameObject("EvenMoreSpace Segment Population Mask"); try { val2.transform.SetParent(((Component)val).transform, false); PolygonCollider2D val3 = val2.AddComponent(); if (!TryGetTranslatedSegmentPath(step, val2.transform, out var path, out var _)) { return false; } val3.pathCount = 1; val3.SetPath(0, path); ((Collider2D)val3).isTrigger = true; float num = ((segmentIndexForStep == 0) ? 1f : 0.75f); int value = EvenMoreSpaceConfig.ExtraSegmentWeedCount.Value; if (value > 0) { int num2 = Mathf.Max(1, Mathf.RoundToInt((float)value * 0.8f * num)); int num3 = Mathf.Max(num2 + 1, Mathf.RoundToInt((float)value * 1.2f * num) + 1); StructureManager.CreateWeeds((FollowerLocation)1, new List { PlacementRegion.Instance.structureBrain }, val3, Random.Range(num2, num3)); } if (landSlots[segmentIndexForStep].ResourcesToPlace != null) { StructureManager.PlaceRubble((FollowerLocation)1, landSlots[segmentIndexForStep].ResourcesToPlace, PlacementRegion.Instance.structureBrain, val3); } EvenMoreSpacePlugin.Log.LogInfo((object)("Populated extra Woolhaven segment " + step + " with vanilla weeds and rubble.")); return true; } catch (Exception ex) { EvenMoreSpacePlugin.Log.LogError((object)("Could not populate extra Woolhaven segment " + step.ToString() + ": " + ex)); return false; } finally { Object.Destroy((Object)(object)val2); } } private static void RebuildGroundVisual(PolygonCollider2D collider) { //IL_00aa: 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_00b4: Unknown result type (might be due to invalid IL or missing references) ClearGroundVisual(); int effectiveExtraSteps = GetEffectiveExtraSteps(); LandSlot[] landSlots = GetLandSlots(); if ((Object)(object)collider == (Object)null || landSlots == null || landSlots.Length == 0 || (Object)(object)landSlots[^1].Land == (Object)null) { return; } SpriteShapeController componentInChildren = landSlots[^1].Land.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { EvenMoreSpacePlugin.Log.LogError((object)"The final Woolhaven land SpriteShape was not found."); return; } CaptureOriginalSpriteShape(componentInChildren); if (effectiveExtraSteps <= 0) { RestoreOriginalSpriteShape(); } else if (!((Object)(object)collider != (Object)(object)_lastExpansionCollider)) { Vector2[] array = (Vector2[])(object)new Vector2[_originalSpriteShapePoints.Count]; for (int i = 0; i < array.Length; i++) { ref Vector2 reference = ref array[i]; reference = Vector2.op_Implicit(_originalSpriteShapePoints[i].Position); } if (!TryBuildExpandedPath(((Component)componentInChildren).transform, array, effectiveExtraSteps, out var expandedPath, out var _, out var _)) { EvenMoreSpacePlugin.Log.LogError((object)"Could not extend the Woolhaven SpriteShape over the extra segments."); return; } ApplyExpandedSpriteShape(componentInChildren, expandedPath, suppressConnectorBorders: true); DebugLog("Extended the vanilla Woolhaven SpriteShape across " + effectiveExtraSteps + " extra segment(s)."); } } private static void CaptureOriginalSpriteShape(SpriteShapeController controller) { //IL_004e: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_0078: 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 (!((Object)(object)_landSpriteShape == (Object)(object)controller) || _originalSpriteShapePoints == null || _originalSpriteShapePoints.Count <= 0) { _landSpriteShape = controller; _originalSpriteShapePoints = new List(); Spline spline = controller.spline; for (int i = 0; i < spline.GetPointCount(); i++) { _originalSpriteShapePoints.Add(new SpriteShapePointSnapshot { Position = spline.GetPosition(i), LeftTangent = spline.GetLeftTangent(i), RightTangent = spline.GetRightTangent(i), TangentMode = spline.GetTangentMode(i), Height = spline.GetHeight(i), SpriteIndex = spline.GetSpriteIndex(i), Corner = spline.GetCorner(i) }); } } } private static void ApplyExpandedSpriteShape(SpriteShapeController controller, Vector2[] points, bool suppressConnectorBorders) { //IL_0059: 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) Spline spline = controller.spline; List corridors = (suppressConnectorBorders ? GetConnectorCorridors(((Component)controller).transform, 6f, 6f) : new List()); int num = 0; spline.Clear(); spline.isOpenEnded = false; for (int i = 0; i < points.Length; i++) { spline.InsertPointAt(i, new Vector3(points[i].x, points[i].y, 0f)); spline.SetTangentMode(i, (ShapeTangentMode)0); bool flag = suppressConnectorBorders && ShouldSuppressConnectorBorder(points, i, ((Component)controller).transform, corridors); spline.SetHeight(i, flag ? 0.01f : 1f); spline.SetSpriteIndex(i, 0); spline.SetCorner(i, false); if (flag) { num++; } } controller.RefreshSpriteShape(); if (UsesVanillaDlcGeometry()) { ForceBakeExpandedGround(); } else { controller.BakeMesh(); WarmSpriteShapeRenderer(((Component)controller).GetComponent()); } DebugLog("Suppressed the expanded SpriteShape border at " + num + " connector boundary point(s)."); } private static void WarmSpriteShapeRenderer(SpriteShapeRenderer renderer) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null || (Object)(object)((Renderer)renderer).sharedMaterial == (Object)null || ((Renderer)renderer).isVisible) { return; } try { CommandBuffer val = new CommandBuffer(); val.name = "EvenMoreSpace offscreen ground warm-up"; val.GetTemporaryRT(0, 256, 256, 0); val.SetRenderTarget(RenderTargetIdentifier.op_Implicit(0)); val.DrawRenderer((Renderer)(object)renderer, ((Renderer)renderer).sharedMaterial); val.ReleaseTemporaryRT(0); Graphics.ExecuteCommandBuffer(val); val.Release(); } catch (Exception ex) { DebugLog("Could not warm the expanded SpriteShape renderer: " + ex.Message); } } internal static bool ForceBakeExpandedGround() { //IL_0121: Unknown result type (might be due to invalid IL or missing references) if (!EvenMoreSpaceConfig.CreateGroundVisuals.Value || !HasActiveExpansion()) { return false; } if (!UsesVanillaDlcGeometry() && ((Object)(object)_lastExpansionCollider == (Object)null || !LastGeometryExpansionSucceeded)) { return false; } if (!UsesVanillaDlcGeometry()) { PolygonCollider2D collider = (((Object)(object)BiomeBaseManager.Instance != (Object)null && (Object)(object)BiomeBaseManager.Instance.Room != (Object)null && BiomeBaseManager.Instance.Room.Pieces != null && BiomeBaseManager.Instance.Room.Pieces.Count > 0) ? BiomeBaseManager.Instance.Room.Pieces[0].Collider : null); RebuildDlcFreeGroundVisual(collider); if (!((Object)(object)_groundRoot != (Object)null)) { return _freeBaseSpriteShapeExpanded; } return true; } SpriteShapeController val = _landSpriteShape; if ((Object)(object)val == (Object)null) { LandSlot[] landSlots = GetLandSlots(); if (landSlots == null || landSlots.Length == 0 || (Object)(object)landSlots[^1].Land == (Object)null) { return false; } val = landSlots[^1].Land.GetComponentInChildren(true); } if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy) { return false; } try { val.RefreshSpriteShape(); val.BakeMesh(); SpriteShapeRenderer component = ((Component)val).GetComponent(); WarmSpriteShapeRenderer(component); DebugLog("Force-baked the expanded Woolhaven ground while its vanilla source bounds were offscreen."); return true; } catch (Exception ex) { EvenMoreSpacePlugin.Log.LogError((object)("Could not force-bake the expanded Woolhaven ground: " + ex)); return false; } } private static bool ShouldSuppressConnectorBorder(Vector2[] points, int index, Transform target, List corridors) { //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_0031: 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_0049: 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_0053: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_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_007c: 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_008b: 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_008f: Unknown result type (might be due to invalid IL or missing references) if (points == null || points.Length < 2 || (Object)(object)target == (Object)null || corridors == null || corridors.Count == 0) { return false; } Vector3 val = target.TransformPoint(Vector2.op_Implicit(points[index])); Vector3 start = target.TransformPoint(Vector2.op_Implicit(points[(index + points.Length - 1) % points.Length])); Vector3 end = target.TransformPoint(Vector2.op_Implicit(points[(index + 1) % points.Length])); for (int i = 0; i < corridors.Count; i++) { if (LineSegmentIntersectsBounds(start, val, corridors[i]) || LineSegmentIntersectsBounds(val, end, corridors[i])) { return true; } } return false; } private static bool LineSegmentIntersectsBounds(Vector3 start, Vector3 end, Bounds bounds) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0080: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Min(start.x, end.x); float num2 = Mathf.Max(start.x, end.x); float num3 = Mathf.Min(start.y, end.y); float num4 = Mathf.Max(start.y, end.y); if (num2 >= ((Bounds)(ref bounds)).min.x && num <= ((Bounds)(ref bounds)).max.x && num4 >= ((Bounds)(ref bounds)).min.y) { return num3 <= ((Bounds)(ref bounds)).max.y; } return false; } private static void RestoreOriginalSpriteShape() { if (!((Object)(object)_landSpriteShape == (Object)null) && _originalSpriteShapePoints != null && _originalSpriteShapePoints.Count != 0) { RestoreSpriteShapeSnapshot(_landSpriteShape, _originalSpriteShapePoints); } } private static void RestoreSpriteShapeSnapshot(SpriteShapeController controller, List points) { //IL_0039: 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_0055: 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_00ab: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)controller == (Object)null || points == null || points.Count == 0) { return; } Spline spline = controller.spline; spline.Clear(); spline.isOpenEnded = false; for (int i = 0; i < points.Count; i++) { SpriteShapePointSnapshot spriteShapePointSnapshot = points[i]; spline.InsertPointAt(i, spriteShapePointSnapshot.Position); spline.SetTangentMode(i, spriteShapePointSnapshot.TangentMode); spline.SetLeftTangent(i, spriteShapePointSnapshot.LeftTangent); spline.SetRightTangent(i, spriteShapePointSnapshot.RightTangent); spline.SetHeight(i, spriteShapePointSnapshot.Height); spline.SetSpriteIndex(i, spriteShapePointSnapshot.SpriteIndex); spline.SetCorner(i, spriteShapePointSnapshot.Corner); } controller.RefreshSpriteShape(); try { controller.BakeMesh(); } catch (Exception ex) { DebugLog("Could not rebake the restored SpriteShape: " + ex.Message); } } private static void RestoreConnectorScenery() { for (int i = 0; i < HiddenConnectorRenderers.Count; i++) { if ((Object)(object)HiddenConnectorRenderers[i] != (Object)null) { HiddenConnectorRenderers[i].enabled = true; } } HiddenConnectorRenderers.Clear(); } private static List GetConnectorCorridorsForStep(int step, Transform target, float width, float height) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_003f: 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) List list = new List(); if (!TryGetTranslatedSegmentPath(step, target, out var _, out var worldBounds)) { return list; } list.Add(new Bounds(new Vector3(((Bounds)(ref worldBounds)).center.x, ((Bounds)(ref worldBounds)).max.y, 0f), new Vector3(width, height, 100f))); return list; } internal static bool IsInsideModdedPlot(Vector3 worldPosition) { //IL_002c: 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) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveExpansion() || (Object)(object)_lastExpansionCollider == (Object)null) { return false; } List moddedPlotInteriors = GetModdedPlotInteriors(((Component)_lastExpansionCollider).transform); for (int i = 0; i < moddedPlotInteriors.Count; i++) { Bounds val = moddedPlotInteriors[i]; if (((Bounds)(ref val)).Contains(worldPosition)) { return true; } } return false; } private static void UpdateConnectorScenery(PolygonCollider2D target) { //IL_00ee: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Invalid comparison between Unknown and I4 //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Invalid comparison between Unknown and I4 //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Invalid comparison between Unknown and I4 //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Invalid comparison between Unknown and I4 //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) if (!EvenMoreSpaceConfig.ClearConnectorScenery.Value || GetEffectiveExtraSteps() <= 0 || (Object)(object)target == (Object)null) { return; } LandSlot[] landSlots = GetLandSlots(); bool flag = UsesVanillaDlcGeometry(); if (flag && (landSlots == null || landSlots.Length == 0 || (Object)(object)landSlots[^1].Land == (Object)null)) { return; } List connectorCorridors = GetConnectorCorridors(((Component)target).transform, 6f, 6f); if (connectorCorridors.Count == 0) { return; } int num = RemoveConnectorResourceStructures(connectorCorridors); if (num > 0) { EvenMoreSpacePlugin.Log.LogInfo((object)("Removed " + num + " generated resource obstruction(s) from expanded bridge entrances.")); } Bounds interior; bool flag2 = TryGetFirstModdedPlotInterior(((Component)target).transform, out interior); List moddedPlotInteriors = GetModdedPlotInteriors(((Component)target).transform); Transform finalLandRoot = (flag ? landSlots[^1].Land.transform : null); Renderer[] array = Object.FindObjectsOfType(); int num2 = 0; List list = new List(); for (int i = 0; i < connectorCorridors.Count; i++) { Bounds corridor = connectorCorridors[i]; List list2 = new List(); foreach (Renderer val in array) { if ((Object)(object)val == (Object)null || !val.enabled || !((Component)val).gameObject.activeInHierarchy || ((Component)val).gameObject.scene != ((Component)target).gameObject.scene || ((Object)(object)_persistentMole != (Object)null && ((Component)val).transform.IsChildOf(((Component)_persistentMole).transform)) || ((Object)(object)_connectorBridgeRoot != (Object)null && ((Component)val).transform.IsChildOf(_connectorBridgeRoot.transform)) || ((Object)(object)_backgroundDecorRoot != (Object)null && ((Component)val).transform.IsChildOf(_backgroundDecorRoot.transform)) || ((Object)(object)_freeGroundShapeRoot != (Object)null && ((Component)val).transform.IsChildOf(_freeGroundShapeRoot.transform))) { continue; } Structure componentInParent = ((Component)val).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && componentInParent.Structure_Info != null) { TYPES type = componentInParent.Structure_Info.Type; if ((int)type != 62 && (int)type != 16 && (int)type != 61 && (int)type != 159) { continue; } } Bounds bounds = val.bounds; string text = GetTransformPath(((Component)val).transform, null).ToLowerInvariant(); bool flag3 = text.Contains("tree") || text.Contains("wall") || text.Contains("grass") || text.Contains("bush") || text.Contains("plant") || text.Contains("shrub") || text.Contains("weed") || text.Contains("foliage") || text.Contains("fern") || text.Contains("flower") || text.Contains("crook") || text.Contains("rock") || text.Contains("stump") || text.Contains("log") || text.Contains("boulder"); bool flag4 = false; for (int k = 0; k < moddedPlotInteriors.Count; k++) { if (((Bounds)(ref bounds)).Intersects(moddedPlotInteriors[k])) { flag4 = (flag ? IsSafeFirstPlotScenery(val, finalLandRoot, text) : IsSafeCustomPlotScenery(val, text)); if (flag4) { break; } } } if (i == 0 && flag2 && ((Bounds)(ref bounds)).Intersects(interior)) { flag4 = (flag ? IsSafeFirstPlotScenery(val, finalLandRoot, text) : IsSafeCustomPlotScenery(val, text)); } bool flag5 = ((Bounds)(ref bounds)).Intersects(corridor) || flag4; float num3 = (flag4 ? 40f : 24f); if ((flag3 || flag4) && flag5 && !(((Bounds)(ref bounds)).size.x > num3) && !(((Bounds)(ref bounds)).size.y > num3) && (!(((Bounds)(ref bounds)).size.x < 0.25f) || !(((Bounds)(ref bounds)).size.y < 0.25f)) && !HiddenConnectorRenderers.Contains(val)) { list2.Add(val); } } list2.Sort(delegate(Renderer left, Renderer right) { //IL_0040: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006c: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) string path = GetTransformPath(((Component)left).transform, null).ToLowerInvariant(); string path2 = GetTransformPath(((Component)right).transform, null).ToLowerInvariant(); int connectorObstructionPriority = GetConnectorObstructionPriority(path); int connectorObstructionPriority2 = GetConnectorObstructionPriority(path2); if (connectorObstructionPriority != connectorObstructionPriority2) { return connectorObstructionPriority.CompareTo(connectorObstructionPriority2); } Bounds bounds2 = left.bounds; Vector3 val3 = ((Bounds)(ref bounds2)).center - ((Bounds)(ref corridor)).center; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; Bounds bounds3 = right.bounds; Vector3 val4 = ((Bounds)(ref bounds3)).center - ((Bounds)(ref corridor)).center; return sqrMagnitude.CompareTo(((Vector3)(ref val4)).sqrMagnitude); }); int num4 = ((i == 0) ? 1024 : 128); int num5 = Mathf.Min(num4, list2.Count); for (int num6 = 0; num6 < num5; num6++) { Renderer val2 = list2[num6]; val2.enabled = false; HiddenConnectorRenderers.Add(val2); num2++; DebugLog("Hid connector scenery renderer " + ((Object)((Component)val2).gameObject).name + "."); } list.Add(num5.ToString()); } EvenMoreSpacePlugin.Log.LogInfo((object)("Cleared " + num2 + " frontier scenery renderer(s) across " + connectorCorridors.Count + " extra connector(s) [" + (flag ? "vanilla" : "DLC-free") + "; per connector: " + string.Join(", ", list.ToArray()) + "].")); } private static int RemoveConnectorResourceStructures(IList corridors) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Invalid comparison between Unknown and I4 //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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) if (corridors == null || corridors.Count == 0) { return 0; } TYPES[] array = (TYPES[])(object)new TYPES[4] { (TYPES)16, (TYPES)61, (TYPES)159, (TYPES)62 }; List list = new List(); for (int i = 0; i < array.Length; i++) { List allStructuresOfType = StructureManager.GetAllStructuresOfType(array[i], false, true); if (allStructuresOfType != null) { list.AddRange(allStructuresOfType); } } int num = 0; HashSet hashSet = new HashSet(); for (int j = 0; j < list.Count; j++) { StructureBrain val = list[j]; if (val == null || val.Data == null || (int)val.Data.Location != 1 || hashSet.Contains(val.Data.ID)) { continue; } float num2 = Mathf.Max(1f, (float)Mathf.Max(((Vector2Int)(ref val.Data.Bounds)).x, ((Vector2Int)(ref val.Data.Bounds)).y)); bool flag = false; for (int k = 0; k < corridors.Count; k++) { Bounds val2 = corridors[k]; ((Bounds)(ref val2)).Expand(new Vector3(num2 + 2f, num2 + 2f, 0f)); if (((Bounds)(ref val2)).Contains(val.Data.Position)) { flag = true; break; } } if (flag) { try { hashSet.Add(val.Data.ID); val.ForceRemoved = true; val.Remove(); num++; } catch (Exception ex) { DebugLog("Could not remove a generated bridge obstruction: " + ex.Message); } } } return num; } private static bool TryGetFirstModdedPlotInterior(Transform target, out Bounds interior) { //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_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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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) interior = new Bounds(Vector3.zero, Vector3.zero); if (!TryGetTranslatedSegmentPath(1, target, out var _, out var worldBounds)) { return false; } float num = Mathf.Max(1f, ((Bounds)(ref worldBounds)).size.x - 2.5f); float num2 = Mathf.Max(1f, ((Bounds)(ref worldBounds)).size.y - 2.5f); interior = new Bounds(((Bounds)(ref worldBounds)).center, new Vector3(num, num2, 100f)); return true; } private static List GetModdedPlotInteriors(Transform target) { //IL_0096: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_0056: 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_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) List list = new List(); for (int i = 1; i <= GetEffectiveExtraSteps(); i++) { if (TryGetTranslatedSegmentPath(i, target, out var _, out var worldBounds)) { if (!UsesVanillaDlcGeometry() && TryGetTranslatedDlcFreeFullTemplatePaths(i, target, out var _, out var worldBounds2)) { float num = Mathf.Max(1f, ((Bounds)(ref worldBounds2)).size.x - 2.5f); float num2 = Mathf.Max(1f, ((Bounds)(ref worldBounds2)).size.y - 2.5f); list.Add(new Bounds(((Bounds)(ref worldBounds2)).center, new Vector3(num, num2, 100f))); } else { float num3 = Mathf.Max(1f, ((Bounds)(ref worldBounds)).size.x - 2.5f); float num4 = Mathf.Max(1f, ((Bounds)(ref worldBounds)).size.y - 2.5f); list.Add(new Bounds(((Bounds)(ref worldBounds)).center, new Vector3(num3, num4, 100f))); } } } return list; } private static bool IsSafeFirstPlotScenery(Renderer renderer, Transform finalLandRoot, string path) { if ((Object)(object)renderer == (Object)null || (Object)(object)finalLandRoot == (Object)null || !((Component)renderer).transform.IsChildOf(finalLandRoot)) { return false; } if ((Object)(object)((Component)renderer).GetComponentInParent() != (Object)null || (Object)(object)((Component)renderer).GetComponentInParent() != (Object)null) { return false; } string[] array = new string[20] { "floor", "ground", "snow", "fog", "mist", "particle", "light", "shadow", "mole", "gofer", "purchase", "bridge", "portal", "door", "shrine", "sign", "building", "structure", "collider", "spriteshape" }; for (int i = 0; i < array.Length; i++) { if (path.Contains(array[i])) { return false; } } return true; } private static bool IsSafeCustomPlotScenery(Renderer renderer, string path) { if ((Object)(object)renderer == (Object)null || (Object)(object)((Component)renderer).GetComponentInParent() != (Object)null || (Object)(object)((Component)renderer).GetComponentInParent() != (Object)null) { return false; } string[] array = new string[21] { "floor", "ground", "snow", "fog", "mist", "particle", "light", "shadow", "mole", "gofer", "purchase", "bridge", "portal", "door", "shrine", "sign", "building", "structure", "collider", "spriteshape", "path" }; for (int i = 0; i < array.Length; i++) { if (path.Contains(array[i])) { return false; } } if (!path.Contains("tree") && !path.Contains("wall") && !path.Contains("grass") && !path.Contains("bush") && !path.Contains("plant") && !path.Contains("shrub") && !path.Contains("weed") && !path.Contains("foliage") && !path.Contains("fern") && !path.Contains("flower") && !path.Contains("crook") && !path.Contains("rock") && !path.Contains("boulder") && !path.Contains("stump")) { return path.Contains("log"); } return true; } private static List GetConnectorCorridors(Transform target, float width, float height) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) List list = new List(); int effectiveExtraSteps = GetEffectiveExtraSteps(); if ((Object)(object)target == (Object)null || effectiveExtraSteps <= 0) { return list; } for (int i = 1; i <= effectiveExtraSteps; i += 3) { List connectorCorridorsForStep = GetConnectorCorridorsForStep(i, target, width, height); for (int j = 0; j < connectorCorridorsForStep.Count; j++) { list.Add(connectorCorridorsForStep[j]); } } return list; } private static int GetConnectorObstructionPriority(string path) { if (path.Contains("tree")) { return 0; } if (path.Contains("wall")) { return 1; } if (path.Contains("bush") || path.Contains("plant") || path.Contains("shrub")) { return 2; } if (path.Contains("rock") || path.Contains("boulder") || path.Contains("stump") || path.Contains("log")) { return 3; } return 3; } private static void RebuildBackgroundDecor(PolygonCollider2D target) { //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) ClearBackgroundDecor(); int effectiveExtraSteps = GetEffectiveExtraSteps(); int value = EvenMoreSpaceConfig.MaxVisualClones.Value; LandSlot[] landSlots = GetLandSlots(); if (!UsesVanillaDlcGeometry() || !EvenMoreSpaceConfig.DuplicateBackgroundDecor.Value || effectiveExtraSteps <= 0 || value <= 0 || (Object)(object)target == (Object)null || landSlots == null || landSlots.Length < 3 || (Object)(object)landSlots[^1].Land == (Object)null) { return; } GameObject land = landSlots[^1].Land; SpriteRenderer[] componentsInChildren = land.GetComponentsInChildren(true); List list = new List(); for (int i = 0; i < componentsInChildren.Length; i++) { if (IsSafeBackgroundDecor(componentsInChildren[i], land.transform)) { list.Add(componentsInChildren[i]); } } if (list.Count == 0) { componentsInChildren = Object.FindObjectsOfType(); for (int j = 0; j < componentsInChildren.Length; j++) { if (IsSafeBackgroundDecor(componentsInChildren[j], null)) { list.Add(componentsInChildren[j]); } } } list.Sort(delegate(SpriteRenderer left, SpriteRenderer right) { //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_0009: 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_001c: 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) //IL_002e: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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) Bounds bounds = ((Renderer)left).bounds; float x = ((Bounds)(ref bounds)).size.x; Bounds bounds2 = ((Renderer)left).bounds; float value2 = x * ((Bounds)(ref bounds2)).size.y; Bounds bounds3 = ((Renderer)right).bounds; float x2 = ((Bounds)(ref bounds3)).size.x; Bounds bounds4 = ((Renderer)right).bounds; return (x2 * ((Bounds)(ref bounds4)).size.y).CompareTo(value2); }); if (list.Count == 0) { EvenMoreSpacePlugin.Log.LogWarning((object)"No active Woolhaven tree, bush, or plant sprites were available for extra background decor."); return; } Transform parent = land.transform.parent; _backgroundDecorRoot = new GameObject("EvenMoreSpace Background Decor"); if ((Object)(object)parent != (Object)null) { _backgroundDecorRoot.transform.SetParent(parent, false); } int num = 0; for (int num2 = 1; num2 <= effectiveExtraSteps; num2++) { if (num >= value) { break; } if (!TryGetTranslatedSegmentPath(num2, ((Component)target).transform, out var path, out var worldBounds)) { continue; } int num3 = Mathf.Min(4, list.Count); for (int num4 = 0; num4 < num3; num4++) { if (num >= value) { break; } int index = ((num4 == 0) ? (num2 % Mathf.Min(list.Count, 16)) : ((num2 * 11 + num4 * 17) % list.Count)); SpriteRenderer val = list[index]; if (TryGetDecorPosition(num2, num4, worldBounds, path, ((Component)target).transform, out var position)) { position.z = ((Component)val).transform.position.z; CreateSpriteVisual(val, position, _backgroundDecorRoot.transform, "EvenMoreSpace decor " + num2 + " " + num4); num++; } } } EvenMoreSpacePlugin.Log.LogInfo((object)("Added " + num + " bare SpriteRenderer Woolhaven background decor clone(s) from " + list.Count + " active candidate(s).")); } private static bool IsSafeBackgroundDecor(SpriteRenderer renderer, Transform root) { //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_0037: 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_0061: 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) if ((Object)(object)renderer == (Object)null || (Object)(object)renderer.sprite == (Object)null || !((Renderer)renderer).enabled || !((Component)renderer).gameObject.activeInHierarchy) { return false; } Bounds bounds = ((Renderer)renderer).bounds; float num = ((Bounds)(ref bounds)).size.x * ((Bounds)(ref bounds)).size.y; if (num < 0.12f || num > 45f || ((Bounds)(ref bounds)).size.x > 9f || ((Bounds)(ref bounds)).size.y > 11f) { return false; } string text = GetTransformPath(((Component)renderer).transform, root).ToLowerInvariant(); string[] array = new string[24] { "wall", "floor", "ground", "border", "collider", "sign", "portal", "door", "mole", "gofer", "light", "particle", "mist", "fog", "bridge", "shrine", "building", "structure", "purchase", "resource", "shadow", "size guide", "spriteshape", "path" }; for (int i = 0; i < array.Length; i++) { if (text.Contains(array[i])) { return false; } } string[] array2 = new string[13] { "tree", "bush", "grass", "flower", "rock", "shrub", "plant", "stump", "log", "fern", "weed", "foliage", "crook" }; for (int j = 0; j < array2.Length; j++) { if (text.Contains(array2[j])) { return true; } } return false; } private static bool TryGetDecorPosition(int step, int decorIndex, Bounds bounds, Vector2[] localPath, Transform target, out Vector3 position) { //IL_003a: 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_0057: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_00b2: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_0098: 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) float[] array = new float[8] { -0.28f, 0.24f, -0.08f, 0.32f, -0.34f, 0.12f, 0.02f, -0.18f }; float[] array2 = new float[8] { 0.12f, 0.18f, -0.2f, -0.12f, -0.28f, 0.3f, -0.04f, 0.26f }; Vector3 val = default(Vector3); for (int i = 0; i < array.Length; i++) { int num = (step * 3 + decorIndex * 2 + i) % array.Length; ((Vector3)(ref val))..ctor(((Bounds)(ref bounds)).center.x + ((Bounds)(ref bounds)).size.x * array[num], ((Bounds)(ref bounds)).center.y + ((Bounds)(ref bounds)).size.y * array2[num], 0f); Vector2 point = Vector2.op_Implicit(target.InverseTransformPoint(val)); if (IsPointInPolygon(point, localPath)) { position = val; return true; } } position = ((Bounds)(ref bounds)).center; return IsPointInPolygon(Vector2.op_Implicit(target.InverseTransformPoint(position)), localPath); } private static void RebuildConnectorBridges(PolygonCollider2D target) { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0233: 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) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) int effectiveExtraSteps = GetEffectiveExtraSteps(); if (!EvenMoreSpaceConfig.DuplicateConnectorBridge.Value || effectiveExtraSteps <= 0 || (Object)(object)target == (Object)null || (Object)(object)DLCLandController.Instance == (Object)null) { ClearConnectorBridges(); return; } GameObject val = null; FieldInfo[] array = new FieldInfo[2] { DLCLandEnabledField, DLCLandDisabledField }; for (int i = 0; i < array.Length; i++) { if (!((Object)(object)val == (Object)null)) { break; } if (array[i] == null || !(array[i].GetValue(DLCLandController.Instance) is GameObject[] array2)) { continue; } for (int j = 0; j < array2.Length; j++) { if ((Object)(object)array2[j] != (Object)null && (Object)(object)array2[j].GetComponentInChildren(true) != (Object)null) { val = array2[j]; break; } } } if ((Object)(object)val == (Object)null) { EvenMoreSpacePlugin.Log.LogWarning((object)"Woolhaven's SHOW DLC connector visuals were not found; extra bridge copies were skipped."); return; } SpriteShapeRenderer componentInChildren = val.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { return; } ClearConnectorBridgeChildren(); Bounds bounds = ((Renderer)componentInChildren).bounds; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds)).center.z); SpriteRenderer[] componentsInChildren = val.GetComponentsInChildren(true); if ((Object)(object)_connectorBridgeRoot == (Object)null) { _connectorBridgeRoot = GameObject.Find("EvenMoreSpace Connector Bridges"); } if ((Object)(object)_connectorBridgeRoot == (Object)null) { _connectorBridgeRoot = new GameObject("EvenMoreSpace Connector Bridges"); } _connectorBridgeRoot.transform.SetParent(((Component)target).transform, false); int num = 0; Vector3 val3 = default(Vector3); for (int k = 1; k <= effectiveExtraSteps; k += 3) { if (!TryGetTranslatedSegmentPath(k, ((Component)target).transform, out var _, out var worldBounds)) { continue; } ((Vector3)(ref val3))..ctor(((Bounds)(ref worldBounds)).center.x, ((Bounds)(ref worldBounds)).max.y, val2.z); Vector3 val4 = val3 - val2; for (int l = 0; l < componentsInChildren.Length; l++) { SpriteRenderer val5 = componentsInChildren[l]; if ((Object)(object)val5 == (Object)null || (Object)(object)val5.sprite == (Object)null) { continue; } string path2 = GetTransformPath(((Component)val5).transform, val.transform).ToLowerInvariant(); if (IsConnectorTrimPath(path2)) { Bounds bounds2 = ((Renderer)val5).bounds; if (!(((Bounds)(ref bounds2)).size.x > 20f) && !(((Bounds)(ref bounds2)).size.y > 20f)) { SpriteRenderer val6 = CreateSpriteVisual(val5, ((Component)val5).transform.position + val4, _connectorBridgeRoot.transform, "EvenMoreSpace connector " + ((k - 1) / 3 + 1) + " " + l); ((Renderer)val6).sortingOrder = ((Renderer)val5).sortingOrder + 2; num++; } } } } EvenMoreSpacePlugin.Log.LogInfo((object)("Added " + num + " bare SpriteRenderer Woolhaven connector-trim sprite(s) for the " + (UsesVanillaDlcGeometry() ? "vanilla" : "DLC-free") + " expansion; no SpriteShape was cloned.")); } private static bool IsConnectorTrimPath(string path) { if (!(path == "wall (1)") && !path.StartsWith("wall (1)/") && !path.Contains("/wall (1)/") && !(path == "wall (2)") && !path.StartsWith("wall (2)/") && !path.Contains("/wall (2)/") && !(path == "top (2)") && !path.EndsWith("/top (2)") && !(path == "top (3)")) { return path.EndsWith("/top (3)"); } return true; } private static void ClearConnectorBridges() { if ((Object)(object)_connectorBridgeRoot == (Object)null) { _connectorBridgeRoot = GameObject.Find("EvenMoreSpace Connector Bridges"); } if ((Object)(object)_connectorBridgeRoot != (Object)null) { Object.Destroy((Object)(object)_connectorBridgeRoot); _connectorBridgeRoot = null; } } private static void ClearConnectorBridgeChildren() { if ((Object)(object)_connectorBridgeRoot == (Object)null) { _connectorBridgeRoot = GameObject.Find("EvenMoreSpace Connector Bridges"); } if ((Object)(object)_connectorBridgeRoot != (Object)null) { ClearChildren(_connectorBridgeRoot.transform); } } private static bool IsPointInPolygon(Vector2 point, Vector2[] polygon) { //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) bool flag = false; int num = 0; int num2 = polygon.Length - 1; while (num < polygon.Length) { Vector2 val = polygon[num]; Vector2 val2 = polygon[num2]; if (val.y > point.y != val2.y > point.y && point.x < (val2.x - val.x) * (point.y - val.y) / (val2.y - val.y) + val.x) { flag = !flag; } num2 = num++; } return flag; } private static SpriteRenderer CreateSpriteVisual(SpriteRenderer source, Vector3 worldPosition, Transform parent, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002b: 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_0058: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_00f1: 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) GameObject val = new GameObject(name); val.layer = ((Component)source).gameObject.layer; val.transform.SetParent(parent, false); val.transform.position = worldPosition; val.transform.rotation = ((Component)source).transform.rotation; Vector3 val2 = (((Object)(object)parent != (Object)null) ? parent.lossyScale : Vector3.one); Vector3 lossyScale = ((Component)source).transform.lossyScale; val.transform.localScale = new Vector3((Mathf.Abs(val2.x) > 0.0001f) ? (lossyScale.x / val2.x) : lossyScale.x, (Mathf.Abs(val2.y) > 0.0001f) ? (lossyScale.y / val2.y) : lossyScale.y, (Mathf.Abs(val2.z) > 0.0001f) ? (lossyScale.z / val2.z) : lossyScale.z); SpriteRenderer val3 = val.AddComponent(); val3.sprite = source.sprite; val3.color = source.color; val3.flipX = source.flipX; val3.flipY = source.flipY; ((Renderer)val3).sharedMaterial = ((Renderer)source).sharedMaterial; ((Renderer)val3).sortingLayerID = ((Renderer)source).sortingLayerID; ((Renderer)val3).sortingOrder = ((Renderer)source).sortingOrder; ((Renderer)val3).enabled = true; return val3; } private static string GetTransformPath(Transform transform, Transform root) { string text = (((Object)(object)transform != (Object)null) ? ((Object)transform).name : string.Empty); Transform val = (((Object)(object)transform != (Object)null) ? transform.parent : null); while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { text = ((Object)val).name + "/" + text; val = val.parent; } return text; } private static void ClearBackgroundDecor() { if ((Object)(object)_backgroundDecorRoot == (Object)null) { _backgroundDecorRoot = GameObject.Find("EvenMoreSpace Background Decor"); } if ((Object)(object)_backgroundDecorRoot != (Object)null) { Object.Destroy((Object)(object)_backgroundDecorRoot); _backgroundDecorRoot = null; } } private static void ClearGroundVisual() { if ((Object)(object)_groundRoot == (Object)null) { _groundRoot = GameObject.Find("EvenMoreSpace Ground"); } if ((Object)(object)_groundRoot != (Object)null) { Object.Destroy((Object)(object)_groundRoot); _groundRoot = null; } if ((Object)(object)_freeGroundShapeRoot == (Object)null) { _freeGroundShapeRoot = GameObject.Find("EvenMoreSpace DLC-Free Ground Shape"); } if ((Object)(object)_freeGroundShapeRoot != (Object)null) { Object.Destroy((Object)(object)_freeGroundShapeRoot); _freeGroundShapeRoot = null; } } private static void RebuildDlcFreeGroundVisual(PolygonCollider2D collider) { //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Expected O, but got Unknown //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Expected O, but got Unknown //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Expected O, but got Unknown //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) ClearGroundVisual(); int effectiveExtraSteps = GetEffectiveExtraSteps(); if ((Object)(object)collider == (Object)null) { return; } SpriteShapeController dlcFreeGroundShape = GetDlcFreeGroundShape(); if ((Object)(object)dlcFreeGroundShape != (Object)null && effectiveExtraSteps > 0) { Vector2[] path = collider.GetPath(0); if (path != null && path.Length >= 3) { CaptureDlcFreeSpriteShape(dlcFreeGroundShape); Vector2[] array = (Vector2[])(object)new Vector2[path.Length]; for (int i = 0; i < path.Length; i++) { Vector3 val = ((Component)collider).transform.TransformPoint(Vector2.op_Implicit(path[i])); Vector3 val2 = ((Component)dlcFreeGroundShape).transform.InverseTransformPoint(val); ref Vector2 reference = ref array[i]; reference = new Vector2(val2.x, val2.y); } NormalizeDlcFreeSpriteShapeWinding(dlcFreeGroundShape, dlcFreeGroundShape, array); SpriteShapeRenderer component = ((Component)dlcFreeGroundShape).GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = true; } _freeBaseSpriteShapeExpanded = true; try { ApplyExpandedSpriteShape(dlcFreeGroundShape, array, suppressConnectorBorders: true); if (_freeBaseSpriteShapeSortingCaptured && (Object)(object)component != (Object)null) { ((Renderer)component).sortingOrder = _originalFreeSpriteShapeSortingOrder - 1; } } catch (Exception ex) { RestoreDlcFreeSpriteShape(); DebugLog("Could not bake the in-place DLC-free SpriteShape: " + ex.Message); } if (_freeBaseSpriteShapeExpanded && (Object)(object)component != (Object)null && IsSpriteShapeVisualUsable(component, ((Collider2D)collider).bounds)) { EvenMoreSpacePlugin.Log.LogInfo((object)("Extended the original base-game SpriteShape across " + effectiveExtraSteps + " DLC-free extra segment(s) without creating a second floor layer.")); return; } RestoreDlcFreeSpriteShape(); EvenMoreSpacePlugin.Log.LogWarning((object)"The DLC-free SpriteShape baked without a usable expanded renderer; using the segment ground fallback."); } } if (effectiveExtraSteps <= 0) { RestoreDlcFreeSpriteShape(); return; } _groundRoot = new GameObject("EvenMoreSpace Ground"); _groundRoot.transform.SetParent(((Component)collider).transform, false); SpriteRenderer baseGroundRenderer = GetBaseGroundRenderer(); Sprite sprite = (((Object)(object)baseGroundRenderer != (Object)null && (Object)(object)baseGroundRenderer.sprite != (Object)null) ? baseGroundRenderer.sprite : GetOrCreateFreeGroundSprite()); int sortingLayerID = (((Object)(object)baseGroundRenderer != (Object)null) ? ((Renderer)baseGroundRenderer).sortingLayerID : 0); int num = (((Object)(object)baseGroundRenderer != (Object)null) ? (((Renderer)baseGroundRenderer).sortingOrder - 1) : (-20)); for (int j = 1; j <= effectiveExtraSteps; j++) { if (TryGetTranslatedSegmentPath(j, ((Component)collider).transform, out var _, out var worldBounds)) { GameObject val3 = new GameObject("EvenMoreSpace base extension ground " + j); val3.transform.SetParent(_groundRoot.transform, true); val3.transform.position = ((Bounds)(ref worldBounds)).center; SpriteRenderer val4 = val3.AddComponent(); val4.sprite = sprite; val4.drawMode = (SpriteDrawMode)2; val4.size = new Vector2(Mathf.Max(1f, ((Bounds)(ref worldBounds)).size.x + 0.5f), Mathf.Max(1f, ((Bounds)(ref worldBounds)).size.y + 0.5f)); ((Renderer)val4).sortingLayerID = sortingLayerID; ((Renderer)val4).sortingOrder = num; if ((Object)(object)baseGroundRenderer != (Object)null) { ((Renderer)val4).sharedMaterial = ((Renderer)baseGroundRenderer).sharedMaterial; val4.color = baseGroundRenderer.color; } } } Vector2[] path3 = collider.GetPath(0); if (path3 != null && path3.Length >= 3) { GameObject val5 = new GameObject("EvenMoreSpace base extension perimeter"); val5.transform.SetParent(_groundRoot.transform, true); LineRenderer val6 = val5.AddComponent(); val6.useWorldSpace = true; val6.loop = true; val6.positionCount = path3.Length; val6.startWidth = 0.32f; val6.endWidth = 0.32f; val6.numCapVertices = 2; val6.numCornerVertices = 2; val6.startColor = new Color(0.16f, 0.2f, 0.12f, 0.9f); val6.endColor = val6.startColor; Shader val7 = Shader.Find("Sprites/Default"); if ((Object)(object)val7 != (Object)null) { ((Renderer)val6).material = new Material(val7); } ((Renderer)val6).sortingLayerID = sortingLayerID; ((Renderer)val6).sortingOrder = num + 2; for (int k = 0; k < path3.Length; k++) { Vector3 val8 = ((Component)collider).transform.TransformPoint(Vector2.op_Implicit(path3[k])); val8.z = -0.05f; val6.SetPosition(k, val8); } } } private static bool IsSpriteShapeVisualUsable(SpriteShapeRenderer renderer, Bounds expectedBounds) { //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_001c: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) if ((Object)(object)renderer == (Object)null || !((Renderer)renderer).enabled) { return false; } Bounds bounds = ((Renderer)renderer).bounds; if (((Bounds)(ref bounds)).size.x < 1f || ((Bounds)(ref bounds)).size.y < 1f) { return false; } float num = Mathf.Max(1f, ((Bounds)(ref expectedBounds)).size.x); float num2 = Mathf.Max(1f, ((Bounds)(ref expectedBounds)).size.y); if (((Bounds)(ref bounds)).size.x >= num * 0.35f) { return ((Bounds)(ref bounds)).size.y >= num2 * 0.35f; } return false; } private static void NormalizeDlcFreeSpriteShapeWinding(SpriteShapeController source, SpriteShapeController expanded, Vector2[] expandedPath) { //IL_004e: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && !((Object)(object)expanded == (Object)null) && expandedPath != null && expandedPath.Length >= 3 && source.spline != null && source.spline.GetPointCount() >= 3) { Vector2[] array = (Vector2[])(object)new Vector2[source.spline.GetPointCount()]; for (int i = 0; i < array.Length; i++) { Vector3 position = source.spline.GetPosition(i); Vector3 val = ((Component)source).transform.TransformPoint(position); Vector3 val2 = ((Component)expanded).transform.InverseTransformPoint(val); ref Vector2 reference = ref array[i]; reference = new Vector2(val2.x, val2.y); } float signedPolygonArea = GetSignedPolygonArea(array); float signedPolygonArea2 = GetSignedPolygonArea(expandedPath); if (Mathf.Abs(signedPolygonArea) > 0.01f && Mathf.Abs(signedPolygonArea2) > 0.01f && Mathf.Sign(signedPolygonArea) != Mathf.Sign(signedPolygonArea2)) { Array.Reverse((Array)expandedPath); DebugLog("Reversed the DLC-free SpriteShape path to match the base room fill winding."); } } } private static SpriteShapeController GetDlcFreeGroundShape() { //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: 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) if ((Object)(object)BiomeBaseManager.Instance == (Object)null || (Object)(object)BiomeBaseManager.Instance.Room == (Object)null) { return null; } SpriteShapeController[] componentsInChildren = ((Component)BiomeBaseManager.Instance.Room).GetComponentsInChildren(true); SpriteShapeController val = null; int num = int.MinValue; foreach (SpriteShapeController val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || val2.spline == null || val2.spline.GetPointCount() < 3 || !((Component)val2).gameObject.activeInHierarchy) { continue; } SpriteShapeRenderer component = ((Component)val2).GetComponent(); if ((Object)(object)component == (Object)null || !((Renderer)component).enabled) { continue; } string text = GetTransformPath(((Component)val2).transform, ((Component)BiomeBaseManager.Instance.Room).transform).ToLowerInvariant(); int num2 = 0; if (text.Contains("sprite shape")) { num2 += 1000; } if (((Renderer)component).sortingLayerName == "Ground") { num2 += 500; } num2 += Mathf.Clamp(val2.spline.GetPointCount(), 0, 200); if (!((Object)(object)val == (Object)null) && num2 <= num) { if (num2 != num) { continue; } Bounds bounds = ((Renderer)component).bounds; Vector3 size = ((Bounds)(ref bounds)).size; float sqrMagnitude = ((Vector3)(ref size)).sqrMagnitude; Bounds bounds2 = ((Renderer)((Component)val).GetComponent()).bounds; Vector3 size2 = ((Bounds)(ref bounds2)).size; if (!(sqrMagnitude > ((Vector3)(ref size2)).sqrMagnitude)) { continue; } } val = val2; num = num2; } return val; } private static void CaptureDlcFreeSpriteShape(SpriteShapeController controller) { //IL_00a9: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00d3: 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) if (!((Object)(object)_freeBaseSpriteShape == (Object)(object)controller) || _originalFreeSpriteShapePoints == null || _originalFreeSpriteShapePoints.Count <= 0) { if ((Object)(object)_freeBaseSpriteShape != (Object)null && (Object)(object)_freeBaseSpriteShape != (Object)(object)controller) { RestoreDlcFreeSpriteShape(); } _freeBaseSpriteShape = controller; _freeBaseSpriteShapeExpanded = false; SpriteShapeRenderer val = (((Object)(object)controller != (Object)null) ? ((Component)controller).GetComponent() : null); _freeBaseSpriteShapeSortingCaptured = (Object)(object)val != (Object)null; _originalFreeSpriteShapeSortingOrder = (((Object)(object)val != (Object)null) ? ((Renderer)val).sortingOrder : 0); _originalFreeSpriteShapePoints = new List(); Spline spline = controller.spline; for (int i = 0; i < spline.GetPointCount(); i++) { _originalFreeSpriteShapePoints.Add(new SpriteShapePointSnapshot { Position = spline.GetPosition(i), LeftTangent = spline.GetLeftTangent(i), RightTangent = spline.GetRightTangent(i), TangentMode = spline.GetTangentMode(i), Height = spline.GetHeight(i), SpriteIndex = spline.GetSpriteIndex(i), Corner = spline.GetCorner(i) }); } } } private static void RestoreDlcFreeSpriteShape() { if (!_freeBaseSpriteShapeExpanded || (Object)(object)_freeBaseSpriteShape == (Object)null || _originalFreeSpriteShapePoints == null || _originalFreeSpriteShapePoints.Count == 0) { return; } RestoreSpriteShapeSnapshot(_freeBaseSpriteShape, _originalFreeSpriteShapePoints); if (_freeBaseSpriteShapeSortingCaptured) { SpriteShapeRenderer component = ((Component)_freeBaseSpriteShape).GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).sortingOrder = _originalFreeSpriteShapeSortingOrder; } } _freeBaseSpriteShapeExpanded = false; } private static SpriteRenderer GetBaseGroundRenderer() { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_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) if ((Object)(object)BiomeBaseManager.Instance == (Object)null || (Object)(object)BiomeBaseManager.Instance.Room == (Object)null) { return null; } SpriteRenderer[] componentsInChildren = ((Component)BiomeBaseManager.Instance.Room).GetComponentsInChildren(true); SpriteRenderer val = null; foreach (SpriteRenderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2.sprite == (Object)null || !((Component)val2).gameObject.activeInHierarchy) { continue; } string text = GetTransformPath(((Component)val2).transform, ((Component)BiomeBaseManager.Instance.Room).transform).ToLowerInvariant(); if (!text.Contains("ground") && !text.Contains("floor") && !text.Contains("base")) { continue; } if (!((Object)(object)val == (Object)null)) { Bounds bounds = ((Renderer)val2).bounds; Vector3 size = ((Bounds)(ref bounds)).size; float sqrMagnitude = ((Vector3)(ref size)).sqrMagnitude; Bounds bounds2 = ((Renderer)val).bounds; Vector3 size2 = ((Bounds)(ref bounds2)).size; if (!(sqrMagnitude > ((Vector3)(ref size2)).sqrMagnitude)) { continue; } } val = val2; } return val; } private static Sprite GetOrCreateFreeGroundSprite() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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) if ((Object)(object)_freeGroundSprite != (Object)null) { return _freeGroundSprite; } _freeGroundTexture = new Texture2D(32, 32, (TextureFormat)4, false); ((Object)_freeGroundTexture).name = "EvenMoreSpace Base Ground Texture"; ((Texture)_freeGroundTexture).wrapMode = (TextureWrapMode)0; ((Texture)_freeGroundTexture).filterMode = (FilterMode)1; Color[] array = (Color[])(object)new Color[1024]; for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { int num = (j * 13 + i * 29 + j * i * 5) & 0xF; float num2 = ((float)num - 7.5f) * 0.006f; ref Color reference = ref array[i * 32 + j]; reference = new Color(0.38f + num2, 0.49f + num2, 0.29f + num2, 1f); } } _freeGroundTexture.SetPixels(array); _freeGroundTexture.Apply(false, true); _freeGroundSprite = Sprite.Create(_freeGroundTexture, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 1f, 0u, (SpriteMeshType)0); ((Object)_freeGroundSprite).name = "EvenMoreSpace Base Ground Sprite"; return _freeGroundSprite; } private static SpriteRenderer CreateFreeExpansionMarkerVisual(Transform parent) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00d5: 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_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_0031: 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_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) //IL_0060: 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_0099: Unknown result type (might be due to invalid IL or missing references) SpriteRenderer dlcFreeMarkerSource = GetDlcFreeMarkerSource(); if ((Object)(object)dlcFreeMarkerSource != (Object)null) { Vector3 worldPosition = parent.position + new Vector3(0f, 0.35f, -0.1f); SpriteRenderer val = CreateSpriteVisual(dlcFreeMarkerSource, worldPosition, parent, "EvenMoreSpace expansion stone visual"); ((Renderer)val).sortingOrder = Mathf.Max(20, ((Renderer)dlcFreeMarkerSource).sortingOrder + 20); Bounds bounds = ((Renderer)val).bounds; float y = ((Bounds)(ref bounds)).size.y; if (y > 0.01f) { float num = Mathf.Clamp(2.35f / y, 0.68f, 1.2f); Transform transform = ((Component)val).transform; transform.localScale *= num; } return val; } GameObject val2 = new GameObject("EvenMoreSpace expansion cairn visual"); val2.transform.SetParent(parent, false); val2.transform.localPosition = new Vector3(0f, 0.45f, -0.1f); SpriteRenderer val3 = val2.AddComponent(); val3.sprite = GetOrCreateFreeMarkerSprite(); ((Renderer)val3).sortingOrder = 20; return val3; } private static SpriteRenderer GetDlcFreeMarkerSource() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)BiomeBaseManager.Instance == (Object)null || (Object)(object)BiomeBaseManager.Instance.Room == (Object)null) { return null; } SpriteRenderer[] componentsInChildren = ((Component)BiomeBaseManager.Instance.Room).GetComponentsInChildren(true); SpriteRenderer val = null; int num = int.MinValue; foreach (SpriteRenderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2.sprite == (Object)null || !((Renderer)val2).enabled || !((Component)val2).gameObject.activeInHierarchy) { continue; } Bounds bounds = ((Renderer)val2).bounds; if (((Bounds)(ref bounds)).size.x < 0.2f || ((Bounds)(ref bounds)).size.y < 0.2f || ((Bounds)(ref bounds)).size.x > 5.5f || ((Bounds)(ref bounds)).size.y > 6.5f) { continue; } string text = GetTransformPath(((Component)val2).transform, ((Component)BiomeBaseManager.Instance.Room).transform).ToLowerInvariant(); string text2 = text + " " + ((Object)((Component)val2).gameObject).name.ToLowerInvariant() + " " + ((Object)val2.sprite).name.ToLowerInvariant(); string[] array = new string[26] { "ground", "floor", "border", "wall", "tree", "grass", "bush", "plant", "flower", "fog", "mist", "particle", "shadow", "light", "bridge", "portal", "door", "shrine", "sign", "building", "structure", "purchase", "mole", "gofer", "connector", "spriteshape" }; bool flag = false; for (int j = 0; j < array.Length; j++) { if (text2.Contains(array[j])) { flag = true; break; } } if (flag) { continue; } string[] array2 = new string[6] { "cairn", "obelisk", "statue", "stone", "rock", "rubble" }; int num2 = 0; for (int k = 0; k < array2.Length; k++) { if (text2.Contains(array2[k])) { num2 += 100 - k * 10; } } num2 += Mathf.Clamp(Mathf.RoundToInt((5f - Mathf.Abs(((Bounds)(ref bounds)).size.y - 2.5f)) * 10f), 0, 50); if ((Object)(object)val == (Object)null || num2 > num) { val = val2; num = num2; } } return val; } private static Sprite GetOrCreateFreeMarkerSprite() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_022b: 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_0075: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_freeMarkerSprite != (Object)null) { return _freeMarkerSprite; } _freeMarkerTexture = new Texture2D(96, 112, (TextureFormat)4, false); ((Object)_freeMarkerTexture).name = "EvenMoreSpace Base Expansion Cairn Texture"; ((Texture)_freeMarkerTexture).filterMode = (FilterMode)0; Color[] array = (Color[])(object)new Color[10752]; for (int i = 0; i < 112; i++) { for (int j = 0; j < 96; j++) { ref Color reference = ref array[i * 96 + j]; reference = new Color(0f, 0f, 0f, 0f); } } FillMarkerEllipse(array, 96, 112, 48, 13, 34, 8, new Color(0.08f, 0.07f, 0.06f, 0.75f), new Color(0.08f, 0.07f, 0.06f, 0.75f)); FillMarkerEllipse(array, 96, 112, 48, 32, 31, 18, new Color(0.22f, 0.2f, 0.16f, 1f), new Color(0.08f, 0.07f, 0.06f, 1f)); FillMarkerEllipse(array, 96, 112, 48, 57, 25, 18, new Color(0.36f, 0.34f, 0.28f, 1f), new Color(0.1f, 0.09f, 0.07f, 1f)); FillMarkerEllipse(array, 96, 112, 48, 80, 18, 16, new Color(0.48f, 0.45f, 0.36f, 1f), new Color(0.12f, 0.1f, 0.08f, 1f)); FillMarkerEllipse(array, 96, 112, 48, 101, 23, 6, new Color(0.12f, 0.1f, 0.08f, 1f), new Color(0.12f, 0.1f, 0.08f, 1f)); DrawMarkerRune(array, 96, 112, 48, 84); _freeMarkerTexture.SetPixels(array); _freeMarkerTexture.Apply(false, true); _freeMarkerSprite = Sprite.Create(_freeMarkerTexture, new Rect(0f, 0f, 96f, 112f), new Vector2(0.5f, 0.12f), 32f, 0u, (SpriteMeshType)0); ((Object)_freeMarkerSprite).name = "EvenMoreSpace Base Expansion Cairn Sprite"; return _freeMarkerSprite; } private static void FillMarkerEllipse(Color[] pixels, int width, int height, int centerX, int centerY, int radiusX, int radiusY, Color fill, Color edge) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) for (int i = Mathf.Max(0, centerY - radiusY); i <= Mathf.Min(height - 1, centerY + radiusY); i++) { for (int j = Mathf.Max(0, centerX - radiusX); j <= Mathf.Min(width - 1, centerX + radiusX); j++) { float num = (float)(j - centerX) / (float)Mathf.Max(1, radiusX); float num2 = (float)(i - centerY) / (float)Mathf.Max(1, radiusY); float num3 = num * num + num2 * num2; if (num3 <= 1f) { pixels[i * width + j] = ((num3 >= 0.72f) ? edge : fill); } } } } private static void DrawMarkerRune(Color[] pixels, int width, int height, int centerX, int centerY) { //IL_004b: 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_0078: 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_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) Color val = default(Color); ((Color)(ref val))..ctor(0.91f, 0.66f, 0.22f, 1f); for (int i = -9; i <= 9; i++) { int num = centerX + i; int num2 = centerY + Mathf.Abs(i) / 2; if (num >= 0 && num < width && num2 >= 0 && num2 < height) { pixels[num2 * width + num] = val; } num2 = centerY - Mathf.Abs(i) / 2; if (num >= 0 && num < width && num2 >= 0 && num2 < height) { pixels[num2 * width + num] = val; } } for (int j = centerY - 8; j <= centerY + 8; j++) { if (centerX >= 0 && centerX < width && j >= 0 && j < height) { pixels[j * width + centerX] = val; } } } private static List ToClipperPath(Vector2[] points) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) List list = new List(points.Length); for (int i = 0; i < points.Length; i++) { list.Add(new IntPoint((long)Math.Round(points[i].x * 1000f), (long)Math.Round(points[i].y * 1000f))); } return list; } private static Vector2[] FromClipperPath(List path) { //IL_0019: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Vector2[] array = (Vector2[])(object)new Vector2[path.Count]; for (int i = 0; i < path.Count; i++) { ref Vector2 reference = ref array[i]; reference = new Vector2((float)path[i].X / 1000f, (float)path[i].Y / 1000f); } return array; } private static double GetClipperArea(List path) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_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) double num = 0.0; for (int i = 0; i < path.Count; i++) { IntPoint val = path[i]; IntPoint val2 = path[(i + 1) % path.Count]; num += (double)val.X * (double)val2.Y - (double)val2.X * (double)val.Y; } return num * 0.5; } private static float GetSignedPolygonArea(Vector2[] path) { //IL_0024: 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) //IL_0037: 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) if (path == null || path.Length < 3) { return 0f; } double num = 0.0; for (int i = 0; i < path.Length; i++) { Vector2 val = path[i]; Vector2 val2 = path[(i + 1) % path.Length]; num += (double)val.x * (double)val2.y - (double)val2.x * (double)val.y; } return (float)(num * 0.5); } internal static void ClearVisualClones() { GameObject val = GameObject.Find("EvenMoreSpace Visual Clones"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } internal static bool CreateFloodFillIterative(PlacementRegion region) { //IL_00c2: 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_00f3: 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_00fb: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) LastFloodFillSucceeded = false; try { if ((Object)(object)region == (Object)null || (Object)(object)region.polygonCollider2D == (Object)null) { throw new InvalidOperationException("The placement collider is missing."); } if (UsesVanillaDlcGeometry()) { Vector2[] array = ((PlacementCachedColliderPointsField != null) ? (PlacementCachedColliderPointsField.GetValue(region) as Vector2[]) : null); if (array == null) { throw new InvalidOperationException("The placement collider cache is missing."); } region.polygonCollider2D = DLCLandController.Instance.CombineColliders(array, region.polygonCollider2D); } int num = Mathf.Max(region.MaxTileCount, Mathf.Max(EvenMoreSpaceConfig.MinimumTileCap.Value, 40000)); region.Grid.Clear(); region.GridTileLookup.Clear(); Queue queue = new Queue(); HashSet hashSet = new HashSet(); HashSet seeded = new HashSet(); EnqueueFloodFillSeed(region, queue, seeded, Vector2.zero); EnqueueFloodFillSeed(region, queue, seeded, new Vector2(-15f, -15f)); EnqueueExpansionFloodFillSeeds(region, queue, seeded); Vector2 val3 = default(Vector2); while (queue.Count > 0 && region.Grid.Count < num) { Vector2Int val = queue.Dequeue(); if (hashSet.Add(val)) { Vector3 val2 = ((Component)region).transform.TransformPoint(Vector2.op_Implicit(new Vector2((float)((Vector2Int)(ref val)).x, (float)((Vector2Int)(ref val)).y))); ((Vector2)(ref val3))..ctor(val2.x, val2.y); Vector2 val4 = ((Collider2D)region.polygonCollider2D).ClosestPoint(val3); Vector2 val5 = val4 - val3; if (!(((Vector2)(ref val5)).sqrMagnitude > 0.0001f)) { TileGridTile val6 = TileGridTile.Create(region, val, false, false); region.Grid.Add(val6); region.GridTileLookup[val] = val6; queue.Enqueue(new Vector2Int(((Vector2Int)(ref val)).x + 1, ((Vector2Int)(ref val)).y)); queue.Enqueue(new Vector2Int(((Vector2Int)(ref val)).x - 1, ((Vector2Int)(ref val)).y)); queue.Enqueue(new Vector2Int(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y + 1)); queue.Enqueue(new Vector2Int(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y - 1)); } } } if (PlacementCountField != null) { PlacementCountField.SetValue(region, region.Grid.Count); } if (UsesVanillaDlcGeometry()) { Interaction_PurchaseLand.OccupyBridgeArea(); } bool flag = queue.Count > 0; LastFloodFillSucceeded = region.Grid.Count > 0 && !flag; if (flag) { EvenMoreSpacePlugin.Log.LogError((object)("Placement grid reached its configured cap of " + num + " tiles before the map was complete.")); } DebugLog("Built iterative placement grid with " + region.Grid.Count + " tiles."); return LastFloodFillSucceeded; } catch (Exception ex) { EvenMoreSpacePlugin.Log.LogError((object)("Failed to build the iterative Woolhaven placement grid: " + ex)); return false; } } private static void EnqueueExpansionFloodFillSeeds(PlacementRegion region, Queue pending, HashSet seeded) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0059: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0074: 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_008b: 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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)region == (Object)null || pending == null || seeded == null) { return; } int effectiveExtraSteps = GetEffectiveExtraSteps(); for (int i = 1; i <= effectiveExtraSteps; i++) { if (!TryGetTranslatedSegmentPath(i, ((Component)region).transform, out var path, out var worldBounds)) { continue; } EnqueueFloodFillSeed(region, pending, seeded, Vector2.op_Implicit(((Component)region).transform.InverseTransformPoint(((Bounds)(ref worldBounds)).center))); if (path != null && path.Length != 0) { Vector2 val = Vector2.zero; for (int j = 0; j < path.Length; j++) { val += path[j]; } EnqueueFloodFillSeed(region, pending, seeded, val / (float)path.Length); for (int k = 0; k < path.Length; k++) { EnqueueFloodFillSeed(region, pending, seeded, path[k]); } } } for (int l = 1; l <= effectiveExtraSteps; l += 3) { List connectorCorridorsForStep = GetConnectorCorridorsForStep(l, ((Component)region).transform, 6f, 6f); for (int m = 0; m < connectorCorridorsForStep.Count; m++) { Transform transform = ((Component)region).transform; Bounds val2 = connectorCorridorsForStep[m]; EnqueueFloodFillSeed(region, pending, seeded, Vector2.op_Implicit(transform.InverseTransformPoint(((Bounds)(ref val2)).center))); } } } private static void EnqueueFloodFillSeed(PlacementRegion region, Queue pending, HashSet seeded, Vector2 localPosition) { //IL_006f: 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)region == (Object)null || pending == null || seeded == null || float.IsNaN(localPosition.x) || float.IsNaN(localPosition.y)) { return; } Vector2Int val = default(Vector2Int); ((Vector2Int)(ref val))..ctor(Mathf.RoundToInt(localPosition.x), Mathf.RoundToInt(localPosition.y)); Vector2Int item = default(Vector2Int); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { ((Vector2Int)(ref item))..ctor(((Vector2Int)(ref val)).x + j, ((Vector2Int)(ref val)).y + i); if (seeded.Add(item)) { pending.Enqueue(item); } } } } internal static void ReAddStructuresToPlacementGrid() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 //IL_0074: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)PlacementRegion.Instance == (Object)null || PlacementRegion.Instance.structureBrain == null) { return; } List list = StructureManager.StructuresAtLocation((FollowerLocation)1); int num = 0; int num2 = 0; for (int i = 0; i < list.Count; i++) { StructureBrain val = list[i]; if (val == null || val.Data == null) { continue; } StructuresData data = val.Data; if (!data.IgnoreGrid && (int)data.Type != 33) { PlacementRegion.Instance.structureBrain.AddStructureToGrid(data, false); num++; if (IsCoreBaseAnchor(data.Type)) { ReserveCoreAnchorTiles(data); num2++; } } } DebugLog("Restored " + num + " live base structure(s) to the expanded placement grid and reserved " + num2 + " core anchor(s)."); } private static bool IsCoreBaseAnchor(TYPES type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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_0005: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Invalid comparison between Unknown and I4 //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //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_001c: Expected I4, but got Unknown //IL_00a4: 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_00b8: Expected I4, but got Unknown //IL_0055: 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) //IL_009a: Expected I4, but got Unknown //IL_0031: 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_0046: Expected I4, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 if ((int)type <= 44) { if ((int)type <= 27) { switch (type - 3) { case 0: case 1: goto IL_00c0; } if ((int)type != 27) { goto IL_00c2; } } else if ((int)type != 32) { switch (type - 42) { case 0: case 1: case 2: break; default: goto IL_00c2; } } } else if ((int)type <= 128) { if ((int)type != 70) { switch (type - 114) { case 0: case 1: case 2: case 3: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 14: break; default: goto IL_00c2; } } } else if ((int)type != 144) { switch (type - 151) { case 0: case 1: goto IL_00c0; } if ((int)type != 156) { goto IL_00c2; } } goto IL_00c0; IL_00c2: return false; IL_00c0: return true; } private static void ReserveCoreAnchorTiles(StructuresData data) { //IL_0054: 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_0070: Unknown result type (might be due to invalid IL or missing references) if (data == null || (Object)(object)PlacementRegion.Instance == (Object)null || ((Vector2Int)(ref data.Bounds)).x <= 0 || ((Vector2Int)(ref data.Bounds)).y <= 0) { return; } for (int i = 0; i < ((Vector2Int)(ref data.Bounds)).x; i++) { for (int j = 0; j < ((Vector2Int)(ref data.Bounds)).y; j++) { TileGridTile tileGridTile = PlacementRegion.Instance.GetTileGridTile(new Vector2Int(((Vector2Int)(ref data.GridTilePosition)).x + i, ((Vector2Int)(ref data.GridTilePosition)).y + j)); if (tileGridTile != null) { tileGridTile.Occupied = true; tileGridTile.ObjectOnTile = data.Type; tileGridTile.ObjectID = data.ID; tileGridTile.Collapsed = data.IsCollapsed; } } } } internal static void ExtendXConstraints(ref Vector2 result) { //IL_0028: 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) if (GetEffectiveExtraSteps() > 0 && IsExpansionReadyForGeometry() && !((Object)(object)_lastExpansionCollider == (Object)null)) { result = new Vector2(-1000f, 1000f); } } internal static void ExtendYConstraints(ref Vector2 result) { //IL_0028: 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) if (GetEffectiveExtraSteps() > 0 && IsExpansionReadyForGeometry() && !((Object)(object)_lastExpansionCollider == (Object)null)) { result = new Vector2(-1000f, 1000f); } } private static void ClearChildren(Transform root) { for (int num = root.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)root.GetChild(num)).gameObject); } } internal static int GetPrivateInt(FieldInfo field, object instance, int fallback) { if (field == null || instance == null) { return fallback; } object value = field.GetValue(instance); if (value is int) { return (int)value; } return fallback; } private static void SetPrivateBool(FieldInfo field, object instance, bool value) { if (field != null && instance != null) { field.SetValue(instance, value); } } internal static ITEM_TYPE GetPrivateCostType(Interaction_PurchaseLand interaction) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (CostTypeField == null || (Object)(object)interaction == (Object)null) { return (ITEM_TYPE)1; } object value = CostTypeField.GetValue(interaction); if (value is ITEM_TYPE) { return (ITEM_TYPE)value; } return (ITEM_TYPE)1; } private static int GetMoleCostForStep(Interaction_PurchaseLand interaction, int purchasedSteps) { int num; if (EvenMoreSpaceConfig.UseVanillaMoleCost.Value && (Object)(object)interaction != (Object)null) { if (_vanillaBaseMoleCost < 0) { _vanillaBaseMoleCost = Mathf.Max(0, GetPrivateInt(CostField, interaction, EvenMoreSpaceConfig.ExtraMoleCost.Value)); } num = _vanillaBaseMoleCost; } else { num = EvenMoreSpaceConfig.ExtraMoleCost.Value; } long val = num + (long)Mathf.Max(0, purchasedSteps / 3) * (long)EvenMoreSpaceConfig.CostIncreasePerCompletedRow.Value; return (int)Math.Min(val, 100000L); } private static void UpdateMoleDisplayedCost(Interaction_PurchaseLand interaction, int purchasedSteps) { if (CostField != null && (Object)(object)interaction != (Object)null) { CostField.SetValue(interaction, GetMoleCostForStep(interaction, purchasedSteps)); } } internal static string GetDlcFreeExpansionLabel() { if (GetExtraSteps() >= EvenMoreSpaceConfig.MaxExtraSteps.Value) { return string.Empty; } return "Expand Base (" + GetMoleCostForStep(null, GetExtraSteps()) + " Logs)"; } internal static bool HasActiveResourceVisual(StructureBrain brain) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (brain == null || brain.Data == null || !HasActiveExpansion()) { return true; } return HasActiveResourceVisual(brain.Data.Type, brain.Data.ID); } internal static bool HasActiveResourceVisual(TYPES type, int id) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Invalid comparison between Unknown and I4 if (!HasActiveExpansion() || id == 0) { return true; } if ((int)type == 16) { for (int i = 0; i < TreeBase.Trees.Count; i++) { TreeBase val = TreeBase.Trees[i]; if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy) { continue; } try { if (val.StructureInfo != null && val.StructureInfo.ID == id) { return true; } } catch { } } return false; } if ((int)type == 61 || (int)type == 159) { for (int j = 0; j < Rubble.Rubbles.Count; j++) { Rubble val2 = Rubble.Rubbles[j]; if ((Object)(object)val2 == (Object)null || !((Component)val2).gameObject.activeInHierarchy) { continue; } try { if (val2.StructureInfo != null && val2.StructureInfo.ID == id) { return true; } } catch { } } return false; } return true; } internal static void EndUnavailableResourceTask(FollowerTask task) { if (task == null) { return; } try { task.End(); } catch (Exception ex) { DebugLog("Could not end an unavailable expanded-map resource task: " + ex.Message); } } private static void ShakePlayer(StateMachine state) { try { PlayerFarming val = (((Object)(object)state != (Object)null) ? ((Component)state).GetComponent() : null); if ((Object)(object)val != (Object)null && (Object)(object)val.indicator != (Object)null) { val.indicator.PlayShake(); } } catch { } } private static void MovePlayersNear(Vector3 position) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_003c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < PlayerFarming.players.Count; i++) { if ((Object)(object)PlayerFarming.players[i] != (Object)null) { ((Component)PlayerFarming.players[i]).transform.position = position + Vector3.up * ((float)(i + 1) / 2f); } } } private static void SafePlayMoleAnimation(SkeletonAnimation spine, string first, string loop) { try { if ((Object)(object)spine != (Object)null && spine.AnimationState != null) { spine.AnimationState.SetAnimation(0, first, false); if (!string.IsNullOrEmpty(loop)) { spine.AnimationState.AddAnimation(0, loop, true, 0f); } } } catch (Exception ex) { DebugLog("Could not play mole animation " + first + ": " + ex.Message); } } private static void PlayAudio(string eventName, Vector3 position) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)AudioManager.Instance != (Object)null) { AudioManager.Instance.PlayOneShot(eventName, position); } } catch (Exception ex) { DebugLog("Could not play audio " + eventName + ": " + ex.Message); } } internal static void DebugLog(string message) { if (EvenMoreSpaceConfig.DebugLogging.Value && EvenMoreSpacePlugin.Log != null) { EvenMoreSpacePlugin.Log.LogInfo((object)message); } } } internal sealed class FreeExpansionInteraction : Interaction { private bool _purchaseRunning; private void Awake() { ((Interaction)this).UpdateLocalisation(); } public override void UpdateLocalisation() { ((Interaction)this).UpdateLocalisation(); base.label = EvenMoreSpaceState.GetDlcFreeExpansionLabel(); } public override void GetLabel() { base.label = EvenMoreSpaceState.GetDlcFreeExpansionLabel(); } public override void OnInteract(StateMachine interactionState) { if (!_purchaseRunning && !((Object)(object)interactionState == (Object)null) && EvenMoreSpaceState.IsDlcFreeExpansionAvailable()) { ((Interaction)this).OnInteract(interactionState); _purchaseRunning = true; ((MonoBehaviour)this).StartCoroutine(RunPurchase(interactionState)); } } private IEnumerator RunPurchase(StateMachine interactionState) { yield return ((MonoBehaviour)this).StartCoroutine(EvenMoreSpaceState.RunDlcFreeExpansion(this, interactionState)); _purchaseRunning = false; ((Interaction)this).UpdateLocalisation(); } } internal static class RemoteBuildStationFeature { internal const string StationName = "Remote Construction Totem"; internal const string StationDescription = "Opens the normal construction menu from wherever this totem is placed."; internal const TYPES StationType = (TYPES)481; internal static bool Enabled { get { if (EvenMoreSpaceConfig.EnableRemoteBuildStation != null) { return EvenMoreSpaceConfig.EnableRemoteBuildStation.Value; } return false; } } internal static void EnsureUnlocked() { if (Enabled && EvenMoreSpaceState.HasActiveExpansion() && DataManager.Instance != null && EvenMoreSpaceState.IsAuthenticatedMajorDlc() && DataManager.Instance.UnlockedStructures != null && !DataManager.Instance.UnlockedStructures.Contains((TYPES)481)) { DataManager.Instance.UnlockedStructures.Add((TYPES)481); EvenMoreSpacePlugin.Log.LogInfo((object)"Unlocked the Remote Construction Totem build-menu entry."); } } internal static void Attach(StructuresData data, GameObject structureObject) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 if (Enabled && data != null && !((Object)(object)structureObject == (Object)null) && (int)data.Type == 481 && (int)data.Location == 1 && !((Object)(object)structureObject.GetComponentInChildren(true) != (Object)null)) { Structure val = structureObject.GetComponent(); if ((Object)(object)val == (Object)null) { val = structureObject.GetComponentInChildren(true); } RemoteBuildStationInteraction remoteBuildStationInteraction = structureObject.AddComponent(); ((Interaction)remoteBuildStationInteraction).OutlineTarget = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : structureObject); ((Interaction)remoteBuildStationInteraction).ActivateDistance = 2.25f; ((Interaction)remoteBuildStationInteraction).PriorityWeight = 5f; ((Interaction)remoteBuildStationInteraction).IgnoreTutorial = true; EvenMoreSpacePlugin.Log.LogInfo((object)("Attached remote build-menu interaction to construction totem " + data.ID + ".")); } } } internal sealed class RemoteBuildStationInteraction : Interaction { private Vector3 _placementOrigin; private bool _openingMenu; private void Awake() { ((Interaction)this).UpdateLocalisation(); } public override void UpdateLocalisation() { ((Interaction)this).UpdateLocalisation(); base.label = Interactions.Build; } public override void OnInteract(StateMachine interactionState) { //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) if (!_openingMenu && !((Object)(object)interactionState == (Object)null) && !((Object)(object)PlacementRegion.Instance == (Object)null) && DataManager.Instance != null && DataManager.Instance.AllowBuilding && !BuildSitePlot.StructureOfTypeUnderConstruction((TYPES)27) && !BuildSitePlotProject.StructureOfTypeUnderConstruction((TYPES)27) && !Interaction_WolfBase.WolvesActive) { ((Interaction)this).OnInteract(interactionState); base.state.CURRENT_STATE = (State)13; DataManager.Instance.NewBuildings = false; _placementOrigin = ((Component)interactionState).transform.position; _openingMenu = true; ((MonoBehaviour)this).StartCoroutine(OpenBuildMenu()); } } private IEnumerator OpenBuildMenu() { UIBuildMenuController buildMenuInstance = null; try { if ((Object)(object)MonoSingleton.Instance == (Object)null || (Object)(object)MonoSingleton.Instance.BuildMenuTemplate == (Object)null) { throw new InvalidOperationException("The vanilla build-menu template is unavailable."); } buildMenuInstance = GameObjectExtensions.Instantiate(MonoSingleton.Instance.BuildMenuTemplate); } catch (Exception ex) { EvenMoreSpacePlugin.Log.LogError((object)("Could not create the remote build menu: " + ex)); RestoreAfterFailure(); yield break; } yield return null; try { ((UIMenuBase)buildMenuInstance).Show(false); UIBuildMenuController obj = buildMenuInstance; obj.OnBuildingChosen = (Action)Delegate.Combine(obj.OnBuildingChosen, new Action(PlaceBuilding)); UIBuildMenuController obj2 = buildMenuInstance; ((UIMenuBase)obj2).OnHide = (Action)Delegate.Combine(((UIMenuBase)obj2).OnHide, (Action)delegate { if ((Object)(object)buildMenuInstance != (Object)null && buildMenuInstance.DidCancel && (Object)(object)WeatherSystemController.Instance != (Object)null) { WeatherSystemController.Instance.ShowWeather(false, false); } if ((Object)(object)AudioManager.Instance != (Object)null) { AudioManager.Instance.SetBuildSnapshotEnabled(false); } }); UIBuildMenuController obj3 = buildMenuInstance; ((UIMenuBase)obj3).OnCancel = (Action)Delegate.Combine(((UIMenuBase)obj3).OnCancel, (Action)delegate { if ((Object)(object)HUD_Manager.Instance != (Object)null) { HUD_Manager.Instance.Show(0, false); } Time.timeScale = 1f; if ((Object)(object)AudioManager.Instance != (Object)null) { AudioManager.Instance.SetBuildSnapshotEnabled(false); } Cancel(); }); if ((Object)(object)HUD_Manager.Instance != (Object)null) { HUD_Manager.Instance.Hide(false, 0, false); } if ((Object)(object)HUD_DisplayName.Instance != (Object)null) { HUD_DisplayName.Instance.HideText(); } if ((Object)(object)WeatherSystemController.Instance != (Object)null) { WeatherSystemController.Instance.HideWeather(false, false); } Time.timeScale = 0f; _openingMenu = false; } catch (Exception ex2) { EvenMoreSpacePlugin.Log.LogError((object)("Could not open the remote build menu: " + ex2)); if ((Object)(object)buildMenuInstance != (Object)null) { Object.Destroy((Object)(object)((Component)buildMenuInstance).gameObject); } RestoreAfterFailure(); } } private void PlaceBuilding(TYPES structureType) { //IL_0006: 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) //IL_008e: 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_0096: Unknown result type (might be due to invalid IL or missing references) PlacementRegion instance = PlacementRegion.Instance; TypeAndPlacementObject byType = TypeAndPlacementObjects.GetByType(structureType); if ((Object)(object)instance == (Object)null || byType == null || (Object)(object)byType.PlacementObject == (Object)null) { EvenMoreSpacePlugin.Log.LogWarning((object)("Remote construction could not resolve placement data for " + ((object)structureType).ToString() + ".")); RestoreAfterFailure(); return; } if ((Object)(object)NotificationCentreScreen.Instance != (Object)null) { NotificationCentreScreen.Instance.Stop(); } if ((Object)(object)AudioManager.Instance != (Object)null) { AudioManager.Instance.SetBuildSnapshotEnabled(true); } instance.PlacementGameObject = byType.PlacementObject; instance.StructureType = structureType; instance.Play(_placementOrigin); } private void Cancel() { _openingMenu = false; if ((Object)(object)base.state != (Object)null) { base.state.CURRENT_STATE = (State)0; } } private void RestoreAfterFailure() { _openingMenu = false; Time.timeScale = 1f; if ((Object)(object)HUD_Manager.Instance != (Object)null) { HUD_Manager.Instance.Show(0, false); } if ((Object)(object)WeatherSystemController.Instance != (Object)null) { WeatherSystemController.Instance.ShowWeather(false, false); } if ((Object)(object)AudioManager.Instance != (Object)null) { AudioManager.Instance.SetBuildSnapshotEnabled(false); } if ((Object)(object)base.state != (Object)null) { base.state.CURRENT_STATE = (State)0; } } } internal static class RemoteBuildStationPlacePatch { public static void Postfix(StructuresData structure, ref GameObject __result) { RemoteBuildStationFeature.Attach(structure, __result); } } internal static class RemoteBuildStationMenuPatch { public static void Prefix() { RemoteBuildStationFeature.EnsureUnlocked(); } } internal static class RemoteBuildStationNamePatch { public static void Postfix(TYPES Type, ref string __result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if (RemoteBuildStationFeature.Enabled && (int)Type == 481) { __result = "Remote Construction Totem"; } } } internal static class RemoteBuildStationDescriptionPatch { public static void Postfix(TYPES Type, ref string __result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if (RemoteBuildStationFeature.Enabled && (int)Type == 481) { __result = "Opens the normal construction menu from wherever this totem is placed."; } } } internal static class PurchaseLandStartPatch { public static bool Prefix(Interaction_PurchaseLand __instance) { if (EvenMoreSpaceState.IsExtraMole(__instance)) { EvenMoreSpaceState.KeepFinalMoleAlive(__instance); return false; } return true; } } internal static class PurchaseLandInteractPatch { public static bool Prefix(Interaction_PurchaseLand __instance, StateMachine state) { if (!EvenMoreSpaceState.IsExtraMole(__instance)) { EvenMoreSpaceState.ScheduleFinalMoleHandoff(__instance); return true; } ((MonoBehaviour)__instance).StartCoroutine(EvenMoreSpaceState.RunExtraMoleExpansion(__instance, state)); return false; } } internal static class DLCLandShowSlotPatch { public static bool Prefix() { if ((Object)(object)EvenMoreSpacePlugin.Instance != (Object)null) { EvenMoreSpacePlugin.Instance.RefreshExpansionRuntimePatches(); } return !EvenMoreSpaceState.ShouldSuppressVanillaLandSlotActivation(); } public static void Postfix() { if (EvenMoreSpaceState.UsesDlcFreeCustomGeometry()) { if (EvenMoreSpaceState.EnsureDlcFreeCustomGeometry()) { EvenMoreSpaceState.EnsureExtraMoleExists(); EvenMoreSpaceState.ScheduleDelayedVisualRepair(); } return; } if (EvenMoreSpaceState.HasActiveExpansion()) { EvenMoreSpaceState.ApplyExpansionToCurrentBase(rebuildPlacementGrid: false, -1, geometryAlreadyApplied: true); } EvenMoreSpaceState.EnsureExtraMoleExists(); EvenMoreSpaceState.ScheduleDelayedVisualRepair(); } } internal static class BiomeBaseActivateRoomPatch { public static void Postfix() { if (EvenMoreSpaceState.UsesDlcFreeCustomGeometry()) { if (EvenMoreSpaceState.EnsureDlcFreeCustomGeometry()) { EvenMoreSpaceState.EnsureExtraMoleExists(); EvenMoreSpaceState.ScheduleDelayedVisualRepair(); } } else if (EvenMoreSpaceState.HasActiveExpansion()) { EvenMoreSpaceState.ForceBakeExpandedGround(); EvenMoreSpaceState.ScheduleDelayedVisualRepair(); } } } internal static class LocationPlaceStructuresPatch { public static void Prefix(LocationManager __instance) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if ((Object)(object)__instance != (Object)null && (int)__instance.Location == 1) { if (EvenMoreSpaceState.UsesDlcFreeCustomGeometry()) { EvenMoreSpaceState.EnsureDlcFreeCustomGeometry(); } EvenMoreSpaceState.RefreshExpansionTrigger(); } } } internal static class WoolhavenDeactivationPatch { public static void Postfix() { if (EvenMoreSpaceState.UsesDlcFreeCustomGeometry()) { EvenMoreSpaceState.EnsureDlcFreeCustomGeometry(); } EvenMoreSpaceState.RefreshExpansionTrigger(); } } internal static class DLCLandCombineCollidersPatch { public static void Postfix(ref PolygonCollider2D __result) { __result = EvenMoreSpaceState.ExpandCollider(__result); } } internal static class PlacementRegionCreateFloodFillPatch { public static bool Prefix(PlacementRegion __instance) { if ((Object)(object)__instance == (Object)null || !EvenMoreSpaceState.HasActiveExpansion()) { return true; } if (EvenMoreSpaceState.CreateFloodFillIterative(__instance)) { EvenMoreSpaceState.SchedulePopulationBackfill(); } return false; } } internal static class PlacementRegionConstraintsPatch { public static void XPostfix(ref Vector2 __result) { EvenMoreSpaceState.ExtendXConstraints(ref __result); RanchPerformanceState.LimitConstraint(ref __result); } public static void YPostfix(ref Vector2 __result) { EvenMoreSpaceState.ExtendYConstraints(ref __result); RanchPerformanceState.LimitConstraint(ref __result); } } internal static class RanchTileScanPatch { public static void Prefix(Structures_Ranch __instance, out RanchPerformanceState.TileScanState __state) { __state = RanchPerformanceState.EnterTileScan(__instance); } public static Exception Finalizer(Exception __exception, RanchPerformanceState.TileScanState __state) { RanchPerformanceState.ExitTileScan(__state); return __exception; } } internal static class RanchInnerScanPatch { private static readonly MethodInfo IndestructibleTypesGetter = AccessTools.PropertyGetter(typeof(StructureManager), "IndestructibleByRanchStructures"); private static readonly MethodInfo CachedIndestructibleTypes = AccessTools.Method(typeof(RanchPerformanceState), "GetIndestructibleRanchStructures", (Type[])null, (Type[])null); private static readonly MethodInfo VanillaContainsFence = AccessTools.Method(typeof(Structures_Ranch), "ContainsFence", new Type[1] { typeof(TileGridTile) }, (Type[])null); private static readonly MethodInfo CachedContainsFence = AccessTools.Method(typeof(RanchPerformanceState), "ContainsFence", (Type[])null, (Type[])null); private static readonly MethodInfo VanillaContainsTile = AccessTools.Method(typeof(List), "Contains", new Type[1] { typeof(TileGridTile) }, (Type[])null); private static readonly MethodInfo CachedContainsTile = AccessTools.Method(typeof(RanchPerformanceState), "ContainsTile", (Type[])null, (Type[])null); public static IEnumerable Transpiler(IEnumerable instructions) { foreach (CodeInstruction instruction in instructions) { if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && object.Equals(instruction.operand, IndestructibleTypesGetter)) { instruction.opcode = OpCodes.Call; instruction.operand = CachedIndestructibleTypes; } else if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && object.Equals(instruction.operand, VanillaContainsFence)) { instruction.opcode = OpCodes.Call; instruction.operand = CachedContainsFence; } else if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && object.Equals(instruction.operand, VanillaContainsTile)) { instruction.opcode = OpCodes.Call; instruction.operand = CachedContainsTile; } yield return instruction; } } } internal static class RanchValidationPatch { public static bool Prefix(Interaction_Ranch __instance, StructuresData structure) { return RanchPerformanceState.ShouldRunValidation(__instance, structure); } } internal static class RanchFenceRefreshPatch { public static bool Prefix(Interaction_Ranch __instance) { return RanchPerformanceState.ShouldRunFenceRefresh(__instance); } } internal static class RanchFencePlacementPositionsPatch { public static bool Prefix(PlacementRegion __instance, List ___fenceableGridPositions, List ___touchingRanchGridPositions) { return RanchPerformanceState.RebuildFencePlacementPositions(__instance, ___fenceableGridPositions, ___touchingRanchGridPositions); } } internal static class BuildModePlaceTilesPatch { public static bool Prefix(PlacementRegion __instance, ref IEnumerator __result) { if (!BuildModePerformanceState.ShouldOptimize(__instance)) { BuildModePerformanceState.ClearOptimizedWindowIfPresent(__instance); return true; } __result = BuildModePerformanceState.PlaceTilesWindow(__instance); return false; } } internal static class BuildModeGetTilePatch { public static bool Prefix(PlacementRegion __instance, Vector3 Position, ref PlacementTile __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!BuildModePerformanceState.TryGetTile(__instance, Position, out var tile)) { return true; } __result = tile; return false; } } internal static class BuildModeGetClosestTilePatch { public static bool Prefix(PlacementRegion __instance, Vector3 Position, float maxDistance, ref PlacementTile __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!BuildModePerformanceState.TryGetClosestTile(__instance, Position, maxDistance, out var tile)) { return true; } __result = tile; return false; } } internal static class BuildModeMouseCameraGatePatch { public static IEnumerable Transpiler(IEnumerable instructions) { MethodInfo placementValidation = AccessTools.Method(typeof(PlacementRegion), "IsValidPlacement", new Type[3] { typeof(Vector3), typeof(bool), typeof(bool) }, (Type[])null); MethodInfo expandedMouseGate = AccessTools.Method(typeof(BuildModeMouseCameraGatePatch), "AllowExpandedMouseTraversal", (Type[])null, (Type[])null); int validationCalls = 0; int movementGateReplacements = 0; int cameraGateReplacements = 0; foreach (CodeInstruction instruction in instructions) { bool isPlacementValidation = (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && object.Equals(instruction.operand, placementValidation); if (isPlacementValidation) { validationCalls++; } if (instruction.opcode == OpCodes.Ldc_R4 && instruction.operand is float && Mathf.Approximately((float)instruction.operand, 5f)) { instruction.operand = 1000f; cameraGateReplacements++; } yield return instruction; if (isPlacementValidation && validationCalls == 2) { yield return new CodeInstruction(OpCodes.Call, (object)expandedMouseGate); movementGateReplacements++; } } if ((validationCalls != 3 || movementGateReplacements != 1 || cameraGateReplacements != 1) && EvenMoreSpacePlugin.Log != null) { EvenMoreSpacePlugin.Log.LogWarning((object)("Unexpected build-mode mouse iterator layout: validations=" + validationCalls + ", movement gates=" + movementGateReplacements + ", camera gates=" + cameraGateReplacements + ".")); } else if (EvenMoreSpacePlugin.Log != null) { EvenMoreSpacePlugin.Log.LogInfo((object)"Patched raw mouse traversal gate in a build-mode iterator."); } } public static bool AllowExpandedMouseTraversal(bool vanillaValid) { if (!vanillaValid) { if (EvenMoreSpaceState.HasActiveExpansion()) { return (Object)(object)PlacementRegion.Instance != (Object)null; } return false; } return true; } } internal static class BuildModeTileAvailabilityPatch { public static bool Prefix(PlacementRegion __instance) { return BuildModePerformanceState.ShouldRefreshAvailability(__instance); } public static IEnumerable Transpiler(IEnumerable instructions) { MethodInfo listContains = AccessTools.Method(typeof(List), "Contains", new Type[1] { typeof(Vector2Int) }, (Type[])null); MethodInfo cachedContains = AccessTools.Method(typeof(BuildModePerformanceState), "ContainsGridPosition", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && object.Equals(instruction.operand, listContains)) { instruction.opcode = OpCodes.Call; instruction.operand = cachedContains; } yield return instruction; } } } internal static class BuildModeClearTilesPatch { public static bool Prefix(PlacementRegion __instance, ref IEnumerator __result) { if (!BuildModePerformanceState.ShouldUseWindowClear(__instance)) { return true; } __result = BuildModePerformanceState.ClearTilesWindow(__instance); return false; } } internal static class BuildModeRegionDestroyPatch { public static void Prefix(PlacementRegion __instance) { BuildModePerformanceState.ForgetRegion(__instance); } } internal static class ExpandedTreeTasksPatch { public static bool Prefix(Structures_Tree __instance) { if (__instance != null) { return EvenMoreSpaceState.HasActiveResourceVisual((StructureBrain)(object)__instance); } return true; } } internal static class ExpandedRubbleTasksPatch { public static bool Prefix(Structures_Rubble __instance) { if (__instance != null) { return EvenMoreSpaceState.HasActiveResourceVisual((StructureBrain)(object)__instance); } return true; } } internal static class ExpandedChopTaskPatch { private static readonly FieldInfo TreeIdField = typeof(FollowerTask_ChopTrees).GetField("_treeID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); public static bool Prefix(FollowerTask_ChopTrees __instance) { int privateInt = EvenMoreSpaceState.GetPrivateInt(TreeIdField, __instance, 0); if (!EvenMoreSpaceState.HasActiveExpansion() || privateInt == 0 || EvenMoreSpaceState.HasActiveResourceVisual((TYPES)16, privateInt)) { return true; } EvenMoreSpaceState.EndUnavailableResourceTask((FollowerTask)(object)__instance); return false; } } internal static class ExpandedRubbleTaskPatch { private static readonly FieldInfo RubbleIdField = typeof(FollowerTask_ClearRubble).GetField("_rubbleID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); public static bool Prefix(FollowerTask_ClearRubble __instance) { int privateInt = EvenMoreSpaceState.GetPrivateInt(RubbleIdField, __instance, 0); if (!EvenMoreSpaceState.HasActiveExpansion() || privateInt == 0 || EvenMoreSpaceState.HasActiveResourceVisual((TYPES)61, privateInt)) { return true; } EvenMoreSpaceState.EndUnavailableResourceTask((FollowerTask)(object)__instance); return false; } } internal static class ExpandedRubbleDestinationPatch { private const float MaximumTaskRadius = 3.75f; public static void Postfix(FollowerTask_ClearRubble __instance, Follower follower, ref Vector3 __result) { //IL_003e: 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_0056: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: 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_00d1: 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_00ef: 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_0101: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) if (__instance == null || (Object)(object)follower == (Object)null || !EvenMoreSpaceState.HasActiveExpansion()) { return; } Structures_Rubble structureByID; try { structureByID = StructureManager.GetStructureByID(__instance.RubbleID); } catch { return; } if (structureByID == null || ((StructureBrain)structureByID).Data == null || structureByID.RockSize == 0 || !EvenMoreSpaceState.IsInsideModdedPlot(((StructureBrain)structureByID).Data.Position) || Vector3.Distance(__result, ((StructureBrain)structureByID).Data.Position) <= 3.75f) { return; } PlacementRegion instance = PlacementRegion.Instance; Vector3 position = ((StructureBrain)structureByID).Data.Position; TileGridTile val = null; float num = float.MaxValue; float num2 = (float)((((Object)follower).GetInstanceID() & 0x7FFFFFFF) % 360) * ((float)Math.PI / 180f); if ((Object)(object)instance != (Object)null && instance.GridTileLookup != null) { Vector2Int val4 = default(Vector2Int); for (int i = 0; i < 16; i++) { float num3 = num2 + (float)i * (float)Math.PI * 0.125f; Vector3 val2 = position + new Vector3(Mathf.Cos(num3), Mathf.Sin(num3), 0f) * 3.25f; Vector3 val3 = ((Component)instance).transform.InverseTransformPoint(val2); ((Vector2Int)(ref val4))..ctor(Mathf.RoundToInt(val3.x), Mathf.RoundToInt(val3.y)); for (int j = -1; j <= 1; j++) { for (int k = -1; k <= 1; k++) { TileGridTile tileGridTile = instance.GetTileGridTile(val4 + new Vector2Int(k, j)); if (tileGridTile == null || tileGridTile.Occupied || tileGridTile.Obstructed || tileGridTile.Collapsed) { continue; } float num4 = Vector3.Distance(tileGridTile.WorldPosition, position); if (!(num4 < 2f) && !(num4 > 3.75f)) { Vector3 val5 = tileGridTile.WorldPosition - val2; float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; val = tileGridTile; } } } } } } if (val != null) { __result = val.WorldPosition; return; } Vector3 val6 = __result - position; if (((Vector3)(ref val6)).sqrMagnitude > 0.001f) { __result = position + ((Vector3)(ref val6)).normalized * 3.75f; } } } internal static class SaveAndLoadResetPatch { public static void Prefix(int saveSlot, bool newGame) { if (newGame) { EvenMoreSpaceState.ClearSaveSlotState(saveSlot); } } } internal static class SaveAndLoadDeletePatch { public static void Postfix(int saveSlot) { if (saveSlot < 10) { EvenMoreSpaceState.ClearSaveSlotState(saveSlot); } } }