Pinning, Hoisting, Recently Lotted

This commit is contained in:
Shawrkie Williams
2026-01-09 17:53:07 -05:00
parent fe7a8136af
commit 665d3b62ba
38 changed files with 802 additions and 268 deletions
+70 -3
View File
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Numerics;
using AetherBags.Inventory.Context;
using AetherBags.Inventory.Items;
using AetherBags.Inventory.State;
using AetherBags.Nodes.Input;
using AetherBags.Nodes.Inventory;
@@ -15,6 +17,7 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
{
private readonly MainBagState _inventoryState = new();
private InventoryNotificationNode _notificationNode = null!;
private LootedItemsCategoryNode _lootedCategoryNode = null!;
protected override InventoryStateBase InventoryState => _inventoryState;
@@ -22,7 +25,7 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
{
InitializeBackgroundDropTarget();
CategoriesNode = new WrappingGridNode<InventoryCategoryNode>
CategoriesNode = new WrappingGridNode<InventoryCategoryNodeBase>
{
Position = ContentStartPosition,
Size = ContentSize,
@@ -33,6 +36,13 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
};
CategoriesNode.AttachNode(this);
_lootedCategoryNode = new LootedItemsCategoryNode
{
ItemsPerLine = 10,
OnDismissItem = OnDismissLootedItem,
OnClearAll = OnClearAllLootedItems,
};
var header = CalculateHeaderLayout(addon);
_notificationNode = new InventoryNotificationNode
@@ -71,14 +81,69 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
addon->SubscribeAtkArrayData(1, (int)NumberArrayType.Inventory);
_isSetupComplete = true;
System.LootedItemsTracker.OnLootedItemsChanged += OnLootedItemsChanged;
IsSetupComplete = true;
_inventoryState.RefreshFromGame();
var existingLoot = System.LootedItemsTracker.LootedItems;
if (existingLoot.Count > 0)
{
UpdateLootedCategory(existingLoot);
}
RefreshCategoriesCore(autosize: true);
base.OnSetup(addon);
}
private void OnLootedItemsChanged(IReadOnlyList<LootedItemInfo> lootedItems)
{
if (!IsOpen || !IsSetupComplete) return;
Services.Framework.RunOnTick(() =>
{
if (!IsOpen) return;
UpdateLootedCategory(lootedItems);
}, delayTicks: 1);
}
private void UpdateLootedCategory(IReadOnlyList<LootedItemInfo> lootedItems)
{
_lootedCategoryNode.UpdateLootedItems(lootedItems);
if (lootedItems.Count > 0)
{
if (CategoriesNode.HoistedNode != _lootedCategoryNode)
{
CategoriesNode.SetHoistedNode(_lootedCategoryNode);
}
}
else
{
using (CategoriesNode.DeferRecalculateLayout())
{
if (CategoriesNode.HoistedNode == _lootedCategoryNode)
{
CategoriesNode.SetHoistedNode(null);
}
CategoriesNode.RemoveNode(_lootedCategoryNode);
}
}
}
private void OnDismissLootedItem(int index)
{
System.LootedItemsTracker.RemoveByIndex(index);
}
private void OnClearAllLootedItems()
{
System.LootedItemsTracker.Clear();
}
public void ManualCurrencyRefresh()
{
if (!Services.ClientState.IsLoggedIn) return;
@@ -95,6 +160,8 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
protected override void OnFinalize(AtkUnitBase* addon)
{
System.LootedItemsTracker.OnLootedItemsChanged -= OnLootedItemsChanged;
ref var blockingAddonId = ref AgentInventoryContext.Instance()->BlockingAddonId;
if (blockingAddonId != 0)
{
@@ -103,7 +170,7 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
addon->UnsubscribeAtkArrayData(1, (int)NumberArrayType.Inventory);
_isSetupComplete = false;
IsSetupComplete = false;
base.OnFinalize(addon);
}
}
+4 -4
View File
@@ -38,7 +38,7 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
WindowNode?.AddColor = _tintColor;
CategoriesNode = new WrappingGridNode<InventoryCategoryNode>
CategoriesNode = new WrappingGridNode<InventoryCategoryNodeBase>
{
Position = ContentStartPosition,
Size = ContentSize,
@@ -107,7 +107,7 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
LayoutContent();
_inventoryState.RefreshFromGame();
_isSetupComplete = true;
IsSetupComplete = true;
RefreshCategoriesCore(autosize: true);
@@ -116,7 +116,7 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
protected override void RefreshCategoriesCore(bool autosize)
{
if (!_isSetupComplete)
if (!IsSetupComplete)
return;
_slotCounterNode.String = _inventoryState.GetEmptySlotsString();
@@ -179,7 +179,7 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
protected override void OnFinalize(AtkUnitBase* addon)
{
_isSetupComplete = false;
IsSetupComplete = false;
CloseRetainerWindows();
+4 -4
View File
@@ -31,7 +31,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
WindowNode?.AddColor = _tintColor;
CategoriesNode = new WrappingGridNode<InventoryCategoryNode>
CategoriesNode = new WrappingGridNode<InventoryCategoryNodeBase>
{
Position = ContentStartPosition,
Size = ContentSize,
@@ -80,7 +80,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
_inventoryState.RefreshFromGame();
_isSetupComplete = true;
IsSetupComplete = true;
RefreshCategoriesCore(autosize: true);
@@ -89,7 +89,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
protected override void RefreshCategoriesCore(bool autosize)
{
if (!_isSetupComplete)
if (!IsSetupComplete)
return;
_slotCounterNode.String = _inventoryState.GetEmptySlotsString();
@@ -99,7 +99,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
protected override void OnFinalize(AtkUnitBase* addon)
{
_isSetupComplete = false;
IsSetupComplete = false;
if (System.Config.General.HideGameSaddleBags)
{
-1
View File
@@ -1,5 +1,4 @@
using AetherBags.Configuration;
using AetherBags.Inventory;
using AetherBags.Inventory.Categories;
using KamiToolKit.Premade;
+3
View File
@@ -1,3 +1,5 @@
using AetherBags.Inventory.Items;
namespace AetherBags.Addons;
public interface IInventoryWindow
@@ -8,4 +10,5 @@ public interface IInventoryWindow
void ManualRefresh();
void ItemRefresh();
void SetSearchText(string searchText);
InventoryStats GetStats();
}
+17 -8
View File
@@ -6,6 +6,7 @@ using AetherBags.Helpers;
using AetherBags.Inventory;
using AetherBags.Inventory.Categories;
using AetherBags.Inventory.Context;
using AetherBags.Inventory.Items;
using AetherBags.Inventory.Scanning;
using AetherBags.Inventory.State;
using AetherBags.Nodes.Input;
@@ -27,7 +28,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
protected readonly HashSet<InventoryCategoryNode> HoverSubscribed = new();
protected DragDropNode BackgroundDropTarget = null!;
protected WrappingGridNode<InventoryCategoryNode> CategoriesNode = null!;
protected WrappingGridNode<InventoryCategoryNodeBase> CategoriesNode = null!;
protected TextInputWithButtonNode SearchInputNode = null!;
protected InventoryFooterNode FooterNode = null!;
protected TextNode? SlotCounterNode { get; set; }
@@ -49,8 +50,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
protected bool RefreshQueued;
protected bool RefreshAutosizeQueued;
private bool _isRefreshing;
protected bool _isSetupComplete;
protected bool IsSetupComplete;
protected abstract InventoryStateBase InventoryState { get; }
@@ -59,13 +59,14 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
protected virtual bool HasSlotCounter => false;
private readonly HashSet<uint> _searchMatchScratch = new();
private bool _isRefreshing;
public void ManualRefresh()
{
if (!IsOpen) return;
if (!Services.ClientState.IsLoggedIn) return;
if (_isRefreshing) return;
if (!_isSetupComplete) return;
if (!IsSetupComplete) return;
try
{
@@ -82,6 +83,8 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
public string GetSearchText() => SearchInputNode?.SearchString.ExtractText() ?? string.Empty;
public InventoryStats GetStats() => InventoryState.GetStats();
public virtual void SetSearchText(string searchText)
{
Services.Framework.RunOnTick(() =>
@@ -93,7 +96,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
public void RefreshFromLifecycle()
{
if (!_isSetupComplete) return;
if (!IsSetupComplete) return;
if (!IsOpen) return;
if (_isRefreshing) return;
@@ -111,7 +114,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
protected virtual void RefreshCategoriesCore(bool autosize)
{
if (!_isSetupComplete)
if (!IsSetupComplete)
return;
var config = System.Config.General;
@@ -166,7 +169,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
CategoriesNode.SyncWithListDataByKey<CategorizedInventory, InventoryCategoryNode, uint>(
dataList: categories,
getKeyFromData: categorizedInventory => categorizedInventory.Key,
getKeyFromNode: node => node.CategorizedInventory.Key,
getKeyFromNode: node => node.Key,
updateNode: (node, data) =>
{
node.CategorizedInventory = data;
@@ -394,7 +397,13 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
protected void ResizeWindow(float width, float height)
=> ResizeWindow(width, height, recalcLayout: true);
public void ItemRefresh() => RefreshCategoriesCore(false);
public void ItemRefresh()
{
if (!IsOpen) return;
if (!IsSetupComplete) return;
RefreshCategoriesCore(false);
}
protected override void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
{
@@ -1,4 +1,3 @@
using System;
using AetherBags.Configuration;
using AetherBags.Inventory;
using AetherBags.Inventory.Context;