Basic Saddlebags
This commit is contained in:
@@ -17,7 +17,8 @@ public class InventoryLifecycles : IDisposable
|
||||
|
||||
public InventoryLifecycles()
|
||||
{
|
||||
Services.AddonLifecycle.RegisterListener(AddonEvent.PreRefresh, ["Inventory", "InventoryLarge", "InventoryExpansion"], PreRefreshHandler);
|
||||
Services.AddonLifecycle.RegisterListener(AddonEvent.PreRefresh, ["Inventory", "InventoryLarge", "InventoryExpansion"], InventoryPreRefreshHandler);
|
||||
Services.AddonLifecycle.RegisterListener(AddonEvent.PreRefresh, ["InventoryBuddy"], InventoryBuddyPreRefreshHandler);
|
||||
Services.Logger.Verbose("InventoryLifecycles initialized");
|
||||
}
|
||||
|
||||
@@ -32,7 +33,7 @@ public class InventoryLifecycles : IDisposable
|
||||
values[7] = can use Saddlebags (Agent InventoryBuddy IsActivatable)
|
||||
*/
|
||||
|
||||
private unsafe void PreRefreshHandler(AddonEvent type, AddonArgs args)
|
||||
private unsafe void InventoryPreRefreshHandler(AddonEvent type, AddonArgs args)
|
||||
{
|
||||
if (args is not AddonRefreshArgs refreshArgs)
|
||||
return;
|
||||
@@ -69,8 +70,23 @@ public class InventoryLifecycles : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private void InventoryBuddyPreRefreshHandler(AddonEvent type, AddonArgs args)
|
||||
{
|
||||
if (args is not AddonRefreshArgs refreshArgs)
|
||||
return;
|
||||
|
||||
GeneralSettings config = System.Config.General;
|
||||
|
||||
if (config.HideGameSaddleBags) refreshArgs.AtkValueCount = 0;
|
||||
if (config.OpenSaddleBagsWithGameInventory)
|
||||
{
|
||||
System.AddonSaddleBagWindow.Toggle();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Services.AddonLifecycle.UnregisterListener(AddonEvent.PreRefresh, ["Inventory", "InventoryLarge", "InventoryExpansion"]);
|
||||
Services.AddonLifecycle.UnregisterListener(AddonEvent.PreRefresh, ["InventoryBuddy"]);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Dalamud.Game.Addon.Lifecycle;
|
||||
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using KamiToolKit.Classes;
|
||||
using KamiToolKit.Nodes;
|
||||
|
||||
namespace AetherBags.Addons;
|
||||
@@ -14,16 +15,20 @@ namespace AetherBags.Addons;
|
||||
public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
||||
{
|
||||
private readonly SaddleBagState _inventoryState = new();
|
||||
private TextNode _slotCounterNode = null!;
|
||||
|
||||
protected override InventoryStateBase InventoryState => _inventoryState;
|
||||
|
||||
protected override bool HasFooter => false;
|
||||
protected override bool HasSlotCounter => true;
|
||||
|
||||
protected override float MinWindowWidth => 400;
|
||||
protected override float MaxWindowWidth => 600;
|
||||
|
||||
protected override void OnSetup(AtkUnitBase* addon)
|
||||
{
|
||||
WindowNode?.AddColor = new Vector3(-16f / 255f, -4f / 255f, 8f / 255f);
|
||||
|
||||
CategoriesNode = new WrappingGridNode<InventoryCategoryNode>
|
||||
{
|
||||
Position = ContentStartPosition,
|
||||
@@ -64,6 +69,19 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
||||
};
|
||||
SettingsButtonNode.AttachNode(this);
|
||||
|
||||
_slotCounterNode = new TextNode
|
||||
{
|
||||
Position = new Vector2(Size.X - 10, 0),
|
||||
Size = new Vector2(82, 20),
|
||||
AlignmentType = AlignmentType.Right,
|
||||
FontType = FontType.MiedingerMed,
|
||||
TextFlags = TextFlags.Glare,
|
||||
TextColor = ColorHelper.GetColor(50),
|
||||
TextOutlineColor = ColorHelper.GetColor(32) // Could also be Color 65
|
||||
};
|
||||
_slotCounterNode.AttachNode(this);
|
||||
SlotCounterNode = _slotCounterNode;
|
||||
|
||||
LayoutContent();
|
||||
|
||||
Services.AddonLifecycle.RegisterListener(AddonEvent.PostRequestedUpdate, "InventoryBuddy", OnSaddleBagUpdate);
|
||||
@@ -74,6 +92,13 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
||||
base.OnSetup(addon);
|
||||
}
|
||||
|
||||
protected override void RefreshCategoriesCore(bool autosize)
|
||||
{
|
||||
_slotCounterNode.String = _inventoryState.GetEmptySlotsString();
|
||||
|
||||
base.RefreshCategoriesCore(autosize);
|
||||
}
|
||||
|
||||
protected override void OnUpdate(AtkUnitBase* addon)
|
||||
{
|
||||
if (RefreshQueued)
|
||||
|
||||
@@ -21,6 +21,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon
|
||||
protected WrappingGridNode<InventoryCategoryNode> CategoriesNode = null!;
|
||||
protected TextInputWithHintNode SearchInputNode = null!;
|
||||
protected InventoryFooterNode FooterNode = null!;
|
||||
protected TextNode? SlotCounterNode { get; set; }
|
||||
protected CircleButtonNode SettingsButtonNode = null!;
|
||||
|
||||
protected virtual float MinWindowWidth => 600;
|
||||
@@ -41,6 +42,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon
|
||||
|
||||
protected virtual bool HasFooter => true;
|
||||
protected virtual bool HasPinning => true;
|
||||
protected virtual bool HasSlotCounter => false;
|
||||
|
||||
public void ManualInventoryRefresh()
|
||||
{
|
||||
@@ -127,10 +129,16 @@ public abstract unsafe class InventoryAddonBase : NativeAddon
|
||||
Vector2 contentPos = ContentStartPosition;
|
||||
Vector2 contentSize = ContentSize;
|
||||
|
||||
float footerH = HasFooter || HasSlotCounter ? FooterHeight : 0;
|
||||
|
||||
if (HasFooter)
|
||||
{
|
||||
FooterNode.Position = new Vector2(contentPos.X, contentPos.Y + contentSize.Y - FooterHeight);
|
||||
FooterNode.Size = new Vector2(contentSize.X, FooterHeight);
|
||||
FooterNode.Position = new Vector2(contentPos.X, contentPos.Y + contentSize.Y - footerH);
|
||||
FooterNode.Size = new Vector2(contentSize.X, footerH);
|
||||
}
|
||||
else if (HasSlotCounter && SlotCounterNode != null)
|
||||
{
|
||||
SlotCounterNode.Position = new Vector2(contentSize.X -80f, contentPos.Y + contentSize.Y - footerH + 4f);
|
||||
}
|
||||
|
||||
float gridH = contentSize.Y - (HasFooter ? FooterHeight + FooterTopSpacing : 0);
|
||||
@@ -168,7 +176,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon
|
||||
|
||||
float contentWidth = finalWidth - (ContentStartPosition.X * 2);
|
||||
|
||||
float footerSpace = HasFooter ? FooterHeight + FooterTopSpacing : 0;
|
||||
float footerSpace = HasFooter || HasSlotCounter ? FooterHeight + FooterTopSpacing : 0;
|
||||
float gridBudget = Math.Max(0f, MaxWindowHeight - footerSpace);
|
||||
|
||||
CategoriesNode.Position = ContentStartPosition;
|
||||
|
||||
@@ -10,6 +10,8 @@ public class GeneralSettings
|
||||
public bool CompactStableInsert { get; set; } = true;
|
||||
public bool OpenWithGameInventory { get; set; } = true;
|
||||
public bool HideGameInventory { get; set; } = false;
|
||||
public bool OpenSaddleBagsWithGameInventory { get; set; } = true;
|
||||
public bool HideGameSaddleBags { get; set; } = false;
|
||||
public bool ShowCategoryItemCount { get; set; } = false;
|
||||
public bool LinkItemEnabled { get; set; } = false;
|
||||
}
|
||||
|
||||
@@ -115,6 +115,9 @@ public static unsafe class InventoryItemExtensions {
|
||||
if (InventoryManager.Instance()->GetInventoryItemCount(itemId, true) > 0)
|
||||
itemId += 1_000_000;
|
||||
|
||||
if (!item.Container.IsMainInventory)
|
||||
return;
|
||||
|
||||
AgentInventoryContext.Instance()->UseItem(itemId, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +165,8 @@ public static unsafe class InventoryTypeExtensions
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
public bool IsLoaded => InventoryManager.Instance()->GetInventoryContainer(inventoryType)->IsLoaded;
|
||||
|
||||
public bool IsSameContainerGroup(InventoryType other)
|
||||
=> inventoryType.ContainerGroup == other.ContainerGroup;
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace AetherBags. Helpers;
|
||||
|
||||
public static unsafe class InventoryMoveHelper
|
||||
{
|
||||
// Requires the visual UI slots instead of actual slots.
|
||||
public static void MoveItem(InventoryType sourceContainer, ushort sourceSlot, InventoryType destContainer, ushort destSlot)
|
||||
{
|
||||
Services.Logger.Debug($"[MoveItem] {sourceContainer}@{sourceSlot} -> {destContainer}@{destSlot}");
|
||||
|
||||
@@ -272,6 +272,9 @@ public class InventoryCategoryNode : SimpleComponentNode
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug: log raw payload values
|
||||
Services. Logger.Debug($"[OnPayload] Raw payload: Type={payload.Type} Int1={payload.Int1} Int2={payload.Int2}");
|
||||
|
||||
InventoryLocation sourceLocation = payload.InventoryLocation;
|
||||
|
||||
if (! sourceLocation.IsValid)
|
||||
@@ -285,6 +288,11 @@ public class InventoryCategoryNode : SimpleComponentNode
|
||||
(ushort)item.Slot
|
||||
);
|
||||
|
||||
// Debug: log resolved locations
|
||||
Services.Logger.Debug($"[OnPayload] Source: {sourceLocation. Container} @ {sourceLocation. Slot}");
|
||||
Services.Logger.Debug($"[OnPayload] Target: {targetLocation.Container} @ {targetLocation.Slot}");
|
||||
|
||||
|
||||
if (sourceLocation.Container.IsSameContainerGroup(targetLocation.Container))
|
||||
{
|
||||
Services.Logger.Debug($"[OnPayload] Source and target are in the same container group; no move performed");
|
||||
@@ -294,6 +302,12 @@ public class InventoryCategoryNode : SimpleComponentNode
|
||||
return;
|
||||
};
|
||||
|
||||
if (!sourceLocation.Container.IsLoaded || !targetLocation.Container.IsLoaded)
|
||||
{
|
||||
Services.Logger.Debug($"[OnPayload] Source or target container is not loaded; cannot move");
|
||||
return;
|
||||
}
|
||||
|
||||
Services.Logger.Debug($"[OnPayload] Moving {sourceLocation} -> {targetLocation}");
|
||||
|
||||
InventoryMoveHelper.MoveItem(
|
||||
|
||||
@@ -80,6 +80,8 @@ public unsafe class Plugin : IDalamudPlugin
|
||||
_commandHandler.Dispose();
|
||||
|
||||
System.AddonInventoryWindow.Dispose();
|
||||
System.AddonSaddleBagWindow.Dispose();
|
||||
//System.AddonRetainerWindow.Dispose();
|
||||
System.AddonConfigurationWindow.Dispose();
|
||||
|
||||
KamiToolKitLibrary.Dispose();
|
||||
@@ -104,6 +106,7 @@ public unsafe class Plugin : IDalamudPlugin
|
||||
Util.SaveConfig(System.Config);
|
||||
InventoryState.TrackLootedItems = false;
|
||||
System.AddonInventoryWindow.Close();
|
||||
System.AddonSaddleBagWindow.Close();
|
||||
System.AddonConfigurationWindow.Close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user