Decompiled source of Iconsee v1.0.3

Iconsee.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[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("Iconsee")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Iconsee")]
[assembly: AssemblyTitle("Iconsee")]
[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 Icons
{
	internal static class ColorSync
	{
		private struct Choice
		{
			public bool Custom;

			public Color Armor;
		}

		private const string RpcName = "Icons_SetArmor";

		private const float BroadcastInterval = 10f;

		private static readonly Dictionary<string, Choice> Others = new Dictionary<string, Choice>();

		private static Choice own;

		private static string lastHex;

		private static bool ownApplied;

		private static float nextBroadcast;

		private static int nextOwnApply;

		private static int nextPrune;

		internal static bool TryParseHex(string hex, out Color c)
		{
			//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)
			c = Color.white;
			if (string.IsNullOrEmpty(hex))
			{
				return false;
			}
			string text = hex.Trim();
			if (!text.StartsWith("#"))
			{
				text = "#" + text;
			}
			if (ColorUtility.TryParseHtmlString(text, ref c))
			{
				c.a = 1f;
				return true;
			}
			return false;
		}

		internal static Color ParseHex(string hex)
		{
			//IL_0010: 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)
			if (!TryParseHex(hex, out var c))
			{
				return Color.white;
			}
			return c;
		}

		internal static string ToHex(Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ColorUtility.ToHtmlStringRGB(c);
		}

		private static Choice Make(string hex)
		{
			//IL_001c: 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)
			Choice result = default(Choice);
			if (TryParseHex(hex, out var c))
			{
				result.Custom = true;
				result.Armor = c;
			}
			return result;
		}

		internal static bool TryGetPlayerColor(string playerName, out Color color)
		{
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			color = Color.white;
			if (Others.TryGetValue(playerName, out var value) && value.Custom)
			{
				color = value.Armor;
				return true;
			}
			return false;
		}

		internal static void Register(ZRoutedRpc rpc)
		{
			Others.Clear();
			nextBroadcast = Time.time + 3f;
			rpc.Register<string, string>("Icons_SetArmor", (Action<long, string, string>)RpcReceive);
		}

		internal static void OnOwnColorChanged()
		{
			nextBroadcast = 0f;
		}

		private static void RpcReceive(long sender, string playerName, string hex)
		{
			if (!string.IsNullOrEmpty(playerName) && playerName.Length <= 64 && (hex == null || hex.Length <= 9))
			{
				Others[playerName] = Make(hex);
			}
		}

		private static void Broadcast()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			ZRoutedRpc instance = ZRoutedRpc.instance;
			Player localPlayer = Player.m_localPlayer;
			if (instance != null && !((Object)(object)localPlayer == (Object)null))
			{
				instance.InvokeRoutedRPC(0L, "Icons_SetArmor", new object[2]
				{
					localPlayer.GetPlayerName(),
					own.Custom ? ToHex(own.Armor) : ""
				});
			}
		}

		internal static void Tick()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			string value = Plugin.IconArmorColor.Value;
			if (value != lastHex)
			{
				lastHex = value;
				own = Make(value);
				nextBroadcast = 0f;
				nextOwnApply = 0;
			}
			if ((Object)(object)Minimap.instance != (Object)null)
			{
				if (Time.frameCount >= nextOwnApply)
				{
					nextOwnApply = Time.frameCount + 4;
					if (own.Custom && Plugin.RecolorOwnArrow.Value)
					{
						MapAccess.RecolorOwn(own.Armor);
						ownApplied = true;
					}
					else if (ownApplied)
					{
						MapAccess.RestoreOwn();
						ownApplied = false;
					}
				}
				if (Others.Count > 0)
				{
					TintOthers();
				}
			}
			if ((Object)(object)Player.m_localPlayer != (Object)null && Time.time >= nextBroadcast)
			{
				nextBroadcast = Time.time + 10f;
				Broadcast();
			}
			if (Time.frameCount >= nextPrune)
			{
				nextPrune = Time.frameCount + 600;
				MapAccess.PruneOriginals();
			}
		}

		private static void TintOthers()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			List<PinData> list = MapAccess.Pins();
			if (list == null)
			{
				return;
			}
			for (int i = 0; i < list.Count; i++)
			{
				PinData val = list[i];
				if (val != null && (int)val.m_type == 10 && !string.IsNullOrEmpty(val.m_name) && !((Object)(object)val.m_uiElement == (Object)null) && Others.TryGetValue(val.m_name, out var value))
				{
					if (value.Custom)
					{
						MapAccess.RecolorImages((Transform)(object)val.m_uiElement, "teammate", value.Armor, armorOnly: true);
					}
					else
					{
						MapAccess.Restore((Transform)(object)val.m_uiElement);
					}
				}
			}
		}
	}
	internal static class ContainerRecipes
	{
		private static readonly FieldInfo FContainer = AccessTools.Field(typeof(InventoryGui), "m_currentContainer");

		private static readonly MethodInfo MIsKnownItem = AccessTools.Method(typeof(Player), "IsKnownItem", new Type[1] { typeof(ItemData) }, (Type[])null);

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

		private static bool warnedNoCheck;

		private static Container last;

		private static float nextCheck;

		internal static void Tick()
		{
			if (!Plugin.LearnFromContainers.Value || Time.unscaledTime < nextCheck)
			{
				return;
			}
			nextCheck = Time.unscaledTime + 0.5f;
			Player localPlayer = Player.m_localPlayer;
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null || FContainer == null || !InventoryGui.IsVisible())
			{
				last = null;
				return;
			}
			object? value = FContainer.GetValue(instance);
			Container val = (Container)((value is Container) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				last = null;
				return;
			}
			if ((Object)(object)val != (Object)(object)last)
			{
				last = val;
				Learned.Clear();
			}
			Inventory inventory = val.GetInventory();
			if (inventory == null)
			{
				return;
			}
			if (MIsKnownItem == null && !warnedNoCheck)
			{
				warnedNoCheck = true;
				Plugin.Log.LogWarning((object)"Icons: Player.IsKnownItem не найден — не могу проверить, известен ли рецепт уже, возможны повторные уведомления об изучении.");
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem != null && allItem.m_shared != null && Learned.Add(allItem.m_shared.m_name))
				{
					bool flag = false;
					if (MIsKnownItem != null)
					{
						object obj = MIsKnownItem.Invoke(localPlayer, new object[1] { allItem });
						flag = obj is bool && (bool)obj;
					}
					if (!flag)
					{
						localPlayer.AddKnownItem(allItem);
					}
				}
			}
		}
	}
	internal static class CookingHud
	{
		private const float ActiveWindow = 60f;

		private const float StationRadius = 3f;

		private static readonly Dictionary<CookingStation, float> Interacted = new Dictionary<CookingStation, float>();

		private static readonly List<CookingStation> Dead = new List<CookingStation>();

		private static readonly Collider[] Hits = (Collider[])(object)new Collider[16];

		internal static void OnInteract(CookingStation station, object user)
		{
			if (!((Object)(object)station == (Object)null))
			{
				Player val = (Player)((user is Player) ? user : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
				{
					Interacted[station] = Time.time + 60f;
				}
			}
		}

		internal static bool IsCooking(Vector3 pos)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (Interacted.Count == 0)
			{
				return false;
			}
			int num = Physics.OverlapSphereNonAlloc(pos, 3f, Hits);
			for (int i = 0; i < num; i++)
			{
				Collider val = Hits[i];
				if (!((Object)(object)val == (Object)null))
				{
					CookingStation componentInParent = ((Component)val).GetComponentInParent<CookingStation>();
					if (!((Object)(object)componentInParent == (Object)null) && Interacted.TryGetValue(componentInParent, out var value) && Time.time < value)
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static void Tick()
		{
			if (Interacted.Count == 0)
			{
				return;
			}
			Dead.Clear();
			foreach (KeyValuePair<CookingStation, float> item in Interacted)
			{
				if (Time.time >= item.Value)
				{
					Dead.Add(item.Key);
				}
			}
			for (int i = 0; i < Dead.Count; i++)
			{
				Interacted.Remove(Dead[i]);
			}
		}
	}
	internal static class DeathMessages
	{
		private const string RpcName = "Icons_Death";

		private const float HitMemorySeconds = 8f;

		private const float TreeCheckRadius = 3.5f;

		private const float TreeMinSpeed = 1.5f;

		private static string lastKind;

		private static string lastValue;

		private static float lastTime = -100f;

		internal static void Register(ZRoutedRpc rpc)
		{
			lastTime = -100f;
			rpc.Register<string, string>("Icons_Death", (Action<long, string, string>)RpcReceive);
		}

		private static bool NearFallingTree(Vector3 pos)
		{
			//IL_0000: 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)
			Collider[] array = Physics.OverlapSphere(pos, 3.5f);
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Transform val2 = ((Component)val).transform;
				bool flag = false;
				int num = 0;
				while (num < 5 && (Object)(object)val2 != (Object)null)
				{
					string name = ((Object)val2).name;
					if (name.IndexOf("Tree", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Log", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						flag = true;
						break;
					}
					num++;
					val2 = val2.parent;
				}
				if (!flag)
				{
					continue;
				}
				Rigidbody attachedRigidbody = val.attachedRigidbody;
				if ((Object)(object)attachedRigidbody != (Object)null && !attachedRigidbody.IsSleeping())
				{
					Vector3 linearVelocity = attachedRigidbody.linearVelocity;
					if (((Vector3)(ref linearVelocity)).sqrMagnitude >= 2.25f)
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static void OnDamage(Character target, HitData hit)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.DeathChatMessages.Value || (Object)(object)target == (Object)null || hit == null || (Object)(object)target != (Object)(object)Player.m_localPlayer || hit.GetTotalDamage() <= 0f)
			{
				return;
			}
			Character attacker = hit.GetAttacker();
			if ((Object)(object)attacker != (Object)null)
			{
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				if ((Object)(object)val != (Object)null)
				{
					lastKind = "player";
					lastValue = val.GetPlayerName();
				}
				else
				{
					lastKind = "mob";
					lastValue = attacker.m_name;
				}
			}
			else if (NearFallingTree(((Component)target).transform.position))
			{
				lastKind = "tree";
				lastValue = "";
			}
			else
			{
				lastKind = "hit";
				lastValue = ((object)Unsafe.As<HitType, HitType>(ref hit.m_hitType)/*cast due to .constrained prefix*/).ToString();
			}
			lastTime = Time.time;
		}

		internal static void OnPlayerDeath(Player player)
		{
			if (Plugin.DeathChatMessages.Value && !((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer))
			{
				string text = "hit";
				string text2 = "Undefined";
				if (Time.time - lastTime <= 8f && lastKind != null)
				{
					text = lastKind;
					text2 = lastValue;
				}
				lastTime = -100f;
				ZRoutedRpc instance = ZRoutedRpc.instance;
				if (instance != null)
				{
					instance.InvokeRoutedRPC(0L, "Icons_Death", new object[2]
					{
						player.GetPlayerName(),
						text + "|" + text2
					});
				}
			}
		}

		private static void RpcReceive(long sender, string playerName, string payload)
		{
			if (string.IsNullOrEmpty(playerName) || string.IsNullOrEmpty(payload) || payload.Length > 200)
			{
				return;
			}
			int num = payload.IndexOf('|');
			if (num <= 0)
			{
				return;
			}
			string text = payload.Substring(0, num);
			string text2 = payload.Substring(num + 1);
			if (text == "tree")
			{
				if ((Object)(object)Chat.instance != (Object)null)
				{
					((Terminal)Chat.instance).AddString(string.Format(Loc.T("death.tree"), playerName));
				}
				return;
			}
			string text3 = "m";
			string text4;
			if (text == "mob")
			{
				text4 = ((Localization.instance != null) ? Localization.instance.Localize(text2) : text2);
			}
			else if (text == "player")
			{
				text4 = text2;
			}
			else
			{
				if (!Loc.TryGet("death.hit." + text2, out var value))
				{
					value = Loc.T("death.hit.Undefined");
				}
				string[] array = value.Split(new char[1] { '|' });
				text4 = array[0];
				if (array.Length > 1)
				{
					text3 = array[1];
				}
			}
			string text5 = Loc.T("death.verb." + text3);
			string text6 = text4 + " " + text5 + " " + playerName;
			if ((Object)(object)Chat.instance != (Object)null)
			{
				((Terminal)Chat.instance).AddString(text6);
			}
		}
	}
	internal sealed class HudContext
	{
		public Camera Cam;

		public Player Player;

		public Vector3 PlayerPos;

		public Rect PlayerRect;

		public bool HasPlayerRect;
	}
	internal static class HudMarkers
	{
		private sealed class Marker
		{
			public RectTransform Rt;

			public Image Icon;

			public Text Label;

			public Outline Outline;

			public string LastLabel;
		}

		private static readonly HudContext Shared = new HudContext();

		private static readonly List<Marker> Pool = new List<Marker>();

		private static GameObject overlayGo;

		private static RectTransform overlayRoot;

		private static GameObject depthGo;

		private static Canvas depthCanvas;

		private static RectTransform depthRoot;

		private static int used;

		internal static HudContext Ctx;

		internal static void Tick()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Ctx = BuildContext();
			if (Ctx == null)
			{
				HideFrom(0);
				return;
			}
			EnsureCanvas();
			if (Plugin.BehindPlayer.Value)
			{
				Camera cam = Ctx.Cam;
				float z = ((Component)cam).transform.InverseTransformPoint(Ctx.PlayerPos).z;
				depthCanvas.worldCamera = cam;
				depthCanvas.planeDistance = Mathf.Clamp(z + 0.35f, cam.nearClipPlane + 0.05f, cam.farClipPlane - 1f);
			}
			used = 0;
			TrackedPins.Collect(Ctx);
			TempMarks.Collect(Ctx);
			TeamHud.Collect(Ctx);
			HideFrom(used);
		}

		private static HudContext BuildContext()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			Camera main = Camera.main;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)main == (Object)null)
			{
				return null;
			}
			if (MapAccess.IsMapOpen() || MapAccess.HudHiddenByUser() || ((Character)localPlayer).IsDead() || MapAccess.AnyWindowOpen())
			{
				return null;
			}
			HudContext shared = Shared;
			shared.Cam = main;
			shared.Player = localPlayer;
			shared.PlayerPos = ((Component)localPlayer).transform.position;
			shared.HasPlayerRect = PlayerScreenRect(main, shared.PlayerPos, out shared.PlayerRect);
			return shared;
		}

		private static bool PlayerScreenRect(Camera cam, Vector3 playerPos, out Rect rect)
		{
			//IL_0001: 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_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)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0081: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			rect = default(Rect);
			Vector3 val = cam.WorldToScreenPoint(playerPos);
			Vector3 val2 = cam.WorldToScreenPoint(playerPos + Vector3.up * 2.1f);
			if (val.z <= 0.1f || val2.z <= 0.1f)
			{
				return false;
			}
			float num = Mathf.Abs(val2.y - val.y);
			float num2 = Mathf.Max(num * 0.6f, 20f);
			rect = Rect.MinMaxRect(val.x - num2 * 0.5f, Mathf.Min(val.y, val2.y) - num * 0.1f, val.x + num2 * 0.5f, Mathf.Max(val.y, val2.y) + num * 0.1f);
			return true;
		}

		private static GameObject NewCanvas(string name, RenderMode mode, out Canvas canvas)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			Object.DontDestroyOnLoad((Object)(object)val);
			canvas = val.AddComponent<Canvas>();
			canvas.renderMode = mode;
			canvas.sortingOrder = 100;
			CanvasScaler obj = val.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)0;
			obj.scaleFactor = 1f;
			return val;
		}

		private static void EnsureCanvas()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			if (!((Object)(object)overlayGo != (Object)null))
			{
				overlayGo = NewCanvas("Icons_HudMarkers", (RenderMode)0, out var _);
				overlayRoot = (RectTransform)overlayGo.transform;
				depthGo = NewCanvas("Icons_HudMarkers_Depth", (RenderMode)1, out depthCanvas);
				depthRoot = (RectTransform)depthGo.transform;
				Pool.Clear();
			}
		}

		private static Marker Get(int index)
		{
			while (Pool.Count <= index)
			{
				Pool.Add(Create());
			}
			return Pool[index];
		}

		private static Marker Create()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0047: Expected O, but got Unknown
			//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_0068: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Marker", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent((Transform)(object)overlayRoot, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.zero;
			val2.pivot = new Vector2(0.5f, 0.5f);
			Image component = val.GetComponent<Image>();
			((Graphic)component).raycastTarget = false;
			component.preserveAspect = true;
			Text val3 = UiUtil.MakeText(val.transform, "Label", "", 13, (TextAnchor)1, Color.white);
			RectTransform rectTransform = ((Graphic)val3).rectTransform;
			rectTransform.anchorMin = new Vector2(0.5f, 0f);
			rectTransform.anchorMax = new Vector2(0.5f, 0f);
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.sizeDelta = new Vector2(260f, 20f);
			rectTransform.anchoredPosition = new Vector2(0f, -2f);
			Outline outline = UiUtil.AddOutline(val3);
			return new Marker
			{
				Rt = val2,
				Icon = component,
				Label = val3,
				Outline = outline
			};
		}

		private static void HideFrom(int from)
		{
			for (int i = from; i < Pool.Count; i++)
			{
				GameObject gameObject = ((Component)Pool[i].Rt).gameObject;
				if (gameObject.activeSelf)
				{
					gameObject.SetActive(false);
				}
			}
		}

		internal static void Add(HudContext c, Sprite icon, Color color, float size, Vector3 world, string label, bool clamp)
		{
			//IL_0051: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)icon == (Object)null)
			{
				return;
			}
			bool flag = !string.IsNullOrEmpty(label);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor((float)Screen.width * 0.5f, (float)Screen.height * 0.5f);
			float num = size * 0.5f + (flag ? 28f : 6f);
			float halfW = Mathf.Max(1f, val.x - num);
			float halfH = Mathf.Max(1f, val.y - num);
			if (UiUtil.ProjectToScreen(c.Cam, world, halfW, halfH, clamp, out var pos))
			{
				Rect val2 = Rect.MinMaxRect(pos.x - size * 0.5f, pos.y - size * 0.5f - (flag ? 22f : 0f), pos.x + size * 0.5f, pos.y + size * 0.5f);
				Marker marker = Get(used++);
				if (!((Component)marker.Rt).gameObject.activeSelf)
				{
					((Component)marker.Rt).gameObject.SetActive(true);
				}
				RectTransform val3 = ((Plugin.BehindPlayer.Value && c.HasPlayerRect && ((Rect)(ref c.PlayerRect)).Overlaps(val2)) ? depthRoot : overlayRoot);
				if ((Object)(object)((Transform)marker.Rt).parent != (Object)(object)val3)
				{
					((Transform)marker.Rt).SetParent((Transform)(object)val3, false);
				}
				marker.Rt.anchoredPosition = pos;
				marker.Rt.sizeDelta = new Vector2(size, size);
				if ((Object)(object)marker.Icon.sprite != (Object)(object)icon)
				{
					marker.Icon.sprite = icon;
				}
				((Graphic)marker.Icon).color = color;
				string text = (flag ? label : "");
				if (marker.LastLabel != text)
				{
					marker.LastLabel = text;
					marker.Label.text = text;
				}
				((Graphic)marker.Label).color = new Color(1f, 1f, 1f, color.a);
				((Shadow)marker.Outline).effectColor = new Color(0f, 0f, 0f, color.a);
			}
		}
	}
	internal static class IconDraw
	{
		private static readonly Dictionary<string, Sprite> Cache = new Dictionary<string, Sprite>();

		private static bool Disk(float x, float y, float cx, float cy, float r)
		{
			float num = x - cx;
			float num2 = y - cy;
			return num * num + num2 * num2 <= r * r;
		}

		private static Sprite Make(string key, Func<float, float, bool> shape)
		{
			//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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_012e: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if (Cache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Color32[] array = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = 0;
					for (int k = 0; k < 2; k++)
					{
						for (int l = 0; l < 2; l++)
						{
							if (shape(((float)j + ((float)l + 0.5f) * 0.5f) / 64f, ((float)i + ((float)k + 0.5f) * 0.5f) / 64f))
							{
								num++;
							}
						}
					}
					array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(num * 255 / 4));
				}
			}
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1
			};
			val.SetPixels32(array);
			val.Apply();
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
			Cache[key] = val2;
			return val2;
		}

		internal static Sprite Ship()
		{
			return Make("ship", delegate(float x, float y)
			{
				if (y >= 0.1875f && y <= 0.375f)
				{
					float num = Mathf.Lerp(0.234f, 0.406f, (y - 0.1875f) / 0.1875f);
					if (Mathf.Abs(x - 0.5f) <= num)
					{
						return true;
					}
				}
				if (x >= 0.484f && x <= 0.516f && y > 0.375f && y <= 0.875f)
				{
					return true;
				}
				if (y >= 0.4375f && y <= 0.8125f)
				{
					float num2 = (0.8125f - y) * 0.62f;
					if (x >= 0.547f && x <= 0.547f + num2)
					{
						return true;
					}
				}
				return false;
			});
		}

		internal static Sprite Circle()
		{
			return Make("circle", delegate(float x, float y)
			{
				float num = x - 0.5f;
				float num2 = y - 0.5f;
				float num3 = Mathf.Sqrt(num * num + num2 * num2);
				return (num3 <= 0.44f && num3 >= 0.3f) || num3 <= 0.15f;
			});
		}

		internal static Sprite Skull()
		{
			return Make("skull", delegate(float x, float y)
			{
				bool num = Disk(x, y, 0.5f, 0.58f, 0.32f);
				bool flag = x >= 0.34f && x <= 0.66f && y >= 0.14f && y <= 0.36f;
				if (!num && !flag)
				{
					return false;
				}
				if (Disk(x, y, 0.375f, 0.6f, 0.085f) || Disk(x, y, 0.625f, 0.6f, 0.085f))
				{
					return false;
				}
				if (y >= 0.38f && y <= 0.5f && Mathf.Abs(x - 0.5f) <= (0.5f - y) * 0.5f)
				{
					return false;
				}
				return (!(y <= 0.3f) || (!(Mathf.Abs(x - 0.42f) < 0.012f) && !(Mathf.Abs(x - 0.5f) < 0.012f) && !(Mathf.Abs(x - 0.58f) < 0.012f))) ? true : false;
			});
		}

		internal static Sprite Person()
		{
			return Make("person", delegate(float x, float y)
			{
				if (Disk(x, y, 0.5f, 0.74f, 0.15f))
				{
					return true;
				}
				float num = (x - 0.5f) / 0.3f;
				float num2 = (y - 0.12f) / 0.42f;
				return y >= 0.12f && num * num + num2 * num2 <= 1f;
			});
		}

		internal static Sprite Sword()
		{
			return Make("sword", delegate(float x, float y)
			{
				float num = (x + y) * 0.5f;
				float num2 = x - y;
				if (num >= 0.36f && num <= 0.92f)
				{
					float num3 = 0.065f;
					if (num > 0.8f)
					{
						num3 *= (0.92f - num) / 0.12f * 0.6f + 0.4f;
					}
					if (Mathf.Abs(num2) <= num3)
					{
						return true;
					}
				}
				if (Mathf.Abs(num - 0.33f) <= 0.035f && Mathf.Abs(num2) <= 0.24f)
				{
					return true;
				}
				return (num >= 0.17f && num <= 0.3f && Mathf.Abs(num2) <= 0.045f) || Disk(x, y, 0.14f, 0.14f, 0.055f);
			});
		}

		internal static Sprite Moon()
		{
			return Make("moon", (float x, float y) => Disk(x, y, 0.5f, 0.5f, 0.38f) && !Disk(x, y, 0.66f, 0.58f, 0.32f));
		}

		internal static Sprite Disc()
		{
			return Make("disc", (float x, float y) => Disk(x, y, 0.5f, 0.5f, 0.47f));
		}

		internal static Sprite Ring()
		{
			return Make("ring", delegate(float x, float y)
			{
				float num = x - 0.5f;
				float num2 = y - 0.5f;
				float num3 = Mathf.Sqrt(num * num + num2 * num2);
				return num3 <= 0.5f && num3 >= 0.4f;
			});
		}

		internal static Sprite Zzz()
		{
			return Make("zzz", delegate(float x, float y)
			{
				bool num = ZLetter(x, y, 0.16f, 0.62f, 0.3f);
				bool flag = ZLetter(x, y, 0.4f, 0.4f, 0.22f);
				bool flag2 = ZLetter(x, y, 0.58f, 0.2f, 0.16f);
				return num || flag || flag2;
			});
		}

		private static bool ZLetter(float x, float y, float cx, float cy, float s)
		{
			float num = (x - cx) / s;
			float num2 = (y - cy) / s;
			if (num2 < -0.5f || num2 > 0.5f || num < -0.5f || num > 0.5f)
			{
				return false;
			}
			float num3 = 0.12f;
			if (Mathf.Abs(num2 - 0.5f) <= num3)
			{
				return true;
			}
			if (Mathf.Abs(num2 + 0.5f) <= num3)
			{
				return true;
			}
			return Mathf.Abs(num - num2) <= num3 * 1.4f;
		}

		internal static Sprite ChefHat()
		{
			return Make("chefhat", delegate(float x, float y)
			{
				bool num = Disk(x, y, 0.32f, 0.72f, 0.2f) || Disk(x, y, 0.5f, 0.8f, 0.22f) || Disk(x, y, 0.68f, 0.72f, 0.2f);
				bool flag = y >= 0.5f && y <= 0.74f && x >= 0.28f && x <= 0.72f;
				bool flag2 = y >= 0.3f && y <= 0.5f && x >= 0.24f && x <= 0.76f;
				return num || flag || flag2;
			});
		}

		internal static Sprite Hammer()
		{
			return Make("hammer", delegate(float x, float y)
			{
				if (Mathf.Abs(x - 0.504f) <= 0.16f && Mathf.Abs(y - 0.806f) <= 0.06f)
				{
					return true;
				}
				if (Mathf.Abs(x - 0.5f) <= 0.045f && Mathf.Abs(y - 0.575f) <= 0.265f)
				{
					return true;
				}
				if (Mathf.Abs(x - 0.323f) <= 0.075f && Mathf.Abs(y - 0.805f) <= 0.07f)
				{
					return true;
				}
				return (Mathf.Abs(x - 0.676f) <= 0.075f && Mathf.Abs(y - 0.805f) <= 0.07f) ? true : false;
			});
		}

		internal static Sprite Pickaxe()
		{
			return Make("pickaxe", delegate(float x, float y)
			{
				float num = x - 0.664f;
				float num2 = y - 0.714f;
				float num3 = num * 0.819f - num2 * 0.574f;
				float num4 = num * 0.574f + num2 * 0.819f;
				if (Mathf.Abs(num3) <= 0.26f && Mathf.Abs(num4) <= 0.04f)
				{
					return true;
				}
				float num5 = x - 0.469f;
				float num6 = y - 0.422f;
				float num7 = num5 * 0.574f - num6 * -0.819f;
				float num8 = num5 * -0.819f + num6 * 0.574f;
				if (Mathf.Abs(num7) <= 0.37f && Mathf.Abs(num8) <= 0.06f)
				{
					return true;
				}
				float num9 = x - 0.424f;
				float num10 = y - 0.831f;
				float num11 = num9 * 0.819f - num10 * 0.574f;
				float num12 = num9 * 0.574f + num10 * 0.819f;
				if (Mathf.Abs(num11) <= 0.09f && Mathf.Abs(num12) <= 0.04f)
				{
					return true;
				}
				float num13 = x - 0.862f;
				float num14 = y - 0.52f;
				float num15 = num13 * 0.819f - num14 * 0.574f;
				float num16 = num13 * 0.574f + num14 * 0.819f;
				return (Mathf.Abs(num15) <= 0.09f && Mathf.Abs(num16) <= 0.04f) ? true : false;
			});
		}

		internal static Sprite Fish()
		{
			return Make("fish", delegate(float x, float y)
			{
				float num = (x - 0.42f) / 0.3f;
				float num2 = (y - 0.5f) / 0.18f;
				bool num3 = num * num + num2 * num2 <= 1f && x <= 0.66f;
				bool flag = x >= 0.64f && x <= 0.86f && Mathf.Abs(y - 0.5f) <= (x - 0.64f) * 0.9f;
				bool flag2 = Disk(x, y, 0.32f, 0.54f, 0.03f);
				return (num3 && !flag2) || flag;
			});
		}

		internal static Sprite AxeIcon()
		{
			return Make("axeicon", delegate(float x, float y)
			{
				float num = x - 0.58f;
				float num2 = y - 0.601f;
				float num3 = num * 0.707f - num2 * 0.707f;
				float num4 = num * 0.707f + num2 * 0.707f;
				if (Mathf.Abs(num3) <= 0.22f && Mathf.Abs(num4) <= 0.15f)
				{
					return true;
				}
				float num5 = x - 0.5f;
				float num6 = y - 0.34f;
				float num7 = num5 * 0.707f - num6 * -0.707f;
				float num8 = num5 * -0.707f + num6 * 0.707f;
				if (Mathf.Abs(num7) <= 0.375f && Mathf.Abs(num8) <= 0.05f)
				{
					return true;
				}
				float num9 = x - 0.494f;
				float num10 = y - 0.605f;
				float num11 = num9 * 0.866f - num10 * 0.5f;
				float num12 = num9 * 0.5f + num10 * 0.866f;
				if (Mathf.Abs(num11) <= 0.2f && Mathf.Abs(num12) <= 0.1f)
				{
					return true;
				}
				float num13 = x - 0.566f;
				float num14 = y - 0.686f;
				float num15 = num13 * 0.588f - num14 * 0.809f;
				float num16 = num13 * 0.809f + num14 * 0.588f;
				return (Mathf.Abs(num15) <= 0.2f && Mathf.Abs(num16) <= 0.1f) ? true : false;
			});
		}

		internal static Sprite Cross()
		{
			return Make("cross", delegate(float x, float y)
			{
				float num = x - y;
				float num2 = x + y - 1f;
				return Mathf.Abs(num) <= 0.1f || Mathf.Abs(num2) <= 0.1f;
			});
		}

		internal static Sprite Weight()
		{
			return Make("weight", delegate(float x, float y)
			{
				if (y >= 0.1f && y <= 0.6f)
				{
					float num = Mathf.Lerp(0.38f, 0.26f, (y - 0.1f) / 0.5f);
					if (Mathf.Abs(x - 0.5f) <= num)
					{
						return true;
					}
				}
				float num2 = x - 0.5f;
				float num3 = y - 0.66f;
				float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
				return y >= 0.58f && num4 >= 0.13f && num4 <= 0.22f;
			});
		}
	}
	internal static class IntroButton
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__ToggleIntro;
		}

		private static GameObject buttonObject;

		private static TMP_Text buttonText;

		internal static void Create(FejdStartup startup)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			if ((Object)(object)startup == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)buttonObject != (Object)null)
				{
					return;
				}
				GameObject mainMenu = startup.m_mainMenu;
				if ((Object)(object)mainMenu == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Icons: m_mainMenu не найден.");
					return;
				}
				Button val = FindSourceButton(mainMenu);
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Icons: не удалось найти кнопку для копирования.");
					return;
				}
				buttonObject = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent);
				((Object)buttonObject).name = "Icons_IntroButton";
				buttonObject.transform.SetSiblingIndex(0);
				EventTrigger component = buttonObject.GetComponent<EventTrigger>();
				if ((Object)(object)component != (Object)null)
				{
					component.triggers.Clear();
				}
				Button component2 = buttonObject.GetComponent<Button>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.onClick = new ButtonClickedEvent();
					ButtonClickedEvent onClick = component2.onClick;
					object obj = <>O.<0>__ToggleIntro;
					if (obj == null)
					{
						UnityAction val2 = ToggleIntro;
						<>O.<0>__ToggleIntro = val2;
						obj = (object)val2;
					}
					((UnityEvent)onClick).AddListener((UnityAction)obj);
				}
				buttonText = buttonObject.GetComponentInChildren<TMP_Text>(true);
				if ((Object)(object)buttonText == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Icons: у скопированной кнопки не найден TMP_Text.");
					return;
				}
				buttonText.text = GetIntroText();
				UpdateVisual();
				Plugin.Log.LogInfo((object)"Icons: кнопка ИНТРО добавлена в главное меню.");
			}
			catch (Exception ex)
			{
				Plugin.ReportOnce("IntroButton", ex);
			}
		}

		private static Button FindSourceButton(GameObject mainMenu)
		{
			Button[] componentsInChildren = mainMenu.GetComponentsInChildren<Button>(true);
			foreach (Button val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				TMP_Text componentInChildren = ((Component)val).GetComponentInChildren<TMP_Text>(true);
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					string text = componentInChildren.text.Trim();
					Plugin.Log.LogInfo((object)("Icons: найден текст кнопки: [" + text + "]"));
					if (text.Equals("Show player.log", StringComparison.OrdinalIgnoreCase))
					{
						return val;
					}
				}
			}
			return null;
		}

		private static void ToggleIntro()
		{
			Plugin.SkipIntro.Value = !Plugin.SkipIntro.Value;
			UpdateVisual();
			Plugin.Log.LogInfo((object)("Icons: SkipIntro = " + Plugin.SkipIntro.Value));
		}

		private static void UpdateVisual()
		{
			//IL_0052: 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)
			if (!((Object)(object)buttonText == (Object)null))
			{
				buttonText.text = GetIntroText();
				if (Plugin.SkipIntro.Value)
				{
					((Graphic)buttonText).color = new Color(0.45f, 0.45f, 0.45f, 1f);
				}
				else
				{
					((Graphic)buttonText).color = Color.white;
				}
			}
		}

		private static string GetIntroText()
		{
			try
			{
				if (Localization.instance != null && Localization.instance.GetSelectedLanguage().Equals("Russian", StringComparison.OrdinalIgnoreCase))
				{
					return "ИНТРО";
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Icons: не удалось определить язык: " + ex.Message));
			}
			return "INTRO";
		}
	}
	internal static class IntroSkip
	{
		internal static void Apply(FejdStartup instance)
		{
			if (!Plugin.SkipIntro.Value || (Object)(object)instance == (Object)null)
			{
				return;
			}
			try
			{
				CinematicsManager s_instance = CinematicsManager.s_instance;
				if ((Object)(object)s_instance == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Icons: CinematicsManager не найден.");
					return;
				}
				s_instance.m_introOnStartup = false;
				Plugin.Log.LogInfo((object)"Icons: стартовое интро отключено.");
			}
			catch (Exception ex)
			{
				Plugin.ReportOnce("IntroSkip", ex);
			}
		}
	}
	internal static class Loc
	{
		private static readonly Dictionary<string, string> Ru = new Dictionary<string, string>
		{
			{ "msg.shown", "Маршрутные метки: показаны" },
			{ "msg.hidden", "Маршрутные метки: скрыты" },
			{ "msg.pinTracked", "Метка стала маршрутной" },
			{ "msg.pinUntracked", "Метка стала обычной" },
			{ "msg.markPlaced", "Временная метка поставлена" },
			{ "msg.noAim", "Не удалось определить точку прицеливания" },
			{ "ship.default", "Корабль" },
			{ "bed.default", "Кровать" },
			{ "unit.m", "м" },
			{ "unit.km", "км" },
			{ "death.tree", "Дерево проникло в {0}" },
			{ "death.verb.m", "унизил" },
			{ "death.verb.f", "унизила" },
			{ "death.verb.n", "унизило" },
			{ "death.hit.Fall", "Гравитация|f" },
			{ "death.hit.Drowning", "Вода|f" },
			{ "death.hit.Water", "Вода|f" },
			{ "death.hit.Burning", "Огонь|m" },
			{ "death.hit.Freezing", "Мороз|m" },
			{ "death.hit.Poisoned", "Яд|m" },
			{ "death.hit.Smoke", "Дым|m" },
			{ "death.hit.EdgeOfWorld", "Край мира|m" },
			{ "death.hit.Impact", "Удар|m" },
			{ "death.hit.Cart", "Телега|f" },
			{ "death.hit.Boat", "Лодка|f" },
			{ "death.hit.Structural", "Обрушение|n" },
			{ "death.hit.Stalagtite", "Сталактит|m" },
			{ "death.hit.Turret", "Турель|f" },
			{ "death.hit.Catapult", "Катапульта|f" },
			{ "death.hit.Self", "Самоубийство|n" },
			{ "death.hit.Undefined", "Неведомая сила|f" },
			{ "log.loaded", "Мод Icons загружен." },
			{ "log.patchMissing", "Не найден метод для патча: " },
			{ "log.patchFailed", "Не удалось применить патч: " },
			{ "log.fieldMissing", "Не найдено поле игры (изменился API?): " },
			{ "log.error", "Ошибка в модуле: " },
			{ "log.saveFailed", "Не удалось сохранить маршрутные метки: " },
			{ "log.loadFailed", "Не удалось прочитать маршрутные метки: " },
			{ "log.shipsSaveFailed", "Не удалось сохранить метки кораблей: " },
			{ "log.shipsLoadFailed", "Не удалось прочитать метки кораблей: " },
			{ "log.iconParts", "Структура значка " },
			{ "log.panelFallback", "Не удалось найти колонку иконок на карте — панель цветов поставлена в запасное место. Подстройте PanelOffsetX/PanelOffsetY в конфиге." }
		};

		private static readonly Dictionary<string, string> En = new Dictionary<string, string>
		{
			{ "msg.shown", "Tracked pins: shown" },
			{ "msg.hidden", "Tracked pins: hidden" },
			{ "msg.pinTracked", "Pin is now tracked" },
			{ "msg.pinUntracked", "Pin is now a normal pin" },
			{ "msg.markPlaced", "Temporary marker placed" },
			{ "msg.noAim", "Could not find an aim point" },
			{ "ship.default", "Ship" },
			{ "bed.default", "Bed" },
			{ "unit.m", "m" },
			{ "unit.km", "km" },
			{ "death.tree", "A tree penetrated {0}" },
			{ "death.verb.m", "humiliated" },
			{ "death.verb.f", "humiliated" },
			{ "death.verb.n", "humiliated" },
			{ "death.hit.Fall", "Gravity|m" },
			{ "death.hit.Drowning", "Water|m" },
			{ "death.hit.Water", "Water|m" },
			{ "death.hit.Burning", "Fire|m" },
			{ "death.hit.Freezing", "Frost|m" },
			{ "death.hit.Poisoned", "Poison|m" },
			{ "death.hit.Smoke", "Smoke|m" },
			{ "death.hit.EdgeOfWorld", "The edge of the world|m" },
			{ "death.hit.Impact", "An impact|m" },
			{ "death.hit.Cart", "A cart|m" },
			{ "death.hit.Boat", "A boat|m" },
			{ "death.hit.Structural", "A collapse|m" },
			{ "death.hit.Stalagtite", "A stalactite|m" },
			{ "death.hit.Turret", "A turret|m" },
			{ "death.hit.Catapult", "A catapult|m" },
			{ "death.hit.Self", "Their own hand|m" },
			{ "death.hit.Undefined", "An unknown force|m" },
			{ "log.loaded", "Icons mod loaded." },
			{ "log.patchMissing", "Patch target method not found: " },
			{ "log.patchFailed", "Failed to apply patch: " },
			{ "log.fieldMissing", "Game field not found (API changed?): " },
			{ "log.error", "Error in module: " },
			{ "log.saveFailed", "Failed to save tracked pins: " },
			{ "log.loadFailed", "Failed to read tracked pins: " },
			{ "log.shipsSaveFailed", "Failed to save ship markers: " },
			{ "log.shipsLoadFailed", "Failed to read ship markers: " },
			{ "log.iconParts", "Icon structure " },
			{ "log.panelFallback", "Could not find the pin-icon column on the map — the color panel uses a fallback position. Adjust PanelOffsetX/PanelOffsetY in the config." }
		};

		public static bool IsRussian()
		{
			switch (Plugin.LanguageSetting.Value)
			{
			case LanguageMode.Russian:
				return true;
			case LanguageMode.English:
				return false;
			default:
				try
				{
					Localization instance = Localization.instance;
					if (instance != null)
					{
						return instance.GetSelectedLanguage() == "Russian";
					}
				}
				catch
				{
				}
				return false;
			}
		}

		public static bool TryGet(string key, out string value)
		{
			return (IsRussian() ? Ru : En).TryGetValue(key, out value);
		}

		public static string T(string key)
		{
			if (!TryGet(key, out var value))
			{
				return key;
			}
			return value;
		}
	}
	internal static class MapAccess
	{
		private struct Orig
		{
			public Color Color;

			public Sprite Sprite;
		}

		private static readonly FieldInfo FPins = AccessTools.Field(typeof(Minimap), "m_pins");

		private static readonly FieldInfo FLargeRoot = AccessTools.Field(typeof(Minimap), "m_largeRoot");

		private static readonly FieldInfo FSmallRoot = AccessTools.Field(typeof(Minimap), "m_smallRoot");

		private static readonly FieldInfo FSelectedType = AccessTools.Field(typeof(Minimap), "m_selectedType");

		private static readonly FieldInfo FUserHidden = AccessTools.Field(typeof(Hud), "m_userHidden");

		private static readonly string[] MarkerNames = new string[4] { "m_smallMarker", "m_largeMarker", "m_smallShipMarker", "m_largeShipMarker" };

		private static readonly FieldInfo[] FMarkers = BuildMarkerFields();

		private static readonly Dictionary<Image, Orig> Originals = new Dictionary<Image, Orig>();

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

		private static FieldInfo[] BuildMarkerFields()
		{
			List<FieldInfo> list = new List<FieldInfo>();
			string[] markerNames = MarkerNames;
			foreach (string text in markerNames)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(Minimap), text);
				if (fieldInfo != null)
				{
					list.Add(fieldInfo);
				}
			}
			return list.ToArray();
		}

		internal static void CheckFields()
		{
			Warn(FPins, "Minimap.m_pins");
			Warn(FLargeRoot, "Minimap.m_largeRoot");
			Warn(FSmallRoot, "Minimap.m_smallRoot");
			Warn(FSelectedType, "Minimap.m_selectedType");
			if (FMarkers.Length < 2)
			{
				Plugin.Log.LogWarning((object)(Loc.T("log.fieldMissing") + "Minimap.m_smallMarker/m_largeMarker"));
			}
		}

		private static void Warn(FieldInfo f, string name)
		{
			if (f == null)
			{
				Plugin.Log.LogWarning((object)(Loc.T("log.fieldMissing") + name));
			}
		}

		internal static List<PinData> Pins()
		{
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null || FPins == null)
			{
				return null;
			}
			return FPins.GetValue(instance) as List<PinData>;
		}

		internal static GameObject LargeRoot()
		{
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null || FLargeRoot == null)
			{
				return null;
			}
			object? value = FLargeRoot.GetValue(instance);
			return (GameObject)((value is GameObject) ? value : null);
		}

		internal static GameObject SmallRoot()
		{
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null || FSmallRoot == null)
			{
				return null;
			}
			object? value = FSmallRoot.GetValue(instance);
			return (GameObject)((value is GameObject) ? value : null);
		}

		internal static bool IsMapOpen()
		{
			GameObject val = LargeRoot();
			if ((Object)(object)val != (Object)null)
			{
				return val.activeInHierarchy;
			}
			return false;
		}

		internal static PinType SelectedPinType()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance != (Object)null && FSelectedType != null)
			{
				object value = FSelectedType.GetValue(instance);
				if (value is PinType)
				{
					return (PinType)value;
				}
			}
			return (PinType)3;
		}

		internal static Rect SmallMapScreenRect()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = SmallRoot();
			RectTransform val2 = (RectTransform)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val2 != (Object)null)
			{
				Rect result = UiUtil.ScreenRect(val2);
				if (((Rect)(ref result)).width > 40f && ((Rect)(ref result)).height > 40f && ((Rect)(ref result)).width < (float)Screen.width * 0.5f && ((Rect)(ref result)).height < (float)Screen.height * 0.6f)
				{
					return result;
				}
			}
			float num = (float)Screen.height / 1080f;
			float num2 = (float)Screen.width - 12f * num;
			float num3 = (float)Screen.height - 12f * num;
			return Rect.MinMaxRect(num2 - 250f * num, num3 - 250f * num, num2, num3);
		}

		internal static bool HudHiddenByUser()
		{
			if (FUserHidden == null)
			{
				return false;
			}
			object obj = null;
			if (!FUserHidden.IsStatic)
			{
				if ((Object)(object)Hud.instance == (Object)null)
				{
					return false;
				}
				obj = Hud.instance;
			}
			object value = FUserHidden.GetValue(obj);
			if (value is bool)
			{
				return (bool)value;
			}
			return false;
		}

		internal static bool AnyWindowOpen()
		{
			if (!InventoryGui.IsVisible() && !Menu.IsVisible() && !StoreGui.IsVisible())
			{
				return TextInput.IsVisible();
			}
			return true;
		}

		internal static string SaveKey()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				return null;
			}
			return Sanitize(ZNet.instance.GetWorldName() + "_" + localPlayer.GetPlayerName());
		}

		internal static string Sanitize(string s)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char oldChar in invalidFileNameChars)
			{
				s = s.Replace(oldChar, '_');
			}
			return s;
		}

		internal static string DataPath(string key, string suffix)
		{
			return Path.Combine(Path.Combine(Paths.ConfigPath, "Icons"), key + suffix);
		}

		internal static void SetOwnArrowScale()
		{
			//IL_0058: 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)
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			for (int i = 0; i < FMarkers.Length; i++)
			{
				string name = FMarkers[i].Name;
				if (!(name != "m_smallMarker") || !(name != "m_largeMarker"))
				{
					object? value = FMarkers[i].GetValue(instance);
					RectTransform val = (RectTransform)((value is RectTransform) ? value : null);
					if (!((Object)(object)val == (Object)null))
					{
						((Transform)val).localScale = Vector3.one * 0.7f;
					}
				}
			}
		}

		internal static List<RectTransform> MarkerRects()
		{
			List<RectTransform> list = new List<RectTransform>();
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return list;
			}
			for (int i = 0; i < FMarkers.Length; i++)
			{
				object? value = FMarkers[i].GetValue(instance);
				RectTransform val = (RectTransform)((value is RectTransform) ? value : null);
				if ((Object)(object)val != (Object)null)
				{
					list.Add(val);
				}
			}
			return list;
		}

		private static bool IsCheckImage(Image img)
		{
			return ((Object)((Component)img).gameObject).name.IndexOf("check", StringComparison.OrdinalIgnoreCase) >= 0;
		}

		internal static void RecolorImages(Transform root, string tag, Color color, bool armorOnly)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00f4: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true);
			LogStructure(tag, componentsInChildren);
			foreach (Image val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || IsCheckImage(val))
				{
					continue;
				}
				if (!Originals.TryGetValue(val, out var value))
				{
					value = new Orig
					{
						Color = ((Graphic)val).color,
						Sprite = val.sprite
					};
					Originals[val] = value;
				}
				if ((Object)(object)value.Sprite == (Object)null)
				{
					continue;
				}
				Sprite val2 = (armorOnly ? SpriteRecolor.Armor(value.Sprite, color) : SpriteRecolor.Full(value.Sprite, color));
				if ((Object)(object)val2 != (Object)null)
				{
					if ((Object)(object)val.sprite != (Object)(object)val2)
					{
						val.sprite = val2;
					}
					((Graphic)val).color = (armorOnly ? value.Color : Color.white);
					if ((int)val.type != 0)
					{
						val.type = (Type)0;
					}
				}
				else if (!armorOnly)
				{
					((Graphic)val).color = color;
				}
			}
		}

		internal static void Restore(Transform root)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null && Originals.TryGetValue(componentsInChildren[i], out var value))
				{
					componentsInChildren[i].sprite = value.Sprite;
					((Graphic)componentsInChildren[i]).color = value.Color;
				}
			}
		}

		internal static void RecolorOwn(Color color)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			for (int i = 0; i < FMarkers.Length; i++)
			{
				string name = FMarkers[i].Name;
				if (!(name != "m_smallMarker") || !(name != "m_largeMarker"))
				{
					object? value = FMarkers[i].GetValue(instance);
					RectTransform val = (RectTransform)((value is RectTransform) ? value : null);
					if (!((Object)(object)val == (Object)null))
					{
						RecolorImages((Transform)(object)val, "own:" + name, color, armorOnly: false);
					}
				}
			}
		}

		internal static void RestoreOwn()
		{
			foreach (RectTransform item in MarkerRects())
			{
				Restore((Transform)(object)item);
			}
		}

		internal static void PruneOriginals()
		{
			List<Image> list = null;
			foreach (KeyValuePair<Image, Orig> original in Originals)
			{
				if (!((Object)(object)original.Key != (Object)null))
				{
					if (list == null)
					{
						list = new List<Image>();
					}
					list.Add(original.Key);
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					Originals.Remove(list[i]);
				}
			}
		}

		private static void LogStructure(string tag, Image[] images)
		{
			if (!LoggedTags.Add(tag))
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(Loc.T("log.iconParts")).Append(tag).Append(": ");
			foreach (Image val in images)
			{
				if (!((Object)(object)val == (Object)null))
				{
					stringBuilder.Append(((Object)((Component)val).gameObject).name).Append('[').Append(((Object)(object)val.sprite != (Object)null) ? ((Object)val.sprite).name : "-")
						.Append("] ");
				}
			}
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}

		internal static Image PinImage(PinData pin)
		{
			if (pin == null || (Object)(object)pin.m_uiElement == (Object)null)
			{
				return null;
			}
			Image val = null;
			Image[] componentsInChildren = ((Component)pin.m_uiElement).GetComponentsInChildren<Image>(true);
			foreach (Image val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					if ((Object)(object)pin.m_icon != (Object)null && (Object)(object)val2.sprite == (Object)(object)pin.m_icon)
					{
						return val2;
					}
					if ((Object)(object)val == (Object)null && !IsCheckImage(val2))
					{
						val = val2;
					}
				}
			}
			return val;
		}
	}
	internal static class MapUI
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__OnClearTracked;
		}

		private static readonly Color ClearRed = new Color(0.95f, 0.2f, 0.15f, 1f);

		private static readonly Color ClearFlash = Color.white;

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

		private static GameObject panel;

		private static Image panelImage;

		private static GameObject clearPanel;

		private static Image clearPanelImage;

		private static Image clearIcon;

		private static readonly List<Image> Borders = new List<Image>();

		private static bool wasOpen;

		private static bool styled;

		private static bool fallbackLogged;

		private static bool dumped;

		private static float nextLayout;

		private static int quickLayouts;

		internal static void Tick()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = MapAccess.LargeRoot();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if ((Object)(object)panel == (Object)null)
			{
				Build(val);
			}
			if (!val.activeInHierarchy)
			{
				wasOpen = false;
				return;
			}
			if (!wasOpen)
			{
				wasOpen = true;
				clearPanel.transform.SetAsLastSibling();
				panel.transform.SetAsLastSibling();
				nextLayout = 0f;
				quickLayouts = 3;
			}
			if (Time.unscaledTime >= nextLayout)
			{
				nextLayout = Time.unscaledTime + ((quickLayouts > 0) ? 0.1f : 0.5f);
				if (quickLayouts > 0)
				{
					quickLayouts--;
				}
				Layout(val);
			}
			for (int i = 0; i < Borders.Count; i++)
			{
				((Graphic)Borders[i]).color = (IsSelected(i) ? UiUtil.SelectColor : UiUtil.NoBorder);
			}
			((Graphic)clearIcon).color = (TrackedPins.HasAny() ? ClearRed : ClearFlash);
		}

		private static void Build(GameObject largeRoot)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			Borders.Clear();
			styled = false;
			clearPanelImage = UiUtil.MakeImage(largeRoot.transform, "Icons_ClearPanel", new Color(0f, 0f, 0f, 0.6f));
			clearPanel = ((Component)clearPanelImage).gameObject;
			clearIcon = UiUtil.MakeImage(clearPanel.transform, "ClearTrackedButton", ClearRed);
			clearIcon.sprite = IconDraw.Cross();
			clearIcon.preserveAspect = true;
			Button obj = ((Component)clearIcon).gameObject.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)clearIcon;
			ButtonClickedEvent onClick = obj.onClick;
			object obj2 = <>O.<0>__OnClearTracked;
			if (obj2 == null)
			{
				UnityAction val = OnClearTracked;
				<>O.<0>__OnClearTracked = val;
				obj2 = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
			panelImage = UiUtil.MakeImage(largeRoot.transform, "Icons_Panel", new Color(0f, 0f, 0f, 0.6f));
			panel = ((Component)panelImage).gameObject;
			for (int i = 0; i < Palette.Hex.Length; i++)
			{
				int index = i;
				Image item = UiUtil.MakeSwatch(panel.transform, "Swatch" + i, ColorSync.ParseHex(Palette.Hex[i]), (UnityAction)delegate
				{
					OnPickColor(index);
				});
				Borders.Add(item);
			}
		}

		private static bool IsSelected(int i)
		{
			return string.Equals(Plugin.IconArmorColor.Value.TrimStart(new char[1] { '#' }), Palette.Hex[i], StringComparison.OrdinalIgnoreCase);
		}

		private static void OnPickColor(int index)
		{
			UiSound.PlayClick();
			Plugin.IconArmorColor.Value = (IsSelected(index) ? "" : Palette.Hex[index]);
		}

		private static void OnClearTracked()
		{
			UiSound.PlayClick();
			TrackedPins.ClearAll();
		}

		private static void Layout(GameObject root)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0133: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Expected O, but got Unknown
			//IL_020e: 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_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Expected O, but got Unknown
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: 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)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = root.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val == (Object)null || (Object)(object)panel == (Object)null)
			{
				return;
			}
			Rect rect = val.rect;
			if (((Rect)(ref rect)).width < 10f || ((Rect)(ref rect)).height < 10f)
			{
				return;
			}
			Image top;
			Rect topRect;
			bool num = FindTopIcon(val, rect, out top, out topRect);
			Rect rect2 = default(Rect);
			Image image = null;
			bool flag = num && FindBackdrop(val, top, ((Rect)(ref topRect)).height, out rect2, out image);
			if (num)
			{
				DumpOnce(val, top);
			}
			float num2;
			float num3;
			float num4;
			float num5;
			if (!num)
			{
				num2 = ((Rect)(ref rect)).height * 0.038f;
				num3 = num2 * 1.5f;
				num4 = ((Rect)(ref rect)).xMax - num3 * 0.9f;
				num5 = ((Rect)(ref rect)).yMin + ((Rect)(ref rect)).height * 0.62f;
				if (!fallbackLogged)
				{
					fallbackLogged = true;
					Plugin.Log.LogWarning((object)Loc.T("log.panelFallback"));
				}
			}
			else
			{
				num2 = ((Rect)(ref topRect)).height;
				float num6 = num2 * 0.7f;
				if (flag)
				{
					num3 = ((Rect)(ref rect2)).width;
					num4 = ((Rect)(ref rect2)).center.x;
					num5 = ((Rect)(ref rect2)).yMax + num6;
				}
				else
				{
					num3 = num2 * 1.5f;
					num4 = ((Rect)(ref topRect)).center.x;
					num5 = ((Rect)(ref topRect)).yMax + num2 * 0.27f + num6;
				}
			}
			num4 += Plugin.PanelX.Value;
			num5 += Plugin.PanelY.Value;
			float num7 = num2 * 0.7f;
			if ((Object)(object)image != (Object)null && !styled)
			{
				styled = true;
				CopyStyle(image, panelImage);
				CopyStyle(image, clearPanelImage);
			}
			float num8 = Mathf.Min(num2 * 0.9f, num3 * 0.8f);
			float num9 = (num3 - num8) * 0.5f;
			float num10 = num8 + num9 * 2f;
			Place((RectTransform)clearPanel.transform, num4, num5, num3, num10, rect);
			RectTransform rectTransform = ((Graphic)clearIcon).rectTransform;
			rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
			rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.sizeDelta = new Vector2(num8, num8);
			rectTransform.anchoredPosition = Vector2.zero;
			float num11 = num5 + num10 + num7;
			float num12 = Mathf.Min(num2 * 0.8f, num3 * 0.8f);
			float num13 = num12 * 0.22f;
			float num14 = (num3 - num12) * 0.5f;
			int num15 = Palette.Hex.Length;
			float num16 = (float)num15 * num12 + (float)(num15 - 1) * num13 + num14 * 2f;
			float num17 = ((Rect)(ref rect)).yMax - num11 - 4f;
			if (num17 > 20f && num16 > num17)
			{
				float num18 = num17 / num16;
				num12 *= num18;
				num13 *= num18;
				num14 *= num18;
				num16 = num17;
			}
			Place((RectTransform)panel.transform, num4, num11, num3, num16, rect);
			float ring = Mathf.Max(1.5f, num12 * 0.07f);
			for (int i = 0; i < Borders.Count; i++)
			{
				RectTransform rectTransform2 = ((Graphic)Borders[i]).rectTransform;
				rectTransform2.anchorMin = new Vector2(0.5f, 1f);
				rectTransform2.anchorMax = new Vector2(0.5f, 1f);
				rectTransform2.pivot = new Vector2(0.5f, 1f);
				rectTransform2.sizeDelta = new Vector2(num12, num12);
				rectTransform2.anchoredPosition = new Vector2(0f, 0f - (num14 + (float)i * (num12 + num13)));
				UiUtil.SetSwatchRing(Borders[i], ring);
			}
		}

		private static void CopyStyle(Image from, Image to)
		{
			//IL_000e: 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)
			to.sprite = from.sprite;
			to.type = from.type;
			((Graphic)to).color = ((Graphic)from).color;
			to.pixelsPerUnitMultiplier = from.pixelsPerUnitMultiplier;
		}

		private static void Place(RectTransform rt, float centerX, float bottom, float w, float h, Rect pr)
		{
			//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_0043: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = new Vector2(0.5f, 0.5f);
			rt.anchorMax = new Vector2(0.5f, 0.5f);
			rt.pivot = new Vector2(0.5f, 0f);
			rt.sizeDelta = new Vector2(w, h);
			rt.anchoredPosition = new Vector2(centerX - ((Rect)(ref pr)).center.x, bottom - ((Rect)(ref pr)).center.y);
		}

		private static bool FindTopIcon(RectTransform parent, Rect pr, out Image top, out Rect topRect)
		{
			//IL_0004: 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_0147: 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_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			top = null;
			topRect = default(Rect);
			HashSet<Transform> hashSet = new HashSet<Transform>();
			List<PinData> list = MapAccess.Pins();
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					if (list[i] != null && (Object)(object)list[i].m_uiElement != (Object)null)
					{
						hashSet.Add((Transform)(object)list[i].m_uiElement);
					}
				}
			}
			foreach (RectTransform item in MapAccess.MarkerRects())
			{
				hashSet.Add((Transform)(object)item);
			}
			float num = float.MinValue;
			Image[] componentsInChildren = ((Component)parent).GetComponentsInChildren<Image>(false);
			foreach (Image val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null || !((Behaviour)val).enabled || ((Graphic)val).color.a < 0.05f || ((Component)val).transform.IsChildOf(clearPanel.transform) || ((Component)val).transform.IsChildOf(panel.transform) || IsExcluded(((Component)val).transform, hashSet))
				{
					continue;
				}
				Rect val2 = LocalRect(parent, ((Graphic)val).rectTransform);
				if (!(((Rect)(ref val2)).height < ((Rect)(ref pr)).height * 0.02f) && !(((Rect)(ref val2)).height > ((Rect)(ref pr)).height * 0.09f))
				{
					float num2 = ((Rect)(ref val2)).width / Mathf.Max(0.001f, ((Rect)(ref val2)).height);
					if (!(num2 < 0.75f) && !(num2 > 1.33f) && !(((Rect)(ref val2)).center.x < ((Rect)(ref pr)).xMin + ((Rect)(ref pr)).width * 0.85f) && ((Rect)(ref val2)).center.y > num)
					{
						num = ((Rect)(ref val2)).center.y;
						top = val;
						topRect = val2;
					}
				}
			}
			return (Object)(object)top != (Object)null;
		}

		private static bool IsExcluded(Transform t, HashSet<Transform> exclude)
		{
			int num = 0;
			while ((Object)(object)t != (Object)null && num < 6)
			{
				if (exclude.Contains(t))
				{
					return true;
				}
				num++;
				t = t.parent;
			}
			return false;
		}

		private static bool FindBackdrop(RectTransform parent, Image top, float iconSize, out Rect rect, out Image image)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			rect = default(Rect);
			image = null;
			Transform parent2 = ((Component)top).transform.parent;
			int num = 0;
			while (num < 4 && (Object)(object)parent2 != (Object)null && (Object)(object)parent2 != (Object)(object)parent)
			{
				RectTransform val = (RectTransform)(object)((parent2 is RectTransform) ? parent2 : null);
				if (!((Object)(object)val == (Object)null))
				{
					Image component = ((Component)parent2).GetComponent<Image>();
					if (!((Object)(object)component == (Object)null) && ((Behaviour)component).enabled)
					{
						Rect val2 = LocalRect(parent, val);
						if (((Rect)(ref val2)).width >= iconSize * 1.3f && ((Rect)(ref val2)).width <= iconSize * 2.8f && ((Rect)(ref val2)).height >= iconSize * 1.3f)
						{
							rect = val2;
							image = component;
							return true;
						}
					}
				}
				num++;
				parent2 = parent2.parent;
			}
			return false;
		}

		private static Rect LocalRect(RectTransform parent, RectTransform rt)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_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_0046: 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_0057: 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_0068: 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)
			rt.GetWorldCorners(Corners);
			Vector3 val = ((Transform)parent).InverseTransformPoint(Corners[0]);
			Vector3 val2 = ((Transform)parent).InverseTransformPoint(Corners[2]);
			return Rect.MinMaxRect(Mathf.Min(val.x, val2.x), Mathf.Min(val.y, val2.y), Mathf.Max(val.x, val2.x), Mathf.Max(val.y, val2.y));
		}

		private static void DumpOnce(RectTransform parent, Image top)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			if (dumped || !Plugin.DebugLayout.Value)
			{
				return;
			}
			dumped = true;
			StringBuilder stringBuilder = new StringBuilder("Icons map UI:");
			Transform val = ((Component)top).transform;
			int num = 0;
			while (num < 6 && (Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)parent)
			{
				stringBuilder.Append("\n  ").Append(((Object)val).name).Append(" [");
				Component[] components = ((Component)val).GetComponents<Component>();
				foreach (Component val2 in components)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						stringBuilder.Append(((object)val2).GetType().Name).Append(' ');
					}
				}
				stringBuilder.Append(']');
				RectTransform val3 = (RectTransform)(object)((val is RectTransform) ? val : null);
				if ((Object)(object)val3 != (Object)null)
				{
					Rect val4 = LocalRect(parent, val3);
					stringBuilder.Append(" rect=(").Append(Mathf.RoundToInt(((Rect)(ref val4)).x)).Append(',')
						.Append(Mathf.RoundToInt(((Rect)(ref val4)).y))
						.Append(' ')
						.Append(Mathf.RoundToInt(((Rect)(ref val4)).width))
						.Append('x')
						.Append(Mathf.RoundToInt(((Rect)(ref val4)).height))
						.Append(')');
				}
				num++;
				val = val.parent;
			}
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}
	}
	internal sealed class NameLabel
	{
		private readonly Text legacy;

		private readonly TextMeshProUGUI tmp;

		internal string text
		{
			get
			{
				if (!((Object)(object)tmp != (Object)null))
				{
					return legacy.text;
				}
				return ((TMP_Text)tmp).text;
			}
			set
			{
				if ((Object)(object)tmp != (Object)null)
				{
					((TMP_Text)tmp).text = value;
				}
				else
				{
					legacy.text = value;
				}
			}
		}

		internal Color color
		{
			set
			{
				//IL_0021: 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)
				if ((Object)(object)tmp != (Object)null)
				{
					((Graphic)tmp).color = value;
				}
				else
				{
					((Graphic)legacy).color = value;
				}
			}
		}

		internal float preferredWidth
		{
			get
			{
				if (!((Object)(object)tmp != (Object)null))
				{
					return legacy.preferredWidth;
				}
				return ((TMP_Text)tmp).preferredWidth;
			}
		}

		internal RectTransform rectTransform
		{
			get
			{
				if (!((Object)(object)tmp != (Object)null))
				{
					return ((Graphic)legacy).rectTransform;
				}
				return ((TMP_Text)tmp).rectTransform;
			}
		}

		internal GameObject gameObject
		{
			get
			{
				if (!((Object)(object)tmp != (Object)null))
				{
					return ((Component)legacy).gameObject;
				}
				return ((Component)tmp).gameObject;
			}
		}

		internal bool Bold
		{
			set
			{
				if ((Object)(object)tmp != (Object)null)
				{
					((TMP_Text)tmp).fontStyle = (FontStyles)(value ? 1 : 0);
				}
				else
				{
					legacy.fontStyle = (FontStyle)(value ? 1 : 0);
				}
			}
		}

		internal NameLabel(Transform parent, string goName, int size, TextAnchor anchor, Color color)
		{
			//IL_00ef: 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)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0071: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			RuneFont.EnsureSearched();
			if ((Object)(object)RuneFont.TmpFont != (Object)null)
			{
				GameObject val = new GameObject(goName, new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(parent, false);
				tmp = val.AddComponent<TextMeshProUGUI>();
				((TMP_Text)tmp).font = RuneFont.TmpFont;
				((TMP_Text)tmp).fontSize = size;
				((Graphic)tmp).color = color;
				((TMP_Text)tmp).alignment = ToTmpAlignment(anchor);
				((TMP_Text)tmp).text = "";
				((Graphic)tmp).raycastTarget = false;
				DisableWrapping(tmp);
				((TMP_Text)tmp).overflowMode = (TextOverflowModes)0;
				((TMP_Text)tmp).outlineWidth = 0.2f;
				((TMP_Text)tmp).outlineColor = new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue);
			}
			else
			{
				legacy = UiUtil.MakeText(parent, goName, "", size, anchor, color);
				if ((Object)(object)RuneFont.LegacyFont != (Object)null)
				{
					legacy.font = RuneFont.LegacyFont;
				}
				UiUtil.AddOutline(legacy);
			}
		}

		private static void DisableWrapping(TextMeshProUGUI t)
		{
			Type type = ((object)t).GetType();
			PropertyInfo property = type.GetProperty("textWrappingMode");
			if (property != null && property.CanWrite && property.PropertyType.IsEnum)
			{
				try
				{
					property.SetValue(t, Enum.Parse(property.PropertyType, "NoWrap"), null);
					return;
				}
				catch
				{
				}
			}
			PropertyInfo property2 = type.GetProperty("enableWordWrapping");
			if (property2 != null && property2.CanWrite)
			{
				property2.SetValue(t, false, null);
			}
		}

		private static TextAlignmentOptions ToTmpAlignment(TextAnchor a)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected I4, but got Unknown
			return (TextAlignmentOptions)((int)a switch
			{
				0 => 257, 
				1 => 258, 
				2 => 260, 
				3 => 4097, 
				5 => 4100, 
				6 => 1025, 
				7 => 1026, 
				8 => 1028, 
				_ => 4098, 
			});
		}
	}
	internal static class Net
	{
		private static readonly List<Action<ZRoutedRpc>> Registrars = new List<Action<ZRoutedRpc>>();

		private static ZRoutedRpc registeredFor;

		internal static void Add(Action<ZRoutedRpc> registrar)
		{
			Registrars.Add(registrar);
		}

		internal static void Tick()
		{
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance == null)
			{
				registeredFor = null;
			}
			else
			{
				if (instance == registeredFor)
				{
					return;
				}
				registeredFor = instance;
				for (int i = 0; i < Registrars.Count; i++)
				{
					try
					{
						Registrars[i](instance);
					}
					catch (Exception ex)
					{
						Plugin.ReportOnce("Net.Register#" + i, ex);
					}
				}
				Plugin.Log.LogInfo((object)"Icons: сетевые обработчики зарегистрированы / network handlers registered");
			}
		}
	}
	[Serializable]
	public class NewRecipesFile
	{
		public string name;

		public List<string> known = new List<string>();

		public List<string> fresh = new List<string>();
	}
	internal static class NewRecipes
	{
		private static readonly FieldInfo FKnown = AccessTools.Field(typeof(Player), "m_knownRecipes");

		private static readonly FieldInfo FAvailable = AccessTools.Field(typeof(InventoryGui), "m_availableRecipes");

		private static PropertyInfo pairElement;

		private static readonly FieldInfo FPieceIcon = AccessTools.Field(typeof(BuildUiPieceButton), "m_icon");

		private const string BadgeName = "Icons_NewBadge";

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

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

		private static long loadedId;

		private static bool hasFile;

		private static float appearedAt;

		private static float nextPoll;

		private static bool warnedNoField;

		internal static bool IsNew(string name)
		{
			if (!string.IsNullOrEmpty(name))
			{
				return Fresh.Contains(name);
			}
			return false;
		}

		internal static void Dismiss(string name)
		{
			if (!string.IsNullOrEmpty(name) && Fresh.Remove(name))
			{
				Save();
			}
		}

		internal static void Tick()
		{
			if (!Plugin.NewBadges.Value)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				loadedId = 0L;
				return;
			}
			long playerID = localPlayer.GetPlayerID();
			if (playerID != loadedId)
			{
				loadedId = playerID;
				appearedAt = Time.time;
				Load(playerID);
			}
			if (Time.time - appearedAt < 3f || Time.time < nextPoll)
			{
				return;
			}
			nextPoll = Time.time + 1f;
			if (FKnown == null)
			{
				if (!warnedNoField)
				{
					warnedNoField = true;
					Plugin.Log.LogWarning((object)(Loc.T("log.fieldMissing") + "Player.m_knownRecipes — пометки «new» работать не будут."));
				}
			}
			else
			{
				if (!(FKnown.GetValue(localPlayer) is IEnumerable<string> enumerable))
				{
					return;
				}
				bool flag = false;
				if (!hasFile)
				{
					foreach (string item in enumerable)
					{
						Known.Add(item);
					}
					hasFile = true;
					flag = true;
				}
				else
				{
					foreach (string item2 in enumerable)
					{
						if (Known.Add(item2))
						{
							Fresh.Add(item2);
							flag = true;
						}
					}
				}
				if (flag)
				{
					Save();
				}
			}
		}

		private static string FilePath(long id)
		{
			return Path.Combine(Path.Combine(Paths.ConfigPath, "Icons"), "newrecipes_" + id + ".json");
		}

		private static void Load(long id)
		{
			Known.Clear();
			Fresh.Clear();
			hasFile = false;
			try
			{
				string path = FilePath(id);
				if (!File.Exists(path))
				{
					return;
				}
				NewRecipesFile newRecipesFile = JsonUtility.FromJson<NewRecipesFile>(File.ReadAllText(path));
				if (newRecipesFile == null)
				{
					return;
				}
				if (newRecipesFile.known != null)
				{
					foreach (string item in newRecipesFile.known)
					{
						Known.Add(item);
					}
				}
				if (newRecipesFile.fresh != null)
				{
					foreach (string item2 in newRecipesFile.fresh)
					{
						Fresh.Add(item2);
					}
				}
				hasFile = true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Icons: не удалось прочитать пометки «new»: " + ex.Message));
			}
		}

		private static void Save()
		{
			if (loadedId == 0L)
			{
				return;
			}
			try
			{
				string path = FilePath(loadedId);
				Directory.CreateDirectory(Path.GetDirectoryName(path));
				NewRecipesFile newRecipesFile = new NewRecipesFile();
				Player localPlayer = Player.m_localPlayer;
				newRecipesFile.name = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetPlayerName() : "");
				foreach (string item in Known)
				{
					newRecipesFile.known.Add(item);
				}
				foreach (string item2 in Fresh)
				{
					newRecipesFile.fresh.Add(item2);
				}
				File.WriteAllText(path, JsonUtility.ToJson((object)newRecipesFile));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Icons: не удалось сохранить пометки «new»: " + ex.Message));
			}
		}

		internal static void OnRecipeRowAdded(InventoryGui gui, Recipe recipe, ItemData upgradeItem)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			if (!Plugin.NewBadges.Value || (Object)(object)gui == (Object)null || (Object)(object)recipe == (Object)null || upgradeItem != null)
			{
				return;
			}
			string name = (((Object)(object)recipe.m_item != (Object)null) ? recipe.m_item.m_itemData.m_shared.m_name : null);
			if (!IsNew(name))
			{
				return;
			}
			GameObject val = LastRowElement(gui);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val2 = val.transform.Find("icon");
			Text val3 = MakeBadge(((Object)(object)val2 != (Object)null) ? val2 : val.transform);
			Button component = val.GetComponent<Button>();
			if (!((Object)(object)component != (Object)null))
			{
				return;
			}
			GameObject badgeGo = ((Component)val3).gameObject;
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				Dismiss(name);
				if ((Object)(object)badgeGo != (Object)null)
				{
					Object.Destroy((Object)(object)badgeGo);
				}
			});
		}

		private static Text MakeBadge(Transform parent)
		{
			//IL_000e: 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_0050: 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_0087: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			Text val = UiUtil.MakeText(parent, "Icons_NewBadge", "new", 10, (TextAnchor)4, Color.white);
			Outline val2 = ((Component)val).gameObject.GetComponent<Outline>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)val).gameObject.AddComponent<Outline>();
			}
			((Shadow)val2).effectColor = Color.black;
			((Shadow)val2).effectDistance = new Vector2(1f, -1f);
			((Shadow)val2).useGraphicAlpha = true;
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			rectTransform.anchorMin = new Vector2(1f, 1f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.pivot = new Vector2(1f, 1f);
			rectTransform.sizeDelta = new Vector2(28f, 12f);
			rectTransform.anchoredPosition = new Vector2(2f, 2f);
			return val;
		}

		private static Transform PieceBadgeParent(BuildUiPieceButton button)
		{
			Image val = (Image)((FPieceIcon != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if (!((Object)(object)val != (Object)null))
			{
				return ((Component)button).transform;
			}
			return ((Component)val).transform;
		}

		internal static void OnPieceButtonSetup(BuildUiPieceButton button, Piece piece)
		{
			if ((Object)(object)button == (Object)null)
			{
				return;
			}
			Transform val = PieceBadgeParent(button);
			Transform val2 = val.Find("Icons_NewBadge");
			if (Plugin.NewBadges.Value && (Object)(object)piece != (Object)null && IsNew(piece.m_name))
			{
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)MakeBadge(val)).transform;
				}
				((Component)val2).gameObject.SetActive(true);
			}
			else if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(false);
			}
		}

		internal static void OnPieceHover(BuildUiPieceButton button)
		{
			if ((Object)(object)button == (Object)null || (Object)(object)button.Piece == (Object)null)
			{
				return;
			}
			string name = button.Piece.m_name;
			if (IsNew(name))
			{
				Dismiss(name);
				Transform val = PieceBadgeParent(button).Find("Icons_NewBadge");
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
		}

		private static GameObject LastRowElement(InventoryGui gui)
		{
			if (FAvailable == null)
			{
				return null;
			}
			if (!(FAvailable.GetValue(gui) is IList { Count: not 0 } list))
			{
				return null;
			}
			object obj = list[list.Count - 1];
			if (pairElement == null)
			{
				pairElement = obj.GetType().GetProperty("InterfaceElement");
			}
			if (!(pairElement != null))
			{
				return null;
			}
			object? value = pairElement.GetValue(obj, null);
			return (GameObject)((value is GameObject) ? value : null);
		}
	}
	public enum LanguageMode
	{
		Auto,
		English,
		Russian
	}
	public enum TeamPanelPlacement
	{
		BelowMap,
		LeftOfMap
	}
	[BepInPlugin("momotie.Iconsee.valheim", "Iconsee", "1.0.3")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "momotie.Iconsee.valheim";

		public const string PluginName = "Iconsee";

		public const string PluginVersion = "1.0.3";

		internal static ManualLogSource Log;

		internal static ConfigEntry<LanguageMode> LanguageSetting;

		internal static ConfigEntry<string> IconArmorColor;

		internal static ConfigEntry<bool> RecolorOwnArrow;

		internal static ConfigEntry<string> TrackedMapColor;

		internal static ConfigEntry<float> Opacity;

		internal static ConfigEntry<float> IconSize;

		internal static ConfigEntry<KeyboardShortcut> ToggleKey;

		internal static ConfigEntry<bool> ShowLabel;

		internal static ConfigEntry<bool> ClampToEdge;

		internal static ConfigEntry<float> HideWithin;

		internal static ConfigEntry<float> HeightOffset;

		internal static ConfigEntry<bool> BehindPlayer;

		internal static ConfigEntry<KeyboardShortcut> PlaceMarkKey;

		internal static ConfigEntry<float> TempMarkSeconds;

		internal static ConfigEntry<string> TempMarkColor;

		internal static ConfigEntry<float> TempMarkOpacity;

		internal static ConfigEntry<float> TempMarkSize;

		internal static ConfigEntry<bool> ShowShipMarkers;

		internal static ConfigEntry<bool> ShowTeammateIcons;

		internal static ConfigEntry<float> TeammateIconOpacity;

		internal static ConfigEntry<float> TeammateIconSize;

		internal static ConfigEntry<int> TeammateIconMax;

		internal static ConfigEntry<float> IconsShowBeyond;

		internal static ConfigEntry<bool> IconsClampToEdge;

		internal static ConfigEntry<bool> ShowTeamPanel;

		internal static ConfigEntry<int> TeamPanelMaxRows;

		internal static ConfigEntry<TeamPanelPlacement> TeamPanelPosition;

		internal static ConfigEntry<float> TeamPanelOffsetX;

		internal static ConfigEntry<float> TeamPanelOffsetY;

		internal static ConfigEntry<float> TeamPanelScale;

		internal static ConfigEntry<float> TeamPanelCompactBelow;

		internal static ConfigEntry<bool> DeathChatMessages;

		internal static ConfigEntry<bool> LearnFromContainers;

		internal static ConfigEntry<bool> RepairAllOnClick;

		internal static ConfigEntry<bool> SignStyle;

		internal static ConfigEntry<bool> NewBadges;

		internal static ConfigEntry<bool> SkipIntro;

		internal static ConfigEntry<float> PanelX;

		internal static ConfigEntry<float> PanelY;

		internal static ConfigEntry<bool> DebugLayout;

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

		private static readonly List<string> PatchReport = new List<string>();

		private static readonly Action[] Ticks = new Action[12]
		{
			Net.Tick,
			MapUI.Tick,
			TrackedPins.Tick,
			TempMarks.Tick,
			ColorSync.Tick,
			ShipMarkers.Tick,
			QuickPin.Tick,
			HudMarkers.Tick,
			TeamHud.Tick,
			ContainerRecipes.Tick,
			SignTweaks.Tick,
			NewRecipes.Tick
		};

		private static readonly string[] TickNames = new string[12]
		{
			"Net", "MapUI", "TrackedPins", "TempMarks", "ColorSync", "ShipMarkers", "QuickPin", "HudMarkers", "TeamHud", "ContainerRecipes",
			"SignTweaks", "NewRecipes"
		};

		private void Awake()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			BindConfig();
			Net.Add(ColorSync.Register);
			Net.Add(TempMarks.Register);
			Net.Add(ShipMarkers.Register);
			Net.Add(TeamHud.Register);
			Net.Add(DeathMessages.Register);
			Harmony harmony = new Harmony("momotie.Iconsee.valheim");
			TryPatch(harmony, typeof(Minimap), "RemovePin", new Type[1] { typeof(PinData) }, "RemovePinPostfix", prefix: false, declaredOnly: false);
			TryPatch(harmony, typeof(Minimap), "OnMapMiddleClick", null, "MiddleClickPrefix", prefix: true, declaredOnly: false);
			TryPatch(harmony, typeof(Chat), "SendPing", new Type[1] { typeof(Vector3) }, "MiddleClickPrefix", prefix: true, declaredOnly: false);
			TryPatch(harmony, typeof(Character), "ApplyDamage", null, "DamagePostfix", prefix: false, declaredOnly: false);
			TryPatch(harmony, typeof(Player), "ApplyDamage", null, "DamagePostfix", prefix: false, declaredOnly: true);
			TryPatch(harmony, typeof(Player), "OnDeath", null, "DeathPostfix", prefix: false, declaredOnly: false);
			TryPatch(harmony, typeof(TreeBase), "Damage", null, "TreeDamagePostfix", prefix: false, declaredOnly: false);
			TryPatch(harmony, typeof(MineRock), "Damage", null, "RockDamagePostfix", prefix: false, declaredOnly: false);
			TryPatch(harmony, typeof(MineRock5), "Damage", null, "RockDamagePostfix", prefix: false, declaredOnly: false);
			TryPatch(harmony, typeof(InventoryGui), "OnRepairPressed", null, "RepairPostfix", prefix: false, declaredOnly: false);
			TryPatch(harmony, typeof(BuildUiPieceButton), "Setup", null, "BuildButtonSetupPostfix", prefix: false, declaredOnly: false);
			Type type = AccessTools.TypeByName("BuildUi");
			if (type != null)
			{
				TryPatch(harmony, type, "OnHoverPiece", new Type[1] { typeof(BuildUiPieceButton) }, "BuildHoverPostfix", prefix: false, declaredOnly: false);
			}
			else
			{
				Log.LogWarning((object)(Loc.T("log.patchMissing") + "BuildUi.OnHoverPiece — «new» у построек не будет сниматься наведением."));
			}
			TryPatch(harmony, typeof(InventoryGui), "AddRecipeToList", null, "RecipeRowPostfix", prefix: false, declaredOnly: false);
			if (!RepairAll.Available)
			{
				Log.LogWarning((object)(Loc.T("log.fieldMissing") + "InventoryGui.RepairOneItem/HaveRepairableItems"));
			}
			TryPatch(harmony, typeof(TextInput), "RequestText", null, "SignRequestPostfix", prefix: false, declaredOnly: false);
			if (!SignTweaks.Available)
			{
				Log.LogWarning((object)(Loc.T("log.fieldMissing") + "TextInput.m_panel"));
			}
			TryPatch(harmony, typeof(FejdStartup), "Start", null, "IntroSkipPrefix", prefix: true, declaredOnly: false);
			SkipIntro = ((BaseUnityPlugin)this).Config.Bind<bool>("Extras", "SkipIntro", false, "Пропускать вступительный ролик при запуске игры.");
			TryPatch(harmony, typeof(FejdStartup), "SetupGui", null, "IntroButtonPostfix", prefix: false, declaredOnly: false);
			MapAccess.CheckFields();
			IconArmorColor.SettingChanged += delegate
			{
				ColorSync.OnOwnColorChanged();
			};
			Log.LogInfo((object)(Loc.T("log.loaded") + " v1.0.3"));
			Log.LogInfo((object)("Icons: patches — " + string.Join("; ", PatchReport.ToArray())));
		}

		private void BindConfig()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Expected O, but got Unknown
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Expected O, but got Unknown
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Expected O, but got Unknown
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Expected O, but got Unknown
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Expected O, but got Unknown
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Expected O, but got Unknown
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Expected O, but got Unknown
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Expected O, but got Unknown
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Expected O, but got Unknown
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Expected O, but got Unknown
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_0541: Expected O, but got Unknown
			LanguageSetting = ((BaseUnityPlugin)this).Config.Bind<LanguageMode>("General", "Language", LanguageMode.Auto, "Interface language: Auto (follow the game), English, Russian.\nЯзык интерфейса: Auto (как в игре), English, Russian.");
			IconArmorColor = ((BaseUnityPlugin)this).Config.Bind<string>("Player", "IconArmorColor", "", "Color of the sword and shield on your player icon (what your teammates see), HEX RRGGBB. Empty = default look. The body of the icon always stays red. Usually set with the palette on the map.\nЦвет меча и щита на вашей иконке игрока (её видят тиммейты), HEX RRGGBB. Пусто = стандартный вид. Тело иконки всегда остаётся красным. Обычно выбирается палитрой на карте.");
			RecolorOwnArrow = ((BaseUnityPlugin)this).Config.Bind<bool>("Player", "RecolorOwnArrow", true, "Also paint your own arrow on your map/minimap in the chosen color.\nТак