Decompiled source of ValheimRecycle v5.0.7

plugins/ValheimRecycle.dll

Decompiled 2 weeks ago
using 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);
				}
			}
		}
	}
}