Decompiled source of TerrainCustomiser v0.2.3

TerrainCustomiser/TerrainCustomiser.dll

Decompiled a day ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Photon.Pun;
using PhotonCustomPropsUtils;
using TMPro;
using TerrainCustomiser.Networking;
using TerrainCustomiser.TerrainGeneration;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TerrainCustomiser")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.2.3")]
[assembly: AssemblyInformationalVersion("0.2.3+1dda0f2fbcbd0c9601217291b535184ed0be6b76")]
[assembly: AssemblyProduct("TerrainCustomiser")]
[assembly: AssemblyTitle("TerrainCustomiser")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.3.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace TerrainCustomiser
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.snosz.terraincustomiser", "TerrainCustomiser", "0.2.3")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(RunManager), "StartRun")]
		public class StartRunPatch
		{
			private static void Postfix()
			{
				if (!((Object)(object)Singleton<MapHandler>.Instance == (Object)null) && Instance.isLoadingTerrainCustomiserMode)
				{
					Instance.CreateCustomiserUI(GUIManager.instance);
				}
			}
		}

		[HarmonyPatch(typeof(MapHandler), "Start")]
		public static class MapHandlerStartPatch
		{
			private static bool Prefix(MapHandler __instance)
			{
				//IL_0041: 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_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Expected O, but got Unknown
				viewIDsToSend = new List<int>();
				viewsRequiringIDs = new List<PhotonView>();
				TerrainData defaultTerrainData = TerrainExporter.GetDefaultTerrainData();
				JsonSerializer val = JsonSerializer.Create(SaveFileManager.JsonSettings);
				JObject val2 = JObject.FromObject((object)defaultTerrainData, val);
				JObject val3 = JObject.FromObject((object)Instance.hostTerrainData, val);
				((JContainer)val2).Merge((object)val3, new JsonMergeSettings
				{
					MergeArrayHandling = (MergeArrayHandling)3,
					MergeNullValueHandling = (MergeNullValueHandling)0
				});
				TerrainData terrainData = ((JToken)val2).ToObject<TerrainData>(val);
				SaveFileManager.RestoreNonSerializedFields(terrainData, defaultTerrainData);
				Instance.ApplyPropertiesFromTerrainData(terrainData);
				Random.InitState(Instance.hostTerrainData.Settings.seed);
				GameObject segmentCampfire = Singleton<MapHandler>.Instance.segments.First((MapSegment s) => ((Object)s.segmentCampfire).name == "Volcano_Campfire").segmentCampfire;
				if ((Object)(object)segmentCampfire != (Object)null)
				{
					segmentCampfire.SetActive(false);
				}
				MapHandlerHelpers.RunAllSegments(__instance.segments);
				MapHandlerHelpers.RunGobal(__instance.globalParent);
				if ((Object)(object)segmentCampfire != (Object)null)
				{
					segmentCampfire.SetActive(true);
				}
				if (PhotonNetwork.IsMasterClient)
				{
					List<int> andAssignAllUnassignedViews = MapHandlerHelpers.GetAndAssignAllUnassignedViews();
					viewIDsToSend.AddRange(andAssignAllUnassignedViews);
					Instance.SendViewIDsToPlayers(viewIDsToSend);
				}
				return true;
			}
		}

		public static Plugin Instance;

		private static Harmony _harmony;

		private PhotonScopedManager manager;

		public string path = Assembly.GetExecutingAssembly().Location;

		private string testJson;

		public AssetBundle terrainCustomiserUIBundle;

		public TerrainCustomiserUI terrainCustomiserUI;

		public static ConfigEntry<KeyCode> LoadTerrainCustomiserModeKey;

		public static ConfigEntry<KeyCode> LoadTerrainDataSaveKey;

		public static ConfigEntry<string> TerrainDataSaveFilenameToLoad;

		public static List<int> viewIDsToSend;

		public static List<PhotonView> viewsRequiringIDs;

		public static List<int> receivedViewIDs;

		private bool canLaunchTerrainCustomiser = false;

		private bool canLaunchCustomTerrain = false;

		public TerrainData hostTerrainData;

		private bool isLoadingCustomTerrain = false;

		private bool isLoadingTerrainCustomiserMode = false;

		private bool patchedTerrainGeneration = false;

		public bool isInTerrainCustomiserMode = false;

		private MainCameraMovement cameraMovement;

		private MainCamera mainCamera;

		private FieldInfo isGodCamFieldInfo;

		private static readonly Dictionary<string, Vector3> teleportPositions = new Dictionary<string, Vector3>
		{
			{
				"BeachPanel",
				new Vector3(9.9005f, 123.3415f, -427.0678f)
			},
			{
				"JunglePanel",
				new Vector3(9.5816f, 360.8353f, 36.5277f)
			},
			{
				"SnowPanel",
				new Vector3(-0.7802f, 572.6466f, 552.7788f)
			},
			{
				"DesertPanel",
				new Vector3(-0.7802f, 572.6466f, 552.7788f)
			},
			{
				"LavaPanel",
				new Vector3(2.2909f, 917.6837f, 1251.495f)
			},
			{
				"VolcanoPanel",
				new Vector3(2.7372f, 862.5374f, 2043.938f)
			}
		};

		private int currentSectionIndex = -1;

		private static readonly Dictionary<string, int> sectionMatches = new Dictionary<string, int>
		{
			{ "BeachPanel", 0 },
			{ "JunglePanel", 1 },
			{ "SnowPanel", 2 },
			{ "DesertPanel", 2 },
			{ "LavaPanel", 3 },
			{ "VolcanoPanel", 4 }
		};

		private void Awake()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			Instance = this;
			TerrainDataSaveFilenameToLoad = ((BaseUnityPlugin)this).Config.Bind<string>("General", "TerrainDataSaveFilenameToLoad", "Default", "Name of json file in Map Saves folder that will be loaded when LoadTerrainDataSaveKey is pressed.");
			LoadTerrainCustomiserModeKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkey", "LoadTerrainCustomiserModeKey", (KeyCode)282, "Keybinding to enter Terrain Customiser Mode when in Offline mode in airport.");
			LoadTerrainDataSaveKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkey", "LoadTerrainDataSaveKey", (KeyCode)282, "Keybinding to load and play chosen terrain data filename when in online mode in airport.");
			byte[] terraincustomiserui = Resource1.terraincustomiserui;
			terrainCustomiserUIBundle = AssetBundle.LoadFromMemory(terraincustomiserui);
			_harmony = new Harmony("com.snosz.terraincustomiser");
			AddPhotonManager();
			SceneManager.activeSceneChanged += Instance.OnSceneChanged;
		}

		private void OnSceneChanged(Scene oldScene, Scene newScene)
		{
			if (!PhotonNetwork.OfflineMode)
			{
				canLaunchTerrainCustomiser = false;
			}
			if (((Scene)(ref newScene)).name == "Airport")
			{
				if (patchedTerrainGeneration)
				{
					_harmony.UnpatchSelf();
					patchedTerrainGeneration = false;
				}
				if (isInTerrainCustomiserMode)
				{
					isInTerrainCustomiserMode = false;
				}
				if (PhotonNetwork.OfflineMode)
				{
					canLaunchTerrainCustomiser = true;
				}
				else
				{
					canLaunchCustomTerrain = true;
				}
			}
			if (((Scene)(ref oldScene)).name == "WilIsland")
			{
				if (patchedTerrainGeneration)
				{
					_harmony.UnpatchSelf();
					patchedTerrainGeneration = false;
				}
				if (isInTerrainCustomiserMode)
				{
					isInTerrainCustomiserMode = false;
				}
			}
		}

		private void AddPhotonManager()
		{
			manager = PhotonCustomPropsUtilsPlugin.GetManager("com.snosz.terraincustomiser");
			manager.RegisterRoomProperty<byte[]>("terrainData", (RoomEventType)2, (Action<byte[]>)delegate(byte[] val)
			{
				string text = NetworkUtils.DecompressBytes(val);
				Debug.LogError((object)text);
				TerrainData terrainData = SaveFileManager.LoadFromString(text);
				if (terrainData != null)
				{
					hostTerrainData = terrainData;
					if (PhotonNetwork.IsMasterClient)
					{
						TransitionToCustomMap();
					}
					else if (!patchedTerrainGeneration)
					{
						_harmony.PatchAll(typeof(GenerationPatches.PropGrouperPatch));
						_harmony.PatchAll(typeof(GenerationPatches.LevelGenStepSpawnPatch));
						_harmony.PatchAll(typeof(GenerationPatches.PropSpawnerSpawnDecorPatch));
						_harmony.PatchAll(typeof(GenerationPatches.DecorSpawner_Add_Prefix));
						_harmony.PatchAll(typeof(GenerationPatches.PropSpawnerAddPatch));
						_harmony.PatchAll(typeof(MapHandlerStartPatch));
						patchedTerrainGeneration = true;
					}
				}
			});
			manager.RegisterRoomProperty<int[]>("propViews", (RoomEventType)2, (Action<int[]>)delegate(int[] val)
			{
				if (!PhotonNetwork.IsMasterClient)
				{
					if (receivedViewIDs == null)
					{
						receivedViewIDs = new List<int>();
					}
					else
					{
						receivedViewIDs.Clear();
					}
					receivedViewIDs = val.ToList();
					Instance.UpdateRequiredViewIDs();
					Debug.Log((object)$"[TerrainCustomiser] Updated receivedViewIDs with {receivedViewIDs.Count} IDs");
				}
			});
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			terrainCustomiserUIBundle.Unload(true);
		}

		private void Update()
		{
			//IL_000b: 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)
			if (UnityInput.Current.GetKeyDown(LoadTerrainCustomiserModeKey.Value) && canLaunchTerrainCustomiser && !canLaunchCustomTerrain)
			{
				LoadTerrainCustomiser();
			}
			if (UnityInput.Current.GetKeyDown((KeyCode)27) && isInTerrainCustomiserMode)
			{
				ForceTogglePauseMenu();
			}
			if (UnityInput.Current.GetKeyDown(LoadTerrainDataSaveKey.Value) && canLaunchCustomTerrain && PhotonNetwork.IsMasterClient && !canLaunchTerrainCustomiser)
			{
				LoadCustomTerrain();
			}
			if (UnityInput.Current.GetMouseButtonDown(1))
			{
				if (isInTerrainCustomiserMode)
				{
					isGodCamFieldInfo.SetValue(cameraMovement, true);
				}
			}
			else if (UnityInput.Current.GetMouseButtonUp(1) && isInTerrainCustomiserMode)
			{
				isGodCamFieldInfo.SetValue(cameraMovement, false);
			}
		}

		public void ForceTogglePauseMenu()
		{
			Object.op_Implicit((Object)(object)GUIManager.instance);
			if (!GUIManager.instance.pauseMenu.activeSelf)
			{
				GUIManager.instance.pauseMenu.SetActive(true);
				return;
			}
			Object.op_Implicit((Object)(object)GUIManager.instance);
			if (GUIManager.instance.pauseMenu.activeSelf)
			{
				GUIManager.instance.pauseMenu.SetActive(false);
			}
		}

		private void TransitionToCustomMap()
		{
			isLoadingCustomTerrain = true;
			AirportCheckInKiosk val = Object.FindFirstObjectByType<AirportCheckInKiosk>();
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"[TerrainCustomiser] Failed to find airportkiosk");
				return;
			}
			((MonoBehaviourPun)val).photonView.RPC("BeginIslandLoadRPC", (RpcTarget)0, new object[2]
			{
				"WilIsland",
				GUIManager.instance.boardingPass.ascentIndex
			});
		}

		private void LoadCustomTerrain()
		{
			AirportCheckInKiosk val = Object.FindFirstObjectByType<AirportCheckInKiosk>();
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"[TerrainCustomiser] Failed to find airportkiosk");
				return;
			}
			canLaunchCustomTerrain = false;
			TerrainData terrainData = SaveFileManager.LoadRaw(TerrainDataSaveFilenameToLoad.Value);
			if (terrainData == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"[TerrainCustomiser] Failed to find save file. Is the set file name correct?");
				return;
			}
			int seed = Random.Range(1, 10001);
			terrainData.Settings.seed = seed;
			NetworkUtils.SetTerrainDataRoomProperty(terrainData, manager);
			if (!patchedTerrainGeneration)
			{
				_harmony.PatchAll(typeof(GenerationPatches.PropGrouperPatch));
				_harmony.PatchAll(typeof(GenerationPatches.LevelGenStepSpawnPatch));
				_harmony.PatchAll(typeof(GenerationPatches.PropSpawnerSpawnDecorPatch));
				_harmony.PatchAll(typeof(GenerationPatches.DecorSpawner_Add_Prefix));
				_harmony.PatchAll(typeof(GenerationPatches.PropSpawnerAddPatch));
				_harmony.PatchAll(typeof(MapHandlerStartPatch));
				patchedTerrainGeneration = true;
			}
		}

		private void LoadTerrainCustomiser()
		{
			AirportCheckInKiosk val = Object.FindFirstObjectByType<AirportCheckInKiosk>();
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"[TerrainCustomiser] Failed to find airportkiosk");
				return;
			}
			viewIDsToSend = new List<int>();
			isLoadingTerrainCustomiserMode = true;
			canLaunchTerrainCustomiser = false;
			if (!patchedTerrainGeneration)
			{
				_harmony.PatchAll(typeof(GenerationPatches.PropGrouperPatch));
				_harmony.PatchAll(typeof(GenerationPatches.LevelGenStepSpawnPatch));
				_harmony.PatchAll(typeof(GenerationPatches.PropSpawnerSpawnDecorPatch));
				_harmony.PatchAll(typeof(GenerationPatches.DecorSpawner_Add_Prefix));
				_harmony.PatchAll(typeof(GenerationPatches.PropSpawnerAddPatch));
				_harmony.PatchAll(typeof(StartRunPatch));
				patchedTerrainGeneration = true;
			}
			((MonoBehaviourPun)val).photonView.RPC("BeginIslandLoadRPC", (RpcTarget)0, new object[2] { "WilIsland", 0 });
		}

		private void CreateCustomiserUI(GUIManager instance)
		{
			if (!((Object)(object)Instance.terrainCustomiserUI != (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("TerrainCustomiserUI"), ((Component)instance).transform);
				Instance.terrainCustomiserUI = val.AddComponent<TerrainCustomiserUI>();
				Instance.terrainCustomiserUI.vector3Prefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("Vector3InputContainer");
				Instance.terrainCustomiserUI.vector3Prefab.AddComponent<Vector3InputUI>();
				Instance.terrainCustomiserUI.vector2Prefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("Vector2InputContainer");
				Instance.terrainCustomiserUI.vector2Prefab.AddComponent<Vector2InputUI>();
				Instance.terrainCustomiserUI.boolPrefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("BooleanInputContainer");
				Instance.terrainCustomiserUI.boolPrefab.AddComponent<BooleanInputUI>();
				Instance.terrainCustomiserUI.numberPrefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("NumberInputContainer");
				Instance.terrainCustomiserUI.numberPrefab.AddComponent<NumberInputUI>();
				Instance.terrainCustomiserUI.propGrouperPrefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("GrouperPanel");
				Instance.terrainCustomiserUI.propGrouperPrefab.AddComponent<PropGrouperUI>();
				Instance.terrainCustomiserUI.propSpawnerPrefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("SpawnerPanel");
				Instance.terrainCustomiserUI.propSpawnerPrefab.AddComponent<PropSpawnerUI>();
				Instance.terrainCustomiserUI.constraintPrefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("ModifierPanel");
				Instance.terrainCustomiserUI.constraintPrefab.AddComponent<ConstraintPanelUI>();
				Instance.terrainCustomiserUI.propertyPanelPrefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("PropertyPanel");
				Instance.terrainCustomiserUI.propertyPanelPrefab.AddComponent<PropertyPanelUI>();
				Instance.terrainCustomiserUI.buttonPanelPrefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("ButtonInputContainer");
				Instance.terrainCustomiserUI.buttonPanelPrefab.AddComponent<ButtonInputUI>();
				Instance.terrainCustomiserUI.dropdownPanelPrefab = Instance.terrainCustomiserUIBundle.LoadAsset<GameObject>("DropdownInputContainer");
				Instance.terrainCustomiserUI.dropdownPanelPrefab.AddComponent<DropdownInputUI>();
				Instance.terrainCustomiserUI.Init();
				Instance.terrainCustomiserUI.Toggle();
				GameObject.Find("Misc/Post Fog").SetActive(false);
				GameObject.Find("FogSphereSystem").SetActive(false);
				((Component)Character.localCharacter).gameObject.SetActive(false);
				Scoutmaster val2 = default(Scoutmaster);
				if (Scoutmaster.GetPrimaryScoutmaster(ref val2))
				{
					((Component)val2).gameObject.SetActive(false);
				}
				Character.localCharacter = null;
				((Component)GUIManager.instance.hudCanvas).gameObject.SetActive(false);
				InitiateTerrainCustomiserCamera();
				terrainCustomiserUI.TogglePanel(terrainCustomiserUI.menuItems[0].panel);
				isLoadingTerrainCustomiserMode = false;
				isInTerrainCustomiserMode = true;
			}
		}

		private void InitiateTerrainCustomiserCamera()
		{
			mainCamera = ((Component)Camera.main).GetComponent<MainCamera>();
			cameraMovement = ((Component)Camera.main).GetComponent<MainCameraMovement>();
			isGodCamFieldInfo = AccessTools.Field(((object)cameraMovement).GetType(), "isGodCam");
			CameraOverride val = ((Component)Camera.main).gameObject.AddComponent<CameraOverride>();
			val.fov = Camera.main.fieldOfView;
			mainCamera.SetCameraOverride(val);
			PerlinShake componentInChildren = ((Component)GamefeelHandler.instance).gameObject.GetComponentInChildren<PerlinShake>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
		}

		public void TeleportPlayer(string panelName)
		{
			if (teleportPositions.TryGetValue(panelName, out var _))
			{
				SetCurrentSection(panelName);
			}
		}

		public void SetCurrentSection(string panelName)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			int num = (currentSectionIndex = sectionMatches[panelName]);
			for (int i = 0; i < Singleton<MapHandler>.Instance.segments.Length; i++)
			{
				if (i != num)
				{
					Singleton<MapHandler>.Instance.segments[i].segmentParent.SetActive(false);
					if ((Object)(object)Singleton<MapHandler>.Instance.segments[i].segmentCampfire != (Object)null)
					{
						Singleton<MapHandler>.Instance.segments[i].segmentCampfire.SetActive(false);
					}
					continue;
				}
				Singleton<MapHandler>.Instance.segments[i].segmentParent.SetActive(true);
				if ((Object)(object)Singleton<MapHandler>.Instance.segments[i].segmentCampfire != (Object)null)
				{
					Singleton<MapHandler>.Instance.segments[i].segmentCampfire.SetActive(true);
				}
				((Component)Camera.main).transform.position = teleportPositions[panelName];
				if ((Object)(object)Singleton<MapHandler>.Instance.segments[i].wallNext != (Object)null)
				{
					((Component)Camera.main).transform.LookAt(Singleton<MapHandler>.Instance.segments[i].wallNext.transform);
				}
			}
		}

		public void UpdateRequiredViewIDs()
		{
			if (PhotonNetwork.IsMasterClient)
			{
				return;
			}
			if (viewsRequiringIDs == null || receivedViewIDs == null)
			{
				Debug.LogError((object)"[TerrainCustomiser] Required lists did not initialize or have already been resolved.");
				return;
			}
			if (viewsRequiringIDs.Count > receivedViewIDs.Count)
			{
				Debug.LogError((object)"[TerrainCustomiser] ID Count mismatch! Map will be out of sync!");
				return;
			}
			for (int i = 0; i < viewsRequiringIDs.Count; i++)
			{
				viewsRequiringIDs[i].ViewID = receivedViewIDs[i];
			}
			List<PhotonView> allUnassignedViews = MapHandlerHelpers.GetAllUnassignedViews();
			for (int j = 0; j < allUnassignedViews.Count; j++)
			{
				allUnassignedViews[j].ViewID = receivedViewIDs[viewsRequiringIDs.Count + j];
			}
			viewsRequiringIDs.Clear();
			viewsRequiringIDs = null;
		}

		public void SendViewIDsToPlayers(List<int> viewIDs)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				Instance.manager.SetRoomProperty("propViews", (object)viewIDs.ToArray());
				Debug.Log((object)$"[TerrainCustomiser] Host sent {viewIDs.Count} generated ViewIDs.");
			}
		}

		public void ApplyPropertiesFromTerrainData(TerrainData terrainData)
		{
			foreach (TerrainData.SegmentData segment in terrainData.Map.segments)
			{
				foreach (TerrainData.PropGrouperData grouper in segment.groupers)
				{
					foreach (TerrainData.LevelGenStepData step in grouper.steps)
					{
						ApplyPropertyList(step._sourceObject, step.properties);
						ApplyConstraintList(step._sourceObject, step.modifiers);
						ApplyConstraintList(step._sourceObject, step.constraints);
						ApplyConstraintList(step._sourceObject, step.postConstraints);
					}
				}
			}
		}

		private void ApplyConstraintList(LevelGenStep sourceObject, List<TerrainData.ConstraintData> constraints)
		{
			if ((Object)(object)sourceObject == (Object)null || constraints == null)
			{
				return;
			}
			Dictionary<string, IEnumerable> dictionary = new Dictionary<string, IEnumerable>();
			string[] array = new string[3] { "modifiers", "constraints", "postConstraints" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				FieldInfo field = ((object)sourceObject).GetType().GetField(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.GetValue(sourceObject) is IEnumerable value)
				{
					dictionary[text] = value;
				}
			}
			foreach (TerrainData.ConstraintData constraint in constraints)
			{
				bool flag = false;
				foreach (IEnumerable value2 in dictionary.Values)
				{
					foreach (object item in value2)
					{
						if (item != null && item.GetType().Name == constraint.type)
						{
							ApplyPropertyList(item, constraint.properties);
							flag = true;
							break;
						}
					}
					if (flag)
					{
						break;
					}
				}
			}
		}

		private void ApplyPropertyList(object target, List<TerrainData.PropertyData> properties)
		{
			Type type = target.GetType();
			foreach (TerrainData.PropertyData property in properties)
			{
				FieldInfo field = type.GetField(property.name, BindingFlags.Instance | BindingFlags.Public);
				if (field != null)
				{
					field.SetValue(target, property.value);
				}
			}
		}
	}
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resource1
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("TerrainCustomiser.Resource1", typeof(Resource1).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] terraincustomiserui
		{
			get
			{
				object @object = ResourceManager.GetObject("terraincustomiserui", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resource1()
		{
		}
	}
	public static class PropGrouperHelpers
	{
		public static void CollectLateLevelGenSteps(PropGrouper grouper, List<LevelGenStep> results)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			results.Clear();
			LevelGenStep[] componentsInChildren = ((Component)grouper).GetComponentsInChildren<LevelGenStep>(true);
			LevelGenStep[] array = componentsInChildren;
			foreach (LevelGenStep val in array)
			{
				PropGrouper componentInParent = ((Component)val).GetComponentInParent<PropGrouper>();
				if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.timing == 1)
				{
					results.Add(val);
				}
			}
		}

		public static void RunLateLevelGenSteps(List<LevelGenStep> steps)
		{
			foreach (LevelGenStep step in steps)
			{
				step.Go();
			}
		}
	}
	public static class PropSpawnerHelpers
	{
		public static readonly HashSet<string> SafeToBatchPropNames = new HashSet<string>
		{
			"LuggageSpawner", "LuggageSpawner_High", "LuggageSpawner_Low", "LuggageSpawner_Canyon", "LuggageSpawner_Mirrage", "TumblerHell", "Aloe", "Dead Grass", "Big", "Cactus",
			"Cactus_Balls (1)", "Cactus_Big", "Cactus_Big_Dry", "Tumblers", "CactusOnTop", "Ivy", "Geysers", "Weed", "ExploShrooms", "PoisonShrooms",
			"Vines", "BeachGrass", "Driftwood", "Behive", "ShittyPiton", "Monsteras", "FlashPlant", "Shrub", "Pine", "Bushes",
			"Trees", "DeadTree", "Palms"
		};

		public static bool TrySpawn(SpawnData spawnData, ref GameObject __result, GameObject[] props, List<PropSpawnerMod> modifiers, List<PropSpawnerConstraintPost> postConstraints, Transform parent, GameObject fallback, List<int> viewIDsToSend, List<PhotonView> viewsRequiringIDs)
		{
			//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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = props[Random.Range(0, props.Length)];
			PhotonView val2 = default(PhotonView);
			if ((Object)(object)val != (Object)null && val.TryGetComponent<PhotonView>(ref val2))
			{
				Quaternion randomRotationWithUp = GetRandomRotationWithUp(Vector3.up);
				GameObject val3 = Object.Instantiate<GameObject>(val, spawnData.pos, randomRotationWithUp, parent);
				RemoveSpineIfLuggage(val3);
				PropGrouper componentInParent = fallback.GetComponentInParent<PropGrouper>();
				ApplyModifiers(val3, spawnData, modifiers);
				if (!CheckAndHandlePostConstraints(val3, spawnData, postConstraints))
				{
					__result = null;
					return false;
				}
				HandleIfBridge(val3);
				if (PhotonNetwork.IsMasterClient)
				{
					viewIDsToSend.Add(AssignMasterClientViewID(val3));
				}
				else
				{
					CollectViewRequiringID(val3, viewsRequiringIDs);
				}
				__result = val3;
				return false;
			}
			return true;
		}

		public static Quaternion GetRandomRotationWithUp(Vector3 normal)
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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)
			Vector3 onUnitSphere = Random.onUnitSphere;
			onUnitSphere.y = 0f;
			onUnitSphere = Vector3.Cross(normal, Vector3.Cross(normal, onUnitSphere));
			return Quaternion.LookRotation(onUnitSphere, normal);
		}

		public static bool CheckAndHandlePostConstraints(GameObject go, SpawnData spawnData, List<PropSpawnerConstraintPost> postConstraints)
		{
			foreach (PropSpawnerConstraintPost postConstraint in postConstraints)
			{
				if (postConstraint.mute || postConstraint.CheckConstraint(go, spawnData))
				{
					continue;
				}
				Object.DestroyImmediate((Object)(object)go);
				return false;
			}
			return true;
		}

		public static void ApplyModifiers(GameObject go, SpawnData spawnData, List<PropSpawnerMod> modifiers)
		{
			foreach (PropSpawnerMod modifier in modifiers)
			{
				if (!modifier.mute)
				{
					modifier.ModifyObject(go, spawnData);
				}
			}
		}

		public static void RemoveSpineIfLuggage(GameObject go)
		{
			Luggage val = default(Luggage);
			if (go.TryGetComponent<Luggage>(ref val))
			{
				SpineCheck component = go.GetComponent<SpineCheck>();
				if ((Object)(object)component != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)component);
				}
			}
		}

		public static void HandleIfBridge(GameObject go)
		{
			BreakableBridge @object = default(BreakableBridge);
			if (go.TryGetComponent<BreakableBridge>(ref @object))
			{
				CollisionModifier[] componentsInChildren = go.GetComponentsInChildren<CollisionModifier>();
				CollisionModifier[] array = componentsInChildren;
				foreach (CollisionModifier val in array)
				{
					val.applyEffects = false;
					val.onCollide = (Action<Character, CollisionModifier, Collision, Bodypart>)Delegate.Combine(val.onCollide, new Action<Character, CollisionModifier, Collision, Bodypart>(@object.OnBridgeCollision));
				}
			}
		}

		public static bool CheckIfBridge(GameObject go)
		{
			BreakableBridge val = default(BreakableBridge);
			if (go.TryGetComponent<BreakableBridge>(ref val))
			{
				return true;
			}
			return false;
		}

		public static int AssignMasterClientViewID(GameObject go)
		{
			int num = PhotonNetwork.AllocateViewID(false);
			PhotonView component = go.GetComponent<PhotonView>();
			component.ViewID = num;
			return num;
		}

		public static void CollectViewRequiringID(GameObject go, List<PhotonView> viewsRequiringIDs)
		{
			PhotonView component = go.GetComponent<PhotonView>();
			viewsRequiringIDs.Add(component);
		}

		public static Ray[] BuildRays(PropSpawner spawner, Ray[] outRays, int count, Vector3 rayDir)
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < count; i++)
			{
				outRays[i] = GetSpawnRay(spawner.area, ((Component)spawner).transform, rayDir);
			}
			return outRays;
		}

		public static Ray GetSpawnRay(Vector2 area, Transform t, Vector3 rayDir)
		{
			//IL_0013: 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_0023: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0069: 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)
			//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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(Random.value, Random.value);
			Vector3 val2 = t.position + t.right * Mathf.Lerp((0f - area.x) * 0.5f, area.x * 0.5f, val.x) + t.up * Mathf.Lerp((0f - area.y) * 0.5f, area.y * 0.5f, val.y);
			return new Ray(val2, rayDir);
		}

		public static int PerformRaycasts(PropSpawner spawner, Ray[] rays, RaycastHit[] hits, int rayCount, int mask)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			int num = 0;
			RaycastHit val = default(RaycastHit);
			for (int i = 0; i < rayCount; i++)
			{
				if (Physics.Raycast(rays[i], ref val, spawner.rayLength, mask, (QueryTriggerInteraction)1))
				{
					hits[i] = val;
					num++;
				}
				else
				{
					hits[i] = default(RaycastHit);
				}
			}
			return num;
		}

		public static SpawnData BuildSpawnData(PropSpawner spawner, Ray ray, RaycastHit hit, bool hasHit, int count)
		{
			//IL_0003: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0066: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_008c: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			Vector3 val = ((Ray)(ref ray)).origin - ((Component)spawner).transform.position;
			Vector2 placement = default(Vector2);
			((Vector2)(ref placement))..ctor(Vector3.Dot(val, ((Component)spawner).transform.right) / spawner.area.x + 0.5f, Vector3.Dot(val, ((Component)spawner).transform.up) / spawner.area.y + 0.5f);
			return new SpawnData
			{
				pos = ((RaycastHit)(ref hit)).point,
				normal = ((RaycastHit)(ref hit)).normal,
				rayDir = ((Component)spawner).transform.forward,
				hit = hit,
				spawnerTransform = ((Component)spawner).transform,
				placement = placement,
				spawnCount = count
			};
		}
	}
	public class BooleanInputUI : MonoBehaviour, IPropertyInputUI
	{
		private Toggle toggle;

		private TerrainData.PropertyData boundProperty;

		private TerrainData.LevelGenStepData stepDataParent;

		private TerrainData.ConstraintData constraintData;

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData)
		{
			toggle = ((Component)((Component)this).transform.Find("Toggle")).GetComponent<Toggle>();
			boundProperty = property;
			stepDataParent = stepData;
			if (property.value is bool isOn)
			{
				toggle.isOn = isOn;
				((UnityEvent<bool>)(object)toggle.onValueChanged).AddListener((UnityAction<bool>)OnToggleChanged);
			}
			else
			{
				Debug.LogWarning((object)"Property is not a bool");
			}
		}

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData, TerrainData.ConstraintData data)
		{
			constraintData = data;
			Init(property, stepData);
		}

		public void InitWithAction(TerrainData.PropertyData property, Action<object> onChanged)
		{
			Action<object> onChanged2 = onChanged;
			toggle = ((Component)((Component)this).transform.Find("Toggle")).GetComponent<Toggle>();
			object value = property.value;
			if (!(value is bool))
			{
				return;
			}
			bool isOn = (bool)value;
			if (true)
			{
				toggle.isOn = isOn;
				((UnityEvent<bool>)(object)toggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool v)
				{
					onChanged2?.Invoke(v);
				});
			}
		}

		private void OnToggleChanged(bool val)
		{
			TerrainCustomiserUI.Instance.SetPropertyValue(stepDataParent, boundProperty, val, constraintData);
		}
	}
	public class ButtonInputUI : MonoBehaviour, IPropertyInputUI
	{
		private Button button;

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData)
		{
			throw new NotImplementedException();
		}

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData, TerrainData.ConstraintData data)
		{
			throw new NotImplementedException();
		}

		public void InitWithAction(TerrainData.PropertyData property, Action<object> onChanged)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			Action<object> onChanged2 = onChanged;
			button = ((Component)((Component)this).transform.Find("Button")).GetComponent<Button>();
			((TMP_Text)((Component)button).GetComponentInChildren<TextMeshProUGUI>()).text = property.name;
			((UnityEvent)button.onClick).AddListener((UnityAction)delegate
			{
				onChanged2(null);
			});
		}
	}
	public class ConstraintPanelUI : MonoBehaviour
	{
		private TextMeshProUGUI title;

		private Transform propertyContainer;

		public Button collapseButton;

		public void Init(TerrainData.ConstraintData data, TerrainData.LevelGenStepData stepData)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			title = ((Component)((Component)this).transform.Find("HeaderPanel/Title")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)title).text = data.type;
			propertyContainer = ((Component)this).transform.Find("PropertiesPanel");
			collapseButton = ((Component)((Component)this).transform.Find("HeaderPanel/CollapseButton")).GetComponent<Button>();
			((UnityEvent)collapseButton.onClick).AddListener((UnityAction)delegate
			{
				//IL_0043: 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)
				((Component)collapseButton).transform.eulerAngles = (((Component)propertyContainer).gameObject.activeSelf ? new Vector3(0f, 0f, 90f) : new Vector3(0f, 0f, 0f));
				((Component)propertyContainer).gameObject.SetActive(!((Component)propertyContainer).gameObject.activeSelf);
			});
			foreach (TerrainData.PropertyData property in data.properties)
			{
				GameObject val = TerrainCustomiserUI.Instance.CreatePropertyPanel(property, propertyContainer);
				PropertyPanelUI component = val.GetComponent<PropertyPanelUI>();
				component.Init(property, stepData, data);
			}
		}
	}
	public class DropdownInputUI : MonoBehaviour
	{
		private TMP_Dropdown dropdown;

		private Action<object> onChangedAction;

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData)
		{
			throw new NotImplementedException();
		}

		public void InitWithAction(TerrainData.PropertyData property, Action<object> onChanged)
		{
			dropdown = ((Component)((Component)this).transform.Find("Dropdown")).GetComponent<TMP_Dropdown>();
			onChangedAction = onChanged;
			((UnityEvent<int>)(object)dropdown.onValueChanged).AddListener((UnityAction<int>)delegate(int val)
			{
				onChangedAction(dropdown.options[val].text);
			});
		}

		public void ClearAndAddOptions(List<string> options)
		{
			List<string> list = new List<string>();
			foreach (string item in options)
			{
				if (dropdown.options.Find((OptionData o) => o.text == item) == null)
				{
					list.Add(item);
				}
			}
			dropdown.AddOptions(list);
		}

		public void ClearAndSetOptions(List<string> options)
		{
			dropdown.ClearOptions();
			dropdown.AddOptions(options);
			if (options.Count > 0)
			{
				onChangedAction(dropdown.options[0].text);
			}
		}
	}
	public interface IPropertyInputUI
	{
		void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData);

		void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData, TerrainData.ConstraintData data);

		void InitWithAction(TerrainData.PropertyData property, Action<object> onChanged);
	}
	public class NumberInputUI : MonoBehaviour, IPropertyInputUI
	{
		private TMP_InputField input;

		private TerrainData.PropertyData boundProperty;

		private TerrainData.LevelGenStepData stepDataParent;

		private Type propertyType;

		private TerrainData.ConstraintData constraintData;

		public event Action<string> OnChanged;

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData)
		{
			input = ((Component)((Component)this).transform.Find("InputFieldX")).GetComponent<TMP_InputField>();
			boundProperty = property;
			stepDataParent = stepData;
			propertyType = property.value?.GetType();
			if (propertyType == typeof(int))
			{
				input.contentType = (ContentType)2;
				input.text = property.value.ToString();
				((UnityEvent<string>)(object)input.onEndEdit).AddListener((UnityAction<string>)OnValueChanged);
			}
			else if (propertyType == typeof(float) || propertyType == typeof(double))
			{
				input.contentType = (ContentType)3;
				input.text = property.value.ToString();
				((UnityEvent<string>)(object)input.onEndEdit).AddListener((UnityAction<string>)OnValueChanged);
			}
			else
			{
				Debug.LogWarning((object)$"[NumberInputUI] Unsupported numeric type: {propertyType}");
				((Selectable)input).interactable = false;
			}
		}

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData, TerrainData.ConstraintData data)
		{
			constraintData = data;
			Init(property, stepData);
		}

		public void InitWithAction(TerrainData.PropertyData property, Action<object> onChanged)
		{
			Action<object> onChanged2 = onChanged;
			input = ((Component)((Component)this).transform.Find("InputFieldX")).GetComponent<TMP_InputField>();
			if (property.value is int)
			{
				input.contentType = (ContentType)2;
				input.text = property.value.ToString();
				((UnityEvent<string>)(object)input.onEndEdit).AddListener((UnityAction<string>)delegate(string v)
				{
					if (int.TryParse(v, out var result))
					{
						onChanged2?.Invoke(result);
					}
				});
			}
			else if (property.value is string)
			{
				input.contentType = (ContentType)4;
				input.text = property.value.ToString();
				((UnityEvent<string>)(object)input.onEndEdit).AddListener((UnityAction<string>)delegate(string v)
				{
					onChanged2?.Invoke(v);
				});
			}
		}

		private void OnValueChanged(string val)
		{
			if (string.IsNullOrWhiteSpace(val))
			{
				return;
			}
			object obj = null;
			try
			{
				float result2;
				double result3;
				if (propertyType == typeof(int) && int.TryParse(val, out var result))
				{
					obj = result;
				}
				else if (propertyType == typeof(float) && float.TryParse(val, out result2))
				{
					obj = result2;
				}
				else if (propertyType == typeof(double) && double.TryParse(val, out result3))
				{
					obj = result3;
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NumberInputUI] Conversion error: " + ex.Message));
				return;
			}
			if (obj != null)
			{
				TerrainCustomiserUI.Instance.SetPropertyValue(stepDataParent, boundProperty, obj, constraintData);
			}
		}

		public void SetValue(string val)
		{
			input.text = val;
		}

		public void SetCharacterLimit(int limit)
		{
			input.characterLimit = limit;
		}
	}
	public class PropertyPanelUI : MonoBehaviour
	{
		private TextMeshProUGUI title;

		private TerrainData.LevelGenStepData parentGenStep;

		private Transform inputContainer;

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData step)
		{
			title = ((Component)((Component)this).transform.Find("Title")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)title).text = property.name;
			inputContainer = ((Component)this).transform.Find("InputContainer");
			parentGenStep = step;
			GameObject val = TerrainCustomiserUI.Instance.CreatePropertyInput(property, inputContainer);
			if (!((Object)(object)val == (Object)null))
			{
				IPropertyInputUI propertyInputUI = default(IPropertyInputUI);
				if (val.TryGetComponent<IPropertyInputUI>(ref propertyInputUI))
				{
					propertyInputUI.Init(property, step);
				}
				else
				{
					Debug.LogWarning((object)("No IPropertyInputUI found on: " + ((Object)val).name));
				}
			}
		}

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData step, TerrainData.ConstraintData data)
		{
			title = ((Component)((Component)this).transform.Find("Title")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)title).text = property.name;
			inputContainer = ((Component)this).transform.Find("InputContainer");
			parentGenStep = step;
			GameObject val = TerrainCustomiserUI.Instance.CreatePropertyInput(property, inputContainer);
			if (!((Object)(object)val == (Object)null))
			{
				IPropertyInputUI propertyInputUI = default(IPropertyInputUI);
				if (val.TryGetComponent<IPropertyInputUI>(ref propertyInputUI))
				{
					propertyInputUI.Init(property, step, data);
				}
				else
				{
					Debug.LogWarning((object)("No IPropertyInputUI found on: " + ((Object)val).name));
				}
			}
		}

		public IPropertyInputUI InitWithAction(TerrainData.PropertyData property, Action<object> onChanged)
		{
			title = ((Component)((Component)this).transform.Find("Title")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)title).text = property.name;
			inputContainer = ((Component)this).transform.Find("InputContainer");
			GameObject val = TerrainCustomiserUI.Instance.CreatePropertyInput(property, inputContainer);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			IPropertyInputUI propertyInputUI = default(IPropertyInputUI);
			if (val.TryGetComponent<IPropertyInputUI>(ref propertyInputUI))
			{
				propertyInputUI.InitWithAction(property, onChanged);
				return propertyInputUI;
			}
			Debug.LogWarning((object)("No IPropertyInputUI found on: " + ((Object)val).name));
			return null;
		}
	}
	public class PropGrouperUI : MonoBehaviour
	{
		private TextMeshProUGUI title;

		public Transform spawnersContainer;

		public Button collapseButton;

		public void Init(TerrainData.PropGrouperData grouper)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			title = ((Component)((Component)this).transform.Find("HeaderPanel/Title")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)title).text = grouper.grouperName;
			spawnersContainer = ((Component)this).transform.Find("SpawnersPanel");
			collapseButton = ((Component)((Component)this).transform.Find("HeaderPanel/CollapseButton")).GetComponent<Button>();
			((UnityEvent)collapseButton.onClick).AddListener((UnityAction)delegate
			{
				//IL_0043: 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)
				((Component)collapseButton).transform.eulerAngles = (((Component)spawnersContainer).gameObject.activeSelf ? new Vector3(0f, 0f, 90f) : new Vector3(0f, 0f, 0f));
				((Component)spawnersContainer).gameObject.SetActive(!((Component)spawnersContainer).gameObject.activeSelf);
			});
			foreach (TerrainData.LevelGenStepData step in grouper.steps)
			{
				GameObject val = TerrainCustomiserUI.Instance.CreateSpawnerPanel(step, spawnersContainer);
				PropSpawnerUI component = val.GetComponent<PropSpawnerUI>();
				component.Init(step);
			}
		}
	}
	public class PropSpawnerUI : MonoBehaviour
	{
		private TextMeshProUGUI title;

		private Transform propertyContainer;

		public Button collapseButton;

		private TerrainData.LevelGenStepData stepData;

		private List<ConstraintPanelUI> constraintPanels;

		public void Init(TerrainData.LevelGenStepData step)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			constraintPanels = new List<ConstraintPanelUI>();
			stepData = step;
			title = ((Component)((Component)this).transform.Find("HeaderPanel/Title")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)title).text = step.stepName;
			propertyContainer = ((Component)this).transform.Find("PropertiesPanel");
			collapseButton = ((Component)((Component)this).transform.Find("HeaderPanel/CollapseButton")).GetComponent<Button>();
			((UnityEvent)collapseButton.onClick).AddListener((UnityAction)delegate
			{
				//IL_0043: 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)
				((Component)collapseButton).transform.eulerAngles = (((Component)propertyContainer).gameObject.activeSelf ? new Vector3(0f, 0f, 90f) : new Vector3(0f, 0f, 0f));
				((Component)propertyContainer).gameObject.SetActive(!((Component)propertyContainer).gameObject.activeSelf);
				foreach (ConstraintPanelUI constraintPanel in constraintPanels)
				{
					((Component)constraintPanel).gameObject.SetActive(!((Component)constraintPanel).gameObject.activeSelf);
				}
			});
			foreach (TerrainData.PropertyData property in step.properties)
			{
				GameObject val = TerrainCustomiserUI.Instance.CreatePropertyPanel(property, propertyContainer);
				PropertyPanelUI component = val.GetComponent<PropertyPanelUI>();
				component.Init(property, step);
			}
			foreach (TerrainData.ConstraintData modifier in step.modifiers)
			{
				CreateConstraintUI(modifier, ((Component)this).transform);
			}
			foreach (TerrainData.ConstraintData constraint in step.constraints)
			{
				CreateConstraintUI(constraint, ((Component)this).transform);
			}
			foreach (TerrainData.ConstraintData postConstraint in step.postConstraints)
			{
				CreateConstraintUI(postConstraint, ((Component)this).transform);
			}
		}

		private void CreateConstraintUI(TerrainData.ConstraintData data, Transform parent)
		{
			GameObject val = TerrainCustomiserUI.Instance.CreateConstraintPanel(data, parent);
			ConstraintPanelUI component = val.GetComponent<ConstraintPanelUI>();
			constraintPanels.Add(component);
			component.Init(data, stepData);
		}
	}
	public static class SaveFileManager
	{
		private static readonly string SavePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty, "Map Saves");

		public static TerrainData DefaultTerrainData;

		public static TerrainData CurrentTerrainData;

		private static bool initialized = false;

		public static readonly JsonSerializerSettings JsonSettings;

		private static void InitializeDefaultData()
		{
			if (DefaultTerrainData == null)
			{
				DefaultTerrainData = TerrainExporter.GetDefaultTerrainData();
				initialized = true;
			}
		}

		public static void CreateNew(string fileName)
		{
			if (!initialized)
			{
				InitializeDefaultData();
			}
			CurrentTerrainData = new TerrainData();
			SaveDirty(fileName);
		}

		public static TerrainData LoadAndMerge(string dirtyFileName)
		{
			//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_008b: Expected O, but got Unknown
			Directory.CreateDirectory(SavePath);
			string path = Path.Combine(SavePath, dirtyFileName + ".json");
			if (!File.Exists(path))
			{
				CreateNew(dirtyFileName);
			}
			CurrentTerrainData = LoadRaw(dirtyFileName) ?? new TerrainData();
			JsonSerializer val = JsonSerializer.Create(JsonSettings);
			JObject val2 = JObject.FromObject((object)DefaultTerrainData, val);
			JObject val3 = JObject.FromObject((object)CurrentTerrainData, val);
			((JContainer)val2).Merge((object)val3, new JsonMergeSettings
			{
				MergeArrayHandling = (MergeArrayHandling)3,
				MergeNullValueHandling = (MergeNullValueHandling)0
			});
			TerrainData terrainData = ((JToken)val2).ToObject<TerrainData>(val);
			RestoreNonSerializedFields(terrainData, DefaultTerrainData);
			return terrainData;
		}

		public static void SaveDirty(string fileName)
		{
			if (!initialized)
			{
				InitializeDefaultData();
			}
			TerrainData dirtyDifferences = GetDirtyDifferences(CurrentTerrainData, DefaultTerrainData);
			JsonSerializer val = JsonSerializer.Create(JsonSettings);
			JObject val2 = JObject.FromObject((object)dirtyDifferences, val);
			Directory.CreateDirectory(SavePath);
			File.WriteAllText(Path.Combine(SavePath, fileName + ".json"), ((JToken)val2).ToString((Formatting)0, Array.Empty<JsonConverter>()));
		}

		public static TerrainData GetDirtyDifferences(TerrainData current, TerrainData defaults)
		{
			TerrainData terrainData = new TerrainData();
			for (int i = 0; i < current.Map.segments.Count; i++)
			{
				TerrainData.SegmentData segmentData = current.Map.segments[i];
				TerrainData.SegmentData segmentData2 = defaults.Map.segments[i];
				TerrainData.SegmentData segmentData3 = new TerrainData.SegmentData
				{
					segmentName = segmentData.segmentName
				};
				for (int j = 0; j < segmentData.groupers.Count; j++)
				{
					TerrainData.PropGrouperData propGrouperData = segmentData.groupers[j];
					TerrainData.PropGrouperData propGrouperData2 = segmentData2.groupers[j];
					TerrainData.PropGrouperData propGrouperData3 = new TerrainData.PropGrouperData
					{
						grouperName = propGrouperData.grouperName
					};
					for (int k = 0; k < propGrouperData.steps.Count; k++)
					{
						TerrainData.LevelGenStepData levelGenStepData = propGrouperData.steps[k];
						TerrainData.LevelGenStepData levelGenStepData2 = propGrouperData2.steps[k];
						if (!PropertiesEqual(levelGenStepData.properties, levelGenStepData2.properties) || !ConstraintsEqual(levelGenStepData.modifiers, levelGenStepData2.modifiers) || !ConstraintsEqual(levelGenStepData.constraints, levelGenStepData2.constraints) || !ConstraintsEqual(levelGenStepData.postConstraints, levelGenStepData2.postConstraints))
						{
							propGrouperData3.steps.Add(levelGenStepData);
							continue;
						}
						propGrouperData3.steps.Add(new TerrainData.LevelGenStepData
						{
							stepName = levelGenStepData.stepName,
							stepType = levelGenStepData.stepType
						});
					}
					segmentData3.groupers.Add(propGrouperData3);
				}
				terrainData.Map.segments.Add(segmentData3);
			}
			terrainData.Settings = current.Settings;
			return terrainData;
		}

		private static bool PropertiesEqual(List<TerrainData.PropertyData> a, List<TerrainData.PropertyData> b)
		{
			if (a.Count != b.Count)
			{
				return false;
			}
			for (int i = 0; i < a.Count; i++)
			{
				if (a[i].name != b[i].name)
				{
					return false;
				}
				if (!object.Equals(a[i].value, b[i].value))
				{
					return false;
				}
				if (!object.Equals(a[i].initialValue, b[i].initialValue))
				{
					return false;
				}
			}
			return true;
		}

		private static bool ConstraintsEqual(List<TerrainData.ConstraintData> a, List<TerrainData.ConstraintData> b)
		{
			if (a.Count != b.Count)
			{
				return false;
			}
			for (int i = 0; i < a.Count; i++)
			{
				if (a[i].type != b[i].type)
				{
					return false;
				}
				if (!PropertiesEqual(a[i].properties, b[i].properties))
				{
					return false;
				}
			}
			return true;
		}

		public static void RestoreNonSerializedFields(TerrainData merged, TerrainData defaults)
		{
			for (int i = 0; i < merged.Map.segments.Count && i < defaults.Map.segments.Count; i++)
			{
				TerrainData.SegmentData segmentData = merged.Map.segments[i];
				TerrainData.SegmentData segmentData2 = defaults.Map.segments[i];
				segmentData._sourceObject = segmentData2._sourceObject;
				for (int j = 0; j < segmentData.groupers.Count && j < segmentData2.groupers.Count; j++)
				{
					TerrainData.PropGrouperData propGrouperData = segmentData.groupers[j];
					TerrainData.PropGrouperData propGrouperData2 = segmentData2.groupers[j];
					for (int k = 0; k < propGrouperData.steps.Count && k < propGrouperData2.steps.Count; k++)
					{
						TerrainData.LevelGenStepData levelGenStepData = propGrouperData.steps[k];
						TerrainData.LevelGenStepData levelGenStepData2 = propGrouperData2.steps[k];
						levelGenStepData._sourceObject = levelGenStepData2._sourceObject;
					}
				}
			}
		}

		public static string ConvertToJsonString(TerrainData terrainData)
		{
			JsonSerializer val = JsonSerializer.Create(JsonSettings);
			JObject val2 = JObject.FromObject((object)terrainData, val);
			return ((JToken)val2).ToString((Formatting)0, Array.Empty<JsonConverter>());
		}

		public static void DeleteSaveFile(string fileName)
		{
			string path = Path.Combine(SavePath, fileName + ".json");
			if (File.Exists(path))
			{
				File.Delete(path);
			}
		}

		public static TerrainData LoadRaw(string fileName)
		{
			string path = Path.Combine(SavePath, fileName + ".json");
			if (!File.Exists(path))
			{
				return null;
			}
			string text = File.ReadAllText(path);
			return JsonConvert.DeserializeObject<TerrainData>(text, JsonSettings);
		}

		public static TerrainData LoadFromString(string text)
		{
			return JsonConvert.DeserializeObject<TerrainData>(text, JsonSettings);
		}

		public static string Serialize(TerrainData terrainData)
		{
			return JsonConvert.SerializeObject((object)terrainData, (Formatting)1, JsonSettings);
		}

		public static TerrainData Deserialize(string json)
		{
			return JsonConvert.DeserializeObject<TerrainData>(json, JsonSettings);
		}

		public static void SaveToFile(string filePath, TerrainData terrainData)
		{
			JsonSerializer val = JsonSerializer.Create(JsonSettings);
			JObject val2 = JObject.FromObject((object)terrainData, val);
			File.WriteAllText(filePath, ((JToken)val2).ToString((Formatting)1, Array.Empty<JsonConverter>()));
		}

		public static TerrainData LoadFromFile(string filePath)
		{
			string text = File.ReadAllText(filePath);
			TerrainData terrainData = JsonConvert.DeserializeObject<TerrainData>(text, JsonSettings);
			Debug.LogError((object)text);
			return Deserialize(text);
		}

		public static List<string> GetAllSaveFiles()
		{
			if (!Directory.Exists(SavePath))
			{
				return new List<string>();
			}
			return (from f in Directory.GetFiles(SavePath, "*.json")
				select Path.GetFileNameWithoutExtension(f)).ToList();
		}

		static SaveFileManager()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			JsonSerializerSettings val = new JsonSerializerSettings();
			val.Formatting = (Formatting)0;
			val.ReferenceLoopHandling = (ReferenceLoopHandling)1;
			val.ContractResolver = (IContractResolver)new CamelCasePropertyNamesContractResolver();
			val.Converters = (IList<JsonConverter>)(object)new JsonConverter[3]
			{
				(JsonConverter)new Vector2Converter(),
				(JsonConverter)new Vector3Converter(),
				(JsonConverter)new PropertyDataConverter()
			};
			JsonSettings = val;
		}
	}
	public class Vector2Converter : JsonConverter<Vector2>
	{
		public override void WriteJson(JsonWriter writer, Vector2 v, JsonSerializer s)
		{
			//IL_0015: 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)
			writer.WriteStartObject();
			writer.WritePropertyName("x");
			writer.WriteValue(v.x);
			writer.WritePropertyName("y");
			writer.WriteValue(v.y);
			writer.WriteEndObject();
		}

		public override Vector2 ReadJson(JsonReader r, Type t, Vector2 existing, bool hasExisting, JsonSerializer s)
		{
			//IL_002a: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			JObject val = JObject.Load(r);
			return new Vector2((float)val["x"], (float)val["y"]);
		}
	}
	public class Vector3Converter : JsonConverter<Vector3>
	{
		public override void WriteJson(JsonWriter writer, Vector3 v, JsonSerializer s)
		{
			//IL_0015: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			writer.WriteStartObject();
			writer.WritePropertyName("x");
			writer.WriteValue(v.x);
			writer.WritePropertyName("y");
			writer.WriteValue(v.y);
			writer.WritePropertyName("z");
			writer.WriteValue(v.z);
			writer.WriteEndObject();
		}

		public override Vector3 ReadJson(JsonReader r, Type t, Vector3 existing, bool hasExisting, JsonSerializer s)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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)
			JObject val = JObject.Load(r);
			return new Vector3((float)val["x"], (float)val["y"], (float)val["z"]);
		}
	}
	public class PropertyDataConverter : JsonConverter<TerrainData.PropertyData>
	{
		public override void WriteJson(JsonWriter writer, TerrainData.PropertyData value, JsonSerializer serializer)
		{
			writer.WriteStartObject();
			writer.WritePropertyName("name");
			writer.WriteValue(value.name);
			writer.WritePropertyName("value");
			serializer.Serialize(writer, value.value);
			writer.WritePropertyName("initialValue");
			serializer.Serialize(writer, value.initialValue);
			writer.WriteEndObject();
		}

		public override TerrainData.PropertyData ReadJson(JsonReader reader, Type objectType, TerrainData.PropertyData existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			JsonSerializer serializer2 = serializer;
			JObject val = JObject.Load(reader);
			return new TerrainData.PropertyData
			{
				name = ((object)val["name"])?.ToString(),
				value = DeserializeValue(val["value"]),
				initialValue = DeserializeValue(val["initialValue"])
			};
			object DeserializeValue(JToken token)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Invalid comparison between Unknown and I4
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: 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
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Expected O, but got Unknown
				//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Invalid comparison between Unknown and I4
				//IL_006c: 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)
				if (token == null || (int)token.Type == 10)
				{
					return null;
				}
				if ((int)token.Type == 1)
				{
					JObject val2 = (JObject)token;
					if (val2["x"] != null && val2["y"] != null && val2["z"] != null)
					{
						return ((JToken)val2).ToObject<Vector3>(serializer2);
					}
					if (val2["x"] != null && val2["y"] != null)
					{
						return ((JToken)val2).ToObject<Vector2>(serializer2);
					}
				}
				else
				{
					if ((int)token.Type == 6)
					{
						return (int)token;
					}
					if ((int)token.Type == 7)
					{
						return (float)token;
					}
				}
				return token.ToObject<object>(serializer2);
			}
		}
	}
	public class SavePanelUI : MonoBehaviour
	{
		public Transform container;

		private string saveName = "";

		private List<string> allFileNames = new List<string>();

		private Action<object> fileDropdownCallback;

		private DropdownInputUI dropdownInputUI;

		private NumberInputUI fileNameInputUI;

		public void Init()
		{
			container = ((Component)this).transform.Find("PropertiesPanel");
			SaveFileManager.CreateNew("Default");
			fileDropdownCallback = delegate(object selected)
			{
				if (selected is string text)
				{
					saveName = text;
					TerrainData terrainData = (SaveFileManager.CurrentTerrainData = SaveFileManager.LoadAndMerge(saveName));
					if ((Object)(object)fileNameInputUI != (Object)null)
					{
						fileNameInputUI.SetValue(saveName);
					}
					TerrainCustomiserUI instance = TerrainCustomiserUI.Instance;
					GameObject panel = instance.menuItems[0].panel;
					InitSegmentPanel((panel != null) ? panel.GetComponent<SegmentPanelUI>() : null, terrainData.Map.segments.Find((TerrainData.SegmentData s) => s.segmentName == "Beach_Segment"));
					GameObject panel2 = instance.menuItems[1].panel;
					InitSegmentPanel((panel2 != null) ? panel2.GetComponent<SegmentPanelUI>() : null, terrainData.Map.segments.Find((TerrainData.SegmentData s) => s.segmentName == "Jungle_Segment"));
					GameObject panel3 = instance.menuItems[2].panel;
					InitSegmentPanel((panel3 != null) ? panel3.GetComponent<SegmentPanelUI>() : null, terrainData.Map.segments.Find((TerrainData.SegmentData s) => s.segmentName == "Snow_Segment"));
					GameObject panel4 = instance.menuItems[3].panel;
					InitSegmentPanel((panel4 != null) ? panel4.GetComponent<SegmentPanelUI>() : null, terrainData.Map.segments.Find((TerrainData.SegmentData s) => s.segmentName == "Desert_Segment"));
					GameObject panel5 = instance.menuItems[4].panel;
					InitSegmentPanel((panel5 != null) ? panel5.GetComponent<SegmentPanelUI>() : null, terrainData.Map.segments.Find((TerrainData.SegmentData s) => s.segmentName == "Caldera_Segment"));
					GameObject panel6 = instance.menuItems[5].panel;
					InitSegmentPanel((panel6 != null) ? panel6.GetComponent<SegmentPanelUI>() : null, terrainData.Map.segments.Find((TerrainData.SegmentData s) => s.segmentName == "Volcano_Segment"));
					instance.menuItems[6].panel.GetComponent<SettingsPanelUI>().Init(terrainData.Settings);
					instance.ApplyPropertiesFromTerrainData(terrainData);
				}
			};
			AddDropdown("FileNames", fileDropdownCallback);
			AddString("SaveName", saveName, delegate(string val)
			{
				saveName = MakeSafeFileName(val);
			});
			AddButton("Save", delegate
			{
				if (string.IsNullOrEmpty(saveName))
				{
					saveName = $"save_{DateTime.Now:yyyyMMdd_HHmmss}";
				}
				SaveFileManager.SaveDirty(saveName);
				dropdownInputUI.ClearAndAddOptions(SaveFileManager.GetAllSaveFiles());
			});
			AddButton("New", delegate
			{
				if (string.IsNullOrEmpty(saveName))
				{
					saveName = $"save_{DateTime.Now:yyyyMMdd_HHmmss}";
				}
				SaveFileManager.CreateNew(saveName);
				TerrainData currentTerrainData = SaveFileManager.LoadAndMerge(saveName);
				SaveFileManager.CurrentTerrainData = currentTerrainData;
				dropdownInputUI.ClearAndSetOptions(SaveFileManager.GetAllSaveFiles());
			});
			AddButton("Delete", delegate
			{
				if (!string.IsNullOrEmpty(saveName))
				{
					SaveFileManager.DeleteSaveFile(saveName);
					saveName = "";
					dropdownInputUI.ClearAndSetOptions(SaveFileManager.GetAllSaveFiles());
					if (SaveFileManager.GetAllSaveFiles().Count == 0)
					{
						SaveFileManager.CreateNew("Default");
						dropdownInputUI.ClearAndSetOptions(SaveFileManager.GetAllSaveFiles());
					}
				}
			});
		}

		private void InitSegmentPanel(SegmentPanelUI panelUI, TerrainData.SegmentData segment)
		{
			if ((Object)(object)panelUI != (Object)null && segment != null && (Object)(object)segment._sourceObject != (Object)null)
			{
				panelUI.Init(segment);
			}
			else
			{
				((Component)TerrainCustomiserUI.Instance.menuItems[2].button).gameObject.SetActive(false);
			}
		}

		private void AddString(string label, string value, Action<string> onChange)
		{
			TerrainData.PropertyData propertyData = new TerrainData.PropertyData
			{
				name = label,
				value = value
			};
			GameObject val = TerrainCustomiserUI.Instance.CreatePropertyPanel(propertyData, container);
			PropertyPanelUI component = val.GetComponent<PropertyPanelUI>();
			fileNameInputUI = (NumberInputUI)component.InitWithAction(propertyData, CastAction(onChange));
			fileNameInputUI.SetCharacterLimit(30);
		}

		private void AddButton(string label, Action<object> onChange)
		{
			TerrainData.PropertyData propertyData = new TerrainData.PropertyData
			{
				name = label,
				value = null
			};
			GameObject val = TerrainCustomiserUI.Instance.CreateButtonPanel(propertyData, container);
			ButtonInputUI component = val.GetComponent<ButtonInputUI>();
			component.InitWithAction(propertyData, onChange);
		}

		private void AddDropdown(string label, Action<object> onChange)
		{
			TerrainData.PropertyData propertyData = new TerrainData.PropertyData
			{
				name = label,
				value = null
			};
			GameObject val = TerrainCustomiserUI.Instance.CreateDropdownPanel(propertyData, container);
			dropdownInputUI = val.GetComponent<DropdownInputUI>();
			dropdownInputUI.InitWithAction(propertyData, onChange);
			dropdownInputUI.ClearAndSetOptions(SaveFileManager.GetAllSaveFiles());
		}

		public static Action<object> CastAction<T>(Action<T> action)
		{
			Action<T> action2 = action;
			return delegate(object obj)
			{
				if (obj is T)
				{
					T obj2 = (T)obj;
					if (true)
					{
						action2?.Invoke(obj2);
					}
				}
			};
		}

		private string MakeSafeFileName(string name)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char c in invalidFileNameChars)
			{
				name = name.Replace(c.ToString(), "_");
			}
			return name.Trim();
		}
	}
	public class SegmentPanelUI : MonoBehaviour
	{
		private TextMeshProUGUI title;

		private Button generateButton;

		public void Init(TerrainData.SegmentData segment)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			TerrainData.SegmentData segment2 = segment;
			title = ((Component)((Component)this).transform.Find("HeaderPanel/Title")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)title).text = segment2.segmentName.Substring(0, segment2.segmentName.IndexOf('_'));
			generateButton = ((Component)((Component)this).transform.Find("HeaderPanel/GeneratePanel/GenerateButton")).GetComponent<Button>();
			((UnityEvent)generateButton.onClick).AddListener((UnityAction)delegate
			{
				segment2._sourceObject.RunAll(true);
			});
			Clear();
			foreach (TerrainData.PropGrouperData grouper in segment2.groupers)
			{
				GameObject val = TerrainCustomiserUI.Instance.CreateGrouperPanel(grouper, ((Component)this).transform);
				PropGrouperUI component = val.GetComponent<PropGrouperUI>();
				component.Init(grouper);
			}
		}

		public void Clear()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			foreach (Transform item in ((Component)this).transform)
			{
				Transform val = item;
				PropGrouperUI component = ((Component)val).GetComponent<PropGrouperUI>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)component).gameObject);
				}
			}
		}
	}
	public class SettingsPanelUI : MonoBehaviour
	{
		public Transform container;

		public void Init(TerrainData.SettingsData data)
		{
			TerrainData.SettingsData data2 = data;
			container = ((Component)this).transform.Find("PropertiesPanel");
			Clear();
			AddBool("UseRandomSeed", data2.useRandomSeed, delegate(bool val)
			{
				data2.useRandomSeed = val;
			});
			AddInt("Seed", data2.seed, delegate(int val)
			{
				data2.seed = val;
			});
			AddBool("EnableBlizzard", data2.enableSnowStorm, delegate(bool val)
			{
				data2.enableSnowStorm = val;
			});
			AddBool("EnableRain", data2.enableRain, delegate(bool val)
			{
				data2.enableRain = val;
			});
			AddButton("Reset", delegate
			{
			});
		}

		private void AddBool(string label, bool value, Action<bool> onChange)
		{
			TerrainData.PropertyData propertyData = new TerrainData.PropertyData
			{
				name = label,
				value = value
			};
			GameObject val = TerrainCustomiserUI.Instance.CreatePropertyPanel(propertyData, container);
			PropertyPanelUI component = val.GetComponent<PropertyPanelUI>();
			component.InitWithAction(propertyData, CastAction(onChange));
		}

		private void AddInt(string label, int value, Action<int> onChange)
		{
			TerrainData.PropertyData propertyData = new TerrainData.PropertyData
			{
				name = label,
				value = value
			};
			GameObject val = TerrainCustomiserUI.Instance.CreatePropertyPanel(propertyData, container);
			PropertyPanelUI component = val.GetComponent<PropertyPanelUI>();
			component.InitWithAction(propertyData, CastAction(onChange));
		}

		private void AddButton(string label, Action<object> onChange)
		{
			TerrainData.PropertyData propertyData = new TerrainData.PropertyData
			{
				name = label,
				value = null
			};
			GameObject val = TerrainCustomiserUI.Instance.CreateButtonPanel(propertyData, container);
			ButtonInputUI component = val.GetComponent<ButtonInputUI>();
			component.InitWithAction(propertyData, onChange);
		}

		public static Action<object> CastAction<T>(Action<T> action)
		{
			Action<T> action2 = action;
			return delegate(object obj)
			{
				if (obj is T)
				{
					T obj2 = (T)obj;
					if (true)
					{
						action2?.Invoke(obj2);
					}
				}
			};
		}

		private void Clear()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			foreach (Transform item in container)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}
	}
	public class TerrainCustomiserUI : MenuWindow
	{
		[Serializable]
		public class MenuButtonPanelPair
		{
			public Button button;

			public GameObject panel;
		}

		private Canvas canvas;

		public List<MenuButtonPanelPair> menuItems;

		private GameObject activePanel;

		public GameObject customisationMenu;

		private Transform leftMenuBar;

		public static TerrainCustomiserUI Instance;

		public GameObject vector3Prefab;

		public GameObject vector2Prefab;

		public GameObject boolPrefab;

		public GameObject numberPrefab;

		public GameObject propGrouperPrefab;

		public GameObject propSpawnerPrefab;

		public GameObject constraintPrefab;

		public GameObject propertyPanelPrefab;

		public GameObject buttonPanelPrefab;

		public GameObject dropdownPanelPrefab;

		public override bool openOnStart => false;

		public override bool selectOnOpen => false;

		public override bool closeOnPause => false;

		public override bool closeOnUICancel => false;

		public override bool autoHideOnClose => false;

		public override GameObject panel => ((Component)canvas).gameObject;

		private void Awake()
		{
			canvas = ((Component)((Component)this).transform).GetComponentInChildren<Canvas>();
			if ((Object)(object)canvas != (Object)null)
			{
				((Component)canvas).gameObject.SetActive(false);
			}
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else
			{
				Instance = this;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(MenuWindow), "Close", (Type[])null, (Type[])null);
			methodInfo.Invoke(this, null);
		}

		public void Toggle()
		{
			if (!((MenuWindow)this).isOpen)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(MenuWindow), "Open", (Type[])null, (Type[])null);
				methodInfo.Invoke(this, null);
			}
			else
			{
				MethodInfo methodInfo2 = AccessTools.Method(typeof(MenuWindow), "Close", (Type[])null, (Type[])null);
				methodInfo2.Invoke(this, null);
			}
		}

		private Button GetButton(string name)
		{
			return ((Component)leftMenuBar.Find(name)).GetComponent<Button>();
		}

		private GameObject GetPanel(string name)
		{
			return ((Component)customisationMenu.transform.Find("Viewport/Content/" + name)).gameObject;
		}

		public void Init()
		{
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Expected O, but got Unknown
			customisationMenu = ((Component)((Component)this).transform.Find("Canvas/CustomisationMenu")).gameObject;
			leftMenuBar = ((Component)this).transform.Find("Canvas/LeftMenuBar");
			menuItems = new List<MenuButtonPanelPair>
			{
				new MenuButtonPanelPair
				{
					button = GetButton("SectionBeachButton"),
					panel = GetPanel("BeachPanel")
				},
				new MenuButtonPanelPair
				{
					button = GetButton("SectionJungleButton"),
					panel = GetPanel("JunglePanel")
				},
				new MenuButtonPanelPair
				{
					button = GetButton("SectionAlpineButton"),
					panel = GetPanel("SnowPanel")
				},
				new MenuButtonPanelPair
				{
					button = GetButton("SectionDesertButton"),
					panel = GetPanel("DesertPanel")
				},
				new MenuButtonPanelPair
				{
					button = GetButton("SectionLavaButton"),
					panel = GetPanel("LavaPanel")
				},
				new MenuButtonPanelPair
				{
					button = GetButton("SectionKilnButton"),
					panel = GetPanel("VolcanoPanel")
				},
				new MenuButtonPanelPair
				{
					button = GetButton("SettingsButton"),
					panel = GetPanel("SettingsPanel")
				},
				new MenuButtonPanelPair
				{
					button = GetButton("SaveButton"),
					panel = GetPanel("SavePanel")
				}
			};
			foreach (MenuButtonPanelPair item in menuItems)
			{
				((UnityEvent)item.button.onClick).AddListener((UnityAction)delegate
				{
					TogglePanel(item.panel);
				});
				item.panel.SetActive(false);
			}
			menuItems[0].panel.AddComponent<SegmentPanelUI>();
			menuItems[1].panel.AddComponent<SegmentPanelUI>();
			menuItems[2].panel.AddComponent<SegmentPanelUI>();
			menuItems[3].panel.AddComponent<SegmentPanelUI>();
			menuItems[4].panel.AddComponent<SegmentPanelUI>();
			menuItems[5].panel.AddComponent<SegmentPanelUI>();
			menuItems[6].panel.AddComponent<SettingsPanelUI>();
			SavePanelUI savePanelUI = menuItems[7].panel.AddComponent<SavePanelUI>();
			savePanelUI.Init();
		}

		public void TogglePanel(GameObject targetPanel)
		{
			if (!customisationMenu.activeSelf)
			{
				customisationMenu.SetActive(true);
			}
			if ((Object)(object)activePanel == (Object)(object)targetPanel)
			{
				activePanel.SetActive(false);
				customisationMenu.SetActive(false);
				activePanel = null;
				return;
			}
			if ((Object)(object)activePanel != (Object)null)
			{
				activePanel.SetActive(false);
			}
			targetPanel.SetActive(true);
			activePanel = targetPanel;
			if ((Object)(object)targetPanel.GetComponent<SegmentPanelUI>() != (Object)null)
			{
				Plugin.Instance.TeleportPlayer(((Object)targetPanel).name);
			}
		}

		public void ApplyPropertiesFromTerrainData(TerrainData terrainData)
		{
			foreach (TerrainData.SegmentData segment in terrainData.Map.segments)
			{
				foreach (TerrainData.PropGrouperData grouper in segment.groupers)
				{
					foreach (TerrainData.LevelGenStepData step in grouper.steps)
					{
						ApplyPropertyList(step._sourceObject, step.properties);
						ApplyConstraintList(step._sourceObject, step.modifiers);
						ApplyConstraintList(step._sourceObject, step.constraints);
						ApplyConstraintList(step._sourceObject, step.postConstraints);
					}
				}
			}
		}

		private void ApplyConstraintList(LevelGenStep sourceObject, List<TerrainData.ConstraintData> constraints)
		{
			if ((Object)(object)sourceObject == (Object)null || constraints == null)
			{
				return;
			}
			Dictionary<string, IEnumerable> dictionary = new Dictionary<string, IEnumerable>();
			string[] array = new string[3] { "modifiers", "constraints", "postConstraints" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				FieldInfo field = ((object)sourceObject).GetType().GetField(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.GetValue(sourceObject) is IEnumerable value)
				{
					dictionary[text] = value;
				}
			}
			foreach (TerrainData.ConstraintData constraint in constraints)
			{
				bool flag = false;
				foreach (IEnumerable value2 in dictionary.Values)
				{
					foreach (object item in value2)
					{
						if (item != null && item.GetType().Name == constraint.type)
						{
							ApplyPropertyList(item, constraint.properties);
							flag = true;
							break;
						}
					}
					if (flag)
					{
						break;
					}
				}
			}
		}

		private void ApplyPropertyList(object target, List<TerrainData.PropertyData> properties)
		{
			Type type = target.GetType();
			foreach (TerrainData.PropertyData property in properties)
			{
				FieldInfo field = type.GetField(property.name, BindingFlags.Instance | BindingFlags.Public);
				if (field != null)
				{
					field.SetValue(target, property.value);
				}
			}
		}

		public void SetPropertyValue(TerrainData.LevelGenStepData stepData, TerrainData.PropertyData property, object newValue, TerrainData.ConstraintData? constraintData = null)
		{
			if (property == null || stepData == null || object.Equals(property.value, newValue))
			{
				return;
			}
			property.value = newValue;
			LevelGenStep sourceObject = stepData._sourceObject;
			if ((Object)(object)sourceObject == (Object)null)
			{
				return;
			}
			if (constraintData == null)
			{
				FieldInfo field = ((object)sourceObject).GetType().GetField(property.name, BindingFlags.Instance | BindingFlags.Public);
				if (field != null)
				{
					field.SetValue(sourceObject, newValue);
				}
				return;
			}
			string type = constraintData.type;
			string[] array = new string[3] { "modifiers", "constraints", "postConstraints" };
			bool flag = false;
			string[] array2 = array;
			foreach (string name in array2)
			{
				FieldInfo field2 = ((object)sourceObject).GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 == null || !(field2.GetValue(sourceObject) is IEnumerable enumerable))
				{
					continue;
				}
				foreach (object item in enumerable)
				{
					if (item == null || !(item.GetType().Name == type))
					{
						continue;
					}
					FieldInfo field3 = item.GetType().GetField(property.name, BindingFlags.Instance | BindingFlags.Public);
					if (field3 != null)
					{
						field3.SetValue(item, newValue);
						flag = true;
					}
					else
					{
						flag = true;
					}
					break;
				}
				if (flag)
				{
					break;
				}
			}
			if (flag)
			{
			}
		}

		public GameObject CreateGrouperPanel(TerrainData.PropGrouperData data, Transform parent)
		{
			GameObject val = Object.Instantiate<GameObject>(propGrouperPrefab, parent);
			((Object)val).name = data.grouperName;
			return val;
		}

		public GameObject CreateSpawnerPanel(TerrainData.LevelGenStepData data, Transform parent)
		{
			GameObject val = Object.Instantiate<GameObject>(propSpawnerPrefab, parent);
			((Object)val).name = data.stepName;
			return val;
		}

		public GameObject CreateConstraintPanel(TerrainData.ConstraintData data, Transform parent)
		{
			GameObject val = Object.Instantiate<GameObject>(constraintPrefab, parent);
			((Object)val).name = data.type;
			return val;
		}

		public GameObject CreatePropertyPanel(TerrainData.PropertyData prop, Transform parent)
		{
			GameObject val = Object.Instantiate<GameObject>(propertyPanelPrefab, parent);
			((Object)val).name = prop.name;
			return val;
		}

		public GameObject CreateButtonPanel(TerrainData.PropertyData prop, Transform parent)
		{
			GameObject val = Object.Instantiate<GameObject>(buttonPanelPrefab, parent);
			((Object)val).name = prop.name;
			return val;
		}

		public GameObject CreateDropdownPanel(TerrainData.PropertyData prop, Transform parent)
		{
			GameObject val = Object.Instantiate<GameObject>(dropdownPanelPrefab, parent);
			((Object)val).name = prop.name;
			return val;
		}

		public GameObject CreatePropertyInput(TerrainData.PropertyData prop, Transform parent)
		{
			GameObject val = null;
			if (prop.value is Vector3)
			{
				val = vector3Prefab;
			}
			else if (prop.value is Vector2)
			{
				val = vector2Prefab;
			}
			else if (prop.value is bool)
			{
				val = boolPrefab;
			}
			else if (prop.value is float || prop.value is int || prop.value is double || prop.value is string)
			{
				val = numberPrefab;
			}
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)$"Unsupported property type for '{prop.name}': {prop.value?.GetType()}");
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, parent);
			((Object)val2).name = prop.name;
			return val2;
		}
	}
	public class TerrainData
	{
		public class MapData
		{
			[JsonProperty("segments")]
			public List<SegmentData> segments = new List<SegmentData>();
		}

		public class SegmentData
		{
			[JsonProperty("segmentName")]
			public string segmentName;

			[JsonProperty("groupers")]
			public List<PropGrouperData> groupers = new List<PropGrouperData>();

			[JsonIgnore]
			public PropGrouper _sourceObject;
		}

		public class PropGrouperData
		{
			[JsonProperty("grouperName")]
			public string grouperName;

			[JsonProperty("steps")]
			public List<LevelGenStepData> steps = new List<LevelGenStepData>();
		}

		public class LevelGenStepData
		{
			[JsonProperty("stepName")]
			public string stepName;

			[JsonProperty("stepType")]
			public string stepType;

			[JsonProperty("properties")]
			public List<PropertyData> properties = new List<PropertyData>();

			[JsonProperty("modifiers")]
			public List<ConstraintData> modifiers = new List<ConstraintData>();

			[JsonProperty("constraints")]
			public List<ConstraintData> constraints = new List<ConstraintData>();

			[JsonProperty("postConstraints")]
			public List<ConstraintData> postConstraints = new List<ConstraintData>();

			[JsonIgnore]
			public LevelGenStep _sourceObject;
		}

		public class ConstraintData
		{
			[JsonProperty("type")]
			public string type;

			[JsonProperty("properties")]
			public List<PropertyData> properties = new List<PropertyData>();
		}

		public class PropertyData
		{
			[JsonProperty("name")]
			public string name;

			[JsonProperty("value")]
			public object value;

			[JsonProperty("initialValue")]
			public object initialValue;
		}

		public class SettingsData
		{
			[JsonProperty("useRandomSeed")]
			public bool useRandomSeed = true;

			[JsonProperty("seed")]
			public int seed;

			[JsonProperty("enableSnowStorm")]
			public bool enableSnowStorm = true;

			[JsonProperty("enableRain")]
			public bool enableRain = true;
		}

		[JsonProperty("Map")]
		public MapData Map = new MapData();

		[JsonProperty("Settings")]
		public SettingsData Settings = new SettingsData();
	}
	public class TerrainDataManager : MonoBehaviour
	{
		public static TerrainDataManager Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Object.FindFirstObjectByType<TerrainCustomiserUI>().menuItems[6].panel.GetComponent<SavePanelUI>().Init();
		}
	}
	public static class TerrainExporter
	{
		private static readonly HashSet<string> ModConstraintWhitelist = new HashSet<string>
		{
			"PSC_Height", "PSC_LineCheck", "PSC_Normal", "PSC_Perlin", "PSC_SameTypeDistance", "PSM_RandomScale", "PSM_RayDirectionOffset", "PSM_SpecificRotation", "PSM_UpLerp", "PSM_RandomRotation",
			"PSM_LocalOffset", "PSM_RandomOffset", "PSM_PlacementOffset", "PSM_SetUpRotationToNormal"
		};

		private static readonly HashSet<string> PropertyNameWhitelist = new HashSet<string> { "mute", "height", "rayLength", "nrOfSpawns", "rayCastSpawn", "area", "chanceToUseSpawner", "overallSpawnChance", "scaleMinMax", "radius" };

		public static TerrainData GetDefaultTerrainData()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Invalid comparison between Unknown and I4
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			TerrainData.MapData mapData = new TerrainData.MapData();
			MapSegment[] segments = Singleton<MapHandler>.Instance.segments;
			foreach (MapSegment val in segments)
			{
				if ((int)val.biome == 3)
				{
					if (((Object)val.segmentParent).name.StartsWith("Volcano"))
					{
						mapData.segments.Add(BuildSegment(((Object)val.segmentParent).name, val.segmentParent.transform));
					}
					if (((Object)val.segmentParent).name.StartsWith("Caldera"))
					{
						mapData.segments.Add(BuildSegment(((Object)val.segmentParent).name, val.segmentParent.transform));
					}
					continue;
				}
				if ((int)val.biome == 6)
				{
					mapData.segments.Add(BuildSegment(((Object)val.segmentParent).name, val.segmentParent.transform));
					continue;
				}
				Transform val2 = null;
				foreach (Transform item in val.segmentParent.transform)
				{
					Transform val3 = item;
					BiomeVariant component = ((Component)val3).GetComponent<BiomeVariant>();
					if ((Object)(object)component != (Object)null && ((Component)component).gameObject.activeSelf)
					{
						val2 = val3;
						break;
					}
				}
				if ((Object)(object)val2 != (Object)null)
				{
					mapData.segments.Add(BuildSegment(((Object)val.segmentParent).name, val2));
				}
				else
				{
					Debug.LogWarning((object)("No active BiomeVariant found under " + ((Object)val.segmentParent).name));
				}
			}
			TerrainData terrainData = new TerrainData();
			terrainData.Map = mapData;
			terrainData.Settings = new TerrainData.SettingsData();
			return terrainData;
		}

		private static TerrainData.SegmentData BuildSegment(string segmentName, Transform parent)
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			Transform parent2 = parent;
			TerrainData.SegmentData segmentData = new TerrainData.SegmentData
			{
				segmentName = segmentName,
				_sourceObject = ((Component)parent2).GetComponent<PropGrouper>()
			};
			if (segmentName == "Desert_Segment")
			{
				PropGrouper sourceObject = ((Component)parent2).gameObject.AddComponent<PropGrouper>();
				segmentData._sourceObject = sourceObject;
			}
			List<PropGrouper> list = (from g in ((Component)parent2).GetComponentsInChildren<PropGrouper>(true)
				where (Object)(object)((Component)g).transform != (Object)(object)parent2 && ((Component)g).transform.IsChildOf(parent2)
				select g).ToList();
			foreach (PropGrouper item in list)
			{
				TerrainData.PropGrouperData propGrouperData = new TerrainData.PropGrouperData
				{
					grouperName = ((Object)item).name
				};
				foreach (Transform item2 in ((Component)item).transform)
				{
					Transform val = item2;
					LevelGenStep component = ((Component)val).GetComponent<LevelGenStep>();
					if ((Object)(object)component == (Object)null)
					{
						continue;
					}
					Type type = ((object)component).GetType();
					TerrainData.LevelGenStepData levelGenStepData = new TerrainData.LevelGenStepData
					{
						stepName = ((Object)component).name,
						stepType = type.Name,
						_sourceObject = component
					};
					FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
					foreach (FieldInfo fieldInfo in fields)
					{
						if (PropertyNameWhitelist.Contains(fieldInfo.Name))
						{
							object value = fieldInfo.GetValue(component);
							levelGenStepData.properties.Add(new TerrainData.PropertyData
							{
								name = fieldInfo.Name,
								value = value,
								initialValue = value
							});
						}
					}
					PopulateList(component, "modifiers", levelGenStepData.modifiers);
					PopulateList(component, "constraints", levelGenStepData.constraints);
					propGrouperData.steps.Add(levelGenStepData);
				}
				if (propGrouperData.steps.Count > 0)
				{
					segmentData.groupers.Add(propGrouperData);
				}
			}
			return segmentData;
		}

		private static void PopulateList(LevelGenStep step, string fieldName, List<TerrainData.ConstraintData> targetList)
		{
			FieldInfo field = ((object)step).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
			if (field == null || !(field.GetValue(step) is IEnumerable enumerable))
			{
				return;
			}
			foreach (object item in enumerable)
			{
				Type type = item.GetType();
				if (ModConstraintWhitelist.Contains(type.Name))
				{
					List<TerrainData.PropertyData> list = new List<TerrainData.PropertyData>();
					FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
					foreach (FieldInfo fieldInfo in fields)
					{
						object value = fieldInfo.GetValue(item);
						list.Add(new TerrainData.PropertyData
						{
							name = fieldInfo.Name,
							value = value,
							initialValue = value
						});
					}
					targetList.Add(new TerrainData.ConstraintData
					{
						type = type.Name,
						properties = list
					});
				}
			}
		}
	}
	public class Vector2InputUI : MonoBehaviour, IPropertyInputUI
	{
		private TMP_InputField xInput;

		private TMP_InputField yInput;

		private TerrainData.PropertyData boundProperty;

		private TerrainData.LevelGenStepData stepDataParent;

		private TerrainData.ConstraintData constraintData;

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			xInput = ((Component)((Component)this).transform.Find("InputFieldX")).GetComponent<TMP_InputField>();
			yInput = ((Component)((Component)this).transform.Find("InputFieldY")).GetComponent<TMP_InputField>();
			boundProperty = property;
			stepDataParent = stepData;
			if (property.value is Vector2 val)
			{
				xInput.text = val.x.ToString();
				yInput.text = val.y.ToString();
				((UnityEvent<string>)(object)xInput.onEndEdit).AddListener((UnityAction<string>)OnXChanged);
				((UnityEvent<string>)(object)yInput.onEndEdit).AddListener((UnityAction<string>)OnYChanged);
			}
			else
			{
				Debug.LogWarning((object)"Property is not a Vector2");
			}
		}

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData, TerrainData.ConstraintData data)
		{
			constraintData = data;
			Init(property, stepData);
		}

		public void InitWithAction(TerrainData.PropertyData property, Action<object> onChanged)
		{
			throw new NotImplementedException();
		}

		private void OnXChanged(string val)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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)
			if (float.TryParse(val, out var result))
			{
				Vector2 val2 = (Vector2)boundProperty.value;
				TerrainCustomiserUI.Instance.SetPropertyValue(stepDataParent, boundProperty, (object)new Vector2(result, val2.y), constraintData);
			}
		}

		private void OnYChanged(string val)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			if (float.TryParse(val, out var result))
			{
				Vector2 val2 = (Vector2)boundProperty.value;
				TerrainCustomiserUI.Instance.SetPropertyValue(stepDataParent, boundProperty, (object)new Vector2(val2.x, result), constraintData);
			}
		}
	}
	public class Vector3InputUI : MonoBehaviour, IPropertyInputUI
	{
		private TMP_InputField xInput;

		private TMP_InputField yInput;

		private TMP_InputField zInput;

		private TerrainData.PropertyData boundProperty;

		private TerrainData.LevelGenStepData stepDataParent;

		private TerrainData.ConstraintData constraintData;

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData)
		{
			//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)
			xInput = ((Component)((Component)this).transform.Find("InputFieldX")).GetComponent<TMP_InputField>();
			yInput = ((Component)((Component)this).transform.Find("InputFieldY")).GetComponent<TMP_InputField>();
			zInput = ((Component)((Component)this).transform.Find("InputFieldZ")).GetComponent<TMP_InputField>();
			boundProperty = property;
			stepDataParent = stepData;
			if (property.value is Vector3 val)
			{
				xInput.text = val.x.ToString();
				yInput.text = val.y.ToString();
				zInput.text = val.z.ToString();
				((UnityEvent<string>)(object)xInput.onEndEdit).AddListener((UnityAction<string>)OnXChanged);
				((UnityEvent<string>)(object)yInput.onEndEdit).AddListener((UnityAction<string>)OnYChanged);
				((UnityEvent<string>)(object)zInput.onEndEdit).AddListener((UnityAction<string>)OnZChanged);
			}
			else
			{
				Debug.LogWarning((object)"Property is not a Vector3");
			}
		}

		public void Init(TerrainData.PropertyData property, TerrainData.LevelGenStepData stepData, TerrainData.ConstraintData data)
		{
			constraintData = data;
			Init(property, stepData);
		}

		public void InitWithAction(TerrainData.PropertyData property, Action<object> onChanged)
		{
			throw new NotImplementedException();
		}

		private void OnXChanged(string val)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			if (float.TryParse(val, out var result))
			{
				Vector3 val2 = (Vector3)boundProperty.value;
				TerrainCustomiserUI.Instance.SetPropertyValue(stepDataParent, boundProperty, (object)new Vector3(result, val2.y, val2.z), constraintData);
			}