Decompiled source of CraftFromChests v0.4.0

CraftFromChests.dll

Decompiled 8 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("CraftFromChests")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Valheim-mod: crafta med material från närliggande kistor")]
[assembly: AssemblyFileVersion("0.4.0.0")]
[assembly: AssemblyInformationalVersion("0.4.0")]
[assembly: AssemblyProduct("CraftFromChests")]
[assembly: AssemblyTitle("CraftFromChests")]
[assembly: AssemblyVersion("0.4.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 CraftFromChests
{
	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Piece),
		typeof(RequirementMode)
	})]
	public static class HaveRequirements_Piece_Patch
	{
		private static readonly FieldInfo KnownStationsField = AccessTools.Field(typeof(Player), "m_knownStations");

		private static bool Prefix(Player __instance, Piece piece, RequirementMode mode, ref bool __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_009e: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Invalid comparison between Unknown and I4
			if ((int)mode == 1)
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)piece.m_craftingStation))
			{
				if ((int)mode == 2)
				{
					if (!((Dictionary<string, int>)KnownStationsField.GetValue(__instance)).ContainsKey(piece.m_craftingStation.m_name))
					{
						__result = false;
						return false;
					}
				}
				else if (!Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)__instance).transform.position)) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)27))
				{
					__result = false;
					return false;
				}
			}
			if (piece.m_dlc.Length > 0 && !DLCMan.instance.IsDLCInstalled(piece.m_dlc))
			{
				__result = false;
				return false;
			}
			if (ZoneSystem.instance.GetGlobalKey(piece.FreeBuildKey()))
			{
				__result = true;
				return false;
			}
			List<Container> nearbyContainers = ContainerUtils.GetNearbyContainers(((Component)__instance).transform.position, ContainerUtils.SearchRadius);
			Requirement[] resources = piece.m_resources;
			foreach (Requirement val in resources)
			{
				if (!Object.op_Implicit((Object)(object)val.m_resItem) || val.m_amount <= 0)
				{
					continue;
				}
				string name = val.m_resItem.m_itemData.m_shared.m_name;
				int num = ((Humanoid)__instance).GetInventory().CountItems(name, -1, true);
				foreach (Container item in nearbyContainers)
				{
					num += item.GetInventory().CountItems(name, -1, true);
				}
				if ((int)mode == 2)
				{
					if (num <= 0)
					{
						__result = false;
						return false;
					}
				}
				else if (num < val.m_amount)
				{
					__result = false;
					return false;
				}
			}
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirementItems")]
	public static class HaveRequirementItems_Patch
	{
		private static readonly MethodInfo GetCurrentCraftingStationMethod = AccessTools.Method(typeof(Player), "GetCurrentCraftingStation", (Type[])null, (Type[])null);

		private static bool Prefix(Player __instance, Recipe piece, bool discover, int qualityLevel, int amount, ref bool __result)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (discover)
			{
				return true;
			}
			CraftingStation val = (CraftingStation)GetCurrentCraftingStationMethod.Invoke(__instance, null);
			List<Container> nearbyContainers = ContainerUtils.GetNearbyContainers(((Component)__instance).transform.position, ContainerUtils.SearchRadius);
			Requirement[] resources = piece.m_resources;
			foreach (Requirement val2 in resources)
			{
				if (((Object)(object)val != (Object)null && val.m_upgrader != val2.m_upgraderResource) || ((Object)(object)val == (Object)null && val2.m_upgraderResource) || (Object)(object)val2.m_resItem == (Object)null)
				{
					continue;
				}
				int num = val2.GetAmount(qualityLevel) * amount;
				int num2 = 0;
				string name = val2.m_resItem.m_itemData.m_shared.m_name;
				int maxQuality = val2.m_resItem.m_itemData.m_shared.m_maxQuality;
				for (int j = 1; j < maxQuality + 1; j++)
				{
					int num3 = ((Humanoid)__instance).GetInventory().CountItems(name, j, true);
					foreach (Container item in nearbyContainers)
					{
						num3 += item.GetInventory().CountItems(name, j, true);
					}
					if (num3 > num2)
					{
						num2 = num3;
					}
				}
				if (piece.m_requireOnlyOneIngredient)
				{
					if (num2 >= num)
					{
						__result = true;
						return false;
					}
				}
				else if (num2 < num)
				{
					__result = false;
					return false;
				}
			}
			__result = !piece.m_requireOnlyOneIngredient;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "ConsumeResources")]
	public static class ConsumeResources_Patch
	{
		private static readonly MethodInfo GetCurrentCraftingStationMethod = AccessTools.Method(typeof(Player), "GetCurrentCraftingStation", (Type[])null, (Type[])null);

		private static bool Prefix(Player __instance, Requirement[] requirements, int qualityLevel, int itemQuality, int multiplier)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			CraftingStation val = (CraftingStation)GetCurrentCraftingStationMethod.Invoke(__instance, null);
			List<Container> nearbyContainers = ContainerUtils.GetNearbyContainers(((Component)__instance).transform.position, ContainerUtils.SearchRadius);
			foreach (Requirement val2 in requirements)
			{
				if ((!((Object)(object)val == (Object)null) && val.m_upgrader != val2.m_upgraderResource) || (!((Object)(object)val != (Object)null) && val2.m_upgraderResource) || (Object)(object)val2.m_resItem == (Object)null)
				{
					continue;
				}
				int num = val2.GetAmount(qualityLevel) * multiplier;
				if (num <= 0)
				{
					continue;
				}
				string name = val2.m_resItem.m_itemData.m_shared.m_name;
				int num2 = Math.Min(num, ((Humanoid)__instance).GetInventory().CountItems(name, -1, true));
				if (num2 > 0)
				{
					((Humanoid)__instance).GetInventory().RemoveItem(name, num2, itemQuality, true);
					num -= num2;
				}
				foreach (Container item in nearbyContainers)
				{
					if (num <= 0)
					{
						break;
					}
					Inventory inventory = item.GetInventory();
					int val3 = inventory.CountItems(name, -1, true);
					int num3 = Math.Min(num, val3);
					if (num3 > 0)
					{
						inventory.RemoveItem(name, num3, itemQuality, true);
						num -= num3;
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "SetupRequirement")]
	public static class SetupRequirement_Patch
	{
		private static void Postfix(Transform elementRoot, Requirement req, Player player, bool craft, int quality, int craftMultiplier, bool __result)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			if (!__result || (Object)(object)req.m_resItem == (Object)null || (Object)(object)player == (Object)null)
			{
				return;
			}
			int num = req.GetAmount(quality) * craftMultiplier;
			if (num <= 0)
			{
				return;
			}
			Transform obj = ((Component)elementRoot).transform.Find("res_amount");
			TMP_Text val = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			string name = req.m_resItem.m_itemData.m_shared.m_name;
			int num2 = ((Humanoid)player).GetInventory().CountItems(name, -1, true);
			foreach (Container nearbyContainer in ContainerUtils.GetNearbyContainers(((Component)player).transform.position, ContainerUtils.SearchRadius))
			{
				num2 += nearbyContainer.GetInventory().CountItems(name, -1, true);
			}
			bool flag = (!craft && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)24)) || (craft && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)25));
			val.text = $"{num}/{num2}";
			((Graphic)val).color = ((!(num2 < num && flag)) ? Color.white : ((Mathf.Sin(Time.time * 10f) > 0f) ? Color.red : Color.white));
		}
	}
	[HarmonyPatch(typeof(Smelter), "OnAddOre")]
	public static class Smelter_OnAddOre_Patch
	{
		private static readonly MethodInfo FindCookableItemMethod = AccessTools.Method(typeof(Smelter), "FindCookableItem", new Type[1] { typeof(Inventory) }, (Type[])null);

		private static void Prefix(Smelter __instance, Humanoid user, ItemData item)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (item != null || FindCookableItemMethod.Invoke(__instance, new object[1] { user.GetInventory() }) != null)
			{
				return;
			}
			foreach (Container nearbyContainer in ContainerUtils.GetNearbyContainers(((Component)user).transform.position, ContainerUtils.SearchRadius))
			{
				Inventory inventory = nearbyContainer.GetInventory();
				object? obj = FindCookableItemMethod.Invoke(__instance, new object[1] { inventory });
				ItemData val = (ItemData)((obj is ItemData) ? obj : null);
				if (val != null)
				{
					GameObject dropPrefab = val.m_dropPrefab;
					inventory.RemoveOneItem(val);
					user.GetInventory().AddItem(dropPrefab, 1);
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Smelter), "OnAddFuel")]
	public static class Smelter_OnAddFuel_Patch
	{
		private static readonly FieldInfo FuelItemField = AccessTools.Field(typeof(Smelter), "m_fuelItem");

		private static void Prefix(Smelter __instance, Humanoid user, ItemData item)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (item != null)
			{
				return;
			}
			object? value = FuelItemField.GetValue(__instance);
			ItemDrop val = (ItemDrop)((value is ItemDrop) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			string name = val.m_itemData.m_shared.m_name;
			if (user.GetInventory().HaveItem(name, true))
			{
				return;
			}
			foreach (Container nearbyContainer in ContainerUtils.GetNearbyContainers(((Component)user).transform.position, ContainerUtils.SearchRadius))
			{
				Inventory inventory = nearbyContainer.GetInventory();
				ItemData item2 = inventory.GetItem(name, -1, false);
				if (item2 != null)
				{
					GameObject dropPrefab = item2.m_dropPrefab;
					inventory.RemoveOneItem(item2);
					user.GetInventory().AddItem(dropPrefab, 1);
					break;
				}
			}
		}
	}
	[BepInPlugin("toxo.craftfromchests", "Craft From Chests", "0.4.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "toxo.craftfromchests";

		public const string PluginName = "Craft From Chests";

		public const string PluginVersion = "0.4.0";

		public static ConfigEntry<float> SearchRadius;

		private Harmony harmony;

		private void Awake()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			SearchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SearchRadius", 40f, new ConfigDescription("Hur långt (i meter) modden letar efter närliggande kistor att crafta eller mata smältverk/kolmilor från.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>()));
			harmony = new Harmony("toxo.craftfromchests");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Craft From Chests v0.4.0 laddad!");
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	public static class ContainerUtils
	{
		private static readonly MethodInfo CheckAccessMethod = AccessTools.Method(typeof(Container), "CheckAccess", new Type[1] { typeof(long) }, (Type[])null);

		public static float SearchRadius => Plugin.SearchRadius.Value;

		public static List<Container> GetNearbyContainers(Vector3 position, float radius)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			List<Container> list = new List<Container>();
			Collider[] array = Physics.OverlapSphere(position, radius);
			for (int i = 0; i < array.Length; i++)
			{
				Container componentInParent = ((Component)array[i]).GetComponentInParent<Container>();
				if (!((Object)(object)componentInParent == (Object)null) && !list.Contains(componentInParent) && componentInParent.GetInventory() != null && (!((Object)(object)Player.m_localPlayer != (Object)null) || (bool)CheckAccessMethod.Invoke(componentInParent, new object[1] { Player.m_localPlayer.GetPlayerID() })))
				{
					list.Add(componentInParent);
				}
			}
			return list;
		}

		public static int CountItemInContainers(List<Container> containers, string itemName)
		{
			int num = 0;
			foreach (Container container in containers)
			{
				num += container.GetInventory().CountItems(itemName, -1, true);
			}
			return num;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "CraftFromChests";

		public const string PLUGIN_NAME = "CraftFromChests";

		public const string PLUGIN_VERSION = "0.4.0";
	}
}