Decompiled source of DungeonMaps v1.1.0

DungeonMaps.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("DungeonMaps")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("DungeonMaps")]
[assembly: AssemblyTitle("DungeonMaps")]
[assembly: AssemblyVersion("1.1.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 DungeonMaps
{
	public static class DungeonGeom
	{
		public static int RoomId(float x, float y, float z)
		{
			return ((int)Math.Round(x) * 73856093) ^ ((int)Math.Round(y) * 19349663) ^ ((int)Math.Round(z) * 83492791);
		}

		public static bool ContainsXZ(float centreX, float centreZ, float yawDegrees, float sizeX, float sizeZ, float pointX, float pointZ, float margin)
		{
			RotateToLocal(pointX - centreX, pointZ - centreZ, yawDegrees, out var localX, out var localZ);
			if (Math.Abs(localX) <= sizeX * 0.5f + margin)
			{
				return Math.Abs(localZ) <= sizeZ * 0.5f + margin;
			}
			return false;
		}

		public static void RotateToLocal(float dx, float dz, float yawDegrees, out float localX, out float localZ)
		{
			double num = (double)yawDegrees * Math.PI / 180.0;
			float num2 = (float)Math.Cos(num);
			float num3 = (float)Math.Sin(num);
			localX = dx * num2 - dz * num3;
			localZ = dx * num3 + dz * num2;
		}

		public static void WorldOffsetToMap(float dx, float dz, float scale, float mapYawDegrees, out float mapX, out float mapY)
		{
			RotateToLocal(dx, dz, mapYawDegrees, out var localX, out var localZ);
			mapX = localX * scale;
			mapY = localZ * scale;
		}

		public static float BaseYaw(float anyRoomYaw)
		{
			float num = anyRoomYaw % 90f;
			if (!(num < 0f))
			{
				return num;
			}
			return num + 90f;
		}
	}
	internal class DungeonMapUI : MonoBehaviour
	{
		private struct Marker
		{
			public Vector3 Pos;

			public Color Colour;

			public float Size;

			public Sprite Icon;

			public Texture Fallback;
		}

		private class Band
		{
			public RectTransform Root;

			public RawImage Stencil;

			public RawImage Bed;

			public RawImage Stone;

			public RawImage Shade;
		}

		private class Overlay
		{
			public RectTransform Root;

			public RawImage Ground;

			public RectTransform FloorRoot;

			public RectTransform MarkerRoot;

			public readonly List<Band> Bands = new List<Band>();

			public readonly List<RawImage> Pool = new List<RawImage>();

			public int BandsUsed;

			public int Used;
		}

		private const float SameFloorBand = 4.5f;

		private const float RevealInterval = 0.2f;

		private const float FlushInterval = 10f;

		private const float StoneTileMetres = 1.4f;

		private const int ScanBudgetPerTick = 2;

		private static readonly Color FlatGround = new Color(0.085f, 0.08f, 0.075f, 1f);

		private static DungeonMapUI _instance;

		private Overlay _small;

		private Overlay _large;

		private Sprite _discSprite;

		private Texture2D _white;

		private Texture2D _disc;

		private Texture2D _arrow;

		private Texture2D _chest;

		private bool _iconsResolved;

		private Sprite _exitIcon;

		private Sprite _dangerIcon;

		private Sprite _playerIcon;

		private static FieldInfo _smallZoomField;

		private static FieldInfo _largeZoomField;

		private float _smallZoomFactor = 1f;

		private float _largeZoomFactor = 1f;

		private float _lastSmallZoom = -1f;

		private float _lastLargeZoom = -1f;

		private float _revealTimer;

		private float _flushTimer;

		private bool _userHidden;

		private bool _chromeHidden;

		private readonly List<Marker> _markers = new List<Marker>();

		private readonly List<DungeonRaster.Layer> _layerOrder = new List<DungeonRaster.Layer>();

		private static readonly Rect FullRect = new Rect(0f, 0f, 1f, 1f);

		public static bool CoversLargeMap { get; private set; }

		public static void Ensure(Minimap minimap)
		{
			if (!((Object)(object)_instance != (Object)null))
			{
				_instance = ((Component)minimap).gameObject.AddComponent<DungeonMapUI>();
			}
		}

		public static string CurrentLabel()
		{
			Dungeon current = DungeonModel.Current;
			if ((Object)(object)_instance == (Object)null || _instance._userHidden || current == null)
			{
				return null;
			}
			return current.Label;
		}

		private void Awake()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			_white = MakeWhite();
			_disc = MakeDisc(256);
			_arrow = MakeArrow(64);
			_chest = MakeChest(48);
			_discSprite = Sprite.Create(_disc, new Rect(0f, 0f, (float)((Texture)_disc).width, (float)((Texture)_disc).height), new Vector2(0.5f, 0.5f));
		}

		private void ResolveIcons(Minimap minimap)
		{
			if (!_iconsResolved)
			{
				_iconsResolved = true;
				_exitIcon = FindPin(minimap, (PinType)6);
				_dangerIcon = FindPin(minimap, (PinType)4);
				_smallZoomField = typeof(Minimap).GetField("m_smallZoom", BindingFlags.Instance | BindingFlags.NonPublic);
				_largeZoomField = typeof(Minimap).GetField("m_largeZoom", BindingFlags.Instance | BindingFlags.NonPublic);
				if (_smallZoomField == null || _largeZoomField == null)
				{
					Plugin.Log.LogWarning((object)"Minimap zoom fields not found; the dungeon map will not zoom.");
				}
				if ((Object)(object)minimap.m_smallMarker != (Object)null)
				{
					Image component = ((Component)minimap.m_smallMarker).GetComponent<Image>();
					_playerIcon = (((Object)(object)component != (Object)null) ? component.sprite : null);
				}
				if (ModConfig.Verbose.Value)
				{
					Plugin.Log.LogInfo((object)("[icons] exit=" + Name(_exitIcon) + " danger=" + Name(_dangerIcon) + " player=" + Name(_playerIcon) + " chest=drawn"));
				}
			}
		}

		private static string Name(Sprite sprite)
		{
			if (!((Object)(object)sprite != (Object)null))
			{
				return "none (using fallback)";
			}
			return ((Object)sprite).name;
		}

		private void FollowVanillaZoom(Minimap minimap)
		{
			Track(ReadZoom(_smallZoomField, minimap), ref _lastSmallZoom, ref _smallZoomFactor);
			Track(ReadZoom(_largeZoomField, minimap), ref _lastLargeZoom, ref _largeZoomFactor);
		}

		private static float ReadZoom(FieldInfo field, Minimap minimap)
		{
			if (field == null)
			{
				return -1f;
			}
			try
			{
				return (float)field.GetValue(minimap);
			}
			catch (Exception)
			{
				return -1f;
			}
		}

		private static void Track(float zoom, ref float last, ref float factor)
		{
			if (!(zoom <= 0f))
			{
				if (last <= 0f)
				{
					last = zoom;
				}
				else if (Mathf.Abs(zoom - last) > 1E-06f)
				{
					factor = Mathf.Clamp(factor * (last / zoom), 0.25f, 10f);
					last = zoom;
				}
			}
		}

		private static Sprite FindPin(Minimap minimap, PinType type)
		{
			//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)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (minimap.m_icons == null)
			{
				return null;
			}
			for (int i = 0; i < minimap.m_icons.Count; i++)
			{
				if (minimap.m_icons[i].m_name == type)
				{
					return minimap.m_icons[i].m_icon;
				}
			}
			return null;
		}

		private static void SetSprite(RawImage image, Sprite sprite, Texture fallback)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sprite == (Object)null || (Object)(object)sprite.texture == (Object)null)
			{
				image.texture = fallback;
				image.uvRect = FullRect;
				return;
			}
			Texture texture = (Texture)(object)sprite.texture;
			Rect textureRect = sprite.textureRect;
			image.texture = texture;
			image.uvRect = new Rect(((Rect)(ref textureRect)).x / (float)texture.width, ((Rect)(ref textureRect)).y / (float)texture.height, ((Rect)(ref textureRect)).width / (float)texture.width, ((Rect)(ref textureRect)).height / (float)texture.height);
		}

		private void OnDestroy()
		{
			SetVanillaChrome(((Component)this).GetComponent<Minimap>() ?? Minimap.instance, visible: true);
			CoversLargeMap = false;
			DestroyTexture(_white);
			DestroyTexture(_disc);
			DestroyTexture(_arrow);
			DestroyTexture(_chest);
			if ((Object)(object)_discSprite != (Object)null)
			{
				Object.Destroy((Object)(object)_discSprite);
				_discSprite = null;
			}
			FogStore.Flush();
			DungeonModel.Leave();
			_instance = null;
		}

		private static void DestroyTexture(Texture2D texture)
		{
			if ((Object)(object)texture != (Object)null)
			{
				Object.Destroy((Object)(object)texture);
			}
		}

		private void Update()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0079: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Invalid comparison between Unknown and I4
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Invalid comparison between Unknown and I4
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || !ModConfig.Enabled.Value || Game.m_noMap)
			{
				HideAll();
				return;
			}
			KeyboardShortcut value = ModConfig.ToggleKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				_userHidden = !_userHidden;
			}
			if (_userHidden)
			{
				HideAll();
				return;
			}
			Vector3 position = ((Component)Player.m_localPlayer).transform.position;
			Dungeon dungeon = DungeonModel.Resolve(position);
			if (dungeon == null)
			{
				HideAll();
				return;
			}
			ResolveIcons(instance);
			FollowVanillaZoom(instance);
			_revealTimer -= Time.deltaTime;
			if (_revealTimer <= 0f)
			{
				_revealTimer = 0.2f;
				DungeonModel.RevealAround(dungeon, position, ModConfig.RevealRadius.Value, ModConfig.RevealAll.Value);
				DungeonModel.ScanRevealed(dungeon, 2);
				RebuildMarkers(dungeon);
			}
			_flushTimer -= Time.deltaTime;
			if (_flushTimer <= 0f)
			{
				_flushTimer = 10f;
				FogStore.Flush();
			}
			bool flag = (int)instance.m_mode == 1 && ModConfig.ShowOnMinimap.Value;
			bool flag2 = (int)instance.m_mode == 2 && ModConfig.ShowOnFullMap.Value;
			if (flag)
			{
				EnsureOverlay(ref _small, ((Graphic)instance.m_mapImageSmall).rectTransform, "DungeonMapSmall", circular: true);
				Draw(_small, dungeon, position, playerCentred: true);
			}
			else
			{
				Hide(_small);
			}
			if (flag2)
			{
				EnsureOverlay(ref _large, ((Graphic)instance.m_mapImageLarge).rectTransform, "DungeonMapLarge", circular: false);
				Draw(_large, dungeon, position, playerCentred: false);
			}
			else
			{
				Hide(_large);
			}
			CoversLargeMap = flag2;
			SetVanillaChrome(instance, !(flag || flag2));
		}

		private void EnsureOverlay(ref Overlay overlay, RectTransform parent, string name, bool circular)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			if (overlay == null || !((Object)(object)overlay.Root != (Object)null))
			{
				RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
				((Transform)component).SetParent((Transform)(object)parent, false);
				Stretch(component);
				if (circular && ModConfig.RoundMinimap.Value)
				{
					Image obj = ((Component)component).gameObject.AddComponent<Image>();
					obj.sprite = _discSprite;
					((Graphic)obj).raycastTarget = false;
					((Component)component).gameObject.AddComponent<Mask>().showMaskGraphic = false;
				}
				else
				{
					((Component)component).gameObject.AddComponent<RectMask2D>();
				}
				RawImage ground = NewChild<RawImage>(component, "Ground");
				RectTransform floorRoot = NewCentred(component, "Floors");
				RectTransform markerRoot = NewCentred(component, "Markers");
				overlay = new Overlay
				{
					Root = component,
					Ground = ground,
					FloorRoot = floorRoot,
					MarkerRoot = markerRoot
				};
				if (ModConfig.Verbose.Value)
				{
					ManualLogSource log = Plugin.Log;
					string[] obj2 = new string[8]
					{
						"[ui] built ",
						name,
						" in '",
						((Object)parent).name,
						"', rect ",
						null,
						null,
						null
					};
					Rect rect = component.rect;
					obj2[5] = ((Rect)(ref rect)).width.ToString("F0");
					obj2[6] = "x";
					rect = component.rect;
					obj2[7] = ((Rect)(ref rect)).height.ToString("F0");
					log.LogInfo((object)string.Concat(obj2));
				}
			}
		}

		private static RectTransform NewCentred(RectTransform parent, string name)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)parent, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = Vector2.zero;
			component.anchoredPosition = Vector2.zero;
			return component;
		}

		private static T NewChild<T>(RectTransform parent, string name) where T : Graphic
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			T component = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(T)
			}).GetComponent<T>();
			((Transform)((Graphic)component).rectTransform).SetParent((Transform)(object)parent, false);
			Stretch(((Graphic)component).rectTransform);
			((Graphic)component).raycastTarget = false;
			return component;
		}

		private static void Stretch(RectTransform rt)
		{
			//IL_0001: 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_0021: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			rt.pivot = new Vector2(0.5f, 0.5f);
			rt.offsetMin = Vector2.zero;
			rt.offsetMax = Vector2.zero;
			((Transform)rt).localScale = Vector3.one;
		}

		private Band NextBand(Overlay overlay)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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)
			Band band;
			if (overlay.BandsUsed < overlay.Bands.Count)
			{
				band = overlay.Bands[overlay.BandsUsed];
			}
			else
			{
				RectTransform component = new GameObject("Floor", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(RawImage)
				}).GetComponent<RectTransform>();
				((Transform)component).SetParent((Transform)(object)overlay.FloorRoot, false);
				component.anchorMin = new Vector2(0.5f, 0.5f);
				component.anchorMax = new Vector2(0.5f, 0.5f);
				component.pivot = new Vector2(0.5f, 0.5f);
				RawImage component2 = ((Component)component).GetComponent<RawImage>();
				((Graphic)component2).raycastTarget = false;
				((Component)component).gameObject.AddComponent<Mask>().showMaskGraphic = false;
				band = new Band
				{
					Root = component,
					Stencil = component2,
					Bed = NewChild<RawImage>(component, "Bed"),
					Stone = NewChild<RawImage>(component, "Stone"),
					Shade = NewChild<RawImage>(component, "Shade")
				};
				overlay.Bands.Add(band);
			}
			overlay.BandsUsed++;
			((Component)band.Root).gameObject.SetActive(true);
			return band;
		}

		private RawImage Next(Overlay overlay, Texture texture)
		{
			//IL_005c: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			RawImage val;
			if (overlay.Used < overlay.Pool.Count)
			{
				val = overlay.Pool[overlay.Used];
			}
			else
			{
				val = new GameObject("Quad", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(RawImage)
				}).GetComponent<RawImage>();
				((Transform)((Graphic)val).rectTransform).SetParent((Transform)(object)overlay.MarkerRoot, false);
				((Graphic)val).rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
				((Graphic)val).rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
				((Graphic)val).rectTransform.pivot = new Vector2(0.5f, 0.5f);
				((Graphic)val).raycastTarget = false;
				overlay.Pool.Add(val);
			}
			overlay.Used++;
			val.texture = texture;
			val.uvRect = new Rect(0f, 0f, 1f, 1f);
			((Component)val).gameObject.SetActive(true);
			return val;
		}

		private void Draw(Overlay overlay, Dungeon dungeon, Vector3 playerPos, bool playerCentred)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0042: 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_009c: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			((Component)overlay.Root).gameObject.SetActive(true);
			overlay.Used = 0;
			overlay.BandsUsed = 0;
			Rect rect = overlay.Root.rect;
			float scale;
			Vector3 origin;
			if (playerCentred)
			{
				scale = ModConfig.MinimapScale.Value * _smallZoomFactor;
				origin = playerPos;
			}
			else
			{
				scale = Mathf.Min(((Rect)(ref rect)).width / Mathf.Max(1f, dungeon.ExtentX + 12f), ((Rect)(ref rect)).height / Mathf.Max(1f, dungeon.ExtentZ + 12f)) * _largeZoomFactor;
				origin = ((_largeZoomFactor > 1.05f) ? playerPos : dungeon.Centre);
			}
			Texture stone = (ModConfig.UseDungeonTexture.Value ? dungeon.Stone : null);
			float value = ModConfig.TextureStrength.Value;
			float mapYaw = (ModConfig.AlignToDungeon.Value ? dungeon.BaseYaw : 0f);
			float value2 = ModConfig.Opacity.Value;
			DrawGround(overlay);
			DrawFloors(overlay, dungeon, playerPos, origin, scale, mapYaw, value2, stone, value);
			DrawMarkers(overlay, dungeon, playerPos, origin, scale, mapYaw);
			for (int i = overlay.BandsUsed; i < overlay.Bands.Count; i++)
			{
				((Component)overlay.Bands[i].Root).gameObject.SetActive(false);
			}
			for (int j = overlay.Used; j < overlay.Pool.Count; j++)
			{
				((Component)overlay.Pool[j]).gameObject.SetActive(false);
			}
		}

		private void DrawFloors(Overlay overlay, Dungeon dungeon, Vector3 playerPos, Vector3 origin, float scale, float mapYaw, float opacity, Texture stone, float stoneStrength)
		{
			//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)
			//IL_0056: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: 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_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: 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)
			DungeonRaster raster = dungeon.Raster;
			if (raster == null)
			{
				return;
			}
			_layerOrder.Clear();
			_layerOrder.AddRange(raster.Layers());
			_layerOrder.Sort((DungeonRaster.Layer a, DungeonRaster.Layer b) => Mathf.Abs(b.Height - playerPos.y).CompareTo(Mathf.Abs(a.Height - playerPos.y)));
			DungeonGeom.WorldOffsetToMap(dungeon.Centre.x - origin.x, dungeon.Centre.z - origin.z, scale, mapYaw, out var mapX, out var mapY);
			Vector2 anchoredPosition = default(Vector2);
			((Vector2)(ref anchoredPosition))..ctor(mapX, mapY);
			Vector2 sizeDelta = default(Vector2);
			((Vector2)(ref sizeDelta))..ctor(raster.MetresWide * scale, raster.MetresDeep * scale);
			Quaternion localRotation = Quaternion.Euler(0f, 0f, 0f - (dungeon.BaseYaw - mapYaw));
			float num = raster.MetresWide / 1.4f;
			float num2 = raster.MetresDeep / 1.4f;
			for (int num3 = 0; num3 < _layerOrder.Count; num3++)
			{
				DungeonRaster.Layer layer = _layerOrder[num3];
				Color val = FloorTint(layer.Height, playerPos.y, opacity);
				if (!(val.a <= 0.01f))
				{
					Band band = NextBand(overlay);
					band.Root.anchoredPosition = anchoredPosition;
					band.Root.sizeDelta = sizeDelta;
					((Transform)band.Root).localRotation = localRotation;
					band.Stencil.texture = (Texture)(object)layer.Texture;
					((Graphic)band.Stencil).color = Color.white;
					band.Bed.texture = (Texture)(object)_white;
					band.Bed.uvRect = FullRect;
					((Graphic)band.Bed).color = val;
					band.Stone.texture = (Texture)(((Object)(object)stone != (Object)null) ? ((object)stone) : ((object)_white));
					band.Stone.uvRect = (Rect)(((Object)(object)stone != (Object)null) ? new Rect(0f, 0f, num, num2) : FullRect);
					((Graphic)band.Stone).color = (((Object)(object)stone != (Object)null) ? new Color(val.r, val.g, val.b, val.a * stoneStrength) : new Color(0f, 0f, 0f, 0f));
					band.Shade.texture = (Texture)(object)layer.Ink;
					band.Shade.uvRect = FullRect;
					((Graphic)band.Shade).color = new Color(1f, 1f, 1f, val.a);
				}
			}
		}

		private static Color FloorTint(float floorHeight, float playerY, float opacity)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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)
			float num = floorHeight - playerY;
			if (!ModConfig.DimByHeight.Value || Mathf.Abs(num) <= 4.5f)
			{
				return new Color(0.8f, 0.77f, 0.69f, opacity);
			}
			if (num > 0f)
			{
				return new Color(0.8f, 0.77f, 0.69f, opacity * 0.3f);
			}
			return new Color(0.4f, 0.385f, 0.345f, opacity * 0.8f);
		}

		private void DrawMarkers(Overlay overlay, Dungeon dungeon, Vector3 playerPos, Vector3 origin, float scale, float mapYaw)
		{
			//IL_0017: 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_002b: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < _markers.Count; i++)
			{
				Marker marker = _markers[i];
				DungeonGeom.WorldOffsetToMap(marker.Pos.x - origin.x, marker.Pos.z - origin.z, scale, mapYaw, out var mapX, out var mapY);
				RawImage obj = Next(overlay, (Texture)(object)_disc);
				Place(obj, new Vector2(mapX, mapY), new Vector2(marker.Size * 1.15f, marker.Size * 1.15f), Quaternion.identity);
				obj.uvRect = FullRect;
				((Graphic)obj).color = new Color(0.04f, 0.04f, 0.05f, 0.7f);
				RawImage obj2 = Next(overlay, (Texture)(object)_disc);
				SetSprite(obj2, marker.Icon, marker.Fallback);
				Place(obj2, new Vector2(mapX, mapY), new Vector2(marker.Size, marker.Size), Quaternion.identity);
				((Graphic)obj2).color = marker.Colour;
			}
			if (ModConfig.MarkPlayer.Value)
			{
				DungeonGeom.WorldOffsetToMap(playerPos.x - origin.x, playerPos.z - origin.z, scale, mapYaw, out var mapX2, out var mapY2);
				Quaternion rotation = ((Component)Player.m_localPlayer).transform.rotation;
				Quaternion rotation2 = Quaternion.Euler(0f, 0f, 0f - (((Quaternion)(ref rotation)).eulerAngles.y - mapYaw));
				RawImage obj3 = Next(overlay, (Texture)(object)_arrow);
				SetSprite(obj3, _playerIcon, (Texture)(object)_arrow);
				Place(obj3, new Vector2(mapX2, mapY2), new Vector2(22f, 22f), rotation2);
				((Graphic)obj3).color = new Color(0f, 0f, 0f, 0.85f);
				RawImage obj4 = Next(overlay, (Texture)(object)_arrow);
				SetSprite(obj4, _playerIcon, (Texture)(object)_arrow);
				Place(obj4, new Vector2(mapX2, mapY2), new Vector2(15f, 15f), rotation2);
				((Graphic)obj4).color = Color.white;
			}
		}

		private static void Place(RawImage image, Vector2 position, Vector2 size, Quaternion rotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((Graphic)image).rectTransform;
			rectTransform.anchoredPosition = position;
			rectTransform.sizeDelta = size;
			((Transform)rectTransform).localRotation = rotation;
		}

		private void DrawGround(Overlay overlay)
		{
			//IL_0017: 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)
			overlay.Ground.texture = (Texture)(object)_white;
			overlay.Ground.uvRect = FullRect;
			((Graphic)overlay.Ground).color = FlatGround;
		}

		private void RebuildMarkers(Dungeon dungeon)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_004f: 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)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			_markers.Clear();
			if (ModConfig.MarkEntrance.Value)
			{
				for (int i = 0; i < dungeon.Rooms.Count; i++)
				{
					DungeonRoom dungeonRoom = dungeon.Rooms[i];
					if (dungeonRoom.IsEntrance && dungeonRoom.Revealed)
					{
						_markers.Add(new Marker
						{
							Pos = dungeonRoom.Centre,
							Colour = new Color(0.5f, 1f, 0.5f, 1f),
							Size = 20f,
							Icon = _exitIcon,
							Fallback = (Texture)(object)_disc
						});
					}
				}
			}
			if (ModConfig.MarkChests.Value)
			{
				List<Container> list = ContainerRegistry.All();
				for (int j = 0; j < list.Count; j++)
				{
					Vector3 position = ((Component)list[j]).transform.position;
					if (InRevealedRoom(dungeon, position))
					{
						_markers.Add(new Marker
						{
							Pos = position,
							Colour = new Color(1f, 0.85f, 0.4f, 1f),
							Size = 16f,
							Fallback = (Texture)(object)_chest
						});
					}
				}
			}
			if (!ModConfig.MarkSpawners.Value)
			{
				return;
			}
			List<CreatureSpawner> list2 = SpawnerRegistry.All();
			for (int k = 0; k < list2.Count; k++)
			{
				if (!((Object)(object)list2[k] == (Object)null))
				{
					Vector3 position2 = ((Component)list2[k]).transform.position;
					if (InRevealedRoom(dungeon, position2))
					{
						_markers.Add(new Marker
						{
							Pos = position2,
							Colour = new Color(1f, 0.45f, 0.45f, 1f),
							Size = 15f,
							Icon = _dangerIcon,
							Fallback = (Texture)(object)_disc
						});
					}
				}
			}
		}

		private static bool InRevealedRoom(Dungeon dungeon, Vector3 pos)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < dungeon.Rooms.Count; i++)
			{
				DungeonRoom dungeonRoom = dungeon.Rooms[i];
				if (dungeonRoom.Revealed && Mathf.Abs(pos.y - dungeonRoom.Centre.y) <= dungeonRoom.SizeY * 0.5f + 1f && DungeonGeom.ContainsXZ(dungeonRoom.Centre.x, dungeonRoom.Centre.z, dungeonRoom.Yaw, dungeonRoom.SizeX, dungeonRoom.SizeZ, pos.x, pos.z, 0.5f))
				{
					return true;
				}
			}
			return false;
		}

		private void HideAll()
		{
			CoversLargeMap = false;
			Hide(_small);
			Hide(_large);
			SetVanillaChrome(Minimap.instance, visible: true);
		}

		private static void Hide(Overlay overlay)
		{
			if (overlay != null && (Object)(object)overlay.Root != (Object)null && ((Component)overlay.Root).gameObject.activeSelf)
			{
				((Component)overlay.Root).gameObject.SetActive(false);
			}
		}

		private void SetVanillaChrome(Minimap minimap, bool visible)
		{
			if ((Object)(object)minimap == (Object)null || _chromeHidden == !visible)
			{
				return;
			}
			_chromeHidden = !visible;
			Fade(minimap.m_pinRootSmall, visible);
			Fade(minimap.m_pinRootLarge, visible);
			Fade(minimap.m_pinNameRootSmall, visible);
			Fade(minimap.m_pinNameRootLarge, visible);
			Fade(minimap.m_smallMarker, visible);
			Fade(minimap.m_largeMarker, visible);
			Fade(minimap.m_smallShipMarker, visible);
			Fade(minimap.m_largeShipMarker, visible);
			if (minimap.m_hints != null)
			{
				for (int i = 0; i < minimap.m_hints.Count; i++)
				{
					Fade(minimap.m_hints[i], visible);
				}
			}
		}

		private static void Fade(RectTransform target, bool visible)
		{
			Fade(((Object)(object)target != (Object)null) ? ((Component)target).gameObject : null, visible);
		}

		private static void Fade(GameObject target, bool visible)
		{
			if (!((Object)(object)target == (Object)null))
			{
				CanvasGroup val = target.GetComponent<CanvasGroup>();
				if ((Object)(object)val == (Object)null)
				{
					val = target.AddComponent<CanvasGroup>();
				}
				val.alpha = (visible ? 1f : 0f);
				val.blocksRaycasts = visible;
			}
		}

		private static Texture2D MakeWhite()
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(4, 4, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[16];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			}
			val.SetPixels32(array);
			val.Apply();
			return val;
		}

		private static Texture2D MakeDisc(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[size * size];
			float num = (float)size * 0.5f;
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num2 = (float)j + 0.5f - num;
					float num3 = (float)i + 0.5f - num;
					float num4 = Mathf.Clamp01(num - Mathf.Sqrt(num2 * num2 + num3 * num3));
					array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(num4 * 255f));
				}
			}
			val.SetPixels32(array);
			val.Apply();
			return val;
		}

		private static Texture2D MakeChest(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_00d9: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[size * size];
			Color32 val2 = default(Color32);
			((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
			Color32 val3 = default(Color32);
			((Color32)(ref val3))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			Color32 val4 = default(Color32);
			((Color32)(ref val4))..ctor((byte)90, (byte)70, (byte)40, byte.MaxValue);
			int num = Mathf.RoundToInt((float)size * 0.16f);
			int num2 = Mathf.RoundToInt((float)size * 0.84f);
			int num3 = Mathf.RoundToInt((float)size * 0.2f);
			int num4 = Mathf.RoundToInt((float)size * 0.76f);
			int num5 = Mathf.RoundToInt((float)size * 0.56f);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					int num6 = i * size + j;
					if (j < num || j > num2 || i < num3 || i > num4)
					{
						array[num6] = val2;
						continue;
					}
					bool flag = j <= num + 1 || j >= num2 - 1 || i <= num3 + 1 || i >= num4 - 1;
					bool flag2 = i >= num5 - 1 && i <= num5 + 1;
					bool flag3 = Mathf.Abs(j - size / 2) <= size / 12 && i >= num5 - size / 8 && i <= num5 + size / 8;
					array[num6] = ((flag || flag2 || flag3) ? val4 : val3);
				}
			}
			val.SetPixels32(array);
			val.Apply();
			return val;
		}

		private static Texture2D MakeArrow(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[size * size];
			for (int i = 0; i < size; i++)
			{
				float num = (float)i / (float)(size - 1);
				float num2 = (1f - num) * 0.5f * (float)size;
				for (int j = 0; j < size; j++)
				{
					byte b = (byte)((Mathf.Abs((float)j + 0.5f - (float)size * 0.5f) <= num2) ? 255u : 0u);
					array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
				}
			}
			val.SetPixels32(array);
			val.Apply();
			return val;
		}
	}
	internal class DungeonRoom
	{
		public int Id;

		public Vector3 Centre;

		public float Yaw;

		public float SizeX;

		public float SizeY;

		public float SizeZ;

		public bool IsEntrance;

		public Theme Theme;

		public bool Revealed;
	}
	internal class Dungeon
	{
		public Vector2i Zone;

		public string Label = "";

		public Theme Theme;

		public readonly List<DungeonRoom> Rooms = new List<DungeonRoom>();

		public Vector3 Centre;

		public float ExtentX;

		public float ExtentZ;

		public float MinY;

		public float MaxY;

		public float BaseYaw;

		public Texture Stone;

		public DungeonRaster Raster;

		public float WorldExtentX;

		public float WorldExtentZ;

		public bool Contains(Vector3 p)
		{
			//IL_0000: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (Mathf.Abs(p.x - Centre.x) <= WorldExtentX * 0.5f + 4f && Mathf.Abs(p.z - Centre.z) <= WorldExtentZ * 0.5f + 4f && p.y >= MinY - 4f)
			{
				return p.y <= MaxY + 4f;
			}
			return false;
		}
	}
	internal static class DungeonModel
	{
		private const float ScanInterval = 0.25f;

		private static Dungeon _current;

		private static DungeonGenerator _currentGenerator;

		private static float _nextScan;

		private static float _nextVerbose;

		public static Dungeon Current => _current;

		public static Dungeon Resolve(Vector3 playerPos)
		{
			//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)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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)
			if (_current != null)
			{
				if ((Object)(object)_currentGenerator != (Object)null && _current.Contains(playerPos))
				{
					return _current;
				}
				Leave();
			}
			if (Time.time < _nextScan)
			{
				return null;
			}
			_nextScan = Time.time + 0.25f;
			List<DungeonGenerator> generators = DungeonGeneratorRegistry.All();
			for (int i = 0; i < generators.Count; i++)
			{
				DungeonGenerator val = generators[i];
				if ((Object)(object)val == (Object)null || (int)val.m_algorithm != 0 || Utils.DistanceXZ(((Component)val).transform.position, playerPos) > 96f)
				{
					continue;
				}
				Dungeon dungeon = Build(val);
				if (dungeon == null)
				{
					Verbose(() => "a nearby generator has no rooms yet (still loading asynchronously)");
					continue;
				}
				if (!dungeon.Contains(playerPos))
				{
					Verbose(() => "in the zone of " + dungeon.Label + " but outside its bounds: player y=" + playerPos.y.ToString("F1") + ", rooms span " + dungeon.MinY.ToString("F1") + ".." + dungeon.MaxY.ToString("F1"));
					continue;
				}
				dungeon.Stone = ResolveStoneTexture(val);
				dungeon.Raster = new DungeonRaster(dungeon, ModConfig.MapDetail.Value);
				_current = dungeon;
				_currentGenerator = val;
				FogStore.Apply(dungeon);
				Plugin.Log.LogInfo((object)("Entered " + dungeon.Label + " (" + ((object)Unsafe.As<Theme, Theme>(ref dungeon.Theme)/*cast due to .constrained prefix*/).ToString() + ") - " + dungeon.Rooms.Count + " rooms"));
				return _current;
			}
			Verbose(() => "no dungeon here (player y=" + playerPos.y.ToString("F1") + ", interior=" + Character.InInterior(playerPos) + ", live generators loaded=" + generators.Count + ")");
			return null;
		}

		private static void Verbose(Func<string> message)
		{
			if (ModConfig.Verbose.Value && !(Time.time < _nextVerbose))
			{
				_nextVerbose = Time.time + 2f;
				Plugin.Log.LogInfo((object)("[scan] " + message()));
			}
		}

		public static void Leave()
		{
			if (_current != null)
			{
				FogStore.Flush();
				_current.Raster?.Dispose();
			}
			_current = null;
			_currentGenerator = null;
		}

		public static void ScanRevealed(Dungeon dungeon, int budget)
		{
			if (dungeon.Raster == null)
			{
				return;
			}
			for (int i = 0; i < dungeon.Rooms.Count; i++)
			{
				if (budget <= 0)
				{
					break;
				}
				DungeonRoom dungeonRoom = dungeon.Rooms[i];
				if (dungeonRoom.Revealed && !dungeon.Raster.HasScanned(dungeonRoom.Id))
				{
					dungeon.Raster.ScanRoom(dungeonRoom);
					budget--;
				}
			}
			dungeon.Raster.Repaint();
		}

		private static Dungeon Build(DungeonGenerator generator)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: 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)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			Room[] componentsInChildren = ((Component)generator).GetComponentsInChildren<Room>(true);
			if (componentsInChildren.Length == 0)
			{
				return null;
			}
			Dungeon dungeon = new Dungeon
			{
				Zone = ZoneSystem.GetZone(((Component)generator).transform.position),
				Theme = generator.m_themes,
				Label = Describe(generator)
			};
			float num = float.MaxValue;
			float num2 = float.MinValue;
			float num3 = float.MaxValue;
			float num4 = float.MinValue;
			float num5 = float.MaxValue;
			float num6 = float.MinValue;
			Room[] array = componentsInChildren;
			foreach (Room val in array)
			{
				Transform transform = ((Component)val).transform;
				Vector3 position = transform.position;
				DungeonRoom obj = new DungeonRoom
				{
					Id = DungeonGeom.RoomId(position.x, position.y, position.z),
					Centre = position
				};
				Quaternion rotation = transform.rotation;
				obj.Yaw = ((Quaternion)(ref rotation)).eulerAngles.y;
				obj.SizeX = ((Vector3Int)(ref val.m_size)).x;
				obj.SizeY = ((Vector3Int)(ref val.m_size)).y;
				obj.SizeZ = ((Vector3Int)(ref val.m_size)).z;
				obj.IsEntrance = val.m_entrance;
				obj.Theme = val.m_theme;
				DungeonRoom dungeonRoom = obj;
				dungeon.Rooms.Add(dungeonRoom);
				float num7 = Mathf.Max(dungeonRoom.SizeX, dungeonRoom.SizeZ) * 0.5f;
				num = Mathf.Min(num, position.x - num7);
				num2 = Mathf.Max(num2, position.x + num7);
				num3 = Mathf.Min(num3, position.z - num7);
				num4 = Mathf.Max(num4, position.z + num7);
				num5 = Mathf.Min(num5, position.y - dungeonRoom.SizeY * 0.5f);
				num6 = Mathf.Max(num6, position.y + dungeonRoom.SizeY * 0.5f);
			}
			dungeon.Centre = new Vector3((num + num2) * 0.5f, (num5 + num6) * 0.5f, (num3 + num4) * 0.5f);
			dungeon.MinY = num5;
			dungeon.MaxY = num6;
			dungeon.BaseYaw = DungeonGeom.BaseYaw(dungeon.Rooms[0].Yaw);
			float num8 = float.MaxValue;
			float num9 = float.MinValue;
			float num10 = float.MaxValue;
			float num11 = float.MinValue;
			for (int j = 0; j < dungeon.Rooms.Count; j++)
			{
				DungeonRoom dungeonRoom2 = dungeon.Rooms[j];
				DungeonGeom.RotateToLocal(dungeonRoom2.Centre.x - dungeon.Centre.x, dungeonRoom2.Centre.z - dungeon.Centre.z, dungeon.BaseYaw, out var localX, out var localZ);
				float num12 = Mathf.Max(dungeonRoom2.SizeX, dungeonRoom2.SizeZ) * 0.5f;
				num8 = Mathf.Min(num8, localX - num12);
				num9 = Mathf.Max(num9, localX + num12);
				num10 = Mathf.Min(num10, localZ - num12);
				num11 = Mathf.Max(num11, localZ + num12);
			}
			dungeon.ExtentX = num9 - num8;
			dungeon.ExtentZ = num11 - num10;
			dungeon.WorldExtentX = num2 - num;
			dungeon.WorldExtentZ = num4 - num3;
			return dungeon;
		}

		private static Texture ResolveStoneTexture(DungeonGenerator generator)
		{
			Dictionary<Texture, int> dictionary = new Dictionary<Texture, int>();
			MeshRenderer[] componentsInChildren = ((Component)generator).GetComponentsInChildren<MeshRenderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Material sharedMaterial = ((Renderer)componentsInChildren[i]).sharedMaterial;
				if (!((Object)(object)sharedMaterial == (Object)null))
				{
					Texture mainTexture = sharedMaterial.mainTexture;
					if (!((Object)(object)mainTexture == (Object)null))
					{
						dictionary.TryGetValue(mainTexture, out var value);
						dictionary[mainTexture] = value + 1;
					}
				}
			}
			Texture val = null;
			int num = 0;
			foreach (KeyValuePair<Texture, int> item in dictionary)
			{
				if (item.Value > num)
				{
					val = item.Key;
					num = item.Value;
				}
			}
			if (ModConfig.Verbose.Value)
			{
				Plugin.Log.LogInfo((object)("[stone] " + (((Object)(object)val != (Object)null) ? (((Object)val).name + " (" + num + " of " + componentsInChildren.Length + " renderers)") : "none found")));
			}
			return val;
		}

		private static string Describe(DungeonGenerator generator)
		{
			//IL_0006: 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)
			Location zoneLocation = Location.GetZoneLocation(((Component)generator).transform.position);
			if ((Object)(object)zoneLocation != (Object)null && !string.IsNullOrEmpty(zoneLocation.m_discoverLabel) && Localization.instance != null)
			{
				return Localization.instance.Localize(zoneLocation.m_discoverLabel);
			}
			return ThemeName(generator.m_themes);
		}

		private static string ThemeName(Theme theme)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0011: 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_0020: 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_002f: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if ((theme & 2) != 0)
			{
				return "Sunken Crypt";
			}
			if ((theme & 0x208) != 0)
			{
				return "Burial Chamber";
			}
			if ((theme & 0x404) != 0)
			{
				return "Frost Cave";
			}
			if ((theme & 0x100) != 0)
			{
				return "Dvergr Fortress";
			}
			if ((theme & 0x80) != 0)
			{
				return "Infested Mine";
			}
			if ((theme & 0x2000) != 0)
			{
				return "Fortress";
			}
			if ((theme & 0x1000) != 0)
			{
				return "Ashlands Ruin";
			}
			return "Crypt";
		}

		public static void RevealAround(Dungeon dungeon, Vector3 playerPos, float radius, bool revealAll)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < dungeon.Rooms.Count; i++)
			{
				DungeonRoom dungeonRoom = dungeon.Rooms[i];
				if (!dungeonRoom.Revealed)
				{
					if (revealAll)
					{
						dungeonRoom.Revealed = true;
					}
					else if (Mathf.Abs(playerPos.y - dungeonRoom.Centre.y) <= dungeonRoom.SizeY * 0.5f + 1f && DungeonGeom.ContainsXZ(dungeonRoom.Centre.x, dungeonRoom.Centre.z, dungeonRoom.Yaw, dungeonRoom.SizeX, dungeonRoom.SizeZ, playerPos.x, playerPos.z, radius))
					{
						dungeonRoom.Revealed = true;
						FogStore.Reveal(dungeon.Zone, dungeonRoom.Id);
					}
				}
			}
		}

		public static DungeonRoom RoomAt(Dungeon dungeon, Vector3 p)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < dungeon.Rooms.Count; i++)
			{
				DungeonRoom dungeonRoom = dungeon.Rooms[i];
				if (Mathf.Abs(p.y - dungeonRoom.Centre.y) <= dungeonRoom.SizeY * 0.5f + 1f && DungeonGeom.ContainsXZ(dungeonRoom.Centre.x, dungeonRoom.Centre.z, dungeonRoom.Yaw, dungeonRoom.SizeX, dungeonRoom.SizeZ, p.x, p.z, 0.5f))
				{
					return dungeonRoom;
				}
			}
			return null;
		}
	}
	internal class DungeonRaster
	{
		internal class Layer
		{
			public int Band;

			public float Height;

			public float[] Floor;

			public Texture2D Texture;

			public Color32[] Pixels;

			public Texture2D Ink;

			public Color32[] InkPixels;

			public bool Dirty;
		}

		private const float BandMetres = 4f;

		private const float RaycastMargin = 1.5f;

		private static int _rayMask;

		private readonly Dungeon _dungeon;

		private readonly float _pixelsPerMetre;

		private readonly int _width;

		private readonly int _height;

		private readonly float _minLocalX;

		private readonly float _minLocalZ;

		private readonly Dictionary<int, Layer> _layers = new Dictionary<int, Layer>();

		private readonly HashSet<int> _scanned = new HashSet<int>();

		private readonly List<Layer> _ordered = new List<Layer>();

		public float MetresWide => (float)_width / _pixelsPerMetre;

		public float MetresDeep => (float)_height / _pixelsPerMetre;

		public DungeonRaster(Dungeon dungeon, float pixelsPerMetre)
		{
			_dungeon = dungeon;
			_pixelsPerMetre = pixelsPerMetre;
			if (_rayMask == 0)
			{
				_rayMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" });
			}
			float num = dungeon.ExtentX + 8f;
			float num2 = dungeon.ExtentZ + 8f;
			_minLocalX = (0f - num) * 0.5f;
			_minLocalZ = (0f - num2) * 0.5f;
			_width = Mathf.Clamp(Mathf.CeilToInt(num * pixelsPerMetre), 16, 1024);
			_height = Mathf.Clamp(Mathf.CeilToInt(num2 * pixelsPerMetre), 16, 1024);
		}

		public List<Layer> Layers()
		{
			_ordered.Clear();
			foreach (KeyValuePair<int, Layer> layer in _layers)
			{
				_ordered.Add(layer.Value);
			}
			return _ordered;
		}

		public bool HasScanned(int roomId)
		{
			return _scanned.Contains(roomId);
		}

		public void ScanRoom(DungeonRoom room)
		{
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			if (!_scanned.Add(room.Id))
			{
				return;
			}
			Layer layer = GetLayer(room.Centre.y);
			float num = room.SizeX * 0.5f;
			float num2 = room.SizeZ * 0.5f;
			float num3 = float.MaxValue;
			float num4 = float.MinValue;
			float num5 = float.MaxValue;
			float num6 = float.MinValue;
			for (int i = 0; i < 4; i++)
			{
				float dx = ((i == 0 || i == 3) ? (0f - num) : num);
				float dz = ((i < 2) ? (0f - num2) : num2);
				DungeonGeom.RotateToLocal(dx, dz, 0f - room.Yaw, out var localX, out var localZ);
				ToLocal(room.Centre.x + localX, room.Centre.z + localZ, out var localX2, out var localZ2);
				num3 = Mathf.Min(num3, localX2);
				num4 = Mathf.Max(num4, localX2);
				num5 = Mathf.Min(num5, localZ2);
				num6 = Mathf.Max(num6, localZ2);
			}
			int num7 = Mathf.Clamp(Mathf.FloorToInt((num3 - _minLocalX) * _pixelsPerMetre), 0, _width - 1);
			int num8 = Mathf.Clamp(Mathf.CeilToInt((num4 - _minLocalX) * _pixelsPerMetre), 0, _width - 1);
			int num9 = Mathf.Clamp(Mathf.FloorToInt((num5 - _minLocalZ) * _pixelsPerMetre), 0, _height - 1);
			int num10 = Mathf.Clamp(Mathf.CeilToInt((num6 - _minLocalZ) * _pixelsPerMetre), 0, _height - 1);
			float num11 = room.Centre.y + room.SizeY * 0.5f + 1.5f;
			float num12 = room.Centre.y - room.SizeY * 0.5f - 1.5f;
			float num13 = num11 - num12;
			RaycastHit val = default(RaycastHit);
			for (int j = num9; j <= num10; j++)
			{
				for (int k = num7; k <= num8; k++)
				{
					int num14 = j * _width + k;
					if (float.IsNaN(layer.Floor[num14]))
					{
						LocalOfPixel(k, j, out var localX3, out var localZ3);
						ToWorld(localX3, localZ3, out var worldX, out var worldZ);
						if (DungeonGeom.ContainsXZ(room.Centre.x, room.Centre.z, room.Yaw, room.SizeX, room.SizeZ, worldX, worldZ, 0f) && Physics.Raycast(new Vector3(worldX, num11, worldZ), Vector3.down, ref val, num13, _rayMask) && ((RaycastHit)(ref val)).point.y >= num12 && ((RaycastHit)(ref val)).point.y <= num11)
						{
							layer.Floor[num14] = ((RaycastHit)(ref val)).point.y;
							layer.Dirty = true;
						}
					}
				}
			}
		}

		public void Repaint()
		{
			foreach (KeyValuePair<int, Layer> layer in _layers)
			{
				Layer value = layer.Value;
				if (value.Dirty)
				{
					value.Dirty = false;
					Paint(value);
				}
			}
		}

		private void Paint(Layer layer)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0129: 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)
			float[] floor = layer.Floor;
			Color32[] pixels = layer.Pixels;
			Color32[] inkPixels = layer.InkPixels;
			Color32 val = default(Color32);
			((Color32)(ref val))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
			Color32 val2 = default(Color32);
			((Color32)(ref val2))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			for (int i = 0; i < _height; i++)
			{
				for (int j = 0; j < _width; j++)
				{
					int num = i * _width + j;
					float num2 = floor[num];
					if (float.IsNaN(num2))
					{
						pixels[num] = val;
						inkPixels[num] = val;
						continue;
					}
					pixels[num] = val2;
					bool num3 = IsSolid(floor, j - 1, i) || IsSolid(floor, j + 1, i) || IsSolid(floor, j, i - 1) || IsSolid(floor, j, i + 1);
					float num4 = Neighbour(floor, j - 1, i, num2);
					float num5 = Neighbour(floor, j, i - 1, num2);
					float num6 = Mathf.Abs(num2 - num4) + Mathf.Abs(num2 - num5);
					byte b = (byte)(num3 ? 215 : ((byte)(Mathf.Clamp01(num6 * 0.7f) * 130f)));
					inkPixels[num] = new Color32((byte)16, (byte)13, (byte)10, b);
				}
			}
			layer.Texture.SetPixels32(pixels);
			layer.Texture.Apply(false);
			layer.Ink.SetPixels32(inkPixels);
			layer.Ink.Apply(false);
		}

		private bool IsSolid(float[] floor, int x, int z)
		{
			if (x < 0 || z < 0 || x >= _width || z >= _height)
			{
				return true;
			}
			return float.IsNaN(floor[z * _width + x]);
		}

		private float Neighbour(float[] floor, int x, int z, float fallback)
		{
			if (x < 0 || z < 0 || x >= _width || z >= _height)
			{
				return fallback;
			}
			float num = floor[z * _width + x];
			if (!float.IsNaN(num))
			{
				return num;
			}
			return fallback;
		}

		private Layer GetLayer(float worldY)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00cf: Expected O, but got Unknown
			int num = Mathf.RoundToInt(worldY / 4f);
			if (_layers.TryGetValue(num, out var value))
			{
				return value;
			}
			Layer layer = new Layer
			{
				Band = num,
				Height = (float)num * 4f,
				Floor = new float[_width * _height],
				Pixels = (Color32[])(object)new Color32[_width * _height],
				InkPixels = (Color32[])(object)new Color32[_width * _height],
				Texture = new Texture2D(_width, _height, (TextureFormat)4, false)
				{
					wrapMode = (TextureWrapMode)1,
					filterMode = (FilterMode)1
				},
				Ink = new Texture2D(_width, _height, (TextureFormat)4, false)
				{
					wrapMode = (TextureWrapMode)1,
					filterMode = (FilterMode)1
				}
			};
			for (int i = 0; i < layer.Floor.Length; i++)
			{
				layer.Floor[i] = float.NaN;
			}
			_layers[num] = layer;
			return layer;
		}

		public void Dispose()
		{
			foreach (KeyValuePair<int, Layer> layer in _layers)
			{
				if ((Object)(object)layer.Value.Texture != (Object)null)
				{
					Object.Destroy((Object)(object)layer.Value.Texture);
				}
				if ((Object)(object)layer.Value.Ink != (Object)null)
				{
					Object.Destroy((Object)(object)layer.Value.Ink);
				}
			}
			_layers.Clear();
			_scanned.Clear();
		}

		private void ToLocal(float worldX, float worldZ, out float localX, out float localZ)
		{
			DungeonGeom.RotateToLocal(worldX - _dungeon.Centre.x, worldZ - _dungeon.Centre.z, _dungeon.BaseYaw, out localX, out localZ);
		}

		private void ToWorld(float localX, float localZ, out float worldX, out float worldZ)
		{
			DungeonGeom.RotateToLocal(localX, localZ, 0f - _dungeon.BaseYaw, out var localX2, out var localZ2);
			worldX = _dungeon.Centre.x + localX2;
			worldZ = _dungeon.Centre.z + localZ2;
		}

		private void LocalOfPixel(int px, int pz, out float localX, out float localZ)
		{
			localX = _minLocalX + ((float)px + 0.5f) / _pixelsPerMetre;
			localZ = _minLocalZ + ((float)pz + 0.5f) / _pixelsPerMetre;
		}
	}
	internal static class FogStore
	{
		private static readonly Dictionary<long, HashSet<int>> ByZone = new Dictionary<long, HashSet<int>>();

		private static string _path;

		private static long _loadedWorld;

		private static bool _dirty;

		private static long Key(Vector2i zone)
		{
			//IL_0000: 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)
			return ((long)zone.x << 32) | (uint)zone.y;
		}

		public static void EnsureLoaded()
		{
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			long worldUID;
			try
			{
				if ((Object)(object)ZNet.instance == (Object)null)
				{
					return;
				}
				worldUID = ZNet.instance.GetWorldUID();
			}
			catch (Exception)
			{
				return;
			}
			if (worldUID == 0L || worldUID == _loadedWorld)
			{
				return;
			}
			Flush();
			ByZone.Clear();
			_loadedWorld = worldUID;
			_dirty = false;
			_path = Path.Combine(Path.Combine(Paths.ConfigPath, "DungeonMaps"), worldUID + ".txt");
			if (!File.Exists(_path))
			{
				return;
			}
			try
			{
				string[] array = File.ReadAllLines(_path);
				foreach (string text in array)
				{
					int num = text.IndexOf(':');
					if (num <= 0)
					{
						continue;
					}
					string[] array2 = text.Substring(0, num).Split(new char[1] { ',' });
					if (array2.Length != 2 || !int.TryParse(array2[0], out var result) || !int.TryParse(array2[1], out var result2))
					{
						continue;
					}
					HashSet<int> hashSet = new HashSet<int>();
					string[] array3 = text.Substring(num + 1).Split(new char[1] { ',' });
					for (int j = 0; j < array3.Length; j++)
					{
						if (int.TryParse(array3[j], out var result3))
						{
							hashSet.Add(result3);
						}
					}
					ByZone[Key(new Vector2i(result, result2))] = hashSet;
				}
				Plugin.Log.LogInfo((object)("Loaded explored rooms for " + ByZone.Count + " dungeon(s)"));
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("Could not read " + _path + ": " + ex2.Message));
				ByZone.Clear();
			}
		}

		public static void Reveal(Vector2i zone, int roomId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			long key = Key(zone);
			if (!ByZone.TryGetValue(key, out var value))
			{
				value = new HashSet<int>();
				ByZone[key] = value;
			}
			if (value.Add(roomId))
			{
				_dirty = true;
			}
		}

		public static void Apply(Dungeon dungeon)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			EnsureLoaded();
			if (!ByZone.TryGetValue(Key(dungeon.Zone), out var value))
			{
				return;
			}
			for (int i = 0; i < dungeon.Rooms.Count; i++)
			{
				if (value.Contains(dungeon.Rooms[i].Id))
				{
					dungeon.Rooms[i].Revealed = true;
				}
			}
		}

		public static void Flush()
		{
			if (!_dirty || string.IsNullOrEmpty(_path))
			{
				return;
			}
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(_path));
				StringBuilder stringBuilder = new StringBuilder();
				foreach (KeyValuePair<long, HashSet<int>> item in ByZone)
				{
					if (item.Value.Count == 0)
					{
						continue;
					}
					int value = (int)(item.Key >> 32);
					int value2 = (int)(item.Key & 0xFFFFFFFFu);
					stringBuilder.Append(value).Append(',').Append(value2)
						.Append(':');
					bool flag = true;
					foreach (int item2 in item.Value)
					{
						if (!flag)
						{
							stringBuilder.Append(',');
						}
						stringBuilder.Append(item2);
						flag = false;
					}
					stringBuilder.Append('\n');
				}
				File.WriteAllText(_path, stringBuilder.ToString());
				_dirty = false;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not save explored rooms to " + _path + ": " + ex.Message));
			}
		}
	}
	internal static class ModConfig
	{
		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<bool> ShowOnMinimap;

		public static ConfigEntry<bool> ShowOnFullMap;

		public static ConfigEntry<KeyboardShortcut> ToggleKey;

		public static ConfigEntry<bool> Verbose;

		public static ConfigEntry<float> RevealRadius;

		public static ConfigEntry<bool> RevealAll;

		public static ConfigEntry<bool> AlignToDungeon;

		public static ConfigEntry<bool> DimByHeight;

		public static ConfigEntry<float> MinimapScale;

		public static ConfigEntry<float> Opacity;

		public static ConfigEntry<bool> RoundMinimap;

		public static ConfigEntry<float> MapDetail;

		public static ConfigEntry<bool> UseDungeonTexture;

		public static ConfigEntry<float> TextureStrength;

		public static ConfigEntry<bool> MarkEntrance;

		public static ConfigEntry<bool> MarkPlayer;

		public static ConfigEntry<bool> MarkChests;

		public static ConfigEntry<bool> MarkSpawners;

		private const float V100MinimapScale = 2.2f;

		private const float V100RevealRadius = 8f;

		public static void Init(ConfigFile config)
		{
			//IL_006c: 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_00b3: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Expected O, but got Unknown
			Enabled = config.Bind<bool>("General", "Enabled", true, "Draw dungeon maps at all. Turn this off to get the vanilla behaviour back without uninstalling.");
			ShowOnMinimap = config.Bind<bool>("General", "ShowOnMinimap", true, "Replace the minimap with the dungeon map while you are inside a dungeon.");
			ShowOnFullMap = config.Bind<bool>("General", "ShowOnFullMap", true, "Replace the full map with the dungeon map while you are inside a dungeon.");
			ToggleKey = config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)109, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Hides the dungeon map so you can read the world map underneath it.");
			RevealRadius = config.Bind<float>("Exploration", "RevealRadius", 0f, new ConfigDescription("Extra metres beyond the room you are standing in that also get revealed. 0 means only rooms you actually walk into. This is applied to every horizontal direction at once, so even small values uncover the neighbours.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			Verbose = config.Bind<bool>("General", "Verbose", false, "Log why no dungeon map is being drawn. Turn this on if the mod appears to do nothing.");
			RevealAll = config.Bind<bool>("Exploration", "RevealAll", false, "Reveal the whole dungeon the moment you step inside, instead of room by room. This is also how you verify the drawn floorplan matches the real one.");
			AlignToDungeon = config.Bind<bool>("Appearance", "AlignToDungeon", true, "Turn the map to the dungeon's own grid so rooms draw square. Valheim spawns dungeons at a random angle, so with this off the map is a field of diamonds. The player arrow turns with the map either way.");
			DimByHeight = config.Bind<bool>("Appearance", "DimByHeight", true, "Fade rooms above you and darken rooms below you. Turning this off makes multi-level crypts hard to read.");
			MinimapScale = config.Bind<float>("Appearance", "MinimapScale", 7f, new ConfigDescription("Pixels per metre on the minimap at default zoom. The map zoom keys scale from here.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>()));
			Opacity = config.Bind<float>("Appearance", "Opacity", 1f, new ConfigDescription("Opacity of the dungeon map.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>()));
			RoundMinimap = config.Bind<bool>("Appearance", "RoundMinimap", false, "Clip the dungeon minimap to a circle. Off by default so it fills the minimap panel exactly, whatever shape that panel is.");
			MapDetail = config.Bind<float>("Appearance", "MapDetail", 3f, new ConfigDescription("Pixels per metre when tracing the dungeon's real floor shape. Higher is sharper and costs more raycasts on first entry.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 8f), Array.Empty<object>()));
			UseDungeonTexture = config.Bind<bool>("Appearance", "UseDungeonTexture", true, "Fill rooms with the dungeon's own wall texture, taken from the geometry around you. Turn off for flat colours.");
			TextureStrength = config.Bind<float>("Appearance", "TextureStrength", 0.55f, new ConfigDescription("How strongly the dungeon's stone texture shows over the room colour. 0 is flat colour, 1 is raw stone.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			MarkEntrance = config.Bind<bool>("Markers", "MarkEntrance", true, "Mark the entrance room. This is the way out.");
			MarkPlayer = config.Bind<bool>("Markers", "MarkPlayer", true, "Draw an arrow for your position and facing.");
			MarkChests = config.Bind<bool>("Markers", "MarkChests", true, "Mark chests in rooms you have already explored. Turn this off for a spoiler-free run.");
			MarkSpawners = config.Bind<bool>("Markers", "MarkSpawners", true, "Mark creature spawners in rooms you have already explored. Turn this off for a spoiler-free run.");
			MigrateFrom100();
		}

		private static void MigrateFrom100()
		{
			AdoptNewDefault(MinimapScale, 2.2f);
			AdoptNewDefault(RevealRadius, 8f);
		}

		private static void AdoptNewDefault(ConfigEntry<float> entry, float oldDefault)
		{
			float value = entry.Value;
			float num = (float)((ConfigEntryBase)entry).DefaultValue;
			if (!(Mathf.Abs(value - num) < 0.0001f) && !(Mathf.Abs(value - oldDefault) > 0.0001f))
			{
				entry.Value = num;
				Plugin.Log.LogInfo((object)("Config: " + ((ConfigEntryBase)entry).Definition.Key + " was still the old 1.0.0 default (" + oldDefault + "), updated to " + num));
			}
		}
	}
	[BepInPlugin("zl.dungeonmaps", "Dungeon Maps", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "zl.dungeonmaps";

		public const string PluginName = "Dungeon Maps";

		public const string PluginVersion = "1.1.0";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Init(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("zl.dungeonmaps");
			_harmony.PatchAll();
			Log.LogInfo((object)"Dungeon Maps 1.1.0 loaded");
		}

		private void OnDestroy()
		{
			FogStore.Flush();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	[HarmonyPatch(typeof(Minimap), "Awake")]
	internal static class MinimapAwakePatch
	{
		private static void Postfix(Minimap __instance)
		{
			DungeonMapUI.Ensure(__instance);
		}
	}
	[HarmonyPatch(typeof(Container), "Awake")]
	internal static class ContainerAwakePatch
	{
		private static void Postfix(Container __instance)
		{
			ContainerRegistry.Add(__instance);
		}
	}
	[HarmonyPatch(typeof(DungeonGenerator), "Awake")]
	internal static class DungeonGeneratorAwakePatch
	{
		private static void Postfix(DungeonGenerator __instance)
		{
			DungeonGeneratorRegistry.Add(__instance);
		}
	}
	[HarmonyPatch(typeof(Minimap))]
	internal static class MapClickPatches
	{
		private static bool Blocked()
		{
			return DungeonMapUI.CoversLargeMap;
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnMapDblClick")]
		private static bool BlockAddPin()
		{
			return !Blocked();
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnMapLeftClick")]
		private static bool BlockCrossOff()
		{
			return !Blocked();
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnMapRightClick")]
		private static bool BlockRemovePin()
		{
			return !Blocked();
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnMapMiddleClick")]
		private static bool BlockPing()
		{
			return !Blocked();
		}
	}
	[HarmonyPatch(typeof(Minimap), "UpdateBiome")]
	internal static class MinimapBiomeLabelPatch
	{
		private static void Postfix(Minimap __instance)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			string text = DungeonMapUI.CurrentLabel();
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			if ((int)__instance.m_mode == 2)
			{
				if ((Object)(object)__instance.m_biomeNameLarge != (Object)null)
				{
					__instance.m_biomeNameLarge.text = text;
				}
			}
			else if ((Object)(object)__instance.m_biomeNameSmall != (Object)null)
			{
				__instance.m_biomeNameSmall.text = text;
			}
		}
	}
	internal static class ContainerRegistry
	{
		private static readonly List<Container> Items = new List<Container>();

		public static void Add(Container container)
		{
			Items.Add(container);
		}

		public static List<Container> All()
		{
			for (int num = Items.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)Items[num] == (Object)null)
				{
					Items.RemoveAt(num);
				}
			}
			return Items;
		}
	}
	internal static class DungeonGeneratorRegistry
	{
		private static readonly List<DungeonGenerator> Items = new List<DungeonGenerator>();

		public static void Add(DungeonGenerator generator)
		{
			Items.Add(generator);
		}

		public static List<DungeonGenerator> All()
		{
			for (int num = Items.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)Items[num] == (Object)null)
				{
					Items.RemoveAt(num);
				}
			}
			return Items;
		}
	}
	internal static class SpawnerRegistry
	{
		private static readonly List<CreatureSpawner> Empty = new List<CreatureSpawner>();

		private static FieldInfo _field;

		private static bool _looked;

		public static List<CreatureSpawner> All()
		{
			if (!_looked)
			{
				_looked = true;
				_field = typeof(CreatureSpawner).GetField("m_creatureSpawners", BindingFlags.Static | BindingFlags.NonPublic);
				if (_field == null)
				{
					Plugin.Log.LogWarning((object)"CreatureSpawner.m_creatureSpawners is gone; spawner markers are disabled.");
				}
			}
			if (_field == null)
			{
				return Empty;
			}
			try
			{
				return (_field.GetValue(null) as List<CreatureSpawner>) ?? Empty;
			}
			catch (Exception)
			{
				return Empty;
			}
		}
	}
}