Decompiled source of MySix Cartographer v0.9.2

MySix.Cartographer.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MySix.Core;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("MySix.TestHarness")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace MySix
{
	internal static class ModVersion
	{
		public const string Value = "0.9.2";
	}
}
namespace MySix.Cartographer
{
	internal static class Burial
	{
		private sealed class Shape
		{
			public Vector3[] Points;

			public int[] Triangles;

			public (int p0, int p1, int t0, int t1, int area)[] Parts;

			public int Areas;
		}

		private struct PieceVerdict
		{
			public bool[] Showing;

			public int Prefab;

			public Vector3 Pos;

			public Quaternion Rot;

			public Vector2s[] Zones;

			public uint[] Revisions;
		}

		private struct Verdict
		{
			public bool Exposed;

			public int Prefab;

			public Vector3 Pos;

			public Vector2s[] Zones;

			public uint[] Revisions;

			public uint Data;
		}

		private sealed class Grid
		{
			private readonly int _ox;

			private readonly int _oz;

			private readonly int _nx;

			private readonly int _nz;

			private readonly float[] _g;

			public Grid(Vector3[] w, List<Vector2s> zones)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0144: Unknown result type (might be due to invalid IL or missing references)
				//IL_0149: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_018c: 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)
				//IL_019c: Unknown result type (might be due to invalid IL or missing references)
				float num = float.MaxValue;
				float num2 = float.MinValue;
				float num3 = float.MaxValue;
				float num4 = float.MinValue;
				foreach (Vector3 val in w)
				{
					num = Mathf.Min(num, val.x);
					num2 = Mathf.Max(num2, val.x);
					num3 = Mathf.Min(num3, val.z);
					num4 = Mathf.Max(num4, val.z);
				}
				_ox = Mathf.FloorToInt(num) - 1;
				_oz = Mathf.FloorToInt(num3) - 1;
				_nx = Mathf.CeilToInt(num2) - _ox + 2;
				_nz = Mathf.CeilToInt(num4) - _oz + 2;
				_g = new float[_nx * _nz];
				for (int j = 0; j < _nz; j++)
				{
					for (int k = 0; k < _nx; k++)
					{
						_g[j * _nx + k] = Ground.HeightAt(_ox + k, _oz + j);
					}
				}
				if (zones == null)
				{
					return;
				}
				Vector2s zone = ZoneSystem.GetZone(new Vector3((float)_ox, 0f, (float)_oz));
				Vector2s zone2 = ZoneSystem.GetZone(new Vector3((float)(_ox + _nx - 1), 0f, (float)(_oz + _nz - 1)));
				for (int l = zone.x; l <= zone2.x; l++)
				{
					for (int m = zone.y; m <= zone2.y; m++)
					{
						zones.Add(new Vector2s(l, m));
					}
				}
			}

			public float At(int gx, int gz)
			{
				return _g[(gz - _oz) * _nx + (gx - _ox)];
			}

			public float G(float x, float z)
			{
				float num = x - (float)_ox;
				float num2 = z - (float)_oz;
				int num3 = Mathf.Clamp(Mathf.FloorToInt(num), 0, _nx - 2);
				int num4 = Mathf.Clamp(Mathf.FloorToInt(num2), 0, _nz - 2);
				float num5 = num - (float)num3;
				float num6 = num2 - (float)num4;
				float num7 = _g[num4 * _nx + num3];
				float num8 = _g[num4 * _nx + num3 + 1];
				float num9 = _g[(num4 + 1) * _nx + num3];
				float num10 = _g[(num4 + 1) * _nx + num3 + 1];
				if (num5 + num6 <= 1f)
				{
					return num7 + num5 * (num8 - num7) + num6 * (num9 - num7);
				}
				return num10 + (1f - num5) * (num9 - num10) + (1f - num6) * (num8 - num10);
			}

			public float Lowest(float x0, float x1, float z0, float z1)
			{
				int num = Mathf.Clamp(Mathf.FloorToInt(x0) - _ox, 0, _nx - 1);
				int num2 = Mathf.Clamp(Mathf.CeilToInt(x1) - _ox, 0, _nx - 1);
				int num3 = Mathf.Clamp(Mathf.FloorToInt(z0) - _oz, 0, _nz - 1);
				int num4 = Mathf.Clamp(Mathf.CeilToInt(z1) - _oz, 0, _nz - 1);
				float num5 = float.MaxValue;
				for (int i = num3; i <= num4; i++)
				{
					for (int j = num; j <= num2; j++)
					{
						num5 = Mathf.Min(num5, _g[i * _nx + j]);
					}
				}
				return num5;
			}
		}

		public const float Showing = 0.1f;

		private static readonly Dictionary<ZDOID, PieceVerdict> PieceVerdicts = new Dictionary<ZDOID, PieceVerdict>();

		private static readonly Dictionary<ZDOID, (uint data, bool[] left)> Lefts = new Dictionary<ZDOID, (uint, bool[])>();

		private static readonly Dictionary<int, Shape> Shapes = new Dictionary<int, Shape>();

		private static readonly Dictionary<ZDOID, Verdict> Verdicts = new Dictionary<ZDOID, Verdict>();

		private static readonly int[] BoxTriangles = new int[36]
		{
			0, 2, 6, 0, 6, 4, 1, 5, 7, 1,
			7, 3, 0, 4, 5, 0, 5, 1, 2, 3,
			7, 2, 7, 6, 0, 1, 3, 0, 3, 2,
			4, 6, 7, 4, 7, 5
		};

		public static void Clear()
		{
			Shapes.Clear();
			Verdicts.Clear();
			PieceVerdicts.Clear();
			Lefts.Clear();
		}

		public static bool Exposed(ZDO zdo)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (zdo == null || !zdo.IsValid())
			{
				return false;
			}
			int prefab = zdo.GetPrefab();
			if (!Kinds.IsBuried(prefab))
			{
				return true;
			}
			Ground.CheckWorld();
			if (Verdicts.TryGetValue(zdo.m_uid, out var value) && value.Data == zdo.DataRevision && value.Prefab == prefab && value.Pos == zdo.GetPosition() && Same(value))
			{
				return value.Exposed;
			}
			value = Judge(zdo, prefab);
			if (Verdicts.Count > 20000)
			{
				Verdicts.Clear();
			}
			Verdicts[zdo.m_uid] = value;
			return value.Exposed;
		}

		internal static List<Collider> GameAreas(GameObject prefab)
		{
			List<Collider> list = new List<Collider>();
			Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				bool flag = true;
				Transform val2 = ((Component)val).transform;
				while ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)prefab.transform)
				{
					flag &= ((Component)val2).gameObject.activeSelf;
					val2 = val2.parent;
				}
				if (flag)
				{
					list.Add(val);
				}
			}
			return list;
		}

		internal static int AreasOf(int prefab)
		{
			return ShapeOf(prefab).Areas;
		}

		internal static bool[] PiecesShowing(ZDO zdo)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			int prefab = zdo.GetPrefab();
			Ground.CheckWorld();
			Vector3 position = zdo.GetPosition();
			Quaternion rotation = zdo.GetRotation();
			if (PieceVerdicts.TryGetValue(zdo.m_uid, out var value) && value.Prefab == prefab && value.Pos == position && value.Rot == rotation && Same(value.Zones, value.Revisions))
			{
				return value.Showing;
			}
			Shape shape = ShapeOf(prefab);
			Vector3[] array = Place(zdo, shape);
			bool[] array2 = new bool[shape.Areas];
			List<Vector2s> list = new List<Vector2s>();
			if (array.Length != 0)
			{
				Grid grid = new Grid(array, list);
				(int, int, int, int, int)[] parts = shape.Parts;
				for (int i = 0; i < parts.Length; i++)
				{
					(int, int, int, int, int) tuple = parts[i];
					if (tuple.Item5 >= 0 && !array2[tuple.Item5])
					{
						array2[tuple.Item5] = RiseOver(grid, array, shape.Triangles, tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, 0.1f) > 0.1f;
					}
				}
			}
			value = new PieceVerdict
			{
				Showing = array2,
				Prefab = prefab,
				Pos = position,
				Rot = rotation,
				Zones = list.ToArray(),
				Revisions = new uint[list.Count]
			};
			for (int j = 0; j < list.Count; j++)
			{
				value.Revisions[j] = Ground.TerrainRevision(list[j]);
			}
			if (PieceVerdicts.Count > 5000)
			{
				PieceVerdicts.Clear();
			}
			PieceVerdicts[zdo.m_uid] = value;
			return array2;
		}

		internal static bool[] Left(ZDO zdo, int areas)
		{
			//IL_0006: 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_0071: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			if (Lefts.TryGetValue(zdo.m_uid, out (uint, bool[]) value) && value.Item1 == zdo.DataRevision && value.Item2.Length == areas)
			{
				return value.Item2;
			}
			bool[] array = new bool[areas];
			for (int i = 0; i < areas; i++)
			{
				array[i] = true;
			}
			string text = zdo.GetString(ZDOVars.s_health, "");
			if (!string.IsNullOrEmpty(text))
			{
				try
				{
					ZPackage val = new ZPackage(Convert.FromBase64String(text));
					int num = val.ReadInt();
					for (int j = 0; j < num; j++)
					{
						float num2 = val.ReadSingle();
						if (j < areas)
						{
							array[j] = num2 > 0f;
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.LogOnce("a broken deposit's record of its pieces could not be read, so all of it is drawn (" + ex.Message + ")");
					for (int k = 0; k < areas; k++)
					{
						array[k] = true;
					}
				}
			}
			if (Lefts.Count > 5000)
			{
				Lefts.Clear();
			}
			Lefts[zdo.m_uid] = (zdo.DataRevision, array);
			return array;
		}

		internal static float Highest(ZDO zdo)
		{
			Ground.CheckWorld();
			return Rise(zdo, float.PositiveInfinity, null);
		}

		internal static Vector3[] Placed(ZDO zdo)
		{
			return Place(zdo, ShapeOf(zdo.GetPrefab()));
		}

		private static Verdict Judge(ZDO zdo, int prefab)
		{
			//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_007d: Unknown result type (might be due to invalid IL or missing references)
			List<Vector2s> list = new List<Vector2s>();
			bool exposed = Rise(zdo, 0.1f, list) > 0.1f;
			Verdict result = new Verdict
			{
				Exposed = exposed,
				Prefab = prefab,
				Pos = zdo.GetPosition(),
				Zones = list.ToArray(),
				Revisions = new uint[list.Count],
				Data = zdo.DataRevision
			};
			for (int i = 0; i < list.Count; i++)
			{
				result.Revisions[i] = Ground.TerrainRevision(list[i]);
			}
			return result;
		}

		private static bool Same(Verdict v)
		{
			return Same(v.Zones, v.Revisions);
		}

		private static bool Same(Vector2s[] zones, uint[] revisions)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < zones.Length; i++)
			{
				if (Ground.TerrainRevision(zones[i]) != revisions[i])
				{
					return false;
				}
			}
			return true;
		}

		private static float Rise(ZDO zdo, float stopAbove, List<Vector2s> zones)
		{
			Shape shape = ShapeOf(zdo.GetPrefab());
			Vector3[] array = Place(zdo, shape);
			if (array.Length == 0)
			{
				return float.MinValue;
			}
			return RiseOver(new Grid(array, zones), array, shape.Triangles, 0, array.Length, 0, shape.Triangles.Length, stopAbove);
		}

		private static float RiseOver(Grid grid, Vector3[] w, int[] t, int p0, int p1, int t0, int t1, float stopAbove)
		{
			//IL_0065: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: 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_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: 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_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: 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_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			float num = float.MinValue;
			for (int i = p0; i < p1; i++)
			{
				num = Mathf.Max(num, w[i].y - grid.G(w[i].x, w[i].z));
			}
			if (num > stopAbove)
			{
				return num;
			}
			for (int j = t0; j + 2 < t1; j += 3)
			{
				Vector3 val = w[t[j]];
				Vector3 val2 = w[t[j + 1]];
				Vector3 val3 = w[t[j + 2]];
				float num2 = Mathf.Min(val.x, Mathf.Min(val2.x, val3.x));
				float num3 = Mathf.Max(val.x, Mathf.Max(val2.x, val3.x));
				float num4 = Mathf.Min(val.z, Mathf.Min(val2.z, val3.z));
				float num5 = Mathf.Max(val.z, Mathf.Max(val2.z, val3.z));
				float num6 = (float.IsPositiveInfinity(stopAbove) ? num : Mathf.Max(num, stopAbove));
				if (Mathf.Max(val.y, Mathf.Max(val2.y, val3.y)) - grid.Lowest(num2, num3, num4, num5) <= num6)
				{
					continue;
				}
				float num7 = (val2.x - val.x) * (val3.z - val.z) - (val3.x - val.x) * (val2.z - val.z);
				if (Mathf.Abs(num7) > 1E-06f)
				{
					for (int k = Mathf.CeilToInt(num4); k <= Mathf.FloorToInt(num5); k++)
					{
						for (int l = Mathf.CeilToInt(num2); l <= Mathf.FloorToInt(num3); l++)
						{
							float num8 = (((float)l - val.x) * (val3.z - val.z) - (val3.x - val.x) * ((float)k - val.z)) / num7;
							float num9 = ((val2.x - val.x) * ((float)k - val.z) - ((float)l - val.x) * (val2.z - val.z)) / num7;
							if (!(num8 < -1E-05f) && !(num9 < -1E-05f) && !(num8 + num9 > 1.00001f))
							{
								float num10 = val.y + num8 * (val2.y - val.y) + num9 * (val3.y - val.y);
								num = Mathf.Max(num, num10 - grid.At(l, k));
							}
						}
					}
				}
				num = Mathf.Max(num, Mathf.Max(Crossings(val, val2), Mathf.Max(Crossings(val2, val3), Crossings(val3, val))));
				if (num > stopAbove)
				{
					return num;
				}
			}
			return num;
			float Crossings(Vector3 val4, Vector3 q)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: 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_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: 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_0082: 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_00f6: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0130: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: 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)
				float r = float.MinValue;
				float num11 = q.x - val4.x;
				float num12 = q.z - val4.z;
				float num13 = num11 + num12;
				float num14 = val4.x + val4.z;
				if (Mathf.Abs(num11) > 1E-06f)
				{
					for (int m = Mathf.CeilToInt(Mathf.Min(val4.x, q.x)); m <= Mathf.FloorToInt(Mathf.Max(val4.x, q.x)); m++)
					{
						At(((float)m - val4.x) / num11);
					}
				}
				if (Mathf.Abs(num12) > 1E-06f)
				{
					for (int n = Mathf.CeilToInt(Mathf.Min(val4.z, q.z)); n <= Mathf.FloorToInt(Mathf.Max(val4.z, q.z)); n++)
					{
						At(((float)n - val4.z) / num12);
					}
				}
				if (Mathf.Abs(num13) > 1E-06f)
				{
					for (int num15 = Mathf.CeilToInt(Mathf.Min(num14, num14 + num13)); num15 <= Mathf.FloorToInt(Mathf.Max(num14, num14 + num13)); num15++)
					{
						At(((float)num15 - num14) / num13);
					}
				}
				return r;
				void At(float s)
				{
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_0018: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0023: Unknown result type (might be due to invalid IL or missing references)
					//IL_002b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0037: Unknown result type (might be due to invalid IL or missing references)
					//IL_003d: Unknown result type (might be due to invalid IL or missing references)
					if (!(s <= 0f) && !(s >= 1f))
					{
						Vector3 val5 = Vector3.LerpUnclamped(val4, q, s);
						r = Mathf.Max(r, val5.y - grid.G(val5.x, val5.z));
					}
				}
			}
		}

		private static Vector3[] Place(ZDO zdo, Shape shape)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_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_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_0045: 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)
			Vector3 position = zdo.GetPosition();
			Quaternion rotation = zdo.GetRotation();
			Vector3 val = ScaleOf(zdo);
			Vector3[] array = (Vector3[])(object)new Vector3[shape.Points.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = position + rotation * Vector3.Scale(shape.Points[i], val);
			}
			return array;
		}

		private static Vector3 ScaleOf(ZDO zdo)
		{
			//IL_0037: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(zdo.GetPrefab()) : null);
			Vector3 val2 = (((Object)(object)val != (Object)null) ? val.transform.localScale : Vector3.one);
			ZNetView val3 = (((Object)(object)val != (Object)null) ? val.GetComponent<ZNetView>() : null);
			if ((Object)(object)val3 == (Object)null || !val3.m_syncInitialScale)
			{
				return val2;
			}
			Vector3 vec = zdo.GetVec3(ZDOVars.s_scaleHash, Vector3.zero);
			if (vec != Vector3.zero)
			{
				return vec;
			}
			float num = zdo.GetFloat(ZDOVars.s_scaleScalarHash, val2.x);
			if (!num.Equals(val2.x))
			{
				return new Vector3(num, num, num);
			}
			return val2;
		}

		private static Shape ShapeOf(int prefab)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: 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_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			if (Shapes.TryGetValue(prefab, out var value))
			{
				return value;
			}
			List<Vector3> list = new List<Vector3>();
			List<int> list2 = new List<int>();
			List<(int, int, int, int, int)> list3 = new List<(int, int, int, int, int)>();
			int areas = 0;
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefab) : null);
			if ((Object)(object)val != (Object)null)
			{
				Matrix4x4 worldToLocalMatrix = val.transform.worldToLocalMatrix;
				List<Collider> list4 = GameAreas(val);
				areas = list4.Count;
				Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
				Bounds bounds = default(Bounds);
				foreach (Collider val2 in componentsInChildren)
				{
					if (val2.isTrigger)
					{
						continue;
					}
					Matrix4x4 val3 = worldToLocalMatrix * ((Component)val2).transform.localToWorldMatrix;
					int count = list.Count;
					int count2 = list2.Count;
					MeshCollider val4 = (MeshCollider)(object)((val2 is MeshCollider) ? val2 : null);
					int[] triangles;
					if (val4 != null && (Object)(object)val4.sharedMesh != (Object)null && val4.sharedMesh.isReadable)
					{
						Vector3[] vertices = val4.sharedMesh.vertices;
						foreach (Vector3 val5 in vertices)
						{
							list.Add(((Matrix4x4)(ref val3)).MultiplyPoint3x4(val5));
						}
						triangles = val4.sharedMesh.triangles;
						foreach (int num in triangles)
						{
							list2.Add(count + num);
						}
						list3.Add((count, list.Count, count2, list2.Count, list4.IndexOf(val2)));
						continue;
					}
					Collider val6 = val2;
					MeshCollider val7 = (MeshCollider)(object)((val6 is MeshCollider) ? val6 : null);
					if (val7 == null)
					{
						BoxCollider val8 = (BoxCollider)(object)((val6 is BoxCollider) ? val6 : null);
						if (val8 == null)
						{
							SphereCollider val9 = (SphereCollider)(object)((val6 is SphereCollider) ? val6 : null);
							if (val9 == null)
							{
								CapsuleCollider val10 = (CapsuleCollider)(object)((val6 is CapsuleCollider) ? val6 : null);
								if (val10 == null)
								{
									continue;
								}
								Vector3 val11 = Vector3.one * val10.radius * 2f;
								((Vector3)(ref val11))[val10.direction] = Mathf.Max(val10.height, val10.radius * 2f);
								((Bounds)(ref bounds))..ctor(val10.center, val11);
							}
							else
							{
								((Bounds)(ref bounds))..ctor(val9.center, Vector3.one * val9.radius * 2f);
							}
						}
						else
						{
							((Bounds)(ref bounds))..ctor(val8.center, val8.size);
						}
					}
					else
					{
						if (!((Object)(object)val7.sharedMesh != (Object)null))
						{
							continue;
						}
						bounds = val7.sharedMesh.bounds;
					}
					for (int k = 0; k < 8; k++)
					{
						list.Add(((Matrix4x4)(ref val3)).MultiplyPoint3x4(new Vector3(((k & 1) == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, ((k & 2) == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, ((k & 4) == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z)));
					}
					triangles = BoxTriangles;
					foreach (int num2 in triangles)
					{
						list2.Add(count + num2);
					}
					list3.Add((count, list.Count, count2, list2.Count, list4.IndexOf(val2)));
				}
			}
			value = new Shape
			{
				Points = list.ToArray(),
				Triangles = list2.ToArray(),
				Parts = list3.ToArray(),
				Areas = areas
			};
			Shapes[prefab] = value;
			return value;
		}

		internal static string Describe(int prefab)
		{
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefab) : null);
			if ((Object)(object)val == (Object)null)
			{
				return "no prefab";
			}
			List<string> list = new List<string>();
			Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren)
			{
				if (!val2.isTrigger)
				{
					MeshCollider val3 = (MeshCollider)(object)((val2 is MeshCollider) ? val2 : null);
					list.Add((val3 != null && (Object)(object)val3.sharedMesh != (Object)null) ? $"mesh {val3.sharedMesh.vertexCount} points, readable {val3.sharedMesh.isReadable}" : ((object)val2).GetType().Name);
				}
			}
			Shape shape = ShapeOf(prefab);
			return string.Format("{0}: {1}; {2} points, {3} faces", ((Object)val).name, string.Join("; ", list), shape.Points.Length, shape.Triangles.Length / 3);
		}
	}
	public class SE_Cartographer : StatusEffect
	{
		public GameObject m_ballPrefab;

		public float m_radius = 1.4f;

		public float m_height = 1.7f;

		public float m_speed = 0.9f;

		public float m_follow = 6f;

		private GameObject m_ball;

		private float m_angle;

		public override void UpdateStatusEffect(float dt)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			((StatusEffect)this).UpdateStatusEffect(dt);
			if ((Plugin.ShowCartographer != null && !Plugin.ShowCartographer.Value) || (Plugin.HideMine != null && Plugin.HideMine.Value) || (Object)(object)m_ballPrefab == (Object)null || (Object)(object)base.m_character == (Object)null)
			{
				RemoveBall();
				return;
			}
			Vector3 position = ((Component)base.m_character).transform.position;
			m_angle += m_speed * dt;
			float num = Mathf.Sin(Time.time * 1.3f) * 0.25f;
			Vector3 val = position + new Vector3(Mathf.Cos(m_angle) * m_radius, m_height + num, Mathf.Sin(m_angle) * m_radius);
			if ((Object)(object)m_ball == (Object)null)
			{
				m_ball = Object.Instantiate<GameObject>(m_ballPrefab, val, Quaternion.identity);
				return;
			}
			Vector3 position2 = m_ball.transform.position;
			m_ball.transform.position = ((Vector3.Distance(position2, val) > 20f) ? val : Vector3.Lerp(position2, val, 1f - Mathf.Exp((0f - m_follow) * dt)));
		}

		private void RemoveBall()
		{
			if (!((Object)(object)m_ball == (Object)null))
			{
				ZNetView component = m_ball.GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.ClaimOwnership();
					component.Destroy();
				}
				else
				{
					Object.Destroy((Object)(object)m_ball);
				}
				m_ball = null;
			}
		}

		public override void Stop()
		{
			((StatusEffect)this).Stop();
			RemoveBall();
		}

		public override void OnDestroy()
		{
			((StatusEffect)this).OnDestroy();
			RemoveBall();
		}

		protected override void OnApplicationQuit()
		{
			((StatusEffect)this).OnApplicationQuit();
			m_ball = null;
		}
	}
	internal static class CartographerItem
	{
		public const string ItemName = "MySix_Cartographer";

		public const string WispItemName = "MySix_RedWispItem";

		public const string BallName = "MySix_CartographerBall";

		public const string EffectName = "MySix_SE_Cartographer";

		private const string WantKey = "MySix.Cartographer.CartographerItem";

		public static readonly Color Red = new Color(1f, 0.16f, 0.1f);

		private const float RedHue = 0.005f;

		private static GameObject _holder;

		private static readonly Dictionary<string, GameObject> Built = new Dictionary<string, GameObject>();

		private static Recipe _recipe;

		private static StatusEffect _effect;

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

		private static bool Graphics => (int)SystemInfo.graphicsDeviceType != 4;

		public static IEnumerable<GameObject> Prefabs => Built.Values;

		public static StatusEffect Effect => _effect;

		public static bool AlwaysOn
		{
			get
			{
				if (Plugin.AlwaysOn != null)
				{
					return Plugin.AlwaysOn.Value;
				}
				return false;
			}
		}

		public static bool Build(ZNetScene scene)
		{
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Expected O, but got Unknown
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Expected O, but got Unknown
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Expected O, but got Unknown
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Expected O, but got Unknown
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Expected O, but got Unknown
			if (Built.Count == 4)
			{
				return true;
			}
			GameObject prefab = scene.GetPrefab("LuredWisp");
			GameObject prefab2 = scene.GetPrefab("Wisp");
			GameObject prefab3 = scene.GetPrefab("Demister");
			GameObject prefab4 = scene.GetPrefab("Raspberry");
			GameObject prefab5 = scene.GetPrefab("Wood");
			GameObject prefab6 = scene.GetPrefab("piece_workbench");
			CraftingStation val = ((prefab6 != null) ? prefab6.GetComponent<CraftingStation>() : null);
			StatusEffect obj = ((prefab3 == null) ? null : prefab3.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_equipStatusEffect);
			SE_Demister val2 = (SE_Demister)(object)((obj is SE_Demister) ? obj : null);
			if ((Object)(object)prefab == (Object)null || (Object)(object)prefab2 == (Object)null || (Object)(object)prefab3 == (Object)null || (Object)(object)prefab4 == (Object)null || (Object)(object)prefab5 == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val2.m_ballPrefab == (Object)null || (Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"The game's wisps, Wisplight, raspberries or wood are not there yet; the Cartographer waits for them");
				return false;
			}
			if ((Object)(object)_holder == (Object)null)
			{
				_holder = new GameObject("MySix_Cartographer_Prefabs");
				_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_holder);
			}
			GameObject val3 = Copy(prefab2, "MySix_RedWispItem");
			SharedData shared = val3.GetComponent<ItemDrop>().m_itemData.m_shared;
			shared.m_name = "$item_mysix_redwisp";
			shared.m_description = "$item_mysix_redwisp_description";
			Redden(val3, 0.9f, 2.5f);
			if (Graphics)
			{
				shared.m_icons = shared.m_icons.Select(Hue).ToArray();
			}
			GameObject val4 = Copy(prefab3, "MySix_Cartographer");
			RemoveMistClearing(val4);
			SharedData shared2 = val4.GetComponent<ItemDrop>().m_itemData.m_shared;
			shared2.m_name = "$item_mysix_cartographer";
			shared2.m_description = "$item_mysix_cartographer_description";
			shared2.m_itemType = (ItemType)16;
			shared2.m_equipStatusEffect = null;
			shared2.m_maxStackSize = 1;
			shared2.m_teleportable = true;
			Redden(val4, 0.6f, 3f);
			if (Graphics)
			{
				shared2.m_icons = shared2.m_icons.Select(Hue).ToArray();
			}
			GameObject val5 = Copy(val2.m_ballPrefab, "MySix_CartographerBall");
			RemoveMistClearing(val5);
			Redden(val5, 0.6f, 3.5f);
			GameObject val6 = Copy(prefab, "MySix_RedWisp");
			Object.DestroyImmediate((Object)(object)val6.GetComponent<LuredWisp>());
			val6.GetComponent<ZNetView>().m_persistent = true;
			Pickable component = val6.GetComponent<Pickable>();
			component.m_itemPrefab = val3;
			component.m_amount = 1;
			component.m_respawnTimeMinutes = 3f;
			component.m_overrideName = "$item_mysix_redwisp";
			GameObject val7 = new GameObject("night");
			val7.transform.SetParent(val6.transform, false);
			GameObject val8 = new GameObject("visual");
			val8.transform.SetParent(val7.transform, false);
			foreach (Transform item in ((IEnumerable)val6.transform).Cast<Transform>().ToList())
			{
				if (((Object)item).name == "demister_ball" || ((Object)item).name == "effects")
				{
					item.SetParent(val8.transform, false);
				}
				else if ((Object)(object)((Component)item).GetComponent<Collider>() != (Object)null)
				{
					item.SetParent(val7.transform, false);
				}
			}
			component.m_hideWhenPicked = val8;
			val6.AddComponent<RedWisp>();
			Redden(val6, 1f, 4f);
			_recipe = ScriptableObject.CreateInstance<Recipe>();
			((Object)_recipe).name = "Recipe_MySix_Cartographer";
			_recipe.m_item = val4.GetComponent<ItemDrop>();
			_recipe.m_amount = 1;
			_recipe.m_enabled = true;
			_recipe.m_craftingStation = val;
			_recipe.m_repairStation = null;
			_recipe.m_minStationLevel = 1;
			_recipe.m_resources = (Requirement[])(object)new Requirement[3]
			{
				new Requirement
				{
					m_resItem = val3.GetComponent<ItemDrop>(),
					m_amount = 1,
					m_recover = true
				},
				new Requirement
				{
					m_resItem = prefab4.GetComponent<ItemDrop>(),
					m_amount = 5,
					m_recover = false
				},
				new Requirement
				{
					m_resItem = prefab5.GetComponent<ItemDrop>(),
					m_amount = 2,
					m_recover = true
				}
			};
			SE_Cartographer sE_Cartographer = ScriptableObject.CreateInstance<SE_Cartographer>();
			((Object)sE_Cartographer).name = "MySix_SE_Cartographer";
			((StatusEffect)sE_Cartographer).m_name = "$item_mysix_cartographer";
			((StatusEffect)sE_Cartographer).m_tooltip = "$se_mysix_cartographer_tooltip";
			((StatusEffect)sE_Cartographer).m_icon = shared2.m_icons.FirstOrDefault();
			sE_Cartographer.m_ballPrefab = val5;
			((StatusEffect)sE_Cartographer).m_ttl = 0f;
			_effect = (StatusEffect)(object)sE_Cartographer;
			Built["MySix_RedWispItem"] = val3;
			Built["MySix_Cartographer"] = val4;
			Built["MySix_CartographerBall"] = val5;
			Built["MySix_RedWisp"] = val6;
			Plugin.Log.LogInfo((object)"Cartographer, red wisps and their light made");
			return true;
		}

		private static GameObject Copy(GameObject source, string name)
		{
			GameObject obj = Object.Instantiate<GameObject>(source, _holder.transform, false);
			((Object)obj).name = name;
			return obj;
		}

		private static void RemoveMistClearing(GameObject go)
		{
			Demister[] componentsInChildren = go.GetComponentsInChildren<Demister>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			ParticleSystemForceField[] componentsInChildren2 = go.GetComponentsInChildren<ParticleSystemForceField>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
		}

		private static void Redden(GameObject go, float intensity, float range)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_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_0084: 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)
			Light[] componentsInChildren = go.GetComponentsInChildren<Light>(true);
			foreach (Light obj in componentsInChildren)
			{
				obj.color = Red;
				obj.intensity = Mathf.Min(obj.intensity, intensity);
				obj.range = Mathf.Min(obj.range, range);
			}
			ParticleSystem[] componentsInChildren2 = go.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem obj2 in componentsInChildren2)
			{
				MainModule main = obj2.main;
				((MainModule)(ref main)).startColor = Reddened(((MainModule)(ref main)).startColor);
				ColorOverLifetimeModule colorOverLifetime = obj2.colorOverLifetime;
				if (((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled)
				{
					((ColorOverLifetimeModule)(ref colorOverLifetime)).color = Reddened(((ColorOverLifetimeModule)(ref colorOverLifetime)).color);
				}
			}
			TrailRenderer[] componentsInChildren3 = go.GetComponentsInChildren<TrailRenderer>(true);
			foreach (TrailRenderer obj3 in componentsInChildren3)
			{
				obj3.colorGradient = Reddened(obj3.colorGradient);
			}
			if (Graphics)
			{
				Renderer[] componentsInChildren4 = go.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer obj4 in componentsInChildren4)
				{
					obj4.sharedMaterials = obj4.sharedMaterials.Select(RedMaterial).ToArray();
				}
			}
		}

		private static Material RedMaterial(Material m)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m == (Object)null)
			{
				return null;
			}
			if (RedMaterials.TryGetValue(m, out var value))
			{
				return value;
			}
			Material val = new Material(m)
			{
				name = ((Object)m).name + "_red"
			};
			string[] array = new string[3] { "_Color", "_TintColor", "_EmissionColor" };
			foreach (string text in array)
			{
				if (val.HasProperty(text))
				{
					val.SetColor(text, Reddened(val.GetColor(text)));
				}
			}
			if (val.HasProperty("_MainTex") && (Object)(object)val.mainTexture != (Object)null)
			{
				Texture2D val2 = Readable(val.mainTexture);
				Color32[] pixels = val2.GetPixels32();
				for (int j = 0; j < pixels.Length; j++)
				{
					pixels[j] = Color32.op_Implicit(Reddened(Color32.op_Implicit(pixels[j])));
				}
				val2.SetPixels32(pixels);
				val2.Apply(true, true);
				((Object)val2).name = ((Object)val.mainTexture).name + "_red";
				val.mainTexture = (Texture)(object)val2;
			}
			RedMaterials[m] = val;
			return val;
		}

		private static Color Reddened(Color c)
		{
			//IL_0000: 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_002d: 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_003b: 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)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(c, ref num, ref num2, ref num3);
			if (num2 < 0.12f)
			{
				return c;
			}
			Color result = Color.HSVToRGB(0.005f, Mathf.Max(num2, 0.75f), num3, true);
			result.a = c.a;
			return result;
		}

		private static MinMaxGradient Reddened(MinMaxGradient g)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//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_001e: Expected I4, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0040: 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_004a: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystemGradientMode mode = ((MinMaxGradient)(ref g)).mode;
			return (MinMaxGradient)((int)mode switch
			{
				0 => new MinMaxGradient(Reddened(((MinMaxGradient)(ref g)).color)), 
				2 => new MinMaxGradient(Reddened(((MinMaxGradient)(ref g)).colorMin), Reddened(((MinMaxGradient)(ref g)).colorMax)), 
				1 => new MinMaxGradient(Reddened(((MinMaxGradient)(ref g)).gradient)), 
				3 => new MinMaxGradient(Reddened(((MinMaxGradient)(ref g)).gradientMin), Reddened(((MinMaxGradient)(ref g)).gradientMax)), 
				_ => g, 
			});
		}

		private static Gradient Reddened(Gradient g)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0052: Expected O, but got Unknown
			if (g == null)
			{
				return null;
			}
			Gradient val = new Gradient
			{
				mode = g.mode
			};
			val.SetKeys(((IEnumerable<GradientColorKey>)g.colorKeys).Select((Func<GradientColorKey, GradientColorKey>)((GradientColorKey k) => new GradientColorKey(Reddened(k.color), k.time))).ToArray(), g.alphaKeys);
			return val;
		}

		private static Sprite Hue(Sprite sprite)
		{
			//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_0026: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_008d: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sprite == (Object)null || (Object)(object)sprite.texture == (Object)null)
			{
				return sprite;
			}
			Rect textureRect = sprite.textureRect;
			Texture2D val = Readable((Texture)(object)sprite.texture, textureRect);
			Color32[] pixels = val.GetPixels32();
			for (int i = 0; i < pixels.Length; i++)
			{
				pixels[i] = Color32.op_Implicit(Reddened(Color32.op_Implicit(pixels[i])));
			}
			val.SetPixels32(pixels);
			val.Apply(false, true);
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), sprite.pivot / ((Rect)(ref textureRect)).size, sprite.pixelsPerUnit);
			((Object)obj).name = ((Object)sprite).name + "_red";
			return obj;
		}

		private static Texture2D Readable(Texture source)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return Readable(source, new Rect(0f, 0f, (float)source.width, (float)source.height));
		}

		private static Texture2D Readable(Texture source, Rect rect)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			RenderTexture active = RenderTexture.active;
			Graphics.Blit(source, temporary);
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D((int)((Rect)(ref rect)).width, (int)((Rect)(ref rect)).height, (TextureFormat)4, false);
			val.ReadPixels(rect, 0, 0);
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			return val;
		}

		public static void Register(ZNetScene scene)
		{
			if (!Build(scene))
			{
				return;
			}
			Dictionary<int, GameObject> value = Traverse.Create((object)scene).Field("m_namedPrefabs").GetValue<Dictionary<int, GameObject>>();
			foreach (GameObject value2 in Built.Values)
			{
				if (!scene.m_prefabs.Contains(value2))
				{
					scene.m_prefabs.Add(value2);
				}
				value[StringExtensionMethods.GetStableHashCode(((Object)value2).name)] = value2;
			}
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				Register(ObjectDB.instance);
			}
		}

		public static void Register(ObjectDB db)
		{
			if ((Object)(object)db == (Object)null || db.m_items == null || db.m_items.Count == 0 || (Built.Count == 0 && ((Object)(object)ZNetScene.instance == (Object)null || !Build(ZNetScene.instance))))
			{
				return;
			}
			bool flag = false;
			string[] array = new string[2] { "MySix_RedWispItem", "MySix_Cartographer" };
			foreach (string key in array)
			{
				if (!db.m_items.Contains(Built[key]))
				{
					db.m_items.Add(Built[key]);
					flag = true;
				}
			}
			if (!db.m_recipes.Contains(_recipe))
			{
				db.m_recipes.Add(_recipe);
			}
			if (!db.m_StatusEffects.Contains(_effect))
			{
				db.m_StatusEffects.Add(_effect);
			}
			if (flag)
			{
				AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null).Invoke(db, null);
			}
		}

		public static bool IsCartographer(ItemData item)
		{
			if (item != null && item.m_shared != null)
			{
				return item.m_shared.m_name == "$item_mysix_cartographer";
			}
			return false;
		}

		public static bool Wanted(Player p)
		{
			if ((Object)(object)p != (Object)null && p.m_customData.TryGetValue("MySix.Cartographer.CartographerItem", out var value))
			{
				return value == "1";
			}
			return false;
		}

		public static bool Carried(Player p)
		{
			if ((Object)(object)p != (Object)null)
			{
				return ((Humanoid)p).GetInventory().GetAllItems().Any(IsCartographer);
			}
			return false;
		}

		public static bool Active(Player p)
		{
			if ((Object)(object)p != (Object)null && !((Character)p).IsDead())
			{
				if (!AlwaysOn)
				{
					if (Wanted(p))
					{
						return Carried(p);
					}
					return false;
				}
				return true;
			}
			return false;
		}

		public static void Toggle(Player p)
		{
			if (AlwaysOn)
			{
				((Character)p).Message((MessageType)2, "$msg_mysix_cartographer_always", 0, (Sprite)null, false);
				return;
			}
			bool flag = !Wanted(p);
			if (flag)
			{
				p.m_customData["MySix.Cartographer.CartographerItem"] = "1";
			}
			else
			{
				p.m_customData.Remove("MySix.Cartographer.CartographerItem");
			}
			((Character)p).Message((MessageType)2, flag ? "$msg_mysix_cartographer_out" : "$msg_mysix_cartographer_away", 0, (Sprite)null, false);
			Keep(p);
		}

		public static void Keep(Player p)
		{
			if (!((Object)(object)p == (Object)null) && !((Object)(object)_effect == (Object)null))
			{
				if ((Object)(object)_recipe != (Object)null)
				{
					_recipe.m_enabled = !AlwaysOn;
				}
				SEMan sEMan = ((Character)p).GetSEMan();
				int num = _effect.NameHash();
				bool flag = Active(p) && !AlwaysOn;
				if (flag && !sEMan.HaveStatusEffect(num))
				{
					sEMan.AddStatusEffect(_effect, false, 0, 0f, (short)(-1));
				}
				else if (!flag && sEMan.HaveStatusEffect(num))
				{
					sEMan.RemoveStatusEffect(num, true);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UseItem")]
	internal static class UseCartographer
	{
		private static bool Prefix(Humanoid __instance, ItemData __1)
		{
			if (CartographerItem.IsCartographer(__1))
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
				{
					CartographerItem.Toggle(val);
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
	internal static class ShowCartographerOut
	{
		private static void Postfix(InventoryGrid __instance, Player __0, Inventory ___m_inventory, List<InventoryElement> ___m_elements, int ___m_width)
		{
			if ((Object)(object)__0 == (Object)null || ___m_inventory == null || CartographerItem.AlwaysOn || !CartographerItem.Active(__0) || ___m_inventory != ((Humanoid)__0).GetInventory())
			{
				return;
			}
			foreach (ItemData allItem in ___m_inventory.GetAllItems())
			{
				if (CartographerItem.IsCartographer(allItem))
				{
					int num = allItem.m_gridPos.y * ___m_width + allItem.m_gridPos.x;
					if (num >= 0 && num < ___m_elements.Count)
					{
						((Behaviour)___m_elements[num].m_equiped).enabled = true;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ZNetSceneAwake
	{
		private static void Postfix(ZNetScene __instance)
		{
			CartographerItem.Register(__instance);
			Kinds.Learn(__instance);
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	internal static class ObjectDBAwake
	{
		private static void Postfix(ObjectDB __instance)
		{
			CartographerItem.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	internal static class ObjectDBCopy
	{
		private static void Postfix(ObjectDB __instance)
		{
			CartographerItem.Register(__instance);
		}
	}
	[BepInPlugin("com.mysix.cartographer", "MySix Cartographer", "0.9.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public enum MapLook
		{
			Atlas,
			Game
		}

		public const string PluginGuid = "com.mysix.cartographer";

		public const string PluginName = "MySix Cartographer";

		public const string PluginVersion = "0.9.2";

		private const int RequiredCoreApi = 3;

		internal static ManualLogSource Log;

		public static Setting<int> RedWisps;

		public static Setting<bool> MarkPortals;

		public static Setting<bool> MarkHomes;

		public static Setting<bool> MarkBoats;

		public static Setting<bool> MarkGraves;

		public static Setting<bool> RedWispsNightOnly;

		public static Setting<bool> ShowCartographer;

		public static Setting<bool> ColourIcons;

		public static Setting<int> IconSize;

		public static Setting<int> MinimapZoom;

		public static Setting<int> MinimapZoomOnTab;

		public const int IconSizeLeast = 50;

		public const int IconSizeMost = 200;

		public static Setting<bool> ThinMarks;

		public static Setting<int> FadeDistance;

		public const int FadeDistanceLeast = 50;

		public const int FadeDistanceMost = 200;

		public static Setting<bool> ShortPlaceNames;

		public static Setting<bool> HideNames;

		public static Setting<bool> LiveMap;

		public static Setting<MapLook> MapStyle;

		public static Setting<bool> DetailedMapAllowed;

		public static Setting<bool> AlwaysOn;

		public static Setting<int> PlaceRange;

		public static Setting<int> LowPlaceRangeMost;

		public static Setting<int> TallPlaceRangeMost;

		public static Setting<int> TallPlaceTimes;

		public static Setting<int> ThingRange;

		public static Setting<int> DenseForestRange;

		public static Setting<int> OpenCountryRange;

		public static Setting<int> MistRange;

		public static Setting<int> FogRange;

		public static Setting<int> SnowstormRange;

		public static Setting<int> NightRange;

		public static Setting<int> LitNightRange;

		public static Setting<int> SeenWithin;

		public static Setting<bool> LightSight;

		public static Setting<bool> BiomeSight;

		public static Setting<bool> MistSight;

		public static Setting<bool> WeatherSight;

		public static Setting<bool> SnowstormSight;

		public static Setting<bool> NightSight;

		private static ConfigEntry<string> _hidden;

		internal static ConfigEntry<bool> LastTab;

		internal static ConfigEntry<bool> ShowHidden;

		internal static ConfigEntry<bool> HideMine;

		private static HashSet<string> _hiddenSet;

		private static HashSet<string> _foldedSet;

		private static ConfigEntry<string> _folded;

		private static readonly HashSet<string> Logged = new HashSet<string>();

		private Harmony _harmony;

		private bool _inWorld;

		private float _nextServer;

		private float _nextKeep;

		private float _nextScan;

		private float _nextPlaces;

		private const float PlacesEvery = 0.5f;

		public static float IconScale
		{
			get
			{
				if (IconSize != null)
				{
					return (float)Mathf.Clamp(IconSize.Value, 50, 200) / 100f;
				}
				return 1f;
			}
		}

		public static bool ThinOn
		{
			get
			{
				if (ThinMarks != null)
				{
					return ThinMarks.Value;
				}
				return true;
			}
		}

		public static float FadeScale
		{
			get
			{
				if (FadeDistance != null)
				{
					return (float)Mathf.Clamp(FadeDistance.Value, 50, 200) / 100f;
				}
				return 1f;
			}
		}

		public static MapLook Look
		{
			get
			{
				if (MapStyle == null)
				{
					return MapLook.Game;
				}
				return MapStyle.Value;
			}
		}

		public static bool DetailedMapOn
		{
			get
			{
				if (LiveMap != null && LiveMap.Value)
				{
					if (DetailedMapAllowed != null)
					{
						return DetailedMapAllowed.Value;
					}
					return true;
				}
				return false;
			}
		}

		internal static (int step, (Setting<int> setting, int was)[] defaults)[] OldSightDefaults => new(int, (Setting<int>, int)[])[2]
		{
			(2, new(Setting<int>, int)[9]
			{
				(PlaceRange, 20),
				(LowPlaceRangeMost, 40),
				(TallPlaceRangeMost, 80),
				(ThingRange, 100),
				(DenseForestRange, 70),
				(MistRange, 50),
				(FogRange, 50),
				(SnowstormRange, 50),
				(NightRange, 60)
			}),
			(3, new(Setting<int>, int)[6]
			{
				(DenseForestRange, 80),
				(MistRange, 70),
				(FogRange, 75),
				(SnowstormRange, 70),
				(NightRange, 75),
				(LitNightRange, 90)
			})
		};

		internal static HashSet<string> Hidden
		{
			get
			{
				if (_hiddenSet == null)
				{
					_hiddenSet = new HashSet<string>(from s in (_hidden?.Value ?? "").Split(new char[1] { ',' })
						select s.Trim() into s
						where s.Length > 0
						select s);
				}
				return _hiddenSet;
			}
		}

		internal static HashSet<string> Folded
		{
			get
			{
				if (_foldedSet == null)
				{
					_foldedSet = new HashSet<string>(from s in (_folded?.Value ?? "").Split(new char[1] { ',' })
						select s.Trim() into s
						where s.Length > 0
						select s);
				}
				return _foldedSet;
			}
		}

		private void Awake()
		{
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Expected O, but got Unknown
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Expected O, but got Unknown
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Expected O, but got Unknown
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Expected O, but got Unknown
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Expected O, but got Unknown
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Expected O, but got Unknown
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Expected O, but got Unknown
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b6: Expected O, but got Unknown
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Expected O, but got Unknown
			//IL_0584: Unknown result type (might be due to invalid IL or missing references)
			//IL_058e: Expected O, but got Unknown
			//IL_05c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cd: Expected O, but got Unknown
			//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e6: Expected O, but got Unknown
			//IL_0746: Unknown result type (might be due to invalid IL or missing references)
			//IL_0750: Expected O, but got Unknown
			//IL_07b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ba: Expected O, but got Unknown
			//IL_08f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08fc: Expected O, but got Unknown
			//IL_0b20: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b2a: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			if (!CorePlugin.RequireApi("MySix Cartographer", 3))
			{
				return;
			}
			LoadTexts();
			RedWisps = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Cartographer", "RedWisps", 1, "How many red wisps drift by each lore runestone. One that is caught comes back about 3 minutes later, so there is always one to catch. 0 to 5."), (Scope)0, (string)null);
			MarkPortals = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "MarkPortals", true, "Every portal a player builds is marked on the Cartographer tab, with its tag, whether or not anyone has a Cartographer."), (Scope)0, (string)null);
			MarkHomes = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "MarkHomes", true, "Every player's building with a fire or other heat in it or by it is marked on the Cartographer tab."), (Scope)0, (string)null);
			MarkBoats = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "MarkBoats", true, "Every boat is marked on the Cartographer tab, each kind with its own picture, and its mark follows it as it sails. Whether or not anyone has a Cartographer."), (Scope)0, (string)null);
			RedWispsNightOnly = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "RedWispsNightOnly", true, "The red wisps come out at night only, like the game's own wisps. Off: they are there day and night."), (Scope)0, (string)null);
			ShowCartographer = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "ShowCartographer", true, "A Cartographer that is out can be seen, circling its player as a dim red light. Off: it is never seen, by its player or anyone else, though it maps just the same."), (Scope)0, (string)null);
			AlwaysOn = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "AlwaysOn", false, "Every character maps for everyone, all the time, with no Cartographer: no red wisps to catch, no wisp following anyone, nothing to make or carry. Off: a Cartographer is caught, made and sent out."), (Scope)0, (string)null);
			AlwaysOn.Changed += delegate
			{
				MapTab.LegendChanged();
			};
			PlaceRange = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "PlaceRange", 35, new ConfigDescription("How close a player must come to a place (a ruin, a cave, a village) for it to be marked, in metres, before half the place's size is added: a small place is marked from about this far. 5 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 100), Array.Empty<object>())), (Scope)0, (string)null);
			LowPlaceRangeMost = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "LowPlaceRangeMost", 60, new ConfigDescription("The furthest a place low to the ground (a burial chamber, a dolmen, a cave) is ever marked from, in metres, before the biome, the weather and the night. 10 to 200.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 200), Array.Empty<object>())), (Scope)0, (string)null);
			TallPlaceTimes = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "TallPlaceTimes", 200, new ConfigDescription("How much further a tall or huge place (a tower, a plains village, a rock spire, a giant) is seen than a low one of its size, as a percentage: 200 is twice as far, 100 no further. 100 to 400.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 400), Array.Empty<object>())), (Scope)0, (string)null);
			TallPlaceRangeMost = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "TallPlaceRangeMost", 120, new ConfigDescription("The furthest a tall or huge place is ever marked from, in metres, before the biome, the weather and the night. 10 to 300.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 300), Array.Empty<object>())), (Scope)0, (string)null);
			ThingRange = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "ThingRange", 150, new ConfigDescription("How far single things and clusters (ore, berries, mushrooms, seeds, giant bones, hives) are marked from, as a percentage of their usual distances (10 m for ore, berries and seeds: at 150, 15 m). 25 to 400.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(25, 400), Array.Empty<object>())), (Scope)0, (string)null);
			BiomeSight = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Sight", "BiomeSight", true, "Trees hide things and open country shows them: marking distances are shortened when the player stands among trees, in any biome (woods in the Meadows as much as the Black Forest), the more trees the more, down to DenseForestRange; and lengthened with no trees round - a meadow, a clearing, a bog, the plains, the sea (OpenCountryRange). The Mountains, the Deep North and the Mistlands hide as much as they show: no lengthening there. Off: the same everywhere."), (Scope)0, (string)null);
			DenseForestRange = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "DenseForestRange", 60, new ConfigDescription("With BiomeSight on: marking distances among the thickest trees, as a percentage of the usual (fewer trees, less of a cut). 10 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>())), (Scope)0, (string)null);
			OpenCountryRange = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "OpenCountryRange", 140, new ConfigDescription("With BiomeSight on: marking distances with no trees round (anywhere but the Mountains, the Deep North and the Mistlands), as a percentage of the usual. 100 to 300.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 300), Array.Empty<object>())), (Scope)0, (string)null);
			MistSight = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Sight", "MistSight", true, "The Mistlands' mist: nothing there is marked unless something is pushing the mist back round the player (a Wisplight, a wisp torch, anything that clears it), and even then only to MistRange. Off: the Mistlands are like anywhere else: the trees round the player, the weather and the night cut how far they see there as anywhere."), (Scope)0, (string)null);
			MistRange = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "MistRange", 40, new ConfigDescription("With MistSight on: marking distances in the Mistlands with the mist pushed back round the player, as a percentage of a clear day's. 10 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>())), (Scope)0, (string)null);
			WeatherSight = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Sight", "WeatherSight", true, "Fog, rain, snow and storms shorten marking distances, the thicker the fog the more, down to FogRange in the thickest. Off: the weather makes no difference."), (Scope)0, (string)null);
			FogRange = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "FogRange", 50, new ConfigDescription("With WeatherSight on: marking distances in the thickest fog or storm, as a percentage of a clear day's. 10 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>())), (Scope)0, (string)null);
			SnowstormSight = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Sight", "SnowstormSight", true, "A snowstorm (in the mountains or the Deep North) shortens marking distances to SnowstormRange while it blows. Off: a snowstorm counts as any other weather (WeatherSight)."), (Scope)0, (string)null);
			SnowstormRange = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "SnowstormRange", 40, new ConfigDescription("With SnowstormSight on: marking distances in a snowstorm, as a percentage of a clear day's. 10 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>())), (Scope)0, (string)null);
			NightSight = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Sight", "NightSight", true, "The dark shortens marking distances, to NightRange from late evening to early morning, easing in at dusk and out at dawn. Off: night makes no difference."), (Scope)0, (string)null);
			NightRange = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "NightRange", 50, new ConfigDescription("With NightSight on: marking distances at night, as a percentage of the day's. 10 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>())), (Scope)0, (string)null);
			LightSight = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Sight", "LightSight", true, "At night a light the player has on - a torch or a lantern in hand, a circlet's light, a Wisplight beside them - lets them see further: marking distances at night are LitNightRange instead of NightRange. Off: a light makes no difference."), (Scope)0, (string)null);
			LitNightRange = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "LitNightRange", 80, new ConfigDescription("With NightSight and LightSight on: marking distances at night for a player with a light on, as a percentage of the day's. 10 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>())), (Scope)0, (string)null);
			SeenWithin = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Sight", "SeenWithin", 10, new ConfigDescription("Anything within this many metres of the player (of a place's edge, for a place) is always marked, whatever the trees, the weather, the night or the mist: they are right on top of it. 0 to 50.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>())), (Scope)0, (string)null);
			MarkGraves = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "MarkGraves", true, "Mark every player's grave on the Cartographer tab, for everyone, with the player's name under it, until everything in it is taken; whether or not anyone has a Cartographer. The game's own skull for your death is then left to your own map tab."), (Scope)0, (string)null);
			DetailedMapAllowed = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "DetailedMapAllowed", true, "The detailed map can be turned on by players. The server draws it from the world, every part the Cartographers have explored, slowly in the background (round players first), and keeps it in a file of its own beside the marks. Off: nobody can have it, the server draws and sends nothing, and the file of what it drew is deleted. On again: it starts drawing over from the start."), (Scope)0, (string)null);
			DetailedMapAllowed.Changed += delegate(Setting<bool> setting)
			{
				if (CorePlugin.IsServerSide)
				{
					DetailServer.AllowedChanged(setting.Value);
				}
				if (CorePlugin.IsPlayerSide && !setting.Value)
				{
					DetailTiles.Clear();
					DetailAsker.Clear();
				}
				MapTab.Redraw();
			};
			ColourIcons = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "IconsInColour", true, "Coloured icons on your Cartographer tab. Off: black and white, like most of the game's own map icons."), (Scope)1, (string)null);
			ColourIcons.Changed += delegate
			{
				MapTab.Redraw();
			};
			IconSize = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Cartographer", "IconSize", 100, new ConfigDescription("How big the icons on your Cartographer tab are, on the map and the minimap, as a percentage of their usual size: 100 is the usual size, in the middle of the slider; 50 half as big, 200 twice as big. Also the slider on the tab.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 200), Array.Empty<object>())), (Scope)1, (string)null);
			IconSize.Changed += delegate
			{
				MapTab.Redraw();
			};
			MinimapZoom = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Cartographer", "MinimapZoom", 0, new ConfigDescription("How close in your minimap is on your own map tab, as a percentage of the game's closest zoom: 100 is the closest, more is further out; 0 starts at the game's own. Kept as you zoom, so the minimap stays as you left it after the big map and from one game to the next.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())), (Scope)1, (string)null);
			MinimapZoom.Changed += delegate
			{
				MapTab.ZoomKeptChanged(onTab: false);
			};
			MinimapZoomOnTab = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Cartographer", "MinimapZoomOnTab", 0, new ConfigDescription("How close in your minimap is on the Cartographer tab, as a percentage of the game's closest zoom: 25 is the tab's closest, 100 the game's closest, more is further out; 0 starts twice as close as your own map tab. Kept as you zoom, so the minimap stays as you left it after the big map and from one game to the next.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())), (Scope)1, (string)null);
			MinimapZoomOnTab.Changed += delegate
			{
				MapTab.ZoomKeptChanged(onTab: true);
			};
			LiveMap = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "DetailedMap", false, "The Cartographer tab's map, zoomed in, drawn in detail: buildings in their materials, walls, doors, trees by kind, rocks, fallen trunks, and ground dug, paved or tilled. The server draws these from the world itself, wherever the Cartographers have explored, and sends the parts you look at, slowly, so the game's own traffic comes first; it draws a part again only when something there is built, cut down, mined, moved or dug. Underneath, your own game draws a sharp map of the land from the world's seed. Off by default: each player's own choice. Also a tick box on the tab"), (Scope)1, (string)null);
			LiveMap.Changed += delegate(Setting<bool> setting)
			{
				MapTab.LegendChanged();
				if (!setting.Value)
				{
					DetailTiles.Clear();
					DetailAsker.Clear();
				}
				Net.WantTiles(setting.Value);
			};
			MapStyle = Settings.Register<MapLook>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<MapLook>("Cartographer", "DetailedMapStyle", MapLook.Game, "The colours of your detailed map. Game (the default): the colours of the game's own map - its muted lands, darker woods and grey water - with buildings, trees and rocks in tones that sit with them. Atlas: the same map, just as sharp, in the atlas's brighter colours. Each player's own choice; switch any time. Also the tab's Brighter map colours tick box (ticked: Atlas)."), (Scope)1, (string)null);
			ThinMarks = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "FewerMarksZoomedOut", true, "Zoomed out on your Cartographer tab, the lesser kinds of mark make way, a step at a time: things to pick first, then ore and materials, then the lesser places (ruins, barrows, runestones, nests...), then the great ones (dungeons, villages, towers, fortresses); players' things, bosses and the game's own marks always show. Zoom in and they come back; the legend fades the kinds made way, with a lens. Off: every mark at every zoom. Also a tick box on the tab."), (Scope)1, (string)null);
			ThinMarks.Changed += delegate
			{
				MapTab.LegendChanged();
			};
			FadeDistance = Settings.Register<int>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<int>("Cartographer", "FadeDistance", 100, new ConfigDescription("With FewerMarksZoomedOut on, how far out on your Cartographer tab the lesser kinds of mark still show before they fade away, as a percentage: 100 as usual, in the middle of the slider; 50 they fade at half the zoom out (sooner), 200 at twice (later). Every step of kinds moves together. Also the Fade distance slider on the tab.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 200), Array.Empty<object>())), (Scope)1, (string)null);
			FadeDistance.Changed += delegate
			{
				MapTab.FadeChanged();
			};
			ShortPlaceNames = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "ShortPlaceNames", false, "On your Cartographer tab, the names under marks that say what kind of place it is (Troll Cave, Abandoned house...) shown short: the first letter of every word, in capitals (TC, AH), each kind of place its own in your language. Names players give marks are never shortened. Pointing at a mark shows its full name. Also a tick box on the tab."), (Scope)1, (string)null);
			HideNames = Settings.Register<bool>("MySix Cartographer", ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "HideNames", false, "On your Cartographer tab, no names under the marks at all, the names players give them included; other players keep theirs. Pointing at a mark shows its full name. Also a tick box on the tab."), (Scope)1, (string)null);
			HideMine = ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "HideMyCartographer", false, "Your Cartographer is not drawn, for you or anyone else, though it maps just the same. Set with the button on the Cartographer tab's legend.");
			HideMine.SettingChanged += delegate
			{
				MapTab.Redraw();
			};
			ShowHidden = ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "ShowHiddenMarks", false, "Show the marks hidden from the Cartographer tab, faded. Set with the button on the tab's legend.");
			ShowHidden.SettingChanged += delegate
			{
				MapTab.Redraw();
			};
			LastTab = ((BaseUnityPlugin)this).Config.Bind<bool>("Cartographer", "OpenOnCartographerTab", false, "The map opens on the tab you last had open; this is where that is kept.");
			_hidden = ((BaseUnityPlugin)this).Config.Bind<string>("Cartographer", "HiddenKinds", "", "The kinds of mark hidden on your Cartographer tab. Set by clicking them in the tab's legend.");
			_hidden.SettingChanged += delegate
			{
				_hiddenSet = null;
			};
			_folded = ((BaseUnityPlugin)this).Config.Bind<string>("Cartographer", "FoldedGroups", "", "The groups of the Cartographer tab's legend you have folded: players, places, ore, pick. Set by clicking a group's heading.");
			_folded.SettingChanged += delegate
			{
				_foldedSet = null;
				MapTab.LegendChanged();
			};
			ConfigEntryBase[] array = (ConfigEntryBase[])(object)new ConfigEntryBase[5]
			{
				(ConfigEntryBase)HideMine,
				(ConfigEntryBase)ShowHidden,
				(ConfigEntryBase)LastTab,
				(ConfigEntryBase)_hidden,
				(ConfigEntryBase)_folded
			};
			for (int num = 0; num < array.Length; num++)
			{
				RegisterOwn(array[num]);
			}
			_harmony = new Harmony("com.mysix.cartographer");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"MySix Cartographer 0.9.2 loaded");
		}

		private static void RegisterOwn(ConfigEntryBase entry)
		{
			if (entry is ConfigEntry<bool> val)
			{
				Settings.Register<bool>("MySix Cartographer", val, (Scope)1, (string)null);
			}
			else if (entry is ConfigEntry<string> val2)
			{
				Settings.Register<string>("MySix Cartographer", val2, (Scope)1, (string)null);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void LoadTexts()
		{
			Texts.Load(typeof(Plugin).Assembly, "Texts.txt");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				if (_inWorld)
				{
					_inWorld = false;
					Server.Unload();
					Ground.Clear();
					Client.Reset();
					DetailTiles.Clear();
					DetailAsker.Clear();
					SharpMap.Clear();
					Net.Reset();
					MapTab.Forget();
				}
				return;
			}
			_inWorld = true;
			if ((int)CorePlugin.Role == 0)
			{
				return;
			}
			try
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (CorePlugin.IsServerSide)
				{
					Server.Load();
				}
				Net.Tick();
				if (CorePlugin.IsPlayerSide)
				{
					SharpMap.Tick();
					DetailTiles.Tick();
				}
				if (CorePlugin.IsServerSide)
				{
					ServerWork.Instance.StartupSlice();
					if (Server.Loaded)
					{
						DetailServer.Work();
					}
				}
				if (CorePlugin.IsServerSide)
				{
					Server.SendNew();
				}
				if (CorePlugin.IsServerSide && realtimeSinceStartup >= _nextServer)
				{
					_nextServer = realtimeSinceStartup + 1f;
					Server.Tick();
					ServerWork.Instance.Tick(realtimeSinceStartup);
				}
				if (CorePlugin.IsPlayerSide)
				{
					PlayerTick(realtimeSinceStartup);
				}
			}
			catch (Exception ex)
			{
				LogOnce("update: " + ex);
			}
		}

		private void PlayerTick(float now)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (now >= _nextKeep)
			{
				_nextKeep = now + 0.5f;
				CartographerItem.Keep(localPlayer);
			}
			if (now >= _nextScan && CartographerItem.Active(localPlayer))
			{
				_nextScan = now + 2f;
				_nextPlaces = now + 0.5f;
				Detector.Scan(localPlayer);
				if ((Object)(object)Minimap.instance != (Object)null)
				{
					Client.Explore(((Component)localPlayer).transform.position, Minimap.instance.m_exploreRadius);
				}
			}
			else if (now >= _nextPlaces && CartographerItem.Active(localPlayer))
			{
				_nextPlaces = now + 0.5f;
				Detector.ScanPlaces(localPlayer);
			}
			Client.Tick();
		}

		internal static void ToggleFolded(string group)
		{
			HashSet<string> hashSet = new HashSet<string>(Folded);
			if (!hashSet.Remove(group))
			{
				hashSet.Add(group);
			}
			if (_folded != null)
			{
				_folded.Value = string.Join(",", hashSet.OrderBy((string s) => s));
			}
		}

		internal static void ToggleHidden(string kind)
		{
			HashSet<string> hidden = Hidden;
			if (!hidden.Remove(kind))
			{
				hidden.Add(kind);
			}
			if (_hidden != null)
			{
				_hidden.Value = string.Join(",", hidden.OrderBy((string s) => s));
			}
		}

		internal static void LogOnce(string message)
		{
			lock (Logged)
			{
				if (Logged.Count >= 50 || !Logged.Add(message))
				{
					return;
				}
			}
			Log.LogError((object)message);
		}
	}
	internal static class Client
	{
		public static readonly PinSet Pins = new PinSet();

		public static readonly Explored Fog = new Explored();

		public static readonly HashSet<int> Hidden = new HashSet<int>();

		private static Texture2D _fog;

		private static bool _fogDirty;

		private static readonly List<Pin> PendingPins = new List<Pin>();

		private static readonly List<int> PendingPixels = new List<int>();

		private static readonly Dictionary<string, float> Proposed = new Dictionary<string, float>();

		private const float ProposeAgainAfter = 30f;

		private static float _nextSend;

		private const float SendNewAfter = 0.1f;

		internal static readonly Color32 Fogged = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);

		internal static readonly Color32 Seen = new Color32((byte)0, (byte)0, byte.MaxValue, byte.MaxValue);

		public static int Version { get; private set; }

		public static bool Synced { get; private set; }

		public static int MapSize
		{
			get
			{
				if (!((Object)(object)Minimap.instance != (Object)null))
				{
					return 0;
				}
				return Minimap.instance.m_textureSize;
			}
		}

		public static Texture2D FogTexture
		{
			get
			{
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Expected O, but got Unknown
				if (Fog.Size == 0 && MapSize > 0)
				{
					Fog.Reset(MapSize);
				}
				if ((Object)(object)_fog == (Object)null && Fog.Size > 0)
				{
					_fog = new Texture2D(Fog.Size, Fog.Size, (TextureFormat)4, false, true)
					{
						name = "MySix_Cartographer_fog",
						wrapMode = (TextureWrapMode)1
					};
					RepaintFog();
				}
				return _fog;
			}
		}

		public static void Reset()
		{
			Pins.Clear();
			Hidden.Clear();
			Fog.Reset(0);
			PendingPins.Clear();
			PendingPixels.Clear();
			Proposed.Clear();
			Synced = false;
			if ((Object)(object)_fog != (Object)null)
			{
				Object.Destroy((Object)(object)_fog);
			}
			_fog = null;
			Version++;
		}

		public static void ReadAll(ZPackage pkg)
		{
			Pins.Clear();
			int num = pkg.ReadInt();
			for (int i = 0; i < num; i++)
			{
				Pins.Add(Pin.Read(pkg));
			}
			int num2 = pkg.ReadInt();
			byte[] bits = pkg.ReadByteArray();
			int mapSize = MapSize;
			if (num2 > 0 && (mapSize == 0 || num2 == mapSize))
			{
				Fog.Load(num2, bits);
			}
			else
			{
				Fog.Reset(mapSize);
			}
			Proposed.Clear();
			Synced = true;
			RepaintFog();
			Version++;
		}

		public static void ReadChanges(ZPackage pkg)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			int num = pkg.ReadInt();
			for (int i = 0; i < num; i++)
			{
				Pins.Add(Pin.Read(pkg));
			}
			int num2 = pkg.ReadInt();
			for (int j = 0; j < num2; j++)
			{
				int num3 = pkg.ReadInt();
				if (Pins.ById.TryGetValue(num3, out var value))
				{
					Proposed.Remove(Key(value.Kind, value.Pos, value.Link));
				}
				Pins.Remove(num3);
			}
			int num4 = pkg.ReadInt();
			int num5 = pkg.ReadInt();
			if (Fog.Size == 0 && num4 > 0 && num4 == MapSize)
			{
				Fog.Reset(num4);
			}
			for (int k = 0; k < num5; k++)
			{
				int i2 = pkg.ReadInt();
				if (num4 == Fog.Size && Fog.Set(i2))
				{
					Paint(i2);
				}
			}
			Version++;
		}

		public static void ReadHidden(bool first, List<int> ids)
		{
			if (first)
			{
				Hidden.Clear();
			}
			foreach (int id in ids)
			{
				Hidden.Add(id);
			}
			Version++;
		}

		public static void Propose(string kind, string source, Vector3 pos, ZDOID link)
		{
			//IL_000c: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			if (Pins.Same(kind, pos, link) != null)
			{
				return;
			}
			string key = Key(kind, pos, link);
			float now = Time.realtimeSinceStartup;
			if (Proposed.TryGetValue(key, out var value) && now - value < 30f)
			{
				return;
			}
			Proposed[key] = now;
			if (Proposed.Count > 4000)
			{
				foreach (string item in (from kv in Proposed
					where now - kv.Value >= 30f
					select kv.Key).ToList())
				{
					Proposed.Remove(item);
				}
			}
			if (PendingPins.Count < 500)
			{
				PendingPins.Add(new Pin
				{
					Kind = kind,
					Source = source,
					Pos = pos,
					Link = link
				});
			}
			_nextSend = Mathf.Min(_nextSend, Time.time + 0.1f);
		}

		private static string Key(string kind, Vector3 pos, ZDOID link)
		{
			//IL_0021: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!((ZDOID)(ref link)).IsNone())
			{
				return $"{kind}#{link}";
			}
			return $"{kind}@{Mathf.RoundToInt(pos.x / 5f)},{Mathf.RoundToInt(pos.z / 5f)}";
		}

		public static void Explore(Vector3 at, float radius)
		{
			//IL_0043: 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)
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			int textureSize = instance.m_textureSize;
			if (Fog.Size == 0)
			{
				Fog.Reset(textureSize);
			}
			if (Fog.Size != textureSize)
			{
				return;
			}
			float pixelSize = instance.m_pixelSize;
			int num = Mathf.RoundToInt(at.x / pixelSize + (float)textureSize / 2f);
			int num2 = Mathf.RoundToInt(at.z / pixelSize + (float)textureSize / 2f);
			int num3 = Mathf.CeilToInt(radius / pixelSize);
			for (int i = num2 - num3; i <= num2 + num3; i++)
			{
				if (i < 0 || i >= textureSize)
				{
					continue;
				}
				for (int j = num - num3; j <= num + num3; j++)
				{
					if (j < 0 || j >= textureSize || (j - num) * (j - num) + (i - num2) * (i - num2) > num3 * num3)
					{
						continue;
					}
					int num4 = i * textureSize + j;
					if (Fog.Set(num4))
					{
						Paint(num4);
						if (PendingPixels.Count < 20000)
						{
							PendingPixels.Add(num4);
						}
					}
				}
			}
		}

		public static void Tick()
		{
			if (_fogDirty && (Object)(object)_fog != (Object)null)
			{
				_fog.Apply(false);
				_fogDirty = false;
			}
			if (!(Time.time < _nextSend) && (PendingPins.Count != 0 || PendingPixels.Count != 0))
			{
				_nextSend = Time.time + 3f;
				if (Net.Report(PendingPins, Fog.Size, PendingPixels))
				{
					PendingPins.Clear();
					PendingPixels.Clear();
					Version++;
				}
			}
		}

		public static bool IsExplored(Vector3 at, Minimap map)
		{
			//IL_0019: 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)
			int size = Fog.Size;
			if (size == 0 || (Object)(object)map == (Object)null)
			{
				return false;
			}
			int num = Mathf.RoundToInt(at.x / map.m_pixelSize + (float)size / 2f);
			int num2 = Mathf.RoundToInt(at.z / map.m_pixelSize + (float)size / 2f);
			if (num >= 0 && num < size && num2 >= 0 && num2 < size)
			{
				return Fog.Has(num2 * size + num);
			}
			return false;
		}

		private static void RepaintFog()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_fog == (Object)null)
			{
				return;
			}
			if (((Texture)_fog).width != Fog.Size)
			{
				Object.Destroy((Object)(object)_fog);
				_fog = null;
				return;
			}
			Color32[] array = (Color32[])(object)new Color32[Fog.Size * Fog.Size];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = (Fog.Has(i) ? Seen : Fogged);
			}
			_fog.SetPixels32(array);
			_fog.Apply(false);
		}

		private static void Paint(int i)
		{
			//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)
			if (!((Object)(object)_fog == (Object)null) && Fog.Size != 0)
			{
				_fog.SetPixel(i % Fog.Size, i / Fog.Size, Color32.op_Implicit(Seen));
				_fogDirty = true;
			}
		}
	}
	internal static class Detail
	{
		public const float TileSize = 32f;

		public const int Pixels = 64;

		public const int Overlap = 8;

		public const int Painted = 80;

		public const float PixelSize = 0.5f;

		public const uint Style = 20u;

		public const uint StyleMask = 255u;

		public static Rect Own => new Rect(0.1f, 0.1f, 0.8f, 0.8f);

		public static long Key(int x, int z)
		{
			return ((long)x << 32) ^ (uint)z;
		}

		public static int KeyX(long key)
		{
			return (int)(key >> 32);
		}

		public static int KeyZ(long key)
		{
			return (int)key;
		}

		public static (int x, int z) TileOf(Vector3 p)
		{
			//IL_0000: 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)
			return (x: Mathf.FloorToInt(p.x / 32f), z: Mathf.FloorToInt(p.z / 32f));
		}

		public static Vector3 Centre(int x, int z)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(((float)x + 0.5f) * 32f, 0f, ((float)z + 0.5f) * 32f);
		}
	}
	internal static class DetailBaker
	{
		internal enum Ground : byte
		{
			None,
			Dirt,
			Tilled,
			Paved
		}

		internal enum Kind