Decompiled source of InventoryPLUS v1.0.0

tony4twentys-InventoryPLUS.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using ExitGames.Client.Photon;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.ControllerSupport;
using Zorro.Core;
using Zorro.Core.Serizalization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyTitle("InventoryPLUS")]
[assembly: AssemblyDescription("Vanilla-like PEAK inventory upgrade with extra pockets and dedicated pack wear")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("InventoryPLUS")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1b961ca0-c097-49c4-b7f6-c69d3084e1a7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace InventoryPLUS
{
	[BepInPlugin("tony4twentys.InventoryPLUS", "InventoryPLUS", "1.0.0")]
	[BepInProcess("PEAK.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "tony4twentys.InventoryPLUS";

		public const string PluginName = "InventoryPLUS";

		public const string PluginVersion = "1.0.0";

		public const byte EventCode = 166;

		public const string EventMagic = "tony4twentys.InventoryPLUS";

		public const int ProtocolVersion = 1;

		public const int BaseSlots = 4;

		public const int BackpackBonusSlots = 4;

		public const int FannyBonusSlots = 2;

		public const int MaxSlots = 10;

		public const byte TempSlotId = 250;

		private Harmony _harmony;

		private Coroutine _hudRoutine;

		private static bool _loggedHotException;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		internal static bool Enabled => InventoryNet.FeaturesEnabled;

		private void Awake()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			InventoryConfig.Bind((BaseUnityPlugin)(object)this);
			_harmony = new Harmony("tony4twentys.InventoryPLUS");
			Type[] types = typeof(Plugin).Assembly.GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				try
				{
					_harmony.CreateClassProcessor(types[i]).Patch();
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Failed to patch " + types[i].Name + ": " + ex.Message));
				}
			}
			InventoryNet.Ensure();
			Log.LogInfo((object)("InventoryPLUS v1.0.0 loaded. 4 pockets, backpack +4, fanny +2, rebindable slot keys 1-0, pack cycle, event " + (byte)166 + "."));
		}

		internal static void NotifyEnabledChanged()
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				InventoryHud.ResetForScene();
				Instance.RestartHud();
			}
		}

		private void OnEnable()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDisable()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void Start()
		{
			RestartHud();
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			RestartHud();
		}

		private void RestartHud()
		{
			if (_hudRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_hudRoutine);
			}
			InventoryHud.ResetForScene();
			_hudRoutine = ((MonoBehaviour)this).StartCoroutine(InventoryHud.Bootstrap());
		}

		internal static void LogHotException(string where, Exception ex)
		{
			if (!_loggedHotException && Log != null)
			{
				_loggedHotException = true;
				Log.LogError((object)(where + " failed (further errors suppressed): " + ex));
			}
		}
	}
	internal static class InventoryConfig
	{
		private static readonly KeyCode[] DefaultExtraKeys;

		private static readonly string[] ExtraLabels;

		internal static ConfigEntry<KeyCode>[] ExtraSlotKeys;

		internal static ConfigEntry<KeyCode> PackCycle;

		internal static KeyCode PackCycleKey => (KeyCode)((PackCycle == null) ? 98 : ((int)PackCycle.Value));

		internal static void Bind(BaseUnityPlugin plugin)
		{
			ExtraSlotKeys = new ConfigEntry<KeyCode>[DefaultExtraKeys.Length];
			for (int i = 0; i < DefaultExtraKeys.Length; i++)
			{
				ExtraSlotKeys[i] = plugin.Config.Bind<KeyCode>("Keybinds", "Slot" + ExtraLabels[i], DefaultExtraKeys[i], "Select extra inventory slot " + ExtraLabels[i] + ".");
				ExtraSlotKeys[i].SettingChanged += OnKeyChanged;
			}
			PackCycle = plugin.Config.Bind<KeyCode>("Keybinds", "PackCycle", (KeyCode)98, "Cycle worn packs into your hands, then wrap back to worn.");
			PackCycle.SettingChanged += OnKeyChanged;
		}

		internal static KeyCode SlotKey(int index)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			int num = index - 4;
			if (num < 0 || ExtraSlotKeys == null || num >= ExtraSlotKeys.Length)
			{
				return (KeyCode)((num >= 0 && num < DefaultExtraKeys.Length) ? ((int)DefaultExtraKeys[num]) : 0);
			}
			if (ExtraSlotKeys[num] == null)
			{
				return DefaultExtraKeys[num];
			}
			return ExtraSlotKeys[num].Value;
		}

		internal unsafe static string KeyboardPath(KeyCode key)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0017: 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)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Invalid comparison between Unknown and I4
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected I4, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Invalid comparison between Unknown and I4
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected I4, but got Unknown
			if ((int)key >= 48 && (int)key <= 57)
			{
				return ((char)(48 + (key - 48))).ToString();
			}
			if ((int)key >= 97 && (int)key <= 122)
			{
				return ((char)(97 + (key - 97))).ToString();
			}
			if ((int)key >= 282 && (int)key <= 296)
			{
				return "f" + (1 + (key - 282));
			}
			if ((int)key >= 256 && (int)key <= 265)
			{
				return "numpad" + (key - 256);
			}
			return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString().ToLowerInvariant();
		}

		private static void OnKeyChanged(object sender, EventArgs args)
		{
			InventoryHud.ForceRelayout();
		}

		static InventoryConfig()
		{
			KeyCode[] array = new KeyCode[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			DefaultExtraKeys = (KeyCode[])(object)array;
			ExtraLabels = new string[6] { "5", "6", "7", "8", "9", "0" };
		}
	}
	internal static class PlayerInventory
	{
		internal static void EnsureBaseSlots(Player player)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			if (player.itemSlots != null && player.itemSlots.Length >= 4)
			{
				for (byte b = 0; b < 4; b++)
				{
					if (player.itemSlots[b] == null)
					{
						player.itemSlots[b] = new ItemSlot(b, player);
					}
					else
					{
						player.itemSlots[b].itemSlotID = b;
					}
				}
				return;
			}
			ItemSlot[] array = (ItemSlot[])(object)new ItemSlot[4];
			int num = ((player.itemSlots != null) ? player.itemSlots.Length : 0);
			for (byte b2 = 0; b2 < 4; b2++)
			{
				if (b2 < num && player.itemSlots[b2] != null)
				{
					array[b2] = player.itemSlots[b2];
					array[b2].itemSlotID = b2;
				}
				else
				{
					array[b2] = new ItemSlot(b2, player);
				}
			}
			player.itemSlots = array;
		}

		internal static int UnlockedCount(Player player)
		{
			int num = 4;
			Character character = (((Object)(object)player != (Object)null) ? player.character : null);
			if (PackWear.HasBackpack(character))
			{
				num += 4;
			}
			if (PackWear.HasFanny(character))
			{
				num += 2;
			}
			if (num > 10)
			{
				num = 10;
			}
			return num;
		}

		internal static bool IsUnlocked(Player player, int slotId)
		{
			if (slotId < 0 || slotId >= 10)
			{
				return false;
			}
			if (slotId < 4)
			{
				return true;
			}
			Character character = (((Object)(object)player != (Object)null) ? player.character : null);
			if (slotId < 8)
			{
				return PackWear.HasBackpack(character);
			}
			return PackWear.HasFanny(character);
		}

		internal static bool IsHotbarVisible(Player player, int slotId)
		{
			if (slotId < 0 || slotId >= 10)
			{
				return false;
			}
			if (slotId < 4)
			{
				return true;
			}
			Character character = (((Object)(object)player != (Object)null) ? player.character : null);
			if (slotId < 8)
			{
				return PackWear.GrantsSlots(character, PackKind.Backpack);
			}
			return PackWear.GrantsSlots(character, PackKind.Fanny);
		}

		internal static int CollectUnlocked(Player player, int[] buffer)
		{
			int num = 0;
			if (buffer == null)
			{
				return 0;
			}
			for (int i = 0; i < 10; i++)
			{
				if (num >= buffer.Length)
				{
					break;
				}
				if (IsHotbarVisible(player, i))
				{
					buffer[num++] = i;
				}
			}
			return num;
		}

		internal static ItemSlot GetSlot(Player player, byte slotId)
		{
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			if (slotId == 250)
			{
				return player.tempFullSlot;
			}
			EnsureBaseSlots(player);
			if (slotId < 4)
			{
				return player.itemSlots[slotId];
			}
			Character character = player.character;
			if (slotId < 8)
			{
				if (!PackWear.HasBackpack(character))
				{
					return null;
				}
				return PackWear.GetBackpackSlot(character, slotId - 4);
			}
			if (slotId < 10)
			{
				if (!PackWear.HasFanny(character))
				{
					return null;
				}
				return PackWear.GetFannySlot(character, slotId - 8);
			}
			return null;
		}

		internal static bool TryFillFirstEmpty(Player player, Item prefab, ItemInstanceData data, out ItemSlot slot)
		{
			slot = null;
			if ((Object)(object)player == (Object)null || (Object)(object)prefab == (Object)null)
			{
				return false;
			}
			EnsureBaseSlots(player);
			for (int i = 0; i < 10; i++)
			{
				if (IsHotbarVisible(player, i))
				{
					ItemSlot slot2 = GetSlot(player, (byte)i);
					if (slot2 != null && slot2.IsEmpty())
					{
						slot2.SetItem(prefab, data);
						slot = slot2;
						return true;
					}
				}
			}
			return false;
		}

		internal static bool HasEmptyItemSlot(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			for (int i = 0; i < 10; i++)
			{
				if (IsHotbarVisible(player, i))
				{
					ItemSlot slot = GetSlot(player, (byte)i);
					if (slot != null && slot.IsEmpty())
					{
						return true;
					}
				}
			}
			return player.tempFullSlot != null && player.tempFullSlot.IsEmpty();
		}

		internal static void ApplySync(Player player, InventorySyncData sync)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || sync.slots == null)
			{
				return;
			}
			EnsureBaseSlots(player);
			int num = player.itemSlots.Length;
			if (sync.slots.Length < num)
			{
				num = sync.slots.Length;
			}
			for (int i = 0; i < num; i++)
			{
				Item prefab = null;
				if (sync.slots[i].ItemID != ushort.MaxValue)
				{
					ItemDatabase.TryGetItem(sync.slots[i].ItemID, ref prefab);
				}
				player.itemSlots[i].prefab = prefab;
				player.itemSlots[i].data = sync.slots[i].Data;
			}
			for (int j = num; j < player.itemSlots.Length; j++)
			{
				if (player.itemSlots[j] != null)
				{
					player.itemSlots[j].EmptyOut();
				}
			}
			if (player.backpackSlot != null)
			{
				player.backpackSlot.backpackType = (BackpackType)sync.backpackType;
				((ItemSlot)player.backpackSlot).data = sync.backpackInstanceData;
				Item val = null;
				if (sync.backpackSlot.ItemID != 0 && sync.backpackSlot.ItemID != ushort.MaxValue)
				{
					ItemDatabase.TryGetItem(sync.backpackSlot.ItemID, ref val);
				}
				if ((Object)(object)val != (Object)null)
				{
					((ItemSlot)player.backpackSlot).prefab = val;
				}
				else if (sync.backpackType == 0)
				{
					((ItemSlot)player.backpackSlot).EmptyOut();
				}
			}
			if (player.tempFullSlot != null)
			{
				Item prefab2 = null;
				if (sync.tempSlot.ItemID != ushort.MaxValue)
				{
					ItemDatabase.TryGetItem(sync.tempSlot.ItemID, ref prefab2);
				}
				player.tempFullSlot.prefab = prefab2;
				player.tempFullSlot.data = sync.tempSlot.Data;
			}
			PackWear.EnsureStorageIds(player.character);
			if ((Object)(object)player.view != (Object)null && player.view.IsMine && (Object)(object)player.character != (Object)null && player.character.refs != null && (Object)(object)player.character.refs.items != (Object)null)
			{
				player.character.refs.items.RefreshAllCharacterCarryWeightRPC();
			}
		}

		internal static void BroadcastVanilla(Player player)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player.view == (Object)null) && (player.view.IsMine || PhotonNetwork.IsMasterClient))
			{
				EnsureBaseSlots(player);
				byte[] array = IBinarySerializable.ToManagedArray<InventorySyncData>(new InventorySyncData(player.itemSlots, player.backpackSlot, player.tempFullSlot));
				player.view.RPC("SyncInventoryRPC", (RpcTarget)1, new object[2] { array, false });
			}
		}

		internal static void NotifyChanged(Player player)
		{
			if (!((Object)(object)player == (Object)null))
			{
				if (player.itemsChangedAction != null)
				{
					player.itemsChangedAction(player.itemSlots);
				}
				Character character = player.character;
				if ((Object)(object)character != (Object)null && character.refs != null && (Object)(object)character.refs.afflictions != (Object)null)
				{
					character.refs.afflictions.UpdateWeight();
				}
			}
		}

		internal static void SyncAll(Player player)
		{
			try
			{
				BroadcastVanilla(player);
			}
			catch (Exception ex)
			{
				Plugin.LogHotException("PlayerInventory.BroadcastVanilla", ex);
			}
			try
			{
				InventoryNet.Broadcast(((Object)(object)player != (Object)null) ? player.character : null);
			}
			catch (Exception ex2)
			{
				Plugin.LogHotException("PlayerInventory.BroadcastNet", ex2);
			}
			try
			{
				NotifyChanged(player);
			}
			catch (Exception ex3)
			{
				Plugin.LogHotException("PlayerInventory.NotifyChanged", ex3);
			}
			InventoryHud.MarkDirty();
		}

		internal static int ExtraWeight(Character character)
		{
			return PackWear.ExtraContentsWeight(character);
		}

		internal static void UnequipIfPackSlotSelected(Character character)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.items == (Object)null || (Object)(object)character.player == (Object)null)
			{
				return;
			}
			CharacterItems items = character.refs.items;
			if (items.currentSelectedSlot.IsSome)
			{
				byte value = items.currentSelectedSlot.Value;
				if (value >= 4 && value != 250 && !IsUnlocked(character.player, value))
				{
					items.EquipSlot(Optionable<byte>.None);
				}
			}
		}
	}
	internal enum PackKind
	{
		None,
		Backpack,
		Fanny,
		Flight
	}
	internal struct WornPack
	{
		public ushort ItemId;

		public ItemInstanceData Data;

		public BackpackType Type;
	}
	internal sealed class PackLoadout
	{
		public WornPack Backpack;

		public WornPack Fanny;
	}
	internal static class PackWear
	{
		private static readonly Dictionary<int, PackLoadout> ExtraByActor = new Dictionary<int, PackLoadout>();

		private static readonly Dictionary<int, PackKind> HeldByActor = new Dictionary<int, PackKind>();

		internal static PackKind SelectedPack;

		internal static bool SuppressNextPickupEquip;

		private static bool _droppingWorn;

		internal static bool IsFlight(BackpackType type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			return (int)type == 3 || (int)type == 4;
		}

		internal static PackKind KindOf(BackpackType type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if ((int)type == 1)
			{
				return PackKind.Backpack;
			}
			if ((int)type == 2)
			{
				return PackKind.Fanny;
			}
			if (IsFlight(type))
			{
				return PackKind.Flight;
			}
			return PackKind.None;
		}

		internal static PackKind KindOf(Item item)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Backpack val = (Backpack)(object)((item is Backpack) ? item : null);
			return ((Object)(object)val != (Object)null) ? KindOf(val.backpackType) : PackKind.None;
		}

		internal static bool IsPackItem(Item item)
		{
			return item is Backpack && KindOf(item) != PackKind.None;
		}

		internal static int ActorOf(Character character)
		{
			if ((Object)(object)character == (Object)null || (Object)(object)((MonoBehaviourPun)character).photonView == (Object)null || ((MonoBehaviourPun)character).photonView.Owner == null)
			{
				return -1;
			}
			return ((MonoBehaviourPun)character).photonView.Owner.ActorNumber;
		}

		internal static PackLoadout GetLoadout(Character character, bool create)
		{
			int num = ActorOf(character);
			if (num < 0)
			{
				return null;
			}
			if (ExtraByActor.TryGetValue(num, out var value))
			{
				return value;
			}
			if (!create)
			{
				return null;
			}
			value = new PackLoadout();
			ExtraByActor[num] = value;
			return value;
		}

		internal static void SetLoadout(int actor, WornPack backpack, WornPack fanny)
		{
			if (actor >= 0)
			{
				if (!Has(backpack) && !Has(fanny))
				{
					ExtraByActor.Remove(actor);
					return;
				}
				PackLoadout packLoadout = new PackLoadout();
				packLoadout.Backpack = backpack;
				packLoadout.Fanny = fanny;
				ExtraByActor[actor] = packLoadout;
				InventoryHud.MarkDirty();
			}
		}

		internal static void ClearActor(int actor)
		{
			ExtraByActor.Remove(actor);
			HeldByActor.Remove(actor);
		}

		internal static void SetHeld(int actor, PackKind kind)
		{
			if (actor >= 0)
			{
				if (kind == PackKind.None)
				{
					HeldByActor.Remove(actor);
				}
				else
				{
					HeldByActor[actor] = kind;
				}
			}
		}

		internal static PackKind GetHeld(Character character)
		{
			if ((Object)(object)character != (Object)null && character.IsLocal)
			{
				return SelectedPack;
			}
			int num = ActorOf(character);
			if (num >= 0 && HeldByActor.TryGetValue(num, out var value))
			{
				return value;
			}
			return PackKind.None;
		}

		internal static bool Has(WornPack pack)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			if (pack.Data == null)
			{
				return false;
			}
			if (pack.ItemId != 0)
			{
				return true;
			}
			return (int)pack.Type == 1 || (int)pack.Type == 2;
		}

		internal static bool HasBackpack(Character character)
		{
			return SlotKind(character) == PackKind.Backpack || HasExtra(character, PackKind.Backpack);
		}

		internal static bool HasFanny(Character character)
		{
			return SlotKind(character) == PackKind.Fanny || HasExtra(character, PackKind.Fanny);
		}

		internal static bool HasFlight(Character character)
		{
			return SlotKind(character) == PackKind.Flight;
		}

		internal static bool IsHeldOffBody(Character character, PackKind kind)
		{
			return kind != PackKind.None && GetHeld(character) == kind;
		}

		internal static bool GrantsSlots(Character character, PackKind kind)
		{
			if (IsHeldOffBody(character, kind))
			{
				return false;
			}
			return kind switch
			{
				PackKind.Backpack => HasBackpack(character), 
				PackKind.Fanny => HasFanny(character), 
				_ => false, 
			};
		}

		internal static PackKind SlotKind(Character character)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || (Object)(object)character.player == (Object)null || character.player.backpackSlot == null)
			{
				return PackKind.None;
			}
			BackpackSlot backpackSlot = character.player.backpackSlot;
			PackKind packKind = KindOf(backpackSlot.backpackType);
			if (packKind != PackKind.None)
			{
				return packKind;
			}
			if (((ItemSlot)backpackSlot).IsEmpty())
			{
				return PackKind.None;
			}
			return KindOf(((ItemSlot)backpackSlot).prefab);
		}

		internal static bool HasExtra(Character character, PackKind kind)
		{
			PackLoadout loadout = GetLoadout(character, create: false);
			if (loadout == null)
			{
				return false;
			}
			return kind switch
			{
				PackKind.Backpack => Has(loadout.Backpack), 
				PackKind.Fanny => Has(loadout.Fanny), 
				_ => false, 
			};
		}

		internal static bool CanWear(Player player, Item prefab)
		{
			PackKind packKind = KindOf(prefab);
			if (packKind == PackKind.None || (Object)(object)player == (Object)null)
			{
				return false;
			}
			Character character = player.character;
			return packKind switch
			{
				PackKind.Backpack => !HasBackpack(character), 
				PackKind.Fanny => !HasFanny(character), 
				_ => !HasFlight(character), 
			};
		}

		internal static bool TryWear(Player player, Item prefab, ItemInstanceData data, out ItemSlot slot)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_00a9: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			slot = null;
			if ((Object)(object)player == (Object)null || player.backpackSlot == null || !CanWear(player, prefab))
			{
				return false;
			}
			Backpack val = (Backpack)(object)((prefab is Backpack) ? prefab : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (data == null)
			{
				data = new ItemInstanceData(Guid.NewGuid());
				ItemInstanceDataHandler.AddInstanceData(data);
			}
			EnsureEntry(data);
			Character character = player.character;
			PackKind packKind = KindOf(val.backpackType);
			PackKind packKind2 = SlotKind(character);
			BackpackSlot backpackSlot = player.backpackSlot;
			switch (packKind)
			{
			case PackKind.Flight:
				ParkSlot(character);
				backpackSlot.backpackType = val.backpackType;
				((ItemSlot)backpackSlot).SetItem(prefab, data);
				break;
			case PackKind.Backpack:
				if (packKind2 == PackKind.None || packKind2 == PackKind.Fanny)
				{
					if (packKind2 == PackKind.Fanny)
					{
						ParkSlot(character);
					}
					backpackSlot.backpackType = (BackpackType)1;
					((ItemSlot)backpackSlot).SetItem(prefab, data);
				}
				else
				{
					SetExtra(character, PackKind.Backpack, prefab.itemID, data, val.backpackType);
				}
				break;
			default:
				if (packKind2 == PackKind.None)
				{
					backpackSlot.backpackType = (BackpackType)2;
					((ItemSlot)backpackSlot).SetItem(prefab, data);
				}
				else
				{
					SetExtra(character, PackKind.Fanny, prefab.itemID, data, val.backpackType);
				}
				break;
			}
			EnsureStorageIds(character);
			slot = (ItemSlot)(object)backpackSlot;
			SuppressNextPickupEquip = true;
			if (packKind == PackKind.Flight)
			{
				ContinueRocketFuse(character, prefab);
			}
			InventoryHud.MarkDirty();
			Plugin.Log.LogInfo((object)("Wore " + packKind.ToString() + "; hotbar slots now " + PlayerInventory.UnlockedCount(player) + "."));
			return true;
		}

		internal static ItemSlot GetBackpackSlot(Character character, int index)
		{
			if (!TryGetStorage(character, PackKind.Backpack, out var data, out var count))
			{
				return null;
			}
			if (index < 0 || index >= count || data.itemSlots == null)
			{
				return null;
			}
			return data.itemSlots[index];
		}

		internal static ItemSlot GetFannySlot(Character character, int index)
		{
			if (!TryGetStorage(character, PackKind.Fanny, out var data, out var count))
			{
				return null;
			}
			if (index < 0 || index >= count || data.itemSlots == null)
			{
				return null;
			}
			return data.itemSlots[index];
		}

		internal static bool TryGetStorage(Character character, PackKind kind, out BackpackData data, out int count)
		{
			data = null;
			count = ((kind == PackKind.Fanny) ? 2 : 4);
			ItemInstanceData packData = GetPackData(character, kind);
			if (packData == null)
			{
				return false;
			}
			data = EnsureEntry(packData);
			if (data == null)
			{
				return false;
			}
			EnsureSlots(data, kind);
			if (data.itemSlots != null && data.itemSlots.Length < count)
			{
				count = data.itemSlots.Length;
			}
			return true;
		}

		internal static ItemInstanceData GetPackData(Character character, PackKind kind)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			if (SlotKind(character) == kind && (Object)(object)character.player != (Object)null && character.player.backpackSlot != null)
			{
				if (((ItemSlot)character.player.backpackSlot).data == null)
				{
					((ItemSlot)character.player.backpackSlot).data = new ItemInstanceData(Guid.NewGuid());
					ItemInstanceDataHandler.AddInstanceData(((ItemSlot)character.player.backpackSlot).data);
				}
				return ((ItemSlot)character.player.backpackSlot).data;
			}
			PackLoadout loadout = GetLoadout(character, create: false);
			if (loadout == null)
			{
				return null;
			}
			if (kind == PackKind.Backpack && Has(loadout.Backpack))
			{
				return loadout.Backpack.Data;
			}
			if (kind == PackKind.Fanny && Has(loadout.Fanny))
			{
				return loadout.Fanny.Data;
			}
			return null;
		}

		internal static Item GetWornPrefab(Character character, PackKind kind)
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character != (Object)null && (Object)(object)character.player != (Object)null && character.player.backpackSlot != null && SlotKind(character) == kind)
			{
				Item val = ResolvePrefab((ItemSlot)(object)character.player.backpackSlot);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			if (kind == PackKind.Flight)
			{
				return null;
			}
			PackLoadout loadout = GetLoadout(character, create: false);
			if (loadout == null)
			{
				return null;
			}
			WornPack pack = kind switch
			{
				PackKind.Fanny => loadout.Fanny, 
				PackKind.Backpack => loadout.Backpack, 
				_ => default(WornPack), 
			};
			if (!Has(pack))
			{
				return null;
			}
			Item val2 = default(Item);
			if (pack.ItemId != 0 && ItemDatabase.TryGetItem(pack.ItemId, ref val2) && (Object)(object)val2 != (Object)null)
			{
				return val2;
			}
			return FindPrefabByType(pack.Type);
		}

		private static Item ResolvePrefab(ItemSlot slot)
		{
			if (slot == null)
			{
				return null;
			}
			if ((Object)(object)slot.prefab != (Object)null)
			{
				return slot.prefab;
			}
			try
			{
				string prefabName = slot.GetPrefabName();
				Item result = default(Item);
				if (!string.IsNullOrEmpty(prefabName) && ItemDatabase.TryGetItem(prefabName, ref result))
				{
					return result;
				}
			}
			catch
			{
			}
			return null;
		}

		internal static void EnsureStorageIds(Character character)
		{
			if (TryGetStorage(character, PackKind.Backpack, out var data, out var count))
			{
				AssignIds(data, 0, count);
			}
			if (TryGetStorage(character, PackKind.Fanny, out var data2, out var count2))
			{
				AssignIds(data2, 0, count2);
			}
		}

		internal static int ExtraContentsWeight(Character character)
		{
			int num = 0;
			PackKind packKind = SlotKind(character);
			if (packKind != PackKind.Backpack)
			{
				num += StorageWeight(GetPackData(character, PackKind.Backpack));
			}
			if (packKind != PackKind.Fanny)
			{
				num += StorageWeight(GetPackData(character, PackKind.Fanny));
			}
			return num;
		}

		internal static void ContinueRocketFuse(Character character, Item source)
		{
			if ((Object)(object)character == (Object)null || (Object)(object)source == (Object)null)
			{
				return;
			}
			Rocketpack component = ((Component)source).GetComponent<Rocketpack>();
			if ((Object)(object)component == (Object)null || !component.lit || component.fired)
			{
				return;
			}
			float num = 3f;
			Backpack val = (Backpack)(object)((source is Backpack) ? source : null);
			if ((Object)(object)val == (Object)null)
			{
				val = component.backpack;
			}
			BackpackData val2 = default(BackpackData);
			if ((Object)(object)val != (Object)null && ((Item)val).data != null && ((Item)val).data.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val2) && val2 != null && val2.litRocketData > 0f)
			{
				num = val2.litRocketData;
			}
			if (num > 0f && num < 1f)
			{
				num = 1f;
			}
			ItemInstanceData packData = GetPackData(character, PackKind.Flight);
			if (packData != null)
			{
				BackpackData val3 = EnsureEntry(packData);
				if (val3 != null)
				{
					val3.LightRocket(num);
				}
			}
			CharacterBackpackHandler val4 = ((character.refs != null) ? character.refs.backpackHandler : null);
			if ((Object)(object)val4 != (Object)null)
			{
				val4.LightRocket(num);
			}
			Plugin.Log.LogInfo((object)("Continued rocket fuse (" + num.ToString("0.00") + "s left) after wearing."));
		}

		internal static int UpgradePackSelfWeight(Character character)
		{
			PackKind packKind = SlotKind(character);
			if (packKind != PackKind.Backpack && packKind != PackKind.Fanny)
			{
				return 0;
			}
			Item wornPrefab = GetWornPrefab(character, packKind);
			return ((Object)(object)wornPrefab != (Object)null) ? wornPrefab.CarryWeight : 0;
		}

		internal static void HoldWorn(Character character, PackKind kind)
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || !character.IsLocal || kind == PackKind.None || character.refs == null || (Object)(object)character.refs.items == (Object)null)
			{
				return;
			}
			Item wornPrefab = GetWornPrefab(character, kind);
			ItemInstanceData packData = GetPackData(character, kind);
			SelectedPack = kind;
			if ((Object)(object)wornPrefab == (Object)null)
			{
				Plugin.Log.LogWarning((object)("Cannot hold worn " + kind.ToString() + " (prefab missing)."));
				return;
			}
			CharacterItems items = character.refs.items;
			string text = "0_Items/" + ((Object)((Component)wornPrefab).gameObject).name;
			Transform val = (((Object)(object)character.GetBodypart((BodypartType)2) != (Object)null) ? character.GetBodypart((BodypartType)2).transform : ((Component)character).transform);
			Vector3 val2 = val.position + val.forward * 0.6f;
			GameObject val3 = PhotonNetwork.Instantiate(text, val2, Quaternion.identity, (byte)0, (object[])null);
			if ((Object)(object)val3 == (Object)null)
			{
				Plugin.Log.LogWarning((object)("Failed to spawn held " + kind.ToString() + " from " + text + "."));
				return;
			}
			PhotonView component = val3.GetComponent<PhotonView>();
			Item component2 = val3.GetComponent<Item>();
			if ((Object)(object)component != (Object)null && packData != null)
			{
				component.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { packData });
			}
			if ((Object)(object)component2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)("Spawned " + kind.ToString() + " has no Item component."));
				return;
			}
			items.currentSelectedSlot = Optionable<byte>.None;
			Item val4 = items.Equip(component2);
			if ((Object)(object)val4 != (Object)null && (Object)(object)((MonoBehaviourPun)val4).photonView != (Object)null && (((MonoBehaviourPun)val4).photonView.IsMine || PhotonNetwork.IsMasterClient))
			{
				PhotonNetwork.Destroy(((Component)val4).gameObject);
			}
			if ((Object)(object)component != (Object)null)
			{
				items.photonView.RPC("EquipSlotRpc", (RpcTarget)1, new object[2] { -1, component.ViewID });
			}
			SetHeld(ActorOf(character), kind);
			PlayerInventory.SyncAll(character.player);
			InventoryHud.ForceRelayout();
			Plugin.Log.LogInfo((object)("Held worn " + kind.ToString() + " in hands. Extra slots hidden until it is worn again."));
		}

		internal static void WearHeldAgain(Character character)
		{
			if (SelectedPack == PackKind.None)
			{
				ReleaseHeldPack(character);
				return;
			}
			PackKind selectedPack = SelectedPack;
			if (selectedPack == PackKind.Flight)
			{
				ContinueRocketFuse(character, ((Object)(object)character.data != (Object)null) ? character.data.currentItem : null);
			}
			ReleaseHeldPack(character);
			SelectedPack = PackKind.None;
			SetHeld(ActorOf(character), PackKind.None);
			PlayerInventory.SyncAll(character.player);
			InventoryHud.NotifyPackSelected();
			InventoryHud.ForceRelayout();
			Plugin.Log.LogInfo((object)("Put " + selectedPack.ToString() + " back on."));
		}

		internal static void ReleaseHeldPack(Character character)
		{
			if (!((Object)(object)character == (Object)null) && !((Object)(object)character.data == (Object)null))
			{
				Item currentItem = character.data.currentItem;
				if (!((Object)(object)currentItem == (Object)null) && IsPackItem(currentItem) && character.refs != null && !((Object)(object)character.refs.items == (Object)null) && !((Object)(object)character.refs.items.photonView == (Object)null))
				{
					character.refs.items.photonView.RPC("DestroyHeldItemRpc", (RpcTarget)0, Array.Empty<object>());
				}
			}
		}

		internal static bool TryDropSelected(Character character)
		{
			if (SelectedPack == PackKind.None || (Object)(object)character == (Object)null || !character.IsLocal)
			{
				return false;
			}
			if (SelectedPack == PackKind.Backpack && !HasBackpack(character))
			{
				return false;
			}
			if (SelectedPack == PackKind.Fanny && !HasFanny(character))
			{
				return false;
			}
			if (SelectedPack == PackKind.Flight && !HasFlight(character))
			{
				return false;
			}
			bool result = TryDrop(character, SelectedPack);
			InventoryHud.ForceRelayout();
			return result;
		}

		internal static bool TryDrop(Character character, PackKind kind, int spread)
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || (Object)(object)character.player == (Object)null || kind == PackKind.None)
			{
				return false;
			}
			Player player = character.player;
			Item val = (((Object)(object)character.data != (Object)null) ? character.data.currentItem : null);
			bool flag = (Object)(object)val != (Object)null && KindOf(val) == kind;
			Item val2 = GetWornPrefab(character, kind);
			ItemInstanceData val3 = ((flag && val.data != null) ? val.data : GetPackData(character, kind));
			if ((Object)(object)val2 == (Object)null && flag)
			{
				val2 = val;
			}
			string text = PrefabResourceName(val2);
			if (string.IsNullOrEmpty(text) || val3 == null)
			{
				Plugin.Log.LogWarning((object)("Cannot drop worn " + kind.ToString() + " (prefab or data missing)."));
				return false;
			}
			Vector3 pos = DropPoint(character, spread);
			GameObject val4 = SpawnWorldPack(text, val3, pos);
			if ((Object)(object)val4 == (Object)null)
			{
				Plugin.Log.LogWarning((object)("Cannot drop worn " + kind.ToString() + " (failed to spawn 0_Items/" + text + ")."));
				return false;
			}
			PlayerInventory.UnequipIfPackSlotSelected(character);
			if (flag)
			{
				ReleaseHeldPack(character);
			}
			RemoveWorn(character, kind);
			if (SelectedPack == kind)
			{
				SelectedPack = PackKind.None;
			}
			SetHeld(ActorOf(character), PackKind.None);
			PlayerInventory.SyncAll(player);
			Plugin.Log.LogInfo((object)("Dropped worn " + kind.ToString() + " as 0_Items/" + text + " at " + ((Vector3)(ref pos)).ToString("F2") + "."));
			return true;
		}

		internal static bool TryDrop(Character character, PackKind kind)
		{
			return TryDrop(character, kind, 0);
		}

		internal static void DropAllWorn(Character character)
		{
			if (!((Object)(object)character == (Object)null) && !_droppingWorn)
			{
				if ((Object)(object)Plugin.Instance != (Object)null)
				{
					((MonoBehaviour)Plugin.Instance).StartCoroutine(DropAllWornRoutine(character));
				}
				else
				{
					DropAllWornImmediate(character);
				}
			}
		}

		private static IEnumerator DropAllWornRoutine(Character character)
		{
			_droppingWorn = true;
			PackKind[] order = new PackKind[3]
			{
				PackKind.Flight,
				PackKind.Backpack,
				PackKind.Fanny
			};
			int spread = 0;
			bool first = true;
			try
			{
				for (int i = 0; i < order.Length; i++)
				{
					PackKind kind = order[i];
					if (StillHas(character, kind))
					{
						if (!first)
						{
							yield return (object)new WaitForSeconds(1f);
						}
						first = false;
						if ((Object)(object)character == (Object)null || (Object)(object)character.player == (Object)null)
						{
							break;
						}
						if (!TryDrop(character, kind, spread))
						{
							Plugin.Log.LogWarning((object)("Failed to drop worn " + kind.ToString() + "."));
						}
						else
						{
							spread++;
						}
					}
				}
			}
			finally
			{
				_droppingWorn = false;
			}
		}

		private static void DropAllWornImmediate(Character character)
		{
			PackKind[] array = new PackKind[3]
			{
				PackKind.Flight,
				PackKind.Backpack,
				PackKind.Fanny
			};
			int num = 0;
			for (int i = 0; i < array.Length; i++)
			{
				if (StillHas(character, array[i]) && TryDrop(character, array[i], num))
				{
					num++;
				}
			}
		}

		private static bool StillHas(Character character, PackKind kind)
		{
			return kind switch
			{
				PackKind.Flight => HasFlight(character), 
				PackKind.Backpack => HasBackpack(character), 
				PackKind.Fanny => HasFanny(character), 
				_ => false, 
			};
		}

		private static GameObject SpawnWorldPack(string resourceName, ItemInstanceData data, Vector3 pos)
		{
			//IL_000d: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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)
			GameObject val;
			try
			{
				val = PhotonNetwork.Instantiate("0_Items/" + resourceName, pos, Quaternion.identity, (byte)0, (object[])null);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Photon spawn failed for 0_Items/" + resourceName + ": " + ex.Message));
				return null;
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Item component = val.GetComponent<Item>();
			PhotonView component2 = val.GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null)
			{
				if ((Object)(object)component2 != (Object)null && (component2.IsMine || PhotonNetwork.IsMasterClient))
				{
					PhotonNetwork.Destroy(val);
				}
				return null;
			}
			if ((Object)(object)component2 != (Object)null && data != null)
			{
				component2.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { data });
			}
			component.SetState((ItemState)0, (Character)null);
			component.Move(pos, val.transform.rotation);
			component.SetKinematicNetworked(false, pos, val.transform.rotation);
			component.ForceSyncForFrames(15);
			Backpack val2 = (Backpack)(object)((component is Backpack) ? component : null);
			if ((Object)(object)val2 != (Object)null)
			{
				try
				{
					val2.EnableVisuals();
				}
				catch
				{
				}
			}
			return val;
		}

		private static string PrefabResourceName(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			Item val = default(Item);
			if (item.itemID != 0 && ItemDatabase.TryGetItem(item.itemID, ref val) && (Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null)
			{
				return ((Object)((Component)val).gameObject).name;
			}
			return StripClone(((Object)(object)((Component)item).gameObject != (Object)null) ? ((Object)((Component)item).gameObject).name : null);
		}

		private static string StripClone(string objectName)
		{
			if (string.IsNullOrEmpty(objectName))
			{
				return objectName;
			}
			if (objectName.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				return objectName.Substring(0, objectName.Length - "(Clone)".Length).Trim();
			}
			return objectName;
		}

		private static Vector3 DropPoint(Character character, int spread)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (((Object)(object)character.GetBodypart((BodypartType)0) != (Object)null) ? character.GetBodypart((BodypartType)0).transform : ((Component)character).transform);
			Vector3 right = val.right;
			right.y = 0f;
			if (((Vector3)(ref right)).sqrMagnitude < 0.01f)
			{
				right = Vector3.right;
			}
			((Vector3)(ref right)).Normalize();
			Vector3 forward = val.forward;
			forward.y = 0f;
			if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
			{
				forward = Vector3.forward;
			}
			((Vector3)(ref forward)).Normalize();
			return val.position + Vector3.up * 1.2f + forward * 0.45f + right * (float)(spread - 1) * 0.55f;
		}

		internal static void ConsumeUsedRocket(Character character)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Invalid comparison between Unknown and I4
			if (!((Object)(object)character == (Object)null) && !((Object)(object)character.player == (Object)null) && character.player.backpackSlot != null && (int)character.player.backpackSlot.backpackType == 4)
			{
				if (SelectedPack == PackKind.Flight)
				{
					SelectedPack = PackKind.None;
				}
				ReleaseHeldPack(character);
				RemoveWorn(character, PackKind.Flight);
				PlayerInventory.SyncAll(character.player);
				InventoryHud.ForceRelayout();
				Plugin.Log.LogInfo((object)"Consumed rocket pack after use.");
			}
		}

		private static void RemoveWorn(Character character, PackKind kind)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (SlotKind(character) == kind)
			{
				((ItemSlot)character.player.backpackSlot).EmptyOut();
				character.player.backpackSlot.backpackType = (BackpackType)0;
				PromoteExtra(character);
				return;
			}
			PackLoadout loadout = GetLoadout(character, create: false);
			if (loadout != null)
			{
				switch (kind)
				{
				case PackKind.Backpack:
					loadout.Backpack = default(WornPack);
					break;
				case PackKind.Fanny:
					loadout.Fanny = default(WornPack);
					break;
				}
				if (!Has(loadout.Backpack) && !Has(loadout.Fanny))
				{
					ExtraByActor.Remove(ActorOf(character));
				}
			}
		}

		private static void PromoteExtra(Character character)
		{
			PackLoadout loadout = GetLoadout(character, create: false);
			if (loadout != null)
			{
				if (Has(loadout.Backpack))
				{
					WearFromExtra(character.player, loadout.Backpack);
					loadout.Backpack = default(WornPack);
				}
				else if (Has(loadout.Fanny))
				{
					WearFromExtra(character.player, loadout.Fanny);
					loadout.Fanny = default(WornPack);
				}
				if (!Has(loadout.Backpack) && !Has(loadout.Fanny))
				{
					ExtraByActor.Remove(ActorOf(character));
				}
			}
		}

		private static void WearFromExtra(Player player, WornPack extra)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Item val = default(Item);
			if (ItemDatabase.TryGetItem(extra.ItemId, ref val) && val is Backpack)
			{
				player.backpackSlot.backpackType = extra.Type;
				((ItemSlot)player.backpackSlot).SetItem(val, extra.Data);
			}
		}

		private static void ParkSlot(Character character)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Invalid comparison between Unknown and I4
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Invalid comparison between Unknown and I4
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || (Object)(object)character.player == (Object)null || character.player.backpackSlot == null || ((ItemSlot)character.player.backpackSlot).IsEmpty())
			{
				return;
			}
			BackpackSlot backpackSlot = character.player.backpackSlot;
			Item val = ResolvePrefab((ItemSlot)(object)backpackSlot);
			PackKind packKind = KindOf(backpackSlot.backpackType);
			if (packKind == PackKind.None)
			{
				packKind = KindOf(val);
			}
			if (packKind == PackKind.Backpack || packKind == PackKind.Fanny)
			{
				if ((Object)(object)val == (Object)null)
				{
					val = FindPrefabByType((BackpackType)((packKind != PackKind.Fanny) ? 1 : 2));
				}
				ushort itemId = (ushort)(((Object)(object)val != (Object)null) ? val.itemID : 0);
				BackpackType val2 = backpackSlot.backpackType;
				if ((int)val2 != 1 && (int)val2 != 2)
				{
					val2 = (BackpackType)((packKind != PackKind.Fanny) ? 1 : 2);
				}
				ItemInstanceData data = CloneData(((ItemSlot)backpackSlot).data);
				SetExtra(character, packKind, itemId, data, val2);
				Plugin.Log.LogInfo((object)("Parked " + packKind.ToString() + " id=" + itemId + " before wearing another pack."));
				((ItemSlot)backpackSlot).EmptyOut();
				backpackSlot.backpackType = (BackpackType)0;
			}
		}

		private static Item FindPrefabByType(BackpackType type)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			ItemDatabase val = null;
			try
			{
				val = SingletonAsset<ItemDatabase>.Instance;
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null || ((DatabaseAsset<ItemDatabase, Item>)(object)val).Objects == null)
			{
				return null;
			}
			for (int i = 0; i < ((DatabaseAsset<ItemDatabase, Item>)(object)val).Objects.Count; i++)
			{
				Item obj2 = ((DatabaseAsset<ItemDatabase, Item>)(object)val).Objects[i];
				Backpack val2 = (Backpack)(object)((obj2 is Backpack) ? obj2 : null);
				if ((Object)(object)val2 != (Object)null && val2.backpackType == type)
				{
					return (Item)(object)val2;
				}
			}
			return null;
		}

		private static ItemInstanceData CloneData(ItemInstanceData source)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			ItemInstanceData val = new ItemInstanceData(Guid.NewGuid());
			ItemInstanceDataHandler.AddInstanceData(val);
			if (source == null)
			{
				return val;
			}
			BackpackData val2 = default(BackpackData);
			if (source.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val2) && val2 != null)
			{
				BackpackData val3 = val.RegisterNewEntry<BackpackData>((DataEntryKey)7);
				if (val3 != null && val2.itemSlots != null)
				{
					val3.itemSlots = (ItemSlot[])(object)new ItemSlot[val2.itemSlots.Length];
					for (int i = 0; i < val2.itemSlots.Length; i++)
					{
						ItemSlot val4 = val2.itemSlots[i];
						val3.itemSlots[i] = new ItemSlot((byte)i);
						if (val4 != null && !val4.IsEmpty())
						{
							val3.itemSlots[i].SetItem(val4.prefab, (val4.data != null) ? CloneData(val4.data) : null);
						}
					}
				}
			}
			if (source.data == null)
			{
				return val;
			}
			DataEntryValue val5 = default(DataEntryValue);
			foreach (KeyValuePair<DataEntryKey, DataEntryValue> datum in source.data)
			{
				if (!(datum.Value is BackpackData) && DataEntryValue.TryCopy(datum.Value, ref val5) && val5 != null)
				{
					val.data[datum.Key] = val5;
				}
			}
			return val;
		}

		private static void SetExtra(Character character, PackKind kind, ushort itemId, ItemInstanceData data, BackpackType type)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			PackLoadout loadout = GetLoadout(character, create: true);
			if (loadout != null)
			{
				WornPack wornPack = default(WornPack);
				wornPack.ItemId = itemId;
				wornPack.Data = data;
				wornPack.Type = type;
				switch (kind)
				{
				case PackKind.Backpack:
					loadout.Backpack = wornPack;
					break;
				case PackKind.Fanny:
					loadout.Fanny = wornPack;
					break;
				}
			}
		}

		private static BackpackData EnsureEntry(ItemInstanceData instance)
		{
			if (instance == null)
			{
				return null;
			}
			BackpackData val = default(BackpackData);
			if (!instance.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val) || val == null)
			{
				val = instance.RegisterNewEntry<BackpackData>((DataEntryKey)7);
			}
			return val;
		}

		private static void EnsureSlots(BackpackData data, PackKind kind)
		{
			if (data == null)
			{
				return;
			}
			int num = ((kind == PackKind.Fanny) ? 2 : 4);
			if (data.itemSlots == null || data.itemSlots.Length < num)
			{
				ItemSlot[] array = (ItemSlot[])(object)new ItemSlot[num];
				int num2 = ((data.itemSlots != null) ? Math.Min(data.itemSlots.Length, num) : 0);
				for (int i = 0; i < num2; i++)
				{
					array[i] = data.itemSlots[i];
				}
				data.itemSlots = array;
			}
			AssignIds(data, 0, num);
		}

		private static void AssignIds(BackpackData data, int startId, int count)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (data == null || data.itemSlots == null)
			{
				return;
			}
			int num = Math.Min(count, data.itemSlots.Length);
			for (byte b = 0; b < num; b++)
			{
				if (data.itemSlots[b] == null)
				{
					data.itemSlots[b] = new ItemSlot((byte)(startId + b));
				}
				else
				{
					data.itemSlots[b].itemSlotID = (byte)(startId + b);
				}
			}
		}

		private static int StorageWeight(ItemInstanceData instance)
		{
			if (instance == null)
			{
				return 0;
			}
			BackpackData val = default(BackpackData);
			if (!instance.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val) || val == null || val.itemSlots == null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < val.itemSlots.Length; i++)
			{
				ItemSlot val2 = val.itemSlots[i];
				if (val2 != null && !val2.IsEmpty() && (Object)(object)val2.prefab != (Object)null)
				{
					num += val2.prefab.CarryWeight;
				}
			}
			return num;
		}
	}
	internal sealed class InventoryNet : MonoBehaviour, IOnEventCallback, IInRoomCallbacks, IMatchmakingCallbacks
	{
		private const string HandshakeTag = "H";

		private const int HandshakeRequest = 0;

		private const int HandshakeHost = 1;

		private const float HostSyncTimeoutSeconds = 10f;

		private const float HostSyncRetrySeconds = 2f;

		private static InventoryNet _instance;

		private static bool _hostConfirmed;

		private static bool _featuresEnabled = true;

		private Coroutine _hostWatch;

		internal static bool HostHasMod { get; private set; } = true;

		internal static bool FeaturesEnabled => _featuresEnabled;

		internal static void Ensure()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_instance != (Object)null))
			{
				GameObject val = new GameObject("InventoryPLUS_Net");
				Object.DontDestroyOnLoad((Object)(object)val);
				_instance = val.AddComponent<InventoryNet>();
				if (PhotonNetwork.InRoom)
				{
					_instance.HandleJoinedRoom();
				}
			}
		}

		private void OnEnable()
		{
			PhotonNetwork.AddCallbackTarget((object)this);
		}

		private void OnDisable()
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
		}

		internal static void Broadcast(Character character)
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			if (!PhotonNetwork.InRoom || !FeaturesEnabled)
			{
				return;
			}
			int num = PackWear.ActorOf(character);
			if (num < 0)
			{
				return;
			}
			PackLoadout loadout = PackWear.GetLoadout(character, create: false);
			int itemId = 0;
			byte[] bytes = null;
			int itemId2 = 0;
			byte[] bytes2 = null;
			int type = 0;
			int type2 = 0;
			if (loadout != null)
			{
				PartsOf(loadout.Backpack, out itemId, out bytes, out type);
				PartsOf(loadout.Fanny, out itemId2, out bytes2, out type2);
			}
			int held = (int)PackWear.GetHeld(character);
			try
			{
				PhotonNetwork.RaiseEvent((byte)166, (object)new object[10] { "tony4twentys.InventoryPLUS", 1, num, itemId, bytes, type, itemId2, bytes2, type2, held }, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
			}
			catch (Exception ex)
			{
				Plugin.LogHotException("InventoryNet.RaiseEvent", ex);
			}
		}

		public void OnEvent(EventData photonEvent)
		{
			if (photonEvent == null || photonEvent.Code != 166 || !(photonEvent.CustomData is object[] array) || array.Length < 3 || !(array[0] is string text) || text != "tony4twentys.InventoryPLUS" || ToInt(array[1]) != 1)
			{
				return;
			}
			if (array[2] is string text2 && text2 == "H")
			{
				HandleHandshake(array, photonEvent.Sender);
			}
			else
			{
				if (array.Length < 9)
				{
					return;
				}
				if (IsMasterSender(photonEvent.Sender))
				{
					ConfirmHost("host inventory sync");
				}
				if (FeaturesEnabled)
				{
					int actor = ToInt(array[2]);
					WornPack backpack = FromParts(array[3], array[4], array[5]);
					WornPack fanny = FromParts(array[6], array[7], array[8]);
					PackWear.SetLoadout(actor, backpack, fanny);
					if (array.Length >= 10)
					{
						PackWear.SetHeld(actor, (PackKind)ToInt(array[9]));
					}
					InventoryHud.MarkDirty();
				}
			}
		}

		public void OnJoinedRoom()
		{
			HandleJoinedRoom();
		}

		public void OnLeftRoom()
		{
			HandleLeftRoom();
		}

		public void OnCreatedRoom()
		{
		}

		public void OnCreateRoomFailed(short returnCode, string message)
		{
		}

		public void OnJoinRoomFailed(short returnCode, string message)
		{
		}

		public void OnJoinRandomFailed(short returnCode, string message)
		{
		}

		public void OnFriendListUpdate(List<FriendInfo> friendList)
		{
		}

		public void OnPlayerEnteredRoom(Player newPlayer)
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			SendHostHello();
			List<Character> allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters();
			if (allPlayerCharacters != null)
			{
				for (int i = 0; i < allPlayerCharacters.Count; i++)
				{
					Broadcast(allPlayerCharacters[i]);
				}
			}
		}

		public void OnPlayerLeftRoom(Player otherPlayer)
		{
			if (otherPlayer != null)
			{
				PackWear.ClearActor(otherPlayer.ActorNumber);
			}
		}

		public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
		}

		public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
		{
		}

		public void OnMasterClientSwitched(Player newMasterClient)
		{
			HandleJoinedRoom();
		}

		private void HandleJoinedRoom()
		{
			if (!PhotonNetwork.InRoom)
			{
				SetHostState(hasMod: true, confirmed: false, "not in room");
			}
			else if (PhotonNetwork.IsMasterClient)
			{
				StopHostWatch();
				SetHostState(hasMod: true, confirmed: true, "we are host");
				SendHostHello();
			}
			else
			{
				SetHostState(hasMod: false, confirmed: false, "awaiting host InventoryPLUS");
				RequestHostHello();
				RestartHostWatch();
			}
		}

		private void HandleLeftRoom()
		{
			StopHostWatch();
			SetHostState(hasMod: true, confirmed: false, "left room");
		}

		private void HandleHandshake(object[] payload, int sender)
		{
			int num = ((payload.Length >= 4) ? ToInt(payload[3]) : 0);
			if (num == 0 && PhotonNetwork.IsMasterClient)
			{
				SendHostHello();
			}
			else if (num == 1 && IsMasterSender(sender))
			{
				ConfirmHost("host RaiseEvent");
			}
		}

		private void ConfirmHost(string reason)
		{
			StopHostWatch();
			SetHostState(hasMod: true, confirmed: true, reason);
		}

		private void RestartHostWatch()
		{
			StopHostWatch();
			_hostWatch = ((MonoBehaviour)this).StartCoroutine(WatchForHost());
		}

		private void StopHostWatch()
		{
			if (_hostWatch != null)
			{
				((MonoBehaviour)this).StopCoroutine(_hostWatch);
				_hostWatch = null;
			}
		}

		private IEnumerator WatchForHost()
		{
			float elapsed = 0f;
			float nextRetry = 2f;
			while (elapsed < 10f)
			{
				if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient || _hostConfirmed)
				{
					yield break;
				}
				elapsed += Time.unscaledDeltaTime;
				if (elapsed >= nextRetry)
				{
					RequestHostHello();
					nextRetry += 2f;
				}
				yield return null;
			}
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient && !_hostConfirmed)
			{
				SetHostState(hasMod: false, confirmed: false, "host missing InventoryPLUS");
			}
			_hostWatch = null;
		}

		private static void SendHostHello()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient)
			{
				return;
			}
			try
			{
				PhotonNetwork.RaiseEvent((byte)166, (object)new object[4] { "tony4twentys.InventoryPLUS", 1, "H", 1 }, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
			}
			catch (Exception ex)
			{
				Plugin.LogHotException("InventoryNet.HostHello", ex);
			}
		}

		private static void RequestHostHello()
		{
			//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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)
			{
				return;
			}
			try
			{
				PhotonNetwork.RaiseEvent((byte)166, (object)new object[4] { "tony4twentys.InventoryPLUS", 1, "H", 0 }, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)2
				}, SendOptions.SendReliable);
			}
			catch (Exception ex)
			{
				Plugin.LogHotException("InventoryNet.HostRequest", ex);
			}
		}

		private static bool IsMasterSender(int sender)
		{
			Player masterClient = PhotonNetwork.MasterClient;
			if (masterClient == null)
			{
				return false;
			}
			return sender == masterClient.ActorNumber || (sender == 0 && PhotonNetwork.IsMasterClient);
		}

		private static void SetHostState(bool hasMod, bool confirmed, string reason)
		{
			HostHasMod = hasMod;
			_hostConfirmed = confirmed;
			bool flag = true;
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				flag = hasMod && confirmed;
			}
			if (flag == _featuresEnabled)
			{
				if (reason == "host missing InventoryPLUS")
				{
					Plugin.Log.LogWarning((object)("InventoryPLUS disabled — " + reason + "."));
				}
				return;
			}
			_featuresEnabled = flag;
			if (flag)
			{
				Plugin.Log.LogInfo((object)("InventoryPLUS enabled — " + reason + "."));
			}
			else
			{
				Plugin.Log.LogWarning((object)("InventoryPLUS disabled — " + reason + "."));
			}
			Plugin.NotifyEnabledChanged();
		}

		private static void PartsOf(WornPack pack, out int itemId, out byte[] bytes, out int type)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected I4, but got Unknown
			itemId = 0;
			bytes = null;
			type = 0;
			if (PackWear.Has(pack))
			{
				itemId = pack.ItemId;
				type = (int)pack.Type;
				bytes = CustomTypeRPCSerialization.SerializeItemData((object)pack.Data);
			}
		}

		private static WornPack FromParts(object idObj, object bytesObj, object typeObj)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			WornPack result = default(WornPack);
			if (idObj == null || bytesObj == null)
			{
				return result;
			}
			result.ItemId = Convert.ToUInt16(idObj);
			if (result.ItemId == 0)
			{
				return default(WornPack);
			}
			result.Type = (BackpackType)ToInt(typeObj);
			result.Data = (ItemInstanceData)CustomTypeRPCSerialization.DeserializeItemData((byte[])bytesObj);
			return result;
		}

		private static int ToInt(object value)
		{
			if (value == null)
			{
				return 0;
			}
			return Convert.ToInt32(value);
		}
	}
	internal static class InventoryInput
	{
		private static readonly int[] UnlockedBuffer = new int[10];

		internal static bool TryHandleSwitching(CharacterItems items)
		{
			if (!Plugin.Enabled)
			{
				return false;
			}
			Character character = items.character;
			if (items.timesSwitchedRecently > 0 && items.lastSwitched + 0.4f < Time.time)
			{
				items.timesSwitchedRecently = 0;
			}
			if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
			{
				return true;
			}
			if (!character.data.fullyConscious || !character.IsLocal || !character.CanDoInput() || items.lockedFromSwitching || character.data.isClimbing || character.data.isRopeClimbing)
			{
				return true;
			}
			TickPackCycle();
			TickPackDrop();
			if ((Object)(object)character.data.currentItem != (Object)null && (character.data.currentItem.progress > 0f || character.data.currentItem.lastFinishedCast + 0.1f > Time.time) && (PackWear.SelectedPack == PackKind.None || !PackWear.IsPackItem(character.data.currentItem)))
			{
				return true;
			}
			Player player = character.player;
			int unlockedCount = PlayerInventory.CollectUnlocked(player, UnlockedBuffer);
			if (character.input.selectSlotForwardWasPressed)
			{
				if (BlockSticky(character))
				{
					return true;
				}
				byte slot = NextSlot(items, UnlockedBuffer, unlockedCount, 1);
				SwitchTo(items, slot);
				return true;
			}
			if (character.input.selectSlotBackwardWasPressed)
			{
				if (BlockSticky(character))
				{
					return true;
				}
				byte slot2 = NextSlot(items, UnlockedBuffer, unlockedCount, -1);
				SwitchTo(items, slot2);
				return true;
			}
			if (character.input.unselectSlotWasPressed && !items.lockedFromSwitching)
			{
				if (BlockSticky(character))
				{
					return true;
				}
				if (PackWear.SelectedPack != PackKind.None)
				{
					PackWear.WearHeldAgain(character);
					return true;
				}
				if (items.currentSelectedSlot.IsSome)
				{
					SwitchToNone(items);
				}
				else if (items.lastSelectedSlot.IsSome && PlayerInventory.IsHotbarVisible(player, items.lastSelectedSlot.Value))
				{
					SwitchTo(items, items.lastSelectedSlot.Value);
				}
				return true;
			}
			for (int i = 0; i < 10; i++)
			{
				if (SlotKeyPressed(character, i))
				{
					if (BlockSticky(character))
					{
						return true;
					}
					if (!PlayerInventory.IsHotbarVisible(player, i))
					{
						return true;
					}
					if (items.currentSelectedSlot.IsSome && items.currentSelectedSlot.Value == i)
					{
						SwitchToNone(items);
					}
					else
					{
						SwitchTo(items, (byte)i);
					}
					return true;
				}
			}
			return true;
		}

		internal static void TickPackCycle()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (!Input.GetKeyDown(InventoryConfig.PackCycleKey))
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || !localCharacter.IsLocal)
			{
				return;
			}
			PackKind[] array = new PackKind[3];
			int num = 0;
			if (PackWear.HasBackpack(localCharacter))
			{
				array[num++] = PackKind.Backpack;
			}
			if (PackWear.HasFanny(localCharacter))
			{
				array[num++] = PackKind.Fanny;
			}
			if (PackWear.HasFlight(localCharacter))
			{
				array[num++] = PackKind.Flight;
			}
			if (num <= 0)
			{
				PackWear.SelectedPack = PackKind.None;
				return;
			}
			int num2 = -1;
			for (int i = 0; i < num; i++)
			{
				if (PackWear.SelectedPack == array[i])
				{
					num2 = i;
					break;
				}
			}
			int num3 = num2 + 1;
			if (num3 >= num)
			{
				PackWear.WearHeldAgain(localCharacter);
				Plugin.Log.LogInfo((object)"Put held pack back on.");
			}
			else
			{
				PackWear.HoldWorn(localCharacter, array[num3]);
				InventoryHud.NotifyPackSelected();
				Plugin.Log.LogInfo((object)("Cycled worn pack to " + array[num3].ToString() + "."));
			}
		}

		internal static void TickPackDrop()
		{
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter == (Object)null) && localCharacter.IsLocal && !((Object)(object)localCharacter.input == (Object)null) && !((Object)(object)localCharacter.data == (Object)null) && localCharacter.CanDoInput() && localCharacter.data.fullyConscious && PackWear.SelectedPack != PackKind.None && localCharacter.input.dropWasPressed)
			{
				PackWear.TryDropSelected(localCharacter);
			}
		}

		internal static KeyCode KeyForSlot(int slotIndex)
		{
			//IL_0002: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			return InventoryConfig.SlotKey(slotIndex);
		}

		internal static bool SlotKeyPressed(Character character, int slotIndex)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || (Object)(object)character.input == (Object)null || slotIndex < 0 || slotIndex >= 10)
			{
				return false;
			}
			if (slotIndex < 3 && character.input.SelectSlotWasPressed(slotIndex))
			{
				return true;
			}
			if (slotIndex == 3 && (character.input.selectBackpackWasPressed || character.input.SelectSlotWasPressed(3)))
			{
				return true;
			}
			if (slotIndex < 4)
			{
				return false;
			}
			KeyCode val = InventoryConfig.SlotKey(slotIndex);
			return (int)val != 0 && Input.GetKeyDown(val);
		}

		private static byte NextSlot(CharacterItems items, int[] unlocked, int unlockedCount, int delta)
		{
			if (unlockedCount <= 0)
			{
				return 0;
			}
			int num = 0;
			if (items.lastSelectedSlot.IsSome)
			{
				num = items.lastSelectedSlot.Value;
			}
			int num2 = 0;
			for (int i = 0; i < unlockedCount; i++)
			{
				if (unlocked[i] == num)
				{
					num2 = i;
					break;
				}
			}
			if (num == 250)
			{
				num2 = ((delta > 0) ? (-1) : 0);
			}
			int num3 = num2 + delta;
			if (num3 >= unlockedCount)
			{
				num3 = 0;
			}
			if (num3 < 0)
			{
				num3 = unlockedCount - 1;
			}
			return (byte)unlocked[num3];
		}

		private static void SwitchTo(CharacterItems items, byte slot)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			PackWear.WearHeldAgain(((Object)(object)items != (Object)null) ? items.character : null);
			items.lastSwitched = Time.time;
			items.timesSwitchedRecently++;
			items.EquipSlot(Optionable<byte>.Some(slot));
		}

		private static void SwitchToNone(CharacterItems items)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			PackWear.WearHeldAgain(((Object)(object)items != (Object)null) ? items.character : null);
			items.lastSwitched = Time.time;
			items.timesSwitchedRecently++;
			items.EquipSlot(Optionable<byte>.None);
		}

		private static bool BlockSticky(Character character)
		{
			if (!Object.op_Implicit((Object)(object)character.data.currentStickyItem))
			{
				return false;
			}
			if (character.refs != null && (Object)(object)character.refs.animations != (Object)null)
			{
				character.refs.animations.throwTime = 0.125f;
			}
			return true;
		}
	}
	internal static class InventoryHud
	{
		private sealed class SlotView
		{
			public GameObject Root;

			public RectTransform Rect;

			public InventoryItemUI Ui;

			public TextMeshProUGUI Name;

			public TextMeshProUGUI Key;

			public Vector2 BaseSize;

			public byte SlotId;

			public PackKind Kind;

			public ItemSlot Fake;

			public bool LastSelected;

			public bool LastHasItem;
		}

		private static readonly SlotView[] ExtraUi = new SlotView[7];

		private static readonly SlotView[] PackIcons = new SlotView[3];

		private static readonly int[] Visible = new int[10];

		private static RectTransform _overlay;

		private static TMP_FontAsset _font;

		private static TMP_SpriteAsset _keySprites;

		private static bool _ready;

		private static bool _loggedSkip;

		private static bool _loggedLayout;

		private static bool _backpackParked;

		private static bool _layoutOff;

		private static bool _haveRest;

		private static int _loggedUnlock = int.MinValue;

		private static int _placedCount = int.MinValue;

		private static Vector2 _slotSize = new Vector2(70f, 70f);

		private static Vector3 _step = new Vector3(80f, 0f, 0f);

		private static Vector3 _rightRest;

		internal static void MarkDirty()
		{
		}

		internal static void ForceRelayout()
		{
			_placedCount = int.MinValue;
			if (_ready)
			{
				Refresh();
			}
		}

		internal static void ResetForScene()
		{
			RestoreVanilla();
			_ready = false;
			_loggedSkip = false;
			_loggedLayout = false;
			_haveRest = false;
			_loggedUnlock = int.MinValue;
			_placedCount = int.MinValue;
			for (int i = 0; i < ExtraUi.Length; i++)
			{
				DestroyView(ref ExtraUi[i]);
			}
			for (int j = 0; j < PackIcons.Length; j++)
			{
				DestroyView(ref PackIcons[j]);
			}
			if ((Object)(object)_overlay != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_overlay).gameObject);
			}
			_overlay = null;
		}

		internal static IEnumerator Bootstrap()
		{
			WaitForSeconds wait = new WaitForSeconds(0.25f);
			while (!_ready)
			{
				if (!CanInit())
				{
					if (!_loggedSkip)
					{
						_loggedSkip = true;
						Plugin.Log.LogInfo((object)"Waiting for airport HUD before drawing extra slots.");
					}
					yield return wait;
					continue;
				}
				yield return (object)new WaitForSeconds(2f);
				if (CanInit())
				{
					try
					{
						TryInit();
					}
					catch (Exception ex)
					{
						Exception ex2 = ex;
						Plugin.LogHotException("InventoryHud.Bootstrap", ex2);
						ResetForScene();
					}
					if (!_ready)
					{
						yield return wait;
					}
				}
			}
			while (_ready && CanInit())
			{
				try
				{
					Refresh();
				}
				catch (Exception ex3)
				{
					Plugin.LogHotException("InventoryHud.Refresh", ex3);
				}
				yield return wait;
			}
		}

		internal static void RefreshItems(GUIManager gui)
		{
			TickItems(gui);
		}

		internal static void RefreshSelection(GUIManager gui)
		{
			TickSelections();
		}

		internal static void TickItems(GUIManager gui)
		{
			if (!Plugin.Enabled || !_ready || (Object)(object)gui == (Object)null)
			{
				return;
			}
			Character observedCharacter = Character.observedCharacter;
			Player val = (((Object)(object)observedCharacter != (Object)null) ? observedCharacter.player : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int num = SelectedSlotId(observedCharacter);
			for (int i = 0; i < ExtraUi.Length; i++)
			{
				SlotView slotView = ExtraUi[i];
				if (slotView != null && !((Object)(object)slotView.Root == (Object)null) && slotView.Root.activeSelf)
				{
					PaintSlot(slotView, PlayerInventory.GetSlot(val, slotView.SlotId), num == slotView.SlotId);
				}
			}
			PackKind[] array = new PackKind[3]
			{
				PackKind.Backpack,
				PackKind.Fanny,
				PackKind.Flight
			};
			for (int j = 0; j < array.Length; j++)
			{
				SlotView slotView2 = PackIcons[j];
				if (slotView2 != null && !((Object)(object)slotView2.Root == (Object)null) && slotView2.Root.activeSelf)
				{
					PaintPrefab(slotView2, PackWear.GetWornPrefab(val.character, array[j]), PackWear.GetPackData(val.character, array[j]), PackWear.SelectedPack == array[j]);
				}
			}
		}

		internal static void TickSelections()
		{
			if (!_ready)
			{
				return;
			}
			for (int i = 0; i < ExtraUi.Length; i++)
			{
				SlotView slotView = ExtraUi[i];
				if (slotView != null && (Object)(object)slotView.Ui != (Object)null && (Object)(object)slotView.Root != (Object)null && slotView.Root.activeSelf)
				{
					slotView.Ui.SetSelected();
				}
			}
			for (int j = 0; j < PackIcons.Length; j++)
			{
				SlotView slotView2 = PackIcons[j];
				if (slotView2 != null && (Object)(object)slotView2.Ui != (Object)null && (Object)(object)slotView2.Root != (Object)null && slotView2.Root.activeSelf)
				{
					slotView2.Ui.SetSelected();
				}
			}
		}

		internal static bool TrySelectClone(InventoryItemUI ui)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			SlotView slotView = FindView(ui);
			if (slotView == null)
			{
				return false;
			}
			bool flag = ((slotView.Kind == PackKind.None) ? (SelectedSlotId(Character.observedCharacter) == slotView.SlotId) : (PackWear.SelectedPack == slotView.Kind));
			bool flag2 = (Object)(object)ui != (Object)null && (Object)(object)ui._itemPrefab != (Object)null;
			if (slotView.LastSelected == flag && slotView.LastHasItem == flag2)
			{
				return true;
			}
			slotView.LastSelected = flag;
			slotView.LastHasItem = flag2;
			PlaySelect(ui, slotView.BaseSize, flag, flag2);
			return true;
		}

		internal static bool TryOverrideSelected(InventoryItemUI ui, out bool selected)
		{
			selected = false;
			return false;
		}

		internal static void OnItemUiStarted(InventoryItemUI ui)
		{
		}

		internal static void SelectPack(PackKind kind)
		{
			PackWear.HoldWorn(Character.localCharacter, kind);
			NotifyPackSelected();
		}

		internal static void NotifyPackSelected()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < PackIcons.Length; i++)
			{
				SlotView slotView = PackIcons[i];
				if (slotView != null && !((Object)(object)slotView.Ui == (Object)null) && !((Object)(object)slotView.Root == (Object)null) && slotView.Root.activeSelf)
				{
					bool flag = PackWear.SelectedPack == slotView.Kind;
					bool flag2 = (Object)(object)slotView.Ui._itemPrefab != (Object)null;
					slotView.LastSelected = flag;
					slotView.LastHasItem = flag2;
					PlaySelect(slotView.Ui, slotView.BaseSize, flag, flag2);
				}
			}
		}

		private static bool CanInit()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Enabled)
			{
				return false;
			}
			if ((Object)(object)Character.localCharacter == (Object)null || (Object)(object)Character.localCharacter.player == (Object)null)
			{
				return false;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			if (string.IsNullOrEmpty(name) || name == "Title")
			{
				return false;
			}
			GUIManager instance = GUIManager.instance;
			return (Object)(object)instance != (Object)null && (Object)(object)instance.hudCanvas != (Object)null && instance.items != null && instance.items.Length >= 3 && (Object)(object)instance.items[0] != (Object)null && (Object)(object)instance.items[0].rectTransform != (Object)null && (Object)(object)instance.items[2] != (Object)null && (Object)(object)instance.backpack != (Object)null;
		}

		private static void TryInit()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.instance;
			if (!CanInit())
			{
				return;
			}
			CacheChrome(instance);
			ReadStride(instance);
			_slotSize = PocketSize(instance.items[0]);
			SnapshotRest(instance);
			if (!_haveRest || !EnsureOverlay(instance))
			{
				return;
			}
			DisableHotbarLayout(instance);
			ParkBackpack(instance);
			for (int i = 0; i < ExtraUi.Length; i++)
			{
				byte b = (byte)(3 + i);
				ExtraUi[i] = CloneSlot(instance.items[0], "InventoryPLUS_Slot_" + (b + 1), _slotSize, pack: false);
				if (ExtraUi[i] == null)
				{
					return;
				}
				ExtraUi[i].SlotId = b;
				BindKey(ExtraUi[i], b);
				ExtraUi[i].Root.SetActive(i == 0);
			}
			PackKind[] array = new PackKind[3]
			{
				PackKind.Backpack,
				PackKind.Fanny,
				PackKind.Flight
			};
			Vector2 size = _slotSize * 0.55f;
			for (int j = 0; j < array.Length; j++)
			{
				PackIcons[j] = CloneSlot(instance.items[0], "InventoryPLUS_Pack_" + array[j], size, pack: true);
				if (PackIcons[j] == null)
				{
					return;
				}
				PackIcons[j].Kind = array[j];
				PackIcons[j].Root.SetActive(false);
			}
			_ready = ExtraUi[0] != null;
			if (_ready)
			{
				Plugin.Log.LogInfo((object)"HUD using cloned pocket chrome. Bar will expand left from slot 4 rest.");
			}
		}

		private static void Refresh()
		{
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			if (!_ready)
			{
				return;
			}
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ParkBackpack(instance);
			DisableHotbarLayout(instance);
			Character observedCharacter = Character.observedCharacter;
			Player val = (((Object)(object)observedCharacter != (Object)null) ? observedCharacter.player : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			PlayerInventory.EnsureBaseSlots(val);
			PackWear.EnsureStorageIds(val.character);
			if (!_haveRest)
			{
				ReadStride(instance);
				SnapshotRest(instance);
			}
			int num = SelectedSlotId(observedCharacter);
			int num2 = PlayerInventory.CollectUnlocked(val, Visible);
			if (num2 <= 0)
			{
				num2 = 4;
				for (int i = 0; i < num2; i++)
				{
					Visible[i] = i;
				}
			}
			if (num2 != _loggedUnlock)
			{
				_loggedUnlock = num2;
				Plugin.Log.LogInfo((object)("Unlocked hotbar slots: " + num2 + ". Expanding left so the right edge stays put."));
			}
			bool flag = num2 != _placedCount;
			Vector3 world = default(Vector3);
			for (int j = 0; j < num2; j++)
			{
				int num3 = Visible[j];
				((Vector3)(ref world))..ctor(_rightRest.x - _step.x * (float)(num2 - 1 - j), _rightRest.y, _rightRest.z);
				if (num3 < 3)
				{
					if (flag)
					{
						PlaceVanilla(instance.items[num3], world);
					}
					continue;
				}
				SlotView slotView = ExtraUi[num3 - 3];
				if (slotView != null)
				{
					slotView.Root.SetActive(true);
					BindKey(slotView, num3);
					PaintSlot(slotView, PlayerInventory.GetSlot(val, (byte)num3), num == num3);
					if (flag)
					{
						PlaceView(slotView, world, instance.items[0]);
					}
				}
			}
			_placedCount = num2;
			for (int k = 0; k < ExtraUi.Length; k++)
			{
				if (ExtraUi[k] == null || (Object)(object)ExtraUi[k].Root == (Object)null)
				{
					continue;
				}
				int num4 = 3 + k;
				bool flag2 = false;
				for (int l = 0; l < num2; l++)
				{
					if (Visible[l] == num4)
					{
						flag2 = true;
						break;
					}
				}
				if (!flag2)
				{
					ExtraUi[k].Root.SetActive(false);
				}
			}
			PackKind[] array = new PackKind[3]
			{
				PackKind.Backpack,
				PackKind.Fanny,
				PackKind.Flight
			};
			int num5 = 0;
			Item[] array2 = (Item[])(object)new Item[3];
			for (int m = 0; m < array.Length; m++)
			{
				array2[m] = PackWear.GetWornPrefab(val.character, array[m]);
				if ((Object)(object)array2[m] != (Object)null)
				{
					num5++;
				}
			}
			float num6 = Mathf.Max(_slotSize.x * 0.7f, 48f);
			int num7 = 0;
			Vector3 world2 = default(Vector3);
			for (int n = 0; n < array.Length; n++)
			{
				SlotView slotView2 = PackIcons[n];
				if (slotView2 != null && !((Object)(object)slotView2.Root == (Object)null))
				{
					bool flag3 = (Object)(object)array2[n] != (Object)null;
					slotView2.Root.SetActive(flag3);
					if (flag3)
					{
						float num8 = _rightRest.x + num6 * ((float)num7 - (float)(num5 - 1) * 0.5f);
						((Vector3)(ref world2))..ctor(num8, _rightRest.y + _slotSize.y * 2.25f, _rightRest.z);
						PaintPrefab(slotView2, array2[n], PackWear.GetPackData(val.character, array[n]), PackWear.SelectedPack == array[n]);
						PlaceView(slotView2, world2, instance.items[0]);
						num7++;
					}
				}
			}
			if (!_loggedLayout)
			{
				_loggedLayout = true;
				Plugin.Log.LogInfo((object)("Inventory layout rest.x=" + _rightRest.x.ToString("0") + " stride=" + _step.x.ToString("0") + " size=" + _slotSize.x.ToString("0")));
			}
		}

		private static void CacheChrome(GUIManager gui)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			InventoryItemUI val = gui.items[0];
			_slotSize = PocketSize(val);
			if ((Object)(object)val != (Object)null && (Object)(object)val.nameText != (Object)null)
			{
				_font = ((TMP_Text)val.nameText).font;
				if ((Object)(object)((TMP_Text)val.nameText).spriteAsset != (Object)null)
				{
					_keySprites = ((TMP_Text)val.nameText).spriteAsset;
				}
			}
			try
			{
				InputSpriteData instance = SingletonAsset<InputSpriteData>.Instance;
				if ((Object)(object)instance != (Object)null && (Object)(object)instance.keyboardSprites != (Object)null)
				{
					_keySprites = instance.keyboardSprites;
				}
			}
			catch
			{
			}
		}

		private static bool EnsureOverlay(GUIManager gui)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_overlay != (Object)null)
			{
				return true;
			}
			Transform transform = ((Component)gui.hudCanvas).transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			GameObject val2 = new GameObject("InventoryPLUS_Overlay", new Type[1] { typeof(RectTransform) });
			_overlay = val2.GetComponent<RectTransform>();
			((Transform)_overlay).SetParent((Transform)(object)val, false);
			_overlay.anchorMin = Vector2.zero;
			_overlay.anchorMax = Vector2.one;
			_overlay.offsetMin = Vector2.zero;
			_overlay.offsetMax = Vector2.zero;
			_overlay.pivot = new Vector2(0.5f, 0.5f);
			((Transform)_overlay).SetAsLastSibling();
			return true;
		}

		private static SlotView CloneSlot(InventoryItemUI donor, string name, Vector2 size, bool pack)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)donor == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(((Component)donor).gameObject, (Transform)(object)_overlay, false);
			((Object)val).name = name;
			val.SetActive(true);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = size;
			((Transform)component).localScale = Vector3.one;
			InventoryItemUI component2 = val.GetComponent<InventoryItemUI>();
			if ((Object)(object)component2 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			component2.isBackpack = false;
			component2.isTemporarySlot = false;
			component2.rectTransform = component;
			component2.startingSizeDelta = size;
			if ((Object)(object)component2.backpackFilledSlotsObject != (Object)null)
			{
				component2.backpackFilledSlotsObject.SetActive(false);
			}
			IgnoreLayout(component);
			MatchScale(component, donor.rectTransform);
			TextMeshProUGUI val2 = KeepVanillaKey(val, component2);
			component2.Clear();
			SlotView slotView = new SlotView();
			slotView.Root = val;
			slotView.Rect = component;
			slotView.Ui = component2;
			slotView.BaseSize = size;
			slotView.Name = component2.nameText;
			slotView.Key = val2;
			if (pack && (Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(false);
			}
			return slotView;
		}

		private static TextMeshProUGUI KeepVanillaKey(GameObject clone, InventoryItemUI ui)
		{
			TextMeshProUGUI val = null;
			InLineInputPrompts[] componentsInChildren = clone.GetComponentsInChildren<InLineInputPrompts>(true);
			foreach (InLineInputPrompts val2 in componentsInChildren)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				if ((Object)(object)val == (Object)null)
				{
					TMP_Text text = val2.text;
					val = (TextMeshProUGUI)(object)((text is TextMeshProUGUI) ? text : null);
					if ((Object)(object)val == (Object)null)
					{
						val = ((Component)val2).GetComponent<TextMeshProUGUI>();
					}
				}
				((Behaviour)val2).enabled = false;
				LocalizedText component = ((Component)val2).GetComponent<LocalizedText>();
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = false;
				}
				Object.Destroy((Object)(object)val2);
			}
			if ((Object)(object)val == (Object)null)
			{
				TextMeshProUGUI[] componentsInChildren2 = clone.GetComponentsInChildren<TextMeshProUGUI>(true);
				for (int j = 0; j < componentsInChildren2.Length; j++)
				{
					if ((Object)(object)componentsInChildren2[j] != (Object)null && (Object)(object)componentsInChildren2[j] != (Object)(object)ui.nameText)
					{
						val = componentsInChildren2[j];
						break;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				LocalizedText component2 = ((Component)val).GetComponent<LocalizedText>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = false;
				}
				((Component)val).gameObject.SetActive(true);
				((Behaviour)val).enabled = true;
				if ((Object)(object)_keySprites != (Object)null)
				{
					((TMP_Text)val).spriteAsset = _keySprites;
				}
			}
			return val;
		}

		private static void BindKey(SlotView view, int slotId)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (view == null || (Object)(object)view.Key == (Object)null)
			{
				return;
			}
			if (slotId >= 0 && slotId < 4)
			{
				try
				{
					InputSpriteData instance = SingletonAsset<InputSpriteData>.Instance;
					if ((Object)(object)instance != (Object)null)
					{
						((TMP_Text)view.Key).text = instance.GetSpriteTag((InputAction)(7 + slotId), (InputScheme)0);
						return;
					}
				}
				catch
				{
				}
			}
			string text = InventoryConfig.KeyboardPath(InventoryConfig.SlotKey(slotId));
			if (string.IsNullOrEmpty(text))
			{
				text = ((slotId == 9) ? "0" : (slotId + 1).ToString());
			}
			try
			{
				InputSpriteData instance2 = SingletonAsset<InputSpriteData>.Instance;
				if ((Object)(object)instance2 != (Object)null)
				{
					if ((Object)(object)instance2.keyboardSprites != (Object)null)
					{
						((TMP_Text)view.Key).spriteAsset = instance2.keyboardSprites;
					}
					string spriteTagFromInputPathKeyboard = instance2.GetSpriteTagFromInputPathKeyboard("<Keyboard>/" + text);
					if (!string.IsNullOrEmpty(spriteTagFromInputPathKeyboard))
					{
						((TMP_Text)view.Key).text = spriteTagFromInputPathKeyboard;
						return;
					}
				}
			}
			catch
			{
			}
			((TMP_Text)view.Key).text = text;
		}

		private static void PaintSlot(SlotView view, ItemSlot slot, bool selected)
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (view == null || (Object)(object)view.Ui == (Object)null)
			{
				return;
			}
			if (slot == null || slot.IsEmpty())
			{
				view.Ui.Clear();
				return;
			}
			view.Ui._itemPrefab = slot.prefab;
			view.Ui._itemData = slot.data;
			if ((Object)(object)view.Ui.icon != (Object)null && (Object)(object)slot.prefab != (Object)null && slot.prefab.UIData != null)
			{
				try
				{
					Texture icon = (Texture)(object)slot.prefab.UIData.GetIcon();
					if ((Object)(object)icon != (Object)null)
					{
						view.Ui.icon.texture = icon;
						((Behaviour)view.Ui.icon).enabled = true;
						((Graphic)view.Ui.icon).color = Color.white;
						((Component)view.Ui.icon).transform.localScale = Vector3.one;
					}
				}
				catch
				{
				}
			}
			if ((Object)(object)view.Ui.nameText != (Object)null)
			{
				try
				{
					((TMP_Text)view.Ui.nameText).text = slot.prefab.GetItemName(slot.data);
				}
				catch
				{
				}
			}
			PaintFuel(view, slot.prefab, slot.data);
		}

		private static void PaintPrefab(SlotView view, Item prefab, ItemInstanceData data, bool selected)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (view == null || (Object)(object)view.Ui == (Object)null)
			{
				return;
			}
			if ((Object)(object)prefab == (Object)null)
			{
				view.Ui.Clear();
				return;
			}
			ItemSlot val = view.Fake;
			if (val == null)
			{
				val = (view.Fake = new ItemSlot((byte)0));
			}
			val.prefab = prefab;
			val.data = data;
			PaintSlot(view, val, selected);
		}

		private static void PaintFuel(SlotView view, Item prefab, ItemInstanceData data)
		{
			if (view != null && !((Object)(object)view.Ui == (Object)null))
			{
				try
				{
					view.Ui.TrySetFuel(data);
				}
				catch
				{
				}
				FloatItemData val = default(FloatItemData);
				if (view.Kind == PackKind.Flight && !((Object)(object)view.Ui.fuelBar == (Object)null) && !((Object)(object)view.Ui.fuelBarFill == (Object)null) && !((Object)(object)Character.observedCharacter != (Object)(object)Character.localCharacter) && data != null && !((Object)(object)prefab == (Object)null) && data.HasData((DataEntryKey)11) && data.TryGetDataEntry<FloatItemData>((DataEntryKey)11, ref val))
				{
					view.Ui.fuelBar.SetActive(true);
					view.Ui.fuelBarFill.fillAmount = val.Value;
				}
			}
		}

		private static void PlaySelect(InventoryItemUI ui, Vector2 baseSize, bool selected, bool hasItem)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missi