Decompiled source of RecycleItemsIntoParts v1.7.3

RecycleItemsIntoParts.dll

Decompiled a week ago
using 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.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.7.2")]
[assembly: AssemblyInformationalVersion("1.7.2+7d943c5bc2542a9a952bef1d9cde32c5ed2980e5")]
[assembly: AssemblyVersion("1.7.2.0")]
namespace DiscardInventoryItem;

[BepInPlugin("cjayride.RecycleItemsIntoParts", "Recycle Items Into Parts", "1.7.2")]
public class BepInExPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(InventoryGui), "UpdateItemDrag")]
	private static class UpdateItemDrag_Patch
	{
		private static void Postfix(InventoryGui __instance, ItemData ___m_dragItem, Inventory ___m_dragInventory, int ___m_dragAmount, ref GameObject ___m_dragGo)
		{
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Expected O, but got Unknown
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Invalid comparison between Unknown and I4
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0545: Unknown result type (might be due to invalid IL or missing references)
			//IL_0549: Invalid comparison between Unknown and I4
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Invalid comparison between Unknown and I4
			//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05de: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0601: Unknown result type (might be due to invalid IL or missing references)
			if (!modEnabled.Value || !Input.GetKeyDown(hotKey.Value) || ___m_dragItem == null || !___m_dragInventory.ContainsItem(___m_dragItem))
			{
				return;
			}
			Dbgl($"Discarding {___m_dragAmount}/{___m_dragItem.m_stack} {((Object)___m_dragItem.m_dropPrefab).name}");
			bool flag = false;
			bool flag2 = false;
			if (!(returnResources.Value > 0f))
			{
				return;
			}
			Recipe recipe = ObjectDB.instance.GetRecipe(___m_dragItem);
			if ((Object)(object)recipe != (Object)null && (returnUnknownResources.Value || Player.m_localPlayer.IsRecipeKnown(___m_dragItem.m_shared.m_name)))
			{
				Dbgl($"Recipe stack: {recipe.m_amount} num of stacks: {___m_dragAmount / recipe.m_amount}");
				List<Requirement> list = recipe.m_resources.ToList();
				if (ObjectDB.instance.GetRecipe(___m_dragItem).m_item.m_itemData.m_shared.m_name.ToString() == "Magic $mod_epicloot_assets_shard")
				{
					flag2 = true;
				}
				if (((object)Unsafe.As<ItemType, ItemType>(ref ObjectDB.instance.GetRecipe(___m_dragItem).m_item.m_itemData.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString() == "Consumable")
				{
					flag = true;
				}
				if (flag2 && !recycleShards.Value)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "Cannot recycle shards.", 0, (Sprite)null, false);
					return;
				}
				if (flag && !recycleConsumables.Value)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "Cannot recycle consumables.", 0, (Sprite)null, false);
				}
				else
				{
					bool flag3 = false;
					bool flag4 = false;
					if (epicLootAssembly != null && returnEnchantedResources.Value)
					{
						MethodInfo? method = epicLootAssembly.GetType("EpicLoot.ItemDataExtensions").GetMethod("IsMagic", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null);
						object[] parameters = (object[])(object)new ItemData[1] { ___m_dragItem };
						flag3 = (bool)method.Invoke(null, parameters);
					}
					if (flag3)
					{
						MethodInfo? method2 = epicLootAssembly.GetType("EpicLoot.ItemDataExtensions").GetMethod("GetRarity", BindingFlags.Static | BindingFlags.Public);
						object[] parameters = (object[])(object)new ItemData[1] { ___m_dragItem };
						int num = (int)method2.Invoke(null, parameters);
						foreach (KeyValuePair<ItemDrop, int> item in (List<KeyValuePair<ItemDrop, int>>)epicLootAssembly.GetType("EpicLoot.Crafting.EnchantHelper").GetMethod("GetEnchantCosts", BindingFlags.Static | BindingFlags.Public).Invoke(null, new object[2] { ___m_dragItem, num }))
						{
							if (!returnUnknownResources.Value && ((Object.op_Implicit((Object)(object)ObjectDB.instance.GetRecipe(item.Key.m_itemData)) && !Player.m_localPlayer.IsRecipeKnown(item.Key.m_itemData.m_shared.m_name)) || !Traverse.Create((object)Player.m_localPlayer).Field("m_knownMaterial").GetValue<HashSet<string>>()
								.Contains(item.Key.m_itemData.m_shared.m_name)))
							{
								((Character)Player.m_localPlayer).Message((MessageType)2, "You don't know all the recipes for this item's materials.", 0, (Sprite)null, false);
								return;
							}
							list.Add(new Requirement
							{
								m_amount = item.Value,
								m_resItem = item.Key
							});
						}
					}
					if (!flag4 && ___m_dragAmount / recipe.m_amount > 0)
					{
						int num2 = 0;
						int index = 0;
						bool flag5 = false;
						foreach (Requirement item2 in list)
						{
							if (item2.m_resItem.m_itemData.m_shared.m_name == "$item_coins" && !recycleCoins.Value)
							{
								index = num2;
								flag5 = true;
								break;
							}
							if ((int)item2.m_resItem.m_itemData.m_shared.m_itemType == 13 && !recycleTrophy.Value)
							{
								index = num2;
								flag5 = true;
								break;
							}
						}
						if (flag5)
						{
							list.RemoveAt(index);
						}
						list.RemoveAll(IsUpgradeOnlyResource);
						for (int i = 0; i < ___m_dragAmount / recipe.m_amount; i++)
						{
							foreach (Requirement item3 in list)
							{
								for (int num3 = ___m_dragItem.m_quality; num3 > 0; num3--)
								{
									GameObject requirementPrefab = GetRequirementPrefab(item3);
									if (!((Object)(object)requirementPrefab == (Object)null))
									{
										ItemDrop component = requirementPrefab.GetComponent<ItemDrop>();
										if (!((Object)(object)component == (Object)null))
										{
											ItemData itemData = component.m_itemData.Clone();
											int num4 = Mathf.RoundToInt((float)item3.GetAmount(num3) * returnResources.Value);
											Dbgl($"Returning {num4}/{item3.GetAmount(num3)} {((Object)requirementPrefab).name}");
											while (num4 > 0)
											{
												int num5 = Mathf.Min(item3.m_resItem.m_itemData.m_shared.m_maxStackSize, num4);
												num4 -= num5;
												ItemType itemType = item3.m_resItem.m_itemData.m_shared.m_itemType;
												if (((((Object)requirementPrefab).name == "Coins" && recycleCoins.Value) || ((int)itemType == 13 && recycleTrophy.Value) || (((Object)requirementPrefab).name != "Coins" && (int)itemType != 13)) && ((Humanoid)Player.m_localPlayer).GetInventory().AddItem(((Object)requirementPrefab).name, num5, item3.m_resItem.m_itemData.m_quality, item3.m_resItem.m_itemData.m_variant, 0L, "", false, true) == null)
												{
													ItemDrop component2 = Object.Instantiate<GameObject>(requirementPrefab, ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward + ((Component)Player.m_localPlayer).transform.up, ((Component)Player.m_localPlayer).transform.rotation).GetComponent<ItemDrop>();
													component2.m_itemData = itemData;
													component2.m_itemData.m_dropPrefab = requirementPrefab;
													component2.m_itemData.m_stack = num5;
													Traverse.Create((object)component2).Method("Save", Array.Empty<object>()).GetValue();
												}
											}
										}
									}
								}
							}
						}
					}
				}
				if (((flag && recycleConsumables.Value) || !flag) && ((flag2 && recycleShards.Value) || !flag2))
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "Recycling...", 0, (Sprite)null, false);
					if (___m_dragAmount == ___m_dragItem.m_stack)
					{
						((Humanoid)Player.m_localPlayer).RemoveEquipAction(___m_dragItem);
						((Humanoid)Player.m_localPlayer).UnequipItem(___m_dragItem, false);
						___m_dragInventory.RemoveItem(___m_dragItem);
					}
					else
					{
						___m_dragInventory.RemoveItem(___m_dragItem, ___m_dragAmount);
					}
					Object.Destroy((Object)(object)___m_dragGo);
					___m_dragGo = null;
					((object)__instance).GetType().GetMethod("UpdateCraftingPanel", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[1] { false });
				}
			}
			else
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "Cannot be recycled or unknown recipe.", 0, (Sprite)null, false);
			}
		}
	}

	private static readonly bool isDebug = true;

	public static ConfigEntry<string> hotKey;

	public static ConfigEntry<bool> modEnabled;

	public static ConfigEntry<bool> returnUnknownResources;

	public static ConfigEntry<bool> returnEnchantedResources;

	public static ConfigEntry<float> returnResources;

	private static BepInExPlugin context;

	private static Assembly epicLootAssembly;

	public static ConfigEntry<bool> recycleCoins;

	public static ConfigEntry<bool> betterArchery;

	public static ConfigEntry<int> betterArcheryCount;

	public static ConfigEntry<bool> equipmentAndQuickSlots;

	public static ConfigEntry<int> equipmentAndQuickSlotsCount;

	public static ConfigEntry<int> inventoryRows;

	public static ConfigEntry<bool> recycleConsumables;

	public static ConfigEntry<bool> recycleTrophy;

	public static ConfigEntry<bool> recycleShards;

	public static void Dbgl(string str = "", bool pref = true)
	{
		if (isDebug)
		{
			Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str));
		}
	}

	private void Awake()
	{
		context = this;
		hotKey = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RecycleHotkey", "delete", "The hotkey to recycle an item");
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
		returnUnknownResources = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ReturnUnknownResources", true, "Return resources if recipe is unknown");
		returnEnchantedResources = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ReturnEnchantedResources", true, "Return resources for Epic Loot enchantments");
		returnResources = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ReturnResources", 1f, "Fraction of resources to return (0.0 - 1.0)");
		recycleCoins = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RecycleCoins", false, "Enable/disable coins on recycling items");
		recycleConsumables = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RecycleConsumables", true, "Enable/disable recycling of consumables (like food) (need to disable for cjaycraft ultimate modpack)");
		recycleTrophy = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RecycleTrophy", true, "Enable/disable recycling of Trophy items (need to disable for cjaycraft ultimate modpack)");
		recycleShards = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RecycleShards", true, "Enable/disable recycling of Shards (need to disable for cjaycraft ultimate modpack)");
		if (modEnabled.Value)
		{
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}
	}

	private void Start()
	{
		if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot"))
		{
			epicLootAssembly = ((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType().Assembly;
		}
	}

	private static bool IsUpgradeOnlyResource(Requirement req)
	{
		if (req == null)
		{
			return true;
		}
		if (req.m_upgraderResource)
		{
			return true;
		}
		string obj = (((Object)(object)req.m_resItem != (Object)null) ? ((Object)req.m_resItem).name : "");
		string text = req.m_resItem?.m_itemData?.m_shared?.m_name ?? "";
		if (obj.IndexOf("Idol", StringComparison.OrdinalIgnoreCase) < 0)
		{
			return text.IndexOf("idol", StringComparison.OrdinalIgnoreCase) >= 0;
		}
		return true;
	}

	private static GameObject GetRequirementPrefab(Requirement req)
	{
		if (req?.m_resItem?.m_itemData?.m_shared == null)
		{
			return null;
		}
		GameObject val = ObjectDB.instance.GetItemPrefab(req.m_resItem.m_itemData.m_shared);
		if ((Object)(object)val == (Object)null)
		{
			val = ObjectDB.instance.GetItemPrefab(((Object)req.m_resItem).name);
		}
		if ((Object)(object)val == (Object)null)
		{
			val = ((Component)req.m_resItem).gameObject;
		}
		return val;
	}
}