Decompiled source of QuickStackDeposit v1.1.1

QuickStackDeposit.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("QuickStackDeposit")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("QuickStackDeposit")]
[assembly: AssemblyTitle("QuickStackDeposit")]
[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 QuickStackDeposit
{
	[BepInPlugin("dreamscapist.valheim.quickstackdeposit", "QuickStackDeposit", "1.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		private class ConfigurationManagerAttributes
		{
			public Action<ConfigEntryBase> CustomDrawer;
		}

		public const string PluginGUID = "dreamscapist.valheim.quickstackdeposit";

		public const string PluginName = "QuickStackDeposit";

		public const string PluginVersion = "1.1.1";

		private static ConfigEntry<KeyboardShortcut> _depositKey;

		private static ConfigEntry<KeyboardShortcut> _lockToggleKey;

		private static ConfigEntry<float> _depositRange;

		private static ConfigEntry<bool> _includeEquipped;

		private const int HotbarRow = 0;

		private static readonly Dictionary<long, HashSet<Vector2i>> _allPlayerLocks = new Dictionary<long, HashSet<Vector2i>>();

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _clearLocksEntry;

		private static ConfigEntry<bool> _debugLogging;

		private static bool _wasInventoryOpenForOverlay;

		private static float _overlayCacheRefreshUntil;

		private static List<(Vector2i pos, RectTransform rect)> _cachedSlotRects = new List<(Vector2i, RectTransform)>();

		private static Texture2D _borderTexture;

		private static string LocksFilePath => Path.Combine(Paths.ConfigPath, "dreamscapist.valheim.quickstackdeposit.locks.txt");

		private static Texture2D BorderTexture
		{
			get
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_borderTexture == (Object)null)
				{
					_borderTexture = new Texture2D(1, 1);
					_borderTexture.SetPixel(0, 0, Color.white);
					_borderTexture.Apply();
				}
				return _borderTexture;
			}
		}

		private void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			_log = ((BaseUnityPlugin)this).Logger;
			LoadLocksFromDisk();
			_depositKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "DepositKey", new KeyboardShortcut((KeyCode)114, Array.Empty<KeyCode>()), "Key to press while your inventory screen is open to deposit matching items into nearby storages.");
			_lockToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "LockToggleKey", new KeyboardShortcut((KeyCode)120, Array.Empty<KeyCode>()), "Key to press while hovering over an inventory slot to lock/unlock it. Locked slots are never deposited.");
			_depositRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DepositRange", 20f, new ConfigDescription("How far away (in meters) to look for storages to deposit into.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 100f), Array.Empty<object>()));
			_includeEquipped = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IncludeEquippedItems", false, "If true, currently equipped items (weapons, armor, etc.) can also be deposited. Off by default so you don't accidentally strip your gear.");
			_debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugLogging", false, "If true, logs detailed diagnostic messages (slot resolution, deposit decisions) to the BepInEx console/log. Off by default to keep the console clean.");
			_clearLocksEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("Locking", "ClearAllLocks", false, new ConfigDescription("Button (in Configuration Manager): unlocks every locked slot for your current character.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = ClearLocksButtonDrawer
				}
			}));
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Deposit key: {2}, lock key: {3}, range: {4}", "QuickStackDeposit", "1.1.1", _depositKey.Value, _lockToggleKey.Value, _depositRange.Value));
		}

		private static void ClearLocksButtonDrawer(ConfigEntryBase entry)
		{
			if (GUILayout.Button("Clear all locked slots for current character", Array.Empty<GUILayoutOption>()))
			{
				ClearLocksForCurrentPlayer();
			}
		}

		private static void ClearLocksForCurrentPlayer()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				DebugLog("[Locks] Clear requested but no character is loaded right now.");
				return;
			}
			HashSet<Vector2i> lockedSlotsForPlayer = GetLockedSlotsForPlayer(Player.m_localPlayer);
			int count = lockedSlotsForPlayer.Count;
			lockedSlotsForPlayer.Clear();
			SaveLocksToDisk();
			DebugLog($"[Locks] Cleared {count} locked slot(s) for current character.");
			((Character)Player.m_localPlayer).Message((MessageType)2, $"Cleared {count} locked slot(s)", 0, (Sprite)null, false);
		}

		private static HashSet<Vector2i> GetLockedSlotsForPlayer(Player player)
		{
			long playerID = player.GetPlayerID();
			if (!_allPlayerLocks.TryGetValue(playerID, out var value))
			{
				value = new HashSet<Vector2i>();
				_allPlayerLocks[playerID] = value;
			}
			return value;
		}

		private static void LoadLocksFromDisk()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			_allPlayerLocks.Clear();
			try
			{
				if (!File.Exists(LocksFilePath))
				{
					return;
				}
				string[] array = File.ReadAllLines(LocksFilePath);
				foreach (string text in array)
				{
					if (string.IsNullOrWhiteSpace(text))
					{
						continue;
					}
					string[] array2 = text.Split('|');
					if (array2.Length != 2 || !long.TryParse(array2[0], out var result))
					{
						continue;
					}
					HashSet<Vector2i> hashSet = new HashSet<Vector2i>();
					string[] array3 = array2[1].Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
					for (int j = 0; j < array3.Length; j++)
					{
						string[] array4 = array3[j].Split(',');
						if (array4.Length == 2 && int.TryParse(array4[0], out var result2) && int.TryParse(array4[1], out var result3))
						{
							hashSet.Add(new Vector2i(result2, result3));
						}
					}
					_allPlayerLocks[result] = hashSet;
				}
				DebugLog($"[Locks] Loaded locks for {_allPlayerLocks.Count} character(s) from disk.");
			}
			catch (Exception arg)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogWarning((object)$"[Locks] Failed to load locks file: {arg}");
				}
			}
		}

		private static void SaveLocksToDisk()
		{
			try
			{
				List<string> list = new List<string>();
				foreach (KeyValuePair<long, HashSet<Vector2i>> allPlayerLock in _allPlayerLocks)
				{
					if (allPlayerLock.Value.Count != 0)
					{
						string arg = string.Join(";", allPlayerLock.Value.Select((Vector2i p) => $"{p.x},{p.y}"));
						list.Add($"{allPlayerLock.Key}|{arg}");
					}
				}
				File.WriteAllLines(LocksFilePath, list);
			}
			catch (Exception arg2)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogWarning((object)$"[Locks] Failed to save locks file: {arg2}");
				}
			}
		}

		private void Update()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Player.m_localPlayer == (Object)null) && (Object)(object)InventoryGui.instance != (Object)null && InventoryGui.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible())
			{
				KeyboardShortcut value = _lockToggleKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ToggleLockOnHoveredSlot(Player.m_localPlayer);
				}
				value = _depositKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					List<Container> containers = FindNearbyContainers(Player.m_localPlayer, _depositRange.Value);
					DepositNearbyMatchingItems(Player.m_localPlayer, containers);
				}
			}
		}

		private void OnGUI()
		{
			//IL_008e: 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)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				_wasInventoryOpenForOverlay = false;
				return;
			}
			if (!((Object)(object)InventoryGui.instance != (Object)null) || !InventoryGui.IsVisible())
			{
				_wasInventoryOpenForOverlay = false;
				return;
			}
			if (!_wasInventoryOpenForOverlay)
			{
				_wasInventoryOpenForOverlay = true;
				_overlayCacheRefreshUntil = Time.unscaledTime + 0.3f;
			}
			if (Time.unscaledTime <= _overlayCacheRefreshUntil)
			{
				_cachedSlotRects = FindAllSlotRects();
			}
			HashSet<Vector2i> lockedSlotsForPlayer = GetLockedSlotsForPlayer(Player.m_localPlayer);
			if (lockedSlotsForPlayer.Count == 0)
			{
				return;
			}
			foreach (var (item, val) in _cachedSlotRects)
			{
				if (!((Object)(object)val == (Object)null) && lockedSlotsForPlayer.Contains(item))
				{
					DrawBorder(RectTransformToScreenRect(val), Color.gray, 4f);
				}
			}
		}

		private static List<(Vector2i pos, RectTransform rect)> FindAllSlotRects()
		{
			List<(Vector2i, RectTransform)> list = new List<(Vector2i, RectTransform)>();
			InventoryGrid val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerGrid : null);
			if ((Object)(object)val == (Object)null)
			{
				return list;
			}
			HashSet<Vector2i> seen = new HashSet<Vector2i>();
			CollectSlotRectsRecursive(((Component)val).transform, list, seen, 0);
			DebugLog($"[Overlay] Found {list.Count} slot rects under player grid.");
			return list;
		}

		private static void CollectSlotRectsRecursive(Transform t, List<(Vector2i, RectTransform)> results, HashSet<Vector2i> seen, int depth)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)t == (Object)null || depth > 10)
			{
				return;
			}
			Component[] components = ((Component)t).GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Vector2i? val2 = FindVector2iField(val);
				if (val2.HasValue && seen.Add(val2.Value))
				{
					RectTransform val3 = (RectTransform)(object)((t is RectTransform) ? t : null);
					if (val3 != null)
					{
						results.Add((val2.Value, val3));
					}
				}
			}
			for (int j = 0; j < t.childCount; j++)
			{
				CollectSlotRectsRecursive(t.GetChild(j), results, seen, depth + 1);
			}
		}

		private static Rect RectTransformToScreenRect(RectTransform rect)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			rect.GetWorldCorners(array);
			float num = Mathf.Min(array[0].x, array[2].x);
			float num2 = Mathf.Max(array[0].x, array[2].x);
			float num3 = Mathf.Min(array[0].y, array[2].y);
			float num4 = Mathf.Max(array[0].y, array[2].y);
			return new Rect(num, (float)Screen.height - num4, num2 - num, num4 - num3);
		}

		private static void DrawBorder(Rect area, Color color, float thickness)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			Color color2 = GUI.color;
			GUI.color = color;
			GUI.DrawTexture(new Rect(((Rect)(ref area)).x, ((Rect)(ref area)).y, ((Rect)(ref area)).width, thickness), (Texture)(object)BorderTexture);
			GUI.DrawTexture(new Rect(((Rect)(ref area)).x, ((Rect)(ref area)).yMax - thickness, ((Rect)(ref area)).width, thickness), (Texture)(object)BorderTexture);
			GUI.DrawTexture(new Rect(((Rect)(ref area)).x, ((Rect)(ref area)).y, thickness, ((Rect)(ref area)).height), (Texture)(object)BorderTexture);
			GUI.DrawTexture(new Rect(((Rect)(ref area)).xMax - thickness, ((Rect)(ref area)).y, thickness, ((Rect)(ref area)).height), (Texture)(object)BorderTexture);
			GUI.color = color2;
		}

		private void ToggleLockOnHoveredSlot(Player player)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			Vector2i? val = FindHoveredSlotPos(player);
			if (!val.HasValue)
			{
				DebugLog($"[LockToggle] No slot resolved under mouse at {Input.mousePosition}.");
				return;
			}
			HashSet<Vector2i> lockedSlotsForPlayer = GetLockedSlotsForPlayer(player);
			bool flag;
			if (lockedSlotsForPlayer.Contains(val.Value))
			{
				lockedSlotsForPlayer.Remove(val.Value);
				flag = false;
			}
			else
			{
				lockedSlotsForPlayer.Add(val.Value);
				flag = true;
			}
			SaveLocksToDisk();
			DebugLog(string.Format("[LockToggle] {0} slot {1}. Currently locked slots: {2}", flag ? "Locking" : "Unlocking", val.Value, string.Join(", ", lockedSlotsForPlayer)));
			((Character)player).Message((MessageType)2, flag ? "Inventory slot locked" : "Inventory slot unlocked", 0, (Sprite)null, false);
		}

		private static Vector2i? FindHoveredSlotPos(Player player)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = RaycastTopmostUIElement(Vector2.op_Implicit(Input.mousePosition));
			if ((Object)(object)val == (Object)null)
			{
				DebugLog("[LockToggle] UI raycast found nothing under the mouse.");
				return null;
			}
			DebugLog("[LockToggle] UI raycast hit: '" + GetHierarchyPath(val.transform) + "'");
			Transform val2 = val.transform;
			int num = 0;
			while ((Object)(object)val2 != (Object)null && num < 12)
			{
				Component[] components = ((Component)val2).GetComponents<Component>();
				foreach (Component val3 in components)
				{
					if (!((Object)(object)val3 == (Object)null))
					{
						Vector2i? result = FindVector2iField(val3);
						if (result.HasValue)
						{
							DebugLog($"[LockToggle] Found Vector2i {result.Value} on {((object)val3).GetType().Name} at '{((Object)val2).name}' (depth {num}).");
							return result;
						}
						ItemData val4 = FindItemDataField(val3);
						if (val4 != null)
						{
							DebugLog($"[LockToggle] Found ItemData field on {((object)val3).GetType().Name} at '{((Object)val2).name}' (depth {num}): '{val4.m_shared.m_name}' at {val4.m_gridPos}.");
							return val4.m_gridPos;
						}
					}
				}
				val2 = val2.parent;
				num++;
			}
			DebugLog("[LockToggle] Walked up the hit hierarchy but found no ItemData/Vector2i field on any component.");
			return null;
		}

		private static GameObject RaycastTopmostUIElement(Vector2 screenPos)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			Type type = FindRuntimeType("UnityEngine.EventSystems.EventSystem");
			Type type2 = FindRuntimeType("UnityEngine.EventSystems.PointerEventData");
			Type type3 = FindRuntimeType("UnityEngine.EventSystems.RaycastResult");
			if (type == null || type2 == null || type3 == null)
			{
				DebugLog("[LockToggle] Could not find UnityEngine.EventSystems types at runtime.");
				return null;
			}
			object obj = type.GetProperty("current", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
			if (obj == null)
			{
				DebugLog("[LockToggle] EventSystem.current is null.");
				return null;
			}
			object obj2 = Activator.CreateInstance(type2, obj);
			type2.GetProperty("position")?.SetValue(obj2, screenPos);
			Type type4 = typeof(List<>).MakeGenericType(type3);
			object obj3 = Activator.CreateInstance(type4);
			MethodInfo method = type.GetMethod("RaycastAll", new Type[2] { type2, type4 });
			if (method == null)
			{
				DebugLog("[LockToggle] EventSystem.RaycastAll method not found.");
				return null;
			}
			method.Invoke(obj, new object[2] { obj2, obj3 });
			IList list = (IList)obj3;
			if (list.Count == 0)
			{
				return null;
			}
			object? obj4 = type3.GetProperty("gameObject")?.GetValue(list[0]);
			return (GameObject)((obj4 is GameObject) ? obj4 : null);
		}

		private static Type FindRuntimeType(string fullName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly asm in assemblies)
			{
				Type type = SafeGet(() => asm.GetType(fullName)) as Type;
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}

		private static string GetHierarchyPath(Transform t)
		{
			List<string> list = new List<string>();
			while ((Object)(object)t != (Object)null)
			{
				list.Add(((Object)t).name);
				t = t.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}

		private static ItemData FindItemDataField(object element)
		{
			FieldInfo[] fields = element.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo field in fields)
			{
				if (field.FieldType == typeof(ItemData))
				{
					object obj = SafeGet(() => field.GetValue(element));
					return (ItemData)((obj is ItemData) ? obj : null);
				}
			}
			return null;
		}

		private static Vector2i? FindVector2iField(object element)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			FieldInfo[] fields = element.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo field in fields)
			{
				if (field.FieldType == typeof(Vector2i))
				{
					object obj = SafeGet(() => field.GetValue(element));
					if (obj != null)
					{
						return (Vector2i)obj;
					}
				}
			}
			return null;
		}

		private static object SafeGet(Func<object> getter)
		{
			try
			{
				return getter();
			}
			catch
			{
				return null;
			}
		}

		private static void DebugLog(string message)
		{
			if (_debugLogging != null && _debugLogging.Value)
			{
				_log.LogInfo((object)message);
			}
		}

		private static bool IsSlotLocked(Player player, Vector2i pos)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return GetLockedSlotsForPlayer(player).Contains(pos);
		}

		private void DepositNearbyMatchingItems(Player player, List<Container> containers)
		{
			//IL_0094: 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_014a: Unknown result type (might be due to invalid IL or missing references)
			containers.RemoveAll((Container c) => (Object)(object)c == (Object)null);
			if (containers.Count == 0)
			{
				((Character)player).Message((MessageType)2, "No nearby storages in range", 0, (Sprite)null, false);
				return;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			List<ItemData> list = new List<ItemData>(inventory.GetAllItems());
			int num = 0;
			foreach (ItemData item in list)
			{
				if (item == null || (item.m_equipped && !_includeEquipped.Value) || item.m_gridPos.y == 0)
				{
					continue;
				}
				if (IsSlotLocked(player, item.m_gridPos))
				{
					DebugLog($"[Deposit] Skipping item '{item.m_shared.m_name}' - slot {item.m_gridPos} is locked.");
					continue;
				}
				foreach (Container container in containers)
				{
					if ((Object)(object)container == (Object)null)
					{
						continue;
					}
					Inventory inventory2 = container.GetInventory();
					if (inventory2 != null && inventory2.HaveItem(item.m_shared.m_name, true))
					{
						int stack = item.m_stack;
						inventory2.MoveItemToThis(inventory, item);
						if (!inventory.ContainsItem(item) || item.m_stack < stack)
						{
							num++;
							DebugLog($"[Deposit] Moved '{item.m_shared.m_name}' (was at {item.m_gridPos}) into a nearby storage.");
						}
						if (!inventory.ContainsItem(item))
						{
							break;
						}
					}
				}
			}
			if (num > 0)
			{
				((Character)player).Message((MessageType)2, "Deposited items into nearby storage(s)", 0, (Sprite)null, false);
			}
			else
			{
				((Character)player).Message((MessageType)2, "Nothing to deposit", 0, (Sprite)null, false);
			}
		}

		private List<Container> FindNearbyContainers(Player player, float range)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			List<Container> list = new List<Container>();
			Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, range);
			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.IsInUse())
				{
					list.Add(componentInParent);
				}
			}
			return list;
		}
	}
}