using System; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; using Lumina.Excel.Sheets; namespace LLib.Inventory; public readonly record struct ItemHandle(uint RawId) { public uint Id { get { if (RawId < 1000000) { return RawId; } return RawId % 1000000; } } public bool IsHq => RawId >= 1000000; private const uint HqThreshold = 1000000u; public static implicit operator ItemHandle(uint itemId) { return new ItemHandle(itemId); } public static ItemHandle FromUInt32(uint itemId) { return new ItemHandle(itemId); } public static implicit operator uint(ItemHandle handle) { return handle.Id; } public uint ToUInt32() { return Id; } public unsafe static ItemHandle FromInventorySlot(InventoryItem* slot) { if (slot == null) { return new ItemHandle(0u); } return new ItemHandle(slot->ItemId); } public unsafe int GetCount(bool checkEquipped = false, bool checkArmory = false) { InventoryManager* ptr = InventoryManager.Instance(); if (ptr == null) { return 0; } return ptr->GetInventoryItemCount(Id, isHq: false, checkEquipped, checkArmory, 0) + ptr->GetInventoryItemCount(Id, isHq: true, checkEquipped, checkArmory, 0); } public int GetCountInContainer(InventoryType container) { return InventoryHelper.GetItemCount(Id, container); } public int CountInContainers(ReadOnlySpan containers) { return InventoryContainers.CountItems(Id, containers); } public bool HasItem(bool checkEquipped = false, bool checkArmory = false) { return GetCount(checkEquipped, checkArmory) > 0; } public bool IsEquipped() { return InventoryHelper.IsItemEquipped(Id); } public int GetEquippedSlot() { return InventoryHelper.GetEquippedItemSlot(Id); } public Item? GetRow(IDataManager dataManager) { return dataManager.GetExcelSheet().GetRowOrDefault(Id); } public uint GetItemLevel(IDataManager dataManager) { return GetRow(dataManager)?.LevelItem.RowId ?? 0; } }