Purchase non-stackable items, filter 'add item' dropdown

This commit is contained in:
Liza 2023-11-14 20:17:04 +01:00
parent 63e2836027
commit 1cd1a2ede4
Signed by: liza
GPG Key ID: 7199F8D727D55F67
5 changed files with 64 additions and 31 deletions

View File

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

View File

@ -17,6 +17,7 @@ internal sealed class GcRewardItem : IEquatable<GcRewardItem>
RequiredRank = 0, RequiredRank = 0,
StackSize = 0, StackSize = 0,
SealCost = 100_000, SealCost = 100_000,
InventoryLimit = int.MaxValue,
}; };
public required uint ItemId { get; init; } public required uint ItemId { get; init; }
@ -28,6 +29,7 @@ internal sealed class GcRewardItem : IEquatable<GcRewardItem>
public required uint RequiredRank { get; init; } public required uint RequiredRank { get; init; }
public required uint StackSize { get; init; } public required uint StackSize { get; init; }
public required uint SealCost { get; init; } public required uint SealCost { get; init; }
public required uint InventoryLimit { get; init; }
public bool IsValid() => ItemId > 0 && GrandCompanies.Count > 0; public bool IsValid() => ItemId > 0 && GrandCompanies.Count > 0;
public bool Limited => GrandCompanies.Count < 3; public bool Limited => GrandCompanies.Count < 3;

View File

@ -33,6 +33,9 @@ internal sealed class GcRewardsCache
RequiredRank = item.RequiredGrandCompanyRank.Row, RequiredRank = item.RequiredGrandCompanyRank.Row,
item.Item!.Value.StackSize, item.Item!.Value.StackSize,
SealCost = item.CostGCSeals, SealCost = item.CostGCSeals,
InventoryLimit = item.Item.Value!.IsUnique ? 1
: item.Item.Row == ItemIds.Venture ? item.Item.Value!.StackSize
: int.MaxValue,
}; };
}) })
.Select(item => new GcRewardItem .Select(item => new GcRewardItem
@ -48,6 +51,7 @@ internal sealed class GcRewardsCache
GrandCompanies = item.Select(x => categories[x.RowId].GrandCompany) GrandCompanies = item.Select(x => categories[x.RowId].GrandCompany)
.ToList() .ToList()
.AsReadOnly(), .AsReadOnly(),
InventoryLimit = item.Key.InventoryLimit,
}) })
.ToList() .ToList()
.AsReadOnly(); .AsReadOnly();

View File

@ -26,6 +26,7 @@ internal sealed class ConfigWindow : LImGui.LWindow
private readonly IconCache _iconCache; private readonly IconCache _iconCache;
private readonly IReadOnlyDictionary<uint, GcRewardItem> _itemLookup; private readonly IReadOnlyDictionary<uint, GcRewardItem> _itemLookup;
private string _searchString = string.Empty;
private uint _dragDropSource; private uint _dragDropSource;
public ConfigWindow(DalamudPluginInterface pluginInterface, DeliverooPlugin plugin, Configuration configuration, public ConfigWindow(DalamudPluginInterface pluginInterface, DeliverooPlugin plugin, Configuration configuration,
@ -147,7 +148,6 @@ internal sealed class ConfigWindow : LImGui.LWindow
List<(uint ItemId, string Name, ushort IconId, bool Limited)> comboValues = _gcRewardsCache.Rewards List<(uint ItemId, string Name, ushort IconId, bool Limited)> comboValues = _gcRewardsCache.Rewards
.Where(x => x.SubCategory is RewardSubCategory.Materials or RewardSubCategory.Materiel) .Where(x => x.SubCategory is RewardSubCategory.Materials or RewardSubCategory.Materiel)
.Where(x => x.StackSize > 1)
.Where(x => !_configuration.ItemsAvailableForPurchase.Contains(x.ItemId)) .Where(x => !_configuration.ItemsAvailableForPurchase.Contains(x.ItemId))
.Select(x => (x.ItemId, x.Name, x.IconId, x.Limited)) .Select(x => (x.ItemId, x.Name, x.IconId, x.Limited))
.OrderBy(x => x.Name) .OrderBy(x => x.Name)
@ -157,8 +157,10 @@ internal sealed class ConfigWindow : LImGui.LWindow
if (ImGui.BeginCombo($"##ItemSelection", "Add Item...", ImGuiComboFlags.HeightLarge)) if (ImGui.BeginCombo($"##ItemSelection", "Add Item...", ImGuiComboFlags.HeightLarge))
{ {
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
bool addFirst = ImGui.InputTextWithHint("", "Filter...", ref _searchString, 256,
ImGuiInputTextFlags.AutoSelectAll | ImGuiInputTextFlags.EnterReturnsTrue);
foreach (var item in comboValues) foreach (var item in comboValues.Where(x => x.Name.ToLower().Contains(_searchString.ToLower())))
{ {
IDalamudTextureWrap? icon = _iconCache.GetIcon(item.IconId); IDalamudTextureWrap? icon = _iconCache.GetIcon(item.IconId);
if (icon != null) if (icon != null)
@ -168,9 +170,17 @@ internal sealed class ConfigWindow : LImGui.LWindow
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3); ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3);
} }
if (ImGui.Selectable($"{item.Name}{(item.Limited ? $" {SeIconChar.Hyadelyn.ToIconString()}" : "")}##SelectVenture{item.IconId}")) bool addThis = ImGui.Selectable($"{item.Name}{(item.Limited ? $" {SeIconChar.Hyadelyn.ToIconString()}" : "")}##SelectVenture{item.IconId}");
if (addThis || addFirst)
{ {
_configuration.ItemsAvailableForPurchase.Add(item.ItemId); _configuration.ItemsAvailableForPurchase.Add(item.ItemId);
if (addFirst)
{
addFirst = false;
ImGui.CloseCurrentPopup();
}
Save(); Save();
} }
} }

View File

@ -20,6 +20,26 @@ namespace Deliveroo.Windows;
internal sealed class TurnInWindow : LImGui.LWindow internal sealed class TurnInWindow : LImGui.LWindow
{ {
private readonly IReadOnlyList<InventoryType> _inventoryTypes = new[]
{
InventoryType.Inventory1,
InventoryType.Inventory2,
InventoryType.Inventory3,
InventoryType.Inventory4,
InventoryType.ArmoryMainHand,
InventoryType.ArmoryOffHand,
InventoryType.ArmoryHead,
InventoryType.ArmoryBody,
InventoryType.ArmoryHands,
InventoryType.ArmoryLegs,
InventoryType.ArmoryFeets,
InventoryType.ArmoryEar,
InventoryType.ArmoryNeck,
InventoryType.ArmoryWrist,
InventoryType.ArmoryRings,
InventoryType.EquippedItems
}.AsReadOnly();
private readonly DeliverooPlugin _plugin; private readonly DeliverooPlugin _plugin;
private readonly DalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
private readonly Configuration _configuration; private readonly Configuration _configuration;
@ -99,7 +119,8 @@ internal sealed class TurnInWindow : LImGui.LWindow
EffectiveLimit = CalculateEffectiveLimit( EffectiveLimit = CalculateEffectiveLimit(
x.Item.ItemId, x.Item.ItemId,
x.Item.Limit <= 0 ? uint.MaxValue : (uint)x.Item.Limit, x.Item.Limit <= 0 ? uint.MaxValue : (uint)x.Item.Limit,
x.Reward.StackSize), x.Reward.StackSize,
x.Reward.InventoryLimit),
SealCost = x.Reward.SealCost, SealCost = x.Reward.SealCost,
Tier = x.Reward.Tier, Tier = x.Reward.Tier,
SubCategory = x.Reward.SubCategory, SubCategory = x.Reward.SubCategory,
@ -153,11 +174,13 @@ internal sealed class TurnInWindow : LImGui.LWindow
InventoryManager* inventoryManager = InventoryManager.Instance(); InventoryManager* inventoryManager = InventoryManager.Instance();
if (inventoryManager->GetInventoryItemCount(ItemIds.PrioritySealAllowance) > 0) if (inventoryManager->GetInventoryItemCount(ItemIds.PrioritySealAllowance) > 0)
{ {
ImGui.BeginDisabled(_condition[ConditionFlag.OccupiedInQuestEvent] || _condition[ConditionFlag.Casting]); ImGui.BeginDisabled(_condition[ConditionFlag.OccupiedInQuestEvent] ||
_condition[ConditionFlag.Casting]);
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Bolt, "Use Priority Seal Allowance (15%)")) if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Bolt, "Use Priority Seal Allowance (15%)"))
{ {
AgentInventoryContext.Instance()->UseItem(ItemIds.PrioritySealAllowance); AgentInventoryContext.Instance()->UseItem(ItemIds.PrioritySealAllowance);
} }
ImGui.EndDisabled(); ImGui.EndDisabled();
} }
} }
@ -180,9 +203,9 @@ internal sealed class TurnInWindow : LImGui.LWindow
var itemsWrapper = ItemsWrapper; var itemsWrapper = ItemsWrapper;
ImGui.Text($"Items to buy ({itemsWrapper.Name}):"); ImGui.Text($"Items to buy ({itemsWrapper.Name}):");
List<(uint ItemId, string Name, IReadOnlyList<GrandCompany> GrandCompanies, uint Rank, ushort IconId)> comboValues = new() List<(GcRewardItem Item, string Name)> comboValues = new()
{ {
(GcRewardItem.None.ItemId, GcRewardItem.None.Name, new List<GrandCompany>(), GcRewardItem.None.RequiredRank, GcRewardItem.None.IconId) (GcRewardItem.None, GcRewardItem.None.Name),
}; };
foreach (uint itemId in _configuration.ItemsAvailableForPurchase) foreach (uint itemId in _configuration.ItemsAvailableForPurchase)
{ {
@ -191,7 +214,7 @@ internal sealed class TurnInWindow : LImGui.LWindow
string itemName = gcReward.Name; string itemName = gcReward.Name;
if (itemCount > 0) if (itemCount > 0)
itemName += $" ({itemCount:N0})"; itemName += $" ({itemCount:N0})";
comboValues.Add((itemId, itemName, gcReward.GrandCompanies, gcReward.RequiredRank, gcReward.IconId)); comboValues.Add((gcReward, itemName));
} }
if (itemsWrapper.GetItemsToPurchase().Count == 0) if (itemsWrapper.GetItemsToPurchase().Count == 0)
@ -215,11 +238,12 @@ internal sealed class TurnInWindow : LImGui.LWindow
item.Enabled = enabled; item.Enabled = enabled;
itemsWrapper.Save(); itemsWrapper.Save();
} }
ImGui.PopID(); ImGui.PopID();
ImGui.SameLine(0, 3); ImGui.SameLine(0, 3);
ImGui.BeginDisabled(!enabled); ImGui.BeginDisabled(!enabled);
int comboValueIndex = comboValues.FindIndex(x => x.ItemId == item.ItemId); int comboValueIndex = comboValues.FindIndex(x => x.Item.ItemId == item.ItemId);
if (comboValueIndex < 0) if (comboValueIndex < 0)
{ {
item.ItemId = 0; item.ItemId = 0;
@ -229,7 +253,8 @@ internal sealed class TurnInWindow : LImGui.LWindow
comboValueIndex = 0; comboValueIndex = 0;
} }
IDalamudTextureWrap? icon = _iconCache.GetIcon(comboValues[comboValueIndex].IconId); var comboItem = comboValues[comboValueIndex];
IDalamudTextureWrap? icon = _iconCache.GetIcon(comboItem.Item.IconId);
if (icon != null) if (icon != null)
{ {
ImGui.Image(icon.ImGuiHandle, new Vector2(23, 23)); ImGui.Image(icon.ImGuiHandle, new Vector2(23, 23));
@ -238,7 +263,8 @@ internal sealed class TurnInWindow : LImGui.LWindow
if (ImGui.Combo("", ref comboValueIndex, comboValues.Select(x => x.Name).ToArray(), comboValues.Count)) if (ImGui.Combo("", ref comboValueIndex, comboValues.Select(x => x.Name).ToArray(), comboValues.Count))
{ {
item.ItemId = comboValues[comboValueIndex].ItemId; comboItem = comboValues[comboValueIndex];
item.ItemId = comboItem.Item.ItemId;
itemsWrapper.Save(); itemsWrapper.Save();
} }
@ -277,16 +303,11 @@ internal sealed class TurnInWindow : LImGui.LWindow
if (comboValueIndex > 0) if (comboValueIndex > 0)
{ {
ImGui.SetNextItemWidth(ImGuiHelpers.GlobalScale * 130); ImGui.SetNextItemWidth(ImGuiHelpers.GlobalScale * 130);
int limit = item.Limit; int limit = Math.Min(item.Limit, (int)comboItem.Item.InventoryLimit);
if (item.ItemId == ItemIds.Venture) int stepSize = comboItem.Item.StackSize < 99 ? 1 : 50;
limit = Math.Min(limit, 65_000); if (ImGui.InputInt("Maximum items to buy", ref limit, stepSize, stepSize * 10))
if (ImGui.InputInt("Maximum items to buy", ref limit, 50, 500))
{ {
item.Limit = Math.Max(0, limit); item.Limit = Math.Min(Math.Max(0, limit), (int)comboItem.Item.InventoryLimit);
if (item.ItemId == ItemIds.Venture)
item.Limit = Math.Min(item.Limit, 65_000);
itemsWrapper.Save(); itemsWrapper.Save();
} }
} }
@ -298,13 +319,12 @@ internal sealed class TurnInWindow : LImGui.LWindow
if (comboValueIndex > 0) if (comboValueIndex > 0)
{ {
var comboItem = comboValues[comboValueIndex]; if (!comboItem.Item.GrandCompanies.Contains(grandCompany))
if (!comboItem.GrandCompanies.Contains(grandCompany))
{ {
ImGui.TextColored(ImGuiColors.DalamudRed, ImGui.TextColored(ImGuiColors.DalamudRed,
"This item will be skipped, as you are in the wrong Grand Company."); "This item will be skipped, as you are in the wrong Grand Company.");
} }
else if (comboItem.Rank > _plugin.GetGrandCompanyRank()) else if (comboItem.Item.RequiredRank > _plugin.GetGrandCompanyRank())
{ {
ImGui.TextColored(ImGuiColors.DalamudRed, ImGui.TextColored(ImGuiColors.DalamudRed,
"This item will be skipped, your rank isn't high enough to buy it."); "This item will be skipped, your rank isn't high enough to buy it.");
@ -347,7 +367,6 @@ internal sealed class TurnInWindow : LImGui.LWindow
itemsWrapper.Add(new Configuration.PurchasePriority { ItemId = itemId, Limit = 0 }); itemsWrapper.Add(new Configuration.PurchasePriority { ItemId = itemId, Limit = 0 });
itemsWrapper.Save(); itemsWrapper.Save();
ImGui.CloseCurrentPopup(); ImGui.CloseCurrentPopup();
} }
} }
} }
@ -357,17 +376,15 @@ internal sealed class TurnInWindow : LImGui.LWindow
} }
} }
private unsafe uint CalculateEffectiveLimit(uint itemId, uint limit, uint stackSize) private unsafe uint CalculateEffectiveLimit(uint itemId, uint limit, uint stackSize, uint inventoryLimit)
{ {
if (itemId == ItemIds.Venture) if (itemId == ItemIds.Venture)
return Math.Min(limit, 65_000); return Math.Min(limit, inventoryLimit);
else else
{ {
uint slotsThatCanBeUsed = 0; uint slotsThatCanBeUsed = 0;
InventoryManager* inventoryManager = InventoryManager.Instance(); InventoryManager* inventoryManager = InventoryManager.Instance();
for (InventoryType inventoryType = InventoryType.Inventory1; foreach (var inventoryType in _inventoryTypes)
inventoryType <= InventoryType.Inventory4;
++inventoryType)
{ {
var container = inventoryManager->GetInventoryContainer(inventoryType); var container = inventoryManager->GetInventoryContainer(inventoryType);
for (int i = 0; i < container->Size; ++i) for (int i = 0; i < container->Size; ++i)
@ -380,7 +397,7 @@ internal sealed class TurnInWindow : LImGui.LWindow
} }
} }
return Math.Min(limit, slotsThatCanBeUsed * stackSize); return Math.Min(Math.Min(limit, slotsThatCanBeUsed * stackSize), inventoryLimit);
} }
} }