Decompiled source of Biome Borders v1.0.0

plugins/BiomeBorders.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("BenjSammy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Biome Borders by BenjSammy")]
[assembly: AssemblyTitle("BiomeBorders")]
[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]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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 BenjSammy.BiomeBorders
{
	internal readonly struct PixelBounds
	{
		internal readonly int Left;

		internal readonly int Bottom;

		internal readonly int Right;

		internal readonly int Top;

		internal PixelBounds(int left, int bottom, int right, int top)
		{
			Left = left;
			Bottom = bottom;
			Right = right;
			Top = top;
		}
	}
	internal readonly struct BiomeEdge
	{
		internal readonly int X;

		internal readonly int Y;

		internal readonly bool Vertical;

		internal BiomeEdge(int x, int y, bool vertical)
		{
			X = x;
			Y = y;
			Vertical = vertical;
		}
	}
	internal readonly struct BiomeLabel
	{
		internal readonly int X;

		internal readonly int Y;

		internal readonly int Area;

		internal readonly byte Biome;

		internal BiomeLabel(int x, int y, byte biome, int area)
		{
			X = x;
			Y = y;
			Biome = biome;
			Area = area;
		}
	}
	internal readonly struct ExploredPixels
	{
		private readonly bool[] _ownArray;

		private readonly bool[] _sharedArray;

		private readonly BitArray _ownBits;

		private readonly BitArray _sharedBits;

		internal readonly bool Valid;

		internal ExploredPixels(object own, object shared, int size)
		{
			_ownArray = own as bool[];
			_ownBits = own as BitArray;
			_sharedArray = ((shared is bool[] array && array.Length == size) ? array : null);
			_sharedBits = ((shared is BitArray bitArray && bitArray.Length == size) ? bitArray : null);
			bool[] ownArray = _ownArray;
			int valid;
			if (ownArray == null || ownArray.Length != size)
			{
				BitArray ownBits = _ownBits;
				valid = ((ownBits != null && ownBits.Length == size) ? 1 : 0);
			}
			else
			{
				valid = 1;
			}
			Valid = (byte)valid != 0;
		}

		internal bool Contains(int pixel)
		{
			if (Valid)
			{
				bool[] ownArray = _ownArray;
				if (!((ownArray != null) ? ownArray[pixel] : _ownBits[pixel]))
				{
					bool[] sharedArray = _sharedArray;
					if (sharedArray == null)
					{
						return _sharedBits?[pixel] ?? false;
					}
					return sharedArray[pixel];
				}
				return true;
			}
			return false;
		}
	}
	internal sealed class BiomeAtlas
	{
		private readonly byte[] _biomes;

		private readonly BiomeEdge[] _edges;

		private readonly int[] _rows;

		internal int Width { get; }

		internal int Height { get; }

		internal int KnownPixels { get; }

		internal BiomeAtlas(int width, int height, byte[] biomes, CancellationToken stop = default(CancellationToken))
		{
			if (width < 1 || height < 1 || biomes.Length != checked(width * height))
			{
				throw new ArgumentException("The biome grid dimensions do not match its data.");
			}
			Width = width;
			Height = height;
			_biomes = biomes;
			_rows = new int[height + 1];
			List<BiomeEdge> list = new List<BiomeEdge>();
			int num = 0;
			for (int i = 0; i < height; i++)
			{
				stop.ThrowIfCancellationRequested();
				_rows[i] = list.Count;
				for (int j = 0; j < width; j++)
				{
					int num2 = i * width + j;
					byte b = biomes[num2];
					if (b != 0)
					{
						num++;
						if (j > 0 && IsDifferent(b, biomes[num2 - 1]))
						{
							list.Add(new BiomeEdge(j, i, vertical: true));
						}
						if (i > 0 && IsDifferent(b, biomes[num2 - width]))
						{
							list.Add(new BiomeEdge(j, i, vertical: false));
						}
					}
				}
			}
			_rows[height] = list.Count;
			_edges = list.ToArray();
			KnownPixels = num;
		}

		private static bool IsDifferent(byte a, byte b)
		{
			if (b != 0)
			{
				return a != b;
			}
			return false;
		}

		internal void VisibleEdges(PixelBounds view, ExploredPixels explored, List<BiomeEdge> result)
		{
			result.Clear();
			if (!explored.Valid || view.Right <= view.Left || view.Top <= view.Bottom)
			{
				return;
			}
			int num = Math.Max(0, view.Bottom);
			int num2 = Math.Min(Height, view.Top + 1);
			for (int i = num; i < num2; i++)
			{
				for (int j = _rows[i]; j < _rows[i + 1]; j++)
				{
					BiomeEdge item = _edges[j];
					if (item.X >= view.Left && item.X <= view.Right && !(item.Vertical ? (i == view.Top) : (item.X == view.Right)))
					{
						int num3 = i * Width + item.X;
						int pixel = num3 - (item.Vertical ? 1 : Width);
						if (explored.Contains(num3) && explored.Contains(pixel))
						{
							result.Add(item);
						}
					}
				}
			}
		}

		internal void VisibleLabels(PixelBounds view, ExploredPixels explored, List<BiomeLabel> result)
		{
			result.Clear();
			if (!explored.Valid)
			{
				return;
			}
			int num = 1;
			while ((view.Right - view.Left) / num > 70 || (view.Top - view.Bottom) / num > 50)
			{
				num *= 2;
			}
			int num2 = SampleStart(Math.Max(0, view.Left), num);
			int num3 = SampleStart(Math.Max(0, view.Bottom), num);
			int num4 = Math.Min(Width, view.Right);
			int num5 = Math.Min(Height, view.Top);
			if (num2 >= num4 || num3 >= num5)
			{
				return;
			}
			int num6 = (num4 - 1 - num2) / num + 1;
			int num7 = (num5 - 1 - num3) / num + 1;
			byte[] array = new byte[num6 * num7];
			bool[] array2 = new bool[array.Length];
			int[] array3 = new int[array.Length];
			for (int i = 0; i < num7; i++)
			{
				for (int j = 0; j < num6; j++)
				{
					int num8 = (num3 + i * num) * Width + num2 + j * num;
					if (explored.Contains(num8))
					{
						array[i * num6 + j] = _biomes[num8];
					}
				}
			}
			for (int k = 0; k < array.Length; k++)
			{
				byte b = array[k];
				if (b == 0 || array2[k])
				{
					continue;
				}
				int count = 1;
				int num9 = 0;
				int num10 = 0;
				array3[0] = k;
				array2[k] = true;
				for (int l = 0; l < count; l++)
				{
					int num11 = array3[l];
					int num12 = num11 % num6;
					int num13 = num11 / num6;
					num9 += num12;
					num10 += num13;
					if (num12 > 0)
					{
						Visit(num11 - 1, b, array, array2, array3, ref count);
					}
					if (num12 + 1 < num6)
					{
						Visit(num11 + 1, b, array, array2, array3, ref count);
					}
					if (num13 > 0)
					{
						Visit(num11 - num6, b, array, array2, array3, ref count);
					}
					if (num13 + 1 < num7)
					{
						Visit(num11 + num6, b, array, array2, array3, ref count);
					}
				}
				if (count < 4)
				{
					continue;
				}
				float num14 = (float)num9 / (float)count;
				float num15 = (float)num10 / (float)count;
				int num16 = array3[0];
				int num17 = -1;
				float num18 = float.MaxValue;
				for (int m = 0; m < count; m++)
				{
					int num19 = array3[m];
					int num20 = num19 % num6;
					int num21 = num19 / num6;
					int num22 = 0;
					if (num20 > 0 && array[num19 - 1] == b)
					{
						num22++;
					}
					if (num20 + 1 < num6 && array[num19 + 1] == b)
					{
						num22++;
					}
					if (num21 > 0 && array[num19 - num6] == b)
					{
						num22++;
					}
					if (num21 + 1 < num7 && array[num19 + num6] == b)
					{
						num22++;
					}
					float num23 = (float)num20 - num14;
					float num24 = (float)num21 - num15;
					float num25 = num23 * num23 + num24 * num24;
					if (num22 >= num17 && (num22 != num17 || !(num25 >= num18)))
					{
						num16 = num19;
						num17 = num22;
						num18 = num25;
					}
				}
				result.Add(new BiomeLabel(num2 + num16 % num6 * num, num3 + num16 / num6 * num, b, count * num * num));
			}
			result.Sort(delegate(BiomeLabel a, BiomeLabel biomeLabel)
			{
				int area = biomeLabel.Area;
				return area.CompareTo(a.Area);
			});
		}

		private static int SampleStart(int minimum, int step)
		{
			int num = minimum / step * step + step / 2;
			if (num >= minimum)
			{
				return num;
			}
			return num + step;
		}

		private static void Visit(int pixel, byte biome, byte[] samples, bool[] visited, int[] queue, ref int count)
		{
			if (!visited[pixel] && samples[pixel] == biome)
			{
				visited[pixel] = true;
				queue[count++] = pixel;
			}
		}
	}
	internal readonly struct PixelProjection
	{
		private readonly float _pixelLeft;

		private readonly float _pixelBottom;

		private readonly float _localLeft;

		private readonly float _localBottom;

		internal readonly float ScaleX;

		internal readonly float ScaleY;

		internal readonly PixelBounds Bounds;

		internal PixelProjection(int width, int height, float u, float v, float uSize, float vSize, float localLeft, float localBottom, float localWidth, float localHeight)
		{
			_pixelLeft = u * (float)width;
			_pixelBottom = v * (float)height;
			_localLeft = localLeft;
			_localBottom = localBottom;
			ScaleX = localWidth / (uSize * (float)width);
			ScaleY = localHeight / (vSize * (float)height);
			Bounds = new PixelBounds((int)Math.Floor(Clamp(_pixelLeft, width)), (int)Math.Floor(Clamp(_pixelBottom, height)), (int)Math.Ceiling(Clamp((u + uSize) * (float)width, width)), (int)Math.Ceiling(Clamp((v + vSize) * (float)height, height)));
		}

		internal float X(float pixel)
		{
			return _localLeft + (pixel - _pixelLeft) * ScaleX;
		}

		internal float Y(float pixel)
		{
			return _localBottom + (pixel - _pixelBottom) * ScaleY;
		}

		private static float Clamp(float value, int limit)
		{
			return Math.Max(0f, Math.Min(limit, value));
		}
	}
	[BepInPlugin("benjsammy.biomeborders", "Biome Borders by BenjSammy", "1.0.0")]
	public sealed class BiomeBordersPlugin : BaseUnityPlugin
	{
		private ConfigEntry<bool> _showCurrent;

		private ConfigEntry<bool> _showBorders;

		private ConfigEntry<bool> _showNames;

		private GameMap _game;

		private MapOverlay _overlay;

		private Component _map;

		private Texture2D _source;

		private Task<BiomeAtlas> _building;

		private CancellationTokenSource _buildStop;

		private BiomeAtlas _atlas;

		private string[] _names;

		private readonly List<BiomeEdge> _edges = new List<BiomeEdge>();

		private readonly List<BiomeLabel> _labels = new List<BiomeLabel>();

		private RectTransform _mini;

		private RectTransform _large;

		private string _current = string.Empty;

		private PixelProjection _projection;

		private Rect _lastUv;

		private Rect _lastRect;

		private int _lastWidth;

		private int _lastHeight;

		private bool _mapOpen;

		private bool _shared;

		private bool _bordersVisible;

		private bool _namesVisible;

		private bool _failedAtlas;

		private float _nextHud;

		private float _nextFog;

		private float _nextNames;

		private float _nextWarning;

		private void Awake()
		{
			if (Application.isBatchMode)
			{
				return;
			}
			_showCurrent = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowCurrentBiome", true, "Show the current biome below the minimap.");
			_showBorders = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowBorders", true, "Draw biome boundaries on the explored world map.");
			_showNames = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowBiomeNames", true, "Label the larger visible biome regions.");
			try
			{
				_game = new GameMap();
				_overlay = new MapOverlay();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Biome Borders 1.0.0 ready. Client only.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Biome Borders could not bind the Valheim map API. " + ex));
			}
		}

		private void LateUpdate()
		{
			if (_game == null || _overlay == null)
			{
				return;
			}
			try
			{
				Component minimap = _game.Minimap;
				Component player = _game.Player;
				if ((Object)(object)_map != (Object)(object)minimap)
				{
					ResetAtlas();
					_map = minimap;
					_nextHud = 0f;
				}
				if (!Object.op_Implicit((Object)(object)minimap) || !Object.op_Implicit((Object)(object)player))
				{
					_mini = null;
					HideLargeMap();
					return;
				}
				float unscaledTime = Time.unscaledTime;
				_mini = ((_showCurrent.Value && _game.IsSmall(minimap)) ? _game.SmallRect(minimap) : null);
				if (Object.op_Implicit((Object)(object)_mini) && unscaledTime >= _nextHud)
				{
					_nextHud = unscaledTime + 0.25f;
					_current = _game.CurrentBiome(player);
				}
				if (!_game.IsLarge(minimap) || (!_showBorders.Value && !_showNames.Value) || !_game.Ready(minimap))
				{
					HideLargeMap();
				}
				else
				{
					UpdateLargeMap(minimap, unscaledTime);
				}
			}
			catch (Exception error)
			{
				HideLargeMap();
				Report(error);
			}
		}

		private void UpdateLargeMap(Component map, float now)
		{
			//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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = _game.Texture(map);
			if ((Object)(object)_source != (Object)(object)val)
			{
				ResetAtlas();
				_source = val;
			}
			if (!Object.op_Implicit((Object)(object)val) || _failedAtlas || !_game.TryReadLargeView(map, out var transform, out var uv))
			{
				HideLargeMap();
				return;
			}
			bool flag = _game.SharedVisible(map);
			ExploredPixels explored = _game.Exploration(map, flag, ((Texture)val).width * ((Texture)val).height);
			if (!explored.Valid)
			{
				HideLargeMap();
				return;
			}
			if (!EnsureAtlas(map, val))
			{
				return;
			}
			Rect rect = transform.rect;
			if (((Rect)(ref rect)).width < 1f || ((Rect)(ref rect)).height < 1f)
			{
				HideLargeMap();
				return;
			}
			int num;
			int num2;
			if (_mapOpen)
			{
				num = (((Object)(object)_large != (Object)(object)transform) ? 1 : 0);
				if (num == 0 && !(uv != _lastUv) && !(rect != _lastRect) && Screen.width == _lastWidth)
				{
					num2 = ((Screen.height != _lastHeight) ? 1 : 0);
					goto IL_0117;
				}
			}
			else
			{
				num = 1;
			}
			num2 = 1;
			goto IL_0117;
			IL_0117:
			bool flag2 = (byte)num2 != 0;
			bool flag3 = num != 0 || now >= _nextFog || flag != _shared;
			if (flag2)
			{
				_projection = new PixelProjection(_atlas.Width, _atlas.Height, ((Rect)(ref uv)).xMin, ((Rect)(ref uv)).yMin, ((Rect)(ref uv)).width, ((Rect)(ref uv)).height, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMin, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height);
				_lastUv = uv;
				_lastRect = rect;
				_lastWidth = Screen.width;
				_lastHeight = Screen.height;
			}
			if (flag3)
			{
				_nextFog = now + 0.6f;
				_shared = flag;
			}
			_large = transform;
			_mapOpen = true;
			if (_showBorders.Value)
			{
				if (!_bordersVisible || flag2 || flag3)
				{
					_atlas.VisibleEdges(_projection.Bounds, explored, _edges);
					_overlay.DrawBorders(transform, _projection, _edges);
					_bordersVisible = true;
				}
			}
			else if (_bordersVisible)
			{
				_overlay.HideBorders();
				_bordersVisible = false;
			}
			if (_showNames.Value)
			{
				if (!_namesVisible || flag3 || now >= _nextNames)
				{
					_atlas.VisibleLabels(_projection.Bounds, explored, _labels);
					_nextNames = now + 0.3f;
					_namesVisible = true;
				}
			}
			else
			{
				_labels.Clear();
				_namesVisible = false;
			}
		}

		private bool EnsureAtlas(Component map, Texture2D texture)
		{
			if (_atlas != null)
			{
				return true;
			}
			try
			{
				if (_building == null)
				{
					int width = ((Texture)texture).width;
					int height = ((Texture)texture).height;
					if (width < 2 || height < 2 || width > 4096 || height > 4096)
					{
						throw new InvalidOperationException("Unsupported world map texture dimensions.");
					}
					string[] names;
					Dictionary<int, byte> palette = _game.ReadPalette(map, out names);
					_names = new string[names.Length];
					for (int i = 1; i < names.Length; i++)
					{
						_names[i] = _game.LocalizedBiome(names[i]);
					}
					Color32[] pixels = texture.GetPixels32();
					_buildStop = new CancellationTokenSource();
					CancellationToken stop = _buildStop.Token;
					_building = Task.Run(() => CreateAtlas(width, height, pixels, palette, stop), stop);
					return false;
				}
				if (!_building.IsCompleted)
				{
					return false;
				}
				_atlas = _building.GetAwaiter().GetResult();
				StopBuilding();
				if (_atlas.KnownPixels == 0)
				{
					throw new InvalidOperationException("The map texture does not contain the known biome palette.");
				}
				return true;
			}
			catch (Exception error)
			{
				StopBuilding();
				_atlas = null;
				_failedAtlas = true;
				Report(error);
				return false;
			}
		}

		private static BiomeAtlas CreateAtlas(int width, int height, Color32[] pixels, Dictionary<int, byte> palette, CancellationToken stop)
		{
			//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)
			//IL_0028: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = new byte[pixels.Length];
			for (int i = 0; i < height; i++)
			{
				stop.ThrowIfCancellationRequested();
				for (int j = 0; j < width; j++)
				{
					int num = i * width + j;
					Color32 val = pixels[num];
					palette.TryGetValue(GameMap.ColorKey(val.r, val.g, val.b), out array[num]);
				}
			}
			return new BiomeAtlas(width, height, array, stop);
		}

		private void OnGUI()
		{
			//IL_00c7: 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_0013: Invalid comparison between Unknown and I4
			//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_0022: Unknown result type (might be due to invalid IL or missing references)
			if (_overlay == null || (int)Event.current.type != 7)
			{
				return;
			}
			Color color = GUI.color;
			int depth = GUI.depth;
			try
			{
				GUI.color = Color.white;
				GUI.depth = -90;
				if (Object.op_Implicit((Object)(object)_mini) && ((Component)_mini).gameObject.activeInHierarchy)
				{
					_overlay.DrawCurrentBiome(_mini, _current);
				}
				if (_mapOpen && Object.op_Implicit((Object)(object)_large) && ((Component)_large).gameObject.activeInHierarchy && _namesVisible)
				{
					_overlay.DrawNames(_large, _projection, _labels, _names);
				}
			}
			catch (Exception error)
			{
				Report(error);
			}
			finally
			{
				GUI.color = color;
				GUI.depth = depth;
			}
		}

		private void HideLargeMap()
		{
			_overlay?.HideBorders();
			_mapOpen = false;
			_large = null;
			_bordersVisible = false;
			_namesVisible = false;
		}

		private void StopBuilding()
		{
			_buildStop?.Cancel();
			_buildStop?.Dispose();
			_buildStop = null;
			_building = null;
		}

		private void ResetAtlas()
		{
			HideLargeMap();
			StopBuilding();
			_overlay?.ClearMap();
			_atlas = null;
			_source = null;
			_names = null;
			_failedAtlas = false;
			_labels.Clear();
			_edges.Clear();
		}

		private void Report(Exception error)
		{
			if (!(Time.unscaledTime < _nextWarning))
			{
				_nextWarning = Time.unscaledTime + 15f;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Biome Borders: " + error));
			}
		}

		private void OnDestroy()
		{
			StopBuilding();
			_overlay?.Dispose();
		}
	}
	internal sealed class GameMap
	{
		private const BindingFlags Members = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private readonly MemberInfo _mapInstance;

		private readonly MemberInfo _localizationInstance;

		private readonly FieldInfo _localPlayer;

		private readonly FieldInfo _mode;

		private readonly FieldInfo _smallImage;

		private readonly FieldInfo _largeImage;

		private readonly FieldInfo _texture;

		private readonly FieldInfo _explored;

		private readonly FieldInfo _others;

		private readonly FieldInfo _showShared;

		private readonly FieldInfo _generated;

		private readonly MethodInfo _currentBiome;

		private readonly MethodInfo _pixelColor;

		private readonly MethodInfo _localize;

		private readonly PropertyInfo _uvRect;

		private readonly object _small;

		private readonly object _large;

		private readonly Array _biomeValues;

		internal Component Minimap
		{
			get
			{
				object obj = ReadSingleton(_mapInstance);
				return (Component)((obj is Component) ? obj : null);
			}
		}

		internal Component Player
		{
			get
			{
				object? value = _localPlayer.GetValue(null);
				return (Component)((value is Component) ? value : null);
			}
		}

		internal GameMap()
		{
			Type type = FindType("Minimap");
			Type type2 = FindType("Player");
			Type type3 = FindType("Heightmap+Biome");
			Type type4 = FindType("Localization", required: false);
			_mapInstance = FindSingleton(type);
			_localPlayer = RequireField(type2, "m_localPlayer");
			_mode = RequireField(type, "m_mode");
			_small = Enum.Parse(_mode.FieldType, "Small");
			_large = Enum.Parse(_mode.FieldType, "Large");
			_smallImage = RequireField(type, "m_mapImageSmall");
			_largeImage = RequireField(type, "m_mapImageLarge");
			_texture = RequireField(type, "m_mapTexture");
			_explored = RequireField(type, "m_explored");
			_others = type.GetField("m_exploredOthers", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			_showShared = type.GetField("m_showSharedMapData", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			_generated = type.GetField("m_hasGenerated", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			_uvRect = _largeImage.FieldType.GetProperty("uvRect", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMemberException("RawImage.uvRect");
			_pixelColor = RequireMethod(type, "GetPixelColor", type3);
			_currentBiome = RequireMethod(type2, "GetCurrentBiome");
			_biomeValues = Enum.GetValues(type3);
			if (type4 != null)
			{
				_localizationInstance = FindSingleton(type4, required: false);
				_localize = type4.GetMethod("Localize", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null) ?? type4.GetMethod("Localize", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
				{
					typeof(string),
					typeof(string[])
				}, null);
			}
		}

		internal bool IsSmall(Component map)
		{
			return _small.Equals(_mode.GetValue(map));
		}

		internal bool IsLarge(Component map)
		{
			return _large.Equals(_mode.GetValue(map));
		}

		internal bool Ready(Component map)
		{
			if (!(_generated == null))
			{
				return (bool)_generated.GetValue(map);
			}
			return true;
		}

		internal RectTransform SmallRect(Component map)
		{
			return ImageRect(_smallImage.GetValue(map));
		}

		internal Texture2D Texture(Component map)
		{
			object? value = _texture.GetValue(map);
			return (Texture2D)((value is Texture2D) ? value : null);
		}

		internal bool SharedVisible(Component map)
		{
			if (_showShared != null)
			{
				return (bool)_showShared.GetValue(map);
			}
			return false;
		}

		private static RectTransform ImageRect(object image)
		{
			Component val = (Component)((image is Component) ? image : null);
			if (!Object.op_Implicit((Object)(object)val) || !val.gameObject.activeInHierarchy)
			{
				return null;
			}
			Transform transform = val.transform;
			return (RectTransform)(object)((transform is RectTransform) ? transform : null);
		}

		internal bool TryReadLargeView(Component map, out RectTransform transform, out Rect uv)
		{
			//IL_0037: 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_0027: 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)
			object value = _largeImage.GetValue(map);
			transform = ImageRect(value);
			uv = (Object.op_Implicit((Object)(object)transform) ? ((Rect)_uvRect.GetValue(value, null)) : default(Rect));
			if (Object.op_Implicit((Object)(object)transform) && ((Rect)(ref uv)).width > 1E-05f && ((Rect)(ref uv)).height > 1E-05f && IsFinite(((Rect)(ref uv)).xMin) && IsFinite(((Rect)(ref uv)).yMin) && IsFinite(((Rect)(ref uv)).xMax))
			{
				return IsFinite(((Rect)(ref uv)).yMax);
			}
			return false;
		}

		internal ExploredPixels Exploration(Component map, bool showShared, int length)
		{
			return new ExploredPixels(_explored.GetValue(map), (!showShared) ? null : _others?.GetValue(map), length);
		}

		internal string CurrentBiome(Component player)
		{
			object obj = _currentBiome.Invoke(player, null);
			if (obj == null || Convert.ToInt64(obj) == 0L)
			{
				return string.Empty;
			}
			return LocalizedBiome(obj.ToString());
		}

		internal string LocalizedBiome(string biome)
		{
			object obj = ReadSingleton(_localizationInstance);
			if (_localize != null && obj != null)
			{
				string text = "biome_" + biome.ToLowerInvariant();
				string text2 = "$" + text;
				object[] parameters = ((_localize.GetParameters().Length != 1) ? new object[2]
				{
					text2,
					Array.Empty<string>()
				} : new object[1] { text2 });
				string text3 = _localize.Invoke(obj, parameters) as string;
				if (!string.IsNullOrWhiteSpace(text3) && text3 != text2 && text3 != text && text3 != "[" + text + "]")
				{
					return text3;
				}
			}
			if (biome == "AshLands")
			{
				return "Ashlands";
			}
			StringBuilder stringBuilder = new StringBuilder(biome.Length + 6);
			for (int i = 0; i < biome.Length; i++)
			{
				if (i > 0 && char.IsUpper(biome[i]) && char.IsLower(biome[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(biome[i]);
			}
			return stringBuilder.ToString();
		}

		internal Dictionary<int, byte> ReadPalette(Component map, out string[] names)
		{
			//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_007a: 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)
			//IL_0083: 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)
			Dictionary<int, byte> dictionary = new Dictionary<int, byte>();
			List<string> list = new List<string> { string.Empty };
			foreach (object biomeValue in _biomeValues)
			{
				long num = Convert.ToInt64(biomeValue);
				if (num > 0 && (num & (num - 1)) == 0L && list.Count < 256)
				{
					Color32 val = Color32.op_Implicit((Color)_pixelColor.Invoke(map, new object[1] { biomeValue }));
					int key = ColorKey(val.r, val.g, val.b);
					byte b = (byte)list.Count;
					list.Add(biomeValue.ToString());
					dictionary[key] = (byte)((!dictionary.ContainsKey(key)) ? b : 0);
				}
			}
			names = list.ToArray();
			Dictionary<int, byte> dictionary2 = new Dictionary<int, byte>();
			foreach (KeyValuePair<int, byte> item in dictionary)
			{
				if (item.Value == 0)
				{
					continue;
				}
				int num2 = item.Key & 0xFF;
				int num3 = (item.Key >> 8) & 0xFF;
				int num4 = item.Key >> 16;
				for (int i = Math.Max(0, num2 - 1); i <= Math.Min(255, num2 + 1); i++)
				{
					for (int j = Math.Max(0, num3 - 1); j <= Math.Min(255, num3 + 1); j++)
					{
						for (int k = Math.Max(0, num4 - 1); k <= Math.Min(255, num4 + 1); k++)
						{
							int key2 = ColorKey(i, j, k);
							if (dictionary2.TryGetValue(key2, out var value) && value != item.Value)
							{
								dictionary2[key2] = 0;
							}
							else
							{
								dictionary2[key2] = item.Value;
							}
						}
					}
				}
			}
			foreach (KeyValuePair<int, byte> item2 in dictionary)
			{
				dictionary2[item2.Key] = item2.Value;
			}
			return dictionary2;
		}

		internal static int ColorKey(int r, int g, int b)
		{
			return r | (g << 8) | (b << 16);
		}

		private static bool IsFinite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		private static Type FindType(string name, bool required = true)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				Type type = assemblies[i].GetType(name, throwOnError: false);
				if (type != null)
				{
					return type;
				}
			}
			if (required)
			{
				throw new TypeLoadException(name);
			}
			return null;
		}

		private static FieldInfo RequireField(Type type, string name)
		{
			return type.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingFieldException(type.Name, name);
		}

		private static MethodInfo RequireMethod(Type type, string name, params Type[] args)
		{
			return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, args, null) ?? throw new MissingMethodException(type.Name, name);
		}

		private static MemberInfo FindSingleton(Type type, bool required = true)
		{
			MemberInfo memberInfo = (MemberInfo)(((object)type.GetProperty("instance", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)(type.GetField("instance", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("m_instance", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))));
			if (required && memberInfo == null)
			{
				throw new MissingMemberException(type.Name, "instance");
			}
			return memberInfo;
		}

		private static object ReadSingleton(MemberInfo member)
		{
			if (member is PropertyInfo propertyInfo)
			{
				return propertyInfo.GetValue(null, null);
			}
			return (member as FieldInfo)?.GetValue(null);
		}
	}
	internal sealed class MapOverlay : IDisposable
	{
		private sealed class Layer
		{
			internal readonly CanvasRenderer Renderer;

			internal readonly Mesh Mesh;

			internal Layer(RectTransform parent, Material material)
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Expected O, but got Unknown
				//IL_0037: 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_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: 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_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: 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_006d: 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_009f: 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_00b4: Expected O, but got Unknown
				GameObject val = new GameObject("Biome Borders", new Type[2]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer)
				});
				RectTransform val2 = (RectTransform)val.transform;
				((Transform)val2).SetParent((Transform)(object)parent, false);
				((Transform)val2).SetAsFirstSibling();
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.pivot = parent.pivot;
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
				Renderer = val.GetComponent<CanvasRenderer>();
				Renderer.SetMaterial(material, (Texture)(object)Texture2D.whiteTexture);
				Mesh = new Mesh
				{
					name = "Biome Borders mesh"
				};
				Mesh.MarkDynamic();
			}
		}

		private const int EdgesPerMesh = 7000;

		private static readonly Color32 HaloColor = new Color32((byte)238, (byte)228, (byte)195, (byte)210);

		private static readonly Color32 LineColor = new Color32((byte)30, (byte)28, (byte)24, (byte)242);

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

		private readonly List<Vector3> _vertices = new List<Vector3>();

		private readonly List<Color32> _colors = new List<Color32>();

		private readonly List<int> _triangles = new List<int>();

		private readonly List<Rect> _occupied = new List<Rect>();

		private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];

		private RectTransform _parent;

		private Material _material;

		private GUIStyle _label;

		private GUIStyle _shadow;

		private int _fontSize;

		private static float UiScale => Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 1.75f);

		internal void DrawBorders(RectTransform map, PixelProjection projection, List<BiomeEdge> edges)
		{
			//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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_012c: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_parent != (Object)(object)map)
			{
				ClearMap();
				_parent = map;
			}
			if (edges.Count == 0)
			{
				HideBorders();
				return;
			}
			if (!Object.op_Implicit((Object)(object)_material))
			{
				Shader val = Shader.Find("UI/Default");
				if (!Object.op_Implicit((Object)(object)val))
				{
					throw new InvalidOperationException("Valheim's UI shader is unavailable.");
				}
				_material = new Material(val)
				{
					name = "Biome Borders UI",
					hideFlags = (HideFlags)61
				};
			}
			Rect rect = map.rect;
			Rect val2 = ScreenRect(map);
			float height = ((Rect)(ref val2)).height;
			float num = ((height > 1f) ? (((Rect)(ref rect)).height / height) : 1f) * UiScale;
			int num2 = 0;
			for (int i = 0; i < edges.Count; i += 7000)
			{
				int end = Math.Min(i + 7000, edges.Count);
				if (num2 == _layers.Count)
				{
					_layers.Add(new Layer(map, _material));
				}
				Layer layer = _layers[num2++];
				_vertices.Clear();
				_colors.Clear();
				_triangles.Clear();
				AddStroke(edges, i, end, projection, rect, 1.6f * num, HaloColor);
				AddStroke(edges, i, end, projection, rect, 0.75f * num, LineColor);
				layer.Mesh.Clear();
				layer.Mesh.SetVertices(_vertices);
				layer.Mesh.SetColors(_colors);
				layer.Mesh.SetTriangles(_triangles, 0);
				if (!((Component)layer.Renderer).gameObject.activeSelf)
				{
					((Component)layer.Renderer).gameObject.SetActive(true);
				}
				layer.Renderer.SetMesh(layer.Mesh);
			}
			for (int j = num2; j < _layers.Count; j++)
			{
				((Component)_layers[j].Renderer).gameObject.SetActive(false);
			}
		}

		private void AddStroke(List<BiomeEdge> edges, int start, int end, PixelProjection projection, Rect clip, float halfWidth, Color32 color)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			for (int i = start; i < end; i++)
			{
				BiomeEdge biomeEdge = edges[i];
				float num = projection.X(biomeEdge.X);
				float num2 = projection.Y(biomeEdge.Y);
				float num3 = num + (biomeEdge.Vertical ? 0f : projection.ScaleX);
				float num4 = num2 + (biomeEdge.Vertical ? projection.ScaleY : 0f);
				AddQuad(Mathf.Max(((Rect)(ref clip)).xMin, num - halfWidth), Mathf.Max(((Rect)(ref clip)).yMin, num2 - halfWidth), Mathf.Min(((Rect)(ref clip)).xMax, num3 + halfWidth), Mathf.Min(((Rect)(ref clip)).yMax, num4 + halfWidth), color);
			}
		}

		private void AddQuad(float x0, float y0, float x1, float y1, Color32 color)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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 (!(x0 >= x1) && !(y0 >= y1))
			{
				int count = _vertices.Count;
				_vertices.Add(new Vector3(x0, y0));
				_vertices.Add(new Vector3(x0, y1));
				_vertices.Add(new Vector3(x1, y1));
				_vertices.Add(new Vector3(x1, y0));
				for (int i = 0; i < 4; i++)
				{
					_colors.Add(color);
				}
				_triangles.Add(count);
				_triangles.Add(count + 1);
				_triangles.Add(count + 2);
				_triangles.Add(count + 2);
				_triangles.Add(count + 3);
				_triangles.Add(count);
			}
		}

		internal void DrawNames(RectTransform map, PixelProjection projection, List<BiomeLabel> labels, string[] names)
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_00e9: 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_0101: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			if (labels.Count == 0)
			{
				return;
			}
			EnsureStyles();
			Rect val = ScreenRect(map);
			Camera canvasCamera = GetCanvasCamera(map);
			float uiScale = UiScale;
			float num = ((Rect)(ref val)).width * ((Rect)(ref val)).height;
			Rect rect = map.rect;
			float width = ((Rect)(ref rect)).width;
			rect = map.rect;
			float num2 = num / (width * ((Rect)(ref rect)).height) * projection.ScaleX * projection.ScaleY;
			_occupied.Clear();
			Rect rect2 = default(Rect);
			foreach (BiomeLabel label in labels)
			{
				if (_occupied.Count >= 12)
				{
					break;
				}
				if ((float)label.Area * num2 < 950f * uiScale * uiScale)
				{
					continue;
				}
				Vector3 val2 = ((Transform)map).TransformPoint(new Vector3(projection.X((float)label.X + 0.5f), projection.Y((float)label.Y + 0.5f)));
				Vector2 val3 = RectTransformUtility.WorldToScreenPoint(canvasCamera, val2);
				GUIContent val4 = new GUIContent(names[label.Biome]);
				Vector2 val5 = _label.CalcSize(val4);
				((Rect)(ref rect2))..ctor(val3.x - val5.x / 2f, (float)Screen.height - val3.y - val5.y / 2f, val5.x, val5.y);
				Rect val6 = Rect.MinMaxRect(((Rect)(ref rect2)).xMin - 9f * uiScale, ((Rect)(ref rect2)).yMin - 5f * uiScale, ((Rect)(ref rect2)).xMax + 9f * uiScale, ((Rect)(ref rect2)).yMax + 5f * uiScale);
				if (((Rect)(ref val6)).xMin < ((Rect)(ref val)).xMin || ((Rect)(ref val6)).xMax > ((Rect)(ref val)).xMax || ((Rect)(ref val6)).yMin < ((Rect)(ref val)).yMin || ((Rect)(ref val6)).yMax > ((Rect)(ref val)).yMax)
				{
					continue;
				}
				bool flag = false;
				foreach (Rect item in _occupied)
				{
					Rect current2 = item;
					if (((Rect)(ref current2)).Overlaps(val6))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					_occupied.Add(val6);
					DrawLabel(rect2, val4);
				}
			}
		}

		internal void DrawCurrentBiome(RectTransform miniMap, string name)
		{
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00f9: 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)
			if (!string.IsNullOrEmpty(name))
			{
				EnsureStyles();
				Rect val = ScreenRect(miniMap);
				float uiScale = UiScale;
				GUIContent val2 = new GUIContent("Biome · " + name);
				Vector2 val3 = _label.CalcSize(val2);
				float num = Mathf.Min(val3.x + 20f * uiScale, (float)Screen.width - 8f);
				float num2 = val3.y + 8f * uiScale;
				float num3 = Mathf.Clamp(((Rect)(ref val)).center.x - num / 2f, 4f, (float)Screen.width - num - 4f);
				float num4 = Mathf.Clamp(((Rect)(ref val)).yMax + 6f * uiScale, 4f, (float)Screen.height - num2 - 4f);
				Rect val4 = default(Rect);
				((Rect)(ref val4))..ctor(num3, num4, num, num2);
				GUI.color = new Color(0.04f, 0.04f, 0.04f, 0.72f);
				GUI.DrawTexture(val4, (Texture)(object)Texture2D.whiteTexture);
				GUI.color = Color.white;
				DrawLabel(val4, val2);
			}
		}

		private void EnsureStyles()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0071: Expected O, but got Unknown
			//IL_008b: 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_00a6: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.RoundToInt(15f * UiScale);
			if (_label == null || num != _fontSize)
			{
				_fontSize = num;
				_label = new GUIStyle(GUI.skin.label)
				{
					fontSize = num,
					alignment = (TextAnchor)4,
					fontStyle = (FontStyle)1,
					richText = false,
					wordWrap = false,
					padding = new RectOffset(0, 0, 0, 0)
				};
				_label.normal.textColor = new Color(1f, 0.97f, 0.89f);
				_shadow = new GUIStyle(_label);
				_shadow.normal.textColor = new Color(0.065f, 0.055f, 0.04f, 0.95f);
			}
		}

		private void DrawLabel(Rect rect, GUIContent content)
		{
			//IL_0024: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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)
			float uiScale = UiScale;
			GUI.Label(new Rect(((Rect)(ref rect)).x - uiScale, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), content, _shadow);
			GUI.Label(new Rect(((Rect)(ref rect)).x + uiScale, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), content, _shadow);
			GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y - uiScale, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), content, _shadow);
			GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + uiScale, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), content, _shadow);
			GUI.Label(rect, content, _label);
		}

		private Rect ScreenRect(RectTransform transform)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			transform.GetWorldCorners(_corners);
			Camera canvasCamera = GetCanvasCamera(transform);
			float num = float.PositiveInfinity;
			float num2 = float.PositiveInfinity;
			float num3 = float.NegativeInfinity;
			float num4 = float.NegativeInfinity;
			Vector3[] corners = _corners;
			foreach (Vector3 val in corners)
			{
				Vector2 val2 = RectTransformUtility.WorldToScreenPoint(canvasCamera, val);
				float num5 = (float)Screen.height - val2.y;
				num = Mathf.Min(num, val2.x);
				num2 = Mathf.Min(num2, num5);
				num3 = Mathf.Max(num3, val2.x);
				num4 = Mathf.Max(num4, num5);
			}
			return Rect.MinMaxRect(num, num2, num3, num4);
		}

		private static Camera GetCanvasCamera(RectTransform transform)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Canvas componentInParent = ((Component)transform).GetComponentInParent<Canvas>();
			if (!Object.op_Implicit((Object)(object)componentInParent) || (int)componentInParent.renderMode == 0)
			{
				return null;
			}
			if (!Object.op_Implicit((Object)(object)componentInParent.worldCamera))
			{
				return Camera.main;
			}
			return componentInParent.worldCamera;
		}

		internal void HideBorders()
		{
			foreach (Layer layer in _layers)
			{
				if (Object.op_Implicit((Object)(object)layer.Renderer) && ((Component)layer.Renderer).gameObject.activeSelf)
				{
					((Component)layer.Renderer).gameObject.SetActive(false);
				}
			}
		}

		internal void ClearMap()
		{
			foreach (Layer layer in _layers)
			{
				if (Object.op_Implicit((Object)(object)layer.Renderer))
				{
					Object.Destroy((Object)(object)((Component)layer.Renderer).gameObject);
				}
				Object.Destroy((Object)(object)layer.Mesh);
			}
			_layers.Clear();
			_parent = null;
		}

		public void Dispose()
		{
			ClearMap();
			if (Object.op_Implicit((Object)(object)_material))
			{
				Object.Destroy((Object)(object)_material);
			}
		}
	}
}