Decompiled source of MiningCamp v1.0.2

plugins/MiningCamp.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using SoftReferenceableAssets;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: IgnoresAccessChecksTo("SoftReferenceableAssets")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("MiningCamp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+884c9add24fcbc918aa958a844a8f538151bb40b")]
[assembly: AssemblyProduct("MiningCamp")]
[assembly: AssemblyTitle("MiningCamp")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MiningCampMod
{
	internal static class CampPanel
	{
		private class PanelBehaviour : MonoBehaviour
		{
			private void Update()
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Current == (Object)null)
				{
					return;
				}
				if (!Current.IsValid || Input.GetKeyDown((KeyCode)27))
				{
					Hide();
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)Current).transform.position) > 12f)
				{
					Hide();
				}
				else if (Time.time >= s_refreshAt)
				{
					Refresh();
				}
			}

			private void OnDestroy()
			{
				if ((Object)(object)Current != (Object)null)
				{
					GUIManager.BlockInput(false);
				}
				Current = null;
				s_root = null;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__Hide;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__14_0;

			public static UnityAction <>9__14_1;

			public static UnityAction <>9__14_2;

			public static UnityAction <>9__14_3;

			public static UnityAction <>9__14_4;

			public static UnityAction <>9__14_5;

			public static UnityAction <>9__14_6;

			internal void <EnsureBuilt>b__14_0()
			{
				Current?.RequestSetPaused(!Current.Paused);
			}

			internal void <EnsureBuilt>b__14_1()
			{
				Current?.RequestAddWorker();
			}

			internal void <EnsureBuilt>b__14_2()
			{
				Current?.RequestRemoveWorker();
			}

			internal void <EnsureBuilt>b__14_3()
			{
				Current?.RequestLinkMine();
			}

			internal void <EnsureBuilt>b__14_4()
			{
				Current?.RequestUnlinkMines();
			}

			internal void <EnsureBuilt>b__14_5()
			{
				Current?.RequestAddChest();
			}

			internal void <EnsureBuilt>b__14_6()
			{
				Current?.RequestClearChests();
			}
		}

		private const float Width = 480f;

		private const float RowStep = 36f;

		private static GameObject s_root;

		private static Text s_status;

		private static Text s_pauseLabel;

		private static float s_refreshAt;

		public static MiningCamp Current { get; private set; }

		public static void Show(MiningCamp camp)
		{
			if (!((Object)(object)camp == (Object)null) && !GUIManager.IsHeadless())
			{
				EnsureBuilt();
				if ((Object)(object)s_root == (Object)null)
				{
					MiningCampPlugin.Log.LogWarning((object)"Camp panel could not be built; Jotunn's GUI is not ready.");
					return;
				}
				Current = camp;
				s_root.SetActive(true);
				GUIManager.BlockInput(true);
				Refresh();
			}
		}

		public static void Hide()
		{
			if ((Object)(object)s_root != (Object)null)
			{
				s_root.SetActive(false);
			}
			if ((Object)(object)Current != (Object)null)
			{
				Current = null;
				GUIManager.BlockInput(false);
			}
		}

		private static void Refresh()
		{
			if (!((Object)(object)Current == (Object)null) && !((Object)(object)s_root == (Object)null))
			{
				s_refreshAt = Time.time + 0.5f;
				s_status.text = Current.StatusSummary();
				s_pauseLabel.text = (Current.Paused ? "Resume work" : "Pause work");
			}
		}

		private static void EnsureBuilt()
		{
			//IL_003c: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Expected O, but got Unknown
			//IL_022c: 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_0237: Expected O, but got Unknown
			//IL_027c: 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)
			//IL_0287: Expected O, but got Unknown
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Expected O, but got Unknown
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Expected O, but got Unknown
			if ((Object)(object)s_root != (Object)null || GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				return;
			}
			s_root = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 480f, 100f, true);
			s_root.SetActive(false);
			s_root.AddComponent<PanelBehaviour>();
			Transform transform = s_root.transform;
			float num = -34f;
			AddText(transform, "Mining Camp", 0f, num, 440f, 30f, 22, (TextAnchor)4);
			num -= 40f;
			s_status = AddText(transform, string.Empty, 0f, num - 105f, 430f, 230f, 14, (TextAnchor)0);
			num -= 238f;
			Section(transform, "Miners", ref num);
			float y = num;
			object obj = <>c.<>9__14_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					Current?.RequestSetPaused(!Current.Paused);
				};
				<>c.<>9__14_0 = val;
				obj = (object)val;
			}
			s_pauseLabel = AddButton(transform, "Pause work", -110f, y, 205f, 30f, (UnityAction)obj);
			float y2 = num;
			object obj2 = <>c.<>9__14_1;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					Current?.RequestAddWorker();
				};
				<>c.<>9__14_1 = val2;
				obj2 = (object)val2;
			}
			AddButton(transform, "Hire a miner", 110f, y2, 205f, 30f, (UnityAction)obj2);
			num -= 36f;
			float y3 = num;
			object obj3 = <>c.<>9__14_2;
			if (obj3 == null)
			{
				UnityAction val3 = delegate
				{
					Current?.RequestRemoveWorker();
				};
				<>c.<>9__14_2 = val3;
				obj3 = (object)val3;
			}
			AddButton(transform, "Send one home", 0f, y3, 205f, 30f, (UnityAction)obj3);
			num -= 36f;
			Section(transform, "Mines", ref num);
			float y4 = num;
			object obj4 = <>c.<>9__14_3;
			if (obj4 == null)
			{
				UnityAction val4 = delegate
				{
					Current?.RequestLinkMine();
				};
				<>c.<>9__14_3 = val4;
				obj4 = (object)val4;
			}
			AddButton(transform, "Link nearest mine", -110f, y4, 205f, 30f, (UnityAction)obj4);
			float y5 = num;
			object obj5 = <>c.<>9__14_4;
			if (obj5 == null)
			{
				UnityAction val5 = delegate
				{
					Current?.RequestUnlinkMines();
				};
				<>c.<>9__14_4 = val5;
				obj5 = (object)val5;
			}
			AddButton(transform, "Unlink all mines", 110f, y5, 205f, 30f, (UnityAction)obj5);
			num -= 36f;
			Section(transform, "Storage", ref num);
			float y6 = num;
			object obj6 = <>c.<>9__14_5;
			if (obj6 == null)
			{
				UnityAction val6 = delegate
				{
					Current?.RequestAddChest();
				};
				<>c.<>9__14_5 = val6;
				obj6 = (object)val6;
			}
			AddButton(transform, "Add nearest chest", -110f, y6, 205f, 30f, (UnityAction)obj6);
			float y7 = num;
			object obj7 = <>c.<>9__14_6;
			if (obj7 == null)
			{
				UnityAction val7 = delegate
				{
					Current?.RequestClearChests();
				};
				<>c.<>9__14_6 = val7;
				obj7 = (object)val7;
			}
			AddButton(transform, "Clear chests", 110f, y7, 205f, 30f, (UnityAction)obj7);
			num -= 44f;
			float y8 = num;
			object obj8 = <>O.<0>__Hide;
			if (obj8 == null)
			{
				UnityAction val8 = Hide;
				<>O.<0>__Hide = val8;
				obj8 = (object)val8;
			}
			AddButton(transform, "Close", 0f, y8, 205f, 30f, (UnityAction)obj8);
			num -= 42f;
			s_root.GetComponent<RectTransform>().sizeDelta = new Vector2(480f, 0f - num);
		}

		private static void Section(Transform parent, string title, ref float y)
		{
			y -= 4f;
			AddText(parent, title, 0f, y, 440f, 24f, 16, (TextAnchor)4);
			y -= 30f;
		}

		private static void Place(GameObject go, float x, float y, float width, float height, Vector2 pivot)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = go.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				component.anchorMin = new Vector2(0.5f, 1f);
				component.anchorMax = new Vector2(0.5f, 1f);
				component.pivot = pivot;
				component.anchoredPosition = new Vector2(x, y);
				component.sizeDelta = new Vector2(width, height);
			}
		}

		private static Text AddText(Transform parent, string text, float x, float y, float width, float height, int size, TextAnchor alignment)
		{
			//IL_0011: 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_0027: 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_0043: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GUIManager.Instance.CreateText(text, parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(x, y), GUIManager.Instance.AveriaSerifBold, size, GUIManager.Instance.ValheimOrange, true, Color.black, width, height, false);
			Text componentInChildren = obj.GetComponentInChildren<Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.alignment = alignment;
				componentInChildren.horizontalOverflow = (HorizontalWrapMode)0;
				componentInChildren.verticalOverflow = (VerticalWrapMode)1;
			}
			Place(obj, x, y, width, height, new Vector2(0.5f, 0.5f));
			return componentInChildren;
		}

		private static Text AddButton(Transform parent, string label, float x, float y, float width, float height, UnityAction action)
		{
			//IL_0011: 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_0027: 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)
			GameObject obj = GUIManager.Instance.CreateButton(label, parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(x, y), width, height);
			Place(obj, x, y, width, height, new Vector2(0.5f, 0.5f));
			Button componentInChildren = obj.GetComponentInChildren<Button>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((UnityEvent)componentInChildren.onClick).AddListener(action);
			}
			return obj.GetComponentInChildren<Text>(true);
		}
	}
	internal class MapMarkers : MonoBehaviour
	{
		private const int SectorsPerFrame = 2000;

		private const float ArrowScale = 0.7f;

		private const float DotScale = 0.45f;

		private static readonly Color Fill = new Color(0.27f, 0.63f, 1f);

		private static readonly Color Outline = new Color(0.04f, 0.1f, 0.26f);

		private static Sprite s_arrow;

		private static Sprite s_dot;

		private int m_workerHash;

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

		private int m_scanIndex;

		private readonly List<ZDO> m_scanFound = new List<ZDO>();

		private readonly List<ZDO> m_known = new List<ZDO>();

		private readonly List<ZDO> m_scanMines = new List<ZDO>();

		private readonly List<ZDO> m_knownMines = new List<ZDO>();

		private readonly HashSet<ZDOID> m_drawn = new HashSet<ZDOID>();

		private readonly List<RectTransform> m_pool = new List<RectTransform>();

		private int m_used;

		private void LateUpdate()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			m_used = 0;
			Minimap instance = Minimap.instance;
			if (MiningCampConfig.MapMarkers.Value && (Object)(object)instance != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null && ZDOMan.instance != null && (Object)(object)ZNetScene.instance != (Object)null)
			{
				Scan();
				if ((int)instance.m_mode != 0)
				{
					Draw(instance);
				}
			}
			else
			{
				m_known.Clear();
				m_scanFound.Clear();
				m_knownMines.Clear();
				m_scanMines.Clear();
				m_scanIndex = 0;
			}
			for (int i = m_used; i < m_pool.Count; i++)
			{
				if ((Object)(object)m_pool[i] != (Object)null && ((Component)m_pool[i]).gameObject.activeSelf)
				{
					((Component)m_pool[i]).gameObject.SetActive(false);
				}
			}
		}

		private void OnDestroy()
		{
			foreach (RectTransform item in m_pool)
			{
				if ((Object)(object)item != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)item).gameObject);
				}
			}
			m_pool.Clear();
		}

		private void Scan()
		{
			if (m_workerHash == 0)
			{
				m_workerHash = StringExtensionMethods.GetStableHashCode("miningcamp_worker");
				OreType[] all = OreType.All;
				foreach (OreType oreType in all)
				{
					m_mineHashes.Add(StringExtensionMethods.GetStableHashCode(oreType.PieceName));
				}
			}
			List<ZDO>[] objectsBySector = ZDOMan.instance.m_objectsBySector;
			if (objectsBySector == null)
			{
				return;
			}
			int num = Mathf.Min(m_scanIndex + 2000, objectsBySector.Length);
			while (m_scanIndex < num)
			{
				List<ZDO> list = objectsBySector[m_scanIndex];
				if (list != null)
				{
					foreach (ZDO item in list)
					{
						if (item != null)
						{
							int prefab = item.GetPrefab();
							if (prefab == m_workerHash)
							{
								m_scanFound.Add(item);
							}
							else if (m_mineHashes.Contains(prefab))
							{
								m_scanMines.Add(item);
							}
						}
					}
				}
				m_scanIndex++;
			}
			if (m_scanIndex >= objectsBySector.Length)
			{
				m_known.Clear();
				m_known.AddRange(m_scanFound);
				m_scanFound.Clear();
				m_knownMines.Clear();
				m_knownMines.AddRange(m_scanMines);
				m_scanMines.Clear();
				m_scanIndex = 0;
			}
		}

		private void Draw(Minimap map)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: 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_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			bool flag = (int)map.m_mode == 2;
			RawImage val = (flag ? map.m_mapImageLarge : map.m_mapImageSmall);
			RectTransform val2 = (flag ? map.m_pinRootLarge : map.m_pinRootSmall);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return;
			}
			float size = (flag ? map.m_pinSizeLarge : map.m_pinSizeSmall) * 0.7f;
			Rect uvRect = val.uvRect;
			Rect rect = ((Graphic)val).rectTransform.rect;
			m_drawn.Clear();
			foreach (MinerWorker instance in MinerWorker.Instances)
			{
				if (!((Object)(object)instance == (Object)null) && instance.IsValid && m_drawn.Add(instance.NetView.GetZDO().m_uid))
				{
					Place(map, val2, uvRect, rect, size, ((Component)instance).transform.position, ((Component)instance).transform.rotation);
				}
			}
			foreach (ZDO item in m_known)
			{
				if (item != null && item.IsValid() && item.GetPrefab() == m_workerHash && m_drawn.Add(item.m_uid))
				{
					ZNetView val3 = ZNetScene.instance.FindInstance(item);
					if ((Object)(object)val3 != (Object)null)
					{
						Place(map, val2, uvRect, rect, size, ((Component)val3).transform.position, ((Component)val3).transform.rotation);
					}
					else
					{
						Place(map, val2, uvRect, rect, size, item.GetPosition(), item.GetRotation());
					}
				}
			}
			float size2 = (flag ? map.m_pinSizeLarge : map.m_pinSizeSmall) * 0.45f;
			m_drawn.Clear();
			foreach (Mine instance2 in Mine.Instances)
			{
				if ((Object)(object)instance2 != (Object)null && instance2.IsValid && m_drawn.Add(instance2.NetView.GetZDO().m_uid))
				{
					PlaceBelow(map, val2, uvRect, rect, size2, ((Component)instance2).transform.position, instance2.InsideCount);
				}
			}
			foreach (ZDO knownMine in m_knownMines)
			{
				if (knownMine != null && knownMine.IsValid() && m_mineHashes.Contains(knownMine.GetPrefab()) && m_drawn.Add(knownMine.m_uid))
				{
					PlaceBelow(map, val2, uvRect, rect, size2, knownMine.GetPosition(), Mine.InsideCountOf(knownMine));
				}
			}
		}

		private void PlaceBelow(Minimap map, RectTransform root, Rect uv, Rect rect, float size, Vector3 pos, int count)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (count <= 0)
			{
				return;
			}
			float num = default(float);
			float num2 = default(float);
			map.WorldToMapPoint(pos, ref num, ref num2);
			if (!(num <= ((Rect)(ref uv)).xMin) && !(num >= ((Rect)(ref uv)).xMax) && !(num2 <= ((Rect)(ref uv)).yMin) && !(num2 >= ((Rect)(ref uv)).yMax))
			{
				Vector2 val = map.MapPointToLocalGuiPos(num, num2, uv, rect);
				float num3 = ((count == 1) ? 0f : (size * 0.5f / Mathf.Sin((float)Math.PI / (float)Mathf.Max(count, 3))));
				for (int i = 0; i < count; i++)
				{
					float num4 = (float)Math.PI / 2f - (float)i * 2f * (float)Math.PI / (float)count;
					RectTransform obj = Take(root, size, Dot());
					obj.anchoredPosition = val + new Vector2(Mathf.Cos(num4), Mathf.Sin(num4)) * num3;
					((Transform)obj).rotation = Quaternion.identity;
				}
			}
		}

		private void Place(Minimap map, RectTransform root, Rect uv, Rect rect, float size, Vector3 pos, Quaternion facing)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			map.WorldToMapPoint(pos, ref num, ref num2);
			if (!(num <= ((Rect)(ref uv)).xMin) && !(num >= ((Rect)(ref uv)).xMax) && !(num2 <= ((Rect)(ref uv)).yMin) && !(num2 >= ((Rect)(ref uv)).yMax))
			{
				RectTransform obj = Take(root, size, Arrow());
				obj.anchoredPosition = map.MapPointToLocalGuiPos(num, num2, uv, rect);
				((Transform)obj).rotation = Quaternion.Euler(0f, 0f, 0f - ((Quaternion)(ref facing)).eulerAngles.y);
			}
		}

		private RectTransform Take(RectTransform root, float size, Sprite sprite)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val;
			if (m_used < m_pool.Count && (Object)(object)m_pool[m_used] != (Object)null)
			{
				val = m_pool[m_used];
			}
			else
			{
				val = Create(root);
				if (m_used < m_pool.Count)
				{
					m_pool[m_used] = val;
				}
				else
				{
					m_pool.Add(val);
				}
			}
			m_used++;
			if ((Object)(object)((Transform)val).parent != (Object)(object)root)
			{
				((Transform)val).SetParent((Transform)(object)root, false);
			}
			if (!Mathf.Approximately(val.sizeDelta.x, size))
			{
				val.sizeDelta = new Vector2(size, size);
			}
			Image component = ((Component)val).GetComponent<Image>();
			if ((Object)(object)component.sprite != (Object)(object)sprite)
			{
				component.sprite = sprite;
			}
			if (!((Component)val).gameObject.activeSelf)
			{
				((Component)val).gameObject.SetActive(true);
			}
			return val;
		}

		private static RectTransform Create(RectTransform root)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			GameObject val = new GameObject("MiningCampMarker", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent((Transform)(object)root, false);
			RectTransform val3 = (RectTransform)(((Object)(object)Minimap.instance != (Object)null && (Object)(object)Minimap.instance.m_pinPrefab != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			val2.anchorMin = (((Object)(object)val3 != (Object)null) ? val3.anchorMin : Vector2.zero);
			val2.anchorMax = (((Object)(object)val3 != (Object)null) ? val3.anchorMax : Vector2.zero);
			val2.pivot = new Vector2(0.5f, 0.5f);
			Image component = val.GetComponent<Image>();
			((Graphic)component).raycastTarget = false;
			component.preserveAspect = true;
			return val2;
		}

		private static Sprite Arrow()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s_arrow == (Object)null)
			{
				Vector2[] dart = (Vector2[])(object)new Vector2[4]
				{
					new Vector2(32f, 60f),
					new Vector2(54f, 6f),
					new Vector2(32f, 19f),
					new Vector2(10f, 6f)
				};
				s_arrow = Paint(64, (Vector2 p) => PolygonDistance(p, dart));
			}
			return s_arrow;
		}

		private static Sprite Dot()
		{
			if ((Object)(object)s_dot == (Object)null)
			{
				s_dot = Paint(64, delegate(Vector2 p)
				{
					//IL_0000: 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_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					Vector2 val = p - new Vector2(32f, 32f);
					return ((Vector2)(ref val)).magnitude - 27f;
				});
			}
			return s_dot;
		}

		private static Sprite Paint(int size, Func<Vector2, float> distance)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_00c4: 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_0045: 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_0056: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false)
			{
				name = "MiningCampMarker",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color[] array = (Color[])(object)new Color[size * size];
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num = distance(new Vector2((float)j + 0.5f, (float)i + 0.5f));
					Color val2 = Color.Lerp(Fill, Outline, Mathf.Clamp01(num + 4.5f + 0.5f));
					val2.a = Mathf.Clamp01(0.5f - num);
					array[i * size + j] = val2;
				}
			}
			val.SetPixels(array);
			val.Apply(false, true);
			return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f);
		}

		private static float PolygonDistance(Vector2 p, Vector2[] poly)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00a9: 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_00b8: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			float num = float.MaxValue;
			bool flag = false;
			int num2 = 0;
			int num3 = poly.Length - 1;
			while (num2 < poly.Length)
			{
				Vector2 val = poly[num3];
				Vector2 val2 = poly[num2];
				Vector2 val3 = val2 - val;
				float num4 = Mathf.Clamp01(Vector2.Dot(p - val, val3) / ((Vector2)(ref val3)).sqrMagnitude);
				float num5 = num;
				Vector2 val4 = p - (val + val3 * num4);
				num = Mathf.Min(num5, ((Vector2)(ref val4)).magnitude);
				if (val.y > p.y != val2.y > p.y && p.x < val.x + (p.y - val.y) / (val2.y - val.y) * (val2.x - val.x))
				{
					flag = !flag;
				}
				num3 = num2++;
			}
			if (!flag)
			{
				return num;
			}
			return 0f - num;
		}
	}
	public class Mine : MonoBehaviour, Hoverable, Interactable
	{
		private const string ZdoKey = "mc_minekey";

		private const string ZdoCamp = "mc_campkey";

		private const string ZdoCampPos = "mc_camppos";

		private const string ZdoJobs = "mc_jobs";

		private const string ZdoLastEnter = "mc_lastenter";

		private const string ZdoPlaced = "mc_placed";

		private const string ZdoStood = "mc_stood";

		private const string RpcLink = "MC_MineLink";

		private const string RpcUnlink = "MC_MineUnlink";

		private const string RpcRecall = "MC_MineRecall";

		private const string RpcMessage = "MC_MineMessage";

		public static readonly List<Mine> Instances = new List<Mine>();

		public string m_oreId;

		[Tooltip("Metres above the piece origin to float the hover text.")]
		public float m_hoverOffset = 1.5f;

		private ZNetView m_nview;

		private WearNTear m_wear;

		private bool m_ready;

		private float m_nextTick;

		private Vector3 m_entryLocal = new Vector3(0f, 0f, 1.5f);

		public OreType Ore => OreType.Get(m_oreId);

		public bool IsValid
		{
			get
			{
				if (m_ready && (Object)(object)m_nview != (Object)null)
				{
					return m_nview.IsValid();
				}
				return false;
			}
		}

		private ZDO Zdo => m_nview.GetZDO();

		private bool Owner
		{
			get
			{
				if (IsValid)
				{
					return m_nview.IsOwner();
				}
				return false;
			}
		}

		public ZNetView NetView => m_nview;

		public long Key
		{
			get
			{
				if (!IsValid)
				{
					return 0L;
				}
				return Zdo.GetLong("mc_minekey", 0L);
			}
		}

		public long CampKey
		{
			get
			{
				if (!IsValid)
				{
					return 0L;
				}
				return Zdo.GetLong("mc_campkey", 0L);
			}
		}

		public Vector3 CampPosition
		{
			get
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				if (!IsValid)
				{
					return ((Component)this).transform.position;
				}
				return Zdo.GetVec3("mc_camppos", ((Component)this).transform.position);
			}
		}

		public bool Linked => CampKey != 0;

		public Vector3 EntryPoint
		{
			get
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0032: 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_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: 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_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: 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_009d: 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)
				Vector3 val = ((Component)this).transform.TransformPoint(m_entryLocal);
				if ((Object)(object)ZoneSystem.instance == (Object)null)
				{
					return val;
				}
				Vector3 val2 = val - ((Component)this).transform.position;
				val2.y = 0f;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.25f)
				{
					val2 = -((Component)this).transform.forward;
				}
				((Vector3)(ref val2)).Normalize();
				float num = default(float);
				for (int i = 0; i <= 12; i++)
				{
					Vector3 val3 = val + val2 * ((float)i * 0.5f);
					if (!ZoneSystem.instance.GetGroundHeight(val3, ref num) || val3.y >= num - 0.5f)
					{
						return val3;
					}
				}
				return val;
			}
		}

		public Vector3 ExitPoint
		{
			get
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: 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_002b: Unknown result type (might be due to invalid IL or missing references)
				if (IsValid)
				{
					Vector3 vec = Zdo.GetVec3("mc_stood", Vector3.zero);
					if (vec != Vector3.zero)
					{
						return vec;
					}
				}
				return EntryPoint;
			}
		}

		public int InsideCount => Jobs().Count;

		public long LastEnter
		{
			get
			{
				if (!IsValid)
				{
					return 0L;
				}
				return Zdo.GetLong("mc_lastenter", 0L);
			}
		}

		public void SetEntryLocal(Vector3 local)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			m_entryLocal = local;
		}

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			MineVisuals.Attach(this);
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				m_ready = true;
				Instances.Add(this);
				m_nview.Register<long, Vector3>("MC_MineLink", (Action<long, long, Vector3>)RPC_Link);
				m_nview.Register("MC_MineUnlink", (Action<long>)RPC_Unlink);
				m_nview.Register("MC_MineRecall", (Action<long>)RPC_Recall);
				m_nview.Register<string>("MC_MineMessage", (Action<long, string>)RPC_Message);
				m_wear = ((Component)this).GetComponent<WearNTear>();
				if ((Object)(object)m_wear != (Object)null)
				{
					WearNTear wear = m_wear;
					wear.m_onDestroyed = (Action)Delegate.Combine(wear.m_onDestroyed, new Action(OnPieceDestroyed));
				}
				m_nextTick = Time.time + Random.Range(0f, 1f);
			}
		}

		private void Start()
		{
			if (Owner)
			{
				EnsureKey();
				if (!Zdo.GetBool("mc_placed", false))
				{
					Zdo.Set("mc_placed", true);
					AutoLink();
				}
			}
		}

		private void Update()
		{
			if (Owner)
			{
				if (Key == 0L)
				{
					EnsureKey();
				}
				if (Time.time >= m_nextTick)
				{
					m_nextTick = Time.time + 1f;
					TickJobs();
				}
			}
		}

		private void OnDestroy()
		{
			Instances.Remove(this);
		}

		private void EnsureKey()
		{
			if (Key == 0L)
			{
				Zdo.Set("mc_minekey", PieceUtil.NewStableKey());
			}
		}

		public static Mine FindByKey(long key)
		{
			if (key == 0L)
			{
				return null;
			}
			foreach (Mine instance in Instances)
			{
				if ((Object)(object)instance != (Object)null && instance.IsValid && instance.Key == key)
				{
					return instance;
				}
			}
			return null;
		}

		public static List<Mine> ForCamp(long campKey)
		{
			List<Mine> list = new List<Mine>();
			if (campKey == 0L)
			{
				return list;
			}
			foreach (Mine instance in Instances)
			{
				if ((Object)(object)instance != (Object)null && instance.IsValid && instance.CampKey == campKey)
				{
					list.Add(instance);
				}
			}
			return list;
		}

		public static Mine FindNearest(Vector3 pos, float radius, Func<Mine, bool> accept)
		{
			//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)
			Mine result = null;
			float num = radius;
			foreach (Mine instance in Instances)
			{
				if (!((Object)(object)instance == (Object)null) && instance.IsValid && (accept == null || accept(instance)))
				{
					float num2 = Vector3.Distance(((Component)instance).transform.position, pos);
					if (num2 <= num)
					{
						num = num2;
						result = instance;
					}
				}
			}
			return result;
		}

		public static long Now()
		{
			if (!((Object)(object)ZNet.instance != (Object)null))
			{
				return (long)Time.time;
			}
			return (long)ZNet.instance.GetTimeSeconds();
		}

		public List<long> Jobs()
		{
			List<long> list = new List<long>();
			string[] array = (IsValid ? Zdo.GetString("mc_jobs", string.Empty) : string.Empty).Split(new char[1] { ';' });
			for (int i = 0; i < array.Length; i++)
			{
				if (long.TryParse(array[i].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
				{
					list.Add(result);
				}
			}
			return list;
		}

		private void SetJobs(List<long> jobs)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (long job in jobs)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(';');
				}
				stringBuilder.Append(job.ToString(CultureInfo.InvariantCulture));
			}
			Zdo.Set("mc_jobs", stringBuilder.ToString());
		}

		public static int InsideCountOf(ZDO zdo)
		{
			int num = 0;
			string[] array = zdo.GetString("mc_jobs", string.Empty).Split(new char[1] { ';' });
			for (int i = 0; i < array.Length; i++)
			{
				if (long.TryParse(array[i].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var _))
				{
					num++;
				}
			}
			return num;
		}

		public long NextUpSeconds()
		{
			long num = Now();
			long num2 = -1L;
			foreach (long item in Jobs())
			{
				long num3 = Math.Max(0L, item - num);
				if (num2 < 0 || num3 < num2)
				{
					num2 = num3;
				}
			}
			return num2;
		}

		public static string FormatSeconds(long seconds)
		{
			if (seconds < 0)
			{
				return "-";
			}
			long num = seconds / 60;
			long num2 = seconds % 60;
			if (num < 60)
			{
				return $"{num}:{num2:00}";
			}
			return $"{num / 60}:{num % 60:00}:{num2:00}";
		}

		public bool Admit(Vector3 stoodAt)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (!Owner)
			{
				return false;
			}
			long num = Now();
			List<long> list = Jobs();
			list.Add(num + (long)MiningCampConfig.TripSeconds(Ore));
			SetJobs(list);
			Zdo.Set("mc_lastenter", num);
			if (stoodAt != Vector3.zero)
			{
				Zdo.Set("mc_stood", stoodAt);
			}
			Log($"admitted a miner; {list.Count} below");
			return true;
		}

		private void TickJobs()
		{
			List<long> list = Jobs();
			if (list.Count == 0)
			{
				return;
			}
			long num = Now();
			int num2 = 0;
			for (int num3 = list.Count - 1; num3 >= 0; num3--)
			{
				if (list[num3] <= num)
				{
					list.RemoveAt(num3);
					num2++;
				}
			}
			if (num2 != 0)
			{
				SetJobs(list);
				for (int i = 0; i < num2; i++)
				{
					Release(withOre: true);
				}
			}
		}

		private void Release(bool withOre)
		{
			//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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_002f: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0071: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			Vector3 exitPoint = ExitPoint;
			Vector3 val = (Linked ? CampPosition : (((Component)this).transform.position + ((Component)this).transform.forward * 4f)) - exitPoint;
			val.y = 0f;
			Quaternion rot = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? Quaternion.LookRotation(val) : ((Component)this).transform.rotation);
			MinerWorker minerWorker = MiningCamp.SpawnWorkerAt(exitPoint, rot);
			if ((Object)(object)minerWorker == (Object)null)
			{
				MiningCampPlugin.Log.LogError((object)"A mine could not spawn the miner coming up; see the log above.");
				return;
			}
			Log($"miner comes up at {exitPoint} (mine at {((Component)this).transform.position})");
			MiningCamp miningCamp = MiningCamp.FindByKey(CampKey);
			if ((Object)(object)miningCamp != (Object)null)
			{
				minerWorker.BindCamp(miningCamp);
			}
			else
			{
				minerWorker.BindCamp(CampKey, CampPosition);
			}
			if (withOre && Ore != null)
			{
				int num = MiningCampConfig.Yield(Ore);
				minerWorker.GiveOre(Ore.OrePrefab, num);
				minerWorker.SetStatus($"Coming up with {num} {Localization.instance.Localize(OreName())}");
				Log($"released a miner with {num} {Ore.OrePrefab}");
			}
			else
			{
				minerWorker.SetStatus("Coming up empty-handed");
			}
		}

		private string OreName()
		{
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null && Ore != null) ? ObjectDB.instance.GetItemPrefab(Ore.OrePrefab) : null);
			return (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_name ?? Ore?.OrePrefab ?? "ore";
		}

		private void OnPieceDestroyed()
		{
			int insideCount = InsideCount;
			SetJobs(new List<long>());
			for (int i = 0; i < insideCount; i++)
			{
				Release(withOre: false);
			}
		}

		private void AutoLink()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			MiningCamp miningCamp = MiningCamp.FindNearest(((Component)this).transform.position, MiningCampConfig.MineLinkRange.Value);
			if (!((Object)(object)miningCamp == (Object)null) && miningCamp.Key != 0L)
			{
				Zdo.Set("mc_campkey", miningCamp.Key);
				Zdo.Set("mc_camppos", ((Component)miningCamp).transform.position);
				Log("linked itself to the nearest camp");
			}
		}

		private void Send(string rpc, params object[] args)
		{
			if (IsValid)
			{
				PieceUtil.Send(m_nview, rpc, args);
			}
		}

		public void RequestLink(MiningCamp camp)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)camp == (Object)null) && camp.Key != 0L)
			{
				Send("MC_MineLink", camp.Key, ((Component)camp).transform.position);
			}
		}

		public void RequestUnlink()
		{
			Send("MC_MineUnlink");
		}

		public void RequestRecall()
		{
			Send("MC_MineRecall");
		}

		private void RequestLinkNearest()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			MiningCamp miningCamp = MiningCamp.FindNearest(((Component)this).transform.position, MiningCampConfig.MineLinkRange.Value);
			if ((Object)(object)miningCamp == (Object)null)
			{
				Notify($"No mining camp within {MiningCampConfig.MineLinkRange.Value:0} m of this mine");
				return;
			}
			if (miningCamp.Key != 0L && miningCamp.Key == CampKey)
			{
				Notify("This mine is already linked to that camp");
				return;
			}
			RequestLink(miningCamp);
			Notify(Localization.instance.Localize(Ore?.NameToken ?? "Mine") + " linked to the camp " + $"{Vector3.Distance(((Component)miningCamp).transform.position, ((Component)this).transform.position):0} m away");
		}

		private void RPC_Link(long sender, long campKey, Vector3 campPos)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (Owner && campKey != 0L)
			{
				Zdo.Set("mc_campkey", campKey);
				Zdo.Set("mc_camppos", campPos);
			}
		}

		private void RPC_Unlink(long sender)
		{
			if (Owner)
			{
				Zdo.Set("mc_campkey", 0L);
			}
		}

		private void RPC_Recall(long sender)
		{
			if (!Owner)
			{
				return;
			}
			List<long> list = Jobs();
			if (list.Count == 0)
			{
				return;
			}
			int index = 0;
			for (int i = 1; i < list.Count; i++)
			{
				if (list[i] > list[index])
				{
					index = i;
				}
			}
			list.RemoveAt(index);
			SetJobs(list);
			Release(withOre: false);
		}

		private void RPC_Message(long sender, string message)
		{
			Notify(message);
		}

		private void Tell(long peer, string message)
		{
			PieceUtil.Tell(m_nview, peer, "MC_MineMessage", message);
		}

		private static void Notify(string message)
		{
			PieceUtil.Notify(message);
		}

		public float GetHoverOffset()
		{
			return m_hoverOffset;
		}

		public string GetHoverName()
		{
			return Localization.instance.Localize(Ore?.NameToken ?? "$piece_mine");
		}

		public string GetHoverText()
		{
			if (!IsValid)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(Ore?.NameToken ?? "Mine").Append('\n');
			stringBuilder.Append(Linked ? "Linked to a camp" : "Not linked to a camp");
			int insideCount = InsideCount;
			stringBuilder.Append($" · Miners below: {insideCount}");
			if (insideCount > 0)
			{
				stringBuilder.Append(" · Next up in " + FormatSeconds(NextUpSeconds()));
			}
			stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] Link to nearest camp");
			return Localization.instance.Localize(stringBuilder.ToString());
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (hold || !IsValid)
			{
				return false;
			}
			RequestLinkNearest();
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public string Summary()
		{
			string text = Localization.instance.Localize(Ore?.NameToken ?? "Mine");
			int insideCount = InsideCount;
			if (insideCount != 0)
			{
				return $"{text}: {insideCount} below, next up in {FormatSeconds(NextUpSeconds())}";
			}
			return text + ": idle";
		}

		private void Log(string message)
		{
			if (MiningCampConfig.DebugLogging.Value)
			{
				MiningCampPlugin.Log.LogInfo((object)$"[{m_oreId} mine {((Object)this).GetInstanceID()}] {message}");
			}
		}
	}
	public class MinerAI : BaseAI
	{
		private enum State
		{
			Idle,
			Deposit,
			ToMine,
			GoHome
		}

		private const float IdleRethinkSeconds = 3f;

		private const float OrphanGraceSeconds = 30f;

		private const float StuckSeconds = 8f;

		private const float EnterDistance = 1.6f;

		private const float SqueezeDistance = 6f;

		private const float DoorwayHeight = 2.5f;

		private const float WalkTimeoutSeconds = 120f;

		private MinerWorker m_worker;

		private Humanoid m_humanoid;

		private State m_state;

		private float m_thinkTimer;

		private bool m_wasOwner;

		private bool m_gone;

		private float m_gearTimer;

		private float m_orphanSince = -1f;

		private float m_jobSince;

		private Mine m_mine;

		private Container m_chest;

		private Vector3 m_doorwayPos;

		private float m_doorwayStill;

		private bool m_holdingPosition;

		private Vector3 m_stuckPos;

		private float m_stuckTimer;

		private readonly Dictionary<int, float> m_blacklist = new Dictionary<int, float>();

		private float m_nextBlacklistPrune;

		public override void Awake()
		{
			((BaseAI)this).Awake();
			m_worker = ((Component)this).GetComponent<MinerWorker>();
			ref Humanoid humanoid = ref m_humanoid;
			Character character = base.m_character;
			humanoid = (Humanoid)(object)((character is Humanoid) ? character : null);
		}

		public override bool UpdateAI(float dt)
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			if (!((BaseAI)this).UpdateAI(dt))
			{
				if (m_wasOwner)
				{
					m_wasOwner = false;
					m_worker?.ForgetBag();
				}
				return false;
			}
			if (m_gone || (Object)(object)m_worker == (Object)null || (Object)(object)m_humanoid == (Object)null)
			{
				return true;
			}
			if (!m_wasOwner)
			{
				m_wasOwner = true;
				m_worker.LoadBag();
				m_worker.Claim = 0L;
				m_state = State.Idle;
				m_thinkTimer = 0f;
			}
			m_holdingPosition = false;
			MiningCamp miningCamp = m_worker.ResolveCamp();
			if ((Object)(object)miningCamp == (Object)null)
			{
				TickOrphan();
				return true;
			}
			m_orphanSince = -1f;
			m_gearTimer -= dt;
			if (m_gearTimer <= 0f)
			{
				m_gearTimer = 2f;
				m_worker.EnsureGear();
			}
			if (miningCamp.Paused)
			{
				ClearJob();
				m_state = State.Idle;
				StayNear(dt, ((Component)miningCamp).transform.position, 4f);
				m_worker.SetStatus("Paused");
				return true;
			}
			m_thinkTimer -= dt;
			if (m_thinkTimer <= 0f)
			{
				m_thinkTimer = MiningCampConfig.ThinkInterval.Value;
				Think(miningCamp);
			}
			switch (m_state)
			{
			case State.Deposit:
				TickDeposit(dt);
				break;
			case State.ToMine:
				TickToMine(dt, miningCamp);
				break;
			case State.GoHome:
				TickHome(dt, miningCamp);
				break;
			default:
				((BaseAI)this).StopMoving();
				m_holdingPosition = true;
				break;
			}
			TickStuck(dt);
			return true;
		}

		private void Think(MiningCamp camp)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			PruneBlacklist();
			switch (m_state)
			{
			case State.Deposit:
				if ((Object)(object)m_chest != (Object)null && (Object)(object)m_chest.m_nview != (Object)null && m_chest.m_nview.IsValid())
				{
					return;
				}
				break;
			case State.ToMine:
				if ((Object)(object)m_mine != (Object)null && m_mine.IsValid && m_mine.CampKey == camp.Key)
				{
					return;
				}
				break;
			}
			ClearJob();
			Vector3 position = ((Component)this).transform.position;
			List<ItemData> list = m_worker.BagItems();
			if (list.Count > 0)
			{
				Container val = camp.FindChestFor(list, position, IsBlacklisted);
				if ((Object)(object)val != (Object)null)
				{
					StartDeposit(val);
				}
				else
				{
					StartHome((camp.ChestCount == 0) ? "Holding ore: no chest assigned" : "Holding ore: every chest is full");
				}
				return;
			}
			Mine mine = PickMine(camp);
			if ((Object)(object)mine == (Object)null)
			{
				StartHome((camp.MineCount == 0) ? "No mine linked to this camp" : "Waiting for a mine");
				return;
			}
			m_mine = mine;
			m_worker.Claim = mine.Key;
			m_jobSince = Time.time;
			m_doorwayPos = ((Component)this).transform.position;
			m_doorwayStill = 0f;
			SetState(State.ToMine);
			m_worker.SetStatus("Walking to the " + Localization.instance.Localize(mine.Ore?.NameToken ?? "mine").ToLowerInvariant());
			Log("job: " + mine.Ore?.Id + " mine");
		}

		private Mine PickMine(MiningCamp camp)
		{
			Mine result = null;
			double num = double.MaxValue;
			foreach (Mine item in camp.Mines())
			{
				if (item.IsValid && !IsBlacklisted(((Object)item).GetInstanceID()))
				{
					double num2 = (double)(item.InsideCount + MinerWorker.ClaimsOn(item.Key, m_worker)) * 1000000000000.0 + (double)item.LastEnter;
					if (num2 < num)
					{
						num = num2;
						result = item;
					}
				}
			}
			return result;
		}

		private void StartDeposit(Container chest)
		{
			m_chest = chest;
			m_jobSince = Time.time;
			SetState(State.Deposit);
			m_worker.SetStatus("Carrying ore to a chest");
		}

		private void StartHome(string status)
		{
			SetState(State.GoHome);
			m_thinkTimer = 3f;
			m_worker.SetStatus(status);
		}

		private void SetState(State state)
		{
			//IL_0019: 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)
			m_state = state;
			m_stuckTimer = 0f;
			m_stuckPos = ((Component)this).transform.position;
		}

		private void ClearJob()
		{
			m_mine = null;
			m_chest = null;
			m_worker.Claim = 0L;
		}

		private void TickToMine(float dt, MiningCamp camp)
		{
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_mine == (Object)null || !m_mine.IsValid)
			{
				m_mine = null;
				m_state = State.Idle;
				m_thinkTimer = 0f;
				return;
			}
			Vector3 entryPoint = m_mine.EntryPoint;
			float num = Utils.DistanceXZ(((Component)this).transform.position, entryPoint);
			bool flag = Mathf.Abs(((Component)this).transform.position.y - entryPoint.y) <= 2.5f;
			if (num > 1.6f || !flag)
			{
				((BaseAI)this).MoveTo(dt, entryPoint, 1.2f, num > 12f);
				if (Vector3.Distance(((Component)this).transform.position, m_doorwayPos) > 0.1f)
				{
					m_doorwayPos = ((Component)this).transform.position;
					m_doorwayStill = 0f;
				}
				else
				{
					m_doorwayStill += dt;
					if (m_doorwayStill > 3f && num <= 6f && flag)
					{
						Log("path ends " + num.ToString("0.0") + " m short of the doorway; going in anyway");
						m_holdingPosition = true;
						((BaseAI)this).StopMoving();
						Enter(m_mine);
						return;
					}
				}
				if (Time.time - m_jobSince > 120f)
				{
					Blacklist(((Object)m_mine).GetInstanceID(), 120f, "could not reach");
					ClearJob();
					m_state = State.Idle;
					m_thinkTimer = 0f;
				}
			}
			else
			{
				m_holdingPosition = true;
				((BaseAI)this).StopMoving();
				Enter(m_mine);
			}
		}

		private void Enter(Mine mine)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (!mine.NetView.IsOwner())
			{
				mine.NetView.ClaimOwnership();
			}
			if (!mine.Admit(((Component)this).transform.position))
			{
				Blacklist(((Object)mine).GetInstanceID(), 30f, "would not admit");
				ClearJob();
				m_state = State.Idle;
				m_thinkTimer = 0f;
			}
			else
			{
				Log("went below");
				m_gone = true;
				m_worker.Claim = 0L;
				m_worker.Vanish();
			}
		}

		private void TickDeposit(float dt)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_00e4: 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)
			if ((Object)(object)m_chest == (Object)null || (Object)(object)m_chest.m_nview == (Object)null || !m_chest.m_nview.IsValid())
			{
				m_chest = null;
				m_state = State.Idle;
				m_thinkTimer = 0f;
				return;
			}
			Vector3 position = ((Component)m_chest).transform.position;
			float num = Utils.DistanceXZ(((Component)this).transform.position, position);
			if (num > 2.4f)
			{
				((BaseAI)this).MoveTo(dt, position, 1.8f, num > 12f);
				if (Time.time - m_jobSince > 120f)
				{
					Blacklist(((Object)m_chest).GetInstanceID(), 60f, "could not reach");
					m_chest = null;
					m_state = State.Idle;
					m_thinkTimer = 0f;
				}
				return;
			}
			m_holdingPosition = true;
			((BaseAI)this).StopMoving();
			((BaseAI)this).LookAt(position);
			if (WorldQuery.ChestInUse(m_chest))
			{
				m_worker.SetStatus("Waiting for someone to close the chest");
				if (Time.time - m_jobSince > 30f)
				{
					Blacklist(((Object)m_chest).GetInstanceID(), 20f, "chest stayed open");
					m_chest = null;
					m_state = State.Idle;
					m_thinkTimer = 0f;
				}
				return;
			}
			if (!m_chest.m_nview.IsOwner())
			{
				m_chest.m_nview.ClaimOwnership();
			}
			Inventory inventory = m_chest.GetInventory();
			Inventory inventory2 = m_humanoid.GetInventory();
			int num2 = 0;
			foreach (ItemData item in new List<ItemData>(m_worker.BagItems()))
			{
				if (inventory.CanAddItem(item, item.m_stack))
				{
					inventory.MoveItemToThis(inventory2, item);
					num2++;
				}
			}
			if (num2 == 0)
			{
				Blacklist(((Object)m_chest).GetInstanceID(), 30f, "no room in");
			}
			else
			{
				m_worker.SaveBag();
				Log("stored " + num2 + " stack(s)");
			}
			m_chest = null;
			m_state = State.Idle;
			m_thinkTimer = 0f;
		}

		private void TickHome(float dt, MiningCamp camp)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)camp).transform.position;
			float num = Utils.DistanceXZ(((Component)this).transform.position, position);
			if (num > 3f)
			{
				((BaseAI)this).MoveTo(dt, position, 2.5f, num > 15f);
				return;
			}
			((BaseAI)this).StopMoving();
			m_holdingPosition = true;
			m_state = State.Idle;
		}

		private void StayNear(float dt, Vector3 point, float dist)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (Utils.DistanceXZ(((Component)this).transform.position, point) > dist)
			{
				((BaseAI)this).MoveTo(dt, point, dist * 0.8f, false);
				return;
			}
			((BaseAI)this).StopMoving();
			m_holdingPosition = true;
		}

		private void TickOrphan()
		{
			((BaseAI)this).StopMoving();
			m_holdingPosition = true;
			m_worker.SetStatus("Waiting for its camp");
			if (m_orphanSince < 0f)
			{
				m_orphanSince = Time.time;
			}
			else if (Time.time - m_orphanSince > 30f && m_worker.CampIsGone())
			{
				MiningCampPlugin.Log.LogInfo((object)"A miner's camp no longer exists; sending him home.");
				m_worker.Dismiss();
			}
		}

		private void TickStuck(float dt)
		{
			//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_0033: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (m_state == State.Idle || m_holdingPosition)
			{
				m_stuckTimer = 0f;
				m_stuckPos = ((Component)this).transform.position;
				return;
			}
			if (Vector3.Distance(((Component)this).transform.position, m_stuckPos) > 0.3f)
			{
				m_stuckPos = ((Component)this).transform.position;
				m_stuckTimer = 0f;
				return;
			}
			m_stuckTimer += dt;
			if (!(m_stuckTimer < 8f))
			{
				int num = (((Object)(object)m_mine != (Object)null) ? ((Object)m_mine).GetInstanceID() : (((Object)(object)m_chest != (Object)null) ? ((Object)m_chest).GetInstanceID() : 0));
				if (num != 0)
				{
					Blacklist(num, 60f, "could not reach");
				}
				ClearJob();
				m_state = State.Idle;
				m_thinkTimer = 0f;
				m_stuckTimer = 0f;
			}
		}

		private bool IsBlacklisted(int id)
		{
			if (m_blacklist.TryGetValue(id, out var value))
			{
				return Time.time < value;
			}
			return false;
		}

		private void Blacklist(int id, float seconds, string why)
		{
			m_blacklist[id] = Time.time + seconds;
			Log(why + " target " + id + "; ignoring it for " + seconds + "s");
		}

		private void PruneBlacklist()
		{
			if (Time.time < m_nextBlacklistPrune || m_blacklist.Count == 0)
			{
				return;
			}
			m_nextBlacklistPrune = Time.time + 30f;
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, float> item in m_blacklist)
			{
				if (Time.time >= item.Value)
				{
					list.Add(item.Key);
				}
			}
			foreach (int item2 in list)
			{
				m_blacklist.Remove(item2);
			}
		}

		private void Log(string message)
		{
			if (MiningCampConfig.DebugLogging.Value)
			{
				MiningCampPlugin.Log.LogInfo((object)$"[miner {((Object)this).GetInstanceID()}] {message}");
			}
		}
	}
	public class MinerWorker : MonoBehaviour
	{
		public const string ZdoCamp = "mc_campkey";

		public const string ZdoHome = "mc_home";

		public const string ZdoBag = "mc_bag";

		public const string ZdoStatus = "mc_status";

		public const string ZdoJob = "mc_job";

		public const string GroupName = "miningcamp";

		public const int BagWidth = 8;

		public const int BagHeight = 8;

		public static readonly List<MinerWorker> Instances = new List<MinerWorker>();

		private ZNetView m_nview;

		private Humanoid m_humanoid;

		private MiningCamp m_camp;

		private float m_nextCampLookup;

		private float m_spawnedAt;

		private int m_suppressSave;

		private bool m_bagLoaded;

		private string m_status;

		private readonly List<ItemData> m_bagScratch = new List<ItemData>();

		public ZNetView NetView => m_nview;

		public bool IsValid
		{
			get
			{
				if ((Object)(object)m_nview != (Object)null)
				{
					return m_nview.IsValid();
				}
				return false;
			}
		}

		public float Age => Time.time - m_spawnedAt;

		public long CampKey
		{
			get
			{
				if (!IsValid)
				{
					return 0L;
				}
				return m_nview.GetZDO().GetLong("mc_campkey", 0L);
			}
		}

		public Vector3 HomePosition
		{
			get
			{
				//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_000e: Unknown result type (might be due to invalid IL or missing references)
				if (!IsValid)
				{
					return ((Component)this).transform.position;
				}
				return m_nview.GetZDO().GetVec3("mc_home", ((Component)this).transform.position);
			}
		}

		public string Status
		{
			get
			{
				if (!IsValid)
				{
					return string.Empty;
				}
				return m_nview.GetZDO().GetString("mc_status", string.Empty);
			}
		}

		public long Claim
		{
			get
			{
				if (!IsValid)
				{
					return 0L;
				}
				return m_nview.GetZDO().GetLong("mc_job", 0L);
			}
			set
			{
				if (IsValid && m_nview.IsOwner())
				{
					m_nview.GetZDO().Set("mc_job", value);
				}
			}
		}

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			m_humanoid = ((Component)this).GetComponent<Humanoid>();
			m_spawnedAt = Time.time;
			Instances.Add(this);
			if (IsValid && !((Object)(object)m_humanoid == (Object)null))
			{
				Inventory inventory = m_humanoid.GetInventory();
				if (inventory != null)
				{
					inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(OnInventoryChanged));
				}
				EnsureBagRoom();
			}
		}

		private void Start()
		{
			EnsureBagRoom();
			if (IsValid && m_nview.IsOwner())
			{
				LoadBag();
			}
		}

		private void EnsureBagRoom()
		{
			Inventory val = (((Object)(object)m_humanoid != (Object)null) ? m_humanoid.GetInventory() : null);
			if (val != null)
			{
				if (val.m_width < 8)
				{
					val.m_width = 8;
				}
				if (val.m_height < 8)
				{
					val.m_height = 8;
				}
			}
		}

		private void OnDestroy()
		{
			Instances.Remove(this);
		}

		public static bool Is(Character character)
		{
			if ((Object)(object)character != (Object)null)
			{
				return (Object)(object)((Component)character).GetComponent<MinerWorker>() != (Object)null;
			}
			return false;
		}

		public static int CountAll()
		{
			int num = 0;
			foreach (MinerWorker instance in Instances)
			{
				if ((Object)(object)instance != (Object)null && instance.IsValid)
				{
					num++;
				}
			}
			foreach (Mine instance2 in Mine.Instances)
			{
				if ((Object)(object)instance2 != (Object)null && instance2.IsValid)
				{
					num += instance2.InsideCount;
				}
			}
			return num;
		}

		public static List<MinerWorker> ForCamp(long campKey)
		{
			List<MinerWorker> list = new List<MinerWorker>();
			if (campKey == 0L)
			{
				return list;
			}
			foreach (MinerWorker instance in Instances)
			{
				if ((Object)(object)instance != (Object)null && instance.IsValid && instance.CampKey == campKey)
				{
					list.Add(instance);
				}
			}
			return list;
		}

		public void BindCamp(MiningCamp camp)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)camp != (Object)null)
			{
				BindCamp(camp.Key, ((Component)camp).transform.position);
				m_camp = camp;
			}
		}

		public void BindCamp(long key, Vector3 home)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (IsValid && key != 0L)
			{
				m_nview.GetZDO().Set("mc_campkey", key);
				m_nview.GetZDO().Set("mc_home", home);
			}
		}

		public MiningCamp ResolveCamp()
		{
			if ((Object)(object)m_camp != (Object)null && m_camp.IsValid)
			{
				return m_camp;
			}
			m_camp = null;
			if (Time.time < m_nextCampLookup)
			{
				return null;
			}
			m_nextCampLookup = Time.time + 1f;
			m_camp = MiningCamp.FindByKey(CampKey);
			return m_camp;
		}

		public bool CampIsGone()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ResolveCamp() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				return !ZNetScene.instance.OutsideActiveArea(HomePosition);
			}
			return false;
		}

		public static bool IsCargo(ItemData item)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			if (item?.m_shared != null && !item.m_equipped)
			{
				return (int)item.m_shared.m_itemType == 1;
			}
			return false;
		}

		public List<ItemData> BagItems()
		{
			m_bagScratch.Clear();
			Inventory val = (((Object)(object)m_humanoid != (Object)null) ? m_humanoid.GetInventory() : null);
			if (val == null)
			{
				return m_bagScratch;
			}
			foreach (ItemData allItem in val.GetAllItems())
			{
				if (IsCargo(allItem))
				{
					m_bagScratch.Add(allItem);
				}
			}
			return m_bagScratch;
		}

		public void EnsureGear()
		{
			if (!IsValid || !m_nview.IsOwner() || (Object)(object)m_humanoid == (Object)null)
			{
				return;
			}
			Inventory inventory = m_humanoid.GetInventory();
			if (inventory == null)
			{
				return;
			}
			List<ItemData> list = null;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem.m_equipped || IsCargo(allItem) || allItem.m_shared == null)
				{
					continue;
				}
				bool flag = false;
				foreach (ItemData allItem2 in inventory.GetAllItems())
				{
					if (allItem2 != allItem && allItem2.m_equipped && allItem2.m_shared != null && allItem2.m_shared.m_name == allItem.m_shared.m_name)
					{
						flag = true;
						break;
					}
				}
				if (flag || !m_humanoid.EquipItem(allItem, false))
				{
					(list ?? (list = new List<ItemData>())).Add(allItem);
				}
			}
			if (list == null)
			{
				return;
			}
			m_suppressSave++;
			try
			{
				foreach (ItemData item in list)
				{
					inventory.RemoveItem(item);
				}
			}
			finally
			{
				m_suppressSave--;
			}
			if (MiningCampConfig.DebugLogging.Value)
			{
				MiningCampPlugin.Log.LogInfo((object)$"[miner] discarded {list.Count} stray piece(s) of gear from the inventory.");
			}
		}

		public void GiveOre(string prefabName, int amount)
		{
			if (!IsValid || !m_nview.IsOwner() || (Object)(object)m_humanoid == (Object)null || amount <= 0)
			{
				return;
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefabName) : null);
			if ((Object)(object)val == (Object)null)
			{
				MiningCampPlugin.Log.LogError((object)("Ore item '" + prefabName + "' does not exist; a miner came up empty-handed."));
				return;
			}
			if (!m_bagLoaded)
			{
				LoadBag();
			}
			EnsureBagRoom();
			Inventory inventory = m_humanoid.GetInventory();
			if (inventory == null || !inventory.AddItem(val, amount))
			{
				MiningCampPlugin.Log.LogWarning((object)$"A miner could not carry {amount} {prefabName}.");
			}
		}

		private void OnInventoryChanged()
		{
			if (m_suppressSave == 0)
			{
				SaveBag();
			}
		}

		public void SaveBag()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			if (!IsValid || !m_nview.IsOwner() || !m_bagLoaded)
			{
				return;
			}
			Inventory val = new Inventory("mc_bag", (Sprite)null, 8, 8);
			foreach (ItemData item in BagItems())
			{
				val.AddItem(item.Clone());
			}
			ZPackage val2 = new ZPackage();
			val.Save(val2);
			m_nview.GetZDO().Set("mc_bag", val2.GetArray());
		}

		public void LoadBag()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			if (!IsValid || (Object)(object)m_humanoid == (Object)null)
			{
				return;
			}
			Inventory inventory = m_humanoid.GetInventory();
			if (inventory == null)
			{
				return;
			}
			byte[] byteArray = m_nview.GetZDO().GetByteArray("mc_bag", (byte[])null);
			m_suppressSave++;
			try
			{
				foreach (ItemData item in new List<ItemData>(BagItems()))
				{
					inventory.RemoveItem(item);
				}
				if (byteArray != null && byteArray.Length != 0)
				{
					Inventory val = new Inventory("mc_bag", (Sprite)null, 8, 8);
					val.Load(new ZPackage(byteArray));
					foreach (ItemData allItem in val.GetAllItems())
					{
						if (allItem.m_shared != null && (int)allItem.m_shared.m_itemType == 1)
						{
							inventory.AddItem(allItem.Clone());
						}
					}
				}
			}
			finally
			{
				m_suppressSave--;
			}
			m_bagLoaded = true;
		}

		public void ForgetBag()
		{
			m_bagLoaded = false;
		}

		public void SetStatus(string status)
		{
			if (IsValid && m_nview.IsOwner() && !(status == m_status))
			{
				m_status = status;
				m_nview.GetZDO().Set("mc_status", status ?? string.Empty);
			}
		}

		public void Dismiss()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Invalid comparison between Unknown and I4
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			if (!IsValid)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			ZDO zDO = m_nview.GetZDO();
			byte[] byteArray = zDO.GetByteArray("mc_bag", (byte[])null);
			Vector3 val = ((Component)this).transform.position + Vector3.up * 0.5f;
			if (byteArray != null && byteArray.Length != 0)
			{
				Inventory val2 = new Inventory("mc_bag", (Sprite)null, 8, 8);
				val2.Load(new ZPackage(byteArray));
				foreach (ItemData allItem in val2.GetAllItems())
				{
					if (!((Object)(object)allItem.m_dropPrefab == (Object)null) && allItem.m_stack > 0 && allItem.m_shared != null && (int)allItem.m_shared.m_itemType == 1)
					{
						Vector2 val3 = Random.insideUnitCircle * 0.4f;
						ItemDrop.DropItem(allItem, allItem.m_stack, val + new Vector3(val3.x, 0f, val3.y), Quaternion.identity);
					}
				}
			}
			zDO.Set("mc_bag", new byte[0]);
			m_nview.ClaimOwnership();
			ZNetScene.instance.Destroy(((Component)this).gameObject);
		}

		public void Vanish()
		{
			if (!IsValid)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			m_nview.GetZDO().Set("mc_bag", new byte[0]);
			m_nview.ClaimOwnership();
			ZNetScene.instance.Destroy(((Component)this).gameObject);
		}

		public string HoverText()
		{
			string text = Localization.instance.Localize("$mc_worker");
			string status = Status;
			if (!string.IsNullOrEmpty(status))
			{
				text = text + "\n" + status;
			}
			return text;
		}

		public static int ClaimsOn(long mineKey, MinerWorker me)
		{
			int num = 0;
			if (mineKey == 0L)
			{
				return 0;
			}
			foreach (MinerWorker instance in Instances)
			{
				if ((Object)(object)instance != (Object)null && (Object)(object)instance != (Object)(object)me && instance.IsValid && instance.Claim == mineKey)
				{
					num++;
				}
			}
			return num;
		}
	}
	internal static class MineVisuals
	{
		private class Template
		{
			public GameObject Root;

			public bool HasEntry;

			public Vector3 EntryLocal;
		}

		private const string ChildName = "mc_visual";

		private static readonly Dictionary<string, Template> s_templates = new Dictionary<string, Template>();

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

		private static GameObject s_holder;

		private static readonly Type[] Kept = new Type[11]
		{
			typeof(Transform),
			typeof(MeshFilter),
			typeof(MeshRenderer),
			typeof(SkinnedMeshRenderer),
			typeof(LODGroup),
			typeof(Collider),
			typeof(Light),
			typeof(ParticleSystem),
			typeof(ParticleSystemRenderer),
			typeof(Animator),
			typeof(AudioSource)
		};

		public static void Reset()
		{
			foreach (Template value in s_templates.Values)
			{
				if ((Object)(object)value?.Root != (Object)null)
				{
					Object.Destroy((Object)(object)value.Root);
				}
			}
			s_templates.Clear();
			s_warned.Clear();
		}

		public static void Attach(Mine mine)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mine == (Object)null || (Object)(object)((Component)mine).transform.Find("mc_visual") != (Object)null)
			{
				return;
			}
			Template template = GetTemplate(mine.Ore);
			if (template != null)
			{
				GameObject obj = Object.Instantiate<GameObject>(template.Root, ((Component)mine).transform, false);
				((Object)obj).name = "mc_visual";
				obj.transform.localPosition = Vector3.zero;
				obj.transform.localRotation = Quaternion.identity;
				obj.transform.localScale = Vector3.one;
				obj.SetActive(true);
				if (template.HasEntry)
				{
					mine.SetEntryLocal(template.EntryLocal);
				}
			}
		}

		private static Template GetTemplate(OreType ore)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if (ore == null)
			{
				return null;
			}
			if (s_templates.TryGetValue(ore.Id, out var value) && (Object)(object)value?.Root != (Object)null)
			{
				return value;
			}
			List<string> list = new List<string>();
			foreach (string item in MiningCampConfig.Entrances(ore))
			{
				list.Add(item);
				GameObject val = FindLocationPrefab(item) ?? FindScenePrefab(item);
				if (!((Object)(object)val == (Object)null))
				{
					Template template = Build(val, item);
					if (template != null)
					{
						s_templates[ore.Id] = template;
						MiningCampPlugin.Log.LogInfo((object)(ore.DisplayName + " is dressed as '" + item + "'" + (template.HasEntry ? $", doorway at {template.EntryLocal}." : "; it has no teleport trigger, so the doorway is assumed 1.5 m in front.")));
						return template;
					}
				}
			}
			if (s_warned.Add(ore.Id))
			{
				MiningCampPlugin.Log.LogWarning((object)("None of the entrances for the " + ore.DisplayName + " exist ('" + string.Join("', '", list) + "'). Set ListLocations in the config to see every location name, then fix " + ore.Id + "Entrance. Falling back to a stone arch."));
			}
			GameObject val2 = FindScenePrefab("stone_arch");
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			Template template2 = Build(val2, "stone_arch");
			if (template2 != null)
			{
				s_templates[ore.Id] = template2;
			}
			return template2;
		}

		private static GameObject FindLocationPrefab(string name)
		{
			//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_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return null;
			}
			ZoneLocation location = ZoneSystem.instance.GetLocation(name);
			if (location == null)
			{
				return null;
			}
			try
			{
				SoftReference<GameObject> prefab = location.m_prefab;
				if (!prefab.IsValid)
				{
					return null;
				}
				if (!prefab.IsLoaded)
				{
					prefab.Load();
				}
				GameObject asset = prefab.Asset;
				if ((Object)(object)asset != (Object)null)
				{
					prefab.HoldReference();
				}
				return asset;
			}
			catch (Exception ex)
			{
				MiningCampPlugin.Log.LogWarning((object)("Could not load location '" + name + "': " + ex.Message));
				return null;
			}
		}

		private static GameObject FindScenePrefab(string name)
		{
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(name) : null);
			if ((Object)(object)val == (Object)null)
			{
				val = PrefabManager.Instance.GetPrefab(name);
			}
			return val;
		}

		private static void EnsureHolder()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)s_holder != (Object)null))
			{
				s_holder = new GameObject("MiningCamp_Dressings");
				s_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)s_holder);
			}
		}

		private static Template Build(GameObject source, string sourceName)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			EnsureHolder();
			GameObject val;
			try
			{
				val = Object.Instantiate<GameObject>(source, s_holder.transform, false);
			}
			catch (Exception ex)
			{
				MiningCampPlugin.Log.LogWarning((object)("Could not copy '" + sourceName + "': " + ex.Message));
				return null;
			}
			((Object)val).name = "dressing_" + sourceName;
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one;
			val.SetActive(true);
			Template template = new Template
			{
				Root = val
			};
			Teleport[] componentsInChildren = val.GetComponentsInChildren<Teleport>(true);
			foreach (Teleport val2 in componentsInChildren)
			{
				Vector3 val3 = val.transform.InverseTransformPoint(((Component)val2).transform.position);
				if (!template.HasEntry || Mathf.Abs(val3.y) < Mathf.Abs(template.EntryLocal.y))
				{
					template.EntryLocal = val3;
					template.HasEntry = true;
				}
			}
			Location[] componentsInChildren2 = val.GetComponentsInChildren<Location>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Transform interiorTransform = componentsInChildren2[i].m_interiorTransform;
				if ((Object)(object)interiorTransform != (Object)null && (Object)(object)interiorTransform != (Object)(object)val.transform)
				{
					Object.DestroyImmediate((Object)(object)((Component)interiorTransform).gameObject);
				}
			}
			DungeonGenerator[] componentsInChildren3 = val.GetComponentsInChildren<DungeonGenerator>(true);
			foreach (DungeonGenerator val4 in componentsInChildren3)
			{
				if ((Object)(object)val4 != (Object)null && (Object)(object)((Component)val4).gameObject != (Object)(object)val)
				{
					Object.DestroyImmediate((Object)(object)((Component)val4).gameObject);
				}
			}
			List<GameObject> list = new List<GameObject>();
			foreach (Transform item in val.transform)
			{
				Transform val5 = item;
				if (Mathf.Abs(val5.localPosition.y) > 200f)
				{
					list.Add(((Component)val5).gameObject);
				}
			}
			foreach (GameObject item2 in list)
			{
				Object.DestroyImmediate((Object)(object)item2);
			}
			List<GameObject> list2 = new List<GameObject>();
			Door[] componentsInChildren4 = val.GetComponentsInChildren<Door>(true);
			foreach (Door val6 in componentsInChildren4)
			{
				if ((Object)(object)val6 != (Object)null && (Object)(object)((Component)val6).gameObject != (Object)(object)val)
				{
					list2.Add(((Component)val6).gameObject);
				}
			}
			foreach (GameObject item3 in list2)
			{
				Object.DestroyImmediate((Object)(object)item3);
			}
			List<GameObject> list3 = new List<GameObject>();
			RandomFlyingBird[] componentsInChildren5 = val.GetComponentsInChildren<RandomFlyingBird>(true);
			foreach (RandomFlyingBird val7 in componentsInChildren5)
			{
				if ((Object)(object)val7 != (Object)null && (Object)(object)((Component)val7).gameObject != (Object)(object)val)
				{
					list3.Add(((Component)val7).gameObject);
				}
			}
			Character[] componentsInChildren6 = val.GetComponentsInChildren<Character>(true);
			foreach (Character val8 in componentsInChildren6)
			{
				if ((Object)(object)val8 != (Object)null && (Object)(object)((Component)val8).gameObject != (Object)(object)val)
				{
					list3.Add(((Component)val8).gameObject);
				}
			}
			foreach (GameObject item4 in list3)
			{
				if ((Object)(object)item4 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)item4);
				}
			}
			Fireplace[] componentsInChildren7 = val.GetComponentsInChildren<Fireplace>(true);
			foreach (Fireplace val9 in componentsInChildren7)
			{
				if ((Object)(object)val9.m_enabledObject != (Object)null)
				{
					val9.m_enabledObject.SetActive(true);
				}
			}
			Strip(val);
			val.SetActive(false);
			return template;
		}

		private static void Strip(GameObject root)
		{
			for (int i = 0; i < 6; i++)
			{
				Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
				int num = 0;
				for (int num2 = componentsInChildren.Length - 1; num2 >= 0; num2--)
				{
					Component val = componentsInChildren[num2];
					if (!((Object)(object)val == (Object)null) && !IsKept(val))
					{
						try
						{
							Object.DestroyImmediate((Object)(object)val);
							if ((Object)(object)val == (Object)null)
							{
								num++;
							}
						}
						catch
						{
						}
					}
				}
				if (num == 0)
				{
					break;
				}
			}
		}

		private static bool IsKept(Component c)
		{
			Type[] kept = Kept;
			for (int i = 0; i < kept.Length; i++)
			{
				if (kept[i].IsInstanceOfType(c))
				{
					return true;
				}
			}
			return false;
		}

		public static void ListLocations()
		{
			if ((Object)(object)ZoneSystem.instance == (Object)null || ZoneSystem.instance.m_locations == null)
			{
				return;
			}
			List<string> list = new List<string>();
			foreach (ZoneLocation location in ZoneSystem.instance.m_locations)
			{
				if (location != null && !string.IsNullOrEmpty(location.m_prefabName))
				{
					list.Add(location.m_prefabName);
				}
			}
			list.Sort(StringComparer.OrdinalIgnoreCase);
			MiningCampPlugin.Log.LogInfo((object)string.Format("Locations known to this world ({0}): {1}", list.Count, string.Join(", ", list)));
		}
	}
	public class MiningCamp : MonoBehaviour, Hoverable, Interactable
	{
		private const string ZdoPaused = "mc_paused";

		private const string ZdoChests = "mc_chests";

		private const string ZdoSpawned = "mc_spawned";

		private const string ZdoKey = "mc_key";

		private const string RpcSetPaused = "MC_SetPaused";

		private const string RpcAddWorker = "MC_AddWorker";

		private const string RpcRemoveWorker = "MC_RemoveWorker";

		private const string RpcAddChest = "MC_AddChest";

		private const string RpcClearChests = "MC_ClearChests";

		private const string RpcLinkMine = "MC_LinkMine";

		private const string RpcUnlinkMines = "MC_UnlinkMines";

		private const string RpcMessage = "MC_Message";

		public static readonly List<MiningCamp> Instances = new List<MiningCamp>();

		[Tooltip("Metres above the piece origin to float the hover text.")]
		public float m_hoverOffset = 0.6f;

		private ZNetView m_nview;

		private WearNTear m_wear;

		private bool m_ready;

		private string m_hoverCache;

		private float m_hoverCacheAt = -1f;

		private float m_nextSweep;

		private const float ChestMatchRadius = 0.6f;

		private const float ChestPruneSeconds = 30f;

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

		private readonly List<KeyValuePair<Vector3, Container>> m_chestCache = new List<KeyValuePair<Vector3, Container>>();

		private readonly Dictionary<Vector3, float> m_chestMissingSince = new Dictionary<Vector3, float>();

		private readonly Dictionary<Vector3, float> m_chestNextLookup = new Dictionary<Vector3, float>();

		public bool IsValid
		{
			get
			{
				if (m_ready && (Object)(object)m_nview != (Object)null)
				{
					return m_nview.IsValid();
				}
				return false;
			}
		}

		public long Key
		{
			get
			{
				if (!IsValid)
				{
					return 0L;
				}
				return Zdo.GetLong("mc_key", 0L);
			}
		}

		private ZDO Zdo => m_nview.GetZDO();

		public bool Paused
		{
			get
			{
				if (IsValid)
				{
					return Zdo.GetBool("mc_paused", false);
				}
				return false;
			}
		}

		public int MineCount => Mines().Count;

		public int BelowCount
		{
			get
			{
				int num = 0;
				foreach (Mine item in Mines())
				{
					num += item.InsideCount;
				}
				return num;
			}
		}

		public int WorkerCount => Workers().Count + BelowCount;

		public int ChestCount => ChestPositions().Count;

		private bool Owner
		{
			get
			{
				if (IsValid)
				{
					return m_nview.IsOwner();
				}
				return false;
			}
		}

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				m_ready = true;
				Instances.Add(this);
				m_nview.Register<bool>("MC_SetPaused", (Action<long, bool>)RPC_SetPaused);
				m_nview.Register("MC_AddWorker", (Action<long>)RPC_AddWorker);
				m_nview.Register("MC_RemoveWorker", (Action<long>)RPC_RemoveWorker);
				m_nview.Register<Vector3>("MC_AddChest", (Action<long, Vector3>)RPC_AddChest);
				m_nview.Register("MC_ClearChests", (Action<long>)RPC_ClearChests);
				m_nview.Register<Vector3>("MC_LinkMine", (Action<long, Vector3>)RPC_LinkMine);
				m_nview.Register("MC_UnlinkMines", (Action<long>)RPC_UnlinkMines);
				m_nview.Register<string>("MC_Message", (Action<long, string>)RPC_Message);
				m_wear = ((Component)this).GetComponent<WearNTear>();
				if ((Object)(object)m_wear != (Object)null)
				{
					WearNTear wear = m_wear;
					wear.m_onDestroyed = (Action)Delegate.Combine(wear.m_onDestroyed, new Action(OnPieceDestroyed));
				}
			}
		}

		private void Start()
		{
			if (IsValid && m_nview.IsOwner())
			{
				EnsureKey();
				if (!Zdo.GetBool("mc_spawned", false))
				{
					Zdo.Set("mc_spawned", true);
					SpawnWorker();
				}
			}
		}

		private void Update()
		{
			if (m_ready && m_nview.IsValid() && m_nview.IsOwner())
			{
				if (Key == 0L)
				{
					EnsureKey();
				}
				if (Time.time >= m_nextSweep)
				{
					m_nextSweep = Time.time + 3f;
					SweepStrayGear();
					TrimSurplusWorkers();
				}
			}
		}

		private void TrimSurplusWorkers()
		{
			int value = MiningCampConfig.MaxWorkersPerCamp.Value;
			int workerCount = WorkerCount;
			if (workerCount <= value)
			{
				return;
			}
			List<MinerWorker> list = new List<MinerWorker>();
			foreach (MinerWorker item in Workers())
			{
				if (item.Age > 5f)
				{
					list.Add(item);
				}
			}
			MinerWorker minerWorker = Farthest(list);
			if (!((Object)(object)minerWorker == (Object)null))
			{
				minerWorker.Dismiss();
				MiningCampPlugin.Log.LogInfo((object)($"A mining camp employed {workerCount} miners with a cap of {value}; one was sent home. " + "He dropped what he carried."));
			}
		}

		private MinerWorker Farthest(List<MinerWorker> workers)
		{
			//IL_001f: 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)
			MinerWorker result = null;
			float num = -1f;
			foreach (MinerWorker worker in workers)
			{
				float num2 = Vector3.Distance(((Component)worker).transform.position, ((Component)this).transform.position);
				if (num2 > num)
				{
					num = num2;
					result = worker;
				}
			}
			return result;
		}

		private void SweepStrayGear()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			float num = MiningCampConfig.MineLinkRange.Value + 20f;
			List<Vector3> list = new List<Vector3> { ((Component)this).transform.position };
			foreach (Mine item in Mines())
			{
				list.Add(((Component)item).transform.position);
			}
			List<ItemDrop> list2 = null;
			foreach (ItemDrop s_instance in ItemDrop.s_instances)
			{
				if ((Object)(object)s_instance == (Object)null || (Object)(object)s_instance.m_nview == (Object)null || !s_instance.m_nview.IsValid() || !((Object)((Component)s_instance).gameObject).name.StartsWith("Dverger", StringComparison.Ordinal) || !PieceUtil.IsCreatureGear(s_instance.m_itemData))
				{
					continue;
				}
				bool flag = false;
				foreach (Vector3 item2 in list)
				{
					if (Utils.DistanceXZ(((Component)s_instance).transform.position, item2) <= num)
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					(list2 ?? (list2 = new List<ItemDrop>())).Add(s_instance);
				}
			}
			if (list2 == null)
			{
				return;
			}
			foreach (ItemDrop item3 in list2)
			{
				if (!item3.m_nview.IsOwner())
				{
					item3.m_nview.ClaimOwnership();
				}
				ZNetScene.instance.Destroy(((Component)item3).gameObject);
			}
			MiningCampPlugin.Log.LogInfo((object)($"Cleared {list2.Count} stray piece(s) of Dvergr gear near a mining camp " + $"(first at {((Component)list2[0]).transform.position})."));
		}

		private void EnsureKey()
		{
			if (Key == 0L)
			{
				Zdo.Set("mc_key", PieceUtil.NewStableKey());
			}
		}

		private void OnDestroy()
		{
			Instances.Remove(this);
			if ((Object)(object)CampPanel.Current == (Object)(object)this)
			{
				CampPanel.Hide();
			}
		}

		public static MiningCamp FindByKey(long key)
		{
			if (key == 0L)
			{
				return null;
			}
			foreach (MiningCamp instance in Instances)
			{
				if ((Object)(object)instance != (Object)null && instance.IsValid && instanc