Decompiled source of SeneaL Radar v1.0.1

plugins/SeneaL-Radar/SeneaL-Radar.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SeneaLUI.Components;
using SeneaLUI.Core;
using SeneaLUI.Net;
using SeneaLUI.Theme;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: 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 SeneaLUI.Radar
{
	public sealed class Blips
	{
		public sealed class Layer
		{
			private readonly bool _circle;

			private readonly RectTransform[] _rt = (RectTransform[])(object)new RectTransform[160];

			private readonly Image[] _img = (Image[])(object)new Image[160];

			private readonly Image[] _ring = (Image[])(object)new Image[160];

			private readonly Image[] _icon = (Image[])(object)new Image[160];

			private readonly byte[] _drawn = new byte[160];

			private readonly Vector2[] _at = (Vector2[])(object)new Vector2[160];

			private int _made;

			private int _used;

			private Minimap _mm;

			private RawImage _map;

			private RectTransform _root;

			private Canvas _canvas;

			private bool _shown = true;

			private bool _probed;

			public RectTransform Root => _root;

			public int Made => _made;

			public Layer(bool circle)
			{
				_circle = circle;
			}

			public void Build(Minimap mm, RawImage map, string name)
			{
				Clear();
				_mm = mm;
				_map = map;
				_root = Ui.Stretch((Transform)(object)((Graphic)map).rectTransform, name, 0f);
				_canvas = ((Graphic)map).canvas;
				_shown = true;
				_probed = false;
				((Transform)_root).SetAsFirstSibling();
			}

			public void Clear()
			{
				if ((Object)(object)_root != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)_root).gameObject);
				}
				_root = null;
				_made = 0;
				_used = 0;
			}

			public void Show(bool on)
			{
				if (_shown != on && !((Object)(object)_root == (Object)null))
				{
					_shown = on;
					((Component)_root).gameObject.SetActive(on);
				}
			}

			public RectTransform Anchor(int i)
			{
				if (i >= _made)
				{
					return null;
				}
				return _rt[i];
			}

			public int Hover(Vector2 screen)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_root == (Object)null || !_shown || !((Component)_root).gameObject.activeInHierarchy)
				{
					return -1;
				}
				Camera val = (((Object)(object)_canvas != (Object)null && (int)_canvas.renderMode != 0) ? _canvas.worldCamera : null);
				Vector2 val2 = default(Vector2);
				if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(_root, screen, val, ref val2))
				{
					return -1;
				}
				Vector2 val3 = val2;
				Rect rect = _root.rect;
				Vector2 val4 = val3 - ((Rect)(ref rect)).min;
				int result = -1;
				float num = float.MaxValue;
				for (int i = 0; i < _used && i < _made; i++)
				{
					byte b = _drawn[i];
					if (b != byte.MaxValue)
					{
						float num2 = Mathf.Max(9f, Sizes[b] * 0.5f + 5f);
						Vector2 val5 = val4 - _at[i];
						float sqrMagnitude = ((Vector2)(ref val5)).sqrMagnitude;
						if (sqrMagnitude <= num2 * num2 && sqrMagnitude < num)
						{
							num = sqrMagnitude;
							result = i;
						}
					}
				}
				return result;
			}

			public void Place(Transform[] tf, byte[] kinds, int count, float now)
			{
				//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_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0277: Unknown result type (might be due to invalid IL or missing references)
				//IL_027c: Unknown result type (might be due to invalid IL or missing references)
				//IL_022d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0232: Unknown result type (might be due to invalid IL or missing references)
				//IL_0378: Unknown result type (might be due to invalid IL or missing references)
				//IL_0382: Unknown result type (might be due to invalid IL or missing references)
				//IL_0387: Unknown result type (might be due to invalid IL or missing references)
				//IL_038c: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0417: Unknown result type (might be due to invalid IL or missing references)
				//IL_0449: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_root == (Object)null)
				{
					return;
				}
				Show(on: true);
				Rect uvRect = _map.uvRect;
				Rect rect = ((Graphic)_map).rectTransform.rect;
				float width = ((Rect)(ref rect)).width;
				float height = ((Rect)(ref rect)).height;
				float num = 1f / (_mm.m_pixelSize * (float)_mm.m_textureSize);
				float num2 = width / ((Rect)(ref uvRect)).width;
				float num3 = height / ((Rect)(ref uvRect)).height;
				float num4 = width * 0.5f;
				float num5 = height * 0.5f;
				float num6 = Mathf.Min(num4, num5) - 2f;
				if (!_probed && count > 0)
				{
					_probed = true;
					Debug.Log((object)("[Radar] " + (_circle ? "small" : "large") + " layer: map " + width.ToString("0") + "x" + height.ToString("0") + ", uv " + ((Rect)(ref uvRect)).x.ToString("0.000") + "," + ((Rect)(ref uvRect)).y.ToString("0.000") + " " + ((Rect)(ref uvRect)).width.ToString("0.000") + "x" + ((Rect)(ref uvRect)).height.ToString("0.000") + ", pixel " + _mm.m_pixelSize + " texture " + _mm.m_textureSize + ", edge " + num6.ToString("0") + ", creatures " + count + ", root active " + ((Component)_root).gameObject.activeInHierarchy + ", scale " + ((Transform)_root).lossyScale.x.ToString("0.00")));
				}
				Vector2 val2 = default(Vector2);
				for (int i = 0; i < count; i++)
				{
					Transform val = tf[i];
					if ((Object)(object)val == (Object)null)
					{
						Hide(i);
						continue;
					}
					Vector3 position = val.position;
					float num7 = (position.x * num + 0.5f - ((Rect)(ref uvRect)).xMin) * num2;
					float num8 = (position.z * num + 0.5f - ((Rect)(ref uvRect)).yMin) * num3;
					byte b = kinds[i];
					float num9 = Sizes[b] * 0.5f;
					if (_circle)
					{
						float num10 = num7 - num4;
						float num11 = num8 - num5;
						float num12 = num6 - num9;
						if (num10 * num10 + num11 * num11 > num12 * num12)
						{
							Hide(i);
							continue;
						}
					}
					else if (num7 < 0f - num9 || num8 < 0f - num9 || num7 > width + num9 || num8 > height + num9)
					{
						Hide(i);
						continue;
					}
					while (i >= _made)
					{
						Make();
					}
					if (_drawn[i] != b)
					{
						Dress(i, b);
					}
					if (b == 5 || b == 7 || b == 8)
					{
						Animate(i, b, now);
					}
					((Vector2)(ref val2))..ctor(num7, num8);
					Vector2 val3 = val2 - _at[i];
					if (!(((Vector2)(ref val3)).sqrMagnitude <= 0.0025f))
					{
						_at[i] = val2;
						_rt[i].anchoredPosition = val2;
					}
					if (b != 9)
					{
						continue;
					}
					Vector3 forward = val.forward;
					if (forward.x * forward.x + forward.z * forward.z > 0.01f)
					{
						float num13 = Mathf.Atan2(forward.z, forward.x) * 57.29578f;
						if (Mathf.Abs(Mathf.DeltaAngle(((Transform)_rt[i]).localEulerAngles.z, num13)) > 4f)
						{
							((Transform)_rt[i]).localRotation = Quaternion.Euler(0f, 0f, num13);
						}
					}
				}
				for (int j = count; j < _used; j++)
				{
					Hide(j);
				}
				_used = count;
			}

			private void Dress(int i, byte kind)
			{
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_011d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0171: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				RectTransform val = _rt[i];
				if (_drawn[i] == byte.MaxValue)
				{
					((Component)val).gameObject.SetActive(true);
				}
				if (_drawn[i] == 9 && kind != 9)
				{
					((Transform)val).localRotation = Quaternion.identity;
				}
				_drawn[i] = kind;
				float num = Sizes[kind] * 1.4545455f;
				Image obj = _img[i];
				obj.sprite = SpriteOf(kind);
				((Graphic)obj).color = Colors[kind];
				val.sizeDelta = new Vector2(num, num);
				Sprite val2 = (Sprite)(kind switch
				{
					3 => Icons.Get("coins"), 
					8 => Icons.Get("star"), 
					_ => null, 
				});
				Image val3 = _icon[i];
				bool flag = (Object)(object)val2 != (Object)null;
				if (((Component)val3).gameObject.activeSelf != flag)
				{
					((Component)val3).gameObject.SetActive(flag);
				}
				if (flag)
				{
					float num2 = Sizes[kind] * ((kind == 8) ? 0.56f : 0.6f);
					val3.sprite = val2;
					((Graphic)val3).color = ((kind == 8) ? Palette.Gold : Palette.Parchment);
					((Graphic)val3).rectTransform.sizeDelta = new Vector2(num2, num2);
				}
				bool flag2 = kind == 5 || kind == 7 || kind == 8;
				Image val4 = _ring[i];
				if (((Component)val4).gameObject.activeSelf != flag2)
				{
					((Component)val4).gameObject.SetActive(flag2);
				}
				if (flag2)
				{
					((Graphic)val4).color = ((kind == 8) ? Halo : Ping);
				}
				if ((kind >= 6 && kind != 9) || kind == 3)
				{
					((Transform)val).SetAsLastSibling();
				}
			}

			private void Animate(int i, byte kind, float now)
			{
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				bool flag = kind == 8;
				float num = (flag ? 2.2f : 1.15f);
				float num2 = (now + (float)i * 0.37f) / num;
				num2 -= Mathf.Floor(num2);
				float num3 = Sizes[kind] * (1f + num2 * (flag ? 0.9f : 1.6f)) * 1.4545455f;
				Image obj = _ring[i];
				Color color = ((Graphic)obj).color;
				color.a = (1f - num2) * (1f - num2) * (flag ? 0.6f : 0.85f);
				((Graphic)obj).color = color;
				((Graphic)obj).rectTransform.sizeDelta = new Vector2(num3, num3);
			}

			private void Make()
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_014a: Unknown result type (might be due to invalid IL or missing references)
				//IL_014f: Unknown result type (might be due to invalid IL or missing references)
				RectTransform val = Ui.Node((Transform)(object)_root, "b" + _made);
				val.anchorMin = Vector2.zero;
				val.anchorMax = Vector2.zero;
				val.pivot = new Vector2(0.5f, 0.5f);
				RectTransform val2 = Ui.Center((Transform)(object)val, "ring", 0f, 0f, 10f, 10f);
				Image val3 = Ui.Img(val2, Sprites.Ring, Color.white);
				Image val4 = Ui.Img(Ui.Stretch((Transform)(object)val, "body", 0f), Sprites.Disc, Color.white);
				RectTransform obj = Ui.Center((Transform)(object)val, "icon", 0f, 0f, 10f, 10f);
				Image val5 = Ui.Img(obj, (Sprite)null, Color.white);
				val5.preserveAspect = true;
				((Component)val2).gameObject.SetActive(false);
				((Component)obj).gameObject.SetActive(false);
				_rt[_made] = val;
				_img[_made] = val4;
				_ring[_made] = val3;
				_icon[_made] = val5;
				_drawn[_made] = byte.MaxValue;
				_at[_made] = new Vector2(float.NaN, float.NaN);
				_made++;
				((Component)val).gameObject.SetActive(false);
			}

			private void Hide(int i)
			{
				if (i < _made && _drawn[i] != byte.MaxValue)
				{
					_drawn[i] = byte.MaxValue;
					((Component)_rt[i]).gameObject.SetActive(false);
				}
			}

			public bool Dot(int i, out Vector2 at, out byte kind, out RectTransform rt)
			{
				//IL_0001: 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)
				at = default(Vector2);
				kind = byte.MaxValue;
				rt = null;
				if (i >= _made || _drawn[i] == byte.MaxValue)
				{
					return false;
				}
				at = _at[i];
				kind = _drawn[i];
				rt = _rt[i];
				return true;
			}
		}

		public const string SmallName = "SeneaL.Radar";

		public const string LargeName = "SeneaL.Radar.Large";

		public const byte Animal = 0;

		public const byte Pet = 1;

		public const byte Neutral = 2;

		public const byte Merchant = 3;

		public const byte Hostile = 4;

		public const byte Hunting = 5;

		public const byte Elite = 6;

		public const byte EliteHunting = 7;

		public const byte Boss = 8;

		public const byte Swimmer = 9;

		public const byte Hidden = byte.MaxValue;

		public const float EliteHealth = 500f;

		private const int Max = 160;

		private const float ScanEvery = 0.25f;

		public static readonly Color[] Colors = (Color[])(object)new Color[10]
		{
			Palette.Rgba(239, 230, 211, 0.78f),
			Palette.Hex(9425002, 1f),
			Palette.Hex(8374488, 1f),
			Palette.Hex(8374488, 1f),
			Palette.Hex(14241855, 1f),
			Palette.Hex(16734780, 1f),
			Palette.Hex(13121322, 1f),
			Palette.Hex(16730670, 1f),
			Palette.Gold,
			Palette.Hex(7322098, 1f)
		};

		public static readonly float[] Sizes = new float[10] { 6f, 8f, 8f, 20f, 8f, 9f, 13f, 14f, 24f, 14f };

		public static readonly List<Trader> Traders = new List<Trader>(8);

		private static readonly Color Ping = new Color(1f, 0.36f, 0.24f, 1f);

		private static readonly Color Halo = Palette.Gold;

		private static readonly Dictionary<string, Sprite> Faces = new Dictionary<string, Sprite>(64);

		private readonly Transform[] _tf = (Transform[])(object)new Transform[160];

		private readonly byte[] _kind = new byte[160];

		private readonly Layer _small = new Layer(circle: true);

		private readonly Layer _large = new Layer(circle: false);

		private readonly Tip _tip = new Tip();

		private readonly Func<Tip> _tipFn;

		private int _count;

		private Minimap _mm;

		private float _scanAt;

		private Transform _hoverTf;

		private byte _hoverKind = byte.MaxValue;

		private Character _hoverC;

		private Trader _hoverTr;

		private Fish _hoverF;

		public static Blips Current { get; private set; }

		public int Count => _count;

		public Layer Small => _small;

		public Layer Large => _large;

		public static float Range => Mathf.Min(RadarPlugin.Range.Value, Policy.MaxRadarRange);

		public Blips()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			Current = this;
			_tipFn = HoverTip;
		}

		public void Tick()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			Minimap instance = Minimap.instance;
			Player localPlayer = Player.m_localPlayer;
			RadarMode radar = Policy.Radar;
			if (!RadarPlugin.On.Value || (int)radar == 0 || (Object)(object)instance == (Object)null || (Object)(object)localPlayer == (Object)null)
			{
				_small.Show(on: false);
				_large.Show(on: false);
				return;
			}
			bool activeInHierarchy = instance.m_smallRoot.activeInHierarchy;
			bool flag = (int)radar == 2 && RadarPlugin.LargeMap.Value && instance.m_largeRoot.activeInHierarchy;
			if (!activeInHierarchy && !flag)
			{
				_small.Show(on: false);
				_large.Show(on: false);
				return;
			}
			if (instance != _mm)
			{
				_mm = instance;
				_scanAt = 0f;
				_small.Build(instance, instance.m_mapImageSmall, "SeneaL.Radar");
				_large.Build(instance, instance.m_mapImageLarge, "SeneaL.Radar.Large");
			}
			float time = Time.time;
			if (time >= _scanAt)
			{
				_scanAt = time + 0.25f;
				Scan(localPlayer);
			}
			if (activeInHierarchy)
			{
				_small.Place(_tf, _kind, _count, time);
			}
			else
			{
				_small.Show(on: false);
			}
			if (flag)
			{
				_large.Place(_tf, _kind, _count, time);
			}
			else
			{
				_large.Show(on: false);
			}
		}

		public void Rescan()
		{
			_scanAt = 0f;
		}

		public void Clear()
		{
			_small.Clear();
			_large.Clear();
			_mm = null;
			_count = 0;
		}

		public Transform Who(int i)
		{
			if (i >= _count)
			{
				return null;
			}
			return _tf[i];
		}

		public byte KindOf(int i)
		{
			if (i >= _count)
			{
				return byte.MaxValue;
			}
			return _kind[i];
		}

		private void Scan(Player p)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			List<Character> allCharacters = Character.GetAllCharacters();
			Vector3 position = ((Component)p).transform.position;
			float range = Range;
			float num = range * range;
			bool value = RadarPlugin.Animals.Value;
			bool value2 = RadarPlugin.Tamed.Value;
			bool value3 = RadarPlugin.Neutral.Value;
			bool radarMonsters = Policy.RadarMonsters;
			int num2 = 0;
			for (int i = 0; i < allCharacters.Count; i++)
			{
				if (num2 >= 160)
				{
					break;
				}
				Character val = allCharacters[i];
				if ((Object)(object)val == (Object)null || val.IsPlayer() || val.IsDead())
				{
					continue;
				}
				Transform transform = ((Component)val).transform;
				Vector3 position2 = transform.position;
				float num3 = position2.x - position.x;
				float num4 = position2.z - position.z;
				if (!(num3 * num3 + num4 * num4 > num))
				{
					byte b = Classify(p, val, value, value2, value3, radarMonsters);
					if (b != byte.MaxValue)
					{
						_tf[num2] = transform;
						_kind[num2] = b;
						num2++;
					}
				}
			}
			for (int num5 = Traders.Count - 1; num5 >= 0; num5--)
			{
				Trader val2 = Traders[num5];
				if ((Object)(object)val2 == (Object)null)
				{
					Traders.RemoveAt(num5);
				}
				else if (value3 && num2 < 160)
				{
					Transform transform2 = ((Component)val2).transform;
					Vector3 position3 = transform2.position;
					float num6 = position3.x - position.x;
					float num7 = position3.z - position.z;
					if (!(num6 * num6 + num7 * num7 > num))
					{
						_tf[num2] = transform2;
						_kind[num2] = 3;
						num2++;
					}
				}
			}
			if (RadarPlugin.Fish.Value)
			{
				List<IMonoUpdater> instances = Fish.Instances;
				for (int j = 0; j < instances.Count; j++)
				{
					if (num2 >= 160)
					{
						break;
					}
					IMonoUpdater obj = instances[j];
					Fish val3 = (Fish)(object)((obj is Fish) ? obj : null);
					if (val3 != null && !((Object)(object)val3 == (Object)null))
					{
						Transform transform3 = ((Component)val3).transform;
						Vector3 position4 = transform3.position;
						float num8 = position4.x - position.x;
						float num9 = position4.z - position.z;
						if (!(num8 * num8 + num9 * num9 > num))
						{
							_tf[num2] = transform3;
							_kind[num2] = 9;
							num2++;
						}
					}
				}
			}
			for (int k = num2; k < _count; k++)
			{
				_tf[k] = null;
			}
			_count = num2;
		}

		private static byte Classify(Player p, Character c, bool animals, bool tamed, bool neutral, bool monsters)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Invalid comparison between Unknown and I4
			Faction faction = c.GetFaction();
			if ((int)faction == 12)
			{
				return byte.MaxValue;
			}
			if (c.IsBoss())
			{
				if (!monsters)
				{
					return byte.MaxValue;
				}
				return 8;
			}
			if (c.IsTamed())
			{
				if (!tamed)
				{
					return byte.MaxValue;
				}
				return 1;
			}
			if (!BaseAI.IsEnemy((Character)(object)p, c))
			{
				if (!neutral)
				{
					return byte.MaxValue;
				}
				return 2;
			}
			BaseAI baseAI = c.GetBaseAI();
			bool flag = c is Humanoid && baseAI is MonsterAI && baseAI.HaveTarget();
			if (baseAI is AnimalAI || ((int)faction == 1 && !flag))
			{
				if (!animals)
				{
					return byte.MaxValue;
				}
				return 0;
			}
			if (!monsters)
			{
				return byte.MaxValue;
			}
			if (c.GetMaxHealth() >= 500f)
			{
				if (!flag)
				{
					return 6;
				}
				return 7;
			}
			if (!flag)
			{
				return 4;
			}
			return 5;
		}

		public RectTransform MapHover(Vector2 screen, out Func<Tip> tip)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			tip = null;
			int num = _large.Hover(screen);
			if (num < 0 || num >= _count || (Object)(object)_tf[num] == (Object)null)
			{
				return null;
			}
			Transform val = _tf[num];
			if ((Object)(object)val != (Object)(object)_hoverTf)
			{
				_hoverTf = val;
				_hoverC = ((Component)val).GetComponent<Character>();
				_hoverTr = (((Object)(object)_hoverC == (Object)null) ? ((Component)val).GetComponent<Trader>() : null);
				_hoverF = (((Object)(object)_hoverC == (Object)null && (Object)(object)_hoverTr == (Object)null) ? ((Component)val).GetComponent<Fish>() : null);
				_tip.Version = int.MinValue;
			}
			_hoverKind = _kind[num];
			tip = _tipFn;
			return _large.Anchor(num);
		}

		private static string TraderName(Trader tr)
		{
			string text = Localization.instance.Localize(tr.m_name ?? "");
			if (text.Trim().Length > 0)
			{
				return text;
			}
			Hoverable componentInParent = (Hoverable)(object)((Component)tr).GetComponentInParent<Character>();
			Hoverable val = (Hoverable)(((object)componentInParent) ?? ((object)((Component)tr).GetComponent<HoverText>()));
			if (val != null)
			{
				text = Localization.instance.Localize(val.GetHoverName() ?? "");
				if (text.Trim().Length > 0)
				{
					return text;
				}
			}
			string prefabName = Utils.GetPrefabName(((Component)tr).gameObject);
			string text2 = "$npc_" + prefabName.ToLowerInvariant();
			string text3 = Localization.instance.Localize(text2);
			if (text3 != text2 && text3.Length > 0 && text3[0] != '[' && text3[0] != '$')
			{
				return text3;
			}
			if (prefabName.Length <= 0)
			{
				return Loc.T("Radar.KindTrader");
			}
			return Regex.Replace(prefabName, "(?<=[a-z])(?=[A-Z])", " ");
		}

		private Tip HoverTip()
		{
			//IL_002e: 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_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			Transform hoverTf = _hoverTf;
			if ((Object)(object)hoverTf == (Object)null)
			{
				return null;
			}
			Player localPlayer = Player.m_localPlayer;
			float num = (((Object)(object)localPlayer != (Object)null) ? Utils.DistanceXZ(((Component)localPlayer).transform.position, hoverTf.position) : 0f);
			byte hoverKind = _hoverKind;
			if ((Object)(object)_hoverC != (Object)null)
			{
				Character hoverC = _hoverC;
				int num2 = Mathf.CeilToInt(hoverC.GetHealth());
				int num3 = Mathf.CeilToInt(hoverC.GetMaxHealth());
				int level = hoverC.GetLevel();
				int num4 = ((hoverKind * 31 + num2) * 31 + num3) * 31 + level * 7 + (int)(num / 2f) * 131 + Loc.Stamp.GetHashCode();
				if (_tip.Version == num4)
				{
					return _tip;
				}
				Tip obj = _tip.Reset(Localization.instance.Localize(hoverC.m_name), num4);
				obj.TitleColor = ((hoverKind == 0) ? Palette.Parchment : Colors[hoverKind]);
				obj.Icon = Face(((Component)hoverC).gameObject);
				obj.Sub = KindName(hoverKind) + ((level > 1) ? (" · " + string.Format(Loc.T("Radar.Stars"), level - 1)) : "") + " · " + Loc.Dist(num);
				obj.AddRow(Loc.T("Radar.Health"), num2 + " / " + num3, (string)null);
				obj.AddRow(Loc.T("Radar.State"), State(hoverKind), (string)null, (Color?)null, (hoverKind == 5 || hoverKind == 7) ? new Color?(Colors[5]) : ((Color?)null), false, false);
				return obj;
			}
			if ((Object)(object)_hoverTr != (Object)null)
			{
				int num5 = 17 + (int)(num / 2f) * 131 + Loc.Stamp.GetHashCode();
				if (_tip.Version == num5)
				{
					return _tip;
				}
				Tip obj2 = _tip.Reset(TraderName(_hoverTr), num5);
				obj2.TitleColor = Colors[3];
				obj2.Icon = Icons.Get("coins");
				obj2.Sub = KindName(3) + " · " + Loc.Dist(num);
				return obj2;
			}
			if ((Object)(object)_hoverF != (Object)null)
			{
				ItemDrop component = ((Component)_hoverF).GetComponent<ItemDrop>();
				int num6 = ((!((Object)(object)component != (Object)null)) ? 1 : component.m_itemData.m_quality);
				int num7 = 29 + num6 * 7 + (int)(num / 2f) * 131 + Loc.Stamp.GetHashCode();
				if (_tip.Version == num7)
				{
					return _tip;
				}
				Tip obj3 = _tip.Reset(Localization.instance.Localize(_hoverF.m_name), num7);
				obj3.TitleColor = Colors[9];
				obj3.Icon = (((Object)(object)component != (Object)null) ? component.m_itemData.GetIcon() : null);
				obj3.Sub = KindName(9) + ((num6 > 1) ? (" · " + new string('★', num6 - 1)) : "") + " · " + Loc.Dist(num);
				return obj3;
			}
			return null;
		}

		private static string State(byte kind)
		{
			switch (kind)
			{
			case 5:
			case 7:
				return Loc.T("Radar.StateHunting");
			case 1:
				return Loc.T("Radar.StateTamed");
			case 2:
			case 3:
				return Loc.T("Radar.StatePeaceful");
			case 0:
				return Loc.T("Radar.StateWild");
			default:
				return Loc.T("Radar.StateCalm");
			}
		}

		public static string KindName(byte kind)
		{
			switch (kind)
			{
			case 0:
				return Loc.T("Radar.KindAnimal");
			case 1:
				return Loc.T("Radar.KindTamed");
			case 2:
				return Loc.T("Radar.KindNeutral");
			case 3:
				return Loc.T("Radar.KindTrader");
			case 5:
				return Loc.T("Radar.KindHunting");
			case 6:
			case 7:
				return Loc.T("Radar.KindElite");
			case 8:
				return Loc.T("Radar.KindBoss");
			case 9:
				return Loc.T("Radar.KindFish");
			default:
				return Loc.T("Radar.KindMonster");
			}
		}

		private static Sprite Face(GameObject go)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Invalid comparison between Unknown and I4
			string prefabName = Utils.GetPrefabName(go);
			if (Faces.TryGetValue(prefabName, out var value))
			{
				return value;
			}
			value = null;
			CharacterDrop component = go.GetComponent<CharacterDrop>();
			if ((Object)(object)component != (Object)null)
			{
				for (int i = 0; i < component.m_drops.Count; i++)
				{
					if (!((Object)(object)value == (Object)null))
					{
						break;
					}
					GameObject prefab = component.m_drops[i].m_prefab;
					ItemDrop val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null);
					if ((Object)(object)val != (Object)null && (int)val.m_itemData.m_shared.m_itemType == 13)
					{
						value = val.m_itemData.GetIcon();
					}
				}
			}
			if ((Object)(object)value == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Trophy" + prefabName);
				ItemDrop val2 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					value = val2.m_itemData.GetIcon();
				}
			}
			Faces[prefabName] = value;
			return value;
		}

		public static Sprite SpriteOf(byte kind)
		{
			switch (kind)
			{
			default:
				return Sprites.Disc;
			case 9:
				return Sprites.FishShape;
			case 6:
			case 7:
				return Sprites.Diamond;
			case 3:
			case 8:
				return Sprites.Badge;
			}
		}
	}
	[BepInPlugin("seneaL.valheim.ui.radar", "SeneaL Radar", "1.0.1")]
	[BepInDependency("seneaL.valheim.ui", "1.1.7")]
	public sealed class RadarPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Trader), "Start")]
		private static class TraderPatch
		{
			private static void Postfix(Trader __instance)
			{
				if (!Blips.Traders.Contains(__instance))
				{
					Blips.Traders.Add(__instance);
				}
			}
		}

		public const string Guid = "seneaL.valheim.ui.radar";

		public const string Name = "SeneaL Radar";

		public const string Version = "1.0.1";

		private const string Texts = "SeneaLUI.Radar.Languages.";

		private readonly Blips _blips = new Blips();

		public static ConfigEntry<bool> On { get; private set; }

		public static ConfigEntry<float> Range { get; private set; }

		public static ConfigEntry<bool> LargeMap { get; private set; }

		public static ConfigEntry<bool> Animals { get; private set; }

		public static ConfigEntry<bool> Tamed { get; private set; }

		public static ConfigEntry<bool> Neutral { get; private set; }

		public static ConfigEntry<bool> Fish { get; private set; }

		public static int PerfSlot { get; private set; }

		private void Awake()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			On = ((BaseUnityPlugin)this).Config.Bind<bool>("Radar", "Enabled", true, "Show creatures on the minimap.");
			Range = ((BaseUnityPlugin)this).Config.Bind<float>("Radar", "Range", 80f, new ConfigDescription("How far away creatures are shown, in metres. The edge of the minimap and the server's MaxRadarRange limit it too.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 200f), Array.Empty<object>()));
			LargeMap = ((BaseUnityPlugin)this).Config.Bind<bool>("Radar", "LargeMap", true, "Also show them on the large world map (within the same range around you). Point at one there to see who it is.");
			Animals = ((BaseUnityPlugin)this).Config.Bind<bool>("Radar", "Animals", true, "Also show animals: deer, hares, birds and other creatures that do not attack (pale dots).");
			Tamed = ((BaseUnityPlugin)this).Config.Bind<bool>("Radar", "Tamed", true, "Also show tamed creatures (green dots).");
			Neutral = ((BaseUnityPlugin)this).Config.Bind<bool>("Radar", "Neutral", true, "Also show traders (coin badge) and creatures that are not hostile to you, such as the Dvergr (blue dots).");
			Fish = ((BaseUnityPlugin)this).Config.Bind<bool>("Radar", "Fish", false, "Also show fish in the water (small blue fish that turn the way they swim).");
			PerfSlot = Perf.Slot("addon.radar");
			LoadTexts();
			new Harmony("seneaL.valheim.ui.radar").PatchAll(typeof(TraderPatch));
			Addons.OnMapHover(new MapHoverFn(_blips.MapHover));
			Func<bool> func = () => (int)Policy.Radar > 0;
			Func<bool> active = () => On.Value && (int)Policy.Radar > 0;
			Addon val = Addons.Register("seneaL.valheim.ui.radar", "SeneaL Radar", (Func<string>)null, (string)null, (string)null);
			val.Notes((Func<string>)Note);
			val.Switch((Func<string>)(() => Loc.T("Radar.Enabled")), On, func, (Func<string>)Addons.WhyServer);
			val.Slider((Func<string>)(() => Loc.T("Radar.Range")), Range, 10f, 200f, (Func<float, string>)((float v) => Mathf.RoundToInt(v) + " " + Loc.M), active, (Func<float>)(() => Policy.MaxRadarRange), (Func<string>)Addons.WhyServer);
			val.Switch((Func<string>)(() => Loc.T("Radar.LargeMap")), LargeMap, (Func<bool>)(() => active() && (int)Policy.Radar == 2), (Func<string>)Addons.WhyServer);
			val.Switch((Func<string>)(() => Loc.T("Radar.Animals")), Animals, active, (Func<string>)Addons.WhyServer);
			val.Switch((Func<string>)(() => Loc.T("Radar.Tamed")), Tamed, active, (Func<string>)Addons.WhyServer);
			val.Switch((Func<string>)(() => Loc.T("Radar.Neutral")), Neutral, active, (Func<string>)Addons.WhyServer);
			val.Switch((Func<string>)(() => Loc.T("Radar.Fish")), Fish, active, (Func<string>)Addons.WhyServer);
			byte[] array = new byte[9] { 4, 5, 6, 8, 3, 2, 1, 0, 9 };
			foreach (byte b in array)
			{
				byte kind = b;
				Sprite val2 = ((kind == 8) ? Icons.Get("star") : ((kind == 3) ? Icons.Get("coins") : null));
				Color val3 = ((kind == 8) ? Palette.Gold : Palette.Parchment);
				val.Marker(Blips.SpriteOf(kind), Blips.Colors[kind], Blips.Sizes[kind] * 1.4545455f * 1.25f, (Func<string>)(() => Blips.KindName(kind)), val2, val3);
			}
		}

		private static string Note()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			if ((int)Policy.State == 0)
			{
				return null;
			}
			if ((int)Policy.Radar == 0)
			{
				if ((int)Policy.State != 2 && (int)Policy.State != 1)
				{
					return Addons.WhyServer();
				}
				return Loc.T("Radar.NoteOff");
			}
			string text = "";
			if ((int)Policy.Radar == 1)
			{
				text = Loc.T("Radar.NoteMinimap");
			}
			if (Policy.MaxRadarRange < 200f)
			{
				text = text + ((text.Length > 0) ? ", " : "") + string.Format(Loc.T("Radar.NoteRange"), Mathf.RoundToInt(Policy.MaxRadarRange));
			}
			if (!Policy.RadarMonsters)
			{
				text = text + ((text.Length > 0) ? ", " : "") + Loc.T("Radar.NoteNoMonsters");
			}
			if (text.Length <= 0)
			{
				return null;
			}
			return string.Format(Loc.T("Radar.NoteLimited"), text);
		}

		private static void LoadTexts()
		{
			Assembly assembly = typeof(RadarPlugin).Assembly;
			string[] manifestResourceNames = assembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (!text.StartsWith("SeneaLUI.Radar.Languages.") || !text.EndsWith(".txt"))
				{
					continue;
				}
				using Stream stream = assembly.GetManifestResourceStream(text);
				using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
				Loc.Extend(text.Substring("SeneaLUI.Radar.Languages.".Length, text.Length - "SeneaLUI.Radar.Languages.".Length - 4), streamReader.ReadToEnd());
			}
		}

		private void LateUpdate()
		{
			long num = Perf.Begin();
			_blips.Tick();
			Perf.End(PerfSlot, num);
		}

		private void OnDestroy()
		{
			_blips.Clear();
		}
	}
	public static class Sprites
	{
		public const int Tex = 64;

		public const float Body = 22f;

		public const float Pad = 1.4545455f;

		private static Sprite _disc;

		private static Sprite _diamond;

		private static Sprite _badge;

		private static Sprite _ring;

		private static Sprite _fish;

		public static Sprite Disc => _disc ?? (_disc = Make(0));

		public static Sprite Diamond => _diamond ?? (_diamond = Make(1));

		public static Sprite Badge => _badge ?? (_badge = Make(2));

		public static Sprite Ring => _ring ?? (_ring = Make(3));

		public static Sprite FishShape => _fish ?? (_fish = Make(4));

		private static float FishSdf(float x, float y)
		{
			float num = x - 5f;
			float num2 = (Mathf.Sqrt(num * num / 289f + y * y / 121f) - 1f) * 11f;
			float num3 = -13f - x;
			float num4 = Mathf.Max(Mathf.Abs(y) - num3 * 1.3f - 1f, Mathf.Max(0f - num3, num3 - 10f));
			return Mathf.Min(num2, num4 * 0.8f);
		}

		private static Sprite Make(int shape)
		{
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: 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_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Expected O, but got Unknown
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4096];
			float num = 32f;
			float num2 = ((shape == 2) ? 3.2f : 3.6f);
			float num3 = 0.0625f;
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num4 = 0f;
					float num5 = 0f;
					float num6 = 0f;
					float num7 = 0f;
					for (int k = 0; k < 4; k++)
					{
						for (int l = 0; l < 4; l++)
						{
							float num8 = (float)j + ((float)l + 0.5f) / 4f - num;
							float num9 = (float)i + ((float)k + 0.5f) / 4f - num;
							float num10 = shape switch
							{
								4 => 22f + FishSdf(num8, num9), 
								1 => (Mathf.Abs(num8) + Mathf.Abs(num9)) * 0.78f, 
								_ => Mathf.Sqrt(num8 * num8 + num9 * num9), 
							};
							if (shape == 3)
							{
								if (num10 <= 22f && num10 >= 18f)
								{
									num4 += 1f;
									num5 += 1f;
									num6 += 1f;
									num7 += 1f;
								}
							}
							else if (num10 <= 22f - num2)
							{
								if (shape == 2)
								{
									num4 += 0.09f;
									num5 += 0.07f;
									num6 += 0.055f;
									num7 += 0.94f;
								}
								else
								{
									float num11 = Mathf.Clamp01(1f - (num9 + 9.9f) * (num9 + 9.9f) / 242f - num8 * num8 / 484f);
									float num12 = 0.82f + 0.18f * num11;
									num4 += num12;
									num5 += num12;
									num6 += num12;
									num7 += 1f;
								}
							}
							else if (num10 <= 22f)
							{
								if (shape == 2)
								{
									num4 += 1f;
									num5 += 1f;
									num6 += 1f;
								}
								else
								{
									num4 += 0.06f;
									num5 += 0.045f;
									num6 += 0.035f;
								}
								num7 += 0.95f;
							}
							else if (num10 <= 29f)
							{
								float num13 = 1f - (num10 - 22f) / 7f;
								num7 += 0.42f * num13 * num13;
							}
						}
					}
					num7 *= num3;
					float num14 = ((num7 > 0f) ? (1f / (num7 / num3)) : 0f);
					array[i * 64 + j] = new Color32((byte)(Mathf.Clamp01(num4 * num14) * 255f), (byte)(Mathf.Clamp01(num5 * num14) * 255f), (byte)(Mathf.Clamp01(num6 * num14) * 255f), (byte)(Mathf.Clamp01(num7) * 255f));
				}
			}
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, true)
			{
				name = "SeneaL.Radar." + shape,
				filterMode = (FilterMode)2,
				wrapMode = (TextureWrapMode)1,
				anisoLevel = 1
			};
			val.SetPixels32(array);
			val.Apply(true, true);
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
		}
	}
}