using System; using FFXIVClientStructs.FFXIV.Client.Game; using Lumina.Excel; using Lumina.Excel.Sheets; namespace LLib.Inventory; public static class InventoryHelper { public unsafe static int GetItemCount(uint itemId, bool checkEquipped = false, bool checkArmory = false) { InventoryManager* ptr = InventoryManager.Instance(); if (ptr == null) { return 0; } return ptr->GetInventoryItemCount(itemId, isHq: false, checkEquipped, checkArmory, 0) + ptr->GetInventoryItemCount(itemId, isHq: true, checkEquipped, checkArmory, 0); } public unsafe static int GetItemCount(uint itemId, InventoryType inventoryType) { InventoryManager* ptr = InventoryManager.Instance(); if (ptr == null) { return 0; } InventoryContainer* inventoryContainer = ptr->GetInventoryContainer(inventoryType); if (inventoryContainer == null) { return 0; } int num = 0; for (int i = 0; i < inventoryContainer->Size; i++) { InventoryItem* inventorySlot = inventoryContainer->GetInventorySlot(i); if (inventorySlot != null && inventorySlot->ItemId == itemId) { num += inventorySlot->Quantity; } } return num; } public static bool HasFreeInventorySlot() { return CountFreeInventorySlots() > 0; } public unsafe static int CountFreeInventorySlots() { InventoryManager* ptr = InventoryManager.Instance(); if (ptr == null) { return 0; } int num = 0; for (InventoryType inventoryType = InventoryType.Inventory1; inventoryType <= InventoryType.Inventory4; inventoryType++) { InventoryContainer* inventoryContainer = ptr->GetInventoryContainer(inventoryType); if (inventoryContainer == null) { continue; } for (int i = 0; i < inventoryContainer->Size; i++) { InventoryItem* inventorySlot = inventoryContainer->GetInventorySlot(i); if (inventorySlot == null || inventorySlot->ItemId == 0) { num++; } } } return num; } public unsafe static int CountInventorySlotsWithCondition(uint itemId, Predicate predicate) { ArgumentNullException.ThrowIfNull(predicate, "predicate"); InventoryManager* ptr = InventoryManager.Instance(); if (ptr == null) { return 0; } int num = 0; for (InventoryType inventoryType = InventoryType.Inventory1; inventoryType <= InventoryType.Inventory4; inventoryType++) { InventoryContainer* inventoryContainer = ptr->GetInventoryContainer(inventoryType); if (inventoryContainer == null) { continue; } for (int i = 0; i < inventoryContainer->Size; i++) { InventoryItem* inventorySlot = inventoryContainer->GetInventorySlot(i); if (inventorySlot != null && inventorySlot->ItemId != 0 && inventorySlot->ItemId == itemId && predicate(inventorySlot->Quantity)) { num++; } } } return num; } public static bool IsItemEquipped(uint itemId) { return GetEquippedItemSlot(itemId) >= 0; } public unsafe static int GetEquippedItemSlot(uint itemId) { InventoryManager* ptr = InventoryManager.Instance(); if (ptr == null) { return -1; } InventoryContainer* inventoryContainer = ptr->GetInventoryContainer(InventoryType.EquippedItems); if (inventoryContainer == null) { return -1; } for (int i = 0; i < inventoryContainer->Size; i++) { InventoryItem* inventorySlot = inventoryContainer->GetInventorySlot(i); if (inventorySlot != null && inventorySlot->ItemId == itemId) { return i; } } return -1; } public unsafe static int GetRemainingStackCapacity(uint itemId, ExcelSheet itemSheet) { ArgumentNullException.ThrowIfNull(itemSheet, "itemSheet"); InventoryManager* ptr = InventoryManager.Instance(); if (ptr == null) { return 0; } int num = (int)(itemSheet.GetRowOrDefault(itemId)?.StackSize ?? 0); if (num <= 1) { return 0; } int num2 = 0; for (InventoryType inventoryType = InventoryType.Inventory1; inventoryType <= InventoryType.Inventory4; inventoryType++) { InventoryContainer* inventoryContainer = ptr->GetInventoryContainer(inventoryType); if (inventoryContainer == null) { continue; } for (int i = 0; i < inventoryContainer->Size; i++) { InventoryItem* inventorySlot = inventoryContainer->GetInventorySlot(i); if (inventorySlot != null && inventorySlot->ItemId == itemId && (inventorySlot->Flags & InventoryItem.ItemFlags.HighQuality) == 0) { num2 += num - inventorySlot->Quantity; } } } return num2; } public static int GetMaxHoldableQuantity(uint itemId, ExcelSheet itemSheet) { ArgumentNullException.ThrowIfNull(itemSheet, "itemSheet"); Item? rowOrDefault = itemSheet.GetRowOrDefault(itemId); if (!rowOrDefault.HasValue) { return 0; } if (rowOrDefault.Value.IsUnique) { return (GetItemCount(itemId, checkEquipped: true, checkArmory: true) <= 0) ? 1 : 0; } int stackSize = (int)rowOrDefault.Value.StackSize; if (stackSize <= 0) { return 0; } return GetRemainingStackCapacity(itemId, itemSheet) + CountFreeInventorySlots() * stackSize; } }