qstbak/LLib/LLib.Inventory/InventoryHelper.cs
2026-08-17 20:29:32 +10:00

184 lines
4.9 KiB
C#

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<int> 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<Item> 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<Item> 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;
}
}