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 DadsEZCrafting v1.0.0
DadsEZCrafting.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("DadsEZCrafting")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+19e798672f4bf44f0cb043cd0827426dc5b2fc7c")] [assembly: AssemblyProduct("DadsEZCrafting")] [assembly: AssemblyTitle("DadsEZCrafting")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DadsEZCrafting { internal static class CraftingPatches { internal static void Install(Harmony harmony) { Patch(harmony, AccessTools.Method(typeof(InventoryGui), "Awake", (Type[])null, (Type[])null), "InventoryGuiAwakePostfix", prefix: false); Patch(harmony, AccessTools.Method(typeof(InventoryGui), "UpdateRecipeList", new Type[1] { typeof(List<Recipe>) }, (Type[])null), "UpdateRecipeListPrefix", prefix: true); Patch(harmony, AccessTools.Method(typeof(InventoryGui), "OnCraftPressed", (Type[])null, (Type[])null), "OnCraftPressedPrefix", prefix: true); } private static void Patch(Harmony harmony, MethodBase original, string patchName, bool prefix) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (original == null) { DadsEZCraftingPlugin.ModLog.LogError((object)("Required Valheim method was not found for " + patchName + "; no invalid Harmony patch was applied.")); return; } HarmonyMethod val = new HarmonyMethod(typeof(CraftingPatches), patchName, (Type[])null); harmony.Patch(original, prefix ? val : null, prefix ? null : val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void InventoryGuiAwakePostfix(InventoryGui __instance) { CraftingUiManager.Attach(__instance); } private static void UpdateRecipeListPrefix(List<Recipe> recipes) { ConfigEntry<bool> enabled = DadsEZCraftingPlugin.Enabled; if (enabled != null && enabled.Value) { RecipeFilterState.Apply(recipes); } } private static void OnCraftPressedPrefix(InventoryGui __instance) { CraftingUiManager.PrepareCrafting(__instance); } } internal sealed class CraftingUiManager : MonoBehaviour { private sealed class DropdownChoice { internal string Label; internal Action Select; } private const float ToolbarHeight = 92f; private const int MaximumCraftQuantity = 9999; private static readonly MethodInfo UpdateCraftingPanelMethod = AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", new Type[1] { typeof(bool) }, (Type[])null); private static readonly FieldInfo SelectedRecipeField = AccessTools.Field(typeof(InventoryGui), "m_selectedRecipe"); private static readonly FieldInfo MultiCraftAmountField = AccessTools.Field(typeof(InventoryGui), "m_multiCraftAmount"); private static readonly FieldInfo TouchMultiCraftingField = AccessTools.Field(typeof(InventoryGui), "m_touchMultiCrafting"); private static readonly FieldInfo SelectedRecipeValueField = AccessTools.Field(SelectedRecipeField.FieldType, "<Recipe>k__BackingField"); private static readonly FieldInfo SelectedItemDataValueField = AccessTools.Field(SelectedRecipeField.FieldType, "<ItemData>k__BackingField"); private InventoryGui _gui; private RectTransform _viewport; private Vector2 _originalViewportOffsetMax; private RectTransform _toolbar; private TMP_InputField _search; private Button _categoryButton; private Button _tierButton; private Button _sortButton; private TMP_Text _categoryLabel; private TMP_Text _tierLabel; private TMP_Text _sortLabel; private GameObject _categoryMenu; private GameObject _tierMenu; private RectTransform _craftControls; private TMP_Text _quantityLabel; private Button _minusButton; private Button _plusButton; private Button _maxButton; private Recipe _lastSelectedRecipe; private ItemData _lastUpgradeItem; private int _craftQuantity = 1; internal static CraftingUiManager Instance { get; private set; } internal static void Attach(InventoryGui gui) { if (!((Object)(object)gui == (Object)null)) { CraftingUiManager craftingUiManager = ((Component)gui).GetComponent<CraftingUiManager>(); if ((Object)(object)craftingUiManager == (Object)null) { craftingUiManager = ((Component)gui).gameObject.AddComponent<CraftingUiManager>(); } craftingUiManager.Initialize(gui); } } internal static void RefreshRecipes() { if (!((Object)(object)Instance?._gui == (Object)null) && !(UpdateCraftingPanelMethod == null)) { UpdateCraftingPanelMethod.Invoke(Instance._gui, new object[1] { false }); } } internal static void PrepareCrafting(InventoryGui gui) { if (!((Object)(object)Instance == (Object)null) && !((Object)(object)gui != (Object)(object)Instance._gui)) { bool flag = Instance._craftQuantity > 1 && GetSelectedItemData(gui) == null; MultiCraftAmountField.SetValue(gui, (!flag) ? 1 : Instance._craftQuantity); TouchMultiCraftingField.SetValue(gui, flag); } } private void Initialize(InventoryGui gui) { if (!((Object)(object)_gui != (Object)null)) { _gui = gui; Instance = this; BuildToolbar(); BuildCraftControls(); RefreshLabels(); } } private void BuildToolbar() { //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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Expected O, but got Unknown //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Expected O, but got Unknown //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Expected O, but got Unknown RectTransform recipeListRoot = _gui.m_recipeListRoot; _viewport = (RectTransform)(((Object)(object)recipeListRoot == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)_viewport == (Object)null || (Object)(object)((Transform)_viewport).parent == (Object)null) { DadsEZCraftingPlugin.ModLog.LogError((object)"The native recipe-list viewport was not found; filtering remains active without the toolbar."); return; } _originalViewportOffsetMax = _viewport.offsetMax; _viewport.offsetMax = new Vector2(_originalViewportOffsetMax.x, _originalViewportOffsetMax.y - 92f - 4f); GameObject val = new GameObject("DadsEZCrafting_FilterToolbar", new Type[1] { typeof(RectTransform) }); _toolbar = val.GetComponent<RectTransform>(); ((Transform)_toolbar).SetParent(((Transform)_viewport).parent, false); _toolbar.anchorMin = new Vector2(_viewport.anchorMin.x, _viewport.anchorMax.y); _toolbar.anchorMax = new Vector2(_viewport.anchorMax.x, _viewport.anchorMax.y); _toolbar.pivot = new Vector2(0.5f, 1f); _toolbar.offsetMin = new Vector2(_viewport.offsetMin.x, _originalViewportOffsetMax.y - 92f); _toolbar.offsetMax = new Vector2(_viewport.offsetMax.x, _originalViewportOffsetMax.y); ((Transform)_toolbar).SetAsLastSibling(); _search = CreateSearchField((Transform)(object)_toolbar); SetRow(((Component)_search).GetComponent<RectTransform>(), 0f, 1f, 0f, 28f); ((UnityEvent<string>)(object)_search.onValueChanged).AddListener((UnityAction<string>)delegate(string value) { RecipeFilterState.Search = value ?? string.Empty; RefreshRecipes(); }); _categoryButton = CreateNativeButton((Transform)(object)_toolbar, "Category", out _categoryLabel); SetRow(((Component)_categoryButton).GetComponent<RectTransform>(), 0f, 0.5f, 32f, 28f, 0f, -2f); ((UnityEvent)_categoryButton.onClick).AddListener((UnityAction)delegate { ToggleMenu(_categoryMenu, _tierMenu); }); _tierButton = CreateNativeButton((Transform)(object)_toolbar, "Tier", out _tierLabel); SetRow(((Component)_tierButton).GetComponent<RectTransform>(), 0.5f, 1f, 32f, 28f, 2f); ((UnityEvent)_tierButton.onClick).AddListener((UnityAction)delegate { ToggleMenu(_tierMenu, _categoryMenu); }); _sortButton = CreateNativeButton((Transform)(object)_toolbar, "Sort", out _sortLabel); SetRow(((Component)_sortButton).GetComponent<RectTransform>(), 0f, 1f, 64f, 28f); ((UnityEvent)_sortButton.onClick).AddListener((UnityAction)delegate { RecipeFilterState.NextSort(); RefreshLabels(); RefreshRecipes(); }); _categoryMenu = CreateDropdownMenu(_categoryButton, "CategoryMenu", Array.ConvertAll(RecipeFilterState.Categories, (RecipeCategory value) => new DropdownChoice { Label = CategoryLabel(value), Select = delegate { RecipeFilterState.SetCategory(value); CloseMenus(); RefreshLabels(); RefreshRecipes(); } })); _tierMenu = CreateDropdownMenu(_tierButton, "TierMenu", Array.ConvertAll(RecipeFilterState.Tiers, (ProgressionTier value) => new DropdownChoice { Label = TierLabel(value), Select = delegate { RecipeFilterState.SetTier(value); CloseMenus(); RefreshLabels(); RefreshRecipes(); } })); } private void BuildCraftControls() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Expected O, but got Unknown RectTransform val = (((Object)(object)_gui.m_craftButton == (Object)null) ? null : ((Component)_gui.m_craftButton).GetComponent<RectTransform>()); if (!((Object)(object)val == (Object)null) && !((Object)(object)((Transform)val).parent == (Object)null)) { GameObject val2 = new GameObject("DadsEZCrafting_CraftControls", new Type[1] { typeof(RectTransform) }); _craftControls = val2.GetComponent<RectTransform>(); ((Transform)_craftControls).SetParent(((Transform)val).parent, false); ((Transform)_craftControls).SetSiblingIndex(((Transform)val).GetSiblingIndex()); CopyRect(val, _craftControls); ((Transform)val).SetParent((Transform)(object)_craftControls, false); SetSlice(val, 0.48f, 1f, 2f, 0f); RectTransform component = new GameObject("QuantitySelector", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)_craftControls, false); SetSlice(component, 0f, 0.46f, 0f, -2f); _minusButton = CreateNativeButton((Transform)(object)component, "QuantityMinus", out var label); label.text = "-"; SetSlice(((Component)_minusButton).GetComponent<RectTransform>(), 0f, 0.18f, 0f, -1f); ((UnityEvent)_minusButton.onClick).AddListener((UnityAction)delegate { ChangeQuantity(-ModifierStep()); }); Button obj = CreateNativeButton((Transform)(object)component, "Quantity", out _quantityLabel); ((Behaviour)obj).enabled = false; SetSlice(((Component)obj).GetComponent<RectTransform>(), 0.18f, 0.43f, 1f, -1f); _plusButton = CreateNativeButton((Transform)(object)component, "QuantityPlus", out var label2); label2.text = "+"; SetSlice(((Component)_plusButton).GetComponent<RectTransform>(), 0.43f, 0.61f, 1f, -1f); ((UnityEvent)_plusButton.onClick).AddListener((UnityAction)delegate { ChangeQuantity(ModifierStep()); }); _maxButton = CreateNativeButton((Transform)(object)component, "QuantityMax", out var label3); label3.text = "Max"; SetSlice(((Component)_maxButton).GetComponent<RectTransform>(), 0.61f, 1f, 1f, 0f); ((UnityEvent)_maxButton.onClick).AddListener(new UnityAction(SetMaximumQuantity)); _lastSelectedRecipe = GetSelectedRecipe(_gui); _lastUpgradeItem = GetSelectedItemData(_gui); RefreshQuantityControls(); } } private GameObject CreateDropdownMenu(Button owner, string name, IReadOnlyList<DropdownChoice> choices) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Expected O, but got Unknown GameObject val = new GameObject("DadsEZCrafting_" + name, new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(((Component)owner).transform, false); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 0f); component.pivot = new Vector2(0.5f, 1f); component.offsetMin = new Vector2(0f, -27f * (float)choices.Count); component.offsetMax = Vector2.zero; Image component2 = val.GetComponent<Image>(); CopyNativeImage(((Component)_gui.m_craftButton).GetComponent<Image>(), component2); ((Graphic)component2).color = new Color(0.16f, 0.13f, 0.11f, 1f); for (int i = 0; i < choices.Count; i++) { DropdownChoice choice = choices[i]; TMP_Text label; Button obj = CreateNativeButton((Transform)(object)component, name + "_" + i, out label); label.text = choice.Label; RectTransform component3 = ((Component)obj).GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 1f); component3.anchorMax = new Vector2(1f, 1f); component3.pivot = new Vector2(0.5f, 1f); component3.offsetMin = new Vector2(2f, -27f * (float)(i + 1) + 1f); component3.offsetMax = new Vector2(-2f, -27f * (float)i - 1f); ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { choice.Select(); }); } val.SetActive(false); return val; } private TMP_InputField CreateSearchField(Transform parent) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DadsEZCrafting_Search", new Type[3] { typeof(RectTransform), typeof(Image), typeof(TMP_InputField) }); val.transform.SetParent(parent, false); Image component = val.GetComponent<Image>(); CopyNativeImage(((Component)_gui.m_craftButton).GetComponent<Image>(), component); ((Graphic)component).color = new Color(0.3f, 0.25f, 0.21f, 0.98f); GameObject val2 = new GameObject("Text Area", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }); val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = new Vector2(8f, 2f); val3.offsetMax = new Vector2(-8f, -2f); TextMeshProUGUI val4 = CreateInputText((Transform)(object)val3, "Placeholder", new Color(0.72f, 0.68f, 0.62f, 0.78f)); ((TMP_Text)val4).text = "Search recipes..."; ((TMP_Text)val4).fontStyle = (FontStyles)2; TextMeshProUGUI textComponent = CreateInputText((Transform)(object)val3, "Text", new Color(1f, 0.72f, 0.36f, 1f)); TMP_InputField component2 = val.GetComponent<TMP_InputField>(); component2.textViewport = val3; component2.textComponent = (TMP_Text)(object)textComponent; component2.placeholder = (Graphic)(object)val4; ((Selectable)component2).targetGraphic = (Graphic)(object)component; component2.lineType = (LineType)0; component2.characterLimit = 80; return component2; } private TextMeshProUGUI CreateInputText(Transform parent, string name, Color color) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).font = _gui.m_recipeName.font; ((TMP_Text)obj).fontSize = 15f; ((Graphic)obj).color = color; ((TMP_Text)obj).alignment = (TextAlignmentOptions)4097; ((TMP_Text)obj).textWrappingMode = (TextWrappingModes)0; ((Graphic)obj).raycastTarget = false; val.SetActive(true); return obj; } private Button CreateNativeButton(Transform parent, string name, out TMP_Text label) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(((Component)_gui.m_craftButton).gameObject, parent, false); ((Object)val).name = "DadsEZCrafting_" + name; val.SetActive(true); Button component = val.GetComponent<Button>(); ((UnityEventBase)component.onClick).RemoveAllListeners(); Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component).navigation = navigation; label = val.GetComponentInChildren<TMP_Text>(true); label.enableAutoSizing = true; label.fontSizeMin = 9f; label.fontSizeMax = 14f; label.alignment = (TextAlignmentOptions)514; label.textWrappingMode = (TextWrappingModes)0; label.overflowMode = (TextOverflowModes)1; ((Graphic)label).raycastTarget = false; label.rectTransform.anchorMin = Vector2.zero; label.rectTransform.anchorMax = Vector2.one; label.rectTransform.offsetMin = new Vector2(4f, 1f); label.rectTransform.offsetMax = new Vector2(-4f, -1f); return component; } private void RefreshLabels() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_categoryLabel == (Object)null)) { _categoryLabel.text = "Type: " + RecipeFilterState.CategoryLabel() + " v"; _tierLabel.text = "Tier: " + RecipeFilterState.TierLabel() + " v"; _sortLabel.text = "Sort: " + RecipeFilterState.SortLabel(); Color white = Color.white; Color val = default(Color); ((Color)(ref val))..ctor(1f, 0.72f, 0.36f, 1f); ((Graphic)_categoryLabel).color = ((RecipeFilterState.Category == RecipeCategory.All) ? white : val); ((Graphic)_tierLabel).color = ((RecipeFilterState.Tier == ProgressionTier.All) ? white : val); ((Graphic)_sortLabel).color = ((RecipeFilterState.Sort == RecipeSort.Native) ? white : val); } } private void Update() { if (!((Object)(object)_gui == (Object)null)) { Recipe selectedRecipe = GetSelectedRecipe(_gui); ItemData selectedItemData = GetSelectedItemData(_gui); if ((Object)(object)selectedRecipe != (Object)(object)_lastSelectedRecipe || selectedItemData != _lastUpgradeItem) { _lastSelectedRecipe = selectedRecipe; _lastUpgradeItem = selectedItemData; _craftQuantity = 1; RefreshQuantityControls(); } PrepareCrafting(_gui); if (Input.GetKeyDown((KeyCode)27)) { CloseMenus(); } if (Input.GetMouseButtonDown(0) && !PointerInside((Component)(object)_categoryButton) && !PointerInside((Component)(object)_tierButton) && !PointerInside((Component)(object)(((Object)(object)_categoryMenu == (Object)null) ? null : _categoryMenu.transform)) && !PointerInside((Component)(object)(((Object)(object)_tierMenu == (Object)null) ? null : _tierMenu.transform))) { CloseMenus(); } } } private void ChangeQuantity(int delta) { if (CanSelectQuantity()) { _craftQuantity = Mathf.Clamp(_craftQuantity + delta, 1, 9999); RefreshQuantityControls(); RefreshRecipes(); } } private void SetMaximumQuantity() { if (!CanSelectQuantity()) { return; } Player localPlayer = Player.m_localPlayer; Recipe selectedRecipe = GetSelectedRecipe(_gui); int num = 1; int num2 = 0; int num3 = 1; while (num3 < 9999 && localPlayer.HaveRequirements(selectedRecipe, false, num, num3)) { num2 = num3; num3 = Math.Min(9999, num3 * 2); if (num3 == num2) { break; } } while (num2 + 1 < num3) { int num4 = num2 + (num3 - num2) / 2; if (localPlayer.HaveRequirements(selectedRecipe, false, num, num4)) { num2 = num4; } else { num3 = num4; } } if (num3 == 9999 && localPlayer.HaveRequirements(selectedRecipe, false, num, num3)) { num2 = num3; } _craftQuantity = Mathf.Max(1, num2); RefreshQuantityControls(); RefreshRecipes(); } private bool CanSelectQuantity() { if ((Object)(object)_gui != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)GetSelectedRecipe(_gui) != (Object)null) { return GetSelectedItemData(_gui) == null; } return false; } private void RefreshQuantityControls() { if (!((Object)(object)_quantityLabel == (Object)null)) { bool flag = CanSelectQuantity(); _quantityLabel.text = _craftQuantity.ToString(); ((Selectable)_minusButton).interactable = flag && _craftQuantity > 1; ((Selectable)_plusButton).interactable = flag && _craftQuantity < 9999; ((Selectable)_maxButton).interactable = flag; } } private static int ModifierStep() { if (!Input.GetKey((KeyCode)306)) { return 1; } return 10; } private static object GetSelectedPair(InventoryGui gui) { if (!((Object)(object)gui == (Object)null)) { return SelectedRecipeField.GetValue(gui); } return null; } private static Recipe GetSelectedRecipe(InventoryGui gui) { object selectedPair = GetSelectedPair(gui); if (selectedPair != null) { object? value = SelectedRecipeValueField.GetValue(selectedPair); return (Recipe)((value is Recipe) ? value : null); } return null; } private static ItemData GetSelectedItemData(InventoryGui gui) { object selectedPair = GetSelectedPair(gui); if (selectedPair != null) { object? value = SelectedItemDataValueField.GetValue(selectedPair); return (ItemData)((value is ItemData) ? value : null); } return null; } private void ToggleMenu(GameObject menu, GameObject other) { if (!((Object)(object)menu == (Object)null)) { if ((Object)(object)other != (Object)null) { other.SetActive(false); } bool flag = !menu.activeSelf; menu.SetActive(flag); if (flag) { menu.transform.parent.SetAsLastSibling(); } } } private void CloseMenus() { if ((Object)(object)_categoryMenu != (Object)null) { _categoryMenu.SetActive(false); } if ((Object)(object)_tierMenu != (Object)null) { _tierMenu.SetActive(false); } } private static bool PointerInside(Component component) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)component == (Object)null || !component.gameObject.activeInHierarchy) { return false; } RectTransform component2 = component.GetComponent<RectTransform>(); if ((Object)(object)component2 != (Object)null) { return RectTransformUtility.RectangleContainsScreenPoint(component2, Vector2.op_Implicit(Input.mousePosition)); } return false; } private static string CategoryLabel(RecipeCategory category) { if (category != RecipeCategory.Ammunition) { return category.ToString(); } return "Ammo / Throwables"; } private static string TierLabel(ProgressionTier tier) { return tier switch { ProgressionTier.All => "All Tiers", ProgressionTier.BlackForest => "Black Forest", ProgressionTier.DeepNorth => "Deep North", _ => tier.ToString(), }; } private static void CopyNativeImage(Image source, Image target) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.sprite = source.sprite; target.overrideSprite = source.overrideSprite; ((Graphic)target).material = ((Graphic)source).material; target.type = source.type; target.preserveAspect = source.preserveAspect; target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; } } private static void SetRow(RectTransform rect, float minX, float maxX, float top, float height, float left = 0f, float right = 0f) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(minX, 1f); rect.anchorMax = new Vector2(maxX, 1f); rect.pivot = new Vector2(0.5f, 1f); rect.offsetMin = new Vector2(left, 0f - top - height); rect.offsetMax = new Vector2(right, 0f - top); } private static void SetSlice(RectTransform rect, float minX, float maxX, float left, float right) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(minX, 0f); rect.anchorMax = new Vector2(maxX, 1f); rect.pivot = new Vector2(0.5f, 0.5f); rect.offsetMin = new Vector2(left, 0f); rect.offsetMax = new Vector2(right, 0f); ((Transform)rect).localScale = Vector3.one; } private static void CopyRect(RectTransform source, RectTransform target) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) target.anchorMin = source.anchorMin; target.anchorMax = source.anchorMax; target.pivot = source.pivot; target.anchoredPosition = source.anchoredPosition; target.sizeDelta = source.sizeDelta; ((Transform)target).localScale = ((Transform)source).localScale; ((Transform)target).localRotation = ((Transform)source).localRotation; } private void OnDestroy() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_viewport != (Object)null) { _viewport.offsetMax = _originalViewportOffsetMax; } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } [BepInPlugin("com.dadisbored.dadsezcrafting", "DadsEZCrafting", "1.0.0")] [BepInProcess("valheim.exe")] public sealed class DadsEZCraftingPlugin : BaseUnityPlugin { public const string PluginGuid = "com.dadisbored.dadsezcrafting"; public const string PluginName = "DadsEZCrafting"; public const string PluginVersion = "1.0.0"; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<string> BlackForestHints; internal static ConfigEntry<string> SwampHints; internal static ConfigEntry<string> MountainHints; internal static ConfigEntry<string> PlainsHints; internal static ConfigEntry<string> MistlandsHints; internal static ConfigEntry<string> AshlandsHints; internal static ConfigEntry<string> DeepNorthHints; internal static ManualLogSource ModLog; private Harmony _harmony; private void Awake() { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown ModLog = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Enable native crafting-menu search, filtering, and sorting."); BlackForestHints = BindTier("Black Forest", "Copper,CopperOre,Tin,TinOre,Bronze,BronzeNails,CoreWood,TrollHide,SurtlingCore,AncientSeed"); SwampHints = BindTier("Swamps", "Iron,IronScrap,IronOre,IronNails,AncientBark,Guck,Root,Bloodbag,Entrails,WitheredBone,Chain,Ooze,Turnip"); MountainHints = BindTier("Mountain", "Silver,SilverOre,WolfPelt,WolfFang,WolfClaw,WolfHairBundle,FreezeGland,Crystal,Obsidian,DragonTear,Onion,JuteRed,Fenring"); PlainsHints = BindTier("Plains", "BlackMetal,BlackMetalScrap,LinenThread,Flax,Barley,BarleyFlour,Tar,LoxPelt,LoxMeat,Needle,Cloudberry,GoblinTotem,VileRibcage"); MistlandsHints = BindTier("Mistlands", "Blackmarble,YggdrasilWood,Sap,Softtissue,Eitr,Carapace,Mandible,ScaleHide,Bilebag,RoyalJelly,Magecap,JotunPuffs,blackcore,GiantBloodSack,JuteBlue,MechanicalSpring,DvergrExtractor,Wisp,SealbreakerFragment"); AshlandsHints = BindTier("Ashlands", "FlametalNew,FlametalOreNew,Grausten,Ashwood,GemstoneRed,GemstoneBlue,GemstoneGreen,AskHide,AskBladder,AskSinew,BonemawTooth,CelestialFeather,CeramicPlate,CharcoalResin,CharredBone,CharredCogwheel,CharredSkull,Fiddlehead,MoltenCore,MorgenHeart,MorgenSinew,PotShard,ProustitePowder,ScrapBronze,ShieldCore,SmokePuff,Sulfur,Vineberry,BellFragment"); DeepNorthHints = BindTier("Deep North", "DeepNorth,Frostcore,LuminousLarva,Mould,Timberwood,Bloodgold,PetrifiedTissue,SealPelt,SealBlubber,MooseMeat,MooseHide,MooseSinew,ElakingHair,LongClaw,FrozenBranch,DeadPulp,Lingonberry,Kale,Snowball,FrostFoundry,NordShield,NordGreatshield,IntricateKey,EmberCharge"); RecipeFilterState.RebuildTierHints(); ConfigEntry<string>[] array = new ConfigEntry<string>[7] { BlackForestHints, SwampHints, MountainHints, PlainsHints, MistlandsHints, AshlandsHints, DeepNorthHints }; for (int i = 0; i < array.Length; i++) { array[i].SettingChanged += OnTierHintsChanged; } _harmony = new Harmony("com.dadisbored.dadsezcrafting"); CraftingPatches.Install(_harmony); ((BaseUnityPlugin)this).Logger.LogInfo((object)"DadsEZCrafting 1.0.0 loaded for Valheim 1.0.12 and BepInEx 5.4.23.5."); } private ConfigEntry<string> BindTier(string name, string defaults) { return ((BaseUnityPlugin)this).Config.Bind<string>("2 - Tier Detection", name + " Prefab Hints", defaults, "Comma-separated prefab or recipe-name fragments used to classify this progression tier."); } private static void OnTierHintsChanged(object sender, EventArgs args) { RecipeFilterState.RebuildTierHints(); CraftingUiManager.RefreshRecipes(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal enum RecipeCategory { All, Weapons, Armor, Shields, Ammunition, Food, Tools, Materials, Other } internal enum ProgressionTier { All, Meadows, BlackForest, Swamps, Mountain, Plains, Mistlands, Ashlands, DeepNorth } internal enum RecipeSort { Native, NameAscending, NameDescending, Health, Stamina, Eitr } internal static class RecipeFilterState { internal static readonly RecipeCategory[] Categories = (RecipeCategory[])Enum.GetValues(typeof(RecipeCategory)); internal static readonly ProgressionTier[] Tiers = (ProgressionTier[])Enum.GetValues(typeof(ProgressionTier)); private static readonly Dictionary<ProgressionTier, string[]> TierHints = new Dictionary<ProgressionTier, string[]>(); internal static RecipeCategory Category { get; private set; } = RecipeCategory.All; internal static ProgressionTier Tier { get; private set; } = ProgressionTier.All; internal static RecipeSort Sort { get; private set; } = RecipeSort.Native; internal static string Search { get; set; } = string.Empty; internal static void RebuildTierHints() { TierHints.Clear(); TierHints[ProgressionTier.BlackForest] = Split(DadsEZCraftingPlugin.BlackForestHints?.Value); TierHints[ProgressionTier.Swamps] = Split(DadsEZCraftingPlugin.SwampHints?.Value); TierHints[ProgressionTier.Mountain] = Split(DadsEZCraftingPlugin.MountainHints?.Value); TierHints[ProgressionTier.Plains] = Split(DadsEZCraftingPlugin.PlainsHints?.Value); TierHints[ProgressionTier.Mistlands] = Split(DadsEZCraftingPlugin.MistlandsHints?.Value); TierHints[ProgressionTier.Ashlands] = Split(DadsEZCraftingPlugin.AshlandsHints?.Value); TierHints[ProgressionTier.DeepNorth] = Split(DadsEZCraftingPlugin.DeepNorthHints?.Value); } internal static void NextCategory() { Category = Categories[(int)(Category + 1) % Categories.Length]; if (Category != RecipeCategory.Food && Sort >= RecipeSort.Health) { Sort = RecipeSort.Native; } } internal static void SetCategory(RecipeCategory category) { Category = category; if (Category != RecipeCategory.Food && Sort >= RecipeSort.Health) { Sort = RecipeSort.Native; } } internal static void NextTier() { Tier = Tiers[(int)(Tier + 1) % Tiers.Length]; } internal static void SetTier(ProgressionTier tier) { Tier = tier; } internal static void NextSort() { RecipeSort[] array = ((Category == RecipeCategory.Food) ? ((RecipeSort[])Enum.GetValues(typeof(RecipeSort))) : new RecipeSort[3] { RecipeSort.Native, RecipeSort.NameAscending, RecipeSort.NameDescending }); int num = Array.IndexOf(array, Sort); Sort = array[(num + 1 + array.Length) % array.Length]; } internal static void Apply(List<Recipe> recipes) { if (recipes != null) { recipes.RemoveAll((Recipe recipe) => !Matches(recipe)); Comparison<Recipe> comparison = GetComparison(); if (comparison != null) { recipes.Sort(comparison); } } } internal static bool Matches(Recipe recipe) { if (recipe?.m_item?.m_itemData?.m_shared == null) { return false; } if (Category != RecipeCategory.All && ClassifyCategory(recipe) != Category) { return false; } if (Tier != ProgressionTier.All && ClassifyTier(recipe) != Tier) { return false; } string text = (Search ?? string.Empty).Trim(); if (text.Length == 0) { return true; } string haystack = BuildSearchText(recipe); return text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries).All((string term) => haystack.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0); } internal static RecipeCategory ClassifyCategory(Recipe recipe) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Invalid comparison between Unknown and I4 //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Invalid comparison between Unknown and I4 //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Invalid comparison between Unknown and I4 //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Invalid comparison between Unknown and I4 //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Invalid comparison between Unknown and I4 //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Invalid comparison between Unknown and I4 SharedData val = recipe?.m_item?.m_itemData?.m_shared; if (val == null) { return RecipeCategory.Other; } if ((int)val.m_itemType == 2 && (val.m_food > 0f || val.m_foodStamina > 0f || val.m_foodEitr > 0f || val.m_foodRegen > 0f)) { return RecipeCategory.Food; } if ((int)val.m_itemType == 5) { return RecipeCategory.Shields; } if ((int)val.m_itemType == 6 || (int)val.m_itemType == 7 || (int)val.m_itemType == 11 || (int)val.m_itemType == 17) { return RecipeCategory.Armor; } if ((int)val.m_itemType == 9 || (int)val.m_itemType == 23) { return RecipeCategory.Ammunition; } if ((int)val.m_itemType == 19) { return RecipeCategory.Tools; } if ((int)val.m_itemType == 1) { return RecipeCategory.Materials; } if (recipe.m_item.m_itemData.IsWeapon()) { return RecipeCategory.Weapons; } return RecipeCategory.Other; } internal static ProgressionTier ClassifyTier(Recipe recipe) { ProgressionTier current = StationTier(recipe?.m_craftingStation); Promote(ref current, Identifier((recipe != null) ? ((Object)recipe).name : null)); object value; if (recipe == null) { value = null; } else { ItemDrop item = recipe.m_item; if (item == null) { value = null; } else { GameObject gameObject = ((Component)item).gameObject; value = ((gameObject != null) ? ((Object)gameObject).name : null); } } Promote(ref current, Identifier((string)value)); if (recipe?.m_resources != null) { Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { object value2; if (val == null) { value2 = null; } else { ItemDrop resItem = val.m_resItem; if (resItem == null) { value2 = null; } else { GameObject gameObject2 = ((Component)resItem).gameObject; value2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null); } } Promote(ref current, Identifier((string)value2)); } } if (current != ProgressionTier.All) { return current; } return ProgressionTier.Meadows; } internal static string CategoryLabel() { if (Category == RecipeCategory.Ammunition) { return "Ammo / Throwables"; } return Category.ToString(); } internal static string TierLabel() { return Tier switch { ProgressionTier.All => "All Tiers", ProgressionTier.BlackForest => "Black Forest", ProgressionTier.DeepNorth => "Deep North", _ => Tier.ToString(), }; } internal static string SortLabel() { return Sort switch { RecipeSort.NameAscending => "Name A-Z", RecipeSort.NameDescending => "Name Z-A", _ => Sort.ToString(), }; } private static Comparison<Recipe> GetComparison() { return Sort switch { RecipeSort.NameAscending => (Recipe left, Recipe right) => CompareNames(left, right), RecipeSort.NameDescending => (Recipe left, Recipe right) => CompareNames(right, left), RecipeSort.Health => (Recipe left, Recipe right) => CompareFoodDescending(left, right, (ItemData item) => item.m_shared.m_food), RecipeSort.Stamina => (Recipe left, Recipe right) => CompareFoodDescending(left, right, (ItemData item) => item.m_shared.m_foodStamina), RecipeSort.Eitr => (Recipe left, Recipe right) => CompareFoodDescending(left, right, (ItemData item) => item.m_shared.m_foodEitr), _ => null, }; } private static int CompareFoodDescending(Recipe left, Recipe right, Func<ItemData, float> selector) { float value = ((left?.m_item?.m_itemData == null) ? 0f : selector(left.m_item.m_itemData)); int num = ((right?.m_item?.m_itemData == null) ? 0f : selector(right.m_item.m_itemData)).CompareTo(value); if (num == 0) { return CompareNames(left, right); } return num; } private static int CompareNames(Recipe left, Recipe right) { return StringComparer.CurrentCultureIgnoreCase.Compare(ItemName(left), ItemName(right)); } private static string ItemName(Recipe recipe) { string text = recipe?.m_item?.m_itemData?.m_shared?.m_name ?? string.Empty; if (Localization.instance != null) { return Localization.instance.Localize(text); } return text; } private static string BuildSearchText(Recipe recipe) { List<string> obj = new List<string> { ItemName(recipe), ((recipe != null) ? ((Object)recipe).name : null) ?? string.Empty }; object obj2; if (recipe == null) { obj2 = null; } else { ItemDrop item = recipe.m_item; if (item == null) { obj2 = null; } else { GameObject gameObject = ((Component)item).gameObject; obj2 = ((gameObject != null) ? ((Object)gameObject).name : null); } } if (obj2 == null) { obj2 = string.Empty; } obj.Add((string)obj2); obj.Add(Localize(recipe?.m_item?.m_itemData?.m_shared?.m_description)); List<string> list = obj; if (recipe?.m_resources != null) { Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { object obj3; if (val == null) { obj3 = null; } else { ItemDrop resItem = val.m_resItem; if (resItem == null) { obj3 = null; } else { GameObject gameObject2 = ((Component)resItem).gameObject; obj3 = ((gameObject2 != null) ? ((Object)gameObject2).name : null); } } if (obj3 == null) { obj3 = string.Empty; } list.Add((string)obj3); list.Add(Localize(val?.m_resItem?.m_itemData?.m_shared?.m_name)); } } return string.Join(" ", list); } private static string Localize(string text) { if (Localization.instance != null) { return Localization.instance.Localize(text ?? string.Empty); } return text ?? string.Empty; } private static ProgressionTier StationTier(CraftingStation station) { object value; if (station == null) { value = null; } else { GameObject gameObject = ((Component)station).gameObject; value = ((gameObject != null) ? ((Object)gameObject).name : null); } string text = Identifier((string)value); if (text.Contains("frostfoundry")) { return ProgressionTier.DeepNorth; } if (text.Contains("blackforge") || text.Contains("galdrtable")) { return ProgressionTier.Mistlands; } if (text.Contains("artisan")) { return ProgressionTier.Plains; } if (text.Contains("stonecutter")) { return ProgressionTier.Swamps; } if (text.Contains("forge")) { return ProgressionTier.BlackForest; } return ProgressionTier.Meadows; } private static void Promote(ref ProgressionTier current, string identifier) { if (identifier.Length == 0) { return; } for (ProgressionTier progressionTier = ProgressionTier.DeepNorth; progressionTier >= ProgressionTier.BlackForest; progressionTier--) { if (TierHints.TryGetValue(progressionTier, out var value) && value.Any(identifier.Contains)) { if (progressionTier > current) { current = progressionTier; } break; } } } private static string Identifier(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } return new string(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray()); } private static string[] Split(string value) { return (from item in (value ?? string.Empty).Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries).Select(Identifier) where item.Length > 0 select item).Distinct<string>(StringComparer.Ordinal).ToArray(); } } }