Decompiled source of CreatureMarker v1.7.0

BepInEx/plugins/CreatureMarker/CreatureMarker.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Kriona.Shared;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.TextCore;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Kriona")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 Kriona Hagen - MIT License")]
[assembly: AssemblyFileVersion("1.7.0.0")]
[assembly: AssemblyInformationalVersion("1.7.0")]
[assembly: AssemblyProduct("Creature Marker")]
[assembly: AssemblyTitle("Creature Marker")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.0.0")]
[module: UnverifiableCode]
[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 CreatureMarker
{
	internal static class CreatureConfig
	{
		private const string FileName = "kriona.CreatureMarker.cfg";

		private const string Comment = "##";

		private const string MarkersSection = "1 - Markers";

		private const string ColorsSection = "2 - Colors";

		private const string CreaturesSection = "3 - Creatures and Fish";

		private const string ShowOnScreenKey = "Show On Screen";

		private const string ShowOnMapKey = "Show On Map";

		private const string MaxDistanceKey = "Max Distance";

		private const string FarDistanceKey = "Far Distance";

		private const string FarScaleKey = "Far Scale";

		private const string BobHeightKey = "Bob Height";

		private const string ShowNameKey = "Show Name";

		private const string ShowDistanceKey = "Show Distance";

		private const string ShowLevelKey = "Show Level";

		private const string PassiveColorKey = "Passive Color";

		private const string HostileColorKey = "Hostile Color";

		private const string AngryColorKey = "Angry Color";

		private const string BossColorKey = "Boss Color";

		private const string FishColorKey = "Fish Color";

		private const string PetColorKey = "Pet Color";

		private const string TraderColorKey = "Trader Color";

		private const string AllPassiveKey = "All Passive Creatures";

		private const string OldAllCreaturesKey = "All Creatures";

		private const string AllHostileKey = "All Hostile Creatures";

		private const string AllFishKey = "All Fish";

		private const string AllBirdsKey = "All Birds";

		private const string MinCreatureLevelKey = "Min Creature Level";

		private const string MinFishLevelKey = "Min Fish Level";

		private const float DefaultMaxDistance = 50f;

		private const float MinMaxDistance = 5f;

		private const float MaxMaxDistance = 500f;

		private const float DefaultFarDistance = 50f;

		private const float DefaultFarScale = 0.66f;

		private const float MinFarScale = 0.2f;

		private const float DefaultBobHeight = 0f;

		private const float MaxBobHeight = 30f;

		private const string DefaultPassiveColor = "#40D940";

		private const string DefaultHostileColor = "#FFD91A";

		private const string DefaultAngryColor = "#FF801A";

		private const string DefaultBossColor = "#FF3333";

		private const string DefaultFishColor = "#33CCFF";

		private const string DefaultPetColor = "#FFF";

		private const int DefaultMinCreatureLevel = 0;

		private const int MaxMinCreatureLevel = 9;

		private const int DefaultMinFishLevel = 1;

		private const int MaxMinFishLevel = 5;

		private static readonly string[] header = new string[4] { "## Creature Marker", "## Changes take effect as soon as this file is saved; you don't need to restart Valheim or rejoin the world", "## Colors are #RRGGBB or a color name like red, yellow, green, cyan or magenta", "" };

		private static readonly string[] creatureHeader = new string[6] { "", "## All Passive Creatures marks every creature that won't attack you, including traders and their pets", "## All Hostile Creatures marks every creature that will attack you", "## All Fish marks every fish", "## All Birds marks every bird", "" };

		private static readonly string[] creatureLinesHeader = new string[4] { "", "## Each creature, trader, pet, fish and bird line is: Prefab = inherit/true/false ## Name in game", "## inherit follows the All switches, while true or false always shows or hides that one's marker", "" };

		private static readonly string showOnScreenNote = "Show an arrow above each marked creature, pinned to the screen edge when it is off-screen, default true";

		private static readonly string showOnMapNote = "Show a dot on the minimap and the large map for each marked creature, default true";

		private static readonly string showNameNote = "Show the creature's name with its marker, default false";

		private static readonly string showLevelNote = "Show stars after a creature's name and the level after a fish's name, like Perch[3], for those above the lowest level, default false";

		private static readonly string showDistanceNote = "Show the creature's distance in meters with its marker, after the name when Show Name is on, default false";

		private static readonly string maxDistanceNote = "Meters, from " + 5f + " to " + 500f + ", default " + 50f;

		private static readonly string farDistanceNote = "Meters beyond which a marker is drawn at Far Scale, from " + 5f + " to " + 500f + ", default " + 50f;

		private static readonly string farScaleNote = "Size of a marker beyond Far Distance, from " + 0.2f.ToString(CultureInfo.InvariantCulture) + " to 1 (no shrinking), default " + 0.66f.ToString(CultureInfo.InvariantCulture);

		private static readonly string bobHeightNote = "Pixels an on-screen arrow bobs up and down, from 0 (disables bobbing) to " + 30f + ", default " + 0f;

		private static readonly string passiveColorNote = "Creatures that won't attack you, including birds, default #40D940";

		private static readonly string hostileColorNote = "Creatures that will attack you, default #FFD91A";

		private static readonly string angryColorNote = "Hostile creatures that are after you right now, default #FF801A";

		private static readonly string bossColorNote = "Bosses, default #FF3333";

		private static readonly string fishColorNote = "Fish, default #33CCFF";

		private static readonly string petColorNote = "Creatures you have tamed, default #FFF";

		private static readonly string traderColorNote = "Traders like Haldor, Hildir and the Bog Witch, blank to use Passive Color, default blank";

		private static readonly string minCreatureLevelNote = "Lowest level a creature needs to get a marker, which is its number of stars, from 0 (every creature) to " + 9 + ", default " + 0 + ", traders, their pets and birds aren't affected";

		private static readonly string minFishLevelNote = "Lowest level a fish needs to get a marker, even when its own line is true, from 1 (every fish) to " + 5 + ", default " + 1;

		private static ConfigMirror mirror;

		private static StateEntries creatureEntries;

		private static ConfigEntry<bool> showOnScreenEntry;

		private static ConfigEntry<bool> showOnMapEntry;

		private static ConfigEntry<bool> showNameEntry;

		private static ConfigEntry<bool> showLevelEntry;

		private static ConfigEntry<bool> showDistanceEntry;

		private static ConfigEntry<float> maxDistanceEntry;

		private static ConfigEntry<float> farDistanceEntry;

		private static ConfigEntry<float> farScaleEntry;

		private static ConfigEntry<float> bobHeightEntry;

		private static ConfigEntry<Color> passiveColorEntry;

		private static ConfigEntry<Color> hostileColorEntry;

		private static ConfigEntry<Color> angryColorEntry;

		private static ConfigEntry<Color> bossColorEntry;

		private static ConfigEntry<Color> fishColorEntry;

		private static ConfigEntry<Color> petColorEntry;

		private static ConfigEntry<string> traderColorEntry;

		private static ConfigEntry<bool> allPassiveEntry;

		private static ConfigEntry<bool> allHostileEntry;

		private static ConfigEntry<bool> allFishEntry;

		private static ConfigEntry<bool> allBirdsEntry;

		private static ConfigEntry<int> minCreatureLevelEntry;

		private static ConfigEntry<int> minFishLevelEntry;

		private static readonly Dictionary<string, string> birdNameTokens = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "Seagal", "$caption_seagull" } };

		private static readonly Dictionary<int, string> birdNamesByHash = new Dictionary<int, string>();

		private static SortedDictionary<string, string> names = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);

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

		private static string passiveColorText = "#40D940";

		private static string hostileColorText = "#FFD91A";

		private static string angryColorText = "#FF801A";

		private static string bossColorText = "#FF3333";

		private static string fishColorText = "#33CCFF";

		private static string petColorText = "#FFF";

		private static Color passiveColor = ParseColor("#40D940", Color.green);

		private static Color hostileColor = ParseColor("#FFD91A", Color.yellow);

		private static Color angryColor = ParseColor("#FF801A", Color.red);

		private static Color bossColor = ParseColor("#FF3333", Color.red);

		private static Color fishColor = ParseColor("#33CCFF", Color.cyan);

		private static Color petColor = ParseColor("#FFF", Color.white);

		private static string traderColorText = "";

		private static Color? traderColor;

		private static bool allPassive;

		private static bool allHostile = true;

		private static bool allFish;

		private static bool allBirds;

		private static int minCreatureLevel = 0;

		private static int minFishLevel = 1;

		private static readonly Dictionary<int, bool> overrides = new Dictionary<int, bool>();

		public static bool ShowOnScreen { get; private set; } = true;

		public static bool ShowOnMap { get; private set; } = true;

		public static float MaxDistance { get; private set; } = 50f;

		public static float FarDistance { get; private set; } = 50f;

		public static float FarScale { get; private set; } = 0.66f;

		public static float BobHeight { get; private set; } = 0f;

		public static bool ShowName { get; private set; }

		public static bool ShowDistance { get; private set; }

		public static bool ShowLevel { get; private set; }

		public static string FilePath => Path.Combine(Paths.ConfigPath, "kriona.CreatureMarker.cfg");

		public static void Init(ConfigFile file)
		{
			mirror = new ConfigMirror(file, OnEntryChanged);
			creatureEntries = new StateEntries(mirror, "inherit follows the All switches, while true or false always shows or hides its marker");
			BindSettings();
			LoadWithoutScene();
		}

		public static void Reload()
		{
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				Load(ZNetScene.instance);
			}
			else
			{
				LoadWithoutScene();
			}
		}

		private static void LoadWithoutScene()
		{
			if (!TryRead(out var values, out var notes))
			{
				return;
			}
			LoadSettings(values);
			SortedDictionary<string, string> sortedDictionary = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			foreach (string key in values.Keys)
			{
				sortedDictionary[key] = (notes.TryGetValue(key, out var value) ? value : "");
			}
			names = sortedDictionary;
			SyncEntries(BuildStates((string key) => (!values.TryGetValue(key, out var value2)) ? ((bool?)null) : ParseState(value2)));
		}

		private static bool TryRead(out Dictionary<string, string> values, out Dictionary<string, string> notes)
		{
			try
			{
				values = Read(FilePath, out notes);
				return true;
			}
			catch (IOException ex)
			{
				Debug.LogWarning((object)("[Creature Marker] Couldn't read " + FilePath + ": " + ex.Message));
				values = null;
				notes = null;
				return false;
			}
		}

		public static void Load(ZNetScene scene)
		{
			if (!TryRead(out var values, out var _))
			{
				return;
			}
			LoadSettings(values);
			SortedDictionary<string, string> sortedDictionary = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			foreach (GameObject prefab in scene.m_prefabs)
			{
				if ((Object)(object)prefab == (Object)null)
				{
					continue;
				}
				Character component = prefab.GetComponent<Character>();
				if ((Object)(object)component != (Object)null && !(component is Player))
				{
					sortedDictionary[((Object)prefab).name] = GetDisplayName(component.m_name);
					continue;
				}
				Trader component2 = prefab.GetComponent<Trader>();
				if ((Object)(object)component2 != (Object)null)
				{
					sortedDictionary[((Object)prefab).name] = GetDisplayName(component2.m_name);
					continue;
				}
				Petable component3 = prefab.GetComponent<Petable>();
				if ((Object)(object)component3 != (Object)null)
				{
					sortedDictionary[((Object)prefab).name] = GetDisplayName(component3.m_name);
					continue;
				}
				Fish component4 = prefab.GetComponent<Fish>();
				if ((Object)(object)component4 != (Object)null)
				{
					sortedDictionary[((Object)prefab).name] = GetDisplayName(component4.m_name);
				}
				else if ((Object)(object)prefab.GetComponent<RandomFlyingBird>() != (Object)null)
				{
					sortedDictionary[((Object)prefab).name] = GetDisplayName(GetBirdNameToken(((Object)prefab).name));
				}
			}
			foreach (KeyValuePair<string, string> npcName in npcNames)
			{
				if (!sortedDictionary.ContainsKey(npcName.Key))
				{
					sortedDictionary[npcName.Key] = npcName.Value;
				}
			}
			foreach (string key in values.Keys)
			{
				if (!sortedDictionary.ContainsKey(key))
				{
					sortedDictionary[key] = "";
				}
			}
			names = sortedDictionary;
			string value;
			Dictionary<string, bool?> states = BuildStates((string key) => (!values.TryGetValue(key, out value)) ? ((bool?)null) : ParseState(value));
			Write(FilePath, sortedDictionary, states);
			SyncEntries(states);
		}

		public static void AddNPC(string key, string nameToken)
		{
			string displayName = GetDisplayName(nameToken);
			if (!npcNames.TryGetValue(key, out var value) || !(value == displayName))
			{
				npcNames[key] = displayName;
				if (!((Object)(object)ZNetScene.instance == (Object)null) && (!names.TryGetValue(key, out var value2) || value2.Length <= 0))
				{
					Load(ZNetScene.instance);
					Plugin.Watcher?.Remember();
				}
			}
		}

		private static Dictionary<string, bool?> BuildStates(Func<string, bool?> getState)
		{
			Dictionary<string, bool?> dictionary = new Dictionary<string, bool?>(StringComparer.OrdinalIgnoreCase);
			overrides.Clear();
			foreach (string key in names.Keys)
			{
				bool? flag = (dictionary[key] = getState(key));
				if (flag.HasValue)
				{
					overrides[StringExtensionMethods.GetStableHashCode(key)] = flag.Value;
				}
			}
			return dictionary;
		}

		private static void BindSettings()
		{
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: 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_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			int num = 100;
			showOnScreenEntry = BindSetting("1 - Markers", "Show On Screen", defaultValue: true, showOnScreenNote, null, num--);
			showOnMapEntry = BindSetting("1 - Markers", "Show On Map", defaultValue: true, showOnMapNote, null, num--);
			showNameEntry = BindSetting("1 - Markers", "Show Name", defaultValue: false, showNameNote, null, num--);
			showLevelEntry = BindSetting("1 - Markers", "Show Level", defaultValue: false, showLevelNote, null, num--);
			showDistanceEntry = BindSetting("1 - Markers", "Show Distance", defaultValue: false, showDistanceNote, null, num--);
			maxDistanceEntry = BindSetting("1 - Markers", "Max Distance", 50f, maxDistanceNote, (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 500f), num--);
			farDistanceEntry = BindSetting("1 - Markers", "Far Distance", 50f, farDistanceNote, (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 500f), num--);
			farScaleEntry = BindSetting("1 - Markers", "Far Scale", 0.66f, farScaleNote, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), num--);
			bobHeightEntry = BindSetting("1 - Markers", "Bob Height", 0f, bobHeightNote, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), num--);
			passiveColorEntry = BindSetting<Color>("2 - Colors", "Passive Color", ParseColor("#40D940", Color.green), passiveColorNote, null, num--);
			hostileColorEntry = BindSetting<Color>("2 - Colors", "Hostile Color", ParseColor("#FFD91A", Color.yellow), hostileColorNote, null, num--);
			angryColorEntry = BindSetting<Color>("2 - Colors", "Angry Color", ParseColor("#FF801A", Color.red), angryColorNote, null, num--);
			bossColorEntry = BindSetting<Color>("2 - Colors", "Boss Color", ParseColor("#FF3333", Color.red), bossColorNote, null, num--);
			fishColorEntry = BindSetting<Color>("2 - Colors", "Fish Color", ParseColor("#33CCFF", Color.cyan), fishColorNote, null, num--);
			petColorEntry = BindSetting<Color>("2 - Colors", "Pet Color", ParseColor("#FFF", Color.white), petColorNote, null, num--);
			traderColorEntry = BindSetting("2 - Colors", "Trader Color", "", traderColorNote, null, num--);
			allPassiveEntry = BindSetting("3 - Creatures and Fish", "All Passive Creatures", defaultValue: false, "Mark every creature that won't attack you, including traders and their pets", null, num--);
			allHostileEntry = BindSetting("3 - Creatures and Fish", "All Hostile Creatures", defaultValue: true, "Mark every creature that will attack you", null, num--);
			allFishEntry = BindSetting("3 - Creatures and Fish", "All Fish", defaultValue: false, "Mark every fish", null, num--);
			allBirdsEntry = BindSetting("3 - Creatures and Fish", "All Birds", defaultValue: false, "Mark every bird", null, num--);
			minCreatureLevelEntry = BindSetting("3 - Creatures and Fish", "Min Creature Level", 0, minCreatureLevelNote, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 9), num--);
			minFishLevelEntry = BindSetting("3 - Creatures and Fish", "Min Fish Level", 1, minFishLevelNote, (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), num--);
		}

		private static ConfigEntry<T> BindSetting<T>(string section, string key, T defaultValue, string description, AcceptableValueBase range, int order)
		{
			return mirror.Bind(section, key, defaultValue, description, range, order, null);
		}

		private static void SyncEntries(Dictionary<string, bool?> states)
		{
			if (mirror == null)
			{
				return;
			}
			mirror.Sync(delegate
			{
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: 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)
				showOnScreenEntry.Value = ShowOnScreen;
				showOnMapEntry.Value = ShowOnMap;
				showNameEntry.Value = ShowName;
				showLevelEntry.Value = ShowLevel;
				showDistanceEntry.Value = ShowDistance;
				maxDistanceEntry.Value = MaxDistance;
				farDistanceEntry.Value = FarDistance;
				farScaleEntry.Value = FarScale;
				bobHeightEntry.Value = BobHeight;
				passiveColorEntry.Value = passiveColor;
				hostileColorEntry.Value = hostileColor;
				angryColorEntry.Value = angryColor;
				bossColorEntry.Value = bossColor;
				fishColorEntry.Value = fishColor;
				petColorEntry.Value = petColor;
				traderColorEntry.Value = traderColorText;
				allPassiveEntry.Value = allPassive;
				allHostileEntry.Value = allHostile;
				allFishEntry.Value = allFish;
				allBirdsEntry.Value = allBirds;
				minCreatureLevelEntry.Value = minCreatureLevel;
				minFishLevelEntry.Value = minFishLevel;
				foreach (KeyValuePair<string, string> name in names)
				{
					creatureEntries.Set("3 - Creatures and Fish", name.Key, name.Value, states[name.Key]);
				}
				creatureEntries.RemoveUnset();
			});
		}

		private static void OnEntryChanged()
		{
			ShowOnScreen = showOnScreenEntry.Value;
			ShowOnMap = showOnMapEntry.Value;
			ShowName = showNameEntry.Value;
			ShowLevel = showLevelEntry.Value;
			ShowDistance = showDistanceEntry.Value;
			MaxDistance = maxDistanceEntry.Value;
			FarDistance = farDistanceEntry.Value;
			FarScale = farScaleEntry.Value;
			BobHeight = bobHeightEntry.Value;
			passiveColorText = TakeEntryColor(passiveColorEntry, passiveColorText, ref passiveColor);
			hostileColorText = TakeEntryColor(hostileColorEntry, hostileColorText, ref hostileColor);
			angryColorText = TakeEntryColor(angryColorEntry, angryColorText, ref angryColor);
			bossColorText = TakeEntryColor(bossColorEntry, bossColorText, ref bossColor);
			fishColorText = TakeEntryColor(fishColorEntry, fishColorText, ref fishColor);
			petColorText = TakeEntryColor(petColorEntry, petColorText, ref petColor);
			traderColorText = ParseOptionalColor("Trader Color", traderColorEntry.Value, out traderColor);
			allPassive = allPassiveEntry.Value;
			allHostile = allHostileEntry.Value;
			allFish = allFishEntry.Value;
			allBirds = allBirdsEntry.Value;
			minCreatureLevel = minCreatureLevelEntry.Value;
			minFishLevel = minFishLevelEntry.Value;
			bool? state;
			Dictionary<string, bool?> states = BuildStates((string key) => (!creatureEntries.TryGetState(key, out state)) ? ((bool?)null) : state);
			Write(FilePath, names, states);
			Plugin.Watcher?.Remember();
		}

		private static string TakeEntryColor(ConfigEntry<Color> entry, string text, ref Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			Color value = entry.Value;
			value.a = 1f;
			if (value == color)
			{
				return text;
			}
			color = value;
			return "#" + ColorUtility.ToHtmlStringRGB(value);
		}

		public static void GetMarked(Player player, List<Target> marked)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			marked.Clear();
			Vector3 position = ((Component)player).transform.position;
			float num = MaxDistance * MaxDistance;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				Vector3 position2 = ((Component)allCharacter).transform.position;
				if (Vector3.SqrMagnitude(position2 - position) > num || allCharacter is Player || allCharacter.IsDead())
				{
					continue;
				}
				int level = allCharacter.GetLevel();
				if (level - 1 >= minCreatureLevel)
				{
					bool flag = IsHostile(allCharacter, player);
					if (IsMarked(allCharacter.m_nview, flag ? allHostile : allPassive))
					{
						marked.Add(new Target
						{
							source = (Object)(object)allCharacter,
							position = position2,
							top = allCharacter.GetTopPoint(),
							nameToken = allCharacter.GetHoverName(),
							level = level,
							color = GetCreatureColor(allCharacter, flag, player)
						});
					}
				}
			}
			Color val = (Color)(((??)traderColor) ?? passiveColor);
			foreach (NPC item in NpcList.Get())
			{
				Vector3 position3 = item.source.transform.position;
				if (!(Vector3.SqrMagnitude(position3 - position) > num) && IsMarked(item.hash, allPassive))
				{
					marked.Add(new Target
					{
						source = (Object)(object)item.source,
						position = position3,
						top = position3 + Vector3.up * item.GetHeight(),
						nameToken = item.nameToken,
						level = 1,
						color = ((item.source is Trader) ? val : passiveColor)
					});
				}
			}
			foreach (IMonoUpdater instance in Fish.Instances)
			{
				Fish val2 = (Fish)(object)((instance is Fish) ? instance : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Vector3 position4 = ((Component)val2).transform.position;
				if (!(Vector3.SqrMagnitude(position4 - position) > num))
				{
					int num2 = ((!((Object)(object)val2.m_itemDrop != (Object)null)) ? 1 : val2.m_itemDrop.m_itemData.m_quality);
					if (num2 >= minFishLevel && IsMarked(val2.m_nview, allFish))
					{
						marked.Add(new Target
						{
							source = (Object)(object)val2,
							position = position4,
							top = position4,
							nameToken = val2.GetHoverName(),
							level = num2,
							fish = true,
							color = fishColor
						});
					}
				}
			}
			foreach (IMonoUpdater instance2 in RandomFlyingBird.Instances)
			{
				RandomFlyingBird val3 = (RandomFlyingBird)(object)((instance2 is RandomFlyingBird) ? instance2 : null);
				if ((Object)(object)val3 == (Object)null || (Object)(object)val3.m_nview == (Object)null || !val3.m_nview.IsValid())
				{
					continue;
				}
				Vector3 position5 = ((Component)val3).transform.position;
				if (!(Vector3.SqrMagnitude(position5 - position) > num))
				{
					int prefab = val3.m_nview.GetZDO().GetPrefab();
					if (IsMarked(prefab, allBirds))
					{
						marked.Add(new Target
						{
							source = (Object)(object)val3,
							position = position5,
							top = position5,
							nameToken = GetBirdNameToken(val3, prefab),
							level = 1,
							color = passiveColor
						});
					}
				}
			}
		}

		private static string GetBirdNameToken(RandomFlyingBird bird, int prefabHash)
		{
			if (!birdNamesByHash.TryGetValue(prefabHash, out var value))
			{
				value = GetBirdNameToken(Utils.GetPrefabName(((Component)bird).gameObject));
				birdNamesByHash[prefabHash] = value;
			}
			return value;
		}

		private static string GetBirdNameToken(string prefabName)
		{
			if (birdNameTokens.TryGetValue(prefabName, out var value))
			{
				return value;
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < prefabName.Length; i++)
			{
				char c = prefabName[i];
				if (c == '_')
				{
					c = ' ';
				}
				else if (i > 0 && char.IsUpper(c) && char.IsLower(prefabName[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString().Trim();
		}

		private static bool IsMarked(ZNetView nview, bool inherited)
		{
			if ((Object)(object)nview != (Object)null && nview.IsValid())
			{
				return IsMarked(nview.GetZDO().GetPrefab(), inherited);
			}
			return inherited;
		}

		private static bool IsMarked(int prefabHash, bool inherited)
		{
			if (overrides.TryGetValue(prefabHash, out var value))
			{
				return value;
			}
			return inherited;
		}

		private static Color GetCreatureColor(Character character, bool hostile, Player player)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			if (character.IsBoss())
			{
				return bossColor;
			}
			if (character.IsTamed())
			{
				return petColor;
			}
			if (!hostile)
			{
				return passiveColor;
			}
			if (!IsAngry(character, player))
			{
				return hostileColor;
			}
			return angryColor;
		}

		private static bool IsAngry(Character character, Player player)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			BaseAI baseAI = character.GetBaseAI();
			MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null);
			if ((Object)(object)val == (Object)null || !character.m_nview.IsValid())
			{
				return false;
			}
			if (character.m_nview.IsOwner())
			{
				return (Object)(object)val.m_targetCreature == (Object)(object)player;
			}
			if (!((BaseAI)val).IsAlerted() || !((BaseAI)val).HaveTarget())
			{
				return false;
			}
			ZDOID zDOID = character.m_nview.GetZDO().GetZDOID(MonsterTargetPatch.TargetHash);
			if (((ZDOID)(ref zDOID)).IsNone())
			{
				return true;
			}
			return zDOID == ((Character)player).GetZDOID();
		}

		private static bool IsHostile(Character character, Player player)
		{
			if (character.GetBaseAI() is MonsterAI)
			{
				return BaseAI.IsEnemy(character, (Character)(object)player);
			}
			return false;
		}

		private static void LoadSettings(Dictionary<string, string> values)
		{
			MaxDistance = TakeFloat(values, "Max Distance", 50f, 5f, 500f);
			FarDistance = TakeFloat(values, "Far Distance", 50f, 5f, 500f);
			FarScale = TakeFloat(values, "Far Scale", 0.66f, 0.2f, 1f);
			BobHeight = TakeFloat(values, "Bob Height", 0f, 0f, 30f);
			passiveColorText = TakeColor(values, "Passive Color", "#40D940", out passiveColor);
			hostileColorText = TakeColor(values, "Hostile Color", "#FFD91A", out hostileColor);
			angryColorText = TakeColor(values, "Angry Color", "#FF801A", out angryColor);
			bossColorText = TakeColor(values, "Boss Color", "#FF3333", out bossColor);
			fishColorText = TakeColor(values, "Fish Color", "#33CCFF", out fishColor);
			petColorText = TakeColor(values, "Pet Color", "#FFF", out petColor);
			traderColorText = ParseOptionalColor("Trader Color", TakeValue(values, "Trader Color"), out traderColor);
			string text = TakeValue(values, "All Creatures");
			string text2 = TakeValue(values, "All Passive Creatures");
			string text3 = TakeValue(values, "All Birds");
			allPassive = ParseState(text2) == true;
			allHostile = ParseState(TakeValue(values, "All Hostile Creatures")) ?? true;
			allFish = ParseState(TakeValue(values, "All Fish")) == true;
			allBirds = ParseState(text3) == true;
			if (text2 == null && ParseState(text) == true)
			{
				allPassive = true;
				allHostile = true;
				if (text3 == null)
				{
					allBirds = true;
				}
			}
			minCreatureLevel = TakeInt(values, "Min Creature Level", 0, 0, 9);
			minFishLevel = TakeInt(values, "Min Fish Level", 1, 1, 5);
			ShowName = ParseState(TakeValue(values, "Show Name")) == true;
			ShowDistance = ParseState(TakeValue(values, "Show Distance")) == true;
			ShowLevel = ParseState(TakeValue(values, "Show Level")) == true;
			ShowOnScreen = ParseState(TakeValue(values, "Show On Screen")) ?? true;
			ShowOnMap = ParseState(TakeValue(values, "Show On Map")) ?? true;
		}

		private static float TakeFloat(Dictionary<string, string> values, string key, float defaultValue, float min, float max)
		{
			string text = TakeValue(values, key);
			if (text == null)
			{
				return defaultValue;
			}
			if (!float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				Warn(key, text);
				return defaultValue;
			}
			return Mathf.Clamp(result, min, max);
		}

		private static int TakeInt(Dictionary<string, string> values, string key, int defaultValue, int min, int max)
		{
			string text = TakeValue(values, key);
			if (text == null)
			{
				return defaultValue;
			}
			if (!int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
			{
				Warn(key, text);
				return defaultValue;
			}
			return Mathf.Clamp(result, min, max);
		}

		private static string TakeColor(Dictionary<string, string> values, string key, string defaultText, out Color color)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			string text = TakeValue(values, key);
			if (text != null && ColorUtility.TryParseHtmlString(text, ref color))
			{
				return text;
			}
			if (text != null)
			{
				Warn(key, text);
			}
			color = ParseColor(defaultText, Color.white);
			return defaultText;
		}

		private static string ParseOptionalColor(string key, string text, out Color? color)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			color = null;
			if (string.IsNullOrWhiteSpace(text))
			{
				return "";
			}
			text = text.Trim();
			Color value = default(Color);
			if (!ColorUtility.TryParseHtmlString(text, ref value))
			{
				Warn(key, text);
				return "";
			}
			color = value;
			return text;
		}

		private static string TakeValue(Dictionary<string, string> values, string key)
		{
			if (!values.TryGetValue(key, out var value))
			{
				return null;
			}
			values.Remove(key);
			return value;
		}

		private static bool? ParseState(string text)
		{
			if (text != null && bool.TryParse(text, out var result))
			{
				return result;
			}
			return null;
		}

		private static Color ParseColor(string text, Color fallback)
		{
			//IL_000c: 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)
			Color result = default(Color);
			if (!ColorUtility.TryParseHtmlString(text, ref result))
			{
				return fallback;
			}
			return result;
		}

		private static void Warn(string key, string text)
		{
			Debug.LogWarning((object)("[Creature Marker] Couldn't read " + key + " = " + text + ", using the default"));
		}

		private static Dictionary<string, string> Read(string path, out Dictionary<string, string> notes)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			notes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			if (!File.Exists(path))
			{
				return dictionary;
			}
			string[] array = File.ReadAllLines(path);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i];
				string text2 = "";
				int num = text.IndexOf("##", StringComparison.Ordinal);
				if (num >= 0)
				{
					text2 = text.Substring(num + "##".Length).Trim();
					text = text.Substring(0, num);
				}
				int num2 = text.IndexOf('=');
				if (num2 <= 0)
				{
					continue;
				}
				string text3 = text.Substring(0, num2).Trim();
				if (text3.Length > 0)
				{
					dictionary[text3] = text.Substring(num2 + 1).Trim();
					if (text2.Length > 0)
					{
						notes[text3] = text2;
					}
				}
			}
			return dictionary;
		}

		private static void Write(string path, SortedDictionary<string, string> names, Dictionary<string, bool?> states)
		{
			StringBuilder stringBuilder = new StringBuilder();
			AppendLines(stringBuilder, header);
			AppendLine(stringBuilder, "Show On Screen", StateEntries.Format(ShowOnScreen), showOnScreenNote);
			AppendLine(stringBuilder, "Show On Map", StateEntries.Format(ShowOnMap), showOnMapNote);
			stringBuilder.Append("\r\n");
			AppendLine(stringBuilder, "Show Name", StateEntries.Format(ShowName), showNameNote);
			AppendLine(stringBuilder, "Show Level", StateEntries.Format(ShowLevel), showLevelNote);
			stringBuilder.Append("\r\n");
			AppendLine(stringBuilder, "Show Distance", StateEntries.Format(ShowDistance), showDistanceNote);
			AppendLine(stringBuilder, "Max Distance", MaxDistance.ToString(CultureInfo.InvariantCulture), maxDistanceNote);
			AppendLine(stringBuilder, "Far Distance", FarDistance.ToString(CultureInfo.InvariantCulture), farDistanceNote);
			AppendLine(stringBuilder, "Far Scale", FarScale.ToString(CultureInfo.InvariantCulture), farScaleNote);
			stringBuilder.Append("\r\n");
			AppendLine(stringBuilder, "Bob Height", BobHeight.ToString(CultureInfo.InvariantCulture), bobHeightNote);
			AppendLine(stringBuilder, "Passive Color", passiveColorText, passiveColorNote);
			AppendLine(stringBuilder, "Hostile Color", hostileColorText, hostileColorNote);
			AppendLine(stringBuilder, "Angry Color", angryColorText, angryColorNote);
			AppendLine(stringBuilder, "Boss Color", bossColorText, bossColorNote);
			AppendLine(stringBuilder, "Fish Color", fishColorText, fishColorNote);
			AppendLine(stringBuilder, "Pet Color", petColorText, petColorNote);
			AppendLine(stringBuilder, "Trader Color", traderColorText, traderColorNote);
			AppendLines(stringBuilder, creatureHeader);
			AppendLine(stringBuilder, "All Passive Creatures", StateEntries.Format(allPassive), "");
			AppendLine(stringBuilder, "All Hostile Creatures", StateEntries.Format(allHostile), "");
			AppendLine(stringBuilder, "All Fish", StateEntries.Format(allFish), "");
			AppendLine(stringBuilder, "All Birds", StateEntries.Format(allBirds), "");
			AppendLine(stringBuilder, "Min Creature Level", minCreatureLevel.ToString(CultureInfo.InvariantCulture), minCreatureLevelNote);
			AppendLine(stringBuilder, "Min Fish Level", minFishLevel.ToString(CultureInfo.InvariantCulture), minFishLevelNote);
			AppendLines(stringBuilder, creatureLinesHeader);
			foreach (KeyValuePair<string, string> name in names)
			{
				AppendLine(stringBuilder, name.Key, StateEntries.Format(states[name.Key]), name.Value);
			}
			string text = stringBuilder.ToString();
			try
			{
				if (!File.Exists(path) || !(File.ReadAllText(path) == text))
				{
					File.WriteAllText(path, text);
				}
			}
			catch (IOException ex)
			{
				Debug.LogWarning((object)("[Creature Marker] Couldn't write " + path + ": " + ex.Message));
			}
		}

		private static void AppendLines(StringBuilder builder, string[] lines)
		{
			foreach (string value in lines)
			{
				builder.Append(value).Append("\r\n");
			}
		}

		private static void AppendLine(StringBuilder builder, string key, string value, string note)
		{
			builder.Append(key).Append(" =");
			if (value.Length > 0)
			{
				builder.Append(" ").Append(value);
			}
			if (note.Length > 0)
			{
				builder.Append(" ").Append("##").Append(" ")
					.Append(note);
			}
			builder.Append("\r\n");
		}

		private static string GetDisplayName(string token)
		{
			string text = token;
			if (Localization.instance != null)
			{
				text = Localization.instance.Localize(text);
			}
			return text.Replace("\r", "").Replace("\n", " ").Replace("#", "");
		}
	}
	internal class LevelStars
	{
		private const string OutlinePath = "level_2/star";

		private const string FillName = "star (1)";

		private const float OutlineSize = 15f;

		private const float FillSize = 12f;

		private const float StarAdvance = 16f;

		private static readonly char[] StarCandidates = new char[3] { '⭐', '★', '*' };

		private Material material;

		private string outlineTag;

		private string character;

		public TMP_SpriteAsset Asset { get; private set; }

		public void Create(EnemyHud enemyHud, TMP_FontAsset font, float fontSize)
		{
			if (outlineTag == null && character == null)
			{
				outlineTag = CreateSpriteStar(enemyHud, font, fontSize);
				if (outlineTag == null)
				{
					character = PickCharacter(font);
				}
			}
		}

		public string GetStar(Color fill)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (outlineTag == null)
			{
				return character ?? "*";
			}
			return outlineTag + "<sprite=1 color=#" + ColorUtility.ToHtmlStringRGBA(fill) + ">";
		}

		public void Destroy()
		{
			if ((Object)(object)material != (Object)null)
			{
				Object.Destroy((Object)(object)material);
			}
			if ((Object)(object)Asset != (Object)null)
			{
				Object.Destroy((Object)(object)Asset);
			}
			material = null;
			Asset = null;
			outlineTag = null;
			character = null;
		}

		private string CreateSpriteStar(EnemyHud enemyHud, TMP_FontAsset font, float fontSize)
		{
			//IL_00a3: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			Transform val = enemyHud.m_baseHud.transform.Find("level_2/star");
			Transform val2 = (((Object)(object)val != (Object)null) ? val.Find("star (1)") : null);
			Image val3 = default(Image);
			Image val4 = default(Image);
			if ((Object)(object)font == (Object)null || (Object)(object)val2 == (Object)null || !((Component)val).TryGetComponent<Image>(ref val3) || !((Component)val2).TryGetComponent<Image>(ref val4))
			{
				return null;
			}
			Sprite sprite = val3.sprite;
			Sprite sprite2 = val4.sprite;
			if ((Object)(object)sprite == (Object)null || (Object)(object)sprite2 == (Object)null || (Object)(object)sprite.texture == (Object)null || (Object)(object)sprite.texture != (Object)(object)sprite2.texture)
			{
				return null;
			}
			Rect textureRect;
			Rect textureRect2;
			try
			{
				textureRect = sprite.textureRect;
				textureRect2 = sprite2.textureRect;
			}
			catch (Exception)
			{
				return null;
			}
			Shader val5 = Shader.Find("TextMeshPro/Sprite");
			if ((Object)(object)val5 == (Object)null)
			{
				val5 = Shader.Find("UI/Default");
			}
			if ((Object)(object)val5 == (Object)null)
			{
				return null;
			}
			FaceInfo faceInfo = ((TMP_Asset)font).faceInfo;
			float num = fontSize / ((FaceInfo)(ref faceInfo)).pointSize * ((FaceInfo)(ref faceInfo)).scale;
			float center = ((FaceInfo)(ref faceInfo)).capLine * num * 0.5f;
			Asset = ScriptableObject.CreateInstance<TMP_SpriteAsset>();
			((Object)Asset).name = "CreatureMarkerStars";
			AccessTools.Field(typeof(TMP_Asset), "m_Version").SetValue(Asset, "1.1.0");
			FaceInfo faceInfo2 = default(FaceInfo);
			((FaceInfo)(ref faceInfo2)).pointSize = fontSize;
			((FaceInfo)(ref faceInfo2)).scale = 1f;
			((FaceInfo)(ref faceInfo2)).ascentLine = ((FaceInfo)(ref faceInfo)).ascentLine * num;
			((FaceInfo)(ref faceInfo2)).descentLine = ((FaceInfo)(ref faceInfo)).descentLine * num;
			((TMP_Asset)Asset).faceInfo = faceInfo2;
			Asset.spriteSheet = (Texture)(object)sprite.texture;
			material = new Material(val5);
			material.mainTexture = (Texture)(object)sprite.texture;
			((TMP_Asset)Asset).material = material;
			AddSprite(0u, textureRect, 15f, 0f, center, 0f);
			AddSprite(1u, textureRect2, 12f, 1.5f, center, 16f);
			Asset.UpdateLookupTables();
			return "<sprite=0 color=#" + ColorUtility.ToHtmlStringRGBA(((Graphic)val3).color) + ">";
		}

		private void AddSprite(uint index, Rect rect, float size, float bearingX, float center, float advance)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			GlyphMetrics val = default(GlyphMetrics);
			((GlyphMetrics)(ref val))..ctor(size, size, bearingX, center + size * 0.5f, advance);
			GlyphRect val2 = default(GlyphRect);
			((GlyphRect)(ref val2))..ctor(Mathf.RoundToInt(((Rect)(ref rect)).x), Mathf.RoundToInt(((Rect)(ref rect)).y), Mathf.RoundToInt(((Rect)(ref rect)).width), Mathf.RoundToInt(((Rect)(ref rect)).height));
			TMP_SpriteGlyph val3 = new TMP_SpriteGlyph(index, val, val2, 1f, 0);
			Asset.spriteGlyphTable.Add(val3);
			TMP_SpriteCharacter val4 = new TMP_SpriteCharacter(65534u, Asset, val3);
			val4.name = "star" + index;
			Asset.spriteCharacterTable.Add(val4);
		}

		private static string PickCharacter(TMP_FontAsset font)
		{
			if ((Object)(object)font != (Object)null)
			{
				char[] starCandidates = StarCandidates;
				for (int i = 0; i < starCandidates.Length; i++)
				{
					char c = starCandidates[i];
					if (font.HasCharacter(c, true, false))
					{
						return c.ToString();
					}
				}
			}
			return "*";
		}
	}
	public class MapMarkers
	{
		private class DotLayer
		{
			public readonly List<Image> dots = new List<Image>();

			public readonly float size;

			public RectTransform root;

			public DotLayer(float size)
			{
				this.size = size;
			}
		}

		private const float SmallDotSize = 10f;

		private const float LargeDotSize = 15f;

		private readonly DotLayer small = new DotLayer(10f);

		private readonly DotLayer large = new DotLayer(15f);

		private Sprite sprite;

		public void Update(List<Target> marked, Player player)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			Minimap instance = Minimap.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				bool flag = CreatureConfig.ShowOnMap && !((Character)player).InInterior();
				UpdateLayer(small, instance.m_pinRootSmall, instance.m_mapImageSmall, flag && (int)instance.m_mode == 1, instance, marked);
				UpdateLayer(large, instance.m_pinRootLarge, instance.m_mapImageLarge, flag && (int)instance.m_mode == 2, instance, marked);
			}
		}

		public void Destroy()
		{
			DestroyLayer(small);
			DestroyLayer(large);
			if ((Object)(object)sprite != (Object)null)
			{
				Object.Destroy((Object)(object)sprite.texture);
				Object.Destroy((Object)(object)sprite);
			}
		}

		private void UpdateLayer(DotLayer layer, RectTransform root, RawImage map, bool show, Minimap minimap, List<Target> marked)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)layer.root != (Object)(object)root)
			{
				layer.root = root;
				layer.dots.Clear();
			}
			int num = 0;
			if (show)
			{
				float num2 = default(float);
				float num3 = default(float);
				foreach (Target item in marked)
				{
					Vector3 position = item.position;
					if (minimap.IsPointVisible(position, map))
					{
						Image dot = GetDot(layer, num);
						num++;
						((Graphic)dot).color = item.color;
						minimap.WorldToMapPoint(position, ref num2, ref num3);
						((Graphic)dot).rectTransform.anchoredPosition = minimap.MapPointToLocalGuiPos(num2, num3, map);
					}
				}
			}
			for (int i = num; i < layer.dots.Count; i++)
			{
				MarkerHud.SetActive(((Component)layer.dots[i]).gameObject, active: false);
			}
		}

		private static void DestroyLayer(DotLayer layer)
		{
			foreach (Image dot in layer.dots)
			{
				if ((Object)(object)dot != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)dot).gameObject);
				}
			}
			layer.dots.Clear();
		}

		private Image GetDot(DotLayer layer, int index)
		{
			if (index >= layer.dots.Count)
			{
				layer.dots.Add(CreateDot(layer));
			}
			Image obj = layer.dots[index];
			MarkerHud.SetActive(((Component)obj).gameObject, active: true);
			((Component)obj).transform.SetAsLastSibling();
			return obj;
		}

		private Image CreateDot(DotLayer layer)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("CreatureMarkerDot", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)layer.root, false);
			Image obj = val.AddComponent<Image>();
			obj.sprite = GetSprite();
			((Graphic)obj).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.zero;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.sizeDelta = new Vector2(layer.size, layer.size);
			return obj;
		}

		private Sprite GetSprite()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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 ((Object)(object)sprite != (Object)null)
			{
				return sprite;
			}
			float num = 16f;
			Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)1;
			Color[] array = (Color[])(object)new Color[1024];
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					float num2 = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(num, num));
					Color val2 = Color.clear;
					if (num2 <= num - 5f)
					{
						val2 = Color.white;
					}
					else if (num2 <= num)
					{
						val2 = MarkerHud.OutlineColor;
					}
					array[i * 32 + j] = val2;
				}
			}
			val.SetPixels(array);
			val.Apply();
			sprite = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f));
			return sprite;
		}
	}
	public class MarkerHud
	{
		private class Marker
		{
			public Image arrow;

			public TextMeshProUGUI label;

			public Object source;

			public string name;

			public string shownName;

			public int shownLevel;

			public bool shownFish;

			public Color shownColor;

			public int shownDistance = -2;
		}

		private const int SortingOrder = 450;

		private const float HeadOffset = 0.4f;

		private const float EdgeMargin = 40f;

		private const float BobSpeed = 5f;

		private const float LabelGap = 2f;

		private const float LabelFontSize = 16f;

		private const float GameHudGap = 4f;

		private static readonly Vector2 ArrowSize = new Vector2(24f, 32f);

		internal static readonly Color OutlineColor = new Color(0.1f, 0.1f, 0.1f, 1f);

		private readonly List<Marker> markers = new List<Marker>();

		private GameObject root;

		private RectTransform layer;

		private Sprite sprite;

		private readonly LevelStars stars = new LevelStars();

		private readonly List<Graphic> graphics = new List<Graphic>();

		private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4];

		public void Update(List<Target> marked, Player player)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Invalid comparison between Unknown and I4
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			EnemyHud instance = EnemyHud.instance;
			Camera mainCamera = Utils.GetMainCamera();
			if ((Object)(object)instance == (Object)null || (Object)(object)mainCamera == (Object)null)
			{
				return;
			}
			if ((Object)(object)root != (Object)(object)instance.m_hudRoot)
			{
				root = instance.m_hudRoot;
				markers.Clear();
				layer = CreateLayer();
			}
			int num = 0;
			bool flag = (Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 2;
			if (CreatureConfig.ShowOnScreen && !flag && !IsLoadingScreenShown())
			{
				bool showName = CreatureConfig.ShowName;
				bool showDistance = CreatureConfig.ShowDistance;
				bool showLevel = CreatureConfig.ShowLevel;
				bool flag2 = showName || showDistance || showLevel;
				float num2 = CreatureConfig.FarDistance * CreatureConfig.FarDistance;
				Vector3 val = Vector3.one * CreatureConfig.FarScale;
				Vector3 position = ((Component)player).transform.position;
				foreach (Target item in marked)
				{
					Marker marker = GetMarker(num, instance);
					num++;
					float num3 = Vector3.SqrMagnitude(item.position - position);
					Vector3 val2 = ((num3 > num2) ? val : Vector3.one);
					((Transform)((Graphic)marker.arrow).rectTransform).localScale = val2;
					((Transform)((TMP_Text)marker.label).rectTransform).localScale = val2;
					((Graphic)marker.arrow).color = item.color;
					float gameHudHeight = GetGameHudHeight(instance, item.source);
					bool onScreen;
					Vector2 pointing = ((!(gameHudHeight >= 0f)) ? Place(((Graphic)marker.arrow).rectTransform, mainCamera, item.top + Vector3.up * 0.4f, 0f, val2.x, out onScreen) : Place(((Graphic)marker.arrow).rectTransform, mainCamera, item.top, gameHudHeight + 4f, val2.x, out onScreen));
					bool flag3 = gameHudHeight >= 0f && onScreen;
					bool flag4 = (flag3 ? showDistance : flag2);
					SetActive(((Component)marker.label).gameObject, flag4);
					if (flag4)
					{
						if (marker.source != item.source)
						{
							marker.source = item.source;
							marker.name = Localization.instance.Localize(item.nameToken);
						}
						int distance = (showDistance ? Mathf.RoundToInt(Mathf.Sqrt(num3)) : (-1));
						string name = ((showName && !flag3) ? marker.name : null);
						int level = ((showLevel && !flag3) ? item.level : 0);
						SetLabelText(marker, name, level, item.fish, item.color, distance);
						((Graphic)marker.label).color = item.color;
						PlaceLabel(marker, pointing);
					}
				}
			}
			for (int i = num; i < markers.Count; i++)
			{
				markers[i].source = null;
				markers[i].shownName = null;
				markers[i].shownDistance = -2;
				SetActive(((Component)markers[i].arrow).gameObject, active: false);
				SetActive(((Component)markers[i].label).gameObject, active: false);
			}
		}

		private static bool IsLoadingScreenShown()
		{
			Hud instance = Hud.instance;
			if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_loadingScreen != (Object)null)
			{
				return ((Component)instance.m_loadingScreen).gameObject.activeSelf;
			}
			return false;
		}

		public void Destroy()
		{
			stars.Destroy();
			if ((Object)(object)layer != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)layer).gameObject);
			}
			markers.Clear();
			if ((Object)(object)sprite != (Object)null)
			{
				Object.Destroy((Object)(object)sprite.texture);
				Object.Destroy((Object)(object)sprite);
			}
		}

		private static Vector2 Place(RectTransform arrow, Camera camera, Vector3 target, float lift, float size, out bool onScreen)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Utils.WorldToScreenPointScaled(camera, target);
			onScreen = val.z > 0f && val.x >= 0f && val.x <= (float)Screen.width && val.y >= 0f && val.y <= (float)Screen.height;
			if (onScreen)
			{
				float num = Mathf.Abs(Mathf.Sin(Time.time * 5f)) * CreatureConfig.BobHeight * size;
				((Transform)arrow).position = new Vector3(val.x, val.y + lift + num, 0f);
				((Transform)arrow).localRotation = Quaternion.identity;
				return Vector2.down;
			}
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)Screen.width * 0.5f, (float)Screen.height * 0.5f);
			Vector2 val3 = new Vector2(val.x, val.y) - val2;
			if (val.z < 0f)
			{
				val3 = -val3;
			}
			if (((Vector2)(ref val3)).sqrMagnitude < 0.01f)
			{
				val3 = Vector2.down;
			}
			float num2 = val2.x - 40f;
			float num3 = val2.y - 40f;
			float num4 = Mathf.Min(num2 / Mathf.Max(Mathf.Abs(val3.x), 0.001f), num3 / Mathf.Max(Mathf.Abs(val3.y), 0.001f));
			Vector2 val4 = val2 + val3 * num4;
			((Transform)arrow).position = new Vector3(val4.x, val4.y, 0f);
			float num5 = Mathf.Atan2(val3.y, val3.x) * 57.29578f + 90f;
			((Transform)arrow).localRotation = Quaternion.Euler(0f, 0f, num5);
			return ((Vector2)(ref val3)).normalized;
		}

		private float GetGameHudHeight(EnemyHud enemyHud, Object source)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			Character val = (Character)(object)((source is Character) ? source : null);
			if ((Object)(object)val == (Object)null || val.IsBoss() || !enemyHud.m_huds.TryGetValue(val, out var value))
			{
				return -1f;
			}
			if (value.m_isMount || (Object)(object)value.m_gui == (Object)null || !value.m_gui.activeSelf || (Object)(object)value.m_name == (Object)null || !((Component)value.m_name).gameObject.activeInHierarchy)
			{
				return -1f;
			}
			float y = value.m_gui.transform.position.y;
			float num = y;
			value.m_gui.GetComponentsInChildren<Graphic>(false, graphics);
			foreach (Graphic graphic in graphics)
			{
				if (graphic.color.a <= 0f)
				{
					continue;
				}
				TMP_Text val2 = (TMP_Text)(object)((graphic is TMP_Text) ? graphic : null);
				if (val2 != null)
				{
					if (!string.IsNullOrEmpty(val2.text))
					{
						float num2 = num;
						RectTransform rectTransform = val2.rectTransform;
						Bounds textBounds = val2.textBounds;
						num = Mathf.Max(num2, ((Transform)rectTransform).TransformPoint(((Bounds)(ref textBounds)).max).y);
					}
				}
				else
				{
					graphic.rectTransform.GetWorldCorners(corners);
					num = Mathf.Max(num, corners[1].y);
				}
			}
			graphics.Clear();
			return num - y;
		}

		private void SetLabelText(Marker marker, string name, int level, bool fish, Color color, int distance)
		{
			//IL_0052: 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)
			//IL_0021: 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)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (name == marker.shownName && level == marker.shownLevel && fish == marker.shownFish && color == marker.shownColor && distance == marker.shownDistance)
			{
				return;
			}
			marker.shownName = name;
			marker.shownLevel = level;
			marker.shownFish = fish;
			marker.shownColor = color;
			marker.shownDistance = distance;
			string text = name ?? "";
			if (level > 1)
			{
				if (fish)
				{
					text = text + "[" + level + "]";
				}
				else
				{
					if (text.Length > 0)
					{
						text += " ";
					}
					string star = stars.GetStar(color);
					for (int i = 1; i < level; i++)
					{
						text += star;
					}
				}
			}
			if (distance >= 0)
			{
				text = ((text.Length > 0) ? (text + " (" + distance + "m)") : (distance + "m"));
			}
			((TMP_Text)marker.label).text = text;
		}

		private static void PlaceLabel(Marker marker, Vector2 pointing)
		{
			//IL_0018: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((Graphic)marker.arrow).rectTransform;
			RectTransform rectTransform2 = ((TMP_Text)marker.label).rectTransform;
			float x = ((Transform)rectTransform).lossyScale.x;
			Vector2 val = (rectTransform2.sizeDelta = ((TMP_Text)marker.label).GetPreferredValues());
			Vector2 val2 = val * x * 0.5f;
			float num = Mathf.Abs(pointing.x) * val2.x + Mathf.Abs(pointing.y) * val2.y;
			Vector2 val3 = Vector2.op_Implicit(((Transform)rectTransform).position) - pointing * ((ArrowSize.y + 2f) * x + num);
			val3.x = Mathf.Clamp(val3.x, val2.x, Mathf.Max(val2.x, (float)Screen.width - val2.x));
			val3.y = Mathf.Clamp(val3.y, val2.y, Mathf.Max(val2.y, (float)Screen.height - val2.y));
			((Transform)rectTransform2).position = new Vector3(val3.x, val3.y, 0f);
		}

		private Marker GetMarker(int index, EnemyHud enemyHud)
		{
			if (index >= markers.Count)
			{
				Marker marker = new Marker();
				marker.arrow = CreateArrow();
				marker.label = CreateLabel(enemyHud);
				markers.Add(marker);
			}
			Marker marker2 = markers[index];
			SetActive(((Component)marker2.arrow).gameObject, active: true);
			return marker2;
		}

		internal static void SetActive(GameObject go, bool active)
		{
			if (go.activeSelf != active)
			{
				go.SetActive(active);
			}
		}

		private RectTransform CreateLayer()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			GameObject val = new GameObject("CreatureMarkers", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(root.transform, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			Canvas obj = val.AddComponent<Canvas>();
			obj.overrideSorting = true;
			obj.sortingOrder = 450;
			return val2;
		}

		private TextMeshProUGUI CreateLabel(EnemyHud enemyHud)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("CreatureMarkerLabel", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)layer, false);
			val.SetActive(false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			TMP_Text nameTemplate = GetNameTemplate(enemyHud);
			if ((Object)(object)nameTemplate != (Object)null)
			{
				((TMP_Text)val2).font = nameTemplate.font;
				((TMP_Text)val2).fontSharedMaterial = nameTemplate.fontSharedMaterial;
			}
			stars.Create(enemyHud, ((TMP_Text)val2).font, 16f);
			if ((Object)(object)stars.Asset != (Object)null)
			{
				((TMP_Text)val2).spriteAsset = stars.Asset;
			}
			((TMP_Text)val2).fontSize = 16f;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0;
			((Graphic)val2).raycastTarget = false;
			((TMP_Text)val2).rectTransform.pivot = new Vector2(0.5f, 0.5f);
			return val2;
		}

		private static TMP_Text GetNameTemplate(EnemyHud enemyHud)
		{
			Transform val = enemyHud.m_baseHud.transform.Find("Name");
			TMP_Text result = default(TMP_Text);
			if ((Object)(object)val != (Object)null && ((Component)val).TryGetComponent<TMP_Text>(ref result))
			{
				return result;
			}
			if ((Object)(object)Hud.instance != (Object)null)
			{
				return Hud.instance.m_healthText;
			}
			return null;
		}

		private Image CreateArrow()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("CreatureMarkerArrow", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)layer, false);
			Image obj = val.AddComponent<Image>();
			obj.sprite = GetSprite();
			((Graphic)obj).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			rectTransform.pivot = new Vector2(0.5f, 0f);
			rectTransform.sizeDelta = ArrowSize;
			return obj;
		}

		private Sprite GetSprite()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sprite != (Object)null)
			{
				return sprite;
			}
			Texture2D val = new Texture2D(48, 64, (TextureFormat)4, false);
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)1;
			Color[] array = (Color[])(object)new Color[3072];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 48; j++)
				{
					float px = Mathf.Abs((float)j + 0.5f - 24f);
					float py = (float)i + 0.5f;
					Color val2 = Color.clear;
					if (InArrow(px, py, 3f, 48, 64))
					{
						val2 = Color.white;
					}
					else if (InArrow(px, py, 0f, 48, 64))
					{
						val2 = OutlineColor;
					}
					array[i * 48 + j] = val2;
				}
			}
			val.SetPixels(array);
			val.Apply();
			sprite = Sprite.Create(val, new Rect(0f, 0f, 48f, 64f), new Vector2(0.5f, 0f));
			return sprite;
		}

		private static bool InArrow(float px, float py, float inset, int width, int height)
		{
			float num = (float)height * 0.55f;
			float num2 = (float)width * 0.5f;
			float num3 = (float)width * 0.2f;
			float num4 = num2 / num;
			float num5 = inset * Mathf.Sqrt(1f + num4 * num4);
			bool num6 = py <= num - inset && px <= py * num4 - num5;
			bool flag = py >= num * 0.5f && py <= (float)height - inset && px <= num3 - inset;
			return num6 || flag;
		}
	}
	internal class NPC
	{
		public Component source;

		public string key;

		public int hash;

		public string nameToken;

		private float height = -1f;

		public float GetHeight()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (height >= 0f)
			{
				return height;
			}
			float y = source.transform.position.y;
			float num = float.MinValue;
			Collider[] componentsInChildren = source.GetComponentsInChildren<Collider>();
			Bounds bounds;
			foreach (Collider val in componentsInChildren)
			{
				if (!val.isTrigger)
				{
					float num2 = num;
					bounds = val.bounds;
					num = Mathf.Max(num2, ((Bounds)(ref bounds)).max.y);
				}
			}
			if (num == float.MinValue)
			{
				Renderer[] componentsInChildren2 = source.GetComponentsInChildren<Renderer>();
				foreach (Renderer val2 in componentsInChildren2)
				{
					float num3 = num;
					bounds = val2.bounds;
					num = Mathf.Max(num3, ((Bounds)(ref bounds)).max.y);
				}
			}
			height = ((num == float.MinValue) ? 2f : Mathf.Max(0f, num - y));
			return height;
		}
	}
	internal static class NpcList
	{
		private static readonly List<NPC> npcs = new List<NPC>();

		public static List<NPC> Get()
		{
			npcs.RemoveAll((NPC npc) => (Object)(object)npc.source == (Object)null);
			return npcs;
		}

		public static void Add(Component source, string nameToken)
		{
			foreach (NPC npc in npcs)
			{
				if ((Object)(object)npc.source == (Object)(object)source)
				{
					return;
				}
			}
			NPC nPC = new NPC();
			nPC.source = source;
			nPC.key = Utils.GetPrefabName(source.gameObject);
			nPC.hash = StringExtensionMethods.GetStableHashCode(nPC.key);
			nPC.nameToken = nameToken;
			npcs.Add(nPC);
			CreatureConfig.AddNPC(nPC.key, nameToken);
		}
	}
	[HarmonyPatch(typeof(Trader), "Start")]
	public static class TraderStartPatch
	{
		private static void Postfix(Trader __instance)
		{
			NpcList.Add((Component)(object)__instance, __instance.m_name);
		}
	}
	[HarmonyPatch(typeof(Location), "Awake")]
	public static class LocationAwakePatch
	{
		private static void Postfix(Location __instance)
		{
			Petable[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Petable>(true);
			foreach (Petable val in componentsInChildren)
			{
				NpcList.Add((Component)(object)val, val.m_name);
			}
		}
	}
	[BepInPlugin("kriona.CreatureMarker", "Creature Marker", "1.7.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "kriona.CreatureMarker";

		public const string PluginName = "Creature Marker";

		public const string PluginVersion = "1.7.0";

		private readonly MarkerHud markers = new MarkerHud();

		private readonly MapMarkers mapMarkers = new MapMarkers();

		private readonly List<Target> marked = new List<Target>();

		private Harmony harmony;

		internal static ConfigWatcher Watcher;

		private void Awake()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			CreatureConfig.Init(((BaseUnityPlugin)this).Config);
			Watcher = new ConfigWatcher(CreatureConfig.FilePath, CreatureConfig.Reload, ((BaseUnityPlugin)this).Logger, "Creature Marker");
			harmony = new Harmony("kriona.CreatureMarker");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Creature Marker 1.7.0 loaded");
		}

		private void Update()
		{
			Watcher.Update();
		}

		private void LateUpdate()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				CreatureConfig.GetMarked(localPlayer, marked);
				markers.Update(marked, localPlayer);
				mapMarkers.Update(marked, localPlayer);
			}
		}

		private void OnDestroy()
		{
			markers.Destroy();
			mapMarkers.Destroy();
			Watcher?.Dispose();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	public static class ZNetSceneAwakePatch
	{
		private static void Postfix(ZNetScene __instance)
		{
			CreatureConfig.Load(__instance);
			Plugin.Watcher?.Remember();
		}
	}
	public struct Target
	{
		public Object source;

		public Vector3 position;

		public Vector3 top;

		public string nameToken;

		public int level;

		public bool fish;

		public Color color;
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateTarget")]
	public static class MonsterTargetPatch
	{
		public static readonly KeyValuePair<int, int> TargetHash = ZDO.GetHashZDOID("kriona.CreatureMarker.target");

		private static void Postfix(MonsterAI __instance)
		{
			//IL_0029: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (((BaseAI)__instance).m_nview.IsValid())
			{
				ZDOID val = (((Object)(object)__instance.m_targetCreature != (Object)null) ? __instance.m_targetCreature.GetZDOID() : ZDOID.None);
				((BaseAI)__instance).m_nview.GetZDO().Set(TargetHash, val);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace Kriona.Shared
{
	internal class ConfigMirror
	{
		private readonly ConfigFile config;

		private readonly Action changed;

		private bool syncing;

		public ConfigMirror(ConfigFile config, Action changed)
		{
			this.config = config;
			this.changed = changed;
			config.SaveOnConfigSet = false;
			config.SettingChanged += OnSettingChanged;
		}

		public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues, int? order, string displayName)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes();
			configurationManagerAttributes.Order = order;
			configurationManagerAttributes.DispName = displayName;
			return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, new object[1] { configurationManagerAttributes }));
		}

		public void Remove(ConfigEntryBase entry)
		{
			config.Remove(entry.Definition);
		}

		public void Sync(Action apply)
		{
			syncing = true;
			try
			{
				apply();
			}
			finally
			{
				syncing = false;
			}
		}

		public static void SetDisplayName(ConfigEntryBase entry, string displayName)
		{
			object[] tags = entry.Description.Tags;
			for (int i = 0; i < tags.Length; i++)
			{
				if (tags[i] is ConfigurationManagerAttributes configurationManagerAttributes)
				{
					configurationManagerAttributes.DispName = displayName;
				}
			}
		}

		private void OnSettingChanged(object sender, SettingChangedEventArgs args)
		{
			if (!syncing)
			{
				changed();
			}
		}
	}
	internal sealed class ConfigurationManagerAttributes
	{
		public int? Order;

		public string DispName;
	}
	internal class ConfigWatcher : IDisposable
	{
		private const float ReloadDelay = 0.5f;

		private readonly string path;

		private readonly Action reload;

		private readonly ManualLogSource log;

		private readonly string pluginName;

		private readonly FileSystemWatcher watcher;

		private string knownContents;

		private volatile bool fileChanged;

		private float reloadTime = -1f;

		public ConfigWatcher(string path, Action reload, ManualLogSource log, string pluginName)
		{
			this.path = path;
			this.reload = reload;
			this.log = log;
			this.pluginName = pluginName;
			Remember();
			try
			{
				watcher = new FileSystemWatcher(Path.GetDirectoryName(path), Path.GetFileName(path));
				watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
				watcher.Changed += delegate
				{
					fileChanged = true;
				};
				watcher.Created += delegate
				{
					fileChanged = true;
				};
				watcher.Renamed += delegate
				{
					fileChanged = true;
				};
				watcher.EnableRaisingEvents = true;
			}
			catch (Exception ex)
			{
				watcher = null;
				log.LogWarning((object)("Couldn't watch " + path + " for changes, so changes made to it while Valheim is running aren't read: " + ex.Message));
			}
		}

		public ConfigWatcher(ConfigFile config, ManualLogSource log, string pluginName)
			: this(config.ConfigFilePath, delegate
			{
				ReloadConfig(config);
			}, log, pluginName)
		{
		}

		private static void ReloadConfig(ConfigFile config)
		{
			bool saveOnConfigSet = config.SaveOnConfigSet;
			config.SaveOnConfigSet = false;
			try
			{
				config.Reload();
			}
			finally
			{
				config.SaveOnConfigSet = saveOnConfigSet;
			}
			if (saveOnConfigSet && !MatchesFile(config))
			{
				config.Save();
			}
		}

		private static bool MatchesFile(ConfigFile config)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			Dictionary<ConfigDefinition, string> dictionary = new Dictionary<ConfigDefinition, string>();
			string text = string.Empty;
			string[] array = File.ReadAllLines(config.ConfigFilePath);
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.StartsWith("#"))
				{
					continue;
				}
				if (text2.StartsWith("[") && text2.EndsWith("]"))
				{
					text = text2.Substring(1, text2.Length - 2);
					continue;
				}
				string[] array2 = text2.Split(new char[1] { '=' }, 2);
				if (array2.Length == 2)
				{
					dictionary[new ConfigDefinition(text, array2[0].Trim())] = array2[1].Trim();
				}
			}
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in config)
			{
				if (!dictionary.TryGetValue(item.Key, out var value))
				{
					return false;
				}
				try
				{
					if (!object.Equals(TomlTypeConverter.ConvertToValue(value, item.Value.SettingType), item.Value.BoxedValue))
					{
						return false;
					}
				}
				catch (Exception)
				{
					return false;
				}
			}
			return true;
		}

		public void Update()
		{
			if (fileChanged)
			{
				fileChanged = false;
				reloadTime = Time.realtimeSinceStartup + 0.5f;
			}
			if (reloadTime < 0f || Time.realtimeSinceStartup < reloadTime)
			{
				return;
			}
			reloadTime = -1f;
			string text;
			try
			{
				text = File.ReadAllText(path);
			}
			catch (FileNotFoundException)
			{
				return;
			}
			catch (IOException)
			{
				reloadTime = Time.realtimeSinceStartup + 0.5f;
				return;
			}
			if (text == knownContents)
			{
				return;
			}
			reload();
			Remember();
			if (pluginName != null)
			{
				log.LogInfo((object)("Reloaded " + Path.GetFileName(path)));
				MessageHud instance = MessageHud.instance;
				if (instance != null)
				{
					instance.ShowMessage((MessageType)1, pluginName + ": config reloaded", 0, (Sprite)null, false, true);
				}
			}
		}

		public void Remember()
		{
			try
			{
				knownContents = File.ReadAllText(path);
			}
			catch (IOException)
			{
				knownContents = null;
			}
		}

		public void Dispose()
		{
			watcher?.Dispose();
		}
	}
	internal class StateEntries
	{
		public const string Inherit = "inherit";

		private static readonly AcceptableValueList<string> values = new AcceptableValueList<string>(new string[3] { "inherit", "true", "false" });

		private readonly ConfigMirror mirror;

		private readonly string help;

		private readonly Dictionary<string, ConfigEntry<string>> entries = new Dictionary<string, ConfigEntry<string>>(StringComparer.OrdinalIgnoreCase);

		private readonly HashSet<string> set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		public StateEntries(ConfigMirror mirror, string help)
		{
			this.mirror = mirror;
			this.help = help;
		}

		public void Set(string section, string key, string displayName, bool? state)
		{
			string entryName = GetEntryName(key, displayName);
			if (entries.TryGetValue(key, out var value) && ((ConfigEntryBase)value).Definition.Section != section)
			{
				mirror.Remove((ConfigEntryBase)(object)value);
				entries.Remove(key);
				value = null;
			}
			if (value == null)
			{
				try
				{
					value = mirror.Bind(section, key, "inherit", "Prefab " + key + " - " + help, (AcceptableValueBase)(object)values, null, entryName);
				}
				catch (ArgumentException)
				{
					return;
				}
				entries[key] = value;
			}
			else
			{
				ConfigMirror.SetDisplayName((ConfigEntryBase)(object)value, entryName);
			}
			value.Value = Format(state);
			set.Add(key);
		}

		public void RemoveUnset()
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, ConfigEntry<string>> entry in entries)
			{
				if (!set.Contains(entry.Key))
				{
					mirror.Remove((ConfigEntryBase)(object)entry.Value);
					list.Add(entry.Key);
				}
			}
			foreach (string item in list)
			{
				entries.Remove(item);
			}
			set.Clear();
		}

		public bool TryGetState(string key, out bool? state)
		{
			state = null;
			if (!entries.TryGetValue(key, out var value))
			{
				return false;
			}
			if (bool.TryParse(value.Value, out var result))
			{
				state = result;
			}
			return true;
		}

		public static string Format(bool? state)
		{
			if (!state.HasValue)
			{
				return "inherit";
			}
			if (!state.Value)
			{
				return "false";
			}
			return "true";
		}

		private static string GetEntryName(string key, string displayName)
		{
			string text = displayName.Trim();
			if (text.Length == 0 || text.Equals(key, StringComparison.OrdinalIgnoreCase))
			{
				return key;
			}
			return text + " (" + key + ")";
		}
	}
}