Decompiled source of Radar Love v1.4.0

RadarLove.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;

[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: AssemblyCompany("RadarLove")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0+e6a3304c36e59bd0d96f2f5066f3270355b88690")]
[assembly: AssemblyProduct("RadarLove")]
[assembly: AssemblyTitle("RadarLove")]
[assembly: AssemblyVersion("1.4.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 DwarfHavenGames.RadarLove
{
	internal class Entry
	{
		public readonly string Section;

		public readonly string Display;

		public readonly string[] Names;

		public readonly string IconItem;

		public readonly bool DefaultOn;

		public ConfigEntry<bool> Toggle;

		public ConfigEntry<bool> Group;

		public ConfigEntry<bool> NameSetting;

		public bool Enabled
		{
			get
			{
				if (Group.Value)
				{
					if (Toggle != null)
					{
						return Toggle.Value;
					}
					return true;
				}
				return false;
			}
		}

		public Entry(string section, string display, string[] names, string iconItem, bool defaultOn = true)
		{
			Section = section;
			Display = display;
			Names = names;
			IconItem = iconItem;
			DefaultOn = defaultOn;
		}
	}
	internal static class Catalog
	{
		private static readonly Dictionary<string, Entry> Creatures = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Entry> Fish = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Entry> Pickables = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Entry> Ores = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Entry> Dungeons = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Entry> Locations = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Entry> Pois = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Entry> Custom = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase);

		private static ConfigEntry<bool> _customGroup;

		private static ConfigEntry<bool> _customNames;

		private static readonly char[] InvalidKeyChars = new char[8] { '=', '\n', '\t', '\\', '"', '\'', '[', ']' };

		private static readonly Entry[] CreatureEntries = new Entry[69]
		{
			new Entry("03 - Creatures (Meadows)", "Boar", new string[3] { "boar", "boar_piggy", "boar_spiritcaller" }, "TrophyBoar"),
			new Entry("03 - Creatures (Meadows)", "Neck", new string[1] { "neck" }, null),
			new Entry("03 - Creatures (Meadows)", "Deer", new string[2] { "deer", "deer_white" }, "TrophyDeer"),
			new Entry("03 - Creatures (Meadows)", "Greyling", new string[1] { "greyling" }, "TrophyGreydwarf"),
			new Entry("03 - Creatures (Meadows)", "Hen", new string[2] { "hen", "chicken" }, null),
			new Entry("03 - Creatures (Black Forest)", "Greydwarf", new string[1] { "greydwarf" }, null),
			new Entry("03 - Creatures (Black Forest)", "Greydwarf Brute", new string[1] { "greydwarf_elite" }, null),
			new Entry("03 - Creatures (Black Forest)", "Greydwarf Shaman", new string[1] { "greydwarf_shaman" }, null),
			new Entry("03 - Creatures (Black Forest)", "Skeleton", new string[2] { "skeleton", "skeleton_noarcher" }, "TrophySkeleton"),
			new Entry("03 - Creatures (Black Forest)", "Rancid Remains", new string[1] { "skeleton_poison" }, null),
			new Entry("03 - Creatures (Black Forest)", "Troll", new string[1] { "troll" }, null),
			new Entry("03 - Creatures (Black Forest)", "Bear", new string[2] { "bjorn", "bjorn_spiritcaller" }, "TrophyBjorn"),
			new Entry("03 - Creatures (Black Forest)", "Ghost", new string[1] { "ghost" }, null),
			new Entry("03 - Creatures (Swamp)", "Draugr", new string[2] { "draugr", "draugr_ranged" }, "TrophyDraugr"),
			new Entry("03 - Creatures (Swamp)", "Draugr Elite", new string[1] { "draugr_elite" }, null),
			new Entry("03 - Creatures (Swamp)", "Blob", new string[1] { "blob" }, null),
			new Entry("03 - Creatures (Swamp)", "Oozer", new string[1] { "blobelite" }, null),
			new Entry("03 - Creatures (Swamp)", "Leech", new string[2] { "leech", "leech_cave" }, "TrophyLeech"),
			new Entry("03 - Creatures (Swamp)", "Wraith", new string[1] { "wraith" }, null),
			new Entry("03 - Creatures (Swamp)", "Abomination", new string[1] { "abomination" }, null),
			new Entry("03 - Creatures (Swamp)", "Surtling", new string[1] { "surtling" }, null),
			new Entry("03 - Creatures (Swamp)", "Writhan", new string[1] { "writhan" }, null),
			new Entry("03 - Creatures (Swamp)", "Kvastur", new string[1] { "bogwitchkvastur" }, null),
			new Entry("03 - Creatures (Mountain)", "Wolf", new string[3] { "wolf", "wolf_cub", "wolf_spiritcaller" }, "TrophyWolf"),
			new Entry("03 - Creatures (Mountain)", "Fenring", new string[1] { "fenring" }, null),
			new Entry("03 - Creatures (Mountain)", "Cultist", new string[1] { "fenring_cultist" }, null),
			new Entry("03 - Creatures (Mountain)", "Ulv", new string[1] { "ulv" }, null),
			new Entry("03 - Creatures (Mountain)", "Stone Golem", new string[1] { "stonegolem" }, null),
			new Entry("03 - Creatures (Mountain)", "Drake", new string[1] { "hatchling" }, null),
			new Entry("03 - Creatures (Mountain)", "Bat", new string[1] { "bat" }, null),
			new Entry("03 - Creatures (Mountain)", "Gammeltroll", new string[1] { "trollfrost" }, null),
			new Entry("03 - Creatures (Mountain)", "Frost Wisp", new string[1] { "frostwisp" }, null),
			new Entry("03 - Creatures (Plains)", "Lox", new string[2] { "lox", "lox_calf" }, "TrophyLox"),
			new Entry("03 - Creatures (Plains)", "Deathsquito", new string[1] { "deathsquito" }, null),
			new Entry("03 - Creatures (Plains)", "Fuling", new string[2] { "goblin", "goblinarcher" }, "TrophyGoblin"),
			new Entry("03 - Creatures (Plains)", "Fuling Berserker", new string[1] { "goblinbrute" }, null),
			new Entry("03 - Creatures (Plains)", "Fuling Shaman", new string[1] { "goblinshaman" }, null),
			new Entry("03 - Creatures (Plains)", "Riktig Fuling", new string[1] { "goblin_gem" }, null),
			new Entry("03 - Creatures (Plains)", "Growth", new string[1] { "blobtar" }, null),
			new Entry("03 - Creatures (Plains)", "Vile", new string[1] { "unbjorn" }, null),
			new Entry("03 - Creatures (Mistlands)", "Seeker", new string[1] { "seeker" }, null),
			new Entry("03 - Creatures (Mistlands)", "Seeker Brood", new string[1] { "seekerbrood" }, "TrophySeeker"),
			new Entry("03 - Creatures (Mistlands)", "Seeker Soldier", new string[1] { "seekerbrute" }, null),
			new Entry("03 - Creatures (Mistlands)", "Gjall", new string[1] { "gjall" }, null),
			new Entry("03 - Creatures (Mistlands)", "Tick", new string[1] { "tick" }, null),
			new Entry("03 - Creatures (Mistlands)", "Dvergr Rogue", new string[2] { "dverger", "dvergerashlands" }, null),
			new Entry("03 - Creatures (Mistlands)", "Dvergr Mage", new string[4] { "dvergermage", "dvergermagefire", "dvergermageice", "dvergermagesupport" }, null),
			new Entry("03 - Creatures (Mistlands)", "Hare", new string[1] { "hare" }, null),
			new Entry("03 - Creatures (Ashlands)", "Asksvin", new string[2] { "asksvin", "asksvin_hatchling" }, "TrophyAsksvin"),
			new Entry("03 - Creatures (Ashlands)", "Charred Warrior", new string[1] { "charred_melee" }, null),
			new Entry("03 - Creatures (Ashlands)", "Charred Marksman", new string[1] { "charred_archer" }, null),
			new Entry("03 - Creatures (Ashlands)", "Charred Warlock", new string[1] { "charred_mage" }, null),
			new Entry("03 - Creatures (Ashlands)", "Charred Twitcher", new string[1] { "charred_twitcher" }, null),
			new Entry("03 - Creatures (Ashlands)", "Fallen Valkyrie", new string[1] { "fallenvalkyrie" }, null),
			new Entry("03 - Creatures (Ashlands)", "Lava Blob", new string[1] { "bloblava" }, null),
			new Entry("03 - Creatures (Ashlands)", "Morgen", new string[2] { "morgen", "morgen_nonsleeping" }, null),
			new Entry("03 - Creatures (Ashlands)", "Volture", new string[1] { "volture" }, null),
			new Entry("03 - Creatures (Ashlands)", "Bonemaw", new string[1] { "bonemawserpent" }, null),
			new Entry("03 - Creatures (Deep North)", "Moose", new string[3] { "moose", "moose_calf", "moose_spiritcaller" }, "TrophyMoose"),
			new Entry("03 - Creatures (Deep North)", "Seal", new string[2] { "seal", "seal_pup" }, "TrophySeal"),
			new Entry("03 - Creatures (Deep North)", "Barka", new string[1] { "barka" }, null),
			new Entry("03 - Creatures (Deep North)", "Elaking", new string[2] { "elaking", "elakinglantern" }, null),
			new Entry("03 - Creatures (Deep North)", "Eyeless One", new string[1] { "elakingmole" }, null),
			new Entry("03 - Creatures (Deep North)", "Hexen", new string[1] { "jotunwitch" }, null),
			new Entry("03 - Creatures (Deep North)", "Krigen", new string[2] { "jotunwarrior", "jotunwarriordualwield" }, null),
			new Entry("03 - Creatures (Deep North)", "Shadow", new string[1] { "shadowperson" }, null),
			new Entry("03 - Creatures (Deep North)", "Frysling", new string[1] { "frysling" }, null),
			new Entry("03 - Creatures (Deep North)", "Fallen Warrior", new string[1] { "fallenwarrior" }, null),
			new Entry("03 - Creatures (Ocean)", "Sea Serpent", new string[1] { "serpent" }, null)
		};

		private static readonly string[] NotCreatures = new string[28]
		{
			"eikthyr", "gd_king", "bonemass", "dragon", "goblinking", "seekerqueen", "fader", "frozenking*", "aspect_*", "thehive",
			"hive", "charred_melee_dyrnwyn", "skeleton_hildir*", "fenring_cultist_hildir*", "goblinbrute_hildir", "goblinshaman_hildir*", "goblinbrutebros*", "*_summoned", "charred_archer_fader", "charred_melee_fader",
			"staff_*", "tentaroot", "skeleton_friendly", "trainingdummy", "dvergertest", "mistile", "dvergerdeepnorth", "goblindeepnorth"
		};

		private static readonly Entry[] FishEntries = new Entry[12]
		{
			new Entry("04 - Fish", "Perch", new string[1] { "fish1" }, null),
			new Entry("04 - Fish", "Pike", new string[1] { "fish2" }, null),
			new Entry("04 - Fish", "Tuna", new string[1] { "fish3" }, null),
			new Entry("04 - Fish", "Tetra", new string[1] { "fish4_cave" }, null),
			new Entry("04 - Fish", "Trollfish", new string[1] { "fish5" }, null),
			new Entry("04 - Fish", "Giant Herring", new string[1] { "fish6" }, null),
			new Entry("04 - Fish", "Grouper", new string[1] { "fish7" }, null),
			new Entry("04 - Fish", "Coral Cod", new string[1] { "fish8" }, null),
			new Entry("04 - Fish", "Anglerfish", new string[1] { "fish9" }, null),
			new Entry("04 - Fish", "Northern Salmon", new string[1] { "fish10" }, null),
			new Entry("04 - Fish", "Magmafish", new string[1] { "fish11" }, null),
			new Entry("04 - Fish", "Pufferfish", new string[1] { "fish12" }, null)
		};

		private static readonly Entry[] PickableEntries = new Entry[42]
		{
			new Entry("05 - Pickables", "Raspberries", new string[1] { "raspberry" }, null),
			new Entry("05 - Pickables", "Blueberries", new string[1] { "blueberries" }, null),
			new Entry("05 - Pickables", "Cloudberries", new string[1] { "cloudberry" }, null),
			new Entry("05 - Pickables", "Lingonberries", new string[1] { "lingonberry" }, null),
			new Entry("05 - Pickables", "Vineberries", new string[1] { "vineberry" }, null),
			new Entry("05 - Pickables", "Mushrooms", new string[1] { "mushroom" }, null),
			new Entry("05 - Pickables", "Yellow Mushrooms", new string[1] { "mushroomyellow" }, null),
			new Entry("05 - Pickables", "Blue Mushrooms", new string[1] { "mushroomblue" }, null),
			new Entry("05 - Pickables", "Magecaps", new string[1] { "mushroommagecap" }, null),
			new Entry("05 - Pickables", "Jotun Puffs", new string[1] { "mushroomjotunpuffs" }, null),
			new Entry("05 - Pickables", "Smoke Puffs", new string[1] { "mushroomsmokepuff" }, null),
			new Entry("05 - Pickables", "Dandelions", new string[1] { "dandelion" }, null),
			new Entry("05 - Pickables", "Thistle", new string[1] { "thistle" }, null),
			new Entry("05 - Pickables", "Fiddleheads", new string[1] { "fiddleheadfern" }, null),
			new Entry("05 - Pickables", "Carrots", new string[2] { "carrotseeds", "carrot" }, null),
			new Entry("05 - Pickables", "Turnips", new string[2] { "turnipseeds", "turnip" }, null),
			new Entry("05 - Pickables", "Onions", new string[2] { "onionseeds", "onion" }, null),
			new Entry("05 - Pickables", "Kale", new string[2] { "kaleseeds", "kale" }, null),
			new Entry("05 - Pickables", "Oats", new string[1] { "oatseeds" }, null),
			new Entry("05 - Pickables", "Poteitr", new string[1] { "poteitr" }, null),
			new Entry("05 - Pickables", "Barley", new string[1] { "barley" }, null),
			new Entry("05 - Pickables", "Flax", new string[1] { "flax" }, null),
			new Entry("05 - Pickables", "Surtling Cores", new string[1] { "surtlingcore" }, null),
			new Entry("05 - Pickables", "Black Cores", new string[1] { "blackcore" }, null),
			new Entry("05 - Pickables", "Molten Cores", new string[1] { "moltencore" }, null),
			new Entry("05 - Pickables", "Frost Cores", new string[1] { "frostcore" }, null),
			new Entry("05 - Pickables", "Crystals", new string[1] { "crystal" }, null),
			new Entry("05 - Pickables", "Dragon Eggs", new string[1] { "dragonegg" }, null),
			new Entry("05 - Pickables", "Volture Eggs", new string[1] { "voltureegg" }, null),
			new Entry("05 - Pickables", "Fenris Hair", new string[1] { "wolfhairbundle" }, null),
			new Entry("05 - Pickables", "Royal Jelly", new string[1] { "royaljelly" }, null),
			new Entry("05 - Pickables", "Sulfur", new string[1] { "sulfurstone" }, null),
			new Entry("05 - Pickables", "Tar", new string[1] { "tar" }, null),
			new Entry("05 - Pickables", "Fuling Totems", new string[1] { "goblintotem" }, null),
			new Entry("05 - Pickables", "Luminous Larva", new string[1] { "glowworm" }, null),
			new Entry("05 - Pickables", "Pot Shards", new string[1] { "pot_shard_green" }, null, defaultOn: false),
			new Entry("05 - Pickables", "Meat Piles", new string[1] { "entrails" }, null, defaultOn: false),
			new Entry("05 - Pickables", "Grausten", new string[1] { "grausten" }, null, defaultOn: false),
			new Entry("05 - Pickables", "Flint", new string[1] { "flint" }, null, defaultOn: false),
			new Entry("05 - Pickables", "Stones", new string[1] { "stone" }, null, defaultOn: false),
			new Entry("05 - Pickables", "Branches", new string[1] { "wood" }, null, defaultOn: false),
			new Entry("05 - Pickables", "Snowballs", new string[1] { "snowball" }, null, defaultOn: false)
		};

		private static readonly Entry[] OreEntries = new Entry[10]
		{
			new Entry("06 - Ores", "Copper", new string[1] { "copperore" }, null),
			new Entry("06 - Ores", "Tin", new string[1] { "tinore" }, null),
			new Entry("06 - Ores", "Iron", new string[2] { "ironscrap", "ironore" }, null),
			new Entry("06 - Ores", "Silver", new string[1] { "silverore" }, null),
			new Entry("06 - Ores", "Obsidian", new string[1] { "obsidian" }, null),
			new Entry("06 - Ores", "Flametal", new string[1] { "flametalorenew" }, null),
			new Entry("06 - Ores", "Black Marble", new string[1] { "blackmarble" }, null),
			new Entry("06 - Ores", "Soft Tissue", new string[1] { "softtissue" }, null),
			new Entry("06 - Ores", "Leviathan", new string[1] { "chitin" }, null),
			new Entry("06 - Ores", "Guck", new string[1] { "guck" }, null)
		};

		private static readonly Entry[] DungeonEntries = new Entry[7]
		{
			new Entry("07 - Dungeons", "Burial Chambers", new string[1] { "$location_forestcrypt" }, "SurtlingCore"),
			new Entry("07 - Dungeons", "Sunken Crypts", new string[1] { "$location_sunkencrypt" }, "WitheredBone"),
			new Entry("07 - Dungeons", "Troll Caves", new string[1] { "$location_forestcave" }, "TrophyForestTroll"),
			new Entry("07 - Dungeons", "Mountain Caves", new string[1] { "$location_mountaincave" }, "JuteRed"),
			new Entry("07 - Dungeons", "Bear Caves", new string[1] { "$location_bearcave" }, "TrophyBjorn"),
			new Entry("07 - Dungeons", "Infested Mines", new string[1] { "$location_dvergrtown" }, "BlackCore"),
			new Entry("07 - Dungeons", "Morgen Holes", new string[1] { "$location_morgenhole" }, "TrophyMorgen")
		};

		private static readonly Entry[] PoiEntries = new Entry[7]
		{
			new Entry("08 - Points of Interest", "Wild Beehives", new string[1] { "beehive" }, "QueenBee"),
			new Entry("08 - Points of Interest", "Greydwarf Nests", new string[1] { "spawner_greydwarfnest" }, "AncientSeed"),
			new Entry("08 - Points of Interest", "Body Piles", new string[1] { "spawner_draugrpile" }, "TrophyDraugr"),
			new Entry("08 - Points of Interest", "Evil Bone Piles", new string[1] { "bonepilespawner" }, "TrophySkeleton"),
			new Entry("08 - Points of Interest", "Effigies of Malice", new string[1] { "spawner_charredcross" }, null),
			new Entry("08 - Points of Interest", "Monuments of Torment", new string[2] { "spawner_charredstone", "spawner_charredstone_elite" }, null),
			new Entry("08 - Points of Interest", "Malicious Ice", new string[1] { "blackice_core" }, null)
		};

		private const string RunestoneIcon = "TankardAnniversary|Thunderstone";

		private static readonly Entry[] LocationEntries = new Entry[47]
		{
			new Entry("09 - Locations", "Runestones", new string[11]
			{
				"runestone_greydwarfs", "runestone_blackforest", "runestone_meadows", "runestone_boars", "runestone_mistlands", "runestone_mountains", "runestone_draugr", "runestone_swamps", "runestone_plains", "runestone_ashlands",
				"drakelorestone"
			}, "TankardAnniversary|Thunderstone"),
			new Entry("09 - Locations", "Drake Nest", new string[1] { "drakenest01" }, "DragonEgg"),
			new Entry("09 - Locations", "Tar Pit", new string[3] { "tarpit1", "tarpit2", "tarpit3" }, "Tar"),
			new Entry("09 - Locations", "Fuling Camp", new string[1] { "goblincamp2" }, "GoblinTotem"),
			new Entry("09 - Locations", "Charred Fortress", new string[1] { "charredfortress" }, null),
			new Entry("09 - Locations", "Shipwreck", new string[4] { "shipwreck01", "shipwreck02", "shipwreck03", "shipwreck04" }, null, defaultOn: false),
			new Entry("09 - Locations", "Black Forest Ruins", new string[3] { "ruin1", "ruin2", "combatruin01" }, null, defaultOn: false),
			new Entry("09 - Locations", "Stone Tower Ruins", new string[7] { "stonetowerruins03", "stonetowerruins04", "stonetowerruins05", "stonetowerruins07", "stonetowerruins08", "stonetowerruins09", "stonetowerruins10" }, null, defaultOn: false),
			new Entry("09 - Locations", "Greydwarf Camp", new string[1] { "greydwarf_camp1" }, null, defaultOn: false),
			new Entry("09 - Locations", "Wood House", new string[13]
			{
				"woodhouse1", "woodhouse2", "woodhouse3", "woodhouse4", "woodhouse5", "woodhouse6", "woodhouse7", "woodhouse8", "woodhouse9", "woodhouse10",
				"woodhouse11", "woodhouse12", "woodhouse13"
			}, null, defaultOn: false),
			new Entry("09 - Locations", "Abandoned Farm", new string[1] { "woodfarm1" }, null, defaultOn: false),
			new Entry("09 - Locations", "Abandoned Village", new string[1] { "woodvillage1" }, null, defaultOn: false),
			new Entry("09 - Locations", "Ship Setting", new string[1] { "shipsetting01" }, null, defaultOn: false),
			new Entry("09 - Locations", "Stone Circle", new string[1] { "stonecircle" }, null, defaultOn: false),
			new Entry("09 - Locations", "Dolmen", new string[3] { "dolmen01", "dolmen02", "dolmen03" }, null, defaultOn: false),
			new Entry("09 - Locations", "Swamp Hut", new string[5] { "swamphut1", "swamphut2", "swamphut3", "swamphut4", "swamphut5" }, null, defaultOn: false),
			new Entry("09 - Locations", "Swamp Ruin", new string[2] { "swampruin1", "swampruin2" }, null, defaultOn: false),
			new Entry("09 - Locations", "Fire Hole", new string[1] { "firehole" }, null, defaultOn: false),
			new Entry("09 - Locations", "Infested Tree", new string[1] { "infestedtree01" }, "Guck", defaultOn: false),
			new Entry("09 - Locations", "Grave", new string[2] { "grave1", "mountaingrave01" }, null, defaultOn: false),
			new Entry("09 - Locations", "Well", new string[2] { "swampwell1", "mountainwell1" }, null, defaultOn: false),
			new Entry("09 - Locations", "Log Cabin", new string[3] { "abandonedlogcabin02", "abandonedlogcabin03", "abandonedlogcabin04" }, null, defaultOn: false),
			new Entry("09 - Locations", "Waymarker", new string[2] { "waymarker01", "waymarker02" }, null, defaultOn: false),
			new Entry("09 - Locations", "Stone Henge", new string[6] { "stonehenge1", "stonehenge2", "stonehenge3", "stonehenge4", "stonehenge5", "stonehenge6" }, null, defaultOn: false),
			new Entry("09 - Locations", "Stone House", new string[5] { "stonehouse1_heath", "stonehouse2_heath", "stonehouse3", "stonehouse4", "stonehouse5_heath" }, null, defaultOn: false),
			new Entry("09 - Locations", "Stone Tower", new string[3] { "stonetower1", "stonetower3", "ruin3" }, null, defaultOn: false),
			new Entry("09 - Locations", "Dvergr Excavation", new string[3] { "mistlands_excavation1", "mistlands_excavation2", "mistlands_excavation3" }, null, defaultOn: false),
			new Entry("09 - Locations", "Dvergr Guard Tower", new string[6] { "mistlands_guardtower1_new", "mistlands_guardtower2_new", "mistlands_guardtower3_new", "mistlands_guardtower1_ruined_new", "mistlands_guardtower1_ruined_new2", "mistlands_guardtower3_ruined_new" }, null, defaultOn: false),
			new Entry("09 - Locations", "Dvergr Harbour", new string[1] { "mistlands_harbour1" }, null, defaultOn: false),
			new Entry("09 - Locations", "Dvergr Lighthouse", new string[1] { "mistlands_lighthouse1_new" }, null, defaultOn: false),
			new Entry("09 - Locations", "Giant Remains", new string[2] { "mistlands_giant1", "mistlands_giant2" }, null, defaultOn: false),
			new Entry("09 - Locations", "Sword Stones", new string[3] { "mistlands_swords1", "mistlands_swords2", "mistlands_swords3" }, null, defaultOn: false),
			new Entry("09 - Locations", "Road Post", new string[1] { "mistlands_roadpost1" }, null, defaultOn: false),
			new Entry("09 - Locations", "Statues", new string[3] { "mistlands_statue1", "mistlands_statue2", "mistlands_statuegroup1" }, null, defaultOn: false),
			new Entry("09 - Locations", "Viaduct", new string[2] { "mistlands_viaduct1", "mistlands_viaduct2" }, null, defaultOn: false),
			new Entry("09 - Locations", "Rock Spire", new string[1] { "mistlands_rockspire1" }, null, defaultOn: false),
			new Entry("09 - Locations", "Charred Ruin", new string[4] { "charredruins1", "charredruins2", "charredruins3", "charredruins4" }, null, defaultOn: false),
			new Entry("09 - Locations", "Charred Tower", new string[4] { "charredtowerruins1", "charredtowerruins1_dvergr", "charredtowerruins2", "charredtowerruins3" }, null, defaultOn: false),
			new Entry("09 - Locations", "Fortress Ruin", new string[1] { "fortressruins" }, null, defaultOn: false),
			new Entry("09 - Locations", "Ashlands Ruin", new string[1] { "ashlandruins" }, null, defaultOn: false),
			new Entry("09 - Locations", "Place of Mystery", new string[3] { "placeofmystery1", "placeofmystery2", "placeofmystery3" }, null, defaultOn: false),
			new Entry("09 - Locations", "Sulfur Arch", new string[1] { "sulfurarch" }, null, defaultOn: false),
			new Entry("09 - Locations", "Volture Nest", new string[1] { "volturenest" }, "VoltureEgg", defaultOn: false),
			new Entry("09 - Locations", "Frozen Ship", new string[3] { "frozenship01_dn", "frozenship02_dn", "frozenship03_dn" }, null, defaultOn: false),
			new Entry("09 - Locations", "North Village", new string[1] { "northvillage" }, null, defaultOn: false),
			new Entry("09 - Locations", "Lumber Camp", new string[1] { "lumbercamp" }, null, defaultOn: false),
			new Entry("09 - Locations", "North Memorial", new string[1] { "northmemorialplace" }, null, defaultOn: false)
		};

		public static Entry OtherCreatures { get; private set; }

		public static Entry OtherPickables { get; private set; }

		public static Entry OtherDungeons { get; private set; }

		public static IEnumerable<Entry> AllDungeons => DungeonEntries;

		public static void Bind(ConfigFile config, Config settings)
		{
			OtherCreatures = new Entry("03 - Creatures (Other)", "Other Creatures", new string[0], null);
			OtherPickables = new Entry("05 - Pickables", "Other Pickables", new string[0], null, defaultOn: false);
			OtherDungeons = new Entry("07 - Dungeons", "Other Dungeons", new string[0], null);
			BindAll(config, CreatureEntries, settings.GroupCreatures, Creatures);
			BindOne(config, OtherCreatures, settings.GroupCreatures, "Creatures not listed above, such as ones other mods add.");
			BindAll(config, FishEntries, settings.GroupFish, Fish);
			BindAll(config, PickableEntries, settings.GroupPickables, Pickables);
			BindOne(config, OtherPickables, settings.GroupPickables, "Pickables not listed above.");
			BindAll(config, OreEntries, settings.GroupOres, Ores);
			BindAll(config, DungeonEntries, settings.GroupDungeons, Dungeons);
			BindOne(config, OtherDungeons, settings.GroupDungeons, "Dungeons not listed above, such as ones other mods add.");
			Entry[] dungeonEntries = DungeonEntries;
			for (int i = 0; i < dungeonEntries.Length; i++)
			{
				dungeonEntries[i].NameSetting = settings.DungeonNames;
			}
			OtherDungeons.NameSetting = settings.DungeonNames;
			BindAll(config, PoiEntries, settings.GroupPois, Pois);
			BindAll(config, LocationEntries, settings.GroupLocations, Locations);
			_customGroup = settings.GroupCustom;
			_customNames = settings.CustomNames;
			ParseCustom(settings.CustomPins.Value);
		}

		public static void ParseCustom(string value)
		{
			Custom.Clear();
			string[] array = value.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { '=' });
				string text = array2[0].Trim();
				if (text.Length != 0)
				{
					string text2 = ((array2.Length > 1) ? array2[1].Trim() : "");
					string display = ((array2.Length > 2 && array2[2].Trim().Length > 0) ? array2[2].Trim() : text);
					Custom[text] = new Entry("11 - Custom", display, new string[1] { text }, (text2.Length > 0) ? text2 : null)
					{
						Group = _customGroup,
						NameSetting = _customNames
					};
				}
			}
		}

		public static Entry CustomFor(string prefab)
		{
			if (!Custom.TryGetValue(prefab, out var value))
			{
				return null;
			}
			return value;
		}

		private static void BindAll(ConfigFile config, Entry[] entries, ConfigEntry<bool> group, Dictionary<string, Entry> lookup)
		{
			foreach (Entry entry in entries)
			{
				BindOne(config, entry, group, "Show " + entry.Display + " on the radar.");
				string[] names = entry.Names;
				foreach (string key in names)
				{
					lookup[key] = entry;
				}
			}
		}

		private static void BindOne(ConfigFile config, Entry entry, ConfigEntry<bool> group, string description)
		{
			entry.Group = group;
			string text = string.Concat(entry.Display.Split(InvalidKeyChars));
			entry.Toggle = config.Bind<bool>(entry.Section, text, entry.DefaultOn, description);
		}

		public static Entry Creature(string prefab)
		{
			if (Creatures.TryGetValue(prefab, out var value))
			{
				return value;
			}
			if (!Matches(NotCreatures, prefab))
			{
				return OtherCreatures;
			}
			return null;
		}

		private static bool Matches(string[] patterns, string prefab)
		{
			foreach (string obj in patterns)
			{
				bool flag = obj.StartsWith("*");
				bool flag2 = obj.EndsWith("*");
				string value = obj.Trim(new char[1] { '*' });
				if (flag ? prefab.EndsWith(value, StringComparison.OrdinalIgnoreCase) : (flag2 ? prefab.StartsWith(value, StringComparison.OrdinalIgnoreCase) : prefab.Equals(value, StringComparison.OrdinalIgnoreCase)))
				{
					return true;
				}
			}
			return false;
		}

		public static Entry FishKind(string prefab)
		{
			if (!Fish.TryGetValue(prefab, out var value))
			{
				return null;
			}
			return value;
		}

		public static Entry Pickable(string item)
		{
			if (!Pickables.TryGetValue(item, out var value))
			{
				return OtherPickables;
			}
			return value;
		}

		public static Entry Ore(string item)
		{
			if (!Ores.TryGetValue(item, out var value))
			{
				return null;
			}
			return value;
		}

		public static Entry Dungeon(string enterText)
		{
			if (enterText == null || !Dungeons.TryGetValue(enterText, out var value))
			{
				return OtherDungeons;
			}
			return value;
		}

		public static Entry Location(string prefab)
		{
			if (!Locations.TryGetValue(prefab, out var value))
			{
				return null;
			}
			return value;
		}

		public static Entry Poi(string prefab)
		{
			if (!Pois.TryGetValue(prefab, out var value))
			{
				return null;
			}
			return value;
		}
	}
	internal class Config
	{
		public ConfigEntry<bool> Enabled { get; }

		public ConfigEntry<float> Radius { get; }

		public ConfigEntry<bool> ShowLabels { get; }

		public ConfigEntry<bool> DungeonNames { get; }

		public ConfigEntry<bool> CustomNames { get; }

		public ConfigEntry<float> GroupDistance { get; }

		public ConfigEntry<float> CreatureGroupDistance { get; }

		public ConfigEntry<bool> RestoreDismissed { get; }

		public ConfigEntry<bool> ConfirmDismiss { get; }

		public ConfigEntry<KeyboardShortcut> KeepKey { get; }

		public ConfigEntry<bool> GroupCreatures { get; }

		public ConfigEntry<bool> GroupFish { get; }

		public ConfigEntry<bool> GroupPickables { get; }

		public ConfigEntry<bool> GroupOres { get; }

		public ConfigEntry<bool> GroupDungeons { get; }

		public ConfigEntry<bool> GroupPois { get; }

		public ConfigEntry<bool> GroupCustom { get; }

		public ConfigEntry<string> CustomPins { get; }

		public ConfigEntry<bool> GroupLocations { get; }

		public ConfigEntry<bool> AutoPinDungeons { get; }

		public ConfigEntry<float> DiscoverDistance { get; }

		public ConfigEntry<bool> PinMessage { get; }

		public Config(ConfigFile config)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Expected O, but got Unknown
			Enabled = config.Bind<bool>("01 - General", "Enabled", true, "Turn the radar on or off. Dungeon pins have their own switch.");
			Radius = config.Bind<float>("01 - General", "Radius", 70f, new ConfigDescription("How close something has to be, in metres, before it appears on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 150f), Array.Empty<object>()));
			ShowLabels = config.Bind<bool>("01 - General", "Show Labels", false, "Show a name under every radar icon. When off, a name only appears under icons that do not already say what they are.");
			DungeonNames = config.Bind<bool>("01 - General", "Show Dungeon Names", true, "Show the dungeon's name under dungeon pins, both on the radar and on the pins saved when you find one.");
			CustomNames = config.Bind<bool>("01 - General", "Show Custom Names", false, "Show the name under pins you added in Custom Pins.");
			ShowLabels.SettingChanged += delegate
			{
				Radar.Refresh();
			};
			DungeonNames.SettingChanged += delegate
			{
				Radar.Refresh();
			};
			CustomNames.SettingChanged += delegate
			{
				Radar.Refresh();
			};
			GroupDistance = config.Bind<float>("01 - General", "Group Distance", 15f, new ConfigDescription("Things of the same kind closer together than this, in metres, share one pin with a count.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>()));
			CreatureGroupDistance = config.Bind<float>("01 - General", "Creature Group Distance", 15f, new ConfigDescription("The same for creatures and fish. Lower it to see them one by one.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>()));
			ConfirmDismiss = config.Bind<bool>("01 - General", "Confirm Before Dismiss", true, "Ask before a right-click removes a radar pin: right-click once, then again within a few seconds to remove it. Your own pins are not affected.");
			KeepKey = config.Bind<KeyboardShortcut>("01 - General", "Keep Pin Key", new KeyboardShortcut((KeyCode)112, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Saves the nearest radar pin to your map, or pins where you stand if there is none nearby.");
			RestoreDismissed = config.Bind<bool>("01 - General", "Restore Dismissed Pins", false, "Set to true to bring back every radar pin you right-clicked away in this world. It switches itself back off.");
			RestoreDismissed.SettingChanged += delegate
			{
				if (RestoreDismissed.Value)
				{
					Dismissals.RestoreAll();
					RestoreDismissed.Value = false;
				}
			};
			GroupCreatures = config.Bind<bool>("02 - Groups", "Creatures", true, "Show creatures. Each one also has its own switch.");
			GroupFish = config.Bind<bool>("02 - Groups", "Fish", true, "Show fish. Each one also has its own switch.");
			GroupPickables = config.Bind<bool>("02 - Groups", "Pickables", true, "Show pickables. Each one also has its own switch.");
			GroupOres = config.Bind<bool>("02 - Groups", "Ores", true, "Show ore deposits. Each one also has its own switch.");
			GroupDungeons = config.Bind<bool>("02 - Groups", "Dungeons", true, "Show dungeon entrances. Each one also has its own switch.");
			GroupPois = config.Bind<bool>("02 - Groups", "Points of Interest", true, "Show spawners and wild beehives. Each one also has its own switch.");
			GroupLocations = config.Bind<bool>("02 - Groups", "Locations", true, "Show runestones, ruins and other locations. Each one also has its own switch.");
			GroupCustom = config.Bind<bool>("02 - Groups", "Custom", true, "Show what you have added under Custom Pins.");
			CustomPins = config.Bind<string>("11 - Custom", "Custom Pins", "", "Add anything the radar does not already know, such as things from other mods. Write the prefab name, then = and the item whose icon to show, separated by commas: MyOreRock=CopperOre, SomeCave=TrophySkeleton. Add a third part for the name shown under the pin: SomeCave=TrophySkeleton=Spooky Cave. Leave the icon out to use the object's own. Look at the thing and use the radar_hover console command to get its prefab name.");
			CustomPins.SettingChanged += delegate
			{
				Catalog.ParseCustom(CustomPins.Value);
				Radar.Rescan();
			};
			AutoPinDungeons = config.Bind<bool>("10 - Dungeon Pins", "Auto-Pin Dungeons", true, "Pin a dungeon entrance to your map the first time you reach it. These pins are saved like your own.");
			DiscoverDistance = config.Bind<float>("10 - Dungeon Pins", "Discover Distance", 10f, new ConfigDescription("How close to the edge of a dungeon entrance you have to come, in metres, for it to be pinned.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
			PinMessage = config.Bind<bool>("10 - Dungeon Pins", "Pinned Message", true, "Show a message when a dungeon is pinned.");
			Catalog.Bind(config, this);
		}
	}
	internal static class Dismissals
	{
		private class SpotStore
		{
			private readonly string _prefix;

			private readonly HashSet<string> _spots = new HashSet<string>();

			private Player _loadedFor;

			public SpotStore(string prefix)
			{
				_prefix = prefix;
			}

			public bool Contains(string spot)
			{
				return Loaded().Contains(spot);
			}

			public void Add(string spot)
			{
				Loaded().Add(spot);
			}

			public void Remove(string spot)
			{
				Loaded().Remove(spot);
			}

			public void Clear()
			{
				Loaded().Clear();
			}

			public void Save()
			{
				Player localPlayer = Player.m_localPlayer;
				string text = Key();
				if (Object.op_Implicit((Object)(object)localPlayer) && text != null)
				{
					if (_spots.Count == 0)
					{
						localPlayer.m_customData.Remove(text);
					}
					else
					{
						localPlayer.m_customData[text] = string.Join(";", _spots);
					}
				}
			}

			private string Key()
			{
				if (!Object.op_Implicit((Object)(object)ZNet.instance))
				{
					return null;
				}
				return _prefix + ZNet.instance.GetWorldUID();
			}

			private HashSet<string> Loaded()
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)(object)_loadedFor)
				{
					return _spots;
				}
				_loadedFor = localPlayer;
				_spots.Clear();
				string text = Key();
				if (Object.op_Implicit((Object)(object)localPlayer) && text != null && localPlayer.m_customData.TryGetValue(text, out var value))
				{
					string[] array = value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
					foreach (string item in array)
					{
						_spots.Add(item);
					}
				}
				return _spots;
			}
		}

		private static readonly SpotStore Dismissed = new SpotStore("dwarfhavengames.radarlove.dismissed.");

		private static readonly SpotStore Crossed = new SpotStore("dwarfhavengames.radarlove.checked.");

		private const float ConfirmWindow = 3f;

		private static Blip _pending;

		private static float _pendingUntil;

		private static readonly FieldRef<Minimap, List<PinData>> PinsRef = AccessTools.FieldRefAccess<Minimap, List<PinData>>("m_pins");

		public static bool IsDismissed(Blip blip)
		{
			if (!blip.Moves)
			{
				return Dismissed.Contains(SpotOf(blip));
			}
			return false;
		}

		public static bool IsCrossed(Blip blip)
		{
			if (!blip.Moves)
			{
				return Crossed.Contains(SpotOf(blip));
			}
			return blip.Crossed;
		}

		public static bool IsCrossed(List<Blip> members)
		{
			if (members.Count > 0)
			{
				return members.All(IsCrossed);
			}
			return false;
		}

		public static bool TryDismiss(Minimap minimap, Vector3 pointer, float radius)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Blip blip = RadarPinUnder(minimap, pointer, radius);
			if (blip == null)
			{
				return false;
			}
			if (RadarLovePlugin.Settings.ConfirmDismiss.Value && (_pending != blip || Time.time > _pendingUntil))
			{
				_pending = blip;
				_pendingUntil = Time.time + 3f;
				string text = ((blip.Members.Count > 1) ? $"these {blip.Members.Count} pins" : ("the " + blip.Name() + " pin"));
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "Right-click again to remove " + text, 0, (Sprite)null, false);
				}
				return true;
			}
			_pending = null;
			foreach (Blip member in blip.Members)
			{
				member.Hidden = true;
				if (!member.Moves && Object.op_Implicit((Object)(object)member.Source))
				{
					Dismissed.Add(SpotOf(member));
				}
			}
			Dismissed.Save();
			Radar.Unpin(blip);
			return true;
		}

		public static void TryToggleCross(Minimap minimap, Vector3 pointer, float radius)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Blip blip = RadarPinUnder(minimap, pointer, radius);
			if (blip == null)
			{
				return;
			}
			bool flag = !IsCrossed(blip.Members);
			foreach (Blip member in blip.Members)
			{
				if (member.Moves)
				{
					member.Crossed = flag;
				}
				else if (Object.op_Implicit((Object)(object)member.Source) && flag)
				{
					Crossed.Add(SpotOf(member));
				}
				else if (Object.op_Implicit((Object)(object)member.Source))
				{
					Crossed.Remove(SpotOf(member));
				}
			}
			Crossed.Save();
			blip.Pin.m_checked = flag;
		}

		public static void RestoreAll()
		{
			Dismissed.Clear();
			Dismissed.Save();
			Radar.ClearHidden();
		}

		internal static Blip RadarPinUnder(Minimap minimap, Vector3 pointer, float radius)
		{
			//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_0036: Unknown result type (might be due to invalid IL or missing references)
			if (PinsRef.Invoke(minimap).Any((PinData p) => p.m_save && Visible(p) && Utils.DistanceXZ(pointer, p.m_pos) < radius))
			{
				return null;
			}
			return Radar.ClosestPinned(pointer, radius);
		}

		private static bool Visible(PinData pin)
		{
			if (Object.op_Implicit((Object)(object)pin.m_uiElement))
			{
				return ((Component)pin.m_uiElement).gameObject.activeInHierarchy;
			}
			return false;
		}

		internal static string SpotOf(Blip blip)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (blip.Spot == null)
			{
				Vector3 position = blip.Source.transform.position;
				blip.Spot = $"{blip.Entry.Display}@{Mathf.RoundToInt(position.x)},{Mathf.RoundToInt(position.z)}";
			}
			return blip.Spot;
		}
	}
	internal static class DungeonPins
	{
		private const PinType SavedType = (PinType)3;

		private const string PinnedKeyPrefix = "dwarfhavengames.radarlove.dungeon.";

		private static readonly FieldRef<Minimap, List<PinData>> PinsRef = AccessTools.FieldRefAccess<Minimap, List<PinData>>("m_pins");

		private static readonly List<Location> Dungeons = new List<Location>();

		public static void Track(Location location)
		{
			//IL_003d: 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_0043: 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)
			if (Radar.PrefabName(((Component)location).gameObject).StartsWith("Hildir_", StringComparison.OrdinalIgnoreCase))
			{
				return;
			}
			if (!Dungeons.Contains(location))
			{
				Dungeons.Add(location);
			}
			Player localPlayer = Player.m_localPlayer;
			Vector3 position = ((Component)location).transform.position;
			string text = PinnedKey(position);
			if (Object.op_Implicit((Object)(object)localPlayer) && text != null && localPlayer.m_customData.TryGetValue(text, out var value) && !TryParse(value, out var _, out var _, out var _))
			{
				int num = value.IndexOf('|');
				if (num >= 0)
				{
					localPlayer.m_customData[text] = Record(value.Substring(0, num), position, value.Substring(num + 1));
				}
			}
		}

		public static void Clear()
		{
			Dungeons.Clear();
		}

		public static void Tick(Vector3 here)
		{
			//IL_0058: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (!RadarLovePlugin.Settings.AutoPinDungeons.Value)
			{
				return;
			}
			float value = RadarLovePlugin.Settings.DiscoverDistance.Value;
			for (int num = Dungeons.Count - 1; num >= 0; num--)
			{
				Location val = Dungeons[num];
				if (!Object.op_Implicit((Object)(object)val))
				{
					Dungeons.RemoveAt(num);
				}
				else
				{
					Vector3 position = ((Component)val).transform.position;
					float num2 = val.m_exteriorRadius + value;
					if (!(Utils.DistanceXZ(here, position) > num2))
					{
						Dungeons.RemoveAt(num);
						Discover(val, position);
					}
				}
			}
		}

		private static void Discover(Location location, Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			string text = PinnedKey(pos);
			Player localPlayer = Player.m_localPlayer;
			if (text == null || localPlayer.m_customData.ContainsKey(text))
			{
				Radar.Suppress((Component)(object)location);
			}
			else if (!HasSavedPinNear(pos, Mathf.Max(location.m_exteriorRadius, 10f)))
			{
				string text2 = Catalog.Dungeon(EnterText(location)).IconItem ?? "";
				string text3 = NameFor(location);
				localPlayer.m_customData[text] = Record(text2, pos, text3);
				Sprite val = Icons.ItemIcon(text2);
				AddPin(Minimap.instance, pos, text3, val, isChecked: false);
				Radar.Suppress((Component)(object)location);
				if (RadarLovePlugin.Settings.PinMessage.Value)
				{
					((Character)localPlayer).Message((MessageType)1, text3 + " pinned to map", 0, val, false);
				}
			}
		}

		private static bool ShowName(Sprite icon)
		{
			if (!RadarLovePlugin.Settings.DungeonNames.Value)
			{
				return (Object)(object)icon == (Object)null;
			}
			return true;
		}

		private static PinData AddPin(Minimap minimap, Vector3 pos, string name, Sprite icon, bool isChecked)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			PinData val = minimap.AddPin(pos, (PinType)3, ShowName(icon) ? name : "", true, isChecked, 0L, default(PlatformUserID));
			if (Object.op_Implicit((Object)(object)icon))
			{
				val.m_icon = icon;
			}
			return val;
		}

		public static void Sync(Minimap minimap)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			//IL_0064: 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)
			//IL_0154: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return;
			}
			List<PinData> list = PinsRef.Invoke(minimap);
			for (int num = list.Count - 1; num >= 0; num--)
			{
				PinData pin = list[num];
				if (!pin.m_save || (int)pin.m_type != 3)
				{
					continue;
				}
				string text = PinnedKey(pin.m_pos);
				if (text == null || !localPlayer.m_customData.TryGetValue(text, out var value))
				{
					continue;
				}
				if (!TryParse(value, out var iconItem, out var spot, out var name))
				{
					if (pin.m_name.Length == 0 || !IsDungeonName(value, pin.m_name))
					{
						continue;
					}
					int num2 = value.IndexOf('|');
					iconItem = ((num2 >= 0) ? value.Substring(0, num2) : (Catalog.AllDungeons.First((Entry e) => e.Names.Any((string t) => Radar.Localize(t) == pin.m_name)).IconItem ?? ""));
					name = pin.m_name;
					spot = pin.m_pos;
					localPlayer.m_customData[text] = Record(iconItem, spot, name);
				}
				if (Utils.DistanceXZ(pin.m_pos, spot) > 1f)
				{
					continue;
				}
				Entry entry = Catalog.AllDungeons.FirstOrDefault((Entry e) => e.Names.Any((string t) => Radar.Localize(t) == name));
				if (entry != null && entry.IconItem != null && entry.IconItem != iconItem)
				{
					iconItem = entry.IconItem;
					localPlayer.m_customData[text] = Record(iconItem, spot, name);
				}
				if (pin.m_name != name && pin.m_name.Length > 0)
				{
					continue;
				}
				Sprite val = Icons.ItemIcon(iconItem);
				if (pin.m_name != (ShowName(val) ? name : ""))
				{
					minimap.RemovePin(pin);
					AddPin(minimap, pin.m_pos, name, val, pin.m_checked);
				}
				else if (Object.op_Implicit((Object)(object)val) && (Object)(object)pin.m_icon != (Object)(object)val)
				{
					pin.m_icon = val;
					if (Object.op_Implicit((Object)(object)pin.m_iconElement))
					{
						pin.m_iconElement.sprite = val;
					}
				}
			}
		}

		public static Sprite IconFor(Location location)
		{
			return Icons.ItemIcon(Catalog.Dungeon(EnterText(location)).IconItem);
		}

		public static string NameFor(Location location)
		{
			string text = EnterText(location);
			if (text == null)
			{
				return Radar.PrefabName(((Component)location).gameObject);
			}
			return Radar.Localize(text);
		}

		public static string EnterText(Location location)
		{
			return ((IEnumerable<Teleport>)((Component)location).GetComponentsInChildren<Teleport>(true)).FirstOrDefault((Func<Teleport, bool>)((Teleport t) => !string.IsNullOrEmpty(t.m_enterText) && t.m_enterText != "$location_exit"))?.m_enterText;
		}

		private static string Record(string iconItem, Vector3 pos, string name)
		{
			return string.Join("|", iconItem, pos.x.ToString("R", CultureInfo.InvariantCulture), pos.z.ToString("R", CultureInfo.InvariantCulture), name);
		}

		private static bool TryParse(string record, out string iconItem, out Vector3 spot, out string name)
		{
			//IL_0009: 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)
			iconItem = (name = null);
			spot = default(Vector3);
			string[] array = record.Split(new char[1] { '|' }, 4);
			if (array.Length < 4 || !float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || !float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
			{
				return false;
			}
			iconItem = array[0];
			spot = new Vector3(result, 0f, result2);
			name = array[3];
			return true;
		}

		private static bool IsDungeonName(string record, string pinName)
		{
			int num = record.IndexOf('|');
			if (num >= 0)
			{
				return record.Substring(num + 1) == pinName;
			}
			return Catalog.AllDungeons.Any((Entry e) => e.Names.Any((string t) => Radar.Localize(t) == pinName));
		}

		private static bool HasSavedPinNear(Vector3 pos, float radius)
		{
			//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)
			return PinsRef.Invoke(Minimap.instance).Any((PinData p) => p.m_save && Utils.DistanceXZ(p.m_pos, pos) < radius);
		}

		private static string PinnedKey(Vector3 pos)
		{
			//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)
			//IL_0014: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return null;
			}
			Vector2s zone = ZoneSystem.GetZone(pos);
			return string.Format("{0}{1}.{2}.{3}", "dwarfhavengames.radarlove.dungeon.", ZNet.instance.GetWorldUID(), zone.x, zone.y);
		}
	}
	internal static class HoverCommand
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__1_0;

			public static Func<RaycastHit, float> <>9__2_0;

			public static Func<string, bool> <>9__4_0;

			public static Func<MonoBehaviour, bool> <>9__4_1;

			public static Func<MonoBehaviour, string> <>9__4_2;

			public static Func<Drop, bool> <>9__6_2;

			internal void <Register>b__1_0(ConsoleEventArgs args)
			{
				Run(args.Context);
			}

			internal float <Run>b__2_0(RaycastHit h)
			{
				return ((RaycastHit)(ref h)).distance;
			}

			internal bool <Report>b__4_0(string d)
			{
				return Catalog.Ore(d) != null;
			}

			internal bool <Report>b__4_1(MonoBehaviour c)
			{
				return Object.op_Implicit((Object)(object)c);
			}

			internal string <Report>b__4_2(MonoBehaviour c)
			{
				return ((object)c).GetType().Name;
			}

			internal bool <DropNames>b__6_2(Drop d)
			{
				return IsTrophy(d.m_prefab);
			}
		}

		private const float Reach = 50f;

		public static void Register()
		{
			//IL_0033: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			object obj = <>c.<>9__1_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					Run(args.Context);
				};
				<>c.<>9__1_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("radar_hover", "Radar Love: shows the prefab name of what you are looking at, for the Custom Pins setting.", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}

		private static void Run(Terminal terminal)
		{
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				Say(terminal, "radar_hover: no player.");
				return;
			}
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			Report(terminal, ((Humanoid)localPlayer).GetHoverObject(), hashSet);
			Character hoverCreature = localPlayer.GetHoverCreature();
			if (Object.op_Implicit((Object)(object)hoverCreature))
			{
				Report(terminal, ((Component)hoverCreature).gameObject, hashSet);
			}
			Transform val = (Object.op_Implicit((Object)(object)GameCamera.instance) ? ((Component)GameCamera.instance).transform : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				foreach (RaycastHit item in from h in Physics.RaycastAll(val.position, val.forward, 50f)
					orderby ((RaycastHit)(ref h)).distance
					select h)
				{
					RaycastHit current = item;
					if (!Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>()) && (Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<ZNetView>()) || Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Location>())))
					{
						Report(terminal, ((Component)((RaycastHit)(ref current)).collider).gameObject, hashSet);
						break;
					}
				}
			}
			Location location = Location.GetLocation(((Component)localPlayer).transform.position, true);
			if (Object.op_Implicit((Object)(object)location))
			{
				string text = Radar.PrefabName(((Component)location).gameObject);
				Say(terminal, "Standing in location: " + text);
				Say(terminal, "  Custom Pins: " + text + "=");
			}
			if (hashSet.Count == 0 && !Object.op_Implicit((Object)(object)location))
			{
				Say(terminal, "radar_hover: nothing under the crosshair.");
			}
		}

		private static void Say(Terminal terminal, string text)
		{
			terminal.AddString(text);
			RadarLovePlugin.Log.LogInfo((object)("[radar_hover] " + text));
		}

		private static void Report(Terminal terminal, GameObject go, HashSet<GameObject> seen)
		{
			//IL_0136: 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)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)go))
			{
				return;
			}
			ZNetView componentInParent = go.GetComponentInParent<ZNetView>();
			GameObject val = (Object.op_Implicit((Object)(object)componentInParent) ? ((Component)componentInParent).gameObject : go);
			if (seen.Add(val))
			{
				string text = Radar.PrefabName(val);
				List<string> list = DropNames(val);
				Say(terminal, (list.Count > 0) ? (text + "  (gives: " + string.Join(", ", list) + ")") : text);
				string text2 = list.FirstOrDefault((string d) => Catalog.Ore(d) != null) ?? list.FirstOrDefault();
				Say(terminal, "  Custom Pins: " + text + "=" + text2);
				Say(terminal, "  Components: " + string.Join(", ", (from c in val.GetComponents<MonoBehaviour>()
					where Object.op_Implicit((Object)(object)c)
					select ((object)c).GetType().Name).Distinct()));
				Destructible component = val.GetComponent<Destructible>();
				if (Object.op_Implicit((Object)(object)component))
				{
					Say(terminal, "  Destructible: " + Damage(component.m_damages, component.m_minToolTier));
				}
				MineRock component2 = val.GetComponent<MineRock>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					Say(terminal, "  MineRock: " + Damage(component2.m_damageModifiers, component2.m_minToolTier));
				}
				MineRock5 component3 = val.GetComponent<MineRock5>();
				if (Object.op_Implicit((Object)(object)component3))
				{
					Say(terminal, "  MineRock5: " + Damage(component3.m_damageModifiers, component3.m_minToolTier));
				}
			}
		}

		private static string Damage(DamageModifiers d, int minToolTier)
		{
			//IL_000d: 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_001b: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0045: 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)
			return $"blunt {d.m_blunt}, slash {d.m_slash}, pierce {d.m_pierce}, chop {d.m_chop}, pickaxe {d.m_pickaxe}, tool tier {minToolTier}";
		}

		private static List<string> DropNames(GameObject root)
		{
			List<string> names = new List<string>();
			Pickable component = root.GetComponent<Pickable>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Add(component.m_itemPrefab);
			}
			CharacterDrop component2 = root.GetComponent<CharacterDrop>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				foreach (Drop item in component2.m_drops.Where((Drop d) => IsTrophy(d.m_prefab)))
				{
					Add(item.m_prefab);
				}
				foreach (Drop drop in component2.m_drops)
				{
					Add(drop.m_prefab);
				}
			}
			MineRock5 component3 = root.GetComponent<MineRock5>();
			if (Object.op_Implicit((Object)(object)component3))
			{
				AddTable(component3.m_dropItems);
			}
			MineRock component4 = root.GetComponent<MineRock>();
			if (Object.op_Implicit((Object)(object)component4))
			{
				AddTable(component4.m_dropItems);
			}
			DropOnDestroyed component5 = root.GetComponent<DropOnDestroyed>();
			if (Object.op_Implicit((Object)(object)component5))
			{
				AddTable(component5.m_dropWhenDestroyed);
			}
			Destructible component6 = root.GetComponent<Destructible>();
			if (Object.op_Implicit((Object)(object)component6) && Object.op_Implicit((Object)(object)component6.m_spawnWhenDestroyed))
			{
				GameObject spawnWhenDestroyed = component6.m_spawnWhenDestroyed;
				if (Object.op_Implicit((Object)(object)spawnWhenDestroyed.GetComponent<MineRock5>()))
				{
					AddTable(spawnWhenDestroyed.GetComponent<MineRock5>().m_dropItems);
				}
				if (Object.op_Implicit((Object)(object)spawnWhenDestroyed.GetComponent<MineRock>()))
				{
					AddTable(spawnWhenDestroyed.GetComponent<MineRock>().m_dropItems);
				}
				if (Object.op_Implicit((Object)(object)spawnWhenDestroyed.GetComponent<DropOnDestroyed>()))
				{
					AddTable(spawnWhenDestroyed.GetComponent<DropOnDestroyed>().m_dropWhenDestroyed);
				}
			}
			return names;
			void Add(GameObject item)
			{
				if (Object.op_Implicit((Object)(object)item) && !names.Contains(((Object)item).name))
				{
					names.Add(((Object)item).name);
				}
			}
			void AddTable(DropTable table)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				if (table != null)
				{
					foreach (DropData drop2 in table.m_drops)
					{
						Add(drop2.m_item);
					}
				}
			}
		}

		private static bool IsTrophy(GameObject item)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			ItemDrop val = (Object.op_Implicit((Object)(object)item) ? item.GetComponent<ItemDrop>() : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				return (int)val.m_itemData.m_shared.m_itemType == 13;
			}
			return false;
		}
	}
	internal static class Icons
	{
		private static readonly HashSet<string> MissingLogged = new HashSet<string>();

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

		private static ObjectDB _indexedFor;

		public static Sprite ItemIcon(GameObject itemPrefab)
		{
			ItemDrop val = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null);
			Sprite[] array = (Object.op_Implicit((Object)(object)val) ? val.m_itemData.m_shared.m_icons : null);
			if (array == null || array.Length == 0)
			{
				return null;
			}
			return array[0];
		}

		public static Sprite ItemIcon(string itemNames)
		{
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || string.IsNullOrEmpty(itemNames))
			{
				return null;
			}
			string[] array = itemNames.Split(new char[1] { '|' });
			foreach (string text in array)
			{
				Sprite val = ItemIcon(ObjectDB.instance.GetItemPrefab(text));
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
				if (MissingLogged.Add(text))
				{
					RadarLovePlugin.Log.LogWarning((object)("No item named '" + text + "' to take an icon from."));
				}
			}
			return null;
		}

		public static Sprite FromDrops(Character character)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Invalid comparison between Unknown and I4
			CharacterDrop component = ((Component)character).GetComponent<CharacterDrop>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return null;
			}
			Sprite val = null;
			foreach (Drop drop in component.m_drops)
			{
				ItemDrop val2 = (Object.op_Implicit((Object)(object)drop.m_prefab) ? drop.m_prefab.GetComponent<ItemDrop>() : null);
				if (Object.op_Implicit((Object)(object)val2))
				{
					if ((int)val2.m_itemData.m_shared.m_itemType == 13)
					{
						return ItemIcon(drop.m_prefab);
					}
					if ((Object)(object)val == (Object)null)
					{
						val = ItemIcon(drop.m_prefab);
					}
				}
			}
			return val;
		}

		public static Sprite VanillaLocationIcon(string prefabName)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Minimap.instance))
			{
				return null;
			}
			foreach (LocationSpriteData locationIcon in Minimap.instance.m_locationIcons)
			{
				if (locationIcon.m_name == prefabName)
				{
					return locationIcon.m_icon;
				}
			}
			return null;
		}

		public static Sprite ByName(string spriteName)
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(spriteName) || !Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return null;
			}
			if ((Object)(object)_indexedFor != (Object)(object)ObjectDB.instance)
			{
				_indexedFor = ObjectDB.instance;
				SpritesByName.Clear();
				foreach (GameObject item in ObjectDB.instance.m_items)
				{
					ItemDrop val = (Object.op_Implicit((Object)(object)item) ? item.GetComponent<ItemDrop>() : null);
					if (!Object.op_Implicit((Object)(object)val) || val.m_itemData.m_shared.m_icons == null)
					{
						continue;
					}
					Sprite[] icons = val.m_itemData.m_shared.m_icons;
					foreach (Sprite val2 in icons)
					{
						if (Object.op_Implicit((Object)(object)val2) && !SpritesByName.ContainsKey(((Object)val2).name))
						{
							SpritesByName[((Object)val2).name] = val2;
						}
					}
				}
			}
			if (SpritesByName.TryGetValue(spriteName, out var value))
			{
				return value;
			}
			if (Object.op_Implicit((Object)(object)Minimap.instance))
			{
				foreach (LocationSpriteData locationIcon in Minimap.instance.m_locationIcons)
				{
					if (Object.op_Implicit((Object)(object)locationIcon.m_icon) && ((Object)locationIcon.m_icon).name == spriteName)
					{
						return locationIcon.m_icon;
					}
				}
			}
			return null;
		}

		public static Sprite Generic()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Minimap.instance))
			{
				return null;
			}
			foreach (SpriteData icon in Minimap.instance.m_icons)
			{
				if ((int)icon.m_name == 3)
				{
					return icon.m_icon;
				}
			}
			return null;
		}
	}
	internal static class KeptPins
	{
		private class Kept
		{
			public string Sprite;

			public Vector3 Pos;

			public string Label;

			public HashSet<string> Spots = new HashSet<string>();
		}

		private const PinType SavedType = (PinType)3;

		private const string KeyPrefix = "dwarfhavengames.radarlove.kept.";

		private const float KeyReach = 20f;

		private static readonly FieldRef<Minimap, List<PinData>> PinsRef = AccessTools.FieldRefAccess<Minimap, List<PinData>>("m_pins");

		private static readonly FieldRef<Minimap, bool> MapLoaded = AccessTools.FieldRefAccess<Minimap, bool>("m_hasGenerated");

		private static readonly MethodInfo TakeInput = AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null);

		private static readonly List<Kept> Records = new List<Kept>();

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

		private static Player _loadedFor;

		private static string _loadedKey;

		public static bool IsKept(Blip blip)
		{
			if (!blip.Moves && Loaded())
			{
				return KeptSpots.Contains(Dismissals.SpotOf(blip));
			}
			return false;
		}

		public static void CheckKey()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)Minimap.instance))
			{
				return;
			}
			KeyboardShortcut value = RadarLovePlugin.Settings.KeepKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown() && (bool)TakeInput.Invoke(localPlayer, null))
			{
				Blip blip = Radar.LeaderOf(((Humanoid)localPlayer).GetHoverObject()) ?? Radar.ClosestPinned(((Component)localPlayer).transform.position, 20f);
				if (blip != null)
				{
					Keep(blip);
					return;
				}
				Minimap.instance.AddPin(((Component)localPlayer).transform.position, (PinType)3, "", true, false, 0L, default(PlatformUserID));
				((Character)localPlayer).Message((MessageType)1, "Your position pinned to map", 0, (Sprite)null, false);
			}
		}

		public static bool TryKeep(Minimap minimap, Vector3 pointer, float radius)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Blip blip = Dismissals.RadarPinUnder(minimap, pointer, radius);
			if (blip == null)
			{
				return false;
			}
			Keep(blip);
			return true;
		}

		private static void Keep(Blip leader)
		{
			//IL_0056: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			if (!Loaded() || leader.Pin == null)
			{
				return;
			}
			Sprite icon = leader.Pin.m_icon;
			bool flag = (Object)(object)icon == (Object)null || (Object)(object)icon == (Object)(object)Icons.Generic();
			Kept kept = new Kept
			{
				Sprite = (flag ? "" : ((Object)icon).name),
				Pos = leader.Pin.m_pos,
				Label = Radar.LabelFor(leader)
			};
			foreach (Blip member in leader.Members)
			{
				if (!member.Moves && Object.op_Implicit((Object)(object)member.Source))
				{
					kept.Spots.Add(Dismissals.SpotOf(member));
				}
			}
			AddPin(Minimap.instance, kept.Pos, kept.Label, flag ? null : icon);
			Records.Add(kept);
			KeptSpots.UnionWith(kept.Spots);
			Save();
			Radar.Unpin(leader);
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)1, leader.Name() + " pinned to map", 0, flag ? null : icon, false);
			}
		}

		private static PinData AddPin(Minimap minimap, Vector3 pos, string label, Sprite icon)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			PinData val = minimap.AddPin(pos, (PinType)3, label, true, false, 0L, default(PlatformUserID));
			if (Object.op_Implicit((Object)(object)icon))
			{
				val.m_icon = icon;
			}
			return val;
		}

		public static void Sync(Minimap minimap)
		{
			if (!Loaded() || Records.Count == 0 || !MapLoaded.Invoke(minimap))
			{
				return;
			}
			List<PinData> source = PinsRef.Invoke(minimap);
			bool flag = false;
			for (int num = Records.Count - 1; num >= 0; num--)
			{
				Kept kept = Records[num];
				PinData val = ((IEnumerable<PinData>)source).FirstOrDefault((Func<PinData, bool>)((PinData p) => p.m_save && (int)p.m_type == 3 && Utils.DistanceXZ(p.m_pos, kept.Pos) < 1f));
				if (val == null)
				{
					Records.RemoveAt(num);
					flag = true;
				}
				else
				{
					Sprite val2 = Icons.ByName(kept.Sprite);
					if (Object.op_Implicit((Object)(object)val2) && (Object)(object)val.m_icon != (Object)(object)val2)
					{
						val.m_icon = val2;
						if (Object.op_Implicit((Object)(object)val.m_iconElement))
						{
							val.m_iconElement.sprite = val2;
						}
					}
				}
			}
			if (!flag)
			{
				return;
			}
			KeptSpots.Clear();
			foreach (Kept record in Records)
			{
				KeptSpots.UnionWith(record.Spots);
			}
			Save();
		}

		private static void Save()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || _loadedKey == null)
			{
				return;
			}
			if (Records.Count == 0)
			{
				localPlayer.m_customData.Remove(_loadedKey);
				return;
			}
			localPlayer.m_customData[_loadedKey] = string.Join("\n", Records.Select((Kept k) => string.Join("|", k.Sprite, k.Pos.x.ToString("R", CultureInfo.InvariantCulture), k.Pos.z.ToString("R", CultureInfo.InvariantCulture), string.Join(";", k.Spots), k.Label)));
		}

		private static bool Loaded()
		{
			//IL_0118: 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)
			Player localPlayer = Player.m_localPlayer;
			string text = ((Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)ZNet.instance)) ? ("dwarfhavengames.radarlove.kept." + ZNet.instance.GetWorldUID()) : null);
			if (text == null)
			{
				return false;
			}
			if ((Object)(object)localPlayer == (Object)(object)_loadedFor && text == _loadedKey)
			{
				return true;
			}
			_loadedFor = localPlayer;
			_loadedKey = text;
			Records.Clear();
			KeptSpots.Clear();
			if (!localPlayer.m_customData.TryGetValue(text, out var value))
			{
				return true;
			}
			string[] array = value.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { '|' }, 5);
				if (array2.Length >= 5 && float.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
				{
					Kept kept = new Kept
					{
						Sprite = array2[0],
						Pos = new Vector3(result, 0f, result2),
						Label = array2[4]
					};
					string[] array3 = array2[3].Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
					foreach (string item in array3)
					{
						kept.Spots.Add(item);
					}
					Records.Add(kept);
					KeptSpots.UnionWith(kept.Spots);
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Location), "Awake")]
	internal static class LocationAwakePatch
	{
		private static void Postfix(Location __instance)
		{
			Radar.AddLocation(__instance);
		}
	}
	[HarmonyPatch(typeof(Pickable), "Awake")]
	internal static class PickableAwakePatch
	{
		private static void Postfix(Pickable __instance)
		{
			Radar.AddPickable(__instance);
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class CharacterAwakePatch
	{
		private static void Postfix(Character __instance)
		{
			Radar.AddCreature(__instance);
		}
	}
	[HarmonyPatch(typeof(Fish), "Awake")]
	internal static class FishAwakePatch
	{
		private static void Postfix(Fish __instance)
		{
			Radar.AddFish(__instance);
		}
	}
	[HarmonyPatch(typeof(DropOnDestroyed), "Awake")]
	internal static class DropOnDestroyedAwakePatch
	{
		private static void Postfix(DropOnDestroyed __instance)
		{
			Radar.AddOre((Component)(object)__instance, __instance.m_dropWhenDestroyed);
		}
	}
	[HarmonyPatch(typeof(Destructible), "Awake")]
	internal static class DestructibleAwakePatch
	{
		private static void Postfix(Destructible __instance)
		{
			Radar.AddDestructible(__instance);
		}
	}
	[HarmonyPatch(typeof(ZNetView), "Awake")]
	internal static class ZNetViewAwakePatch
	{
		private static void Postfix(ZNetView __instance)
		{
			Radar.AddNetworked((Component)(object)__instance);
		}
	}
	[HarmonyPatch(typeof(MineRock), "Start")]
	internal static class MineRockStartPatch
	{
		private static void Postfix(MineRock __instance)
		{
			Radar.AddOre((Component)(object)__instance, __instance.m_dropItems);
		}
	}
	[HarmonyPatch(typeof(MineRock5), "Awake")]
	internal static class MineRock5AwakePatch
	{
		private static void Postfix(MineRock5 __instance)
		{
			Radar.AddOre((Component)(object)__instance, __instance.m_dropItems);
		}
	}
	[HarmonyPatch(typeof(Minimap), "RemovePinUnderPointer")]
	internal static class MinimapRemovePinUnderPointerPatch
	{
		internal static readonly MethodInfo ScreenToWorldPoint = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", (Type[])null, (Type[])null);

		internal static readonly MethodInfo PinInteractRadius = AccessTools.PropertyGetter(typeof(Minimap), "PinInteractRadius");

		private static bool Prefix(Minimap __instance)
		{
			//IL_000e: 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_0023: 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)
			Vector3 pointer = (Vector3)ScreenToWorldPoint.Invoke(__instance, new object[1] { ZInput.pointerPosition });
			float radius = (float)PinInteractRadius.Invoke(__instance, null);
			return !Dismissals.TryDismiss(__instance, pointer, radius);
		}
	}
	[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
	internal static class MinimapOnMapLeftClickPatch
	{
		private static bool Prefix(Minimap __instance)
		{
			//IL_000e: 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_0023: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			Vector3 pointer = (Vector3)MinimapRemovePinUnderPointerPatch.ScreenToWorldPoint.Invoke(__instance, new object[1] { ZInput.pointerPosition });
			float radius = (float)MinimapRemovePinUnderPointerPatch.PinInteractRadius.Invoke(__instance, null);
			if ((ZInput.GetKey((KeyCode)304, true) || ZInput.GetKey((KeyCode)303, true)) && KeptPins.TryKeep(__instance, pointer, radius))
			{
				return false;
			}
			Dismissals.TryToggleCross(__instance, pointer, radius);
			return true;
		}
	}
	[BepInPlugin("dwarfhavengames.radarlove", "Radar Love", "1.4.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class RadarLovePlugin : BaseUnityPlugin
	{
		public const string Guid = "dwarfhavengames.radarlove";

		internal static ManualLogSource Log;

		internal static Config Settings;

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = new Config(((BaseUnityPlugin)this).Config);
			new Harmony("dwarfhavengames.radarlove").PatchAll();
			HoverCommand.Register();
		}

		private void Update()
		{
			Radar.Tick();
			KeptPins.CheckKey();
		}
	}
	internal class Blip
	{
		public Component Source;

		public Entry Entry;

		public Func<Sprite> FindIcon;

		public Func<string> Name;

		public bool Moves;

		public Pickable Pickable;

		public bool Suppressed;

		public bool Hidden;

		public bool Crossed;

		public string Spot;

		public bool InRange;

		public readonly List<Blip> Members = new List<Blip>();

		public PinData Pin;

		public int PinCount;

		private Sprite _icon;

		private bool _iconResolved;

		public Sprite Icon
		{
			get
			{
				if (!_iconResolved)
				{
					_icon = FindIcon();
					_iconResolved = true;
				}
				return _icon;
			}
		}
	}
	internal static class Radar
	{
		private const float Hysteresis = 10f;

		private const float RangeInterval = 0.25f;

		private const float InteriorHeight = 3000f;

		private static readonly List<Blip> Blips = new List<Blip>();

		private static readonly HashSet<GameObject> Tracked = new HashSet<GameObject>();

		private static readonly Dictionary<Entry, List<Blip>> ByKind = new Dictionary<Entry, List<Blip>>();

		private static Minimap _minimap;

		private static float _nextRangeCheck;

		private static Config Cfg => RadarLovePlugin.Settings;

		public static void AddLocation(Location location)
		{
			string prefab = PrefabName(((Component)location).gameObject);
			if (location.m_hasInterior)
			{
				DungeonPins.Track(location);
				Entry dungeon = Catalog.Dungeon(DungeonPins.EnterText(location));
				Add((Component)(object)location, dungeon, () => Icons.ItemIcon(dungeon.IconItem), () => DungeonPins.NameFor(location));
				return;
			}
			Entry entry = Catalog.Location(prefab);
			if (entry != null)
			{
				Add((Component)(object)location, entry, () => Icons.ItemIcon(entry.IconItem) ?? Icons.VanillaLocationIcon(prefab), () => entry.Display);
			}
		}

		public static void AddPickable(Pickable pickable)
		{
			GameObject item = pickable.m_itemPrefab;
			if (Object.op_Implicit((Object)(object)item))
			{
				Entry entry = Catalog.Ore(((Object)item).name) ?? Catalog.Pickable(((Object)item).name);
				Blip blip = Add((Component)(object)pickable, entry, () => Icons.ItemIcon(item), () => ItemName(item));
				if (blip != null)
				{
					blip.Pickable = pickable;
				}
			}
		}

		public static void AddOre(Component source, DropTable drops)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (drops == null)
			{
				return;
			}
			foreach (DropData drop in drops.m_drops)
			{
				GameObject item = drop.m_item;
				Entry entry = (Object.op_Implicit((Object)(object)item) ? Catalog.Ore(((Object)item).name) : null);
				if (entry == null)
				{
					continue;
				}
				if (IsDeposit(source.gameObject, drops, entry))
				{
					Add(source, entry, () => Icons.ItemIcon(item), () => entry.Display);
				}
				break;
			}
		}

		private static bool IsDeposit(GameObject go, DropTable drops, Entry ore)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)go.GetComponent<MineRock>()) || Object.op_Implicit((Object)(object)go.GetComponent<MineRock5>()))
			{
				return true;
			}
			Destructible component = go.GetComponent<Destructible>();
			if (Object.op_Implicit((Object)(object)component) && IsMined(component.m_damages))
			{
				return true;
			}
			return drops.m_drops.All((DropData d) => Object.op_Implicit((Object)(object)d.m_item) && Catalog.Ore(((Object)d.m_item).name) == ore);
		}

		private static bool IsMined(DamageModifiers d)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_001a: 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_0027: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (Shrugs(d.m_blunt) && Shrugs(d.m_slash) && Shrugs(d.m_pierce) && Shrugs(d.m_chop))
			{
				return !Shrugs(d.m_pickaxe);
			}
			return false;
		}

		private static bool Shrugs(DamageModifier m)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)m != 3)
			{
				return (int)m == 4;
			}
			return true;
		}

		public static void AddDestructible(Destructible destructible)
		{
			GameObject spawnWhenDestroyed = destructible.m_spawnWhenDestroyed;
			if (Object.op_Implicit((Object)(object)spawnWhenDestroyed))
			{
				MineRock5 component = spawnWhenDestroyed.GetComponent<MineRock5>();
				MineRock component2 = spawnWhenDestroyed.GetComponent<MineRock>();
				DropOnDestroyed component3 = spawnWhenDestroyed.GetComponent<DropOnDestroyed>();
				AddOre((Component)(object)destructible, Object.op_Implicit((Object)(object)component) ? component.m_dropItems : (Object.op_Implicit((Object)(object)component2) ? component2.m_dropItems : (Object.op_Implicit((Object)(object)component3) ? component3.m_dropWhenDestroyed : null)));
			}
		}

		public static bool AddPoi(Component source)
		{
			Entry entry = Catalog.Poi(PrefabName(source.gameObject));
			if (entry == null)
			{
				return false;
			}
			Add(source, entry, () => Icons.ItemIcon(entry.IconItem), () => entry.Display);
			return true;
		}

		public static void AddCreature(Character character)
		{
			if (!character.IsPlayer())
			{
				Entry entry = Catalog.Creature(PrefabName(((Component)character).gameObject));
				Blip blip = Add((Component)(object)character, entry, () => Icons.ItemIcon(entry.IconItem) ?? Icons.FromDrops(character), () => Localize(character.m_name));
				if (blip != null)
				{
					blip.Moves = true;
				}
			}
		}

		public static void AddFish(Fish fish)
		{
			Entry entry = Catalog.FishKind(PrefabName(((Component)fish).gameObject));
			ItemDrop item = ((Component)fish).GetComponent<ItemDrop>();
			if (entry != null && Object.op_Implicit((Object)(object)item))
			{
				Blip blip = Add((Component)(object)fish, entry, () => Icons.ItemIcon(((Component)fish).gameObject), () => Localize(item.m_itemData.m_shared.m_name));
				if (blip != null)
				{
					blip.Moves = true;
				}
			}
		}

		public static void Suppress(Component source)
		{
			foreach (Blip blip in Blips)
			{
				if ((Object)(object)blip.Source == (Object)(object)source)
				{
					blip.Suppressed = true;
				}
			}
		}

		public static void AddNetworked(Component source)
		{
			Entry custom = Catalog.CustomFor(PrefabName(source.gameObject));
			if (custom != null)
			{
				Add(source, custom, () => (Sprite)null, () => custom.Display);
			}
			else
			{
				AddPoi(source);
			}
		}

		private static Blip Add(Component source, Entry entry, Func<Sprite> icon, Func<string> name)
		{
			Entry custom = Catalog.CustomFor(PrefabName(source.gameObject));
			if (custom != null)
			{
				Func<Sprite> own = icon;
				entry = custom;
				icon = () => Icons.ItemIcon(custom.IconItem) ?? own();
				name = () => custom.Display;
			}
			if (entry == null || !Tracked.Add(source.gameObject))
			{
				return null;
			}
			Blip blip = new Blip
			{
				Source = source,
				Entry = entry,
				FindIcon = icon,
				Name = name,
				Moves = (Object.op_Implicit((Object)(object)source.GetComponent<Character>()) || Object.op_Implicit((Object)(object)source.GetComponent<Fish>()))
			};
			Blips.Add(blip);
			return blip;
		}

		public static void Rescan()
		{
			foreach (Blip blip in Blips)
			{
				Unpin(blip);
			}
			Blips.Clear();
			Tracked.Clear();
			DungeonPins.Clear();
			Location[] array = Object.FindObjectsOfType<Location>();
			for (int i = 0; i < array.Length; i++)
			{
				AddLocation(array[i]);
			}
			Pickable[] array2 = Object.FindObjectsOfType<Pickable>();
			for (int i = 0; i < array2.Length; i++)
			{
				AddPickable(array2[i]);
			}
			Character[] array3 = Object.FindObjectsOfType<Character>();
			for (int i = 0; i < array3.Length; i++)
			{
				AddCreature(array3[i]);
			}
			Fish[] array4 = Object.FindObjectsOfType<Fish>();
			for (int i = 0; i < array4.Length; i++)
			{
				AddFish(array4[i]);
			}
			Destructible[] array5 = Object.FindObjectsOfType<Destructible>();
			for (int i = 0; i < array5.Length; i++)
			{
				AddDestructible(array5[i]);
			}
			DropOnDestroyed[] array6 = Object.FindObjectsOfType<DropOnDestroyed>();
			foreach (DropOnDestroyed val in array6)
			{
				AddOre((Component)(object)val, val.m_dropWhenDestroyed);
			}
			MineRock[] array7 = Object.FindObjectsOfType<MineRock>();
			foreach (MineRock val2 in array7)
			{
				AddOre((Component)(object)val2, val2.m_dropItems);
			}
			MineRock5[] array8 = Object.FindObjectsOfType<MineRock5>();
			foreach (MineRock5 val3 in array8)
			{
				AddOre((Component)(object)val3, val3.m_dropItems);
			}
			ZNetView[] array9 = Object.FindObjectsOfType<ZNetView>();
			for (int i = 0; i < array9.Length; i++)
			{
				AddNetworked((Component)(object)array9[i]);
			}
		}

		public static void Tick()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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)
			Player localPlayer = Player.m_localPlayer;
			Minimap instance = Minimap.instance;
			if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)instance))
			{
				return;
			}
			if ((Object)(object)instance != (Object)(object)_minimap)
			{
				_minimap = instance;
				foreach (Blip blip in Blips)
				{
					blip.Pin = null;
				}
			}
			foreach (Blip blip2 in Blips)
			{
				if (blip2.Pin != null)
				{
					blip2.Pin.m_pos = Centre(blip2.Members);
				}
			}
			if (!(Time.time < _nextRangeCheck))
			{
				_nextRangeCheck = Time.time + 0.25f;
				Vector3 position = ((Component)localPlayer).transform.position;
				UpdateRange(position);
				UpdateGroups();
				RaiseCrossed();
				Tracked.RemoveWhere((GameObject go) => !Object.op_Implicit((Object)(object)go));
				DungeonPins.Tick(position);
				DungeonPins.Sync(instance);
				KeptPins.Sync(instance);
			}
		}

		private static void UpdateRange(Vector3 here)
		{
			//IL_006c: 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)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			bool value = Cfg.Enabled.Value;
			float value2 = Cfg.Radius.Value;
			for (int num = Blips.Count - 1; num >= 0; num--)
			{
				Blip blip = Blips[num];
				if (!Object.op_Implicit((Object)(object)blip.Source))
				{
					Unpin(blip);
					Blips.RemoveAt(num);
				}
				else
				{
					Vector3 position = blip.Source.transform.position;
					float num2 = (blip.InRange ? (value2 + 10f) : value2);
					blip.InRange = value && blip.Entry.Enabled && !blip.Suppressed && !blip.Hidden && position.y < 3000f && Utils.DistanceXZ(here, position) < num2 && ((Object)(object)blip.Pickable == (Object)null || blip.Pickable.CanBePicked()) && !Dismissals.IsDismissed(blip) && !KeptPins.IsKept(blip);
				}
			}
		}

		private static void UpdateGroups()
		{
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			foreach (List<Blip> value2 in ByKind.Values)
			{
				value2.Clear();
			}
			foreach (Blip blip in Blips)
			{
				if (!blip.InRange)
				{
					Unpin(blip);
					continue;
				}
				if (!ByKind.TryGetValue(blip.Entry, out var value))
				{
					value = (ByKind[blip.Entry] = new List<Blip>());
				}
				value.Add(blip);
			}
			HashSet<Blip> hashSet = new HashSet<Blip>();
			foreach (List<Blip> value3 in ByKind.Values)
			{
				if (value3.Count == 0)
				{
					continue;
				}
				float num = (value3[0].Moves ? Cfg.CreatureGroupDistance.Value : Cfg.GroupDistance.Value);
				value3.Sort((Blip a, Blip b) => (b.Pin != null).CompareTo(a.Pin != null));
				foreach (Blip item in value3)
				{
					if (hashSet.Contains(item))
					{
						continue;
					}
					item.Members.Clear();
					Vector3 position = item.Source.transform.position;
					foreach (Blip item2 in value3)
					{
						if (!hashSet.Contains(item2) && !(Utils.DistanceXZ(position, item2.Source.transform.position) > num))
						{
							hashSet.Add(item2);
							item.Members.Add(item2);
						}
					}
					foreach (Blip member in item.Members)
					{
						if (member != item)
						{
							Unpin(member);
						}
					}
					if (item.Pin == null || item.PinCount != item.Members.Count)
					{
						Unpin(item);
						Pin(item);
					}
				}
			}
		}

		private static void Pin(Blip blip)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			Sprite icon = blip.Icon ?? Icons.Generic();
			int count = blip.Members.Count;
			string text = LabelFor(blip);
			string text2 = ((count > 1) ? $"{count}x {text}".TrimEnd(Array.Empty<char>()) : text);
			blip.Pin = Minimap.instance.AddPin(Centre(blip.Members), (PinType)8, text2, false, Dismissals.IsCrossed(blip.Members), 0L, default(PlatformUserID));
			blip.Pin.m_icon = icon;
			blip.PinCount = count;
		}

		internal static string LabelFor(Blip blip)
		{
			if (!Cfg.ShowLabels.Value && !((Object)(object)blip.Icon == (Object)null))
			{
				ConfigEntry<bool> nameSetting = blip.Entry.NameSetting;
				if (nameSetting == null || !nameSetting.Value)
				{
					return "";
				}
			}
			return blip.Name();
		}

		internal static Blip LeaderOf(GameObject go)
		{
			if (!Object.op_Implicit((Object)(object)go))
			{
				return null;
			}
			foreach (Blip blip in Blips)
			{
				if (blip.Pin != null && blip.Members.Any((Blip m) => Object.op_Implicit((Object)(object)m.Source) && go.transform.IsChildOf(m.Source.transform)))
				{
					return blip;
				}
			}
			return null;
		}

		internal static void Unpin(Blip blip)
		{
			if (blip.Pin != null && Object.op_Implicit((Object)(object)Minimap.instance))
			{
				Minimap.instance.RemovePin(blip.Pin);
			}
			blip.Pin = null;
			blip.PinCount = 0;
		}

		internal static Blip ClosestPinned(Vector3 point, float radius)
		{
			//IL_0021: 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)
			Blip result = null;
			float num = radius;
			foreach (Blip blip in Blips)
			{
				if (blip.Pin != null)
				{
					float num2 = Utils.DistanceXZ(point, blip.Pin.m_pos);
					if (num2 < num)
					{
						result = blip;
						num = num2;
					}
				}
			}
			return result;
		}

		private static void RaiseCrossed()
		{
			foreach (Blip blip in Blips)
			{
				PinData pin = blip.Pin;
				if (pin != null && pin.m_checked && Object.op_Implicit((Object)(object)pin.m_uiElement) && Object.op_Implicit((Object)(object)pin.m_checkedElement))
				{
					((Transform)pin.m_uiElement).SetAsLastSibling();
					pin.m_checkedElement.transform.SetAsLastSibling();
				}
			}
		}

		internal static void Refresh()
		{
			foreach (Blip blip in Blips)
			{
				Unpin(blip);
			}
		}

		internal static void ClearHidden()
		{
			foreach (Blip blip in Blips)
			{
				blip.Hidden = false;
			}
		}

		private static Vector3 Centre(List<Blip> members)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			int num = 0;
			foreach (Blip member in members)
			{
				if (Object.op_Implicit((Object)(object)member.Source))
				{
					val += member.Source.transform.position;
					num++;
				}
			}
			if (num <= 0)
			{
				return Vector3.zero;
			}
			return val / (float)num;
		}

		internal static string PrefabName(GameObject go)
		{
			ZNetView component = go.GetComponent<ZNetView>();
			ZDO val = (Object.op_Implicit((Object)(object)component) ? component.GetZDO() : null);
			GameObject val2 = ((val != null && Object.op_Implicit((Object)(object)ZNetScene.instance)) ? ZNetScene.instance.GetPrefab(val.GetPrefab()) : null);
			if (Object.op_Implicit((Object)(object)val2))
			{
				return ((Object)val2).name;
			}
			string name = ((Object)go).name;
			int num = name.IndexOf("(Clone)", StringComparison.Ordinal);
			if (num < 0)
			{
				return name;
			}
			return name.Substring(0, num).TrimEnd(Array.Empty<char>());
		}

		private static string ItemName(GameObject item)
		{
			ItemDrop component = item.GetComponent<ItemDrop>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return ((Object)item).name;
			}
			return Localize(component.m_itemData.m_shared.m_name);
		}

		internal static string Localize(string text)
		{
			if (Localization.instance == null)
			{
				return text;
			}
			return Localization.instance.Localize(text);
		}
	}
}