Decompiled source of CDEV EquipmentSlots v0.1.4

plugins\CDEV.EquipmentSlots\CDEV.EquipmentSlots.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("CDEV.EquipmentSlots")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.4.0")]
[assembly: AssemblyInformationalVersion("0.1.4+dc973356a9e1d4377ae0cec010ca435f57d87290")]
[assembly: AssemblyProduct("CDEV.EquipmentSlots")]
[assembly: AssemblyTitle("CDEV.EquipmentSlots")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.4.0")]
[module: UnverifiableCode]
[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 CDEV.EquipmentSlots
{
	internal static class BetterArcheryHost
	{
		internal const string Guid = "ishid4.mods.betterarchery";

		private static FieldInfo s_rowIndex;

		private static Func<bool> s_isQuiverEquipped;

		private static Func<ItemData, string> s_customSlotName;

		private static ConfigEntry<bool> s_enabled;

		private static readonly Dictionary<SharedData, bool> Quivers = new Dictionary<SharedData, bool>();

		internal static bool Hosted { get; private set; }

		internal static bool QuiverActive
		{
			get
			{
				if (Hosted && s_enabled != null)
				{
					return s_enabled.Value;
				}
				return false;
			}
		}

		internal static void Setup()
		{
			if (!Chainloader.PluginInfos.TryGetValue("ishid4.mods.betterarchery", out var value) || (Object)(object)value.Instance == (Object)null)
			{
				return;
			}
			try
			{
				Type type = ((object)value.Instance).GetType();
				FieldInfo field = type.GetField("eaqsPresent", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				s_rowIndex = type.GetField("QuiverRowIndex", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				MethodInfo method = type.GetMethod("IsQuiverEquipped", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				s_enabled = type.GetField("ConfigQuiverEnabled", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) as ConfigEntry<bool>;
				if (field == null || field.FieldType != typeof(int) || s_rowIndex == null || s_rowIndex.FieldType != typeof(int) || method == null || s_enabled == null)
				{
					Plugin.Log.LogWarning((object)($"Better Archery {value.Metadata.Version}: its quiver members were not found; the quiver is not hosted " + "(written for 2.0.0). Keep Better Archery's 'Enable Quiver' off, or arrows in the quiver may be lost."));
					return;
				}
				MethodInfo methodInfo = type.Assembly.GetType("Common.CustomSlotCreator")?.GetMethod("GetCustomSlotName", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(ItemData) }, null);
				s_customSlotName = ((methodInfo != null && methodInfo.ReturnType == typeof(string)) ? ((Func<ItemData, string>)Delegate.CreateDelegate(typeof(Func<ItemData, string>), methodInfo)) : null);
				if (s_customSlotName == null)
				{
					Plugin.Log.LogWarning((object)"Better Archery: Common.CustomSlotCreator.GetCustomSlotName was not found; the ammo slot cannot tell its quiver from arrows.");
				}
				field.SetValue(null, 1);
				s_rowIndex.SetValue(null, 23);
				s_isQuiverEquipped = (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), method);
				Hosted = true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Better Archery quiver hosting failed: " + ex.Message));
			}
		}

		internal static void KeepRow()
		{
			if (Hosted && (int)s_rowIndex.GetValue(null) != 23)
			{
				s_rowIndex.SetValue(null, 23);
			}
		}

		internal static bool IsQuiver(ItemData item)
		{
			if (!Hosted || s_customSlotName == null || item?.m_shared == null || (Object)(object)item.m_dropPrefab == (Object)null)
			{
				return false;
			}
			if (Quivers.TryGetValue(item.m_shared, out var value))
			{
				return value;
			}
			bool flag;
			try
			{
				flag = s_customSlotName(item) == "quiver";
			}
			catch
			{
				flag = false;
			}
			Quivers[item.m_shared] = flag;
			return flag;
		}

		internal static bool IsQuiverEquipped()
		{
			if (!QuiverActive)
			{
				return false;
			}
			try
			{
				return s_isQuiverEquipped();
			}
			catch
			{
				return false;
			}
		}
	}
	internal static class QuickStackStoreHost
	{
		internal const string Guid = "goldenrevolver.quick_stack_store";

		internal static bool Hooked { get; private set; }

		internal static void Setup(Harmony harmony)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			if (harmony == null || !Chainloader.PluginInfos.TryGetValue("goldenrevolver.quick_stack_store", out var value) || (Object)(object)value.Instance == (Object)null)
			{
				return;
			}
			try
			{
				Type type = ((object)value.Instance).GetType().Assembly.GetType("QuickStackStore.CompatibilitySupport");
				HarmonyMethod val = new HarmonyMethod(typeof(QuickStackStoreHost), "LeaveLockedCellsAlone", (Type[])null);
				Type[] types = new Type[3]
				{
					typeof(int),
					typeof(int),
					typeof(Vector2i)
				};
				int num = 0;
				string[] array = new string[2] { "IsEquipOrQuickSlot", "IsEquipSlot" };
				foreach (string name in array)
				{
					MethodInfo methodInfo = type?.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, types, null);
					if (methodInfo != null)
					{
						harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						num++;
					}
				}
				if (num == 0)
				{
					Plugin.Log.LogWarning((object)($"QuickStackStore {value.Metadata.Version}: its IsEquipOrQuickSlot check was not " + "found, so locked cells are only kept out of vanilla's own stack-all (written for 1.4.13)."));
				}
				else
				{
					Hooked = true;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not teach QuickStackStore about locked cells: " + ex.Message));
			}
		}

		private static void LeaveLockedCellsAlone(Vector2i itemPos, ref bool __result)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (!__result && Plugin.Active && Locks.IsLocked(itemPos))
			{
				__result = true;
			}
		}
	}
	internal static class EquipSync
	{
		[StructLayout(LayoutKind.Sequential, Size = 1)]
		internal readonly struct BusyScope : IDisposable
		{
			internal static BusyScope Enter()
			{
				s_busy++;
				return default(BusyScope);
			}

			public void Dispose()
			{
				s_busy--;
			}
		}

		internal struct DragState
		{
			internal bool Dropping;

			internal Inventory TargetInventory;

			internal Vector2i TargetPos;

			internal Inventory SourceInventory;

			internal Vector2i SourcePos;
		}

		private static int s_busy;

		internal static int EquipDepth;

		private static bool s_dirty = true;

		private static float s_nextPass;

		private static readonly List<ItemData> Items = new List<ItemData>();

		private static readonly Dictionary<ItemData, Vector2i> Refused = new Dictionary<ItemData, Vector2i>();

		private static Player s_refusedFor;

		internal static bool Busy => s_busy > 0;

		internal static void Enter()
		{
			s_busy++;
		}

		internal static void Exit()
		{
			s_busy = Math.Max(0, s_busy - 1);
		}

		internal static void MarkDirty()
		{
			s_dirty = true;
		}

		internal static bool IsLocal(Humanoid humanoid)
		{
			if ((Object)(object)humanoid != (Object)null)
			{
				return (Object)(object)humanoid == (Object)(object)Player.m_localPlayer;
			}
			return false;
		}

		private static bool CanManage(Player player)
		{
			if ((Object)(object)player != (Object)null && !player.m_isLoading && !((Character)player).IsDead())
			{
				return ((Humanoid)player).m_inventory != null;
			}
			return false;
		}

		internal static void OnEquipped(Player player, ItemData item)
		{
			if (Busy || !CanManage(player) || item == null)
			{
				return;
			}
			SlotKind slotKind = SlotLayout.HomeKind(item);
			if (slotKind == SlotKind.None || SlotInventory.InOwnCell(item) || !((Humanoid)player).m_inventory.ContainsItem(item))
			{
				return;
			}
			using (BusyScope.Enter())
			{
				if (PlaceIntoSlot(((Humanoid)player).m_inventory, item, slotKind))
				{
					((Humanoid)player).m_inventory.Changed(false, false);
				}
			}
		}

		internal static void OnUnequipped(Player player, ItemData item)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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)
			if (Busy || EquipDepth > 0 || !CanManage(player) || item == null || ((Humanoid)player).IsItemEquiped(item) || !SlotInventory.InOwnCell(item) || !((Humanoid)player).m_inventory.ContainsItem(item))
			{
				return;
			}
			SlotCell slotCell = SlotLayout.At(item.m_gridPos);
			if (slotCell != null && slotCell.Kind == SlotKind.Quiver)
			{
				return;
			}
			using (BusyScope.Enter())
			{
				Vector2i val = SlotInventory.FreeGridCellPreferBag(((Humanoid)player).m_inventory);
				if (val.x >= 0)
				{
					item.m_gridPos = val;
					((Humanoid)player).m_inventory.Changed(false, false);
				}
			}
		}

		internal static bool PlaceIntoSlot(Inventory inventory, ItemData item, SlotKind kind)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_009a: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (kind == SlotKind.Ammo && BetterArcheryHost.IsQuiverEquipped() && !BetterArcheryHost.IsQuiver(item))
			{
				foreach (SlotCell item2 in SlotLayout.Quiver)
				{
					if (SlotInventory.ItemIn(inventory, item2) == null)
					{
						item.m_gridPos = item2.Pos;
						return true;
					}
				}
				return false;
			}
			SlotCell slotCell = SlotInventory.TargetCell(inventory, kind, item);
			if (slotCell == null)
			{
				return false;
			}
			ItemData val = SlotInventory.ItemIn(inventory, slotCell);
			if (val == item)
			{
				return false;
			}
			if (val != null && BetterArcheryHost.IsQuiver(val))
			{
				return false;
			}
			Vector2i gridPos = item.m_gridPos;
			if (val != null)
			{
				SlotCell slotCell2 = SlotLayout.At(gridPos);
				if ((slotCell2 == null) ? SlotInventory.InGrid(inventory, gridPos) : SlotLayout.Accepts(slotCell2, val))
				{
					val.m_gridPos = gridPos;
				}
				else
				{
					item.m_gridPos = new Vector2i(-1000, -1000);
					if (!SlotInventory.MoveToGridOrStash(inventory, val))
					{
						item.m_gridPos = gridPos;
						return false;
					}
				}
				if (val.m_equipped && (Object)(object)Player.m_localPlayer != (Object)null && ((Humanoid)Player.m_localPlayer).m_inventory == inventory)
				{
					((Humanoid)Player.m_localPlayer).UnequipItem(val, false);
				}
			}
			item.m_gridPos = slotCell.Pos;
			return true;
		}

		internal static void AfterDrop(DragState state)
		{
			//IL_0030: 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_005b: 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)
			Player localPlayer = Player.m_localPlayer;
			if (!state.Dropping || !CanManage(localPlayer))
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).m_inventory;
			using (BusyScope.Enter())
			{
				if (state.TargetInventory == inventory)
				{
					ApplyLocation(localPlayer, inventory.GetItemAt(state.TargetPos.x, state.TargetPos.y));
				}
				if (state.SourceInventory == inventory)
				{
					ApplyLocation(localPlayer, inventory.GetItemAt(state.SourcePos.x, state.SourcePos.y));
				}
			}
			MarkDirty();
		}

		private static void ApplyLocation(Player player, ItemData item)
		{
			if (item == null || !((Humanoid)player).m_inventory.ContainsItem(item) || SlotLayout.HomeKind(item) == SlotKind.None)
			{
				return;
			}
			bool flag = SlotInventory.InOwnCell(item);
			bool flag2 = ((Humanoid)player).IsItemEquiped(item);
			if (flag && !flag2)
			{
				if (item.m_shared.m_equipDuration > 0f && SlotInventory.InGridOrSlot(item))
				{
					if (!player.IsEquipActionQueued(item))
					{
						player.QueueEquipAction(item);
					}
				}
				else
				{
					((Humanoid)player).EquipItem(item, false);
				}
			}
			else if (!flag && flag2)
			{
				((Humanoid)player).UnequipItem(item, false);
			}
		}

		internal static void OnSlotRightClick(Player player, SlotCell cell, ItemData item)
		{
			//IL_0035: 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_003b: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			if (item == null || !CanManage(player))
			{
				return;
			}
			if (cell.Kind == SlotKind.Quick || cell.Kind == SlotKind.Quiver)
			{
				((Humanoid)player).UseItem(((Humanoid)player).m_inventory, item, true);
				return;
			}
			Vector2i val = SlotInventory.FreeGridCellPreferBag(((Humanoid)player).m_inventory);
			if (val.x < 0)
			{
				((Character)player).Message((MessageType)2, "$cdev_es_nospace", 0, (Sprite)null, false);
				return;
			}
			using (BusyScope.Enter())
			{
				if (((Humanoid)player).IsItemEquiped(item))
				{
					((Humanoid)player).RemoveEquipAction(item);
					((Humanoid)player).UnequipItem(item, true);
				}
				item.m_gridPos = val;
				item.m_equipped = false;
			}
			((Humanoid)player).m_inventory.Changed(false, false);
		}

		internal static bool AllowToggle(Player player, ItemData item)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!IsLocal((Humanoid)(object)player) || item == null || !((Humanoid)player).IsItemEquiped(item) || !SlotInventory.InOwnCell(item))
			{
				return true;
			}
			if (SlotInventory.FreeGridCellPreferBag(((Humanoid)player).m_inventory).x >= 0)
			{
				return true;
			}
			((Character)player).Message((MessageType)2, "$cdev_es_nospace", 0, (Sprite)null, false);
			return false;
		}

		internal static void Tick()
		{
			Player localPlayer = Player.m_localPlayer;
			if (Busy || !CanManage(localPlayer) || (!s_dirty && Time.time < s_nextPass))
			{
				return;
			}
			s_dirty = false;
			s_nextPass = Time.time + 1f;
			try
			{
				if (Repair(localPlayer))
				{
					((Humanoid)localPlayer).m_inventory.Changed(false, false);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Slot pass failed: {arg}");
			}
			s_dirty = false;
		}

		private static bool Repair(Player player)
		{
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = ((Humanoid)player).m_inventory;
			bool flag = false;
			if ((Object)(object)s_refusedFor != (Object)(object)player)
			{
				Refused.Clear();
				s_refusedFor = player;
			}
			using (BusyScope.Enter())
			{
				Items.Clear();
				Items.AddRange(inventory.m_inventory);
				foreach (ItemData item in Items)
				{
					flag |= SlotMemory.Restore(player, inventory, item);
				}
				foreach (ItemData item2 in Items)
				{
					if (item2.m_equipped && Jewelry.IsJewelry(item2) && !SlotInventory.InOwnCell(item2))
					{
						item2.m_equipped = false;
						flag = true;
					}
				}
				foreach (ItemData item3 in Items)
				{
					SlotKind slotKind = SlotLayout.HomeKind(item3);
					if (slotKind != SlotKind.None && !SlotInventory.InOwnCell(item3) && ((Humanoid)player).IsItemEquiped(item3))
					{
						flag |= PlaceIntoSlot(inventory, item3, slotKind);
					}
				}
				foreach (ItemData item4 in Items)
				{
					SlotCell slotCell = SlotLayout.At(item4.m_gridPos);
					if (slotCell != null && slotCell.Kind != SlotKind.Stash && !SlotLayout.Accepts(slotCell, item4))
					{
						if (((Humanoid)player).IsItemEquiped(item4))
						{
							((Humanoid)player).UnequipItem(item4, false);
						}
						if (!((Humanoid)player).IsItemEquiped(item4))
						{
							item4.m_equipped = false;
						}
						if (SlotInventory.MoveToGridOrStash(inventory, item4))
						{
							flag = true;
						}
					}
				}
				foreach (SlotCell item5 in SlotLayout.Equipment)
				{
					ItemData val = SlotInventory.ItemIn(inventory, item5);
					if (val != null && !val.m_equipped && SlotLayout.Accepts(item5, val) && !((Humanoid)player).IsItemEquiped(val) && !player.IsEquipActionQueued(val) && (!val.m_shared.m_useDurability || !(val.m_durability <= 0f)) && (!Refused.TryGetValue(val, out var value) || !(value == val.m_gridPos)) && !((Character)player).InAttack() && !((Character)player).InDodge() && (!((Character)player).IsSwimming() || ((Character)player).IsOnGround()))
					{
						if (((Humanoid)player).EquipItem(val, false))
						{
							Refused.Remove(val);
						}
						else
						{
							Refused[val] = val.m_gridPos;
						}
					}
				}
				foreach (SlotCell item6 in SlotLayout.Stash)
				{
					ItemData val2 = SlotInventory.ItemIn(inventory, item6);
					if (val2 != null)
					{
						Vector2i val3 = SlotInventory.FreeGridCellPreferBag(inventory);
						if (val3.x < 0)
						{
							break;
						}
						val2.m_gridPos = val3;
						flag = true;
					}
				}
				Items.Clear();
				return flag;
			}
		}
	}
	internal static class Jewelry
	{
		private static readonly Dictionary<string, SlotKind> FromConfig = new Dictionary<string, SlotKind>(StringComparer.Ordinal);

		private static readonly Dictionary<string, SlotKind> FromApi = new Dictionary<string, SlotKind>(StringComparer.Ordinal);

		private static readonly Dictionary<SharedData, SlotKind> Cache = new Dictionary<SharedData, SlotKind>();

		private static readonly ConditionalWeakTable<Humanoid, HashSet<StatusEffect>> Effects = new ConditionalWeakTable<Humanoid, HashSet<StatusEffect>>();

		private static readonly HashSet<StatusEffect> Wanted = new HashSet<StatusEffect>();

		private static readonly List<StatusEffect> Stale = new List<StatusEffect>();

		private static readonly List<ItemData> Worn = new List<ItemData>();

		internal static bool AnyKnown
		{
			get
			{
				if (FromApi.Count <= 0)
				{
					return FromConfig.Count > 0;
				}
				return true;
			}
		}

		internal static void ReloadConfig()
		{
			FromConfig.Clear();
			Read(ModConfig.Rings.Value, SlotKind.Ring);
			Read(ModConfig.Earrings.Value, SlotKind.Earring);
			Read(ModConfig.Amulets.Value, SlotKind.Amulet);
			Cache.Clear();
		}

		internal static void Register(string prefabName, SlotKind kind)
		{
			if (!string.IsNullOrWhiteSpace(prefabName) && SlotLayout.IsJewelryKind(kind))
			{
				FromApi[prefabName.Trim()] = kind;
				Cache.Clear();
			}
		}

		internal static void Unregister(string prefabName)
		{
			if (prefabName != null && FromApi.Remove(prefabName.Trim()))
			{
				Cache.Clear();
			}
		}

		private static void Read(string list, SlotKind kind)
		{
			if (string.IsNullOrEmpty(list))
			{
				return;
			}
			string[] array = list.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string text2 = text.Trim();
				if (text2.Length > 0)
				{
					FromConfig[text2] = kind;
				}
			}
		}

		internal static SlotKind KindOf(ItemData item)
		{
			//IL_008a: 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_0077: Invalid comparison between Unknown and I4
			if (item?.m_shared == null || (Object)(object)item.m_dropPrefab == (Object)null)
			{
				return SlotKind.None;
			}
			if (Cache.TryGetValue(item.m_shared, out var value))
			{
				return value;
			}
			string name = ((Object)item.m_dropPrefab).name;
			if (!FromConfig.TryGetValue(name, out value) && !FromApi.TryGetValue(name, out value))
			{
				value = SlotKind.None;
			}
			if (value != SlotKind.None && (item.IsEquipableVanilla() || (int)item.m_shared.m_itemType == 2))
			{
				Plugin.Log.LogWarning((object)$"{name} is listed as jewelry but is a {item.m_shared.m_itemType}; ignored.");
				value = SlotKind.None;
			}
			Cache[item.m_shared] = value;
			return value;
		}

		internal static bool IsJewelry(ItemData item)
		{
			return KindOf(item) != SlotKind.None;
		}

		internal static bool IsWorn(Humanoid humanoid, ItemData item)
		{
			if (item.m_equipped && IsJewelry(item) && SlotInventory.InOwnCell(item))
			{
				return humanoid.m_inventory.ContainsItem(item);
			}
			return false;
		}

		internal static void CollectWorn(Humanoid humanoid, List<ItemData> worn)
		{
			worn.Clear();
			Inventory inventory = humanoid.m_inventory;
			if (inventory == null)
			{
				return;
			}
			foreach (SlotCell item in SlotLayout.Equipment)
			{
				if (SlotLayout.IsJewelryKind(item.Kind))
				{
					ItemData val = SlotInventory.ItemIn(inventory, item);
					if (val != null && val.m_equipped && KindOf(val) == item.Kind)
					{
						worn.Add(val);
					}
				}
			}
		}

		internal static float Armor(Humanoid humanoid)
		{
			CollectWorn(humanoid, Worn);
			float num = 0f;
			foreach (ItemData item in Worn)
			{
				num += item.GetArmor();
			}
			Worn.Clear();
			return num;
		}

		internal static void SyncStatusEffects(Humanoid humanoid)
		{
			if (((Character)humanoid).m_seman == null)
			{
				return;
			}
			HashSet<StatusEffect> orCreateValue = Effects.GetOrCreateValue(humanoid);
			CollectWorn(humanoid, Worn);
			Wanted.Clear();
			foreach (ItemData item in Worn)
			{
				if ((Object)(object)item.m_shared.m_equipStatusEffect != (Object)null)
				{
					Wanted.Add(item.m_shared.m_equipStatusEffect);
				}
			}
			Worn.Clear();
			Stale.Clear();
			foreach (StatusEffect item2 in orCreateValue)
			{
				if (!Wanted.Contains(item2))
				{
					Stale.Add(item2);
				}
			}
			foreach (StatusEffect item3 in Stale)
			{
				orCreateValue.Remove(item3);
				if (!humanoid.m_equipmentStatusEffects.Contains(item3))
				{
					((Character)humanoid).m_seman.RemoveStatusEffect(item3.NameHash(), true);
				}
			}
			foreach (StatusEffect item4 in Wanted)
			{
				orCreateValue.Add(item4);
				if (!((Character)humanoid).m_seman.HaveStatusEffect(item4.NameHash()))
				{
					((Character)humanoid).m_seman.AddStatusEffect(item4, false, 0, 0f, (short)(-1));
				}
			}
			Stale.Clear();
			Wanted.Clear();
		}

		private static bool IsEquipableVanilla(this ItemData item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected I4, but got Unknown
			ItemType itemType = item.m_shared.m_itemType;
			switch (itemType - 3)
			{
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 6:
			case 8:
			case 11:
			case 12:
			case 14:
			case 15:
			case 16:
			case 19:
			case 21:
				return true;
			default:
				return false;
			}
		}
	}
	public static class EquipmentSlotsApi
	{
		public static bool RegisterJewelry(string prefabName, string kind)
		{
			SlotKind kind2;
			switch ((kind ?? "").Trim().ToLowerInvariant())
			{
			case "ring":
				kind2 = SlotKind.Ring;
				break;
			case "earring":
				kind2 = SlotKind.Earring;
				break;
			case "amulet":
			case "necklace":
				kind2 = SlotKind.Amulet;
				break;
			default:
				return false;
			}
			Jewelry.Register(prefabName, kind2);
			return true;
		}

		public static void GetWornJewelry(Humanoid humanoid, List<ItemData> worn)
		{
			if ((Object)(object)humanoid == (Object)null || worn == null)
			{
				worn?.Clear();
			}
			else
			{
				Jewelry.CollectWorn(humanoid, worn);
			}
		}
	}
	internal static class Locks
	{
		internal const string DataKey = "cdev_es_locks";

		private static readonly HashSet<int> Cells = new HashSet<int>();

		private static Player s_for;

		internal static bool Any
		{
			get
			{
				EnsureLoaded(Player.m_localPlayer);
				return Cells.Count > 0;
			}
		}

		private static int Key(Vector2i pos)
		{
			//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)
			return (pos.y << 8) | pos.x;
		}

		private static void EnsureLoaded(Player player)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || player == s_for)
			{
				return;
			}
			s_for = player;
			Cells.Clear();
			if (player.m_customData == null || !player.m_customData.TryGetValue("cdev_es_locks", out var value) || string.IsNullOrEmpty(value))
			{
				return;
			}
			string[] array = value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string[] array2 = text.Split(new char[1] { ',' });
				if (array2.Length == 2 && int.TryParse(array2[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(array2[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) && result >= 0 && result < 256 && result2 >= 0)
				{
					Cells.Add(Key(new Vector2i(result, result2)));
				}
			}
		}

		internal static bool IsLocked(Vector2i pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (pos.x < 0 || pos.y < 0)
			{
				return false;
			}
			EnsureLoaded(Player.m_localPlayer);
			if (Cells.Count > 0)
			{
				return Cells.Contains(Key(pos));
			}
			return false;
		}

		internal static void Toggle(Vector2i pos)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && pos.x >= 0 && pos.y >= 0)
			{
				EnsureLoaded(localPlayer);
				int item = Key(pos);
				if (!Cells.Remove(item))
				{
					Cells.Add(item);
				}
				Save(localPlayer);
			}
		}

		private static void Save(Player player)
		{
			if (player.m_customData == null)
			{
				return;
			}
			if (Cells.Count == 0)
			{
				player.m_customData.Remove("cdev_es_locks");
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (int cell in Cells)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(';');
				}
				stringBuilder.Append(cell & 0xFF).Append(',').Append(cell >> 8);
			}
			player.m_customData["cdev_es_locks"] = stringBuilder.ToString();
		}
	}
	internal static class Migration
	{
		private const string EaqsSlot = "eaqs_slot";

		private const string EaqsPlayer = "eaqs_player";

		internal static int Normalize(Inventory inventory, int visibleRows)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: 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_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_01c2: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			List<ItemData> list = new List<ItemData>();
			HashSet<Vector2i> hashSet = new HashSet<Vector2i>();
			foreach (ItemData item in inventory.m_inventory)
			{
				Vector2i gridPos = item.m_gridPos;
				if (((gridPos.x < 0 || gridPos.x >= inventory.m_width || gridPos.y < 0 || gridPos.y >= visibleRows) && !SlotLayout.InRegion(gridPos)) || !hashSet.Add(gridPos))
				{
					list.Add(item);
				}
			}
			if (list.Count == 0)
			{
				return 0;
			}
			list.Sort((ItemData a, ItemData b) => StampRank(a).CompareTo(StampRank(b)));
			int num = 0;
			foreach (ItemData item2 in list)
			{
				Vector2i gridPos2 = item2.m_gridPos;
				SlotCell slotCell = FromEaqsStamp(item2);
				if (slotCell == null && item2.m_equipped)
				{
					SlotKind slotKind = SlotLayout.HomeKind(item2);
					if (slotKind != SlotKind.None)
					{
						foreach (SlotCell item3 in SlotLayout.CellsOf(slotKind))
						{
							if (!hashSet.Contains(item3.Pos))
							{
								slotCell = item3;
								break;
							}
						}
					}
				}
				Vector2i val;
				if (slotCell != null && !hashSet.Contains(slotCell.Pos) && (slotCell.Kind == SlotKind.Quiver || SlotLayout.Accepts(slotCell, item2)))
				{
					val = slotCell.Pos;
				}
				else
				{
					val = FreeCell(inventory, visibleRows, hashSet);
					if (val.x < 0)
					{
						continue;
					}
					if (SlotLayout.At(val) == null || !SlotLayout.At(val).IsEquipment)
					{
						item2.m_equipped = false;
					}
				}
				hashSet.Add(val);
				item2.m_gridPos = val;
				if (item2.m_customData != null)
				{
					item2.m_customData.Remove("eaqs_slot");
					item2.m_customData.Remove("eaqs_player");
				}
				SlotCell slotCell2 = SlotLayout.At(val);
				num++;
			}
			return num;
		}

		private static int StampRank(ItemData item)
		{
			if (FromEaqsStamp(item) == null)
			{
				if (!item.m_equipped)
				{
					return 2;
				}
				return 1;
			}
			return 0;
		}

		private static SlotCell FromEaqsStamp(ItemData item)
		{
			if (item.m_customData == null || !item.m_customData.TryGetValue("eaqs_slot", out var value) || string.IsNullOrEmpty(value))
			{
				return null;
			}
			if (value.StartsWith("Quick") && int.TryParse(value.Substring(5), out var result) && result >= 1 && result <= 6)
			{
				return SlotLayout.Quick[result - 1];
			}
			if (value.StartsWith("CustomBetterArcheryQuiver") && int.TryParse(value.Substring("CustomBetterArcheryQuiver".Length), out var result2) && result2 >= 1 && result2 <= 3)
			{
				return SlotLayout.Quiver[result2 - 1];
			}
			SlotKind kind;
			switch (value)
			{
			case "Helmet":
				kind = SlotKind.Helmet;
				break;
			case "Chest":
				kind = SlotKind.Chest;
				break;
			case "Legs":
				kind = SlotKind.Legs;
				break;
			case "Shoulder":
				kind = SlotKind.Cape;
				break;
			case "Utility":
				kind = SlotKind.Belt;
				break;
			case "Trinket":
				kind = SlotKind.Trinket;
				break;
			default:
				return null;
			}
			using (IEnumerator<SlotCell> enumerator = SlotLayout.CellsOf(kind).GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					return enumerator.Current;
				}
			}
			return null;
		}

		private static Vector2i FreeCell(Inventory inventory, int visibleRows, HashSet<Vector2i> taken)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			Vector2i val = default(Vector2i);
			for (int i = 1; i < visibleRows; i++)
			{
				for (int j = 0; j < inventory.m_width; j++)
				{
					((Vector2i)(ref val))..ctor(j, i);
					if (!taken.Contains(val))
					{
						return val;
					}
				}
			}
			Vector2i val2 = default(Vector2i);
			for (int k = 0; k < inventory.m_width; k++)
			{
				((Vector2i)(ref val2))..ctor(k, 0);
				if (!taken.Contains(val2))
				{
					return val2;
				}
			}
			foreach (SlotCell item in SlotLayout.Stash)
			{
				if (!taken.Contains(item.Pos))
				{
					return item.Pos;
				}
			}
			return new Vector2i(-1, -1);
		}

		private static string Name(ItemData item)
		{
			string text = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : (item.m_shared?.m_name ?? "?"));
			if (item.m_stack <= 1)
			{
				return text;
			}
			return $"{text} x{item.m_stack}";
		}

		internal static int VisibleRows(Player player)
		{
			string s = default(string);
			if (player.TryGetUniqueKeyValue("invrows", ref s) && int.TryParse(s, out var result))
			{
				return Mathf.Clamp(result, 1, 9);
			}
			return Mathf.Max(((Humanoid)player).m_inventory.m_height, 4);
		}
	}
	internal static class ModConfig
	{
		internal static ConfigEntry<KeyCode> Quick1;

		internal static ConfigEntry<KeyCode> Quick2;

		internal static ConfigEntry<KeyCode> Quick3;

		internal static ConfigEntry<KeyCode> Quick4;

		internal static ConfigEntry<KeyCode> Quick5;

		internal static ConfigEntry<KeyCode> Quick6;

		internal static ConfigEntry<KeyCode> AltModifier;

		internal static ConfigEntry<bool> KeysWinOverVanilla;

		internal static ConfigEntry<bool> HudEnabled;

		internal static ConfigEntry<Vector2> HudOffset;

		internal static ConfigEntry<float> HudSpacing;

		internal static ConfigEntry<bool> CellLockIcons;

		internal static ConfigEntry<Vector2> PanelOffset;

		internal static ConfigEntry<bool> PanelCharacter;

		internal static ConfigEntry<string> Rings;

		internal static ConfigEntry<string> Earrings;

		internal static ConfigEntry<string> Amulets;

		internal static void Bind(ConfigFile config)
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Expected O, but got Unknown
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Expected O, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Expected O, but got Unknown
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Expected O, but got Unknown
			Quick1 = config.Bind<KeyCode>("QuickSlots", "Key1", (KeyCode)122, "Uses quick slot 1 (with the Alt modifier held: slot 4).");
			Quick2 = config.Bind<KeyCode>("QuickSlots", "Key2", (KeyCode)118, "Uses quick slot 2 (with the Alt modifier held: slot 5).");
			Quick3 = config.Bind<KeyCode>("QuickSlots", "Key3", (KeyCode)98, "Uses quick slot 3 (with the Alt modifier held: slot 6).");
			Quick4 = config.Bind<KeyCode>("QuickSlots", "Key4", (KeyCode)0, "Uses quick slot 4 on a key of its own, with no modifier held. None: slot 4 is only the Alt modifier with Key1.");
			Quick5 = config.Bind<KeyCode>("QuickSlots", "Key5", (KeyCode)0, "Uses quick slot 5 on a key of its own, with no modifier held. None: slot 5 is only the Alt modifier with Key2.");
			Quick6 = config.Bind<KeyCode>("QuickSlots", "Key6", (KeyCode)0, "Uses quick slot 6 on a key of its own, with no modifier held. None: slot 6 is only the Alt modifier with Key3.");
			AltModifier = config.Bind<KeyCode>("QuickSlots", "AltModifier", (KeyCode)308, "Hold to switch the quick slot keys and the HUD to slots 4-6. Works next to Key4-Key6; None: only those keys.");
			KeysWinOverVanilla = config.Bind<bool>("QuickSlots", "KeysWinOverVanilla", true, "A quick slot key also bound to a vanilla action does only the quick slot (vanilla binds V to auto-pickup).");
			HudEnabled = config.Bind<bool>("Hud", "Enabled", true, "Show the quick slots next to the forsaken power.");
			HudOffset = config.Bind<Vector2>("Hud", "Offset", Vector2.zero, "Moves the HUD quick slots from their place right of the forsaken power (pixels, x right, y up).");
			HudSpacing = config.Bind<float>("Hud", "Spacing", 8f, new ConfigDescription("Gap between the HUD quick slots.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 64f), Array.Empty<object>()));
			CellLockIcons = config.Bind<bool>("Inventory", "CellLocks", true, "Show a padlock in the bottom left corner of every inventory cell. Click it to lock the cell: its item is then never moved into a chest by a button that empties the inventory - vanilla's \"stack similar\" and QuickStackStore's quick stack, store and sort.");
			PanelOffset = config.Bind<Vector2>("Panel", "Offset", Vector2.zero, "Moves the equipment panel from its place between the inventory and the crafting panel (pixels, x right, y up).");
			PanelCharacter = config.Bind<bool>("Panel", "ShowCharacter", true, "Draw your character, as it is dressed right now, behind the equipment slots.");
			Rings = config.Bind<string>("Jewelry", "Rings", "", new ConfigDescription("Item prefab names worn in the ring slots, comma-separated.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			Earrings = config.Bind<string>("Jewelry", "Earrings", "", new ConfigDescription("Item prefab names worn in the earring slots, comma-separated.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			Amulets = config.Bind<string>("Jewelry", "Amulets", "", new ConfigDescription("Item prefab names worn in the amulet slot, comma-separated.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			Rings.SettingChanged += delegate
			{
				Jewelry.ReloadConfig();
			};
			Earrings.SettingChanged += delegate
			{
				Jewelry.ReloadConfig();
			};
			Amulets.SettingChanged += delegate
			{
				Jewelry.ReloadConfig();
			};
			Jewelry.ReloadConfig();
		}

		internal static KeyCode QuickKey(int ordinal)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0042: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			return (KeyCode)(ordinal switch
			{
				0 => Quick1.Value, 
				1 => Quick2.Value, 
				2 => Quick3.Value, 
				3 => Quick4.Value, 
				4 => Quick5.Value, 
				_ => Quick6.Value, 
			});
		}
	}
	[BepInPlugin("cdev.equipmentslots", "CDEV.EquipmentSlots", "0.1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal const string EaqsGuid = "randyknapp.mods.equipmentandquickslots";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		internal static bool Active { get; private set; }

		private void Awake()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			Translations.Register();
			Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(SlotPanel.Invalidate));
			if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.equipmentandquickslots"))
			{
				Log.LogError((object)"EquipmentAndQuickSlots is installed: CDEV.EquipmentSlots replaces it and stays switched off. Remove EquipmentAndQuickSlots; its slot items are converted on the next load.");
				return;
			}
			Active = true;
			BetterArcheryHost.Setup();
			_harmony = new Harmony("cdev.equipmentslots");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			QuickStackStoreHost.Setup(_harmony);
			ModConfig.Quick1.SettingChanged += delegate
			{
				SlotPanel.Invalidate();
			};
			ModConfig.Quick2.SettingChanged += delegate
			{
				SlotPanel.Invalidate();
			};
			ModConfig.Quick3.SettingChanged += delegate
			{
				SlotPanel.Invalidate();
			};
			ModConfig.Quick4.SettingChanged += delegate
			{
				SlotPanel.Invalidate();
			};
			ModConfig.Quick5.SettingChanged += delegate
			{
				SlotPanel.Invalidate();
			};
			ModConfig.Quick6.SettingChanged += delegate
			{
				SlotPanel.Invalidate();
			};
			ModConfig.AltModifier.SettingChanged += delegate
			{
				SlotPanel.Invalidate();
			};
		}

		private void Update()
		{
			if (Active)
			{
				QuickSlots.Tick();
				EquipSync.Tick();
				QuickBar.Tick();
				PlayerPreview.Tick();
			}
		}

		private void LateUpdate()
		{
			InventoryGui instance = InventoryGui.instance;
			if (Active && (Object)(object)instance != (Object)null && InventoryGui.IsVisible() && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				SlotPanel.Refresh(instance, Player.m_localPlayer);
			}
		}

		private void OnDestroy()
		{
			Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(SlotPanel.Invalidate));
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class QuickSlots
	{
		private static readonly bool[] Wanted = new bool[6];

		internal static bool AltHeld()
		{
			//IL_0005: 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)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			KeyCode value = ModConfig.AltModifier.Value;
			if ((int)value != 0)
			{
				return ZInput.GetKey(value, false);
			}
			return false;
		}

		internal static void Tick()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ZInput.instance == null || !((Character)localPlayer).TakeInput() || Hud.InRadial())
			{
				return;
			}
			bool flag = AltHeld();
			for (int i = 0; i < 6; i++)
			{
				Wanted[i] = false;
			}
			for (int j = 0; j < 3; j++)
			{
				KeyCode val = ModConfig.QuickKey(j);
				if ((int)val != 0 && ZInput.GetKeyDown(val, false))
				{
					Wanted[flag ? (j + 3) : j] = true;
				}
			}
			for (int k = 3; k < 6; k++)
			{
				KeyCode val2 = ModConfig.QuickKey(k);
				if ((int)val2 != 0 && ZInput.GetKeyDown(val2, false))
				{
					Wanted[k] = true;
				}
			}
			for (int l = 0; l < 6; l++)
			{
				if (Wanted[l])
				{
					SlotCell slotCell = SlotLayout.QuickCell(l);
					ItemData itemAt = ((Humanoid)localPlayer).m_inventory.GetItemAt(slotCell.Pos.x, slotCell.Pos.y);
					if (itemAt != null)
					{
						((Humanoid)localPlayer).UseItem((Inventory)null, itemAt, false);
					}
				}
			}
		}

		internal static bool AnyKeyDown()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			for (int i = 0; i < 6; i++)
			{
				KeyCode val = ModConfig.QuickKey(i);
				if ((int)val != 0 && ZInput.GetKeyDown(val, false))
				{
					return true;
				}
			}
			return false;
		}

		internal static string Label(int ordinal)
		{
			//IL_0011: 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_0017: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (ordinal < 3)
			{
				return KeyName(ModConfig.QuickKey(ordinal));
			}
			KeyCode val = ModConfig.QuickKey(ordinal);
			if ((int)val != 0)
			{
				return KeyName(val);
			}
			return KeyName(ModConfig.AltModifier.Value) + "+" + KeyName(ModConfig.QuickKey(ordinal - 3));
		}

		private unsafe static string KeyName(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected I4, but got Unknown
			if ((int)key != 0)
			{
				switch (key - 303)
				{
				case 4:
				case 5:
					return "Alt";
				case 2:
				case 3:
					return "Ctrl";
				case 0:
				case 1:
					return "Shift";
				default:
				{
					string text = ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
					if (!text.StartsWith("Alpha"))
					{
						return text;
					}
					return text.Substring(5);
				}
				}
			}
			return "-";
		}
	}
	internal static class SlotInventory
	{
		private static readonly ConditionalWeakTable<Inventory, object> Registered = new ConditionalWeakTable<Inventory, object>();

		private static readonly object Marker = new object();

		internal static void Register(Inventory inventory)
		{
			if (inventory != null && !Registered.TryGetValue(inventory, out var _))
			{
				Registered.Add(inventory, Marker);
			}
		}

		internal static void Unregister(Inventory inventory)
		{
			if (inventory != null)
			{
				Registered.Remove(inventory);
			}
		}

		internal static bool IsSlotInventory(Inventory inventory)
		{
			object value;
			if (inventory != null && Plugin.Active)
			{
				return Registered.TryGetValue(inventory, out value);
			}
			return false;
		}

		internal static bool InGrid(Inventory inventory, Vector2i pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (pos.x >= 0 && pos.y >= 0 && pos.x < inventory.m_width)
			{
				return pos.y < inventory.m_height;
			}
			return false;
		}

		internal static int GridItemCount(Inventory inventory)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			List<ItemData> inventory2 = inventory.m_inventory;
			for (int i = 0; i < inventory2.Count; i++)
			{
				if (InGrid(inventory, inventory2[i].m_gridPos))
				{
					num++;
				}
			}
			return num;
		}

		internal static Vector2i FreeGridCell(Inventory inventory)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < inventory.m_height; i++)
			{
				for (int j = 0; j < inventory.m_width; j++)
				{
					if (inventory.GetItemAt(j, i) == null)
					{
						return new Vector2i(j, i);
					}
				}
			}
			return new Vector2i(-1, -1);
		}

		internal static Vector2i FreeGridCell(Inventory inventory, bool topFirst)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < inventory.m_height; i++)
			{
				int num = (topFirst ? i : (inventory.m_height - 1 - i));
				for (int j = 0; j < inventory.m_width; j++)
				{
					if (inventory.GetItemAt(j, num) == null)
					{
						return new Vector2i(j, num);
					}
				}
			}
			return new Vector2i(-1, -1);
		}

		internal static Vector2i FreeGridCellPreferBag(Inventory inventory)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 1; i < inventory.m_height; i++)
			{
				for (int j = 0; j < inventory.m_width; j++)
				{
					if (inventory.GetItemAt(j, i) == null)
					{
						return new Vector2i(j, i);
					}
				}
			}
			for (int k = 0; k < inventory.m_width; k++)
			{
				if (inventory.GetItemAt(k, 0) == null)
				{
					return new Vector2i(k, 0);
				}
			}
			return new Vector2i(-1, -1);
		}

		internal static SlotCell FreeStashCell(Inventory inventory)
		{
			foreach (SlotCell item in SlotLayout.Stash)
			{
				if (inventory.GetItemAt(item.Pos.x, item.Pos.y) == null)
				{
					return item;
				}
			}
			return null;
		}

		internal static bool MoveToGridOrStash(Inventory inventory, ItemData item)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Vector2i val = FreeGridCellPreferBag(inventory);
			if (val.x >= 0)
			{
				item.m_gridPos = val;
				return true;
			}
			SlotCell slotCell = FreeStashCell(inventory);
			if (slotCell != null)
			{
				item.m_gridPos = slotCell.Pos;
				return true;
			}
			return false;
		}

		internal static ItemData ItemIn(Inventory inventory, SlotCell cell)
		{
			return inventory.GetItemAt(cell.Pos.x, cell.Pos.y);
		}

		internal static SlotCell TargetCell(Inventory inventory, SlotKind kind, ItemData item)
		{
			SlotCell slotCell = null;
			foreach (SlotCell item2 in SlotLayout.CellsOf(kind))
			{
				ItemData val = ItemIn(inventory, item2);
				if (val == item || val == null)
				{
					return item2;
				}
				if (slotCell == null)
				{
					slotCell = item2;
				}
			}
			return slotCell;
		}

		internal static bool InGridOrSlot(ItemData item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (SlotLayout.At(item.m_gridPos) == null)
			{
				return item.m_gridPos.y < 20;
			}
			return true;
		}

		internal static bool InOwnCell(ItemData item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			SlotCell slotCell = SlotLayout.At(item.m_gridPos);
			if (slotCell == null)
			{
				return false;
			}
			SlotKind slotKind = SlotLayout.HomeKind(item);
			if (!slotCell.IsEquipment || slotCell.Kind != slotKind)
			{
				if (slotCell.Kind == SlotKind.Quiver)
				{
					return slotKind == SlotKind.Ammo;
				}
				return false;
			}
			return true;
		}
	}
	internal enum SlotKind
	{
		None,
		Helmet,
		Chest,
		Legs,
		Cape,
		Belt,
		Trinket,
		Ring,
		Earring,
		Amulet,
		Ammo,
		Quick,
		Quiver,
		Stash
	}
	internal sealed class SlotCell
	{
		internal readonly int Index;

		internal readonly SlotKind Kind;

		internal readonly int Ordinal;

		internal readonly Vector2i Pos;

		internal bool IsEquipment => SlotLayout.IsEquipmentKind(Kind);

		internal SlotCell(int index, SlotKind kind, int ordinal, Vector2i pos)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Index = index;
			Kind = kind;
			Ordinal = ordinal;
			Pos = pos;
		}
	}
	internal static class SlotLayout
	{
		internal const int Width = 8;

		internal const int FirstRow = 20;

		internal const int QuickRow = 22;

		internal const int QuiverRow = 23;

		internal const int FirstStashRow = 24;

		internal const int LastRow = 31;

		internal const int QuickCount = 6;

		internal const int QuiverCount = 3;

		internal static readonly List<SlotCell> All;

		internal static readonly List<SlotCell> Equipment;

		internal static readonly List<SlotCell> Quick;

		internal static readonly List<SlotCell> Quiver;

		internal static readonly List<SlotCell> Stash;

		private static readonly SlotCell[,] ByPos;

		static SlotLayout()
		{
			All = new List<SlotCell>();
			Equipment = new List<SlotCell>();
			Quick = new List<SlotCell>();
			Quiver = new List<SlotCell>();
			Stash = new List<SlotCell>();
			ByPos = new SlotCell[8, 12];
			Add(SlotKind.Helmet, 0, 0, 20);
			Add(SlotKind.Chest, 0, 1, 20);
			Add(SlotKind.Legs, 0, 2, 20);
			Add(SlotKind.Cape, 0, 3, 20);
			Add(SlotKind.Belt, 0, 4, 20);
			Add(SlotKind.Trinket, 0, 5, 20);
			Add(SlotKind.Amulet, 0, 6, 20);
			Add(SlotKind.Ring, 0, 7, 20);
			Add(SlotKind.Ring, 1, 0, 21);
			Add(SlotKind.Earring, 0, 1, 21);
			Add(SlotKind.Earring, 1, 2, 21);
			Add(SlotKind.Ammo, 0, 3, 21);
			for (int i = 0; i < 6; i++)
			{
				Add(SlotKind.Quick, i, i, 22);
			}
			for (int j = 0; j < 3; j++)
			{
				Add(SlotKind.Quiver, j, j, 23);
			}
			int num = 0;
			for (int k = 24; k <= 31; k++)
			{
				for (int l = 0; l < 8; l++)
				{
					Add(SlotKind.Stash, num++, l, k);
				}
			}
		}

		private static void Add(SlotKind kind, int ordinal, int x, int y)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			SlotCell slotCell = new SlotCell(All.Count, kind, ordinal, new Vector2i(x, y));
			All.Add(slotCell);
			ByPos[x, y - 20] = slotCell;
			if (IsEquipmentKind(kind))
			{
				Equipment.Add(slotCell);
				return;
			}
			switch (kind)
			{
			case SlotKind.Quick:
				Quick.Add(slotCell);
				break;
			case SlotKind.Quiver:
				Quiver.Add(slotCell);
				break;
			default:
				Stash.Add(slotCell);
				break;
			}
		}

		internal static bool InRegion(Vector2i pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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)
			if (pos.x >= 0 && pos.x < 8 && pos.y >= 20)
			{
				return pos.y <= 31;
			}
			return false;
		}

		internal static SlotCell At(Vector2i pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!InRegion(pos))
			{
				return null;
			}
			return ByPos[pos.x, pos.y - 20];
		}

		internal static SlotCell At(int x, int y)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return At(new Vector2i(x, y));
		}

		internal static bool IsEquipmentKind(SlotKind kind)
		{
			if (kind >= SlotKind.Helmet)
			{
				return kind <= SlotKind.Ammo;
			}
			return false;
		}

		internal static bool IsJewelryKind(SlotKind kind)
		{
			if (kind != SlotKind.Ring && kind != SlotKind.Earring)
			{
				return kind == SlotKind.Amulet;
			}
			return true;
		}

		internal static SlotKind HomeKind(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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_0021: 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_0041: Expected I4, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			if (item?.m_shared == null)
			{
				return SlotKind.None;
			}
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType <= 17)
			{
				switch (itemType - 6)
				{
				default:
					if ((int)itemType != 17)
					{
						goto IL_0068;
					}
					return SlotKind.Cape;
				case 0:
					return SlotKind.Helmet;
				case 1:
					return SlotKind.Chest;
				case 5:
					return SlotKind.Legs;
				case 3:
					break;
				case 2:
				case 4:
					goto IL_0068;
				}
			}
			else
			{
				if ((int)itemType == 18)
				{
					return SlotKind.Belt;
				}
				if ((int)itemType != 23)
				{
					if ((int)itemType != 24)
					{
						goto IL_0068;
					}
					return SlotKind.Trinket;
				}
			}
			return SlotKind.Ammo;
			IL_0068:
			SlotKind slotKind = Jewelry.KindOf(item);
			if (slotKind == SlotKind.None)
			{
				if (!BetterArcheryHost.IsQuiver(item))
				{
					return SlotKind.None;
				}
				return SlotKind.Ammo;
			}
			return slotKind;
		}

		internal static bool Accepts(SlotCell cell, ItemData item)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			if (cell == null || item?.m_shared == null)
			{
				return false;
			}
			switch (cell.Kind)
			{
			case SlotKind.Quick:
				return true;
			case SlotKind.Quiver:
				if (BetterArcheryHost.QuiverActive && BetterArcheryHost.IsQuiverEquipped())
				{
					return (int)item.m_shared.m_itemType == 9;
				}
				return false;
			case SlotKind.Stash:
				return false;
			case SlotKind.Ammo:
				return HomeKind(item) == SlotKind.Ammo;
			default:
				return HomeKind(item) == cell.Kind;
			}
		}

		internal static IEnumerable<SlotCell> CellsOf(SlotKind kind)
		{
			foreach (SlotCell item in Equipment)
			{
				if (item.Kind == kind)
				{
					yield return item;
				}
			}
		}

		internal static SlotCell QuickCell(int ordinal)
		{
			return Quick[ordinal];
		}
	}
	internal static class SlotMemory
	{
		internal const string Key = "CDEV_EquipmentSlots_slot";

		internal static void Stamp(ItemData item, SlotCell cell, long playerId)
		{
			if (item.m_customData == null)
			{
				item.m_customData = new Dictionary<string, string>();
			}
			Dictionary<string, string> customData = item.m_customData;
			int index = cell.Index;
			customData["CDEV_EquipmentSlots_slot"] = index + "|" + playerId;
		}

		internal static bool Restore(Player player, Inventory inventory, ItemData item)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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)
			if (item.m_customData == null || !item.m_customData.TryGetValue("CDEV_EquipmentSlots_slot", out var value))
			{
				return false;
			}
			item.m_customData.Remove("CDEV_EquipmentSlots_slot");
			string[] array = value.Split(new char[1] { '|' });
			if (array.Length != 2 || !int.TryParse(array[0], out var result) || !long.TryParse(array[1], out var result2) || result2 != player.GetPlayerID() || result < 0 || result >= SlotLayout.All.Count)
			{
				return false;
			}
			SlotCell slotCell = SlotLayout.All[result];
			if (SlotLayout.At(item.m_gridPos) != null || !SlotLayout.Accepts(slotCell, item) || SlotInventory.ItemIn(inventory, slotCell) != null)
			{
				return false;
			}
			item.m_gridPos = slotCell.Pos;
			return true;
		}

		internal static void CompactGrave(Inventory grave, long playerId)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			List<ItemData> inventory = grave.m_inventory;
			HashSet<Vector2i> hashSet = new HashSet<Vector2i>();
			List<ItemData> list = new List<ItemData>();
			foreach (ItemData item in inventory)
			{
				if (!SlotInventory.InGrid(grave, item.m_gridPos) || !hashSet.Add(item.m_gridPos))
				{
					list.Add(item);
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			list.Sort((ItemData a, ItemData b) => Order(a).CompareTo(Order(b)));
			int width = grave.m_width;
			int num = 0;
			int num2 = grave.m_height - 1;
			Vector2i val = default(Vector2i);
			foreach (ItemData item2 in list)
			{
				SlotCell slotCell = SlotLayout.At(item2.m_gridPos);
				if (slotCell != null && slotCell.Kind != SlotKind.Stash)
				{
					Stamp(item2, slotCell, playerId);
				}
				do
				{
					((Vector2i)(ref val))..ctor(num % width, num / width);
					num++;
				}
				while (hashSet.Contains(val));
				hashSet.Add(val);
				item2.m_gridPos = val;
				if (val.y > num2)
				{
					num2 = val.y;
				}
			}
			if (num2 + 1 > grave.m_height)
			{
				grave.m_height = num2 + 1;
			}
		}

		private static int Order(ItemData item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return SlotLayout.At(item.m_gridPos)?.Index ?? int.MaxValue;
		}
	}
	internal static class Translations
	{
		private static readonly string[] Keys = new string[25]
		{
			"cdev_es_title", "cdev_es_quick", "cdev_es_quiver", "cdev_es_stash", "cdev_es_slot_helmet", "cdev_es_slot_chest", "cdev_es_slot_legs", "cdev_es_slot_cape", "cdev_es_slot_belt", "cdev_es_slot_trinket",
			"cdev_es_slot_ring", "cdev_es_slot_earring", "cdev_es_slot_amulet", "cdev_es_slot_ammo", "cdev_es_slot_quick", "cdev_es_slot_quiver", "cdev_es_slot_stash", "cdev_es_quick_hint", "cdev_es_nospace", "cdev_es_nojewelry",
			"cdev_es_preview_attack", "cdev_es_preview_block", "cdev_es_preview_attack_icon", "cdev_es_preview_block_icon", "cdev_es_lock"
		};

		private static readonly Dictionary<string, string[]> Languages = new Dictionary<string, string[]>
		{
			["English"] = new string[25]
			{
				"Equipment", "Quick slots", "Quiver", "Did not fit", "Helmet", "Chest", "Legs", "Cape", "Belt", "Trinket",
				"Ring", "Earring", "Amulet", "Ammo", "Quick slot", "Quiver: arrows", "Did not fit", "Any item. Its key uses it like a hotbar key.", "No free space in the inventory", "Needs the jewelry mod CDEV.ExtJewelry.",
				"LMB attack", "RMB block", "attack", "block", "Lock slot"
			},
			["Russian"] = new string[25]
			{
				"Экипировка", "Быстрые слоты", "Колчан", "Не поместилось", "Шлем", "Нагрудник", "Штаны", "Плащ", "Пояс", "Тринкет",
				"Кольцо", "Серьга", "Амулет", "Стрелы", "Быстрый слот", "Колчан: стрелы", "Не поместилось", "Любой предмет. Клавиша слота использует его, как клавиша панели 1-8.", "Нет места в инвентаре", "Нужен мод CDEV.ExtJewelry (бижутерия).",
				"ЛКМ удар", "ПКМ блок", "удар", "блок", "Заблокировать слот"
			},
			["Ukrainian"] = new string[25]
			{
				"Спорядження", "Швидкі слоти", "Сагайдак", "Не вмістилося", "Шолом", "Нагрудник", "Штани", "Плащ", "Пояс", "Дрібничка",
				"Каблучка", "Сережка", "Амулет", "Стріли", "Швидкий слот", "Сагайдак: стріли", "Не вмістилося", "Будь-який предмет. Клавіша слота використовує його, як клавіша панелі 1-8.", "Немає місця в інвентарі", "Потрібен мод CDEV.ExtJewelry (біжутерія).",
				"ЛКМ удар", "ПКМ блок", "удар", "блок", "Заблокувати слот"
			},
			["German"] = new string[25]
			{
				"Ausrüstung", "Schnellplätze", "Köcher", "Passte nicht", "Helm", "Brust", "Beine", "Umhang", "Gürtel", "Schmuckstück",
				"Ring", "Ohrring", "Amulett", "Munition", "Schnellplatz", "Köcher: Pfeile", "Passte nicht", "Beliebiger Gegenstand. Seine Taste benutzt ihn wie eine Taste der Schnellleiste.", "Kein freier Platz im Inventar", "Benötigt den Schmuck-Mod CDEV.ExtJewelry.",
				"LMT Angriff", "RMT Blocken", "Angriff", "Blocken", "Platz sperren"
			},
			["French"] = new string[25]
			{
				"Équipement", "Emplacements rapides", "Carquois", "N'a pas pu être rangé", "Casque", "Torse", "Jambes", "Cape", "Ceinture", "Babiole",
				"Anneau", "Boucle d'oreille", "Amulette", "Munitions", "Emplacement rapide", "Carquois : flèches", "N'a pas pu être rangé", "N'importe quel objet. Sa touche l'utilise comme une touche de la barre rapide.", "Plus de place dans l'inventaire", "Nécessite le mod de bijoux CDEV.ExtJewelry.",
				"Clic gauche : attaque", "Clic droit : parade", "attaque", "parade", "Verrouiller la case"
			},
			["Spanish"] = new string[25]
			{
				"Equipo", "Ranuras rápidas", "Carcaj", "No cupo", "Casco", "Pecho", "Piernas", "Capa", "Cinturón", "Abalorio",
				"Anillo", "Pendiente", "Amuleto", "Munición", "Ranura rápida", "Carcaj: flechas", "No cupo", "Cualquier objeto. Su tecla lo usa como una tecla de la barra rápida.", "No hay espacio libre en el inventario", "Requiere el mod de joyería CDEV.ExtJewelry.",
				"Clic izq.: atacar", "Clic der.: bloquear", "atacar", "bloquear", "Bloquear casilla"
			},
			["Italian"] = new string[25]
			{
				"Equipaggiamento", "Slot rapidi", "Faretra", "Non c'era spazio", "Elmo", "Torso", "Gambe", "Mantello", "Cintura", "Ninnolo",
				"Anello", "Orecchino", "Amuleto", "Munizioni", "Slot rapido", "Faretra: frecce", "Non c'era spazio", "Qualsiasi oggetto. Il suo tasto lo usa come un tasto della barra rapida.", "Nessuno spazio libero nell'inventario", "Richiede la mod di gioielli CDEV.ExtJewelry.",
				"Clic sin.: attacco", "Clic des.: parata", "attacco", "parata", "Blocca casella"
			},
			["Portuguese_Brazilian"] = new string[25]
			{
				"Equipamento", "Espaços rápidos", "Aljava", "Não coube", "Capacete", "Peitoral", "Pernas", "Capa", "Cinto", "Bugiganga",
				"Anel", "Brinco", "Amuleto", "Munição", "Espaço rápido", "Aljava: flechas", "Não coube", "Qualquer item. Sua tecla o usa como uma tecla da barra rápida.", "Sem espaço livre no inventário", "Requer o mod de joias CDEV.ExtJewelry.",
				"Botão esq.: atacar", "Botão dir.: bloquear", "atacar", "bloquear", "Travar espaço"
			},
			["Portuguese_European"] = new string[25]
			{
				"Equipamento", "Espaços rápidos", "Aljava", "Não coube", "Capacete", "Peitoral", "Pernas", "Capa", "Cinto", "Berloque",
				"Anel", "Brinco", "Amuleto", "Munições", "Espaço rápido", "Aljava: flechas", "Não coube", "Qualquer objeto. A sua tecla usa-o como uma tecla da barra rápida.", "Sem espaço livre no inventário", "Requer o mod de joias CDEV.ExtJewelry.",
				"Botão esq.: atacar", "Botão dir.: bloquear", "atacar", "bloquear", "Trancar espaço"
			},
			["Polish"] = new string[25]
			{
				"Ekwipunek", "Szybkie sloty", "Kołczan", "Nie zmieściło się", "Hełm", "Tors", "Nogi", "Peleryna", "Pas", "Błyskotka",
				"Pierścień", "Kolczyk", "Amulet", "Amunicja", "Szybki slot", "Kołczan: strzały", "Nie zmieściło się", "Dowolny przedmiot. Jego klawisz używa go jak klawisza paska szybkiego dostępu.", "Brak wolnego miejsca w ekwipunku", "Wymaga moda z biżuterią CDEV.ExtJewelry.",
				"LPM atak", "PPM blok", "atak", "blok", "Zablokuj pole"
			},
			["Czech"] = new string[25]
			{
				"Výbava", "Rychlé sloty", "Toulec", "Nevešlo se", "Helma", "Hruď", "Nohy", "Plášť", "Opasek", "Cetka",
				"Prsten", "Náušnice", "Amulet", "Munice", "Rychlý slot", "Toulec: šípy", "Nevešlo se", "Libovolný předmět. Jeho klávesa ho použije jako klávesa rychlé lišty.", "V inventáři není volné místo", "Vyžaduje mod se šperky CDEV.ExtJewelry.",
				"LTM útok", "PTM blok", "útok", "blok", "Zamknout políčko"
			},
			["Hungarian"] = new string[25]
			{
				"Felszerelés", "Gyorshelyek", "Tegez", "Nem fért el", "Sisak", "Mellvért", "Lábvért", "Köpeny", "Öv", "Csecsebecse",
				"Gyűrű", "Fülbevaló", "Amulett", "Lőszer", "Gyorshely", "Tegez: nyilak", "Nem fért el", "Bármilyen tárgy. A billentyűje úgy használja, mint a gyorssáv billentyűit.", "Nincs szabad hely a tárgylistában", "Szükséges az ékszer mod: CDEV.ExtJewelry.",
				"Bal klikk: támadás", "Jobb klikk: védés", "támadás", "védés", "Cella zárolása"
			},
			["Dutch"] = new string[25]
			{
				"Uitrusting", "Snelle vakken", "Pijlkoker", "Paste niet", "Helm", "Borst", "Benen", "Cape", "Riem", "Snuisterij",
				"Ring", "Oorbel", "Amulet", "Munitie", "Snel vak", "Pijlkoker: pijlen", "Paste niet", "Elk voorwerp. De toets gebruikt het als een toets van de snelbalk.", "Geen vrije ruimte in de inventaris", "Vereist de sieraden-mod CDEV.ExtJewelry.",
				"LMK: aanval", "RMK: blokkeren", "aanval", "blokkeren", "Vakje vergrendelen"
			},
			["Swedish"] = new string[25]
			{
				"Utrustning", "Snabbplatser", "Koger", "Fick inte plats", "Hjälm", "Bröst", "Ben", "Mantel", "Bälte", "Prydnad",
				"Ring", "Örhänge", "Amulett", "Ammunition", "Snabbplats", "Koger: pilar", "Fick inte plats", "Valfritt föremål. Dess tangent använder det som en snabbfältstangent.", "Inget ledigt utrymme i inventariet", "Kräver smyckesmodden CDEV.ExtJewelry.",
				"V-klick: attack", "H-klick: blockera", "attack", "blockera", "Lås ruta"
			},
			["Norwegian"] = new string[25]
			{
				"Utstyr", "Hurtigplasser", "Kogger", "Fikk ikke plass", "Hjelm", "Bryst", "Bein", "Kappe", "Belte", "Pyntegjenstand",
				"Ring", "Ørering", "Amulett", "Ammunisjon", "Hurtigplass", "Kogger: piler", "Fikk ikke plass", "Hvilken som helst gjenstand. Tasten bruker den som en hurtiglinjetast.", "Ingen ledig plass i inventaret", "Krever smykkemodden CDEV.ExtJewelry.",
				"V-klikk: angrep", "H-klikk: blokker", "angrep", "blokker", "Lås rute"
			},
			["Danish"] = new string[25]
			{
				"Udstyr", "Hurtigpladser", "Kogger", "Var der ikke plads til", "Hjelm", "Bryst", "Ben", "Kappe", "Bælte", "Pyntegenstand",
				"Ring", "Ørering", "Amulet", "Ammunition", "Hurtigplads", "Kogger: pile", "Var der ikke plads til", "Enhver genstand. Tasten bruger den som en hurtigbjælketast.", "Ingen ledig plads i inventaret", "Kræver smykke-moddet CDEV.ExtJewelry.",
				"V-klik: angreb", "H-klik: bloker", "angreb", "bloker", "Lås felt"
			},
			["Finnish"] = new string[25]
			{
				"Varusteet", "Pikapaikat", "Viini", "Ei mahtunut", "Kypärä", "Rinta", "Jalat", "Viitta", "Vyö", "Koriste",
				"Sormus", "Korvakoru", "Amuletti", "Ammukset", "Pikapaikka", "Viini: nuolet", "Ei mahtunut", "Mikä tahansa esine. Sen näppäin käyttää sitä kuin pikapalkin näppäin.", "Tavaraluettelossa ei ole tilaa", "Vaatii korumodin CDEV.ExtJewelry.",
				"Vasen: hyökkäys", "Oikea: torjunta", "hyökkäys", "torjunta", "Lukitse ruutu"
			},
			["Turkish"] = new string[25]
			{
				"Teçhizat", "Hızlı yuvalar", "Sadak", "Sığmadı", "Miğfer", "Göğüs", "Bacaklar", "Pelerin", "Kemer", "Süs eşyası",
				"Yüzük", "Küpe", "Muska", "Mühimmat", "Hızlı yuva", "Sadak: oklar", "Sığmadı", "Herhangi bir eşya. Tuşu onu hızlı çubuk tuşu gibi kullanır.", "Envanterde boş yer yok", "CDEV.ExtJewelry takı modu gerekli.",
				"Sol tık: saldırı", "Sağ tık: blok", "saldırı", "blok", "Hücreyi kilitle"
			},
			["Chinese"] = new string[25]
			{
				"装备", "快捷栏位", "箭袋", "放不下的物品", "头盔", "胸甲", "腿甲", "披风", "腰带", "饰品",
				"戒指", "耳环", "护身符", "弹药", "快捷栏位", "箭袋:箭矢", "放不下的物品", "任意物品。按下此栏位的按键即可使用,与快捷栏按键相同。", "背包没有空位", "需要首饰模组 CDEV.ExtJewelry。",
				"左键 攻击", "右键 格挡", "攻击", "格挡", "锁定格子"
			},
			["Chinese_Trad"] = new string[25]
			{
				"裝備", "快捷欄位", "箭袋", "放不下的物品", "頭盔", "胸甲", "腿甲", "披風", "腰帶", "飾品",
				"戒指", "耳環", "護身符", "彈藥", "快捷欄位", "箭袋:箭矢", "放不下的物品", "任意物品。按下此欄位的按鍵即可使用,與快捷列按鍵相同。", "背包沒有空位", "需要首飾模組 CDEV.ExtJewelry。",
				"左鍵 攻擊", "右鍵 格擋", "攻擊", "格擋", "鎖定格子"
			},
			["Japanese"] = new string[25]
			{
				"装備", "クイックスロット", "矢筒", "入りきらなかった物", "兜", "胴", "脚", "マント", "ベルト", "装飾品",
				"指輪", "イヤリング", "アミュレット", "弾薬", "クイックスロット", "矢筒:矢", "入りきらなかった物", "任意のアイテム。スロットのキーでホットバーのキーと同じように使えます。", "インベントリに空きがありません", "装飾品MOD「CDEV.ExtJewelry」が必要です。",
				"左クリック 攻撃", "右クリック ブロック", "攻撃", "ブロック", "枠をロック"
			},
			["Korean"] = new string[25]
			{
				"장비", "빠른 슬롯", "화살통", "들어가지 않은 물건", "투구", "흉갑", "다리", "망토", "허리띠", "장신구",
				"반지", "귀걸이", "부적", "탄약", "빠른 슬롯", "화살통: 화살", "들어가지 않은 물건", "아무 아이템. 슬롯 키로 단축키처럼 사용합니다.", "인벤토리에 빈 공간이 없습니다", "장신구 모드 CDEV.ExtJewelry가 필요합니다.",
				"좌클릭 공격", "우클릭 방어", "공격", "방어", "칸 잠그기"
			}
		};

		internal static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			foreach (KeyValuePair<string, string[]> language in Languages)
			{
				if (language.Value.Length != Keys.Length)
				{
					Plugin.Log.LogError((object)$"Translation '{language.Key}' has {language.Value.Length} texts, expected {Keys.Length}; skipped.");
					continue;
				}
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				for (int i = 0; i < Keys.Length; i++)
				{
					dictionary[Keys[i]] = language.Value[i];
				}
				string key = language.Key;
				localization.AddTranslation(ref key, dictionary);
			}
		}
	}
	internal static class CellLocks
	{
		private const string ChildName = "CDEV_Lock";

		private const float Size = 15f;

		private const float Margin = 3f;

		private static readonly Color Open = new Color(1f, 1f, 1f, 0.16f);

		private static readonly Color Shut = new Color(1f, 0.82f, 0.45f, 1f);

		private static Sprite s_icon;

		internal static void Refresh(InventoryGrid grid, Player player)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			bool value = ModConfig.CellLockIcons.Value;
			for (int i = 0; i < grid.m_elements.Count; i++)
			{
				InventoryElement val = grid.m_elements[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Transform val2 = ((Component)val).transform.Find("CDEV_Lock");
				if (!value)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						((Component)val2).gameObject.SetActive(false);
					}
					continue;
				}
				Image val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<Image>() : Create(val));
				if (!((Object)(object)val3 == (Object)null))
				{
					if (!((Component)val3).gameObject.activeSelf)
					{
						((Component)val3).gameObject.SetActive(true);
					}
					Color val4 = (Locks.IsLocked(val.Position) ? Shut : Open);
					if (((Graphic)val3).color != val4)
					{
						((Graphic)val3).color = val4;
					}
				}
			}
		}

		private static Image Create(InventoryElement element)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			Sprite val = Icon();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = new GameObject("CDEV_Lock", new Type[1] { typeof(RectTransform) });
			RectTransform val3 = (RectTransform)val2.transform;
			((Transform)val3).SetParent(((Component)element).transform, false);
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(0f, 1f);
			val3.pivot = val4;
			Vector2 anchorMin = (val3.anchorMax = val4);
			val3.anchorMin = anchorMin;
			val3.sizeDelta = new Vector2(15f, 15f);
			val3.anchoredPosition = new Vector2(3f, -3f);
			((Transform)val3).SetAsLastSibling();
			Image val6 = val2.AddComponent<Image>();
			val6.sprite = val;
			val6.preserveAspect = true;
			((Graphic)val6).raycastTarget = true;
			AddTooltip(val2, element);
			Button val7 = val2.AddComponent<Button>();
			((Selectable)val7).targetGraphic = (Graphic)(object)val6;
			((Selectable)val7).transition = (Transition)0;
			InventoryElement cell = element;
			((UnityEvent)val7.onClick).AddListener((UnityAction)delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				Locks.Toggle(cell.Position);
			});
			return val6;
		}

		private static void AddTooltip(GameObject go, InventoryElement element)
		{
			UITooltip tooltip = element.m_tooltip;
			if (!((Object)(object)tooltip == (Object)null) && !((Object)(object)tooltip.m_tooltipPrefab == (Object)null))
			{
				UITooltip val = go.AddComponent<UITooltip>();
				val.m_tooltipPrefab = tooltip.m_tooltipPrefab;
				val.m_anchor = tooltip.m_anchor;
				val.m_topic = Localization.instance.Localize("$cdev_es_lock");
				val.m_text = "";
			}
		}

		private static Sprite Icon()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s_icon != (Object)null)
			{
				return s_icon;
			}
			try
			{
				Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
				{
					filterMode = (FilterMode)1
				};
				Color32[] array = (Color32[])(object)new Color32[4096];
				for (int i = 0; i < 64; i++)
				{
					for (int j = 0; j < 64; j++)
					{
						int num = 0;
						for (int k = 0; k < 4; k++)
						{
							for (int l = 0; l < 4; l++)
							{
								if (Inside(j * 4 + l, i * 4 + k, 256))
								{
									num++;
								}
							}
						}
						byte b = (byte)(255 * num / 16);
						array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
					}
				}
				val.SetPixels32(array);
				val.Apply();
				s_icon = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
				((Object)s_icon).name = "CDEV_LockIcon";
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Could not draw the lock icon: " + ex));
			}
			return s_icon;
		}

		private static bool Inside(int px, int py, int big)
		{
			float num = (float)px / (float)big;
			float num2 = (float)py / (float)big;
			bool flag = RoundedBox(num, num2, 0.16f, 0.84f, 0.06f, 0.58f, 0.09f);
			float num3 = num - 0.5f;
			float num4 = num2 - 0.58f;
			float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4);
			bool flag2 = num4 >= 0f && num5 <= 0.3f && num5 >= 0.185f;
			bool flag3 = num2 >= 0.46f && num2 <= 0.6f && Mathf.Abs(num3) >= 0.185f && Mathf.Abs(num3) <= 0.3f;
			if (!flag && !flag2 && !flag3)
			{
				return false;
			}
			float num6 = num - 0.5f;
			float num7 = num2 - 0.38f;
			bool flag4 = Mathf.Sqrt(num6 * num6 + num7 * num7) <= 0.075f;
			bool flag5 = num2 >= 0.19f && num2 <= 0.38f && Mathf.Abs(num6) <= 0.032f;
			if (!flag4)
			{
				return !flag5;
			}
			return false;
		}

		private static bool RoundedBox(float u, float v, float left, float right, float bottom, float top, float radius)
		{
			if (u < left || u > right || v < bottom || v > top)
			{
				return false;
			}
			float num = Mathf.Max(left + radius - u, u - (right - radius));
			float num2 = Mathf.Max(bottom + radius - v, v - (top - radius));
			if (num <= 0f || num2 <= 0f)
			{
				return true;
			}
			return num * num + num2 * num2 <= radius * radius;
		}
	}
	internal static class EquipProgress
	{
		private const string ChildName = "CDEV_EquipProgress";

		private static readonly Color RingColor = new Color(1f, 1f, 1f, 1f);

		private static readonly Color TrackColor = new Color(0f, 0f, 0f, 0.75f);

		private static readonly Color ShadeColor = new Color(0f, 0f, 0f, 0.6f);

		private static Sprite s_ring;

		private static readonly Dictionary<InventoryGrid, List<Image>> Shown = new Dictionary<InventoryGrid, List<Image>>();

		private static readonly List<Image> Still = new List<Image>();

		private static Sprite s_outline;

		internal static void Draw(InventoryGrid grid, Player player)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			if ((Object)(object)player == (Object)null || grid.m_inventory != ((Humanoid)player).m_inventory)
			{
				return;
			}
			Shown.TryGetValue(grid, out var value);
			Still.Clear();
			List<MinorActionData> actionQueue = player.m_actionQueue;
			for (int i = 0; i < actionQueue.Count; i++)
			{
				MinorActionData val = actionQueue[i];
				if (val.m_item == null || ((int)val.m_type != 0 && (int)val.m_type != 1))
				{
					continue;
				}
				InventoryElement val2 = ElementAt(grid, val.m_item.m_gridPos);
				if (!((Object)(object)val2 == (Object)null))
				{
					float num = ((i == 0 && val.m_duration > 0f) ? Mathf.Clamp01(val.m_time / val.m_duration) : 0f);
					Image val3 = RingOf(val2);
					val3.fillAmount = num;
					Image component = ((Component)((Component)val3).transform.parent.parent).GetComponent<Image>();
					component.fillAmount = 1f - num;
					GameObject gameObject = ((Component)((Component)val3).transform.parent.parent).gameObject;
					if (!gameObject.activeSelf)
					{
						gameObject.SetActive(true);
					}
					Still.Add(val3);
				}
			}
			if (value != null)
			{
				foreach (Image item in value)
				{
					if ((Object)(object)item != (Object)null && !Still.Contains(item))
					{
						((Component)((Component)item).transform.parent.parent).gameObject.SetActive(false);
					}
				}
				value.Clear();
				value.AddRange(Still);
			}
			else if (Still.Count > 0)
			{
				Shown[grid] = new List<Image>(Still);
			}
			Still.Clear();
		}

		private static InventoryElement ElementAt(InventoryGrid grid, Vector2i pos)
		{
			//IL_0021: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			List<InventoryElement> elements = grid.m_elements;
			for (int i = 0; i < elements.Count; i++)
			{
				if ((Object)(object)elements[i] != (Object)null && elements[i].Position.x == pos.x && elements[i].Position.y == pos.y)
				{
					return elements[i];
				}
			}
			return null;
		}

		private static Image RingOf(InventoryElement element)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			//IL_011c: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01c1: 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)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)element).transform.Find("CDEV_EquipProgress");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val.GetChild(0).GetChild(0)).GetComponent<Image>();
			}
			GameObject val2 = new GameObject("CDEV_EquipProgress", new Type[1] { typeof(RectTransform) });
			RectTransform val3 = (RectTransform)val2.transform;
			((Transform)val3).SetParent(((Component)element).transform, false);
			val3.anchorMin = Vector2.zero;
			val3.anchorMax = Vector2.one;
			val3.offsetMin = new Vector2(2f, 2f);
			val3.offsetMax = new Vector2(-2f, -2f);
			Image val4 = val2.AddComponent<Image>();
			((Graphic)val4).color = ShadeColor;
			((Graphic)val4).raycastTarget = false;
			val4.type = (Type)3;
			val4.fillMethod = (FillMethod)4;
			val4.fillOrigin = 2;
			val4.fillClockwise = false;
			val4.fillAmount = 1f;
			GameObject val5 = new GameObject("Track", new Type[1] { typeof(RectTransform) });
			RectTransform val6 = (RectTransform)val5.transform;
			((Transform)val6).SetParent((Transform)(object)val3, false);
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = new Vector2(3f, 3f);
			val6.offsetMax = new Vector2(-3f, -3f);
			Image val7 = val5.AddComponent<Image>();
			val7.sprite = Ring(outline: true);
			((Graphic)val7).color = TrackColor;
			((Graphic)val7).raycastTarget = false;
			GameObject val8 = new GameObject("Fill", new Type[1] { typeof(RectTransform) });
			RectTransform val9 = (RectTransform)val8.transform;
			((Transform)val9).SetParent((Transform)(object)val6, false);
			val9.anchorMin = Vector2.zero;
			val9.anchorMax = Vector2.one;
			val9.offsetMin = Vector2.zero;
			val9.offsetMax = Vector2.zero;
			Image val10 = val8.AddComponent<Image>();
			val10.sprite = Ring(outline: false);
			((Graphic)val10).color = RingColor;
			((Graphic)val10).raycastTarget = false;
			val10.type = (Type)3;
			val10.fillMethod = (FillMethod)4;
			val10.fillOrigin = 2;
			val10.fillClockwise = true;
			val10.fillAmount = 0f;
			val2.transform.SetAsLastSibling();
			return val10;
		}

		private static Sprite Ring(bool outline)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			ref Sprite reference = ref outline ? ref s_outline : ref s_ring;
			if ((Object)(object)reference != (Object)null)
			{
				return reference;
			}
			float num = (outline ? 63f : 59f);
			float num2 = (outline ? 22f : 14f);
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				name = "CDEV_EquipProgressRing",
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[16384];
			float num3 = 63.5f;
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num4 = Mathf.Sqrt(((float)j - num3) * ((float)j - num3) + ((float)i - num3) * ((float)i - num3));
					float num5 = Mathf.Min(num - num4, num4 - (num - num2));
					byte b = (byte)(Mathf.Clamp01(num5 + 0.5f) * 255f);
					array[i * 128 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
				}
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			reference = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f);
			((Object)reference).name = ((Object)val).name;
			return reference;
		}
	}
	internal static class Placeholders
	{
		internal static readonly Color Tint = new Color(0.55f, 0.55f, 0.55f, 0.3f);

		private static readonly Dictionary<SlotKind, Sprite> Cache = new Dictionary<SlotKind, Sprite>();

		private static ObjectDB s_cachedFor;

		internal static Sprite Get(SlotKind kind)
		{
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			if ((Object)(object)s_cachedFor != (Object)(object)instance)
			{
				Cache.Clear();
				s_cachedFor = instance;
			}
			if (!Cache.TryGetValue(kind, out var value))
			{
				string text = PrefabName(kind);
				GameObject val = ((text != null) ? instance.GetItemPrefab(text) : null);
				ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
				Sprite[] array = (((Object)(object)val2 != (Object)null) ? val2.m_itemData.m_shared.m_icons : null);
				value = ((array != null && array.Length != 0) ? array[0] : null);
				Cache[kind] = value;
			}
			return value;
		}

		private static string PrefabName(SlotKind kind)
		{
			switch (kind)
			{
			case SlotKind.Helmet:
				return "HelmetLeather";
			case SlotKind.Chest:
				return "ArmorLeatherChest";
			case SlotKind.Legs:
				return "ArmorLeatherLegs";
			case SlotKind.Cape:
				return "CapeDeerHide";
			case SlotKind.Belt:
				return "BeltStrength";
			case SlotKind.Trinket:
				return "TrinketBronzeHealth";
			case SlotKind.Ring:
				return "Ruby";
			case SlotKind.Earring:
				return "AmberPearl";
			case SlotKind.Amulet:
				return "SilverNecklace";
			case SlotKind.Ammo:
			case SlotKind.Quiver:
				return "ArrowWood";
			default:
				return null;
			}
		}

		internal static string NameKey(SlotKind kind)
		{
			return kind switch
			{
				SlotKind.Helmet => "$cdev_es_slot_helmet", 
				SlotKind.Chest => "$cdev_es_slot_chest", 
				SlotKind.Legs => "$cdev_es_slot_legs", 
				SlotKind.Cape => "$cdev_es_slot_cape", 
				SlotKind.Belt => "$cdev_es_slot_belt", 
				SlotKind.Trinket => "$cdev_es_slot_trinket", 
				SlotKind.Ring => "$cdev_es_slot_ring", 
				SlotKind.Earring => "$cdev_es_slot_earring", 
				SlotKind.Amulet => "$cdev_es_slot_amulet", 
				SlotKind.Ammo => "$cdev_es_slot_ammo", 
				SlotKind.Quick => "$cdev_es_slot_quick", 
				SlotKind.Quiver => "$cdev_es_slot_quiver", 
				_ => "$cdev_es_slot_stash", 
			};
		}
	}
	internal static class PlayerPreview
	{
		private static readonly Vector3 Origin = new Vector3(0f, 5000f, 0f);

		private const float FieldOfView = 26f;

		private const float ViewHeight = 2.7f;

		private const float DefaultYaw = -18f;

		private const float DragDegreesPerPixel = 0.5f;

		private static GameObject s_holder;

		private static Transform s_model;

		private static Animator s_animator;

		private static float s_blockUntil;

		private static readonly int StateF = Animator.StringToHash("statef");

		private static readonly int StateI = Animator.StringToHash("statei");

		private static readonly int Blocking = Animator.StringToHash("blocking");

		private const float BlockSeconds = 0.9f;

		private static float s_yaw = -18f;

		private static bool s_returning;

		private const float ReturnSpeed = 6f;

		private static VisEquipment s_vis;

		private static Camera s_camera;

		private static RenderTexture s_texture;

		private static Vector2 s_aspect = new Vector2(200f, 400f);

		private static int s_lastFrame = -10;

		private static bool s_failed;

		internal static void SetAspect(Vector2 size)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (size.x > 1f && size.y > 1f)
			{
				s_aspect