Add commands to buy certain quantities of ceruleum tanks

This commit is contained in:
Liza 2024-05-11 13:56:39 +02:00
parent 9ae2785fae
commit af964b0723
Signed by: liza
GPG Key ID: 7199F8D727D55F67
4 changed files with 129 additions and 10 deletions

View File

@ -20,18 +20,21 @@ internal sealed class CeruleumTankWindow : ShopWindow
private readonly WorkshopPlugin _plugin;
private readonly IPluginLog _pluginLog;
private readonly Configuration _configuration;
private readonly IChatGui _chatGui;
private int _companyCredits;
private int _buyStackCount;
private bool _buyPartialStacks = true;
public CeruleumTankWindow(WorkshopPlugin plugin, IPluginLog pluginLog,
IGameGui gameGui, IAddonLifecycle addonLifecycle, Configuration configuration,
ExternalPluginHandler externalPluginHandler)
: base("Ceruleum Tanks###WorkshoppaCeruleumTankWindow", "FreeCompanyCreditShop", plugin, pluginLog, gameGui, addonLifecycle, externalPluginHandler)
public CeruleumTankWindow(WorkshopPlugin plugin, IPluginLog pluginLog, IGameGui gameGui,
IAddonLifecycle addonLifecycle, Configuration configuration, ExternalPluginHandler externalPluginHandler,
IChatGui chatGui)
: base("Ceruleum Tanks###WorkshoppaCeruleumTankWindow", "FreeCompanyCreditShop", plugin, pluginLog, gameGui,
addonLifecycle, externalPluginHandler)
{
_plugin = plugin;
_pluginLog = pluginLog;
_chatGui = chatGui;
_configuration = configuration;
}
@ -41,7 +44,8 @@ internal sealed class CeruleumTankWindow : ShopWindow
{
if (addon->AtkValuesCount != 170)
{
_pluginLog.Error($"Unexpected amount of atkvalues for FreeCompanyCreditShop addon ({addon->AtkValuesCount})");
_pluginLog.Error(
$"Unexpected amount of atkvalues for FreeCompanyCreditShop addon ({addon->AtkValuesCount})");
_companyCredits = 0;
ItemForSale = null;
return;
@ -56,6 +60,7 @@ internal sealed class CeruleumTankWindow : ShopWindow
ItemForSale = null;
return;
}
ItemForSale = Enumerable.Range(0, (int)itemCount)
.Select(i => new ItemForSale
{
@ -79,7 +84,7 @@ internal sealed class CeruleumTankWindow : ShopWindow
}
int ceruleumTanks = GetItemCount(CeruleumTankItemId);
int freeInventorySlots = _plugin.GetFreeInventorySlots();
int freeInventorySlots = _plugin.CountFreeInventorySlots();
ImGui.Text("Inventory");
ImGui.Indent();
@ -149,4 +154,61 @@ internal sealed class CeruleumTankWindow : ShopWindow
};
addonShop->FireCallback(3, buyItem);
}
public bool TryParseBuyRequest(string arguments, out int missingQuantity)
{
if (!int.TryParse(arguments, out int stackCount) || stackCount <= 0)
{
missingQuantity = 0;
return false;
}
int freeInventorySlots = _plugin.CountFreeInventorySlots();
stackCount = Math.Min(freeInventorySlots, stackCount);
missingQuantity = Math.Min(GetMaxItemsToPurchase(), stackCount * 999);
return true;
}
public bool TryParseFillRequest(string arguments, out int missingQuantity)
{
if (!int.TryParse(arguments, out int stackCount) || stackCount < 0)
{
missingQuantity = 0;
return false;
}
int freeInventorySlots = _plugin.CountFreeInventorySlots();
int partialStacks = _plugin.CountInventorySlotsWithCondition(CeruleumTankItemId, q => q < 999);
int fullStacks = _plugin.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);
if (tanks <= owned)
missingQuantity = 0;
else
missingQuantity = Math.Min(GetMaxItemsToPurchase(), tanks - owned);
return true;
}
public void StartPurchase(int quantity)
{
if (!IsOpen || ItemForSale == null)
{
_chatGui.PrintError("Could not start purchase, shop window is not open.");
return;
}
if (quantity <= 0)
{
_chatGui.Print("Not buying ceruleum tanks, you already have enough.");
return;
}
_chatGui.Print($"Starting purchase of {FormatStackCount(quantity)} ceruleum tanks.");
//StartAutoPurchase(quantity);
//HandleNextPurchaseStep();
}
}

View File

@ -232,9 +232,9 @@ partial class WorkshopPlugin
return false;
}
public bool HasFreeInventorySlot() => GetFreeInventorySlots() > 0;
public bool HasFreeInventorySlot() => CountFreeInventorySlots() > 0;
public unsafe int GetFreeInventorySlots()
public unsafe int CountFreeInventorySlots()
{
var inventoryManger = InventoryManager.Instance();
if (inventoryManger == null)
@ -255,6 +255,32 @@ partial class WorkshopPlugin
return count;
}
public unsafe int CountInventorySlotsWithCondition(uint itemId, Predicate<int> 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();

View File

@ -80,7 +80,7 @@ public sealed partial class WorkshopPlugin : IDalamudPlugin
_externalPluginHandler);
_windowSystem.AddWindow(_repairKitWindow);
_ceruleumTankWindow = new(this, _pluginLog, _gameGui, addonLifecycle, _configuration,
_externalPluginHandler);
_externalPluginHandler, _chatGui);
_windowSystem.AddWindow(_ceruleumTankWindow);
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
@ -91,6 +91,18 @@ public sealed partial class WorkshopPlugin : IDalamudPlugin
{
HelpMessage = "Open UI"
});
_commandManager.AddHandler("/workshoppa", new CommandInfo(ProcessCommand)
{
ShowInHelp = false,
});
_commandManager.AddHandler("/buy-tanks", new CommandInfo(ProcessBuyCommand)
{
HelpMessage = "Buy a given number of ceruleum tank stacks.",
});
_commandManager.AddHandler("/fill-tanks", new CommandInfo(ProcessFillCommand)
{
HelpMessage = "Fill your inventory with a given number of ceruleum tank stacks.",
});
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "SelectYesno", SelectYesNoPostSetup);
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "Request", RequestPostSetup);
@ -259,6 +271,22 @@ public sealed partial class WorkshopPlugin : IDalamudPlugin
_mainWindow.Toggle(MainWindow.EOpenReason.Command);
}
private void ProcessBuyCommand(string command, string arguments)
{
if (_ceruleumTankWindow.TryParseBuyRequest(arguments, out int missingQuantity))
_ceruleumTankWindow.StartPurchase(missingQuantity);
else
_chatGui.PrintError($"Usage: {command} <stacks>");
}
private void ProcessFillCommand(string command, string arguments)
{
if (_ceruleumTankWindow.TryParseFillRequest(arguments, out int missingQuantity))
_ceruleumTankWindow.StartPurchase(missingQuantity);
else
_chatGui.PrintError($"Usage: {command} <stacks>");
}
private void OpenMainUi()
=> _mainWindow.Toggle(MainWindow.EOpenReason.PluginInstaller);
@ -268,6 +296,9 @@ public sealed partial class WorkshopPlugin : IDalamudPlugin
_addonLifecycle.UnregisterListener(AddonEvent.PostRefresh, "Request", RequestPostRefresh);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "Request", RequestPostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "SelectYesno", SelectYesNoPostSetup);
_commandManager.RemoveHandler("/fill-tanks");
_commandManager.RemoveHandler("/buy-tanks");
_commandManager.RemoveHandler("/workshoppa");
_commandManager.RemoveHandler("/ws");
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
_pluginInterface.UiBuilder.OpenConfigUi -= _configWindow.Toggle;

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Version>5.3</Version>
<Version>5.4</Version>
<LangVersion>11.0</LangVersion>
<Nullable>enable</Nullable>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>