Decompiled source of WindheimShips v0.1.1

plugins\Windheim.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using Windheim.Config;
using Windheim.ShipRecall;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Windheim
{
	[BepInPlugin("com.TAIJI.windheim", "WindheimShips", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class WindheimPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.TAIJI.windheim";

		public const string PluginName = "WindheimShips";

		public const string PluginVersion = "0.1.0";

		public static WindheimPlugin Instance { get; private set; }

		private void Awake()
		{
			//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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00c2: 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)
			Instance = this;
			GeneralConfig.Bind(((BaseUnityPlugin)this).Config);
			FleetConfig.Bind(((BaseUnityPlugin)this).Config);
			RecallConfig.Bind(((BaseUnityPlugin)this).Config);
			MapConfig.Bind(((BaseUnityPlugin)this).Config);
			UIConfig.Bind(((BaseUnityPlugin)this).Config);
			PersistenceConfig.Bind(((BaseUnityPlugin)this).Config);
			CompatibilityConfig.Bind(((BaseUnityPlugin)this).Config);
			DebugConfig.Bind(((BaseUnityPlugin)this).Config);
			ExperimentalConfig.Bind(((BaseUnityPlugin)this).Config);
			InputManager.Instance.AddButton("com.TAIJI.windheim", new ButtonConfig
			{
				Name = "WH_ShipRecall",
				Key = RecallConfig.RecallKey.Value,
				HintToken = "Recall Ship"
			});
			new Harmony("com.TAIJI.windheim").PatchAll();
			GameObject val = new GameObject("Windheim_Host");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<ShipRegistry>();
			val.AddComponent<ShipRecallSystem>();
			val.AddComponent<QuickRecallUI>();
			if (GeneralConfig.ShowWelcomeMessage.Value)
			{
				Logger.LogInfo((object)"WindheimShips 0.1.0 loaded.");
			}
		}

		private void Update()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				QuickRecallUI instance = QuickRecallUI.Instance;
				if ((instance == null || !instance.IsOpen) && !IsTyping() && Input.GetKeyDown(RecallConfig.RecallKey.Value))
				{
					ShipRecallSystem.Instance?.TrySummon();
				}
			}
		}

		private static bool IsTyping()
		{
			try
			{
				EventSystem current = EventSystem.current;
				if ((Object)(object)current == (Object)null)
				{
					return false;
				}
				GameObject currentSelectedGameObject = current.currentSelectedGameObject;
				InputField val = default(InputField);
				return (Object)(object)currentSelectedGameObject != (Object)null && currentSelectedGameObject.TryGetComponent<InputField>(ref val);
			}
			catch
			{
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(Ship), "Awake")]
	internal static class Patch_Ship_Awake
	{
		private static void Postfix(Ship __instance)
		{
			ShipRegistry.Instance?.RegisterShip(__instance);
		}
	}
}
namespace Windheim.ShipRecall
{
	public class QuickRecallUI : MonoBehaviour
	{
		private Canvas _canvas;

		private CanvasGroup _group;

		private GameObject _root;

		private const float W = 460f;

		private const float CARD_W = 310f;

		private const float CARD_H = 52f;

		private const float ICON_W = 44f;

		private const float PAD_TOP = 28f;

		private const float TITLE_H = 54f;

		private const float SUB_H = 22f;

		private const float GAP = 44f;

		private const float CARD_GAP = 10f;

		private const float PAD_BOT = 28f;

		private static readonly Color C_Title = new Color(0.97f, 0.94f, 0.83f, 1f);

		private static readonly Color C_Sub = new Color(0.78f, 0.72f, 0.58f, 1f);

		private static readonly Color C_CardBg = new Color(0.04f, 0.04f, 0.03f, 0.84f);

		private static readonly Color C_CardHov = new Color(0.16f, 0.12f, 0.05f, 0.92f);

		private static readonly Color C_CardPrs = new Color(0.26f, 0.18f, 0.06f, 0.96f);

		private static readonly Color C_Name = new Color(0.97f, 0.93f, 0.82f, 1f);

		private static readonly Color C_NameNone = new Color(0.6f, 0.54f, 0.44f, 1f);

		private static readonly Color C_IconPri = new Color(0.97f, 0.8f, 0.24f, 1f);

		private static readonly Color C_IconSec = new Color(0.86f, 0.9f, 0.96f, 1f);

		private static readonly Color C_Overlay = new Color(0f, 0f, 0f, 0.42f);

		private static readonly Color C_Border = new Color(0.58f, 0.46f, 0.18f, 0.85f);

		public static QuickRecallUI Instance { get; private set; }

		public bool IsOpen
		{
			get
			{
				if ((Object)(object)_root != (Object)null)
				{
					return _root.activeSelf;
				}
				return false;
			}
		}

		private static Font NorseFont
		{
			get
			{
				GUIManager instance = GUIManager.Instance;
				return ((instance != null) ? instance.NorseBold : null) ?? Resources.GetBuiltinResource<Font>("Arial.ttf");
			}
		}

		private static Font BodyFont
		{
			get
			{
				GUIManager instance = GUIManager.Instance;
				object obj = ((instance != null) ? instance.AveriaSerifBold : null);
				if (obj == null)
				{
					GUIManager instance2 = GUIManager.Instance;
					obj = ((instance2 != null) ? instance2.AveriaSerif : null) ?? Resources.GetBuiltinResource<Font>("Arial.ttf");
				}
				return (Font)obj;
			}
		}

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			GUIManager.BlockInput(false);
		}

		private void LateUpdate()
		{
			if (IsOpen)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)2;
				if (Input.GetKeyDown((KeyCode)27))
				{
					Close();
				}
			}
		}

		public void Open()
		{
			EnsureCanvas();
			Rebuild();
			_root.SetActive(true);
			GUIManager.BlockInput(true);
			((MonoBehaviour)this).StopAllCoroutines();
			((MonoBehaviour)this).StartCoroutine(FadeIn());
		}

		public void Close()
		{
			if (IsOpen)
			{
				((MonoBehaviour)this).StopAllCoroutines();
				((MonoBehaviour)this).StartCoroutine(FadeClose());
			}
		}

		private IEnumerator FadeIn()
		{
			if (!((Object)(object)_group == (Object)null))
			{
				_group.alpha = 0f;
				float t = 0f;
				while (t < 0.2f)
				{
					t += Time.unscaledDeltaTime;
					_group.alpha = Mathf.Clamp01(t / 0.2f);
					yield return null;
				}
				_group.alpha = 1f;
			}
		}

		private IEnumerator FadeClose()
		{
			if ((Object)(object)_group != (Object)null)
			{
				float s = _group.alpha;
				float t = 0f;
				while (t < 0.14f)
				{
					t += Time.unscaledDeltaTime;
					_group.alpha = Mathf.Lerp(s, 0f, t / 0.14f);
					yield return null;
				}
				_group.alpha = 0f;
			}
			if ((Object)(object)_root != (Object)null)
			{
				_root.SetActive(false);
			}
			GUIManager.BlockInput(false);
		}

		private void Rebuild()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			ShipRegistry instance = ShipRegistry.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				float num = 290f;
				float leftX = 75f;
				_root = new GameObject("WH_QR_Root");
				_root.transform.SetParent(((Component)_canvas).transform, false);
				RectTransform obj = _root.AddComponent<RectTransform>();
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0.5f, 0.5f);
				obj.anchorMax = val;
				obj.anchorMin = val;
				obj.pivot = new Vector2(0.5f, 0.5f);
				obj.anchoredPosition = Vector2.zero;
				obj.sizeDelta = new Vector2(460f, num);
				_group = _root.AddComponent<CanvasGroup>();
				GameObject obj2 = MakeGo("Bg", _root.transform);
				((Graphic)obj2.AddComponent<Image>()).color = C_Overlay;
				Fill(obj2.GetComponent<RectTransform>());
				float num2 = -28f;
				GameObject obj3 = MakeGo("Title", _root.transform);
				Text obj4 = obj3.AddComponent<Text>();
				obj4.font = NorseFont;
				obj4.fontSize = 36;
				obj4.fontStyle = (FontStyle)1;
				((Graphic)obj4).color = C_Title;
				obj4.alignment = (TextAnchor)4;
				obj4.supportRichText = true;
				obj4.text = "<color=#C09040>∾∾</color>  Windheim Fleet  <color=#C09040>∾∾</color>";
				obj4.horizontalOverflow = (HorizontalWrapMode)1;
				obj4.verticalOverflow = (VerticalWrapMode)1;
				PinRT(obj3.GetComponent<RectTransform>(), 0f, num2, 460f, 54f);
				num2 -= 54f;
				GameObject obj5 = MakeGo("Sub", _root.transform);
				Text obj6 = obj5.AddComponent<Text>();
				obj6.font = BodyFont;
				obj6.fontSize = 12;
				((Graphic)obj6).color = C_Sub;
				obj6.alignment = (TextAnchor)4;
				obj6.text = "Choose a ship to recall";
				obj6.horizontalOverflow = (HorizontalWrapMode)1;
				obj6.verticalOverflow = (VerticalWrapMode)1;
				PinRT(obj5.GetComponent<RectTransform>(), 0f, num2, 460f, 22f);
				num2 -= 66f;
				Game instance2 = Game.instance;
				object obj7;
				if (instance2 == null)
				{
					obj7 = null;
				}
				else
				{
					PlayerProfile playerProfile = instance2.GetPlayerProfile();
					obj7 = ((playerProfile != null) ? playerProfile.GetName() : null);
				}
				if (obj7 == null)
				{
					Player localPlayer = Player.m_localPlayer;
					obj7 = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "Wanderer";
				}
				string playerName = (string)obj7;
				BuildCard(_root.transform, instance.Primary, isPrimary: true, leftX, num2, playerName);
				num2 -= 62f;
				BuildCard(_root.transform, instance.Secondary, isPrimary: false, leftX, num2, playerName);
			}
		}

		private void BuildCard(Transform parent, ShipRecord rec, bool isPrimary, float leftX, float topY, string playerName)
		{
			//IL_0024: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: 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_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected O, but got Unknown
			float num = 308f;
			float num2 = 50f;
			GameObject val = MakeGo("Border", parent);
			((Graphic)val.AddComponent<Image>()).color = C_Border;
			PinRT(val.GetComponent<RectTransform>(), leftX, topY, 310f, 52f);
			GameObject val2 = MakeGo("Fill", val.transform);
			Image val3 = val2.AddComponent<Image>();
			((Graphic)val3).color = C_CardBg;
			PinRT(val2.GetComponent<RectTransform>(), 1f, -1f, num, num2);
			GameObject obj = MakeGo("IconBg", val2.transform);
			((Graphic)obj.AddComponent<Image>()).color = new Color(0.07f, 0.06f, 0.04f, 0.72f);
			PinRT(obj.GetComponent<RectTransform>(), 0f, 0f, 44f, num2);
			float num3 = 24f;
			BuildIconCell(x: (44f - num3) * 0.5f, y: 0f - Mathf.Floor((num2 - num3) * 0.5f), parent: obj.transform, rec: rec, isPrimary: isPrimary, size: num3);
			GameObject obj2 = MakeGo("Div", val2.transform);
			((Graphic)obj2.AddComponent<Image>()).color = new Color(0.5f, 0.4f, 0.16f, 0.6f);
			PinRT(obj2.GetComponent<RectTransform>(), 44f, -8f, 1f, num2 - 16f);
			float num4 = 58f;
			float w = num - num4 - 10f;
			float num5 = 22f;
			float y = 0f - Mathf.Floor((num2 - num5) * 0.5f);
			string text = ((rec == null) ? (isPrimary ? "No Flagship" : "No Boat") : (isPrimary ? "Flagship" : "Boat"));
			GameObject obj3 = MakeGo("Name", val2.transform);
			Text obj4 = obj3.AddComponent<Text>();
			obj4.font = NorseFont;
			obj4.fontSize = 16;
			((Graphic)obj4).color = ((rec != null) ? C_Name : C_NameNone);
			obj4.alignment = (TextAnchor)3;
			obj4.text = text;
			obj4.horizontalOverflow = (HorizontalWrapMode)1;
			obj4.verticalOverflow = (VerticalWrapMode)1;
			PinRT(obj3.GetComponent<RectTransform>(), num4, y, w, num5);
			if (rec != null)
			{
				Button obj5 = val.AddComponent<Button>();
				((Selectable)obj5).targetGraphic = (Graphic)(object)val3;
				ColorBlock defaultColorBlock = ColorBlock.defaultColorBlock;
				((ColorBlock)(ref defaultColorBlock)).normalColor = C_CardBg;
				((ColorBlock)(ref defaultColorBlock)).highlightedColor = C_CardHov;
				((ColorBlock)(ref defaultColorBlock)).pressedColor = C_CardPrs;
				((ColorBlock)(ref defaultColorBlock)).fadeDuration = 0.1f;
				((Selectable)obj5).colors = defaultColorBlock;
				ShipRecord captured = rec;
				((UnityEvent)obj5.onClick).AddListener((UnityAction)delegate
				{
					ShipRecallSystem.Instance?.PerformSummon(captured);
				});
			}
		}

		internal static void BuildIconCell(Transform parent, ShipRecord rec, bool isPrimary, float x, float y, float size)
		{
			//IL_004b: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = ((rec != null) ? GetSpriteByName(isPrimary ? "mapicon_hammer" : "mapicon_pin") : null);
			if ((Object)(object)val != (Object)null)
			{
				Image obj = MakeGo("Spr", parent).AddComponent<Image>();
				obj.sprite = val;
				obj.type = (Type)0;
				obj.preserveAspect = true;
				((Graphic)obj).color = rec.MapIconColor;
				PinRT(((Graphic)obj).rectTransform, x, y, size, size);
				return;
			}
			Image obj2 = MakeGo("Dot", parent).AddComponent<Image>();
			((Graphic)obj2).color = (Color)((rec != null) ? C_IconSec : new Color(0.38f, 0.34f, 0.26f, 0.55f));
			PinRT(((Graphic)obj2).rectTransform, x, y, size, size);
			GameObject obj3 = MakeGo("Abbr", parent);
			Text obj4 = obj3.AddComponent<Text>();
			obj4.font = NorseFont;
			obj4.fontSize = 12;
			obj4.fontStyle = (FontStyle)1;
			((Graphic)obj4).color = new Color(0.06f, 0.04f, 0.02f, 1f);
			obj4.alignment = (TextAnchor)4;
			obj4.text = ShipAbbr(rec, isPrimary);
			obj4.horizontalOverflow = (HorizontalWrapMode)1;
			obj4.verticalOverflow = (VerticalWrapMode)1;
			PinRT(obj3.GetComponent<RectTransform>(), x, y, size, size);
		}

		private void EnsureCanvas()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_canvas != (Object)null))
			{
				GameObject val = new GameObject("WH_QuickRecall_Canvas");
				Object.DontDestroyOnLoad((Object)(object)val);
				_canvas = val.AddComponent<Canvas>();
				_canvas.renderMode = (RenderMode)0;
				_canvas.sortingOrder = 200;
				CanvasScaler obj = val.AddComponent<CanvasScaler>();
				obj.uiScaleMode = (ScaleMode)1;
				obj.referenceResolution = new Vector2(1920f, 1080f);
				val.AddComponent<GraphicRaycaster>();
			}
		}

		internal static Sprite GetPinSprite(PinType pinType)
		{
			//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_0030: 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_0036: 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)
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				return null;
			}
			List<SpriteData> icons = Minimap.instance.m_icons;
			if (icons == null)
			{
				return null;
			}
			foreach (SpriteData item in icons)
			{
				if (item.m_name == pinType)
				{
					return item.m_icon;
				}
			}
			return null;
		}

		internal static Sprite GetSpriteByName(string spriteName)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (Minimap.instance?.m_icons != null)
			{
				foreach (SpriteData icon in Minimap.instance.m_icons)
				{
					if ((Object)(object)icon.m_icon != (Object)null && ((Object)icon.m_icon).name == spriteName)
					{
						return icon.m_icon;
					}
				}
			}
			Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>();
			foreach (Sprite val in array)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name == spriteName)
				{
					return val;
				}
			}
			return null;
		}

		private static string ShipAbbr(ShipRecord rec, bool isPrimary)
		{
			if (rec == null)
			{
				if (!isPrimary)
				{
					return "S";
				}
				return "P";
			}
			return rec.Type switch
			{
				"Karve" => "K", 
				"Longship" => "L", 
				"Drakkar" => "D", 
				_ => "R", 
			};
		}

		private static string TitleCase(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return s;
			}
			char[] array = s.ToLower().ToCharArray();
			array[0] = char.ToUpper(array[0]);
			for (int i = 1; i < array.Length; i++)
			{
				if (array[i - 1] == ' ')
				{
					array[i] = char.ToUpper(array[i]);
				}
			}
			return new string(array);
		}

		internal static GameObject MakeGo(string name, Transform parent)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.AddComponent<RectTransform>();
			val.transform.SetParent(parent, false);
			return val;
		}

		internal static void PinRT(RectTransform rt, float x, float y, float w, float h)
		{
			//IL_000b: 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_0035: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = new Vector2(0f, 1f);
			rt.anchorMax = new Vector2(0f, 1f);
			rt.pivot = new Vector2(0f, 1f);
			rt.anchoredPosition = new Vector2(x, y);
			rt.sizeDelta = new Vector2(w, h);
		}

		internal static void Fill(RectTransform rt)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			rt.anchoredPosition = Vector2.zero;
			rt.sizeDelta = Vector2.zero;
		}
	}
	[HarmonyPatch(typeof(ShipControlls), "Interact")]
	internal static class Patch_ShipControlls_SetPrimary
	{
		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AccessTools.Method(typeof(ShipControlls), "Interact", new Type[3]
			{
				typeof(Humanoid),
				typeof(bool),
				typeof(bool)
			}, (Type[])null) != null;
		}

		private static void Postfix(ShipControlls __instance)
		{
			HelmHelper.DoSetPrimary(__instance);
		}
	}
	[HarmonyPatch(typeof(ShipControlls), "TryInteract")]
	internal static class Patch_ShipControlls_SetPrimary_TryInteract
	{
		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AccessTools.Method(typeof(ShipControlls), "TryInteract", new Type[3]
			{
				typeof(Humanoid),
				typeof(bool),
				typeof(bool)
			}, (Type[])null) != null;
		}

		private static void Postfix(ShipControlls __instance)
		{
			HelmHelper.DoSetPrimary(__instance);
		}
	}
	internal static class HelmHelper
	{
		internal static void DoSetPrimary(ShipControlls controls)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			Ship componentInParent = ((Component)controls).GetComponentInParent<Ship>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			ShipRegistry.Instance?.RegisterShip(componentInParent);
			ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (zDO == null)
			{
				return;
			}
			long ownerID = ShipRegistry.GetOwnerID();
			long myUID = ShipRegistry.GetMyUID();
			long num = zDO.GetLong("WH_Owner", 0L);
			if (num == 0L && component.IsOwner())
			{
				zDO.Set("WH_Owner", ownerID);
				num = ownerID;
			}
			else if (num == myUID && num != ownerID && component.IsOwner())
			{
				zDO.Set("WH_Owner", ownerID);
				num = ownerID;
			}
			if (num == ownerID)
			{
				ShipRecord shipRecord = ShipRegistry.Instance?.GetOwnedRecord(zDO.m_uid);
				if (shipRecord != null && !shipRecord.IsSecondary)
				{
					ShipRegistry.Instance?.SetPrimary(shipRecord);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Minimap), "UpdatePins")]
	internal static class Patch_Minimap_UpdatePins_ApplyColors
	{
		private static Sprite _hammerSprite;

		private static Sprite _pinSprite;

		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AccessTools.Method(typeof(Minimap), "UpdatePins", (Type[])null, (Type[])null) != null;
		}

		private static void EnsureSprites()
		{
			if ((Object)(object)_hammerSprite != (Object)null && (Object)(object)_pinSprite != (Object)null)
			{
				return;
			}
			Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>();
			foreach (Sprite val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					if (((Object)val).name == "mapicon_hammer")
					{
						_hammerSprite = val;
					}
					else if (((Object)val).name == "mapicon_pin")
					{
						_pinSprite = val;
					}
					if ((Object)(object)_hammerSprite != (Object)null && (Object)(object)_pinSprite != (Object)null)
					{
						break;
					}
				}
			}
		}

		private static void Postfix()
		{
			//IL_0026: 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_0047: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_0099: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			ShipRegistry instance = ShipRegistry.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			EnsureSprites();
			ZDOID val = instance.Primary?.ID ?? ZDOID.None;
			foreach (ShipRecord item in instance.GetOwnedByLocalPlayer())
			{
				PinData pinData = instance.GetPinData(item.ID);
				if ((Object)(object)pinData?.m_uiElement == (Object)null)
				{
					continue;
				}
				Sprite val2 = ((val != ZDOID.None && item.ID == val) ? _hammerSprite : _pinSprite);
				Color mapIconColor = item.MapIconColor;
				try
				{
					Image componentInChildren = ((Component)pinData.m_uiElement).GetComponentInChildren<Image>();
					if ((Object)(object)componentInChildren != (Object)null && (Object)(object)val2 != (Object)null)
					{
						componentInChildren.sprite = val2;
					}
					Image[] componentsInChildren = ((Component)pinData.m_uiElement).GetComponentsInChildren<Image>();
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						((Graphic)componentsInChildren[i]).color = mapIconColor;
					}
				}
				catch
				{
				}
			}
		}
	}
	[HarmonyPatch(typeof(Minimap), "SetMapMode")]
	internal static class Patch_Minimap_SetMapMode_EnsurePins
	{
		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AccessTools.Method(typeof(Minimap), "SetMapMode", (Type[])null, (Type[])null) != null;
		}

		private static void Postfix(MapMode mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)mode == 2)
			{
				ShipRegistry.Instance?.EnsurePinsOnMap();
			}
		}
	}
	[HarmonyPatch(typeof(Minimap), "ClearPins")]
	internal static class Patch_Minimap_ClearPins_RestoreShipPins
	{
		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AccessTools.Method(typeof(Minimap), "ClearPins", (Type[])null, (Type[])null) != null;
		}

		private static void Postfix()
		{
			ShipRegistry.Instance?.RestorePins();
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	internal static class Patch_Player_ShipRecallSpawn
	{
		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				ShipRegistry.Instance?.OnPlayerSpawned();
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "Damage")]
	internal static class Patch_WearNTear_SecondaryIndestructible
	{
		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AccessTools.Method(typeof(WearNTear), "Damage", (Type[])null, (Type[])null) != null;
		}

		private static bool Prefix(WearNTear __instance)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Component)__instance).GetComponent<Ship>() == (Object)null)
			{
				return true;
			}
			ShipRegistry instance = ShipRegistry.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return true;
			}
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				return !instance.IsSecondaryShip(zDO.m_uid);
			}
			return true;
		}
	}
	public class ShipRecallSystem : MonoBehaviour
	{
		private float _cooldown;

		private bool _spawnInProgress;

		public static ShipRecallSystem Instance { get; private set; }

		public bool OnCooldown => _cooldown > 0f;

		public float CooldownRemaining => _cooldown;

		private static float PrimaryMaxRadius => Mathf.Max(RecallConfig.RadiusMin.Value, RecallConfig.RadiusMax.Value - 20f);

		private static float SecondaryMaxRadius => Mathf.Max(RecallConfig.RadiusMin.Value, RecallConfig.RadiusMax.Value - 40f);

		private static float SecondaryMinDepth => 1.2f;

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void Update()
		{
			if (!(_cooldown <= 0f))
			{
				_cooldown -= Time.deltaTime;
				if (_cooldown < 0f)
				{
					_cooldown = 0f;
				}
			}
		}

		public void TrySummon()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (OnCooldown)
			{
				if (RecallConfig.ShowCooldownMessage.Value)
				{
					((Character)localPlayer).Message((MessageType)2, $"Ship Recall: {_cooldown:F0}s", 0, (Sprite)null);
				}
				return;
			}
			ShipRegistry.Instance?.ScanLoaded();
			ShipRegistry instance = ShipRegistry.Instance;
			if ((Object)(object)instance != (Object)null && !instance.HasPrimary && !instance.HasSecondary)
			{
				((Character)localPlayer).Message((MessageType)2, "No ships assigned. Build a ship and take the helm to set your Primary.", 0, (Sprite)null);
			}
			else
			{
				QuickRecallUI.Instance?.Open();
			}
		}

		public void PerformSummon(ShipRecord record)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: 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_0189: 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_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (record.IsSecondary && !record.IsDeployed)
			{
				if (_spawnInProgress)
				{
					((Character)localPlayer).Message((MessageType)2, "Boat is already being summoned.", 0, (Sprite)null);
					return;
				}
				QuickRecallUI.Instance?.Close();
				((MonoBehaviour)this).StartCoroutine(SpawnStoredSecondary());
				return;
			}
			if ((Object)(object)record.Ship == (Object)null)
			{
				RecoverShipRef(record);
			}
			if ((Object)(object)record.Ship == (Object)null)
			{
				long ownerID = ShipRegistry.GetOwnerID();
				ZDOMan instance = ZDOMan.instance;
				ZDO val = ((instance != null) ? instance.GetZDO(record.ID) : null);
				if (val != null)
				{
					bool num = val.GetLong("WH_Owner", 0L) == ownerID;
					bool flag = (record.IsSecondary ? val.GetBool("WH_IsSec", false) : val.GetBool("WH_IsPri", false));
					if (!num || !flag)
					{
						val = null;
					}
				}
				if (val == null)
				{
					val = FindShipZDO(record, ownerID);
					if (val != null)
					{
						ShipRegistry.Instance?.UpdateShipZDOID(record, val.m_uid);
					}
				}
				if (val == null)
				{
					if (record.IsSecondary)
					{
						ShipRegistry.Instance?.ReturnSecondaryToStorage();
						QuickRecallUI.Instance?.Close();
						((MonoBehaviour)this).StartCoroutine(SpawnStoredSecondary());
					}
					else
					{
						((Character)localPlayer).Message((MessageType)2, "Ship not found.", 0, (Sprite)null);
					}
					return;
				}
				float maxRadius = (record.IsSecondary ? SecondaryMaxRadius : PrimaryMaxRadius);
				float minDepth = (record.IsSecondary ? SecondaryMinDepth : RecallConfig.MinDepth.Value);
				WaterScanner.ScanResult scanResult = WaterScanner.FindSummonPosition(((Component)localPlayer).transform.position, FlatForward(localPlayer), RecallConfig.RadiusMin.Value, maxRadius, minDepth);
				Vector3 position = (scanResult.Found ? scanResult.Position : (((Component)localPlayer).transform.position + FlatForward(localPlayer) * 15f));
				position.y = WaterLevel();
				val.SetOwner(ZNet.GetUID());
				val.SetPosition(position);
				record.Position = position;
				ShipRegistry.Instance?.ClearStaleRoleFlags(record.IsSecondary, val.m_uid, ownerID);
				((Character)localPlayer).Message((MessageType)1, record.DisplayName + " is on its way.", 0, (Sprite)null);
				BeginCooldown();
				ShipRegistry.Instance?.TouchLastUsed(record);
				QuickRecallUI.Instance?.Close();
			}
			else if (IsOccupied(record.Ship) && FleetConfig.OccupiedShipMode?.Value == "block")
			{
				((Character)localPlayer).Message((MessageType)2, "That ship is currently occupied.", 0, (Sprite)null);
			}
			else
			{
				float maxRadius2 = (record.IsSecondary ? SecondaryMaxRadius : PrimaryMaxRadius);
				float minDepth2 = (record.IsSecondary ? SecondaryMinDepth : RecallConfig.MinDepth.Value);
				WaterScanner.ScanResult scanResult2 = WaterScanner.FindSummonPosition(((Component)localPlayer).transform.position, FlatForward(localPlayer), RecallConfig.RadiusMin.Value, maxRadius2, minDepth2, record.Ship);
				if (!scanResult2.Found)
				{
					((Character)localPlayer).Message((MessageType)2, "No valid water location found nearby.", 0, (Sprite)null);
					return;
				}
				TeleportShip(record.Ship, scanResult2.Position, scanResult2.Rotation);
				ShipRegistry.Instance?.TouchLastUsed(record);
				BeginCooldown();
				QuickRecallUI.Instance?.Close();
				((Character)localPlayer).Message((MessageType)1, record.DisplayName + " recalled.", 0, (Sprite)null);
			}
		}

		private IEnumerator SpawnStoredSecondary()
		{
			if (_spawnInProgress)
			{
				yield break;
			}
			_spawnInProgress = true;
			try
			{
				Player player = Player.m_localPlayer;
				if ((Object)(object)player == (Object)null)
				{
					yield break;
				}
				ShipRegistry reg = ShipRegistry.Instance;
				if ((Object)(object)reg == (Object)null || !reg.HasSecondary)
				{
					yield break;
				}
				ZNetScene instance = ZNetScene.instance;
				GameObject val = ((instance != null) ? instance.GetPrefab(reg.SecondaryType) : null);
				if ((Object)(object)val == (Object)null)
				{
					((Character)player).Message((MessageType)2, "Could not find ship prefab (" + reg.SecondaryType + ").", 0, (Sprite)null);
					yield break;
				}
				WaterScanner.ScanResult scanResult = WaterScanner.FindSummonPosition(((Component)player).transform.position, FlatForward(player), RecallConfig.RadiusMin.Value, SecondaryMaxRadius, SecondaryMinDepth);
				if (!scanResult.Found)
				{
					((Character)player).Message((MessageType)2, "No valid water location found nearby.", 0, (Sprite)null);
					yield break;
				}
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(scanResult.Position.x, WaterLevel(), scanResult.Position.z);
				GameObject raftGo = Object.Instantiate<GameObject>(val, val2, scanResult.Rotation);
				if ((Object)(object)raftGo == (Object)null)
				{
					yield break;
				}
				ZNetView nv = raftGo.GetComponent<ZNetView>();
				for (int i = 0; i < 60; i++)
				{
					if (!((Object)(object)nv == (Object)null) && nv.IsValid())
					{
						break;
					}
					yield return null;
					if ((Object)(object)nv == (Object)null)
					{
						nv = raftGo.GetComponent<ZNetView>();
					}
				}
				Ship component = raftGo.GetComponent<Ship>();
				if ((Object)(object)component != (Object)null)
				{
					reg.DeploySecondary(component);
				}
				BeginCooldown();
				((Character)player).Message((MessageType)1, "Boat deployed nearby.", 0, (Sprite)null);
			}
			finally
			{
				_spawnInProgress = false;
			}
		}

		private void TeleportShip(Ship ship, Vector3 scanPos, Quaternion rot)
		{
			//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_0066: 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_003d: 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_0053: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			Rigidbody component2 = ((Component)ship).GetComponent<Rigidbody>();
			if (component != null)
			{
				component.ClaimOwnership();
			}
			float num = WaterLevel();
			Vector3 position = default(Vector3);
			((Vector3)(ref position))..ctor(scanPos.x, num, scanPos.z);
			if ((Object)(object)component2 != (Object)null)
			{
				component2.linearVelocity = Vector3.zero;
				component2.angularVelocity = Vector3.zero;
				component2.position = position;
				component2.rotation = rot;
			}
			((Component)ship).transform.position = position;
			((Component)ship).transform.rotation = rot;
			Physics.SyncTransforms();
			if (component != null)
			{
				ZDO zDO = component.GetZDO();
				if (zDO != null)
				{
					zDO.SetPosition(position);
				}
			}
			if ((Object)(object)component2 != (Object)null)
			{
				((MonoBehaviour)this).StartCoroutine(PinY(component2));
			}
		}

		private static IEnumerator PinY(Rigidbody rb)
		{
			if (!((Object)(object)rb == (Object)null))
			{
				RigidbodyConstraints saved = rb.constraints;
				rb.constraints = (RigidbodyConstraints)(saved | 4);
				yield return (object)new WaitForSeconds(1f);
				if (!((Object)(object)rb == (Object)null))
				{
					Vector3 linearVelocity = rb.linearVelocity;
					linearVelocity.y = 0f;
					rb.linearVelocity = linearVelocity;
					rb.constraints = saved;
				}
			}
		}

		private static void RecoverShipRef(ShipRecord record)
		{
			//IL_002e: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			ZNetView[] array = Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0);
			foreach (ZNetView val in array)
			{
				ZDOID? val2 = val.GetZDO()?.m_uid;
				ZDOID iD = record.ID;
				if (val2.HasValue && !(val2.GetValueOrDefault() != iD))
				{
					record.Ship = ((Component)val).GetComponent<Ship>();
					record.IsLoaded = (Object)(object)record.Ship != (Object)null;
					if ((Object)(object)record.Ship != (Object)null)
					{
						return;
					}
				}
			}
			int typeHash = ShipRegistry.GetTypeHash(record.Type);
			if (typeHash == 0)
			{
				return;
			}
			Ship val3 = null;
			ZDOID iD2 = ZDOID.None;
			float num = 50f;
			array = Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0);
			foreach (ZNetView val4 in array)
			{
				Ship component = ((Component)val4).GetComponent<Ship>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				ZDO zDO = val4.GetZDO();
				if (zDO != null && zDO.GetPrefab() == typeHash)
				{
					float num2 = Vector3.Distance(((Component)component).transform.position, record.Position);
					if (num2 < num)
					{
						val3 = component;
						num = num2;
						iD2 = zDO.m_uid;
					}
				}
			}
			if ((Object)(object)val3 != (Object)null)
			{
				record.Ship = val3;
				record.IsLoaded = true;
				record.ID = iD2;
			}
		}

		private static ZDO FindShipZDO(ShipRecord record, long ownerID)
		{
			if (ZDOMan.instance == null)
			{
				return null;
			}
			string text = ShipRegistry.TypeToPrefabName((!record.IsSecondary) ? record.Type : (ShipRegistry.Instance?.SecondaryType ?? "Raft"));
			string text2 = (record.IsSecondary ? "WH_IsSec" : "WH_IsPri");
			List<ZDO> list = new List<ZDO>();
			int num = 0;
			while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(text, list, ref num))
			{
			}
			foreach (ZDO item in list)
			{
				if (item.GetLong("WH_Owner", 0L) == ownerID && item.GetBool(text2, false))
				{
					return item;
				}
			}
			return null;
		}

		private void BeginCooldown()
		{
			_cooldown = RecallConfig.Cooldown.Value;
		}

		private static bool IsOccupied(Ship ship)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				int mask = LayerMask.GetMask(new string[1] { "character" });
				Collider[] array = Physics.OverlapSphere(((Component)ship).transform.position, 8f, mask);
				for (int i = 0; i < array.Length; i++)
				{
					Player component = ((Component)array[i]).GetComponent<Player>();
					if ((Object)(object)component != (Object)null && (Object)(object)component != (Object)(object)Player.m_localPlayer)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static float WaterLevel()
		{
			if (!((Object)(object)ZoneSystem.instance != (Object)null) || !(ZoneSystem.instance.m_waterLevel > 1f))
			{
				return 30f;
			}
			return ZoneSystem.instance.m_waterLevel;
		}

		private static Vector3 FlatForward(Player player)
		{
			//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_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)
			//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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane(((Component)player).transform.forward, Vector3.up);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			if (!(((Vector3)(ref normalized)).sqrMagnitude > 0.01f))
			{
				return Vector3.forward;
			}
			return normalized;
		}
	}
	public class ShipRecord
	{
		public ZDOID ID;

		public string Type;

		public string CustomName;

		public long OwnerID;

		public Vector3 Position;

		public Quaternion Rotation;

		public DateTime LastUsed;

		public bool IsLoaded;

		public bool IsSecondary;

		public Color MapIconColor = Color.white;

		public PinType MapIconType;

		public Ship Ship;

		public bool IsDeployed => ID != ZDOID.None;

		public string DisplayName
		{
			get
			{
				if (!string.IsNullOrEmpty(CustomName))
				{
					return CustomName;
				}
				return Type;
			}
		}

		public string DisplayNameWithOwner(string ownerName)
		{
			return DisplayName + " (" + ownerName + ")";
		}

		public float DistanceTo(Vector3 pos)
		{
			//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)
			return Vector3.Distance(Position, pos);
		}

		public float HealthPercent()
		{
			try
			{
				Ship ship = Ship;
				float? obj;
				if (ship == null)
				{
					obj = null;
				}
				else
				{
					WearNTear component = ((Component)ship).GetComponent<WearNTear>();
					obj = ((component != null) ? new float?(component.GetHealthPercentage()) : ((float?)null));
				}
				return obj ?? 1f;
			}
			catch
			{
				return 1f;
			}
		}
	}
	public class ShipRegistry : MonoBehaviour
	{
		private readonly Dictionary<ZDOID, ShipRecord> _records = new Dictionary<ZDOID, ShipRecord>();

		private readonly Dictionary<ZDOID, PinData> _pins = new Dictionary<ZDOID, PinData>();

		internal const string ZDO_OWNER = "WH_Owner";

		internal const string ZDO_NAME = "WH_Name";

		private const string ZDO_LASTUSED = "WH_LastUsed";

		internal const string ZDO_ISSEC = "WH_IsSec";

		internal const string ZDO_ISPRI = "WH_IsPri";

		private static readonly PinType ShipPinType = (PinType)0;

		public static readonly int HashRaft = StableHash("Raft");

		public static readonly int HashKarve = StableHash("Karve");

		public static readonly int HashVikingShip = StableHash("VikingShip");

		public static readonly int HashDrakkar = StableHash("Drakkar");

		private ZDOID _primaryID = ZDOID.None;

		private ZDOID _secondaryID = ZDOID.None;

		private bool _hasSecondary;

		private string _secondaryType = "Raft";

		private string _secondaryCustomName = "Boat";

		private bool _sessionLoaded;

		private bool _miniPinsEnsured;

		private bool _dirty;

		private float _pruneTimer = 5f;

		private bool _pendingSpawn;

		private float _diagTriggerTimer;

		private float _diagScanCountdown = -1f;

		private bool _diagScanDone;

		private const int SAVE_VERSION = 5;

		public static ShipRegistry Instance { get; private set; }

		public ShipRecord Primary => GetRecord(_primaryID);

		public bool HasPrimary => Primary != null;

		public bool HasSecondary => _hasSecondary;

		public bool SecondaryDeployed
		{
			get
			{
				//IL_0009: 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 (_hasSecondary)
				{
					return _secondaryID != ZDOID.None;
				}
				return false;
			}
		}

		public string SecondaryType => _secondaryType;

		public ShipRecord Secondary
		{
			get
			{
				//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_0039: 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_006d: 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_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_0023: Unknown result type (might be due to invalid IL or missing references)
				if (!_hasSecondary)
				{
					return null;
				}
				if (_secondaryID != ZDOID.None && _records.TryGetValue(_secondaryID, out var value))
				{
					return value;
				}
				return new ShipRecord
				{
					ID = ZDOID.None,
					Type = _secondaryType,
					CustomName = "Boat",
					OwnerID = GetOwnerID(),
					IsSecondary = true,
					MapIconColor = Color.white,
					MapIconType = ShipPinType,
					LastUsed = DateTime.UtcNow
				};
			}
		}

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			ClearAllPins();
		}

		private void Update()
		{
			if (_sessionLoaded && (Object)(object)ZNet.instance == (Object)null)
			{
				ResetSession();
				return;
			}
			if (!_sessionLoaded && (Object)(object)ZNet.instance != (Object)null)
			{
				_diagTriggerTimer -= Time.deltaTime;
				if (_diagTriggerTimer <= 0f)
				{
					_diagTriggerTimer = 2f;
					long myUID = GetMyUID();
					Game instance = Game.instance;
					long? obj;
					if (instance == null)
					{
						obj = null;
					}
					else
					{
						PlayerProfile playerProfile = instance.GetPlayerProfile();
						obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null));
					}
					long? num = obj;
					long valueOrDefault = num.GetValueOrDefault();
					long worldUID = GetWorldUID();
					Logger.LogInfo((object)$"[WH Trigger] waiting — myUID={myUID} profileID={valueOrDefault} worldUID={worldUID}");
				}
			}
			if (!_sessionLoaded && (Object)(object)ZNet.instance != (Object)null && GetMyUID() != 0L)
			{
				Game instance2 = Game.instance;
				long? obj2;
				if (instance2 == null)
				{
					obj2 = null;
				}
				else
				{
					PlayerProfile playerProfile2 = instance2.GetPlayerProfile();
					obj2 = ((playerProfile2 != null) ? new long?(playerProfile2.GetPlayerID()) : ((long?)null));
				}
				long? num = obj2;
				if (num.GetValueOrDefault() != 0L && GetWorldUID() != 0L)
				{
					Game instance3 = Game.instance;
					long? obj3;
					if (instance3 == null)
					{
						obj3 = null;
					}
					else
					{
						PlayerProfile playerProfile3 = instance3.GetPlayerProfile();
						obj3 = ((playerProfile3 != null) ? new long?(playerProfile3.GetPlayerID()) : ((long?)null));
					}
					num = obj3;
					long valueOrDefault2 = num.GetValueOrDefault();
					Logger.LogInfo((object)($"[WH Trigger] FIRED — myUID={GetMyUID()} profileID={valueOrDefault2} worldUID={GetWorldUID()} pendingSpawn={_pendingSpawn}\n" + "  path=" + SavePath()));
					_sessionLoaded = true;
					_diagScanCountdown = 4f;
					LoadRegistry();
					if (_pendingSpawn)
					{
						EnsureSecondaryEntry();
					}
				}
			}
			if (_sessionLoaded && !_miniPinsEnsured && (Object)(object)Minimap.instance != (Object)null)
			{
				_miniPinsEnsured = true;
				EnsurePinsOnMap();
			}
			if (_sessionLoaded && !_diagScanDone && _diagScanCountdown > 0f)
			{
				_diagScanCountdown -= Time.deltaTime;
				if (_diagScanCountdown <= 0f)
				{
					_diagScanDone = true;
					DiagnosticWorldScan();
				}
			}
			_pruneTimer -= Time.deltaTime;
			if (!(_pruneTimer > 0f))
			{
				_pruneTimer = 5f;
				PruneGone();
				UpdateLoadedPositions();
				if (_dirty)
				{
					SaveRegistry();
					_dirty = false;
				}
			}
		}

		public void RegisterShip(Ship ship)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: 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_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ship == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (zDO == null)
			{
				return;
			}
			int prefab = zDO.GetPrefab();
			if (prefab == 0)
			{
				return;
			}
			ZDOID uid = zDO.m_uid;
			long ownerID = GetOwnerID();
			long myUID = GetMyUID();
			long num = zDO.GetLong("WH_Owner", 0L);
			if (component.IsOwner())
			{
				if (num == 0L)
				{
					zDO.Set("WH_Owner", ownerID);
					num = ownerID;
					_dirty = true;
				}
				else if (num == myUID && num != ownerID)
				{
					zDO.Set("WH_Owner", ownerID);
					num = ownerID;
					_dirty = true;
				}
			}
			bool flag = ownerID != 0L && num == ownerID;
			ShipRecord value;
			bool flag2 = !_records.TryGetValue(uid, out value);
			if (flag2)
			{
				value = new ShipRecord
				{
					ID = uid,
					Type = TypeName(prefab),
					OwnerID = num,
					LastUsed = DateTime.UtcNow
				};
				_records[uid] = value;
				if (flag)
				{
					_dirty = true;
				}
			}
			Logger.LogInfo((object)($"[WH Ship] {TypeName(prefab)} zdoid={uid} zdoOwner={num} ownerID={ownerID} " + $"isNew={flag2} recOwner={value.OwnerID} ownedByMe={flag}"));
			value.Ship = ship;
			value.IsLoaded = true;
			value.Position = ((Component)ship).transform.position;
			value.Rotation = ((Component)ship).transform.rotation;
			value.CustomName = zDO.GetString("WH_Name", "");
			value.MapIconType = ShipPinType;
			long num2 = zDO.GetLong("WH_LastUsed", 0L);
			if (num2 > 0)
			{
				value.LastUsed = new DateTime(num2, DateTimeKind.Utc);
			}
			if (!flag)
			{
				return;
			}
			value.OwnerID = ownerID;
			if (zDO.GetBool("WH_IsPri", false))
			{
				if (_primaryID != ZDOID.None && _primaryID != uid)
				{
					RemovePin(_primaryID);
					_records.Remove(_primaryID);
				}
				_primaryID = uid;
			}
			if (zDO.GetBool("WH_IsSec", false))
			{
				if (_secondaryID != ZDOID.None && _secondaryID != uid)
				{
					RemovePin(_secondaryID);
					_records.Remove(_secondaryID);
				}
				_secondaryID = uid;
				value.IsSecondary = true;
			}
			else if (uid == _secondaryID)
			{
				value.IsSecondary = true;
			}
			AddOrUpdatePin(value);
		}

		public void UnregisterShip(ZDOID id)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (id == _primaryID)
			{
				_primaryID = ZDOID.None;
			}
			if (id == _secondaryID)
			{
				_secondaryID = ZDOID.None;
				Logger.LogInfo((object)"Windheim: secondary destroyed — returned to storage.");
			}
			RemovePin(id);
			_records.Remove(id);
			_dirty = true;
		}

		public void SetPrimary(ShipRecord rec)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (rec == null || rec.ID == _primaryID)
			{
				return;
			}
			if (_primaryID != ZDOID.None && _records.TryGetValue(_primaryID, out var value))
			{
				Ship ship = value.Ship;
				object obj;
				if (ship == null)
				{
					obj = null;
				}
				else
				{
					ZNetView component = ((Component)ship).GetComponent<ZNetView>();
					obj = ((component != null) ? component.GetZDO() : null);
				}
				if (obj == null)
				{
					ZDOMan instance = ZDOMan.instance;
					obj = ((instance != null) ? instance.GetZDO(value.ID) : null);
				}
				ZDO val = (ZDO)obj;
				if (val != null)
				{
					try
					{
						val.SetOwner(ZNet.GetUID());
						val.Set("WH_IsPri", false);
					}
					catch
					{
					}
				}
			}
			_primaryID = rec.ID;
			try
			{
				Ship ship2 = rec.Ship;
				if (ship2 != null)
				{
					ZNetView component2 = ((Component)ship2).GetComponent<ZNetView>();
					if (component2 != null)
					{
						ZDO zDO = component2.GetZDO();
						if (zDO != null)
						{
							zDO.Set("WH_IsPri", true);
						}
					}
				}
			}
			catch
			{
			}
			_dirty = true;
			AddOrUpdatePin(rec);
			if (_sessionLoaded)
			{
				SaveRegistry();
			}
			Logger.LogInfo((object)("Windheim: primary → " + rec.DisplayName + " (" + rec.Type + ")"));
		}

		public void EnsureSecondaryEntry()
		{
			if (!_hasSecondary)
			{
				_hasSecondary = true;
				_secondaryType = "Raft";
				_secondaryCustomName = "Boat";
				_dirty = true;
				if (_sessionLoaded)
				{
					SaveRegistry();
				}
				Logger.LogInfo((object)"Windheim: secondary entry created (stored).");
			}
		}

		public void DeploySecondary(Ship ship)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ship == (Object)null || !_hasSecondary)
			{
				return;
			}
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				long ownerID = GetOwnerID();
				zDO.Set("WH_Owner", ownerID);
				zDO.Set("WH_Name", "Boat");
				zDO.Set("WH_IsSec", true);
				ZDOID uid = zDO.m_uid;
				ShipRecord shipRecord = new ShipRecord
				{
					ID = uid,
					Type = _secondaryType,
					CustomName = "Boat",
					OwnerID = ownerID,
					Position = ((Component)ship).transform.position,
					Rotation = ((Component)ship).transform.rotation,
					IsSecondary = true,
					IsLoaded = true,
					Ship = ship,
					LastUsed = DateTime.UtcNow,
					MapIconColor = Color.white,
					MapIconType = ShipPinType
				};
				_records[uid] = shipRecord;
				_secondaryID = uid;
				_dirty = true;
				ClearStaleRoleFlags(isSecondary: true, uid, ownerID);
				AddOrUpdatePin(shipRecord);
				if (_sessionLoaded)
				{
					SaveRegistry();
				}
				Logger.LogInfo((object)$"Windheim: secondary deployed ({uid})");
			}
		}

		public void ReturnSecondaryToStorage()
		{
			//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_001a: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (_secondaryID == ZDOID.None)
			{
				return;
			}
			if (_records.TryGetValue(_secondaryID, out var value))
			{
				Ship ship = value.Ship;
				object obj;
				if (ship == null)
				{
					obj = null;
				}
				else
				{
					ZNetView component = ((Component)ship).GetComponent<ZNetView>();
					obj = ((component != null) ? component.GetZDO() : null);
				}
				if (obj == null)
				{
					ZDOMan instance = ZDOMan.instance;
					obj = ((instance != null) ? instance.GetZDO(value.ID) : null);
				}
				ZDO val = (ZDO)obj;
				if (val != null)
				{
					try
					{
						val.SetOwner(ZNet.GetUID());
						val.Set("WH_IsSec", false);
					}
					catch
					{
					}
				}
			}
			ClearStaleRoleFlags(isSecondary: true, ZDOID.None, GetOwnerID());
			RemovePin(_secondaryID);
			_records.Remove(_secondaryID);
			_secondaryID = ZDOID.None;
			_dirty = true;
			if (_sessionLoaded)
			{
				SaveRegistry();
			}
			Logger.LogInfo((object)"Windheim: secondary returned to storage.");
		}

		internal PinData GetPinData(ZDOID id)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_pins.TryGetValue(id, out var value);
			return value;
		}

		public void RestorePins()
		{
			if (_sessionLoaded && !((Object)(object)Minimap.instance == (Object)null))
			{
				_pins.Clear();
				EnsurePinsOnMap();
			}
		}

		public void EnsurePinsOnMap()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				return;
			}
			long ownerID = GetOwnerID();
			int num = 0;
			foreach (ShipRecord value in _records.Values)
			{
				if (value.ID != ZDOID.None && value.OwnerID == ownerID)
				{
					num++;
				}
			}
			Logger.LogInfo((object)$"[WH Pins] EnsurePinsOnMap — ownerID={ownerID} totalRecords={_records.Count} owned={num}");
			foreach (ShipRecord value2 in _records.Values)
			{
				if (value2.ID != ZDOID.None && value2.OwnerID == ownerID)
				{
					AddOrUpdatePin(value2);
				}
			}
		}

		public ShipRecord GetRecord(ZDOID id)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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)
			if (id == ZDOID.None)
			{
				return null;
			}
			_records.TryGetValue(id, out var value);
			return value;
		}

		public ShipRecord GetOwnedRecord(ZDOID id)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (!_records.TryGetValue(id, out var value))
			{
				return null;
			}
			if (value.OwnerID != GetOwnerID())
			{
				return null;
			}
			return value;
		}

		public bool IsSecondaryShip(ZDOID id)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (id != ZDOID.None)
			{
				return id == _secondaryID;
			}
			return false;
		}

		public List<ShipRecord> GetOwnedByLocalPlayer()
		{
			long ownerID = GetOwnerID();
			List<ShipRecord> list = new List<ShipRecord>();
			foreach (ShipRecord value in _records.Values)
			{
				if (value.OwnerID == ownerID)
				{
					list.Add(value);
				}
			}
			return list;
		}

		public void TouchLastUsed(ShipRecord rec)
		{
			//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)
			if (rec == null || rec.ID == ZDOID.None)
			{
				return;
			}
			rec.LastUsed = DateTime.UtcNow;
			_dirty = true;
			try
			{
				Ship ship = rec.Ship;
				if (ship == null)
				{
					return;
				}
				ZNetView component = ((Component)ship).GetComponent<ZNetView>();
				if (component != null)
				{
					ZDO zDO = component.GetZDO();
					if (zDO != null)
					{
						zDO.Set("WH_LastUsed", rec.LastUsed.Ticks);
					}
				}
			}
			catch
			{
			}
		}

		public void ScanLoaded()
		{
			ZNetView[] array = Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0);
			for (int i = 0; i < array.Length; i++)
			{
				Ship component = ((Component)array[i]).GetComponent<Ship>();
				if ((Object)(object)component != (Object)null)
				{
					RegisterShip(component);
				}
			}
		}

		public void MarkDirty()
		{
			_dirty = true;
		}

		public void OnPlayerSpawned()
		{
			Logger.LogInfo((object)$"[WH Timing] OnPlayerSpawned — sessionLoaded={_sessionLoaded} time={Time.time:F1}");
			_pendingSpawn = true;
			if (_sessionLoaded)
			{
				EnsureSecondaryEntry();
			}
		}

		private void SaveRegistry()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0015: 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_00d4: 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)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				long ownerID = GetOwnerID();
				ZPackage val = new ZPackage();
				val.Write(5);
				val.Write(_primaryID);
				val.Write(_secondaryID);
				val.Write(_hasSecondary);
				val.Write(_secondaryType ?? "Raft");
				val.Write(_secondaryCustomName ?? "Boat");
				int num = 0;
				foreach (ShipRecord value in _records.Values)
				{
					if (value.OwnerID == ownerID)
					{
						num++;
					}
				}
				val.Write(num);
				foreach (ShipRecord value2 in _records.Values)
				{
					if (value2.OwnerID == ownerID)
					{
						val.Write(value2.ID);
						val.Write(value2.Type ?? "");
						val.Write(value2.CustomName ?? "");
						val.Write(value2.Position);
						val.Write(value2.LastUsed.Ticks);
						val.Write(value2.IsSecondary);
					}
				}
				string text = SavePath();
				Game instance = Game.instance;
				long? obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					PlayerProfile playerProfile = instance.GetPlayerProfile();
					obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null));
				}
				long? num2 = obj;
				long valueOrDefault = num2.GetValueOrDefault();
				long worldUID = GetWorldUID();
				Logger.LogInfo((object)($"[WH Save] CharUID={valueOrDefault} WorldUID={worldUID}\n" + "  Path=" + text + "\n" + $"  Primary={_primaryID} Secondary={_secondaryID} HasSec={_hasSecondary} Count={num}"));
				string @base = val.GetBase64();
				Directory.CreateDirectory(Path.GetDirectoryName(text));
				File.WriteAllText(text, @base);
				Logger.LogInfo((object)$"[WH Save] done — exists={File.Exists(text)} bytes={new FileInfo(text).Length}");
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Windheim: ship save error: " + ex.Message));
			}
		}

		private void LoadRegistry()
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//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)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: 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_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			string text = SavePath();
			Game instance = Game.instance;
			long? obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PlayerProfile playerProfile = instance.GetPlayerProfile();
				obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null));
			}
			long? num = obj;
			long valueOrDefault = num.GetValueOrDefault();
			long worldUID = GetWorldUID();
			bool flag = File.Exists(text);
			Logger.LogInfo((object)($"[WH Load] CharUID={valueOrDefault} WorldUID={worldUID}\n" + "  Path=" + text + "\n" + $"  Exists={flag} Size={(flag ? new FileInfo(text).Length : 0)}B"));
			if (!flag)
			{
				TryMigrateV1();
				return;
			}
			try
			{
				string text2 = File.ReadAllText(text).Trim();
				if (string.IsNullOrEmpty(text2))
				{
					return;
				}
				ZPackage val = new ZPackage(text2);
				int num2 = val.ReadInt();
				if (num2 < 2)
				{
					Logger.LogWarning((object)"Windheim: ship save too old.");
					return;
				}
				_primaryID = val.ReadZDOID();
				_secondaryID = val.ReadZDOID();
				if (num2 >= 4)
				{
					_hasSecondary = val.ReadBool();
					_secondaryType = val.ReadString();
					val.ReadString();
					_secondaryCustomName = "Boat";
					if (num2 == 4)
					{
						val.ReadInt();
						val.ReadInt();
						val.ReadInt();
						val.ReadInt();
					}
				}
				else
				{
					_hasSecondary = _secondaryID != ZDOID.None;
					_secondaryType = "Raft";
				}
				int num3 = val.ReadInt();
				long ownerID = GetOwnerID();
				for (int i = 0; i < num3; i++)
				{
					ZDOID val2 = val.ReadZDOID();
					string type = val.ReadString();
					string text3 = val.ReadString();
					Vector3 position = val.ReadVector3();
					long num4 = val.ReadLong();
					bool flag2 = val.ReadBool();
					if (num2 < 5)
					{
						val.ReadInt();
						val.ReadInt();
						val.ReadInt();
						if (num2 >= 3)
						{
							val.ReadInt();
						}
					}
					if (_records.TryGetValue(val2, out var value))
					{
						value.OwnerID = ownerID;
						value.IsSecondary = flag2;
						value.MapIconType = ShipPinType;
						AddOrUpdatePin(value);
						continue;
					}
					_records[val2] = new ShipRecord
					{
						ID = val2,
						Type = type,
						CustomName = (flag2 ? "Boat" : text3),
						OwnerID = ownerID,
						Position = position,
						Rotation = Quaternion.identity,
						LastUsed = ((num4 > 0) ? new DateTime(num4, DateTimeKind.Utc) : DateTime.UtcNow),
						IsSecondary = flag2,
						MapIconColor = Color.white,
						MapIconType = ShipPinType
					};
					AddOrUpdatePin(_records[val2]);
				}
				Logger.LogInfo((object)($"Windheim: loaded {num3} ship(s). " + $"P={_primaryID} S={_secondaryID} hasSecondary={_hasSecondary}"));
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Windheim: ship load error: " + ex.Message));
			}
		}

		private void TryMigrateV1()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_0194: Unknown result type (might be due to invalid IL or missing references)
			ZNet instance = ZNet.instance;
			string text = ((instance != null) ? instance.GetWorldName() : null) ?? "world";
			Game instance2 = Game.instance;
			object obj;
			if (instance2 == null)
			{
				obj = null;
			}
			else
			{
				PlayerProfile playerProfile = instance2.GetPlayerProfile();
				obj = ((playerProfile != null) ? playerProfile.GetName() : null);
			}
			if (obj == null)
			{
				Player localPlayer = Player.m_localPlayer;
				obj = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "player";
			}
			string text2 = (string)obj;
			string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)WindheimPlugin.Instance).Config.ConfigFilePath), "windheim_ships_" + text2 + "_" + text + ".dat");
			if (!File.Exists(path))
			{
				return;
			}
			try
			{
				string text3 = File.ReadAllText(path).Trim();
				if (!string.IsNullOrEmpty(text3))
				{
					ZPackage val = new ZPackage(text3);
					int num = val.ReadInt();
					long ownerID = GetOwnerID();
					for (int i = 0; i < num; i++)
					{
						ZDOID val2 = val.ReadZDOID();
						string type = val.ReadString();
						string text4 = val.ReadString();
						Vector3 position = val.ReadVector3();
						long num2 = val.ReadLong();
						bool isSecondary = text4 == "Boat";
						_records[val2] = new ShipRecord
						{
							ID = val2,
							Type = type,
							CustomName = text4,
							OwnerID = ownerID,
							Position = position,
							IsSecondary = isSecondary,
							MapIconColor = Color.white,
							MapIconType = ShipPinType,
							LastUsed = ((num2 > 0) ? new DateTime(num2, DateTimeKind.Utc) : DateTime.UtcNow)
						};
						AddOrUpdatePin(_records[val2]);
					}
					_dirty = true;
					Logger.LogInfo((object)$"Windheim: migrated {num} ship(s) from v1.");
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Windheim: v1 migration error: " + ex.Message));
			}
		}

		private string SavePath()
		{
			string? directoryName = Path.GetDirectoryName(((BaseUnityPlugin)WindheimPlugin.Instance).Config.ConfigFilePath);
			Game instance = Game.instance;
			long? obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PlayerProfile playerProfile = instance.GetPlayerProfile();
				obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null));
			}
			long? num = obj;
			long valueOrDefault = num.GetValueOrDefault();
			return Path.Combine(directoryName, string.Format(arg1: GetWorldUID(), format: "windheim_ships_v3_{0}_{1}.dat", arg0: valueOrDefault));
		}

		private static long GetWorldUID()
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return 0L;
			}
			try
			{
				MethodInfo method = typeof(ZNet).GetMethod("GetWorldUID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					return (long)method.Invoke(ZNet.instance, null);
				}
			}
			catch
			{
			}
			try
			{
				object obj2 = typeof(ZNet).GetField("m_world", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(ZNet.instance);
				if (obj2 == null)
				{
					return 0L;
				}
				FieldInfo field = obj2.GetType().GetField("m_uid", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				return (field != null) ? ((long)field.GetValue(obj2)) : 0;
			}
			catch
			{
				return 0L;
			}
		}

		private void ResetSession()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			_sessionLoaded = false;
			_miniPinsEnsured = false;
			_dirty = false;
			_pendingSpawn = false;
			_hasSecondary = false;
			_secondaryType = "Raft";
			_secondaryCustomName = "Boat";
			_primaryID = ZDOID.None;
			_secondaryID = ZDOID.None;
			_records.Clear();
			ClearAllPins();
			_diagTriggerTimer = 0f;
			_diagScanCountdown = -1f;
			_diagScanDone = false;
		}

		private void DiagnosticWorldScan()
		{
			//IL_0095: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			long myUID = GetMyUID();
			Game instance = Game.instance;
			long? obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PlayerProfile playerProfile = instance.GetPlayerProfile();
				obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null));
			}
			long? num = obj;
			long valueOrDefault = num.GetValueOrDefault();
			long worldUID = GetWorldUID();
			Ship[] array = Object.FindObjectsByType<Ship>((FindObjectsSortMode)0);
			Logger.LogInfo((object)($"[WH WorldScan] myUID={myUID} profileID={valueOrDefault} worldUID={worldUID}\n" + $"  Ships in scene={array.Length}  registry records={_records.Count}\n" + $"  primary={_primaryID} secondary={_secondaryID} hasSecondary={_hasSecondary}"));
			int num2 = 0;
			Ship[] array2 = array;
			foreach (Ship val in array2)
			{
				num2++;
				ZNetView component = ((Component)val).GetComponent<ZNetView>();
				ZDO obj2 = ((component != null) ? component.GetZDO() : null);
				ZDOID val2 = obj2?.m_uid ?? ZDOID.None;
				int hash = ((obj2 != null) ? obj2.GetPrefab() : 0);
				long num3 = ((obj2 != null) ? obj2.GetLong("WH_Owner", 0L) : 0);
				bool flag = _records.ContainsKey(val2);
				bool flag2 = flag && _records[val2].OwnerID == myUID;
				Logger.LogInfo((object)($"[WH WorldScan] #{num2}: {TypeName(hash)} zdoid={val2}\n" + $"    pos={((Component)val).transform.position:F0} nvValid={component != null && component.IsValid()}\n" + $"    zdoOwner={num3} inRegistry={flag} ownedByMe={flag2}"));
			}
			foreach (KeyValuePair<ZDOID, ShipRecord> record in _records)
			{
				ShipRecord value = record.Value;
				Logger.LogInfo((object)($"[WH WorldScan] reg: {value.Type} zdoid={record.Key} owner={value.OwnerID} " + string.Format("isLoaded={0} isSec={1} ship={2}", value.IsLoaded, value.IsSecondary, ((Object)(object)value.Ship != (Object)null) ? "ref" : "null")));
			}
		}

		internal void ClearStaleRoleFlags(bool isSecondary, ZDOID keepID, long ownerID)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			if (ZDOMan.instance == null)
			{
				return;
			}
			string text = (isSecondary ? "WH_IsSec" : "WH_IsPri");
			string[] obj = new string[4] { "Raft", "Karve", "VikingShip", "Drakkar" };
			List<ZDO> list = new List<ZDO>();
			string[] array = obj;
			foreach (string text2 in array)
			{
				list.Clear();
				int num = 0;
				while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(text2, list, ref num))
				{
				}
				foreach (ZDO item in list)
				{
					if (!(item.m_uid == keepID) && item.GetLong("WH_Owner", 0L) == ownerID && item.GetBool(text, false))
					{
						item.SetOwner(ZNet.GetUID());
						item.Set(text, false);
						Logger.LogInfo((object)$"[WH Cleanup] Cleared stale {text} on zdoid={item.m_uid}");
					}
				}
			}
		}

		private void AddOrUpdatePin(ShipRecord rec)
		{
			//IL_000e: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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)
			//IL_0062: 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_00d6: 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_00e1: 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_006d: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Minimap.instance == (Object)null || rec.ID == ZDOID.None)
			{
				object arg = rec?.ID;
				object arg2 = (Object)(object)Minimap.instance != (Object)null;
				ZDOID? val = rec?.ID;
				ZDOID none = ZDOID.None;
				Logger.LogInfo((object)$"[WH Pin] SKIP {arg} — minimap={arg2} validID={!val.HasValue || val.GetValueOrDefault() != none}");
				return;
			}
			Color white = Color.white;
			string text = ((rec.ID == _primaryID) ? "Flagship" : (rec.IsSecondary ? "Boat" : rec.DisplayName));
			rec.MapIconColor = white;
			rec.MapIconType = ShipPinType;
			if (_pins.TryGetValue(rec.ID, out var value))
			{
				if (value.m_type != rec.MapIconType)
				{
					RemovePin(rec.ID);
					AddOrUpdatePin(rec);
					return;
				}
				value.m_pos = rec.Position;
				value.m_name = text;
				TryApplyPinColor(value, white);
				Logger.LogInfo((object)$"[WH Pin] UPDATE '{text}' zdoid={rec.ID} pos={rec.Position:F0}");
				return;
			}
			try
			{
				value = Minimap.instance.AddPin(rec.Position, rec.MapIconType, text, false, false, 0L, default(PlatformUserID));
				_pins[rec.ID] = value;
				TryApplyPinColor(value, white);
				Logger.LogInfo((object)$"[WH Pin] ADD '{text}' zdoid={rec.ID} pos={rec.Position:F0}");
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Windheim: pin error: " + ex.Message));
			}
		}

		private static void TryApplyPinColor(PinData pin, Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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)
			if (color == Color.white || (Object)(object)pin?.m_uiElement == (Object)null)
			{
				return;
			}
			try
			{
				Image val = ((Component)pin.m_uiElement).GetComponent<Image>() ?? ((Component)pin.m_uiElement).GetComponentInChildren<Image>();
				if ((Object)(object)val != (Object)null)
				{
					((Graphic)val).color = color;
				}
			}
			catch
			{
			}
		}

		private void RemovePin(ZDOID id)
		{
			//IL_0006: 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)
			if (!_pins.TryGetValue(id, out var value))
			{
				return;
			}
			try
			{
				Minimap instance = Minimap.instance;
				if (instance != null)
				{
					instance.RemovePin(value);
				}
			}
			catch
			{
			}
			_pins.Remove(id);
		}

		private void ClearAllPins()
		{
			foreach (PinData value in _pins.Values)
			{
				try
				{
					Minimap instance = Minimap.instance;
					if (instance != null)
					{
						instance.RemovePin(value);
					}
				}
				catch
				{
				}
			}
			_pins.Clear();
		}

		private void PruneGone()
		{
			foreach (ShipRecord value in _records.Values)
			{
				if (value.IsLoaded && (Object)(object)value.Ship == (Object)null)
				{
					value.IsLoaded = false;
				}
			}
		}

		private void UpdateLoadedPositions()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_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)
			long ownerID = GetOwnerID();
			bool flag = false;
			foreach (ShipRecord value in _records.Values)
			{
				if (!value.IsLoaded || (Object)(object)value.Ship == (Object)null)
				{
					continue;
				}
				Vector3 position = ((Component)value.Ship).transform.position;
				if (!(position == value.Position))
				{
					value.Position = position;
					value.Rotation = ((Component)value.Ship).transform.rotation;
					flag = true;
					if (value.OwnerID == ownerID)
					{
						AddOrUpdatePin(value);
					}
				}
			}
			if (flag)
			{
				_dirty = true;
			}
		}

		public static int GetTypeHash(string type)
		{
			return type switch
			{
				"Raft" => HashRaft, 
				"Karve" => HashKarve, 
				"Longship" => HashVikingShip, 
				"Drakkar" => HashDrakkar, 
				_ => 0, 
			};
		}

		internal static string TypeToPrefabName(string type)
		{
			object obj;
			if (!(type == "Longship"))
			{
				obj = type;
				if (obj == null)
				{
					return "Raft";
				}
			}
			else
			{
				obj = "VikingShip";
			}
			return (string)obj;
		}

		public void UpdateShipZDOID(ShipRecord record, ZDOID newID)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0050: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			ZDOID iD = record.ID;
			if (!(iD == newID))
			{
				if (_records.ContainsKey(iD))
				{
					RemovePin(iD);
					_records.Remove(iD);
				}
				record.ID = newID;
				_records[newID] = record;
				if (record.IsSecondary)
				{
					_secondaryID = newID;
				}
				else if (iD == _primaryID)
				{
					_primaryID = newID;
				}
				_dirty = true;
				AddOrUpdatePin(record);
			}
		}

		private static int ShipRank(int hash)
		{
			if (hash == HashRaft)
			{
				return 0;
			}
			if (hash == HashKarve)
			{
				return 1;
			}
			if (hash == HashVikingShip)
			{
				return 2;
			}
			if (hash == HashDrakkar)
			{
				return 3;
			}
			return -1;
		}

		private static string TypeName(int hash)
		{
			if (hash == HashRaft)
			{
				return "Raft";
			}
			if (hash == HashKarve)
			{
				return "Karve";
			}
			if (hash == HashVikingShip)
			{
				return "Longship";
			}
			if (hash == HashDrakkar)
			{
				return "Drakkar";
			}
			return "Ship";
		}

		internal static long GetMyUID()
		{
			try
			{
				return ZNet.GetUID();
			}
			catch
			{
				return 0L;
			}
		}

		internal static long GetOwnerID()
		{
			Game instance = Game.instance;
			long? obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PlayerProfile playerProfile = instance.GetPlayerProfile();
				obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null));
			}
			return obj ?? GetMyUID();
		}

		private static int StableHash(string s)
		{
			int num = 5381;
			int num2 = num;
			for (int i = 0; i < s.Length && s[i] != 0; i += 2)
			{
				num = ((num << 5) + num) ^ s[i];
				if (i + 1 < s.Length && s[i + 1] != 0)
				{
					num2 = ((num2 << 5) + num2) ^ s[i + 1];
				}
			}
			return num + num2 * 1566083941;
		}
	}
	public static class WaterScanner
	{
		public struct ScanResult
		{
			public bool Found;

			public Vector3 Position;

			public Quaternion Rotation;

			public float Score;
		}

		private static readonly int ObstacleMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "piece", "character", "vehicle" });

		public static ScanResult FindSummonPosition(Vector3 playerPos, Vector3 playerFwd, float minRadius, float maxRadius, float minDepth, Ship excludeShip = null)
		{
			//IL_0014: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0049: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			float water = WaterLevel();
			ScanResult result = default(ScanResult);
			float num = -1f;
			foreach (Vector3 item in GenerateCandidates(playerPos, playerFwd, minRadius, maxRadius))
			{
				float num2 = WaterDepthAt(item, water);
				if (!(num2 < minDepth) && IsOpen(item, water, minDepth) && !HasObstacle(item, excludeShip))
				{
					float num3 = Score(item, playerPos, playerFwd, maxRadius, num2);
					if (num3 > num)
					{
						num = num3;
						result = new ScanResult
						{
							Found = true,
							Position = item,
							Rotation = RotationAwayFrom(item, playerPos),
							Score = num3
						};
					}
				}
			}
			return result;
		}

		private static IEnumerable<Vector3> GenerateCandidates(Vector3 origin, Vector3 fwd, float minR, float maxR)
		{
			//IL_0008: 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_000f: 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)
			float water = WaterLevel();
			float step = (maxR - minR) / 4f;
			for (int ring = 0; ring < 5; ring++)
			{
				float r = minR + step * (float)ring;
				for (int a = -5; a <= 5; a++)
				{
					Vector3 val = Quaternion.AngleAxis((float)a * 15f, Vector3.up) * fwd;
					Vector3 val2 = origin + val * r;
					val2.y = water;
					yield return val2;
				}
			}
			for (int ring = 0; ring < 24; ring++)
			{
				Vector3 val3 = Quaternion.AngleAxis((float)ring * 15f, Vector3.up) * fwd;
				Vector3 val4 = origin + val3 * maxR;
				val4.y = water;
				yield return val4;
			}
		}

		private static float WaterDepthAt(Vector3 pos, float water)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			float num = TerrainHeightAt(pos);
			return water - num;
		}

		private static bool IsOpen(Vector3 center, float water, float minDepth)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			/