Decompiled source of DadsEPI v1.4.11

DadsEPI.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("DadsEPI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.11.0")]
[assembly: AssemblyInformationalVersion("1.4.11+ddddd6244dbffd0cb45f333fab804fa19841936a")]
[assembly: AssemblyProduct("DadsEPI")]
[assembly: AssemblyTitle("DadsEPI")]
[assembly: AssemblyVersion("1.4.11.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DadsEPI
{
	[BepInPlugin("com.dadisbored.dadsepi", "DadsEPI", "1.4.11")]
	[BepInProcess("valheim.exe")]
	public sealed class DadsEPIPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.dadisbored.dadsepi";

		public const string PluginName = "DadsEPI";

		public const string PluginVersion = "1.4.11";

		internal static ConfigEntry<bool> ModEnabled;

		internal static ConfigEntry<int> ExtraRows;

		internal static ConfigEntry<bool> EquipmentRowEnabled;

		internal static ConfigEntry<bool> SeparateEquipmentPanel;

		internal static ConfigEntry<bool> AutoEquip;

		internal static ConfigEntry<int> QuickSlotCount;

		internal static ConfigEntry<bool> ShowQuickSlots;

		internal static ConfigEntry<bool> AlwaysShowQuickSlots;

		internal static ConfigEntry<int> QuickSlotsPerRow;

		internal static ConfigEntry<bool> WisplightSlot;

		internal static ConfigEntry<bool> WishboneSlot;

		internal static ConfigEntry<bool> CryptKeySlot;

		internal static ConfigEntry<bool> ArrowsSlot;

		internal static ConfigEntry<bool> TrinketSlot;

		internal static ConfigEntry<bool> ShieldSlot;

		internal static ConfigEntry<bool> UtilitySlot;

		internal static ConfigEntry<string> RemovedEquipmentSlots;

		internal static readonly ConfigEntry<string>[] CustomSlotNames = new ConfigEntry<string>[10];

		internal static readonly ConfigEntry<string>[] CustomSlotItems = new ConfigEntry<string>[10];

		internal static ConfigEntry<string> HeadLabel;

		internal static ConfigEntry<string> ChestLabel;

		internal static ConfigEntry<string> LegsLabel;

		internal static ConfigEntry<string> BackLabel;

		internal static ConfigEntry<string> UtilityLabel;

		internal static ConfigEntry<float> HudScale;

		internal static ConfigEntry<Vector2> HudPosition;

		internal static ConfigEntry<KeyboardShortcut> HudDragKeys;

		internal static readonly ConfigEntry<KeyboardShortcut>[] QuickHotkeys = new ConfigEntry<KeyboardShortcut>[8];

		internal static readonly ConfigEntry<string>[] QuickHotkeyLabels = new ConfigEntry<string>[8];

		internal static ManualLogSource ModLogger;

		private Harmony _harmony;

		private float _nextLayoutCheck;

		private static int _configEditDepth;

		private static bool _layoutChangePending;

		private static bool _displayChangePending;

		internal static bool ConfigEditActive => _configEditDepth > 0;

		public static void BeginConfigEdit()
		{
			_configEditDepth++;
		}

		public static void EndConfigEdit()
		{
			if (_configEditDepth != 0 && --_configEditDepth <= 0)
			{
				bool layoutChangePending = _layoutChangePending;
				bool displayChangePending = _displayChangePending;
				_layoutChangePending = false;
				_displayChangePending = false;
				if (layoutChangePending)
				{
					OnLayoutSettingChanged(null, EventArgs.Empty);
				}
				else if (displayChangePending)
				{
					OnDisplaySettingChanged(null, EventArgs.Empty);
				}
			}
		}

		private void Awake()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0578: Unknown result type (might be due to invalid IL or missing references)
			//IL_057d: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_09cb: Expected O, but got Unknown
			ModLogger = ((BaseUnityPlugin)this).Logger;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Server & Sync", "Mod Enabled", true, "Enable DadsEPI.");
			ExtraRows = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Inventory", "Extra Inventory Rows", 0, new ConfigDescription("Additional ordinary rows; zero retains the native inventory size.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>()));
			EquipmentRowEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Inventory", "Enable Equipment Row", true, "Add dedicated equipment and quick slots.");
			SeparateEquipmentPanel = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Inventory", "Display Equipment in Separate Panel", true, "Render dedicated slots in a labeled side panel.");
			AutoEquip = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Inventory", "Auto-Equip Items", true, "Equip items placed in equipment slots.");
			QuickSlotCount = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Quick Slots", "Number of Quick Slots", 3, new ConfigDescription("Number of quick slots.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 8), Array.Empty<object>()));
			ShowQuickSlots = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Quick Slots", "Show Quick Slots on HUD", true, "Display quick slots during gameplay.");
			AlwaysShowQuickSlots = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Quick Slots", "Always Show All Slots", true, "Display empty quick slots on the HUD.");
			QuickSlotsPerRow = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Quick Slots", "Slots Per Row", 8, new ConfigDescription("Maximum quick slots per HUD row.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>()));
			WisplightSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Wisplight Slot", true, "Add a Wisplight-only slot.");
			WishboneSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Wishbone Slot", true, "Add a Wishbone-only slot.");
			CryptKeySlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Crypt Key Slot", true, "Add a Crypt Key-only slot.");
			ArrowsSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Arrows Slot", true, "Add an arrow and bolt ammunition slot.");
			TrinketSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Trinket Slot", true, "Add a slot for the listed trinket prefabs.");
			ShieldSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Shield Slot", true, "Add a shield-only slot.");
			UtilitySlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Utility Slot", true, "Add a utility-item slot.");
			RemovedEquipmentSlots = ((BaseUnityPlugin)this).Config.Bind<string>("4.5 - Equipment Slot Management", "Removed Equipment Slots", "", "Comma or semicolon separated slot names.");
			for (int i = 0; i < CustomSlotNames.Length; i++)
			{
				int num = i + 1;
				CustomSlotNames[i] = ((BaseUnityPlugin)this).Config.Bind<string>("4.5 - Equipment Slot Management", $"Custom Slot {num} Name", "", "Visible name for this custom equipment slot. Leave blank to disable it.");
				CustomSlotItems[i] = ((BaseUnityPlugin)this).Config.Bind<string>("4.5 - Equipment Slot Management", $"Custom Slot {num} Items", "", "Comma-separated exact in-game prefab names accepted by this slot.");
			}
			HeadLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Head Slot Label", "Head", "Helmet slot label.");
			ChestLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Chest Slot Label", "Chest", "Chest slot label.");
			LegsLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Legs Slot Label", "Legs", "Leg slot label.");
			BackLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Back Slot Label", "Back", "Shoulder slot label.");
			UtilityLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Utility Slot Label", "Utility", "Utility slot label.");
			HudScale = ((BaseUnityPlugin)this).Config.Bind<float>("7 - Quick Slots Customization", "HUD Size", 1f, "Quick-slot HUD scale.");
			HudPosition = ((BaseUnityPlugin)this).Config.Bind<Vector2>("7 - Quick Slots Customization", "HUD Position", new Vector2(47f, -115f), "Legacy setting; quick slots stay anchored directly below the hotbar.");
			HudDragKeys = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("7 - Quick Slots Customization", "Drag to Reposition Keys", new KeyboardShortcut((KeyCode)323, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Legacy setting; quick-slot dragging is disabled.");
			KeyboardShortcut[] array = (KeyboardShortcut[])(object)new KeyboardShortcut[8]
			{
				new KeyboardShortcut((KeyCode)122, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
				new KeyboardShortcut((KeyCode)120, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
				new KeyboardShortcut((KeyCode)99, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
				new KeyboardShortcut((KeyCode)118, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
				new KeyboardShortcut((KeyCode)98, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
				new KeyboardShortcut((KeyCode)110, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
				new KeyboardShortcut((KeyCode)49, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
				new KeyboardShortcut((KeyCode)50, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 })
			};
			for (int j = 0; j < 8; j++)
			{
				int num2 = j + 1;
				QuickHotkeys[j] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("8 - Quick Slot Hotkeys", $"Hotkey {num2}", array[j], $"Shortcut for quick slot {num2}.");
				QuickHotkeyLabels[j] = ((BaseUnityPlugin)this).Config.Bind<string>("8 - Quick Slot Hotkeys", $"Hotkey {num2} Display Text", "Alt + " + ((object)((KeyboardShortcut)(ref array[j])).MainKey/*cast due to .constrained prefix*/).ToString().Replace("Alpha", ""), $"HUD text for quick slot {num2}.");
			}
			Watch<bool>(ModEnabled, OnDisplaySettingChanged);
			Watch<int>(ExtraRows, OnLayoutSettingChanged);
			Watch<bool>(EquipmentRowEnabled, OnLayoutSettingChanged);
			Watch<bool>(SeparateEquipmentPanel, OnDisplaySettingChanged);
			Watch<bool>(AutoEquip, OnDisplaySettingChanged);
			Watch<int>(QuickSlotCount, OnLayoutSettingChanged);
			Watch<bool>(ShowQuickSlots, OnDisplaySettingChanged);
			Watch<bool>(AlwaysShowQuickSlots, OnDisplaySettingChanged);
			Watch<int>(QuickSlotsPerRow, OnDisplaySettingChanged);
			Watch<bool>(WisplightSlot, OnLayoutSettingChanged);
			Watch<bool>(WishboneSlot, OnLayoutSettingChanged);
			Watch<bool>(CryptKeySlot, OnLayoutSettingChanged);
			Watch<bool>(ArrowsSlot, OnLayoutSettingChanged);
			Watch<bool>(TrinketSlot, OnLayoutSettingChanged);
			Watch<bool>(ShieldSlot, OnLayoutSettingChanged);
			Watch<bool>(UtilitySlot, OnLayoutSettingChanged);
			Watch<string>(RemovedEquipmentSlots, OnLayoutSettingChanged);
			for (int k = 0; k < CustomSlotNames.Length; k++)
			{
				Watch<string>(CustomSlotNames[k], OnLayoutSettingChanged);
				Watch<string>(CustomSlotItems[k], OnLayoutSettingChanged);
			}
			Watch<string>(HeadLabel, OnLayoutSettingChanged);
			Watch<string>(ChestLabel, OnLayoutSettingChanged);
			Watch<string>(LegsLabel, OnLayoutSettingChanged);
			Watch<string>(BackLabel, OnLayoutSettingChanged);
			Watch<string>(UtilityLabel, OnLayoutSettingChanged);
			for (int l = 0; l < 8; l++)
			{
				Watch<KeyboardShortcut>(QuickHotkeys[l], OnDisplaySettingChanged);
				Watch<string>(QuickHotkeyLabels[l], OnDisplaySettingChanged);
			}
			InventoryLayout.RebuildSlots();
			_harmony = new Harmony("com.dadisbored.dadsepi");
			_harmony.PatchAll(typeof(DadsEPIPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DadsEPI 1.4.11 initialized with separate equipment and quick-slot compartments.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void Watch<T>(ConfigEntry<T> entry, EventHandler handler)
		{
			entry.SettingChanged += handler;
		}

		private static void OnLayoutSettingChanged(object sender, EventArgs args)
		{
			if (ConfigEditActive)
			{
				_layoutChangePending = true;
				return;
			}
			InventoryLayout.RebuildForConfigChange(Player.m_localPlayer);
			SlotVisuals.Reset();
			QuickSlotHud.Reset();
		}

		private static void OnDisplaySettingChanged(object sender, EventArgs args)
		{
			if (ConfigEditActive)
			{
				_displayChangePending = true;
				return;
			}
			InventoryLayout.RebuildSlots();
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				InventoryLayout.Apply(Player.m_localPlayer, normalizeItems: false);
			}
			SlotVisuals.Reset();
			QuickSlotHud.Reset();
		}

		private void Update()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigEditActive)
			{
				return;
			}
			ConfigEntry<bool> modEnabled = ModEnabled;
			if (modEnabled == null || !modEnabled.Value || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			if (Time.unscaledTime >= _nextLayoutCheck)
			{
				_nextLayoutCheck = Time.unscaledTime + 0.5f;
				InventoryLayout.Apply(Player.m_localPlayer, normalizeItems: false);
			}
			if (InputBlocked())
			{
				return;
			}
			for (int i = 0; i < InventoryLayout.EnabledQuickSlots; i++)
			{
				if (ShortcutPressed(QuickHotkeys[i].Value))
				{
					InventoryLayout.UseQuickSlot(i);
				}
			}
		}

		private static bool ShortcutPressed(KeyboardShortcut shortcut)
		{
			//IL_0002: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return true;
		}

		private static bool InputBlocked()
		{
			if (!Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen())
			{
				if ((Object)(object)Chat.instance != (Object)null)
				{
					return Chat.instance.HasFocus();
				}
				return false;
			}
			return true;
		}
	}
	internal sealed class DedicatedSlot
	{
		internal string Id;

		internal string Label;

		internal bool Quick;

		internal Func<ItemData, bool> Accepts;
	}
	internal static class InventoryLayout
	{
		internal const int BaseVanillaRows = 4;

		internal const int MaximumVanillaRows = 9;

		internal static readonly List<DedicatedSlot> Slots = new List<DedicatedSlot>();

		private static bool _normalizing;

		private static ItemData _pendingAutoItem;

		private static int _equipmentSlotCount;

		private static int _layoutNormalRows = 4;

		private static InventoryGui _lastGui;

		private static int _lastDisplayedRows = -1;

		private static bool _lastSeparatePanel;

		private static readonly HashSet<string> DefaultAmmoPrefabs = new HashSet<string>(StringComparer.Ordinal)
		{
			"ArrowWood", "ArrowFlint", "ArrowBronze", "ArrowFire", "ArrowIron", "ArrowPoison", "ArrowObsidian", "ArrowFrost", "ArrowSilver", "ArrowNeedle",
			"ArrowCarapace", "ArrowCharred", "ArrowBloodGold", "BoltBone", "BoltIron", "BoltBlackmetal", "BoltCarapace", "BoltCharred", "BoltBloodGold"
		};

		private static readonly HashSet<string> TrinketPrefabs = new HashSet<string>(StringComparer.Ordinal)
		{
			"TrinketBlackDamageHealth", "TrinketBlackStamina", "TrinketBloodGoldHealth", "TrinketBloodGoldStamina", "TrinketBronzeHealth", "TrinketBronzeStamina", "TrinketCarapaceEitr", "TrinketChitinSwim", "TrinketFlametalEitr", "TrinketFlametalStaminaHealth",
			"TrinketIronHealth", "TrinketIronStamina", "TrinketScaleStaminaDamage", "TrinketSilverDamage", "TrinketSilverResist"
		};

		internal static int VanillaRows { get; private set; } = 4;

		internal static int NormalRows
		{
			get
			{
				if (!DadsEPIPlugin.ConfigEditActive)
				{
					return Mathf.Clamp(VanillaRows, 4, 9) + Mathf.Clamp(DadsEPIPlugin.ExtraRows.Value, 0, 5);
				}
				return _layoutNormalRows;
			}
		}

		internal static int EquipmentSlotCount => _equipmentSlotCount;

		internal static int EnabledQuickSlots
		{
			get
			{
				if (!DadsEPIPlugin.ConfigEditActive)
				{
					if (!DadsEPIPlugin.EquipmentRowEnabled.Value)
					{
						return 0;
					}
					return Mathf.Clamp(DadsEPIPlugin.QuickSlotCount.Value, 0, 8);
				}
				return Slots.Count - _equipmentSlotCount;
			}
		}

		internal static int StorageRows(int width)
		{
			if (!DadsEPIPlugin.ConfigEditActive && !DadsEPIPlugin.EquipmentRowEnabled.Value)
			{
				return 0;
			}
			return Mathf.CeilToInt((float)Slots.Count / (float)Mathf.Max(1, width));
		}

		internal static int TotalRows(int width)
		{
			return NormalRows + StorageRows(width);
		}

		internal static void RebuildSlots()
		{
			Slots.Clear();
			_equipmentSlotCount = 0;
			_layoutNormalRows = NormalRows;
			_lastDisplayedRows = -1;
			ConfigEntry<bool> equipmentRowEnabled = DadsEPIPlugin.EquipmentRowEnabled;
			if (equipmentRowEnabled == null || !equipmentRowEnabled.Value)
			{
				return;
			}
			AddEquipment("Head", DadsEPIPlugin.HeadLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 6);
			AddEquipment("Chest", DadsEPIPlugin.ChestLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 7);
			AddEquipment("Legs", DadsEPIPlugin.LegsLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 11);
			AddEquipment("Back", DadsEPIPlugin.BackLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 17);
			if (DadsEPIPlugin.WisplightSlot.Value)
			{
				AddEquipment("Wisplight", "Wisplight", IsWisplight);
			}
			if (DadsEPIPlugin.WishboneSlot.Value)
			{
				AddEquipment("Wishbone", "Wishbone", (ItemData item) => IsPrefab(item, "Wishbone"));
			}
			if (DadsEPIPlugin.CryptKeySlot.Value)
			{
				AddEquipment("Crypt Key", "Crypt Key", (ItemData item) => IsPrefab(item, "CryptKey"));
			}
			if (DadsEPIPlugin.ArrowsSlot.Value)
			{
				AddEquipment("Arrows", "Arrows", IsArrow);
			}
			if (DadsEPIPlugin.TrinketSlot.Value)
			{
				AddEquipment("Trinket", "Trinket", (ItemData item) => TrinketPrefabs.Contains(PrefabName(item)));
			}
			if (DadsEPIPlugin.ShieldSlot.Value)
			{
				AddEquipment("Shield", "Shield", (ItemData item) => (int)item.m_shared.m_itemType == 5);
			}
			if (DadsEPIPlugin.UtilitySlot.Value)
			{
				AddEquipment("Utility", DadsEPIPlugin.UtilityLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 18 && (!DadsEPIPlugin.WishboneSlot.Value || !IsPrefab(item, "Wishbone")) && (!DadsEPIPlugin.WisplightSlot.Value || !IsWisplight(item)));
			}
			for (int num = 0; num < DadsEPIPlugin.CustomSlotNames.Length; num++)
			{
				string text = (DadsEPIPlugin.CustomSlotNames[num].Value ?? string.Empty).Trim();
				HashSet<string> prefabs = new HashSet<string>(from value in (DadsEPIPlugin.CustomSlotItems[num].Value ?? string.Empty).Split(new char[1] { ',' })
					select value.Trim() into value
					where value.Length > 0
					select value, StringComparer.Ordinal);
				if (text.Length > 0 && prefabs.Count > 0)
				{
					AddEquipment(text, text, (ItemData item) => prefabs.Contains(PrefabName(item)));
				}
			}
			_equipmentSlotCount = Slots.Count;
			for (int num2 = 0; num2 < Mathf.Clamp(DadsEPIPlugin.QuickSlotCount.Value, 0, 8); num2++)
			{
				int num3 = num2;
				Slots.Add(new DedicatedSlot
				{
					Id = $"Quick{num3 + 1}",
					Label = QuickLabel(num3),
					Quick = true,
					Accepts = (ItemData item) => true
				});
			}
		}

		internal static void RebuildForConfigChange(Player player)
		{
			int layoutNormalRows = _layoutNormalRows;
			DedicatedSlot[] array = Slots.ToArray();
			RebuildSlots();
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value)
			{
				return;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory != null)
			{
				bool flag = layoutNormalRows != NormalRows || array.Length != Slots.Count;
				int num = 0;
				while (!flag && num < array.Length)
				{
					flag = array[num].Id != Slots[num].Id || array[num].Quick != Slots[num].Quick;
					num++;
				}
				if (flag)
				{
					MigrateSlots(inventory, layoutNormalRows, array);
				}
				Apply(player, normalizeItems: false);
			}
		}

		private static void MigrateSlots(Inventory inventory, int previousRows, DedicatedSlot[] previousSlots)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: 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)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: 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_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: 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_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			int width = inventory.GetWidth();
			if (width <= 0)
			{
				return;
			}
			List<ItemData> list = new List<ItemData>(inventory.GetAllItems());
			Dictionary<ItemData, Vector2i> dictionary = new Dictionary<ItemData, Vector2i>();
			HashSet<long> hashSet = new HashSet<long>();
			HashSet<int> hashSet2 = new HashSet<int>();
			Vector2i val = default(Vector2i);
			for (int i = 0; i < previousSlots.Length; i++)
			{
				((Vector2i)(ref val))..ctor(i % width, previousRows + i / width);
				ItemData itemAt = inventory.GetItemAt(val.x, val.y);
				if (itemAt == null)
				{
					continue;
				}
				for (int j = 0; j < Slots.Count; j++)
				{
					if (!hashSet2.Contains(j) && !(previousSlots[i].Id != Slots[j].Id) && previousSlots[i].Quick == Slots[j].Quick && Slots[j].Accepts(itemAt))
					{
						Vector2i position = (dictionary[itemAt] = SlotPosition(j, width));
						hashSet.Add(PositionKey(position, width));
						hashSet2.Add(j);
						break;
					}
				}
			}
			foreach (ItemData item2 in list)
			{
				if (!dictionary.ContainsKey(item2))
				{
					Vector2i gridPos = item2.m_gridPos;
					int num = (gridPos.y - previousRows) * width + gridPos.x;
					bool flag = num >= 0 && num < previousSlots.Length;
					bool flag2 = gridPos.y >= 0 && gridPos.y < NormalRows;
					bool flag3 = gridPos.y >= NormalRows && SlotIndex(gridPos, width) < 0 && !flag;
					long item = PositionKey(gridPos, width);
					if (gridPos.x >= 0 && gridPos.x < width && (flag2 || flag3) && hashSet.Add(item))
					{
						dictionary[item2] = gridPos;
					}
				}
			}
			int k = Math.Max(TotalRows(width), inventory.GetHeight());
			Vector2i val3 = default(Vector2i);
			foreach (ItemData item3 in list)
			{
				if (dictionary.ContainsKey(item3))
				{
					continue;
				}
				((Vector2i)(ref val3))..ctor(-1, -1);
				for (int l = 0; l < NormalRows; l++)
				{
					if (val3.x >= 0)
					{
						break;
					}
					for (int m = 0; m < width; m++)
					{
						if (hashSet.Add(PositionKey(new Vector2i(m, l), width)))
						{
							((Vector2i)(ref val3))..ctor(m, l);
							break;
						}
					}
				}
				if (val3.x < 0)
				{
					for (; hashSet.Contains(PositionKey(new Vector2i(0, k), width)); k++)
					{
					}
					((Vector2i)(ref val3))..ctor(0, k++);
					hashSet.Add(PositionKey(val3, width));
					ManualLogSource modLogger = DadsEPIPlugin.ModLogger;
					if (modLogger != null)
					{
						modLogger.LogWarning((object)"Inventory capacity decreased; an item was retained in an overflow row.");
					}
				}
				dictionary[item3] = val3;
			}
			bool flag4 = false;
			foreach (ItemData item4 in list)
			{
				Vector2i val4 = dictionary[item4];
				if (!(item4.m_gridPos == val4))
				{
					item4.m_gridPos = val4;
					flag4 = true;
				}
			}
			if (flag4)
			{
				inventory.m_onChanged?.Invoke();
			}
		}

		private static long PositionKey(Vector2i position, int width)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return (long)position.y * (long)width + position.x;
		}

		internal static void SetVanillaRows(int rows)
		{
			VanillaRows = Mathf.Clamp(rows, 4, 9);
		}

		internal static void ReadVanillaRows(Player player)
		{
			string s = default(string);
			if ((Object)(object)player != (Object)null && player.TryGetUniqueKeyValue("invrows", ref s) && int.TryParse(s, out var result))
			{
				SetVanillaRows(result);
			}
			else
			{
				SetVanillaRows(4);
			}
		}

		internal static void Apply(Player player, bool normalizeItems)
		{
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value)
			{
				return;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return;
			}
			ReadVanillaRows(player);
			int num = TotalRows(inventory.GetWidth());
			if (inventory.GetHeight() < num)
			{
				inventory.SetHeight(num);
			}
			if (normalizeItems)
			{
				Normalize(player, inventory);
			}
			int num2 = 0;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				num2 = Math.Max(num2, allItem.m_gridPos.y + 1);
			}
			int num3 = Mathf.Max(num, num2);
			if (inventory.GetHeight() != num3)
			{
				inventory.SetHeight(num3);
			}
			_layoutNormalRows = NormalRows;
			InventoryGui instance = InventoryGui.instance;
			bool value = DadsEPIPlugin.SeparateEquipmentPanel.Value;
			int num4 = (value ? NormalRows : num3);
			if ((Object)(object)instance != (Object)null && ((Object)(object)instance != (Object)(object)_lastGui || num4 != _lastDisplayedRows || value != _lastSeparatePanel || normalizeItems))
			{
				instance.SetInventorySize(num4);
				_lastGui = instance;
				_lastDisplayedRows = num4;
				_lastSeparatePanel = value;
			}
			if ((Object)(object)player.m_tombstone != (Object)null)
			{
				Container component = player.m_tombstone.GetComponent<Container>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_height = num3;
				}
			}
		}

		internal static bool IsPlayerInventory(Inventory inventory)
		{
			if (inventory != null && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				return inventory == ((Humanoid)Player.m_localPlayer).GetInventory();
			}
			return false;
		}

		internal static int SlotIndex(Vector2i position, int width)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			int num = position.y * width + position.x - NormalRows * width;
			if (num < 0 || num >= Slots.Count)
			{
				return -1;
			}
			return num;
		}

		internal static Vector2i SlotPosition(int slotIndex, int width)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			int num = NormalRows * width + slotIndex;
			return new Vector2i(num % width, num / width);
		}

		internal static bool IsReserved(Vector2i position, int width)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return SlotIndex(position, width) >= 0;
		}

		internal static bool IsInEquipmentSlot(Inventory inventory, ItemData item)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (inventory == null || item == null)
			{
				return false;
			}
			int num = SlotIndex(item.m_gridPos, inventory.GetWidth());
			if (num < 0 || num >= EquipmentSlotCount || !Slots[num].Accepts(item))
			{
				return false;
			}
			return inventory.GetItemAt(item.m_gridPos.x, item.m_gridPos.y) == item;
		}

		internal static bool UsesSeparateEquipmentSlot(Inventory inventory, ItemData item, ItemData equippedItem)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (inventory == null || item == null || equippedItem == null)
			{
				return false;
			}
			int num = FindEquipmentSlot(item);
			int num2 = SlotIndex(equippedItem.m_gridPos, inventory.GetWidth());
			if (num >= 0 && num2 >= 0 && num2 < EquipmentSlotCount)
			{
				return num != num2;
			}
			return false;
		}

		internal static bool CanPlace(ItemData item, Vector2i position, int width)
		{
			//IL_0000: 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)
			int num = SlotIndex(position, width);
			if (num < 0)
			{
				return position.y < NormalRows;
			}
			if (item != null)
			{
				return Slots[num].Accepts(item);
			}
			return true;
		}

		internal static Vector2i FindGeneralEmpty(Inventory inventory, bool topFirst)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (topFirst)
			{
				for (int i = 0; i < NormalRows; i++)
				{
					for (int j = 0; j < inventory.GetWidth(); j++)
					{
						if (inventory.GetItemAt(j, i) == null)
						{
							return new Vector2i(j, i);
						}
					}
				}
			}
			else
			{
				for (int num = NormalRows - 1; num >= 0; num--)
				{
					for (int k = 0; k < inventory.GetWidth(); k++)
					{
						if (inventory.GetItemAt(k, num) == null)
						{
							return new Vector2i(k, num);
						}
					}
				}
			}
			return new Vector2i(-1, -1);
		}

		internal static void BeginAutoAdd(Inventory inventory, ItemData item)
		{
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			object pendingAutoItem;
			if (modEnabled != null && modEnabled.Value)
			{
				ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip;
				if (autoEquip != null && autoEquip.Value && IsPlayerInventory(inventory))
				{
					pendingAutoItem = item;
					goto IL_0032;
				}
			}
			pendingAutoItem = null;
			goto IL_0032;
			IL_0032:
			_pendingAutoItem = (ItemData)pendingAutoItem;
		}

		internal static void EndAutoAdd()
		{
			_pendingAutoItem = null;
		}

		internal static Vector2i FindPreferredEmpty(Inventory inventory, bool topFirst)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (_pendingAutoItem != null)
			{
				int num = FindEquipmentSlot(_pendingAutoItem);
				if (num >= 0)
				{
					Vector2i val = SlotPosition(num, inventory.GetWidth());
					if (inventory.GetItemAt(val.x, val.y) == null)
					{
						return val;
					}
				}
			}
			return FindGeneralEmpty(inventory, topFirst);
		}

		internal static int CountGeneralEmpty(Inventory inventory)
		{
			int num = 0;
			for (int i = 0; i < NormalRows; i++)
			{
				for (int j = 0; j < inventory.GetWidth(); j++)
				{
					if (inventory.GetItemAt(j, i) == null)
					{
						num++;
					}
				}
			}
			return num;
		}

		internal static void UseQuickSlot(int index)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && index >= 0 && index < EnabledQuickSlots)
			{
				int slotIndex = EquipmentSlotCount + index;
				ItemData itemAt = ((Humanoid)localPlayer).GetInventory().GetItemAt(SlotPosition(slotIndex, ((Humanoid)localPlayer).GetInventory().GetWidth()).x, SlotPosition(slotIndex, ((Humanoid)localPlayer).GetInventory().GetWidth()).y);
				if (itemAt != null)
				{
					((Humanoid)localPlayer).UseItem(((Humanoid)localPlayer).GetInventory(), itemAt, false);
				}
			}
		}

		internal static void MoveEquippedItemToDedicatedSlot(Player player, ItemData item)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!_normalizing && !((Object)(object)player == (Object)null) && item != null)
			{
				int num = FindEquipmentSlot(item);
				if (num >= 0)
				{
					MoveItem(player, ((Humanoid)player).GetInventory(), item, SlotPosition(num, ((Humanoid)player).GetInventory().GetWidth()));
				}
			}
		}

		internal static void AutoPlaceNewItem(Player player, Inventory inventory, ItemData item)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			if (_normalizing || (Object)(object)player == (Object)null || inventory == null || item == null)
			{
				return;
			}
			ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip;
			if (autoEquip == null || !autoEquip.Value || inventory != ((Humanoid)player).GetInventory())
			{
				return;
			}
			int slot = FindEquipmentSlot(item);
			if (slot < 0)
			{
				return;
			}
			Vector2i val = SlotPosition(slot, inventory.GetWidth());
			ItemData itemAt = inventory.GetItemAt(val.x, val.y);
			if (itemAt != null)
			{
				if (itemAt == item && itemAt.IsEquipable() && !itemAt.m_equipped)
				{
					((Humanoid)player).EquipItem(itemAt, true);
				}
				return;
			}
			ItemData val2 = (ItemData)(inventory.GetAllItems().Contains(item) ? ((object)item) : ((object)((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData candidate) => Slots[slot].Accepts(candidate) && string.Equals(PrefabName(candidate), PrefabName(item), StringComparison.Ordinal)))));
			if (val2 != null)
			{
				MoveItem(player, inventory, val2, val);
				if (val2.IsEquipable() && !val2.m_equipped)
				{
					((Humanoid)player).EquipItem(val2, true);
				}
			}
		}

		internal static void AutoEquipDedicatedItems(Player player)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (_normalizing || (Object)(object)player == (Object)null)
			{
				return;
			}
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value)
			{
				return;
			}
			ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip;
			if (autoEquip == null || !autoEquip.Value)
			{
				return;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return;
			}
			for (int i = 0; i < EquipmentSlotCount; i++)
			{
				Vector2i val = SlotPosition(i, inventory.GetWidth());
				ItemData itemAt = inventory.GetItemAt(val.x, val.y);
				if (itemAt != null && Slots[i].Accepts(itemAt) && itemAt.IsEquipable() && !itemAt.m_equipped)
				{
					((Humanoid)player).EquipItem(itemAt, true);
				}
			}
		}

		internal static int FindEquipmentSlot(ItemData item)
		{
			for (int i = 0; i < EquipmentSlotCount; i++)
			{
				if (Slots[i].Accepts(item))
				{
					return i;
				}
			}
			return -1;
		}

		private static void Normalize(Player player, Inventory inventory)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: 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_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			if (_normalizing)
			{
				return;
			}
			_normalizing = true;
			try
			{
				foreach (ItemData item in new List<ItemData>(inventory.GetAllItems()))
				{
					if (!item.m_equipped)
					{
						continue;
					}
					int num = SlotIndex(item.m_gridPos, inventory.GetWidth());
					if (num < 0 || !Slots[num].Accepts(item))
					{
						int num2 = FindEquipmentSlot(item);
						if (num2 >= 0)
						{
							MoveItem(player, inventory, item, SlotPosition(num2, inventory.GetWidth()));
						}
					}
				}
				int slot;
				for (slot = 0; slot < EquipmentSlotCount; slot++)
				{
					Vector2i val = SlotPosition(slot, inventory.GetWidth());
					if (inventory.GetItemAt(val.x, val.y) == null)
					{
						ItemData val2 = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => item != null && SlotIndex(item.m_gridPos, inventory.GetWidth()) < 0 && Slots[slot].Accepts(item)));
						if (val2 != null)
						{
							MoveItem(player, inventory, val2, val);
						}
					}
				}
				foreach (ItemData item2 in new List<ItemData>(inventory.GetAllItems()))
				{
					if (item2.m_gridPos.y >= NormalRows && !CanPlace(item2, item2.m_gridPos, inventory.GetWidth()))
					{
						Vector2i val3 = FindGeneralEmpty(inventory, topFirst: true);
						if (val3.x >= 0)
						{
							MoveItem(player, inventory, item2, val3);
						}
					}
				}
				ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip;
				if (autoEquip == null || !autoEquip.Value)
				{
					return;
				}
				for (int num3 = 0; num3 < EquipmentSlotCount; num3++)
				{
					Vector2i val4 = SlotPosition(num3, inventory.GetWidth());
					ItemData itemAt = inventory.GetItemAt(val4.x, val4.y);
					if (itemAt != null && Slots[num3].Accepts(itemAt) && itemAt.IsEquipable() && !itemAt.m_equipped)
					{
						((Humanoid)player).EquipItem(itemAt, true);
					}
				}
			}
			finally
			{
				_normalizing = false;
			}
		}

		private static void MoveItem(Player player, Inventory inventory, ItemData item, Vector2i destination)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!(item.m_gridPos == destination))
			{
				ItemData itemAt = inventory.GetItemAt(destination.x, destination.y);
				Vector2i gridPos = item.m_gridPos;
				if (itemAt != null && itemAt != item)
				{
					Vector2i val = FindGeneralEmpty(inventory, topFirst: true);
					itemAt.m_gridPos = ((val.x >= 0) ? val : gridPos);
				}
				item.m_gridPos = destination;
				inventory.m_onChanged?.Invoke();
			}
		}

		private static void AddEquipment(string id, string label, Func<ItemData, bool> accepts)
		{
			HashSet<string> hashSet = new HashSet<string>(from value in (DadsEPIPlugin.RemovedEquipmentSlots.Value ?? string.Empty).Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
				select value.Trim(), StringComparer.OrdinalIgnoreCase);
			if (!hashSet.Contains(id) && !hashSet.Contains(label))
			{
				Slots.Add(new DedicatedSlot
				{
					Id = id,
					Label = label,
					Accepts = accepts
				});
			}
		}

		private static string QuickLabel(int index)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			string value = DadsEPIPlugin.QuickHotkeyLabels[index].Value;
			if (!string.IsNullOrWhiteSpace(value))
			{
				return value;
			}
			return ((object)DadsEPIPlugin.QuickHotkeys[index].Value/*cast due to .constrained prefix*/).ToString();
		}

		private static string PrefabName(ItemData item)
		{
			if (!((Object)(object)item?.m_dropPrefab != (Object)null))
			{
				return string.Empty;
			}
			return Utils.GetPrefabName(item.m_dropPrefab);
		}

		private static bool IsPrefab(ItemData item, string prefab)
		{
			return string.Equals(PrefabName(item), prefab, StringComparison.Ordinal);
		}

		private static bool IsWisplight(ItemData item)
		{
			if (!IsPrefab(item, "Demister"))
			{
				return IsPrefab(item, "Wisplight");
			}
			return true;
		}

		private static bool IsArrow(ItemData item)
		{
			return DefaultAmmoPrefabs.Contains(PrefabName(item));
		}
	}
	[HarmonyPatch(typeof(Player), "Load", new Type[] { typeof(ZPackage) })]
	internal static class PlayerLoadPatch
	{
		private static void Prefix(Player __instance)
		{
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled != null && modEnabled.Value)
			{
				Inventory inventory = ((Humanoid)__instance).GetInventory();
				if (inventory != null)
				{
					inventory.SetHeight(Math.Max(inventory.GetHeight(), InventoryLayout.TotalRows(inventory.GetWidth())));
				}
			}
		}

		private static void Postfix(Player __instance)
		{
			InventoryLayout.Apply(__instance, normalizeItems: true);
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned", new Type[] { typeof(bool) })]
	internal static class PlayerSpawnedPatch
	{
		private static void Postfix(Player __instance)
		{
			InventoryLayout.Apply(__instance, normalizeItems: true);
		}
	}
	[HarmonyPatch(typeof(Player), "EquipInventoryItems")]
	internal static class EquipInventoryItemsPatch
	{
		private static bool Prefix(Player __instance)
		{
			UtilityEquipment.BeginInventoryRestore();
			Inventory val = ((__instance != null) ? ((Humanoid)__instance).GetInventory() : null);
			if (val == null)
			{
				return false;
			}
			foreach (ItemData item in new List<ItemData>(val.GetAllItems()))
			{
				if (item == null || !item.m_equipped)
				{
					continue;
				}
				if (item.m_shared == null)
				{
					item.m_equipped = false;
					ManualLogSource modLogger = DadsEPIPlugin.ModLogger;
					if (modLogger != null)
					{
						modLogger.LogWarning((object)"Skipped an equipped inventory record with no shared item data while loading the character.");
					}
					continue;
				}
				try
				{
					if (!((Humanoid)__instance).EquipItem(item, false))
					{
						item.m_equipped = false;
					}
				}
				catch (Exception ex)
				{
					item.m_equipped = false;
					string text = ((!string.IsNullOrEmpty(item.m_shared.m_name)) ? item.m_shared.m_name : "unknown item");
					ManualLogSource modLogger2 = DadsEPIPlugin.ModLogger;
					if (modLogger2 != null)
					{
						modLogger2.LogError((object)("Could not restore equipped item '" + text + "'; it was left in the inventory unequipped. " + ex.GetType().Name + ": " + ex.Message));
					}
				}
			}
			return false;
		}

		private static Exception Finalizer(Exception __exception)
		{
			UtilityEquipment.EndInventoryRestore();
			return __exception;
		}
	}
	[HarmonyPatch(typeof(Player), "SetInventorySize")]
	internal static class NativeInventorySizePatch
	{
		private static bool Prefix(Player __instance, int rows)
		{
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value)
			{
				return true;
			}
			rows = Mathf.Clamp(rows, 4, 9);
			InventoryLayout.SetVanillaRows(rows);
			__instance.AddUniqueKeyValue("invrows", rows.ToString());
			Inventory inventory = ((Humanoid)__instance).GetInventory();
			inventory.SetHeight(InventoryLayout.TotalRows(inventory.GetWidth()));
			InventoryLayout.Apply(__instance, normalizeItems: true);
			((Humanoid)__instance).DropInvalidItems();
			return false;
		}
	}
	[HarmonyPatch(typeof(Inventory), "FindEmptySlot")]
	internal static class FindEmptySlotPatch
	{
		private static bool Prefix(Inventory __instance, bool __0, ref Vector2i __result)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value || !InventoryLayout.IsPlayerInventory(__instance))
			{
				return true;
			}
			__result = InventoryLayout.FindPreferredEmpty(__instance, __0);
			return false;
		}
	}
	[HarmonyPatch(typeof(Inventory), "GetEmptySlots")]
	internal static class GetEmptySlotsPatch
	{
		private static void Postfix(Inventory __instance, ref int __result)
		{
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled != null && modEnabled.Value && InventoryLayout.IsPlayerInventory(__instance))
			{
				__result = InventoryLayout.CountGeneralEmpty(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Inventory), "HaveEmptySlot")]
	internal static class HaveEmptySlotPatch
	{
		private static void Postfix(Inventory __instance, ref bool __result)
		{
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled != null && modEnabled.Value && InventoryLayout.IsPlayerInventory(__instance))
			{
				__result = InventoryLayout.CountGeneralEmpty(__instance) > 0;
			}
		}
	}
	[HarmonyPatch(typeof(Inventory), "CanAddItem", new Type[]
	{
		typeof(ItemData),
		typeof(int)
	})]
	internal static class CanAddItemPatch
	{
		private static void Postfix(Inventory __instance, ItemData item, int stack, ref bool __result)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value || !InventoryLayout.IsPlayerInventory(__instance) || item?.m_shared == null || !__result)
			{
				return;
			}
			int num = ((stack > 0) ? stack : item.m_stack);
			if (num <= item.m_shared.m_maxStackSize && InventoryLayout.FindGeneralEmpty(__instance, topFirst: true).x >= 0)
			{
				return;
			}
			ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip;
			int num2 = ((autoEquip != null && autoEquip.Value) ? InventoryLayout.FindEquipmentSlot(item) : (-1));
			bool flag = false;
			if (num2 >= 0)
			{
				Vector2i val = InventoryLayout.SlotPosition(num2, __instance.GetWidth());
				flag = __instance.GetItemAt(val.x, val.y) == null;
				if (flag && num <= item.m_shared.m_maxStackSize)
				{
					return;
				}
			}
			int num3 = 0;
			foreach (ItemData allItem in __instance.GetAllItems())
			{
				if (allItem.m_shared.m_name == item.m_shared.m_name && allItem.m_quality == item.m_quality && allItem.m_worldLevel == item.m_worldLevel)
				{
					num3 += Math.Max(0, allItem.m_shared.m_maxStackSize - allItem.m_stack);
				}
			}
			int num4 = InventoryLayout.CountGeneralEmpty(__instance);
			if (flag)
			{
				num4++;
			}
			__result = num3 + num4 * item.m_shared.m_maxStackSize >= num;
		}
	}
	[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
	internal static class AddItemAutoEquipmentPatch
	{
		private static void Prefix(Inventory __instance, ItemData item)
		{
			InventoryLayout.BeginAutoAdd(__instance, item);
		}

		private static void Postfix(Inventory __instance, ItemData item, bool __result)
		{
			InventoryLayout.EndAutoAdd();
			if (__result)
			{
				ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
				if (modEnabled != null && modEnabled.Value && !((Object)(object)Player.m_localPlayer == (Object)null))
				{
					InventoryLayout.AutoPlaceNewItem(Player.m_localPlayer, __instance, item);
				}
			}
		}

		private static Exception Finalizer(Exception __exception)
		{
			InventoryLayout.EndAutoAdd();
			return __exception;
		}
	}
	[HarmonyPatch(typeof(TombStone), "OnTakeAllSuccess")]
	internal static class TombStoneAutoEquipPatch
	{
		private static void Postfix()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
				if (modEnabled != null && modEnabled.Value)
				{
					InventoryLayout.Apply(localPlayer, normalizeItems: true);
					InventoryLayout.AutoEquipDedicatedItems(localPlayer);
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "DropItem", new Type[]
	{
		typeof(Inventory),
		typeof(ItemData),
		typeof(int),
		typeof(Vector2i)
	})]
	internal static class InventoryGridDropPatch
	{
		private sealed class DropState
		{
			internal Vector2i Source;

			internal bool SourceInPlayerInventory;

			internal bool SourceEquipment;

			internal bool TargetEquipment;
		}

		private static readonly HashSet<ItemData> SuppressedEquipItems = new HashSet<ItemData>();

		private static int _suppressionFrame = -1;

		private static bool Prefix(InventoryGrid __instance, Inventory __0, ItemData item, Vector2i pos, ref bool __result, out DropState __state)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			__state = null;
			Inventory inventory = __instance.GetInventory();
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value || !InventoryLayout.IsPlayerInventory(inventory))
			{
				return true;
			}
			if (!InventoryLayout.CanPlace(item, pos, inventory.GetWidth()))
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "This item does not match that dedicated slot.", 0, (Sprite)null, false);
				}
				__result = false;
				return false;
			}
			bool flag = item != null && __0 == inventory && inventory.GetItemAt(item.m_gridPos.x, item.m_gridPos.y) == item;
			int num = (flag ? InventoryLayout.SlotIndex(item.m_gridPos, inventory.GetWidth()) : (-1));
			int num2 = InventoryLayout.SlotIndex(pos, inventory.GetWidth());
			__state = new DropState
			{
				Source = (Vector2i)(((??)item?.m_gridPos) ?? new Vector2i(-1, -1)),
				SourceInPlayerInventory = flag,
				SourceEquipment = (num >= 0 && num < InventoryLayout.EquipmentSlotCount),
				TargetEquipment = (num2 >= 0 && num2 < InventoryLayout.EquipmentSlotCount)
			};
			if (item != null && num >= 0 && num < InventoryLayout.EquipmentSlotCount && (num2 < 0 || num2 >= InventoryLayout.EquipmentSlotCount) && flag)
			{
				ItemData itemAt = inventory.GetItemAt(pos.x, pos.y);
				if (itemAt != null && !InventoryLayout.CanPlace(itemAt, item.m_gridPos, inventory.GetWidth()))
				{
					__result = false;
					return false;
				}
			}
			if (item != null && item.m_equipped && num >= 0 && num2 < 0)
			{
				Player localPlayer2 = Player.m_localPlayer;
				if (localPlayer2 != null)
				{
					((Humanoid)localPlayer2).UnequipItem(item, true);
				}
			}
			if (item != null && num2 >= 0 && num2 < InventoryLayout.EquipmentSlotCount)
			{
				ItemData itemAt2 = inventory.GetItemAt(pos.x, pos.y);
				if (itemAt2 != null && itemAt2 != item && itemAt2.m_equipped)
				{
					Player localPlayer3 = Player.m_localPlayer;
					if (localPlayer3 != null)
					{
						((Humanoid)localPlayer3).UnequipItem(itemAt2, true);
					}
				}
			}
			return true;
		}

		private static void Postfix(InventoryGrid __instance, Vector2i pos, bool __result, DropState __state)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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)
			if (!__result || __state == null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			Inventory inventory = __instance.GetInventory();
			if (!InventoryLayout.IsPlayerInventory(inventory))
			{
				return;
			}
			if (__state.SourceEquipment && !__state.TargetEquipment)
			{
				Suppress(inventory.GetItemAt(pos.x, pos.y));
			}
			if (__state.SourceInPlayerInventory && !__state.SourceEquipment && __state.TargetEquipment)
			{
				Suppress(inventory.GetItemAt(__state.Source.x, __state.Source.y));
			}
			ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip;
			if (autoEquip == null || !autoEquip.Value)
			{
				return;
			}
			Vector2i val = (Vector2i)(__state.TargetEquipment ? pos : (__state.SourceEquipment ? __state.Source : new Vector2i(-1, -1)));
			if (val.x >= 0)
			{
				ItemData itemAt = inventory.GetItemAt(val.x, val.y);
				if (itemAt != null && !itemAt.m_equipped && itemAt.IsEquipable() && InventoryLayout.CanPlace(itemAt, val, inventory.GetWidth()))
				{
					((Humanoid)Player.m_localPlayer).EquipItem(itemAt, true);
				}
			}
		}

		private static void Suppress(ItemData item)
		{
			if (item != null)
			{
				if (_suppressionFrame != Time.frameCount)
				{
					SuppressedEquipItems.Clear();
					_suppressionFrame = Time.frameCount;
				}
				SuppressedEquipItems.Add(item);
			}
		}

		internal static bool IsSuppressed(ItemData item)
		{
			if (item != null && _suppressionFrame == Time.frameCount)
			{
				return SuppressedEquipItems.Contains(item);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "EquipItem", new Type[]
	{
		typeof(ItemData),
		typeof(bool)
	})]
	internal static class EquipItemPatch
	{
		private static bool Prefix(Humanoid __instance, ItemData item, ref bool __result, out ItemData __state)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && InventoryGridDropPatch.IsSuppressed(item))
			{
				__state = null;
				__result = false;
				return false;
			}
			__state = UtilityEquipment.BeginEquip(__instance, item);
			return true;
		}

		private static void Postfix(Humanoid __instance, ItemData item, bool __result, ItemData __state)
		{
			UtilityEquipment.EndEquip(__instance, __state, __result);
			if (!__result || UtilityEquipment.IsRestoringInventoryEquipment)
			{
				return;
			}
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled != null && modEnabled.Value)
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer)
				{
					InventoryLayout.MoveEquippedItemToDedicatedSlot(val, item);
				}
			}
		}

		private static Exception Finalizer(Exception __exception, Humanoid __instance, ItemData __state)
		{
			if (__exception != null)
			{
				UtilityEquipment.EndEquip(__instance, __state, equipped: false);
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "IsItemEquiped")]
	internal static class IsItemEquippedPatch
	{
		private static void Postfix(Humanoid __instance, ItemData item, ref bool __result)
		{
			if (!__result && UtilityEquipment.IsManagedUtility(__instance, item))
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "IsItemTypeEquiped")]
	internal static class IsItemTypeEquippedPatch
	{
		private static void Postfix(Humanoid __instance, ItemData item, ref bool __result)
		{
			if (!__result && UtilityEquipment.HasEquippedUtilityType(__instance, item))
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UpdateEquipmentStatusEffects")]
	internal static class EquipmentStatusEffectsPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			FieldInfo objB = AccessTools.Field(typeof(Humanoid), "m_equipmentStatusEffects");
			MethodInfo methodInfo = AccessTools.Method(typeof(UtilityEquipment), "AddStatusEffects", (Type[])null, (Type[])null);
			for (int i = 1; i < list.Count; i++)
			{
				if (!(list[i].opcode != OpCodes.Ldfld) && object.Equals(list[i].operand, objB) && !(list[i - 1].opcode != OpCodes.Ldarg_0))
				{
					int index = i - 1;
					CodeInstruction val = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					val.labels.AddRange(list[index].labels);
					val.blocks.AddRange(list[index].blocks);
					list[index].labels.Clear();
					list[index].blocks.Clear();
					list.InsertRange(index, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[3]
					{
						val,
						new CodeInstruction(OpCodes.Ldloc_0, (object)null),
						new CodeInstruction(OpCodes.Call, (object)methodInfo)
					});
					return list;
				}
			}
			ManualLogSource modLogger = DadsEPIPlugin.ModLogger;
			if (modLogger != null)
			{
				modLogger.LogError((object)"Could not patch utility status-effect collection.");
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UnequipAllItems")]
	internal static class UnequipAllItemsPatch
	{
		private static void Postfix(Humanoid __instance)
		{
			UtilityEquipment.UnequipAdditionalUtilities(__instance);
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
	internal static class CraftingAutoEquipPatch
	{
		private static void Postfix(Player __0)
		{
			InventoryLayout.AutoEquipDedicatedItems(__0);
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateInventory")]
	internal static class InventoryGridUpdatePatch
	{
		private static void Postfix(InventoryGrid __instance)
		{
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled != null && modEnabled.Value && InventoryLayout.IsPlayerInventory(__instance.GetInventory()))
			{
				SlotVisuals.Refresh(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Hud), "Update")]
	internal static class HudUpdatePatch
	{
		private static void Postfix(Hud __instance)
		{
			QuickSlotHud.Refresh(__instance);
		}
	}
	[HarmonyPatch(typeof(Hud), "OnDestroy")]
	internal static class HudDestroyPatch
	{
		private static void Prefix()
		{
			QuickSlotHud.Reset();
		}
	}
	internal static class QuickSlotHud
	{
		private const string RootName = "DadsEPI_QuickSlots";

		private const float HotbarGap = 10f;

		private static RectTransform _root;

		private static readonly List<GameObject> Elements = new List<GameObject>();

		private static readonly string[] HiddenChildren = new string[3] { "equiped", "queued", "selected" };

		private static readonly Vector3[] Corners = (Vector3[])(object)new Vector3[4];

		private static float _nextRefresh;

		private static RectTransform _messageTextRect;

		private static RectTransform _messageIconRect;

		private static Vector2 _messageTextPosition;

		private static Vector2 _messageIconPosition;

		internal static void Reset()
		{
			RestorePickupMessagePosition();
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_root).gameObject);
			}
			_root = null;
			Elements.Clear();
			_nextRefresh = 0f;
		}

		internal static void Refresh(Hud hud)
		{
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hud == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value)
			{
				return;
			}
			Ensure(hud);
			if ((Object)(object)_root == (Object)null)
			{
				return;
			}
			HotkeyBar componentInChildren = hud.m_rootObject.GetComponentInChildren<HotkeyBar>(true);
			if (Time.unscaledTime < _nextRefresh)
			{
				if (((Component)_root).gameObject.activeSelf)
				{
					AlignWithHotbar(componentInChildren);
				}
				return;
			}
			_nextRefresh = Time.unscaledTime + 0.1f;
			bool flag = DadsEPIPlugin.ShowQuickSlots.Value && InventoryLayout.EnabledQuickSlots > 0;
			((Component)_root).gameObject.SetActive(flag);
			if (!flag)
			{
				PositionPickupMessage(belowSlots: false);
				return;
			}
			int num = VisibleSlotCount();
			EnsureElementCount(componentInChildren, num);
			int num2 = Mathf.Clamp(DadsEPIPlugin.QuickSlotsPerRow.Value, 1, 8);
			float num3 = (((Object)(object)componentInChildren != (Object)null) ? ((Transform)_root).InverseTransformVector(((Component)componentInChildren).transform.TransformVector(new Vector3(componentInChildren.m_elementSpace, 0f, 0f))).x : 70f);
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			for (int i = 0; i < Elements.Count; i++)
			{
				GameObject val = Elements[i];
				bool flag2 = i < num;
				val.SetActive(flag2);
				if (flag2)
				{
					RectTransform component = val.GetComponent<RectTransform>();
					component.anchorMin = new Vector2(0f, 1f);
					component.anchorMax = new Vector2(0f, 1f);
					component.pivot = new Vector2(0f, 1f);
					component.anchoredPosition = new Vector2((float)(i % num2) * num3, (float)(-(i / num2)) * num3);
					Vector2i val2 = InventoryLayout.SlotPosition(InventoryLayout.EquipmentSlotCount + i, inventory.GetWidth());
					ItemData itemAt = inventory.GetItemAt(val2.x, val2.y);
					SetElement(val, itemAt, i);
				}
			}
			_root.sizeDelta = new Vector2((float)Mathf.Min(num, num2) * num3, (float)Mathf.CeilToInt((float)num / (float)num2) * num3);
			((Transform)_root).localScale = Vector3.one * Mathf.Clamp(DadsEPIPlugin.HudScale.Value, 0.25f, 3f);
			AlignWithHotbar(componentInChildren);
			PositionPickupMessage(num > 0);
		}

		private static int VisibleSlotCount()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			int enabledQuickSlots = InventoryLayout.EnabledQuickSlots;
			if (DadsEPIPlugin.AlwaysShowQuickSlots.Value)
			{
				return enabledQuickSlots;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			int result = 0;
			for (int i = 0; i < enabledQuickSlots; i++)
			{
				Vector2i val = InventoryLayout.SlotPosition(InventoryLayout.EquipmentSlotCount + i, inventory.GetWidth());
				if (inventory.GetItemAt(val.x, val.y) != null)
				{
					result = i + 1;
				}
			}
			return result;
		}

		private static void Ensure(Hud hud)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_root != (Object)null))
			{
				GameObject val = new GameObject("DadsEPI_QuickSlots", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(hud.m_rootObject.transform, false);
				_root = val.GetComponent<RectTransform>();
				_root.anchorMin = new Vector2(0f, 1f);
				_root.anchorMax = new Vector2(0f, 1f);
				_root.pivot = new Vector2(0f, 1f);
			}
		}

		private static void EnsureElementCount(HotkeyBar sourceBar, int count)
		{
			if (Elements.Count < count && !((Object)(object)sourceBar == (Object)null) && !((Object)(object)sourceBar.m_elementPrefab == (Object)null))
			{
				while (Elements.Count < count)
				{
					GameObject val = Object.Instantiate<GameObject>(sourceBar.m_elementPrefab, (Transform)(object)_root, false);
					((Object)val).name = $"DadsEPI_QuickSlot_{Elements.Count + 1}";
					Elements.Add(val);
				}
			}
		}

		private static void AlignWithHotbar(HotkeyBar sourceBar)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)sourceBar == (Object)null) && ((Component)sourceBar).transform.childCount != 0 && Elements.Count != 0)
			{
				Transform child = ((Component)sourceBar).transform.GetChild(0);
				RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null);
				Transform transform = Elements[0].transform;
				RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
				{
					val.GetWorldCorners(Corners);
					float x = Corners[0].x;
					float y = Corners[0].y;
					val2.GetWorldCorners(Corners);
					float num = Mathf.Abs(((Component)sourceBar).transform.TransformVector(new Vector3(0f, 10f, 0f)).y);
					RectTransform root = _root;
					((Transform)root).position = ((Transform)root).position + new Vector3(x - Corners[0].x, y - num - Corners[1].y, 0f);
				}
			}
		}

		private static void SetElement(GameObject element, ItemData item, int index)
		{
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			Transform val = element.transform.Find("icon");
			if ((Object)(object)val != (Object)null)
			{
				Image component = ((Component)val).GetComponent<Image>();
				((Component)component).gameObject.SetActive(item != null);
				if (item != null)
				{
					component.sprite = item.GetIcon();
				}
			}
			Transform val2 = element.transform.Find("amount");
			if ((Object)(object)val2 != (Object)null)
			{
				TMP_Text component2 = ((Component)val2).GetComponent<TMP_Text>();
				((Component)component2).gameObject.SetActive(item != null && item.m_shared.m_maxStackSize > 1);
				if (item != null)
				{
					component2.text = item.m_stack.ToString();
				}
			}
			Transform val3 = element.transform.Find("binding");
			if ((Object)(object)val3 != (Object)null)
			{
				TMP_Text component3 = ((Component)val3).GetComponent<TMP_Text>();
				if ((Object)(object)component3 != (Object)null)
				{
					component3.text = InventoryLayout.Slots[InventoryLayout.EquipmentSlotCount + index].Label;
					component3.enableAutoSizing = false;
					component3.textWrappingMode = (TextWrappingModes)0;
					component3.overflowMode = (TextOverflowModes)0;
					component3.fontSize = 11f;
					component3.alignment = (TextAlignmentOptions)514;
					RectTransform rectTransform = component3.rectTransform;
					rectTransform.anchorMin = new Vector2(0f, 1f);
					rectTransform.anchorMax = new Vector2(1f, 1f);
					rectTransform.pivot = new Vector2(0.5f, 1f);
					rectTransform.offsetMin = new Vector2(2f, -18f);
					rectTransform.offsetMax = new Vector2(-2f, -2f);
				}
			}
			string[] hiddenChildren = HiddenChildren;
			foreach (string text in hiddenChildren)
			{
				Transform val4 = element.transform.Find(text);
				if ((Object)(object)val4 != (Object)null)
				{
					((Component)val4).gameObject.SetActive(false);
				}
			}
			GuiBar[] componentsInChildren = element.GetComponentsInChildren<GuiBar>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Component)componentsInChildren[i]).gameObject.SetActive(false);
			}
		}

		private static void PositionPickupMessage(bool belowSlots)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			MessageHud instance = MessageHud.instance;
			RectTransform textRect = (((Object)(object)instance != (Object)null && (Object)(object)instance.m_messageText != (Object)null) ? instance.m_messageText.rectTransform : null);
			RectTransform iconRect = (((Object)(object)instance != (Object)null && (Object)(object)instance.m_messageIcon != (Object)null) ? ((Graphic)instance.m_messageIcon).rectTransform : null);
			CapturePickupMessagePosition(textRect, iconRect);
			RestorePickupMessagePosition();
			if (!belowSlots || (Object)(object)_root == (Object)null)
			{
				return;
			}
			float num = WorldEdge(_root, top: false);
			float num2 = Mathf.Max(WorldEdge(_messageTextRect, top: true), WorldEdge(_messageIconRect, top: true));
			float num3 = Mathf.Abs(((Transform)_root).TransformVector(new Vector3(0f, 10f, 0f)).y);
			float num4 = num - num3 - num2;
			if (!(num4 >= 0f))
			{
				MoveVertically(_messageTextRect, _messageTextPosition, num4);
				if ((Object)(object)_messageIconRect != (Object)null && ((Object)(object)_messageTextRect == (Object)null || !((Transform)_messageIconRect).IsChildOf((Transform)(object)_messageTextRect)))
				{
					MoveVertically(_messageIconRect, _messageIconPosition, num4);
				}
			}
		}

		private static void CapturePickupMessagePosition(RectTransform textRect, RectTransform iconRect)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_messageTextRect != (Object)(object)textRect)
			{
				_messageTextRect = textRect;
				if ((Object)(object)_messageTextRect != (Object)null)
				{
					_messageTextPosition = _messageTextRect.anchoredPosition;
				}
			}
			if ((Object)(object)_messageIconRect != (Object)(object)iconRect)
			{
				_messageIconRect = iconRect;
				if ((Object)(object)_messageIconRect != (Object)null)
				{
					_messageIconPosition = _messageIconRect.anchoredPosition;
				}
			}
		}

		private static void RestorePickupMessagePosition()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_messageTextRect != (Object)null)
			{
				_messageTextRect.anchoredPosition = _messageTextPosition;
			}
			if ((Object)(object)_messageIconRect != (Object)null)
			{
				_messageIconRect.anchoredPosition = _messageIconPosition;
			}
		}

		private static float WorldEdge(RectTransform rect, bool top)
		{
			if ((Object)(object)rect == (Object)null)
			{
				if (!top)
				{
					return float.PositiveInfinity;
				}
				return float.NegativeInfinity;
			}
			rect.GetWorldCorners(Corners);
			float num = Corners[0].y;
			for (int i = 1; i < Corners.Length; i++)
			{
				num = (top ? Mathf.Max(num, Corners[i].y) : Mathf.Min(num, Corners[i].y));
			}
			return num;
		}

		private static void MoveVertically(RectTransform rect, Vector2 originalPosition, float worldOffset)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rect == (Object)null) && !((Object)(object)((Transform)rect).parent == (Object)null))
			{
				float y = ((Transform)rect).parent.InverseTransformVector(new Vector3(0f, worldOffset, 0f)).y;
				rect.anchoredPosition = originalPosition + new Vector2(0f, y);
			}
		}
	}
	internal static class SlotVisuals
	{
		private const string PanelName = "DadsEPI_EquipmentPanel";

		private const string LabelName = "DadsEPI_SlotLabel";

		private const int EquipmentColumns = 3;

		private static readonly Dictionary<int, Transform> OriginalParents = new Dictionary<int, Transform>();

		private static readonly Dictionary<int, Vector2> OriginalPositions = new Dictionary<int, Vector2>();

		private static RectTransform _panel;

		internal static void Reset()
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			List<InventoryElement> list = new List<InventoryElement>();
			if ((Object)(object)InventoryGui.instance != (Object)null && (Object)(object)InventoryGui.instance.m_playerGrid != (Object)null)
			{
				list.AddRange(((Component)InventoryGui.instance.m_playerGrid).GetComponentsInChildren<InventoryElement>(true));
			}
			if ((Object)(object)_panel != (Object)null)
			{
				list.AddRange(((Component)_panel).GetComponentsInChildren<InventoryElement>(true));
			}
			foreach (InventoryElement item in list)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)item).GetInstanceID();
				Transform transform = ((Component)item).transform;
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val != (Object)null && OriginalParents.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null)
				{
					((Transform)val).SetParent(value, false);
					if (OriginalPositions.TryGetValue(instanceID, out var value2))
					{
						val.anchoredPosition = value2;
					}
				}
				((Component)item).gameObject.SetActive(true);
				Transform val2 = ((Component)item).transform.Find("DadsEPI_SlotLabel");
				if ((Object)(object)val2 != (Object)null)
				{
					((Component)val2).gameObject.SetActive(false);
				}
			}
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_panel).gameObject);
			}
			_panel = null;
			OriginalParents.Clear();
			OriginalPositions.Clear();
		}

		internal static void Refresh(InventoryGrid grid)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)grid == (Object)null || !InventoryLayout.IsPlayerInventory(grid.GetInventory()))
			{
				return;
			}
			EnsurePanel(grid);
			List<InventoryElement> list = new List<InventoryElement>(((Component)grid).GetComponentsInChildren<InventoryElement>(true));
			if ((Object)(object)_panel != (Object)null)
			{
				list.AddRange(((Component)_panel).GetComponentsInChildren<InventoryElement>(true));
			}
			foreach (InventoryElement item in list)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				Transform transform = ((Component)item).transform;
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)item).GetInstanceID();
				if (!OriginalParents.ContainsKey(instanceID))
				{
					OriginalParents[instanceID] = ((Transform)val).parent;
					OriginalPositions[instanceID] = val.anchoredPosition;
				}
				int num = InventoryLayout.SlotIndex(item.Position, grid.GetInventory().GetWidth());
				if (num < 0 && item.Position.y >= InventoryLayout.NormalRows)
				{
					((Component)val).gameObject.SetActive(false);
					continue;
				}
				((Component)val).gameObject.SetActive(true);
				TMP_Text orCreateLabel = GetOrCreateLabel(item);
				if (num < 0 || !DadsEPIPlugin.SeparateEquipmentPanel.Value)
				{
					if (OriginalParents.TryGetValue(instanceID, out var value) && (Object)(object)((Transform)val).parent != (Object)(object)value)
					{
						((Transform)val).SetParent(value, false);
						if (OriginalPositions.TryGetValue(instanceID, out var value2))
						{
							val.anchoredPosition = value2;
						}
					}
					((Component)orCreateLabel).gameObject.SetActive(num >= 0);
					if (num >= 0)
					{
						orCreateLabel.text = InventoryLayout.Slots[num].Label;
					}
				}
				else
				{
					((Transform)val).SetParent((Transform)(object)_panel, false);
					val.anchorMin = new Vector2(0f, 1f);
					val.anchorMax = new Vector2(0f, 1f);
					val.pivot = new Vector2(0f, 1f);
					val.anchoredPosition = PanelPosition(num, grid.m_elementSpace);
					orCreateLabel.text = InventoryLayout.Slots[num].Label;
					((Component)orCreateLabel).gameObject.SetActive(true);
					orCreateLabel.transform.SetAsLastSibling();
				}
			}
			if ((Object)(object)_panel != (Object)null)
			{
				UpdatePanelLayout(grid);
				((Component)_panel).gameObject.SetActive(DadsEPIPlugin.SeparateEquipmentPanel.Value && InventoryLayout.Slots.Count > 0);
			}
		}

		private static Vector2 PanelPosition(int slotIndex, float space)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (slotIndex < InventoryLayout.EquipmentSlotCount)
			{
				int num = slotIndex % 3;
				int num2 = slotIndex / 3;
				return new Vector2(10f + (float)num * space, -10f - (float)num2 * space);
			}
			int num3 = slotIndex - InventoryLayout.EquipmentSlotCount;
			int num4 = Mathf.Min(3, Mathf.Max(1, InventoryLayout.EnabledQuickSlots));
			int num5 = num3 / num4;
			int num6 = num3 % num4;
			int num7 = Mathf.CeilToInt((float)InventoryLayout.EquipmentSlotCount / 3f);
			return new Vector2(10f + (float)num6 * space, -10f - ((float)num7 + 0.35f) * space - (float)num5 * space);
		}

		private static void EnsurePanel(InventoryGrid grid)
		{
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panel != (Object)null)
			{
				return;
			}
			RectTransform val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_player : null);
			Transform val2 = (((Object)(object)val != (Object)null && (Object)(object)((Transform)val).parent != (Object)null) ? ((Transform)val).parent : ((Component)grid).transform.parent);
			Transform val3 = val2.Find("DadsEPI_EquipmentPanel");
			if ((Object)(object)val3 != (Object)null)
			{
				_panel = ((Component)val3).GetComponent<RectTransform>();
				if ((Object)(object)val != (Object)null && (Object)(object)_panel != (Object)null)
				{
					((Transform)_panel).SetSiblingIndex(((Transform)val).GetSiblingIndex() + 1);
				}
				return;
			}
			Transform val4 = (((Object)(object)InventoryGui.instance != (Object)null && (Object)(object)InventoryGui.instance.m_crafting != (Object)null) ? ((Transform)InventoryGui.instance.m_crafting).Find("Bkg") : null);
			if ((Object)(object)val4 == (Object)null && (Object)(object)val != (Object)null)
			{
				val4 = ((Transform)val).Find("Bkg");
			}
			GameObject val5;
			if ((Object)(object)val4 != (Object)null)
			{
				val5 = Object.Instantiate<GameObject>(((Component)val4).gameObject, val2, false);
				((Object)val5).name = "DadsEPI_EquipmentPanel";
				val5.SetActive(true);
			}
			else
			{
				val5 = new GameObject("DadsEPI_EquipmentPanel", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val5.transform.SetParent(val2, false);
			}
			_panel = val5.GetComponent<RectTransform>();
			_panel.anchorMin = (Vector2)(((Object)(object)val != (Object)null) ? val.anchorMin : new Vector2(0f, 1f));
			_panel.anchorMax = _panel.anchorMin;
			_panel.pivot = new Vector2(0f, 1f);
			Image component = val5.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = true;
				((Graphic)component).raycastTarget = false;
			}
			if ((Object)(object)val != (Object)null && (Object)(object)((Transform)_panel).parent == (Object)(object)((Transform)val).parent)
			{
				((Transform)_panel).SetSiblingIndex(((Transform)val).GetSiblingIndex() + 1);
			}
			UpdatePanelLayout(grid);
		}

		private static void UpdatePanelLayout(InventoryGrid grid)
		{
			//IL_003b: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_panel == (Object)null))
			{
				RectTransform val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_player : null);
				if ((Object)(object)val != (Object)null)
				{
					_panel.anchorMin = val.anchorMin;
					_panel.anchorMax = val.anchorMin;
					Vector3[] array = (Vector3[])(object)new Vector3[4];
					val.GetWorldCorners(array);
					float rightEdge = Mathf.Max(array[2].x, array[3].x);
					float num = Mathf.Max(array[1].y, array[2].y);
					IncludeRightEdge(((Object)(object)InventoryGui.instance.m_weight != (Object)null) ? InventoryGui.instance.m_weight.rectTransform : null, val, ref rightEdge);
					IncludeRightEdge(((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor.rectTransform : null, val, ref rightEdge);
					float num2 = Mathf.Abs(((Transform)val).TransformVector(new Vector3(12f, 0f, 0f)).x);
					((Transform)_panel).position = new Vector3(rightEdge + num2, num, ((Transform)val).position.z);
				}
				int num3 = Mathf.CeilToInt((float)InventoryLayout.EquipmentSlotCount / 3f);
				int num4 = Mathf.Min(3, Mathf.Max(1, InventoryLayout.EnabledQuickSlots));
				int num5 = Mathf.CeilToInt((float)InventoryLayout.EnabledQuickSlots / (float)num4);
				int num6 = Mathf.Max(3, num4);
				float num7 = (float)num3 + ((num5 > 0) ? (0.35f + (float)num5) : 0f);
				_panel.sizeDelta = new Vector2((float)num6 * grid.m_elementSpace + 20f, num7 * grid.m_elementSpace + 20f);
			}
		}

		private static void IncludeRightEdge(RectTransform rect, RectTransform playerPanel, ref float rightEdge)
		{
			if (!((Object)(object)rect == (Object)null))
			{
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				rect.GetWorldCorners(array);
				rightEdge = Mathf.Max(rightEdge, Mathf.Max(array[2].x, array[3].x));
				Transform parent = ((Transform)rect).parent;
				RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)playerPanel) && !((Object)(object)val == (Object)(object)((Transform)_panel).parent))
				{
					val.GetWorldCorners(array);
					rightEdge = Mathf.Max(rightEdge, Mathf.Max(array[2].x, array[3].x));
				}
			}
		}

		private static TMP_Text GetOrCreateLabel(InventoryElement element)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_005f: 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)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)element).transform.Find("DadsEPI_SlotLabel");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).GetComponent<TMP_Text>();
			}
			GameObject val2 = new GameObject("DadsEPI_SlotLabel", new Type[1] { typeof(RectTransform) });
			val2.SetActive(false);
			val2.transform.SetParent(((Component)element).transform, false);
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = new Vector2(2f, 2f);
			component.offsetMax = new Vector2(-2f, -2f);
			TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>();
			TMP_Text val4 = (((Object)(object)element.m_amount != (Object)null && (Object)(object)element.m_amount.font != (Object)null) ? element.m_amount : null);
			if ((Object)(object)val4 == (Object)null && (Object)(object)InventoryGui.instance != (Object)null)
			{
				TMP_Text[] componentsInChildren = ((Component)InventoryGui.instance).GetComponentsInChildren<TMP_Text>(true);
				foreach (TMP_Text val5 in componentsInChildren)
				{
					if (!((Object)(object)val5.font == (Object)null))
					{
						val4 = val5;
						break;
					}
				}
			}
			if ((Object)(object)val4 != (Object)null)
			{
				((TMP_Text)val3).font = val4.font;
				((TMP_Text)val3).fontSharedMaterial = val4.fontSharedMaterial;
			}
			((Behaviour)val3).enabled = true;
			((TMP_Text)val3).alignment = (TextAlignmentOptions)258;
			((TMP_Text)val3).fontSize = 11f;
			((TMP_Text)val3).fontStyle = (FontStyles)1;
			((Graphic)val3).color = new Color(0.95f, 0.84f, 0.6f, 1f);
			((Graphic)val3).raycastTarget = false;
			val2.SetActive(true);
			return (TMP_Text)(object)val3;
		}
	}
	internal static class UtilityEquipment
	{
		private static readonly FieldRef<Humanoid, ItemData> UtilityItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_utilityItem");

		private static bool _restoringInventoryEquipment;

		internal static bool IsRestoringInventoryEquipment => _restoringInventoryEquipment;

		internal static void BeginInventoryRestore()
		{
			_restoringInventoryEquipment = true;
		}

		internal static void EndInventoryRestore()
		{
			_restoringInventoryEquipment = false;
		}

		internal static ItemData BeginEquip(Humanoid humanoid, ItemData item)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			if (!IsLocalUtilityItem(humanoid, item) || (item.m_equipped && !_restoringInventoryEquipment))
			{
				return null;
			}
			ItemData val = UtilityItem.Invoke(humanoid);
			if (val == null || val == item || !val.m_equipped)
			{
				return null;
			}
			Player val2 = (Player)humanoid;
			if (!InventoryLayout.IsInEquipmentSlot(((Humanoid)val2).GetInventory(), val))
			{
				return null;
			}
			if (!InventoryLayout.UsesSeparateEquipmentSlot(((Humanoid)val2).GetInventory(), item, val))
			{
				return null;
			}
			UtilityItem.Invoke(humanoid) = null;
			return val;
		}

		internal static void EndEquip(Humanoid humanoid, ItemData previous, bool equipped)
		{
			if (previous != null)
			{
				previous.m_equipped = true;
				if (!equipped && UtilityItem.Invoke(humanoid) == null)
				{
					UtilityItem.Invoke(humanoid) = previous;
				}
			}
		}

		internal static bool IsManagedUtility(Humanoid humanoid, ItemData item)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (_restoringInventoryEquipment || !IsLocalUtilityItem(humanoid, item) || !item.m_equipped)
			{
				return false;
			}
			return InventoryLayout.IsInEquipmentSlot(((Humanoid)(Player)humanoid).GetInventory(), item);
		}

		internal static bool HasEquippedUtilityType(Humanoid humanoid, ItemData item)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			if (!IsLocalUtilityItem(humanoid, item))
			{
				return false;
			}
			foreach (ItemData managedUtility in GetManagedUtilities((Player)humanoid))
			{
				if (managedUtility.m_shared.m_name == item.m_shared.m_name)
				{
					return true;
				}
			}
			return false;
		}

		internal static void AddStatusEffects(Humanoid humanoid, HashSet<StatusEffect> effects)
		{
			Player val = (Player)(object)((humanoid is Player) ? humanoid : null);
			if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value)
			{
				return;
			}
			foreach (ItemData managedUtility in GetManagedUtilities(val))
			{
				StatusEffect equipStatusEffect = managedUtility.m_shared.m_equipStatusEffect;
				if ((Object)(object)equipStatusEffect != (Object)null)
				{
					effects.Add(equipStatusEffect);
				}
			}
		}

		internal static void UnequipAdditionalUtilities(Humanoid humanoid)
		{
			Player val = (Player)(object)((humanoid is Player) ? humanoid : null);
			if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value)
			{
				return;
			}
			foreach (ItemData item in new List<ItemData>(GetManagedUtilities(val)))
			{
				if (item.m_equipped)
				{
					humanoid.UnequipItem(item, false);
				}
			}
		}

		private static IEnumerable<ItemData> GetManagedUtilities(Player player)
		{
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				yield break;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem?.m_shared != null && allItem.m_equipped && (int)allItem.m_shared.m_itemType == 18 && InventoryLayout.IsInEquipmentSlot(inventory, allItem))
				{
					yield return allItem;
				}
			}
		}

		private static bool IsLocalUtilityItem(Humanoid humanoid, ItemData item)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled;
			if (modEnabled == null || !modEnabled.Value || item?.m_shared == null || (int)item.m_shared.m_itemType != 18)
			{
				return false;
			}
			Player val = (Player)(object)((humanoid is Player) ? humanoid : null);
			if (val != null)
			{
				return (Object)(object)val == (Object)(object)Player.m_localPlayer;
			}
			return false;
		}
	}
}