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 ValheimRecycle v5.0.7
plugins/ValheimRecycle.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValheimRecycle")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValheimRecycle")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("fb50dee1-4008-48a0-a8c1-721c194137b1")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace ValheimRecycle { public static class RecycleConfig { public enum TabPositions { Left, Middle, Right } } [HarmonyPatch(typeof(InventoryGui))] public class InventoryGuiPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<ItemData, int> <>9__5_0; public static Func<ItemData, int> <>9__5_1; public static Func<ItemData, int> <>9__8_0; public static Func<ItemData, int> <>9__8_1; public static PopupButtonCallback <>9__8_3; internal int <PostfixUpdateRecipeList>b__5_0(ItemData item) { return ((object)item).GetHashCode(); } internal int <PostfixUpdateRecipeList>b__5_1(ItemData item) { return ((object)item).GetHashCode(); } internal int <PrefixOnCraftPressed>b__8_0(ItemData item) { return ((object)item).GetHashCode(); } internal int <PrefixOnCraftPressed>b__8_1(ItemData item) { return ((object)item).GetHashCode(); } internal void <PrefixOnCraftPressed>b__8_3() { UnifiedPopup.Pop(); } } internal static bool skipPopup; [HarmonyPostfix] [HarmonyPatch("Update")] internal static void PostfixUpdate(InventoryGui __instance) { ValheimRecycle.instance?.RebuildRecycleTab(); } [HarmonyPrefix] [HarmonyPatch("OnTabCraftPressed")] internal static bool PrefixOnTabCraftPressed(InventoryGui __instance) { ValheimRecycle.IsRecycleTabActive = false; ((Selectable)ValheimRecycle.instance.recycleButton).interactable = true; return true; } [HarmonyPrefix] [HarmonyPatch("OnTabUpgradePressed")] internal static bool PrefixOnTabUpgradePressed(InventoryGui __instance) { ValheimRecycle.IsRecycleTabActive = false; ((Selectable)ValheimRecycle.instance.recycleButton).interactable = true; return true; } [HarmonyPostfix] [HarmonyPatch("SetupRequirement")] internal static void PostfixSetupRequirement(Transform elementRoot, Requirement req, int quality) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!((Component)elementRoot).gameObject.activeSelf) { ((Component)elementRoot).gameObject.SetActive(true); } if (ValheimRecycle.instance.InTabDeconstruct()) { TMP_Text component = ((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent<TMP_Text>(); component.text = Utils.GetModifiedAmount(quality, req).ToString(); ((Graphic)component).color = Color.green; } } [HarmonyPostfix] [HarmonyPatch("UpdateCraftingPanel")] internal static void PostfixUpdateCraftingPanel(InventoryGui __instance, bool focusView) { if ((Object)(object)ValheimRecycle.instance == (Object)null || (Object)(object)ValheimRecycle.instance.recycleObject == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer.GetCurrentCraftingStation()) && ((Object)((Component)localPlayer.GetCurrentCraftingStation()).gameObject).name.Contains("cauldron")) { ValheimRecycle.instance.recycleObject.SetActive(false); if ((Object)(object)ValheimRecycle.instance.toggleEquippedObject != (Object)null) { ValheimRecycle.instance.toggleEquippedObject.SetActive(false); } ((Selectable)ValheimRecycle.instance.recycleButton).interactable = true; if (ValheimRecycle.IsRecycleTabActive) { ValheimRecycle.IsRecycleTabActive = false; } return; } ValheimRecycle.instance.recycleObject.SetActive(((Component)__instance.m_tabUpgrade).gameObject.activeSelf); if (ValheimRecycle.IsRecycleTabActive) { ((Selectable)__instance.m_tabUpgrade).interactable = true; ((Selectable)__instance.m_tabCraft).interactable = true; ((Selectable)ValheimRecycle.instance.recycleButton).interactable = false; if ((Object)(object)ValheimRecycle.instance.toggleEquippedObject != (Object)null) { ValheimRecycle.instance.toggleEquippedObject.SetActive(true); } } else { ((Selectable)ValheimRecycle.instance.recycleButton).interactable = true; if ((Object)(object)ValheimRecycle.instance.toggleEquippedObject != (Object)null) { ValheimRecycle.instance.toggleEquippedObject.SetActive(false); } } } [HarmonyPostfix] [HarmonyPatch("UpdateRecipeList")] internal static void PostfixUpdateRecipeList(InventoryGui __instance, List<Recipe> recipes) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) if (!ValheimRecycle.instance.InTabDeconstruct()) { return; } Player localPlayer = Player.m_localPlayer; Inventory inventory = ((Humanoid)localPlayer).GetInventory(); foreach (RecipeDataPair availableRecipe in __instance.m_availableRecipes) { RecipeDataPair current = availableRecipe; Object.Destroy((Object)(object)((RecipeDataPair)(ref current)).InterfaceElement); } __instance.m_availableRecipes.Clear(); List<KeyValuePair<Recipe, ItemData>> list = new List<KeyValuePair<Recipe, ItemData>>(); for (int i = 0; i < recipes.Count; i++) { Recipe val = recipes[i]; if (val.m_item.m_itemData.m_shared.m_maxQuality < 1) { continue; } __instance.m_tempItemList.Clear(); if (val.m_item.m_itemData.m_shared.m_maxStackSize == 1) { inventory.GetAllItems(val.m_item.m_itemData.m_shared.m_name, __instance.m_tempItemList); } else { for (int j = 0; j < inventory.m_inventory.Count; j++) { if (inventory.m_inventory[j].m_shared.m_name.Equals(val.m_item.m_itemData.m_shared.m_name) && inventory.m_inventory[j].m_stack >= val.m_amount) { __instance.m_tempItemList.Add(inventory.m_inventory[j]); break; } } } foreach (ItemData tempItem in __instance.m_tempItemList) { if (tempItem.m_quality >= 1) { list.Add(new KeyValuePair<Recipe, ItemData>(val, tempItem)); } } } List<int> equipped = (from item in inventory.GetEquippedItems() select ((object)item).GetHashCode()).ToList(); List<ItemData> list2 = new List<ItemData>(); inventory.GetBoundItems(list2); List<int> hotbarItemsHashes = list2.Select((ItemData item) => ((object)item).GetHashCode()).ToList(); if (!ValheimRecycle.instance.showEquippedAndHotbar.Value) { list.RemoveAll((KeyValuePair<Recipe, ItemData> x) => equipped.Contains(((object)x.Value).GetHashCode()) || hotbarItemsHashes.Contains(((object)x.Value).GetHashCode())); } list.Sort(delegate(KeyValuePair<Recipe, ItemData> a, KeyValuePair<Recipe, ItemData> b) { bool flag4 = equipped.Contains(((object)a.Value).GetHashCode()) || hotbarItemsHashes.Contains(((object)a.Value).GetHashCode()); bool value2 = equipped.Contains(((object)b.Value).GetHashCode()) || hotbarItemsHashes.Contains(((object)b.Value).GetHashCode()); return flag4.CompareTo(value2); }); CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation(); foreach (KeyValuePair<Recipe, ItemData> item in list) { Recipe key = item.Key; ItemData value = item.Value; int num = value?.m_quality ?? 1; CraftingStation requiredStation = key.GetRequiredStation(num); int requiredStationLevel = key.GetRequiredStationLevel(num); bool num2 = (Object)(object)requiredStation == (Object)null || ((Object)(object)currentCraftingStation != (Object)null && currentCraftingStation.CheckUsable(localPlayer, false) && currentCraftingStation.GetLevel(true) >= requiredStationLevel); int num3 = ((value == null) ? 1 : ((value.m_quality >= 1) ? (value.m_quality - 1) : 0)); bool flag = Utils.HaveEmptySlotsForRecipe(inventory, key, num3 + 1); bool flag2 = equipped.Contains(((object)value).GetHashCode()) || hotbarItemsHashes.Contains(((object)value).GetHashCode()); bool flag3 = (num2 || localPlayer.NoCostCheat()) && flag; __instance.AddRecipeToList(localPlayer, key, value, flag3); if (value == null || __instance.m_availableRecipes.Count <= 0) { continue; } RecipeDataPair val2 = __instance.m_availableRecipes[__instance.m_availableRecipes.Count - 1]; Image component = ((Component)((RecipeDataPair)(ref val2)).InterfaceElement.transform.Find("icon")).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { component.sprite = value.GetIcon(); } if (!flag2) { continue; } TMP_Text component2 = ((Component)((RecipeDataPair)(ref val2)).InterfaceElement.transform.Find("name")).GetComponent<TMP_Text>(); if ((Object)(object)component2 != (Object)null) { if (equipped.Contains(((object)value).GetHashCode())) { component2.text += " <color=yellow>(Equipped)</color>"; } else { component2.text += " <color=yellow>(Hotbar)</color>"; } } } float num4 = (float)__instance.m_availableRecipes.Count * __instance.m_recipeListSpace; num4 = Mathf.Max(__instance.m_recipeListBaseSize, num4); __instance.m_recipeListRoot.SetSizeWithCurrentAnchors((Axis)1, num4); } [HarmonyPostfix] [HarmonyPatch("UpdateRecipe")] internal static void PostfixUpdateRecipe(InventoryGui __instance, Player player, float dt) { //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) if (ValheimRecycle.instance.InTabDeconstruct() && Object.op_Implicit((Object)(object)((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe)) { ItemData itemData = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).ItemData; int num = ((itemData == null) ? 1 : ((itemData.m_quality >= 1) ? (itemData.m_quality - 1) : 0)); bool flag = num <= ((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe.m_item.m_itemData.m_shared.m_maxQuality; bool flag2 = Utils.HaveEmptySlotsForRecipe(((Humanoid)player).GetInventory(), ((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe, num + 1); CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); int num2 = itemData?.m_quality ?? 1; CraftingStation requiredStation = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe.GetRequiredStation(num2); int requiredStationLevel = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe.GetRequiredStationLevel(num2); bool flag3 = (Object)(object)requiredStation == (Object)null || ((Object)(object)currentCraftingStation != (Object)null && currentCraftingStation.CheckUsable(player, false) && currentCraftingStation.GetLevel(true) >= requiredStationLevel); if ((Object)(object)requiredStation != (Object)null && flag) { ((Component)__instance.m_minStationLevelIcon).gameObject.SetActive(true); __instance.m_minStationLevelText.text = requiredStationLevel.ToString(); if ((Object)(object)currentCraftingStation == (Object)null || currentCraftingStation.GetLevel(true) < requiredStationLevel) { ((Graphic)__instance.m_minStationLevelText).color = ((Mathf.Sin(Time.time * 10f) > 0f) ? Color.red : __instance.m_minStationLevelBasecolor); } else { ((Graphic)__instance.m_minStationLevelText).color = __instance.m_minStationLevelBasecolor; } } else { ((Component)__instance.m_minStationLevelIcon).gameObject.SetActive(false); } if (itemData != null && itemData.m_quality == 1) { ((Behaviour)__instance.m_recipeDecription).enabled = false; } string text = Localization.instance.Localize(((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe.m_item.m_itemData.m_shared.m_name); if (((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe.m_amount > 1) { text = text + " x" + ((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe.m_amount; } __instance.m_recipeName.text = text; if (itemData != null) { ((Component)__instance.m_itemCraftType).gameObject.SetActive(true); if (itemData.m_quality <= 1) { __instance.m_itemCraftType.text = "Item will be recycled"; } else { string text2 = Localization.instance.Localize(itemData.m_shared.m_name); __instance.m_itemCraftType.text = "Downgrade " + text2 + " quality to " + (itemData.m_quality - 1); } } Recipe recipe = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe; Requirement[] resources = recipe.m_resources; List<Requirement> list = new List<Requirement>(); bool flag4 = false; Requirement[] array = resources; foreach (Requirement val in array) { if (!val.m_upgraderResource && !(recipe.m_requireOnlyOneIngredient && flag4)) { list.Add(val); flag4 = true; } } recipe.m_resources = list.ToArray(); __instance.SetupRequirementList(num + 1, player, flag, 1); recipe.m_resources = resources; ((Selectable)__instance.m_craftButton).interactable = (flag3 || player.NoCostCheat()) && flag2 && flag; ((Component)__instance.m_craftButton).GetComponentInChildren<TMP_Text>().text = "Recycle"; TMP_Text componentInChildren = ((Component)__instance.m_craftProgressPanel).GetComponentInChildren<TMP_Text>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = "Recycling..."; } UITooltip component = ((Component)__instance.m_craftButton).GetComponent<UITooltip>(); if (!flag2) { component.m_text = Localization.instance.Localize("$inventory_full"); } else if (!flag3) { if ((Object)(object)currentCraftingStation != (Object)null && currentCraftingStation.CheckUsable(player, false) && currentCraftingStation.GetLevel(true) < requiredStationLevel) { component.m_text = "Workstation level too low"; } else { component.m_text = Localization.instance.Localize("$msg_missingstation"); } } else { component.m_text = ""; } } else if ((Object)(object)__instance.m_craftProgressPanel != (Object)null) { TMP_Text componentInChildren2 = ((Component)__instance.m_craftProgressPanel).GetComponentInChildren<TMP_Text>(); if ((Object)(object)componentInChildren2 != (Object)null && componentInChildren2.text == "Recycling...") { componentInChildren2.text = Localization.instance.Localize("$inventory_crafting"); } } } [HarmonyPrefix] [HarmonyPatch("OnCraftPressed")] internal static bool PrefixOnCraftPressed(InventoryGui __instance) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown if (ValheimRecycle.instance.InTabDeconstruct() && !skipPopup) { if ((Object)(object)((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe == (Object)null || ((RecipeDataPair)(ref __instance.m_selectedRecipe)).ItemData == null) { return true; } Player localPlayer = Player.m_localPlayer; ItemData itemData = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).ItemData; List<int> list = (from item in ((Humanoid)localPlayer).GetInventory().GetEquippedItems() select ((object)item).GetHashCode()).ToList(); List<ItemData> list2 = new List<ItemData>(); ((Humanoid)localPlayer).GetInventory().GetBoundItems(list2); List<int> list3 = list2.Select((ItemData item) => ((object)item).GetHashCode()).ToList(); if (list.Contains(((object)itemData).GetHashCode()) || list3.Contains(((object)itemData).GetHashCode())) { PopupButtonCallback val = delegate { skipPopup = true; ((UnityEvent)__instance.m_craftButton.onClick).Invoke(); skipPopup = false; UnifiedPopup.Pop(); }; object obj = <>c.<>9__8_3; if (obj == null) { PopupButtonCallback val2 = delegate { UnifiedPopup.Pop(); }; <>c.<>9__8_3 = val2; obj = (object)val2; } UnifiedPopup.Push((PopupBase)new YesNoPopup("Recycle Item", "This item is currently equipped or in your hotbar.\nAre you sure you want to recycle it?", val, (PopupButtonCallback)obj, false, false)); return false; } } return true; } [HarmonyPrefix] [HarmonyPatch("DoCrafting")] internal static bool PrefixDoCrafting(InventoryGui __instance, Player player) { if (ValheimRecycle.instance.InTabDeconstruct()) { Utils.DoRecycle(player, __instance); return false; } return true; } } public class Utils { public static int GetModifiedAmount(int quality, Requirement requirement) { return (int)Math.Round(ValheimRecycle.instance.resourceMultiplier.Value * (float)requirement.GetAmount(quality), 0); } public static bool HaveEmptySlotsForRecipe(Inventory inventory, Recipe recipe, int quality) { int emptySlots = inventory.GetEmptySlots(); int num = 0; Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if (!Object.op_Implicit((Object)(object)val.m_resItem) || val.m_upgraderResource) { continue; } int modifiedAmount = GetModifiedAmount(quality, val); if (modifiedAmount > 0) { int num2 = inventory.FindFreeStackSpace(val.m_resItem.m_itemData.m_shared.m_name, (float)val.m_resItem.m_itemData.m_worldLevel); int num3 = Mathf.Max(0, modifiedAmount - num2); if (num3 > 0) { int maxStackSize = val.m_resItem.m_itemData.m_shared.m_maxStackSize; num += Mathf.CeilToInt((float)num3 / (float)maxStackSize); } } if (recipe.m_requireOnlyOneIngredient) { break; } } return emptySlots >= num; } public static void AddResources(Inventory inventory, Recipe recipe, int qualityLevel) { Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if (Object.op_Implicit((Object)(object)val.m_resItem) && !val.m_upgraderResource) { int modifiedAmount = GetModifiedAmount(qualityLevel + 1, val); if (modifiedAmount > 0) { Debug.Log((object)("Adding item: " + ((Object)val.m_resItem).name)); Debug.Log((object)("Amount: " + val.GetAmount(qualityLevel + 1))); inventory.AddItem(((Object)val.m_resItem).name, modifiedAmount, val.m_resItem.m_itemData.m_quality, val.m_resItem.m_itemData.m_variant, 0L, "", false, false); } if (recipe.m_requireOnlyOneIngredient) { break; } } } } internal static void DoRecycle(Player player, InventoryGui __instance) { //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.m_craftRecipe == (Object)null) { return; } int num = ((__instance.m_craftUpgradeItem != null) ? (__instance.m_craftUpgradeItem.m_quality - 1) : 0); if ((__instance.m_craftUpgradeItem != null && !((Humanoid)player).GetInventory().ContainsItem(__instance.m_craftUpgradeItem)) || (__instance.m_craftUpgradeItem == null && HaveEmptySlotsForRecipe(((Humanoid)player).GetInventory(), __instance.m_craftRecipe, num + 1))) { return; } int variant = __instance.m_craftUpgradeItem.m_variant; long playerID = player.GetPlayerID(); string playerName = player.GetPlayerName(); if (__instance.m_craftUpgradeItem != null) { if (num >= 1) { ((Humanoid)player).UnequipItem(__instance.m_craftUpgradeItem, true); if (ValheimRecycle.instance.preserveOriginalItem.Value) { __instance.m_craftUpgradeItem.m_quality = num; } else { ((Humanoid)player).GetInventory().RemoveItem(__instance.m_craftUpgradeItem); ((Humanoid)player).GetInventory().AddItem(((Object)((Component)__instance.m_craftRecipe.m_item).gameObject).name, __instance.m_craftRecipe.m_amount, num, variant, playerID, playerName, false, false); } } else { ((Humanoid)player).UnequipItem(__instance.m_craftUpgradeItem, true); ((Humanoid)player).GetInventory().RemoveItem(__instance.m_craftUpgradeItem, __instance.m_craftRecipe.m_amount); } } AddResources(((Humanoid)player).GetInventory(), __instance.m_craftRecipe, num); __instance.UpdateCraftingPanel(true); CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation(); if (Object.op_Implicit((Object)(object)currentCraftingStation)) { currentCraftingStation.m_craftItemDoneEffects.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } else { __instance.m_craftItemDoneEffects.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } } } [BepInPlugin("org.lafchi.plugins.valheim_recycle", "Valheim Recycle", "5.0.7")] [BepInProcess("valheim.exe")] public class ValheimRecycle : BaseUnityPlugin { internal static ValheimRecycle instance; internal GameObject recycleObject; internal Button recycleButton; internal GameObject toggleEquippedObject; internal Button toggleEquippedButton; internal float width; private Vector3 craftingPos; private Harmony harmony; internal ConfigEntry<RecycleConfig.TabPositions> tabPosition; internal ConfigEntry<float> resourceMultiplier; internal ConfigEntry<bool> preserveOriginalItem; internal ConfigEntry<int> nexusID; internal ConfigEntry<bool> showEquippedAndHotbar; internal static bool IsRecycleTabActive; internal bool InTabDeconstruct() { if (IsRecycleTabActive) { return InventoryGui.IsVisible(); } return false; } internal void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown ((BaseUnityPlugin)this).Logger.LogInfo((object)"AWAKE - ValheimRecycle 5.0.7"); instance = this; harmony = new Harmony("org.lafchi.plugins.valheim_recycle"); harmony.PatchAll(); tabPosition = ((BaseUnityPlugin)this).Config.Bind<RecycleConfig.TabPositions>("General", "TabPosition", RecycleConfig.TabPositions.Left, "The Recycle tab's position in the crafting menu after Upgrade. (Requires restart)"); resourceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ResourceMultiplier", 1f, new ConfigDescription("The amount of resources to return from recycling (0 to 1, where 1 returns 100% of the resources and 0 returns 0%)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); preserveOriginalItem = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PreserveOriginalItem", true, "Whether the original item's data should be preserved when downgrading. Useful for mods which add extra properties to items like EpicLoot.\nTurn off if experiencing problems."); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 425, "Nexus mod ID for updates"); showEquippedAndHotbar = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowEquippedAndHotbar", true, "Whether to show equipped and hotbar items in the recycle list."); } internal void OnDestroy() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"DESTROY"); Object.Destroy((Object)(object)recycleObject); harmony.UnpatchSelf(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Unpatched InventoryGui"); } internal GameObject GetOrCreateRecycleTab() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_0101: Expected O, but got Unknown //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_0213: 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_02ad: Expected O, but got Unknown //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Expected O, but got Unknown //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)instance.recycleObject != (Object)null) { return instance.recycleObject; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"CreateRecycleButton"); recycleObject = Object.Instantiate<GameObject>(((Component)InventoryGui.instance.m_tabUpgrade).gameObject, ((Component)InventoryGui.instance.m_tabUpgrade).gameObject.transform.parent, false); if (recycleObject == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"RecycletButton couldn't be instantiated."); return null; } ((Object)recycleObject).name = "Recycle"; recycleObject.GetComponentInChildren<TMP_Text>().text = "RECYCLE"; Rect rect = recycleObject.GetComponent<RectTransform>().rect; width = ((Rect)(ref rect)).width; float num = ((Component)InventoryGui.instance.m_tabUpgrade).transform.localPosition.x; foreach (Transform item in ((Component)InventoryGui.instance.m_tabUpgrade).transform.parent) { Transform val = item; if (!((Object)(object)val == (Object)(object)recycleObject.transform) && ((Component)val).gameObject.activeSelf && (Object)(object)((Component)val).GetComponent<Button>() != (Object)null) { num = Mathf.Max(num, val.localPosition.x); } } float num2 = (float)tabPosition.Value * (width + 10f); craftingPos = new Vector3(num + width + 10f + num2, ((Component)InventoryGui.instance.m_tabUpgrade).transform.localPosition.y, ((Component)InventoryGui.instance.m_tabUpgrade).transform.localPosition.z); recycleButton = recycleObject.GetComponent<Button>(); ((UnityEventBase)recycleButton.onClick).RemoveAllListeners(); ((UnityEvent)recycleButton.onClick).AddListener(new UnityAction(SelectRecycleTab)); ((Component)recycleButton).transform.localPosition = craftingPos; ((Selectable)recycleButton).interactable = true; ((Object)recycleButton).name = "RecycleButton"; recycleObject.SetActive(false); if ((Object)(object)toggleEquippedObject == (Object)null) { toggleEquippedObject = Object.Instantiate<GameObject>(recycleObject, ((Component)InventoryGui.instance.m_craftButton).transform.parent, false); ((Object)toggleEquippedObject).name = "ToggleEquipped"; toggleEquippedButton = toggleEquippedObject.GetComponent<Button>(); toggleEquippedButton.onClick = new ButtonClickedEvent(); ((UnityEvent)toggleEquippedButton.onClick).AddListener(new UnityAction(ToggleEquipped)); toggleEquippedObject.transform.localPosition = new Vector3(140f, -45f, 0f); toggleEquippedObject.GetComponent<RectTransform>().sizeDelta = new Vector2(160f, 30f); } UpdateToggleText(); toggleEquippedObject.SetActive(false); return recycleObject; } internal void SelectRecycleTab() { ((BaseUnityPlugin)this).Logger.LogDebug((object)"Selected recycle"); IsRecycleTabActive = true; ((Selectable)recycleButton).interactable = false; ((Selectable)InventoryGui.m_instance.m_tabCraft).interactable = true; ((Selectable)InventoryGui.m_instance.m_tabUpgrade).interactable = true; InventoryGui.m_instance.UpdateCraftingPanel(false); } internal void ToggleEquipped() { showEquippedAndHotbar.Value = !showEquippedAndHotbar.Value; ((BaseUnityPlugin)this).Config.Save(); UpdateToggleText(); InventoryGui.m_instance.UpdateCraftingPanel(false); } internal void UpdateToggleText() { if ((Object)(object)toggleEquippedObject != (Object)null) { TMP_Text componentInChildren = toggleEquippedObject.GetComponentInChildren<TMP_Text>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = (showEquippedAndHotbar.Value ? "[X] Include Equipped" : "[ ] Include Equipped"); componentInChildren.fontSize = 16f; componentInChildren.alignment = (TextAlignmentOptions)516; } } } internal void RebuildRecycleTab() { GetOrCreateRecycleTab(); } } } namespace ValheimRecycle.GameClasses { [HarmonyPatch(typeof(Humanoid))] internal class HumanoidPatch { [HarmonyPatch("EquipItem")] [HarmonyPostfix] private static void EquipItem(Humanoid __instance, ItemData item, bool triggerEquipEffects = true) { if (((Character)__instance).IsPlayer()) { InventoryGui instance = InventoryGui.instance; if (instance != null) { instance.UpdateCraftingPanel(false); } } } [HarmonyPatch("UnequipItem")] [HarmonyPostfix] private static void UnequipItem(Humanoid __instance, ItemData item, bool triggerEquipEffects = true) { if (((Character)__instance).IsPlayer()) { InventoryGui instance = InventoryGui.instance; if (instance != null) { instance.UpdateCraftingPanel(false); } } } } }