Decompiled source of HexRareScanner v1.3.1

Plugins/HexRareScanner.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Splatform;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("HexRareScanner")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HexRareScanner")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3c9bc10-9d16-4f15-b8bd-d4fe1c71af33")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HexRareScanner
{
	internal static class PinManager
	{
		private static readonly Dictionary<ZDOID, PinData> PinsByZdoid = new Dictionary<ZDOID, PinData>();

		private static readonly FieldInfo CharacterNViewField = AccessTools.Field(typeof(Character), "m_nview");

		private static readonly MethodInfo RemovePinMethod = AccessTools.Method(typeof(Minimap), "RemovePin", new Type[1] { typeof(PinData) }, (Type[])null);

		internal static void AddCreaturePin(Character character, Vector3 position, string pinName)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0049: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Minimap.instance == (Object)null || (Object)(object)character == (Object)null)
			{
				return;
			}
			ZDOID zdoId = GetZdoId(character);
			if (zdoId == ZDOID.None || PinsByZdoid.ContainsKey(zdoId))
			{
				return;
			}
			PinData val = Minimap.instance.AddPin(position, (PinType)12, pinName, false, false, 0L, default(PlatformUserID));
			if (val == null)
			{
				return;
			}
			TrackedCreatureDefinition creatureDefinition = GetCreatureDefinition(PrefabNameHelper.GetPrefabNameFromClone(((Object)((Component)character).gameObject).name));
			if (creatureDefinition != null && Plugin.IsCreatureIconsEnabled)
			{
				Sprite creatureIcon = GetCreatureIcon(creatureDefinition.TrophyPrefabName);
				if ((Object)(object)creatureIcon != (Object)null)
				{
					SetPinIcon(val, creatureIcon);
				}
			}
			PinsByZdoid[zdoId] = val;
		}

		internal static void RemoveCreaturePin(Character character)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//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_0028: 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)
			if (!((Object)(object)Minimap.instance == (Object)null))
			{
				ZDOID zdoId = GetZdoId(character);
				if (!(zdoId == ZDOID.None) && PinsByZdoid.TryGetValue(zdoId, out var value))
				{
					RemovePinMethod?.Invoke(Minimap.instance, new object[1] { value });
					PinsByZdoid.Remove(zdoId);
				}
			}
		}

		internal static PinData GetClosestCreaturePin(Vector3 position, float radius)
		{
			//IL_0045: 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)
			PinData result = null;
			float num = float.MaxValue;
			foreach (PinData value in PinsByZdoid.Values)
			{
				if (value != null && !((Object)(object)value.m_uiElement == (Object)null) && ((Component)value.m_uiElement).gameObject.activeInHierarchy)
				{
					float num2 = Utils.DistanceXZ(position, value.m_pos);
					if (!(num2 >= radius) && !(num2 >= num))
					{
						result = value;
						num = num2;
					}
				}
			}
			return result;
		}

		internal static bool RemoveCreaturePin(PinData pin)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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)
			if (pin == null || (Object)(object)Minimap.instance == (Object)null)
			{
				return false;
			}
			ZDOID val = ZDOID.None;
			foreach (KeyValuePair<ZDOID, PinData> item in PinsByZdoid)
			{
				if (item.Value == pin)
				{
					val = item.Key;
					break;
				}
			}
			if (val == ZDOID.None)
			{
				return false;
			}
			RemovePinMethod?.Invoke(Minimap.instance, new object[1] { pin });
			PinsByZdoid.Remove(val);
			return true;
		}

		internal static ZDOID GetZdoId(Character character)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || CharacterNViewField == null)
			{
				return ZDOID.None;
			}
			object? value = CharacterNViewField.GetValue(character);
			ZNetView val = (ZNetView)((value is ZNetView) ? value : null);
			if ((Object)(object)val == (Object)null || val.GetZDO() == null)
			{
				return ZDOID.None;
			}
			return val.GetZDO().m_uid;
		}

		internal static bool HasCreaturePin(Character character)
		{
			//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_0008: 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)
			ZDOID zdoId = GetZdoId(character);
			if (zdoId == ZDOID.None)
			{
				return false;
			}
			return PinsByZdoid.ContainsKey(zdoId);
		}

		internal static void Clear()
		{
			PinsByZdoid.Clear();
		}

		private static TrackedCreatureDefinition GetCreatureDefinition(string prefabName)
		{
			foreach (TrackedCreatureDefinition creature in TrackedCreatureDefinition.Creatures)
			{
				if (creature.PrefabName == prefabName)
				{
					return creature;
				}
			}
			return null;
		}

		private static Sprite GetCreatureIcon(string trophyPrefabName)
		{
			if (string.IsNullOrEmpty(trophyPrefabName) || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(trophyPrefabName);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return null;
			}
			ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || component.m_itemData == null)
			{
				return null;
			}
			return component.m_itemData.GetIcon();
		}

		private static void SetPinIcon(PinData pin, Sprite icon)
		{
			if (pin != null && !((Object)(object)icon == (Object)null))
			{
				pin.m_icon = icon;
				if ((Object)(object)pin.m_iconElement != (Object)null)
				{
					pin.m_iconElement.sprite = icon;
				}
			}
		}
	}
	[BepInPlugin("com.hex.rarescanner", "HexRareScanner", "1.3.1")]
	public class Plugin : BaseUnityPlugin
	{
		internal sealed class TrackedCreatureSetting
		{
			internal ConfigEntry<bool> Enabled { get; }

			internal string DisplayName { get; }

			internal string SoundEffectName { get; }

			internal int RarityLevel { get; }

			internal TrackedCreatureSetting(ConfigEntry<bool> enabled, string displayName, string soundEffectName, int rarityLevel)
			{
				Enabled = enabled;
				DisplayName = displayName;
				SoundEffectName = soundEffectName;
				RarityLevel = rarityLevel;
			}
		}

		private const string PluginGuid = "com.hex.rarescanner";

		private const string PluginName = "HexRareScanner";

		private const string PluginVersion = "1.3.1";

		private Harmony _harmonyInstance;

		private static ConfigEntry<bool> _isModEnabled;

		private static ConfigEntry<bool> _playTrackedCreatureSound;

		private static ConfigEntry<bool> _isManualPinRemovalEnabled;

		private static ConfigEntry<bool> _isCreatureIconsEnabled;

		private static readonly Dictionary<string, TrackedCreatureSetting> TrackedCreatures = new Dictionary<string, TrackedCreatureSetting>();

		internal static Plugin Instance;

		internal static ManualLogSource Log;

		internal static readonly FieldInfo CharacterMLevelField = AccessTools.Field(typeof(Character), "m_level");

		internal static bool IsModEnabled => _isModEnabled?.Value ?? false;

		internal static bool PlayTrackedCreatureSound => _playTrackedCreatureSound?.Value ?? false;

		internal static bool IsManualPinRemovalEnabled => _isManualPinRemovalEnabled?.Value ?? true;

		internal static bool IsCreatureIconsEnabled => _isCreatureIconsEnabled?.Value ?? true;

		private void Awake()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			InitializeConfig();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmonyInstance = new Harmony("com.hex.rarescanner");
			_harmonyInstance.PatchAll(executingAssembly);
			Log.LogInfo((object)"HexRareScanner v1.3.1 loaded.");
		}

		private void OnDestroy()
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)"HexRareScanner v1.3.1 unloaded.");
			}
			Harmony harmonyInstance = _harmonyInstance;
			if (harmonyInstance != null)
			{
				harmonyInstance.UnpatchSelf();
			}
			_harmonyInstance = null;
			Instance = null;
			Log = null;
		}

		private void InitializeConfig()
		{
			TrackedCreatures.Clear();
			_isModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsModEnabled", true, "Enable or disable the mod.");
			_playTrackedCreatureSound = ((BaseUnityPlugin)this).Config.Bind<bool>("Sounds", "PlayTrackedCreatureSound", true, "Enable or disable the tracked creature spawn sound.");
			_isManualPinRemovalEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Map Pins", "Enable Manual Pin Removal", true, "Allow tracked creature pins to be removed by right-clicking them on the map.");
			_isCreatureIconsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Map Pins", "Enable Creature Icons", true, "Use creature icons for tracked creature map pins. When disabled, the default Valheim blue ping icon is used. Requires a game restart.");
			foreach (TrackedCreatureDefinition creature in TrackedCreatureDefinition.Creatures)
			{
				AddTrackedCreature(creature.ConfigSection, creature.PrefabName, creature.ConfigName, creature.DisplayName, creature.SoundEffectName, creature.MinimumLevel);
			}
		}

		private void AddTrackedCreature(string configSection, string prefabName, string configName, string displayName, string soundEffectName, int rarityLevel = 1)
		{
			TrackedCreatures[prefabName] = new TrackedCreatureSetting(((BaseUnityPlugin)this).Config.Bind<bool>(configSection, configName, true, "Enable or disable tracking of " + displayName + "."), displayName, soundEffectName, rarityLevel);
		}

		internal static TrackedCreatureSetting GetTrackedCreature(string prefabName)
		{
			if (!TrackedCreatures.TryGetValue(prefabName, out var value))
			{
				return null;
			}
			if (!value.Enabled.Value)
			{
				return null;
			}
			return value;
		}
	}
	internal static class PrefabNameHelper
	{
		internal static string GetPrefabNameFromClone(string objectName)
		{
			if (string.IsNullOrEmpty(objectName))
			{
				return string.Empty;
			}
			if (objectName.EndsWith("(Clone)"))
			{
				return objectName.Substring(0, objectName.Length - "(Clone)".Length);
			}
			return objectName;
		}
	}
	internal sealed class TrackedCreatureDefinition
	{
		internal static class Biomes
		{
			internal const string Ocean = "Tracked Creatures - Ocean";

			internal const string Meadows = "Tracked Creatures - Meadows";

			internal const string BlackForest = "Tracked Creatures - Black Forest";

			internal const string Swamp = "Tracked Creatures - Swamp";

			internal const string Mountains = "Tracked Creatures - Mountains";

			internal const string Plains = "Tracked Creatures - Plains";

			internal const string Mistlands = "Tracked Creatures - Mistlands";

			internal const string Ashlands = "Tracked Creatures - Ashlands";

			internal const string DeepNorth = "Tracked Creatures - Deep North";
		}

		internal static readonly List<TrackedCreatureDefinition> Creatures = new List<TrackedCreatureDefinition>
		{
			new TrackedCreatureDefinition("Tracked Creatures - Ocean", "Serpent", "Track Sea Serpents", "Sea Serpent", "sfx_serpent_taunt", "TrophySerpent"),
			new TrackedCreatureDefinition("Tracked Creatures - Ocean", "BonemawSerpent", "Track Bonemaw Serpents", "Bonemaw Serpent", "sfx_bonemaw_serpent_alert", "TrophyBonemawSerpent"),
			new TrackedCreatureDefinition("Tracked Creatures - Meadows", "Deer", "Track 2-star Deer", "Deer", "sfx_deer_idle", "TrophyDeer", 3),
			new TrackedCreatureDefinition("Tracked Creatures - Meadows", "Deer_White", "Track White Deer", "White Deer", "sfx_deer_idle", "TrophyDeerWhite"),
			new TrackedCreatureDefinition("Tracked Creatures - Meadows", "Boar", "Track 2-star Boars", "Boar", "sfx_boar_idle", "TrophyBoar", 3),
			new TrackedCreatureDefinition("Tracked Creatures - Black Forest", "Troll", "Track Trolls", "Troll", "sfx_troll_idle", "TrophyForestTroll"),
			new TrackedCreatureDefinition("Tracked Creatures - Black Forest", "Bjorn", "Track Black Forest Bears", "Black Forest Bear", "sfx_bear_bite_attack", "TrophyBjorn"),
			new TrackedCreatureDefinition("Tracked Creatures - Swamp", "Abomination", "Track Abominations", "Abomination", "sfx_abomination_arise_end", "TrophyAbomination"),
			new TrackedCreatureDefinition("Tracked Creatures - Swamp", "Writhan", "Track Writhan", "Writhan", "sfx_writhan_verse_attack", "TrophyWrithan"),
			new TrackedCreatureDefinition("Tracked Creatures - Mountains", "StoneGolem", "Track Stone Golems", "Stone Golem", "sfx_stonegolem_idle", "TrophySGolem"),
			new TrackedCreatureDefinition("Tracked Creatures - Mountains", "Wolf", "Track 2-star Wolves", "Wolf", "sfx_wolf_alerted", "TrophyWolf", 3),
			new TrackedCreatureDefinition("Tracked Creatures - Plains", "Unbjorn", "Track Vile Bears", "Vile Bear", "sfx_bear_bite_attack", "TrophyBjorn"),
			new TrackedCreatureDefinition("Tracked Creatures - Mistlands", "SeekerBrute", "Track Seeker Soldiers", "Seeker Soldier", null, "TrophySeekerBrute"),
			new TrackedCreatureDefinition("Tracked Creatures - Mistlands", "Seeker", "Track 1-star or higher Seekers", "Seeker", null, "TrophySeeker", 2),
			new TrackedCreatureDefinition("Tracked Creatures - Mistlands", "Gjall", "Track Gjalls", "Gjall", null, "TrophyGjall"),
			new TrackedCreatureDefinition("Tracked Creatures - Ashlands", "Asksvin", "Track 2-star Asksvin", "Asksvin", "sfx_asksvin_idle", "TrophyAsksvin", 3),
			new TrackedCreatureDefinition("Tracked Creatures - Ashlands", "FallenValkyrie", "Track Fallen Valkyrie", "FallenValkyrie", "sfx_fallenvalkyrie_alert", "TrophyFallenValkyrie"),
			new TrackedCreatureDefinition("Tracked Creatures - Ashlands", "Morgen", "Track Morgens", "Morgen", "sfx_morgen_idle", "TrophyMorgen"),
			new TrackedCreatureDefinition("Tracked Creatures - Deep North", "Barka", "Track Barkas", "Barka", "Enemy_Barka_Footstep", "TrophyBarka"),
			new TrackedCreatureDefinition("Tracked Creatures - Deep North", "ShadowPerson", "Track Shadow Persons", "Shadow Person", null),
			new TrackedCreatureDefinition("Tracked Creatures - Deep North", "Skeleton_DeepNorth", "Track Deep North Skeletons", "Deep North Skeleton", null, "TrophySkeleton"),
			new TrackedCreatureDefinition("Tracked Creatures - Deep North", "Greydwarf_Frozen", "Track 2-star Frozen Greydwarfs", "Frozen Greydwarf", null, "TrophyGreydwarf", 3),
			new TrackedCreatureDefinition("Tracked Creatures - Deep North", "TrollFrost", "Track Gammeltrolls", "Gammeltroll", "sfx_gameltroll_melee_attack", "TrophyFrostTroll"),
			new TrackedCreatureDefinition("Tracked Creatures - Deep North", "Moose", "Track Moose", "Moose", "sfx_moose_alert", "TrophyMoose"),
			new TrackedCreatureDefinition("Tracked Creatures - Deep North", "FallenWarrior", "Track Fallen Warriors", "Fallen Warrior", "sfx_fallenwarrior_attack"),
			new TrackedCreatureDefinition("Tracked Creatures - Deep North", "ElakingMole", "Track Eyeless One", "Eyeless One", "ElakingMole_AttackClaw", "TrophyElaking"),
			new TrackedCreatureDefinition("Tracked Creatures - Deep North", "Elaking", "Track Elaking", "Elaking", "ElakingMole_AttackClaw", "TrophyElaking")
		};

		internal string ConfigSection { get; }

		internal string PrefabName { get; }

		internal string ConfigName { get; }

		internal string DisplayName { get; }

		internal string SoundEffectName { get; }

		internal string TrophyPrefabName { get; }

		internal int MinimumLevel { get; }

		internal TrackedCreatureDefinition(string configSection, string prefabName, string configName, string displayName, string soundEffectName, string trophyPrefabName = null, int minimumLevel = 1)
		{
			ConfigSection = configSection;
			PrefabName = prefabName;
			ConfigName = configName;
			DisplayName = displayName;
			SoundEffectName = soundEffectName;
			TrophyPrefabName = trophyPrefabName;
			MinimumLevel = minimumLevel;
		}
	}
}
namespace HexRareScanner.Patches
{
	[HarmonyPatch(typeof(Character), "OnDeath")]
	internal static class PatchCharacterOnDeath
	{
		private static void Prefix(Character __instance)
		{
			if (!Plugin.IsModEnabled || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			string prefabNameFromClone = PrefabNameHelper.GetPrefabNameFromClone(((Object)((Component)__instance).gameObject).name);
			if (!string.IsNullOrWhiteSpace(prefabNameFromClone))
			{
				Plugin.TrackedCreatureSetting trackedCreature = Plugin.GetTrackedCreature(prefabNameFromClone);
				if (trackedCreature != null && (int)Plugin.CharacterMLevelField.GetValue(__instance) >= trackedCreature.RarityLevel)
				{
					PinManager.RemoveCreaturePin(__instance);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class PatchCharacterAwake
	{
		private static void Postfix(Character __instance)
		{
			//IL_007e: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsModEnabled || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			string prefabNameFromClone = PrefabNameHelper.GetPrefabNameFromClone(((Object)((Component)__instance).gameObject).name);
			if (string.IsNullOrWhiteSpace(prefabNameFromClone))
			{
				return;
			}
			Plugin.TrackedCreatureSetting trackedCreature = Plugin.GetTrackedCreature(prefabNameFromClone);
			if (trackedCreature == null)
			{
				return;
			}
			int num = (int)Plugin.CharacterMLevelField.GetValue(__instance);
			if (num >= trackedCreature.RarityLevel && !PinManager.HasCreaturePin(__instance))
			{
				string text = trackedCreature.DisplayName;
				if (num > 1)
				{
					text = $"{num - 1}-star {text}";
				}
				Vector3 position = ((Component)__instance).transform.position;
				if (Plugin.PlayTrackedCreatureSound)
				{
					((MonoBehaviour)Plugin.Instance).StartCoroutine(PlayTrackedCreatureSound(trackedCreature.SoundEffectName, position));
				}
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "A " + text + " spawned!", 0, (Sprite)null, false);
				}
				PinManager.AddCreaturePin(__instance, position, text);
			}
		}

		private static IEnumerator PlayTrackedCreatureSound(string soundEffectName, Vector3 position)
		{
			//IL_000e: 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)
			yield return null;
			if (!string.IsNullOrEmpty(soundEffectName) && !((Object)(object)ZNetScene.instance == (Object)null))
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(soundEffectName);
				if (!((Object)(object)prefab == (Object)null))
				{
					Object.Instantiate<GameObject>(prefab, position, Quaternion.identity);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Minimap), "RemovePinUnderPointer")]
	internal static class PatchMinimapRemovePinUnderPointer
	{
		private static readonly MethodInfo ScreenToWorldPointMethod = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", new Type[1] { typeof(Vector3) }, (Type[])null);

		private static readonly MethodInfo GetClosestPinMethod = AccessTools.Method(typeof(Minimap), "GetClosestPin", new Type[3]
		{
			typeof(Vector3),
			typeof(float),
			typeof(bool)
		}, (Type[])null);

		private static readonly MethodInfo HidePinTextInputMethod = AccessTools.Method(typeof(Minimap), "HidePinTextInput", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly PropertyInfo PinInteractRadiusProperty = AccessTools.Property(typeof(Minimap), "PinInteractRadius");

		private static readonly FieldInfo NamePinField = AccessTools.Field(typeof(Minimap), "m_namePin");

		private static bool Prefix(Minimap __instance)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsModEnabled || !Plugin.IsManualPinRemovalEnabled || (Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (ScreenToWorldPointMethod == null || GetClosestPinMethod == null || PinInteractRadiusProperty == null)
			{
				return true;
			}
			Vector3 val = (Vector3)ScreenToWorldPointMethod.Invoke(__instance, new object[1] { ZInput.pointerPosition });
			float num = (float)PinInteractRadiusProperty.GetValue(__instance);
			PinData closestCreaturePin = PinManager.GetClosestCreaturePin(val, num);
			if (closestCreaturePin == null)
			{
				return true;
			}
			object? obj = GetClosestPinMethod.Invoke(__instance, new object[3] { val, num, true });
			PinData val2 = (PinData)((obj is PinData) ? obj : null);
			if (val2 != null)
			{
				float num2 = Utils.DistanceXZ(val, closestCreaturePin.m_pos);
				if (Utils.DistanceXZ(val, val2.m_pos) < num2)
				{
					return true;
				}
			}
			HidePinTextInputMethod?.Invoke(__instance, new object[1] { false });
			PinManager.RemoveCreaturePin(closestCreaturePin);
			NamePinField?.SetValue(__instance, null);
			return false;
		}
	}
}