Decompiled source of TerrainRandomiser v1.1.7

TerrainRandomiser.dll

Decompiled a month ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Photon.Pun;
using Photon.Realtime;
using PhotonCustomPropsUtils;
using Steamworks;
using TerrainRandomiser.TerrainGeneration;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
using Zorro.ControllerSupport;
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("TerrainRandomiser")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.1.6")]
[assembly: AssemblyInformationalVersion("1.1.6+08cc08ce79d4943a800271485298219e6520b1d3")]
[assembly: AssemblyProduct("TerrainRandomiser")]
[assembly: AssemblyTitle("TerrainRandomiser")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.6.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 TerrainRandomiser
{
	public static class BiomeDatabase
	{
		public static List<SectionData> GetAllSections()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			return new List<SectionData>
			{
				new SectionData
				{
					sectionName = "Biome_1",
					biomes = new List<BiomeData>
					{
						new BiomeData
						{
							biomeName = "Shore",
							biomeType = (BiomeType)0,
							variants = new List<string> { "Default", "SnakeBeach", "RedBeach", "BlueBeach", "JellyHell", "BlackSand" },
							variantSelectionType = VariantSelectionType.BiomeVariant
						}
					}
				},
				new SectionData
				{
					sectionName = "Biome_2",
					biomes = new List<BiomeData>
					{
						new BiomeData
						{
							biomeName = "Tropics",
							biomeType = (BiomeType)1,
							variants = new List<string> { "Default", "Lava", "Pillars", "Thorny", "Bombs", "Ivy", "SkyJungle" },
							variantSelectionType = VariantSelectionType.BiomeVariant
						},
						new BiomeData
						{
							biomeName = "Roots",
							biomeType = (BiomeType)7,
							variants = new List<string> { "Default", "Cave Mania", "Deep Water", "Bomb Beetle", "Deep Woods", "Clearcut" },
							variantSelectionType = VariantSelectionType.VariantObject
						}
					}
				},
				new SectionData
				{
					sectionName = "Biome_3",
					biomes = new List<BiomeData>
					{
						new BiomeData
						{
							biomeName = "Alpine",
							biomeType = (BiomeType)2,
							variants = new List<string> { "Default", "Lava", "Spiky", "GeyserHell" },
							variantSelectionType = VariantSelectionType.BiomeVariant
						},
						new BiomeData
						{
							biomeName = "Mesa",
							biomeType = (BiomeType)6,
							variants = new List<string> { "NoVariant", "ScorpionsHell", "CacusHell", "CactusForest", "DynamiteHell", "TornadoHell", "TumblerHell" },
							variantSelectionType = VariantSelectionType.VariantObject
						}
					}
				}
			};
		}

		public static List<SectionData> GetRuntimeValidSections()
		{
			HashSet<string> validBiomeNames = Enum.GetNames(typeof(BiomeType)).ToHashSet();
			List<SectionData> allSections = GetAllSections();
			return (from section in allSections
				select new SectionData
				{
					sectionName = section.sectionName,
					biomes = section.biomes.Where((BiomeData b) => validBiomeNames.Contains(b.biomeName)).ToList()
				} into section
				where section.biomes.Count > 0
				select section).ToList();
		}
	}
	public enum VariantSelectionType
	{
		BiomeVariant,
		VariantObject
	}
	[Serializable]
	public class MapSettings
	{
		public bool enableRandomiser;

		public int seed;

		public bool autoRandomSeed;

		public bool fullyRandom;

		public List<BiomeSettings> biomes = new List<BiomeSettings>();

		public static MapSettings CreateDefaultMapSettings()
		{
			List<SectionData> runtimeValidSections = BiomeDatabase.GetRuntimeValidSections();
			List<BiomeSettings> list = new List<BiomeSettings>();
			foreach (SectionData item in runtimeValidSections)
			{
				if (item.biomes.Count != 0)
				{
					BiomeData biomeData = item.biomes[0];
					string selectedVariant = ((biomeData.variants.Count > 0) ? biomeData.variants[0] : "");
					list.Add(new BiomeSettings
					{
						overrideEnabled = true,
						sectionName = item.sectionName,
						selectedBiome = biomeData,
						selectedVariant = selectedVariant
					});
				}
			}
			return new MapSettings
			{
				seed = 42,
				autoRandomSeed = false,
				fullyRandom = false,
				biomes = list
			};
		}
	}
	[Serializable]
	public class BiomeSettings
	{
		public bool overrideEnabled;

		public string sectionName;

		public BiomeData selectedBiome;

		public string selectedVariant;

		public bool randomBiome;

		public bool randomVariant;
	}
	[Serializable]
	public class SectionData
	{
		public string sectionName;

		public List<BiomeData> biomes = new List<BiomeData>();
	}
	[Serializable]
	public class BiomeData
	{
		public string biomeName;

		public BiomeType biomeType;

		public List<string> variants = new List<string>();

		public VariantSelectionType variantSelectionType = VariantSelectionType.BiomeVariant;
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.snosz.terrainrandomiser", "TerrainRandomiser", "1.1.7")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(BoardingPass), "Initialize")]
		private static class BoardingPassInitializePatch
		{
			private static void Postfix(BoardingPass __instance)
			{
				Instance.CreateUI(__instance);
			}
		}

		[HarmonyPatch(typeof(BoardingPass), "StartGame")]
		private static class BoardingPassStartGamePatch
		{
			private static void Prefix(BoardingPass __instance)
			{
				if (!PhotonNetwork.IsMasterClient)
				{
					return;
				}
				if (!Instance.mapSettings.enableRandomiser)
				{
					Instance.roomMapSettings = Instance.mapSettings;
					SaveMapSettings();
					SyncWithClients(Instance.mapSettings);
					return;
				}
				MapSettings mapSettings = Instance.mapSettings;
				SaveMapSettings();
				if (mapSettings.fullyRandom || mapSettings.autoRandomSeed)
				{
					RandomiseSeed(mapSettings);
				}
				if (mapSettings.fullyRandom)
				{
					RandomiseAllSections(mapSettings);
				}
				else
				{
					RandomiseOverrides(mapSettings);
				}
				SyncWithClients(mapSettings);
			}
		}

		[HarmonyPatch(typeof(NavigationContainerHandler), "LateUpdate")]
		internal static class NavHandler_LateUpdate_Patch
		{
			public static bool Prefix()
			{
				if ((Object)(object)GUIManager.instance == (Object)null || (Object)(object)GUIManager.instance.boardingPass == (Object)null)
				{
					return true;
				}
				if (((MenuWindow)GUIManager.instance.boardingPass).isOpen)
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(SteamLobbyHandler), "OnLobbyEnter")]
		private static class OnLobbyEnter
		{
			private static void Postfix(SteamLobbyHandler __instance, LobbyEnter_t param)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				if (param.m_EChatRoomEnterResponse == 1)
				{
					string lobbyData = SteamMatchmaking.GetLobbyData(__instance.LobbySteamId, "TR_roomMapSettings");
					if (!string.IsNullOrEmpty(lobbyData))
					{
						Instance.roomMapSettings = JsonConvert.DeserializeObject<MapSettings>(lobbyData);
					}
				}
			}
		}

		[HarmonyPatch(typeof(MapHandler), "InitializeMap")]
		private static class MapHandlerInitializeMapPatch
		{
			private static bool Prefix()
			{
				if (Instance.roomMapSettings == null || !Instance.roomMapSettings.enableRandomiser)
				{
					return true;
				}
				MapSettings roomMapSettings = Instance.roomMapSettings;
				viewIDsToSend = new List<int>();
				viewsRequiringIDs = new List<PhotonView>();
				Debug.Log((object)$"[TerrainRandomiser] Starting generation with seed: {roomMapSettings.seed}");
				string text = JsonConvert.SerializeObject((object)roomMapSettings, (Formatting)0);
				Debug.Log((object)text);
				Random.InitState(roomMapSettings.seed);
				for (int i = 0; i < roomMapSettings.biomes.Count; i++)
				{
					MapHandlerHelpers.ApplyBiomeToSegment(Singleton<MapHandler>.Instance, i, roomMapSettings.biomes[i]);
				}
				List<MapSegment> list = Singleton<MapHandler>.Instance.segments.ToList();
				list.AddRange(Singleton<MapHandler>.Instance.variantSegments);
				foreach (MapSegment item in list)
				{
					if ((Object)(object)item.segmentParent.GetComponent<PropGrouper>() == (Object)null)
					{
						item.segmentParent.gameObject.AddComponent<PropGrouper>();
					}
				}
				Stopwatch stopwatch = Stopwatch.StartNew();
				PropGrouper component = ((Component)Singleton<MapHandler>.Instance).GetComponent<PropGrouper>();
				PropGrouperHelpers.RunRootPropGrouper(component);
				stopwatch.Stop();
				Debug.Log((object)$"[TerrainRandomiser] Generation took: {stopwatch.ElapsedMilliseconds}");
				if (PhotonNetwork.IsMasterClient)
				{
					List<int> andAssignAllUnassignedViews = MapHandlerHelpers.GetAndAssignAllUnassignedViews();
					viewIDsToSend.AddRange(andAssignAllUnassignedViews);
					Instance.SendViewIDsToClients(viewIDsToSend);
				}
				else
				{
					awaitingViewIDs = true;
					if (receivedViewIDs != null && receivedViewIDs.Count > 0)
					{
						Instance.UpdateRequiredViewIDs();
					}
				}
				FakeItemManager.Instance.RefreshList();
				return true;
			}

			private static void Postfix(MapHandler __instance)
			{
				if (Instance.roomMapSettings != null && Instance.roomMapSettings.enableRandomiser && !PhotonNetwork.IsMasterClient)
				{
					Instance.roomMapSettings = null;
				}
			}
		}

		public static Plugin Instance;

		private static Harmony _harmony;

		public static List<int> viewIDsToSend;

		public static List<PhotonView>? viewsRequiringIDs;

		public static List<int> receivedViewIDs;

		public static bool awaitingViewIDs = false;

		public AssetBundle seedPickerUIBundle;

		public const int MAX_SEED_VALUE = 999999999;

		public MapSettings mapSettings;

		public MapSettings roomMapSettings;

		private RandomiserUIManager uiManager;

		private PhotonScopedManager photonManager;

		private GameObject uidocObject;

		public AssetBundle visibilityComputeBundle;

		private static readonly string SavePath = Path.Combine(Application.persistentDataPath, "TerrainRandomiser", "MapSettings.json");

		public static ConfigEntry<bool> EnableLightMapBaking;

		public static int masterSeed => Instance.roomMapSettings.seed;

		private void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Instance = this;
			_harmony = new Harmony("com.snosz.terrainrandomiser");
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			EnableLightMapBaking = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableLightMapBaking", true, "Generates a lightmap which is used for certain game mechanics. Disable this if the game crashes.");
			byte[] terrainrandomiser = Resource1.terrainrandomiser;
			seedPickerUIBundle = AssetBundle.LoadFromMemory(terrainrandomiser);
			byte[] visibilitycompute = Resource1.visibilitycompute;
			visibilityComputeBundle = AssetBundle.LoadFromMemory(visibilitycompute);
			LightMapBaker.computeShader = visibilityComputeBundle.LoadAsset<ComputeShader>("SkyVisibilityDDA");
			LoadMapSettings();
			if (mapSettings == null)
			{
				mapSettings = MapSettings.CreateDefaultMapSettings();
			}
			AddPhotonManager();
			_harmony.PatchAll();
		}

		private void OnDestroy()
		{
			_harmony.UnpatchSelf();
			if ((Object)(object)seedPickerUIBundle != (Object)null)
			{
				if ((Object)(object)uidocObject != (Object)null)
				{
					uidocObject.GetComponent<UIDocument>().rootVisualElement.Clear();
					Object.Destroy((Object)(object)uidocObject);
				}
				seedPickerUIBundle.Unload(true);
				seedPickerUIBundle = null;
			}
		}

		private void AddPhotonManager()
		{
			photonManager = PhotonCustomPropsUtilsPlugin.GetManager("com.snosz.terrainrandomiser");
			photonManager.RegisterOnJoinedRoom((Action<Player>)delegate
			{
				if (PhotonNetwork.IsMasterClient)
				{
					string text = JsonConvert.SerializeObject((object)mapSettings, (Formatting)0);
					photonManager.SetRoomProperty("roomMapSettings", (object)text);
				}
			});
			photonManager.RegisterRoomProperty<string>("roomMapSettings", (RoomEventType)2, (Action<string>)delegate(string value)
			{
				roomMapSettings = JsonConvert.DeserializeObject<MapSettings>(value);
			});
			photonManager.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();
					if (awaitingViewIDs)
					{
						Instance.UpdateRequiredViewIDs();
					}
				}
			});
		}

		public void UpdateRequiredViewIDs()
		{
			if (PhotonNetwork.IsMasterClient)
			{
				return;
			}
			if (viewsRequiringIDs == null || receivedViewIDs == null)
			{
				Debug.LogError((object)"[TerrainRandomiser] Required lists did not initialize or have already been resolved.");
				return;
			}
			if (viewsRequiringIDs.Count > receivedViewIDs.Count)
			{
				Debug.LogError((object)"[TerrainRandomiser] ID Count mismatch! Map will be out of sync!");
				return;
			}
			for (int i = 0; i < viewsRequiringIDs.Count; i++)
			{
				if ((Object)(object)viewsRequiringIDs[i] != (Object)null && (Object)(object)((Component)viewsRequiringIDs[i]).gameObject != (Object)null)
				{
					viewsRequiringIDs[i].ViewID = receivedViewIDs[i];
				}
				else
				{
					Debug.LogError((object)$"Null or destroyed PhotonView at index {i}");
				}
			}
			List<PhotonView> allUnassignedViews = MapHandlerHelpers.GetAllUnassignedViews();
			for (int j = 0; j < allUnassignedViews.Count; j++)
			{
				allUnassignedViews[j].ViewID = receivedViewIDs[viewsRequiringIDs.Count + j];
			}
			Debug.LogError((object)$"[TerrainRandomiser] Updated receivedViewIDs with {receivedViewIDs.Count} IDs");
			receivedViewIDs.Clear();
			viewsRequiringIDs.Clear();
			viewsRequiringIDs = null;
			awaitingViewIDs = false;
		}

		private void CreateUI(BoardingPass bpInstance)
		{
			GameObject val = Instance.seedPickerUIBundle.LoadAsset<GameObject>("UIDocument");
			Instance.uidocObject = Object.Instantiate<GameObject>(val, ((Component)bpInstance).transform);
			uiManager = Instance.uidocObject.AddComponent<RandomiserUIManager>();
		}

		private static void RandomiseSeed(MapSettings settings)
		{
			settings.seed = Random.Range(0, 999999999);
		}

		private static void RandomiseAllSections(MapSettings settings)
		{
			List<SectionData> runtimeValidSections = BiomeDatabase.GetRuntimeValidSections();
			for (int i = 0; i < runtimeValidSections.Count; i++)
			{
				ApplyRandomBiomeAndVariant(settings, i, runtimeValidSections[i]);
			}
		}

		private static void RandomiseOverrides(MapSettings settings)
		{
			List<SectionData> runtimeValidSections = BiomeDatabase.GetRuntimeValidSections();
			for (int i = 0; i < settings.biomes.Count; i++)
			{
				BiomeSettings biomeSettings = settings.biomes[i];
				if (biomeSettings.overrideEnabled)
				{
					if (biomeSettings.randomBiome)
					{
						ApplyRandomBiomeAndVariant(settings, i, runtimeValidSections[i]);
					}
					else if (biomeSettings.randomVariant)
					{
						ApplyRandomVariant(settings, i);
					}
				}
			}
		}

		private static void ApplyRandomBiomeAndVariant(MapSettings settings, int index, SectionData section)
		{
			int index2 = Random.Range(0, section.biomes.Count);
			settings.biomes[index].selectedBiome = section.biomes[index2];
			ApplyRandomVariant(settings, index);
		}

		private static void ApplyRandomVariant(MapSettings settings, int index)
		{
			BiomeData selectedBiome = settings.biomes[index].selectedBiome;
			int index2 = Random.Range(0, selectedBiome.variants.Count);
			settings.biomes[index].selectedVariant = selectedBiome.variants[index2];
		}

		private static void SyncWithClients(MapSettings settings)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			Instance.roomMapSettings = settings;
			string text = JsonConvert.SerializeObject((object)Instance.roomMapSettings, (Formatting)0);
			Instance.photonManager.SetRoomProperty("roomMapSettings", (object)text);
			SteamLobbyHandler service = GameHandler.GetService<SteamLobbyHandler>();
			SteamMatchmaking.SetLobbyData(service.LobbySteamId, "TR_roomMapSettings", text);
		}

		public void SendViewIDsToClients(List<int> viewIDs)
		{
			photonManager.SetRoomProperty("propViews", (object)viewIDs.ToArray());
		}

		public static void SaveMapSettings()
		{
			string contents = JsonConvert.SerializeObject((object)Instance.mapSettings, (Formatting)1);
			File.WriteAllText(SavePath, contents);
		}

		public static void LoadMapSettings()
		{
			string directoryName = Path.GetDirectoryName(SavePath);
			if (!Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			if (!File.Exists(SavePath))
			{
				return;
			}
			string text = File.ReadAllText(SavePath);
			MapSettings mapSettings = JsonConvert.DeserializeObject<MapSettings>(text);
			if (mapSettings == null)
			{
				return;
			}
			Instance.mapSettings = mapSettings;
			foreach (BiomeSettings biome in Instance.mapSettings.biomes)
			{
				if (biome.selectedBiome.variants.Count == 0)
				{
					Instance.mapSettings = MapSettings.CreateDefaultMapSettings();
					break;
				}
			}
		}
	}
	public class RandomiserUIManager : MonoBehaviour
	{
		[SerializeField]
		private UIDocument uiDocument;

		private IntegerField seedInput;

		private Button randomSeedButton;

		private Toggle autoSeedToggle;

		private Toggle fullyRandomToggle;

		private Toggle enableRandomiserToggle;

		private VisualElement randomiserMenu;

		private VisualElement biomeTabContainer;

		private List<Toggle> biomeOverrideToggles = new List<Toggle>();

		private List<DropdownField> biomeDropdowns = new List<DropdownField>();

		private List<DropdownField> variantDropdowns = new List<DropdownField>();

		private List<SectionData> runtimeSections;

		private MapSettings mapSettings;

		public void OnEnable()
		{
			runtimeSections = BiomeDatabase.GetRuntimeValidSections();
			mapSettings = Plugin.Instance.mapSettings;
			biomeOverrideToggles.Clear();
			biomeDropdowns.Clear();
			variantDropdowns.Clear();
			uiDocument = ((Component)this).GetComponent<UIDocument>();
			VisualElement rootVisualElement = uiDocument.rootVisualElement;
			seedInput = UQueryExtensions.Q<IntegerField>(rootVisualElement, "seedInput", (string)null);
			randomSeedButton = UQueryExtensions.Q<Button>(rootVisualElement, "randomSeedButton", (string)null);
			autoSeedToggle = UQueryExtensions.Q<Toggle>(rootVisualElement, "autoSeedToggle", (string)null);
			fullyRandomToggle = UQueryExtensions.Q<Toggle>(rootVisualElement, "fullyRandomToggle", (string)null);
			randomiserMenu = UQueryExtensions.Q<VisualElement>(rootVisualElement, "SeedPicker", (string)null);
			enableRandomiserToggle = UQueryExtensions.Q<Toggle>(rootVisualElement, "enableRandomiserToggle", (string)null);
			biomeTabContainer = (VisualElement)(object)UQueryExtensions.Q<TabView>(rootVisualElement, (string)null, (string)null);
			for (int i = 0; i < mapSettings.biomes.Count; i++)
			{
				VisualElement val = UQueryExtensions.Q<VisualElement>(rootVisualElement, $"biome{i + 1}Tab", (string)null);
				biomeOverrideToggles.Add(UQueryExtensions.Q<Toggle>(val, "overrideBiomeToggle", (string)null));
				biomeDropdowns.Add(UQueryExtensions.Q<DropdownField>(val, "biomeDropdown", (string)null));
				variantDropdowns.Add(UQueryExtensions.Q<DropdownField>(val, "variantDropdown", (string)null));
			}
			SetupBindings();
		}

		private void SetupBindings()
		{
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			((BaseField<bool>)(object)enableRandomiserToggle).value = Plugin.Instance.mapSettings.enableRandomiser;
			INotifyValueChangedExtensions.RegisterValueChangedCallback<bool>((INotifyValueChanged<bool>)(object)enableRandomiserToggle, (EventCallback<ChangeEvent<bool>>)delegate(ChangeEvent<bool> evt)
			{
				OnEnableRandomiserChanged(evt.newValue);
			});
			OnEnableRandomiserChanged(Plugin.Instance.mapSettings.enableRandomiser);
			randomSeedButton.clicked += OnRandomSeedPressed;
			((BaseField<int>)(object)seedInput).value = mapSettings.seed;
			INotifyValueChangedExtensions.RegisterValueChangedCallback<int>((INotifyValueChanged<int>)(object)seedInput, (EventCallback<ChangeEvent<int>>)delegate(ChangeEvent<int> evt)
			{
				mapSettings.seed = evt.newValue;
			});
			((BaseField<bool>)(object)autoSeedToggle).value = mapSettings.autoRandomSeed;
			INotifyValueChangedExtensions.RegisterValueChangedCallback<bool>((INotifyValueChanged<bool>)(object)autoSeedToggle, (EventCallback<ChangeEvent<bool>>)delegate(ChangeEvent<bool> evt)
			{
				OnAutoSeedChanged(evt.newValue);
			});
			OnAutoSeedChanged(mapSettings.autoRandomSeed);
			((BaseField<bool>)(object)fullyRandomToggle).value = mapSettings.fullyRandom;
			INotifyValueChangedExtensions.RegisterValueChangedCallback<bool>((INotifyValueChanged<bool>)(object)fullyRandomToggle, (EventCallback<ChangeEvent<bool>>)delegate(ChangeEvent<bool> evt)
			{
				OnFullyRandomChanged(evt.newValue);
			});
			OnFullyRandomChanged(mapSettings.fullyRandom);
			for (int i = 0; i < mapSettings.biomes.Count; i++)
			{
				int index = i;
				BiomeSettings biome2 = mapSettings.biomes[i];
				((BaseField<bool>)(object)biomeOverrideToggles[i]).value = biome2.overrideEnabled;
				INotifyValueChangedExtensions.RegisterValueChangedCallback<bool>((INotifyValueChanged<bool>)(object)biomeOverrideToggles[i], (EventCallback<ChangeEvent<bool>>)delegate(ChangeEvent<bool> evt)
				{
					OnOverrideBiomeChanged(index, evt.newValue);
				});
				OnOverrideBiomeChanged(index, biome2.overrideEnabled);
				if (runtimeSections[i].biomes.Count > 1)
				{
					((BasePopupField<string, string>)(object)biomeDropdowns[i]).choices.Add("Random");
				}
				((BasePopupField<string, string>)(object)biomeDropdowns[i]).choices.AddRange(runtimeSections[i].biomes.Select((BiomeData x) => x.biomeName));
				((BaseField<string>)(object)biomeDropdowns[i]).value = (biome2.randomBiome ? "Random" : biome2.selectedBiome.biomeName);
				INotifyValueChangedExtensions.RegisterValueChangedCallback<string>((INotifyValueChanged<string>)(object)biomeDropdowns[i], (EventCallback<ChangeEvent<string>>)delegate(ChangeEvent<string> evt)
				{
					OnBiomeChanged(index, evt.newValue);
				});
				List<string> variants = runtimeSections[i].biomes.Find((BiomeData biome) => biome.biomeType == mapSettings.biomes[i].selectedBiome.biomeType).variants;
				if (variants.Count > 1)
				{
					((BasePopupField<string, string>)(object)variantDropdowns[i]).choices.Add("Random");
				}
				((BasePopupField<string, string>)(object)variantDropdowns[i]).choices.AddRange(variants);
				((BaseField<string>)(object)variantDropdowns[i]).value = (biome2.randomVariant ? "Random" : biome2.selectedVariant);
				INotifyValueChangedExtensions.RegisterValueChangedCallback<string>((INotifyValueChanged<string>)(object)variantDropdowns[i], (EventCallback<ChangeEvent<string>>)delegate(ChangeEvent<string> evt)
				{
					OnBiomeVariantChanged(index, biome2, evt.newValue);
				});
				TabView val = UQueryExtensions.Q<TabView>(uiDocument.rootVisualElement, (string)null, (string)null);
				List<Tab> list = UQueryExtensions.Query<Tab>((VisualElement)(object)val, (string)null, (string)null).ToList();
				BiomeSettings biomeSettings = mapSettings.biomes[i];
				list[i].label = biomeSettings.selectedBiome.biomeName.ToUpper();
			}
		}

		private void OnBiomeChanged(int index, string value)
		{
			string value2 = value;
			if (value2 == "Random")
			{
				mapSettings.biomes[index].randomBiome = true;
				mapSettings.biomes[index].randomVariant = true;
				((BasePopupField<string, string>)(object)variantDropdowns[index]).choices.Clear();
				((BasePopupField<string, string>)(object)variantDropdowns[index]).choices.Add("Random");
				((BaseField<string>)(object)variantDropdowns[index]).SetValueWithoutNotify("Random");
				OnBiomeVariantChanged(index, mapSettings.biomes[index], "Random");
				TabView val = UQueryExtensions.Q<TabView>(uiDocument.rootVisualElement, (string)null, (string)null);
				val.activeTab.label = "RANDOM";
				return;
			}
			mapSettings.biomes[index].randomBiome = false;
			List<string> variants = runtimeSections[index].biomes.Find((BiomeData biome) => biome.biomeName == value2).variants;
			((BasePopupField<string, string>)(object)variantDropdowns[index]).choices.Clear();
			if (variants.Count > 1)
			{
				((BasePopupField<string, string>)(object)variantDropdowns[index]).choices.Add("Random");
			}
			((BasePopupField<string, string>)(object)variantDropdowns[index]).choices.AddRange(variants);
			BiomeData biomeData = runtimeSections[index].biomes.Find((BiomeData biome) => biome.biomeName == value2);
			mapSettings.biomes[index].selectedBiome = biomeData;
			TabView val2 = UQueryExtensions.Q<TabView>(uiDocument.rootVisualElement, (string)null, (string)null);
			val2.activeTab.label = biomeData.biomeName.ToUpper();
			((BaseField<string>)(object)variantDropdowns[index]).SetValueWithoutNotify("Random");
			OnBiomeVariantChanged(index, mapSettings.biomes[index], "Random");
		}

		private void OnBiomeVariantChanged(int index, BiomeSettings biome, string value)
		{
			if (value == "Random")
			{
				mapSettings.biomes[index].randomVariant = true;
			}
			else
			{
				mapSettings.biomes[index].randomVariant = false;
			}
			biome.selectedVariant = value;
		}

		private void OnOverrideBiomeChanged(int index, bool value)
		{
			mapSettings.biomes[index].overrideEnabled = value;
			((VisualElement)biomeDropdowns[index]).SetEnabled(value);
			((VisualElement)variantDropdowns[index]).SetEnabled(value);
		}

		private void OnRandomSeedPressed()
		{
			int value = Random.Range(0, 999999999);
			((BaseField<int>)(object)seedInput).value = value;
		}

		private void OnAutoSeedChanged(bool value)
		{
			if (((BaseField<bool>)(object)fullyRandomToggle).value && !value)
			{
				((BaseField<bool>)(object)autoSeedToggle).SetValueWithoutNotify(true);
				return;
			}
			mapSettings.autoRandomSeed = value;
			((VisualElement)seedInput).SetEnabled(!value);
			((VisualElement)randomSeedButton).SetEnabled(!value);
		}

		private void OnEnableRandomiserChanged(bool value)
		{
			randomiserMenu.visible = value;
			mapSettings.enableRandomiser = value;
		}

		private void OnFullyRandomChanged(bool value)
		{
			if (value && !((BaseField<bool>)(object)autoSeedToggle).value)
			{
				((BaseField<bool>)(object)autoSeedToggle).value = true;
			}
			biomeTabContainer.SetEnabled(!value);
			((VisualElement)autoSeedToggle).SetEnabled(!value);
			mapSettings.fullyRandom = value;
		}
	}
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "18.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("TerrainRandomiser.Resource1", typeof(Resource1).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

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

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

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

		internal Resource1()
		{
		}
	}
}
namespace TerrainRandomiser.TerrainGeneration
{
	public static class AreaVoxeliser
	{
		[BurstCompile]
		private struct BuildOverlapCommandsJob : IJobParallelFor
		{
			[WriteOnly]
			public NativeArray<OverlapBoxCommand> commands;

			public int3 gridRes;

			public float spacing;

			public float3 offset;

			public float3 halfExtents;

			public QueryParameters query;

			public void Execute(int index)
			{
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				int num = index % gridRes.x;
				int num2 = index / gridRes.x % gridRes.y;
				int num3 = index / (gridRes.x * gridRes.y);
				float3 val = default(float3);
				((float3)(ref val))..ctor(((float)num + 0.5f) * spacing, ((float)num2 + 0.5f) * spacing, ((float)num3 + 0.5f) * spacing);
				val -= float3.op_Implicit(gridRes) * spacing * 0.5f;
				val += offset;
				commands[index] = new OverlapBoxCommand(float3.op_Implicit(val), float3.op_Implicit(halfExtents), quaternion.op_Implicit(quaternion.identity), query);
			}
		}

		[BurstCompile]
		private struct ProcessOverlapResultsJob : IJobParallelFor
		{
			[ReadOnly]
			public NativeArray<ColliderHit> results;

			[WriteOnly]
			public NativeArray<uint> occupancy;

			public void Execute(int index)
			{
				//IL_000f: 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)
				ref NativeArray<uint> reference = ref occupancy;
				ColliderHit val = results[index];
				reference[index] = ((((ColliderHit)(ref val)).instanceID != 0) ? 1u : 0u);
			}
		}

		private static NativeArray<OverlapBoxCommand> commands;

		private static NativeArray<ColliderHit> results;

		public static NativeArray<uint> occupancyNative;

		public static NativeArray<uint> BuildOccupancyGrid(LayerMask occluderMask)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			LightVolume val = LightVolume.Instance();
			Vector3Int gridRes = val.gridRes;
			float raySpacing = val.raySpacing;
			int num = ((Vector3Int)(ref gridRes)).x * ((Vector3Int)(ref gridRes)).y * ((Vector3Int)(ref gridRes)).z;
			CreateArrays(num);
			float3 offset = float3.op_Implicit(val.gridOffset);
			float3 halfExtents = default(float3);
			((float3)(ref halfExtents))..ctor(raySpacing * 0.5f);
			BuildOverlapCommandsJob buildOverlapCommandsJob = default(BuildOverlapCommandsJob);
			buildOverlapCommandsJob.commands = commands;
			buildOverlapCommandsJob.gridRes = new int3(((Vector3Int)(ref gridRes)).x, ((Vector3Int)(ref gridRes)).y, ((Vector3Int)(ref gridRes)).z);
			buildOverlapCommandsJob.spacing = raySpacing;
			buildOverlapCommandsJob.offset = offset;
			buildOverlapCommandsJob.halfExtents = halfExtents;
			buildOverlapCommandsJob.query = new QueryParameters
			{
				layerMask = LayerMask.op_Implicit(occluderMask),
				hitTriggers = (QueryTriggerInteraction)1
			};
			BuildOverlapCommandsJob buildOverlapCommandsJob2 = buildOverlapCommandsJob;
			JobHandle val2 = IJobParallelForExtensions.Schedule<BuildOverlapCommandsJob>(buildOverlapCommandsJob2, num, 128, default(JobHandle));
			JobHandle val3 = OverlapBoxCommand.ScheduleBatch(commands, results, 128, 1, val2);
			ProcessOverlapResultsJob processOverlapResultsJob = default(ProcessOverlapResultsJob);
			processOverlapResultsJob.results = results;
			processOverlapResultsJob.occupancy = occupancyNative;
			ProcessOverlapResultsJob processOverlapResultsJob2 = processOverlapResultsJob;
			JobHandle val4 = IJobParallelForExtensions.Schedule<ProcessOverlapResultsJob>(processOverlapResultsJob2, num, 128, val3);
			((JobHandle)(ref val4)).Complete();
			return occupancyNative;
		}

		private static void CreateArrays(int voxelCount)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			DisposeArrays();
			commands = new NativeArray<OverlapBoxCommand>(voxelCount, (Allocator)4, (NativeArrayOptions)1);
			results = new NativeArray<ColliderHit>(voxelCount, (Allocator)4, (NativeArrayOptions)1);
			occupancyNative = new NativeArray<uint>(voxelCount, (Allocator)4, (NativeArrayOptions)1);
		}

		public static void DisposeArrays()
		{
			if (commands.IsCreated)
			{
				commands.Dispose();
			}
			if (results.IsCreated)
			{
				results.Dispose();
			}
			if (occupancyNative.IsCreated)
			{
				occupancyNative.Dispose();
			}
		}
	}
	public static class GenerationPatches
	{
		[HarmonyPatch]
		public static class RemoveDebugLogsPatch
		{
			[CompilerGenerated]
			private sealed class <Transpiler>d__0 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
			{
				private int <>1__state;

				private CodeInstruction <>2__current;

				private int <>l__initialThreadId;

				private IEnumerable<CodeInstruction> instructions;

				public IEnumerable<CodeInstruction> <>3__instructions;

				private MethodInfo <logMethod>5__1;

				private MethodInfo <logErrorMethod>5__2;

				private IEnumerator<CodeInstruction> <>s__3;

				private CodeInstruction <instruction>5__4;

				CodeInstruction IEnumerator<CodeInstruction>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <Transpiler>d__0(int <>1__state)
				{
					this.<>1__state = <>1__state;
					<>l__initialThreadId = Environment.CurrentManagedThreadId;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					int num = <>1__state;
					if (num == -3 || (uint)(num - 1) <= 1u)
					{
						try
						{
						}
						finally
						{
							<>m__Finally1();
						}
					}
					<logMethod>5__1 = null;
					<logErrorMethod>5__2 = null;
					<>s__3 = null;
					<instruction>5__4 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
					//IL_0100: Expected O, but got Unknown
					try
					{
						switch (<>1__state)
						{
						default:
							return false;
						case 0:
							<>1__state = -1;
							<logMethod>5__1 = AccessTools.Method(typeof(Debug), "Log", new Type[1] { typeof(object) }, (Type[])null);
							<logErrorMethod>5__2 = AccessTools.Method(typeof(Debug), "LogError", new Type[1] { typeof(object) }, (Type[])null);
							<>s__3 = instructions.GetEnumerator();
							<>1__state = -3;
							break;
						case 1:
							<>1__state = -3;
							break;
						case 2:
							<>1__state = -3;
							<instruction>5__4 = null;
							break;
						}
						if (<>s__3.MoveNext())
						{
							<instruction>5__4 = <>s__3.Current;
							if (CodeInstructionExtensions.Calls(<instruction>5__4, <logMethod>5__1) || CodeInstructionExtensions.Calls(<instruction>5__4, <logErrorMethod>5__2))
							{
								<>2__current = new CodeInstruction(OpCodes.Pop, (object)null);
								<>1__state = 1;
								return true;
							}
							<>2__current = <instruction>5__4;
							<>1__state = 2;
							return true;
						}
						<>m__Finally1();
						<>s__3 = null;
						return false;
					}
					catch
					{
						//try-fault
						((IDisposable)this).Dispose();
						throw;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				private void <>m__Finally1()
				{
					<>1__state = -1;
					if (<>s__3 != null)
					{
						<>s__3.Dispose();
					}
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}

				[DebuggerHidden]
				IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
				{
					<Transpiler>d__0 <Transpiler>d__;
					if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
					{
						<>1__state = 0;
						<Transpiler>d__ = this;
					}
					else
					{
						<Transpiler>d__ = new <Transpiler>d__0(0);
					}
					<Transpiler>d__.instructions = <>3__instructions;
					return <Transpiler>d__;
				}

				[DebuggerHidden]
				IEnumerator IEnumerable.GetEnumerator()
				{
					return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
				}
			}

			[IteratorStateMachine(typeof(<Transpiler>d__0))]
			[HarmonyTranspiler]
			[HarmonyPatch(typeof(JungleVine), "Awake")]
			[HarmonyPatch(typeof(JungleVine), "PickTreePlatforms")]
			[HarmonyPatch(typeof(SpawnConnectingBridge), "CheckCondition")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <Transpiler>d__0(-2)
				{
					<>3__instructions = instructions
				};
			}
		}

		[HarmonyPatch(typeof(Looker), "ToggleLookers")]
		internal static class ToggleLookersPatch
		{
			public static bool Prefix(Looker __instance)
			{
				Looker[] componentsInChildren = ((Component)((Component)__instance).transform.parent).GetComponentsInChildren<Looker>();
				int num = Random.Range(0, componentsInChildren.Length);
				if (Random.value < 0.95f)
				{
					num = -1;
				}
				Looker[] array = componentsInChildren;
				Looker[] array2 = array;
				foreach (Looker val in array2)
				{
					if ((Object)(object)val.view == (Object)null)
					{
						val.view = ((Component)val).GetComponent<PhotonView>();
					}
					if (((Component)val).transform.GetSiblingIndex() != num)
					{
						val.view.RPC("RPCA_DisableLooker", (RpcTarget)3, Array.Empty<object>());
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(PropSpawner_Sphere), "SpawnNew")]
		public static class PropSpawnerSphereAddPatch
		{
			private static Ray[] rays = (Ray[])(object)new Ray[0];

			private static bool Prefix(PropSpawner_Sphere __instance, bool executeDeferredImmediately)
			{
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0116: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_015a: Unknown result type (might be due to invalid IL or missing references)
				//IL_015f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				//IL_0167: Unknown result type (might be due to invalid IL or missing references)
				//IL_016c: Unknown result type (might be due to invalid IL or missing references)
				//IL_016f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0174: Unknown result type (might be due to invalid IL or missing references)
				//IL_0179: Unknown result type (might be due to invalid IL or missing references)
				//IL_0186: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0190: Unknown result type (might be due to invalid IL or missing references)
				//IL_0191: Unknown result type (might be due to invalid IL or missing references)
				//IL_0193: Unknown result type (might be due to invalid IL or missing references)
				//IL_0198: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a6: Expected O, but got Unknown
				//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ba: Invalid comparison between Unknown and I4
				if (!Plugin.Instance.roomMapSettings.enableRandomiser)
				{
					return true;
				}
				if (__instance.spawnChance < Random.value)
				{
					return false;
				}
				if (!CanBatch(((Object)((Component)__instance).gameObject).name, __instance.rayCastSpawn, __instance.syncTransforms))
				{
					return true;
				}
				int num = __instance.nrOfSpawns;
				if (__instance.randomSpawns)
				{
					num = Random.Range(__instance.minSpawnCount, __instance.nrOfSpawns);
				}
				int num2 = 50000;
				int num3 = 0;
				int num4 = 256;
				if (rays.Length < num4)
				{
					rays = (Ray[])(object)new Ray[num4];
				}
				LayerMask mask = HelperFunctions.GetMask(__instance.layerType);
				QueryParameters @default = QueryParameters.Default;
				@default.layerMask = ((LayerMask)(ref mask)).value;
				@default.hitTriggers = (QueryTriggerInteraction)1;
				NativeArray<RaycastHit> results = default(NativeArray<RaycastHit>);
				results..ctor(num4, (Allocator)3, (NativeArrayOptions)1);
				NativeArray<RaycastCommand> commands = default(NativeArray<RaycastCommand>);
				commands..ctor(num4, (Allocator)3, (NativeArrayOptions)1);
				while (num3 < num && num2 > 0)
				{
					rays = PropSpawnerHelpers.BuildRays_Sphere(__instance, rays, num4);
					ExecuteJob(commands, results, rays, @default, num4, __instance.rayLength);
					num2 -= num4;
					int num5 = 0;
					for (int i = 0; i < num4; i++)
					{
						if (num3 >= num)
						{
							break;
						}
						RaycastHit hit = results[i];
						if (!Object.op_Implicit((Object)(object)((RaycastHit)(ref hit)).transform))
						{
							continue;
						}
						SpawnData val = new SpawnData
						{
							pos = ((RaycastHit)(ref hit)).point,
							normal = ((RaycastHit)(ref hit)).normal,
							rayDir = ((Ray)(ref rays[i])).direction,
							hit = hit,
							spawnerTransform = ((Component)__instance).transform
						};
						bool flag = true;
						for (int j = 0; j < __instance.constraints.Count; j++)
						{
							if (!__instance.constraints[j].CheckConstraint(val))
							{
								flag = false;
								break;
							}
						}
						if (flag)
						{
							GameObject val2 = Spawn(__instance, val);
							if ((Object)(object)val2 != (Object)null)
							{
								__instance.spawnedProps.Add(val2);
								num3++;
								num5++;
							}
						}
					}
					if (num <= 10 && num5 == 0)
					{
						break;
					}
				}
				commands.Dispose();
				results.Dispose();
				foreach (PostSpawnBehavior postSpawnBehavior in __instance.postSpawnBehaviors)
				{
					if (!postSpawnBehavior.mute)
					{
						if (executeDeferredImmediately || (int)postSpawnBehavior.DeferredTiming != 2)
						{
							postSpawnBehavior.RunBehavior((IEnumerable<GameObject>)__instance.spawnedProps);
						}
						else
						{
							__instance._deferredSteps.Add(postSpawnBehavior.ConstructDeferred((IMayHaveDeferredStep)(object)__instance));
						}
					}
				}
				return false;
			}

			private static GameObject Spawn(PropSpawner_Sphere spawner, SpawnData spawnData)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = HelperFunctions.SpawnPrefab(spawner.props[Random.Range(0, spawner.props.Length)], spawnData.pos, HelperFunctions.GetRandomRotationWithUp(Vector3.up), ((Component)spawner).transform);
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				for (int i = 0; i < spawner.modifiers.Count; i++)
				{
					spawner.modifiers[i].ModifyObject(val, spawnData);
				}
				for (int j = 0; j < spawner.postConstraints.Count; j++)
				{
					if (!spawner.postConstraints[j].CheckConstraint(val, spawnData))
					{
						Object.DestroyImmediate((Object)(object)val);
						return null;
					}
				}
				return val;
			}
		}

		[HarmonyPatch(typeof(PropSpawner), "SpawnNew")]
		public static class PropSpawnerSpawnNewPatch
		{
			private static Ray[] rays = (Ray[])(object)new Ray[0];

			private static bool Prefix(PropSpawner __instance, bool executeDeferredImmediately)
			{
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_015a: Unknown result type (might be due to invalid IL or missing references)
				if (!Plugin.Instance.roomMapSettings.enableRandomiser)
				{
					return true;
				}
				if (__instance.chanceToUseSpawner < 0.999f && Random.value > __instance.chanceToUseSpawner)
				{
					return false;
				}
				if (!CanBatch(((Object)((Component)__instance).gameObject).name, __instance.raycastPosition, __instance.syncTransforms))
				{
					return true;
				}
				int num = __instance.nrOfSpawns;
				if (__instance.randomSpawns)
				{
					num = Random.Range(__instance.minSpawnCount, __instance.nrOfSpawns);
				}
				int num2 = 25000;
				int i = 0;
				int num3 = 256;
				LayerMask mask = HelperFunctions.GetMask(__instance.layerType);
				if (rays.Length < num3)
				{
					rays = (Ray[])(object)new Ray[num3];
				}
				Vector3 val = ((Component)__instance).transform.forward + __instance.rayDirectionOffset;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				QueryParameters @default = QueryParameters.Default;
				@default.layerMask = ((LayerMask)(ref mask)).value;
				@default.hitTriggers = (QueryTriggerInteraction)1;
				NativeArray<RaycastHit> results = default(NativeArray<RaycastHit>);
				results..ctor(num3, (Allocator)3, (NativeArrayOptions)1);
				NativeArray<RaycastCommand> commands = default(NativeArray<RaycastCommand>);
				commands..ctor(num3, (Allocator)3, (NativeArrayOptions)1);
				int num4;
				for (; i < num; i += num4)
				{
					if (num2 <= 0)
					{
						break;
					}
					rays = PropSpawnerHelpers.BuildRays(__instance, rays, num3, normalized);
					ExecuteJob(commands, results, rays, @default, num3, __instance.rayLength);
					num2 -= num3;
					num4 = ProcessResults(results, rays, __instance, i, num);
				}
				commands.Dispose();
				results.Dispose();
				Physics.SyncTransforms();
				__instance.currentSpawns = ((Component)__instance).transform.childCount;
				__instance.SpawnDecor();
				HandlePostSpawnBehaviors(__instance, executeDeferredImmediately);
				return false;
			}

			private static void HandlePostSpawnBehaviors(PropSpawner __instance, bool executeDeferredImmediately)
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Invalid comparison between Unknown and I4
				foreach (PostSpawnBehavior postSpawnBehavior in __instance.postSpawnBehaviors)
				{
					if (!postSpawnBehavior.mute)
					{
						if (executeDeferredImmediately || (int)postSpawnBehavior.DeferredTiming != 2)
						{
							postSpawnBehavior.RunBehavior(__instance.SpawnedProps);
						}
						else
						{
							__instance._deferredSteps.Add(postSpawnBehavior.ConstructDeferred((IMayHaveDeferredStep)(object)__instance));
						}
					}
				}
			}
		}

		[HarmonyPatch]
		public static class LevelGenStepSpawnPatch
		{
			[CompilerGenerated]
			private sealed class <>c__DisplayClass0_0
			{
				public Type baseType;

				public Func<Type, bool> <>9__0;

				internal bool <TargetMethods>b__0(Type t)
				{
					return baseType.IsAssignableFrom(t) && !t.IsAbstract;
				}
			}

			[CompilerGenerated]
			private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
			{
				private int <>1__state;

				private MethodBase <>2__current;

				private int <>l__initialThreadId;

				private <>c__DisplayClass0_0 <>8__1;

				private IEnumerator<Type> <>s__2;

				private Type <type>5__3;

				private MethodInfo <method>5__4;

				MethodBase IEnumerator<MethodBase>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <TargetMethods>d__0(int <>1__state)
				{
					this.<>1__state = <>1__state;
					<>l__initialThreadId = Environment.CurrentManagedThreadId;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					int num = <>1__state;
					if (num == -3 || num == 1)
					{
						try
						{
						}
						finally
						{
							<>m__Finally1();
						}
					}
					<>8__1 = null;
					<>s__2 = null;
					<type>5__3 = null;
					<method>5__4 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					try
					{
						int num = <>1__state;
						if (num != 0)
						{
							if (num != 1)
							{
								return false;
							}
							<>1__state = -3;
							goto IL_00ff;
						}
						<>1__state = -1;
						<>8__1 = new <>c__DisplayClass0_0();
						<>8__1.baseType = typeof(LevelGenStep);
						<>s__2 = (from t in <>8__1.baseType.Assembly.GetTypes()
							where <>8__1.baseType.IsAssignableFrom(t) && !t.IsAbstract
							select t).GetEnumerator();
						<>1__state = -3;
						goto IL_010e;
						IL_010e:
						if (<>s__2.MoveNext())
						{
							<type>5__3 = <>s__2.Current;
							<method>5__4 = <type>5__3.GetMethod("Spawn", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
							if (<method>5__4 != null)
							{
								<>2__current = <method>5__4;
								<>1__state = 1;
								return true;
							}
							goto IL_00ff;
						}
						<>m__Finally1();
						<>s__2 = null;
						return false;
						IL_00ff:
						<method>5__4 = null;
						<type>5__3 = null;
						goto IL_010e;
					}
					catch
					{
						//try-fault
						((IDisposable)this).Dispose();
						throw;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				private void <>m__Finally1()
				{
					<>1__state = -1;
					if (<>s__2 != null)
					{
						<>s__2.Dispose();
					}
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}

				[DebuggerHidden]
				IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
				{
					if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
					{
						<>1__state = 0;
						return this;
					}
					return new <TargetMethods>d__0(0);
				}

				[DebuggerHidden]
				IEnumerator IEnumerable.GetEnumerator()
				{
					return ((IEnumerable<MethodBase>)this).GetEnumerator();
				}
			}

			[IteratorStateMachine(typeof(<TargetMethods>d__0))]
			private static IEnumerable<MethodBase> TargetMethods()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <TargetMethods>d__0(-2);
			}

			private static bool Prefix(LevelGenStep __instance, MethodBase __originalMethod, SpawnData spawnData, ref GameObject __result)
			{
				if (!Plugin.Instance.roomMapSettings.enableRandomiser)
				{
					return true;
				}
				Type type = ((object)__instance).GetType();
				GameObject[] array = type.GetField("props", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(__instance) as GameObject[];
				IList list = type.GetField("modifiers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(__instance) as IList;
				IList list2 = type.GetField("postConstraints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(__instance) as IList;
				if (array == null)
				{
					return true;
				}
				List<PropSpawnerMod> modifiers = ((list != null) ? new List<PropSpawnerMod>(list.Cast<PropSpawnerMod>()) : new List<PropSpawnerMod>());
				List<PropSpawnerConstraintPost> postConstraints = ((list2 != null) ? new List<PropSpawnerConstraintPost>(list2.Cast<PropSpawnerConstraintPost>()) : new List<PropSpawnerConstraintPost>());
				return PropSpawnerHelpers.TrySpawn(spawnData, ref __result, array, modifiers, postConstraints, ((Component)__instance).transform, ((Component)__instance).gameObject, Plugin.viewIDsToSend, Plugin.viewsRequiringIDs);
			}
		}

		public static bool CanBatch(string spawnerName, bool raycastPosition, bool syncTransforms)
		{
			if (!raycastPosition)
			{
				return false;
			}
			if (!syncTransforms || PropSpawnerHelpers.SafeToBatchPropNames.Contains(spawnerName))
			{
				return true;
			}
			return true;
		}

		public static bool PassedConstraints(PropSpawner spawner, SpawnData sd)
		{
			for (int i = 0; i < spawner.constraints.Count; i++)
			{
				if (!spawner.constraints[i].CheckConstraint(sd))
				{
					return false;
				}
			}
			return true;
		}

		public static void ExecuteJob(NativeArray<RaycastCommand> commands, NativeArray<RaycastHit> results, Ray[] rays, QueryParameters queryParams, int batchCount, float rayLength)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < batchCount; i++)
			{
				commands[i] = new RaycastCommand(((Ray)(ref rays[i])).origin, ((Ray)(ref rays[i])).direction, queryParams, rayLength);
			}
			JobHandle val = RaycastCommand.ScheduleBatch(commands, results, 4, default(JobHandle));
			((JobHandle)(ref val)).Complete();
		}

		public static int ProcessResults(NativeArray<RaycastHit> results, Ray[] rays, PropSpawner spawner, int successes, int nrOfSpawns)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < results.Length; i++)
			{
				if (successes >= nrOfSpawns)
				{
					break;
				}
				RaycastHit hit = results[i];
				if ((Object)(object)((RaycastHit)(ref hit)).collider == (Object)null)
				{
					continue;
				}
				num++;
				SpawnData val = PropSpawnerHelpers.BuildSpawnData(spawner, rays[i], hit, hasHit: true, successes);
				if (PassedConstraints(spawner, val))
				{
					GameObject val2 = spawner.Spawn(val);
					if ((Object)(object)val2 != (Object)null)
					{
						successes++;
						num2++;
						spawner.AllSpawnData[val2] = val;
					}
				}
			}
			return num2;
		}
	}
	public static class LightMapBaker
	{
		public static ComputeShader computeShader;

		public static int rayCount = 128;

		public static int maxSteps = 64;

		public static void RunBake()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			LightVolume val = LightVolume.Instance();
			val.lightMap = null;
			Shader.SetGlobalTexture("_LightMap", (Texture)null);
			Stopwatch stopwatch = Stopwatch.StartNew();
			NativeArray<uint> occupancy = AreaVoxeliser.BuildOccupancyGrid(val.occluderMask);
			stopwatch.Stop();
			Debug.Log((object)("[TerrainRandomiser] Occupancy took: " + stopwatch.ElapsedMilliseconds));
			stopwatch = Stopwatch.StartNew();
			RenderTexture val2 = DispatchAndCreateRenderTexture(computeShader, occupancy, val.gridRes, rayCount, maxSteps, val.skyColor);
			AreaVoxeliser.DisposeArrays();
			RenderTexture val3 = val.RunBlur(val2);
			((Object)val3).name = "LightVolumeRenderTexture";
			val.SetShaderVars();
			val.SaveTex(val3, (Action)null);
			stopwatch.Stop();
			Debug.Log((object)("[TerrainRandomiser] Visibility took: " + stopwatch.ElapsedMilliseconds));
		}

		private static RenderTexture DispatchAndCreateRenderTexture(ComputeShader cs, NativeArray<uint> occupancy, Vector3Int gridRes, int rayCount, int maxSteps, Color skyColor)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			int num = cs.FindKernel("SkyVisibilityDDA");
			int num2 = ((Vector3Int)(ref gridRes)).x * ((Vector3Int)(ref gridRes)).y * ((Vector3Int)(ref gridRes)).z;
			ComputeBuffer val = new ComputeBuffer(num2, 4);
			val.SetData<uint>(occupancy);
			List<GpuLight> list = BuildLights();
			ComputeBuffer val2 = new ComputeBuffer(list.Count, 52);
			val2.SetData<GpuLight>(list);
			RenderTexture val3 = new RenderTexture(((Vector3Int)(ref gridRes)).x, ((Vector3Int)(ref gridRes)).y, 0)
			{
				enableRandomWrite = true,
				format = (RenderTextureFormat)2,
				dimension = (TextureDimension)3,
				volumeDepth = ((Vector3Int)(ref gridRes)).z,
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1
			};
			val3.Create();
			LightVolume val4 = LightVolume.Instance();
			cs.SetInts("_GridRes", new int[3]
			{
				((Vector3Int)(ref gridRes)).x,
				((Vector3Int)(ref gridRes)).y,
				((Vector3Int)(ref gridRes)).z
			});
			cs.SetVector("_GridOffset", Vector4.op_Implicit(val4.gridOffset));
			cs.SetFloat("_RaySpacing", val4.raySpacing);
			cs.SetBuffer(num, "_Occupancy", val);
			cs.SetTexture(num, "_LightMap", (Texture)(object)val3);
			cs.SetInt("_RayCount", rayCount);
			cs.SetInt("_MaxSteps", maxSteps);
			cs.SetVector("_SkyColor", Color.op_Implicit(skyColor));
			cs.SetBuffer(num, "_LightBuffer", val2);
			cs.SetInt("_LightBufferLength", list.Count);
			int num3 = (((Vector3Int)(ref gridRes)).x + 3) / 4;
			int num4 = (((Vector3Int)(ref gridRes)).y + 3) / 4;
			int num5 = (((Vector3Int)(ref gridRes)).z + 3) / 4;
			cs.Dispatch(num, num3, num4, num5);
			val.Release();
			val2.Release();
			return val3;
		}

		public static List<GpuLight> BuildLights()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Invalid comparison between Unknown and I4
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			LightVolume val = LightVolume.Instance();
			List<GpuLight> list = new List<GpuLight>();
			GameObject val2 = (((Object)(object)val.sceneParent == (Object)null) ? ((Component)val).gameObject : val.sceneParent);
			BakedVolumeLight[] componentsInChildren = val2.GetComponentsInChildren<BakedVolumeLight>();
			BakedVolumeLight[] array = componentsInChildren;
			Vector3 val4 = default(Vector3);
			foreach (BakedVolumeLight val3 in array)
			{
				((Vector3)(ref val4))..ctor(val3.color.r, val3.color.g, val3.color.b);
				LightModes mode = val3.mode;
				if (1 == 0)
				{
				}
				float num;
				if ((int)mode != 0)
				{
					if ((int)mode != 1)
					{
						throw new Exception();
					}
					num = val3.coneSize * (MathF.PI / 180f);
				}
				else
				{
					num = 0f;
				}
				if (1 == 0)
				{
				}
				float coneSize = num;
				list.Add(new GpuLight
				{
					Position = ((Component)val3).transform.position,
					ConeSize = coneSize,
					Direction = ((Component)val3).transform.forward,
					Radius = val3.GetRadius(),
					Color = val4 * val3.intensity,
					Falloff = val3.falloff,
					ConeFalloff = val3.coneFalloff
				});
			}
			if (list.Count == 0)
			{
				list.Add(default(GpuLight));
			}
			return list;
		}
	}
	public class MapHandlerHelpers
	{
		private static void ApplyBiomeVariant(MapSegment seg, BiomeSettings biomeSettings)
		{
			BiomeSettings biomeSettings2 = biomeSettings;
			BiomeVariant[] componentsInChildren = seg.segmentParent.GetComponentsInChildren<BiomeVariant>(true);
			BiomeVariant val = ((IEnumerable<BiomeVariant>)componentsInChildren).FirstOrDefault((Func<BiomeVariant, bool>)((BiomeVariant v) => ((Component)v).gameObject.activeSelf));
			BiomeVariant val2 = ((IEnumerable<BiomeVariant>)componentsInChildren).FirstOrDefault((Func<BiomeVariant, bool>)((BiomeVariant v) => ((Object)v).name == biomeSettings2.selectedVariant));
			if ((Object)(object)val2 == (Object)null || (Object)(object)val == (Object)(object)val2)
			{
				return;
			}
			PropGrouper component = seg.segmentParent.gameObject.GetComponent<PropGrouper>();
			if ((Object)(object)component == (Object)null)
			{
				seg.segmentParent.gameObject.AddComponent<PropGrouper>();
			}
			if ((Object)(object)val != (Object)null)
			{
				PropGrouper component2 = ((Component)val).GetComponent<PropGrouper>();
				if (component2 != null)
				{
					component2.ClearAll();
				}
				((Component)val).gameObject.SetActive(false);
			}
			((Component)val2).gameObject.SetActive(true);
		}

		public static void ApplyBiomeToSegment(MapHandler handler, int index, BiomeSettings biomeSettings)
		{
			//IL_000b: 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)
			MapSegment val = handler.segments[index];
			if (val.biome == biomeSettings.selectedBiome.biomeType)
			{
				ApplyVariant(val, biomeSettings);
			}
			else
			{
				SwapBiome(val, handler, biomeSettings);
			}
		}

		private static void ApplyVariant(MapSegment seg, BiomeSettings biomeSettings)
		{
			switch (biomeSettings.selectedBiome.variantSelectionType)
			{
			case VariantSelectionType.BiomeVariant:
				ApplyBiomeVariant(seg, biomeSettings);
				break;
			case VariantSelectionType.VariantObject:
				ApplyVariantObject(seg, biomeSettings);
				break;
			}
		}

		private static void ApplyVariantObject(MapSegment seg, BiomeSettings biomeSettings)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			BiomeSettings biomeSettings2 = biomeSettings;
			VariantObject[] componentsInChildren = seg.segmentParent.GetComponentsInChildren<VariantObject>(true);
			VariantObject val = ((IEnumerable<VariantObject>)componentsInChildren).FirstOrDefault((Func<VariantObject, bool>)((VariantObject v) => ((Object)v).name.ToLower().Contains(biomeSettings2.selectedVariant.ToLower())));
			if (!((Object)(object)val == (Object)null))
			{
				VariantObject[] array = componentsInChildren;
				foreach (VariantObject val2 in array)
				{
					bool active = (int)val2.group == 0 && ((Object)val2).name.ToLower().Contains(biomeSettings2.selectedVariant.ToLower());
					((Component)val2).gameObject.SetActive(active);
				}
			}
		}

		private static void SwapBiome(MapSegment seg, MapHandler handler, BiomeSettings biomeSettings)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			MapSegment seg2 = seg;
			PropGrouper component = seg2.segmentParent.GetComponent<PropGrouper>();
			if (component != null)
			{
				component.ClearAll();
			}
			((Component)seg2.segmentParent.transform.parent).gameObject.SetActive(false);
			int index = handler.biomes.FindIndex((BiomeType x) => x == seg2.biome);
			handler.biomes[index] = biomeSettings.selectedBiome.biomeType;
			((Component)seg2.segmentParent.transform.parent).gameObject.SetActive(true);
			GameObject segmentCampfire = seg2.segmentCampfire;
			PropGrouper val = segmentCampfire.GetComponent<PropGrouper>();
			if ((Object)(object)val == (Object)null)
			{
				val = segmentCampfire.AddComponent<PropGrouper>();
			}
			val.RunAll(true);
			ApplyVariant(seg2, biomeSettings);
		}

		public static List<PhotonView> GetAllUnassignedViews()
		{
			PhotonView[] componentsInChildren = ((Component)Singleton<MapHandler>.Instance).gameObject.GetComponentsInChildren<PhotonView>();
			List<PhotonView> list = new List<PhotonView>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (componentsInChildren[i].ViewID == 0)
				{
					list.Add(componentsInChildren[i]);
				}
			}
			return list;
		}

		public static List<int> GetAndAssignAllUnassignedViews()
		{
			List<PhotonView> allUnassignedViews = GetAllUnassignedViews();
			List<int> list = new List<int>();
			for (int i = 0; i < allUnassignedViews.Count; i++)
			{
				int item = PropSpawnerHelpers.AssignMasterClientViewID(((Component)allUnassignedViews[i]).gameObject);
				list.Add(item);
			}
			return list;
		}
	}
	public static class PropGrouperHelpers
	{
		public static Dictionary<DeferredStepTiming, List<IDeferredStep>> deferredSteps = new Dictionary<DeferredStepTiming, List<IDeferredStep>>();

		private static void AddToStepList(DeferredStepTiming key, IDeferredStep stepToAdd)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!deferredSteps.ContainsKey(key))
			{
				deferredSteps.Add(key, new List<IDeferredStep>());
			}
			deferredSteps[key].Add(stepToAdd);
		}

		private static void ExecuteAndClearDeferredStepsFor(DeferredStepTiming key)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!deferredSteps.ContainsKey(key))
			{
				return;
			}
			foreach (IDeferredStep item in deferredSteps[key])
			{
				item.DeferredGo();
			}
			deferredSteps[key].Clear();
		}

		public static void RunRootPropGrouper(PropGrouper rootGrouper)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Invalid comparison between Unknown and I4
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			deferredSteps.Clear();
			rootGrouper.ClearAll();
			LevelGenStep[] componentsInChildren = ((Component)rootGrouper).GetComponentsInChildren<LevelGenStep>();
			List<LevelGenStep> list = new List<LevelGenStep>();
			List<LevelGenStep> list2 = new List<LevelGenStep>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				PropGrouperTiming timing = ((Component)componentsInChildren[i]).GetComponentInParent<PropGrouper>().timing;
				PropGrouperTiming val = timing;
				if ((int)val != 0)
				{
					if ((int)val == 1)
					{
						list2.Add(componentsInChildren[i]);
					}
				}
				else
				{
					list.Add(componentsInChildren[i]);
				}
			}
			foreach (LevelGenStep item in list)
			{
				item.Execute();
				if ((int)item.DeferredTiming > 0)
				{
					AddToStepList(item.DeferredTiming, item.ConstructDeferred((IMayHaveDeferredStep)(object)item));
				}
			}
			((PhotonPeer)PhotonNetwork.NetworkingClient.LoadBalancingPeer).SendOutgoingCommands();
			if (Plugin.EnableLightMapBaking.Value)
			{
				LightMapBaker.RunBake();
			}
			((PhotonPeer)PhotonNetwork.NetworkingClient.LoadBalancingPeer).SendOutgoingCommands();
			ExecuteAndClearDeferredStepsFor((DeferredStepTiming)2);
			foreach (LevelGenStep item2 in list2)
			{
				item2.Execute();
			}
		}
	}
	public static class PropSpawnerHelpers
	{
		public static readonly HashSet<string> SafeToBatchPropNames = new HashSet<string>
		{
			"LuggageSpawner", "Ivy", "Geysers", "Weed", "ExploShrooms", "PoisonShrooms", "Vines", "BeachGrass", "Driftwood", "Behive",
			"ShittyPiton", "Monsteras", "FlashPlant", "Shrub", "Pine", "Bushes", "Trees", "DeadTree", "Ice_DeadTree", "Palms",
			"Luggage", "Cacti", "Dynamite", "Ferns", "Zombie Spawner", "Exploding Shrooms", "Glow Mushrooms", "Spiders", "Bounce Shrooms", "Shroom Spawners",
			"Root Spawner", "Evil Shroom"
		};

		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);
				if ((Object)(object)val3 == (Object)null)
				{
					Debug.LogError((object)("Failed to instantiate prop " + ((Object)val).name));
					__result = null;
					return false;
				}
				RemoveSpineIfLuggage(val3);
				ApplyModifiers(val3, spawnData, modifiers);
				if (!CheckAndHandlePostConstraints(val3, spawnData, postConstraints))
				{
					__result = null;
					return false;
				}
				if ((Object)(object)val3 == (Object)null)
				{
					__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_Sphere(PropSpawner_Sphere spawner, Ray[] outRays, int count)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)spawner).transform.position;
			for (int i = 0; i < count; i++)
			{
				Vector3 onUnitSphere = Random.onUnitSphere;
				outRays[i] = new Ray(position, onUnitSphere);
			}
			return outRays;
		}

		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 SpawnData BuildSpawnData(PropSpawner spawner, Ray ray, RaycastHit hit, bool hasHit, int count)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			Vector2 placement = default(Vector2);
			((Vector2)(ref placement))..ctor(Random.value, Random.value);
			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
			};
		}
	}
}