Character specific settings

This commit is contained in:
Liza 2023-09-25 22:27:19 +02:00
parent 342564d6bf
commit 7c9f7e01bc
Signed by: liza
GPG Key ID: 7199F8D727D55F67
6 changed files with 196 additions and 24 deletions

View File

@ -0,0 +1,35 @@
using System.IO;
using Dalamud.Plugin;
using Newtonsoft.Json;
namespace Deliveroo;
internal sealed class CharacterConfiguration
{
public ulong LocalContentId { get; set; }
public string? CachedPlayerName { get; set; }
public string? CachedWorldName { get; set; }
public bool DisableForCharacter { get; set; } = false;
public bool UseHideArmouryChestItemsFilter { get; set; } = false;
public static string ResolveFilePath(DalamudPluginInterface pluginInterface, ulong localContentId)
=> Path.Join(pluginInterface.GetPluginConfigDirectory(), $"char.{localContentId:X}.json");
public static CharacterConfiguration? Load(DalamudPluginInterface pluginInterface, ulong localContentId)
{
string path = ResolveFilePath(pluginInterface, localContentId);
if (!File.Exists(path))
return null;
return JsonConvert.DeserializeObject<CharacterConfiguration>(File.ReadAllText(path));
}
public void Save(DalamudPluginInterface pluginInterface)
{
File.WriteAllText(ResolveFilePath(pluginInterface, LocalContentId), JsonConvert.SerializeObject(this, Formatting.Indented));
}
public void Delete(DalamudPluginInterface pluginInterface) =>
File.Delete(ResolveFilePath(pluginInterface, LocalContentId));
}

View File

@ -11,7 +11,6 @@ internal sealed class Configuration : IPluginConfiguration
public List<PurchasePriority> ItemsToPurchase { get; set; } = new(); public List<PurchasePriority> ItemsToPurchase { get; set; } = new();
public int ReservedSealCount { get; set; } = 0; public int ReservedSealCount { get; set; } = 0;
public ItemFilterType ItemFilter { get; set; } = ItemFilterType.HideGearSetItems;
public bool IgnoreCertainLimitations { get; set; } = false; public bool IgnoreCertainLimitations { get; set; } = false;
internal sealed class PurchasePriority internal sealed class PurchasePriority
@ -20,10 +19,4 @@ internal sealed class Configuration : IPluginConfiguration
public int Limit { get; set; } public int Limit { get; set; }
} }
public enum ItemFilterType
{
ShowAllItems = 0,
HideGearSetItems = 1,
HideArmouryChestItems = 2,
}
} }

View File

@ -86,10 +86,11 @@ partial class DeliverooPlugin
return; return;
} }
if (addonGc->SelectedFilter == 0 || addonGc->SelectedFilter != (int)_configuration.ItemFilter) ItemFilterType configuredFilter = ResolveSelectedSupplyFilter();
if (addonGc->SelectedFilter == 0 || addonGc->SelectedFilter != (int)configuredFilter)
{ {
_turnInWindow.Error = _turnInWindow.Error =
$"Wrong filter selected (expected {_configuration.ItemFilter}, but is {(Configuration.ItemFilterType)addonGc->SelectedFilter})"; $"Wrong filter selected (expected {configuredFilter}, but is {(ItemFilterType)addonGc->SelectedFilter})";
return; return;
} }
@ -169,7 +170,7 @@ partial class DeliverooPlugin
var updateFilter = stackalloc AtkValue[] var updateFilter = stackalloc AtkValue[]
{ {
new() { Type = ValueType.Int, Int = 5 }, new() { Type = ValueType.Int, Int = 5 },
new() { Type = ValueType.Int, Int = (int)_configuration.ItemFilter }, new() { Type = ValueType.Int, Int = (int)ResolveSelectedSupplyFilter() },
new() { Type = 0, Int = 0 } new() { Type = 0, Int = 0 }
}; };
addonSupplyList->AtkUnitBase.FireCallback(3, updateFilter); addonSupplyList->AtkUnitBase.FireCallback(3, updateFilter);
@ -217,4 +218,12 @@ partial class DeliverooPlugin
} }
} }
} }
private ItemFilterType ResolveSelectedSupplyFilter()
{
if (CharacterConfiguration is { UseHideArmouryChestItemsFilter: true })
return ItemFilterType.HideArmouryChestItems;
return ItemFilterType.HideGearSetItems;
}
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using Dalamud.Data; using Dalamud.Data;
using Dalamud.Game; using Dalamud.Game;
@ -18,6 +19,7 @@ using Deliveroo.Windows;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Component.GUI; using FFXIVClientStructs.FFXIV.Component.GUI;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
using Newtonsoft.Json;
using Condition = Dalamud.Game.ClientState.Conditions.Condition; using Condition = Dalamud.Game.ClientState.Conditions.Condition;
namespace Deliveroo; namespace Deliveroo;
@ -72,7 +74,7 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
_yesAlreadyIpc = new YesAlreadyIpc(dalamudReflector); _yesAlreadyIpc = new YesAlreadyIpc(dalamudReflector);
_configuration = (Configuration?)_pluginInterface.GetPluginConfig() ?? new Configuration(); _configuration = (Configuration?)_pluginInterface.GetPluginConfig() ?? new Configuration();
_gcRewardsCache = new GcRewardsCache(dataManager); _gcRewardsCache = new GcRewardsCache(dataManager);
_configWindow = new ConfigWindow(_pluginInterface, this, _configuration, _gcRewardsCache); _configWindow = new ConfigWindow(_pluginInterface, this, _configuration, _gcRewardsCache, _clientState);
_windowSystem.AddWindow(_configWindow); _windowSystem.AddWindow(_configWindow);
_turnInWindow = new TurnInWindow(this, _pluginInterface, _configuration, _gcRewardsCache, _configWindow); _turnInWindow = new TurnInWindow(this, _pluginInterface, _configuration, _gcRewardsCache, _configWindow);
_windowSystem.AddWindow(_turnInWindow); _windowSystem.AddWindow(_turnInWindow);
@ -82,14 +84,22 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
_framework.Update += FrameworkUpdate; _framework.Update += FrameworkUpdate;
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw; _pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
_pluginInterface.UiBuilder.OpenConfigUi += _configWindow.Toggle; _pluginInterface.UiBuilder.OpenConfigUi += _configWindow.Toggle;
_clientState.Login += Login;
_clientState.Logout += Logout;
_commandManager.AddHandler("/deliveroo", new CommandInfo(ProcessCommand) _commandManager.AddHandler("/deliveroo", new CommandInfo(ProcessCommand)
{ {
HelpMessage = "Open the configuration" HelpMessage = "Open the configuration"
}); });
if (_clientState.IsLoggedIn)
Login(this, EventArgs.Empty);
} }
public string Name => "Deliveroo"; public string Name => "Deliveroo";
internal CharacterConfiguration? CharacterConfiguration { get; set; }
internal Stage CurrentStage internal Stage CurrentStage
{ {
get => _currentStageInternal; get => _currentStageInternal;
@ -103,13 +113,53 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
} }
} }
private void Login(object? sender, EventArgs e)
{
try
{
CharacterConfiguration = CharacterConfiguration.Load(_pluginInterface, _clientState.LocalContentId);
if (CharacterConfiguration != null)
{
if (CharacterConfiguration.CachedPlayerName != _clientState.LocalPlayer!.Name.ToString() ||
CharacterConfiguration.CachedWorldName !=
_clientState.LocalPlayer.HomeWorld.GameData!.Name.ToString())
{
CharacterConfiguration.CachedPlayerName = _clientState.LocalPlayer!.Name.ToString();
CharacterConfiguration.CachedWorldName =
_clientState.LocalPlayer.HomeWorld.GameData!.Name.ToString();
CharacterConfiguration.Save(_pluginInterface);
}
PluginLog.Information($"Loaded character-specific information for {_clientState.LocalContentId}");
}
else
{
PluginLog.Verbose(
$"No character-specific information for {_clientState.LocalContentId}");
}
}
catch (Exception ex)
{
PluginLog.Error(ex, "Unable to load character configuration");
CharacterConfiguration = null;
}
}
private void Logout(object? sender, EventArgs e)
{
CharacterConfiguration = null;
}
private unsafe void FrameworkUpdate(Framework f) private unsafe void FrameworkUpdate(Framework f)
{ {
_turnInWindow.Error = string.Empty; _turnInWindow.Error = string.Empty;
if (!_clientState.IsLoggedIn || _clientState.TerritoryType is not 128 and not 130 and not 132 || if (!_clientState.IsLoggedIn ||
_clientState.TerritoryType is not 128 and not 130 and not 132 ||
_condition[ConditionFlag.OccupiedInCutSceneEvent] || _condition[ConditionFlag.OccupiedInCutSceneEvent] ||
GetDistanceToNpc(GetQuartermasterId(), out GameObject? quartermaster) >= 7f || GetDistanceToNpc(GetQuartermasterId(), out GameObject? quartermaster) >= 7f ||
GetDistanceToNpc(GetPersonnelOfficerId(), out GameObject? personnelOfficer) >= 7f || GetDistanceToNpc(GetPersonnelOfficerId(), out GameObject? personnelOfficer) >= 7f ||
CharacterConfiguration is { DisableForCharacter: true } ||
_configWindow.IsOpen) _configWindow.IsOpen)
{ {
_turnInWindow.IsOpen = false; _turnInWindow.IsOpen = false;
@ -241,6 +291,8 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
public void Dispose() public void Dispose()
{ {
_commandManager.RemoveHandler("/deliveroo"); _commandManager.RemoveHandler("/deliveroo");
_clientState.Logout -= Logout;
_clientState.Login -= Login;
_pluginInterface.UiBuilder.OpenConfigUi -= _configWindow.Toggle; _pluginInterface.UiBuilder.OpenConfigUi -= _configWindow.Toggle;
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw; _pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
_framework.Update -= FrameworkUpdate; _framework.Update -= FrameworkUpdate;

View File

@ -0,0 +1,8 @@
namespace Deliveroo.GameData;
public enum ItemFilterType
{
ShowAllItems = 0,
HideGearSetItems = 1,
HideArmouryChestItems = 2,
}

View File

@ -2,8 +2,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Game.ClientState;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Components;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Logging;
using Dalamud.Plugin; using Dalamud.Plugin;
using Deliveroo.GameData; using Deliveroo.GameData;
using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Client.UI.Agent;
@ -13,24 +16,24 @@ namespace Deliveroo.Windows;
internal sealed class ConfigWindow : Window internal sealed class ConfigWindow : Window
{ {
private static string[] _itemFilterValues = { "Hide Gear Set Items", "Hide Armoury Chest Items" };
private readonly DalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
private readonly DeliverooPlugin _plugin; private readonly DeliverooPlugin _plugin;
private readonly Configuration _configuration; private readonly Configuration _configuration;
private readonly GcRewardsCache _gcRewardsCache; private readonly GcRewardsCache _gcRewardsCache;
private readonly ClientState _clientState;
private readonly Dictionary<uint, GcRewardItem> _itemLookup; private readonly Dictionary<uint, GcRewardItem> _itemLookup;
private uint _dragDropSource = 0; private uint _dragDropSource = 0;
public ConfigWindow(DalamudPluginInterface pluginInterface, DeliverooPlugin plugin, Configuration configuration, public ConfigWindow(DalamudPluginInterface pluginInterface, DeliverooPlugin plugin, Configuration configuration,
GcRewardsCache gcRewardsCache) GcRewardsCache gcRewardsCache, ClientState clientState)
: base("Deliveroo - Configuration###DeliverooConfig") : base("Deliveroo - Configuration###DeliverooConfig")
{ {
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
_plugin = plugin; _plugin = plugin;
_configuration = configuration; _configuration = configuration;
_gcRewardsCache = gcRewardsCache; _gcRewardsCache = gcRewardsCache;
_clientState = clientState;
_itemLookup = _gcRewardsCache.Rewards.Values _itemLookup = _gcRewardsCache.Rewards.Values
.SelectMany(x => x) .SelectMany(x => x)
@ -58,6 +61,7 @@ internal sealed class ConfigWindow : Window
if (ImGui.BeginTabBar("DeliverooConfigTabs")) if (ImGui.BeginTabBar("DeliverooConfigTabs"))
{ {
DrawBuyList(); DrawBuyList();
DrawCharacterSpecificSettings();
DrawAdditionalSettings(); DrawAdditionalSettings();
ImGui.EndTabBar(); ImGui.EndTabBar();
@ -154,7 +158,86 @@ internal sealed class ConfigWindow : Window
else else
{ {
int currentItem = 0; int currentItem = 0;
ImGui.Combo("Add Item", ref currentItem, new string[] { "(Not part of a GC)" }, 1); ImGui.Combo("Add Item", ref currentItem, new[] { "(Not part of a GC)" }, 1);
}
ImGui.EndTabItem();
}
}
private void DrawCharacterSpecificSettings()
{
if (ImGui.BeginTabItem("Character Settings"))
{
if (_clientState is { IsLoggedIn: true, LocalContentId: > 0 })
{
string currentCharacterName = _clientState.LocalPlayer!.Name.ToString();
string currentWorldName = _clientState.LocalPlayer.HomeWorld.GameData!.Name.ToString();
ImGui.Text($"Current Character: {currentCharacterName} @ {currentWorldName}");
ImGui.Spacing();
ImGui.Separator();
ImGui.Spacing();
var charConfiguration = _plugin.CharacterConfiguration;
if (charConfiguration != null)
{
bool disableForCharacter = charConfiguration.DisableForCharacter;
if (ImGui.Checkbox("Disable plugin for this character", ref disableForCharacter))
{
charConfiguration.DisableForCharacter = disableForCharacter;
charConfiguration.Save(_pluginInterface);
}
ImGui.BeginDisabled(charConfiguration.DisableForCharacter);
bool useHideArmouryChestItemsFilter = charConfiguration.UseHideArmouryChestItemsFilter;
if (ImGui.Checkbox("Use 'Hide Armoury Chest Items' filter", ref useHideArmouryChestItemsFilter))
{
charConfiguration.UseHideArmouryChestItemsFilter = useHideArmouryChestItemsFilter;
charConfiguration.Save(_pluginInterface);
}
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.EndDisabled();
ImGui.Spacing();
ImGui.Separator();
ImGui.Spacing();
ImGui.BeginDisabled(!ImGui.GetIO().KeyCtrl);
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.PersonCircleMinus,
"Remove character-specific settings"))
{
charConfiguration.Delete(_pluginInterface);
_plugin.CharacterConfiguration = null;
}
ImGui.EndDisabled();
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled) && !ImGui.GetIO().KeyCtrl)
ImGui.SetTooltip(
$"Hold CTRL to remove the configuration for {currentCharacterName} (non-reversible).");
}
else
{
// no settings
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.PersonCirclePlus,
"Enable character-specific settings"))
{
_plugin.CharacterConfiguration = new()
{
LocalContentId = _clientState.LocalContentId,
CachedPlayerName = currentCharacterName,
CachedWorldName = currentWorldName,
};
_plugin.CharacterConfiguration.Save(_pluginInterface);
PluginLog.Information(
$"Created character-specific configuration for {_clientState.LocalContentId}");
}
}
}
else
{
ImGui.Text("You are not currently logged in.");
} }
ImGui.EndTabItem(); ImGui.EndTabItem();
@ -173,14 +256,6 @@ internal sealed class ConfigWindow : Window
Save(); 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(); ImGui.EndTabItem();
} }
} }