Decompiled source of TamedRadar v1.0.1

TamedRadar.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("TamedRadar")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("TamedRadar")]
[assembly: AssemblyTitle("TamedRadar")]
[assembly: AssemblyVersion("1.0.1.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 TamedRadar
{
	[BepInPlugin("si.sori-resitve.tamedradar", "TamedRadar", "1.0.1")]
	public class TamedRadarPlugin : BaseUnityPlugin
	{
		private sealed class Marker
		{
			public RectTransform Small;

			public RectTransform Large;
		}

		public const string PluginGuid = "si.sori-resitve.tamedradar";

		public const string PluginName = "TamedRadar";

		public const string PluginVersion = "1.0.1";

		private const float IconScale = 0.8f;

		private const float ScanInterval = 1f;

		private readonly Dictionary<Character, Marker> markers = new Dictionary<Character, Marker>();

		private readonly Dictionary<string, Sprite> iconCache = new Dictionary<string, Sprite>();

		private readonly List<Character> scratch = new List<Character>();

		private Minimap boundMinimap;

		private float scanTimer;

		private void OnDestroy()
		{
			ClearMarkers();
		}

		private void LateUpdate()
		{
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				ClearMarkers();
				return;
			}
			if ((Object)(object)instance != (Object)(object)boundMinimap)
			{
				ClearMarkers();
				iconCache.Clear();
				boundMinimap = instance;
				scanTimer = 0f;
			}
			scanTimer -= Time.deltaTime;
			if (scanTimer <= 0f)
			{
				scanTimer = 1f;
				Rescan(instance);
			}
			UpdatePositions(instance);
		}

		private void Rescan(Minimap minimap)
		{
			HashSet<Character> hashSet = new HashSet<Character>();
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (IsTracked(allCharacter))
				{
					hashSet.Add(allCharacter);
					if (!markers.ContainsKey(allCharacter))
					{
						Sprite icon = ResolveIcon(minimap, allCharacter);
						markers[allCharacter] = new Marker
						{
							Small = CreateMarker(minimap, minimap.m_pinRootSmall, icon),
							Large = CreateMarker(minimap, minimap.m_pinRootLarge, icon)
						};
					}
				}
			}
			scratch.Clear();
			foreach (Character key in markers.Keys)
			{
				if (!hashSet.Contains(key))
				{
					scratch.Add(key);
				}
			}
			foreach (Character item in scratch)
			{
				RemoveMarker(item);
			}
		}

		private void UpdatePositions(Minimap minimap)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_0073: 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)
			scratch.Clear();
			foreach (KeyValuePair<Character, Marker> marker in markers)
			{
				Character key = marker.Key;
				if (!IsTracked(key))
				{
					scratch.Add(key);
					continue;
				}
				Vector3 position = ((Component)key).transform.position;
				bool flag = (int)minimap.m_mode == 2;
				Place(marker.Value.Small, minimap, minimap.m_mapImageSmall, minimap.m_pinSizeSmall, position, !flag);
				Place(marker.Value.Large, minimap, minimap.m_mapImageLarge, minimap.m_pinSizeLarge, position, flag);
			}
			foreach (Character item in scratch)
			{
				RemoveMarker(item);
			}
		}

		private static bool IsTracked(Character character)
		{
			if ((Object)(object)character != (Object)null && !character.IsPlayer() && character.IsTamed())
			{
				return !character.IsDead();
			}
			return false;
		}

		private void Place(RectTransform marker, Minimap minimap, RawImage map, float pinSize, Vector3 world, bool wanted)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)marker == (Object)null)
			{
				return;
			}
			if (!wanted || (Object)(object)map == (Object)null || !TryMapToGui(minimap, map, world, out var gui))
			{
				if (((Component)marker).gameObject.activeSelf)
				{
					((Component)marker).gameObject.SetActive(false);
				}
				return;
			}
			if (!((Component)marker).gameObject.activeSelf)
			{
				((Component)marker).gameObject.SetActive(true);
			}
			float num = pinSize * 0.8f;
			marker.SetSizeWithCurrentAnchors((Axis)0, num);
			marker.SetSizeWithCurrentAnchors((Axis)1, num);
			marker.anchoredPosition = gui;
		}

		private static bool TryMapToGui(Minimap minimap, RawImage map, Vector3 world, out Vector2 gui)
		{
			//IL_0009: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_00b3: 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)
			int num = minimap.m_textureSize / 2;
			float num2 = (world.x / minimap.m_pixelSize + (float)num) / (float)minimap.m_textureSize;
			float num3 = (world.z / minimap.m_pixelSize + (float)num) / (float)minimap.m_textureSize;
			Rect uvRect = map.uvRect;
			if (num2 <= ((Rect)(ref uvRect)).xMin || num2 >= ((Rect)(ref uvRect)).xMax || num3 <= ((Rect)(ref uvRect)).yMin || num3 >= ((Rect)(ref uvRect)).yMax)
			{
				gui = default(Vector2);
				return false;
			}
			Rect rect = ((Graphic)map).rectTransform.rect;
			gui = new Vector2((num2 - ((Rect)(ref uvRect)).xMin) / ((Rect)(ref uvRect)).width * ((Rect)(ref rect)).width, (num3 - ((Rect)(ref uvRect)).yMin) / ((Rect)(ref uvRect)).height * ((Rect)(ref rect)).height);
			return true;
		}

		private static RectTransform CreateMarker(Minimap minimap, RectTransform root, Sprite icon)
		{
			if ((Object)(object)root == (Object)null || (Object)(object)minimap.m_pinPrefab == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(minimap.m_pinPrefab, (Transform)(object)root);
			((Object)val).name = "TamedRadarMarker";
			Graphic[] componentsInChildren = val.GetComponentsInChildren<Graphic>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].raycastTarget = false;
			}
			CanvasGroup val2 = val.GetComponent<CanvasGroup>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val.AddComponent<CanvasGroup>();
			}
			val2.blocksRaycasts = false;
			val2.interactable = false;
			Transform val3 = val.transform.Find("Checked");
			if ((Object)(object)val3 != (Object)null)
			{
				((Component)val3).gameObject.SetActive(false);
			}
			Image component = val.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				component.sprite = icon;
			}
			val.SetActive(false);
			Transform transform = val.transform;
			return (RectTransform)(object)((transform is RectTransform) ? transform : null);
		}

		private void RemoveMarker(Character character)
		{
			if (markers.TryGetValue(character, out var value))
			{
				if ((Object)(object)value.Small != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)value.Small).gameObject);
				}
				if ((Object)(object)value.Large != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)value.Large).gameObject);
				}
			}
			markers.Remove(character);
		}

		private void ClearMarkers()
		{
			if (markers.Count == 0)
			{
				return;
			}
			scratch.Clear();
			scratch.AddRange(markers.Keys);
			foreach (Character item in scratch)
			{
				RemoveMarker(item);
			}
		}

		private Sprite ResolveIcon(Minimap minimap, Character character)
		{
			string text = ((Object)((Component)character).gameObject).name.Replace("(Clone)", "").Trim();
			if (iconCache.TryGetValue(text, out var value))
			{
				return value;
			}
			Sprite val = TrophyFromDrops(character) ?? TrophyFromObjectDb(text) ?? FallbackSprite(minimap);
			iconCache[text] = val;
			return val;
		}

		private static Sprite TrophyFromDrops(Character character)
		{
			CharacterDrop component = ((Component)character).GetComponent<CharacterDrop>();
			if ((Object)(object)component == (Object)null || component.m_drops == null)
			{
				return null;
			}
			foreach (Drop drop in component.m_drops)
			{
				if (!((Object)(object)drop?.m_prefab == (Object)null) && ((Object)drop.m_prefab).name.StartsWith("Trophy"))
				{
					Sprite val = IconOf(drop.m_prefab);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
			}
			return null;
		}

		private static Sprite TrophyFromObjectDb(string prefab)
		{
			if (!((Object)(object)ObjectDB.instance != (Object)null))
			{
				return null;
			}
			return IconOf(ObjectDB.instance.GetItemPrefab("Trophy" + prefab));
		}

		private static Sprite IconOf(GameObject itemPrefab)
		{
			ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if (!((Object)(object)val != (Object)null) || val.m_itemData == null || val.m_itemData.m_shared.m_icons.Length == 0)
			{
				return null;
			}
			return val.m_itemData.GetIcon();
		}

		private static Sprite FallbackSprite(Minimap minimap)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_001d: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			foreach (SpriteData icon in minimap.m_icons)
			{
				if ((int)icon.m_name == 3)
				{
					return icon.m_icon;
				}
			}
			return null;
		}
	}
}