Decompiled source of Carturs Compass and Clock v1.5.7

plugins/CarturCompassAndClock.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CarturCompassAndClock
{
	[BepInPlugin("com.jekkle.valheim.carturcompassandclock", "Cartur's Compass and Clock", "1.5.6")]
	public class Plugin : BaseUnityPlugin
	{
		public enum DeathMarkerMode
		{
			All,
			InRange,
			Off
		}

		private class DragHandle : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
		{
			private Plugin _owner;

			private bool _resizes;

			public void Init(Plugin owner, bool resizes)
			{
				_owner = owner;
				_resizes = resizes;
			}

			public void OnBeginDrag(PointerEventData eventData)
			{
				_owner._dragging = true;
			}

			public void OnDrag(PointerEventData eventData)
			{
				//IL_0001: 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_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				Vector2 val = eventData.delta / _owner._canvasGo.GetComponent<Canvas>().scaleFactor;
				if (_resizes)
				{
					_owner.ResizeBy(val.x);
				}
				else
				{
					_owner.MoveBy(val);
				}
			}

			public void OnEndDrag(PointerEventData eventData)
			{
				_owner._dragging = false;
				_owner.CommitLayout();
			}
		}

		[HarmonyPatch(typeof(Minimap), "Awake")]
		private static class ClearLootedGravesPatch
		{
			private static void Postfix()
			{
				LootedGraves.Clear();
			}
		}

		[HarmonyPatch(typeof(TombStone), "UpdateDespawn")]
		private static class GraveLootedPatch
		{
			private static void Postfix(TombStone __instance)
			{
				//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_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				if (TombStoneContainer == null || TombStoneGetOwner == null || PinsField == null || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Minimap.instance == (Object)null)
				{
					return;
				}
				object? value = TombStoneContainer.GetValue(__instance);
				Container val = (Container)((value is Container) ? value : null);
				if ((Object)(object)val == (Object)null || val.IsInUse())
				{
					return;
				}
				Inventory inventory = val.GetInventory();
				if (inventory == null || inventory.NrOfItems() > 0 || !(TombStoneGetOwner.Invoke(__instance, null) is long num) || num != Player.m_localPlayer.GetPlayerID())
				{
					return;
				}
				Vector3 position = ((Component)__instance).transform.position;
				List<PinData> obj = (List<PinData>)PinsField.GetValue(Minimap.instance);
				PinData val2 = null;
				float num2 = 40f;
				foreach (PinData item in obj)
				{
					if (IsDeath(item))
					{
						float num3 = Vector3.Distance(item.m_pos, position);
						if (!(num3 > num2))
						{
							num2 = num3;
							val2 = item;
						}
					}
				}
				if (val2 != null)
				{
					LootedGraves.Add(val2);
				}
			}
		}

		public const string PluginGuid = "com.jekkle.valheim.carturcompassandclock";

		public const string PluginName = "Cartur's Compass and Clock";

		public const string PluginVersion = "1.5.6";

		public static ConfigEntry<float> PinRange;

		public static ConfigEntry<DeathMarkerMode> DeathMarkers;

		public static ConfigEntry<float> FieldOfView;

		public static ConfigEntry<int> FrameWidth;

		public static ConfigEntry<float> FrameOffsetX;

		public static ConfigEntry<float> FrameOffsetY;

		public static ConfigEntry<bool> ShowPinNames;

		public static ConfigEntry<bool> ShowClock;

		public static ConfigEntry<bool> TwelveHourClock;

		public static ConfigEntry<bool> ShowDay;

		public static ConfigEntry<string> ClockFormat;

		public static ConfigEntry<int> ClockTextSize;

		public static ConfigEntry<float> Opacity;

		public static ConfigEntry<string> Style;

		public static ConfigEntry<bool> EditMode;

		private const float MinFrameWidth = 200f;

		private const float MaxFrameWidth = 1600f;

		private const string MapPinsGuid = "com.jekkle.valheim.carturmappins";

		private const int MapPinsCurrentBaseFallback = 183;

		private const int MapPinsLegacyBase = 100;

		private const int MapPinsLegacyMarker = 1000;

		private static MethodInfo _pinStylesFor;

		private static MethodInfo _pinStylesColourFor;

		private static MethodInfo _pinStylesTintFor;

		private static bool _pinStylesResolved;

		private static readonly object[] OneArg = new object[1];

		private static readonly object[] TintArgs = new object[2];

		private ConfigEntry<bool> _mapPinsCustomIcons;

		private ConfigEntryBase _mapPinsLootedIcon;

		private int _mapPinsCurrentBase = 183;

		private bool _mapPinsResolved;

		private const float MinBearingDistance = 8f;

		private const int HomePinType = 5;

		private const int DeathPinType = 4;

		private static readonly HashSet<PinData> LootedGraves = new HashSet<PinData>();

		private const float GravePinMatchRange = 40f;

		private static readonly FieldInfo TombStoneContainer = typeof(TombStone).GetField("m_container", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly MethodInfo TombStoneGetOwner = typeof(TombStone).GetMethod("GetOwner", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly Color HomeColor = new Color(1f, 0.82f, 0.25f, 1f);

		private static readonly Color DeathColor = new Color(0.75f, 0.13f, 0.13f, 1f);

		private const float PriorityIconScale = 1.5f;

		private const float FocusConeDegrees = 12f;

		private const float MarkerMinSpacing = 22f;

		private const float RangeSlack = 1.1f;

		private static readonly FieldInfo PinsField = typeof(Minimap).GetField("m_pins", BindingFlags.Instance | BindingFlags.NonPublic);

		private const float WinXMin = 0.0605f;

		private const float WinXMax = 0.9395f;

		private const float WinYMin = 0.2536f;

		private const float WinYMax = 0.7174f;

		private const float FrameNativeAspect = 14.492754f;

		private const float ClockHeight = 40f;

		private const float ClockToFrameGap = 0f;

		private const int EdgeFadePx = 22;

		private const int MinorTickStep = 15;

		private GameObject _canvasGo;

		private RectTransform _viewport;

		private RectTransform _markerRoot;

		private readonly Dictionary<PinData, GameObject> _markerPool = new Dictionary<PinData, GameObject>();

		private readonly List<PinData> _toRemove = new List<PinData>();

		private readonly List<GameObject> _bearingMarks = new List<GameObject>();

		private readonly List<float> _bearingAngles = new List<float>();

		private readonly List<Transform> _sortedMarkers = new List<Transform>();

		private readonly List<float> _sortedDistances = new List<float>();

		private readonly List<float> _keptX = new List<float>();

		private readonly List<Transform> _priorityMarkers = new List<Transform>();

		private Font _font;

		private const int Morning = 0;

		private const int Afternoon = 1;

		private const int Night = 2;

		private const int DayFormat = 3;

		private const int Am = 4;

		private const int Pm = 5;

		private const int Home = 6;

		private static readonly Dictionary<string, string[]> Phrases = new Dictionary<string, string[]>
		{
			{
				"English",
				new string[7] { "Morning", "Afternoon", "Night", "Day {0}", "AM", "PM", "Home" }
			},
			{
				"German",
				new string[7] { "Morgen", "Nachmittag", "Nacht", "Tag {0}", "AM", "PM", "Zuhause" }
			},
			{
				"Russian",
				new string[7] { "Утро", "День", "Ночь", "День {0}", "AM", "PM", "Дом" }
			},
			{
				"French",
				new string[7] { "Matin", "Après-midi", "Nuit", "Jour {0}", "AM", "PM", "Maison" }
			},
			{
				"Spanish",
				new string[7] { "Mañana", "Tarde", "Noche", "Día {0}", "a.m.", "p.m.", "Hogar" }
			},
			{
				"Italian",
				new string[7] { "Mattino", "Pomeriggio", "Notte", "Giorno {0}", "AM", "PM", "Casa" }
			},
			{
				"Polish",
				new string[7] { "Poranek", "Popołudnie", "Noc", "Dzień {0}", "AM", "PM", "Dom" }
			},
			{
				"Portuguese_Brazilian",
				new string[7] { "Manhã", "Tarde", "Noite", "Dia {0}", "AM", "PM", "Casa" }
			},
			{
				"Chinese",
				new string[7] { "早晨", "下午", "夜晚", "第{0}天", "上午", "下午", "家" }
			},
			{
				"Japanese",
				new string[7] { "朝", "午後", "夜", "{0}日目", "午前", "午後", "拠点" }
			},
			{
				"Korean",
				new string[7] { "아침", "오후", "밤", "{0}일차", "오전", "오후", "집" }
			}
		};

		private string[] _phrases;

		private const string ClockFontName = "Valheim-AveriaSerifLibre";

		private TMP_FontAsset _clockFont;

		private float _contentWidthPx;

		private TextMeshProUGUI _clockText;

		private Text _focusLabel;

		private bool _rebuildQueued;

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

		private RectTransform _frameRoot;

		private bool _dragging;

		private float _nextFontTry;

		private const string RuneGuid = "com.jekkle.valheim.carturruneui";

		private static bool Rune
		{
			get
			{
				if (!(Style.Value == "Rune"))
				{
					if (Style.Value == "Auto")
					{
						return Chainloader.PluginInfos.ContainsKey("com.jekkle.valheim.carturruneui");
					}
					return false;
				}
				return true;
			}
		}

		private void Awake()
		{
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Expected O, but got Unknown
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected O, but got Unknown
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Expected O, but got Unknown
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			PinRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PinRange", 300f, "Only show map pins within this many meters.");
			DeathMarkers = ((BaseUnityPlugin)this).Config.Bind<DeathMarkerMode>("General", "DeathMarkers", DeathMarkerMode.All, "Which grave markers the compass draws. All: every death pin still on your map, at any distance - graves ignore PinRange, so a long-lived character shows every grave it ever left. InRange: graves obey PinRange like everything else, so the one you just made still shows while you walk back to it and the old ones stop crowding the bar. Off: no grave markers at all. This only changes the compass; your map is untouched either way.");
			FieldOfView = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FieldOfView", 90f, "Total degrees of heading visible across the compass window.");
			FrameWidth = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "FrameWidth", 657, "Frame width, in reference-resolution pixels (1920x1080 basis - scales with screen size). Height follows the frame image's aspect ratio.");
			FrameOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "FrameOffsetX", 0f, "Distance right of screen centre to the middle of the frame, in reference-resolution pixels (1920x1080 basis). Negative moves it left.");
			FrameOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "FrameOffsetY", 54f, "Distance from the top of the screen down to the frame's top edge, in reference-resolution pixels (1920x1080 basis). The clock sits directly above the frame.");
			ShowClock = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowClock", true, "Show the clock above the compass. Off hides it completely; the compass stays.");
			TwelveHourClock = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "TwelveHourClock", true, "Show the clock as 12-hour with AM/PM (1:05 PM). Off is 24-hour (13:05).");
			ShowDay = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowDay", true, "Show the time of day and the day number with the clock (Morning, Day 12 - 8:30 AM). Off shows the time alone.");
			ClockFormat = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ClockFormat", "", "Custom clock text (Discord request). Empty keeps the built-in text, which TwelveHourClock and ShowDay control. Tokens: {phase} Morning/Afternoon/Night, {day} Day 12, {daynum} 12, {time} as TwelveHourClock says, {time12} 1:05 PM, {time24} 13:05, {hour} 13, {hour12} 1, {minute} 05, {ampm} PM. Words follow the game language. Example: {day} | {time24}. Unknown tokens are shown as typed.");
			ClockTextSize = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ClockTextSize", 26, new ConfigDescription("Size of the clock text. Separate from FrameWidth, so the clock can be bigger or smaller than the compass.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 60), Array.Empty<object>()));
			Opacity = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "Opacity", 1f, new ConfigDescription("How solid the compass and clock are. 1 is fully solid, lower lets the game show through.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
			Style = ((BaseUnityPlugin)this).Config.Bind<string>("Layout", "Style", "Auto", new ConfigDescription("Bronze is the bronze frame. Rune is a flat dark panel with a thin black border, matching Cartur's RuneUI. Auto picks Rune when Cartur's RuneUI is installed, Bronze otherwise.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Auto", "Bronze", "Rune" }), Array.Empty<object>()));
			ShowPinNames = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowPinNames", true, "Show the name and distance of the pin nearest the center of the compass, under the frame.");
			EditMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Layout", "EditMode", false, "Draw a box around the compass and let you drag it to move it, or drag the grip on its right edge to resize it. The compass stays on screen while this is on, even in menus. Turn it off when you are happy with it.");
			try
			{
				_font = Resources.GetBuiltinResource<Font>("Arial.ttf");
				BuildUi();
			}
			catch (Exception arg)
			{
				((Behaviour)this).enabled = false;
				((BaseUnityPlugin)this).Logger.LogError((object)$"Could not build the compass, disabling it: {arg}");
				return;
			}
			try
			{
				Harmony val = new Harmony("com.jekkle.valheim.carturcompassandclock");
				val.PatchAll(typeof(GraveLootedPatch));
				val.PatchAll(typeof(ClearLootedGravesPatch));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not patch TombStone.UpdateDespawn - recovered graves will keep their marker: " + ex.Message));
			}
			((BaseUnityPlugin)this).Config.SettingChanged += delegate
			{
				_rebuildQueued = true;
			};
			Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, (Action)delegate
			{
				_phrases = null;
			});
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Cartur's Compass and Clock 1.5.6 loaded - compass built, TombStone.UpdateDespawn patched for recovered graves.");
		}

		private Sprite LoadFrameSprite()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			using Stream input = Assembly.GetExecutingAssembly().GetManifestResourceStream("CarturCompassAndClock.compass_frame.rgba");
			using BinaryReader binaryReader = new BinaryReader(input);
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			Color32[] array = (Color32[])(object)new Color32[num * num2];
			for (int i = 0; i < array.Length; i++)
			{
				byte b = binaryReader.ReadByte();
				byte b2 = binaryReader.ReadByte();
				byte b3 = binaryReader.ReadByte();
				byte b4 = binaryReader.ReadByte();
				array[i] = new Color32(b, b2, b3, b4);
			}
			Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false);
			val.SetPixels32(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f));
		}

		private void BuildUi()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00d3: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: 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_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: 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_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Expected O, but got Unknown
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Expected O, but got Unknown
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_052b: Expected O, but got Unknown
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_0561: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			//IL_0590: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Expected O, but got Unknown
			//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_061c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_070b: Unknown result type (might be due to invalid IL or missing references)
			//IL_071a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0721: Expected O, but got Unknown
			//IL_074e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0764: Unknown result type (might be due to invalid IL or missing references)
			//IL_077a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0790: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_081c: Unknown result type (might be due to invalid IL or missing references)
			//IL_085a: Unknown result type (might be due to invalid IL or missing references)
			//IL_086e: Unknown result type (might be due to invalid IL or missing references)
			_canvasGo = new GameObject("CarturCompassCanvas");
			Object.DontDestroyOnLoad((Object)(object)_canvasGo);
			Canvas obj = _canvasGo.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 30;
			CanvasScaler obj2 = _canvasGo.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.matchWidthOrHeight = 0.5f;
			_canvasGo.AddComponent<GraphicRaycaster>();
			_canvasGo.AddComponent<CanvasGroup>().alpha = Opacity.Value;
			float num = FrameWidth.Value;
			float num2 = num / 14.492754f;
			GameObject val = new GameObject("CompassRoot");
			val.transform.SetParent(_canvasGo.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0.5f, 1f);
			val2.anchorMax = new Vector2(0.5f, 1f);
			val2.pivot = new Vector2(0.5f, 1f);
			val2.sizeDelta = new Vector2(num, num2);
			val2.anchoredPosition = new Vector2(FrameOffsetX.Value, 0f - FrameOffsetY.Value);
			_frameRoot = val2;
			_movable.Clear();
			_movable.Add(val2);
			GameObject val3 = new GameObject("FrameArt");
			val3.transform.SetParent(val.transform, false);
			RectTransform obj3 = val3.AddComponent<RectTransform>();
			obj3.anchorMin = Vector2.zero;
			obj3.anchorMax = Vector2.one;
			obj3.offsetMin = Vector2.zero;
			obj3.offsetMax = Vector2.zero;
			Image val4 = val3.AddComponent<Image>();
			val4.type = (Type)0;
			((Graphic)val4).raycastTarget = false;
			if (Rune)
			{
				((Graphic)val4).color = Color.black;
				GameObject val5 = new GameObject("RuneFill");
				val5.transform.SetParent(val3.transform, false);
				RectTransform obj4 = val5.AddComponent<RectTransform>();
				obj4.anchorMin = Vector2.zero;
				obj4.anchorMax = Vector2.one;
				obj4.offsetMin = new Vector2(1f, 1f);
				obj4.offsetMax = new Vector2(-1f, -1f);
				Image obj5 = val5.AddComponent<Image>();
				((Graphic)obj5).color = new Color(0.054f, 0.054f, 0.054f, 0.75f);
				((Graphic)obj5).raycastTarget = false;
			}
			else
			{
				val4.sprite = LoadFrameSprite();
			}
			GameObject val6 = new GameObject("Content");
			val6.transform.SetParent(val.transform, false);
			RectTransform obj6 = val6.AddComponent<RectTransform>();
			obj6.anchorMin = new Vector2(0.0605f, 0.2826f);
			obj6.anchorMax = new Vector2(0.9395f, 0.7464f);
			obj6.offsetMin = Vector2.zero;
			obj6.offsetMax = Vector2.zero;
			_contentWidthPx = 0.87899995f * num;
			GameObject val7 = new GameObject("Viewport");
			val7.transform.SetParent(val6.transform, false);
			_viewport = val7.AddComponent<RectTransform>();
			_viewport.anchorMin = Vector2.zero;
			_viewport.anchorMax = Vector2.one;
			_viewport.offsetMin = Vector2.zero;
			_viewport.offsetMax = Vector2.zero;
			val7.AddComponent<RectMask2D>().softness = new Vector2Int(22, 0);
			GameObject val8 = new GameObject("CenterTick");
			val8.transform.SetParent((Transform)(object)_viewport, false);
			RectTransform obj7 = val8.AddComponent<RectTransform>();
			obj7.anchorMin = new Vector2(0.5f, 0f);
			obj7.anchorMax = new Vector2(0.5f, 1f);
			obj7.pivot = new Vector2(0.5f, 0.5f);
			obj7.sizeDelta = new Vector2(2f, 0f);
			obj7.anchoredPosition = Vector2.zero;
			Image obj8 = val8.AddComponent<Image>();
			((Graphic)obj8).color = new Color(1f, 0.85f, 0.2f, 0.9f);
			((Graphic)obj8).raycastTarget = false;
			_bearingMarks.Clear();
			_bearingAngles.Clear();
			Color color = default(Color);
			((Color)(ref color))..ctor(1f, 0.9f, 0.6f);
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(1f, 1f, 1f, 0.8f);
			CreateBearingLabel("N", 0f, 18, color);
			CreateBearingLabel("NE", 45f, 12, color2);
			CreateBearingLabel("E", 90f, 18, Color.white);
			CreateBearingLabel("SE", 135f, 12, color2);
			CreateBearingLabel("S", 180f, 18, Color.white);
			CreateBearingLabel("SW", 225f, 12, color2);
			CreateBearingLabel("W", 270f, 18, Color.white);
			CreateBearingLabel("NW", 315f, 12, color2);
			for (int i = 0; i < 360; i += 15)
			{
				if (i % 45 != 0)
				{
					CreateBearingTick(i);
				}
			}
			GameObject val9 = new GameObject("Markers");
			val9.transform.SetParent((Transform)(object)_viewport, false);
			_markerRoot = val9.AddComponent<RectTransform>();
			_markerRoot.anchorMin = Vector2.zero;
			_markerRoot.anchorMax = Vector2.one;
			_markerRoot.offsetMin = Vector2.zero;
			_markerRoot.offsetMax = Vector2.zero;
			GameObject val10 = new GameObject("Clock");
			val10.transform.SetParent(_canvasGo.transform, false);
			RectTransform val11 = val10.AddComponent<RectTransform>();
			val11.anchorMin = new Vector2(0.5f, 1f);
			val11.anchorMax = new Vector2(0.5f, 1f);
			val11.pivot = new Vector2(0.5f, 1f);
			float num3 = 40f * (float)ClockTextSize.Value / 26f;
			val11.sizeDelta = new Vector2(300f, num3);
			val11.anchoredPosition = new Vector2(FrameOffsetX.Value, 0f - FrameOffsetY.Value + 0f + num3);
			_movable.Add(val11);
			val10.SetActive(false);
			_clockText = val10.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_clockText).fontSize = ClockTextSize.Value;
			((TMP_Text)_clockText).fontStyle = (FontStyles)1;
			((TMP_Text)_clockText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_clockText).textWrappingMode = (TextWrappingModes)0;
			((Graphic)_clockText).color = new Color(1f, 0.9f, 0.65f);
			((Graphic)_clockText).raycastTarget = false;
			Shadow obj9 = val10.AddComponent<Shadow>();
			obj9.effectColor = new Color(0f, 0f, 0f, 0.8f);
			obj9.effectDistance = new Vector2(1.5f, -1.5f);
			GameObject val12 = new GameObject("FocusLabel");
			val12.transform.SetParent(_canvasGo.transform, false);
			RectTransform val13 = val12.AddComponent<RectTransform>();
			val13.anchorMin = new Vector2(0.5f, 1f);
			val13.anchorMax = new Vector2(0.5f, 1f);
			val13.pivot = new Vector2(0.5f, 1f);
			val13.sizeDelta = new Vector2(500f, 20f);
			val13.anchoredPosition = new Vector2(FrameOffsetX.Value, 0f - (FrameOffsetY.Value + num2) - 2f);
			_movable.Add(val13);
			_focusLabel = val12.AddComponent<Text>();
			_focusLabel.font = _font;
			_focusLabel.fontSize = 14;
			_focusLabel.alignment = (TextAnchor)1;
			((Graphic)_focusLabel).color = new Color(1f, 0.95f, 0.85f);
			_focusLabel.horizontalOverflow = (HorizontalWrapMode)1;
			((Graphic)_focusLabel).raycastTarget = false;
			Shadow obj10 = val12.AddComponent<Shadow>();
			obj10.effectColor = new Color(0f, 0f, 0f, 0.8f);
			obj10.effectDistance = new Vector2(1.5f, -1.5f);
			if (EditMode.Value)
			{
				BuildEditOverlay(val.transform);
			}
		}

		private void BuildEditOverlay(Transform parent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0077: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("EditBox");
			val.transform.SetParent(parent, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			obj.offsetMin = new Vector2(-4f, -4f);
			obj.offsetMax = new Vector2(4f, 4f);
			((Graphic)val.AddComponent<Image>()).color = new Color(1f, 0.85f, 0.2f, 0.15f);
			val.AddComponent<DragHandle>().Init(this, resizes: false);
			GameObject val2 = new GameObject("ResizeGrip");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj2 = val2.AddComponent<RectTransform>();
			obj2.anchorMin = new Vector2(1f, 0.5f);
			obj2.anchorMax = new Vector2(1f, 0.5f);
			obj2.pivot = new Vector2(0.5f, 0.5f);
			obj2.sizeDelta = new Vector2(14f, 14f);
			obj2.anchoredPosition = Vector2.zero;
			((Graphic)val2.AddComponent<Image>()).color = new Color(1f, 0.85f, 0.2f, 0.9f);
			val2.AddComponent<DragHandle>().Init(this, resizes: true);
		}

		private void MoveBy(Vector2 delta)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			foreach (RectTransform item in _movable)
			{
				item.anchoredPosition += delta;
			}
		}

		private void ResizeBy(float deltaX)
		{
			//IL_0006: 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)
			float num = Mathf.Clamp(_frameRoot.sizeDelta.x + deltaX * 2f, 200f, 1600f);
			_frameRoot.sizeDelta = new Vector2(num, num / 14.492754f);
			_contentWidthPx = 0.87899995f * num;
		}

		private void CommitLayout()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			FrameOffsetX.Value = _frameRoot.anchoredPosition.x;
			FrameOffsetY.Value = 0f - _frameRoot.anchoredPosition.y;
			FrameWidth.Value = Mathf.RoundToInt(_frameRoot.sizeDelta.x);
		}

		private void CreateBearingLabel(string text, float bearing, int fontSize, Color color)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0034: 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_005e: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Cardinal_" + text);
			val.transform.SetParent((Transform)(object)_viewport, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.5f, 0f);
			obj.anchorMax = new Vector2(0.5f, 1f);
			obj.pivot = new Vector2(0.5f, 0.5f);
			obj.sizeDelta = new Vector2(30f, 0f);
			Text obj2 = val.AddComponent<Text>();
			obj2.text = text;
			obj2.font = _font;
			obj2.fontSize = fontSize;
			obj2.fontStyle = (FontStyle)1;
			obj2.alignment = (TextAnchor)4;
			((Graphic)obj2).color = color;
			((Graphic)obj2).raycastTarget = false;
			_bearingMarks.Add(val);
			_bearingAngles.Add(bearing);
		}

		private void CreateBearingTick(float bearing)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0039: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"Tick_{bearing:F0}");
			val.transform.SetParent((Transform)(object)_viewport, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.5f, 0f);
			obj.anchorMax = new Vector2(0.5f, 0f);
			obj.pivot = new Vector2(0.5f, 0f);
			obj.sizeDelta = new Vector2(2f, 6f);
			Image obj2 = val.AddComponent<Image>();
			((Graphic)obj2).color = new Color(1f, 0.95f, 0.8f, 0.35f);
			((Graphic)obj2).raycastTarget = false;
			_bearingMarks.Add(val);
			_bearingAngles.Add(bearing);
		}

		private GameObject CreateMarker()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00a4: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("PinMarker");
			val.transform.SetParent((Transform)(object)_markerRoot, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.5f, 0.5f);
			obj.anchorMax = new Vector2(0.5f, 0.5f);
			obj.pivot = new Vector2(0.5f, 0.5f);
			obj.sizeDelta = new Vector2(20f, 20f);
			GameObject val2 = new GameObject("Icon");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj2 = val2.AddComponent<RectTransform>();
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = Vector2.zero;
			obj2.offsetMax = Vector2.zero;
			((Graphic)val2.AddComponent<Image>()).raycastTarget = false;
			return val;
		}

		private void ClaimClockFont()
		{
			if (!ShowClock.Value || (Object)(object)_clockText == (Object)null || ((Component)_clockText).gameObject.activeSelf || Time.time < _nextFontTry)
			{
				return;
			}
			_nextFontTry = Time.time + 0.5f;
			TMP_FontAsset val = (Rune ? RuneFont() : null);
			TMP_FontAsset val2 = val ?? SerifFont();
			if (!((Object)(object)val2 == (Object)null))
			{
				((TMP_Text)_clockText).font = val2;
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)_clockText).fontStyle = (FontStyles)0;
				}
				((Component)_clockText).gameObject.SetActive(true);
			}
		}

		private string[] Phrasebook()
		{
			if (_phrases == null)
			{
				string selectedLanguage = Localization.instance.GetSelectedLanguage();
				if (selectedLanguage == null || !Phrases.TryGetValue(selectedLanguage, out _phrases))
				{
					_phrases = Phrases["English"];
				}
			}
			return _phrases;
		}

		private static TMP_FontAsset RuneFont()
		{
			if (!Chainloader.PluginInfos.TryGetValue("com.jekkle.valheim.carturruneui", out var value) || (Object)(object)((value != null) ? value.Instance : null) == (Object)null)
			{
				return null;
			}
			object? obj = ((object)value.Instance).GetType().Assembly.GetType("CarturRuneUI.Fonts")?.GetProperty("Bold", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null, null);
			return (TMP_FontAsset)((obj is TMP_FontAsset) ? obj : null);
		}

		private TMP_FontAsset SerifFont()
		{
			if ((Object)(object)_clockFont == (Object)null)
			{
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				foreach (TMP_FontAsset val in array)
				{
					if ((Object)(object)val != (Object)null && ((Object)val).name == "Valheim-AveriaSerifLibre")
					{
						_clockFont = val;
						break;
					}
				}
			}
			return _clockFont;
		}

		private void Update()
		{
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Invalid comparison between Unknown and I4
			if (_rebuildQueued && !_dragging)
			{
				_rebuildQueued = false;
				Rebuild();
			}
			ClaimClockFont();
			Player localPlayer = Player.m_localPlayer;
			GameCamera instance = GameCamera.instance;
			bool flag = (Object)(object)localPlayer != (Object)null && (Object)(object)instance != (Object)null && (Object)(object)Minimap.instance != (Object)null;
			if (flag && !EditMode.Value)
			{
				flag = !Hud.IsUserHidden() && (int)Minimap.instance.m_mode != 2 && !InventoryGui.IsVisible() && !Menu.IsVisible() && !CinematicsManager.IsStartedPlaying();
			}
			_canvasGo.SetActive(flag);
			if (flag)
			{
				if ((Object)(object)EnvMan.instance != (Object)null)
				{
					int num = (int)(EnvMan.instance.GetDayFraction() * 24f * 60f) % 1440;
					int num2 = num / 60;
					int num3 = num % 60;
					string[] array = Phrasebook();
					string text = (TwelveHourClock.Value ? $"{((num2 % 12 == 0) ? 12 : (num2 % 12))}:{num3:D2} {((num2 < 12) ? array[4] : array[5])}" : $"{num2:D2}:{num3:D2}");
					string text2 = string.Format(array[3], EnvMan.instance.GetDay());
					string text3 = ((num2 < 12) ? array[4] : array[5]);
					string newValue = $"{((num2 % 12 == 0) ? 12 : (num2 % 12))}:{num3:D2} {text3}";
					string newValue2 = $"{num2:D2}:{num3:D2}";
					string text4 = PhaseName(num2, array);
					((TMP_Text)_clockText).text = ((!string.IsNullOrEmpty(ClockFormat.Value)) ? ClockFormat.Value.Replace("{phase}", text4).Replace("{day}", text2).Replace("{daynum}", EnvMan.instance.GetDay().ToString())
						.Replace("{time}", text)
						.Replace("{time12}", newValue)
						.Replace("{time24}", newValue2)
						.Replace("{hour}", num2.ToString("D2"))
						.Replace("{hour12}", ((num2 % 12 == 0) ? 12 : (num2 % 12)).ToString())
						.Replace("{minute}", num3.ToString("D2"))
						.Replace("{ampm}", text3) : (ShowDay.Value ? (text4 + ", " + text2 + " - " + text) : text));
				}
				float y = ((Component)instance).transform.eulerAngles.y;
				float halfFov = FieldOfView.Value * 0.5f;
				float halfWidth = _contentWidthPx * 0.5f;
				for (int i = 0; i < _bearingMarks.Count; i++)
				{
					PositionOnCompass(_bearingMarks[i], _bearingAngles[i], y, halfFov, halfWidth);
				}
				UpdatePins(localPlayer, y, halfFov, halfWidth);
			}
		}

		private void Rebuild()
		{
			Object.Destroy((Object)(object)_canvasGo);
			_markerPool.Clear();
			_sortedMarkers.Clear();
			_sortedDistances.Clear();
			BuildUi();
		}

		private void PositionOnCompass(GameObject go, float bearing, float heading, float halfFov, float halfWidth)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.DeltaAngle(heading, bearing);
			if (Mathf.Abs(num) > halfFov)
			{
				go.SetActive(false);
				return;
			}
			go.SetActive(true);
			float num2 = num / halfFov * halfWidth;
			go.GetComponent<RectTransform>().anchoredPosition = new Vector2(num2, 0f);
		}

		private bool ShouldShow(PinData pin, Vector3 playerPos, float range, int lootedType, float slack)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0052: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pin.m_icon == (Object)null)
			{
				return false;
			}
			if (pin.m_checked)
			{
				return false;
			}
			if (lootedType >= 0 && (int)pin.m_type == lootedType)
			{
				return false;
			}
			if (LootedGraves.Contains(pin))
			{
				return false;
			}
			if (IsDeath(pin) && DeathMarkers.Value == DeathMarkerMode.Off)
			{
				return false;
			}
			Vector3 val = pin.m_pos - playerPos;
			float num = range * slack;
			if (!IsPriority(pin) && ((Vector3)(ref val)).sqrMagnitude > num * num)
			{
				return false;
			}
			float num2 = 8f / slack;
			return val.x * val.x + val.z * val.z > num2 * num2;
		}

		private static bool IsHome(PinData pin)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			return (int)pin.m_type == 5;
		}

		private static bool IsDeath(PinData pin)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			return (int)pin.m_type == 4;
		}

		private static bool IsPriority(PinData pin)
		{
			if (!IsHome(pin))
			{
				if (IsDeath(pin))
				{
					return DeathMarkers.Value == DeathMarkerMode.All;
				}
				return false;
			}
			return true;
		}

		private int LootedChestType()
		{
			if (!_mapPinsResolved)
			{
				_mapPinsResolved = true;
				if (Chainloader.PluginInfos.TryGetValue("com.jekkle.valheim.carturmappins", out var value) && (Object)(object)value.Instance != (Object)null)
				{
					value.Instance.Config.TryGetEntry<bool>("CustomIcons", "Enabled", ref _mapPinsCustomIcons);
					string[] array = new string[2] { "LootedIcon", "LootedIconIndex" };
					foreach (string text in array)
					{
						ConfigDefinition val = null;
						foreach (ConfigDefinition key in value.Instance.Config.Keys)
						{
							if (!(key.Key != text) && (val == (ConfigDefinition)null || key.Section.Contains("Chest")))
							{
								val = key;
							}
						}
						if (!(val == (ConfigDefinition)null))
						{
							_mapPinsLootedIcon = value.Instance.Config[val];
							break;
						}
					}
					if (_mapPinsLootedIcon == null)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)"CarturMapPins is loaded but its looted-chest icon setting was not found - looted chests will still show.");
					}
					try
					{
						FieldInfo fieldInfo = ((object)value.Instance).GetType().Assembly.GetType("CarturMapPins.CustomIcons")?.GetField("CurrentBase", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
						if (fieldInfo != null && fieldInfo.IsLiteral)
						{
							_mapPinsCurrentBase = (int)fieldInfo.GetRawConstantValue();
						}
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)$"Could not read CarturMapPins.CustomIcons.CurrentBase, assuming {183}: {ex.Message}");
					}
				}
			}
			if (_mapPinsLootedIcon == null)
			{
				return -1;
			}
			if (_mapPinsCustomIcons != null && !_mapPinsCustomIcons.Value)
			{
				return -1;
			}
			int num;
			try
			{
				num = Convert.ToInt32(_mapPinsLootedIcon.BoxedValue);
			}
			catch (Exception)
			{
				return -1;
			}
			if (num < 0)
			{
				return -1;
			}
			if (num >= 1000)
			{
				return 100 + (num - 1000);
			}
			return _mapPinsCurrentBase + num;
		}

		private Color? PinColour(PinData pin)
		{
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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_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_01d5: Unknown result type (might be due to invalid IL or missing references)
			if (!_pinStylesResolved)
			{
				_pinStylesResolved = true;
				try
				{
					if (Chainloader.PluginInfos.TryGetValue("com.jekkle.valheim.carturmappins", out var value) && (Object)(object)value.Instance != (Object)null)
					{
						Type? type = ((object)value.Instance).GetType().Assembly.GetType("CarturMapPins.PinStyles");
						_pinStylesFor = type?.GetMethod("For", BindingFlags.Static | BindingFlags.Public);
						_pinStylesColourFor = type?.GetMethod("ColourFor", BindingFlags.Static | BindingFlags.Public);
						_pinStylesTintFor = type?.GetMethod("TintFor", BindingFlags.Static | BindingFlags.Public);
						if (_pinStylesFor == null || _pinStylesColourFor == null)
						{
							((BaseUnityPlugin)this).Logger.LogWarning((object)"CarturMapPins is loaded but PinStyles.For/ColourFor were not found - compass pins stay white.");
						}
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not read CarturMapPins pin colours, compass pins stay white: " + ex.Message));
				}
			}
			if (_pinStylesFor == null || _pinStylesColourFor == null)
			{
				return null;
			}
			try
			{
				OneArg[0] = pin.m_pos;
				object obj = _pinStylesFor.Invoke(null, OneArg);
				OneArg[0] = obj;
				if (_pinStylesColourFor.Invoke(null, OneArg) is Color value2)
				{
					return value2;
				}
				if (_pinStylesTintFor != null)
				{
					TintArgs[0] = pin.m_type;
					TintArgs[1] = null;
					object obj2 = _pinStylesTintFor.Invoke(null, TintArgs);
					bool flag = default(bool);
					int num;
					if (obj2 is bool)
					{
						flag = (bool)obj2;
						num = 1;
					}
					else
					{
						num = 0;
					}
					if (((uint)num & (flag ? 1u : 0u)) != 0 && TintArgs[1] is Color value3)
					{
						return value3;
					}
				}
			}
			catch (Exception)
			{
				_pinStylesFor = null;
			}
			return null;
		}

		private void UpdatePins(Player player, float heading, float halfFov, float halfWidth)
		{
			//IL_001b: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			List<PinData> list = (List<PinData>)PinsField.GetValue(Minimap.instance);
			Vector3 position = ((Component)player).transform.position;
			float value = PinRange.Value;
			int lootedType = LootedChestType();
			_toRemove.Clear();
			foreach (KeyValuePair<PinData, GameObject> item in _markerPool)
			{
				if (!list.Contains(item.Key) || !ShouldShow(item.Key, position, value, lootedType, 1.1f))
				{
					_toRemove.Add(item.Key);
				}
			}
			foreach (PinData item2 in _toRemove)
			{
				Object.Destroy((Object)(object)_markerPool[item2]);
				_markerPool.Remove(item2);
			}
			_sortedMarkers.Clear();
			_sortedDistances.Clear();
			PinData val = null;
			float num = 0f;
			float num2 = float.MaxValue;
			_priorityMarkers.Clear();
			foreach (PinData item3 in list)
			{
				if (!ShouldShow(item3, position, value, lootedType, 1f))
				{
					if (_markerPool.TryGetValue(item3, out var value2))
					{
						value2.SetActive(false);
					}
					continue;
				}
				Vector3 val2 = item3.m_pos - position;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				bool flag = IsPriority(item3);
				if (!_markerPool.TryGetValue(item3, out var value3))
				{
					value3 = CreateMarker();
					_markerPool[item3] = value3;
				}
				float num3 = (flag ? 0f : magnitude);
				int num4 = _sortedDistances.Count;
				while (num4 > 0 && _sortedDistances[num4 - 1] < num3)
				{
					num4--;
				}
				_sortedDistances.Insert(num4, num3);
				_sortedMarkers.Insert(num4, value3.transform);
				float num5 = Mathf.Atan2(val2.x, val2.z) * 57.29578f;
				float num6 = Mathf.DeltaAngle(heading, num5);
				if (Mathf.Abs(num6) > halfFov)
				{
					value3.SetActive(false);
					continue;
				}
				value3.SetActive(true);
				float num7 = num6 / halfFov * halfWidth;
				value3.GetComponent<RectTransform>().anchoredPosition = new Vector2(num7, 0f);
				if (flag)
				{
					_priorityMarkers.Add(value3.transform);
				}
				float num8 = 1f - Mathf.Clamp01(magnitude / value);
				Transform obj = value3.transform.Find("Icon");
				obj.localScale = Vector3.one * (flag ? 1.5f : Mathf.Lerp(1f, 2f, num8));
				Image component = ((Component)obj).GetComponent<Image>();
				if ((Object)(object)component.sprite != (Object)(object)item3.m_icon)
				{
					component.sprite = item3.m_icon;
				}
				((Behaviour)component).enabled = (Object)(object)item3.m_icon != (Object)null;
				if (flag)
				{
					((Graphic)component).color = (IsHome(item3) ? HomeColor : DeathColor);
				}
				else
				{
					Color color = (Color)(((??)PinColour(item3)) ?? Color.white);
					color.a *= Mathf.Lerp(0.45f, 1f, num8);
					((Graphic)component).color = color;
				}
				float num9 = Mathf.Abs(num6);
				if (num9 <= 12f && num9 < num2 && (flag || !string.IsNullOrEmpty(item3.m_name)))
				{
					num2 = num9;
					val = item3;
					num = magnitude;
				}
			}
			Declutter();
			for (int i = 0; i < _sortedMarkers.Count; i++)
			{
				if (_sortedMarkers[i].GetSiblingIndex() != i)
				{
					_sortedMarkers[i].SetSiblingIndex(i);
				}
			}
			bool flag2 = ShowPinNames.Value && val != null;
			((Behaviour)_focusLabel).enabled = flag2;
			if (flag2)
			{
				string text = PinLabel(val);
				if (string.IsNullOrEmpty(text))
				{
					text = Phrasebook()[6];
				}
				_focusLabel.text = $"{text} ({Mathf.RoundToInt(num)}m)";
			}
		}

		private static string PhaseName(int hour, string[] words)
		{
			if (hour >= 6 && hour < 12)
			{
				return words[0];
			}
			if (hour >= 12 && hour < 18)
			{
				return words[1];
			}
			return words[2];
		}

		private void Declutter()
		{
			//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_009b: 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)
			_keptX.Clear();
			for (int i = 0; i < _priorityMarkers.Count; i++)
			{
				if (((Component)_priorityMarkers[i]).gameObject.activeSelf)
				{
					_keptX.Add(((RectTransform)_priorityMarkers[i]).anchoredPosition.x);
				}
			}
			for (int num = _sortedMarkers.Count - 1; num >= 0; num--)
			{
				Transform val = _sortedMarkers[num];
				if (((Component)val).gameObject.activeSelf && !_priorityMarkers.Contains(val))
				{
					float x = ((RectTransform)val).anchoredPosition.x;
					bool flag = false;
					for (int j = 0; j < _keptX.Count; j++)
					{
						if (Mathf.Abs(_keptX[j] - x) < 22f)
						{
							flag = true;
							break;
						}
					}
					if (flag)
					{
						((Component)val).gameObject.SetActive(false);
					}
					else
					{
						_keptX.Add(x);
					}
				}
			}
		}

		private static string PinLabel(PinData pin)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			string text = Localization.instance.Localize(pin.m_name);
			if (!((PlatformUserID)(ref pin.m_author)).IsValid || pin.m_author == ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID)
			{
				return text;
			}
			return CensorShittyWords.FilterUGC(text, (UGCType)4, pin.m_author, 0L, (GetUserProfileCompletedHandler)null);
		}
	}
}