The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of TerrainCustomiser v0.2.3
TerrainCustomiser/TerrainCustomiser.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.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); }