More changes
This commit is contained in:
@@ -0,0 +1,120 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using AetherBags.Inventory.State;
|
||||||
|
using AetherBags.Nodes.Input;
|
||||||
|
using AetherBags.Nodes.Inventory;
|
||||||
|
using AetherBags.Nodes.Layout;
|
||||||
|
using Dalamud.Game.Addon.Lifecycle;
|
||||||
|
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
using KamiToolKit.Nodes;
|
||||||
|
|
||||||
|
namespace AetherBags.Addons;
|
||||||
|
|
||||||
|
public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
||||||
|
{
|
||||||
|
private readonly SaddleBagState _inventoryState = new();
|
||||||
|
|
||||||
|
protected override InventoryStateBase InventoryState => _inventoryState;
|
||||||
|
|
||||||
|
protected override bool HasFooter => false;
|
||||||
|
|
||||||
|
protected override float MinWindowWidth => 400;
|
||||||
|
protected override float MaxWindowWidth => 600;
|
||||||
|
|
||||||
|
protected override void OnSetup(AtkUnitBase* addon)
|
||||||
|
{
|
||||||
|
CategoriesNode = new WrappingGridNode<InventoryCategoryNode>
|
||||||
|
{
|
||||||
|
Position = ContentStartPosition,
|
||||||
|
Size = ContentSize,
|
||||||
|
HorizontalSpacing = CategorySpacing,
|
||||||
|
VerticalSpacing = CategorySpacing,
|
||||||
|
TopPadding = 4.0f,
|
||||||
|
BottomPadding = 4.0f,
|
||||||
|
};
|
||||||
|
CategoriesNode.AttachNode(this);
|
||||||
|
|
||||||
|
var size = new Vector2(addon->Size.X / 2.0f, 28.0f);
|
||||||
|
|
||||||
|
var header = addon->WindowHeaderCollisionNode;
|
||||||
|
|
||||||
|
float headerX = header->X;
|
||||||
|
float headerY = header->Y;
|
||||||
|
float headerW = header->Width;
|
||||||
|
float headerH = header->Height;
|
||||||
|
|
||||||
|
float x = headerX + (headerW - size.X) * 0.5f;
|
||||||
|
float y = headerY + (headerH - size.Y) * 0.5f;
|
||||||
|
|
||||||
|
SearchInputNode = new TextInputWithHintNode
|
||||||
|
{
|
||||||
|
Position = new Vector2(x, y),
|
||||||
|
Size = size,
|
||||||
|
OnInputReceived = _ => RefreshCategoriesCore(autosize: false),
|
||||||
|
};
|
||||||
|
SearchInputNode.AttachNode(this);
|
||||||
|
|
||||||
|
SettingsButtonNode = new CircleButtonNode
|
||||||
|
{
|
||||||
|
Position = new Vector2(headerW - 48f, y),
|
||||||
|
Size = new Vector2(28f),
|
||||||
|
Icon = ButtonIcon.GearCog,
|
||||||
|
OnClick = System.AddonConfigurationWindow.Toggle
|
||||||
|
};
|
||||||
|
SettingsButtonNode.AttachNode(this);
|
||||||
|
|
||||||
|
LayoutContent();
|
||||||
|
|
||||||
|
Services.AddonLifecycle.RegisterListener(AddonEvent.PostRequestedUpdate, "InventoryBuddy", OnSaddleBagUpdate);
|
||||||
|
|
||||||
|
_inventoryState.RefreshFromGame();
|
||||||
|
RefreshCategoriesCore(autosize: true);
|
||||||
|
|
||||||
|
base.OnSetup(addon);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(AtkUnitBase* addon)
|
||||||
|
{
|
||||||
|
if (RefreshQueued)
|
||||||
|
{
|
||||||
|
bool doAutosize = RefreshAutosizeQueued;
|
||||||
|
RefreshQueued = false;
|
||||||
|
RefreshAutosizeQueued = false;
|
||||||
|
|
||||||
|
RefreshCategoriesCore(doAutosize);
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnUpdate(addon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSaddleBagUpdate(AddonEvent type, AddonArgs args)
|
||||||
|
{
|
||||||
|
_inventoryState.RefreshFromGame();
|
||||||
|
RefreshCategoriesCore(autosize: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
|
||||||
|
{
|
||||||
|
base.OnRequestedUpdate(addon, numberArrayData, stringArrayData);
|
||||||
|
|
||||||
|
_inventoryState.RefreshFromGame();
|
||||||
|
RefreshCategoriesCore(autosize: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSearchText(string searchText)
|
||||||
|
{
|
||||||
|
Services.Framework.RunOnTick(() =>
|
||||||
|
{
|
||||||
|
if (IsOpen) SearchInputNode.SearchString = searchText;
|
||||||
|
RefreshCategoriesCore(autosize: true);
|
||||||
|
}, delayTicks: 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFinalize(AtkUnitBase* addon)
|
||||||
|
{
|
||||||
|
Services.AddonLifecycle.UnregisterListener(OnSaddleBagUpdate);
|
||||||
|
|
||||||
|
base.OnFinalize(addon);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -91,6 +91,10 @@ public class CommandHandler : IDisposable
|
|||||||
PrintChat($"{stats.UsedSlots}/{stats.TotalSlots} slots used ({stats.UsagePercent:F0}%) | {stats.TotalItems} unique items | {stats.CategoryCount} categories");
|
PrintChat($"{stats.UsedSlots}/{stats.TotalSlots} slots used ({stats.UsagePercent:F0}%) | {stats.TotalItems} unique items | {stats.CategoryCount} categories");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "saddle":
|
||||||
|
System.AddonSaddleBagWindow.Toggle();
|
||||||
|
break;
|
||||||
|
|
||||||
case "help":
|
case "help":
|
||||||
case "?":
|
case "?":
|
||||||
PrintHelp();
|
PrintHelp();
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public static unsafe class InventoryScanner
|
|||||||
public static ulong MakeNaturalSlotKey(InventoryType container, int slot)
|
public static ulong MakeNaturalSlotKey(InventoryType container, int slot)
|
||||||
=> ((ulong)(uint)container << 32) | (uint)slot;
|
=> ((ulong)(uint)container << 32) | (uint)slot;
|
||||||
|
|
||||||
// Backwards compatible
|
// Backwards compatible TODO: Remove
|
||||||
public static void ScanBags(
|
public static void ScanBags(
|
||||||
InventoryManager* inventoryManager,
|
InventoryManager* inventoryManager,
|
||||||
InventoryStackMode stackMode,
|
InventoryStackMode stackMode,
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ public enum InventorySourceType
|
|||||||
{
|
{
|
||||||
MainBags,
|
MainBags,
|
||||||
SaddleBag,
|
SaddleBag,
|
||||||
|
PremiumSaddleBag,
|
||||||
|
AllSaddleBags,
|
||||||
Retainer,
|
Retainer,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,6 +22,18 @@ public static class InventorySourceDefinitions
|
|||||||
];
|
];
|
||||||
|
|
||||||
public static readonly InventoryType[] SaddleBag =
|
public static readonly InventoryType[] SaddleBag =
|
||||||
|
[
|
||||||
|
InventoryType.SaddleBag1,
|
||||||
|
InventoryType.SaddleBag2,
|
||||||
|
];
|
||||||
|
|
||||||
|
public static readonly InventoryType[] PremiumSaddleBag =
|
||||||
|
[
|
||||||
|
InventoryType.PremiumSaddleBag1,
|
||||||
|
InventoryType.PremiumSaddleBag2,
|
||||||
|
];
|
||||||
|
|
||||||
|
public static readonly InventoryType[] AllSaddleBags =
|
||||||
[
|
[
|
||||||
InventoryType.SaddleBag1,
|
InventoryType.SaddleBag1,
|
||||||
InventoryType.SaddleBag2,
|
InventoryType.SaddleBag2,
|
||||||
@@ -49,7 +63,9 @@ public static class InventorySourceDefinitions
|
|||||||
public static int GetTotalSlots(InventorySourceType source) => source switch
|
public static int GetTotalSlots(InventorySourceType source) => source switch
|
||||||
{
|
{
|
||||||
InventorySourceType.MainBags => 140, // 4 * 35
|
InventorySourceType.MainBags => 140, // 4 * 35
|
||||||
InventorySourceType.SaddleBag => 70, // 2 * 35 TODO: Premium adds another 70
|
InventorySourceType.SaddleBag => 70, // 2 * 35
|
||||||
|
InventorySourceType.PremiumSaddleBag => 70, // 2 * 35
|
||||||
|
InventorySourceType.AllSaddleBags => 140, // 2 * 35
|
||||||
InventorySourceType.Retainer => 175, // 7 * 25
|
InventorySourceType.Retainer => 175, // 7 * 25
|
||||||
_ => 140,
|
_ => 140,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,27 @@
|
|||||||
using AetherBags.Inventory.Scanning;
|
using AetherBags.Inventory.Scanning;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game.UI;
|
||||||
|
|
||||||
namespace AetherBags.Inventory.State;
|
namespace AetherBags.Inventory.State;
|
||||||
|
|
||||||
public class SaddleBagState : InventoryStateBase
|
public class SaddleBagState : InventoryStateBase
|
||||||
{
|
{
|
||||||
public override InventorySourceType SourceType => InventorySourceType.SaddleBag;
|
public override InventorySourceType SourceType => HasPremiumSaddlebag
|
||||||
public override InventoryType[] Inventories => InventorySourceDefinitions.SaddleBag;
|
? InventorySourceType.AllSaddleBags
|
||||||
|
: InventorySourceType.SaddleBag;
|
||||||
|
|
||||||
|
public override InventoryType[] Inventories => HasPremiumSaddlebag
|
||||||
|
? InventorySourceDefinitions.AllSaddleBags
|
||||||
|
: InventorySourceDefinitions.SaddleBag;
|
||||||
|
|
||||||
|
private static unsafe bool HasPremiumSaddlebag
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!Services.ClientState.IsLoggedIn) return false;
|
||||||
|
|
||||||
|
var playerState = PlayerState.Instance();
|
||||||
|
return playerState != null && playerState->HasPremiumSaddlebag;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ public sealed class InventoryNotificationNode : SimpleComponentNode
|
|||||||
|
|
||||||
Timeline?.PlayAnimation(101);
|
Timeline?.PlayAnimation(101);
|
||||||
}
|
}
|
||||||
}
|
} = null!;
|
||||||
|
|
||||||
// Future Zeff, this always goes on a parent
|
// Future Zeff, this always goes on a parent
|
||||||
private Timeline ParentLabels => new TimelineBuilder()
|
private Timeline ParentLabels => new TimelineBuilder()
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System. Numerics;
|
||||||
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
using KamiToolKit.Classes;
|
||||||
|
using KamiToolKit.Nodes;
|
||||||
|
|
||||||
|
namespace AetherBags.Nodes.Inventory;
|
||||||
|
|
||||||
|
public class SaddleBagFooterNode : SimpleComponentNode
|
||||||
|
{
|
||||||
|
private readonly TextNode _slotCounterNode;
|
||||||
|
|
||||||
|
private const float Padding = 8f;
|
||||||
|
|
||||||
|
public SaddleBagFooterNode()
|
||||||
|
{
|
||||||
|
_slotCounterNode = new TextNode
|
||||||
|
{
|
||||||
|
Position = new Vector2(Padding, 4f),
|
||||||
|
Size = new Vector2(100, 20),
|
||||||
|
AlignmentType = AlignmentType.Left,
|
||||||
|
TextColor = new Vector4(1f, 1f, 1f, 1f),
|
||||||
|
FontSize = 14,
|
||||||
|
};
|
||||||
|
_slotCounterNode.AttachNode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SlotAmountText
|
||||||
|
{
|
||||||
|
get => _slotCounterNode.String;
|
||||||
|
set => _slotCounterNode.String = $"Slots: {value}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,14 @@ public unsafe class Plugin : IDalamudPlugin
|
|||||||
|
|
||||||
System.AddonInventoryWindow = new AddonInventoryWindow
|
System.AddonInventoryWindow = new AddonInventoryWindow
|
||||||
{
|
{
|
||||||
InternalName = "AetherBags",
|
InternalName = "AetherBags_MainBags",
|
||||||
|
Title = "AetherBags",
|
||||||
|
Size = new Vector2(750, 750),
|
||||||
|
};
|
||||||
|
|
||||||
|
System.AddonSaddleBagWindow = new AddonSaddleBagWindow
|
||||||
|
{
|
||||||
|
InternalName = "AetherBags_SaddleBag",
|
||||||
Title = "AetherBags",
|
Title = "AetherBags",
|
||||||
Size = new Vector2(750, 750),
|
Size = new Vector2(750, 750),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ public class Services
|
|||||||
[PluginService] public static IGameGui GameGui { get; private set; } = null!;
|
[PluginService] public static IGameGui GameGui { get; private set; } = null!;
|
||||||
[PluginService] public static IGameInventory GameInventory { get; set; } = null!;
|
[PluginService] public static IGameInventory GameInventory { get; set; } = null!;
|
||||||
[PluginService] public static IKeyState KeyState { get; private set; } = null!;
|
[PluginService] public static IKeyState KeyState { get; private set; } = null!;
|
||||||
|
[PluginService] public static IPlayerState PlayerState { get; private set; } = null!;
|
||||||
[PluginService] public static IPluginLog Logger { get; private set; } = null!;
|
[PluginService] public static IPluginLog Logger { get; private set; } = null!;
|
||||||
[PluginService] public static INotificationManager NotificationManager { get; private set; } = null!;
|
[PluginService] public static INotificationManager NotificationManager { get; private set; } = null!;
|
||||||
|
[PluginService] public static IObjectTable ObjectTable { get; private set; } = null!;
|
||||||
// TODO: Remove cause temp
|
// TODO: Remove cause temp
|
||||||
[PluginService] public static ISigScanner SigScanner { get; private set; } = null!;
|
[PluginService] public static ISigScanner SigScanner { get; private set; } = null!;
|
||||||
[PluginService] public static IGameInteropProvider GameInteropProvider { get; private set; } = null!;
|
[PluginService] public static IGameInteropProvider GameInteropProvider { get; private set; } = null!;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ namespace AetherBags;
|
|||||||
public static class System
|
public static class System
|
||||||
{
|
{
|
||||||
public static AddonInventoryWindow AddonInventoryWindow { get; set; } = null!;
|
public static AddonInventoryWindow AddonInventoryWindow { get; set; } = null!;
|
||||||
public static AddonInventoryWindow AddonSaddleBagWindow { get; set; } = null!;
|
public static AddonSaddleBagWindow AddonSaddleBagWindow { get; set; } = null!;
|
||||||
public static AddonInventoryWindow AddonRetainerWindow { get; set; } = null!;
|
//public static AddonRetainerWindow AddonRetainerWindow { get; set; } = null!;
|
||||||
public static AddonConfigurationWindow AddonConfigurationWindow { get; set; } = null!;
|
public static AddonConfigurationWindow AddonConfigurationWindow { get; set; } = null!;
|
||||||
public static SystemConfiguration Config { get; set; } = null!;
|
public static SystemConfiguration Config { get; set; } = null!;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user