Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RecipeBook v1.0.0
plugins/RecipeBook/RecipeBook.dll
Decompiled 3 hours agousing 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(); } } }