diff --git a/Deliveroo/Configuration.cs b/Deliveroo/Configuration.cs index 7a8c8d3..62aeb86 100644 --- a/Deliveroo/Configuration.cs +++ b/Deliveroo/Configuration.cs @@ -11,4 +11,12 @@ internal sealed class Configuration : IPluginConfiguration public uint SelectedPurchaseItemId { get; set; } = 0; public int ReservedSealCount { get; set; } = 0; + public ItemFilterType ItemFilter { get; set; } = ItemFilterType.HideGearSetItems; + + public enum ItemFilterType + { + ShowAllItems = 0, + HideGearSetItems = 1, + HideArmouryChestItems = 2, + } } diff --git a/Deliveroo/DeliverooPlugin.Exchange.cs b/Deliveroo/DeliverooPlugin.Exchange.cs new file mode 100644 index 0000000..12fdbb6 --- /dev/null +++ b/Deliveroo/DeliverooPlugin.Exchange.cs @@ -0,0 +1,111 @@ +using System; +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Logging; +using FFXIVClientStructs.FFXIV.Component.GUI; +using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType; + +namespace Deliveroo; + +partial class DeliverooPlugin +{ + private void InteractWithQuartermaster(GameObject personnelOfficer, GameObject quartermaster) + { + if (GetCurrentSealCount() < _configuration.ReservedSealCount) + { + CurrentStage = Stage.RequestStop; + return; + } + + if (_targetManager.Target == personnelOfficer) + return; + + InteractWithTarget(quartermaster); + CurrentStage = Stage.SelectRewardTier; + } + + private unsafe void SelectRewardTier() + { + if (TryGetAddonByName("GrandCompanyExchange", out var addonExchange) && + IsAddonReady(addonExchange)) + { + PluginLog.Information($"Selecting tier 1, {(int)_selectedRewardItem.Tier - 1}"); + var selectRank = stackalloc AtkValue[] + { + new() { Type = ValueType.Int, Int = 1 }, + new() { Type = ValueType.Int, Int = (int)_selectedRewardItem.Tier - 1 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 } + }; + addonExchange->FireCallback(9, selectRank); + _continueAt = DateTime.Now.AddSeconds(0.5); + CurrentStage = Stage.SelectRewardSubCategory; + } + } + + private unsafe void SelectRewardSubCategory() + { + if (TryGetAddonByName("GrandCompanyExchange", out var addonExchange) && + IsAddonReady(addonExchange)) + { + PluginLog.Information($"Selecting subcategory 2, {(int)_selectedRewardItem.SubCategory}"); + var selectType = stackalloc AtkValue[] + { + new() { Type = ValueType.Int, Int = 2 }, + new() { Type = ValueType.Int, Int = (int)_selectedRewardItem.SubCategory }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 }, + new() { Type = 0, Int = 0 } + }; + addonExchange->FireCallback(9, selectType); + _continueAt = DateTime.Now.AddSeconds(0.5); + CurrentStage = Stage.SelectReward; + } + } + + private unsafe void SelectReward() + { + if (TryGetAddonByName("GrandCompanyExchange", out var addonExchange) && + IsAddonReady(addonExchange)) + { + if (SelectRewardItem(addonExchange)) + { + _continueAt = DateTime.Now.AddSeconds(0.5); + CurrentStage = Stage.ConfirmReward; + } + else + { + PluginLog.Warning("Could not find selected reward item"); + _continueAt = DateTime.Now.AddSeconds(0.5); + CurrentStage = Stage.CloseGcExchange; + } + } + } + + private void ConfirmReward() + { + if (SelectSelectYesno(0)) + { + CurrentStage = Stage.CloseGcExchange; + _continueAt = DateTime.Now.AddSeconds(0.5); + } + } + + private unsafe void CloseGcExchange() + { + if (TryGetAddonByName("GrandCompanyExchange", out var addonExchange) && + IsAddonReady(addonExchange)) + { + addonExchange->FireCallbackInt(-1); + CurrentStage = Stage.TargetPersonnelOfficer; + } + } +} diff --git a/Deliveroo/DeliverooPlugin.Supply.cs b/Deliveroo/DeliverooPlugin.Supply.cs new file mode 100644 index 0000000..2ab2825 --- /dev/null +++ b/Deliveroo/DeliverooPlugin.Supply.cs @@ -0,0 +1,197 @@ +using System; +using System.Collections.Generic; +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Logging; +using Dalamud.Memory; +using Deliveroo.GameData; +using FFXIVClientStructs.FFXIV.Client.UI; +using FFXIVClientStructs.FFXIV.Client.UI.Agent; +using FFXIVClientStructs.FFXIV.Component.GUI; +using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType; + +namespace Deliveroo; + +partial class DeliverooPlugin +{ + private void InteractWithPersonnelOfficer(GameObject personnelOfficer, GameObject quartermaster) + { + if (_targetManager.Target == quartermaster) + return; + + InteractWithTarget(personnelOfficer); + CurrentStage = Stage.OpenGcSupply; + } + + private void OpenGcSupply() + { + if (SelectSelectString(0)) + CurrentStage = Stage.SelectExpertDeliveryTab; + } + + private unsafe void SelectExpertDeliveryTab() + { + var agentInterface = AgentModule.Instance()->GetAgentByInternalId(AgentId.GrandCompanySupply); + if (agentInterface != null && agentInterface->IsAgentActive()) + { + var addonId = agentInterface->GetAddonID(); + if (addonId == 0) + return; + + AtkUnitBase* addon = GetAddonById(addonId); + if (addon == null || !IsAddonReady(addon)) + return; + + // if using haseltweaks, this *can* be the default + var addonGc = (AddonGrandCompanySupplyList*)addon; + if (addonGc->SelectedTab == 2) + { + PluginLog.Information("Tab already selected, probably due to haseltweaks"); + CurrentStage = Stage.SelectItemToTurnIn; + return; + } + + PluginLog.Information("Switching to expert deliveries"); + var selectExpertDeliveryTab = stackalloc AtkValue[] + { + new() { Type = ValueType.Int, Int = 0 }, + new() { Type = ValueType.Int, Int = 2 }, + new() { Type = 0, Int = 0 } + }; + addon->FireCallback(3, selectExpertDeliveryTab); + } + } + + private unsafe void SelectItemToTurnIn() + { + var agentInterface = AgentModule.Instance()->GetAgentByInternalId(AgentId.GrandCompanySupply); + if (agentInterface != null && agentInterface->IsAgentActive()) + { + var addonId = agentInterface->GetAddonID(); + if (addonId == 0) + return; + + AtkUnitBase* addon = GetAddonById(addonId); + if (addon == null || !IsAddonReady(addon) || addon->UldManager.NodeListCount <= 20 || + !addon->UldManager.NodeList[5]->IsVisible) + return; + + var addonGc = (AddonGrandCompanySupplyList*)addon; + if (addonGc->SelectedTab != 2) + { + _turnInWindow.Error = "Wrong tab selected"; + return; + } + + if (addonGc->SelectedFilter == 0 || addonGc->SelectedFilter != (int)_configuration.ItemFilter) + { + _turnInWindow.Error = + $"Wrong filter selected (expected {_configuration.ItemFilter}, but is {(Configuration.ItemFilterType)addonGc->SelectedFilter})"; + return; + } + + var agent = (AgentGrandCompanySupply*)agentInterface; + List items = BuildTurnInList(agent); + if (items.Count == 0 || addon->UldManager.NodeList[20]->IsVisible) + { + CurrentStage = Stage.CloseGcSupplyThenStop; + addon->FireCallbackInt(-1); + return; + } + + if (GetCurrentSealCount() + items[0].SealsWithBonus > GetSealCap()) + { + CurrentStage = Stage.CloseGcSupply; + addon->FireCallbackInt(-1); + return; + } + + var selectFirstItem = stackalloc AtkValue[] + { + new() { Type = ValueType.Int, Int = 1 }, + new() { Type = ValueType.Int, Int = 0 /* position within list */ }, + new() { Type = 0, Int = 0 } + }; + addon->FireCallback(3, selectFirstItem); + CurrentStage = Stage.TurnInSelected; + } + } + + private unsafe void TurnInSelectedItem() + { + if (TryGetAddonByName("SelectYesno", out var addonSelectYesno) && + IsAddonReady(&addonSelectYesno->AtkUnitBase)) + { + if (MemoryHelper.ReadSeString(&addonSelectYesno->PromptText->NodeText).ToString() + .StartsWith("Do you really want to trade a high-quality item?")) + { + addonSelectYesno->AtkUnitBase.FireCallbackInt(0); + return; + } + } + + if (TryGetAddonByName("GrandCompanySupplyReward", + out var addonSupplyReward) && IsAddonReady(&addonSupplyReward->AtkUnitBase)) + { + addonSupplyReward->AtkUnitBase.FireCallbackInt(0); + _continueAt = DateTime.Now.AddSeconds(0.58); + CurrentStage = Stage.FinalizeTurnIn; + } + } + + private unsafe void FinalizeTurnInItem() + { + if (TryGetAddonByName("GrandCompanySupplyList", + out var addonSupplyList) && IsAddonReady(&addonSupplyList->AtkUnitBase)) + { + var updateFilter = stackalloc AtkValue[] + { + new() { Type = ValueType.Int, Int = 5 }, + new() { Type = ValueType.Int, Int = (int)_configuration.ItemFilter }, + new() { Type = 0, Int = 0 } + }; + addonSupplyList->AtkUnitBase.FireCallback(3, updateFilter); + CurrentStage = Stage.SelectItemToTurnIn; + } + } + + private void CloseGcSupply() + { + if (SelectSelectString(3)) + { + if (!_selectedRewardItem.IsValid()) + { + _turnInWindow.State = false; + CurrentStage = Stage.RequestStop; + } + else + { + // you can occasionally get a 'not enough seals' warning lol + _continueAt = DateTime.Now.AddSeconds(1); + CurrentStage = Stage.TargetQuartermaster; + } + } + } + + private void CloseGcSupplyThenStop() + { + if (SelectSelectString(3)) + { + if (!_selectedRewardItem.IsValid()) + { + _turnInWindow.State = false; + CurrentStage = Stage.RequestStop; + } + else if (GetCurrentSealCount() <= + _configuration.ReservedSealCount + _selectedRewardItem.SealCost) + { + _turnInWindow.State = false; + CurrentStage = Stage.RequestStop; + } + else + { + _continueAt = DateTime.Now.AddSeconds(1); + CurrentStage = Stage.TargetQuartermaster; + } + } + } +} diff --git a/Deliveroo/DeliverooPlugin.cs b/Deliveroo/DeliverooPlugin.cs index 3fa358e..9477163 100644 --- a/Deliveroo/DeliverooPlugin.cs +++ b/Deliveroo/DeliverooPlugin.cs @@ -30,7 +30,7 @@ using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType; namespace Deliveroo; -public sealed class DeliverooPlugin : IDalamudPlugin +public sealed partial class DeliverooPlugin : IDalamudPlugin { private readonly WindowSystem _windowSystem = new(typeof(DeliverooPlugin).AssemblyQualifiedName); @@ -78,7 +78,7 @@ public sealed class DeliverooPlugin : IDalamudPlugin _gcRewardsCache = new GcRewardsCache(dataManager); _configWindow = new ConfigWindow(_pluginInterface, this, _configuration, _gcRewardsCache); _windowSystem.AddWindow(_configWindow); - _turnInWindow = new TurnInWindow(this, _pluginInterface, _configuration, _gcRewardsCache); + _turnInWindow = new TurnInWindow(this, _pluginInterface, _configuration, _gcRewardsCache, _configWindow); _windowSystem.AddWindow(_turnInWindow); _sealCaps = dataManager.GetExcelSheet()!.Where(x => x.RowId > 0) .ToDictionary(x => x.RowId, x => x.MaxSeals); @@ -105,6 +105,7 @@ public sealed class DeliverooPlugin : IDalamudPlugin private unsafe void FrameworkUpdate(Framework f) { + _turnInWindow.Error = string.Empty; if (!_clientState.IsLoggedIn || _clientState.TerritoryType is not 128 and not 130 and not 132 || GetDistanceToNpc(GetQuartermasterId(), out GameObject? quartermaster) >= 7f || GetDistanceToNpc(GetPersonnelOfficerId(), out GameObject? personnelOfficer) >= 7f || @@ -145,7 +146,7 @@ public sealed class DeliverooPlugin : IDalamudPlugin if (TryGetAddonByName("GrandCompanySupplyList", out var gcSupplyList) && IsAddonReady(&gcSupplyList->AtkUnitBase)) - CurrentStage = Stage.SelectItemToTurnIn; + CurrentStage = Stage.SelectExpertDeliveryTab; if (TryGetAddonByName("GrandCompanyExchange", out var gcExchange) && IsAddonReady(gcExchange)) @@ -158,247 +159,60 @@ public sealed class DeliverooPlugin : IDalamudPlugin switch (CurrentStage) { case Stage.TargetPersonnelOfficer: - if (_targetManager.Target == quartermaster!) - break; - - InteractWithTarget(personnelOfficer!); - CurrentStage = Stage.OpenGcSupply; + InteractWithPersonnelOfficer(personnelOfficer!, quartermaster!); break; + case Stage.OpenGcSupply: - if (SelectSelectString(0)) - CurrentStage = Stage.SelectItemToTurnIn; - + OpenGcSupply(); break; + + case Stage.SelectExpertDeliveryTab: + SelectExpertDeliveryTab(); + break; + case Stage.SelectItemToTurnIn: - var agentInterface = AgentModule.Instance()->GetAgentByInternalId(AgentId.GrandCompanySupply); - if (agentInterface != null && agentInterface->IsAgentActive()) - { - var addonId = agentInterface->GetAddonID(); - if (addonId == 0) - break; - - AtkUnitBase* addon = GetAddonById(addonId); - if (addon == null || !IsAddonReady(addon) || addon->UldManager.NodeListCount <= 20 || - !addon->UldManager.NodeList[5]->IsVisible) - break; - - var addonGc = (AddonGrandCompanySupplyList*)addon; - if (addonGc->SelectedTab != 2 || addonGc->SelectedFilter != 1) - break; - - var agent = (AgentGrandCompanySupply*)agentInterface; - List items = BuildTurnInList(agent); - if (items.Count == 0 || addon->UldManager.NodeList[20]->IsVisible) - { - CurrentStage = Stage.CloseGcSupplyThenStop; - addon->FireCallbackInt(-1); - break; - } - - if (GetCurrentSealCount() + items[0].SealsWithBonus > GetSealCap()) - { - CurrentStage = Stage.CloseGcSupply; - addon->FireCallbackInt(-1); - break; - } - - var selectFirstItem = stackalloc AtkValue[] - { - new() { Type = ValueType.Int, Int = 1 }, - new() { Type = ValueType.Int, Int = 0 /* position within list */ }, - new() { Type = 0, Int = 0 } - }; - addon->FireCallback(3, selectFirstItem); - CurrentStage = Stage.TurnInSelected; - } - + SelectItemToTurnIn(); break; + case Stage.TurnInSelected: - if (TryGetAddonByName("SelectYesno", out var addonSelectYesno) && - IsAddonReady(&addonSelectYesno->AtkUnitBase)) - { - if (MemoryHelper.ReadSeString(&addonSelectYesno->PromptText->NodeText).ToString() - .StartsWith("Do you really want to trade a high-quality item?")) - { - addonSelectYesno->AtkUnitBase.FireCallbackInt(0); - break; - } - } - - if (TryGetAddonByName("GrandCompanySupplyReward", - out var addonSupplyReward) && IsAddonReady(&addonSupplyReward->AtkUnitBase)) - { - addonSupplyReward->AtkUnitBase.FireCallbackInt(0); - _continueAt = DateTime.Now.AddSeconds(0.58); - CurrentStage = Stage.FinalizeTurnIn; - } - + TurnInSelectedItem(); break; case Stage.FinalizeTurnIn: - if (TryGetAddonByName("GrandCompanySupplyList", - out var addonSupplyList) && IsAddonReady(&addonSupplyList->AtkUnitBase)) - { - var updateFilter = stackalloc AtkValue[] - { - new() { Type = ValueType.Int, Int = 5 }, - new() { Type = ValueType.Int, Int = addonSupplyList->SelectedFilter }, - new() { Type = 0, Int = 0 } - }; - addonSupplyList->AtkUnitBase.FireCallback(3, updateFilter); - CurrentStage = Stage.SelectItemToTurnIn; - } - + FinalizeTurnInItem(); break; case Stage.CloseGcSupply: - if (SelectSelectString(3)) - { - if (!_selectedRewardItem.IsValid()) - { - _turnInWindow.State = false; - CurrentStage = Stage.RequestStop; - } - else - { - // you can occasionally get a 'not enough seals' warning lol - _continueAt = DateTime.Now.AddSeconds(1); - CurrentStage = Stage.TargetQuartermaster; - } - } - + CloseGcSupply(); break; case Stage.CloseGcSupplyThenStop: - if (SelectSelectString(3)) - { - if (!_selectedRewardItem.IsValid()) - { - _turnInWindow.State = false; - CurrentStage = Stage.RequestStop; - } - else if (GetCurrentSealCount() <= - _configuration.ReservedSealCount + _selectedRewardItem.SealCost) - { - _turnInWindow.State = false; - CurrentStage = Stage.RequestStop; - } - else - { - _continueAt = DateTime.Now.AddSeconds(1); - CurrentStage = Stage.TargetQuartermaster; - } - } - + CloseGcSupplyThenStop(); break; case Stage.TargetQuartermaster: - if (GetCurrentSealCount() < _configuration.ReservedSealCount) - { - CurrentStage = Stage.RequestStop; - break; - } - - if (_targetManager.Target == personnelOfficer!) - break; - - InteractWithTarget(quartermaster!); - CurrentStage = Stage.SelectRewardTier; + InteractWithQuartermaster(personnelOfficer!, quartermaster!); break; case Stage.SelectRewardTier: - { - if (TryGetAddonByName("GrandCompanyExchange", out var addonExchange) && - IsAddonReady(addonExchange)) - { - PluginLog.Information($"Selecting tier 1, {(int)_selectedRewardItem.Tier - 1}"); - var selectRank = stackalloc AtkValue[] - { - new() { Type = ValueType.Int, Int = 1 }, - new() { Type = ValueType.Int, Int = (int)_selectedRewardItem.Tier - 1 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 } - }; - addonExchange->FireCallback(9, selectRank); - _continueAt = DateTime.Now.AddSeconds(0.5); - CurrentStage = Stage.SelectRewardSubCategory; - } - + SelectRewardTier(); break; - } case Stage.SelectRewardSubCategory: - { - if (TryGetAddonByName("GrandCompanyExchange", out var addonExchange) && - IsAddonReady(addonExchange)) - { - PluginLog.Information($"Selecting subcategory 2, {(int)_selectedRewardItem.SubCategory}"); - var selectType = stackalloc AtkValue[] - { - new() { Type = ValueType.Int, Int = 2 }, - new() { Type = ValueType.Int, Int = (int)_selectedRewardItem.SubCategory }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 }, - new() { Type = 0, Int = 0 } - }; - addonExchange->FireCallback(9, selectType); - _continueAt = DateTime.Now.AddSeconds(0.5); - CurrentStage = Stage.SelectReward; - } - + SelectRewardSubCategory(); break; - } case Stage.SelectReward: - { - if (TryGetAddonByName("GrandCompanyExchange", out var addonExchange) && - IsAddonReady(addonExchange)) - { - if (SelectRewardItem(addonExchange)) - { - _continueAt = DateTime.Now.AddSeconds(0.5); - CurrentStage = Stage.ConfirmReward; - } - else - { - PluginLog.Warning("Could not find selected reward item"); - _continueAt = DateTime.Now.AddSeconds(0.5); - CurrentStage = Stage.CloseGcExchange; - } - } - + SelectReward(); break; - } case Stage.ConfirmReward: - if (SelectSelectYesno(0)) - { - CurrentStage = Stage.CloseGcExchange; - _continueAt = DateTime.Now.AddSeconds(0.5); - } - + ConfirmReward(); break; case Stage.CloseGcExchange: - { - if (TryGetAddonByName("GrandCompanyExchange", out var addonExchange) && - IsAddonReady(addonExchange)) - { - addonExchange->FireCallbackInt(-1); - CurrentStage = Stage.TargetPersonnelOfficer; - } - + CloseGcExchange(); break; - } case Stage.RequestStop: RestoreYesAlready(); @@ -699,6 +513,7 @@ public sealed class DeliverooPlugin : IDalamudPlugin { TargetPersonnelOfficer, OpenGcSupply, + SelectExpertDeliveryTab, SelectItemToTurnIn, TurnInSelected, FinalizeTurnIn, diff --git a/Deliveroo/Windows/ConfigWindow.cs b/Deliveroo/Windows/ConfigWindow.cs index 808d956..d86bdd2 100644 --- a/Deliveroo/Windows/ConfigWindow.cs +++ b/Deliveroo/Windows/ConfigWindow.cs @@ -13,6 +13,8 @@ namespace Deliveroo.Windows; internal sealed class ConfigWindow : Window { + private static string[] _itemFilterValues = { "Hide Gear Set Items", "Hide Armoury Chest Items" }; + private readonly DalamudPluginInterface _pluginInterface; private readonly DeliverooPlugin _plugin; private readonly Configuration _configuration; @@ -170,6 +172,16 @@ internal sealed class ConfigWindow : Window _configuration.ReservedSealCount = Math.Max(0, Math.Min(90_000, reservedSealCount)); Save(); } + + ImGui.Separator(); + int selectedItemFilter = Math.Max(0, (int)_configuration.ItemFilter - 1); + if (ImGui.Combo("Item Filter", ref selectedItemFilter, _itemFilterValues, _itemFilterValues.Length)) + { + _configuration.ItemFilter = (Configuration.ItemFilterType)(selectedItemFilter + 1); + Save(); + } + + ImGui.EndTabItem(); } } diff --git a/Deliveroo/Windows/TurnInWindow.cs b/Deliveroo/Windows/TurnInWindow.cs index 302458f..6d1a247 100644 --- a/Deliveroo/Windows/TurnInWindow.cs +++ b/Deliveroo/Windows/TurnInWindow.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; +using Dalamud.Interface; using Dalamud.Interface.Colors; +using Dalamud.Interface.Components; using Dalamud.Interface.Windowing; using Dalamud.Plugin; using Deliveroo.GameData; @@ -17,16 +19,18 @@ internal sealed class TurnInWindow : Window private readonly DalamudPluginInterface _pluginInterface; private readonly Configuration _configuration; private readonly GcRewardsCache _gcRewardsCache; + private readonly ConfigWindow _configWindow; private int _selectedAutoBuyItem = 0; public TurnInWindow(DeliverooPlugin plugin, DalamudPluginInterface pluginInterface, Configuration configuration, - GcRewardsCache gcRewardsCache) + GcRewardsCache gcRewardsCache, ConfigWindow configWindow) : base("GC Delivery###DeliverooTurnIn") { _plugin = plugin; _pluginInterface = pluginInterface; _configuration = configuration; _gcRewardsCache = gcRewardsCache; + _configWindow = configWindow; Position = new Vector2(100, 100); PositionCondition = ImGuiCond.FirstUseEver; @@ -37,6 +41,7 @@ internal sealed class TurnInWindow : Window public bool State { get; set; } public decimal Multiplier { private get; set; } + public string Error { private get; set; } public uint SelectedItemId { @@ -97,40 +102,50 @@ internal sealed class TurnInWindow : Window State = state; } + ImGui.SameLine(); + if (ImGuiComponents.IconButton("###OpenConfig", FontAwesomeIcon.Cog)) + _configWindow.IsOpen = true; + ImGui.Indent(27); - if (Multiplier == 1m) + if (!string.IsNullOrEmpty(Error)) { - ImGui.TextColored(ImGuiColors.DalamudRed, "You do not have an active seal buff."); - } - else - { - ImGui.TextColored(ImGuiColors.HealerGreen, $"Current Buff: {(Multiplier - 1m) * 100:N0}%%"); - } - - ImGui.Spacing(); - ImGui.BeginDisabled(state); - - List comboValues = new() { GcRewardItem.None.Name }; - foreach (var itemId in _configuration.ItemsAvailableForPurchase) - { - var name = _gcRewardsCache.Rewards[grandCompany].First(x => x.ItemId == itemId).Name; - int itemCount = GetItemCount(itemId); - if (itemCount > 0) - comboValues.Add($"{name} ({itemCount:N0})"); + ImGui.TextColored(ImGuiColors.DalamudRed, Error); + } else { + if (Multiplier == 1m) + { + ImGui.TextColored(ImGuiColors.DalamudYellow, "You do not have an active seal buff."); + } else - comboValues.Add(name); + { + ImGui.TextColored(ImGuiColors.HealerGreen, $"Current Buff: {(Multiplier - 1m) * 100:N0}%%"); + } + + ImGui.Spacing(); + ImGui.BeginDisabled(state); + + List comboValues = new() { GcRewardItem.None.Name }; + foreach (var itemId in _configuration.ItemsAvailableForPurchase) + { + var name = _gcRewardsCache.Rewards[grandCompany].First(x => x.ItemId == itemId).Name; + int itemCount = GetItemCount(itemId); + if (itemCount > 0) + comboValues.Add($"{name} ({itemCount:N0})"); + else + comboValues.Add(name); + } + + if (ImGui.Combo("", ref _selectedAutoBuyItem, comboValues.ToArray(), comboValues.Count)) + { + _configuration.SelectedPurchaseItemId = SelectedItemId; + _pluginInterface.SavePluginConfig(_configuration); + } + + if (SelectedItem.IsValid() && SelectedItem.RequiredRank > _plugin.GetGrandCompanyRank()) + ImGui.TextColored(ImGuiColors.DalamudRed, "Your rank isn't high enough to buy this item."); + + ImGui.EndDisabled(); } - if (ImGui.Combo("", ref _selectedAutoBuyItem, comboValues.ToArray(), comboValues.Count)) - { - _configuration.SelectedPurchaseItemId = SelectedItemId; - _pluginInterface.SavePluginConfig(_configuration); - } - - if (SelectedItem.IsValid() && SelectedItem.RequiredRank > _plugin.GetGrandCompanyRank()) - ImGui.TextColored(ImGuiColors.DalamudRed, "Your rank isn't high enough to buy this item."); - - ImGui.EndDisabled(); ImGui.Unindent(27); ImGui.Separator();