Decompiled source of BuildMaterials v1.0.1

BuildMaterials.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 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: AssemblyCompany("BuildMaterials")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BuildMaterials")]
[assembly: AssemblyTitle("BuildMaterials")]
[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 BuildMaterials
{
	[BepInPlugin("com.dreich.buildmaterials", "Build Materials", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BuildMaterialsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.dreich.buildmaterials";

		public const string PluginName = "Build Materials";

		public const string PluginVersion = "1.0.0";

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<int> Multiplier;

		internal static ConfigEntry<bool> ShowMessage;

		internal static ConfigEntry<bool> UseDverger;

		internal static ConfigEntry<bool> UseCraftyBoxes;

		internal static ConfigEntry<bool> DebugLog;

		internal static ConfigEntry<bool> PullEvenIfCarrying;

		internal static ConfigEntry<bool> PlaySound;

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Right-click a piece in the build menu to pull the materials out of nearby storage (Dvergr Automation and/or AzuCraftyBoxes).");
			Multiplier = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Multiplier", 1, new ConfigDescription("How many pieces' worth of materials one right-click pulls (see PullEvenIfCarrying).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			PullEvenIfCarrying = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PullEvenIfCarrying", true, "On: every right-click pulls a full piece's worth of materials (times Multiplier), even if you already carry them. Off: only pull what you're short of, so you end up carrying enough for Multiplier pieces.");
			PlaySound = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PlaySound", true, "Play the build menu's select sound (the one a left-click makes) when a right-click pulls materials.");
			ShowMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMessage", true, "Show a message in the top left corner listing the materials you pulled.");
			UseDverger = ((BaseUnityPlugin)this).Config.Bind<bool>("Storage", "UseDvergrAutomation", true, "Pull from the chests Dvergr Automation's AutoSorter links.");
			UseCraftyBoxes = ((BaseUnityPlugin)this).Config.Bind<bool>("Storage", "UseAzuCraftyBoxes", true, "Pull from the containers AzuCraftyBoxes reaches (same range and per-container item rules it uses for building).");
			DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogRightClicks", true, "Write a line to the BepInEx log for every right-click in the build menu, saying what happened. Handy if right-click seems to do nothing.");
			bool flag = Dverger.Init();
			bool flag2 = CraftyBoxes.Init();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Dvergr Automation: " + (flag ? "found" : "not found") + ", AzuCraftyBoxes: " + (flag2 ? "found" : "not found")));
			if (!flag && !flag2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Neither Dvergr Automation (tested 0.12.4) nor AzuCraftyBoxes (tested 1.8.28) was found, or their internals changed; right-click pulling is turned off.");
			}
			else
			{
				new Harmony("com.dreich.buildmaterials").PatchAll(typeof(BuildMaterialsPlugin).Assembly);
			}
		}

		private void Update()
		{
			RightClick.Poll();
			Pull.Tick();
		}
	}
	[HarmonyPatch(typeof(Hud), "OnRightClickPiece")]
	internal static class HudOnRightClickPiecePatch
	{
		private static bool Prefix(Hud __instance, UIInputHandler ih)
		{
			if (RightClick.HandledThisFrame)
			{
				return false;
			}
			return !RightClick.Handle(__instance, ih, "icon callback");
		}
	}
	internal static class RightClick
	{
		private const BindingFlags AnyInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly MethodInfo GetSelectedGridMethod = typeof(Hud).GetMethod("GetSelectedGrid", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(UIInputHandler) }, null);

		private static readonly FieldInfo HoveredPieceField = typeof(Hud).GetField("m_hoveredPiece", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo BuildPiecesField = typeof(Player).GetField("m_buildPieces", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo GetRightItemMethod = typeof(Humanoid).GetMethod("GetRightItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

		private const string HammerName = "$item_hammer";

		private static int handledFrame = -1;

		internal static bool HandledThisFrame => handledFrame == Time.frameCount;

		internal static void Poll()
		{
			if (!HandledThisFrame && BuildMaterialsPlugin.Enabled.Value && ZInput.GetMouseButtonDown(1) && Hud.IsPieceSelectionVisible())
			{
				Hud instance = Hud.instance;
				if (!((Object)(object)instance == (Object)null))
				{
					Handle(instance, null, "mouse");
				}
			}
		}

		internal static bool Handle(Hud hud, UIInputHandler ih, string source)
		{
			if (!BuildMaterialsPlugin.Enabled.Value)
			{
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
			{
				return false;
			}
			if (!HoldingHammer(localPlayer, out var held))
			{
				Debug("right-click (" + source + ") ignored: holding '" + held + "', not the hammer");
				return false;
			}
			Piece val = FindPiece(hud, ih, localPlayer);
			if ((Object)(object)val == (Object)null)
			{
				Debug("right-click (" + source + ") ignored: no build piece under the cursor");
				return false;
			}
			handledFrame = Time.frameCount;
			Debug("right-click (" + source + ") on " + val.m_name);
			if (!localPlayer.HaveRequirements(val, (RequirementMode)0))
			{
				Pull.Say(localPlayer, "You can't build " + val.m_name + " right now");
				return true;
			}
			PlaySelectSound(hud);
			Pull.Start(localPlayer, val);
			return true;
		}

		private static void PlaySelectSound(Hud hud)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!BuildMaterialsPlugin.PlaySound.Value || hud.m_selectItemEffect == null)
			{
				return;
			}
			try
			{
				hud.m_selectItemEffect.Create(((Component)hud).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
			catch (Exception ex)
			{
				Debug("playing the select sound failed: " + ex.Message);
			}
		}

		private static Piece FindPiece(Hud hud, UIInputHandler ih, Player player)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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)
			Piece val = (Piece)((HoveredPieceField == null) ? null : /*isinst with value type is only supported in some contexts*/);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			if ((Object)(object)ih == (Object)null || GetSelectedGridMethod == null || BuildPiecesField == null)
			{
				return null;
			}
			Vector2Int val2 = (Vector2Int)GetSelectedGridMethod.Invoke(hud, new object[1] { ih });
			if (((Vector2Int)(ref val2)).x == -1)
			{
				return null;
			}
			object? value = BuildPiecesField.GetValue(player);
			PieceTable val3 = (PieceTable)((value is PieceTable) ? value : null);
			if (!((Object)(object)val3 == (Object)null))
			{
				return val3.GetPiece(val2);
			}
			return null;
		}

		private static bool HoldingHammer(Player player, out string held)
		{
			held = "nothing";
			if (GetRightItemMethod == null)
			{
				held = "(GetRightItem not found)";
				return false;
			}
			object? obj = GetRightItemMethod.Invoke(player, null);
			ItemData val = (ItemData)((obj is ItemData) ? obj : null);
			if (val == null || val.m_shared == null)
			{
				return false;
			}
			held = val.m_shared.m_name;
			return held == "$item_hammer";
		}

		private static void Debug(string message)
		{
			if (BuildMaterialsPlugin.DebugLog.Value)
			{
				BuildMaterialsPlugin.Log.LogInfo((object)message);
			}
		}
	}
	internal static class Pull
	{
		private struct Need
		{
			internal string Name;

			internal ItemDrop Drop;

			internal int Amount;
		}

		private const float Patience = 5f;

		private static Piece pendingPiece;

		private static float pendingUntil;

		internal static void Start(Player player, Piece piece)
		{
			pendingPiece = null;
			if (!TryPull(player, piece, lastTry: false))
			{
				pendingPiece = piece;
				pendingUntil = Time.time + 5f;
				Say(player, "Fetching materials for " + piece.m_name + " from storage...");
			}
		}

		internal static void Tick()
		{
			if ((Object)(object)pendingPiece == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
			{
				pendingPiece = null;
				return;
			}
			bool flag = Time.time >= pendingUntil;
			if (TryPull(localPlayer, pendingPiece, flag) || flag)
			{
				pendingPiece = null;
			}
		}

		private static bool TryPull(Player player, Piece piece, bool lastTry)
		{
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			int multiplier = Mathf.Max(1, BuildMaterialsPlugin.Multiplier.Value);
			Requirement[] resources = piece.m_resources;
			if (resources == null)
			{
				return true;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			List<Need> list = Needs(inventory, resources, multiplier);
			if (list.Count == 0)
			{
				Say(player, "You are already carrying the materials for " + piece.m_name);
				return true;
			}
			bool flag = BuildMaterialsPlugin.UseDverger.Value && Dverger.Available;
			bool num = BuildMaterialsPlugin.UseCraftyBoxes.Value && CraftyBoxes.Available && CraftyBoxes.PullingAllowed();
			List<Container> list2 = (flag ? Dverger.Pool(player) : new List<Container>());
			List<object> list3 = (num ? CraftyBoxes.Nearby(player) : new List<object>());
			if (list2.Count == 0 && list3.Count == 0)
			{
				Say(player, "No storage in range to pull from");
				return true;
			}
			if (list2.Count > 0 && !lastTry && Dverger.CheckStorage(player, list2, resources, DvergerMultiplier(inventory, resources, multiplier)) == Dverger.Readiness.Pending)
			{
				return false;
			}
			List<string> list4 = new List<string>();
			bool flag2 = false;
			bool flag3 = false;
			foreach (Need item in list)
			{
				int num2 = Mathf.Min(item.Amount, Room(inventory, item.Drop.m_itemData));
				if (num2 < item.Amount)
				{
					flag2 = true;
				}
				if (num2 <= 0)
				{
					continue;
				}
				int num3 = 0;
				if (list2.Count > 0)
				{
					num3 += Dverger.SpendReserve(item.Name, num2);
					if (num3 < num2)
					{
						num3 += Dverger.RemoveFromContainers(list2, item.Name, num2 - num3);
					}
				}
				if (num3 < num2 && list3.Count > 0)
				{
					num3 += CraftyBoxes.Take(list3, item.Name, ((Object)item.Drop).name, num2 - num3);
				}
				if (num3 < num2)
				{
					flag3 = true;
				}
				if (num3 > 0)
				{
					int num4 = Add(inventory, ((Component)item.Drop).gameObject, item.Drop.m_itemData, num3);
					if (num4 > 0)
					{
						Transform transform = ((Component)player).transform;
						ItemDrop.DropItem(item.Drop.m_itemData, num4, transform.position + transform.forward + Vector3.up, transform.rotation);
						flag2 = true;
					}
					list4.Add(num3 + " " + item.Name);
				}
			}
			if (list4.Count == 0)
			{
				Say(player, flag2 ? "Your inventory is full" : "Nothing could be taken from storage");
			}
			else
			{
				Say(player, "Pulled " + string.Join(", ", list4.ToArray()) + (flag2 ? " (inventory full)" : (flag3 ? " (storage ran short)" : "")));
			}
			return true;
		}

		private static int DvergerMultiplier(Inventory inventory, Requirement[] requirements, int multiplier)
		{
			if (!BuildMaterialsPlugin.PullEvenIfCarrying.Value)
			{
				return multiplier;
			}
			int num = 0;
			foreach (Requirement val in requirements)
			{
				if (val != null && !((Object)(object)val.m_resItem == (Object)null))
				{
					int amount = val.GetAmount(0);
					if (amount > 0)
					{
						int num2 = inventory.CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true);
						num = Mathf.Max(num, (num2 + amount - 1) / amount);
					}
				}
			}
			return multiplier + num;
		}

		private static List<Need> Needs(Inventory inventory, Requirement[] requirements, int multiplier)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			List<Need> list = new List<Need>();
			foreach (Requirement val in requirements)
			{
				if (val == null || (Object)(object)val.m_resItem == (Object)null)
				{
					continue;
				}
				int num = val.GetAmount(0) * multiplier;
				if (num > 0)
				{
					string name = val.m_resItem.m_itemData.m_shared.m_name;
					if (dictionary.TryGetValue(name, out var value))
					{
						Need value2 = list[value];
						value2.Amount += num;
						list[value] = value2;
					}
					else
					{
						dictionary[name] = list.Count;
						list.Add(new Need
						{
							Name = name,
							Drop = val.m_resItem,
							Amount = num
						});
					}
				}
			}
			if (BuildMaterialsPlugin.PullEvenIfCarrying.Value)
			{
				return list;
			}
			for (int num2 = list.Count - 1; num2 >= 0; num2--)
			{
				Need value3 = list[num2];
				value3.Amount -= inventory.CountItems(value3.Name, -1, true);
				if (value3.Amount <= 0)
				{
					list.RemoveAt(num2);
				}
				else
				{
					list[num2] = value3;
				}
			}
			return list;
		}

		private static int Room(Inventory inventory, ItemData itemData)
		{
			int num = Mathf.Max(1, itemData.m_shared.m_maxStackSize);
			return inventory.FindFreeStackSpace(itemData.m_shared.m_name, (float)Game.m_worldLevel) + inventory.GetEmptySlots() * num;
		}

		private static int Add(Inventory inventory, GameObject prefab, ItemData itemData, int amount)
		{
			int num = Mathf.Max(1, itemData.m_shared.m_maxStackSize);
			while (amount > 0)
			{
				int num2 = Mathf.Min(num, amount);
				while (num2 > 0 && !inventory.CanAddItem(prefab, num2))
				{
					num2 = ((num2 > 1) ? (num2 / 2) : 0);
				}
				if (num2 == 0 || !inventory.AddItem(prefab, num2))
				{
					break;
				}
				amount -= num2;
			}
			return amount;
		}

		internal static void Say(Player player, string message)
		{
			if (BuildMaterialsPlugin.ShowMessage.Value)
			{
				((Character)player).Message((MessageType)1, message, 0, (Sprite)null, false);
			}
		}
	}
	internal static class Dverger
	{
		internal enum Readiness
		{
			Covered,
			Pending,
			Short
		}

		internal const string Guid = "MidngightsFX.DvergerAutomation";

		internal const string TestedVersion = "0.12.4";

		private const BindingFlags AnyStatic = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static MethodInfo nearPoint;

		private static MethodInfo removeFrom;

		private static MethodInfo checkStorage;

		private static MethodInfo spend;

		internal static bool Available { get; private set; }

		internal static bool Init()
		{
			Type type = AccessTools.TypeByName("DvergerAutomation.ContainerNetwork");
			Type type2 = AccessTools.TypeByName("DvergerAutomation.CraftFromStoragePatches");
			Type type3 = AccessTools.TypeByName("DvergerAutomation.StorageOwnership");
			Type type4 = AccessTools.TypeByName("DvergerAutomation.StorageReserve");
			if (type == null || type2 == null || type3 == null || type4 == null)
			{
				return false;
			}
			nearPoint = type.GetMethod("GetContainersNearPoint", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Vector3) }, null);
			removeFrom = type2.GetMethod("RemoveFromContainers", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[4]
			{
				typeof(List<Container>),
				typeof(string),
				typeof(int),
				typeof(int)
			}, null);
			checkStorage = type3.GetMethod("CheckStorage", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[6]
			{
				typeof(Player),
				typeof(List<Container>),
				typeof(Requirement[]),
				typeof(CraftingStation),
				typeof(int),
				typeof(int)
			}, null);
			spend = type4.GetMethod("Spend", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[3]
			{
				typeof(string),
				typeof(int),
				typeof(int)
			}, null);
			Available = nearPoint != null && removeFrom != null && checkStorage != null && spend != null;
			if (!Available)
			{
				BuildMaterialsPlugin.Log.LogWarning((object)"Dvergr Automation is installed but its internals don't match 0.12.4; not using it.");
			}
			return Available;
		}

		internal static List<Container> Pool(Player player)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (nearPoint.Invoke(null, new object[1] { ((Component)player).transform.position }) is List<Container> collection)
			{
				return new List<Container>(collection);
			}
			return new List<Container>();
		}

		internal static Readiness CheckStorage(Player player, List<Container> pool, Requirement[] requirements, int multiplier)
		{
			return (Readiness)Convert.ToInt32(checkStorage.Invoke(null, new object[6] { player, pool, requirements, null, 0, multiplier }));
		}

		internal static int SpendReserve(string name, int amount)
		{
			return (int)spend.Invoke(null, new object[3] { name, amount, -1 });
		}

		internal static int RemoveFromContainers(List<Container> pool, string name, int amount)
		{
			return (int)removeFrom.Invoke(null, new object[4] { pool, name, amount, -1 });
		}
	}
	internal static class CraftyBoxes
	{
		internal const string Guid = "Azumatt.AzuCraftyBoxes";

		internal const string TestedVersion = "1.8.28";

		private const BindingFlags AnyStatic = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static MethodInfo getNearby;

		private static MethodInfo canBePulled;

		private static MethodInfo shouldPrevent;

		private static FieldInfo rangeField;

		private static MethodInfo itemCount;

		private static MethodInfo process;

		private static MethodInfo prefabName;

		internal static bool Available { get; private set; }

		internal static bool Init()
		{
			Type type = AccessTools.TypeByName("AzuCraftyBoxes.API");
			Type type2 = AccessTools.TypeByName("AzuCraftyBoxes.AzuCraftyBoxesPlugin");
			Type type3 = AccessTools.TypeByName("AzuCraftyBoxes.Util.Functions.MiscFunctions");
			Type type4 = AccessTools.TypeByName("AzuCraftyBoxes.IContainers.IContainer");
			if (type == null || type2 == null || type4 == null)
			{
				return false;
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name == "GetNearbyContainers" && methodInfo.IsGenericMethodDefinition && methodInfo.GetParameters().Length == 2)
				{
					try
					{
						getNearby = methodInfo.MakeGenericMethod(typeof(Player));
					}
					catch (ArgumentException)
					{
					}
				}
			}
			canBePulled = type.GetMethod("CanItemBePulled", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
			{
				typeof(string),
				typeof(string)
			}, null);
			shouldPrevent = ((type3 == null) ? null : type3.GetMethod("ShouldPrevent", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null));
			rangeField = type2.GetField("mRange", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			itemCount = type4.GetMethod("ItemCount", new Type[1] { typeof(string) });
			process = type4.GetMethod("ProcessContainerInventory", new Type[3]
			{
				typeof(string),
				typeof(int),
				typeof(int)
			});
			prefabName = type4.GetMethod("GetPrefabName", Type.EmptyTypes);
			Available = getNearby != null && rangeField != null && itemCount != null && process != null && prefabName != null;
			if (!Available)
			{
				BuildMaterialsPlugin.Log.LogWarning((object)"AzuCraftyBoxes is installed but its internals don't match 1.8.28; not using it.");
			}
			return Available;
		}

		internal static bool PullingAllowed()
		{
			if (shouldPrevent == null)
			{
				return true;
			}
			try
			{
				return !(bool)shouldPrevent.Invoke(null, null);
			}
			catch (Exception)
			{
				return true;
			}
		}

		internal static List<object> Nearby(Player player)
		{
			List<object> list = new List<object>();
			if (!(rangeField.GetValue(null) is ConfigEntry<float> val))
			{
				return list;
			}
			if (!(getNearby.Invoke(null, new object[2] { player, val.Value }) is IEnumerable enumerable))
			{
				return list;
			}
			foreach (object item in enumerable)
			{
				if (item != null)
				{
					list.Add(item);
				}
			}
			return list;
		}

		internal static int Take(List<object> pool, string name, string itemPrefab, int amount)
		{
			int num = 0;
			foreach (object item in pool)
			{
				if (num >= amount)
				{
					break;
				}
				try
				{
					if (!(canBePulled != null))
					{
						goto IL_0066;
					}
					string text = prefabName.Invoke(item, null) as string;
					if ((bool)canBePulled.Invoke(null, new object[2] { text, itemPrefab }))
					{
						goto IL_0066;
					}
					goto end_IL_0020;
					IL_0066:
					int num2 = (int)itemCount.Invoke(item, new object[1] { name });
					if (num2 > 0)
					{
						int num3 = Mathf.Min(num2, amount - num);
						process.Invoke(item, new object[3] { name, 0, num3 });
						int num4 = (int)itemCount.Invoke(item, new object[1] { name });
						num += Mathf.Max(0, Mathf.Min(num3, num2 - num4));
					}
					end_IL_0020:;
				}
				catch (Exception ex)
				{
					BuildMaterialsPlugin.Log.LogWarning((object)("AzuCraftyBoxes: taking " + name + " from a container failed: " + ex.Message));
				}
			}
			return num;
		}
	}
}