Decompiled source of TerrainCustomiser v0.2.3
TerrainCustomiser/TerrainCustomiser.dll
Decompiled 4 months 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); }