Decompiled source of MapMaker v0.13.0

MapMaker.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Burst2Flame;
using Burst2Flame.Observable;
using HarmonyLib;
using HexMapTools;
using MapNodeSystem;
using Microsoft.CodeAnalysis;
using ModNet;
using ModsMenu;
using Newtonsoft.Json;
using StolenRealmModAPI;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MapMaker")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e541341b423e7e02f062bf9975ad907cb3f30935")]
[assembly: AssemblyProduct("MapMaker")]
[assembly: AssemblyTitle("MapMaker")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MapMaker
{
	internal static class Icons
	{
		internal const int TileSize = 48;

		internal const int PropSize = 96;

		private const int Layer = 31;

		private const float Crop = 0.55f;

		private const float Pitch = 35f;

		private const float Turn = 30f;

		private static readonly Color TileBack = new Color(0.1f, 0.1f, 0.1f, 1f);

		private static readonly Color PropBack = new Color(0.17f, 0.18f, 0.2f, 1f);

		private static readonly Vector3 At = new Vector3(0f, -2000f, 0f);

		private static readonly Dictionary<Object, Texture2D> Done = new Dictionary<Object, Texture2D>();

		private static readonly List<Object> Wanted = new List<Object>();

		private static readonly Dictionary<GameObject, PropCatalog.Prop> Props = new Dictionary<GameObject, PropCatalog.Prop>();

		internal static readonly Texture2D NoPicture = new Texture2D(1, 1)
		{
			name = "MapMaker no picture",
			hideFlags = (HideFlags)61
		};

		internal static Texture2D Tile(Material material)
		{
			return Get((Object)(object)material);
		}

		internal static Texture2D Prop(PropCatalog.Prop prop)
		{
			if ((Object)(object)prop?.Source == (Object)null)
			{
				return null;
			}
			Props[prop.Source] = prop;
			return Get((Object)(object)prop.Source);
		}

		private static Texture2D Get(Object key)
		{
			if (key == (Object)null)
			{
				return null;
			}
			if (Done.TryGetValue(key, out var value))
			{
				return value;
			}
			if (!Wanted.Contains(key))
			{
				Wanted.Add(key);
			}
			return null;
		}

		internal static void Tick()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			if (Wanted.Count == 0)
			{
				return;
			}
			HexCell hex = ((IEnumerable<HexCell>)MapBuilder.Cells).FirstOrDefault((Func<HexCell, bool>)delegate(HexCell c)
			{
				if ((Object)(object)c != (Object)null)
				{
					MeshFilter component = ((Component)c).GetComponent<MeshFilter>();
					return (Object)(object)((component != null) ? component.sharedMesh : null) != (Object)null;
				}
				return false;
			});
			foreach (Object item in Wanted.Where((Object k) => (Object)(object)hex != (Object)null || !(k is Material)).Take(4).ToList())
			{
				Wanted.Remove(item);
				Texture2D val = null;
				if (item != (Object)null)
				{
					try
					{
						Material val2 = (Material)(object)((item is Material) ? item : null);
						val = ((val2 != null) ? RenderTile(((Component)hex).transform, ((Component)hex).GetComponent<MeshFilter>().sharedMesh, val2) : RenderProp(Props[(GameObject)item]));
					}
					catch (Exception ex)
					{
						Plugin.ModLog.LogWarning((object)("MapMaker: no picture of '" + item.name + "': " + ex.Message));
					}
				}
				Done[item] = (((Object)(object)val != (Object)null || item is Material) ? val : NoPicture);
			}
		}

		private static Texture2D RenderTile(Transform model, Mesh mesh, Material material)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0021: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("MapMaker tile icon")
			{
				layer = 31,
				hideFlags = (HideFlags)61
			};
			try
			{
				val.transform.SetPositionAndRotation(At, model.rotation);
				val.transform.localScale = model.lossyScale;
				Bounds val2 = Show(val, mesh, (Material[])(object)new Material[1] { material });
				Quaternion look = Quaternion.Euler(90f, 0f, 0f);
				return Snap(new Vector3(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).max.y + 2f, ((Bounds)(ref val2)).center.z), look, Mathf.Min(((Bounds)(ref val2)).extents.x, ((Bounds)(ref val2)).extents.z) * 0.55f, 10f, 48, TileBack, "MapMaker tile " + ((Object)material).name);
			}
			finally
			{
				Object.DestroyImmediate((Object)(object)val);
			}
		}

		private static Texture2D RenderProp(PropCatalog.Prop prop)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			//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_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			GameObject source = prop.Source;
			HashSet<Renderer> hashSet = new HashSet<Renderer>();
			LODGroup[] componentsInChildren = source.GetComponentsInChildren<LODGroup>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				foreach (LOD item4 in componentsInChildren[i].GetLODs().Skip(1))
				{
					Renderer[] renderers = item4.renderers;
					foreach (Renderer val in renderers)
					{
						if ((Object)(object)val != (Object)null)
						{
							hashSet.Add(val);
						}
					}
				}
			}
			GameObject val2 = new GameObject("MapMaker prop icon")
			{
				hideFlags = (HideFlags)61
			};
			try
			{
				Bounds? val3 = null;
				foreach (MeshFilter item5 in MapBuilder.ShownMeshes(source))
				{
					MeshRenderer component = ((Component)item5).GetComponent<MeshRenderer>();
					if (!((Object)(object)component == (Object)null) && ((Renderer)component).enabled && !hashSet.Contains((Renderer)(object)component))
					{
						GameObject val4 = new GameObject(((Object)item5).name)
						{
							layer = 31,
							hideFlags = (HideFlags)61
						};
						val4.transform.SetParent(val2.transform, false);
						val4.transform.SetPositionAndRotation(At + ((Component)item5).transform.position - source.transform.position, ((Component)item5).transform.rotation);
						val4.transform.localScale = ((Component)item5).transform.lossyScale;
						Bounds val5 = Show(val4, item5.sharedMesh, ((Renderer)component).sharedMaterials);
						if (!val3.HasValue)
						{
							val3 = val5;
							continue;
						}
						Bounds value = val3.Value;
						((Bounds)(ref value)).Encapsulate(val5);
						val3 = value;
					}
				}
				if (!val3.HasValue)
				{
					return null;
				}
				(float length, float width, int axis) tuple = PropCatalog.Footprint(source);
				float item = tuple.length;
				float item2 = tuple.width;
				int item3 = tuple.axis;
				int num = PropCatalog.Front(prop, item, item2, item3);
				Quaternion val6 = Quaternion.Euler(35f, ((num >= 0) ? ((float)num + 180f) : 0f) + 30f, 0f);
				Bounds value2 = val3.Value;
				Quaternion val7 = Quaternion.Inverse(val6);
				Vector2 val8 = default(Vector2);
				((Vector2)(ref val8))..ctor(float.MaxValue, float.MaxValue);
				Vector2 val9 = default(Vector2);
				((Vector2)(ref val9))..ctor(float.MinValue, float.MinValue);
				for (int k = 0; k < 8; k++)
				{
					Vector3 val10 = val7 * Vector3.Scale(((Bounds)(ref value2)).extents, new Vector3((float)(((k & 1) != 0) ? 1 : (-1)), (float)(((k & 2) != 0) ? 1 : (-1)), (float)(((k & 4) != 0) ? 1 : (-1))));
					val8 = Vector2.Min(val8, Vector2.op_Implicit(val10));
					val9 = Vector2.Max(val9, Vector2.op_Implicit(val10));
				}
				Vector2 val11 = (val8 + val9) / 2f;
				float num2 = Mathf.Max(val9.x - val8.x, val9.y - val8.y) / 2f * 1.06f;
				Vector3 extents = ((Bounds)(ref value2)).extents;
				float num3 = ((Vector3)(ref extents)).magnitude + 1f;
				return Snap(((Bounds)(ref value2)).center + val6 * new Vector3(val11.x, val11.y, 0f - num3), val6, Mathf.Max(num2, 0.05f), num3 * 2f, 96, PropBack, "MapMaker prop " + prop.Key);
			}
			finally
			{
				Object.DestroyImmediate((Object)(object)val2);
			}
		}

		private static Bounds Show(GameObject go, Mesh mesh, Material[] materials)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			go.AddComponent<MeshFilter>().sharedMesh = mesh;
			MeshRenderer obj = go.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterials = materials;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)obj).receiveShadows = false;
			return ((Renderer)obj).bounds;
		}

		private static Texture2D Snap(Vector3 eye, Quaternion look, float half, float far, int size, Color background, string name)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0078: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			GameObject val = new GameObject("MapMaker icon camera")
			{
				hideFlags = (HideFlags)61
			};
			GameObject val2 = new GameObject("MapMaker icon light")
			{
				hideFlags = (HideFlags)61
			};
			RenderTexture temporary = RenderTexture.GetTemporary(size, size, 16, (RenderTextureFormat)0, (RenderTextureReadWrite)0);
			RenderTexture active = RenderTexture.active;
			try
			{
				Light obj = val2.AddComponent<Light>();
				obj.type = (LightType)1;
				obj.cullingMask = int.MinValue;
				obj.intensity = 1.1f;
				obj.shadows = (LightShadows)0;
				val2.transform.rotation = Quaternion.Euler(60f, 30f, 0f);
				Camera obj2 = val.AddComponent<Camera>();
				((Behaviour)obj2).enabled = false;
				obj2.cullingMask = int.MinValue;
				obj2.clearFlags = (CameraClearFlags)2;
				obj2.backgroundColor = background;
				obj2.orthographic = true;
				obj2.orthographicSize = half;
				obj2.nearClipPlane = 0.01f;
				obj2.farClipPlane = far;
				obj2.allowHDR = false;
				obj2.allowMSAA = false;
				val.transform.SetPositionAndRotation(eye, look);
				obj2.targetTexture = temporary;
				obj2.Render();
				RenderTexture.active = temporary;
				Texture2D val3 = new Texture2D(size, size, (TextureFormat)3, false)
				{
					name = name,
					hideFlags = (HideFlags)61
				};
				val3.ReadPixels(new Rect(0f, 0f, (float)size, (float)size), 0, 0);
				val3.Apply(false, true);
				return val3;
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				Object.DestroyImmediate((Object)(object)val);
				Object.DestroyImmediate((Object)(object)val2);
			}
		}
	}
	internal static class MapAdventure
	{
		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<int> FixedChance;

		private static readonly Random Rand = new Random();

		public static string Trial = null;

		public static readonly Queue<NodeType> TrialRooms = new Queue<NodeType>();

		public static string StartTrial(string map)
		{
			MapFile.Load(MapBuilder.PathOf(map));
			Trial = map;
			TrialRooms.Clear();
			TrialRooms.Enqueue((NodeType)7);
			TrialRooms.Enqueue((NodeType)4);
			TrialRooms.Enqueue((NodeType)0);
			Plugin.ModLog.LogInfo((object)("MapMaker: trial of '" + map + "': the next rooms are an Event, a Shop and a fight, each on this map."));
			return "trial of '" + map + "': Event, Shop, fight";
		}

		internal static List<NodeType> TrialCircle()
		{
			//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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(Trial) || TrialRooms.Count == 0)
			{
				return null;
			}
			NodeType val = TrialRooms.Dequeue();
			Plugin.ModLog.LogInfo((object)$"MapMaker: trial: the next circle offers only {val} ({TrialRooms.Count} trial rooms after it).");
			return new List<NodeType> { val };
		}

		internal static bool InPool(MapFile file)
		{
			if (file.adventure && file.party.Length != 0)
			{
				return file.enemies.Length != 0;
			}
			return false;
		}

		internal static List<MapFile> Candidates(string terrain)
		{
			List<MapFile> list = new List<MapFile>();
			foreach (string item in MapBuilder.Maps())
			{
				try
				{
					MapFile mapFile = MapFile.Load(MapBuilder.PathOf(item));
					if (InPool(mapFile) && string.Equals(mapFile.terrain, terrain, StringComparison.OrdinalIgnoreCase) && MapPool.IsOn(item))
					{
						list.Add(mapFile);
					}
				}
				catch (Exception ex)
				{
					Plugin.ModLog.LogWarning((object)("MapMaker: map '" + item + "' can't be read: " + ex.Message));
				}
			}
			return list;
		}

		internal static MapFile Pick(string terrain, NodeType room)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(Trial))
			{
				try
				{
					MapFile mapFile = MapFile.Load(MapBuilder.PathOf(Trial));
					Plugin.ModLog.LogInfo((object)$"MapMaker: trial map '{mapFile.name}' takes the next {room} room.");
					return mapFile;
				}
				catch (Exception ex)
				{
					Plugin.ModLog.LogWarning((object)("MapMaker: trial map '" + Trial + "' can't be read (" + ex.Message + "); the room stays as the game made it."));
					return null;
				}
			}
			List<MapFile> list = Candidates(terrain);
			if (list.Count == 0)
			{
				Plugin.ModLog.LogInfo((object)("MapMaker: no adventure map for " + terrain + " (\"adventure\": true, with party and enemy spots); the room stays as the game made it."));
				return null;
			}
			int num = Layouts(terrain);
			bool num2 = ((FixedChance.Value > 0) ? (Rand.Next(100) < FixedChance.Value) : (Rand.Next(list.Count + num) < list.Count));
			string arg = Odds(list.Count, num);
			if (!num2)
			{
				Plugin.ModLog.LogInfo((object)$"MapMaker: the roll ({arg}) keeps the next {room} room as the game made it.");
				return null;
			}
			MapFile mapFile2 = list[Rand.Next(list.Count)];
			Plugin.ModLog.LogInfo((object)$"MapMaker: the roll ({arg}) gives the next {room} room to '{mapFile2.name}'.");
			return mapFile2;
		}

		internal static int Layouts(string terrain)
		{
			return MapPool.LayoutsOn(terrain);
		}

		private static string Odds(int maps, int layouts)
		{
			if (FixedChance.Value <= 0)
			{
				return string.Format("{0} in {1}: {2} map{3}, {4} of the game's rooms", maps, maps + layouts, maps, (maps == 1) ? "" : "s", layouts);
			}
			return $"{FixedChance.Value}%";
		}

		public static string Odds(string terrain)
		{
			return Odds(Candidates(terrain).Count, Layouts(terrain));
		}

		private static string Vanilla(PortalManager portals, BattleInfo battle, BattleOverrideInfo over)
		{
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Invalid comparison between Unknown and I4
			NetworkingManager instance = NetworkingManager.Instance;
			if ((Object)(object)instance == (Object)null || !instance.IsServer || (Object)(object)GameLogic.instance == (Object)null)
			{
				return "";
			}
			if (MapBattle.Active)
			{
				return "a map battle is on";
			}
			if ((Object)(object)battle == (Object)null)
			{
				return "no battle info";
			}
			if (battle.IsFinalBattle)
			{
				return "the final battle";
			}
			if (!string.IsNullOrEmpty(battle.bossName) && ((battle.enemies != null && battle.enemies.Any((CharacterInfo e) => (Object)(object)e != (Object)null && ((Object)e).name == battle.bossName)) || (battle.guaranteedEnemies != null && battle.guaranteedEnemies.Any((CharacterInfo e) => (Object)(object)e != (Object)null && ((Object)e).name == battle.bossName)) || Mathf.Abs((float)battle.CalculatedBattlePointValue - battle.CalculatedBattlePointValueWithoutBoss) > 0.5f))
			{
				return "a boss battle";
			}
			if (battle.isTownBattle)
			{
				return "a town battle";
			}
			if ((Object)(object)battle.nextBattle != (Object)null)
			{
				return "a chained battle";
			}
			if ((battle.battleOverrideInfo != null && battle.battleOverrideInfo.ForceMap) || (over != null && over.ForceMap))
			{
				return "the battle brings its own map";
			}
			if ((Object)(object)portals.CurrentIsland == (Object)null || portals.OpeningIsland)
			{
				return "no island";
			}
			if ((Object)(object)GUIManager.instance == (Object)null || (int)GUIManager.instance.CurrentGuiState == 2)
			{
				return "a battle is on";
			}
			return MapNet.CannotShare();
		}

		internal static bool OnBattleNode(PortalManager portals, Vector3 cellPos, BattleInfo battle, BattleOverrideInfo over)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			HexCellManager val = (((Object)(object)portals.CurrentIsland != (Object)null) ? portals.CurrentIsland.HexCellManager : null);
			if (!MapRoom.Holds(((Object)(object)val != (Object)null) ? val.GetHexCellFromPos(cellPos) : null))
			{
				return true;
			}
			string text = Vanilla(portals, battle, over);
			if (text != null)
			{
				if (text.Length > 0)
				{
					Plugin.ModLog.LogInfo((object)("MapMaker: this encounter on '" + MapBuilder.Current.name + "' is fought the game's way: " + text + "."));
				}
				return true;
			}
			try
			{
				MapBattle.BeginAdventure(MapBuilder.Current);
			}
			catch (Exception ex)
			{
				Plugin.ModLog.LogWarning((object)("MapMaker: '" + MapBuilder.Current.name + "' can't take this encounter (" + ex.Message + "); the game places everyone."));
				MapBattle.Abandon();
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PortalManager), "BattleNodeActivate")]
	internal static class MapAdventurePatch
	{
		private static bool Prefix(PortalManager __instance, Vector3 cellPos, BattleInfo battleInfo, BattleOverrideInfo battleOverrideInfo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return MapAdventure.OnBattleNode(__instance, cellPos, battleInfo, battleOverrideInfo);
			}
			catch (Exception arg)
			{
				Plugin.ModLog.LogError((object)$"MapMaker: adventure map failed; the encounter stays on the island: {arg}");
				MapBattle.Abandon();
				return true;
			}
		}

		private static void Postfix()
		{
			MapBattle.AfterBattleNode();
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class MapTrialCirclePatch
	{
		private static void Postfix(ref List<NodeType> __result, ref PartyEvent forcedEvent)
		{
			try
			{
				if (__result != null && !__result.Contains((NodeType)5))
				{
					List<NodeType> list = MapAdventure.TrialCircle();
					if (list != null)
					{
						__result = list;
						forcedEvent = null;
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.ModLog.LogError((object)$"MapMaker: trial circle failed; the game's options stay: {arg}");
			}
		}
	}
	public static class MapBattle
	{
		internal static bool Armed;

		internal static bool QuietSetup;

		private static readonly Dictionary<Character, HexCell> ReturnTo = new Dictionary<Character, HexCell>();

		private static readonly List<Character> SetAside = new List<Character>();

		private static Character _battleObject;

		private static bool _seenInBattle;

		private static float _overSince = -1f;

		private static object _island;

		private static bool _eventSwapped;

		private static HexCell _previousEvent;

		private static Character _movedEncounter;

		private static HexCell _movedFrom;

		private static int _reservedSpot = -1;

		private static readonly Dictionary<Character, HexCell> HeroSpots = new Dictionary<Character, HexCell>();

		private static readonly HashSet<HexCell> SpotsTaken = new HashSet<HexCell>();

		private static int _enemiesSpawned;

		public static bool Active { get; private set; }

		public static string Status { get; private set; } = "";

		internal static bool Adventure { get; private set; }

		public static string CannotStart()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Invalid comparison between Unknown and I4
			NetworkingManager instance = NetworkingManager.Instance;
			if ((Object)(object)GameLogic.instance == (Object)null || ((instance == null) ? null : ((Observer<Root>)(object)instance.NetworkManager)?.Root) == null)
			{
				return "Load a game first.";
			}
			PortalManager instance2 = PortalManager.Instance;
			if ((Object)(object)((instance2 != null) ? instance2.CurrentIsland : null) == (Object)null || PortalManager.Instance.OpeningIsland)
			{
				return "Go on an adventure first: maps are fought next to a quest island.";
			}
			if (Active || (int)GUIManager.instance.CurrentGuiState == 2)
			{
				return "A battle is already on.";
			}
			if ((int)GUIManager.instance.CurrentGuiState != 3)
			{
				return "Only while exploring an island.";
			}
			if (!instance.IsServer)
			{
				return "Only the host can start a map battle.";
			}
			if (MapRoom.Placed)
			{
				return MapRoom.Busy + ".";
			}
			return MapNet.CannotShare();
		}

		public static IEnumerator Fight(string map = null, bool skipPlacement = false, bool hard = false)
		{
			string text = CannotStart();
			if (text != null)
			{
				throw new InvalidOperationException(text);
			}
			if (map != null)
			{
				Status = "Building '" + map + "'...";
				IEnumerator share = MapNet.BuildEverywhere(MapFile.Load(MapBuilder.PathOf(map)));
				while (share.MoveNext())
				{
					yield return share.Current;
				}
			}
			if (!MapBuilder.Ready)
			{
				throw new InvalidOperationException("no map built");
			}
			MapFile current = MapBuilder.Current;
			if (current.enemies.Length == 0)
			{
				throw new InvalidOperationException("map '" + current.name + "' has no enemy spots");
			}
			GameLogic instance = GameLogic.instance;
			Root root = ((Observer<Root>)(object)NetworkingManager.Instance.NetworkManager).Root;
			BattleInfo val = GlobalSettingsManager.instance.globalSettings.testBattle ?? throw new InvalidOperationException("GlobalSettings.testBattle is null");
			val.enemies = RollEnemies(current, hard);
			val.guaranteedEnemies = new List<CharacterInfo>();
			val.dontFillOutBattlePoints = true;
			val.enemyMods = new Dictionary<int, List<EnemyMod>>();
			instance.CurrentBattle = val;
			instance.CurrentBattleObjectEnemyIndex = -1;
			ReturnTo.Clear();
			foreach (Character partyCharacter in NetworkingManager.Instance.PartyCharacters)
			{
				if (partyCharacter != null && (Object)(object)partyCharacter.Cell != (Object)null && MapBuilder.Where(partyCharacter) == null)
				{
					ReturnTo[partyCharacter] = partyCharacter.Cell;
				}
			}
			_island = PortalManager.Instance.CurrentIsland;
			PortalManager portals = PortalManager.Instance;
			HexCell previousEvent = portals.currentEventHex;
			portals.currentEventHex = PartyCentre(current) ?? MapBuilder.Cell(0, 0) ?? MapBuilder.Cells.First((HexCell c) => c.IsWalkable);
			_battleObject = root.BattleObjectCharacter;
			root.BattleObjectCharacter = null;
			SetAside.Clear();
			SetAsideStrays(root);
			Armed = true;
			Active = true;
			_seenInBattle = false;
			_overSince = -1f;
			Status = "Fighting on '" + current.name + "'.";
			try
			{
				root.SendOpenBattle();
				IEnumerator share = Follow(current, skipPlacement);
				while (share.MoveNext())
				{
					yield return share.Current;
				}
			}
			finally
			{
				Armed = false;
				portals.currentEventHex = previousEvent;
			}
		}

		private static IEnumerator Follow(MapFile file, bool skipPlacement)
		{
			GameLogic logic = GameLogic.instance;
			Root root = ((Observer<Root>)(object)NetworkingManager.Instance.NetworkManager).Root;
			float until = Time.realtimeSinceStartup + 60f;
			while (Armed || (!logic.CurrentlyPlacingCharacters && !logic.GameStarted))
			{
				if (!Active)
				{
					yield break;
				}
				if (Time.realtimeSinceStartup > until)
				{
					if (!Adventure)
					{
						throw new TimeoutException("the placement phase didn't begin");
					}
					Plugin.ModLog.LogWarning((object)("MapMaker: the battle on '" + file.name + "' didn't begin in 60 s; back to the island."));
					Finish();
					yield break;
				}
				yield return null;
			}
			SetAsideStrays(root);
			List<string> list = PlaceSpawns(root, file, party: true);
			Plugin.ModLog.LogInfo((object)("MapMaker: battle on '" + file.name + "': " + string.Join("; ", Who())));
			if (list.Count > 0)
			{
				Plugin.ModLog.LogWarning((object)("MapMaker: moved after they appeared: " + string.Join("; ", list)));
			}
			if (skipPlacement)
			{
				foreach (Character item in NetworkingManager.Instance.MyPartyCharacters.ToList())
				{
					if ((Object)(object)((item != null) ? item.PlayerMovement : null) != (Object)null && !item.EndedTurn)
					{
						item.PlayerMovement.EndTurn();
					}
				}
			}
			until = Time.realtimeSinceStartup + 900f;
			while ((int)GUIManager.instance.CurrentGuiState != 2 || !logic.GameStarted)
			{
				if (!Active)
				{
					yield break;
				}
				if (Time.realtimeSinceStartup > until)
				{
					if (!Adventure)
					{
						throw new TimeoutException("the battle didn't start");
					}
					yield break;
				}
				yield return null;
			}
			List<string> list2 = PlaceSpawns(root, file, party: false);
			if (list2.Count > 0)
			{
				Plugin.ModLog.LogInfo((object)("MapMaker: placed late: " + string.Join("; ", list2)));
			}
		}

		internal static void BeginAdventure(MapFile file)
		{
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			if (!MapBuilder.Ready || MapBuilder.Current != file)
			{
				throw new InvalidOperationException("the map isn't built");
			}
			if (file.party.Length == 0 || file.enemies.Length == 0)
			{
				throw new InvalidOperationException("the map needs party and enemy spots");
			}
			NetworkingManager instance = NetworkingManager.Instance;
			Root root = ((Observer<Root>)(object)instance.NetworkManager).Root;
			GameLogic instance2 = GameLogic.instance;
			PortalManager instance3 = PortalManager.Instance;
			HeroSpots.Clear();
			SpotsTaken.Clear();
			ReturnTo.Clear();
			if (!MapRoom.Placed)
			{
				foreach (Character partyCharacter in instance.PartyCharacters)
				{
					if (partyCharacter != null && (Object)(object)partyCharacter.Cell != (Object)null && MapBuilder.Where(partyCharacter) == null)
					{
						ReturnTo[partyCharacter] = partyCharacter.Cell;
					}
				}
			}
			_island = instance3.CurrentIsland;
			_reservedSpot = -1;
			_movedEncounter = null;
			Character battleObjectCharacter = root.BattleObjectCharacter;
			int num;
			if (battleObjectCharacter != null)
			{
				(int, int)? tuple = MapBuilder.QR(battleObjectCharacter);
				if (tuple.HasValue)
				{
					(int, int) valueOrDefault = tuple.GetValueOrDefault();
					int bq = valueOrDefault.Item1;
					int br = valueOrDefault.Item2;
					num = Array.FindIndex(file.enemies, (Spot e) => e.q == bq && e.r == br);
					goto IL_0156;
				}
			}
			num = -1;
			goto IL_0156;
			IL_0156:
			int num2 = num;
			if (battleObjectCharacter != null && !battleObjectCharacter.IsDead && num2 >= 0)
			{
				SpotsTaken.Add(battleObjectCharacter.Cell);
				_reservedSpot = num2;
			}
			else if (battleObjectCharacter != null && !battleObjectCharacter.IsDead)
			{
				int num3 = Mathf.Clamp(instance2.CurrentBattleObjectEnemyIndex, 0, file.enemies.Length - 1);
				HexCell val = Claim(file.enemies[num3].q, file.enemies[num3].r, battleObjectCharacter) ?? throw new InvalidOperationException("no free enemy spot");
				_movedEncounter = battleObjectCharacter;
				_movedFrom = battleObjectCharacter.Cell;
				battleObjectCharacter.WarpToDestination(((Component)val).transform.position, false, false, false);
				if (MapBuilder.Where(battleObjectCharacter) == null)
				{
					throw new InvalidOperationException("the encounter's enemy didn't reach the map");
				}
				_reservedSpot = num3;
			}
			else
			{
				_previousEvent = instance3.currentEventHex;
				instance3.currentEventHex = PartyCentre(file) ?? MapBuilder.Cells.First((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable);
				_eventSwapped = true;
			}
			SetAside.Clear();
			SetAsideStrays(root);
			Adventure = true;
			Armed = true;
			Active = true;
			_seenInBattle = false;
			_overSince = -1f;
			Status = "Fighting on '" + file.name + "'.";
			Plugin.ModLog.LogInfo((object)("MapMaker: adventure battle on '" + file.name + "' (" + file.terrain + "; " + ((battleObjectCharacter == null) ? "no enemy stood on the island" : ((num2 >= 0) ? $"{battleObjectCharacter.CharacterName} waits on enemy spot {num2}" : $"{battleObjectCharacter.CharacterName} moved to enemy spot {_reservedSpot}")) + ")."));
			Plugin.Run(Follow(file, skipPlacement: false), "adventure battle", quiet: true);
		}

		internal static void Abandon()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (_movedEncounter != null && (Object)(object)_movedFrom != (Object)null && MapBuilder.Where(_movedEncounter) != null)
			{
				_movedEncounter.WarpToDestination(((Component)_movedFrom).transform.position, false, false, false);
			}
			_movedEncounter = null;
			_movedFrom = null;
			AfterBattleNode();
			foreach (Character item in SetAside)
			{
				if (item != null && !item.IsDead)
				{
					item.SelectedForBattle = true;
				}
			}
			SetAside.Clear();
			ReturnTo.Clear();
			Adventure = false;
			Armed = false;
			Active = false;
			_reservedSpot = -1;
			if (!MapRoom.Placed)
			{
				MapNet.RemoveEverywhere();
			}
		}

		internal static void AfterBattleNode()
		{
			if (_eventSwapped)
			{
				_eventSwapped = false;
				if ((Object)(object)PortalManager.Instance != (Object)null)
				{
					PortalManager.Instance.currentEventHex = _previousEvent;
				}
				_previousEvent = null;
			}
		}

		internal static List<HexCell> ObjectCells()
		{
			MapFile current = MapBuilder.Current;
			HashSet<HexCell> spots = new HashSet<HexCell>(from c in current.party.Select((Spot s) => MapBuilder.Cell(s.q, s.r)).Concat(current.enemies.Select((Spot s) => MapBuilder.Cell(s.q, s.r))).Concat((current.lesserEvents ?? new Spot[0]).Select((Spot s) => MapBuilder.Cell(s.q, s.r)))
				where (Object)(object)c != (Object)null
				select c);
			return MapBuilder.Cells.Where((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable && c.IsEmpty && !spots.Contains(c)).ToList();
		}

		internal static HexCell PartyCentre(MapFile file)
		{
			if (file.party.Length == 0)
			{
				return null;
			}
			float q = (float)file.party.Average((Spot s) => s.q);
			float r = (float)file.party.Average((Spot s) => s.r);
			return MapBuilder.Cells.Where((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable).OrderBy(delegate(HexCell c)
			{
				(int, int) value = MapBuilder.QR(c).Value;
				return Mathf.Abs((float)value.Item1 - q) + Mathf.Abs((float)value.Item2 - r) + Mathf.Abs((float)(value.Item1 + value.Item2) - q - r);
			}).FirstOrDefault();
		}

		internal static HexCell NextEnemyHex()
		{
			MapFile current = MapBuilder.Current;
			if (current == null)
			{
				return null;
			}
			int num = _enemiesSpawned++;
			if (num == _reservedSpot)
			{
				num = _enemiesSpawned++;
			}
			if (current.enemies.Length == 0)
			{
				return null;
			}
			Spot spot = current.enemies[num % current.enemies.Length];
			return Claim(spot.q, spot.r, null);
		}

		internal static HexCell HeroHex(Character hero, Vector3 pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			MapFile current = MapBuilder.Current;
			GameLogic instance = GameLogic.instance;
			if (current == null || current.party.Length == 0 || hero == null || hero.TeamIndex != 0 || HeroSpots.ContainsKey(hero))
			{
				return null;
			}
			if ((Object)(object)instance == (Object)null || instance.CurrentlyPlacingCharacters || instance.GameStarted)
			{
				return null;
			}
			if (!MapBuilder.Cells.Any(delegate(HexCell c)
			{
				//IL_000f: 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)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)c != (Object)null)
				{
					Vector3 val2 = ((Component)c).transform.position - pos;
					return ((Vector3)(ref val2)).sqrMagnitude < 0.01f;
				}
				return false;
			}))
			{
				return null;
			}
			Spot spot = current.party[Mathf.Min(HeroSpots.Count, current.party.Length - 1)];
			return HeroSpots[hero] = Claim(spot.q, spot.r, hero);
		}

		private static HexCell Claim(int q, int r, Character who)
		{
			HexCell val = MapBuilder.Cell(q, r);
			if (!Free(val))
			{
				val = MapBuilder.Cells.Where(Free).OrderBy(delegate(HexCell c)
				{
					(int, int) value = MapBuilder.QR(c).Value;
					return MapBuilder.Distance(value.Item1, value.Item2, q, r);
				}).FirstOrDefault();
			}
			if ((Object)(object)val != (Object)null)
			{
				SpotsTaken.Add(val);
			}
			return val;
			bool Free(HexCell c)
			{
				if ((Object)(object)c != (Object)null && c.IsValid && c.IsWalkable && !SpotsTaken.Contains(c))
				{
					if (c.Player != null)
					{
						return c.Player == who;
					}
					return true;
				}
				return false;
			}
		}

		private static List<string> PlaceSpawns(Root root, MapFile map, bool party)
		{
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			List<Character> source = root.CharactersInBattle.Where((Character c) => c != null && !c.IsDead && IsFighter(c) && MapBuilder.Where(c) != null).ToList();
			List<Character> who = source.Where((Character c) => c.TeamIndex == 0).ToList();
			List<Character> who2 = source.Where((Character c) => c.TeamIndex != 0).ToList();
			List<(Character, HexCell)> list = new List<(Character, HexCell)>();
			HashSet<HexCell> taken = new HashSet<HexCell>();
			List<(int, int)> spots = map.party.Select((Spot s) => (q: s.q, r: s.r)).ToList();
			List<(int, int)> spots2 = map.enemies.Select((Spot s) => (q: s.q, r: s.r)).ToList();
			KeepOnSpots(who, spots, taken);
			KeepOnSpots(who2, spots2, taken);
			if (party)
			{
				Assign(who, spots, list, taken);
			}
			Assign(who2, spots2, list, taken);
			List<string> list2 = new List<string>();
			foreach (var item in list)
			{
				var (val, to) = item;
				if (to.Player != null && to.Player != val && list.All<(Character, HexCell)>(((Character who, HexCell to) m) => m.who != to.Player))
				{
					HexCell val2 = ((IEnumerable<HexCell>)MapBuilder.Cells).FirstOrDefault((Func<HexCell, bool>)((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable && c.IsEmpty && !taken.Contains(c)));
					if ((Object)(object)val2 != (Object)null)
					{
						taken.Add(val2);
						to.Player.WarpToDestination(((Component)val2).transform.position, false, false, false);
					}
				}
				val.WarpToDestination(((Component)to).transform.position, false, false, false);
				list2.Add($"{val.CharacterName} (team {val.TeamIndex}) at {MapBuilder.Where(to)}");
			}
			return list2;
		}

		private static void KeepOnSpots(List<Character> who, List<(int q, int r)> spots, HashSet<HexCell> taken)
		{
			foreach (Character item in who.ToList())
			{
				(int, int)? tuple = MapBuilder.QR(item);
				if (!tuple.HasValue)
				{
					continue;
				}
				var (q, r) = tuple.GetValueOrDefault();
				if (spots.Any(((int q, int r) s) => s.q == q && s.r == r))
				{
					who.Remove(item);
					spots.RemoveAll(((int q, int r) s) => s.q == q && s.r == r);
					taken.Add(item.Cell);
				}
			}
		}

		private static void Assign(List<Character> who, List<(int q, int r)> spots, List<(Character, HexCell)> moves, HashSet<HexCell> taken)
		{
			List<Character> list = who.ToList();
			foreach (var spot in spots)
			{
				HexCell val = MapBuilder.Cell(spot.q, spot.r);
				if (!((Object)(object)val == (Object)null) && val.IsValid && val.IsWalkable && !taken.Contains(val) && list.Count != 0)
				{
					Character val2 = list[0];
					list.Remove(val2);
					taken.Add(val);
					moves.Add((val2, val));
				}
			}
			if (list.Count == 0 || spots.Count == 0)
			{
				return;
			}
			foreach (Character c in list)
			{
				HexCell val3 = (from x in MapBuilder.Cells
					where (Object)(object)x != (Object)null && x.IsValid && x.IsWalkable && !taken.Contains(x) && (x.IsEmpty || x.Player == c)
					orderby spots.Min(delegate((int q, int r) s)
					{
						(int, int) value = MapBuilder.QR(x).Value;
						return MapBuilder.Distance(value.Item1, value.Item2, s.q, s.r);
					})
					select x).FirstOrDefault();
				if ((Object)(object)val3 == (Object)null)
				{
					break;
				}
				taken.Add(val3);
				moves.Add((c, val3));
			}
		}

		private static void SetAsideStrays(Root root)
		{
			foreach (Character item in root.CharactersInBattle.ToList())
			{
				if (item != null && item.TeamIndex != 0 && !item.IsDead && IsFighter(item) && MapBuilder.Where(item) == null)
				{
					item.SelectedForBattle = false;
					if (!SetAside.Contains(item))
					{
						SetAside.Add(item);
					}
				}
			}
		}

		internal static void Tick()
		{
			//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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Invalid comparison between Unknown and I4
			if (!Active)
			{
				return;
			}
			PortalManager instance = PortalManager.Instance;
			Island val = ((instance != null) ? instance.CurrentIsland : null);
			if ((Object)(object)val == (Object)null || val != _island)
			{
				Plugin.ModLog.LogInfo((object)"MapMaker: the island changed during a map battle; the map is gone with it.");
				Finish(warp: false);
				return;
			}
			GUIState currentGuiState = GUIManager.instance.CurrentGuiState;
			if ((int)currentGuiState == 2)
			{
				_seenInBattle = true;
				_overSince = -1f;
			}
			else if (_seenInBattle && !Armed)
			{
				bool flag = PostBattleManager.IsNotNullAndIsActive || ((Object)(object)BattleFailureWindow.instance != (Object)null && (Object)(object)BattleFailureWindow.instance.Content != (Object)null && BattleFailureWindow.instance.Content.activeInHierarchy);
				if ((int)currentGuiState != 3 || flag)
				{
					_overSince = -1f;
				}
				else if (_overSince < 0f)
				{
					_overSince = Time.realtimeSinceStartup;
				}
				else if (!(Time.realtimeSinceStartup - _overSince < 1f))
				{
					Finish();
				}
			}
		}

		public static string Finish(bool warp = true)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			if (warp)
			{
				HashSet<HexCell> hashSet = new HashSet<HexCell>();
				foreach (KeyValuePair<Character, HexCell> item in ReturnTo)
				{
					Character key = item.Key;
					if (key == null || MapBuilder.Where(key) == null)
					{
						continue;
					}
					HexCell val = item.Value;
					if (!((Object)(object)val == (Object)null))
					{
						if ((val.Player != null && val.Player != key) || hashSet.Contains(val))
						{
							val = val.ValidEmptyNeighbor ?? val;
						}
						hashSet.Add(val);
						key.WarpToDestination(((Component)val).transform.position, false, false, false);
						list.Add(key.CharacterName);
					}
				}
			}
			foreach (Character item2 in SetAside)
			{
				if (item2 != null && !item2.IsDead)
				{
					item2.SelectedForBattle = true;
				}
			}
			NetworkingManager instance = NetworkingManager.Instance;
			Root val2 = ((instance == null) ? null : ((Observer<Root>)(object)instance.NetworkManager)?.Root);
			if (val2 != null && _battleObject != null && val2.BattleObjectCharacter == null)
			{
				val2.BattleObjectCharacter = _battleObject;
			}
			SetAside.Clear();
			ReturnTo.Clear();
			_battleObject = null;
			_movedEncounter = null;
			_movedFrom = null;
			_reservedSpot = -1;
			AfterBattleNode();
			Adventure = false;
			Active = false;
			Armed = false;
			if (!MapRoom.Placed)
			{
				MapNet.RemoveEverywhere(warp);
				if (warp)
				{
					CameraController instance2 = CameraController.instance;
					if (instance2 != null)
					{
						instance2.SnapToCurrentlySelectedCharacter();
					}
				}
			}
			Status = ((list.Count > 0) ? ("Back on the island: " + string.Join(", ", list) + ".") : "Map battle over.");
			Plugin.ModLog.LogInfo((object)("MapMaker: " + Status));
			return Status;
		}

		private static bool IsFighter(Character c)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			return (int)c.CharacterType == 0;
		}

		public static List<CharacterInfo> RollEnemies(MapFile file, bool hard = false)
		{
			//IL_0028: 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_0029: 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_0035: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			GlobalSettings globalSettings = GlobalSettingsManager.instance.globalSettings;
			Game instance = Game.Instance;
			TerrainType result;
			TerrainType val = (Enum.TryParse<TerrainType>(file.terrain, out result) ? result : instance.CurrentRoomTerrainType);
			int currentActiveGameLevel = instance.CurrentActiveGameLevel;
			List<EnemyGroup> possibleEnemyGroups = globalSettings.GetPossibleEnemyGroups(val, instance.CurrentRoomTimeOfDay, currentActiveGameLevel);
			if (possibleEnemyGroups == null || possibleEnemyGroups.Count == 0)
			{
				throw new InvalidOperationException($"no enemy factions for {val}");
			}
			int generatedBattlePointTotal = globalSettings.GeneratedBattlePointTotal;
			int num = (int)((float)(generatedBattlePointTotal + (hard ? globalSettings.HardBattlePointAdder : 0)) + (float)(generatedBattlePointTotal * GameLogic.instance.CurrentDifficulty.AdditionalBattlePointsPerc) / 100f) + Random.Range(-globalSettings.GeneratedBattlePointVariance, globalSettings.GeneratedBattlePointVariance + 1) + Math.Max(0, NetworkingManager.Instance.PartyCharacters.Count - 1) * globalSettings.AdditionalBattlePointsPerPlayer;
			List<EnemyGroup> list = possibleEnemyGroups.OrderBy((EnemyGroup _) => Random.value).ToList();
			bool flag = list.Count > 1 && Random.value < globalSettings.MixedEnemyGroupBattleChance / 100f;
			List<CharacterInfo> list2 = new List<CharacterInfo>();
			foreach (EnemyGroup item in list.Take((!flag) ? 1 : 2))
			{
				list2.AddRange(GameLogic.GetEnemiesByGroupAndPoints(new List<EnemyGroup> { item }, (float)(flag ? (num / 2) : num), currentActiveGameLevel));
			}
			if (list2.Count == 0)
			{
				throw new InvalidOperationException($"no enemies drawn for {val} at level {currentActiveGameLevel}");
			}
			Plugin.ModLog.LogInfo((object)(string.Format("MapMaker: test fight: {0} island fight of {1}, {2}, ", hard ? "a hard" : "an", val, string.Join(" + ", list.Take((!flag) ? 1 : 2))) + string.Format("{0} points: {1} enemies on {2} spots ({3})", num, list2.Count, file.enemies.Length, string.Join(", ", list2.Select((CharacterInfo e) => ((Object)e).name)))));
			return list2;
		}

		public static List<string> Who()
		{
			NetworkingManager instance = NetworkingManager.Instance;
			Root val = ((instance == null) ? null : ((Observer<Root>)(object)instance.NetworkManager)?.Root);
			if (val == null)
			{
				return new List<string>();
			}
			return (from c in (IEnumerable<Character>)val.AllCharacters
				where c != null && MapBuilder.Where(c) != null
				select string.Format("{0} team {1} at {2}{3}", c.CharacterName, c.TeamIndex, MapBuilder.Where(c), c.IsDead ? " (dead)" : "")).ToList();
		}

		internal static IEnumerator Quietly(IEnumerator setup)
		{
			HeroSpots.Clear();
			SpotsTaken.Clear();
			_enemiesSpawned = 0;
			QuietSetup = true;
			try
			{
				while (setup.MoveNext())
				{
					yield return setup.Current;
				}
			}
			finally
			{
				QuietSetup = false;
			}
		}
	}
	[HarmonyPatch(typeof(GameLogic), "StartCurrentBattle")]
	internal static class MapStartBattlePatch
	{
		private static readonly FieldRef<GameLogic, Coroutine> SetupCoroutine = AccessTools.FieldRefAccess<GameLogic, Coroutine>("setupGameCoroutine");

		private static bool Prefix(GameLogic __instance)
		{
			if ((!MapBattle.Armed && !MapBattle.Active) || !MapBuilder.Ready)
			{
				return true;
			}
			MapBattle.Armed = false;
			List<HexCell> list = MapBuilder.Cells.Where((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable).ToList();
			if (list.Count == 0)
			{
				Plugin.ModLog.LogError((object)"MapMaker: no walkable map hex; the battle runs on the island instead.");
				return true;
			}
			SetupCoroutine.Invoke(__instance) = ((MonoBehaviour)__instance).StartCoroutine(MapBattle.Quietly(__instance.SetupGame(__instance.CurrentBattle, list)));
			return false;
		}
	}
	[HarmonyPatch(typeof(GameLogic), "GetSpawnPoint")]
	internal static class MapEnemySpotPatch
	{
		private static void Postfix(ref HexCell __result)
		{
			if (MapBattle.QuietSetup && MapBuilder.Ready)
			{
				__result = MapBattle.NextEnemyHex() ?? __result;
			}
		}
	}
	[HarmonyPatch(typeof(Character), "WarpToDestination")]
	internal static class MapHeroSpotPatch
	{
		private static void Prefix(Character __instance, ref Vector3 pos)
		{
			//IL_0011: 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)
			if (MapBattle.QuietSetup && MapBuilder.Ready)
			{
				HexCell val = MapBattle.HeroHex(__instance, pos);
				if ((Object)(object)val != (Object)null)
				{
					pos = ((Component)val).transform.position;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Root), "StartSpawnPlacementForAll")]
	internal static class MapPlacementOriginPatch
	{
		private static void Prefix(Root __instance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (MapBattle.Active && MapBuilder.Ready)
			{
				HexCell val = MapBattle.PartyCentre(MapBuilder.Current);
				if ((Object)(object)val != (Object)null)
				{
					__instance.SpawnPlacementOrigin = ((Component)val).transform.position;
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class MapNoRandomObjectsPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(GameLogic), "SpawnShrines", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameLogic), "SpawnDestructables", (Type[])null, (Type[])null);
		}

		private static bool Prefix(ref IEnumerator __result, ref List<HexCell> possibleSpawns)
		{
			if (!MapBattle.QuietSetup)
			{
				return true;
			}
			if (MapBattle.Adventure && MapBuilder.Ready)
			{
				possibleSpawns = MapBattle.ObjectCells();
				return true;
			}
			__result = Enumerable.Empty<object>().GetEnumerator();
			return false;
		}
	}
	public static class MapBuilder
	{
		private sealed class HexView
		{
			public HexEntry Entry;

			public HexCell Cell;

			public GameObject Side;

			public float Height;
		}

		private sealed class PropView
		{
			public PropEntry Entry;

			public GameObject Go;
		}

		private const float Margin = 40f;

		private const float DefaultDepth = 1.2f;

		public static readonly List<HexCell> Cells = new List<HexCell>();

		private static readonly Dictionary<long, HexView> Views = new Dictionary<long, HexView>();

		private static readonly List<PropView> PropViews = new List<PropView>();

		private static HexCoordinates _origin;

		private static HexCell _anchor;

		private static Vector3 _anchorPos;

		private static HexCalculator _calc;

		private static PropCatalog.Terrain _terrain;

		private static Material _defaultTile;

		private static GameObject _decor;

		private static GameObject _staging;

		private static float _bottom;

		private static float _lift;

		private const float BlockedShade = 0.45f;

		private static readonly Dictionary<Material, Material> _blocked = new Dictionary<Material, Material>();

		private static readonly string[] OverlayObjects = new string[3] { "overlay", "overlayBorderObj", "_AreaIndicator" };

		private static readonly string[] OverlayRefs = new string[5] { "overlayHighlight", "overlayBorderHighlight", "overlayBorderObjMaterial", "_AreaIndicatorRenderer", "overlayLight" };

		private const float CarryLift = 0.35f;

		private static GameObject _carried;

		private const float TrunkWidth = 1.4f;

		private const float WideBlocker = 2.2f;

		private static readonly string[] Plants = new string[4] { "Tree", "Bush", "Hedge", "Plant" };

		public static MapFile Current { get; private set; }

		public static HexCellManager Grid { get; private set; }

		public static (int x, int y) Anchor
		{
			get
			{
				if (!((Object)(object)_anchor != (Object)null))
				{
					return (x: 0, y: 0);
				}
				return (x: ((HexCoordinates)(ref _anchor.Coordinates)).X, y: ((HexCoordinates)(ref _anchor.Coordinates)).Y);
			}
		}

		public static (int x, int y) Origin => (x: ((HexCoordinates)(ref _origin)).X, y: ((HexCoordinates)(ref _origin)).Y);

		internal static GameObject Decor => _decor;

		internal static float Lift => _lift;

		public static bool Ready
		{
			get
			{
				if ((Object)(object)Grid != (Object)null && Cells.Count > 0)
				{
					return (Object)(object)Cells[0] != (Object)null;
				}
				return false;
			}
		}

		public static string MapsFolder => Path.Combine(Plugin.Folder, "maps");

		internal static Material DefaultTile => _defaultTile;

		public static List<string> Maps()
		{
			if (!Directory.Exists(MapsFolder))
			{
				return new List<string>();
			}
			return (from n in Directory.GetFiles(MapsFolder, "*.json").Select(Path.GetFileNameWithoutExtension)
				orderby n
				select n).ToList();
		}

		public static string PathOf(string map)
		{
			if (!File.Exists(map))
			{
				return Path.Combine(MapsFolder, map + ".json");
			}
			return map;
		}

		public static string Build(string map)
		{
			string path = PathOf(map);
			if (!File.Exists(path))
			{
				throw new FileNotFoundException("no map '" + map + "' (maps: " + string.Join(", ", Maps()) + ")");
			}
			return Build(MapFile.Load(path));
		}

		public static HexCellManager GridHere()
		{
			Island val = (((Object)(object)PortalManager.Instance != (Object)null) ? PortalManager.Instance.CurrentIsland : null);
			if (!((Object)(object)val != (Object)null))
			{
				return HexCellManager.instance;
			}
			return val.HexCellManager;
		}

		public static string Build(MapFile file, (int x, int y)? anchor = null, (int x, int y)? origin = null, float lift = 0f, bool room = false)
		{
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Expected O, but got Unknown
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Expected O, but got Unknown
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			Island val = (((Object)(object)PortalManager.Instance != (Object)null) ? PortalManager.Instance.CurrentIsland : null);
			HexCellManager val2 = GridHere();
			if ((Object)(object)val2 == (Object)null)
			{
				throw new InvalidOperationException("no hex grid: a map hangs off the town's or a quest island's grid");
			}
			if (!room && MapRoom.Placed)
			{
				throw new InvalidOperationException(MapRoom.Busy);
			}
			Discard();
			PropCatalog.Terrain terrain = PropCatalog.Of(file);
			Dictionary<(int, int), HexEntry> dictionary = file.Layout();
			if (dictionary.Count == 0)
			{
				throw new InvalidOperationException("map '" + file.name + "' has no hexes");
			}
			HexCell anchor2;
			if (anchor.HasValue)
			{
				(int, int) valueOrDefault = anchor.GetValueOrDefault();
				int ax = valueOrDefault.Item1;
				int ay = valueOrDefault.Item2;
				anchor2 = ((IEnumerable<HexCell>)val2.FastCells).FirstOrDefault((Func<HexCell, bool>)((HexCell c) => (Object)(object)c != (Object)null && ((HexCoordinates)(ref c.Coordinates)).X == ax && ((HexCoordinates)(ref c.Coordinates)).Y == ay));
			}
			else
			{
				anchor2 = PickAnchor(val2);
			}
			_anchor = anchor2;
			if ((Object)(object)_anchor == (Object)null)
			{
				throw new InvalidOperationException(anchor.HasValue ? $"no island hex at {anchor} to copy (is everyone on the same island?)" : "no flat walkable hex here to copy");
			}
			_calc = ((HexGrid)AccessTools.Field(typeof(HexCellManager), "hexGrid").GetValue(val2)).HexCalculator;
			_anchorPos = _calc.HexToPosition(_anchor.Coordinates);
			_lift = lift;
			_terrain = terrain;
			object obj = TileMaterial(file.tile);
			if (obj == null)
			{
				MeshRenderer component = ((Component)_anchor).GetComponent<MeshRenderer>();
				obj = ((component != null) ? ((Renderer)component).sharedMaterial : null) ?? TileMaterial((from kv in PropCatalog.For(file.terrain).TileUse
					orderby kv.Value descending
					select kv.Key).FirstOrDefault());
			}
			_defaultTile = (Material)obj;
			if (origin.HasValue)
			{
				(int x, int y) valueOrDefault2 = origin.GetValueOrDefault();
				int item = valueOrDefault2.x;
				int item2 = valueOrDefault2.y;
				_origin = new HexCoordinates(item, item2, 0f);
			}
			else
			{
				int num = dictionary.Keys.Max<(int, int)>(((int q, int r) k) => Distance(k.q, k.r, 0, 0));
				Vector3 val3 = _calc.HexToPosition(new HexCoordinates(((HexCoordinates)(ref _anchor.Coordinates)).X + 1, ((HexCoordinates)(ref _anchor.Coordinates)).Y, 0f)) - _anchorPos;
				val3.y = 0f;
				float num2 = 0f;
				foreach (HexCell item3 in ((val != null) ? val.AllHexes : null) ?? val2.FastCells)
				{
					if ((Object)(object)item3 != (Object)null)
					{
						num2 = Mathf.Max(num2, Vector3.Dot(((Component)item3).transform.position - ((Component)_anchor).transform.position, ((Vector3)(ref val3)).normalized));
					}
				}
				int num3 = Mathf.CeilToInt((num2 + 40f) / ((Vector3)(ref val3)).magnitude) + num;
				_origin = new HexCoordinates(((HexCoordinates)(ref _anchor.Coordinates)).X + num3, ((HexCoordinates)(ref _anchor.Coordinates)).Y, 0f);
			}
			_decor = new GameObject("MapMaker " + file.name);
			_decor.transform.SetParent(((Component)val2).transform, false);
			_staging = new GameObject("staging");
			_staging.SetActive(false);
			_staging.transform.SetParent(_decor.transform, false);
			Grid = val2;
			Current = file;
			_bottom = Bottom(dictionary.Values);
			foreach (HexEntry value in dictionary.Values)
			{
				MakeHex(value);
			}
			val2.AddCells(Cells);
			foreach (HexCell cell in Cells)
			{
				SetHeight(cell);
			}
			val2.SetCameraBounds();
			int num4 = 0;
			List<string> list = new List<string>();
			PropEntry[] props = file.props;
			for (int num5 = 0; num5 < props.Length; num5++)
			{
				if ((Object)(object)AddProp(props[num5], out var why) != (Object)null)
				{
					num4++;
				}
				else
				{
					list.Add(why);
				}
			}
			if (list.Count > 0)
			{
				Plugin.ModLog.LogWarning((object)("MapMaker: '" + file.name + "': not placed: " + string.Join(", ", list)));
			}
			string text = $"'{file.name}' ({file.terrain}): {Cells.Count} hexes ({Cells.Count((HexCell c) => !c.IsWalkable)} impassable), " + $"{num4}/{file.props.Length} props, centre {WorldOf(0, 0, 0f)}";
			Plugin.ModLog.LogInfo((object)("MapMaker: built " + text));
			string text2 = file.CutOffNote();
			if (text2 != "")
			{
				Plugin.ModLog.LogWarning((object)("MapMaker: '" + file.name + "': " + text2));
			}
			return text;
		}

		internal static HexCell PickAnchor(HexCellManager grid)
		{
			IEnumerable<HexCell> source = grid.FastCells.Where((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable && ((Behaviour)c).enabled && Mathf.Abs(((Component)c).transform.localPosition.z) < 0.01f);
			return source.FirstOrDefault((Func<HexCell, bool>)Bare) ?? source.FirstOrDefault();
		}

		private static bool Bare(HexCell c)
		{
			if (c.isEvent || (Object)(object)c.eventObj != (Object)null || (Object)(object)((Component)c).GetComponent<NavigationHex>() != (Object)null)
			{
				return false;
			}
			for (int i = 0; i < ((Component)c).transform.childCount; i++)
			{
				if (((Object)((Component)c).transform.GetChild(i)).name.EndsWith("(Clone)"))
				{
					return false;
				}
			}
			return true;
		}

		internal static List<(Transform t, Vector3 at)> Parts()
		{
			return (from t in (from v in Views.Values
					where (Object)(object)v.Cell != (Object)null
					select ((Component)v.Cell).transform).Append(_decor.transform)
				select (t: t, position: t.position)).ToList();
		}

		private static IEnumerator Glide(List<(Transform t, Vector3 at)> parts, Func<bool> still, Action done)
		{
			WorldMapGenerator instance = WorldMapGenerator.instance;
			float speed = (((Object)(object)instance != (Object)null && instance.riseSpeed > 0f) ? instance.riseSpeed : 4f);
			float snap = (((Object)(object)instance != (Object)null && instance.riseSnapDistance > 0f) ? instance.riseSnapDistance : 0.005f);
			while (still())
			{
				bool flag = false;
				foreach (var (val, val2) in parts)
				{
					if (!((Object)(object)val == (Object)null))
					{
						Vector3 val3 = Vector3.Lerp(val.position, val2, Time.deltaTime * speed);
						Vector3 val4 = val3 - val2;
						if (((Vector3)(ref val4)).sqrMagnitude <= snap * snap)
						{
							val3 = val2;
						}
						else
						{
							flag = true;
						}
						val.position = val3;
					}
				}
				if (!flag)
				{
					break;
				}
				yield return null;
			}
			done();
		}

		public static void Remove(bool sink = false)
		{
			if (MapRoom.Placed)
			{
				Plugin.ModLog.LogWarning((object)("MapMaker: not removed: " + MapRoom.Busy));
			}
			else
			{
				Discard(sink);
			}
		}

		internal static void Discard(bool sink = false)
		{
			MapRoom.Forget();
			if (sink && (Object)(object)Grid != (Object)null && (Object)(object)_decor != (Object)null)
			{
				foreach (HexCell cell in Cells)
				{
					Unregister(cell);
				}
				List<(Transform, Vector3)> list = Parts();
				foreach (var item2 in list)
				{
					Collider[] componentsInChildren = ((Component)item2.Item1).GetComponentsInChildren<Collider>();
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						componentsInChildren[i].enabled = false;
					}
				}
				WorldMapGenerator instance = WorldMapGenerator.instance;
				float drop = (((Object)(object)instance != (Object)null && instance.fallDropY > 0f) ? instance.fallDropY : 30f);
				List<(Transform t, Vector3)> down = list.Select<(Transform, Vector3), (Transform, Vector3)>(((Transform t, Vector3 at) p) => (t: p.t, p.at + Vector3.down * drop)).ToList();
				Plugin.Run(Glide(down, () => true, delegate
				{
					foreach (var item3 in down)
					{
						Transform item = item3.t;
						if ((Object)(object)item != (Object)null)
						{
							Object.Destroy((Object)(object)((Component)item).gameObject);
						}
					}
				}), "map sink", quiet: true);
			}
			else
			{
				if ((Object)(object)Grid != (Object)null)
				{
					foreach (HexCell cell2 in Cells)
					{
						Unregister(cell2);
					}
					foreach (HexView value in Views.Values)
					{
						if ((Object)(object)value.Cell != (Object)null)
						{
							Object.Destroy((Object)(object)((Component)value.Cell).gameObject);
						}
					}
				}
				if ((Object)(object)_decor != (Object)null)
				{
					Object.Destroy((Object)(object)_decor);
				}
			}
			Reset();
		}

		internal static GameObject Detach()
		{
			GameObject decor = _decor;
			Reset();
			return decor;
		}

		private static void Reset()
		{
			_decor = null;
			Cells.Clear();
			Views.Clear();
			PropViews.Clear();
			_carried = null;
			Grid = null;
			Current = null;
			_anchor = null;
			_lift = 0f;
		}

		public static HexCell SetHex(HexEntry h)
		{
			//IL_0132: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			if (!Ready)
			{
				throw new InvalidOperationException("no map built");
			}
			h.height = Mathf.Clamp(h.height, -0.9f, 4f);
			float num = Bottom((from v in Views.Values
				select v.Entry into e
				where e.q != h.q || e.r != h.r
				select e).Append(h));
			if (Views.TryGetValue(Key(h.q, h.r), out var value))
			{
				float num2 = h.height - value.Height;
				value.Entry = h;
				if (Mathf.Abs(num2) > 0.0001f)
				{
					foreach (PropView item in PropViews.Where((PropView p) => p.Entry.q == h.q && p.Entry.r == h.r && (Object)(object)p.Go != (Object)null))
					{
						Transform transform = item.Go.transform;
						transform.position += Vector3.up * num2;
					}
				}
				Apply(value);
			}
			else
			{
				value = MakeHex(h);
				Grid.AddCells(new List<HexCell> { value.Cell });
				Grid.SetCameraBounds();
			}
			SetHeight(value.Cell);
			if (Mathf.Abs(num - _bottom) > 0.0001f)
			{
				_bottom = num;
				foreach (HexView value2 in Views.Values)
				{
					Side(value2);
				}
			}
			return value.Cell;
		}

		public static bool RemoveHex(int q, int r)
		{
			if (!Views.TryGetValue(Key(q, r), out var value))
			{
				return false;
			}
			foreach (PropView item in PropViews.Where((PropView p) => p.Entry.q == q && p.Entry.r == r).ToList())
			{
				RemoveProp(item.Entry);
			}
			Unregister(value.Cell);
			Cells.Remove(value.Cell);
			Views.Remove(Key(q, r));
			if ((Object)(object)value.Cell != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)value.Cell).gameObject);
			}
			if ((Object)(object)value.Side != (Object)null)
			{
				Object.Destroy((Object)(object)value.Side);
			}
			return true;
		}

		public static HexEntry HexAt(int q, int r)
		{
			if (!Views.TryGetValue(Key(q, r), out var value))
			{
				return null;
			}
			return value.Entry;
		}

		private static HexView MakeHex(HexEntry h)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			h.height = Mathf.Clamp(h.height, -0.9f, 4f);
			GameObject obj = Object.Instantiate<GameObject>(((Component)_anchor).gameObject, ((Component)Grid).transform);
			StripRuntimeAdditions(obj);
			((Object)obj).name = $"Map Hex {h.q},{h.r}";
			EnsureVisible(obj);
			HexCell component = obj.GetComponent<HexCell>();
			component.Coordinates = new HexCoordinates(((HexCoordinates)(ref _origin)).X + h.q, ((HexCoordinates)(ref _origin)).Y + h.r, 0f);
			component.isEventHexNeighbor = (component.isEvent = (component.isJob = (component.eventCompleted = false)));
			component.spawnPointTeam1 = (component.spawnPointTeam2 = (component.shrineSpawn = false));
			component.eventObj = null;
			StripRuntimeOverlays(component);
			HexView hexView = new HexView
			{
				Entry = h,
				Cell = component
			};
			Views[Key(h.q, h.r)] = hexView;
			Cells.Add(component);
			Apply(hexView);
			return hexView;
		}

		private static void EnsureVisible(GameObject go)
		{
			if (!((Object)(object)go.GetComponent<MeshRenderer>() != (Object)null))
			{
				MeshCollider component = go.GetComponent<MeshCollider>();
				Mesh val = ((component != null) ? component.sharedMesh : null);
				if ((Object)(object)val == (Object)null)
				{
					throw new InvalidOperationException("the hexes here have no mesh to copy");
				}
				if ((Object)(object)go.GetComponent<MeshFilter>() == (Object)null)
				{
					go.AddComponent<MeshFilter>().sharedMesh = val;
				}
				go.AddComponent<MeshRenderer>();
			}
		}

		private static void Apply(HexView view)
		{
			//IL_002c: 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)
			HexEntry entry = view.Entry;
			HexCell cell = view.Cell;
			GameObject gameObject = ((Component)cell).gameObject;
			gameObject.transform.position = WorldOf(entry.q, entry.r, entry.height);
			view.Height = entry.height;
			Material val = TileMaterial(entry.tile) ?? _defaultTile;
			((Renderer)gameObject.GetComponent<MeshRenderer>()).sharedMaterial = (entry.Impassable ? Blocked(val) : val);
			cell.islandHexType = (IslandHexType)(entry.Impassable ? 1 : 0);
			((Behaviour)cell).enabled = true;
			gameObject.SetActive(true);
			cell.ProcessWalkable();
			Side(view);
		}

		private static Material Blocked(Material tile)
		{
			//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_0042: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)tile == (Object)null)
			{
				return null;
			}
			if (_blocked.TryGetValue(tile, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = new Material(tile)
			{
				name = ((Object)tile).name + " (impassable)"
			};
			string[] array = new string[3] { "_Color", "_BaseColor", "_Tint" };
			foreach (string text in array)
			{
				if (value.HasProperty(text))
				{
					Color color = value.GetColor(text);
					value.SetColor(text, new Color(color.r * 0.45f, color.g * 0.45f, color.b * 0.45f, color.a));
				}
			}
			_blocked[tile] = value;
			return value;
		}

		private static void SetHeight(HexCell cell)
		{
			//IL_0002: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			cell.Coordinates = HexUtility.SetHeightValue(cell.Coordinates, Grid);
		}

		private static void StripRuntimeAdditions(GameObject go)
		{
			Component[] components = go.GetComponents<Component>();
			foreach (Component val in components)
			{
				if (val is NavigationHex || val is EventClicker)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
			for (int num = go.transform.childCount - 1; num >= 0; num--)
			{
				Transform child = go.transform.GetChild(num);
				if (((Object)child).name.EndsWith("(Clone)") || (Object)(object)((Component)child).GetComponentInChildren<EventClicker>(true) != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
				}
			}
		}

		private static void StripRuntimeOverlays(HexCell cell)
		{
			string[] overlayObjects = OverlayObjects;
			foreach (string text in overlayObjects)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(HexCell), text);
				if (!(fieldInfo == null))
				{
					object? value = fieldInfo.GetValue(cell);
					GameObject val = (GameObject)((value is GameObject) ? value : null);
					if (val != null && (Object)(object)val != (Object)null && val.transform.IsChildOf(((Component)cell).transform))
					{
						Object.DestroyImmediate((Object)(object)val);
					}
					fieldInfo.SetValue(cell, null);
				}
			}
			overlayObjects = OverlayRefs;
			foreach (string text2 in overlayObjects)
			{
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(HexCell), text2);
				if (!(fieldInfo2 == null))
				{
					object? value2 = fieldInfo2.GetValue(cell);
					Component val2 = (Component)((value2 is Component) ? value2 : null);
					if (val2 == null || !((Object)(object)val2 != (Object)null) || !val2.transform.IsChildOf(((Component)cell).transform))
					{
						fieldInfo2.SetValue(cell, null);
					}
				}
			}
			AccessTools.Field(typeof(HexCell), "overlayMarkersSet")?.SetValue(cell, false);
		}

		internal static void Unregister(HexCell c)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)c == (Object)null) && !((Object)(object)Grid == (Object)null))
			{
				((HexContainer<HexCell>)AccessTools.Field(typeof(HexCellManager), "cells").GetValue(Grid))?.Remove(c.Coordinates);
				Grid.FastCells.Remove(c);
			}
		}

		private static float Bottom(IEnumerable<HexEntry> hexes)
		{
			float num = Mathf.Min(0f, hexes.Select((HexEntry e) => e.height).DefaultIfEmpty(0f).Min());
			MapFile current = Current;
			return num - ((current != null && current.depth > 0f) ? Current.depth : 1.2f);
		}

		private static Material TileMaterial(string name)
		{
			if (string.IsNullOrEmpty(name) || _terrain == null)
			{
				return null;
			}
			if (_terrain.Tiles.TryGetValue(name, out var value))
			{
				return value;
			}
			Plugin.ModLog.LogWarning((object)("MapMaker: no tile material '" + name + "' in " + Where(_terrain)));
			return null;
		}

		private static string Where(PropCatalog.Terrain t)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (t != null)
			{
				if (!t.Mixed)
				{
					return $"{t.Type}'s rooms";
				}
				return "any terrain's rooms";
			}
			return "no terrain";
		}

		private static void Side(HexView view)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_008e: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00e0: Expected O, but got Unknown
			//IL_00db: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)view.Side != (Object)null)
			{
				Object.Destroy((Object)(object)view.Side);
			}
			GameObject gameObject = ((Component)view.Cell).gameObject;
			GameObject val = new GameObject("Map Hex Side");
			val.transform.SetParent(_decor.transform, false);
			val.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
			GameObject val2 = new GameObject("tile");
			val2.transform.SetParent(val.transform, false);
			val2.transform.SetPositionAndRotation(gameObject.transform.position, gameObject.transform.rotation);
			val2.transform.localScale = gameObject.transform.localScale;
			val2.AddComponent<MeshFilter>().sharedMesh = gameObject.GetComponent<MeshFilter>().sharedMesh;
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)gameObject.GetComponent<MeshRenderer>()).sharedMaterials;
			Bounds val3 = Bounds(val2);
			Transform transform = val2.transform;
			transform.position -= new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).max.y, ((Bounds)(ref val3)).center.z);
			float num = ((Bounds)(ref val3)).max.y - (((Component)_anchor).transform.position.y + _lift + _bottom);
			val.transform.position = new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).max.y - 0.005f, ((Bounds)(ref val3)).center.z);
			val.transform.localScale = new Vector3(1f, Mathf.Max(num, ((Bounds)(ref val3)).size.y) / Mathf.Max(((Bounds)(ref val3)).size.y, 0.01f), 1f);
			view.Side = val;
		}

		public static GameObject AddProp(PropEntry p, out string why)
		{
			//IL_00a4: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: 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)
			why = null;
			PropCatalog.Prop prop = PropCatalog.Find(_terrain, p.name);
			if (prop == null)
			{
				why = p.name + " (not in " + Where(_terrain) + ")";
				return null;
			}
			if (!Views.TryGetValue(Key(p.q, p.r), out var value))
			{
				why = $"{p.name}@{p.q},{p.r} (no hex)";
				return null;
			}
			float num = ((p.scale > 0f) ? p.scale : 1f);
			Quaternion val = Quaternion.AngleAxis(p.rot, Vector3.up);
			GameObject val2 = Copy(prop, ((Component)value.Cell).transform.position - val * prop.Offset * num + new Vector3(p.dx, 0f, p.dz), val * prop.Source.transform.rotation, prop.Source.transform.lossyScale * num, ((Component)value.Cell).transform.position.y);
			PropViews.Add(new PropView
			{
				Entry = p,
				Go = val2
			});
			return val2;
		}

		public static bool RemoveProp(PropEntry p)
		{
			PropView propView = PropViews.FirstOrDefault((PropView v) => v.Entry == p);
			if (propView == null)
			{
				return false;
			}
			if ((Object)(object)propView.Go != (Object)null)
			{
				Object.Destroy((Object)(object)propView.Go);
			}
			PropViews.Remove(propView);
			return true;
		}

		public static bool Carry(PropEntry p, int q, int r, out string why)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			why = null;
			if (!Ready)
			{
				why = "no map built";
				return false;
			}
			PropCatalog.Prop prop = PropCatalog.Find(_terrain, p.name);
			if (prop == null)
			{
				why = p.name + " (not in " + Where(_terrain) + ")";
				return false;
			}
			float num = ((p.scale > 0f) ? p.scale : 1f);
			Quaternion val = Quaternion.AngleAxis(p.rot, Vector3.up);
			float num2 = HexAt(q, r)?.height ?? 0f;
			Vector3 val2 = WorldOf(q, r, num2) - val * prop.Offset * num + new Vector3(p.dx, 0.35f, p.dz);
			if ((Object)(object)_carried == (Object)null || ((Object)_carried).name != prop.Key)
			{
				Drop();
				_carried = Copy(prop, val2, val * prop.Source.transform.rotation, prop.Source.transform.lossyScale * num, num2);
				Collider[] componentsInChildren = _carried.GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = false;
				}
			}
			else
			{
				_carried.transform.SetPositionAndRotation(val2, val * prop.Source.transform.rotation);
			}
			return true;
		}

		public static void Drop()
		{
			if ((Object)(object)_carried != (Object)null)
			{
				Object.Destroy((Object)(object)_carried);
			}
			_carried = null;
		}

		private static GameObject Copy(PropCatalog.Prop prop, Vector3 position, Quaternion rotation, Vector3 scale, float ground)
		{
			//IL_0018: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_0166: 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_0117: 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: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(prop.Source, position, rotation, _staging.transform);
			((Object)val).name = prop.Key;
			val.transform.localScale = scale;
			MaterialsByQualityObject[] componentsInChildren = val.GetComponentsInChildren<MaterialsByQualityObject>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			bool flag = Plants.Any((string word) => prop.Key.IndexOf(word, StringComparison.OrdinalIgnoreCase) >= 0);
			LOSBlocker[] componentsInChildren2 = val.GetComponentsInChildren<LOSBlocker>(true);
			foreach (LOSBlocker val2 in componentsInChildren2)
			{
				List<Bounds> list = new List<Bounds>();
				MeshFilter component = ((Component)val2).GetComponent<MeshFilter>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
				{
					list.Add(component.sharedMesh.bounds);
				}
				Collider[] components = ((Component)val2).GetComponents<Collider>();
				if (components.Length != 0)
				{
					if (!flag)
					{
						continue;
					}
					bool flag2 = false;
					Collider[] array = components;
					foreach (Collider val3 in array)
					{
						if (Shape(val3, out var shape))
						{
							list.Add(shape);
							if (Wide(((Component)val2).transform, shape))
							{
								val3.enabled = false;
								flag2 = true;
							}
						}
					}
					if (!flag2)
					{
						continue;
					}
				}
				if (list.Count == 0)
				{
					continue;
				}
				Bounds val4 = list[0];
				foreach (Bounds item in list)
				{
					((Bounds)(ref val4)).Encapsulate(item);
				}
				BoxCollider val5 = ((Component)val2).gameObject.AddComponent<BoxCollider>();
				val5.center = ((Bounds)(ref val4)).center;
				val5.size = ((Bounds)(ref val4)).size;
				if (flag)
				{
					Trunk(val5, ground);
				}
			}
			val.SetActive(true);
			val.transform.SetParent(_decor.transform, true);
			return val;
		}

		private static int Vertical(Transform t)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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)
			Vector3 val = t.InverseTransformDirection(Vector3.up);
			if (!(Mathf.Abs(val.x) > Mathf.Abs(val.y)))
			{
				if (!(Mathf.Abs(val.y) > Mathf.Abs(val.z)))
				{
					return 2;
				}
				return 1;
			}
			if (!(Mathf.Abs(val.x) > Mathf.Abs(val.z)))
			{
				return 2;
			}
			return 0;
		}

		private static bool Wide(Transform t, Bounds shape)
		{
			//IL_0011: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			int num = Vertical(t);
			for (int i = 0; i < 3; i++)
			{
				if (i != num)
				{
					Vector3 val = ((Bounds)(ref shape)).size;
					float num2 = ((Vector3)(ref val))[i];
					val = t.lossyScale;
					if (num2 * Mathf.Abs(((Vector3)(ref val))[i]) > 2.2f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool Shape(Collider collider, out Bounds shape)
		{
			//IL_0001: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			shape = default(Bounds);
			MeshCollider val = (MeshCollider)(object)((collider is MeshCollider) ? collider : null);
			if (val != null && (Object)(object)val.sharedMesh != (Object)null)
			{
				shape = val.sharedMesh.bounds;
			}
			else
			{
				BoxCollider val2 = (BoxCollider)(object)((collider is BoxCollider) ? collider : null);
				if (val2 == null)
				{
					return false;
				}
				shape = new Bounds(val2.center, val2.size);
			}
			return true;
		}

		private static void Trunk(BoxCollider box, float ground)
		{
			//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_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)
			//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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)box).transform;
			Vector3 lossyScale = transform.lossyScale;
			Vector3 center = box.center;
			Vector3 size = box.size;
			int num = Vertical(transform);
			for (int i = 0; i < 3; i++)
			{
				if (i == num)
				{
					Vector3 val = transform.InverseTransformPoint(new Vector3(transform.position.x, ground, transform.position.z));
					float num2 = ((Vector3)(ref val))[i];
					float num3 = Mathf.Min(((Vector3)(ref center))[i] - ((Vector3)(ref size))[i] / 2f, num2);
					float num4 = Mathf.Max(((Vector3)(ref center))[i] + ((Vector3)(ref size))[i] / 2f, num2);
					((Vector3)(ref center))[i] = (num3 + num4) / 2f;
					((Vector3)(ref size))[i] = num4 - num3;
				}
				else
				{
					float num5 = 1.4f / Mathf.Max(Mathf.Abs(((Vector3)(ref lossyScale))[i]), 0.01f);
					if (!(((Vector3)(ref size))[i] <= num5))
					{
						float num6 = (((Vector3)(ref size))[i] - num5) / 2f;
						((Vector3)(ref center))[i] = Mathf.Clamp(0f, ((Vector3)(ref center))[i] - num6, ((Vector3)(ref center))[i] + num6);
						((Vector3)(ref size))[i] = num5;
					}
				}
			}
			box.center = center;
			box.size = size;
		}

		internal static IEnumerable<MeshFilter> ShownMeshes(GameObject go)
		{
			MeshFilter[] componentsInChildren = go.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if ((Object)(object)val.sharedMesh == (Object)null)
				{
					continue;
				}
				bool flag = true;
				Transform val2 = ((Component)val).transform;
				while ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)go.transform)
				{
					if (!((Component)val2).gameObject.activeSelf)
					{
						flag = false;
						break;
					}
					val2 = val2.parent;
				}
				if (flag)
				{
					yield return val;
				}
			}
		}

		internal static Bounds Bounds(GameObject go)
		{
			//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_003c: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_0069: 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_007d: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			Bounds? val = null;
			foreach (MeshFilter item in ShownMeshes(go))
			{
				Bounds bounds = item.sharedMesh.bounds;
				for (int i = 0; i < 8; i++)
				{
					Vector3 val2 = ((Component)item).transform.TransformPoint(((Bounds)(ref bounds)).center + Vector3.Scale(((B