Character specific settings

pull/3/head
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 int ReservedSealCount { get; set; } = 0;
public ItemFilterType ItemFilter { get; set; } = ItemFilterType.HideGearSetItems;
public bool IgnoreCertainLimitations { get; set; } = false;
internal sealed class PurchasePriority
@ -20,10 +19,4 @@ internal sealed class Configuration : IPluginConfiguration
public int Limit { get; set; }
}
public enum ItemFilterType
{
ShowAllItems = 0,
HideGearSetItems = 1,
HideArmouryChestItems = 2,
}
}

View File

@ -86,10 +86,11 @@ partial class DeliverooPlugin
return;
}
if (addonGc->SelectedFilter == 0 || addonGc->SelectedFilter != (int)_configuration.ItemFilter)
ItemFilterType configuredFilter = ResolveSelectedSupplyFilter();
if (addonGc->SelectedFilter == 0 || addonGc->SelectedFilter != (int)configuredFilter)
{
_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;
}
@ -169,7 +170,7 @@ partial class DeliverooPlugin
var updateFilter = stackalloc AtkValue[]
{
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 }
};
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.Collections.Generic;
using System.IO;
using System.Linq;
using Dalamud.Data;
using Dalamud.Game;
@ -18,6 +19,7 @@ using Deliveroo.Windows;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Component.GUI;
using Lumina.Excel.GeneratedSheets;
using Newtonsoft.Json;
using Condition = Dalamud.Game.ClientState.Conditions.Condition;
namespace Deliveroo;
@ -72,7 +74,7 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
_yesAlreadyIpc = new YesAlreadyIpc(dalamudReflector);
_configuration = (Configuration?)_pluginInterface.GetPluginConfig() ?? new Configuration();
_gcRewardsCache = new GcRewardsCache(dataManager);
_configWindow = new ConfigWindow(_pluginInterface, this, _configuration, _gcRewardsCache);
_configWindow = new ConfigWindow(_pluginInterface, this, _configuration, _gcRewardsCache, _clientState);
_windowSystem.AddWindow(_configWindow);
_turnInWindow = new TurnInWindow(this, _pluginInterface, _configuration, _gcRewardsCache, _configWindow);
_windowSystem.AddWindow(_turnInWindow);
@ -82,14 +84,22 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
_framework.Update += FrameworkUpdate;
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
_pluginInterface.UiBuilder.OpenConfigUi += _configWindow.Toggle;
_clientState.Login += Login;
_clientState.Logout += Logout;
_commandManager.AddHandler("/deliveroo", new CommandInfo(ProcessCommand)
{
HelpMessage = "Open the configuration"
});
if (_clientState.IsLoggedIn)
Login(this, EventArgs.Empty);
}
public string Name => "Deliveroo";
internal CharacterConfiguration? CharacterConfiguration { get; set; }
internal Stage CurrentStage
{
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)
{
_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] ||
GetDistanceToNpc(GetQuartermasterId(), out GameObject? quartermaster) >= 7f ||
GetDistanceToNpc(GetPersonnelOfficerId(), out GameObject? personnelOfficer) >= 7f ||
CharacterConfiguration is { DisableForCharacter: true } ||
_configWindow.IsOpen)
{
_turnInWindow.IsOpen = false;
@ -241,6 +291,8 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
public void Dispose()
{
_commandManager.RemoveHandler("/deliveroo");
_clientState.Logout -= Logout;
_clientState.Login -= Login;
_pluginInterface.UiBuilder.OpenConfigUi -= _configWindow.Toggle;
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
_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.Linq;
using System.Numerics;
using Dalamud.Game.ClientState;
using Dalamud.Interface;
using Dalamud.Interface.Components;
using Dalamud.Interface.Windowing;
using Dalamud.Logging;
using Dalamud.Plugin;
using Deliveroo.GameData;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
@ -13,24 +16,24 @@ 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;
private readonly GcRewardsCache _gcRewardsCache;
private readonly ClientState _clientState;
private readonly Dictionary<uint, GcRewardItem> _itemLookup;
private uint _dragDropSource = 0;
public ConfigWindow(DalamudPluginInterface pluginInterface, DeliverooPlugin plugin, Configuration configuration,
GcRewardsCache gcRewardsCache)
GcRewardsCache gcRewardsCache, ClientState clientState)
: base("Deliveroo - Configuration###DeliverooConfig")
{
_pluginInterface = pluginInterface;
_plugin = plugin;
_configuration = configuration;
_gcRewardsCache = gcRewardsCache;
_clientState = clientState;
_itemLookup = _gcRewardsCache.Rewards.Values
.SelectMany(x => x)
@ -58,6 +61,7 @@ internal sealed class ConfigWindow : Window
if (ImGui.BeginTabBar("DeliverooConfigTabs"))
{
DrawBuyList();
DrawCharacterSpecificSettings();
DrawAdditionalSettings();
ImGui.EndTabBar();
@ -154,7 +158,86 @@ internal sealed class ConfigWindow : Window
else
{
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();
@ -173,14 +256,6 @@ internal sealed class ConfigWindow : Window
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();
}
}