diff --git a/LLib b/LLib index 43c3dba..fde09c7 160000 --- a/LLib +++ b/LLib @@ -1 +1 @@ -Subproject commit 43c3dba112c202e2d0ff1a6909020c2b83e20dc3 +Subproject commit fde09c705b648f03c287814191a554f0a4b92cc4 diff --git a/Workshoppa/GameData/Shops/ItemForSale.cs b/Workshoppa/GameData/Shops/ItemForSale.cs deleted file mode 100644 index ab012d1..0000000 --- a/Workshoppa/GameData/Shops/ItemForSale.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Workshoppa.GameData.Shops; - -internal sealed class ItemForSale -{ - public required int Position { get; init; } - public required uint ItemId { get; init; } - public required string? ItemName { get; init; } - public required uint Price { get; init; } - public required uint OwnedItems { get; init; } -} diff --git a/Workshoppa/GameData/Shops/PurchaseState.cs b/Workshoppa/GameData/Shops/PurchaseState.cs deleted file mode 100644 index 36245df..0000000 --- a/Workshoppa/GameData/Shops/PurchaseState.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace Workshoppa.GameData.Shops; - -internal sealed class PurchaseState -{ - public PurchaseState(int desiredItems, int ownedItems) - { - DesiredItems = desiredItems; - OwnedItems = ownedItems; - } - - public int DesiredItems { get; } - public int OwnedItems { get; set; } - public int ItemsLeftToBuy => Math.Max(0, DesiredItems - OwnedItems); - public bool IsComplete => ItemsLeftToBuy == 0; - public bool IsAwaitingYesNo { get; set; } - public DateTime NextStep { get; set; } = DateTime.MinValue; -} diff --git a/Workshoppa/Windows/CeruleumTankWindow.cs b/Workshoppa/Windows/CeruleumTankWindow.cs index beb19c2..8b58530 100644 --- a/Workshoppa/Windows/CeruleumTankWindow.cs +++ b/Workshoppa/Windows/CeruleumTankWindow.cs @@ -5,10 +5,9 @@ using Dalamud.Interface.Components; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; -using LLib; using LLib.GameUI; +using LLib.Shop.Model; using Workshoppa.External; -using Workshoppa.GameData.Shops; using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType; namespace Workshoppa.Windows; @@ -17,7 +16,6 @@ internal sealed class CeruleumTankWindow : ShopWindow { private const int CeruleumTankItemId = 10155; - private readonly WorkshopPlugin _plugin; private readonly IPluginLog _pluginLog; private readonly Configuration _configuration; private readonly IChatGui _chatGui; @@ -26,28 +24,31 @@ internal sealed class CeruleumTankWindow : ShopWindow private int _buyStackCount; private bool _buyPartialStacks = true; - public CeruleumTankWindow(WorkshopPlugin plugin, IPluginLog pluginLog, IGameGui gameGui, - IAddonLifecycle addonLifecycle, Configuration configuration, ExternalPluginHandler externalPluginHandler, + public CeruleumTankWindow( + IPluginLog pluginLog, + IGameGui gameGui, + IAddonLifecycle addonLifecycle, + Configuration configuration, + ExternalPluginHandler externalPluginHandler, IChatGui chatGui) - : base("Ceruleum Tanks###WorkshoppaCeruleumTankWindow", "FreeCompanyCreditShop", plugin, pluginLog, gameGui, + : base("Ceruleum Tanks###WorkshoppaCeruleumTankWindow", "FreeCompanyCreditShop", pluginLog, gameGui, addonLifecycle, externalPluginHandler) { - _plugin = plugin; _pluginLog = pluginLog; _chatGui = chatGui; _configuration = configuration; } - protected override bool Enabled => _configuration.EnableCeruleumTankCalculator; + public override bool IsEnabled => _configuration.EnableCeruleumTankCalculator; - protected override unsafe void UpdateShopStock(AtkUnitBase* addon) + public override unsafe void UpdateShopStock(AtkUnitBase* addon) { if (addon->AtkValuesCount != 170) { _pluginLog.Error( $"Unexpected amount of atkvalues for FreeCompanyCreditShop addon ({addon->AtkValuesCount})"); _companyCredits = 0; - ItemForSale = null; + Shop.ItemForSale = null; return; } @@ -57,11 +58,11 @@ internal sealed class CeruleumTankWindow : ShopWindow uint itemCount = atkValues[9].UInt; if (itemCount == 0) { - ItemForSale = null; + Shop.ItemForSale = null; return; } - ItemForSale = Enumerable.Range(0, (int)itemCount) + Shop.ItemForSale = Enumerable.Range(0, (int)itemCount) .Select(i => new ItemForSale { Position = i, @@ -73,18 +74,18 @@ internal sealed class CeruleumTankWindow : ShopWindow .FirstOrDefault(x => x.ItemId == CeruleumTankItemId); } - protected override int GetCurrencyCount() => _companyCredits; + public override int GetCurrencyCount() => _companyCredits; public override void Draw() { - if (ItemForSale == null) + if (Shop.ItemForSale == null) { IsOpen = false; return; } - int ceruleumTanks = GetItemCount(CeruleumTankItemId); - int freeInventorySlots = _plugin.CountFreeInventorySlots(); + int ceruleumTanks = Shop.GetItemCount(CeruleumTankItemId); + int freeInventorySlots = Shop.CountFreeInventorySlots(); ImGui.Text("Inventory"); ImGui.Indent(); @@ -94,7 +95,7 @@ internal sealed class CeruleumTankWindow : ShopWindow ImGui.Separator(); - if (PurchaseState == null) + if (Shop.PurchaseState == null) { ImGui.SetNextItemWidth(100); ImGui.InputInt("Stacks to Buy", ref _buyStackCount); @@ -108,27 +109,27 @@ internal sealed class CeruleumTankWindow : ShopWindow if (_buyPartialStacks && ceruleumTanks % 999 > 0) missingItems += (999 - ceruleumTanks % 999); - if (PurchaseState != null) + if (Shop.PurchaseState != null) { - HandleNextPurchaseStep(); - if (PurchaseState != null) + Shop.HandleNextPurchaseStep(); + if (Shop.PurchaseState != null) { - ImGui.Text($"Buying {FormatStackCount(PurchaseState.ItemsLeftToBuy)}..."); + ImGui.Text($"Buying {FormatStackCount(Shop.PurchaseState.ItemsLeftToBuy)}..."); if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Times, "Cancel Auto-Buy")) - CancelAutoPurchase(); + Shop.CancelAutoPurchase(); } } else { - int toPurchase = Math.Min(GetMaxItemsToPurchase(), missingItems); + int toPurchase = Math.Min(Shop.GetMaxItemsToPurchase(), missingItems); if (toPurchase > 0) { ImGui.Spacing(); if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.DollarSign, - $"Auto-Buy {FormatStackCount(toPurchase)} for {ItemForSale.Price * toPurchase:N0} CC")) + $"Auto-Buy {FormatStackCount(toPurchase)} for {Shop.ItemForSale.Price * toPurchase:N0} CC")) { - StartAutoPurchase(toPurchase); - HandleNextPurchaseStep(); + Shop.StartAutoPurchase(toPurchase); + Shop.HandleNextPurchaseStep(); } } } @@ -144,12 +145,12 @@ internal sealed class CeruleumTankWindow : ShopWindow return $"{fullStacks:N0} {stacks}"; } - protected override unsafe void FirePurchaseCallback(AtkUnitBase* addonShop, int buyNow) + public override unsafe void TriggerPurchase(AtkUnitBase* addonShop, int buyNow) { var buyItem = stackalloc AtkValue[] { new() { Type = ValueType.Int, Int = 0 }, - new() { Type = ValueType.UInt, UInt = (uint)ItemForSale!.Position }, + new() { Type = ValueType.UInt, UInt = (uint)Shop.ItemForSale!.Position }, new() { Type = ValueType.UInt, UInt = (uint)buyNow }, }; addonShop->FireCallback(3, buyItem); @@ -163,9 +164,9 @@ internal sealed class CeruleumTankWindow : ShopWindow return false; } - int freeInventorySlots = _plugin.CountFreeInventorySlots(); + int freeInventorySlots = Shop.CountFreeInventorySlots(); stackCount = Math.Min(freeInventorySlots, stackCount); - missingQuantity = Math.Min(GetMaxItemsToPurchase(), stackCount * 999); + missingQuantity = Math.Min(Shop.GetMaxItemsToPurchase(), stackCount * 999); return true; } @@ -177,25 +178,25 @@ internal sealed class CeruleumTankWindow : ShopWindow return false; } - int freeInventorySlots = _plugin.CountFreeInventorySlots(); - int partialStacks = _plugin.CountInventorySlotsWithCondition(CeruleumTankItemId, q => q < 999); - int fullStacks = _plugin.CountInventorySlotsWithCondition(CeruleumTankItemId, q => q == 999); + int freeInventorySlots = Shop.CountFreeInventorySlots(); + int partialStacks = Shop.CountInventorySlotsWithCondition(CeruleumTankItemId, q => q < 999); + int fullStacks = Shop.CountInventorySlotsWithCondition(CeruleumTankItemId, q => q == 999); int tanks = Math.Min((fullStacks + partialStacks + freeInventorySlots) * 999, Math.Max(stackCount * 999, (fullStacks + partialStacks) * 999)); _pluginLog.Information("T: " + tanks); - int owned = GetItemCount(CeruleumTankItemId); + int owned = Shop.GetItemCount(CeruleumTankItemId); if (tanks <= owned) missingQuantity = 0; else - missingQuantity = Math.Min(GetMaxItemsToPurchase(), tanks - owned); + missingQuantity = Math.Min(Shop.GetMaxItemsToPurchase(), tanks - owned); return true; } public void StartPurchase(int quantity) { - if (!IsOpen || ItemForSale == null) + if (!IsOpen || Shop.ItemForSale == null) { _chatGui.PrintError("Could not start purchase, shop window is not open."); return; @@ -208,7 +209,7 @@ internal sealed class CeruleumTankWindow : ShopWindow } _chatGui.Print($"Starting purchase of {FormatStackCount(quantity)} ceruleum tanks."); - StartAutoPurchase(quantity); - HandleNextPurchaseStep(); + Shop.StartAutoPurchase(quantity); + Shop.HandleNextPurchaseStep(); } } diff --git a/Workshoppa/Windows/RepairKitWindow.cs b/Workshoppa/Windows/RepairKitWindow.cs index 59509f2..b7ee3d9 100644 --- a/Workshoppa/Windows/RepairKitWindow.cs +++ b/Workshoppa/Windows/RepairKitWindow.cs @@ -8,8 +8,8 @@ using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; using LLib.GameUI; +using LLib.Shop.Model; using Workshoppa.External; -using Workshoppa.GameData.Shops; using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType; namespace Workshoppa.Windows; @@ -21,29 +21,32 @@ internal sealed class RepairKitWindow : ShopWindow private readonly IPluginLog _pluginLog; private readonly Configuration _configuration; - public RepairKitWindow(WorkshopPlugin plugin, IPluginLog pluginLog, - IGameGui gameGui, IAddonLifecycle addonLifecycle, Configuration configuration, + public RepairKitWindow( + IPluginLog pluginLog, + IGameGui gameGui, + IAddonLifecycle addonLifecycle, + Configuration configuration, ExternalPluginHandler externalPluginHandler) - : base("Repair Kits###WorkshoppaRepairKitWindow", "Shop", plugin, pluginLog, gameGui, addonLifecycle, externalPluginHandler) + : base("Repair Kits###WorkshoppaRepairKitWindow", "Shop", pluginLog, gameGui, addonLifecycle, externalPluginHandler) { _pluginLog = pluginLog; _configuration = configuration; } - protected override bool Enabled => _configuration.EnableRepairKitCalculator; + public override bool IsEnabled => _configuration.EnableRepairKitCalculator; - protected override unsafe void UpdateShopStock(AtkUnitBase* addon) + public override unsafe void UpdateShopStock(AtkUnitBase* addon) { if (GetDarkMatterClusterCount() == 0) { - ItemForSale = null; + Shop.ItemForSale = null; return; } if (addon->AtkValuesCount != 625) { _pluginLog.Error($"Unexpected amount of atkvalues for Shop addon ({addon->AtkValuesCount})"); - ItemForSale = null; + Shop.ItemForSale = null; return; } @@ -52,18 +55,18 @@ internal sealed class RepairKitWindow : ShopWindow // Check if on 'Current Stock' tab? if (atkValues[0].UInt != 0) { - ItemForSale = null; + Shop.ItemForSale = null; return; } uint itemCount = atkValues[2].UInt; if (itemCount == 0) { - ItemForSale = null; + Shop.ItemForSale = null; return; } - ItemForSale = Enumerable.Range(0, (int)itemCount) + Shop.ItemForSale = Enumerable.Range(0, (int)itemCount) .Select(i => new ItemForSale { Position = i, @@ -75,14 +78,14 @@ internal sealed class RepairKitWindow : ShopWindow .FirstOrDefault(x => x.ItemId == DarkMatterCluster6ItemId); } - private int GetDarkMatterClusterCount() => GetItemCount(10335); + private int GetDarkMatterClusterCount() => Shop.GetItemCount(10335); - protected override int GetCurrencyCount() => GetItemCount(1); + public override int GetCurrencyCount() => Shop.GetItemCount(1); public override void Draw() { int darkMatterClusters = GetDarkMatterClusterCount(); - if (ItemForSale == null || darkMatterClusters == 0) + if (Shop.ItemForSale == null || darkMatterClusters == 0) { IsOpen = false; return; @@ -91,43 +94,43 @@ internal sealed class RepairKitWindow : ShopWindow ImGui.Text("Inventory"); ImGui.Indent(); ImGui.Text($"Dark Matter Clusters: {darkMatterClusters:N0}"); - ImGui.Text($"Grade 6 Dark Matter: {ItemForSale.OwnedItems:N0}"); + ImGui.Text($"Grade 6 Dark Matter: {Shop.ItemForSale.OwnedItems:N0}"); ImGui.Unindent(); - int missingItems = Math.Max(0, darkMatterClusters * 5 - (int)ItemForSale.OwnedItems); + int missingItems = Math.Max(0, darkMatterClusters * 5 - (int)Shop.ItemForSale.OwnedItems); ImGui.TextColored(missingItems == 0 ? ImGuiColors.HealerGreen : ImGuiColors.DalamudRed, $"Missing Grade 6 Dark Matter: {missingItems:N0}"); - if (PurchaseState != null) + if (Shop.PurchaseState != null) { - HandleNextPurchaseStep(); - if (PurchaseState != null) + Shop.HandleNextPurchaseStep(); + if (Shop.PurchaseState != null) { if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Times, "Cancel Auto-Buy")) - CancelAutoPurchase(); + Shop.CancelAutoPurchase(); } } else { - int toPurchase = Math.Min(GetMaxItemsToPurchase(), missingItems); + int toPurchase = Math.Min(Shop.GetMaxItemsToPurchase(), missingItems); if (toPurchase > 0) { if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.DollarSign, - $"Auto-Buy missing Dark Matter for {ItemForSale.Price * toPurchase:N0}{SeIconChar.Gil.ToIconString()}")) + $"Auto-Buy missing Dark Matter for {Shop.ItemForSale.Price * toPurchase:N0}{SeIconChar.Gil.ToIconString()}")) { - StartAutoPurchase(toPurchase); - HandleNextPurchaseStep(); + Shop.StartAutoPurchase(toPurchase); + Shop.HandleNextPurchaseStep(); } } } } - protected override unsafe void FirePurchaseCallback(AtkUnitBase* addonShop, int buyNow) + public override unsafe void TriggerPurchase(AtkUnitBase* addonShop, int buyNow) { var buyItem = stackalloc AtkValue[] { new() { Type = ValueType.Int, Int = 0 }, - new() { Type = ValueType.Int, Int = ItemForSale!.Position }, + new() { Type = ValueType.Int, Int = Shop.ItemForSale!.Position }, new() { Type = ValueType.Int, Int = buyNow }, new() { Type = 0, Int = 0 } }; diff --git a/Workshoppa/Windows/ShopWindow.cs b/Workshoppa/Windows/ShopWindow.cs index d964be8..721e8b4 100644 --- a/Workshoppa/Windows/ShopWindow.cs +++ b/Workshoppa/Windows/ShopWindow.cs @@ -1,198 +1,49 @@ using System; using System.Numerics; -using Dalamud.Game.Addon.Lifecycle; -using Dalamud.Game.Addon.Lifecycle.AddonArgTypes; using Dalamud.Plugin.Services; -using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; -using LLib.GameUI; using LLib.ImGui; +using LLib.Shop; using Workshoppa.External; -using Workshoppa.GameData.Shops; namespace Workshoppa.Windows; -internal abstract class ShopWindow : LWindow, IDisposable +internal abstract class ShopWindow : LWindow, IShopWindow, IDisposable { - private readonly string _addonName; - private readonly WorkshopPlugin _plugin; - private readonly IPluginLog _pluginLog; - private readonly IGameGui _gameGui; - private readonly IAddonLifecycle _addonLifecycle; private readonly ExternalPluginHandler _externalPluginHandler; - protected ItemForSale? ItemForSale; - protected PurchaseState? PurchaseState; - - protected ShopWindow(string name, string addonName, WorkshopPlugin plugin, IPluginLog pluginLog, - IGameGui gameGui, IAddonLifecycle addonLifecycle, ExternalPluginHandler externalPluginHandler) - : base(name) + protected ShopWindow( + string windowName, + string addonName, + IPluginLog pluginLog, + IGameGui gameGui, + IAddonLifecycle addonLifecycle, + ExternalPluginHandler externalPluginHandler) + : base(windowName) { - _addonName = addonName; - _plugin = plugin; - _pluginLog = pluginLog; - _gameGui = gameGui; - _addonLifecycle = addonLifecycle; _externalPluginHandler = externalPluginHandler; + Shop = new RegularShopBase(this, addonName, pluginLog, gameGui, addonLifecycle); Position = new Vector2(100, 100); PositionCondition = ImGuiCond.Always; Flags = ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoNav | ImGuiWindowFlags.NoCollapse; - - _addonLifecycle.RegisterListener(AddonEvent.PostSetup, _addonName, ShopPostSetup); - _addonLifecycle.RegisterListener(AddonEvent.PreFinalize, _addonName, ShopPreFinalize); - _addonLifecycle.RegisterListener(AddonEvent.PostUpdate, _addonName, ShopPostUpdate); } - public bool AutoBuyEnabled => PurchaseState != null; - - protected abstract bool Enabled { get; } + public void Dispose() => Shop.Dispose(); + public bool AutoBuyEnabled => Shop.AutoBuyEnabled; public bool IsAwaitingYesNo { - get => PurchaseState?.IsAwaitingYesNo ?? false; - set => PurchaseState!.IsAwaitingYesNo = value; + get { return Shop.IsAwaitingYesNo; } + set { Shop.IsAwaitingYesNo = value; } } - private unsafe void ShopPostSetup(AddonEvent type, AddonArgs args) - { - if (!Enabled) - { - ItemForSale = null; - IsOpen = false; - return; - } - - UpdateShopStock((AtkUnitBase*)args.Addon); - PostUpdateShopStock(); - if (ItemForSale != null) - IsOpen = true; - } - - private void ShopPreFinalize(AddonEvent type, AddonArgs args) - { - PurchaseState = null; - _externalPluginHandler.Restore(); - - IsOpen = false; - } - - private unsafe void ShopPostUpdate(AddonEvent type, AddonArgs args) - { - if (!Enabled) - { - ItemForSale = null; - IsOpen = false; - return; - } - - UpdateShopStock((AtkUnitBase*)args.Addon); - PostUpdateShopStock(); - if (ItemForSale != null) - { - AtkUnitBase* addon = (AtkUnitBase*)args.Addon; - short x = 0, y = 0; - addon->GetPosition(&x, &y); - - short width = 0, height = 0; - addon->GetSize(&width, &height, true); - x += width; - - if ((short)Position!.Value.X != x || (short)Position!.Value.Y != y) - Position = new Vector2(x, y); - - IsOpen = true; - } - else - IsOpen = false; - } - - protected abstract unsafe void UpdateShopStock(AtkUnitBase* addon); - - private void PostUpdateShopStock() - { - if (ItemForSale != null && PurchaseState != null) - { - int ownedItems = (int)ItemForSale.OwnedItems; - if (PurchaseState.OwnedItems != ownedItems) - { - PurchaseState.OwnedItems = ownedItems; - PurchaseState.NextStep = DateTime.Now.AddSeconds(0.25); - } - } - } - - protected unsafe int GetItemCount(uint itemId) - { - InventoryManager* inventoryManager = InventoryManager.Instance(); - return inventoryManager->GetInventoryItemCount(itemId, checkEquipped: false, checkArmory: false); - } - - protected abstract int GetCurrencyCount(); - - protected int GetMaxItemsToPurchase() - { - if (ItemForSale == null) - return 0; - - int currency = GetCurrencyCount(); - return (int)(currency / ItemForSale!.Price); - } - - protected void CancelAutoPurchase() - { - PurchaseState = null; - _externalPluginHandler.Restore(); - } - - protected void StartAutoPurchase(int toPurchase) - { - PurchaseState = new((int)ItemForSale!.OwnedItems + toPurchase, (int)ItemForSale.OwnedItems); - _externalPluginHandler.Save(); - } - - protected unsafe void HandleNextPurchaseStep() - { - if (ItemForSale == null || PurchaseState == null) - return; - - int maxStackSize = _plugin.DetermineMaxStackSize(ItemForSale.ItemId); - if (maxStackSize == 0 && !_plugin.HasFreeInventorySlot()) - { - _pluginLog.Warning($"No free inventory slots, can't buy more {ItemForSale.ItemName}"); - PurchaseState = null; - _externalPluginHandler.Restore(); - } - else if (!PurchaseState.IsComplete) - { - if (PurchaseState.NextStep <= DateTime.Now && - _gameGui.TryGetAddonByName(_addonName, out AtkUnitBase* addonShop)) - { - int buyNow = Math.Min(PurchaseState.ItemsLeftToBuy, maxStackSize); - _pluginLog.Information($"Buying {buyNow}x {ItemForSale.ItemName}"); - - FirePurchaseCallback(addonShop, buyNow); - - PurchaseState.NextStep = DateTime.MaxValue; - PurchaseState.IsAwaitingYesNo = true; - } - } - else - { - _pluginLog.Information( - $"Stopping item purchase (desired = {PurchaseState.DesiredItems}, owned = {PurchaseState.OwnedItems})"); - PurchaseState = null; - _externalPluginHandler.Restore(); - } - } - - protected abstract unsafe void FirePurchaseCallback(AtkUnitBase* addonShop, int buyNow); - - public void Dispose() - { - _addonLifecycle.UnregisterListener(AddonEvent.PostSetup, _addonName, ShopPostSetup); - _addonLifecycle.UnregisterListener(AddonEvent.PreFinalize, _addonName, ShopPreFinalize); - _addonLifecycle.UnregisterListener(AddonEvent.PostUpdate, _addonName, ShopPostUpdate); - } + protected RegularShopBase Shop { get; } + public abstract bool IsEnabled { get; } + public abstract int GetCurrencyCount(); + public abstract unsafe void UpdateShopStock(AtkUnitBase* addon); + public abstract unsafe void TriggerPurchase(AtkUnitBase* addonShop, int buyNow); + public void SaveExternalPluginState() => _externalPluginHandler.Save(); + public void RestoreExternalPluginState() => _externalPluginHandler.Restore(); } diff --git a/Workshoppa/WorkshopPlugin.GameFunctions.cs b/Workshoppa/WorkshopPlugin.GameFunctions.cs index c267d4f..98e4fb8 100644 --- a/Workshoppa/WorkshopPlugin.GameFunctions.cs +++ b/Workshoppa/WorkshopPlugin.GameFunctions.cs @@ -225,81 +225,4 @@ partial class WorkshopPlugin return false; } - - public bool HasFreeInventorySlot() => CountFreeInventorySlots() > 0; - - public unsafe int CountFreeInventorySlots() - { - var inventoryManger = InventoryManager.Instance(); - if (inventoryManger == null) - return 0; - - int count = 0; - for (InventoryType t = InventoryType.Inventory1; t <= InventoryType.Inventory4; ++t) - { - var container = inventoryManger->GetInventoryContainer(t); - for (int i = 0; i < container->Size; ++i) - { - var item = container->GetInventorySlot(i); - if (item == null || item->ItemId == 0) - ++count; - } - } - - return count; - } - - public unsafe int CountInventorySlotsWithCondition(uint itemId, Predicate predicate) - { - ArgumentNullException.ThrowIfNull(predicate); - - var inventoryManager = InventoryManager.Instance(); - if (inventoryManager == null) - return 0; - - int count = 0; - for (InventoryType t = InventoryType.Inventory1; t <= InventoryType.Inventory4; ++t) - { - var container = inventoryManager->GetInventoryContainer(t); - for (int i = 0; i < container->Size; ++i) - { - var item = container->GetInventorySlot(i); - if (item == null || item->ItemId == 0) - continue; - - if (item->ItemId == itemId && predicate((int)item->Quantity)) - ++count; - } - } - - return count; - } - - public unsafe int DetermineMaxStackSize(uint itemId) - { - var inventoryManger = InventoryManager.Instance(); - if (inventoryManger == null) - return 0; - - int max = 0; - for (InventoryType t = InventoryType.Inventory1; t <= InventoryType.Inventory4; ++t) - { - var container = inventoryManger->GetInventoryContainer(t); - for (int i = 0; i < container->Size; ++i) - { - var item = container->GetInventorySlot(i); - if (item == null || item->ItemId == 0) - return 99; - - if (item->ItemId == itemId) - { - max += (999 - (int)item->Quantity); - if (max >= 99) - break; - } - } - } - - return Math.Min(99, max); - } } diff --git a/Workshoppa/WorkshopPlugin.cs b/Workshoppa/WorkshopPlugin.cs index 5bd86fc..5ed0f7c 100644 --- a/Workshoppa/WorkshopPlugin.cs +++ b/Workshoppa/WorkshopPlugin.cs @@ -76,10 +76,10 @@ public sealed partial class WorkshopPlugin : IDalamudPlugin _windowSystem.AddWindow(_mainWindow); _configWindow = new(_pluginInterface, _configuration); _windowSystem.AddWindow(_configWindow); - _repairKitWindow = new(this, _pluginLog, _gameGui, addonLifecycle, _configuration, + _repairKitWindow = new(_pluginLog, _gameGui, addonLifecycle, _configuration, _externalPluginHandler); _windowSystem.AddWindow(_repairKitWindow); - _ceruleumTankWindow = new(this, _pluginLog, _gameGui, addonLifecycle, _configuration, + _ceruleumTankWindow = new(_pluginLog, _gameGui, addonLifecycle, _configuration, _externalPluginHandler, _chatGui); _windowSystem.AddWindow(_ceruleumTankWindow);