Decompiled source of DadsEPI v1.0.1

DadsEPI.dll

Decompiled 42 minutes ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using 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.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+6ce04159a5c42760f58692b85f16965be21fc08f")]
[assembly: AssemblyProduct("DadsEPI")]
[assembly: AssemblyTitle("DadsEPI")]
[assembly: AssemblyVersion("1.0.1.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.0.1")]
	[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.0.1";

		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> 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 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_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e3: 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-ammunition slot.");
			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), "Quick-slot HUD anchored position.");
			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 }), "Drag the quick-slot HUD.");
			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);
			Watch<int>(ExtraRows);
			Watch<bool>(EquipmentRowEnabled);
			Watch<bool>(SeparateEquipmentPanel);
			Watch<bool>(AutoEquip);
			Watch<int>(QuickSlotCount);
			Watch<bool>(ShowQuickSlots);
			Watch<bool>(AlwaysShowQuickSlots);
			Watch<int>(QuickSlotsPerRow);
			Watch<bool>(WisplightSlot);
			Watch<bool>(WishboneSlot);
			Watch<bool>(CryptKeySlot);
			Watch<bool>(ArrowsSlot);
			Watch<bool>(ShieldSlot);
			Watch<bool>(UtilitySlot);
			Watch<string>(RemovedEquipmentSlots);
			for (int k = 0; k < CustomSlotNames.Length; k++)
			{
				Watch<string>(CustomSlotNames[k]);
				Watch<string>(CustomSlotItems[k]);
			}
			Watch<string>(HeadLabel);
			Watch<string>(ChestLabel);
			Watch<string>(LegsLabel);
			Watch<string>(BackLabel);
			Watch<string>(UtilityLabel);
			for (int l = 0; l < 8; l++)
			{
				Watch<KeyboardShortcut>(QuickHotkeys[l]);
				Watch<string>(QuickHotkeyLabels[l]);
			}
			InventoryLayout.RebuildSlots();
			_harmony = new Harmony("com.dadisbored.dadsepi");
			_harmony.PatchAll(typeof(DadsEPIPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DadsEPI 1.0.1 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)
		{
			entry.SettingChanged += OnLayoutSettingChanged;
		}

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

		private void Update()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			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: true);
			}
			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;

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

		internal static int NormalRows => Mathf.Clamp(VanillaRows, 4, 9) + Mathf.Clamp(DadsEPIPlugin.ExtraRows.Value, 0, 5);

		internal static int EquipmentSlotCount => Slots.Count((DedicatedSlot slot) => !slot.Quick);

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

		internal static int StorageRows(int width)
		{
			if (!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();
			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.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)));
				}
			}
			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 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 = ((inventory.GetAllItems().Count != 0) ? inventory.GetAllItems().Max((ItemData item) => item.m_gridPos.y + 1) : 0);
			int num3 = Mathf.Max(num, num2);
			if (inventory.GetHeight() != num3)
			{
				inventory.SetHeight(num3);
			}
			if ((Object)(object)InventoryGui.instance != (Object)null)
			{
				InventoryGui.instance.SetInventorySize(DadsEPIPlugin.SeparateEquipmentPanel.Value ? NormalRows : num3);
			}
			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 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_00c5: 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());
			if (inventory.GetItemAt(val.x, val.y) == null)
			{
				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);
					((Humanoid)player).EquipItem(val2, 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_0046: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if (_normalizing)
			{
				return;
			}
			_normalizing = true;
			try
			{
				foreach (ItemData item in new List<ItemData>(inventory.GetAllItems()))
				{
					if (item.m_equipped)
					{
						int num = FindEquipmentSlot(item);
						if (num >= 0)
						{
							MoveItem(player, inventory, item, SlotPosition(num, inventory.GetWidth()));
						}
					}
				}
				foreach (ItemData item2 in new List<ItemData>(inventory.GetAllItems()))
				{
					if (item2.m_gridPos.y >= NormalRows && !CanPlace(item2, item2.m_gridPos, inventory.GetWidth()))
					{
						Vector2i val = FindGeneralEmpty(inventory, topFirst: true);
						if (val.x >= 0)
						{
							MoveItem(player, inventory, item2, val);
						}
					}
				}
			}
			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)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			if (item?.m_shared == null)
			{
				return false;
			}
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType == 9 || (int)itemType == 23)
			{
				return PrefabName(item).StartsWith("Arrow", StringComparison.Ordinal);
			}
			return false;
		}
	}
	[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), "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), "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(InventoryGrid), "DropItem", new Type[]
	{
		typeof(Inventory),
		typeof(ItemData),
		typeof(int),
		typeof(Vector2i)
	})]
	internal static class InventoryGridDropPatch
	{
		private static bool Prefix(InventoryGrid __instance, ItemData item, Vector2i pos, ref bool __result)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			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;
			}
			int num = InventoryLayout.SlotIndex((Vector2i)(((??)item?.m_gridPos) ?? new Vector2i(-1, -1)), inventory.GetWidth());
			int num2 = InventoryLayout.SlotIndex(pos, inventory.GetWidth());
			if (item != null && item.m_equipped && num >= 0 && num2 < 0)
			{
				Player localPlayer2 = Player.m_localPlayer;
				if (localPlayer2 != null)
				{
					((Humanoid)localPlayer2).UnequipItem(item, true);
				}
			}
			return true;
		}

		private static void Postfix(InventoryGrid __instance, ItemData item, Vector2i pos, bool __result)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!__result || item == null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			Inventory inventory = __instance.GetInventory();
			if (InventoryLayout.IsPlayerInventory(inventory))
			{
				int num = InventoryLayout.SlotIndex(pos, inventory.GetWidth());
				if (num >= 0 && num < InventoryLayout.EquipmentSlotCount && DadsEPIPlugin.AutoEquip.Value)
				{
					((Humanoid)Player.m_localPlayer).EquipItem(item, true);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "EquipItem", new Type[]
	{
		typeof(ItemData),
		typeof(bool)
	})]
	internal static class EquipItemPatch
	{
		private static void Postfix(Humanoid __instance, ItemData item, bool __result)
		{
			if (!__result)
			{
				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);
				}
			}
		}
	}
	[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 static RectTransform _root;

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

		private static Vector3 _lastMouse;

		private static bool _dragging;

		internal static void Reset()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_root).gameObject);
			}
			_root = null;
			Elements.Clear();
			_dragging = false;
		}

		internal static void Refresh(Hud hud)
		{
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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;
			}
			bool flag = DadsEPIPlugin.ShowQuickSlots.Value && InventoryLayout.EnabledQuickSlots > 0;
			((Component)_root).gameObject.SetActive(flag);
			if (!flag)
			{
				return;
			}
			int num = VisibleSlotCount();
			EnsureElementCount(hud, num);
			int num2 = Mathf.Clamp(DadsEPIPlugin.QuickSlotsPerRow.Value, 1, 8);
			float num3 = 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)
				{
					val.GetComponent<RectTransform>().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);
			_root.anchoredPosition = DadsEPIPlugin.HudPosition.Value;
			UpdateDrag();
		}

		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(Hud hud, int count)
		{
			HotkeyBar componentInChildren = hud.m_rootObject.GetComponentInChildren<HotkeyBar>(true);
			if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)componentInChildren.m_elementPrefab == (Object)null))
			{
				while (Elements.Count < count)
				{
					GameObject val = Object.Instantiate<GameObject>(componentInChildren.m_elementPrefab, (Transform)(object)_root, false);
					((Object)val).name = $"DadsEPI_QuickSlot_{Elements.Count + 1}";
					Elements.Add(val);
				}
			}
		}

		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[] array = new string[3] { "equiped", "queued", "selected" };
			foreach (string text in array)
			{
				Transform val4 = element.transform.Find(text);
				if ((Object)(object)val4 != (Object)null)
				{
					((Component)val4).gameObject.SetActive(false);
				}
			}
		}

		private static void UpdateDrag()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Vector3 mousePosition = Input.mousePosition;
			KeyboardShortcut value = DadsEPIPlugin.HudDragKeys.Value;
			if (((KeyboardShortcut)(ref value)).IsPressed())
			{
				if (!_dragging)
				{
					_dragging = RectTransformUtility.RectangleContainsScreenPoint(_root, Vector2.op_Implicit(mousePosition));
				}
				if (_dragging && _lastMouse != Vector3.zero)
				{
					Vector3 val = mousePosition - _lastMouse;
					ConfigEntry<Vector2> hudPosition = DadsEPIPlugin.HudPosition;
					hudPosition.Value += new Vector2(val.x, val.y);
				}
			}
			else
			{
				_dragging = false;
			}
			_lastMouse = mousePosition;
		}
	}
	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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: 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>();
				return;
			}
			GameObject val4 = new GameObject("DadsEPI_EquipmentPanel", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val4.transform.SetParent(val2, false);
			_panel = val4.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 = val4.GetComponent<Image>();
			Image val5 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Image>() : ((Component)val2).GetComponent<Image>());
			if ((Object)(object)val5 != (Object)null)
			{
				component.sprite = val5.sprite;
				component.type = val5.type;
				((Graphic)component).material = ((Graphic)val5).material;
			}
			((Graphic)component).color = new Color(0.12f, 0.09f, 0.07f, 0.94f);
			((Graphic)component).raycastTarget = false;
			((Transform)_panel).SetAsLastSibling();
			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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//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_012b: 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;
					RectTransform panel = _panel;
					Vector2 anchoredPosition = val.anchoredPosition;
					Rect rect = val.rect;
					float num = ((Rect)(ref rect)).width * (1f - val.pivot.x) + 12f;
					rect = val.rect;
					panel.anchoredPosition = anchoredPosition + new Vector2(num, ((Rect)(ref rect)).height * (1f - val.pivot.y));
				}
				int num2 = Mathf.CeilToInt((float)InventoryLayout.EquipmentSlotCount / 3f);
				int num3 = Mathf.Min(3, Mathf.Max(1, InventoryLayout.EnabledQuickSlots));
				int num4 = Mathf.CeilToInt((float)InventoryLayout.EnabledQuickSlots / (float)num3);
				int num5 = Mathf.Max(3, num3);
				float num6 = (float)num2 + ((num4 > 0) ? (0.35f + (float)num4) : 0f);
				_panel.sizeDelta = new Vector2((float)num5 * grid.m_elementSpace + 20f, num6 * grid.m_elementSpace + 20f);
			}
		}

		private static TMP_Text GetOrCreateLabel(InventoryElement element)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			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[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			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 component2 = val2.GetComponent<TextMeshProUGUI>();
			if ((Object)(object)element.m_amount != (Object)null)
			{
				((TMP_Text)component2).font = element.m_amount.font;
				((TMP_Text)component2).fontSharedMaterial = element.m_amount.fontSharedMaterial;
			}
			((Behaviour)component2).enabled = true;
			((TMP_Text)component2).alignment = (TextAlignmentOptions)258;
			((TMP_Text)component2).fontSize = 11f;
			((TMP_Text)component2).fontStyle = (FontStyles)1;
			((Graphic)component2).color = new Color(0.95f, 0.84f, 0.6f, 1f);
			((Graphic)component2).raycastTarget = false;
			return (TMP_Text)(object)component2;
		}
	}
}