diff --git a/Deliveroo/Deliveroo.csproj b/Deliveroo/Deliveroo.csproj index 7015949..60206c6 100644 --- a/Deliveroo/Deliveroo.csproj +++ b/Deliveroo/Deliveroo.csproj @@ -1,7 +1,7 @@ net7.0-windows - 2.18 + 2.19 11.0 enable true diff --git a/Deliveroo/DeliverooPlugin.cs b/Deliveroo/DeliverooPlugin.cs index e3d850a..3978a18 100644 --- a/Deliveroo/DeliverooPlugin.cs +++ b/Deliveroo/DeliverooPlugin.cs @@ -16,6 +16,7 @@ using Deliveroo.GameData; using Deliveroo.Windows; using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Component.GUI; +using LLib; using LLib.GameUI; using Lumina.Excel.GeneratedSheets; @@ -46,6 +47,7 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable private readonly GcRewardsCache _gcRewardsCache; + private readonly IconCache _iconCache; private readonly ConfigWindow _configWindow; private readonly TurnInWindow _turnInWindow; private readonly IReadOnlyDictionary _sealCaps; @@ -59,7 +61,7 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin public DeliverooPlugin(DalamudPluginInterface pluginInterface, IChatGui chatGui, IGameGui gameGui, IFramework framework, IClientState clientState, IObjectTable objectTable, ITargetManager targetManager, IDataManager dataManager, ICondition condition, ICommandManager commandManager, IPluginLog pluginLog, - IAddonLifecycle addonLifecycle) + IAddonLifecycle addonLifecycle, ITextureProvider textureProvider) { _pluginInterface = pluginInterface; _chatGui = chatGui; @@ -77,9 +79,10 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin _externalPluginHandler = new ExternalPluginHandler(_pluginInterface, _pluginLog); _configuration = (Configuration?)_pluginInterface.GetPluginConfig() ?? new Configuration(); _gcRewardsCache = new GcRewardsCache(dataManager); - _configWindow = new ConfigWindow(_pluginInterface, this, _configuration, _gcRewardsCache, _clientState, _pluginLog); + _iconCache = new IconCache(textureProvider); + _configWindow = new ConfigWindow(_pluginInterface, this, _configuration, _gcRewardsCache, _clientState, _pluginLog, _iconCache); _windowSystem.AddWindow(_configWindow); - _turnInWindow = new TurnInWindow(this, _pluginInterface, _configuration, _condition, _gcRewardsCache, _configWindow); + _turnInWindow = new TurnInWindow(this, _pluginInterface, _configuration, _condition, _gcRewardsCache, _configWindow, _iconCache); _windowSystem.AddWindow(_turnInWindow); _sealCaps = dataManager.GetExcelSheet()!.Where(x => x.RowId > 0) .ToDictionary(x => x.RowId, x => x.MaxSeals); @@ -348,6 +351,9 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin _framework.Update -= FrameworkUpdate; _externalPluginHandler.Restore(); + + _externalPluginHandler.Dispose(); + _iconCache.Dispose(); } private void ProcessCommand(string command, string arguments) diff --git a/Deliveroo/External/ExternalPluginHandler.cs b/Deliveroo/External/ExternalPluginHandler.cs index 9a1d152..9eb101e 100644 --- a/Deliveroo/External/ExternalPluginHandler.cs +++ b/Deliveroo/External/ExternalPluginHandler.cs @@ -1,10 +1,11 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Dalamud.Plugin; using Dalamud.Plugin.Services; namespace Deliveroo.External; -internal sealed class ExternalPluginHandler +internal sealed class ExternalPluginHandler : IDisposable { private readonly DalamudPluginInterface _pluginInterface; private readonly IPluginLog _pluginLog; @@ -83,4 +84,9 @@ internal sealed class ExternalPluginHandler if (_pandoraState == true) _pandoraIpc.Enable(); } + + public void Dispose() + { + _deliverooIpc.Dispose(); + } } diff --git a/Deliveroo/GameData/GcRewardItem.cs b/Deliveroo/GameData/GcRewardItem.cs index 0b918ff..b957c4b 100644 --- a/Deliveroo/GameData/GcRewardItem.cs +++ b/Deliveroo/GameData/GcRewardItem.cs @@ -10,6 +10,7 @@ internal sealed class GcRewardItem : IEquatable { ItemId = 0, Name = "---", + IconId = 0, GrandCompanies = new List().AsReadOnly(), Tier = RewardTier.First, SubCategory = RewardSubCategory.Unknown, @@ -20,6 +21,7 @@ internal sealed class GcRewardItem : IEquatable public required uint ItemId { get; init; } public required string Name { get; init; } + public required ushort IconId { get; init; } public required IReadOnlyList GrandCompanies { get; init; } public required RewardTier Tier { get; init; } public required RewardSubCategory SubCategory { get; init; } @@ -28,6 +30,7 @@ internal sealed class GcRewardItem : IEquatable public required uint SealCost { get; init; } public bool IsValid() => ItemId > 0 && GrandCompanies.Count > 0; + public bool Limited => GrandCompanies.Count < 3; public bool Equals(GcRewardItem? other) { diff --git a/Deliveroo/GameData/GcRewardsCache.cs b/Deliveroo/GameData/GcRewardsCache.cs index 1755fc4..6201bf9 100644 --- a/Deliveroo/GameData/GcRewardsCache.cs +++ b/Deliveroo/GameData/GcRewardsCache.cs @@ -27,6 +27,7 @@ internal sealed class GcRewardsCache { ItemId = item.Item.Row, Name = item.Item.Value!.Name.ToString(), + IconId = item.Item.Row == ItemIds.Venture ? 25917 : item.Item.Value!.Icon, category.Tier, category.SubCategory, RequiredRank = item.RequiredGrandCompanyRank.Row, @@ -38,6 +39,7 @@ internal sealed class GcRewardsCache { ItemId = item.Key.ItemId, Name = item.Key.Name, + IconId = (ushort)item.Key.IconId, Tier = item.Key.Tier, SubCategory = item.Key.SubCategory, RequiredRank = item.Key.RequiredRank, diff --git a/Deliveroo/Windows/ConfigWindow.cs b/Deliveroo/Windows/ConfigWindow.cs index c275bbd..9af5663 100644 --- a/Deliveroo/Windows/ConfigWindow.cs +++ b/Deliveroo/Windows/ConfigWindow.cs @@ -2,8 +2,10 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; +using Dalamud.Game.Text; using Dalamud.Interface; using Dalamud.Interface.Components; +using Dalamud.Interface.Internal; using Dalamud.Interface.Utility; using Dalamud.Plugin; using Dalamud.Plugin.Services; @@ -21,12 +23,13 @@ internal sealed class ConfigWindow : LImGui.LWindow private readonly GcRewardsCache _gcRewardsCache; private readonly IClientState _clientState; private readonly IPluginLog _pluginLog; + private readonly IconCache _iconCache; private readonly IReadOnlyDictionary _itemLookup; private uint _dragDropSource; public ConfigWindow(DalamudPluginInterface pluginInterface, DeliverooPlugin plugin, Configuration configuration, - GcRewardsCache gcRewardsCache, IClientState clientState, IPluginLog pluginLog) + GcRewardsCache gcRewardsCache, IClientState clientState, IPluginLog pluginLog, IconCache iconCache) : base("Deliveroo - Configuration###DeliverooConfig") { _pluginInterface = pluginInterface; @@ -35,6 +38,7 @@ internal sealed class ConfigWindow : LImGui.LWindow _gcRewardsCache = gcRewardsCache; _clientState = clientState; _pluginLog = pluginLog; + _iconCache = iconCache; _itemLookup = _gcRewardsCache.RewardLookup; @@ -79,7 +83,16 @@ internal sealed class ConfigWindow : LImGui.LWindow ImGui.BeginDisabled( _configuration.ItemsAvailableForPurchase.Count == 1 && itemId == ItemIds.Venture); - ImGui.Selectable(_itemLookup[itemId].Name); + var item = _itemLookup[itemId]; + IDalamudTextureWrap? icon = _iconCache.GetIcon(item.IconId); + if (icon != null) + { + ImGui.Image(icon.ImGuiHandle, new Vector2(23, 23)); + ImGui.SameLine(); + ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3); + } + + ImGui.Selectable($"{item.Name}{(item.Limited ? $" {SeIconChar.Hyadelyn.ToIconString()}" : "")}"); if (ImGui.BeginDragDropSource()) { @@ -132,22 +145,37 @@ internal sealed class ConfigWindow : LImGui.LWindow Save(); } - List<(uint ItemId, string Name)> 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.StackSize > 1) .Where(x => !_configuration.ItemsAvailableForPurchase.Contains(x.ItemId)) - .Select(x => (x.ItemId, x.Name)) + .Select(x => (x.ItemId, x.Name, x.IconId, x.Limited)) .OrderBy(x => x.Name) .ThenBy(x => x.GetHashCode()) .ToList(); - comboValues.Insert(0, (0, "")); - int currentItem = 0; - if (ImGui.Combo("Add Item", ref currentItem, comboValues.Select(x => x.Name).ToArray(), comboValues.Count) - && comboValues[currentItem].ItemId != GcRewardItem.None.ItemId) + if (ImGui.BeginCombo($"##ItemSelection", "Add Item...", ImGuiComboFlags.HeightLarge)) { - _configuration.ItemsAvailableForPurchase.Add(comboValues[currentItem].ItemId); - Save(); + ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); + + foreach (var item in comboValues) + { + IDalamudTextureWrap? icon = _iconCache.GetIcon(item.IconId); + if (icon != null) + { + ImGui.Image(icon.ImGuiHandle, new Vector2(23, 23)); + ImGui.SameLine(); + ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3); + } + + if (ImGui.Selectable($"{item.Name}{(item.Limited ? $" {SeIconChar.Hyadelyn.ToIconString()}" : "")}##SelectVenture{item.IconId}")) + { + _configuration.ItemsAvailableForPurchase.Add(item.ItemId); + Save(); + } + } + + ImGui.EndCombo(); } ImGui.EndTabItem(); diff --git a/Deliveroo/Windows/TurnInWindow.cs b/Deliveroo/Windows/TurnInWindow.cs index 5357aa4..9357ca9 100644 --- a/Deliveroo/Windows/TurnInWindow.cs +++ b/Deliveroo/Windows/TurnInWindow.cs @@ -6,6 +6,7 @@ using Dalamud.Game.ClientState.Conditions; using Dalamud.Interface; using Dalamud.Interface.Colors; using Dalamud.Interface.Components; +using Dalamud.Interface.Internal; using Dalamud.Interface.Utility; using Dalamud.Plugin; using Dalamud.Plugin.Services; @@ -24,9 +25,10 @@ internal sealed class TurnInWindow : LImGui.LWindow private readonly Configuration _configuration; private readonly ICondition _condition; private readonly GcRewardsCache _gcRewardsCache; + private readonly IconCache _iconCache; public TurnInWindow(DeliverooPlugin plugin, DalamudPluginInterface pluginInterface, Configuration configuration, - ICondition condition, GcRewardsCache gcRewardsCache, ConfigWindow configWindow) + ICondition condition, GcRewardsCache gcRewardsCache, ConfigWindow configWindow, IconCache iconCache) : base("GC Delivery###DeliverooTurnIn") { _plugin = plugin; @@ -34,6 +36,7 @@ internal sealed class TurnInWindow : LImGui.LWindow _configuration = configuration; _condition = condition; _gcRewardsCache = gcRewardsCache; + _iconCache = iconCache; Position = new Vector2(100, 100); PositionCondition = ImGuiCond.FirstUseEver; @@ -177,9 +180,9 @@ internal sealed class TurnInWindow : LImGui.LWindow var itemsWrapper = ItemsWrapper; ImGui.Text($"Items to buy ({itemsWrapper.Name}):"); - List<(uint ItemId, string Name, IReadOnlyList GrandCompanies, uint Rank)> comboValues = new() + List<(uint ItemId, string Name, IReadOnlyList GrandCompanies, uint Rank, ushort IconId)> comboValues = new() { - (GcRewardItem.None.ItemId, GcRewardItem.None.Name, new List(), GcRewardItem.None.RequiredRank) + (GcRewardItem.None.ItemId, GcRewardItem.None.Name, new List(), GcRewardItem.None.RequiredRank, GcRewardItem.None.IconId) }; foreach (uint itemId in _configuration.ItemsAvailableForPurchase) { @@ -188,7 +191,7 @@ internal sealed class TurnInWindow : LImGui.LWindow string itemName = gcReward.Name; if (itemCount > 0) itemName += $" ({itemCount:N0})"; - comboValues.Add((itemId, itemName, gcReward.GrandCompanies, gcReward.RequiredRank)); + comboValues.Add((itemId, itemName, gcReward.GrandCompanies, gcReward.RequiredRank, gcReward.IconId)); } if (itemsWrapper.GetItemsToPurchase().Count == 0) @@ -204,6 +207,7 @@ internal sealed class TurnInWindow : LImGui.LWindow { ImGui.PushID($"ItemToBuy{i}"); var item = itemsWrapper.GetItemsToPurchase()[i]; + bool enabled = item.Enabled; ImGui.PushID($"Enable{i}"); if (ImGui.Checkbox("", ref enabled)) @@ -225,6 +229,13 @@ internal sealed class TurnInWindow : LImGui.LWindow comboValueIndex = 0; } + IDalamudTextureWrap? icon = _iconCache.GetIcon(comboValues[comboValueIndex].IconId); + if (icon != null) + { + ImGui.Image(icon.ImGuiHandle, new Vector2(23, 23)); + ImGui.SameLine(0, 3); + } + if (ImGui.Combo("", ref comboValueIndex, comboValues.Select(x => x.Name).ToArray(), comboValues.Count)) { item.ItemId = comboValues[comboValueIndex].ItemId; @@ -262,7 +273,7 @@ internal sealed class TurnInWindow : LImGui.LWindow if (enabled) { - ImGui.Indent(27); + ImGui.Indent(52); if (comboValueIndex > 0) { ImGui.SetNextItemWidth(ImGuiHelpers.GlobalScale * 130); @@ -300,7 +311,7 @@ internal sealed class TurnInWindow : LImGui.LWindow } } - ImGui.Unindent(27); + ImGui.Unindent(52); } ImGui.PopID();