Decompiled source of MapRadar v1.5.0

MapRadar.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
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 ModHub;
using Splatform;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.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 MapRadar
{
	internal static class ConfigSync
	{
		public static void Submit(RadarData d)
		{
			RadarSettings.ApplyLocal(d);
		}

		public static void OnDisconnected()
		{
			ResourceMemory.Unload();
		}
	}
	internal static class ModHubBridge
	{
		private const string Owner = "Brat.MapRadar";

		public static void Register()
		{
			try
			{
				ModHubAPI.Register("Brat.MapRadar", "Radar", (Action)RadarMenu.Open, "Wishbone", (Sprite)null, (Color?)null, "Метки мобов и ресурсов на миникарте", 50, (Func<bool>)(() => true), (Action)RadarMenu.Close, (Func<bool>)(() => RadarMenu.IsOpen));
				MapRadarPlugin.Log.LogInfo((object)"MapRadar добавлен в ModHub");
			}
			catch (Exception ex)
			{
				MapRadarPlugin.Log.LogError((object)("Не удалось зарегистрироваться в ModHub: " + ex));
			}
		}

		public static void SetInputBlock(bool blocked)
		{
			try
			{
				ModHubAPI.SetInputBlock("Brat.MapRadar", blocked);
			}
			catch (Exception ex)
			{
				MapRadarPlugin.Log.LogError((object)("ModHub SetInputBlock: " + ex.Message));
			}
		}
	}
	internal static class Patches
	{
		public static void Apply(Harmony h)
		{
			Post(h, typeof(ZNetScene), "Awake", "ZNetScene_Awake");
			Post(h, typeof(ZNet), "OnDestroy", "ZNet_OnDestroy");
			Post(h, typeof(Minimap), "UpdatePins", "Minimap_UpdatePins");
			Post(h, typeof(Menu), "IsVisible", "Menu_IsVisible");
			Post(h, typeof(PlayerController), "TakeInput", "BlockBool");
			Pre(h, typeof(Player), "SetMouseLook", "SkipWhenMenuOpen");
			Pre(h, typeof(GameCamera), "UpdateMouseCapture", "FreeCursor");
			Post(h, typeof(Pickable), "Awake", "Resource_Awake");
			Post(h, typeof(MineRock5), "Awake", "Resource_Awake");
			Post(h, typeof(MineRock), "Start", "Resource_Awake");
			Post(h, typeof(Destructible), "Awake", "Resource_Awake");
		}

		private static void Post(Harmony h, Type type, string method, string patch)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(type, method, (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				MapRadarPlugin.Log.LogWarning((object)("Не найден " + type.Name + "." + method + " — эта часть мода работать не будет"));
			}
			else
			{
				h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), patch, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void Pre(Harmony h, Type type, string method, string patch)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(type, method, (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				MapRadarPlugin.Log.LogWarning((object)("Не найден " + type.Name + "." + method + " — эта часть мода работать не будет"));
			}
			else
			{
				h.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Patches), patch, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void BlockBool(ref bool __result)
		{
			if (RadarMenu.IsOpen)
			{
				__result = false;
			}
		}

		private static bool SkipWhenMenuOpen()
		{
			return !RadarMenu.IsOpen;
		}

		private static bool FreeCursor()
		{
			if (!RadarMenu.IsOpen)
			{
				return true;
			}
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			return false;
		}

		private static void ZNetScene_Awake(ZNetScene __instance)
		{
			TypeDatabase.Build(__instance);
		}

		private static void ZNet_OnDestroy()
		{
			ConfigSync.OnDisconnected();
		}

		private static void Minimap_UpdatePins()
		{
			RadarTracker.StylePins();
		}

		private static void Menu_IsVisible(ref bool __result)
		{
			if (RadarMenu.IsOpen)
			{
				__result = true;
			}
		}

		private static void Resource_Awake(MonoBehaviour __instance)
		{
			RadarTracker.RegisterResource((Component)(object)__instance);
		}
	}
	[BepInPlugin("Brat.MapRadar", "MapRadar", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MapRadarPlugin : BaseUnityPlugin
	{
		public const string GUID = "Brat.MapRadar";

		public const string ModName = "MapRadar";

		public const string Version = "1.5.0";

		internal static MapRadarPlugin Instance;

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ClientSettings.Bind(((BaseUnityPlugin)this).Config);
			RadarSettings.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("Brat.MapRadar");
			Patches.Apply(_harmony);
		}

		private void Start()
		{
			ModHubBridge.Register();
		}

		private void Update()
		{
			try
			{
				ResourceMemory.Tick(Time.deltaTime);
				RadarTracker.Tick(Time.deltaTime);
				RadarTracker.DiagTick(Time.deltaTime);
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex);
			}
		}

		private void LateUpdate()
		{
			try
			{
				RadarTracker.StylePins();
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex);
			}
		}

		private void OnGUI()
		{
			RadarMenu.Draw();
		}

		private void OnApplicationQuit()
		{
			ResourceMemory.Save();
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class ClientSettings
	{
		public static ConfigEntry<bool> ColorByLevel;

		public static ConfigEntry<bool> NamesOnLargeMap;

		public static ConfigEntry<float> MobIconScale;

		public static ConfigEntry<float> ResourceIconScale;

		public static ConfigEntry<float> ClusterRadius;

		public static ConfigEntry<bool> ClusterMobs;

		public static ConfigEntry<int> MaxResourcePins;

		public static void Bind(ConfigFile cfg)
		{
			ColorByLevel = cfg.Bind<bool>("1. Клиент", "ColorByLevel", true, "Красить иконку моба по количеству звёзд");
			NamesOnLargeMap = cfg.Bind<bool>("1. Клиент", "NamesOnLargeMap", true, "Подписи (имя + звёзды) на большой карте");
			MobIconScale = cfg.Bind<float>("1. Клиент", "MobIconScale", 1f, "Размер иконок мобов");
			ResourceIconScale = cfg.Bind<float>("1. Клиент", "ResourceIconScale", 0.8f, "Размер иконок ресурсов");
			ClusterRadius = cfg.Bind<float>("1. Клиент", "ClusterRadius", 12f, "Одинаковые объекты ближе этого расстояния (м) сливаются в одну метку «x N». 0 — не группировать");
			ClusterMobs = cfg.Bind<bool>("1. Клиент", "ClusterMobs", true, "Группировать и мобов (стаи одного вида и уровня)");
			MaxResourcePins = cfg.Bind<int>("1. Клиент", "MaxResourcePins", 1500, "Максимум меток запомненных ресурсов (ближайшие). Если карта начнёт тормозить — уменьши");
			NamesOnLargeMap.SettingChanged += delegate
			{
				RadarTracker.MarkDirty();
			};
			ClusterRadius.SettingChanged += delegate
			{
				RadarTracker.MarkDirty();
			};
			ClusterMobs.SettingChanged += delegate
			{
				RadarTracker.MarkDirty();
			};
		}
	}
	internal static class RadarMenu
	{
		private struct DropTarget
		{
			public Rect R;

			public int Biome;

			public int Cat;

			public TrackType Before;
		}

		private static RadarData _edit;

		private static bool _dirty;

		private static int _tab;

		private static Vector2 _scroll;

		private static string _search;

		private static readonly string[] Tabs;

		private static readonly Color Gold;

		private static readonly Color Text;

		private static readonly Color Dim;

		private static bool _styles;

		private static GUIStyle sPanel;

		private static GUIStyle sTitle;

		private static GUIStyle sBiome;

		private static GUIStyle sSub;

		private static GUIStyle sHandle;

		private static GUIStyle sRowDrag;

		private static GUIStyle sDragLabel;

		private static GUIStyle sLabel;

		private static GUIStyle sDim;

		private static GUIStyle sHeader;

		private static GUIStyle sButton;

		private static GUIStyle sTab;

		private static GUIStyle sTabOn;

		private static GUIStyle sOn;

		private static GUIStyle sOff;

		private static GUIStyle sRow;

		private static GUIStyle sField;

		private static GUIStyle sWarn;

		private static Texture2D tGold;

		private static Texture2D tSlot;

		private static readonly Dictionary<Sprite, Rect> UvCache;

		private static readonly HashSet<string> Folded;

		private static readonly List<TrackType> Shown;

		private static bool _editLayout;

		private static TrackType _drag;

		private static List<TrackType> _dragList;

		private static readonly List<DropTarget> Targets;

		private static readonly ResCategory[] AllCats;

		public static bool IsOpen { get; private set; }

		static RadarMenu()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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)
			_search = "";
			Tabs = new string[4] { "Общее", "Мобы", "Ресурсы", "Мои настройки" };
			Gold = new Color(0.87f, 0.7f, 0.36f);
			Text = new Color(0.93f, 0.88f, 0.78f);
			Dim = new Color(0.62f, 0.57f, 0.49f);
			UvCache = new Dictionary<Sprite, Rect>();
			Folded = new HashSet<string>();
			Shown = new List<TrackType>();
			Targets = new List<DropTarget>();
			AllCats = new ResCategory[4]
			{
				ResCategory.Ore,
				ResCategory.Food,
				ResCategory.Pickable,
				ResCategory.Other
			};
			RadarSettings.Changed += delegate
			{
				if (IsOpen && !_dirty)
				{
					_edit = RadarSettings.Current.Clone();
				}
			};
		}

		public static void Open()
		{
			_edit = RadarSettings.Current.Clone();
			_dirty = false;
			IsOpen = true;
			ModHubBridge.SetInputBlock(blocked: true);
		}

		public static void Close()
		{
			if (IsOpen)
			{
				IsOpen = false;
				ModHubBridge.SetInputBlock(blocked: false);
			}
		}

		public static void Toggle()
		{
			if (IsOpen)
			{
				Close();
			}
			else
			{
				Open();
			}
		}

		public static void Draw()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Invalid comparison between Unknown and I4
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen)
			{
				return;
			}
			EnsureStyles();
			TypeDatabase.EnsureBiomes();
			float num = Mathf.Min(860f, (float)Screen.width - 40f);
			float num2 = Mathf.Min(640f, (float)Screen.height - 40f);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2);
			GUI.Box(val, GUIContent.none, sPanel);
			Frame(val, 2f);
			GUILayout.BeginArea(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 14f, num - 36f, num2 - 28f));
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("MapRadar — миникарта", sTitle, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Закрыть", sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
			{
				Close();
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			for (int i = 0; i < Tabs.Length; i++)
			{
				if (GUILayout.Button(Tabs[i], (i == _tab) ? sTabOn : sTab, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
				{
					_tab = i;
					_scroll = Vector2.zero;
				}
			}
			GUILayout.EndHorizontal();
			Line();
			bool flag = _tab != 3;
			_scroll = GUILayout.BeginScrollView(_scroll, Array.Empty<GUILayoutOption>());
			bool enabled = GUI.enabled;
			GUI.enabled = !flag || RadarSettings.CanEdit;
			switch (_tab)
			{
			case 0:
				DrawGeneral();
				break;
			case 1:
				DrawMobs();
				break;
			case 2:
				DrawResources();
				break;
			case 3:
				DrawClient();
				break;
			}
			GUI.enabled = enabled;
			GUILayout.EndScrollView();
			if (flag)
			{
				Line();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUI.enabled = RadarSettings.CanEdit && _dirty;
				if (GUILayout.Button("Применить", sButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Height(32f),
					GUILayout.Width(280f)
				}))
				{
					ConfigSync.Submit(_edit.Clone());
					_dirty = false;
				}
				if (GUILayout.Button("Отменить изменения", sButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Height(32f),
					GUILayout.Width(200f)
				}))
				{
					_edit = RadarSettings.Current.Clone();
					_dirty = false;
				}
				GUI.enabled = enabled;
				GUILayout.FlexibleSpace();
				if (_dirty)
				{
					GUILayout.Label("есть несохранённые изменения", sWarn, Array.Empty<GUILayoutOption>());
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.EndArea();
			Event current = Event.current;
			if (_drag != null)
			{
				if ((int)current.type == 1)
				{
					_drag = null;
				}
				else
				{
					GUI.Label(new Rect(current.mousePosition.x + 14f, current.mousePosition.y - 6f, 300f, 26f), "≡  " + _drag.Display, sDragLabel);
				}
			}
		}

		private static void DrawGeneral()
		{
			Header("Радар");
			_edit.Enabled = Toggle("Радар включён", _edit.Enabled);
			_edit.ShowLevels = Toggle("Показывать уровень (звёзды) мобов", _edit.ShowLevels);
			_edit.RememberResources = Toggle("Запоминать найденные ресурсы навсегда", _edit.RememberResources);
			GUILayout.Label("Ресурсы, которые ты хоть раз видел, остаются на карте всегда (у каждого игрока своя память). Выкопанные пропадают, когда снова окажешься рядом. Мобы видны только вблизи.", sDim, Array.Empty<GUILayoutOption>());
			Header("Дальность и производительность");
			_edit.MobRange = Mathf.Round(Slider("Дальность мобов", _edit.MobRange, 10f, 300f, "0 м"));
			_edit.ResourceRange = Mathf.Round(Slider(_edit.RememberResources ? "Дальность обнаружения ресурсов" : "Дальность ресурсов", _edit.ResourceRange, 10f, 300f, "0 м"));
			_edit.MaxPins = Mathf.RoundToInt(Slider("Максимум меток мобов", _edit.MaxPins, 20f, 500f, "0"));
			_edit.UpdateInterval = Mathf.Round(Slider("Обновление раз в", _edit.UpdateInterval, 0.1f, 3f, "0.0 с") * 10f) / 10f;
			GUILayout.Space(6f);
			GUILayout.Label("Метки ставятся только на ближайшие объекты в пределах дальности. Если начнёт подлагивать — уменьши максимум меток или увеличь интервал.", sDim, Array.Empty<GUILayoutOption>());
		}

		private static void DrawMobs()
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			Header("Каких мобов показывать");
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			_edit.ShowHostile = ToggleBtn("Враждебные", _edit.ShowHostile);
			_edit.ShowPassive = ToggleBtn("Мирные", _edit.ShowPassive);
			_edit.ShowTamed = ToggleBtn("Приручённые", _edit.ShowTamed);
			_edit.ShowBosses = ToggleBtn("Боссы", _edit.ShowBosses);
			GUILayout.EndHorizontal();
			_edit.MinStars = Mathf.RoundToInt(Slider("Только от звёзд", _edit.MinStars, 0f, 5f, "0"));
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Цвет меток: ", sDim, Array.Empty<GUILayoutOption>());
			for (int i = 0; i <= 4; i++)
			{
				Color color = GUI.color;
				GUI.color = RadarTracker.StarColor(i);
				GUILayout.Label((i == 4) ? "■ 4+" : $"■ {i}*", sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) });
				GUI.color = color;
			}
			GUILayout.EndHorizontal();
			TypeList(TypeDatabase.Mobs);
		}

		private static void DrawResources()
		{
			Header("Категории");
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			_edit.CatOre = ToggleBtn("Руда", _edit.CatOre);
			_edit.CatPickable = ToggleBtn("Еда и собирательство", _edit.CatPickable);
			_edit.CatOther = ToggleBtn("Остальное", _edit.CatOther);
			GUILayout.EndHorizontal();
			GUILayout.Label("Сверху — стоящие ресурсы по биомам. Камни, кости, потроха и прочий мусор — в группе «Остальное» в самом низу, по умолчанию скрыты. Любой ресурс можно включить/выключить поштучно.", sDim, Array.Empty<GUILayoutOption>());
			TypeList(TypeDatabase.Resources);
		}

		private static void DrawClient()
		{
			Header("Вид меток");
			ClientSettings.ColorByLevel.Value = Toggle("Красить мобов по звёздам", ClientSettings.ColorByLevel.Value, markDirty: false);
			ClientSettings.NamesOnLargeMap.Value = Toggle("Подписи на большой карте", ClientSettings.NamesOnLargeMap.Value, markDirty: false);
			ClientSettings.MobIconScale.Value = Mathf.Round(Slider("Размер иконок мобов", ClientSettings.MobIconScale.Value, 0.4f, 2.5f, "0.0x", markDirty: false) * 10f) / 10f;
			ClientSettings.ResourceIconScale.Value = Mathf.Round(Slider("Размер иконок ресурсов", ClientSettings.ResourceIconScale.Value, 0.4f, 2.5f, "0.0x", markDirty: false) * 10f) / 10f;
			Header("Запомненные ресурсы");
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"В этом мире запомнено: {ResourceMemory.Count}", sLabel, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Забыть всё в этом мире", sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) }))
			{
				ResourceMemory.ForgetAll();
			}
			GUILayout.EndHorizontal();
			ClientSettings.MaxResourcePins.Value = Mathf.RoundToInt(Slider("Максимум меток ресурсов", ClientSettings.MaxResourcePins.Value, 100f, 5000f, "0", markDirty: false));
			Header("Группировка меток");
			ClientSettings.ClusterRadius.Value = Mathf.Round(Slider("Радиус группы", ClientSettings.ClusterRadius.Value, 0f, 60f, "0 м", markDirty: false));
			ClientSettings.ClusterMobs.Value = Toggle("Группировать мобов тоже", ClientSettings.ClusterMobs.Value, markDirty: false);
			GUILayout.Label("Одинаковые объекты рядом сливаются в одну метку, на большой карте подпись «Морошка x7». Чем больше группа — тем крупнее иконка. 0 м — без группировки.", sDim, Array.Empty<GUILayoutOption>());
		}

		private static IEnumerable<int> BiomeSequence(bool resources)
		{
			for (int b = 0; b < 9; b++)
			{
				yield return b;
			}
			yield return 99;
			if (resources)
			{
				yield return 100;
			}
		}

		private static void TypeList(List<TrackType> list)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ca: Invalid comparison between Unknown and I4
			//IL_06f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0701: Unknown result type (might be due to invalid IL or missing references)
			bool flag = list == TypeDatabase.Resources;
			bool canEdit = RadarSettings.CanEdit;
			if (!canEdit)
			{
				_editLayout = false;
			}
			Event current = Event.current;
			if ((int)current.type != 8)
			{
				Targets.Clear();
			}
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Поиск:", sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
			bool enabled = GUI.enabled;
			GUI.enabled = true;
			_search = GUILayout.TextField(_search ?? "", sField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
			GUI.enabled = enabled;
			GUILayout.FlexibleSpace();
			if (canEdit)
			{
				if (GUILayout.Button(_editLayout ? "✔ Готово" : "✎ Расставить", _editLayout ? sOn : sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(130f) }))
				{
					_editLayout = !_editLayout;
					_drag = null;
				}
				if (_editLayout && GUILayout.Button("Сбросить расстановку", sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }))
				{
					foreach (TrackType item2 in list)
					{
						_edit.Layout.Remove(item2.Prefab);
					}
					_dirty = true;
				}
			}
			if (!_editLayout)
			{
				if (GUILayout.Button("Показать все", sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
				{
					SetAll(list, int.MinValue, v: true);
				}
				if (GUILayout.Button("Скрыть все", sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
				{
					SetAll(list, int.MinValue, v: false);
				}
			}
			GUILayout.EndHorizontal();
			if (_editLayout)
			{
				GUILayout.Label("Тащи строку за ≡ на другую строку, подгруппу или заголовок биома. ▲▼ — сдвиг внутри группы. Потом «Применить» — расстановка сохранится.", sDim, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(4f);
			if (list.Count == 0)
			{
				GUILayout.Label("Список появится, когда зайдёшь в мир.", sDim, Array.Empty<GUILayoutOption>());
				return;
			}
			Shown.Clear();
			foreach (TrackType item3 in list)
			{
				if (Matches(item3))
				{
					Shown.Add(item3);
				}
			}
			Shown.Sort((TrackType x, TrackType y) => TypeDatabase.Compare(x, y, _edit));
			foreach (int biome in BiomeSequence(flag))
			{
				List<TrackType> list2 = Shown.Where((TrackType t) => TypeDatabase.BiomeOf(t, _edit) == biome).ToList();
				if (list2.Count == 0 && !_editLayout)
				{
					continue;
				}
				string item = (flag ? "r" : "m") + biome;
				bool flag2 = Folded.Contains(item) && string.IsNullOrEmpty(_search) && _drag == null;
				int num = list2.Count((TrackType t) => RadarTracker.IsVisible(t, _edit));
				GUILayout.Space(6f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				bool enabled2 = GUI.enabled;
				GUI.enabled = true;
				if (GUILayout.Button((flag2 ? "►  " : "▼  ") + TypeDatabase.BiomeName(biome), sBiome, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }) && !Folded.Remove(item))
				{
					Folded.Add(item);
				}
				GUI.enabled = enabled2;
				GUILayout.Label($"видно {num} из {list2.Count}", sDim, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
				if (!_editLayout)
				{
					if (GUILayout.Button("Показать", sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
					{
						SetAll(list, biome, v: true);
					}
					if (GUILayout.Button("Скрыть", sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
					{
						SetAll(list, biome, v: false);
					}
				}
				GUILayout.EndHorizontal();
				AddTarget(biome, -1, null);
				if (flag2)
				{
					continue;
				}
				if (flag)
				{
					ResCategory[] allCats = AllCats;
					foreach (ResCategory cat in allCats)
					{
						List<TrackType> list3 = list2.Where((TrackType t) => TypeDatabase.CategoryOf(t, _edit) == cat).ToList();
						if (list3.Count == 0 && !_editLayout)
						{
							continue;
						}
						GUILayout.Label("   " + CatTitle(cat) + ((list3.Count == 0) ? "  (пусто — можно перетащить сюда)" : ""), sSub, Array.Empty<GUILayoutOption>());
						AddTarget(biome, (int)cat, null);
						foreach (TrackType item4 in list3)
						{
							Row(item4, list, biome, (int)cat);
						}
					}
					continue;
				}
				foreach (TrackType item5 in list2)
				{
					Row(item5, list, biome, -1);
				}
			}
			if (_drag == null || _dragList != list || (int)current.type != 1)
			{
				return;
			}
			foreach (DropTarget target in Targets)
			{
				Rect r = target.R;
				if (!((Rect)(ref r)).Contains(current.mousePosition))
				{
					continue;
				}
				if (target.Before != _drag)
				{
					int cat2 = ((target.Cat >= 0) ? target.Cat : ((int)(flag ? TypeDatabase.CategoryOf(_drag, _edit) : ((ResCategory)(-1)))));
					MoveTo(_drag, list, target.Biome, cat2, target.Before);
				}
				break;
			}
			_drag = null;
			current.Use();
		}

		private static void AddTarget(int biome, int cat, TrackType before)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Invalid comparison between Unknown and I4
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (_editLayout && (int)Event.current.type != 8)
			{
				Rect lastRect = GUILayoutUtility.GetLastRect();
				Targets.Add(new DropTarget
				{
					R = lastRect,
					Biome = biome,
					Cat = cat,
					Before = before
				});
				if (_drag != null && (int)Event.current.type == 7 && ((Rect)(ref lastRect)).Contains(Event.current.mousePosition))
				{
					GUI.DrawTexture(new Rect(((Rect)(ref lastRect)).x, ((Rect)(ref lastRect)).y - 1f, ((Rect)(ref lastRect)).width, 3f), (Texture)(object)tGold);
				}
			}
		}

		private static void MoveTo(TrackType t, List<TrackType> list, int biome, int cat, TrackType before)
		{
			List<TrackType> list2 = list.Where((TrackType x) => x != t && TypeDatabase.BiomeOf(x, _edit) == biome && (cat < 0 || TypeDatabase.CategoryOf(x, _edit) == (ResCategory)cat)).ToList();
			list2.Sort((TrackType x, TrackType y) => TypeDatabase.Compare(x, y, _edit));
			int num = ((before != null) ? list2.IndexOf(before) : (-1));
			if (num < 0)
			{
				num = list2.Count;
			}
			list2.Insert(num, t);
			for (int num2 = 0; num2 < list2.Count; num2++)
			{
				_edit.Layout[list2[num2].Prefab] = new LayoutEntry
				{
					Biome = biome,
					Category = cat,
					Order = num2 + 1
				};
			}
			_dirty = true;
		}

		private static void MoveBy(TrackType t, List<TrackType> list, int biome, int cat, int dir)
		{
			List<TrackType> list2 = list.Where((TrackType x) => TypeDatabase.BiomeOf(x, _edit) == biome && (cat < 0 || TypeDatabase.CategoryOf(x, _edit) == (ResCategory)cat)).ToList();
			list2.Sort((TrackType x, TrackType y) => TypeDatabase.Compare(x, y, _edit));
			int num = list2.IndexOf(t);
			int num2 = num + dir;
			if (num >= 0 && num2 >= 0 && num2 < list2.Count)
			{
				list2[num] = list2[num2];
				list2[num2] = t;
				for (int num3 = 0; num3 < list2.Count; num3++)
				{
					_edit.Layout[list2[num3].Prefab] = new LayoutEntry
					{
						Biome = biome,
						Category = cat,
						Order = num3 + 1
					};
				}
				_dirty = true;
			}
		}

		private static void Row(TrackType t, List<TrackType> list, int biome, int cat)
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			bool flag = RadarTracker.IsVisible(t, _edit);
			Event current = Event.current;
			GUILayout.BeginHorizontal((t == _drag) ? sRowDrag : sRow, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) });
			if (_editLayout)
			{
				Rect rect = GUILayoutUtility.GetRect(24f, 28f, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(24f),
					GUILayout.Height(28f)
				});
				GUI.Label(rect, "≡", sHandle);
				if ((int)current.type == 0 && current.button == 0 && ((Rect)(ref rect)).Contains(current.mousePosition))
				{
					_drag = t;
					_dragList = list;
					current.Use();
				}
			}
			Rect rect2 = GUILayoutUtility.GetRect(28f, 28f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(28f),
				GUILayout.Height(28f)
			});
			GUI.DrawTexture(rect2, (Texture)(object)tSlot);
			DrawSprite(new Rect(((Rect)(ref rect2)).x + 2f, ((Rect)(ref rect2)).y + 2f, ((Rect)(ref rect2)).width - 4f, ((Rect)(ref rect2)).height - 4f), t.Icon);
			GUILayout.Space(6f);
			GUILayout.Label(t.Boss ? (t.Display + "  (босс)") : t.Display, sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) });
			string text = ((t.Kind == TrackKind.Resource) ? (t.Prefab + " · " + CatName(TypeDatabase.CategoryOf(t, _edit))) : t.Prefab);
			if (_edit.Overrides.ContainsKey(t.Prefab))
			{
				text += " · вручную";
			}
			GUILayout.Label(text, sDim, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (_editLayout)
			{
				if (GUILayout.Button("▲", sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
				{
					MoveBy(t, list, biome, cat, -1);
				}
				if (GUILayout.Button("▼", sButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
				{
					MoveBy(t, list, biome, cat, 1);
				}
			}
			else if (GUILayout.Button(flag ? "Видно" : "Скрыто", flag ? sOn : sOff, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
			{
				SetVisible(t, !flag);
			}
			GUILayout.EndHorizontal();
			AddTarget(biome, cat, t);
		}

		private static void SetVisible(TrackType t, bool v)
		{
			if (v == RadarTracker.DefaultVisible(t, _edit))
			{
				_edit.Overrides.Remove(t.Prefab);
			}
			else
			{
				_edit.Overrides[t.Prefab] = v;
			}
			_dirty = true;
		}

		private static void SetAll(List<TrackType> list, int biome, bool v)
		{
			foreach (TrackType item in list)
			{
				if (Matches(item) && (biome == int.MinValue || TypeDatabase.BiomeOf(item, _edit) == biome))
				{
					SetVisible(item, v);
				}
			}
		}

		private static bool Matches(TrackType t)
		{
			return string.IsNullOrEmpty(_search) || t.Display.IndexOf(_search, StringComparison.OrdinalIgnoreCase) >= 0 || t.Prefab.IndexOf(_search, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static string CatTitle(ResCategory c)
		{
			return c switch
			{
				ResCategory.Ore => "Руда и металлы", 
				ResCategory.Food => "Еда", 
				ResCategory.Pickable => "Собирательство", 
				ResCategory.Rock => "Камни", 
				_ => "Прочее", 
			};
		}

		private static string CatName(ResCategory c)
		{
			return c switch
			{
				ResCategory.Ore => "руда", 
				ResCategory.Food => "еда", 
				ResCategory.Pickable => "собирательство", 
				ResCategory.Rock => "камень", 
				_ => "прочее", 
			};
		}

		private static bool Toggle(string label, bool v, bool markDirty = true)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label, sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(360f) });
			bool flag = v;
			if (GUILayout.Button(v ? "Вкл" : "Выкл", v ? sOn : sOff, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
			{
				flag = !v;
			}
			GUILayout.EndHorizontal();
			if (markDirty && flag != v)
			{
				_dirty = true;
			}
			return flag;
		}

		private static bool ToggleBtn(string label, bool v)
		{
			if (GUILayout.Button((v ? "✔ " : "✖ ") + label, v ? sOn : sOff, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				_dirty = true;
				return !v;
			}
			return v;
		}

		private static float Slider(string label, float v, float min, float max, string fmt, bool markDirty = true)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label + ": " + v.ToString(fmt), sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) });
			float num = GUILayout.HorizontalSlider(v, min, max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			if (markDirty && Mathf.Abs(num - v) > 0.0001f)
			{
				_dirty = true;
			}
			return num;
		}

		private static void Header(string text)
		{
			GUILayout.Space(8f);
			GUILayout.Label(text, sHeader, Array.Empty<GUILayoutOption>());
		}

		private static void Line()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Space(4f);
			Rect rect = GUILayoutUtility.GetRect(1f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(1f)
			});
			GUI.DrawTexture(rect, (Texture)(object)tGold);
			GUILayout.Space(4f);
		}

		private static void Frame(Rect r, float t)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, t), (Texture)(object)tGold);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - t, ((Rect)(ref r)).width, t), (Texture)(object)tGold);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), (Texture)(object)tGold);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).xMax - t, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), (Texture)(object)tGold);
		}

		private static void DrawSprite(Rect r, Sprite s)
		{
			//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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s == (Object)null || (Object)(object)s.texture == (Object)null)
			{
				return;
			}
			if (!UvCache.TryGetValue(s, out var value))
			{
				Rect val;
				try
				{
					val = s.textureRect;
				}
				catch
				{
					val = s.rect;
				}
				Texture2D texture = s.texture;
				((Rect)(ref value))..ctor(((Rect)(ref val)).x / (float)((Texture)texture).width, ((Rect)(ref val)).y / (float)((Texture)texture).height, ((Rect)(ref val)).width / (float)((Texture)texture).width, ((Rect)(ref val)).height / (float)((Texture)texture).height);
				UvCache[s] = value;
			}
			GUI.DrawTextureWithTexCoords(r, (Texture)(object)s.texture, value);
		}

		private static Texture2D Tex(Color c)
		{
			//IL_0003: 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_0012: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(1, 1)
			{
				hideFlags = (HideFlags)61
			};
			val.SetPixel(0, 0, c);
			val.Apply();
			return val;
		}

		private static GUIStyle Btn(Color bg, Color hover, Color text)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			GUIStyle val = new GUIStyle(GUI.skin.button)
			{
				fontSize = 14,
				alignment = (TextAnchor)4
			};
			val.normal.background = Tex(bg);
			val.normal.textColor = text;
			val.hover.background = Tex(hover);
			val.hover.textColor = Color.white;
			val.active.background = Tex(hover * 1.2f);
			val.active.textColor = Color.white;
			return val;
		}

		private static void EnsureStyles()
		{
			//IL_0015: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00b8: 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_00d2: 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_00e8: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_013c: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Expected O, but got Unknown
			//IL_01ed: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Expected O, but got Unknown
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Expected O, but got Unknown
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Expected O, but got Unknown
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Expected O, but got Unknown
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Expected O, but got Unknown
			//IL_0412: Expected O, but got Unknown
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Expected O, but got Unknown
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Expected O, but got Unknown
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Expected O, but got Unknown
			//IL_04ec: Expected O, but got Unknown
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: Expected O, but got Unknown
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_059e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
			if (!_styles)
			{
				_styles = true;
				tGold = Tex(Gold);
				tSlot = Tex(new Color(0.16f, 0.13f, 0.1f, 1f));
				sPanel = new GUIStyle(GUI.skin.box);
				sPanel.normal.background = Tex(new Color(0.09f, 0.075f, 0.06f, 0.97f));
				sTitle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 22,
					fontStyle = (FontStyle)1
				};
				sTitle.normal.textColor = Gold;
				sHeader = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16,
					fontStyle = (FontStyle)1
				};
				sHeader.normal.textColor = Gold;
				sBiome = new GUIStyle(GUI.skin.button)
				{
					fontSize = 15,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)3,
					padding = new RectOffset(10, 10, 4, 4)
				};
				sBiome.normal.background = Tex(new Color(0.2f, 0.15f, 0.09f));
				sBiome.hover.background = Tex(new Color(0.28f, 0.21f, 0.12f));
				sBiome.normal.textColor = Gold;
				sBiome.hover.textColor = Color.white;
				sSub = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					fontStyle = (FontStyle)1,
					margin = new RectOffset(0, 0, 6, 2)
				};
				sSub.normal.textColor = new Color(0.78f, 0.62f, 0.32f);
				sLabel = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					alignment = (TextAnchor)3
				};
				sLabel.normal.textColor = Text;
				sDim = new GUIStyle(sLabel)
				{
					fontSize = 12,
					wordWrap = true
				};
				sDim.normal.textColor = Dim;
				sWarn = new GUIStyle(sLabel)
				{
					fontSize = 13
				};
				sWarn.normal.textColor = new Color(1f, 0.6f, 0.35f);
				sButton = Btn(new Color(0.22f, 0.17f, 0.12f), new Color(0.34f, 0.26f, 0.16f), Gold);
				sTab = Btn(new Color(0.15f, 0.12f, 0.09f), new Color(0.28f, 0.21f, 0.13f), Dim);
				sTabOn = Btn(new Color(0.42f, 0.31f, 0.15f), new Color(0.48f, 0.36f, 0.18f), Color.white);
				sOn = Btn(new Color(0.2f, 0.3f, 0.14f), new Color(0.26f, 0.38f, 0.18f), new Color(0.85f, 1f, 0.7f));
				sOff = Btn(new Color(0.18f, 0.14f, 0.12f), new Color(0.28f, 0.2f, 0.16f), Dim);
				sRow = new GUIStyle(GUI.skin.box)
				{
					padding = new RectOffset(6, 6, 3, 3),
					margin = new RectOffset(0, 0, 1, 1)
				};
				sRow.normal.background = Tex(new Color(0.13f, 0.11f, 0.085f, 1f));
				sHandle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 20,
					alignment = (TextAnchor)4
				};
				sHandle.normal.textColor = Gold;
				sRowDrag = new GUIStyle(sRow);
				sRowDrag.normal.background = Tex(new Color(0.3f, 0.22f, 0.1f, 1f));
				sDragLabel = new GUIStyle(GUI.skin.box)
				{
					fontSize = 14,
					alignment = (TextAnchor)3,
					padding = new RectOffset(8, 8, 3, 3)
				};
				sDragLabel.normal.background = Tex(new Color(0.42f, 0.31f, 0.15f, 0.95f));
				sDragLabel.normal.textColor = Color.white;
				sField = new GUIStyle(GUI.skin.textField)
				{
					fontSize = 14
				};
				sField.normal.background = Tex(new Color(0.05f, 0.04f, 0.03f));
				sField.focused.background = sField.normal.background;
				sField.normal.textColor = Text;
				sField.focused.textColor = Color.white;
			}
		}
	}
	internal class LayoutEntry
	{
		public int Biome;

		public int Category = -1;

		public int Order;
	}
	internal class RadarData
	{
		private const int FormatVersion = 3;

		public bool Enabled = true;

		public float MobRange = 60f;

		public float ResourceRange = 80f;

		public int MaxPins = 150;

		public float UpdateInterval = 0.5f;

		public bool ShowHostile = true;

		public bool ShowPassive = true;

		public bool ShowTamed = true;

		public bool ShowBosses = true;

		public int MinStars = 0;

		public bool ShowLevels = true;

		public bool CatOre = true;

		public bool CatPickable = true;

		public bool CatRock = false;

		public bool CatOther = false;

		public bool RememberResources = true;

		public Dictionary<string, LayoutEntry> Layout = new Dictionary<string, LayoutEntry>();

		public Dictionary<string, bool> Overrides = new Dictionary<string, bool>
		{
			{ "Pickable_Stone", false },
			{ "Pickable_Branch", false }
		};

		public void Write(ZPackage p)
		{
			p.Write(3);
			p.Write(Enabled);
			p.Write(MobRange);
			p.Write(ResourceRange);
			p.Write(MaxPins);
			p.Write(UpdateInterval);
			p.Write(ShowHostile);
			p.Write(ShowPassive);
			p.Write(ShowTamed);
			p.Write(ShowBosses);
			p.Write(MinStars);
			p.Write(ShowLevels);
			p.Write(CatOre);
			p.Write(CatPickable);
			p.Write(CatRock);
			p.Write(CatOther);
			p.Write(RememberResources);
			p.Write(Layout.Count);
			foreach (KeyValuePair<string, LayoutEntry> item in Layout)
			{
				p.Write(item.Key);
				p.Write(item.Value.Biome);
				p.Write(item.Value.Category);
				p.Write(item.Value.Order);
			}
			p.Write(Overrides.Count);
			foreach (KeyValuePair<string, bool> @override in Overrides)
			{
				p.Write(@override.Key);
				p.Write(@override.Value);
			}
		}

		public static RadarData Read(ZPackage p)
		{
			int num = p.ReadInt();
			if (num != 3)
			{
				MapRadarPlugin.Log.LogWarning((object)$"Неизвестная версия настроек {num}, ожидалась {3}.");
			}
			RadarData radarData = new RadarData();
			radarData.Enabled = p.ReadBool();
			radarData.MobRange = p.ReadSingle();
			radarData.ResourceRange = p.ReadSingle();
			radarData.MaxPins = p.ReadInt();
			radarData.UpdateInterval = p.ReadSingle();
			radarData.ShowHostile = p.ReadBool();
			radarData.ShowPassive = p.ReadBool();
			radarData.ShowTamed = p.ReadBool();
			radarData.ShowBosses = p.ReadBool();
			radarData.MinStars = p.ReadInt();
			radarData.ShowLevels = p.ReadBool();
			radarData.CatOre = p.ReadBool();
			radarData.CatPickable = p.ReadBool();
			radarData.CatRock = p.ReadBool();
			radarData.CatOther = p.ReadBool();
			if (num >= 2)
			{
				radarData.RememberResources = p.ReadBool();
			}
			if (num >= 3)
			{
				int num2 = p.ReadInt();
				for (int i = 0; i < num2; i++)
				{
					radarData.Layout[p.ReadString()] = new LayoutEntry
					{
						Biome = p.ReadInt(),
						Category = p.ReadInt(),
						Order = p.ReadInt()
					};
				}
			}
			radarData.Overrides = new Dictionary<string, bool>();
			int num3 = p.ReadInt();
			for (int j = 0; j < num3; j++)
			{
				radarData.Overrides[p.ReadString()] = p.ReadBool();
			}
			return radarData;
		}

		public RadarData Clone()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			Write(val);
			val.SetPos(0);
			return Read(val);
		}

		public string OverridesToString()
		{
			return string.Join(";", Overrides.Select((KeyValuePair<string, bool> kv) => kv.Key + ":" + (kv.Value ? "1" : "0")));
		}

		public string LayoutToString()
		{
			return string.Join(";", Layout.Select((KeyValuePair<string, LayoutEntry> kv) => $"{kv.Key}:{kv.Value.Biome}:{kv.Value.Category}:{kv.Value.Order}"));
		}

		public static Dictionary<string, LayoutEntry> ParseLayout(string s)
		{
			Dictionary<string, LayoutEntry> dictionary = new Dictionary<string, LayoutEntry>();
			if (string.IsNullOrWhiteSpace(s))
			{
				return dictionary;
			}
			string[] array = s.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string[] array2 = text.Split(':');
				if (array2.Length == 4 && int.TryParse(array2[1], out var result) && int.TryParse(array2[2], out var result2) && int.TryParse(array2[3], out var result3))
				{
					dictionary[array2[0].Trim()] = new LayoutEntry
					{
						Biome = result,
						Category = result2,
						Order = result3
					};
				}
			}
			return dictionary;
		}

		public static Dictionary<string, bool> ParseOverrides(string s)
		{
			Dictionary<string, bool> dictionary = new Dictionary<string, bool>();
			if (string.IsNullOrWhiteSpace(s))
			{
				return dictionary;
			}
			string[] array = s.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				int num = text.LastIndexOf(':');
				if (num > 0)
				{
					dictionary[text.Substring(0, num).Trim()] = text.Substring(num + 1).Trim() == "1";
				}
			}
			return dictionary;
		}
	}
	internal static class RadarSettings
	{
		public static RadarData Current = new RadarData();

		private static ConfigFile _cfg;

		private static bool _saving;

		private static ConfigEntry<bool> eRemember;

		private static ConfigEntry<bool> eEnabled;

		private static ConfigEntry<bool> eHostile;

		private static ConfigEntry<bool> ePassive;

		private static ConfigEntry<bool> eTamed;

		private static ConfigEntry<bool> eBosses;

		private static ConfigEntry<bool> eLevels;

		private static ConfigEntry<bool> eOre;

		private static ConfigEntry<bool> ePick;

		private static ConfigEntry<bool> eRock;

		private static ConfigEntry<bool> eOther;

		private static ConfigEntry<float> eMobRange;

		private static ConfigEntry<float> eResRange;

		private static ConfigEntry<float> eInterval;

		private static ConfigEntry<int> eMaxPins;

		private static ConfigEntry<int> eMinStars;

		private static ConfigEntry<string> eOverrides;

		private static ConfigEntry<string> eLayout;

		public static bool CanEdit => true;

		public static event Action Changed;

		public static void Bind(ConfigFile cfg)
		{
			_cfg = cfg;
			RadarData radarData = new RadarData();
			eEnabled = cfg.Bind<bool>("2. Радар", "Enabled", radarData.Enabled, "Радар включён");
			eMobRange = cfg.Bind<float>("2. Радар", "MobRange", radarData.MobRange, "Дальность пометки мобов (м)");
			eResRange = cfg.Bind<float>("2. Радар", "ResourceRange", radarData.ResourceRange, "Дальность пометки ресурсов (м)");
			eMaxPins = cfg.Bind<int>("2. Радар", "MaxPins", radarData.MaxPins, "Максимум меток одновременно (ближайшие)");
			eInterval = cfg.Bind<float>("2. Радар", "UpdateInterval", radarData.UpdateInterval, "Как часто обновлять метки (сек)");
			eHostile = cfg.Bind<bool>("2. Радар", "ShowHostile", radarData.ShowHostile, "Враждебные мобы");
			ePassive = cfg.Bind<bool>("2. Радар", "ShowPassive", radarData.ShowPassive, "Мирные животные (олени, кабаны...)");
			eTamed = cfg.Bind<bool>("2. Радар", "ShowTamed", radarData.ShowTamed, "Приручённые и призванные");
			eBosses = cfg.Bind<bool>("2. Радар", "ShowBosses", radarData.ShowBosses, "Боссы");
			eMinStars = cfg.Bind<int>("2. Радар", "MinStars", radarData.MinStars, "Показывать мобов только от N звёзд");
			eLevels = cfg.Bind<bool>("2. Радар", "ShowLevels", radarData.ShowLevels, "Показывать уровень мобов");
			eOre = cfg.Bind<bool>("2. Радар", "CategoryOre", radarData.CatOre, "Руда и металлолом");
			ePick = cfg.Bind<bool>("2. Радар", "CategoryPickable", radarData.CatPickable, "Собирательство (ягоды, грибы, кремень...)");
			eRock = cfg.Bind<bool>("2. Радар", "CategoryRock", radarData.CatRock, "Обычные камни");
			eOther = cfg.Bind<bool>("2. Радар", "CategoryOther", radarData.CatOther, "Прочее");
			eRemember = cfg.Bind<bool>("2. Радар", "RememberResources", radarData.RememberResources, "Запоминать найденные ресурсы навсегда (видны на всей карте). Выкл — только рядом с игроком");
			eOverrides = cfg.Bind<string>("2. Радар", "Overrides", radarData.OverridesToString(), "Ручные исключения: Префаб:1 (показать) / Префаб:0 (скрыть), через ;");
			eLayout = cfg.Bind<string>("2. Радар", "Layout", "", "Расстановка в меню (меняется в игре режимом «Расставить»): Префаб:биом:категория:порядок, через ;");
			Current = LoadLocal();
			cfg.SettingChanged += delegate(object _, SettingChangedEventArgs e)
			{
				if (!_saving)
				{
					object obj;
					if (e == null)
					{
						obj = null;
					}
					else
					{
						ConfigEntryBase changedSetting = e.ChangedSetting;
						obj = ((changedSetting != null) ? changedSetting.Definition.Section : null);
					}
					if (!((string?)obj != "2. Радар"))
					{
						Current = LoadLocal();
						NotifyChanged();
					}
				}
			};
		}

		public static RadarData LoadLocal()
		{
			return new RadarData
			{
				Enabled = eEnabled.Value,
				MobRange = eMobRange.Value,
				ResourceRange = eResRange.Value,
				MaxPins = eMaxPins.Value,
				UpdateInterval = eInterval.Value,
				ShowHostile = eHostile.Value,
				ShowPassive = ePassive.Value,
				ShowTamed = eTamed.Value,
				ShowBosses = eBosses.Value,
				MinStars = eMinStars.Value,
				ShowLevels = eLevels.Value,
				CatOre = eOre.Value,
				CatPickable = ePick.Value,
				CatRock = eRock.Value,
				CatOther = eOther.Value,
				RememberResources = eRemember.Value,
				Overrides = RadarData.ParseOverrides(eOverrides.Value),
				Layout = RadarData.ParseLayout(eLayout.Value)
			};
		}

		private static void SaveLocal(RadarData d)
		{
			_saving = true;
			try
			{
				eEnabled.Value = d.Enabled;
				eMobRange.Value = d.MobRange;
				eResRange.Value = d.ResourceRange;
				eMaxPins.Value = d.MaxPins;
				eInterval.Value = d.UpdateInterval;
				eHostile.Value = d.ShowHostile;
				ePassive.Value = d.ShowPassive;
				eTamed.Value = d.ShowTamed;
				eBosses.Value = d.ShowBosses;
				eMinStars.Value = d.MinStars;
				eLevels.Value = d.ShowLevels;
				eOre.Value = d.CatOre;
				ePick.Value = d.CatPickable;
				eRock.Value = d.CatRock;
				eOther.Value = d.CatOther;
				eRemember.Value = d.RememberResources;
				eOverrides.Value = d.OverridesToString();
				eLayout.Value = d.LayoutToString();
				_cfg.Save();
			}
			finally
			{
				_saving = false;
			}
		}

		public static void ApplyLocal(RadarData d)
		{
			Current = d;
			SaveLocal(d);
			NotifyChanged();
		}

		private static void NotifyChanged()
		{
			RadarTracker.MarkDirty();
			RadarSettings.Changed?.Invoke();
		}
	}
	internal static class RadarTracker
	{
		private class Entry
		{
			public PinData Pin;

			public int Stars;

			public int Count;

			public Sprite Icon;

			public TrackKind Kind;

			public TrackType Type;

			public Image Overlay;

			public Image Badge;

			public Transform UiRoot;

			public int UiChildCount = -1;

			public readonly List<Image> Foreign = new List<Image>();
		}

		private class Cluster
		{
			public int Key;

			public Vector3 Sum;

			public int Count;

			public TrackType Type;

			public int Stars;

			public Vector3 Pos => Sum / (float)Count;
		}

		private struct Candidate
		{
			public int Id;

			public Vector3 Pos;

			public float Dist;

			public TrackType Type;

			public int Stars;
		}

		private static readonly Dictionary<Component, TrackType> Resources = new Dictionary<Component, TrackType>();

		private static readonly Dictionary<int, TrackType> MobTypeCache = new Dictionary<int, TrackType>();

		private static readonly Dictionary<int, Entry> Pins = new Dictionary<int, Entry>();

		private static readonly List<Candidate> Cands = new List<Candidate>();

		private static readonly List<Cluster> Clusters = new List<Cluster>();

		private static readonly Dictionary<int, Cluster> ClusterByKey = new Dictionary<int, Cluster>();

		private static readonly HashSet<int> Keep = new HashSet<int>();

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

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

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

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

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

		private static Minimap _owner;

		private static float _timer;

		private static bool _dirty;

		private static readonly FieldRef<Pickable, bool> PickedRef = MakePickedRef();

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

		private static readonly FieldInfo FNameData = AccessTools.Field(typeof(PinData), "m_NamePinData");

		private static readonly FieldInfo FUpdateRequired = AccessTools.Field(typeof(Minimap), "m_pinUpdateRequired");

		private static readonly MethodInfo MDestroyMarker = AccessTools.Method(typeof(Minimap), "DestroyPinMarker", (Type[])null, (Type[])null);

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

		private static readonly Regex Suffix = new Regex("( x\\d+)?( \\[\\d+\\*\\])?$");

		public static bool DumpOnMapOpen;

		private static float _mapOpenTime;

		private static Sprite _transparent;

		private static bool _layoutLogged;

		private static Sprite _circle;

		private static Sprite Transparent
		{
			get
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Expected O, but got Unknown
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_transparent != (Object)null)
				{
					return _transparent;
				}
				Texture2D val = new Texture2D(4, 4, (TextureFormat)4, false)
				{
					hideFlags = (HideFlags)61
				};
				Color[] pixels = (Color[])(object)new Color[16];
				val.SetPixels(pixels);
				val.Apply();
				_transparent = Sprite.Create(val, new Rect(0f, 0f, 4f, 4f), new Vector2(0.5f, 0.5f));
				((Object)_transparent).hideFlags = (HideFlags)61;
				return _transparent;
			}
		}

		private static Sprite Circle
		{
			get
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_00fe: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: 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_0085: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_circle != (Object)null)
				{
					return _circle;
				}
				Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false)
				{
					hideFlags = (HideFlags)61
				};
				for (int i = 0; i < 32; i++)
				{
					for (int j = 0; j < 32; j++)
					{
						float num = (float)j - 16f + 0.5f;
						float num2 = (float)i - 16f + 0.5f;
						float num3 = Mathf.Sqrt(num * num + num2 * num2);
						Color val2 = (Color)((num3 < 12f) ? Color.white : ((num3 < 15f) ? new Color(0.1f, 0.08f, 0.05f, 1f) : Color.clear));
						val.SetPixel(j, i, val2);
					}
				}
				val.Apply();
				_circle = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f));
				((Object)_circle).hideFlags = (HideFlags)61;
				return _circle;
			}
		}

		private static FieldRef<Pickable, bool> MakePickedRef()
		{
			try
			{
				return AccessTools.FieldRefAccess<Pickable, bool>("m_picked");
			}
			catch
			{
				return null;
			}
		}

		public static void MarkDirty()
		{
			_dirty = true;
		}

		public static void MarkResourcesChanged()
		{
		}

		public static void RegisterResource(Component c)
		{
			if (!((Object)(object)c == (Object)null))
			{
				TrackType trackType = TypeDatabase.Get(c.gameObject);
				if (trackType != null && trackType.Kind == TrackKind.Resource)
				{
					Resources[c] = trackType;
				}
			}
		}

		public static bool DefaultVisible(TrackType t, RadarData d)
		{
			if (t.Kind == TrackKind.Mob)
			{
				return true;
			}
			switch (TypeDatabase.CategoryOf(t, d))
			{
			case ResCategory.Ore:
				return d.CatOre;
			case ResCategory.Food:
			case ResCategory.Pickable:
				return d.CatPickable;
			case ResCategory.Rock:
				return d.CatRock;
			default:
				return d.CatOther;
			}
		}

		public static bool IsVisible(TrackType t, RadarData d)
		{
			bool value;
			return d.Overrides.TryGetValue(t.Prefab, out value) ? value : DefaultVisible(t, d);
		}

		private static bool PassesMobFilters(Character c, TrackType t, RadarData d, out int stars)
		{
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Invalid comparison between Unknown and I4
			stars = Mathf.Max(0, c.GetLevel() - 1);
			if (t.Boss || c.IsBoss())
			{
				return d.ShowBosses;
			}
			if (c.IsTamed())
			{
				return d.ShowTamed;
			}
			Faction faction = c.GetFaction();
			if ((int)faction == 11)
			{
				return d.ShowTamed;
			}
			if (((int)faction == 1) ? (!d.ShowPassive) : (!d.ShowHostile))
			{
				return false;
			}
			return stars >= d.MinStars;
		}

		public static void Tick(float dt)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0716: Unknown result type (might be due to invalid IL or missing references)
			//IL_072a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_060d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0612: Unknown result type (might be due to invalid IL or missing references)
			//IL_0619: Unknown result type (might be due to invalid IL or missing references)
			//IL_0621: Unknown result type (might be due to invalid IL or missing references)
			//IL_0921: Unknown result type (might be due to invalid IL or missing references)
			//IL_0799: Unknown result type (might be due to invalid IL or missing references)
			//IL_079e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0762: Unknown result type (might be due to invalid IL or missing references)
			//IL_0769: Unknown result type (might be due to invalid IL or missing references)
			//IL_076e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0773: Unknown result type (might be due to invalid IL or missing references)
			//IL_0900: Unknown result type (might be due to invalid IL or missing references)
			//IL_0905: Unknown result type (might be due to invalid IL or missing references)
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance != (Object)(object)_owner)
			{
				Pins.Clear();
				_owner = instance;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)instance == (Object)null || (Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (_dirty)
			{
				ClearPins();
				_dirty = false;
				_timer = 0f;
			}
			_timer -= dt;
			if (_timer > 0f)
			{
				return;
			}
			RadarData current = RadarSettings.Current;
			_timer = Mathf.Max(0.1f, current.UpdateInterval);
			if (!current.Enabled)
			{
				ClearPins();
				return;
			}
			TypeDatabase.EnsureBiomes();
			Vector3 position = ((Component)localPlayer).transform.position;
			Cands.Clear();
			float num = current.MobRange * current.MobRange;
			if (MobTypeCache.Count > 4000)
			{
				MobTypeCache.Clear();
			}
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if ((Object)(object)allCharacter == (Object)null || allCharacter is Player || allCharacter.IsDead())
				{
					continue;
				}
				Vector3 position2 = ((Component)allCharacter).transform.position;
				float num2 = DistXZ2(position, position2);
				if (!(num2 > num))
				{
					int instanceID = ((Object)allCharacter).GetInstanceID();
					if (!MobTypeCache.TryGetValue(instanceID, out var value))
					{
						value = TypeDatabase.Get(((Component)allCharacter).gameObject);
						MobTypeCache[instanceID] = value;
					}
					if (value != null && TypeDatabase.IsFindable(value) && IsVisible(value, current) && PassesMobFilters(allCharacter, value, current, out var stars))
					{
						Cands.Add(new Candidate
						{
							Id = instanceID,
							Pos = position2,
							Dist = num2,
							Type = value,
							Stars = stars
						});
					}
				}
			}
			bool rememberResources = current.RememberResources;
			float num3 = current.ResourceRange * current.ResourceRange;
			Dead.Clear();
			LiveKeys.Clear();
			PickedKeys.Clear();
			foreach (KeyValuePair<Component, TrackType> resource in Resources)
			{
				Component key = resource.Key;
				if ((Object)(object)key == (Object)null)
				{
					Dead.Add(key);
				}
				else
				{
					if (!key.gameObject.activeInHierarchy)
					{
						continue;
					}
					Vector3 position3 = key.transform.position;
					float num4 = DistXZ2(position, position3);
					if (num4 > num3)
					{
						continue;
					}
					TrackType value2 = resource.Value;
					Pickable val = (Pickable)(object)((key is Pickable) ? key : null);
					bool flag = val != null && PickedRef != null && PickedRef.Invoke(val);
					string text = ResourceMemory.Key(value2.Prefab, position3);
					if (rememberResources)
					{
						LiveKeys.Add(text);
						if (flag)
						{
							PickedKeys.Add(text);
						}
						ResourceMemory.Remember(value2.Prefab, position3);
					}
					else if (!flag && IsVisible(value2, current))
					{
						Cands.Add(new Candidate
						{
							Id = text.GetHashCode(),
							Pos = position3,
							Dist = num4,
							Type = value2
						});
					}
				}
			}
			foreach (Component item in Dead)
			{
				Resources.Remove(item);
			}
			if (rememberResources)
			{
				if (ResourceMemory.CanForget)
				{
					float num5 = Mathf.Min(current.ResourceRange, 40f);
					float num6 = num5 * num5;
					ToForget.Clear();
					foreach (KeyValuePair<string, ResourceMemory.Spot> spot in ResourceMemory.Spots)
					{
						if (!LiveKeys.Contains(spot.Key) && !(DistXZ2(position, spot.Value.Pos) > num6) && (!((Object)(object)ZoneSystem.instance != (Object)null) || ZoneSystem.instance.IsZoneLoaded(spot.Value.Pos)))
						{
							ToForget.Add(spot.Key);
						}
					}
					foreach (string item2 in ToForget)
					{
						ResourceMemory.Forget(item2);
					}
				}
				foreach (KeyValuePair<string, ResourceMemory.Spot> spot2 in ResourceMemory.Spots)
				{
					if (!PickedKeys.Contains(spot2.Key) && TypeDatabase.Types.TryGetValue(spot2.Value.Prefab, out var value3) && IsVisible(value3, current))
					{
						Cands.Add(new Candidate
						{
							Id = spot2.Key.GetHashCode(),
							Pos = spot2.Value.Pos,
							Dist = DistXZ2(position, spot2.Value.Pos),
							Type = value3
						});
					}
				}
			}
			Cands.Sort((Candidate a, Candidate b) => a.Dist.CompareTo(b.Dist));
			float value4 = ClientSettings.ClusterRadius.Value;
			bool value5 = ClientSettings.ClusterMobs.Value;
			Clusters.Clear();
			ClusterByKey.Clear();
			foreach (Candidate cand in Cands)
			{
				bool flag2 = value4 >= 1f && (cand.Type.Kind == TrackKind.Resource || value5);
				int key2 = (flag2 ? CellKey(cand.Type.Prefab, cand.Stars, Mathf.FloorToInt(cand.Pos.x / value4), Mathf.FloorToInt(cand.Pos.z / value4)) : cand.Id);
				if (flag2 && ClusterByKey.TryGetValue(key2, out var value6))
				{
					Cluster cluster = value6;
					cluster.Sum += cand.Pos;
					value6.Count++;
					continue;
				}
				value6 = new Cluster
				{
					Key = key2,
					Sum = cand.Pos,
					Count = 1,
					Type = cand.Type,
					Stars = cand.Stars
				};
				Clusters.Add(value6);
				if (flag2)
				{
					ClusterByKey[key2] = value6;
				}
			}
			int num7 = Mathf.Max(1, current.MaxPins);
			int num8 = Mathf.Max(1, ClientSettings.MaxResourcePins.Value);
			Keep.Clear();
			for (int num9 = 0; num9 < Clusters.Count; num9++)
			{
				Cluster cluster2 = Clusters[num9];
				if (cluster2.Type.Kind == TrackKind.Mob)
				{
					if (num7-- <= 0)
					{
						continue;
					}
				}
				else if (num8-- <= 0)
				{
					continue;
				}
				Keep.Add(cluster2.Key);
				Sprite icon = TypeDatabase.GetIcon(cluster2.Type);
				if (Pins.TryGetValue(cluster2.Key, out var value7))
				{
					if (value7.Stars == cluster2.Stars && value7.Count == cluster2.Count)
					{
						value7.Pin.m_pos = cluster2.Pos;
						continue;
					}
					DeletePin(instance, value7.Pin);
				}
				PinData pin = CreatePin(instance, cluster2.Pos, PinName(cluster2, current));
				HideStandardIcon(pin, icon);
				Pins[cluster2.Key] = new Entry
				{
					Pin = pin,
					Stars = cluster2.Stars,
					Count = cluster2.Count,
					Icon = icon,
					Kind = cluster2.Type.Kind,
					Type = cluster2.Type
				};
			}
			ToRemove.Clear();
			foreach (int key3 in Pins.Keys)
			{
				if (!Keep.Contains(key3))
				{
					ToRemove.Add(key3);
				}
			}
			foreach (int item3 in ToRemove)
			{
				DeletePin(instance, Pins[item3].Pin);
				Pins.Remove(item3);
			}
		}

		private static List<PinData> PinList(Minimap mm)
		{
			return FPins?.GetValue(mm) as List<PinData>;
		}

		private static PinData CreatePin(Minimap mm, Vector3 pos, string name)
		{
			//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_004c: 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_0012: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			List<PinData> list = PinList(mm);
			if (list == null)
			{
				PinData val = mm.AddPin(pos, (PinType)3, name, false, false, 0L, default(PlatformUserID));
				HideStandardIcon(val, null);
				OurPins.Add(val);
				return val;
			}
			PinData val2 = new PinData
			{
				m_type = (PinType)3,
				m_name = (name ?? ""),
				m_pos = pos,
				m_icon = Transparent,
				m_save = false,
				m_checked = false
			};
			if (!string.IsNullOrEmpty(val2.m_name))
			{
				bool flag = false;
				if (FNameData != null)
				{
					try
					{
						FNameData.SetValue(val2, Activator.CreateInstance(FNameData.FieldType, val2));
						flag = true;
					}
					catch
					{
					}
				}
				if (!flag && FNameData != null)
				{
					val2.m_name = "";
				}
			}
			list.Add(val2);
			FUpdateRequired?.SetValue(mm, true);
			OurPins.Add(val2);
			return val2;
		}

		private static void DeletePin(Minimap mm, PinData pin)
		{
			if ((Object)(object)mm == (Object)null || pin == null)
			{
				return;
			}
			OurPins.Remove(pin);
			List<PinData> list = PinList(mm);
			if (list == null)
			{
				mm.RemovePin(pin);
				return;
			}
			try
			{
				if (MDestroyMarker != null)
				{
					MDestroyMarker.Invoke(mm, new object[1] { pin });
				}
				else if ((Object)(object)pin.m_uiElement != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)pin.m_uiElement).gameObject);
				}
			}
			catch (Exception ex)
			{
				MapRadarPlugin.Log.LogDebug((object)("DestroyPinMarker: " + ex.Message));
			}
			list.Remove(pin);
			FUpdateRequired?.SetValue(mm, true);
		}

		public static int CleanupLegacyPins()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Invalid comparison between Unknown and I4
			Minimap instance = Minimap.instance;
			List<PinData> list = (((Object)(object)instance != (Object)null) ? PinList(instance) : null);
			if (list == null)
			{
				return 0;
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (TrackType value in TypeDatabase.Types.Values)
			{
				hashSet.Add(value.Display);
			}
			List<PinData> list2 = new List<PinData>();
			foreach (PinData item2 in list)
			{
				if (!OurPins.Contains(item2) && (int)item2.m_type == 3 && !string.IsNullOrEmpty(item2.m_name))
				{
					string item = Suffix.Replace(item2.m_name, "");
					if (hashSet.Contains(item))
					{
						list2.Add(item2);
					}
				}
			}
			foreach (PinData item3 in list2)
			{
				instance.RemovePin(item3);
			}
			MapRadarPlugin.Log.LogInfo((object)$"MapRadar: удалено старых копий меток: {list2.Count}");
			return list2.Count;
		}

		public static void DiagTick(float dt)
		{
			if (!DumpOnMapOpen)
			{
				return;
			}
			if (!Minimap.IsOpen())
			{
				_mapOpenTime = 0f;
				return;
			}
			_mapOpenTime += dt;
			if (!(_mapOpenTime < 2f))
			{
				DumpOnMapOpen = false;
				DumpMapToLog();
				MessageHud instance = MessageHud.instance;
				if (instance != null)
				{
					instance.ShowMessage((MessageType)2, "MapRadar: карта записана в лог", 0, (Sprite)null, false, true);
				}
			}
		}

		public static void DumpMapToLog()
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				MapRadarPlugin.Log.LogWarning((object)"MapRadar диагностика: карты нет");
				return;
			}
			StringBuilder stringBuilder = new StringBuilder("MapRadar ДИАГНОСТИКА КАРТЫ\n");
			HashSet<Transform> hashSet = new HashSet<Transform>();
			FieldInfo[] fields = typeof(Minimap).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				object value;
				try
				{
					value = fieldInfo.GetValue(instance);
				}
				catch
				{
					continue;
				}
				Component val = (Component)((value is Component) ? value : null);
				object obj2;
				if (val == null)
				{
					GameObject val2 = (GameObject)((value is GameObject) ? value : null);
					obj2 = ((val2 != null) ? val2.transform : null);
				}
				else
				{
					obj2 = val.transform;
				}
				Transform val3 = (Transform)obj2;
				if ((Object)(object)val3 != (Object)null)
				{
					hashSet.Add(val3);
				}
			}
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			HashSet<Image> hashSet2 = new HashSet<Image>();
			foreach (Transform item in hashSet)
			{
				Image[] componentsInChildren = ((Component)item).GetComponentsInChildren<Image>(false);
				foreach (Image val4 in componentsInChildren)
				{
					if (hashSet2.Add(val4) && ((Behaviour)val4).enabled && !(((Graphic)val4).color.a < 0.05f))
					{
						Transform transform = ((Component)val4).transform;
						string text = ((Object)transform).name;
						if ((Object)(object)transform.parent != (Object)null)
						{
							text = ((Object)transform.parent).name + "/" + text;
						}
						if ((Object)(object)transform.parent != (Object)null && (Object)(object)transform.parent.parent != (Object)null)
						{
							text = ((Object)transform.parent.parent).name + "/" + text;
						}
						string key = string.Format("{0}  sprite={1}  color={2}", text, ((Object)(object)val4.sprite != (Object)null) ? ((Object)val4.sprite).name : "null", ((Graphic)val4).color);
						dictionary.TryGetValue(key, out var value2);
						dictionary[key] = value2 + 1;
					}
				}
			}
			stringBuilder.Append("Видимые картинки (кол-во x путь):\n");
			foreach (KeyValuePair<string, int> item2 in dictionary)
			{
				stringBuilder.Append("  ").Append(item2.Value).Append(" x ")
					.Append(item2.Key)
					.Append('\n');
			}
			List<PinData> list = PinList(instance);
			if (list != null)
			{
				int num = 0;
				int num2 = 0;
				stringBuilder.Append("Чужие метки:\n");
				foreach (PinData item3 in list)
				{
					if (OurPins.Contains(item3))
					{
						num++;
						continue;
					}
					num2++;
					if (num2 <= 60)
					{
						stringBuilder.Append(string.Format("  type={0} name='{1}' save={2} owner={3} icon={4}\n", item3.m_type, item3.m_name, item3.m_save, item3.m_ownerID, ((Object)(object)item3.m_icon != (Object)null) ? ((Object)item3.m_icon).name : "null"));
					}
				}
				stringBuilder.Append($"Всего меток: {list.Count}, MapRadar: {num}, чужих: {num2}\n");
			}
			MapRadarPlugin.Log.LogInfo((object)stringBuilder.ToString());
		}

		private static int CellKey(string prefab, int stars, int cx, int cz)
		{
			int hashCode = prefab.GetHashCode();
			hashCode = (hashCode * 397) ^ stars;
			hashCode = (hashCode * 397) ^ (cx * 73856093);
			return (hashCode * 397) ^ (cz * 19349663);
		}

		private static void HideStandardIcon(PinData pin, Sprite icon)
		{
			if (pin != null)
			{
				pin.m_icon = Transparent;
				if ((Object)(object)pin.m_iconElement != (Object)null)
				{
					pin.m_iconElement.sprite = Transparent;
				}
			}
		}

		private static string PinName(Cluster c, RadarData d)
		{
			if (!ClientSettings.NamesOnLargeMap.Value)
			{
				return "";
			}
			string text = c.Type.Display;
			if (c.Count > 1)
			{
				text += $" x{c.Count}";
			}
			if (c.Type.Kind == TrackKind.Mob && d.ShowLevels && c.Stars > 0)
			{
				text += $" [{c.Stars}*]";
			}
			return text;
		}

		private static void ClearPins()
		{
			if ((Object)(object)_owner != (Object)null)
			{
				foreach (Entry value in Pins.Values)
				{
					DeletePin(_owner, value.Pin);
				}
			}
			Pins.Clear();
		}

		public static void StylePins()
		{
			//IL_00ee: 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)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_042e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
			if (Pins.Count == 0)
			{
				return;
			}
			RadarData current = RadarSettings.Current;
			bool flag = current.ShowLevels && ClientSettings.ColorByLevel.Value;
			float value = ClientSettings.MobIconScale.Value;
			float value2 = ClientSettings.ResourceIconScale.Value;
			foreach (Entry value3 in Pins.Values)
			{
				PinData pin = value3.Pin;
				if (pin == null)
				{
					continue;
				}
				if ((Object)(object)value3.Icon == (Object)null && value3.Type != null)
				{
					value3.Icon = TypeDatabase.GetIcon(value3.Type);
				}
				if ((Object)(object)pin.m_iconElement == (Object)null)
				{
					continue;
				}
				Color val = ((value3.Kind == TrackKind.Mob && flag) ? StarColor(value3.Stars) : Color.white);
				if ((Object)(object)pin.m_icon != (Object)(object)Transparent)
				{
					pin.m_icon = Transparent;
				}
				if ((Object)(object)pin.m_iconElement.sprite != (Object)(object)Transparent)
				{
					pin.m_iconElement.sprite = Transparent;
				}
				Transform val2 = (Transform)(((Object)(object)pin.m_uiElement != (Object)null) ? ((object)pin.m_uiElement) : ((object)((Component)pin.m_iconElement).transform));
				Transform val3 = val2.Find("sl");
				if ((Object)(object)val3 != (Object)null && ((Component)val3).gameObject.activeSelf)
				{
					((Component)val3).gameObject.SetActive(false);
				}
				int num = CountChildren(val2);
				if ((Object)(object)value3.UiRoot != (Object)(object)val2 || value3.UiChildCount != num)
				{
					value3.UiRoot = val2;
					value3.UiChildCount = num;
					value3.Foreign.Clear();
					Image[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Image>(true);
					foreach (Image val4 in componentsInChildren)
					{
						if (((Object)((Component)val4).gameObject).name != "MapRadarIcon" && ((Object)((Component)val4).gameObject).name != "MapRadarStars")
						{
							value3.Foreign.Add(val4);
						}
					}
					LogPinLayoutOnce(val2);
				}
				foreach (Image item in value3.Foreign)
				{
					if (!((Object)(object)item == (Object)null))
					{
						if (((Behaviour)item).enabled)
						{
							((Behaviour)item).enabled = false;
						}
						((Graphic)item).color = Color.clear;
					}
				}
				bool flag2 = (Object)(object)value3.Icon != (Object)null;
				RectTransform rectTransform = ((Graphic)pin.m_iconElement).rectTransform;
				if ((Object)(object)value3.Overlay != (Object)null && (Object)(object)((Component)value3.Overlay).transform.parent != (Object)(object)rectTransform)
				{
					Object.Destroy((Object)(object)((Component)value3.Overlay).gameObject);
					value3.Overlay = null;
				}
				if ((Object)(object)value3.Badge != (Object)null && (Object)(object)((Component)value3.Badge).transform.parent != (Object)(object)rectTransform)
				{
					Object.Destroy((Object)(object)((Component)value3.Badge).gameObject);
					value3.Badge = null;
				}
				if ((Object)(object)value3.Overlay == (Object)null)
				{
					value3.Overlay = MakeImage("MapRadarIcon", ((Graphic)pin.m_iconElement).rectTransform, Vector2.zero, Vector2.one);
				}
				((Behaviour)value3.Overlay).enabled = true;
				if (flag2)
				{
					if ((Object)(object)value3.Overlay.sprite != (Object)(object)value3.Icon)
					{
						value3.Overlay.sprite = value3.Icon;
					}
					SetAnchors(value3.Overlay, Vector2.zero, Vector2.one);
					((Graphic)value3.Overlay).color = Color.white;
				}
				else
				{
					if ((Object)(object)value3.Overlay.sprite != (Object)(object)Circle)
					{
						value3.Overlay.sprite = Circle;
					}
					SetAnchors(value3.Overlay, new Vector2(0.2f, 0.2f), new Vector2(0.8f, 0.8f));
					((Graphic)value3.Overlay).color = (Color)((value3.Kind != TrackKind.Mob) ? new Color(0.8f, 0.8f, 0.8f) : ((value3.Stars > 0 && flag) ? val : new Color(0.95f, 0.45f, 0.4f)));
				}
				bool flag3 = flag2 && value3.Kind == TrackKind.Mob && flag && value3.Stars > 0;
				if (flag3 && (Object)(object)value3.Badge == (Object)null)
				{
					value3.Badge = MakeImage("MapRadarStars", ((Graphic)pin.m_iconElement).rectTransform, new Vector2(0.6f, 0f), new Vector2(1.05f, 0.45f), Circle);
				}
				if ((Object)(object)value3.Badge != (Object)null)
				{
					((Behaviour)value3.Badge).enabled = flag3;
					((Graphic)value3.Badge).color = val;
				}
				if ((Object)(object)pin.m_uiElement != (Object)null)
				{
					float num2 = ((value3.Kind == TrackKind.Mob) ? value : value2);
					num2 *= 1f + (float)Mathf.Min(value3.Count - 1, 10) * 0.04f;
					((Transform)pin.m_uiElement).localScale = Vector3.one * num2;
				}
			}
		}

		private static int CountChildren(Transform t)
		{
			int num = t.childCount;
			for (int i = 0; i < t.childCount; i++)
			{
				num += CountChildren(t.GetChild(i));
			}
			return num;
		}

		private static void LogPinLayoutOnce(Transform root)
		{
			if (_layoutLogged)
			{
				return;
			}
			_layoutLogged = true;
			StringBuilder stringBuilder = new StringBuilder("MapRadar: структура метки карты:");
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				stringBuilder.Append("\n  ").Append(((Object)(object)val == (Object)(object)root) ? ((Object)val).name : (((Object)val.parent).name + "/" + ((Object)val).name));
				Component[] components = ((Component)val).GetComponents<Component>();
				foreach (Component val2 in components)
				{
					if (!(val2 is Transform))
					{
						stringBuilder.Append(" [").Append(((object)val2).GetType().Name).Append(']');
					}
				}
			}
			MapRadarPlugin.Log.LogInfo((object)stringBuilder.ToString());
		}

		private static void SetAnchors(Image img, Vector2 min, Vector2 max)
		{
			//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_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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			RectTransform rectTransform = ((Graphic)img).rectTransform;
			if (!(rectTransform.anchorMin == min) || !(rectTransform.anchorMax == max))
			{
				rectTransform.anchorMin = min;
				rectTransform.anchorMax = max;
				rectTransform.offsetMin = Vector2.zero;
				rectTransform.offsetMax = Vector2.zero;
			}
		}

		private static Image MakeImage(string name, RectTransform parent, Vector2 anchorMin, Vector2 anchorMax, Sprite sprite = null)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_003e: 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_004e: 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)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent((Transform)(object)parent, false);
			val2.anchorMin = anchorMin;
			val2.anchorMax = anchorMax;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			Image component = val.GetComponent<Image>();
			((Graphic)component).raycastTarget = false;
			component.preserveAspect = true;
			component.sprite = sprite;
			return component;
		}

		public static Color StarColor(int stars)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(stars switch
			{
				0 => Color.white, 
				1 => new Color(1f, 0.85f, 0.2f), 
				2 => new Color(1f, 0.5f, 0.1f), 
				3 => new Color(1f, 0.2f, 0.2f), 
				_ => new Color(0.8f, 0.35f, 1f), 
			});
		}

		private static float DistXZ2(Vector3 a, Vector3 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			float num = a.x - b.x;
			float num2 = a.z - b.z;
			return num * num + num2 * num2;
		}
	}
	internal static class ResourceMemory
	{
		public class Spot
		{
			public string Prefab;

			public Vector3 Pos;
		}

		public static readonly Dictionary<string, Spot> Spots = new Dictionary<string, Spot>();

		private static string _fileKey;

		private static bool _dirty;

		private static float _saveTimer;

		private static float _sinceLoad;

		public static int Count => Spots.Count;

		private static string Folder => Path.Combine(Paths.ConfigPath, "MapRadar");

		public static bool CanForget => _sinceLoad > 15f;

		public static string Key(string prefab, Vector3 pos)
		{
			//IL_0014: 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)
			return prefab + "|" + Mathf.RoundToInt(pos.x * 2f) + "|" + Mathf.RoundToInt(pos.z * 2f);
		}

		public static void Tick(float dt)
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				_sinceLoad = 0f;
				return;
			}
			_sinceLoad += dt;
			string text = CurrentFileKey();
			if (text != null)
			{
				if (text != _fileKey)
				{
					Save();
					Load(text);
				}
				_saveTimer += dt;
				if (_dirty && _saveTimer > 30f)
				{
					Save();
				}
			}
		}

		public static void Remember(string prefab, Vector3 pos)
		{
			//IL_0010: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			if (_fileKey != null)
			{
				string key = Key(prefab, pos);
				if (!Spots.ContainsKey(key))
				{
					Spots[key] = new Spot
					{
						Prefab = prefab,
						Pos = pos
					};
					_dirty = true;
					RadarTracker.MarkResourcesChanged();
				}
			}
		}

		public static void Forget(string key)
		{
			if (Spots.Remove(key))
			{
				_dirty = true;
				RadarTracker.MarkResourcesChanged();
			}
		}

		public static void ForgetAll()
		{
			Spots.Clear();
			_dirty = true;
			Save();
			RadarTracker.MarkDirty();
		}

		public static void Unload()
		{
			Save();
			Spots.Clear();
			_fileKey = null;
			_sinceLoad = 0f;
		}

		public static void Save()