Decompiled source of RecipeBook v1.0.0

plugins/RecipeBook/RecipeBook.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace RecipeBook;

internal static class Book
{
	internal class Entry
	{
		public Recipe R;

		public string Name;

		public string Key;

		public string Station;

		public string Tag;

		public Sprite Icon;

		public int Stage;

		public int Order;

		public int Day;
	}

	private const float W = 1120f;

	private const float H = 700f;

	private static readonly List<Entry> All = new List<Entry>();

	private static readonly List<Entry> Shown = new List<Entry>();

	private static bool _recent;

	private static int _stage;

	private static string _tag;

	private static bool _tagPop;

	private static string _material;

	private static string _materialLabel;

	private static Sprite _materialIcon;

	private static string _search = "";

	private static string _lastSearch = "";

	private static Entry _sel;

	private static Vector2 _listScroll;

	private static Vector2 _detailScroll;

	internal static bool SearchFocused;

	private static bool _dirty = true;

	private static readonly List<KeyValuePair<string, Sprite>> Metals = new List<KeyValuePair<string, Sprite>>();

	private static readonly List<string> MetalNames = new List<string>();

	private static GUIStyle _bg;

	private static GUIStyle _panel;

	private static GUIStyle _title;

	private static GUIStyle _text;

	private static GUIStyle _small;

	private static GUIStyle _row;

	private static GUIStyle _rowSel;

	private static GUIStyle _tab;

	private static GUIStyle _tabOn;

	private static GUIStyle _chip;

	private static GUIStyle _head;

	private static GUIStyle _link;

	internal static void Refresh(Player p)
	{
		All.Clear();
		Stages.Reset();
		if ((Object)(object)ObjectDB.instance == (Object)null)
		{
			return;
		}
		Unlocks.Check(p);
		Dictionary<string, Unlocks.Info> dictionary = Unlocks.Load(p);
		foreach (Recipe recipe in ObjectDB.instance.m_recipes)
		{
			if ((Object)(object)recipe == (Object)null || !recipe.m_enabled || (Object)(object)recipe.m_item == (Object)null || recipe.m_resources == null || recipe.m_resources.Length == 0)
			{
				continue;
			}
			string name = recipe.m_item.m_itemData.m_shared.m_name;
			if (!p.IsRecipeKnown(name))
			{
				continue;
			}
			bool flag = false;
			Requirement[] resources = recipe.m_resources;
			foreach (Requirement val in resources)
			{
				if (val != null && (Object)(object)val.m_resItem != (Object)null)
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				Entry entry = new Entry();
				entry.R = recipe;
				entry.Key = name;
				entry.Name = L(name);
				entry.Icon = Icon(recipe.m_item);
				entry.Stage = Stages.Of(recipe);
				Entry entry2 = entry;
				entry2.Station = StationText(recipe);
				entry2.Tag = Tags.Category(recipe.m_item);
				if (dictionary.TryGetValue(name, out var value))
				{
					entry2.Order = value.Order;
					entry2.Day = value.Day;
				}
				else
				{
					entry2.Order = 0;
					entry2.Day = -1;
				}
				All.Add(entry2);
			}
		}
		Metals.Clear();
		string[] array = new string[9] { "Copper", "Tin", "Bronze", "Iron", "Silver", "BlackMetal", "Eitr", "Flametal", "FlametalNew" };
		foreach (string text in array)
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				continue;
			}
			ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || !UsedBy(component.m_itemData.m_shared.m_name))
			{
				continue;
			}
			bool flag2 = false;
			foreach (KeyValuePair<string, Sprite> metal in Metals)
			{
				if (metal.Key == component.m_itemData.m_shared.m_name)
				{
					flag2 = true;
				}
			}
			if (!flag2)
			{
				Metals.Add(new KeyValuePair<string, Sprite>(component.m_itemData.m_shared.m_name, Icon(component)));
			}
		}
		MetalNames.Clear();
		foreach (KeyValuePair<string, Sprite> metal2 in Metals)
		{
			MetalNames.Add(L(metal2.Key));
		}
		if (_sel != null)
		{
			Entry sel = null;
			foreach (Entry item in All)
			{
				if ((Object)(object)item.R == (Object)(object)_sel.R)
				{
					sel = item;
				}
			}
			_sel = sel;
		}
		_dirty = true;
	}

	private static bool UsedBy(string material)
	{
		foreach (Entry item in All)
		{
			Requirement[] resources = item.R.m_resources;
			foreach (Requirement val in resources)
			{
				if (val != null && (Object)(object)val.m_resItem != (Object)null && val.m_resItem.m_itemData.m_shared.m_name == material)
				{
					return true;
				}
			}
		}
		return false;
	}

	private static void Filter()
	{
		Shown.Clear();
		string text = (_search ?? "").Trim().ToLowerInvariant();
		foreach (Entry item in All)
		{
			if ((_stage == 0 || item.Stage == _stage) && (_tag == null || !(item.Tag != _tag)) && (_material == null || Uses(item.R, _material)) && (text.Length <= 0 || item.Name.ToLowerInvariant().IndexOf(text, StringComparison.Ordinal) >= 0 || UsesNamed(item.R, text)))
			{
				Shown.Add(item);
			}
		}
		if (_recent)
		{
			Shown.Sort(delegate(Entry a, Entry b)
			{
				if (a.Order != b.Order)
				{
					return b.Order.CompareTo(a.Order);
				}
				return (a.Stage != b.Stage) ? b.Stage.CompareTo(a.Stage) : string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase);
			});
		}
		else
		{
			Shown.Sort((Entry a, Entry b) => (a.Stage != b.Stage) ? a.Stage.CompareTo(b.Stage) : string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
		}
		_dirty = false;
	}

	private static bool Uses(Recipe r, string material)
	{
		Requirement[] resources = r.m_resources;
		foreach (Requirement val in resources)
		{
			if (val != null && (Object)(object)val.m_resItem != (Object)null && val.m_resItem.m_itemData.m_shared.m_name == material)
			{
				return true;
			}
		}
		return false;
	}

	private static bool UsesNamed(Recipe r, string lower)
	{
		Requirement[] resources = r.m_resources;
		foreach (Requirement val in resources)
		{
			if (val != null && (Object)(object)val.m_resItem != (Object)null && L(val.m_resItem.m_itemData.m_shared.m_name).ToLowerInvariant().IndexOf(lower, StringComparison.Ordinal) >= 0)
			{
				return true;
			}
		}
		return false;
	}

	private static void PickMaterial(ItemDrop item)
	{
		//IL_002f: 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)
		_material = item.m_itemData.m_shared.m_name;
		_materialLabel = L(_material);
		_materialIcon = Icon(item);
		_listScroll = Vector2.zero;
		_dirty = true;
	}

	private static void ClearMaterial()
	{
		_material = null;
		_dirty = true;
	}

	private static void Styles()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		//IL_0032: 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_0057: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Expected O, but got Unknown
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Expected O, but got Unknown
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Expected O, but got Unknown
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Expected O, but got Unknown
		//IL_0196: 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_01b8: Expected O, but got Unknown
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Expected O, but got Unknown
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0272: Expected O, but got Unknown
		//IL_028d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02be: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Expected O, but got Unknown
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_030e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0333: Unknown result type (might be due to invalid IL or missing references)
		//IL_0349: Unknown result type (might be due to invalid IL or missing references)
		//IL_035f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0366: Expected O, but got Unknown
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bc: Expected O, but got Unknown
		//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d5: Expected O, but got Unknown
		//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e8: Expected O, but got Unknown
		//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0402: Expected O, but got Unknown
		if (_bg == null)
		{
			GUIStyle val = new GUIStyle(GUI.skin.box);
			val.normal.background = Tex(new Color(0.08f, 0.07f, 0.06f, 0.94f));
			_bg = val;
			GUIStyle val2 = new GUIStyle(GUI.skin.box);
			val2.normal.background = Tex(new Color(0f, 0f, 0f, 0.35f));
			val2.padding = new RectOffset(8, 8, 8, 8);
			_panel = val2;
			GUIStyle val3 = new GUIStyle(GUI.skin.label);
			val3.fontSize = 22;
			val3.fontStyle = (FontStyle)1;
			val3.normal.textColor = new Color(1f, 0.82f, 0.45f);
			_title = val3;
			GUIStyle val4 = new GUIStyle(GUI.skin.label);
			val4.fontSize = 16;
			val4.fontStyle = (FontStyle)1;
			val4.normal.textColor = new Color(1f, 0.82f, 0.45f);
			_head = val4;
			GUIStyle val5 = new GUIStyle(GUI.skin.label);
			val5.fontSize = 15;
			val5.wordWrap = true;
			val5.normal.textColor = new Color(0.92f, 0.9f, 0.85f);
			_text = val5;
			GUIStyle val6 = new GUIStyle(GUI.skin.label);
			val6.fontSize = 12;
			val6.normal.textColor = new Color(0.7f, 0.68f, 0.62f);
			_small = val6;
			GUIStyle val7 = new GUIStyle(GUI.skin.button);
			val7.alignment = (TextAnchor)3;
			val7.fontSize = 15;
			val7.padding = new RectOffset(44, 6, 2, 2);
			val7.normal.background = Tex(new Color(1f, 1f, 1f, 0.03f));
			val7.normal.textColor = new Color(0.92f, 0.9f, 0.85f);
			val7.hover.background = Tex(new Color(1f, 0.8f, 0.4f, 0.12f));
			val7.hover.textColor = Color.white;
			_row = val7;
			GUIStyle val8 = new GUIStyle(_row);
			val8.normal.background = Tex(new Color(1f, 0.75f, 0.3f, 0.3f));
			val8.normal.textColor = Color.white;
			_rowSel = val8;
			GUIStyle val9 = new GUIStyle(GUI.skin.button);
			val9.fontSize = 15;
			val9.normal.background = Tex(new Color(0f, 0f, 0f, 0.5f));
			val9.normal.textColor = new Color(0.85f, 0.83f, 0.78f);
			val9.hover.background = Tex(new Color(1f, 0.8f, 0.4f, 0.2f));
			val9.hover.textColor = Color.white;
			_tab = val9;
			GUIStyle val10 = new GUIStyle(_tab);
			val10.normal.background = Tex(new Color(0.95f, 0.72f, 0.3f, 0.85f));
			val10.normal.textColor = Color.black;
			val10.fontStyle = (FontStyle)1;
			_tabOn = val10;
			GUIStyle val11 = new GUIStyle(_tab);
			val11.fontSize = 13;
			val11.padding = new RectOffset(4, 4, 2, 2);
			_chip = val11;
			GUIStyle val12 = new GUIStyle(_row);
			val12.fontSize = 15;
			val12.padding = new RectOffset(36, 6, 2, 2);
			_link = val12;
		}
	}

	internal static void Draw()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: 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_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: 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_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0539: Unknown result type (might be due to invalid IL or missing references)
		//IL_0686: Unknown result type (might be due to invalid IL or missing references)
		//IL_068b: Unknown result type (might be due to invalid IL or missing references)
		//IL_068d: Unknown result type (might be due to invalid IL or missing references)
		//IL_077b: Unknown result type (might be due to invalid IL or missing references)
		//IL_079c: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_055e: Expected O, but got Unknown
		//IL_0756: Unknown result type (might be due to invalid IL or missing references)
		//IL_075b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0477: Unknown result type (might be due to invalid IL or missing references)
		//IL_047c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0985: Unknown result type (might be due to invalid IL or missing references)
		//IL_0990: Unknown result type (might be due to invalid IL or missing references)
		//IL_0995: Unknown result type (might be due to invalid IL or missing references)
		//IL_085c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0863: Expected O, but got Unknown
		//IL_0882: Unknown result type (might be due to invalid IL or missing references)
		//IL_0887: Unknown result type (might be due to invalid IL or missing references)
		//IL_0889: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a7d: Unknown result type (might be due to invalid IL or missing references)
		//IL_09ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_09ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a15: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a24: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a2b: Expected O, but got Unknown
		//IL_0a46: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a5c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a6c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a76: Expected O, but got Unknown
		//IL_08e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0923: Unknown result type (might be due to invalid IL or missing references)
		//IL_092f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0936: Expected O, but got Unknown
		Styles();
		float num = (float)Screen.height / 1080f * Plugin.Scale.Value;
		Matrix4x4 matrix = GUI.matrix;
		GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f));
		float num2 = (float)Screen.width / num;
		float num3 = (float)Screen.height / num;
		Rect val = default(Rect);
		((Rect)(ref val))..ctor((num2 - 1120f) / 2f, (num3 - 700f) / 2f, 1120f, 700f);
		GUI.Box(val, GUIContent.none, _bg);
		GUI.Box(val, GUIContent.none, _bg);
		GUILayout.BeginArea(new Rect(((Rect)(ref val)).x + 14f, ((Rect)(ref val)).y + 10f, 1092f, 680f));
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Label("Recipe Book", _title, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.FlexibleSpace();
		GUILayout.Label(string.Concat(All.Count, " recipes known   ·   ", Plugin.Key.Value, " or Esc to close"), _small, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		if (GUILayout.Button("✕", _tab, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) }))
		{
			Plugin.Open = false;
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(6f);
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(470f) });
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		if (GUILayout.Button("All", _recent ? _tab : _tabOn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
		{
			_recent = false;
			_dirty = true;
			_listScroll = Vector2.zero;
		}
		if (GUILayout.Button("Recent", _recent ? _tabOn : _tab, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
		{
			_recent = true;
			_dirty = true;
			_listScroll = Vector2.zero;
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(4f);
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Label("Search", _small, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(46f) });
		GUI.SetNextControlName("rb_search");
		_search = GUILayout.TextField(_search ?? "", 40, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.EndHorizontal();
		SearchFocused = GUI.GetNameOfFocusedControl() == "rb_search";
		GUILayout.Space(4f);
		if (GUILayout.Button((_tag == null) ? "Filter: All" : ("Filter: " + _tag), (_tag == null) ? _chip : _tabOn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }))
		{
			_tagPop = !_tagPop;
		}
		if (_tagPop)
		{
			List<string> list = new List<string>();
			list.Add("All");
			List<string> list2 = list;
			string[] all = Tags.All;
			foreach (string text in all)
			{
				foreach (Entry item in All)
				{
					if (item.Tag == text)
					{
						list2.Add(text);
						break;
					}
				}
			}
			for (int j = 0; j < list2.Count; j++)
			{
				if (j % 5 == 0)
				{
					if (j > 0)
					{
						GUILayout.EndHorizontal();
					}
					GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
				}
				string text2 = list2[j];
				bool flag = ((text2 == "All") ? (_tag == null) : (text2 == _tag));
				if (GUILayout.Button(text2, flag ? _tabOn : _chip, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(88f) }))
				{
					_tag = ((text2 == "All") ? null : text2);
					_tagPop = false;
					_dirty = true;
					_listScroll = Vector2.zero;
				}
			}
			GUILayout.EndHorizontal();
		}
		if (_search != _lastSearch)
		{
			_lastSearch = _search;
			_dirty = true;
		}
		GUILayout.Space(4f);
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		if (GUILayout.Button("Any stage", (_stage == 0) ? _tabOn : _chip, (GUILayoutOption[])(object)new GUILayoutOption[0]))
		{
			_stage = 0;
			_dirty = true;
		}
		for (int k = 1; k <= 7; k++)
		{
			if (k == 5)
			{
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
			}
			if (Stages.Present(k, All) && GUILayout.Button(new GUIContent(Stages.Short[k], Stages.Long[k]), (_stage == k) ? _tabOn : _chip, (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				_stage = ((_stage != k) ? k : 0);
				_dirty = true;
			}
		}
		GUILayout.EndHorizontal();
		if (Metals.Count > 0)
		{
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
			for (int l = 0; l < Metals.Count; l++)
			{
				bool flag2 = _material == Metals[l].Key;
				if (!GUILayout.Button(MetalNames[l], flag2 ? _tabOn : _chip, (GUILayoutOption[])(object)new GUILayoutOption[0]))
				{
					continue;
				}
				if (flag2)
				{
					ClearMaterial();
					continue;
				}
				GameObject val2 = FindItem(Metals[l].Key);
				if ((Object)(object)val2 != (Object)null)
				{
					PickMaterial(val2.GetComponent<ItemDrop>());
				}
			}
			GUILayout.EndHorizontal();
		}
		if (_material != null)
		{
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
			Rect rect = GUILayoutUtility.GetRect(22f, 22f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(22f) });
			DrawSprite(rect, _materialIcon);
			GUILayout.Label("Recipes that use " + _materialLabel, _head, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("clear", _chip, (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				ClearMaterial();
			}
			GUILayout.EndHorizontal();
			Entry entry = MakerOf(_material);
			if (entry != null)
			{
				GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
				GUILayout.Label("Made by:", _small, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(56f) });
				if (GUILayout.Button(entry.Name + "  (" + entry.Station + ")", _chip, (GUILayoutOption[])(object)new GUILayoutOption[0]))
				{
					_sel = entry;
					_detailScroll = Vector2.zero;
				}
				GUILayout.EndHorizontal();
			}
		}
		if (_dirty)
		{
			Filter();
		}
		GUILayout.Space(4f);
		_listScroll = GUILayout.BeginScrollView(_listScroll, false, true, GUIStyle.none, GUI.skin.verticalScrollbar, _panel, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		if (Shown.Count == 0)
		{
			GUILayout.Label("Nothing here.", _small, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		}
		int num4 = -1;
		foreach (Entry item2 in Shown)
		{
			if (!_recent && item2.Stage != num4)
			{
				num4 = item2.Stage;
				GUILayout.Label(Stages.Long[item2.Stage], _small, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			}
			string text3 = ((!_recent) ? item2.Station : ((item2.Day >= 0) ? ("day " + item2.Day) : ""));
			GUIContent val3 = new GUIContent(item2.Name);
			Rect rect2 = GUILayoutUtility.GetRect(val3, _row, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(36f) });
			if (GUI.Button(rect2, val3, (item2 == _sel) ? _rowSel : _row))
			{
				_sel = item2;
				_detailScroll = Vector2.zero;
				GUI.FocusControl((string)null);
			}
			DrawSprite(new Rect(((Rect)(ref rect2)).x + 6f, ((Rect)(ref rect2)).y + 3f, 30f, 30f), item2.Icon);
			if (text3.Length > 0)
			{
				Rect val4 = new Rect(((Rect)(ref rect2)).xMax - 170f, ((Rect)(ref rect2)).y + 9f, 164f, 20f);
				GUIStyle val5 = new GUIStyle(_small);
				val5.alignment = (TextAnchor)5;
				GUI.Label(val4, text3, val5);
			}
		}
		GUILayout.EndScrollView();
		GUILayout.EndVertical();
		GUILayout.Space(12f);
		GUILayout.BeginVertical(_panel, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		_detailScroll = GUILayout.BeginScrollView(_detailScroll, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		if (_sel == null)
		{
			GUILayout.Label("Pick a recipe on the left.\n\nClick a material in a recipe to see every recipe of yours that uses it.", _text, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		}
		else
		{
			Detail(_sel);
		}
		GUILayout.EndScrollView();
		GUILayout.EndVertical();
		GUILayout.EndHorizontal();
		GUILayout.EndArea();
		if (!string.IsNullOrEmpty(GUI.tooltip))
		{
			Vector2 mousePosition = Event.current.mousePosition;
			Rect val6 = new Rect(mousePosition.x + 14f, mousePosition.y + 14f, 260f, 24f);
			string tooltip = GUI.tooltip;
			GUIStyle val7 = new GUIStyle(_small);
			val7.normal.background = Tex(new Color(0f, 0f, 0f, 0.85f));
			val7.normal.textColor = Color.white;
			val7.padding = new RectOffset(6, 6, 3, 3);
			GUI.Label(val6, tooltip, val7);
		}
		GUI.matrix = matrix;
	}

	private static void Detail(Entry e)
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		Recipe r = e.R;
		SharedData shared = r.m_item.m_itemData.m_shared;
		Player localPlayer = Player.m_localPlayer;
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		Rect rect = GUILayoutUtility.GetRect(64f, 64f, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Width(64f),
			GUILayout.Height(64f)
		});
		DrawSprite(rect, e.Icon);
		GUILayout.Space(8f);
		GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Label(e.Name + ((r.m_amount > 1) ? ("  ×" + r.m_amount) : ""), _title, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Label(e.Tag + "   ·   " + e.Station + "   ·   " + Stages.Long[e.Stage], _small, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		if (e.Day >= 0)
		{
			GUILayout.Label("Unlocked on day " + e.Day, _small, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		}
		GUILayout.EndVertical();
		GUILayout.EndHorizontal();
		string text = L(shared.m_description);
		if (!string.IsNullOrEmpty(text) && !text.StartsWith("["))
		{
			GUILayout.Label(text, _text, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		}
		GUILayout.Space(8f);
		GUILayout.Label(r.m_requireOnlyOneIngredient ? "Needs one of" : "Needs", _head, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		Materials(r, 1, localPlayer);
		if (shared.m_maxQuality <= 1)
		{
			return;
		}
		bool flag = false;
		Requirement[] resources = r.m_resources;
		foreach (Requirement val in resources)
		{
			if (val != null && (Object)(object)val.m_resItem != (Object)null && val.m_amountPerLevel > 0)
			{
				flag = true;
			}
		}
		if (flag)
		{
			GUILayout.Space(10f);
			GUILayout.Label("Upgrades (up to quality " + shared.m_maxQuality + ")", _head, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			for (int j = 2; j <= shared.m_maxQuality; j++)
			{
				string text2 = (((Object)(object)r.m_craftingStation != (Object)null) ? (L(r.m_craftingStation.m_name) + " level " + r.GetRequiredStationLevel(j)) : "");
				GUILayout.Label("Quality " + j + ((text2.Length > 0) ? ("  ·  " + text2) : ""), _small, (GUILayoutOption[])(object)new GUILayoutOption[0]);
				Materials(r, j, localPlayer);
			}
		}
	}

	private static void Materials(Recipe r, int quality, Player p)
	{
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Expected O, but got Unknown
		//IL_00d7: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Expected O, but got Unknown
		//IL_01e6: 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)
		Requirement[] resources = r.m_resources;
		foreach (Requirement val in resources)
		{
			if (val == null || (Object)(object)val.m_resItem == (Object)null)
			{
				continue;
			}
			int num = ((quality <= 1) ? val.m_amount : (val.m_amountPerLevel * (quality - 1)));
			if (num <= 0)
			{
				continue;
			}
			string text = L(val.m_resItem.m_itemData.m_shared.m_name);
			int num2 = (((Object)(object)p != (Object)null) ? ((Humanoid)p).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) : 0);
			GUIContent val2 = new GUIContent(num + " × " + text, "Show the recipes that use " + text);
			Rect rect = GUILayoutUtility.GetRect(val2, _link, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
			bool flag = _material == val.m_resItem.m_itemData.m_shared.m_name;
			if (GUI.Button(rect, val2, flag ? _rowSel : _link))
			{
				if (flag)
				{
					ClearMaterial();
				}
				else
				{
					PickMaterial(val.m_resItem);
				}
			}
			DrawSprite(new Rect(((Rect)(ref rect)).x + 5f, ((Rect)(ref rect)).y + 3f, 24f, 24f), Icon(val.m_resItem));
			Rect val3 = new Rect(((Rect)(ref rect)).xMax - 130f, ((Rect)(ref rect)).y + 6f, 124f, 20f);
			string text2 = "you have " + num2;
			GUIStyle val4 = new GUIStyle(_small);
			val4.alignment = (TextAnchor)5;
			val4.normal.textColor = ((num2 >= num) ? new Color(0.6f, 0.85f, 0.5f) : new Color(0.7f, 0.68f, 0.62f));
			GUI.Label(val3, text2, val4);
		}
	}

	private static Entry MakerOf(string material)
	{
		foreach (Entry item in All)
		{
			if (item.Key == material)
			{
				return item;
			}
		}
		return null;
	}

	private static GameObject FindItem(string sharedName)
	{
		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 && val.m_itemData.m_shared.m_name == sharedName)
			{
				return item;
			}
		}
		return null;
	}

	private static string StationText(Recipe r)
	{
		if ((Object)(object)r.m_craftingStation != (Object)null)
		{
			return L(r.m_craftingStation.m_name) + ((r.m_minStationLevel > 1) ? (" lv " + r.m_minStationLevel) : "");
		}
		if ((Object)(object)r.m_repairStation != (Object)null)
		{
			return L(r.m_repairStation.m_name);
		}
		return "By hand";
	}

	internal static string L(string s)
	{
		if (string.IsNullOrEmpty(s))
		{
			return "";
		}
		if (Localization.instance == null)
		{
			return s;
		}
		return Localization.instance.Localize(s);
	}

	private static Sprite Icon(ItemDrop d)
	{
		if ((Object)(object)d == (Object)null)
		{
			return null;
		}
		Sprite[] icons = d.m_itemData.m_shared.m_icons;
		if (icons == null || icons.Length <= 0)
		{
			return null;
		}
		return icons[0];
	}

	private static void DrawSprite(Rect r, Sprite s)
	{
		//IL_0020: 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_0026: 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)
		if (!((Object)(object)s == (Object)null) && !((Object)(object)s.texture == (Object)null))
		{
			Texture2D texture = s.texture;
			Rect textureRect = s.textureRect;
			GUI.DrawTextureWithTexCoords(r, (Texture)(object)texture, new Rect(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height));
		}
	}

	private static Texture2D Tex(Color c)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(1, 1);
		val.SetPixel(0, 0, c);
		val.Apply();
		Object.DontDestroyOnLoad((Object)(object)val);
		return val;
	}
}
[BepInPlugin("felih.RecipeBook", "Recipe Book", "1.0.0")]
[HarmonyPatch]
public class Plugin : BaseUnityPlugin
{
	internal static ConfigEntry<KeyboardShortcut> Key;

	internal static ConfigEntry<float> Scale;

	internal static ManualLogSource Log;

	internal static bool Open;

	private void Awake()
	{
		//IL_0023: 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_0070: Expected O, but got Unknown
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		Key = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Key", new KeyboardShortcut((KeyCode)105, (KeyCode[])(object)new KeyCode[0]), "Opens and closes the recipe book.");
		Scale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Scale", 1f, new ConfigDescription("Size of the recipe book window (1 = normal).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 2f), new object[0]));
		new Harmony("felih.RecipeBook").PatchAll(typeof(Plugin).Assembly);
	}

	private void Update()
	{
		//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_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			Open = false;
			return;
		}
		Unlocks.Watch(localPlayer);
		if (Open && (InventoryGui.IsVisible() || Minimap.IsOpen() || Menu.IsVisible() || StoreGui.IsVisible() || ((Character)localPlayer).IsDead()))
		{
			Open = false;
		}
		if (Open && Book.SearchFocused)
		{
			return;
		}
		KeyboardShortcut value = Key.Value;
		if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
		{
			return;
		}
		KeyboardShortcut value2 = Key.Value;
		if (((KeyboardShortcut)(ref value2)).IsDown() && (Open || ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen() && !Menu.IsVisible() && !StoreGui.IsVisible())))
		{
			Open = !Open;
			if (Open)
			{
				Book.Refresh(localPlayer);
			}
		}
	}

	private void OnGUI()
	{
		if (Open && (Object)(object)Player.m_localPlayer != (Object)null)
		{
			Book.Draw();
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")]
	private static void FreeCursor()
	{
		if (Open)
		{
			ZCursor.LockState = (CursorLockMode)0;
			ZCursor.Show();
		}
	}

	[HarmonyPatch(typeof(PlayerController), "TakeInput")]
	[HarmonyPrefix]
	private static bool NoControl(ref bool __result)
	{
		if (!Open)
		{
			return true;
		}
		__result = false;
		return false;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(Player), "TakeInput")]
	private static bool NoHotkeys(ref bool __result)
	{
		if (!Open)
		{
			return true;
		}
		__result = false;
		return false;
	}

	[HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")]
	[HarmonyPrefix]
	private static bool NoZoom(ref float __result)
	{
		if (!Open)
		{
			return true;
		}
		__result = 0f;
		return false;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(ZInput), "Internal_GetMouseScrollWheel")]
	private static bool NoZoomInner(ref float __result)
	{
		return NoZoom(ref __result);
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(Minimap), "Update")]
	private static bool NoMapWhileTyping()
	{
		if (Open)
		{
			return !Book.SearchFocused;
		}
		return true;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(Menu), "Update")]
	private static bool EscCloses()
	{
		if (Open && ZInput.GetKeyDown((KeyCode)27, true))
		{
			Open = false;
			return false;
		}
		return true;
	}

	[HarmonyPatch(typeof(Player), "AddKnownRecipe")]
	[HarmonyPrefix]
	private static void BeforeLearn(Player __instance, Recipe recipe, out bool __state)
	{
		__state = (Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item != (Object)null && !__instance.IsRecipeKnown(recipe.m_item.m_itemData.m_shared.m_name);
	}

	[HarmonyPatch(typeof(Player), "AddKnownRecipe")]
	[HarmonyPostfix]
	private static void AfterLearn(Player __instance, Recipe recipe, bool __state)
	{
		if (__state && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
		{
			Unlocks.Add(__instance, recipe.m_item.m_itemData.m_shared.m_name);
		}
	}
}
internal static class Stages
{
	internal const int Count = 7;

	internal static readonly string[] Short;

	internal static readonly string[] Long;

	private static readonly Dictionary<string, int> Table;

	private static readonly Dictionary<string, int> Cache;

	static Stages()
	{
		Short = new string[8] { "", "Meadows", "Black Forest", "Swamp", "Mountain", "Plains", "Mistlands", "Ashlands" };
		Long = new string[8] { "", "Meadows · start", "Black Forest · after Eikthyr", "Swamp · after The Elder", "Mountain · after Bonemass", "Plains · after Moder", "Mistlands · after Yagluth", "Ashlands · after The Queen" };
		Table = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
		Cache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
		Put(1, "Wood", "Stone", "Flint", "LeatherScraps", "DeerHide", "Resin", "Feathers", "BoneFragments", "Raspberry", "Mushroom", "Honey", "NeckTail", "RawMeat", "Dandelion", "DeerMeat", "MushroomYellow", "TrophyDeer", "TrophyBoar", "TrophyNeck", "QueenBee");
		Put(2, "HardAntler", "TrophyEikthyr", "Copper", "CopperOre", "Tin", "TinOre", "Bronze", "BronzeNails", "FineWood", "RoundLog", "TrollHide", "GreydwarfEye", "SurtlingCore", "AncientSeed", "Coal", "Blueberries", "Carrot", "CarrotSeeds", "Thistle", "TrophyGreydwarf", "TrophyFrostTroll", "TrophySkeleton", "BeechSeeds", "PineCone", "FirCone", "CopperScrap", "Bjorn", "BjornHide", "BjornPaw");
		Put(3, "TrophyTheElder", "CryptKey", "Iron", "IronScrap", "IronOre", "IronNails", "ElderBark", "Guck", "Chain", "Bloodbag", "Entrails", "Ooze", "Root", "Chitin", "Turnip", "TurnipSeeds", "WitheredBone", "SerpentScale", "SerpentMeat", "TrophyDraugr", "TrophyAbomination", "TrophyLeech");
		Put(4, "TrophyBonemass", "Wishbone", "Silver", "SilverOre", "WolfPelt", "WolfFang", "WolfClaw", "WolfHairBundle", "WolfMeat", "Obsidian", "FreezeGland", "Crystal", "DragonEgg", "JuteRed", "Onion", "OnionSeeds", "TrophyWolf", "TrophyHatchling", "TrophyFenring", "TrophyUlv", "TrophySGolem", "TrophyCultist", "BearMeat", "Bjorn_sleeping");
		Put(5, "TrophyDragonQueen", "DragonTear", "BlackMetal", "BlackMetalScrap", "LoxPelt", "LoxMeat", "Needle", "Barley", "BarleyFlour", "Flax", "LinenThread", "Tar", "GoblinTotem", "Cloudberry", "TrophyLox", "TrophyDeathsquito", "TrophyGoblin", "TrophyGrowth", "TrophyGoblinShaman", "TrophyGoblinBrute");
		Put(6, "TrophyGoblinKing", "YagluthDrop", "Eitr", "BlackCore", "Carapace", "Mandible", "Softtissue", "YggdrasilWood", "ScaleHide", "BlackMarble", "JuteBlue", "Sap", "Wisp", "RoyalJelly", "GiantBloodSack", "Bilebag", "BugMeat", "HareMeat", "MushroomJotunPuffs", "MushroomMagecap", "TrophyGjall", "TrophySeeker", "TrophySeekerBrute", "TrophyTick", "TrophyHare", "TrophyDvergr", "DvergrNeedle", "DvergrKeyFragment", "ChickenMeat", "ChickenEgg", "Feaster", "BlackSoup");
		Put(7, "TrophySeekerQueen", "QueenDrop", "Flametal", "FlametalNew", "FlametalOre", "FlametalOreNew", "CharredBone", "AskHide", "AsksvinMeat", "Blackwood", "Grausten", "CelestialFeather", "MorgenSinew", "MorgenHeart", "CharcoalResin", "BellFragment", "CharredCogwheel", "MoltenCore", "ProustitePowder", "SulfurStone", "Fiddleheadfern", "Vineberry", "VineberrySeeds", "MushroomSmokePuff", "BonemawSerpentTooth", "BonemawSerpentScale", "VoltureEgg", "VoltureMeat", "AsksvinEgg", "PowderedDragonEgg", "TrophyAsksvin", "TrophyCharredMelee", "TrophyMorgen", "TrophyVolture", "TrophyFallenValkyrie", "TrophyBonemawSerpent", "FaderDrop", "TrophyFader");
	}

	private static void Put(int stage, params string[] names)
	{
		foreach (string key in names)
		{
			Table[key] = stage;
		}
	}

	internal static void Reset()
	{
		Cache.Clear();
	}

	internal static int Of(Recipe r)
	{
		return Of(r, 0);
	}

	private static int Of(Recipe r, int depth)
	{
		int num = 1;
		if ((Object)(object)r == (Object)null || r.m_resources == null)
		{
			return num;
		}
		Requirement[] resources = r.m_resources;
		foreach (Requirement val in resources)
		{
			if (val != null && (Object)(object)val.m_resItem != (Object)null)
			{
				num = Math.Max(num, Material(val.m_resItem, depth));
			}
		}
		return num;
	}

	private static int Material(ItemDrop item, int depth)
	{
		string prefabName = Utils.GetPrefabName(((Component)item).gameObject);
		if (Table.TryGetValue(prefabName, out var value))
		{
			return value;
		}
		if (Cache.TryGetValue(prefabName, out value))
		{
			return value;
		}
		value = 1;
		if (depth < 3 && (Object)(object)ObjectDB.instance != (Object)null)
		{
			string name = item.m_itemData.m_shared.m_name;
			foreach (Recipe recipe in ObjectDB.instance.m_recipes)
			{
				if ((Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item != (Object)null && recipe.m_item.m_itemData.m_shared.m_name == name)
				{
					value = Math.Max(value, Of(recipe, depth + 1));
					break;
				}
			}
		}
		Cache[prefabName] = value;
		return value;
	}

	internal static bool Present(int stage, List<Book.Entry> all)
	{
		foreach (Book.Entry item in all)
		{
			if (item.Stage == stage)
			{
				return true;
			}
		}
		return false;
	}
}
internal static class Tags
{
	internal static readonly string[] All = new string[20]
	{
		"Weapons", "Ammo", "Armor", "Tools", "Food", "Meads", "Meat", "Fish", "Crops", "Seeds",
		"Ores", "Metals", "Wood", "Stone", "Hides", "Creature", "Valuables", "Trophies", "Materials", "Misc"
	};

	private static bool Has(string name, params string[] parts)
	{
		foreach (string value in parts)
		{
			if (name.Contains(value))
			{
				return true;
			}
		}
		return false;
	}

	internal static string Category(ItemDrop item)
	{
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Invalid comparison between Unknown and I4
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: 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)
		//IL_0194: Expected I4, but got Unknown
		SharedData shared = item.m_itemData.m_shared;
		string text = (shared.m_name ?? "").ToLowerInvariant();
		string prefabName = Utils.GetPrefabName(((Component)item).gameObject);
		if (prefabName.StartsWith("Beastkeeper_"))
		{
			return "Tools";
		}
		if (prefabName.StartsWith("Catapult") || prefabName.StartsWith("BombSiege"))
		{
			return "Ammo";
		}
		if (prefabName.StartsWith("MeadBase") || prefabName == "BarleyWineBase")
		{
			return "Meads";
		}
		if ((prefabName.StartsWith("Feast") && prefabName.EndsWith("_Material")) || prefabName.StartsWith("Spice") || prefabName.EndsWith("Flour") || prefabName == "BreadDough")
		{
			return "Food";
		}
		if (prefabName.EndsWith("Uncooked") && !Gear(prefabName))
		{
			return "Food";
		}
		if ((int)shared.m_itemType == 1 && (prefabName.StartsWith("Mold") || prefabName.StartsWith("Orb") || prefabName.StartsWith("Staff") || prefabName.EndsWith("Uncooked")))
		{
			return "Materials";
		}
		ItemType itemType = shared.m_itemType;
		switch (itemType - 1)
		{
		case 2:
		case 3:
		case 4:
		case 13:
		case 19:
		case 21:
			return "Weapons";
		case 8:
		case 22:
			return "Ammo";
		case 5:
		case 6:
		case 10:
		case 11:
		case 16:
		case 17:
		case 23:
			return "Armor";
		case 14:
		case 18:
			return "Tools";
		case 12:
			return "Trophies";
		case 20:
			return "Fish";
		case 1:
			if (shared.m_food > 0f || shared.m_foodStamina > 0f || shared.m_foodEitr > 0f)
			{
				return "Food";
			}
			return "Meads";
		case 0:
			if (Has(text, "coin", "amber", "ruby", "pearl", "necklace", "gemstone", "jewel"))
			{
				return "Valuables";
			}
			if (Has(text, "seed", "sapling", "cone", "acorn"))
			{
				return "Seeds";
			}
			if (text.StartsWith("$item_fish"))
			{
				return "Fish";
			}
			if (Has(text, "hide", "pelt", "leather"))
			{
				return "Hides";
			}
			if (Has(text, "meat", "entrails", "necktail", "neck_tail", "chicken"))
			{
				return "Meat";
			}
			if (Has(text, "feather", "gland", "bone", "claw", "fang", "tooth", "horn", "antler", "carapace", "mandible", "chitin", "tissue", "ooze", "guck", "bile", "ectoplasm", "scale", "blood", "wing", "hair", "core", "eye", "needle", "skull", "tail", "bladder", "carrion", "paw", "sinew", "heart", "blubber", "ribcage", "larva"))
			{
				return "Creature";
			}
			if (Has(text, "barley", "flax", "turnip", "onion", "thistle", "dandelion", "fiddlehead", "mushroom", "berr", "carrot", "smokepuff", "jotunpuff", "magecap", "vineberry", "seaweed"))
			{
				return "Crops";
			}
			if (Has(text, "ore", "scrap"))
			{
				return "Ores";
			}
			if (Has(text, "copper", "tin", "bronze", "iron", "silver", "blackmetal", "flametal", "ingot", "metal"))
			{
				return "Metals";
			}
			if (Has(text, "wood", "roundlog", "elderbark", "log"))
			{
				return "Wood";
			}
			if (Has(text, "stone", "marble", "obsidian", "flint", "grausten", "crystal"))
			{
				return "Stone";
			}
			return "Materials";
		default:
			return "Misc";
		}
	}

	private static bool Gear(string id)
	{
		string[] array = new string[19]
		{
			"Armor", "Atgeir", "Axe", "Battleaxe", "Bow", "Crossbow", "Fist", "Keys", "Knife", "Mace",
			"Shield", "Sledge", "SmallParts", "Spear", "Staff", "Sword", "THSword", "Generic", "Mold"
		};
		foreach (string value in array)
		{
			if (id.StartsWith(value))
			{
				return true;
			}
		}
		return false;
	}
}
internal static class Unlocks
{
	internal class Info
	{
		public int Order;

		public int Day;
	}

	private const string SaveKey = "RecipeBook_unlocks";

	private const string BaseKey = "RecipeBook_base";

	private static readonly FieldInfo KnownField = AccessTools.Field(typeof(Player), "m_knownRecipes");

	private static int _lastCount = -1;

	private static Player _lastPlayer;

	private static float _next;

	internal static Dictionary<string, Info> Load(Player p)
	{
		Dictionary<string, Info> dictionary = new Dictionary<string, Info>();
		if ((Object)(object)p == (Object)null || !p.m_customData.TryGetValue("RecipeBook_unlocks", out var value) || string.IsNullOrEmpty(value))
		{
			return dictionary;
		}
		int num = 0;
		string[] array = value.Split('\n');
		foreach (string text in array)
		{
			int num2 = text.LastIndexOf('\t');
			if (num2 > 0)
			{
				if (!int.TryParse(text.Substring(num2 + 1), out var result))
				{
					result = -1;
				}
				string key = text.Substring(0, num2);
				Info info = new Info();
				num = (info.Order = num + 1);
				info.Day = result;
				dictionary[key] = info;
			}
		}
		return dictionary;
	}

	internal static void Watch(Player p)
	{
		if (!((Object)(object)p == (Object)null) && !(Time.time < _next) && !((Object)(object)ObjectDB.instance == (Object)null))
		{
			_next = Time.time + 3f;
			HashSet<string> hashSet = ((KnownField != null) ? (KnownField.GetValue(p) as HashSet<string>) : null);
			if (hashSet != null && (!((Object)(object)p == (Object)(object)_lastPlayer) || hashSet.Count != _lastCount))
			{
				_lastPlayer = p;
				_lastCount = hashSet.Count;
				Check(p);
			}
		}
	}

	internal static void Check(Player p)
	{
		List<string> list = new List<string>();
		foreach (Recipe recipe in ObjectDB.instance.m_recipes)
		{
			if ((Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item != (Object)null && p.IsRecipeKnown(recipe.m_item.m_itemData.m_shared.m_name))
			{
				list.Add(recipe.m_item.m_itemData.m_shared.m_name);
			}
		}
		if (!p.m_customData.TryGetValue("RecipeBook_base", out var value))
		{
			Dictionary<string, Info> dictionary = Load(p);
			List<string> list2 = new List<string>();
			foreach (string item in list)
			{
				if (!dictionary.ContainsKey(item) && !list2.Contains(item))
				{
					list2.Add(item);
				}
			}
			p.m_customData["RecipeBook_base"] = string.Join("|", list2.ToArray());
			return;
		}
		HashSet<string> hashSet = new HashSet<string>(value.Split('|'));
		Dictionary<string, Info> dictionary2 = Load(p);
		foreach (string item2 in list)
		{
			if (!hashSet.Contains(item2) && !dictionary2.ContainsKey(item2))
			{
				Add(p, item2);
				dictionary2 = Load(p);
			}
		}
	}

	internal static void Add(Player p, string name)
	{
		if ((Object)(object)p == (Object)null || string.IsNullOrEmpty(name))
		{
			return;
		}
		Dictionary<string, Info> dictionary = Load(p);
		if (!dictionary.ContainsKey(name))
		{
			int value = (((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetDay() : (-1));
			p.m_customData.TryGetValue("RecipeBook_unlocks", out var value2);
			StringBuilder stringBuilder = new StringBuilder(value2 ?? "");
			if (stringBuilder.Length > 0)
			{
				stringBuilder.Append('\n');
			}
			stringBuilder.Append(name.Replace("\n", "").Replace("\t", "")).Append('\t').Append(value);
			p.m_customData["RecipeBook_unlocks"] = stringBuilder.ToString();
		}
	}
}