Decompiled source of InventoryPLUS v1.0.0
tony4twentys-InventoryPLUS.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
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