Decompiled source of CopperGolem v0.2.4

BepInEx/plugins/CopperGolem/CopperGolem.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using GoblinHeim.CoreInventory;
using GoblinHeim.CoreStorage;
using GoblinHeim.ValheimCore;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("CopperGolem")]
[assembly: AssemblyDescription("A virtual withdraw-only wooden chest for ValheimCore")]
[assembly: AssemblyCompany("GoblinHeim")]
[assembly: AssemblyProduct("CopperGolem")]
[assembly: AssemblyFileVersion("0.2.4.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.2.4.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 GoblinHeim.CopperGolem
{
	[BepInPlugin("goblinheim.coppergolem", "CopperGolem", "0.2.4")]
	[BepInDependency("goblinheim.valheimcore", "1.0.8")]
	public sealed class CopperGolemPlugin : BaseUnityPlugin
	{
		public const string Guid = "goblinheim.coppergolem";

		public const string Name = "CopperGolem";

		public const string Version = "0.2.4";

		private Harmony harmony;

		internal static ManualLogSource Log;

		private string localizedLanguage;

		internal static float Range => CorePlugin.CopperGolemRange;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony("goblinheim.coppergolem");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"CopperGolem 0.2.4 chargé avec ValheimCore 1.0.8.");
		}

		private void Update()
		{
			if (Localization.instance == null)
			{
				return;
			}
			string selectedLanguage = Localization.instance.GetSelectedLanguage();
			if (!(selectedLanguage == localizedLanguage))
			{
				localizedLanguage = selectedLanguage;
				MethodInfo methodInfo = AccessTools.Method(typeof(Localization), "AddWord", new Type[2]
				{
					typeof(string),
					typeof(string)
				}, (Type[])null);
				if (!(methodInfo == null))
				{
					bool flag = selectedLanguage.StartsWith("French", StringComparison.OrdinalIgnoreCase);
					methodInfo.Invoke(Localization.instance, new object[2]
					{
						"piece_withdrawer",
						flag ? "Coffre de retrait" : "Withdrawal Chest"
					});
					methodInfo.Invoke(Localization.instance, new object[2]
					{
						"piece_withdrawer_description",
						flag ? "Affiche et retire les objets des stockages accessibles proches." : "Views and withdraws items from nearby accessible storage."
					});
				}
			}
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	public sealed class Withdrawer : MonoBehaviour, IStorageRegistryExclusion
	{
		private struct ItemKey : IEquatable<ItemKey>
		{
			private readonly string name;

			private readonly int quality;

			internal string Name => name;

			internal int Quality => quality;

			internal ItemKey(ItemData i)
			{
				name = i.m_shared.m_name;
				quality = i.m_quality;
			}

			internal ItemKey(string n, int q)
			{
				name = n;
				quality = q;
			}

			public bool Equals(ItemKey x)
			{
				if (name == x.name)
				{
					return quality == x.quality;
				}
				return false;
			}

			public override bool Equals(object o)
			{
				if (o is ItemKey)
				{
					return Equals((ItemKey)o);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return name.GetHashCode() ^ (quality * 397);
			}
		}

		private sealed class Origin
		{
			internal StorageEntry Entry;

			internal int Remaining;
		}

		private sealed class OriginUse
		{
			internal Origin Origin;

			internal int Amount;
		}

		private sealed class Aggregate
		{
			internal readonly ItemData Sample;

			internal int Count;

			internal Aggregate(ItemData sample)
			{
				Sample = sample;
			}
		}

		private static readonly HashSet<Inventory> Displays = new HashSet<Inventory>();

		internal Container Container;

		internal Inventory Virtual;

		internal bool Refreshing;

		private long revision = -1L;

		private float snapshotRange = -1f;

		private string filter = "";

		private WithdrawCategory category;

		private readonly Dictionary<ItemKey, List<Origin>> origins = new Dictionary<ItemKey, List<Origin>>();

		private static readonly FieldRef<Inventory, int> Width = AccessTools.FieldRefAccess<Inventory, int>("m_width");

		private static readonly FieldRef<Inventory, int> Height = AccessTools.FieldRefAccess<Inventory, int>("m_height");

		private static readonly FieldRef<Container, Inventory> ContainerInventory = AccessTools.FieldRefAccess<Container, Inventory>("m_inventory");

		private static readonly Action<Inventory, bool, bool> NotifyChanged = AccessTools.MethodDelegate<Action<Inventory, bool, bool>>(AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null), (object)null, true);

		internal static bool IsVirtual(Inventory inventory)
		{
			if (inventory != null)
			{
				return Displays.Contains(inventory);
			}
			return false;
		}

		private void OnDestroy()
		{
			if (Virtual != null)
			{
				Displays.Remove(Virtual);
			}
		}

		private void Awake()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			Container = ((Component)this).GetComponent<Container>();
			Virtual = new Inventory("$piece_withdrawer", Object.op_Implicit((Object)(object)Container) ? Container.m_bkg : null, 8, 1);
			Displays.Add(Virtual);
			if (Object.op_Implicit((Object)(object)Container))
			{
				ContainerInventory.Invoke(Container) = Virtual;
			}
		}

		internal void SetFilter(string value, WithdrawCategory selected)
		{
			filter = value ?? "";
			category = selected;
			revision = -1L;
			Refresh();
		}

		internal void Refresh()
		{
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			if (Refreshing || !Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return;
			}
			float range = CopperGolemPlugin.Range;
			ResourceSnapshot val = ResourceLedger.Snapshot(Player.m_localPlayer, range);
			if (revision == val.StorageRevision && Mathf.Approximately(snapshotRange, range))
			{
				return;
			}
			Refreshing = true;
			try
			{
				Dictionary<ItemKey, Aggregate> dictionary = new Dictionary<ItemKey, Aggregate>();
				StorageEntry[] sources = val.Sources;
				foreach (StorageEntry val2 in sources)
				{
					if (!Eligible(val2) || val2.Container == Container)
					{
						continue;
					}
					foreach (ItemData allItem in val2.Inventory.GetAllItems())
					{
						ItemKey key = new ItemKey(allItem);
						if (!dictionary.TryGetValue(key, out var value))
						{
							value = (dictionary[key] = new Aggregate(allItem));
						}
						value.Count += allItem.m_stack;
					}
				}
				List<Aggregate> list = (from a in dictionary.Values
					where ItemCategories.Visible(a.Sample, category, filter)
					orderby ItemCategories.Order(a.Sample)
					select a).ThenBy<Aggregate, string>((Aggregate a) => ItemCategories.LocalName(a.Sample), StringComparer.CurrentCultureIgnoreCase).ToList();
				Virtual.GetAllItems().Clear();
				int height = Math.Max(1, (list.Count + 7) / 8);
				SetInventorySize(Virtual, 8, height);
				for (int num = 0; num < list.Count; num++)
				{
					ItemData val3 = list[num].Sample.Clone();
					val3.m_stack = list[num].Count;
					val3.m_gridPos = new Vector2i(num % 8, num / 8);
					Virtual.GetAllItems().Add(val3);
				}
				revision = val.StorageRevision;
				snapshotRange = range;
				NotifyChanged(Virtual, arg2: true, arg3: false);
			}
			finally
			{
				Refreshing = false;
			}
		}

		internal static bool Eligible(StorageEntry entry)
		{
			if (entry == null || !Object.op_Implicit((Object)(object)entry.Container) || Object.op_Implicit((Object)(object)((Component)entry.Container).GetComponent<Withdrawer>()))
			{
				return false;
			}
			return true;
		}

		internal bool Withdraw(ItemData display, int amount)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || display == null || amount <= 0)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			Dictionary<StorageEntry, int> before = SourceCounts(ResourceLedger.Snapshot(Player.m_localPlayer, CopperGolemPlugin.Range), display.m_shared.m_name, display.m_quality);
			int num = InventoryAccess.Count(inventory, display.m_shared.m_name, display.m_quality);
			List<ResourceCost> list = new List<ResourceCost>
			{
				new ResourceCost
				{
					Name = display.m_shared.m_name,
					Quality = display.m_quality,
					Amount = num + amount
				}
			};
			bool num2 = ResourceLedger.Prepare(Player.m_localPlayer, list, CopperGolemPlugin.Range, true);
			if (num2)
			{
				RecordOrigins(before, display.m_shared.m_name, display.m_quality);
			}
			revision = -1L;
			Refresh();
			return num2;
		}

		internal bool WithdrawAll()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00d0: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return false;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			ResourceSnapshot snapshot = ResourceLedger.Snapshot(Player.m_localPlayer, CopperGolemPlugin.Range);
			Dictionary<ItemKey, Dictionary<StorageEntry, int>> dictionary = new Dictionary<ItemKey, Dictionary<StorageEntry, int>>();
			List<ResourceCost> list = new List<ResourceCost>();
			foreach (ItemData allItem in Virtual.GetAllItems())
			{
				ItemKey key = new ItemKey(allItem);
				dictionary[key] = SourceCounts(snapshot, allItem.m_shared.m_name, allItem.m_quality);
				list.Add(new ResourceCost
				{
					Name = allItem.m_shared.m_name,
					Quality = allItem.m_quality,
					Amount = InventoryAccess.Count(inventory, allItem.m_shared.m_name, allItem.m_quality) + allItem.m_stack
				});
			}
			bool flag = ResourceLedger.Prepare(Player.m_localPlayer, list, CopperGolemPlugin.Range, true);
			if (flag)
			{
				foreach (KeyValuePair<ItemKey, Dictionary<StorageEntry, int>> item in dictionary)
				{
					RecordOrigins(item.Value, item.Key.Name, item.Key.Quality);
				}
			}
			revision = -1L;
			Refresh();
			return flag;
		}

		internal void BeginSession()
		{
			origins.Clear();
		}

		internal void EndSession()
		{
			origins.Clear();
		}

		internal bool ReturnToOrigins(ItemData item, int amount)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || item == null || amount <= 0)
			{
				return false;
			}
			ItemKey key = new ItemKey(item);
			if (!origins.TryGetValue(key, out var value) || value.Count == 0)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			List<TransferStep> list = new List<TransferStep>();
			List<OriginUse> used = new List<OriginUse>();
			int num = Math.Min(amount, item.m_stack);
			foreach (Origin item2 in value)
			{
				if (num == 0)
				{
					break;
				}
				if (item2.Remaining > 0 && Object.op_Implicit((Object)(object)item2.Entry.Container) && Object.op_Implicit((Object)(object)item2.Entry.View) && item2.Entry.View.IsOwner() && StorageRegistry.Accessible(item2.Entry, Player.m_localPlayer, ((Component)Player.m_localPlayer).transform.position, CopperGolemPlugin.Range))
				{
					int num2 = Math.Min(num, item2.Remaining);
					int num3 = new CapacityPlan(item2.Entry.Inventory).Allocate(inventory, item2.Entry.Inventory, item, num2, list);
					if (num3 > 0)
					{
						used.Add(new OriginUse
						{
							Origin = item2,
							Amount = num3
						});
						num -= num3;
					}
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			bool flag = SafeTransfers.Execute(list, (Func<bool>)(() => used.All((OriginUse x) => Object.op_Implicit((Object)(object)x.Origin.Entry.Container) && StorageRegistry.Accessible(x.Origin.Entry, Player.m_localPlayer, ((Component)Player.m_localPlayer).transform.position, CopperGolemPlugin.Range))));
			if (flag)
			{
				foreach (OriginUse item3 in used)
				{
					item3.Origin.Remaining -= item3.Amount;
				}
			}
			revision = -1L;
			Refresh();
			return flag;
		}

		private static Dictionary<StorageEntry, int> SourceCounts(ResourceSnapshot snapshot, string name, int quality)
		{
			Dictionary<StorageEntry, int> dictionary = new Dictionary<StorageEntry, int>();
			StorageEntry[] sources = snapshot.Sources;
			foreach (StorageEntry val in sources)
			{
				int num = 0;
				foreach (ItemData allItem in val.Inventory.GetAllItems())
				{
					if (allItem.m_shared.m_name == name && allItem.m_quality == quality)
					{
						num += allItem.m_stack;
					}
				}
				dictionary[val] = num;
			}
			return dictionary;
		}

		private void RecordOrigins(Dictionary<StorageEntry, int> before, string name, int quality)
		{
			ItemKey key = new ItemKey(name, quality);
			if (!origins.TryGetValue(key, out var value))
			{
				value = (origins[key] = new List<Origin>());
			}
			foreach (KeyValuePair<StorageEntry, int> pair in before)
			{
				int num = 0;
				foreach (ItemData allItem in pair.Key.Inventory.GetAllItems())
				{
					if (allItem.m_shared.m_name == name && allItem.m_quality == quality)
					{
						num += allItem.m_stack;
					}
				}
				int num2 = pair.Value - num;
				if (num2 > 0)
				{
					Origin origin = value.FirstOrDefault((Origin x) => x.Entry.Inventory == pair.Key.Inventory);
					if (origin == null)
					{
						value.Add(new Origin
						{
							Entry = pair.Key,
							Remaining = num2
						});
					}
					else
					{
						origin.Remaining += num2;
					}
				}
			}
		}

		internal bool Deposit(Inventory source, ItemData item, int amount)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || source == null || item == null || amount <= 0)
			{
				return false;
			}
			ResourceSnapshot snapshot = ResourceLedger.Snapshot(Player.m_localPlayer, CopperGolemPlugin.Range);
			List<TransferStep> steps = new List<TransferStep>();
			int num = amount;
			StorageEntry[] sources = snapshot.Sources;
			foreach (StorageEntry val in sources)
			{
				if (num == 0)
				{
					break;
				}
				if (Eligible(val) && val.View.IsOwner() && val.Inventory.HaveItem(item.m_shared.m_name, true))
				{
					int num2 = new CapacityPlan(val.Inventory).Allocate(source, val.Inventory, item, num, steps);
					num -= num2;
				}
			}
			if (steps.Count == 0)
			{
				return false;
			}
			bool result = SafeTransfers.Execute(steps, (Func<bool>)delegate
			{
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				StorageEntry[] sources2 = snapshot.Sources;
				foreach (StorageEntry target in sources2)
				{
					if (steps.Any((TransferStep s) => s.Target == target.Inventory) && !StorageRegistry.Accessible(target, Player.m_localPlayer, ((Component)Player.m_localPlayer).transform.position, CopperGolemPlugin.Range))
					{
						return false;
					}
				}
				return true;
			});
			revision = -1L;
			Refresh();
			return result;
		}

		private static void SetInventorySize(Inventory inventory, int width, int height)
		{
			Width.Invoke(inventory) = width;
			Height.Invoke(inventory) = height;
		}
	}
	internal enum WithdrawCategory
	{
		All,
		Arrows,
		Weapons,
		Bows,
		Shields,
		Armor,
		Tools,
		Food,
		Materials,
		Capes,
		Trinkets,
		Utility,
		Wood,
		Minerals,
		Metals,
		Hides,
		Monster,
		Engineering,
		Gems,
		FoodIngredients,
		MeadIngredients,
		Trophies,
		Misc
	}
	internal static class ItemCategories
	{
		private static readonly string[] IconPrefabs = new string[23]
		{
			"piece_chest_wood", "ArrowFire", "MaceSilver", "Bow", "ShieldWood", "HelmetIron", "Cultivator", "CookedMeat", "Bronze", "CapeLox",
			"Wishbone", "Demister", "Wood", "Stone", "Iron", "DeerHide", "GreydwarfEye", "SurtlingCore", "GemstoneRed", "Carrot",
			"Honey", "TrophyDeer", "Coins"
		};

		private static readonly Dictionary<string, WithdrawCategory> CategoryCache = new Dictionary<string, WithdrawCategory>();

		private static readonly HashSet<string> Cooking = new HashSet<string>();

		private static readonly HashSet<string> Mead = new HashSet<string>();

		private static readonly HashSet<string> Engineering = new HashSet<string>();

		private static ObjectDB ingredientDb;

		internal static Sprite Icon(WithdrawCategory category)
		{
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return null;
			}
			string text = ((category >= WithdrawCategory.All && (int)category < IconPrefabs.Length) ? IconPrefabs[(int)category] : "");
			if (!string.IsNullOrEmpty(text))
			{
				GameObject val = ObjectDB.instance.GetItemPrefab(text) ?? (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab(text) : null);
				ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null);
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.m_itemData.GetIcon()))
				{
					return val2.m_itemData.GetIcon();
				}
				Piece val3 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Piece>() : null);
				if (Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val3.m_icon))
				{
					return val3.m_icon;
				}
			}
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				ItemDrop val4 = (Object.op_Implicit((Object)(object)item) ? item.GetComponent<ItemDrop>() : null);
				if (Object.op_Implicit((Object)(object)val4) && Classify(val4.m_itemData) == category && Object.op_Implicit((Object)(object)val4.m_itemData.GetIcon()))
				{
					return val4.m_itemData.GetIcon();
				}
			}
			return null;
		}

		internal static string LocalName(ItemData item)
		{
			if (Localization.instance == null)
			{
				return item.m_shared.m_name;
			}
			return Localization.instance.Localize(item.m_shared.m_name);
		}

		internal static bool Visible(ItemData item, WithdrawCategory category, string filter)
		{
			if (category != WithdrawCategory.All && Classify(item) != category)
			{
				return false;
			}
			if (string.IsNullOrWhiteSpace(filter))
			{
				return true;
			}
			string value = Fold(filter);
			string text = Fold(LocalName(item));
			string text2 = Fold(English(item.m_shared.m_name));
			if (!text.Contains(value) && !text2.Contains(value))
			{
				return Fold(Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : "").Contains(value);
			}
			return true;
		}

		internal static int Order(ItemData item)
		{
			string text = (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : item.m_shared.m_name).ToLowerInvariant();
			string[] array = new string[17]
			{
				"wood", "stone", "flint", "deer", "troll", "bronze", "copper", "tin", "iron", "silver",
				"blackmetal", "yggdrasil", "carapace", "flametal", "ashwood", "grausten", "northpine"
			};
			for (int i = 0; i < array.Length; i++)
			{
				if (text.Contains(array[i]))
				{
					return i;
				}
			}
			return 100;
		}

		internal static WithdrawCategory Classify(ItemData item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected I4, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			ItemType itemType = item.m_shared.m_itemType;
			string key = (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : item.m_shared.m_name) + "#" + (int)itemType;
			if (CategoryCache.TryGetValue(key, out var value))
			{
				return value;
			}
			WithdrawCategory withdrawCategory = ClassifyUncached(item, itemType);
			CategoryCache[key] = withdrawCategory;
			return withdrawCategory;
		}

		private static WithdrawCategory ClassifyUncached(ItemData item, ItemType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Invalid comparison between Unknown and I4
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Invalid comparison between Unknown and I4
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Invalid comparison between Unknown and I4
			if ((int)type == 9)
			{
				return WithdrawCategory.Arrows;
			}
			if ((int)type == 4)
			{
				return WithdrawCategory.Bows;
			}
			if ((int)type == 5)
			{
				return WithdrawCategory.Shields;
			}
			if ((int)type == 6 || (int)type == 7 || (int)type == 11)
			{
				return WithdrawCategory.Armor;
			}
			if ((int)type == 17)
			{
				return WithdrawCategory.Capes;
			}
			if ((int)type == 19)
			{
				return WithdrawCategory.Tools;
			}
			if ((int)type == 18)
			{
				return WithdrawCategory.Utility;
			}
			if ((int)type == 3 || (int)type == 14 || (int)type == 15)
			{
				return WithdrawCategory.Weapons;
			}
			string text = (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : item.m_shared.m_name).ToLowerInvariant();
			if (text.Contains("trophy"))
			{
				return WithdrawCategory.Trophies;
			}
			if (Any(text, "wood", "bark", "roundlog", "elderbark", "yggdrasil", "ashwood", "northpine"))
			{
				return WithdrawCategory.Wood;
			}
			if (Any(text, "ore", "scrapiron", "metal", "bronze", "copper", "tin", "iron", "silver", "flametal"))
			{
				return WithdrawCategory.Metals;
			}
			if (Any(text, "stone", "flint", "obsidian", "marble", "grausten"))
			{
				return WithdrawCategory.Minerals;
			}
			if (Any(text, "hide", "leather", "pelt", "scalehide"))
			{
				return WithdrawCategory.Hides;
			}
			if (Any(text, "gem", "jade", "bloodstone", "sulfurstone", "iolite"))
			{
				return WithdrawCategory.Gems;
			}
			if (EngineeringIngredient(item))
			{
				return WithdrawCategory.Engineering;
			}
			if (MeadIngredient(item))
			{
				return WithdrawCategory.MeadIngredients;
			}
			if (CookingIngredient(item))
			{
				return WithdrawCategory.FoodIngredients;
			}
			if (item.m_shared.m_food > 0f || item.m_shared.m_foodStamina > 0f)
			{
				return WithdrawCategory.Food;
			}
			if ((int)type == 1)
			{
				return WithdrawCategory.Monster;
			}
			return WithdrawCategory.Misc;
		}

		private static bool CookingIngredient(ItemData item)
		{
			EnsureIngredientSets();
			return Cooking.Contains(item.m_shared.m_name);
		}

		private static bool MeadIngredient(ItemData item)
		{
			EnsureIngredientSets();
			return Mead.Contains(item.m_shared.m_name);
		}

		private static bool EngineeringIngredient(ItemData item)
		{
			EnsureIngredientSets();
			return Engineering.Contains(item.m_shared.m_name);
		}

		private static void EnsureIngredientSets()
		{
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || ingredientDb == ObjectDB.instance)
			{
				return;
			}
			ingredientDb = ObjectDB.instance;
			Cooking.Clear();
			Mead.Clear();
			Engineering.Clear();
			CategoryCache.Clear();
			foreach (Recipe recipe in ObjectDB.instance.m_recipes)
			{
				if (!Object.op_Implicit((Object)(object)recipe))
				{
					continue;
				}
				bool flag = Object.op_Implicit((Object)(object)recipe.m_craftingStation) && Any(recipe.m_craftingStation.m_name.ToLowerInvariant(), "cook", "food", "prep", "cauldron");
				bool flag2 = (Object.op_Implicit((Object)(object)recipe.m_item) && recipe.m_item.m_itemData.m_shared.m_name.ToLowerInvariant().Contains("mead")) || (((Object)recipe).name ?? "").ToLowerInvariant().Contains("mead");
				if (!flag && !flag2)
				{
					continue;
				}
				Requirement[] resources = recipe.m_resources;
				foreach (Requirement val in resources)
				{
					if (Object.op_Implicit((Object)(object)val.m_resItem))
					{
						string name = val.m_resItem.m_itemData.m_shared.m_name;
						if (flag)
						{
							Cooking.Add(name);
						}
						if (flag2)
						{
							Mead.Add(name);
						}
					}
				}
			}
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				ItemDrop val2 = (Object.op_Implicit((Object)(object)item) ? item.GetComponent<ItemDrop>() : null);
				PieceTable val3 = (Object.op_Implicit((Object)(object)val2) ? val2.m_itemData.m_shared.m_buildPieces : null);
				if (!Object.op_Implicit((Object)(object)val3))
				{
					continue;
				}
				foreach (GameObject piece in val3.m_pieces)
				{
					Piece val4 = (Object.op_Implicit((Object)(object)piece) ? piece.GetComponent<Piece>() : null);
					if (!Object.op_Implicit((Object)(object)val4) || (!Object.op_Implicit((Object)(object)piece.GetComponent<CraftingStation>()) && !Object.op_Implicit((Object)(object)piece.GetComponent<TeleportWorld>()) && !Object.op_Implicit((Object)(object)piece.GetComponent<Ship>()) && !Object.op_Implicit((Object)(object)piece.GetComponent<Vagon>())))
					{
						continue;
					}
					Requirement[] resources = val4.m_resources;
					foreach (Requirement val5 in resources)
					{
						if (Object.op_Implicit((Object)(object)val5.m_resItem))
						{
							Engineering.Add(val5.m_resItem.m_itemData.m_shared.m_name);
						}
					}
				}
			}
		}

		private static string English(string key)
		{
			return key;
		}

		private static string Fold(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder();
			string text2 = text.Normalize(NormalizationForm.FormD);
			foreach (char c in text2)
			{
				if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
				{
					stringBuilder.Append(char.ToLowerInvariant(c));
				}
			}
			return stringBuilder.ToString();
		}

		private static bool Any(string value, params string[] tokens)
		{
			foreach (string value2 in tokens)
			{
				if (value.Contains(value2))
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class WithdrawerPrefab
	{
		internal const string PrefabName = "piece_withdrawer";

		internal const string SourcePrefabName = "piece_chest_wood";

		private static GameObject prefabRoot;

		private static GameObject prefab;

		internal static void RegisterBeforeSceneAwake(ZNetScene scene)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)scene))
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)prefab))
			{
				if (!scene.m_prefabs.Contains(prefab))
				{
					scene.m_prefabs.Add(prefab);
				}
				return;
			}
			GameObject val = ((IEnumerable<GameObject>)scene.m_prefabs).FirstOrDefault((Func<GameObject, bool>)((GameObject candidate) => Object.op_Implicit((Object)(object)candidate) && ((Object)candidate).name == "piece_chest_wood"));
			if (!Object.op_Implicit((Object)(object)val))
			{
				CopperGolemPlugin.Log.LogError((object)"CopperGolem : coffre en bois Vanilla 'piece_chest_wood' introuvable.");
				return;
			}
			prefabRoot = new GameObject("CopperGolem_PrefabRoot");
			Object.DontDestroyOnLoad((Object)(object)prefabRoot);
			prefabRoot.SetActive(false);
			prefab = Object.Instantiate<GameObject>(val, prefabRoot.transform, false);
			((Object)prefab).name = "piece_withdrawer";
			Piece component = prefab.GetComponent<Piece>();
			Container component2 = prefab.GetComponent<Container>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2))
			{
				CopperGolemPlugin.Log.LogError((object)"CopperGolem : le coffre en bois Vanilla ne contient pas Piece et Container.");
				Object.Destroy((Object)(object)prefab);
				prefab = null;
				return;
			}
			component.m_name = "$piece_withdrawer";
			component.m_description = "$piece_withdrawer_description";
			component2.m_name = "$piece_withdrawer";
			component2.m_width = 10;
			component2.m_height = 1;
			component2.m_autoDestroyEmpty = false;
			component2.m_destroyedLootPrefab = null;
			prefab.AddComponent<Withdrawer>();
			Recolor(prefab);
			scene.m_prefabs.Add(prefab);
			CopperGolemPlugin.Log.LogInfo((object)"Coffre de retrait créé depuis le coffre en bois Vanilla.");
		}

		internal static void RegisterInHammer()
		{
			if (!Object.op_Implicit((Object)(object)prefab) || !Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hammer");
			ItemDrop val = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null);
			PieceTable val2 = (Object.op_Implicit((Object)(object)val) ? val.m_itemData.m_shared.m_buildPieces : null);
			if (Object.op_Implicit((Object)(object)val2) && !val2.m_pieces.Contains(prefab))
			{
				int num = val2.m_pieces.FindIndex((GameObject candidate) => Object.op_Implicit((Object)(object)candidate) && ((Object)candidate).name == "piece_chest_wood");
				if (num < 0)
				{
					val2.m_pieces.Add(prefab);
				}
				else
				{
					val2.m_pieces.Insert(num + 1, prefab);
				}
				CopperGolemPlugin.Log.LogInfo((object)"Coffre de retrait ajouté au marteau à côté du coffre en bois.");
			}
		}

		private static void Recolor(GameObject go)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			((Color)(ref val))..ctor(0.38f, 0.43f, 0.42f, 1f);
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				Material[] materials = val2.materials;
				Material[] array = materials;
				foreach (Material val3 in array)
				{
					if (Object.op_Implicit((Object)(object)val3) && val3.HasProperty("_Color"))
					{
						val3.color = Color.Lerp(val3.color, val, 0.68f);
					}
				}
				val2.materials = materials;
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class SceneRegistration
	{
		[HarmonyPrefix]
		private static void Prefix(ZNetScene __instance)
		{
			WithdrawerPrefab.RegisterBeforeSceneAwake(__instance);
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			WithdrawerPrefab.RegisterInHammer();
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	internal static class ObjectRegistration
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			WithdrawerPrefab.RegisterInHammer();
		}
	}
	[HarmonyPatch(typeof(Container), "Awake")]
	internal static class WithdrawerAwake
	{
		private static readonly FieldRef<Container, Inventory> InventoryField = AccessTools.FieldRefAccess<Container, Inventory>("m_inventory");

		[HarmonyPostfix]
		private static void Postfix(Container __instance)
		{
			Withdrawer component = ((Component)__instance).GetComponent<Withdrawer>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.Container = __instance;
				if (component.Virtual != null)
				{
					InventoryField.Invoke(__instance) = component.Virtual;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Container), "Save")]
	internal static class NoVirtualSave
	{
		[HarmonyPrefix]
		private static bool Prefix(Container __instance)
		{
			return !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Withdrawer>());
		}
	}
	[HarmonyPatch(typeof(Container), "Load")]
	internal static class NoVirtualLoad
	{
		[HarmonyPrefix]
		private static bool Prefix(Container __instance)
		{
			return !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Withdrawer>());
		}
	}
	[HarmonyPatch(typeof(Container), "DropAllItems", new Type[] { })]
	internal static class NoVirtualDrop
	{
		[HarmonyPrefix]
		private static bool Prefix(Container __instance)
		{
			return !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Withdrawer>());
		}
	}
	[HarmonyPatch(typeof(Container), "OnDestroyed")]
	internal static class NoVirtualDestroyedLoot
	{
		[HarmonyPrefix]
		private static bool Prefix(Container __instance)
		{
			return !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Withdrawer>());
		}
	}
	[HarmonyPatch(typeof(Humanoid), "DropItem")]
	internal static class NoVirtualWorldDrop
	{
		[HarmonyPrefix]
		private static bool Prefix(Inventory inventory, ref bool __result)
		{
			if (!Withdrawer.IsVirtual(inventory))
			{
				return true;
			}
			__result = false;
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "Retirez d’abord cet objet dans votre inventaire.", 0, (Sprite)null, false);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class NoVirtualNativeTransfer
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return from m in typeof(Inventory).GetMethods(BindingFlags.Instance | BindingFlags.Public)
				where (m.Name == "MoveItemToThis" || m.Name == "MoveAll" || m.Name == "StackAll") && m.GetParameters().Length != 0 && m.GetParameters()[0].ParameterType == typeof(Inventory)
				select m;
		}

		[HarmonyPrefix]
		private static bool Prefix(Inventory __instance, Inventory __0)
		{
			if (!Withdrawer.IsVirtual(__instance))
			{
				return !Withdrawer.IsVirtual(__0);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Container), "Interact")]
	internal static class RefreshOnInteract
	{
		[HarmonyPrefix]
		private static void Prefix(Container __instance, Humanoid character)
		{
			if ((Object)(object)character == (Object)(object)Player.m_localPlayer)
			{
				((Component)__instance).GetComponent<Withdrawer>()?.Refresh();
			}
		}
	}
	internal sealed class WithdrawerUi : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		private sealed class RectState
		{
			internal RectTransform Rect;

			internal Vector2 AnchorMin;

			internal Vector2 AnchorMax;

			internal Vector2 Pivot;

			internal Vector2 Position;

			internal Vector2 Size;

			internal void Restore()
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: 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_0059: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)Rect))
				{
					Rect.anchorMin = AnchorMin;
					Rect.anchorMax = AnchorMax;
					Rect.pivot = Pivot;
					Rect.anchoredPosition = Position;
					Rect.sizeDelta = Size;
				}
			}
		}

		private static readonly string[] Labels = new string[23]
		{
			"Tous", "Flèches", "Armes", "Arcs", "Boucliers", "Équipement", "Outils", "Nourriture", "Matériaux", "Capes",
			"Bijoux", "Utilitaires", "Bois", "Minéraux", "Métaux", "Peaux", "Monstres", "Ingénierie", "Gemmes", "Cuisine",
			"Hydromel", "Trophées", "Divers"
		};

		private static Vector2? savedPosition;

		internal InventoryGui Gui;

		internal Withdrawer Withdrawer;

		private RectTransform panel;

		private RectTransform gridRect;

		private RectTransform dragHandle;

		private RectTransform backgroundRect;

		private InventoryGrid inventoryGrid;

		private NativeFilterStrip controls;

		private bool backgroundStretched;

		private Vector2 originalPosition;

		private Vector2 originalSize;

		private Vector2 originalGridPosition;

		private Vector2 originalGridSize;

		private Vector2 originalBackgroundSize;

		private Vector2 originalBackgroundPosition;

		private Vector2 dragPosition;

		private Vector2 fixedGridPosition;

		private RectState gridState;

		private readonly List<RectState> headerStates = new List<RectState>();

		private float canvasScale = 1f;

		private float appliedExtraHeight;

		private float nextRefresh;

		private float scrollValue = 1f;

		private int lastRows = -1;

		private int visibleRows = 1;

		private bool dragging;

		private bool cleaned;

		private UnityAction<float> scrollChanged;

		internal bool Typing
		{
			get
			{
				if (Object.op_Implicit((Object)(object)controls))
				{
					return controls.IsTyping;
				}
				return false;
			}
		}

		internal void Build(InventoryGui gui, Withdrawer withdrawer)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_06c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			//IL_072a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_057a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0609: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0528: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			Gui = gui;
			Withdrawer = withdrawer;
			Withdrawer.BeginSession();
			try
			{
				originalPosition = gui.m_container.anchoredPosition;
				originalSize = gui.m_container.sizeDelta;
				if (savedPosition.HasValue)
				{
					gui.m_container.anchoredPosition = savedPosition.Value;
				}
				Canvas.ForceUpdateCanvases();
				FieldInfo fieldInfo = AccessTools.Field(typeof(InventoryGui), "m_stackAllButton");
				Button val = (Button)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null);
				List<RectTransform> list = new List<RectTransform>();
				Button[] array = (Button[])(object)new Button[2] { gui.m_takeAllButton, val };
				foreach (Button val2 in array)
				{
					if (Object.op_Implicit((Object)(object)val2))
					{
						list.Add((RectTransform)((Component)val2).transform);
					}
				}
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(InventoryGui), "m_containerName");
				Component val3 = (Component)((fieldInfo2 != null) ? /*isinst with value type is only supported in some contexts*/: null);
				if (Object.op_Implicit((Object)(object)val3) && val3.transform is RectTransform)
				{
					list.Add((RectTransform)val3.transform);
				}
				foreach (RectTransform item in list)
				{
					headerStates.Add(PinToTop(item, topPivot: false));
				}
				Canvas.ForceUpdateCanvases();
				float num = float.PositiveInfinity;
				foreach (RectTransform item2 in list.Take(2))
				{
					Vector3[] array2 = (Vector3[])(object)new Vector3[4];
					item2.GetWorldCorners(array2);
					num = Mathf.Min(num, Mathf.Min(array2[0].y, array2[3].y));
				}
				ref RectTransform reference = ref backgroundRect;
				Transform obj = ((Transform)gui.m_container).Find("Bkg");
				reference = (RectTransform)(object)((obj is RectTransform) ? obj : null);
				if (Object.op_Implicit((Object)(object)backgroundRect))
				{
					originalBackgroundSize = backgroundRect.sizeDelta;
					originalBackgroundPosition = backgroundRect.anchoredPosition;
					backgroundStretched = !Mathf.Approximately(backgroundRect.anchorMin.y, backgroundRect.anchorMax.y);
				}
				inventoryGrid = ((Component)gui.m_container).GetComponentInChildren<InventoryGrid>(true);
				gridRect = ((!Object.op_Implicit((Object)(object)inventoryGrid)) ? ((RectTransform)null) : ((RectTransform)((Component)inventoryGrid).transform));
				if (Object.op_Implicit((Object)(object)gridRect))
				{
					originalGridPosition = gridRect.anchoredPosition;
					originalGridSize = gridRect.sizeDelta;
					gridState = PinToTop(gridRect, topPivot: true);
				}
				if (Object.op_Implicit((Object)(object)inventoryGrid) && Object.op_Implicit((Object)(object)inventoryGrid.m_scrollbar))
				{
					scrollChanged = delegate(float value)
					{
						scrollValue = value;
						ApplyScroll();
					};
					((UnityEvent<float>)(object)inventoryGrid.m_scrollbar.onValueChanged).AddListener(scrollChanged);
					inventoryGrid.m_scrollbar.value = 1f;
				}
				panel = new GameObject("CopperGolem Controls", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
				((Transform)panel).SetParent((Transform)(object)gui.m_container, false);
				panel.sizeDelta = new Vector2(Mathf.Max(220f, originalSize.x - 20f), 94f);
				RectTransform obj2 = panel;
				Vector2 anchorMin = (panel.anchorMax = new Vector2(0.5f, 1f));
				obj2.anchorMin = anchorMin;
				panel.pivot = new Vector2(0.5f, 1f);
				panel.anchoredPosition = new Vector2(0f, -90f);
				((Transform)panel).localScale = Vector3.one;
				if (!float.IsPositiveInfinity(num))
				{
					Vector3 position = ((Transform)panel).position;
					position.y = num - 8f * UiScale(gui.m_container);
					((Transform)panel).position = position;
				}
				controls = ((Component)panel).gameObject.AddComponent<NativeFilterStrip>();
				controls.Build(gui, panel.sizeDelta.x, Labels, (Func<int, Sprite>)((int index) => ItemCategories.Icon((WithdrawCategory)index)), (Action<string, int>)delegate(string value, int selected)
				{
					Withdrawer.SetFilter(value, (selected >= 0) ? ((WithdrawCategory)selected) : WithdrawCategory.All);
					LayoutRows(force: true);
				}, (TMP_InputField)null, 11, 12);
				Canvas.ForceUpdateCanvases();
				if (Object.op_Implicit((Object)(object)gridRect))
				{
					Vector3[] array3 = (Vector3[])(object)new Vector3[4];
					panel.GetWorldCorners(array3);
					Vector3 position2 = ((Transform)gridRect).position;
					position2.y = Mathf.Min(array3[0].y, array3[3].y) - 8f * UiScale(gui.m_container);
					((Transform)gridRect).position = position2;
					fixedGridPosition = gridRect.anchoredPosition;
				}
				LayoutRows(force: true);
				dragHandle = new GameObject("CopperGolem Drag Handle", new Type[3]
				{
					typeof(RectTransform),
					typeof(Image),
					typeof(WithdrawerUiDrag)
				}).GetComponent<RectTransform>();
				((Transform)dragHandle).SetParent((Transform)(object)gui.m_container, false);
				RectTransform obj3 = dragHandle;
				anchorMin = (dragHandle.anchorMax = new Vector2(0.5f, 1f));
				obj3.anchorMin = anchorMin;
				dragHandle.pivot = new Vector2(0.5f, 1f);
				dragHandle.sizeDelta = new Vector2(260f, 32f);
				dragHandle.anchoredPosition = new Vector2(0f, -3f);
				((Graphic)((Component)dragHandle).GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0f);
				((Component)dragHandle).GetComponent<WithdrawerUiDrag>().Owner = this;
			}
			catch (Exception ex)
			{
				CopperGolemPlugin.Log.LogError((object)("Construction de l'interface du Coffre de retrait annulée : " + ex));
				if (Object.op_Implicit((Object)(object)panel))
				{
					Object.Destroy((Object)(object)((Component)panel).gameObject);
				}
				if (Object.op_Implicit((Object)(object)dragHandle))
				{
					Object.Destroy((Object)(object)((Component)dragHandle).gameObject);
				}
				if (Object.op_Implicit((Object)(object)gridRect))
				{
					gridRect.anchoredPosition = originalGridPosition;
				}
				if (Object.op_Implicit((Object)(object)backgroundRect))
				{
					backgroundRect.sizeDelta = originalBackgroundSize;
					backgroundRect.anchoredPosition = originalBackgroundPosition;
				}
				if (Object.op_Implicit((Object)(object)gui) && Object.op_Implicit((Object)(object)gui.m_container))
				{
					gui.m_container.sizeDelta = originalSize;
					gui.m_container.anchoredPosition = originalPosition;
				}
				Withdrawer.EndSession();
				Object.Destroy((Object)(object)this);
			}
		}

		private static float UiScale(RectTransform rect)
		{
			Canvas val = (Object.op_Implicit((Object)(object)rect) ? ((Component)rect).GetComponentInParent<Canvas>() : null);
			if (!Object.op_Implicit((Object)(object)val) || !(val.scaleFactor > 0f))
			{
				return 1f;
			}
			return val.scaleFactor;
		}

		private static RectState PinToTop(RectTransform rect, bool topPivot)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_007b: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			RectState result = new RectState
			{
				Rect = rect,
				AnchorMin = rect.anchorMin,
				AnchorMax = rect.anchorMax,
				Pivot = rect.pivot,
				Position = rect.anchoredPosition,
				Size = rect.sizeDelta
			};
			Vector3 position = ((Transform)rect).position;
			rect.anchorMin = new Vector2(rect.anchorMin.x, 1f);
			rect.anchorMax = new Vector2(rect.anchorMax.x, 1f);
			if (topPivot)
			{
				rect.pivot = new Vector2(rect.pivot.x, 1f);
			}
			((Transform)rect).position = position;
			return result;
		}

		private void Update()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Gui) || !Object.op_Implicit((Object)(object)Withdrawer) || !InventoryGui.IsVisible())
			{
				return;
			}
			if (!Typing && Object.op_Implicit((Object)(object)inventoryGrid) && Object.op_Implicit((Object)(object)inventoryGrid.m_scrollbar) && ((Component)inventoryGrid.m_scrollbar).gameObject.activeSelf && Input.mouseScrollDelta.y != 0f)
			{
				Camera val = null;
				Canvas componentInParent = ((Component)Gui).GetComponentInParent<Canvas>();
				if (Object.op_Implicit((Object)(object)componentInParent) && (int)componentInParent.renderMode != 0)
				{
					val = componentInParent.worldCamera;
				}
				if (RectTransformUtility.RectangleContainsScreenPoint(gridRect, Vector2.op_Implicit(Input.mousePosition), val))
				{
					int num = Mathf.Max(1, Withdrawer.Virtual.GetHeight() - visibleRows);
					inventoryGrid.m_scrollbar.value = Mathf.Clamp01(inventoryGrid.m_scrollbar.value + Input.mouseScrollDelta.y / (float)num);
				}
			}
			if (!(Time.unscaledTime < nextRefresh))
			{
				nextRefresh = Time.unscaledTime + 0.2f;
				Withdrawer.Refresh();
				LayoutRows(force: false);
			}
		}

		private void LayoutRows(bool force)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: 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_019b: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Gui) || !Object.op_Implicit((Object)(object)Withdrawer) || !Object.op_Implicit((Object)(object)inventoryGrid) || !Object.op_Implicit((Object)(object)gridRect))
			{
				return;
			}
			int num = Math.Max(1, Withdrawer.Virtual.GetHeight());
			if (force || num != lastRows)
			{
				lastRows = num;
				visibleRows = Mathf.Clamp(num, 1, 6);
				float num2 = (float)visibleRows * inventoryGrid.m_elementSpace;
				float num3 = Mathf.Max(230f, 0f - fixedGridPosition.y + num2 + 14f) - originalSize.y;
				float num4 = num3 - appliedExtraHeight;
				appliedExtraHeight = num3;
				Gui.m_container.sizeDelta = originalSize + new Vector2(0f, num3);
				RectTransform container = Gui.m_container;
				container.anchoredPosition += new Vector2(0f, (0f - (1f - Gui.m_container.pivot.y)) * num4);
				if (Object.op_Implicit((Object)(object)backgroundRect))
				{
					backgroundRect.sizeDelta = (backgroundStretched ? originalBackgroundSize : (originalBackgroundSize + new Vector2(0f, num3)));
					backgroundRect.anchoredPosition = (backgroundStretched ? originalBackgroundPosition : (originalBackgroundPosition + new Vector2(0f, (0f - (1f - backgroundRect.pivot.y)) * num3)));
				}
				gridRect.anchoredPosition = fixedGridPosition;
				gridRect.SetSizeWithCurrentAnchors((Axis)1, num2);
				if (Object.op_Implicit((Object)(object)inventoryGrid.m_gridRoot))
				{
					inventoryGrid.m_gridRoot.pivot = new Vector2(inventoryGrid.m_gridRoot.pivot.x, 1f);
					ApplyScroll();
				}
				if (Object.op_Implicit((Object)(object)inventoryGrid.m_scrollbar))
				{
					((Component)inventoryGrid.m_scrollbar).gameObject.SetActive(num > visibleRows);
				}
			}
		}

		internal void ApplyScroll()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)inventoryGrid) && Object.op_Implicit((Object)(object)inventoryGrid.m_gridRoot) && Object.op_Implicit((Object)(object)Withdrawer))
			{
				int num = Mathf.Max(0, Withdrawer.Virtual.GetHeight() - visibleRows);
				inventoryGrid.m_gridRoot.pivot = new Vector2(inventoryGrid.m_gridRoot.pivot.x, 1f);
				inventoryGrid.m_gridRoot.anchoredPosition = new Vector2(0f, (float)num * inventoryGrid.m_elementSpace * (1f - scrollValue));
			}
		}

		public void OnBeginDrag(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eventData.button == 0 && Object.op_Implicit((Object)(object)Gui))
			{
				dragging = true;
				dragPosition = Gui.m_container.anchoredPosition;
				Canvas componentInParent = ((Component)this).GetComponentInParent<Canvas>();
				canvasScale = ((Object.op_Implicit((Object)(object)componentInParent) && componentInParent.scaleFactor > 0f) ? componentInParent.scaleFactor : 1f);
			}
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (dragging && Object.op_Implicit((Object)(object)Gui))
			{
				dragPosition += eventData.delta / canvasScale;
				Gui.m_container.anchoredPosition = dragPosition;
			}
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (dragging)
			{
				dragging = false;
				savedPosition = dragPosition;
			}
		}

		internal void Close()
		{
			Cleanup();
			Object.Destroy((Object)(object)this);
		}

		private void Cleanup()
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			if (cleaned)
			{
				return;
			}
			cleaned = true;
			if (Object.op_Implicit((Object)(object)Withdrawer))
			{
				Withdrawer.EndSession();
			}
			if (Object.op_Implicit((Object)(object)inventoryGrid) && Object.op_Implicit((Object)(object)inventoryGrid.m_scrollbar) && scrollChanged != null)
			{
				((UnityEvent<float>)(object)inventoryGrid.m_scrollbar.onValueChanged).RemoveListener(scrollChanged);
			}
			if (Object.op_Implicit((Object)(object)panel))
			{
				((Component)panel).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)panel).gameObject);
			}
			if (Object.op_Implicit((Object)(object)dragHandle))
			{
				((Component)dragHandle).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)dragHandle).gameObject);
			}
			if (gridState != null)
			{
				gridState.Restore();
			}
			foreach (RectState headerState in headerStates)
			{
				headerState.Restore();
			}
			headerStates.Clear();
			if (Object.op_Implicit((Object)(object)backgroundRect))
			{
				backgroundRect.sizeDelta = originalBackgroundSize;
				backgroundRect.anchoredPosition = originalBackgroundPosition;
			}
			if (Object.op_Implicit((Object)(object)Gui) && Object.op_Implicit((Object)(object)Gui.m_container))
			{
				Gui.m_container.sizeDelta = originalSize;
				Gui.m_container.anchoredPosition = originalPosition;
			}
		}

		private void OnDestroy()
		{
			Cleanup();
		}
	}
	internal sealed class WithdrawerUiDrag : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		internal WithdrawerUi Owner;

		public void OnBeginDrag(PointerEventData eventData)
		{
			Owner?.OnBeginDrag(eventData);
		}

		public void OnDrag(PointerEventData eventData)
		{
			Owner?.OnDrag(eventData);
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			Owner?.OnEndDrag(eventData);
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Show")]
	internal static class WithdrawerShow
	{
		[HarmonyPostfix]
		private static void Postfix(InventoryGui __instance, Container container)
		{
			WithdrawerUi component = ((Component)__instance).GetComponent<WithdrawerUi>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.Close();
			}
			Withdrawer withdrawer = (Object.op_Implicit((Object)(object)container) ? ((Component)container).GetComponent<Withdrawer>() : null);
			if (Object.op_Implicit((Object)(object)withdrawer))
			{
				((Component)__instance).gameObject.AddComponent<WithdrawerUi>().Build(__instance, withdrawer);
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "CloseContainer")]
	internal static class WithdrawerClose
	{
		[HarmonyPrefix]
		private static void Prefix(InventoryGui __instance)
		{
			WithdrawerUi component = ((Component)__instance).GetComponent<WithdrawerUi>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.Close();
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnTakeAll")]
	internal static class WithdrawerTakeAll
	{
		private static readonly FieldRef<InventoryGui, Container> Current = AccessTools.FieldRefAccess<InventoryGui, Container>("m_currentContainer");

		[HarmonyPrefix]
		private static bool Prefix(InventoryGui __instance)
		{
			Container val = Current.Invoke(__instance);
			Withdrawer withdrawer = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<Withdrawer>() : null);
			if (!Object.op_Implicit((Object)(object)withdrawer))
			{
				return true;
			}
			withdrawer.WithdrawAll();
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
	internal static class WithdrawerRightClick
	{
		[HarmonyPrefix]
		private static bool Prefix(InventoryGrid grid, ItemData item)
		{
			WithdrawerUi withdrawerUi = (Object.op_Implicit((Object)(object)InventoryGui.instance) ? ((Component)InventoryGui.instance).GetComponent<WithdrawerUi>() : null);
			if (!Object.op_Implicit((Object)(object)withdrawerUi) || !Object.op_Implicit((Object)(object)withdrawerUi.Withdrawer) || grid.GetInventory() != withdrawerUi.Withdrawer.Virtual)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "DropItem")]
	internal static class WithdrawerDrop
	{
		[HarmonyPrefix]
		private static bool Prefix(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, ref bool __result)
		{
			WithdrawerUi withdrawerUi = (Object.op_Implicit((Object)(object)InventoryGui.instance) ? ((Component)InventoryGui.instance).GetComponent<WithdrawerUi>() : null);
			if (!Object.op_Implicit((Object)(object)withdrawerUi) || !Object.op_Implicit((Object)(object)withdrawerUi.Withdrawer))
			{
				return true;
			}
			Inventory inventory = __instance.GetInventory();
			if (fromInventory == withdrawerUi.Withdrawer.Virtual)
			{
				__result = withdrawerUi.Withdrawer.Withdraw(item, amount);
				return false;
			}
			if (inventory == withdrawerUi.Withdrawer.Virtual)
			{
				__result = withdrawerUi.Withdrawer.ReturnToOrigins(item, amount);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
	internal static class WithdrawerSelection
	{
		private static readonly FieldRef<InventoryGui, ItemData> DragItem = AccessTools.FieldRefAccess<InventoryGui, ItemData>("m_dragItem");

		private static readonly FieldRef<InventoryGui, Inventory> DragInventory = AccessTools.FieldRefAccess<InventoryGui, Inventory>("m_dragInventory");

		private static readonly FieldRef<InventoryGui, int> DragAmount = AccessTools.FieldRefAccess<InventoryGui, int>("m_dragAmount");

		private static readonly Action<InventoryGui, ItemData, Inventory, int> ClearDrag = AccessTools.MethodDelegate<Action<InventoryGui, ItemData, Inventory, int>>(AccessTools.Method(typeof(InventoryGui), "SetupDragItem", (Type[])null, (Type[])null), (object)null, true);

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod)
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Invalid comparison between Unknown and I4
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Invalid comparison between Unknown and I4
			WithdrawerUi component = ((Component)__instance).GetComponent<WithdrawerUi>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.Withdrawer) || (Object)(object)grid == (Object)null)
			{
				return true;
			}
			Inventory val = DragInventory.Invoke(__instance);
			ItemData val2 = DragItem.Invoke(__instance);
			if (val2 != null && val == component.Withdrawer.Virtual)
			{
				Inventory inventory = grid.GetInventory();
				if (inventory == component.Withdrawer.Virtual)
				{
					ClearDrag(__instance, null, null, 1);
					return false;
				}
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && inventory == ((Humanoid)Player.m_localPlayer).GetInventory())
				{
					int amount = Math.Min(DragAmount.Invoke(__instance), val2.m_stack);
					if (component.Withdrawer.Withdraw(val2, amount))
					{
						ClearDrag(__instance, null, null, 1);
					}
				}
				return false;
			}
			if (item != null && (int)mod == 2 && Object.op_Implicit((Object)(object)Player.m_localPlayer) && grid.GetInventory() == ((Humanoid)Player.m_localPlayer).GetInventory())
			{
				component.Withdrawer.ReturnToOrigins(item, item.m_stack);
				return false;
			}
			if (grid.GetInventory() != component.Withdrawer.Virtual || item == null)
			{
				return true;
			}
			if ((int)mod == 2)
			{
				component.Withdrawer.Withdraw(item, item.m_stack);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Update")]
	internal static class WithdrawerTypingBlock
	{
		[HarmonyPrefix]
		private static void Prefix(InventoryGui __instance)
		{
			WithdrawerUi component = ((Component)__instance).GetComponent<WithdrawerUi>();
			if (Object.op_Implicit((Object)(object)component) && component.Typing)
			{
				string[] array = new string[8] { "Use", "Inventory", "JoyButtonB", "JoyButtonY", "JoyButtonA", "Attack", "SecondaryAttack", "Block" };
				for (int i = 0; i < array.Length; i++)
				{
					ZInput.ResetButtonStatus(array[i]);
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
	internal static class WithdrawerGridTopAlignment
	{
		[HarmonyPostfix]
		private static void Postfix(InventoryGrid __instance)
		{
			WithdrawerUi withdrawerUi = (Object.op_Implicit((Object)(object)InventoryGui.instance) ? ((Component)InventoryGui.instance).GetComponent<WithdrawerUi>() : null);
			if (Object.op_Implicit((Object)(object)withdrawerUi) && Object.op_Implicit((Object)(object)withdrawerUi.Withdrawer) && __instance.GetInventory() == withdrawerUi.Withdrawer.Virtual && Object.op_Implicit((Object)(object)__instance.m_gridRoot))
			{
				withdrawerUi.ApplyScroll();
			}
		}
	}
	[HarmonyPatch]
	internal static class WithdrawerStackSimilar
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(Container), "StackAll", (Type[])null, (Type[])null);
		}

		[HarmonyPrepare]
		private static bool Prepare()
		{
			return TargetMethod() != null;
		}

		[HarmonyPrefix]
		private static bool Prefix(Container __instance)
		{
			if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Withdrawer>()))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				QuickStack.Deposit(Player.m_localPlayer);
			}
			return false;
		}
	}
}