Fix tickets of the wrong GC messing up turn-in window, fix adding itemId 0 to your purchase list

pull/3/head
Liza 2023-10-07 12:08:00 +02:00
parent 5723b64142
commit 62bc3fe03c
Signed by: liza
GPG Key ID: 7199F8D727D55F67
4 changed files with 85 additions and 73 deletions

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Client.UI.Agent;
namespace Deliveroo.GameData; namespace Deliveroo.GameData;
@ -9,7 +10,7 @@ internal sealed class GcRewardItem : IEquatable<GcRewardItem>
{ {
ItemId = 0, ItemId = 0,
Name = "---", Name = "---",
GrandCompany = GrandCompany.None, GrandCompanies = new List<GrandCompany>().AsReadOnly(),
Tier = RewardTier.First, Tier = RewardTier.First,
SubCategory = RewardSubCategory.Unknown, SubCategory = RewardSubCategory.Unknown,
RequiredRank = 0, RequiredRank = 0,
@ -19,14 +20,14 @@ internal sealed class GcRewardItem : IEquatable<GcRewardItem>
public required uint ItemId { get; init; } public required uint ItemId { get; init; }
public required string Name { get; init; } public required string Name { get; init; }
public required GrandCompany GrandCompany { get; init; } public required IReadOnlyList<GrandCompany> GrandCompanies { get; init; }
public required RewardTier Tier { get; init; } public required RewardTier Tier { get; init; }
public required RewardSubCategory SubCategory { get; init; } public required RewardSubCategory SubCategory { get; init; }
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 bool IsValid() => ItemId > 0 && GrandCompany != GrandCompany.None; public bool IsValid() => ItemId > 0 && GrandCompanies.Count > 0;
public bool Equals(GcRewardItem? other) public bool Equals(GcRewardItem? other)
{ {

View File

@ -18,34 +18,42 @@ internal sealed class GcRewardsCache
Tier: (RewardTier)x.Tier, Tier: (RewardTier)x.Tier,
SubCategory: (RewardSubCategory)x.SubCategory)); SubCategory: (RewardSubCategory)x.SubCategory));
var items = dataManager.GetExcelSheet<GCScripShopItem>()! Rewards = dataManager.GetExcelSheet<GCScripShopItem>()!
.Where(x => x.RowId > 0 && x.Item.Row > 0) .Where(x => x.RowId > 0 && x.Item.Row > 0)
.ToList(); .GroupBy(item =>
foreach (var item in items)
{
var category = categories[item.RowId];
Rewards[category.GrandCompany].Add(new GcRewardItem
{ {
ItemId = item.Item.Row, var category = categories[item.RowId];
Name = item.Item.Value!.Name.ToString(), return new
GrandCompany = category.GrandCompany, {
Tier = category.Tier, ItemId = item.Item.Row,
SubCategory = category.SubCategory, Name = item.Item.Value!.Name.ToString(),
RequiredRank = item.RequiredGrandCompanyRank.Row, category.Tier,
StackSize = item.Item!.Value.StackSize, category.SubCategory,
SealCost = item.CostGCSeals, RequiredRank = item.RequiredGrandCompanyRank.Row,
}); item.Item!.Value.StackSize,
} SealCost = item.CostGCSeals,
};
})
.Select(item => new GcRewardItem
{
ItemId = item.Key.ItemId,
Name = item.Key.Name,
Tier = item.Key.Tier,
SubCategory = item.Key.SubCategory,
RequiredRank = item.Key.RequiredRank,
StackSize = item.Key.StackSize,
SealCost = item.Key.SealCost,
GrandCompanies = item.Select(x => categories[x.RowId].GrandCompany)
.ToList()
.AsReadOnly(),
})
.ToList()
.AsReadOnly();
RewardLookup = Rewards.ToDictionary(x => x.ItemId).AsReadOnly();
} }
public Dictionary<GrandCompany, List<GcRewardItem>> Rewards { get; } = new() public IReadOnlyList<GcRewardItem> Rewards { get; }
{ public IReadOnlyDictionary<uint, GcRewardItem> RewardLookup { get; }
{ GrandCompany.Maelstrom, new() },
{ GrandCompany.TwinAdder, new() },
{ GrandCompany.ImmortalFlames, new() }
};
public GcRewardItem GetReward(GrandCompany grandCompany, uint itemId) public GcRewardItem GetReward(uint itemId) => RewardLookup[itemId];
=> Rewards[grandCompany].Single(x => x.ItemId == itemId);
} }

View File

@ -23,8 +23,8 @@ internal sealed class ConfigWindow : Window
private readonly IClientState _clientState; private readonly IClientState _clientState;
private readonly IPluginLog _pluginLog; private readonly IPluginLog _pluginLog;
private readonly Dictionary<uint, GcRewardItem> _itemLookup; private readonly IReadOnlyDictionary<uint, GcRewardItem> _itemLookup;
private uint _dragDropSource = 0; private uint _dragDropSource;
public ConfigWindow(DalamudPluginInterface pluginInterface, DeliverooPlugin plugin, Configuration configuration, public ConfigWindow(DalamudPluginInterface pluginInterface, DeliverooPlugin plugin, Configuration configuration,
GcRewardsCache gcRewardsCache, IClientState clientState, IPluginLog pluginLog) GcRewardsCache gcRewardsCache, IClientState clientState, IPluginLog pluginLog)
@ -37,10 +37,7 @@ internal sealed class ConfigWindow : Window
_clientState = clientState; _clientState = clientState;
_pluginLog = pluginLog; _pluginLog = pluginLog;
_itemLookup = _gcRewardsCache.Rewards.Values _itemLookup = _gcRewardsCache.RewardLookup;
.SelectMany(x => x)
.Distinct()
.ToDictionary(x => x.ItemId, x => x);
Size = new Vector2(420, 300); Size = new Vector2(420, 300);
SizeCondition = ImGuiCond.Appearing; SizeCondition = ImGuiCond.Appearing;
@ -136,33 +133,22 @@ internal sealed class ConfigWindow : Window
Save(); Save();
} }
if (_plugin.GetGrandCompany() != GrandCompany.None) List<(uint ItemId, string Name)> comboValues = _gcRewardsCache.Rewards
{ .Where(x => x.SubCategory is RewardSubCategory.Materials or RewardSubCategory.Materiel)
List<(uint ItemId, string Name)> comboValues = _gcRewardsCache.Rewards[_plugin.GetGrandCompany()] .Where(x => x.StackSize > 1)
.Where(x => x.SubCategory == RewardSubCategory.Materials || .Where(x => !_configuration.ItemsAvailableForPurchase.Contains(x.ItemId))
x.SubCategory == RewardSubCategory.Materiel) .Select(x => (x.ItemId, x.Name))
.Where(x => x.StackSize > 1) .OrderBy(x => x.Name)
.Where(x => !_configuration.ItemsAvailableForPurchase.Contains(x.ItemId)) .ThenBy(x => x.GetHashCode())
.Select(x => (x.ItemId, x.Name)) .ToList();
.OrderBy(x => x.Name) comboValues.Insert(0, (0, ""));
.ThenBy(x => x.GetHashCode())
.ToList();
comboValues.Insert(0, (0, ""));
int currentItem = 0; int currentItem = 0;
if (ImGui.Combo("Add Item", ref currentItem, comboValues.Select(x => x.Name).ToArray(), if (ImGui.Combo("Add Item", ref currentItem, comboValues.Select(x => x.Name).ToArray(), comboValues.Count)
comboValues.Count)) && comboValues[currentItem].ItemId != GcRewardItem.None.ItemId)
{
_configuration.ItemsAvailableForPurchase.Add(comboValues[currentItem].ItemId);
Save();
}
}
else
{ {
ImGui.BeginDisabled(); _configuration.ItemsAvailableForPurchase.Add(comboValues[currentItem].ItemId);
int currentItem = 0; Save();
ImGui.Combo("Add Item", ref currentItem, new[] { "(Not part of a GC)" }, 1);
ImGui.EndDisabled();
} }
ImGui.EndTabItem(); ImGui.EndTabItem();
@ -185,7 +171,6 @@ internal sealed class ConfigWindow : Window
var charConfiguration = _plugin.CharacterConfiguration; var charConfiguration = _plugin.CharacterConfiguration;
if (charConfiguration != null) if (charConfiguration != null)
{ {
bool disableForCharacter = charConfiguration.DisableForCharacter; bool disableForCharacter = charConfiguration.DisableForCharacter;
if (ImGui.Checkbox("Disable plugin for this character", ref disableForCharacter)) if (ImGui.Checkbox("Disable plugin for this character", ref disableForCharacter))
{ {
@ -203,7 +188,8 @@ internal sealed class ConfigWindow : Window
} }
if (charConfiguration.ItemsToPurchase.Count > 1 || if (charConfiguration.ItemsToPurchase.Count > 1 ||
(charConfiguration.ItemsToPurchase.Count == 1 && charConfiguration.ItemsToPurchase[0].ItemId != GcRewardItem.None.ItemId)) (charConfiguration.ItemsToPurchase.Count == 1 &&
charConfiguration.ItemsToPurchase[0].ItemId != GcRewardItem.None.ItemId))
{ {
ImGui.SameLine(); ImGui.SameLine();
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Trash, "Clear")) if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Trash, "Clear"))
@ -219,8 +205,10 @@ internal sealed class ConfigWindow : Window
charConfiguration.UseHideArmouryChestItemsFilter = useHideArmouryChestItemsFilter; charConfiguration.UseHideArmouryChestItemsFilter = useHideArmouryChestItemsFilter;
charConfiguration.Save(_pluginInterface); charConfiguration.Save(_pluginInterface);
} }
if (ImGui.IsItemHovered()) if (ImGui.IsItemHovered())
ImGui.SetTooltip("The default filter for all characters is 'Hide Gear Set Items', but you may want to override this to hide all Armoury Chest items (regardless of whether they're part of a gear set) e.g. for your main character."); ImGui.SetTooltip(
"The default filter for all characters is 'Hide Gear Set Items', but you may want to override this to hide all Armoury Chest items (regardless of whether they're part of a gear set) e.g. for your main character.");
ImGui.EndDisabled(); ImGui.EndDisabled();
ImGui.Spacing(); ImGui.Spacing();

View File

@ -50,7 +50,8 @@ internal sealed class TurnInWindow : Window
public decimal Multiplier { private get; set; } public decimal Multiplier { private get; set; }
public string Error { private get; set; } = string.Empty; public string Error { private get; set; } = string.Empty;
private bool UseCharacterSpecificItemsToPurchase => _plugin.CharacterConfiguration is {OverrideItemsToPurchase: true }; private bool UseCharacterSpecificItemsToPurchase =>
_plugin.CharacterConfiguration is { OverrideItemsToPurchase: true };
private IItemsToPurchase ItemsWrapper => UseCharacterSpecificItemsToPurchase private IItemsToPurchase ItemsWrapper => UseCharacterSpecificItemsToPurchase
? new CharacterSpecificItemsToPurchase(_plugin.CharacterConfiguration!, _pluginInterface) ? new CharacterSpecificItemsToPurchase(_plugin.CharacterConfiguration!, _pluginInterface)
@ -67,7 +68,8 @@ internal sealed class TurnInWindow : Window
var rank = _plugin.GetGrandCompanyRank(); var rank = _plugin.GetGrandCompanyRank();
return ItemsWrapper.GetItemsToPurchase() return ItemsWrapper.GetItemsToPurchase()
.Where(x => x.ItemId != 0) .Where(x => x.ItemId != 0)
.Select(x => new { Item = x, Reward = _gcRewardsCache.GetReward(grandCompany, x.ItemId) }) .Select(x => new { Item = x, Reward = _gcRewardsCache.GetReward(x.ItemId) })
.Where(x => x.Reward.GrandCompanies.Contains(grandCompany))
.Where(x => x.Reward.RequiredRank <= rank) .Where(x => x.Reward.RequiredRank <= rank)
.Select(x => new PurchaseItemRequest .Select(x => new PurchaseItemRequest
{ {
@ -147,16 +149,18 @@ internal sealed class TurnInWindow : Window
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, uint Rank)> comboValues = new() List<(uint ItemId, string Name, IReadOnlyList<GrandCompany> GrandCompanies, uint Rank)> comboValues = new()
{ (GcRewardItem.None.ItemId, GcRewardItem.None.Name, GcRewardItem.None.RequiredRank) }; {
(GcRewardItem.None.ItemId, GcRewardItem.None.Name, new List<GrandCompany>(), GcRewardItem.None.RequiredRank)
};
foreach (uint itemId in _configuration.ItemsAvailableForPurchase) foreach (uint itemId in _configuration.ItemsAvailableForPurchase)
{ {
var gcReward = _gcRewardsCache.GetReward(grandCompany, itemId); var gcReward = _gcRewardsCache.GetReward(itemId);
int itemCount = _plugin.GetItemCount(itemId); int itemCount = _plugin.GetItemCount(itemId);
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.RequiredRank)); comboValues.Add((itemId, itemName, gcReward.GrandCompanies, gcReward.RequiredRank));
} }
if (itemsWrapper.GetItemsToPurchase().Count == 0) if (itemsWrapper.GetItemsToPurchase().Count == 0)
@ -216,10 +220,19 @@ internal sealed class TurnInWindow : Window
itemsWrapper.Save(); itemsWrapper.Save();
} }
if (comboValueIndex > 0 && comboValues[comboValueIndex].Rank > _plugin.GetGrandCompanyRank()) if (comboValueIndex > 0)
{ {
ImGui.TextColored(ImGuiColors.DalamudRed, var comboItem = comboValues[comboValueIndex];
"This item will be skipped, your rank isn't high enough to buy it."); if (!comboItem.GrandCompanies.Contains(grandCompany))
{
ImGui.TextColored(ImGuiColors.DalamudRed,
"This item will be skipped, as you are in the wrong Grand Company.");
}
else if (comboItem.Rank > _plugin.GetGrandCompanyRank())
{
ImGui.TextColored(ImGuiColors.DalamudRed,
"This item will be skipped, your rank isn't high enough to buy it.");
}
} }
ImGui.Unindent(27); ImGui.Unindent(27);
@ -232,7 +245,8 @@ internal sealed class TurnInWindow : Window
itemsWrapper.Save(); itemsWrapper.Save();
} }
if (_configuration.ItemsAvailableForPurchase.Any(x => itemsWrapper.GetItemsToPurchase().All(y => x != y.ItemId))) if (_configuration.ItemsAvailableForPurchase.Any(x =>
itemsWrapper.GetItemsToPurchase().All(y => x != y.ItemId)))
{ {
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add Item")) if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add Item"))
{ {
@ -284,7 +298,8 @@ internal sealed class TurnInWindow : Window
private readonly CharacterConfiguration _characterConfiguration; private readonly CharacterConfiguration _characterConfiguration;
private readonly DalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
public CharacterSpecificItemsToPurchase(CharacterConfiguration characterConfiguration, DalamudPluginInterface pluginInterface) public CharacterSpecificItemsToPurchase(CharacterConfiguration characterConfiguration,
DalamudPluginInterface pluginInterface)
{ {
_characterConfiguration = characterConfiguration; _characterConfiguration = characterConfiguration;
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;