Decompiled source of Pit Organizador v1.3.3

QuickStack.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("QuickStack")]
[assembly: AssemblyDescription("Quick stack items to nearby chests and sort inventory with visual feedback")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("QuickStack")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("A1E73C92-3B45-42E3-9BD8-7F624FBE42E0")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 QuickStack
{
	[BepInPlugin("org.bepinex.plugins.quickstacksort", "QuickStackSort", "1.3.3")]
	public class QuickStackPlugin : BaseUnityPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		public const string ModName = "QuickStackSort";

		public const string ModVersion = "1.3.3";

		public const string ModGUID = "org.bepinex.plugins.quickstacksort";

		private static readonly ConfigSync configSync = new ConfigSync("org.bepinex.plugins.quickstacksort")
		{
			DisplayName = "QuickStackSort",
			CurrentVersion = "1.3.3",
			MinimumRequiredVersion = "1.0.0"
		};

		public static ConfigEntry<float> QuickStackRange = null;

		public static ConfigEntry<Toggle> ProtectHotbar = null;

		public static ConfigEntry<Toggle> CraftFromContainers = null;

		public static ConfigEntry<Toggle> BuildFromContainers = null;

		public static ConfigEntry<float> CraftRange = null;

		public static ConfigEntry<Toggle> EnableOpenContainerRouting = null;

		public static ConfigEntry<Toggle> EnableSmartGrouping = null;

		public static ConfigEntry<Toggle> IgnoreNonStackable = null;

		public static ConfigEntry<KeyboardShortcut> SortKey = null;

		public static ConfigEntry<KeyboardShortcut> QuickStackKey = null;

		public static ConfigEntry<KeyboardShortcut> AutoFuelKey = null;

		public static ConfigEntry<Toggle> EnableAutoFuelFireplaces = null;

		public static ConfigEntry<Toggle> EnableAutoFuelSmelters = null;

		public static ConfigEntry<Toggle> EnableAutoLoadOre = null;

		public static ConfigEntry<Toggle> AutoFuelUsePlayerInventory = null;

		public static ConfigEntry<Toggle> RefuelOnQuickStack = null;

		public static ConfigEntry<float> AutoFuelRange = null;

		public static ConfigEntry<float> HighlightDuration = null;

		public static ConfigEntry<Toggle> ShowFloatingText = null;

		public static ConfigEntry<float> ButtonPosX = null;

		public static ConfigEntry<float> ButtonPosY = null;

		private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
			configSync.AddConfigEntry<T>(val).SynchronizedConfig = synchronizedSetting;
			return val;
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		private void Awake()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Expected O, but got Unknown
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Expected O, but got Unknown
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			QuickStackRange = config("1 - General", "QuickStackRange", 150f, new ConfigDescription("Raio de alcance em metros para detecção dos baús próximos no Quick Stack.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 300f), Array.Empty<object>()));
			ProtectHotbar = config("1 - General", "ProtectHotbar", Toggle.On, "Se ativado, não mexe na primeira linha do inventário (barra de atalhos 1-8).");
			CraftFromContainers = config("1 - General", "CraftFromContainers", Toggle.On, "Permite criar e aprimorar itens nas bancadas (workbench, forja, etc.) usando materiais dos baús próximos.");
			BuildFromContainers = config("1 - General", "BuildFromContainers", Toggle.On, "Permite construir estruturas com o martelo/cultivador usando materiais dos baús próximos.");
			CraftRange = config("1 - General", "CraftRange", 150f, new ConfigDescription("Raio de alcance em metros para puxar materiais dos baús para bancadas e construção.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 300f), Array.Empty<object>()));
			EnableOpenContainerRouting = config("1 - General", "EnableOpenContainerRouting", Toggle.On, "Ao mover itens para um baú aberto (arrastando, shift-clique ou Stack All), roteia o item para o baú correto da base se já houver um baú demarcado (segure Ctrl para forçar no baú atual).");
			EnableSmartGrouping = config("1 - General", "EnableSmartGrouping", Toggle.On, "Agrupamento inteligente por categorias (Troféus, Sementes, Madeiras, Metais, Comidas, Poções, Tesouros).");
			IgnoreNonStackable = config("1 - General", "IgnoreNonStackable", Toggle.On, "Ignora itens não empilháveis (armas, armaduras e ferramentas) no roteamento automático e Quick Stack para evitar guardar seus equipamentos por engano.");
			SortKey = config<KeyboardShortcut>("2 - Hotkeys", "SortKey", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Tecla de atalho opcional para organizar o inventário (padrão None / desativado para funcionar apenas pelo clique).", synchronizedSetting: false);
			QuickStackKey = config<KeyboardShortcut>("2 - Hotkeys", "QuickStackKey", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Tecla de atalho opcional para guardar nos baús (padrão None / desativado para funcionar apenas pelo clique).", synchronizedSetting: false);
			AutoFuelKey = config<KeyboardShortcut>("2 - Hotkeys", "AutoFuelKey", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Tecla de atalho opcional para alimentar tochas e fornalhas da base (padrão None / desativado para funcionar exclusivamente pelo botão \ud83d\udd25 do inventário).", synchronizedSetting: false);
			EnableAutoFuelFireplaces = config("5 - Auto Fuel", "EnableAutoFuelFireplaces", Toggle.On, "Alimenta automaticamente tochas, arandelas, braseiros, fogueiras e lareiras com resina, carvão e madeira.");
			EnableAutoFuelSmelters = config("5 - Auto Fuel", "EnableAutoFuelSmelters", Toggle.On, "Alimenta fornalhas, fundições, carvoarias, moinhos e refinarias com carvão, madeira ou seiva.");
			EnableAutoLoadOre = config("5 - Auto Fuel", "EnableAutoLoadOre", Toggle.On, "Carrega minérios nas fundições, cevada nos moinhos, linho nas rodas de fiar e tecido mole na refinaria.");
			AutoFuelUsePlayerInventory = config("5 - Auto Fuel", "AutoFuelUsePlayerInventory", Toggle.Off, "Se ativado, também consome combustíveis e minérios do inventário do jogador (respeitando itens da barra de atalhos e equipamentos).");
			RefuelOnQuickStack = config("5 - Auto Fuel", "RefuelOnQuickStack", Toggle.Off, "Também reabastece automaticamente as tochas e fornalhas da base ao clicar em Guardar Tudo (Q).");
			AutoFuelRange = config("5 - Auto Fuel", "AutoFuelRange", 150f, new ConfigDescription("Raio de alcance em metros para alimentar tochas e fornalhas da base.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 300f), Array.Empty<object>()));
			HighlightDuration = config("3 - Visual", "HighlightDuration", 10f, new ConfigDescription("Duração em segundos do brilho verde e animação nos baús que receberem itens.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 60f), Array.Empty<object>()), synchronizedSetting: false);
			ShowFloatingText = config("3 - Visual", "ShowFloatingText", Toggle.On, "Exibir texto flutuante verde acima do baú com a quantidade de itens guardados.", synchronizedSetting: false);
			ButtonPosX = config("4 - UI", "ButtonPosX", 7f, "Posição horizontal (X) dos botões em relação ao canto inferior direito do inventário.", synchronizedSetting: false);
			ButtonPosY = config("4 - UI", "ButtonPosY", -48f, "Posição vertical (Y) dos botões em relação ao canto inferior direito do inventário.", synchronizedSetting: false);
			new Harmony("org.bepinex.plugins.quickstacksort").PatchAll();
			Debug.Log((object)"[QuickStackSort] Inicializado com sucesso (v1.3.3)!");
		}
	}
	public static class InventorySort
	{
		public static void Sort(Inventory inventory, bool protectHotbar = true)
		{
			//IL_0087: 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)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: 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_019d: Unknown result type (might be due to invalid IL or missing references)
			if (inventory == null)
			{
				return;
			}
			List<ItemData> allItems = inventory.GetAllItems();
			if (allItems == null || allItems.Count == 0)
			{
				return;
			}
			bool flag = (Object)(object)Player.m_localPlayer != (Object)null && inventory == ((Humanoid)Player.m_localPlayer).GetInventory();
			int num = (flag ? PlayerInventoryHelper.GetPlayerInventoryWidth(inventory) : inventory.GetWidth());
			int num2 = (flag ? PlayerInventoryHelper.GetPlayerInventoryHeight(inventory) : inventory.GetHeight());
			List<ItemData> list = new List<ItemData>();
			HashSet<Vector2i> hashSet = new HashSet<Vector2i>();
			foreach (ItemData item in allItems)
			{
				if (item.m_equipped)
				{
					hashSet.Add(item.m_gridPos);
				}
				else if (flag && PlayerInventoryHelper.IsExtraSlot(item, inventory))
				{
					hashSet.Add(item.m_gridPos);
				}
				else if (protectHotbar && item.m_gridPos.y == 0)
				{
					hashSet.Add(item.m_gridPos);
				}
				else
				{
					list.Add(item);
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			MergeStacks(inventory, list);
			list = list.Where((ItemData i) => i.m_stack > 0).ToList();
			list.Sort(CompareItems);
			int num3 = (protectHotbar ? 1 : 0);
			int num4 = 0;
			int num5 = num;
			int num6 = num2;
			Vector2i val = default(Vector2i);
			foreach (ItemData item2 in list)
			{
				while (num3 < num6)
				{
					((Vector2i)(ref val))..ctor(num4, num3);
					if (!hashSet.Contains(val))
					{
						item2.m_gridPos = val;
						hashSet.Add(val);
						num4++;
						if (num4 >= num5)
						{
							num4 = 0;
							num3++;
						}
						break;
					}
					num4++;
					if (num4 >= num5)
					{
						num4 = 0;
						num3++;
					}
				}
			}
			inventory.Changed(false, false);
		}

		private static void MergeStacks(Inventory inventory, List<ItemData> items)
		{
			for (int i = 0; i < items.Count; i++)
			{
				ItemData val = items[i];
				if (val.m_stack <= 0 || val.m_stack >= val.m_shared.m_maxStackSize || val.m_shared.m_maxStackSize <= 1)
				{
					continue;
				}
				for (int j = i + 1; j < items.Count; j++)
				{
					ItemData val2 = items[j];
					if (val2.m_stack > 0 && val.m_shared.m_name == val2.m_shared.m_name && val.m_quality == val2.m_quality && val.m_variant == val2.m_variant)
					{
						int num = Math.Min(val.m_shared.m_maxStackSize - val.m_stack, val2.m_stack);
						val.m_stack += num;
						val2.m_stack -= num;
						if (val2.m_stack <= 0)
						{
							inventory.RemoveItem(val2);
						}
						if (val.m_stack >= val.m_shared.m_maxStackSize)
						{
							break;
						}
					}
				}
			}
		}

		private static int CompareItems(ItemData a, ItemData b)
		{
			int categoryPriority = GetCategoryPriority(a);
			int categoryPriority2 = GetCategoryPriority(b);
			int num = categoryPriority.CompareTo(categoryPriority2);
			if (num != 0)
			{
				return num;
			}
			string itemName = GetItemName(a);
			string itemName2 = GetItemName(b);
			int num2 = string.Compare(itemName, itemName2, StringComparison.CurrentCultureIgnoreCase);
			if (num2 != 0)
			{
				return num2;
			}
			int num3 = b.m_quality.CompareTo(a.m_quality);
			if (num3 != 0)
			{
				return num3;
			}
			return b.m_stack.CompareTo(a.m_stack);
		}

		private static string GetItemName(ItemData item)
		{
			if (Localization.instance != null)
			{
				return Localization.instance.Localize(item.m_shared.m_name);
			}
			return item.m_shared.m_name;
		}

		private static int GetCategoryPriority(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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected I4, but got Unknown
			ItemType itemType = item.m_shared.m_itemType;
			return (itemType - 1) switch
			{
				1 => 1, 
				2 => 2, 
				13 => 2, 
				3 => 2, 
				4 => 2, 
				18 => 3, 
				5 => 4, 
				6 => 4, 
				10 => 4, 
				16 => 4, 
				17 => 4, 
				8 => 5, 
				0 => 6, 
				12 => 7, 
				9 => 8, 
				15 => 9, 
				_ => 10, 
			};
		}
	}
	public static class ContainerDeposit
	{
		internal static readonly HashSet<Container> ActiveContainers = new HashSet<Container>();

		public static void RegisterContainer(Container container)
		{
			if ((Object)(object)container != (Object)null && !ActiveContainers.Contains(container))
			{
				ActiveContainers.Add(container);
			}
		}

		public static void UnregisterContainer(Container container)
		{
			if ((Object)(object)container != (Object)null)
			{
				ActiveContainers.Remove(container);
			}
		}

		public static void QuickStackToNearbyContainers()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			if (inventory == null)
			{
				return;
			}
			float value = QuickStackPlugin.QuickStackRange.Value;
			_ = QuickStackPlugin.ProtectHotbar.Value;
			Vector3 playerPos = ((Component)localPlayer).transform.position;
			ActiveContainers.RemoveWhere((Container c) => (Object)(object)c == (Object)null || (Object)(object)((Component)c).gameObject == (Object)null);
			foreach (Piece s_allPiece in Piece.s_allPieces)
			{
				if ((Object)(object)s_allPiece != (Object)null && (Object)(object)((Component)s_allPiece).gameObject != (Object)null)
				{
					Container val = ((Component)s_allPiece).GetComponent<Container>() ?? ((Component)s_allPiece).GetComponentInChildren<Container>();
					if ((Object)(object)val != (Object)null && !ActiveContainers.Contains(val))
					{
						ActiveContainers.Add(val);
					}
				}
			}
			Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0);
			foreach (Container val2 in array)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && !ActiveContainers.Contains(val2))
				{
					ActiveContainers.Add(val2);
				}
			}
			List<Container> list = new List<Container>();
			foreach (Container activeContainer in ActiveContainers)
			{
				if (!((Object)(object)activeContainer == (Object)null) && !((Object)(object)((Component)activeContainer).transform == (Object)null) && !(Vector3.Distance(playerPos, ((Component)activeContainer).transform.position) > value) && activeContainer.CheckAccess(localPlayer.GetPlayerID()) && PrivateArea.CheckAccess(((Component)activeContainer).transform.position, 0f, false, false) && !((Object)(object)((Component)activeContainer).GetComponent<TombStone>() != (Object)null) && !((Object)activeContainer).name.StartsWith("Player_tombstone", StringComparison.OrdinalIgnoreCase) && (!activeContainer.IsInUse() || !((Object)(object)InventoryGui.instance?.m_currentContainer != (Object)(object)activeContainer)) && activeContainer.GetInventory() != null)
				{
					list.Add(activeContainer);
				}
			}
			if (list.Count == 0)
			{
				((Character)localPlayer).Message((MessageType)2, "Nenhum baú próximo encontrado", 0, (Sprite)null, false);
				return;
			}
			list.Sort((Container a, Container b) => Vector3.Distance(playerPos, ((Component)a).transform.position).CompareTo(Vector3.Distance(playerPos, ((Component)b).transform.position)));
			int num2 = 0;
			int num3 = 0;
			foreach (Container item in list)
			{
				Inventory inventory2 = item.GetInventory();
				if (inventory2 == null)
				{
					continue;
				}
				if ((Object)(object)item.m_nview != (Object)null && item.m_nview.IsValid())
				{
					item.Load();
				}
				List<ItemData> allItems = inventory2.GetAllItems();
				if (allItems == null || allItems.Count == 0)
				{
					continue;
				}
				HashSet<string> hashSet = new HashSet<string>();
				foreach (ItemData item2 in allItems)
				{
					hashSet.Add(item2.m_shared.m_name);
				}
				List<ItemData> list2 = new List<ItemData>(inventory.GetAllItems());
				int num4 = 0;
				foreach (ItemData item3 in list2)
				{
					if (SmartContainers.ShouldIgnoreItem(item3, inventory))
					{
						continue;
					}
					bool flag = hashSet.Contains(item3.m_shared.m_name);
					if (!flag && QuickStackPlugin.EnableSmartGrouping.Value == QuickStackPlugin.Toggle.On)
					{
						ItemCategory itemCategory = SmartContainers.GetItemCategory(item3);
						if (itemCategory != ItemCategory.None)
						{
							flag = SmartContainers.ContainerHasCategory(item, itemCategory);
						}
					}
					if (!flag)
					{
						continue;
					}
					int stack = item3.m_stack;
					if (inventory2.AddItem(item3))
					{
						inventory.RemoveItem(item3);
						num4 += stack;
						num2 += stack;
						continue;
					}
					int num5 = stack - item3.m_stack;
					if (num5 > 0)
					{
						num4 += num5;
						num2 += num5;
						if (item3.m_stack <= 0)
						{
							inventory.RemoveItem(item3);
						}
					}
				}
				if (num4 > 0)
				{
					num3++;
					if ((Object)(object)item.m_nview != (Object)null && item.m_nview.IsValid() && !item.m_nview.IsOwner())
					{
						item.m_nview.ClaimOwnership();
					}
					inventory2.Changed(false, false);
					item.Save();
					ContainerHighlight.Trigger(item, num4);
				}
			}
			if (num3 > 0)
			{
				inventory.Changed(false, false);
				if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.m_moveItemEffects != null)
				{
					InventoryGui.instance.m_moveItemEffects.Create(((Component)localPlayer).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
				((Character)localPlayer).Message((MessageType)1, $"Quick Stack: guardou {num2} itens em {num3} baú(s)!", 0, (Sprite)null, false);
			}
			else
			{
				((Character)localPlayer).Message((MessageType)1, "Quick Stack: nenhum item correspondente para guardar", 0, (Sprite)null, false);
			}
		}
	}
	public class ContainerHighlight : MonoBehaviour
	{
		private class RendererMaterialInfo
		{
			public Renderer renderer;

			public Material[] originalMaterials;

			public Color[] originalEmissionColors;

			public bool[] hadEmissionKeyword;
		}

		private static readonly int EmissionColorProperty = Shader.PropertyToID("_EmissionColor");

		private readonly List<RendererMaterialInfo> renderersInfo = new List<RendererMaterialInfo>();

		private Light? pointLight;

		private Coroutine? activeCoroutine;

		public static void Trigger(Container container, int itemCount)
		{
			if (!((Object)(object)container == (Object)null) && !((Object)(object)((Component)container).gameObject == (Object)null))
			{
				(((Component)container).GetComponent<ContainerHighlight>() ?? ((Component)container).gameObject.AddComponent<ContainerHighlight>()).StartHighlight(itemCount);
			}
		}

		private void Awake()
		{
			InitRenderers();
			InitLight();
		}

		private void InitRenderers()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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)
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!(val is MeshRenderer) && !(val is SkinnedMeshRenderer))
				{
					continue;
				}
				Material[] materials = val.materials;
				if (materials.Length == 0)
				{
					continue;
				}
				Color[] array = (Color[])(object)new Color[materials.Length];
				bool[] array2 = new bool[materials.Length];
				for (int j = 0; j < materials.Length; j++)
				{
					Material val2 = materials[j];
					if (val2.HasProperty(EmissionColorProperty))
					{
						array[j] = val2.GetColor(EmissionColorProperty);
						array2[j] = val2.IsKeywordEnabled("_EMISSION");
					}
					else
					{
						array[j] = Color.black;
						array2[j] = false;
					}
				}
				renderersInfo.Add(new RendererMaterialInfo
				{
					renderer = val,
					originalMaterials = materials,
					originalEmissionColors = array,
					hadEmissionKeyword = array2
				});
			}
		}

		private void InitLight()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("QuickStack_Light");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = Vector3.up * 0.8f;
			pointLight = val.AddComponent<Light>();
			pointLight.type = (LightType)2;
			pointLight.color = new Color(0.2f, 1f, 0.35f);
			pointLight.range = 4f;
			pointLight.intensity = 0f;
			((Behaviour)pointLight).enabled = false;
		}

		public void StartHighlight(int itemCount)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (activeCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(activeCoroutine);
			}
			if ((Object)(object)DamageText.instance != (Object)null && QuickStackPlugin.ShowFloatingText.Value == QuickStackPlugin.Toggle.On)
			{
				Vector3 val = ((Component)this).transform.position + Vector3.up * 1.3f;
				DamageText.instance.ShowText((TextType)4, val, $"+{itemCount}", false);
			}
			activeCoroutine = ((MonoBehaviour)this).StartCoroutine(HighlightRoutine());
		}

		private IEnumerator HighlightRoutine()
		{
			float duration = QuickStackPlugin.HighlightDuration.Value;
			if (duration <= 0.1f)
			{
				duration = 2.5f;
			}
			if ((Object)(object)pointLight != (Object)null)
			{
				((Behaviour)pointLight).enabled = true;
				pointLight.intensity = 2.5f;
			}
			Color targetGreen = new Color(0.1f, 0.9f, 0.25f);
			foreach (RendererMaterialInfo item in renderersInfo)
			{
				if ((Object)(object)item.renderer == (Object)null)
				{
					continue;
				}
				for (int i = 0; i < item.originalMaterials.Length; i++)
				{
					Material val = item.originalMaterials[i];
					if ((Object)(object)val != (Object)null && val.HasProperty(EmissionColorProperty))
					{
						val.EnableKeyword("_EMISSION");
						val.SetColor(EmissionColorProperty, targetGreen * 1.8f);
					}
				}
			}
			float elapsed = 0f;
			while (elapsed < duration)
			{
				elapsed += Time.deltaTime;
				float num = Mathf.Clamp01(elapsed / duration);
				float num2 = Mathf.Sin(elapsed * (float)Math.PI * 1.5f) * 0.18f;
				float num3 = Mathf.Clamp01(1f - num + num2);
				if ((Object)(object)pointLight != (Object)null)
				{
					pointLight.intensity = 2.5f * num3;
				}
				foreach (RendererMaterialInfo item2 in renderersInfo)
				{
					if ((Object)(object)item2.renderer == (Object)null)
					{
						continue;
					}
					for (int j = 0; j < item2.originalMaterials.Length; j++)
					{
						Material val2 = item2.originalMaterials[j];
						if ((Object)(object)val2 != (Object)null && val2.HasProperty(EmissionColorProperty))
						{
							Color val3 = Color.Lerp(item2.originalEmissionColors[j], targetGreen * 1.5f, num3);
							val2.SetColor(EmissionColorProperty, val3);
						}
					}
				}
				yield return null;
			}
			ResetHighlight();
			activeCoroutine = null;
		}

		private void ResetHighlight()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pointLight != (Object)null)
			{
				pointLight.intensity = 0f;
				((Behaviour)pointLight).enabled = false;
			}
			foreach (RendererMaterialInfo item in renderersInfo)
			{
				if ((Object)(object)item.renderer == (Object)null)
				{
					continue;
				}
				for (int i = 0; i < item.originalMaterials.Length; i++)
				{
					Material val = item.originalMaterials[i];
					if ((Object)(object)val != (Object)null && val.HasProperty(EmissionColorProperty))
					{
						val.SetColor(EmissionColorProperty, item.originalEmissionColors[i]);
						if (!item.hadEmissionKeyword[i])
						{
							val.DisableKeyword("_EMISSION");
						}
					}
				}
			}
		}

		private void OnDestroy()
		{
			ResetHighlight();
		}
	}
	public static class CraftFromContainers
	{
		private static float _lastScanTime = 0f;

		private static Vector3 _lastPlayerPos = Vector3.positiveInfinity;

		private static readonly List<Container> _cachedNearbyContainers = new List<Container>();

		public static List<Container> GetNearbyContainers(Player player)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//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_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)((Component)player).transform == (Object)null)
			{
				return _cachedNearbyContainers;
			}
			float time = Time.time;
			Vector3 pos = ((Component)player).transform.position;
			if (time - _lastScanTime < 0.5f && Vector3.Distance(pos, _lastPlayerPos) < 1f)
			{
				return _cachedNearbyContainers;
			}
			_lastScanTime = time;
			_lastPlayerPos = pos;
			_cachedNearbyContainers.Clear();
			float value = QuickStackPlugin.CraftRange.Value;
			ContainerDeposit.ActiveContainers.RemoveWhere((Container c) => (Object)(object)c == (Object)null || (Object)(object)((Component)c).gameObject == (Object)null);
			if (Piece.s_allPieces != null)
			{
				foreach (Piece s_allPiece in Piece.s_allPieces)
				{
					if ((Object)(object)s_allPiece != (Object)null && (Object)(object)((Component)s_allPiece).gameObject != (Object)null)
					{
						Container val = ((Component)s_allPiece).GetComponent<Container>() ?? ((Component)s_allPiece).GetComponentInChildren<Container>();
						if ((Object)(object)val != (Object)null && !ContainerDeposit.ActiveContainers.Contains(val))
						{
							ContainerDeposit.ActiveContainers.Add(val);
						}
					}
				}
			}
			Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0);
			foreach (Container val2 in array)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && !ContainerDeposit.ActiveContainers.Contains(val2))
				{
					ContainerDeposit.ActiveContainers.Add(val2);
				}
			}
			long playerID = player.GetPlayerID();
			foreach (Container activeContainer in ContainerDeposit.ActiveContainers)
			{
				if (!((Object)(object)activeContainer == (Object)null) && !((Object)(object)((Component)activeContainer).transform == (Object)null) && !(Vector3.Distance(pos, ((Component)activeContainer).transform.position) > value) && activeContainer.CheckAccess(playerID) && PrivateArea.CheckAccess(((Component)activeContainer).transform.position, 0f, false, false) && !((Object)(object)((Component)activeContainer).GetComponent<TombStone>() != (Object)null) && !((Object)activeContainer).name.StartsWith("Player_tombstone", StringComparison.OrdinalIgnoreCase) && (!activeContainer.IsInUse() || !((Object)(object)InventoryGui.instance?.m_currentContainer != (Object)(object)activeContainer)) && activeContainer.GetInventory() != null)
				{
					if ((Object)(object)activeContainer.m_nview != (Object)null && activeContainer.m_nview.IsValid())
					{
						activeContainer.Load();
					}
					_cachedNearbyContainers.Add(activeContainer);
				}
			}
			_cachedNearbyContainers.Sort((Container a, Container b) => Vector3.Distance(pos, ((Component)a).transform.position).CompareTo(Vector3.Distance(pos, ((Component)b).transform.position)));
			return _cachedNearbyContainers;
		}

		public static int GetTotalItemCount(Player player, string itemName, int quality = -1)
		{
			int num = ((Humanoid)player).GetInventory().CountItems(itemName, quality, true);
			if (QuickStackPlugin.CraftFromContainers.Value != QuickStackPlugin.Toggle.On)
			{
				return num;
			}
			foreach (Container nearbyContainer in GetNearbyContainers(player))
			{
				Inventory inventory = nearbyContainer.GetInventory();
				if (inventory != null)
				{
					num += inventory.CountItems(itemName, quality, true);
				}
			}
			return num;
		}

		public static ItemData? FindItemInNearbyContainers(Player player, string itemName, int quality = -1)
		{
			foreach (Container nearbyContainer in GetNearbyContainers(player))
			{
				Inventory inventory = nearbyContainer.GetInventory();
				if (inventory != null)
				{
					ItemData item = inventory.GetItem(itemName, quality, false);
					if (item != null)
					{
						return item;
					}
				}
			}
			return null;
		}

		public static void ConsumeItemFromPlayerAndContainers(Player player, string itemName, int amount, int quality = -1)
		{
			if (amount <= 0)
			{
				return;
			}
			int num = Mathf.Min(((Humanoid)player).GetInventory().CountItems(itemName, quality, true), amount);
			if (num > 0)
			{
				((Humanoid)player).GetInventory().RemoveItem(itemName, num, quality, true);
				amount -= num;
			}
			if (amount <= 0 || QuickStackPlugin.CraftFromContainers.Value != QuickStackPlugin.Toggle.On)
			{
				return;
			}
			foreach (Container nearbyContainer in GetNearbyContainers(player))
			{
				Inventory inventory = nearbyContainer.GetInventory();
				if (inventory == null)
				{
					continue;
				}
				int num2 = inventory.CountItems(itemName, quality, true);
				if (num2 > 0)
				{
					int num3 = Mathf.Min(num2, amount);
					inventory.RemoveItem(itemName, num3, quality, true);
					amount -= num3;
					if ((Object)(object)nearbyContainer.m_nview != (Object)null && nearbyContainer.m_nview.IsValid() && !nearbyContainer.m_nview.IsOwner())
					{
						nearbyContainer.m_nview.ClaimOwnership();
					}
					inventory.Changed(false, false);
					nearbyContainer.Save();
					ContainerHighlight.Trigger(nearbyContainer, num3);
					if (amount <= 0)
					{
						break;
					}
				}
			}
		}
	}
	[HarmonyPatch]
	public static class CraftFromContainersPatches
	{
		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		public static class InventoryGui_DoCrafting_Patch
		{
			private static int _preCraftCount = 0;

			private static string? _singleReqName = null;

			private static int _singleReqNeed = 0;

			private static int _singleReqQuality = -1;

			[HarmonyPrefix]
			public static void Prefix(InventoryGui __instance, Player player)
			{
				if (QuickStackPlugin.CraftFromContainers.Value == QuickStackPlugin.Toggle.On && !((Object)(object)__instance.m_craftRecipe == (Object)null) && __instance.m_craftRecipe.m_requireOnlyOneIngredient)
				{
					int num = ((__instance.m_craftUpgradeItem == null) ? 1 : (__instance.m_craftUpgradeItem.m_quality + 1));
					int num2 = ((!__instance.m_multiCrafting) ? 1 : __instance.m_multiCraftAmount);
					int singleReqNeed = default(int);
					ItemData val = default(ItemData);
					__instance.m_craftRecipe.GetAmount(num, ref singleReqNeed, ref val, num2);
					if (val != null)
					{
						_singleReqName = val.m_shared.m_name;
						_singleReqNeed = singleReqNeed;
						_singleReqQuality = val.m_quality;
						_preCraftCount = ((Humanoid)player).GetInventory().CountItems(_singleReqName, _singleReqQuality, true);
					}
				}
			}

			[HarmonyPostfix]
			public static void Postfix(InventoryGui __instance, Player player)
			{
				if (_singleReqName != null)
				{
					int num = ((Humanoid)player).GetInventory().CountItems(_singleReqName, _singleReqQuality, true);
					int num2 = _preCraftCount - num;
					int num3 = _singleReqNeed - num2;
					if (num3 > 0)
					{
						CraftFromContainers.ConsumeItemFromPlayerAndContainers(player, _singleReqName, num3, _singleReqQuality);
					}
					_singleReqName = null;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "HaveRequirementItems")]
		[HarmonyPrefix]
		public static bool Player_HaveRequirementItems_Prefix(Player __instance, Recipe piece, bool discover, int qualityLevel, int amount, ref bool __result)
		{
			if (discover || QuickStackPlugin.CraftFromContainers.Value != QuickStackPlugin.Toggle.On)
			{
				return true;
			}
			CraftingStation currentCraftingStation = __instance.GetCurrentCraftingStation();
			Requirement[] resources = piece.m_resources;
			foreach (Requirement val in resources)
			{
				if (((Object)(object)currentCraftingStation != (Object)null && currentCraftingStation.m_upgrader != val.m_upgraderResource) || ((Object)(object)currentCraftingStation == (Object)null && val.m_upgraderResource) || !Object.op_Implicit((Object)(object)val.m_resItem))
				{
					continue;
				}
				int num = val.GetAmount(qualityLevel) * amount;
				int num2 = 0;
				string name = val.m_resItem.m_itemData.m_shared.m_name;
				int maxQuality = val.m_resItem.m_itemData.m_shared.m_maxQuality;
				for (int j = 1; j <= maxQuality; j++)
				{
					int totalItemCount = CraftFromContainers.GetTotalItemCount(__instance, name, j);
					if (totalItemCount > num2)
					{
						num2 = totalItemCount;
					}
				}
				if (piece.m_requireOnlyOneIngredient)
				{
					if (num2 >= num)
					{
						__result = true;
						return false;
					}
				}
				else if (num2 < num)
				{
					__result = false;
					return false;
				}
			}
			if (piece.m_requireOnlyOneIngredient)
			{
				__result = false;
				return false;
			}
			__result = true;
			return false;
		}

		[HarmonyPatch(typeof(Player), "GetFirstRequiredItem")]
		[HarmonyPrefix]
		public static bool Player_GetFirstRequiredItem_Prefix(Player __instance, Inventory inventory, Recipe recipe, int qualityLevel, ref int amount, ref int extraAmount, int craftMultiplier, ref ItemData? __result)
		{
			if (QuickStackPlugin.CraftFromContainers.Value != QuickStackPlugin.Toggle.On)
			{
				return true;
			}
			CraftingStation currentCraftingStation = __instance.GetCurrentCraftingStation();
			Requirement[] resources = recipe.m_resources;
			foreach (Requirement val in resources)
			{
				if (((Object)(object)currentCraftingStation != (Object)null && currentCraftingStation.m_upgrader != val.m_upgraderResource) || ((Object)(object)currentCraftingStation == (Object)null && val.m_upgraderResource) || !Object.op_Implicit((Object)(object)val.m_resItem))
				{
					continue;
				}
				int num = val.GetAmount(qualityLevel) * craftMultiplier;
				string name = val.m_resItem.m_itemData.m_shared.m_name;
				int maxQuality = val.m_resItem.m_itemData.m_shared.m_maxQuality;
				for (int j = 0; j <= maxQuality; j++)
				{
					if (CraftFromContainers.GetTotalItemCount(__instance, name, j) >= num)
					{
						amount = num;
						extraAmount = val.m_extraAmountOnlyOneIngredient;
						ItemData val2 = inventory.GetItem(name, j, false);
						if (val2 == null)
						{
							val2 = CraftFromContainers.FindItemInNearbyContainers(__instance, name, j);
						}
						__result = val2;
						return false;
					}
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(Player), "ConsumeResources")]
		[HarmonyPrefix]
		public static bool Player_ConsumeResources_Prefix(Player __instance, Requirement[] requirements, int qualityLevel, int itemQuality, int multiplier)
		{
			if (QuickStackPlugin.CraftFromContainers.Value != QuickStackPlugin.Toggle.On)
			{
				return true;
			}
			CraftingStation currentCraftingStation = __instance.GetCurrentCraftingStation();
			foreach (Requirement val in requirements)
			{
				if ((!((Object)(object)currentCraftingStation != (Object)null) || currentCraftingStation.m_upgrader == val.m_upgraderResource) && (!((Object)(object)currentCraftingStation == (Object)null) || !val.m_upgraderResource) && Object.op_Implicit((Object)(object)val.m_resItem))
				{
					int num = val.GetAmount(qualityLevel) * multiplier;
					if (num > 0)
					{
						CraftFromContainers.ConsumeItemFromPlayerAndContainers(__instance, val.m_resItem.m_itemData.m_shared.m_name, num, itemQuality);
					}
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
		{
			typeof(Piece),
			typeof(RequirementMode)
		})]
		[HarmonyPrefix]
		public static bool Player_HaveRequirements_Piece_Prefix(Player __instance, Piece piece, RequirementMode mode, ref bool __result)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Invalid comparison between Unknown and I4
			if (QuickStackPlugin.BuildFromContainers.Value != QuickStackPlugin.Toggle.On)
			{
				return true;
			}
			if ((int)mode == 1)
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)piece.m_craftingStation))
			{
				if ((int)mode == 2)
				{
					if (!__instance.m_knownStations.ContainsKey(piece.m_craftingStation.m_name))
					{
						__result = false;
						return false;
					}
				}
				else if (!Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)__instance).transform.position)) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)27))
				{
					__result = false;
					return false;
				}
			}
			if (piece.m_dlc.Length > 0 && !DLCMan.instance.IsDLCInstalled(piece.m_dlc))
			{
				__result = false;
				return false;
			}
			if (ZoneSystem.instance.GetGlobalKey(piece.FreeBuildKey()))
			{
				__result = true;
				return false;
			}
			Requirement[] resources = piece.m_resources;
			foreach (Requirement val in resources)
			{
				if (!Object.op_Implicit((Object)(object)val.m_resItem) || val.m_amount <= 0)
				{
					continue;
				}
				string name = val.m_resItem.m_itemData.m_shared.m_name;
				if ((int)mode != 0)
				{
					if ((int)mode == 2 && CraftFromContainers.GetTotalItemCount(__instance, name) <= 0)
					{
						__result = false;
						return false;
					}
				}
				else if (CraftFromContainers.GetTotalItemCount(__instance, name) < val.m_amount)
				{
					__result = false;
					return false;
				}
			}
			__result = true;
			return false;
		}

		[HarmonyPatch(typeof(InventoryGui), "SetupRequirement")]
		[HarmonyPostfix]
		public static void InventoryGui_SetupRequirement_Postfix(Transform elementRoot, Requirement req, Player player, bool craft, int quality, int craftMultiplier, ref bool __result)
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			if (!__result || QuickStackPlugin.CraftFromContainers.Value != QuickStackPlugin.Toggle.On || (Object)(object)req.m_resItem == (Object)null)
			{
				return;
			}
			int num = req.GetAmount(quality) * craftMultiplier;
			if (num <= 0)
			{
				return;
			}
			string name = req.m_resItem.m_itemData.m_shared.m_name;
			int totalItemCount = CraftFromContainers.GetTotalItemCount(player, name);
			Transform obj = ((Component)elementRoot).transform.Find("res_amount");
			TMP_Text val = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.text = $"{totalItemCount}/{num}";
				if (totalItemCount < num && ((!craft && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)24)) || (craft && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)25))))
				{
					((Graphic)val).color = ((Mathf.Sin(Time.time * 10f) > 0f) ? Color.red : Color.white);
				}
				else
				{
					((Graphic)val).color = Color.white;
				}
			}
		}
	}
	public enum ItemCategory
	{
		None,
		Trophies,
		SeedsAndCrops,
		Wood,
		OresAndMetals,
		FoodAndCooking,
		PotionsAndMead,
		Valuables,
		Ammo,
		StonesAndBuilding,
		CreatureMaterials,
		MagicAndEitr
	}
	public static class SmartContainers
	{
		public static ItemCategory GetItemCategory(ItemData? item)
		{
			//IL_0073: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Invalid comparison between Unknown and I4
			//IL_07cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ce: Invalid comparison between Unknown and I4
			if (item == null || item.m_shared == null)
			{
				return ItemCategory.None;
			}
			string text = item.m_shared.m_name.ToLowerInvariant();
			string text2 = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name.ToLowerInvariant() : "");
			string text3 = ((Localization.instance != null) ? Localization.instance.Localize(item.m_shared.m_name).ToLowerInvariant() : "");
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType == 13 || text.Contains("trophy") || text2.Contains("trophy") || text3.Contains("troféu") || text3.Contains("trofeu"))
			{
				return ItemCategory.Trophies;
			}
			if ((int)itemType == 9 || (int)itemType == 23 || text.Contains("arrow") || text2.Contains("arrow") || text.Contains("bolt") || text2.Contains("bolt") || text3.Contains("flecha") || text3.Contains("virote"))
			{
				return ItemCategory.Ammo;
			}
			if (item.m_shared.m_isDrink || text.Contains("mead") || text2.Contains("mead") || text3.Contains("hidromel") || text.Contains("potion") || text2.Contains("potion") || text3.Contains("poção") || text3.Contains("pocao") || text.Contains("elixir") || text.Contains("barleywine") || text.Contains("brew") || text.Contains("tonic") || ((Object)(object)item.m_shared.m_consumeStatusEffect != (Object)null && item.m_shared.m_food <= 0f))
			{
				return ItemCategory.PotionsAndMead;
			}
			if (item.m_shared.m_value > 0 || text.Contains("coins") || text2.Contains("coins") || text3.Contains("moeda") || text.Contains("ruby") || text2.Contains("ruby") || text3.Contains("rubi") || text.Contains("amber") || text2.Contains("amber") || text3.Contains("âmbar") || text3.Contains("ambar") || text.Contains("necklace") || text.Contains("thunderstone") || text.Contains("bloodstone") || text2.Contains("bloodstone") || text.Contains("iolite") || text2.Contains("iolite") || text.Contains("jade") || text2.Contains("jade"))
			{
				return ItemCategory.Valuables;
			}
			if (text.Contains("wood") || text2.Contains("wood") || text3.Contains("madeira") || text.Contains("roundlog") || text2.Contains("roundlog") || text.Contains("elderbark") || text.Contains("ancientbark") || text3.Contains("casca") || text.Contains("ashwood") || text2.Contains("ashwood") || text.Contains("frostwood") || text2.Contains("frostwood") || text.Contains("icewood") || text2.Contains("icewood") || text.Contains("glacierwood") || text2.Contains("glacierwood") || text.Contains("charcoal") || text2.Contains("coal") || text3.Contains("carvão") || text3.Contains("carvao"))
			{
				return ItemCategory.Wood;
			}
			if (text.Contains("ore") || text2.Contains("ore") || text3.Contains("minério") || text3.Contains("minerio") || text.Contains("scrap") || text2.Contains("scrap") || text3.Contains("sucata") || text.Contains("copper") || text2.Contains("copper") || text3.Contains("cobre") || text.Contains("tin") || text2.Contains("tin") || text3.Contains("estanho") || text.Contains("bronze") || text2.Contains("bronze") || text.Contains("iron") || text2.Contains("iron") || text3.Contains("ferro") || text.Contains("silver") || text2.Contains("silver") || text3.Contains("prata") || text.Contains("blackmetal") || text2.Contains("blackmetal") || text.Contains("flametal") || text2.Contains("flametal") || text.Contains("frometal") || text2.Contains("frometal") || text.Contains("frostmetal") || text2.Contains("frostmetal") || text.Contains("titanium") || text2.Contains("titanium"))
			{
				return ItemCategory.OresAndMetals;
			}
			if (text.Contains("seed") || text2.Contains("seed") || text3.Contains("semente") || text.Contains("cone") || text2.Contains("cone") || text3.Contains("pinha") || text.Contains("acorn") || text3.Contains("bolota") || text.Contains("carrot") || text.Contains("turnip") || text.Contains("onion") || text.Contains("barley") || text.Contains("flax") || text.Contains("magecap") || text.Contains("jotunpuffs") || text.Contains("vineberry") || text.Contains("fiddlehead") || text.Contains("frostfern") || text.Contains("icefern"))
			{
				return ItemCategory.SeedsAndCrops;
			}
			if (text.Contains("eitr") || text2.Contains("eitr") || text.Contains("sap") || text2.Contains("sap") || text3.Contains("seiva") || text.Contains("softtissue") || text.Contains("moltencore") || text.Contains("wisp") || text.Contains("guck") || text.Contains("frostessence") || text2.Contains("frostessence") || text.Contains("glaciercore") || text2.Contains("glaciercore"))
			{
				return ItemCategory.MagicAndEitr;
			}
			if (item.m_shared.m_food > 0f || (int)itemType == 21 || text.Contains("meat") || text2.Contains("meat") || text3.Contains("carne") || text.Contains("fish") || text2.Contains("fish") || text3.Contains("peixe") || text.Contains("tail") || text3.Contains("cauda") || text.Contains("mushroom") || text3.Contains("cogumelo") || text.Contains("berry") || text3.Contains("baga") || text3.Contains("amora") || text.Contains("sausage") || text3.Contains("linguiça") || text3.Contains("linguica") || text.Contains("soup") || text3.Contains("sopa") || text.Contains("stew") || text3.Contains("ensopado") || text.Contains("pie") || text3.Contains("torta") || text.Contains("feast") || text3.Contains("banquete") || text.Contains("piddle") || text.Contains("asksvin") || text.Contains("volture") || text.Contains("mammoth") || text2.Contains("mammoth") || text.Contains("polar") || text2.Contains("polar") || text.Contains("frostberry") || text.Contains("arctic") || text.Contains("seaweed") || text.Contains("cinnamon") || text.Contains("spices") || text.Contains("bread") || text.Contains("flour") || text.Contains("honey") || text3.Contains("mel"))
			{
				return ItemCategory.FoodAndCooking;
			}
			if (text.Contains("stone") || text2.Contains("stone") || text3.Contains("pedra") || text.Contains("grausten") || text2.Contains("grausten") || text3.Contains("grausten") || text3.Contains("rocha cinzenta") || text.Contains("flint") || text3.Contains("sílex") || text3.Contains("silex") || text.Contains("blackmarble") || text3.Contains("mármore") || text3.Contains("marmore") || text.Contains("tar") || text3.Contains("piche"))
			{
				return ItemCategory.StonesAndBuilding;
			}
			if (text.Contains("hide") || text.Contains("pelt") || text3.Contains("couro") || text3.Contains("pele") || text.Contains("leather") || text3.Contains("fragmento de couro") || text.Contains("resin") || text3.Contains("resina") || text.Contains("bone") || text3.Contains("osso") || text.Contains("chitin") || text3.Contains("quitina") || text.Contains("feather") || text3.Contains("pena") || text.Contains("scale") || text3.Contains("escama") || text.Contains("sinew") || text3.Contains("tendão") || text3.Contains("tendao") || text.Contains("bilebag") || text3.Contains("bile") || text.Contains("freezegland") || text2.Contains("freezegland") || text3.Contains("congelamento") || text.Contains("iceshard") || text2.Contains("iceshard") || text.Contains("glaciershard") || text2.Contains("glaciershard") || text.Contains("tusk") || text.Contains("fur") || text3.Contains("presa") || text3.Contains("pelo"))
			{
				return ItemCategory.CreatureMaterials;
			}
			return ItemCategory.None;
		}

		public static bool ContainerHasCategory(Container container, ItemCategory category)
		{
			if ((Object)(object)container == (Object)null || category == ItemCategory.None)
			{
				return false;
			}
			Inventory inventory = container.GetInventory();
			if (inventory == null)
			{
				return false;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (GetItemCategory(allItem) == category)
				{
					return true;
				}
			}
			return false;
		}

		public static bool ShouldIgnoreItem(ItemData item, Inventory playerInv)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Invalid comparison between Unknown and I4
			if (item == null)
			{
				return true;
			}
			if (item.m_equipped)
			{
				return true;
			}
			if (item.m_shared.m_questItem)
			{
				return true;
			}
			if (PlayerInventoryHelper.IsExtraSlot(item, playerInv))
			{
				return true;
			}
			if (QuickStackPlugin.ProtectHotbar.Value == QuickStackPlugin.Toggle.On && item.m_gridPos.y == 0)
			{
				return true;
			}
			if (QuickStackPlugin.IgnoreNonStackable.Value == QuickStackPlugin.Toggle.On && item.m_shared.m_maxStackSize <= 1 && (int)item.m_shared.m_itemType != 13)
			{
				return true;
			}
			return false;
		}

		public static Container? FindTargetContainerForItem(Player player, ItemData item, Container? currentContainer)
		{
			if ((Object)(object)player == (Object)null || item == null)
			{
				return null;
			}
			if (ShouldIgnoreItem(item, ((Humanoid)player).GetInventory()))
			{
				return null;
			}
			List<Container> nearbyContainers = CraftFromContainers.GetNearbyContainers(player);
			if ((Object)(object)currentContainer != (Object)null && currentContainer.GetInventory() != null && currentContainer.GetInventory().ContainsItemByName(item.m_shared.m_name) && currentContainer.GetInventory().CanAddItem(item, item.m_stack))
			{
				return currentContainer;
			}
			foreach (Container item2 in nearbyContainers)
			{
				if (!((Object)(object)item2 == (Object)(object)currentContainer))
				{
					Inventory inventory = item2.GetInventory();
					if (inventory != null && inventory.ContainsItemByName(item.m_shared.m_name) && inventory.CanAddItem(item, item.m_stack))
					{
						return item2;
					}
				}
			}
			if (QuickStackPlugin.EnableSmartGrouping.Value == QuickStackPlugin.Toggle.On)
			{
				ItemCategory itemCategory = GetItemCategory(item);
				if (itemCategory != ItemCategory.None)
				{
					if ((Object)(object)currentContainer != (Object)null && ContainerHasCategory(currentContainer, itemCategory) && currentContainer.GetInventory().CanAddItem(item, item.m_stack))
					{
						return currentContainer;
					}
					foreach (Container item3 in nearbyContainers)
					{
						if (!((Object)(object)item3 == (Object)(object)currentContainer) && ContainerHasCategory(item3, itemCategory) && item3.GetInventory().CanAddItem(item, item.m_stack))
						{
							return item3;
						}
					}
				}
			}
			return null;
		}

		public static bool RouteItemFromPlayer(Player player, ItemData item, Container currentContainer)
		{
			Container val = FindTargetContainerForItem(player, item, currentContainer);
			if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)currentContainer)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			Inventory inventory2 = val.GetInventory();
			int stack = item.m_stack;
			if (inventory2.AddItem(item))
			{
				inventory.RemoveItem(item);
			}
			else
			{
				if (stack - item.m_stack <= 0)
				{
					return false;
				}
				if (item.m_stack <= 0)
				{
					inventory.RemoveItem(item);
				}
			}
			if ((Object)(object)val.m_nview != (Object)null && val.m_nview.IsValid() && !val.m_nview.IsOwner())
			{
				val.m_nview.ClaimOwnership();
			}
			inventory2.Changed(false, false);
			val.Save();
			inventory.Changed(false, false);
			int num = ((stack - item.m_stack > 0) ? (stack - item.m_stack) : stack);
			ContainerHighlight.Trigger(val, num);
			string text = val.m_name;
			if (string.IsNullOrEmpty(text))
			{
				text = "Baú";
			}
			((Character)player).Message((MessageType)1, $"Roteado para {text}: {item.m_shared.m_name} x{num}", 0, (Sprite)null, false);
			return true;
		}

		public static void RouteAllMatchingFromPlayer(Player player, Container currentContainer)
		{
			Inventory inventory = ((Humanoid)player).GetInventory();
			List<ItemData> list = new List<ItemData>(inventory.GetAllItems());
			int num = 0;
			foreach (ItemData item in list)
			{
				if (ShouldIgnoreItem(item, inventory))
				{
					continue;
				}
				Container val = FindTargetContainerForItem(player, item, currentContainer);
				if (!((Object)(object)val != (Object)null) || !((Object)(object)val != (Object)(object)currentContainer))
				{
					continue;
				}
				Inventory inventory2 = val.GetInventory();
				int stack = item.m_stack;
				if (inventory2.AddItem(item))
				{
					inventory.RemoveItem(item);
					num += stack;
				}
				else
				{
					int num2 = stack - item.m_stack;
					if (num2 > 0)
					{
						num += num2;
						if (item.m_stack <= 0)
						{
							inventory.RemoveItem(item);
						}
					}
				}
				if ((Object)(object)val.m_nview != (Object)null && val.m_nview.IsValid() && !val.m_nview.IsOwner())
				{
					val.m_nview.ClaimOwnership();
				}
				inventory2.Changed(false, false);
				val.Save();
				ContainerHighlight.Trigger(val, stack);
			}
			if (num > 0)
			{
				inventory.Changed(false, false);
				((Character)player).Message((MessageType)1, $"Roteamento inteligente: {num} itens distribuídos nos baús da base!", 0, (Sprite)null, false);
			}
		}
	}
	[HarmonyPatch]
	public static class SmartContainersPatches
	{
		[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
		[HarmonyPrefix]
		public static bool InventoryGui_OnSelectedItem_Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Vector2i pos, Modifier mod)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Invalid comparison between Unknown and I4
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting())
			{
				return true;
			}
			if (QuickStackPlugin.EnableOpenContainerRouting.Value != QuickStackPlugin.Toggle.On)
			{
				return true;
			}
			if (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305))
			{
				return true;
			}
			if ((Object)(object)__instance.m_currentContainer == (Object)null)
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)__instance.m_dragGo) && (int)mod == 2)
			{
				if (item == null || item.m_shared.m_questItem)
				{
					return true;
				}
				if (grid.GetInventory() != __instance.m_currentContainer.GetInventory())
				{
					((Humanoid)localPlayer).RemoveEquipAction(item);
					((Humanoid)localPlayer).UnequipItem(item, true);
					if (SmartContainers.RouteItemFromPlayer(localPlayer, item, __instance.m_currentContainer))
					{
						if (__instance.m_moveItemEffects != null)
						{
							__instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
						}
						return false;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)__instance.m_dragGo) && grid.GetInventory() == __instance.m_currentContainer.GetInventory() && __instance.m_dragInventory == ((Humanoid)localPlayer).GetInventory() && __instance.m_dragItem != null)
			{
				Container val = SmartContainers.FindTargetContainerForItem(localPlayer, __instance.m_dragItem, __instance.m_currentContainer);
				if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)__instance.m_currentContainer)
				{
					Inventory inventory = val.GetInventory();
					int dragAmount = __instance.m_dragAmount;
					ItemData val2 = __instance.m_dragItem.Clone();
					val2.m_stack = dragAmount;
					if (inventory.AddItem(val2))
					{
						__instance.m_dragInventory.RemoveItem(__instance.m_dragItem, dragAmount);
						if ((Object)(object)val.m_nview != (Object)null && val.m_nview.IsValid() && !val.m_nview.IsOwner())
						{
							val.m_nview.ClaimOwnership();
						}
						inventory.Changed(false, false);
						val.Save();
						__instance.m_dragInventory.Changed(false, false);
						ContainerHighlight.Trigger(val, dragAmount);
						if (__instance.m_moveItemEffects != null)
						{
							__instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
						}
						string text = val.m_name;
						if (string.IsNullOrEmpty(text))
						{
							text = "Baú";
						}
						((Character)localPlayer).Message((MessageType)1, $"Roteado para {text}: {__instance.m_dragItem.m_shared.m_name} x{dragAmount}", 0, (Sprite)null, false);
						__instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
						__instance.UpdateCraftingPanel(false);
						return false;
					}
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(InventoryGui), "OnStackAll")]
		[HarmonyPrefix]
		public static void InventoryGui_OnStackAll_Prefix(InventoryGui __instance)
		{
			if (QuickStackPlugin.EnableOpenContainerRouting.Value == QuickStackPlugin.Toggle.On && !((Object)(object)__instance.m_currentContainer == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Character)Player.m_localPlayer).IsTeleporting())
			{
				SmartContainers.RouteAllMatchingFromPlayer(Player.m_localPlayer, __instance.m_currentContainer);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "CloseContainer")]
		[HarmonyPostfix]
		public static void InventoryGui_CloseContainer_Postfix(InventoryGui __instance)
		{
			Container currentContainer = __instance.m_currentContainer;
			if ((Object)(object)currentContainer != (Object)null && currentContainer.GetInventory() != null && currentContainer.GetInventory().GetAllItems().Count == 0 && (Object)(object)currentContainer.m_nview != (Object)null && currentContainer.m_nview.IsValid())
			{
				if (!currentContainer.m_nview.IsOwner())
				{
					currentContainer.m_nview.ClaimOwnership();
				}
				currentContainer.Save();
			}
		}
	}
	public static class BaseAutoFuel
	{
		public class RefuelSummary
		{
			public int FireplacesFed;

			public int FuelAddedToFireplaces;

			public int SmeltersFed;

			public int FuelAddedToSmelters;

			public int OreAddedToSmelters;

			public int OvensFed;

			public int FuelAddedToOvens;

			public bool AnyActivity => FireplacesFed + SmeltersFed + OvensFed > 0;
		}

		public static bool IsTorch(Fireplace fp)
		{
			if ((Object)(object)fp == (Object)null || (Object)(object)((Component)fp).gameObject == (Object)null)
			{
				return false;
			}
			string text = ((Object)((Component)fp).gameObject).name.ToLowerInvariant();
			if (text.Contains("torch") || text.Contains("sconce") || text.Contains("brazier") || text.Contains("lantern") || text.Contains("lamp") || text.Contains("jackoturnip"))
			{
				return true;
			}
			if ((Object)(object)fp.m_fuelItem != (Object)null && fp.m_fuelItem.m_itemData != null && fp.m_fuelItem.m_itemData.m_shared != null)
			{
				string text2 = fp.m_fuelItem.m_itemData.m_shared.m_name.ToLowerInvariant();
				if (text2.Contains("resin") || text2.Contains("guck"))
				{
					return true;
				}
			}
			return false;
		}

		public static void RefuelTorchesOnly(Player player, bool silentIfNothing = false)
		{
			//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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)((Component)player).transform == (Object)null || ((Character)player).IsDead())
			{
				return;
			}
			float value = QuickStackPlugin.AutoFuelRange.Value;
			Vector3 position = ((Component)player).transform.position;
			long playerID = player.GetPlayerID();
			List<Container> nearbyContainers = CraftFromContainers.GetNearbyContainers(player);
			HashSet<Container> hashSet = new HashSet<Container>();
			RefuelSummary refuelSummary = new RefuelSummary();
			RefuelFireplaces(player, position, value, playerID, nearbyContainers, hashSet, refuelSummary, torchesOnly: true);
			foreach (Container item in hashSet)
			{
				if ((Object)(object)item != (Object)null && item.GetInventory() != null)
				{
					item.GetInventory().Changed(false, false);
					item.Save();
				}
			}
			if (refuelSummary.FireplacesFed > 0)
			{
				((Character)player).Message((MessageType)2, $"\ud83d\udd6f\ufe0f Tochas abastecidas: {refuelSummary.FireplacesFed} tochas/arandelas ({refuelSummary.FuelAddedToFireplaces} comb.)", 0, (Sprite)null, false);
				if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.m_moveItemEffects != null)
				{
					InventoryGui.instance.m_moveItemEffects.Create(position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
			}
			else if (!silentIfNothing)
			{
				((Character)player).Message((MessageType)2, "\ud83d\udd6f\ufe0f Todas as tochas e arandelas já estão cheias e acesas!", 0, (Sprite)null, false);
			}
		}

		public static void RefuelFurnacesAndFires(Player player, bool silentIfNothing = false)
		{
			//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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: 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_0293: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)((Component)player).transform == (Object)null || ((Character)player).IsDead())
			{
				return;
			}
			float value = QuickStackPlugin.AutoFuelRange.Value;
			Vector3 position = ((Component)player).transform.position;
			long playerID = player.GetPlayerID();
			List<Container> nearbyContainers = CraftFromContainers.GetNearbyContainers(player);
			HashSet<Container> hashSet = new HashSet<Container>();
			RefuelSummary refuelSummary = new RefuelSummary();
			RefuelFireplaces(player, position, value, playerID, nearbyContainers, hashSet, refuelSummary, torchesOnly: false, excludeTorches: true);
			if (QuickStackPlugin.EnableAutoFuelSmelters.Value == QuickStackPlugin.Toggle.On || QuickStackPlugin.EnableAutoLoadOre.Value == QuickStackPlugin.Toggle.On)
			{
				RefuelSmelters(player, position, value, playerID, nearbyContainers, hashSet, refuelSummary);
			}
			if (QuickStackPlugin.EnableAutoFuelSmelters.Value == QuickStackPlugin.Toggle.On)
			{
				RefuelCookingStations(player, position, value, playerID, nearbyContainers, hashSet, refuelSummary);
			}
			foreach (Container item in hashSet)
			{
				if ((Object)(object)item != (Object)null && item.GetInventory() != null)
				{
					item.GetInventory().Changed(false, false);
					item.Save();
				}
			}
			if (refuelSummary.AnyActivity)
			{
				List<string> list = new List<string>();
				if (refuelSummary.FireplacesFed > 0)
				{
					list.Add($"{refuelSummary.FireplacesFed} fogueiras/lareiras ({refuelSummary.FuelAddedToFireplaces} lenhas)");
				}
				if (refuelSummary.SmeltersFed > 0)
				{
					string text = $"{refuelSummary.SmeltersFed} fornalhas";
					if (refuelSummary.FuelAddedToSmelters > 0 && refuelSummary.OreAddedToSmelters > 0)
					{
						text += $" ({refuelSummary.FuelAddedToSmelters} comb., {refuelSummary.OreAddedToSmelters} minérios)";
					}
					else if (refuelSummary.FuelAddedToSmelters > 0)
					{
						text += $" ({refuelSummary.FuelAddedToSmelters} comb.)";
					}
					else if (refuelSummary.OreAddedToSmelters > 0)
					{
						text += $" ({refuelSummary.OreAddedToSmelters} minérios)";
					}
					list.Add(text);
				}
				if (refuelSummary.OvensFed > 0)
				{
					list.Add($"{refuelSummary.OvensFed} fornos ({refuelSummary.FuelAddedToOvens} lenhas)");
				}
				string text2 = "\ud83d\udd25 Fornalhas/Fogueiras abastecidas: " + string.Join(", ", list);
				((Character)player).Message((MessageType)2, text2, 0, (Sprite)null, false);
				if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.m_moveItemEffects != null)
				{
					InventoryGui.instance.m_moveItemEffects.Create(position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
			}
			else if (!silentIfNothing)
			{
				((Character)player).Message((MessageType)2, "\ud83d\udd25 Todas as fornalhas e fogueiras já estão abastecidas!", 0, (Sprite)null, false);
			}
		}

		public static void RefuelAll(Player player, bool silentIfNothing)
		{
			//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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)((Component)player).transform == (Object)null || ((Character)player).IsDead())
			{
				return;
			}
			float value = QuickStackPlugin.AutoFuelRange.Value;
			Vector3 position = ((Component)player).transform.position;
			long playerID = player.GetPlayerID();
			List<Container> nearbyContainers = CraftFromContainers.GetNearbyContainers(player);
			HashSet<Container> hashSet = new HashSet<Container>();
			RefuelSummary refuelSummary = new RefuelSummary();
			if (QuickStackPlugin.EnableAutoFuelFireplaces.Value == QuickStackPlugin.Toggle.On)
			{
				RefuelFireplaces(player, position, value, playerID, nearbyContainers, hashSet, refuelSummary);
			}
			if (QuickStackPlugin.EnableAutoFuelSmelters.Value == QuickStackPlugin.Toggle.On || QuickStackPlugin.EnableAutoLoadOre.Value == QuickStackPlugin.Toggle.On)
			{
				RefuelSmelters(player, position, value, playerID, nearbyContainers, hashSet, refuelSummary);
			}
			if (QuickStackPlugin.EnableAutoFuelSmelters.Value == QuickStackPlugin.Toggle.On)
			{
				RefuelCookingStations(player, position, value, playerID, nearbyContainers, hashSet, refuelSummary);
			}
			foreach (Container item in hashSet)
			{
				if ((Object)(object)item != (Object)null && item.GetInventory() != null)
				{
					item.GetInventory().Changed(false, false);
					item.Save();
				}
			}
			if (refuelSummary.AnyActivity)
			{
				List<string> list = new List<string>();
				if (refuelSummary.FireplacesFed > 0)
				{
					list.Add($"{refuelSummary.FireplacesFed} tochas/fogueiras ({refuelSummary.FuelAddedToFireplaces} comb.)");
				}
				if (refuelSummary.SmeltersFed > 0)
				{
					string text = $"{refuelSummary.SmeltersFed} fornalhas";
					if (refuelSummary.FuelAddedToSmelters > 0 && refuelSummary.OreAddedToSmelters > 0)
					{
						text += $" ({refuelSummary.FuelAddedToSmelters} comb., {refuelSummary.OreAddedToSmelters} minérios)";
					}
					else if (refuelSummary.FuelAddedToSmelters > 0)
					{
						text += $" ({refuelSummary.FuelAddedToSmelters} comb.)";
					}
					else if (refuelSummary.OreAddedToSmelters > 0)
					{
						text += $" ({refuelSummary.OreAddedToSmelters} minérios)";
					}
					list.Add(text);
				}
				if (refuelSummary.OvensFed > 0)
				{
					list.Add($"{refuelSummary.OvensFed} fornos ({refuelSummary.FuelAddedToOvens} lenhas)");
				}
				string text2 = "\ud83d\udd25 Base abastecida: " + string.Join(", ", list);
				((Character)player).Message((MessageType)2, text2, 0, (Sprite)null, false);
				if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.m_moveItemEffects != null)
				{
					InventoryGui.instance.m_moveItemEffects.Create(position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
			}
			else if (!silentIfNothing)
			{
				((Character)player).Message((MessageType)2, "\ud83d\udd25 Todas as tochas e fornalhas já estão abastecidas!", 0, (Sprite)null, false);
			}
		}

		private static void RefuelFireplaces(Player player, Vector3 playerPos, float range, long playerID, List<Container> containers, HashSet<Container> modifiedContainers, RefuelSummary summary, bool torchesOnly = false, bool excludeTorches = false)
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			HashSet<Fireplace> hashSet = new HashSet<Fireplace>();
			if (Piece.s_allPieces != null)
			{
				foreach (Piece s_allPiece in Piece.s_allPieces)
				{
					if (!((Object)(object)s_allPiece == (Object)null) && !((Object)(object)((Component)s_allPiece).gameObject == (Object)null))
					{
						Fireplace val = ((Component)s_allPiece).GetComponent<Fireplace>() ?? ((Component)s_allPiece).GetComponentInChildren<Fireplace>();
						if ((Object)(object)val != (Object)null)
						{
							hashSet.Add(val);
						}
					}
				}
			}
			Fireplace[] array = Object.FindObjectsByType<Fireplace>((FindObjectsSortMode)0);
			foreach (Fireplace val2 in array)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null)
				{
					hashSet.Add(val2);
				}
			}
			foreach (Fireplace item in hashSet)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).transform == (Object)null || Vector3.Distance(playerPos, ((Component)item).transform.position) > range || !PrivateArea.CheckAccess(((Component)item).transform.position, 0f, false, false) || !item.m_canRefill || item.m_infiniteFuel || (Object)(object)item.m_fuelItem == (Object)null || (torchesOnly && !IsTorch(item)) || (excludeTorches && IsTorch(item)))
				{
					continue;
				}
				ZNetView nview = item.m_nview;
				if ((Object)(object)nview == (Object)null || !nview.IsValid())
				{
					continue;
				}
				float num = nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f);
				int num2 = Mathf.FloorToInt(item.m_maxFuel - num);
				if (num2 <= 0)
				{
					continue;
				}
				string name = item.m_fuelItem.m_itemData.m_shared.m_name;
				int num3 = TakeItem(containers, player, name, num2, modifiedContainers);
				if (num3 > 0)
				{
					if (!nview.IsOwner())
					{
						nview.ClaimOwnership();
					}
					nview.InvokeRPC("RPC_AddFuelAmount", new object[1] { (float)num3 });
					EffectList fuelAddedEffects = item.m_fuelAddedEffects;
					if (fuelAddedEffects != null)
					{
						fuelAddedEffects.Create(((Component)item).transform.position, ((Component)item).transform.rotation, (Transform)null, 1f, -1, default(ZDOID));
					}
					summary.FireplacesFed++;
					summary.FuelAddedToFireplaces += num3;
				}
			}
		}

		private static void RefuelSmelters(Player player, Vector3 playerPos, float range, long playerID, List<Container> containers, HashSet<Container> modifiedContainers, RefuelSummary summary)
		{
			//IL_0111: 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)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: 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_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			HashSet<Smelter> hashSet = new HashSet<Smelter>();
			if (Piece.s_allPieces != null)
			{
				foreach (Piece s_allPiece in Piece.s_allPieces)
				{
					if (!((Object)(object)s_allPiece == (Object)null) && !((Object)(object)((Component)s_allPiece).gameObject == (Object)null))
					{
						Smelter val = ((Component)s_allPiece).GetComponent<Smelter>() ?? ((Component)s_allPiece).GetComponentInChildren<Smelter>();
						if ((Object)(object)val != (Object)null)
						{
							hashSet.Add(val);
						}
					}
				}
			}
			Smelter[] array = Object.FindObjectsByType<Smelter>((FindObjectsSortMode)0);
			foreach (Smelter val2 in array)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null)
				{
					hashSet.Add(val2);
				}
			}
			bool flag = QuickStackPlugin.EnableAutoFuelSmelters.Value == QuickStackPlugin.Toggle.On;
			bool flag2 = QuickStackPlugin.EnableAutoLoadOre.Value == QuickStackPlugin.Toggle.On;
			foreach (Smelter item in hashSet)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).transform == (Object)null || Vector3.Distance(playerPos, ((Component)item).transform.position) > range || !PrivateArea.CheckAccess(((Component)item).transform.position, 0f, false, false))
				{
					continue;
				}
				ZNetView nview = item.m_nview;
				if ((Object)(object)nview == (Object)null || !nview.IsValid())
				{
					continue;
				}
				bool flag3 = false;
				if (flag && (Object)(object)item.m_fuelItem != (Object)null && item.m_maxFuel > 0)
				{
					float fuel = item.GetFuel();
					int num = Mathf.FloorToInt((float)item.m_maxFuel - fuel);
					if (num > 0)
					{
						string name = item.m_fuelItem.m_itemData.m_shared.m_name;
						int num2 = TakeItem(containers, player, name, num, modifiedContainers);
						if (num2 > 0)
						{
							for (int j = 0; j < num2; j++)
							{
								nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>());
							}
							EffectList fuelAddedEffects = item.m_fuelAddedEffects;
							if (fuelAddedEffects != null)
							{
								fuelAddedEffects.Create(((Component)item).transform.position, ((Component)item).transform.rotation, ((Component)item).transform, 1f, -1, default(ZDOID));
							}
							summary.FuelAddedToSmelters += num2;
							flag3 = true;
						}
					}
				}
				if (flag2 && item.m_conversion != null && item.m_conversion.Count > 0 && item.m_maxOre > 0)
				{
					int queueSize = item.GetQueueSize();
					int num3 = item.m_maxOre - queueSize;
					if (num3 > 0)
					{
						string text = ((Object)item).name.ToLower();
						bool flag4 = text.Contains("kiln") || text.Contains("charcoal");
						if (queueSize > 0)
						{
							string queuedPrefab = item.GetQueuedOre();
							ItemConversion val3 = item.m_conversion.Find((ItemConversion c) => (Object)(object)c.m_from != (Object)null && ((Object)((Component)c.m_from).gameObject).name == queuedPrefab);
							if (val3 != null && (Object)(object)val3.m_from != (Object)null && (!flag4 || ((Object)((Component)val3.m_from).gameObject).name == "Wood"))
							{
								string name2 = val3.m_from.m_itemData.m_shared.m_name;
								int num4 = TakeItem(containers, player, name2, num3, modifiedContainers);
								if (num4 > 0)
								{
									for (int num5 = 0; num5 < num4; num5++)
									{
										nview.InvokeRPC("RPC_AddOre", new object[2]
										{
											((Object)((Component)val3.m_from).gameObject).name,
											false
										});
									}
									EffectList oreAddedEffects = item.m_oreAddedEffects;
									if (oreAddedEffects != null)
									{
										oreAddedEffects.Create(((Component)item).transform.position, ((Component)item).transform.rotation, (Transform)null, 1f, -1, default(ZDOID));
									}
									summary.OreAddedToSmelters += num4;
									flag3 = true;
								}
							}
						}
						else
						{
							foreach (ItemConversion item2 in item.m_conversion)
							{
								if (item2 == null || (Object)(object)item2.m_from == (Object)null || (flag4 && ((Object)((Component)item2.m_from).gameObject).name != "Wood"))
								{
									continue;
								}
								string name3 = item2.m_from.m_itemData.m_shared.m_name;
								int num6 = TakeItem(containers, player, name3, num3, modifiedContainers);
								if (num6 > 0)
								{
									for (int num7 = 0; num7 < num6; num7++)
									{
										nview.InvokeRPC("RPC_AddOre", new object[2]
										{
											((Object)((Component)item2.m_from).gameObject).name,
											false
										});
									}
									EffectList oreAddedEffects2 = item.m_oreAddedEffects;
									if (oreAddedEffects2 != null)
									{
										oreAddedEffects2.Create(((Component)item).transform.position, ((Component)item).transform.rotation, (Transform)null, 1f, -1, default(ZDOID));
									}
									summary.OreAddedToSmelters += num6;
									flag3 = true;
									break;
								}
							}
						}
					}
				}
				if (flag3)
				{
					summary.SmeltersFed++;
				}
			}
		}

		private static void RefuelCookingStations(Player player, Vector3 playerPos, float range, long playerID, List<Container> containers, HashSet<Container> modifiedContainers, RefuelSummary summary)
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			HashSet<CookingStation> hashSet = new HashSet<CookingStation>();
			if (Piece.s_allPieces != null)
			{
				foreach (Piece s_allPiece in Piece.s_allPieces)
				{
					if (!((Object)(object)s_allPiece == (Object)null) && !((Object)(object)((Component)s_allPiece).gameObject == (Object)null))
					{
						CookingStation val = ((Component)s_allPiece).GetComponent<CookingStation>() ?? ((Component)s_allPiece).GetComponentInChildren<CookingStation>();
						if ((Object)(object)val != (Object)null)
						{
							hashSet.Add(val);
						}
					}
				}
			}
			CookingStation[] array = Object.FindObjectsByType<CookingStation>((FindObjectsSortMode)0);
			foreach (CookingStation val2 in array)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null)
				{
					hashSet.Add(val2);
				}
			}
			foreach (CookingStation item in hashSet)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).transform == (Object)null || Vector3.Distance(playerPos, ((Component)item).transform.position) > range || !PrivateArea.CheckAccess(((Component)item).transform.position, 0f, false, false) || !item.m_useFuel || (Object)(object)item.m_fuelItem == (Object)null || item.m_maxFuel <= 0)
				{
					continue;
				}
				ZNetView nview = item.m_nview;
				if ((Object)(object)nview == (Object)null || !nview.IsValid())
				{
					continue;
				}
				float fuel = item.GetFuel();
				int num = Mathf.FloorToInt((float)item.m_maxFuel - fuel);
				if (num <= 0)
				{
					continue;
				}
				string name = item.m_fuelItem.m_itemData.m_shared.m_name;
				int num2 = TakeItem(containers, player, name, num, modifiedContainers);
				if (num2 > 0)
				{
					for (int j = 0; j < num2; j++)
					{
						nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>());
					}
					EffectList fuelAddedEffects = item.m_fuelAddedEffects;
					if (fuelAddedEffects != null)
					{
						fuelAddedEffects.Create(((Component)item).transform.position, ((Component)item).transform.rotation, (Transform)null, 1f, -1, default(ZDOID));
					}
					summary.OvensFed++;
					summary.FuelAddedToOvens += num2;
				}
			}
		}

		private static int TakeItem(List<Container> containers, Player player, string itemSharedName, int maxAmount, HashSet<Container> modifiedContainers)
		{
			if (maxAmount <= 0 || string.IsNullOrEmpty(itemSharedName))
			{
				return 0;
			}
			int num = 0;
			foreach (Container container in containers)
			{
				if ((Object)(object)container == (Object)null)
				{
					continue;
				}
				Inventory inventory = container.GetInventory();
				if (inventory == null)
				{
					continue;
				}
				foreach (ItemData item in new List<ItemData>(inventory.GetAllItems()))
				{
					if (item == null || !(item.m_shared.m_name == itemSharedName))
					{
						continue;
					}
					int num2 = Math.Min(item.m_stack, maxAmount - num);
					if (num2 > 0)
					{
						inventory.RemoveItem(item, num2);
						modifiedContainers.Add(container);
						num += num2;
						if (num >= maxAmount)
						{
							return num;
						}
					}
				}
			}
			if (QuickStackPlugin.AutoFuelUsePlayerInventory.Value == QuickStackPlugin.Toggle.On && num < maxAmount)
			{
				Inventory inventory2 = ((Humanoid)player).GetInventory();
				if (inventory2 != null)
				{
					foreach (ItemData item2 in new List<ItemData>(inventory2.GetAllItems()))
					{
						if (item2 == null || !(item2.m_shared.m_name == itemSharedName) || SmartContainers.ShouldIgnoreItem(item2, inventory2))
						{
							continue;
						}
						int num3 = Math.Min(item2.m_stack, maxAmount - num);
						if (num3 > 0)
						{
							inventory2.RemoveItem(item2, num3);
							num += num3;
							if (num >= maxAmount)
							{
								break;
							}
						}
					}
				}
			}
			return num;
		}
	}
	[HarmonyPatch]
	public static class InventoryGuiPatches
	{
		[HarmonyPatch(typeof(UITooltip), "OnHoverStart")]
		public static class UITooltip_OnHoverStart_Patch
		{
			private static GameObject? _cachedTooltipPrefab;

			public static bool Prefix(UITooltip __instance, GameObject go)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return false;
				}
				if ((Object)(object)__instance.m_tooltipPrefab != (Object)null)
				{
					_cachedTooltipPrefab = __instance.m_tooltipPrefab;
				}
				else if ((Object)(object)_cachedTooltipPrefab != (Object)null)
				{
					__instance.m_tooltipPrefab = _cachedTooltipPrefab;
				}
				else if ((Object)(object)InventoryGui.instance != (Object)null)
				{
					UITooltip componentInChildren = ((Component)InventoryGui.instance).GetComponentInChildren<UITooltip>(true);
					if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.m_tooltipPrefab != (Object)null)
					{
						_cachedTooltipPrefab = componentInChildren.m_tooltipPrefab;
						__instance.m_tooltipPrefab = componentInChildren.m_tooltipPrefab;
					}
				}
				if ((Object)(object)UITooltip.m_tooltip == (Object)null && (Object)(object)__instance.m_tooltipPrefab == (Object)null)
				{
					return false;
				}
				return true;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__OnSortClicked;

			public static UnityAction <1>__OnQuickStackClicked;

			public static UnityAction <2>__OnRefuelClicked;

			public static UnityAction <3>__OnRefuelTorchClicked;
		}

		private static GameObject? tabObj;

		private static GameObject? sortButtonObj;

		private static GameObject? quickStackButtonObj;

		private static GameObject? refuelButtonObj;

		private static GameObject? refuelTorchButtonObj;

		private static Sprite? _cachedFlameSprite;

		private static Sprite? _cachedTorchSprite;

		[HarmonyPatch(typeof(InventoryGui), "Awake")]
		[HarmonyPostfix]
		public static void InventoryGui_Awake_Postfix(InventoryGui __instance)
		{
			CreateInventoryButtons(__instance);
		}

		[HarmonyPatch(typeof(InventoryGui), "Show")]
		[HarmonyPostfix]
		public static void InventoryGui_Show_Postfix(InventoryGui __instance)
		{
			if ((Object)(object)tabObj == (Object)null || (Object)(object)sortButtonObj == (Object)null || (Object)(object)quickStackButtonObj == (Object)null || (Object)(object)refuelButtonObj == (Object)null || (Object)(object)refuelTorchButtonObj == (Object)null)
			{
				CreateInventoryButtons(__instance);
			}
			else
			{
				UpdateButtonsPosition();
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Update")]
		[HarmonyPostfix]
		public static void InventoryGui_Update_Postfix(InventoryGui __instance)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//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_0044: 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)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (InventoryGui.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible())
			{
				KeyboardShortcut value = QuickStackPlugin.SortKey.Value;
				KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
				if ((int)mainKey != 0 && Input.GetKeyDown(mainKey))
				{
					OnSortClicked();
				}
				value = QuickStackPlugin.QuickStackKey.Value;
				KeyCode mainKey2 = ((KeyboardShortcut)(ref value)).MainKey;
				if ((int)mainKey2 != 0 && Input.GetKeyDown(mainKey2))
				{
					OnQuickStackClicked();
				}
			}
		}

		private static void UpdateButtonsPosition()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			float value = QuickStackPlugin.ButtonPosX.Value;
			float value2 = QuickStackPlugin.ButtonPosY.Value;
			if ((Object)(object)tabObj != (Object)null)
			{
				RectTransform component = tabObj.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.anchoredPosition = new Vector2(value - 4f, value2);
				}
			}
		}

		private static void CreateInventoryButtons(InventoryGui gui)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Expected O, but got Unknown
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Expected O, but got Unknown
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Expected O, but got Unknown
			if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_player == (Object)null)
			{
				return;
			}
			GameObject val = null;
			if ((Object)(object)gui.m_takeAllButton != (Object)null)
			{
				val = ((Component)gui.m_takeAllButton).gameObject;
			}
			else if ((Object)(object)gui.m_dropButton != (Object)null)
			{
				val = ((Component)gui.m_dropButton).gameObject;
			}
			Transform transform = ((Component)gui.m_player).transform;
			float value = QuickStackPlugin.ButtonPosX.Value;
			float value2 = QuickStackPlugin.ButtonPosY.Value;
			if ((Object)(object)tabObj == (Object)null)
			{
				tabObj = new GameObject("QuickStack_Tab", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				tabObj.transform.SetParent(transform, false);
				tabObj.transform.SetSiblingIndex(0);
				RectTransform component = tabObj.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(1f, 0f);
				component.anchorMax = new Vector2(1f, 0f);
				component.pivot = new Vector2(0f, 0f);
				component.anchoredPosition = new Vector2(value - 4f, value2);
				component.sizeDelta = new Vector2(88f, 82f);
				Image component2 = tabObj.GetComponent<Image>();
				Image tabSourceImage = GetTabSourceImage(gui);
				if ((Object)(object)tabSourceImage != (Object)null && (Object)(object)tabSourceImage.sprite != (Object)null)
				{
					component2.sprite = tabSourceImage.sprite;
					component2.type = (Type)1;
					((Graphic)component2).material = ((Graphic)tabSourceImage).material;
					((Graphic)component2).color = ((Graphic)tabSourceImage).color;
				}
				else
				{
					((Graphic)component2).color = new Color(0.2f, 0.15f, 0.12f, 0.85f);
				}
			}
			Transform transform2 = tabObj.transform;
			if ((Object)(object)sortButtonObj == (Object)null)
			{
				GameObject template = val;
				Vector2 pos = new Vector2(6f, 43f);
				object obj = <>O.<0>__OnSortClicked;
				if (obj == null)
				{
					UnityAction val2 = OnSortClicked;
					<>O.<0>__OnSortClicked = val2;
					obj = (object)val2;
				}
				sortButtonObj = SetupButton(template, transform2, "QuickStack_SortBtn", "S", "Organizar Inventário", pos, (UnityAction)obj);
			}
			if ((Object)(object)quickStackButtonObj == (Object)null)
			{
				GameObject template2 = val;
				Vector2 pos2 = new Vector2(46f, 43f);
				object obj2 = <>O.<1>__OnQuickStackClicked;
				if (obj2 == null)
				{
					UnityAction val3 = OnQuickStackClicked;
					<>O.<1>__OnQuickStackClicked = val3;
					obj2 = (object)val3;
				}
				quickStackButtonObj = SetupButton(template2, transform2, "QuickStack_QuickStackBtn", "Q", "Guardar nos Baús Próximos", pos2, (UnityAction)obj2);
			}
			if ((Object)(object)refuelButtonObj == (Object)null)
			{
				GameObject template3 = val;
				Vector2 pos3 = new Vector2(6f, 5f);
				object obj3 = <>O.<2>__OnRefuelClicked;
				if (obj3 == null)
				{
					UnityAction val4 = OnRefuelClicked;
					<>O.<2>__OnRefuelClicked = val4;
					obj3 = (object)val4;
				}
				refuelButtonObj = SetupButton(template3, transform2, "QuickStack_RefuelBtn", "\ud83d\udd25", "Alimentar Fornalhas e Fogueiras (Carvão, Madeira, Minérios)", pos3, (UnityAction)obj3, (Vector2?)new Vector2(34f, 34f));
			}
			if ((Object)(object)refuelTorchButtonObj == (Object)null)
			{
				GameObject template4 = val;
				Vector2 pos4 = new Vector2(46f, 5f);
				object obj4 = <>O.<3>__OnRefuelTorchClicked;
				if (obj4 == null)
				{
					UnityAction val5 = OnRefuelTorchClicked;
					<>O.<3>__OnRefuelTorchClicked = val5;
					obj4 = (object)val5;
				}
				refuelTorchButtonObj = SetupButton(template4, transform2, "QuickStack_RefuelTorchBtn", "\ud83d\udd6f\ufe0f", "Alimentar Tochas e Iluminação (Resina, Madeira, Carvão)", pos4, (UnityAction)obj4, (Vector2?)new Vector2(34f, 34f));
			}
		}

		private static Image? GetTabSourceImage(InventoryGui gui)
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			if ((Object)(object)gui.m_weight != (Object)null && (Object)(object)gui.m_weight.transform.parent != (Object)null)
			{
				Image component = ((Component)gui.m_weight.transform.parent).GetComponent<Image>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null)
				{
					return component;
				}
			}
			if ((Object)(object)gui.m_armor != (Object)null && (Object)(object)gui.m_armor.transform.parent != (Object)null)
			{
				Image component2 = ((Component)gui.m_armor.transform.parent).GetComponent<Image>();
				if ((Object)(object)component2 != (Object)null && (Object)(object)component2.sprite != (Object)null)
				{
					return component2;
				}
			}
			if ((Object)(object)gui.m_player != (Object)null)
			{
				foreach (Transform item in ((Component)gui.m_player).transform)
				{
					Transform val = item;
					string text = ((Object)val).name.ToLower();
					if (text.Contains("weight") || text.Contains("armor") || text.Contains("info"))
					{
						Image component3 = ((Component)val).GetComponent<Image>();
						if ((Object)(object)component3 != (Object)null && (Object)(object)component3.sprite != (Object)null)
						{
							return component3;
						}
					}
				}