Decompiled source of MaterialTracker v1.0.0

MaterialTracker.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Koendertjh.Shared;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("MaterialTracker")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a45c570d17c512d77d75166ff42bc1dee72ef243")]
[assembly: AssemblyProduct("MaterialTracker")]
[assembly: AssemblyTitle("MaterialTracker")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Koendertjh.Shared
{
	internal enum Boss
	{
		None,
		Eikthyr,
		Elder,
		Bonemass,
		Moder,
		Yagluth,
		Queen,
		Fader,
		Kall
	}
	internal static class BossProgress
	{
		private static readonly string[] EnemyNames = new string[9] { null, "$enemy_eikthyr", "$enemy_gdking", "$enemy_bonemass", "$enemy_dragon", "$enemy_goblinking", "$enemy_seekerqueen", "$enemy_fader", "$enemy_frozenking_p3" };

		private static Dictionary<string, string> s_defeatKeys;

		private static ZNetScene s_keysScene;

		internal static string EnemyName(Boss boss)
		{
			return EnemyNames[(int)boss];
		}

		internal static bool IsDefeated(Boss boss)
		{
			if (boss == Boss.None)
			{
				return true;
			}
			string enemyName = EnemyName(boss);
			if (HasKilled(enemyName))
			{
				return true;
			}
			string text = DefeatKey(enemyName);
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			if (!((Object)(object)ZoneSystem.instance != (Object)null) || !ZoneSystem.instance.GetGlobalKey(text))
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					return ((Humanoid)Player.m_localPlayer).HaveUniqueKey(text);
				}
				return false;
			}
			return true;
		}

		internal static bool HasKilled(string enemyName)
		{
			Game instance = Game.instance;
			PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null);
			if (val == null)
			{
				return false;
			}
			PlayerStats[] playerStats = val.m_playerStats;
			foreach (PlayerStats val2 in playerStats)
			{
				if (val2?.m_enemyStats == null)
				{
					continue;
				}
				Dictionary<string, float>[] enemyStats = val2.m_enemyStats;
				foreach (Dictionary<string, float> dictionary in enemyStats)
				{
					if (dictionary != null && dictionary.TryGetValue(enemyName, out var value) && value > 0f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static string DefeatKey(string enemyName)
		{
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return null;
			}
			if (s_defeatKeys == null || (Object)(object)s_keysScene != (Object)(object)ZNetScene.instance)
			{
				s_defeatKeys = new Dictionary<string, string>();
				s_keysScene = ZNetScene.instance;
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					Character val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Character>() : null);
					if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.m_defeatSetGlobalKey))
					{
						s_defeatKeys[val.m_name] = val.m_defeatSetGlobalKey;
					}
				}
			}
			s_defeatKeys.TryGetValue(enemyName, out var value);
			return value;
		}
	}
	internal enum Stage
	{
		Meadows,
		BlackForest,
		Swamp,
		Mountain,
		Plains,
		Mistlands,
		Ashlands,
		DeepNorth
	}
	internal static class Stages
	{
		internal static Boss RevealedBy(Stage stage)
		{
			return (Boss)stage;
		}

		internal static bool IsRevealed(Stage stage)
		{
			return BossProgress.IsDefeated(RevealedBy(stage));
		}

		internal static Stage FromBiome(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_0005: 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_001d: Expected I4, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				case 0:
					return Stage.Meadows;
				case 1:
					goto IL_0043;
				case 3:
					return Stage.Mountain;
				case 2:
					goto IL_004d;
				}
				if ((int)biome == 8)
				{
					return Stage.BlackForest;
				}
				if ((int)biome == 16)
				{
					return Stage.Plains;
				}
			}
			else
			{
				if ((int)biome == 32)
				{
					return Stage.Ashlands;
				}
				if ((int)biome == 256)
				{
					goto IL_0043;
				}
				if ((int)biome == 512)
				{
					return Stage.Mistlands;
				}
			}
			goto IL_004d;
			IL_0043:
			return Stage.Swamp;
			IL_004d:
			return Stage.DeepNorth;
		}

		internal static Stage Earliest(Biome biomes)
		{
			//IL_001f: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			Stage stage = Stage.DeepNorth;
			foreach (Biome value in Enum.GetValues(typeof(Biome)))
			{
				if ((int)value != 0 && (int)value != 895 && (Biome)(biomes & value) == value)
				{
					Stage stage2 = FromBiome(value);
					if (stage2 < stage)
					{
						stage = stage2;
					}
				}
			}
			return stage;
		}

		internal static string BiomeName(Stage stage)
		{
			return stage switch
			{
				Stage.Meadows => "the Meadows", 
				Stage.BlackForest => "the Black Forest", 
				Stage.Swamp => "the Swamp", 
				Stage.Mountain => "the Mountains", 
				Stage.Plains => "the Plains", 
				Stage.Mistlands => "the Mistlands", 
				Stage.Ashlands => "the Ashlands", 
				_ => "the Deep North", 
			};
		}
	}
	internal enum EntryState
	{
		Done,
		Missing,
		Hidden
	}
	internal class WindowEntry
	{
		public Sprite Icon;

		public string Name;

		public string Description;

		public EntryState State;
	}
	internal sealed class InventoryWindow
	{
		private sealed class Slot
		{
			public GameObject Root;

			public Image Icon;

			public TMP_Text Name;

			public TMP_Text Description;

			public Color NameColor;

			public Color DescriptionColor;

			public GameObject QuestionMark;
		}

		private const string PanelSuffix = "_InventoryWindow";

		private const string HiddenText = "<i>Only Odin knows what is hidden here.</i>";

		private static readonly Color GreyIcon = new Color(0.25f, 0.25f, 0.25f, 0.85f);

		private static readonly Color GreyText = new Color(0.55f, 0.55f, 0.55f, 1f);

		private readonly string _id;

		private readonly string _title;

		private readonly string _tooltip;

		private readonly Func<Sprite> _buttonIcon;

		private readonly Func<List<WindowEntry>, string> _fill;

		private GameObject _panel;

		private RectTransform _listRoot;

		private Scrollbar _scrollbar;

		private TMP_Text _titleText;

		private float _baseHeight;

		private readonly List<Slot> _slots = new List<Slot>();

		private static int s_columns;

		private static ObjectDB s_columnsDb;

		public bool IsOpen
		{
			get
			{
				if ((Object)(object)_panel != (Object)null)
				{
					return _panel.activeSelf;
				}
				return false;
			}
		}

		public InventoryWindow(string id, string title, string tooltip, Func<Sprite> buttonIcon, Func<List<WindowEntry>, string> fill)
		{
			_id = id;
			_title = title;
			_tooltip = tooltip;
			_buttonIcon = buttonIcon;
			_fill = fill;
		}

		public bool Create(InventoryGui gui, ManualLogSource log)
		{
			try
			{
				CreatePanel(gui);
				CreateButton(gui, log);
				return true;
			}
			catch (Exception arg)
			{
				log.LogWarning((object)$"Couldn't add the {_title} window: {arg}");
				if ((Object)(object)_panel != (Object)null)
				{
					Object.Destroy((Object)(object)_panel);
				}
				_panel = null;
				return false;
			}
		}

		private void CreatePanel(InventoryGui gui)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00bf: 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_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Expected O, but got Unknown
			GameObject trophiesPanel = gui.m_trophiesPanel;
			string text = PathFrom(trophiesPanel.transform, (Transform)(object)gui.m_trophieListRoot);
			string text2 = PathFrom(trophiesPanel.transform, ((Component)gui.m_trophyListScroll).transform);
			_slots.Clear();
			_panel = Object.Instantiate<GameObject>(trophiesPanel, trophiesPanel.transform.parent);
			((Object)_panel).name = _id + "_InventoryWindow";
			_panel.SetActive(false);
			_listRoot = (RectTransform)_panel.transform.Find(text);
			Transform obj = _panel.transform.Find(text2);
			_scrollbar = ((obj != null) ? ((Component)obj).GetComponent<Scrollbar>() : null);
			Rect rect = gui.m_trophieListRoot.rect;
			_baseHeight = ((Rect)(ref rect)).height;
			for (int num = ((Transform)_listRoot).childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)((Transform)_listRoot).GetChild(num)).gameObject);
			}
			UIGroupHandler[] componentsInChildren = _panel.GetComponentsInChildren<UIGroupHandler>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			string text3 = Localization.instance.Localize("$inventory_trophies");
			TMP_Text[] componentsInChildren2 = _panel.GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren2)
			{
				if (val.transform.IsChildOf((Transform)(object)_listRoot) || (val.text != text3 && val.text != "$inventory_trophies"))
				{
					continue;
				}
				Component[] components = ((Component)val).GetComponents<Component>();
				foreach (Component val2 in components)
				{
					if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Name == "Localize")
					{
						Object.Destroy((Object)(object)val2);
					}
				}
				val.text = _title;
				_titleText = val;
			}
			Button[] componentsInChildren3 = _panel.GetComponentsInChildren<Button>(true);
			foreach (Button val3 in componentsInChildren3)
			{
				if (Rewire((UnityEventBase)(object)val3.onClick, "OnCloseTrophies"))
				{
					((UnityEvent)val3.onClick).AddListener(new UnityAction(Close));
				}
			}
		}

		private void CreateButton(InventoryGui gui, ManualLogSource log)
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0137: 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_014c: Expected O, but got Unknown
			//IL_014c: Expected O, but got Unknown
			//IL_016c: 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)
			Button val = null;
			Button[] componentsInChildren = ((Component)gui).GetComponentsInChildren<Button>(true);
			foreach (Button val2 in componentsInChildren)
			{
				if (HasPersistent((UnityEventBase)(object)val2.onClick, "OnOpenTrophies") && !((Object)val2).name.EndsWith("_Button") && !((Component)val2).transform.IsChildOf(_panel.transform))
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				log.LogWarning((object)("Couldn't find the Trophies button; the " + _title + " window has no button."));
				return;
			}
			GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent);
			((Object)val3).name = _id + "_Button";
			Button component = val3.GetComponent<Button>();
			Rewire((UnityEventBase)(object)component.onClick, "OnOpenTrophies");
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				Open(gui);
			});
			val3.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex() + 1);
			if ((Object)(object)((Component)val3.transform.parent).GetComponent<LayoutGroup>() == (Object)null)
			{
				SpreadRow((RectTransform)((Component)val).transform, (RectTransform)val3.transform);
			}
			UITooltip component2 = val3.GetComponent<UITooltip>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.Set(_title, _tooltip, (RectTransform)null, default(Vector2));
			}
			Transform obj = val3.transform.Find("Image");
			Image val4 = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			Sprite val5 = _buttonIcon?.Invoke();
			if ((Object)(object)val4 != (Object)null && (Object)(object)val5 != (Object)null)
			{
				val4.sprite = val5;
				val4.preserveAspect = true;
			}
		}

		private static void SpreadRow(RectTransform trophies, RectTransform added)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_003c: 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_0060: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			List<RectTransform> list = new List<RectTransform>();
			foreach (Transform item in ((Transform)trophies).parent)
			{
				Transform val = item;
				RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
				if (val2 != null && (Object)(object)val != (Object)(object)added && Mathf.Abs(val2.anchoredPosition.y - trophies.anchoredPosition.y) < 1f)
				{
					Vector2 val3 = val2.sizeDelta - trophies.sizeDelta;
					if (((Vector2)(ref val3)).sqrMagnitude < 1f)
					{
						list.Add(val2);
					}
				}
			}
			list.Sort((RectTransform a, RectTransform b) => a.anchoredPosition.x.CompareTo(b.anchoredPosition.x));
			list.Insert(list.IndexOf(trophies) + 1, added);
			if (list.Count < 3)
			{
				return;
			}
			float x = list[0].anchoredPosition.x;
			float x2 = list[list.Count - 1].anchoredPosition.x;
			float num = Mathf.Max(x2 - x, 0f) / (float)(list.Count - 2);
			Rect rect = ((RectTransform)((Transform)trophies).parent).rect;
			float width = ((Rect)(ref rect)).width;
			if (width > 0f)
			{
				num = Mathf.Min(num, (width - trophies.sizeDelta.x - 8f) / (float)(list.Count - 1));
			}
			float num2 = (x + x2) / 2f - num * (float)(list.Count - 1) / 2f;
			foreach (RectTransform item2 in list)
			{
				item2.anchoredPosition = new Vector2(num2, trophies.anchoredPosition.y);
				num2 += num;
			}
		}

		private static string PathFrom(Transform root, Transform target)
		{
			List<string> list = new List<string>();
			Transform val = target;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				list.Insert(0, ((Object)val).name);
				val = val.parent;
			}
			return string.Join("/", list);
		}

		private static bool HasPersistent(UnityEventBase onClick, string method)
		{
			for (int i = 0; i < onClick.GetPersistentEventCount(); i++)
			{
				if (onClick.GetPersistentMethodName(i) == method)
				{
					return true;
				}
			}
			return false;
		}

		private static bool Rewire(UnityEventBase onClick, string method)
		{
			bool result = false;
			for (int i = 0; i < onClick.GetPersistentEventCount(); i++)
			{
				if (!(onClick.GetPersistentMethodName(i) != method))
				{
					onClick.SetPersistentListenerState(i, (UnityEventCallState)0);
					result = true;
				}
			}
			return result;
		}

		private void Open(InventoryGui gui)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			if ((Object)(object)_panel == (Object)null)
			{
				return;
			}
			gui.m_trophiesPanel.SetActive(false);
			((Component)gui.m_achievementsPanel).gameObject.SetActive(false);
			foreach (Transform item in _panel.transform.parent)
			{
				Transform val = item;
				if ((Object)(object)((Component)val).gameObject != (Object)(object)_panel && ((Object)val).name.EndsWith("_InventoryWindow"))
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
			_panel.SetActive(true);
			Fill(gui);
		}

		public void Close()
		{
			if ((Object)(object)_panel != (Object)null)
			{
				_panel.SetActive(false);
			}
		}

		public bool HandleEscape()
		{
			if (!IsOpen || (!ZInput.GetButtonDown("JoyButtonB") && !ZInput.GetKeyDown((KeyCode)27, true)))
			{
				return false;
			}
			Close();
			return true;
		}

		private void Fill(InventoryGui gui)
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)_listRoot == (Object)null)
			{
				return;
			}
			List<WindowEntry> list = new List<WindowEntry>();
			string text = _fill(list);
			float trophieListSpace = gui.m_trophieListSpace;
			int num = Columns();
			while (_slots.Count < list.Count)
			{
				_slots.Add(NewSlot(gui));
			}
			for (int i = 0; i < _slots.Count; i++)
			{
				Slot slot = _slots[i];
				if (i >= list.Count)
				{
					if (slot.Root.activeSelf)
					{
						slot.Root.SetActive(false);
					}
					continue;
				}
				WindowEntry windowEntry = list[i];
				slot.Root.SetActive(true);
				((RectTransform)slot.Root.transform).anchoredPosition = new Vector2((float)(i % num) * trophieListSpace, (float)(i / num) * (0f - trophieListSpace));
				switch (windowEntry.State)
				{
				case EntryState.Done:
					SetIcon(slot, windowEntry.Icon, Color.white);
					SetText(slot.Name, windowEntry.Name, slot.NameColor);
					SetText(slot.Description, windowEntry.Description, slot.DescriptionColor);
					break;
				case EntryState.Missing:
					SetIcon(slot, windowEntry.Icon, GreyIcon);
					SetText(slot.Name, windowEntry.Name, GreyText);
					SetText(slot.Description, windowEntry.Description, GreyText);
					break;
				default:
					SetIcon(slot, null, GreyIcon);
					SetText(slot.Name, "??????", GreyText);
					SetText(slot.Description, "<i>Only Odin knows what is hidden here.</i>", GreyText);
					break;
				}
			}
			if ((Object)(object)_titleText != (Object)null)
			{
				_titleText.text = text ?? _title;
			}
			int num2 = (list.Count + num - 1) / num;
			_listRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(_baseHeight, (float)num2 * trophieListSpace));
			if ((Object)(object)_scrollbar != (Object)null)
			{
				_scrollbar.value = 1f;
			}
		}

		private Slot NewSlot(InventoryGui gui)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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)
			GameObject val = Object.Instantiate<GameObject>(gui.m_trophieElementPrefab, (Transform)(object)_listRoot);
			Transform transform = val.transform;
			Slot obj = new Slot
			{
				Root = val
			};
			Transform obj2 = transform.Find("icon_bkg/icon");
			obj.Icon = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
			Transform obj3 = transform.Find("name");
			obj.Name = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null);
			Transform obj4 = transform.Find("description");
			obj.Description = ((obj4 != null) ? ((Component)obj4).GetComponent<TMP_Text>() : null);
			Slot slot = obj;
			slot.NameColor = (((Object)(object)slot.Name != (Object)null) ? ((Graphic)slot.Name).color : Color.white);
			slot.DescriptionColor = (((Object)(object)slot.Description != (Object)null) ? ((Graphic)slot.Description).color : Color.white);
			return slot;
		}

		private static void SetText(TMP_Text text, string value, Color color)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)text == (Object)null))
			{
				text.text = value;
				((Graphic)text).color = color;
			}
		}

		private static void SetIcon(Slot slot, Sprite sprite, Color color)
		{
			//IL_0029: 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_0095: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			Image icon = slot.Icon;
			if ((Object)(object)icon == (Object)null)
			{
				return;
			}
			if ((Object)(object)sprite != (Object)null)
			{
				((Behaviour)icon).enabled = true;
				icon.sprite = sprite;
				((Graphic)icon).color = color;
				if ((Object)(object)slot.QuestionMark != (Object)null)
				{
					slot.QuestionMark.SetActive(false);
				}
				return;
			}
			((Behaviour)icon).enabled = false;
			if ((Object)(object)slot.QuestionMark == (Object)null && (Object)(object)slot.Name != (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(((Component)slot.Name).gameObject, ((Component)icon).transform);
				RectTransform val2 = (RectTransform)val.transform;
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.pivot = new Vector2(0.5f, 0.5f);
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
				((Transform)val2).localScale = Vector3.one;
				TMP_Text component = val.GetComponent<TMP_Text>();
				Rect rect = ((RectTransform)((Component)icon).transform).rect;
				float height = ((Rect)(ref rect)).height;
				component.enableAutoSizing = false;
				component.fontSize = ((height > 0f) ? (height * 0.8f) : 48f);
				component.alignment = (TextAlignmentOptions)514;
				((Graphic)component).color = GreyText;
				component.text = "?";
				slot.QuestionMark = val;
			}
			if ((Object)(object)slot.QuestionMark != (Object)null)
			{
				slot.QuestionMark.SetActive(true);
			}
		}

		private static int Columns()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Invalid comparison between Unknown and I4
			if ((Object)(object)s_columnsDb == (Object)(object)ObjectDB.instance && s_columns > 0)
			{
				return s_columns;
			}
			int num = 1;
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val != (Object)null && (int)val.m_itemData.m_shared.m_itemType == 13)
				{
					num = Mathf.Max(num, ((Vector2Int)(ref val.m_itemData.m_shared.m_trophyPos)).x + 1);
				}
			}
			s_columnsDb = ObjectDB.instance;
			s_columns = num;
			return num;
		}
	}
	internal static class ShapeIcon
	{
		private const int Size = 128;

		private const int MaxDistance = 16;

		internal static Sprite Create(string name, Func<float, float, bool> inside)
		{
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			//IL_016c: 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)
			float[] array = new float[16384];
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					int num = 0;
					for (int k = 0; k < 4; k++)
					{
						for (int l = 0; l < 4; l++)
						{
							if (inside((float)j + ((float)l + 0.5f) / 4f, (float)i + ((float)k + 0.5f) / 4f))
							{
								num++;
							}
						}
					}
					array[i * 128 + j] = (float)num / 16f;
				}
			}
			float[] array2 = new float[16384];
			for (int m = 0; m < 128; m++)
			{
				for (int n = 0; n < 128; n++)
				{
					array2[m * 128 + n] = ((array[m * 128 + n] > 0f) ? DistanceToEdge(array, n, m) : 0f);
				}
			}
			Color32[] array3 = (Color32[])(object)new Color32[16384];
			for (int num2 = 0; num2 < 128; num2++)
			{
				for (int num3 = 0; num3 < 128; num3++)
				{
					float num4 = array[num2 * 128 + num3];
					byte b = (byte)(Mathf.Clamp01((num4 > 0f) ? Shade(array2, num3, num2) : 1f) * 255f);
					array3[num2 * 128 + num3] = new Color32(b, b, b, (byte)(num4 * 255f));
				}
			}
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			val.SetPixels32(array3);
			val.Apply();
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f);
			((Object)obj).name = name;
			return obj;
		}

		private static float Shade(float[] distance, int x, int y)
		{
			float num = Mathf.PerlinNoise((float)x * 0.07f + 3.1f, (float)y * 0.07f + 7.7f) * 0.6f + Mathf.PerlinNoise((float)x * 0.19f + 11.3f, (float)y * 0.19f + 1.9f) * 0.4f;
			float num2 = Mathf.Lerp(0.78f, 1f, num) * Mathf.Lerp(1f, 0.86f, (float)x / 128f);
			float num3 = distance[y * 128 + x];
			if (num3 < 2.5f)
			{
				num2 *= Mathf.Lerp(0.55f, 1f, num3 / 2.5f);
			}
			else if (num3 >= 6f && num3 < 8f && DeepNearby(distance, x, y))
			{
				num2 *= 0.62f;
			}
			return num2;
		}

		private static bool DeepNearby(float[] distance, int x, int y)
		{
			for (int i = -5; i <= 5; i++)
			{
				for (int j = -5; j <= 5; j++)
				{
					int num = x + j;
					int num2 = y + i;
					if (num >= 0 && num2 >= 0 && num < 128 && num2 < 128 && distance[num2 * 128 + num] >= 13f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static float DistanceToEdge(float[] coverage, int x, int y)
		{
			int num = 256;
			for (int i = -16; i <= 16; i++)
			{
				int num2 = y + i;
				for (int j = -16; j <= 16; j++)
				{
					int num3 = j * j + i * i;
					if (num3 < num)
					{
						int num4 = x + j;
						if (num4 < 0 || num2 < 0 || num4 >= 128 || num2 >= 128 || coverage[num2 * 128 + num4] < 0.5f)
						{
							num = num3;
						}
					}
				}
			}
			return Mathf.Sqrt((float)num);
		}

		internal static bool Trapezoid(float x, float y, float bottom, float top, float bottomLeft, float bottomRight, float topLeft, float topRight)
		{
			if (y < bottom || y > top)
			{
				return false;
			}
			float num = (y - bottom) / (top - bottom);
			if (x >= Mathf.Lerp(bottomLeft, topLeft, num))
			{
				return x <= Mathf.Lerp(bottomRight, topRight, num);
			}
			return false;
		}

		internal static bool Ellipse(float x, float y, float cx, float cy, float rx, float ry)
		{
			float num = (x - cx) / rx;
			float num2 = (y - cy) / ry;
			return num * num + num2 * num2 <= 1f;
		}
	}
}
namespace MaterialTracker
{
	internal static class BarIcon
	{
		private static Sprite s_sprite;

		internal static Sprite Get()
		{
			if (!((Object)(object)s_sprite != (Object)null))
			{
				return s_sprite = ShapeIcon.Create("MaterialTracker_Bars", (float x, float y) => ShapeIcon.Trapezoid(x, y, 22f, 54f, 12f, 116f, 26f, 102f) || ShapeIcon.Trapezoid(x, y, 62f, 94f, 28f, 100f, 40f, 88f));
			}
			return s_sprite;
		}
	}
	internal class MaterialInfo
	{
		public string Name;

		public ItemDrop Item;

		public Stage Stage;

		public string Hint;
	}
	internal static class Materials
	{
		private static List<MaterialInfo> s_all;

		private static ObjectDB s_db;

		private static readonly Dictionary<string, List<string>> s_droppedBy = new Dictionary<string, List<string>>();

		private static readonly Dictionary<string, Recipe> s_recipes = new Dictionary<string, Recipe>();

		private static readonly Dictionary<string, KeyValuePair<string, ItemDrop>> s_converted = new Dictionary<string, KeyValuePair<string, ItemDrop>>();

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

		private static readonly Dictionary<string, Stage> s_creatureStage = new Dictionary<string, Stage>();

		private static readonly Dictionary<string, Stage> s_stages = new Dictionary<string, Stage>();

		internal static List<MaterialInfo> All
		{
			get
			{
				if (s_all == null || (Object)(object)s_db != (Object)(object)ObjectDB.instance)
				{
					Build();
				}
				return s_all;
			}
		}

		private static void Build()
		{
			s_all = new List<MaterialInfo>();
			s_db = ObjectDB.instance;
			if ((Object)(object)s_db == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			ReadSources();
			Dictionary<string, ItemDrop> dictionary = new Dictionary<string, ItemDrop>();
			foreach (Recipe recipe in s_db.m_recipes)
			{
				if ((Object)(object)recipe != (Object)null && recipe.m_enabled && (Object)(object)recipe.m_item != (Object)null)
				{
					AddRequirements(dictionary, recipe.m_resources);
				}
			}
			foreach (GameObject item in s_db.m_items)
			{
				PieceTable val = ((!((Object)(object)item != (Object)null)) ? null : item.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				foreach (GameObject piece in val.m_pieces)
				{
					Piece val2 = (((Object)(object)piece != (Object)null) ? piece.GetComponent<Piece>() : null);
					if ((Object)(object)val2 != (Object)null && val2.m_enabled)
					{
						AddRequirements(dictionary, val2.m_resources);
					}
				}
			}
			foreach (KeyValuePair<string, ItemDrop> item2 in dictionary)
			{
				s_all.Add(new MaterialInfo
				{
					Name = item2.Key,
					Item = item2.Value,
					Stage = StageOf(item2.Value, new HashSet<string>()),
					Hint = HintFor(item2.Key)
				});
			}
			s_all = (from m in s_all
				orderby m.Stage, Localization.instance.Localize(m.Name)
				select m).ToList();
		}

		private static void AddRequirements(Dictionary<string, ItemDrop> items, Requirement[] requirements)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			if (requirements == null)
			{
				return;
			}
			for (int i = 0; i < requirements.Length; i++)
			{
				ItemDrop val = requirements[i]?.m_resItem;
				if (!((Object)(object)val == (Object)null) && (int)val.m_itemData.m_shared.m_itemType != 13)
				{
					items[val.m_itemData.m_shared.m_name] = val;
				}
			}
		}

		private static string NameOf(GameObject prefab)
		{
			if (!((Object)(object)prefab != (Object)null))
			{
				return null;
			}
			return prefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_name;
		}

		private static void Found(GameObject prefab, string how)
		{
			string text = NameOf(prefab);
			if (text != null && !s_found.ContainsKey(text))
			{
				s_found[text] = how;
			}
		}

		private static void FoundAll(DropTable table, string how)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (table?.m_drops == null)
			{
				return;
			}
			foreach (DropData drop in table.m_drops)
			{
				Found(drop.m_item, how);
			}
		}

		private static void ReadSources()
		{
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			s_droppedBy.Clear();
			s_recipes.Clear();
			s_converted.Clear();
			s_found.Clear();
			s_creatureStage.Clear();
			s_stages.Clear();
			foreach (Recipe recipe in s_db.m_recipes)
			{
				string text = (((Object)(object)recipe?.m_item != (Object)null) ? recipe.m_item.m_itemData.m_shared.m_name : null);
				if (text != null && recipe.m_enabled && !s_recipes.ContainsKey(text))
				{
					s_recipes[text] = recipe;
				}
			}
			Dictionary<string, Stage> dictionary = new Dictionary<string, Stage>();
			SpawnSystemList[] array = Resources.FindObjectsOfTypeAll<SpawnSystemList>();
			for (int i = 0; i < array.Length; i++)
			{
				foreach (SpawnData spawner in array[i].m_spawners)
				{
					if (!((Object)(object)spawner?.m_prefab == (Object)null) && spawner.m_enabled)
					{
						Stage stage = Stages.Earliest(spawner.m_biome);
						if (!dictionary.TryGetValue(((Object)spawner.m_prefab).name, out var value) || stage < value)
						{
							dictionary[((Object)spawner.m_prefab).name] = stage;
						}
					}
				}
			}
			foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
			{
				if ((Object)(object)prefab == (Object)null)
				{
					continue;
				}
				Character component = prefab.GetComponent<Character>();
				CharacterDrop component2 = prefab.GetComponent<CharacterDrop>();
				if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
				{
					if (dictionary.TryGetValue(((Object)prefab).name, out var value2) && (!s_creatureStage.TryGetValue(component.m_name, out var value3) || value2 < value3))
					{
						s_creatureStage[component.m_name] = value2;
					}
					foreach (Drop drop in component2.m_drops)
					{
						string text2 = NameOf(drop.m_prefab);
						if (text2 != null)
						{
							if (!s_droppedBy.TryGetValue(text2, out var value4))
							{
								value4 = (s_droppedBy[text2] = new List<string>());
							}
							if (!value4.Contains(component.m_name))
							{
								value4.Add(component.m_name);
							}
						}
					}
				}
				Smelter component3 = prefab.GetComponent<Smelter>();
				if ((Object)(object)component3 != (Object)null)
				{
					AddConversions(component3.m_conversion?.Select((ItemConversion c) => (m_from: c.m_from, m_to: c.m_to)), component3.m_name);
				}
				Fermenter component4 = prefab.GetComponent<Fermenter>();
				if ((Object)(object)component4 != (Object)null)
				{
					AddConversions(component4.m_conversion?.Select((ItemConversion c) => (m_from: c.m_from, m_to: c.m_to)), component4.m_name);
				}
				CookingStation component5 = prefab.GetComponent<CookingStation>();
				if ((Object)(object)component5 != (Object)null)
				{
					AddConversions(component5.m_conversion?.Select((ItemConversion c) => (m_from: c.m_from, m_to: c.m_to)), component5.m_name);
				}
				FoundAll(prefab.GetComponent<MineRock>()?.m_dropItems, "Mined from rocks and deposits");
				FoundAll(prefab.GetComponent<MineRock5>()?.m_dropItems, "Mined from rocks and deposits");
				FoundAll(prefab.GetComponent<TreeBase>()?.m_dropWhenDestroyed, "Chopped from trees");
				FoundAll(prefab.GetComponent<TreeLog>()?.m_dropWhenDestroyed, "Chopped from trees");
				Pickable component6 = prefab.GetComponent<Pickable>();
				if ((Object)(object)component6 != (Object)null)
				{
					Found(component6.m_itemPrefab, "Picked up in the wild");
				}
				FoundAll(prefab.GetComponent<DropOnDestroyed>()?.m_dropWhenDestroyed, "Found by breaking things in the world");
				Trader component7 = prefab.GetComponent<Trader>();
				if (!((Object)(object)component7 != (Object)null))
				{
					continue;
				}
				foreach (TradeItem item in component7.m_items)
				{
					Found(((Object)(object)item.m_prefab != (Object)null) ? ((Component)item.m_prefab).gameObject : null, "Sold by " + Localization.instance.Localize(component7.m_name));
				}
			}
		}

		private static void AddConversions(IEnumerable<(ItemDrop from, ItemDrop to)> conversions, string station)
		{
			if (conversions == null)
			{
				return;
			}
			foreach (var (val, val2) in conversions)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
				{
					string name = val2.m_itemData.m_shared.m_name;
					if (!s_converted.ContainsKey(name))
					{
						s_converted[name] = new KeyValuePair<string, ItemDrop>(station ?? "", val);
					}
				}
			}
		}

		private static Stage StageOf(ItemDrop item, HashSet<string> visiting)
		{
			string name = item.m_itemData.m_shared.m_name;
			if (s_stages.TryGetValue(name, out var value))
			{
				return value;
			}
			if (StageTable.Raw.TryGetValue(name, out var value2))
			{
				return s_stages[name] = value2;
			}
			if (!visiting.Add(name))
			{
				return Stage.Meadows;
			}
			Stage? stage2 = null;
			if (s_droppedBy.TryGetValue(name, out var value3))
			{
				foreach (string item2 in value3)
				{
					if (s_creatureStage.TryGetValue(item2, out var value4) && (!stage2.HasValue || value4 < stage2))
					{
						stage2 = value4;
					}
				}
			}
			if (!stage2.HasValue && s_recipes.TryGetValue(name, out var value5))
			{
				Stage stage3 = Stage.Meadows;
				Requirement[] resources = value5.m_resources;
				foreach (Requirement val in resources)
				{
					if ((Object)(object)val?.m_resItem != (Object)null)
					{
						Stage stage4 = StageOf(val.m_resItem, visiting);
						if (stage4 > stage3)
						{
							stage3 = stage4;
						}
					}
				}
				stage2 = stage3;
			}
			if (!stage2.HasValue && s_converted.TryGetValue(name, out var value6))
			{
				stage2 = StageOf(value6.Value, visiting);
			}
			if (!stage2.HasValue)
			{
				MaterialTrackerPlugin.Log.LogDebug((object)("No stage known for " + name + "; using Plains."));
				stage2 = Stage.Plains;
			}
			return s_stages[name] = stage2.Value;
		}

		private static string HintFor(string name)
		{
			Localization loc = Localization.instance;
			if (s_droppedBy.TryGetValue(name, out var value))
			{
				string text = string.Join(", ", from c in value.Take(2)
					select loc.Localize(c));
				return "Dropped by " + text + ((value.Count > 2) ? " and others" : "");
			}
			if (s_converted.TryGetValue(name, out var value2))
			{
				return "Made in a " + loc.Localize(value2.Key).ToLowerInvariant() + " from " + loc.Localize(value2.Value.m_itemData.m_shared.m_name);
			}
			if (s_recipes.TryGetValue(name, out var value3))
			{
				if (!((Object)(object)value3.m_craftingStation != (Object)null))
				{
					return "Crafted by hand";
				}
				return "Crafted at the " + loc.Localize(value3.m_craftingStation.m_name).ToLowerInvariant();
			}
			if (s_found.TryGetValue(name, out var value4))
			{
				return value4;
			}
			return "Found somewhere in the world";
		}
	}
	[HarmonyPatch(typeof(InventoryGui))]
	internal static class MaterialsPanel
	{
		private const string Title = "Materials";

		private static readonly InventoryWindow Window = new InventoryWindow("MaterialTracker", "Materials", "Every crafting material, and where to find it", BarIcon.Get, Fill);

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void Create(InventoryGui __instance)
		{
			Window.Create(__instance, MaterialTrackerPlugin.Log);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Hide")]
		private static void AfterHide()
		{
			Window.Close();
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnOpenTrophies")]
		private static void AfterOpenTrophies()
		{
			Window.Close();
		}

		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		private static bool BeforeUpdate()
		{
			return !Window.HandleEscape();
		}

		private static string Fill(List<WindowEntry> entries)
		{
			Player localPlayer = Player.m_localPlayer;
			List<MaterialInfo> all = Materials.All;
			int num = 0;
			foreach (MaterialInfo item in all)
			{
				bool flag = localPlayer.IsMaterialKnown(item.Name);
				if (flag)
				{
					num++;
				}
				if (!flag || MaterialTrackerPlugin.ShowFound.Value)
				{
					string text = (MaterialTrackerPlugin.ShowHints.Value ? item.Hint : "");
					bool flag2 = flag || MaterialTrackerPlugin.ShowAll.Value || Stages.IsRevealed(item.Stage);
					entries.Add(new WindowEntry
					{
						Icon = item.Item.m_itemData.GetIcon(),
						Name = Localization.instance.Localize(item.Name),
						Description = (flag ? text : (((text.Length > 0) ? (text + "\n") : "") + "<i>Not found yet</i>")),
						State = ((!flag) ? (flag2 ? EntryState.Missing : EntryState.Hidden) : EntryState.Done)
					});
				}
			}
			return string.Format("{0} {1} / {2}", "Materials", num, all.Count);
		}
	}
	[BepInPlugin("com.koendertjh.materialtracker", "MaterialTracker", "1.0.0")]
	public class MaterialTrackerPlugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.koendertjh.materialtracker";

		public const string ModName = "MaterialTracker";

		public const string ModVersion = "1.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ShowAll;

		internal static ConfigEntry<bool> ShowFound;

		internal static ConfigEntry<bool> ShowHints;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ShowAll = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Spoilers", "ShowAll", false, "Show every missing material right away. Off = materials of a biome show once you defeated the boss before it; later ones show as '?'.");
			ShowFound = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Display", "ShowFound", true, "Also list the materials you have already found. Off = only the missing ones.");
			ShowHints = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Display", "ShowHints", true, "Show where each material comes from (dropped by, crafted at, mined...).");
			_harmony = new Harmony("com.koendertjh.materialtracker");
			_harmony.PatchAll(typeof(MaterialTrackerPlugin).Assembly);
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class StageTable
	{
		internal static readonly Dictionary<string, Stage> Raw = new Dictionary<string, Stage>
		{
			{
				"$item_wood",
				Stage.Meadows
			},
			{
				"$item_stone",
				Stage.Meadows
			},
			{
				"$item_flint",
				Stage.Meadows
			},
			{
				"$item_resin",
				Stage.Meadows
			},
			{
				"$item_feathers",
				Stage.Meadows
			},
			{
				"$item_leatherscraps",
				Stage.Meadows
			},
			{
				"$item_deerhide",
				Stage.Meadows
			},
			{
				"$item_dandelion",
				Stage.Meadows
			},
			{
				"$item_raspberries",
				Stage.Meadows
			},
			{
				"$item_mushroomcommon",
				Stage.Meadows
			},
			{
				"$item_honey",
				Stage.Meadows
			},
			{
				"$item_queenbee",
				Stage.Meadows
			},
			{
				"$item_hardantler",
				Stage.Meadows
			},
			{
				"$item_beechseeds",
				Stage.Meadows
			},
			{
				"$item_coins",
				Stage.Meadows
			},
			{
				"$item_fishingbait",
				Stage.Meadows
			},
			{
				"$item_fish_raw",
				Stage.Meadows
			},
			{
				"$item_necktail",
				Stage.Meadows
			},
			{
				"$item_finewood",
				Stage.BlackForest
			},
			{
				"$item_roundlog",
				Stage.BlackForest
			},
			{
				"$item_copperore",
				Stage.BlackForest
			},
			{
				"$item_tinore",
				Stage.BlackForest
			},
			{
				"$item_surtlingcore",
				Stage.BlackForest
			},
			{
				"$item_greydwarfeye",
				Stage.BlackForest
			},
			{
				"$item_ancientseed",
				Stage.BlackForest
			},
			{
				"$item_trollhide",
				Stage.BlackForest
			},
			{
				"$item_bonefragments",
				Stage.BlackForest
			},
			{
				"$item_blueberries",
				Stage.BlackForest
			},
			{
				"$item_carrotseeds",
				Stage.BlackForest
			},
			{
				"$item_thistle",
				Stage.BlackForest
			},
			{
				"$item_fircone",
				Stage.BlackForest
			},
			{
				"$item_pinecone",
				Stage.BlackForest
			},
			{
				"$item_birchseeds",
				Stage.BlackForest
			},
			{
				"$item_coal",
				Stage.BlackForest
			},
			{
				"$item_cryptkey",
				Stage.BlackForest
			},
			{
				"$item_mushroomyellow",
				Stage.BlackForest
			},
			{
				"$item_bjornhide",
				Stage.BlackForest
			},
			{
				"$item_bjornpaw",
				Stage.BlackForest
			},
			{
				"$item_fishingbait_forest",
				Stage.BlackForest
			},
			{
				"$item_ironscrap",
				Stage.Swamp
			},
			{
				"$item_guck",
				Stage.Swamp
			},
			{
				"$item_entrails",
				Stage.Swamp
			},
			{
				"$item_witheredbone",
				Stage.Swamp
			},
			{
				"$item_elderbark",
				Stage.Swamp
			},
			{
				"$item_bloodbag",
				Stage.Swamp
			},
			{
				"$item_ooze",
				Stage.Swamp
			},
			{
				"$item_turnipseeds",
				Stage.Swamp
			},
			{
				"$item_root",
				Stage.Swamp
			},
			{
				"$item_oakseeds",
				Stage.Swamp
			},
			{
				"$item_chain",
				Stage.Swamp
			},
			{
				"$item_serpentscale",
				Stage.Swamp
			},
			{
				"$item_serpentmeat",
				Stage.Swamp
			},
			{
				"$item_chitin",
				Stage.Swamp
			},
			{
				"$item_ymirremains",
				Stage.Swamp
			},
			{
				"$item_fishingbait_swamp",
				Stage.Swamp
			},
			{
				"$item_fishingbait_ocean",
				Stage.Swamp
			},
			{
				"$item_amber",
				Stage.Swamp
			},
			{
				"$item_amberpearl",
				Stage.Swamp
			},
			{
				"$item_ruby",
				Stage.Swamp
			},
			{
				"$item_silverore",
				Stage.Mountain
			},
			{
				"$item_obsidian",
				Stage.Mountain
			},
			{
				"$item_wolfpelt",
				Stage.Mountain
			},
			{
				"$item_wolffang",
				Stage.Mountain
			},
			{
				"$item_freezegland",
				Stage.Mountain
			},
			{
				"$item_crystal",
				Stage.Mountain
			},
			{
				"$item_dragonegg",
				Stage.Mountain
			},
			{
				"$item_dragontear",
				Stage.Mountain
			},
			{
				"$item_onionseeds",
				Stage.Mountain
			},
			{
				"$item_wolfclaw",
				Stage.Mountain
			},
			{
				"$item_wolfhairbundle",
				Stage.Mountain
			},
			{
				"$item_jutered",
				Stage.Mountain
			},
			{
				"$item_fishingbait_cave",
				Stage.Mountain
			},
			{
				"$item_barley",
				Stage.Plains
			},
			{
				"$item_flax",
				Stage.Plains
			},
			{
				"$item_needle",
				Stage.Plains
			},
			{
				"$item_loxpelt",
				Stage.Plains
			},
			{
				"$item_blackmetalscrap",
				Stage.Plains
			},
			{
				"$item_tar",
				Stage.Plains
			},
			{
				"$item_cloudberries",
				Stage.Plains
			},
			{
				"$item_goblintotem",
				Stage.Plains
			},
			{
				"$item_yagluththing",
				Stage.Plains
			},
			{
				"$item_fishingbait_plains",
				Stage.Plains
			},
			{
				"$item_blackmarble",
				Stage.Mistlands
			},
			{
				"$item_carapace",
				Stage.Mistlands
			},
			{
				"$item_mandible",
				Stage.Mistlands
			},
			{
				"$item_sap",
				Stage.Mistlands
			},
			{
				"$item_yggdrasilwood",
				Stage.Mistlands
			},
			{
				"$item_magecap",
				Stage.Mistlands
			},
			{
				"$item_jotunpuffs",
				Stage.Mistlands
			},
			{
				"$item_royaljelly",
				Stage.Mistlands
			},
			{
				"$item_softtissue",
				Stage.Mistlands
			},
			{
				"$item_bilebag",
				Stage.Mistlands
			},
			{
				"$item_scalehide",
				Stage.Mistlands
			},
			{
				"$item_dvergrkeyfragment",
				Stage.Mistlands
			},
			{
				"$item_mechanicalspring",
				Stage.Mistlands
			},
			{
				"$item_blackcore",
				Stage.Mistlands
			},
			{
				"$item_wisp",
				Stage.Mistlands
			},
			{
				"$item_copperscrap",
				Stage.Mistlands
			},
			{
				"$item_bronzescrap",
				Stage.Mistlands
			},
			{
				"$item_juteblue",
				Stage.Mistlands
			},
			{
				"$item_queen_drop",
				Stage.Mistlands
			},
			{
				"$item_seekerqueen_drop",
				Stage.Mistlands
			},
			{
				"$item_fishingbait_mistlands",
				Stage.Mistlands
			},
			{
				"$item_flametalore",
				Stage.Ashlands
			},
			{
				"$item_grausten",
				Stage.Ashlands
			},
			{
				"$item_charredbone",
				Stage.Ashlands
			},
			{
				"$item_morgenheart",
				Stage.Ashlands
			},
			{
				"$item_morgensinew",
				Stage.Ashlands
			},
			{
				"$item_celestialfeather",
				Stage.Ashlands
			},
			{
				"$item_bonemawtooth",
				Stage.Ashlands
			},
			{
				"$item_askhide",
				Stage.Ashlands
			},
			{
				"$item_askbladder",
				Stage.Ashlands
			},
			{
				"$item_charcoalresin",
				Stage.Ashlands
			},
			{
				"$item_blackwood",
				Stage.Ashlands
			},
			{
				"$item_sulfurstone",
				Stage.Ashlands
			},
			{
				"$item_voltureegg",
				Stage.Ashlands
			},
			{
				"$item_vineberry",
				Stage.Ashlands
			},
			{
				"$item_vineberryseeds",
				Stage.Ashlands
			},
			{
				"$item_proustitepowder",
				Stage.Ashlands
			},
			{
				"$item_gemstone_red",
				Stage.Ashlands
			},
			{
				"$item_gemstone_green",
				Stage.Ashlands
			},
			{
				"$item_gemstone_blue",
				Stage.Ashlands
			},
			{
				"$item_moltencore",
				Stage.Ashlands
			},
			{
				"$item_bellfragment",
				Stage.Ashlands
			},
			{
				"$item_fiddleheadfern",
				Stage.Ashlands
			},
			{
				"$item_smokepuff",
				Stage.Ashlands
			},
			{
				"$item_fader_drop",
				Stage.Ashlands
			},
			{
				"$item_charredskull",
				Stage.Ashlands
			},
			{
				"$item_charredcogwheel",
				Stage.Ashlands
			},
			{
				"$item_pot_shard_green",
				Stage.Ashlands
			},
			{
				"$item_fishingbait_ashlands",
				Stage.Ashlands
			},
			{
				"$item_frostwood",
				Stage.DeepNorth
			},
			{
				"$item_ice",
				Stage.DeepNorth
			},
			{
				"$item_frozenfuel",
				Stage.DeepNorth
			},
			{
				"$item_goldore",
				Stage.DeepNorth
			},
			{
				"$item_glowworm",
				Stage.DeepNorth
			},
			{
				"$item_fryslingcore",
				Stage.DeepNorth
			},
			{
				"$item_blubber",
				Stage.DeepNorth
			},
			{
				"$item_sealhide",
				Stage.DeepNorth
			},
			{
				"$item_elakinghairbundle",
				Stage.DeepNorth
			},
			{
				"$item_frostcore",
				Stage.DeepNorth
			},
			{
				"$item_moleclaws",
				Stage.DeepNorth
			},
			{
				"$item_moosehide",
				Stage.DeepNorth
			},
			{
				"$item_moosesinew",
				Stage.DeepNorth
			},
			{
				"$item_lingonberries",
				Stage.DeepNorth
			},
			{
				"$item_oatseeds",
				Stage.DeepNorth
			},
			{
				"$item_kaleseeds",
				Stage.DeepNorth
			},
			{
				"$item_poteitrseeds",
				Stage.DeepNorth
			},
			{
				"$item_ooze_mork",
				Stage.DeepNorth
			},
			{
				"$item_hatefulblood",
				Stage.DeepNorth
			},
			{
				"$item_frozenking_drop",
				Stage.DeepNorth
			},
			{
				"$item_fircone_big",
				Stage.DeepNorth
			},
			{
				"$item_barkabranch",
				Stage.DeepNorth
			},
			{
				"$item_writhanroots",
				Stage.DeepNorth
			},
			{
				"$item_faderember",
				Stage.DeepNorth
			},
			{
				"$item_ancientgemstone_black",
				Stage.DeepNorth
			},
			{
				"$item_ancientgemstone_green",
				Stage.DeepNorth
			},
			{
				"$item_ancientgemstone_orange",
				Stage.DeepNorth
			},
			{
				"$item_ancientgemstone_purple",
				Stage.DeepNorth
			},
			{
				"$item_ancientcoin",
				Stage.DeepNorth
			},
			{
				"$item_fishingbait_deepnorth",
				Stage.DeepNorth
			}
		};
	}
	internal static class PluginInfo
	{
		public const string Version = "1.0.0";
	}
}