mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-24 21:51:48 +01:00
Add retained selections and filters and config for them.
This commit is contained in:
parent
baedba11f8
commit
67ee7bd507
26 changed files with 605 additions and 92 deletions
|
|
@ -23,6 +23,9 @@ public sealed partial class Configuration : IPluginConfiguration, ISavable, ISer
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public readonly UiConfig Ui;
|
public readonly UiConfig Ui;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public readonly FilterConfig Filters;
|
||||||
|
|
||||||
public bool AttachToPcp { get; set; } = true;
|
public bool AttachToPcp { get; set; } = true;
|
||||||
public bool UseRestrictedGearProtection { get; set; } = false;
|
public bool UseRestrictedGearProtection { get; set; } = false;
|
||||||
public bool OpenFoldersByDefault { get; set; } = false;
|
public bool OpenFoldersByDefault { get; set; } = false;
|
||||||
|
|
@ -54,6 +57,11 @@ public sealed partial class Configuration : IPluginConfiguration, ISavable, ISer
|
||||||
public bool PreventRandomRepeats { get; set; } = false;
|
public bool PreventRandomRepeats { get; set; } = false;
|
||||||
public string PcpFolder { get; set; } = "PCP";
|
public string PcpFolder { get; set; } = "PCP";
|
||||||
public string PcpColor { get; set; } = "";
|
public string PcpColor { get; set; } = "";
|
||||||
|
public bool RememberActorFilter { get; set; } = false;
|
||||||
|
public bool RememberDesignFilter { get; set; } = false;
|
||||||
|
public bool RememberNpcFilter { get; set; } = true;
|
||||||
|
public bool RememberAutomationFilter { get; set; } = false;
|
||||||
|
public bool RememberUnlocksFilters { get; set; } = true;
|
||||||
|
|
||||||
public RoughnessSetting RoughnessSetting { get; set; } = RoughnessSetting.AsIs;
|
public RoughnessSetting RoughnessSetting { get; set; } = RoughnessSetting.AsIs;
|
||||||
|
|
||||||
|
|
@ -95,11 +103,12 @@ public sealed partial class Configuration : IPluginConfiguration, ISavable, ISer
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
private readonly SaveService _saveService;
|
private readonly SaveService _saveService;
|
||||||
|
|
||||||
public Configuration(SaveService saveService, ConfigMigrationService migrator, EphemeralConfig ephemeral, UiConfig ui)
|
public Configuration(SaveService saveService, ConfigMigrationService migrator, EphemeralConfig ephemeral, UiConfig ui, FilterConfig filters)
|
||||||
{
|
{
|
||||||
_saveService = saveService;
|
_saveService = saveService;
|
||||||
Ephemeral = ephemeral;
|
Ephemeral = ephemeral;
|
||||||
Ui = ui;
|
Ui = ui;
|
||||||
|
Filters = filters;
|
||||||
Load(migrator);
|
Load(migrator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
201
Glamourer/Config/FilterConfig.cs
Normal file
201
Glamourer/Config/FilterConfig.cs
Normal file
|
|
@ -0,0 +1,201 @@
|
||||||
|
using Glamourer.Gui.Tabs.UnlocksTab;
|
||||||
|
using Glamourer.Services;
|
||||||
|
using ImSharp.Table;
|
||||||
|
using Luna;
|
||||||
|
using Luna.Generators;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Penumbra.GameData.DataContainers;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
namespace Glamourer.Config;
|
||||||
|
|
||||||
|
public sealed partial class FilterConfig : ConfigurationFile<FilenameService>
|
||||||
|
{
|
||||||
|
private readonly DictJob _jobs;
|
||||||
|
|
||||||
|
public FilterConfig(SaveService saveService, MessageService messager, DictJob jobs)
|
||||||
|
: base(saveService, messager, TimeSpan.FromMinutes(5))
|
||||||
|
{
|
||||||
|
_jobs = jobs;
|
||||||
|
_unlocksJobFilter = _jobs.AllAvailableJobs;
|
||||||
|
Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int CurrentVersion
|
||||||
|
=> 1;
|
||||||
|
|
||||||
|
protected override void AddData(JsonTextWriter j)
|
||||||
|
{
|
||||||
|
WriteFilter(j, ActorFilter, "Actors");
|
||||||
|
WriteFilter(j, DesignFilter, "Designs");
|
||||||
|
WriteFilter(j, NpcFilter, "Npcs");
|
||||||
|
WriteAutomation(j);
|
||||||
|
WriteUnlocksTab(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadData(JObject j)
|
||||||
|
{
|
||||||
|
_actorFilter = j["Actors"]?["Filter"]?.Value<string>() ?? string.Empty;
|
||||||
|
_designFilter = j["Designs"]?["Filter"]?.Value<string>() ?? string.Empty;
|
||||||
|
_npcFilter = j["Npcs"]?["Filter"]?.Value<string>() ?? string.Empty;
|
||||||
|
_automationFilter = j["Automation"]?["Filter"]?.Value<string>() ?? string.Empty;
|
||||||
|
_automationStateFilter = j["Automation"]?["State"]?.Value<bool>();
|
||||||
|
LoadUnlocksTab(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private string _designFilter = string.Empty;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private string _actorFilter = string.Empty;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private string _automationFilter = string.Empty;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private bool? _automationStateFilter;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private string _npcFilter = string.Empty;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private YesNoColumn.YesNoFlag _unlocksFavoriteFilter = YesNoColumn.YesOrNo;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private UnlockCacheItem.Modded _unlocksModdedFilter = UnlockCacheItem.ModdedAll;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private string _unlocksNameFilter = string.Empty;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private string _unlocksTypeFilter = string.Empty;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private EquipFlag _unlocksSlotFilter = UnlockCacheItem.SlotsAll;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private YesNoColumn.YesNoFlag _unlocksUnlockedFilter = YesNoColumn.YesOrNo;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private string _unlocksItemIdFilter = string.Empty;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private string _unlocksModelDataFilter = string.Empty;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private string _unlocksLevelFilter = string.Empty;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private JobFlag _unlocksJobFilter;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private UnlockCacheItem.Dyability _unlocksDyabilityFilter = UnlockCacheItem.DyableAll;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private YesNoColumn.YesNoFlag _unlocksTradableFilter = YesNoColumn.YesOrNo;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private YesNoColumn.YesNoFlag _unlocksCrestFilter = YesNoColumn.YesOrNo;
|
||||||
|
|
||||||
|
private void WriteUnlocksTab(JsonTextWriter j)
|
||||||
|
{
|
||||||
|
var obj = new JObject();
|
||||||
|
if (UnlocksFavoriteFilter is not YesNoColumn.YesOrNo)
|
||||||
|
obj["Favorite"] = (uint)UnlocksFavoriteFilter;
|
||||||
|
if (UnlocksCrestFilter is not YesNoColumn.YesOrNo)
|
||||||
|
obj["Crest"] = (uint)UnlocksCrestFilter;
|
||||||
|
if (UnlocksTradableFilter is not YesNoColumn.YesOrNo)
|
||||||
|
obj["Tradable"] = (uint)UnlocksTradableFilter;
|
||||||
|
if (UnlocksUnlockedFilter is not YesNoColumn.YesOrNo)
|
||||||
|
obj["Unlocked"] = (uint)UnlocksUnlockedFilter;
|
||||||
|
|
||||||
|
if (UnlocksModdedFilter is not UnlockCacheItem.ModdedAll)
|
||||||
|
obj["Modded"] = (uint)UnlocksModdedFilter;
|
||||||
|
|
||||||
|
if (UnlocksDyabilityFilter is not UnlockCacheItem.DyableAll)
|
||||||
|
obj["Dyability"] = (uint)UnlocksDyabilityFilter;
|
||||||
|
|
||||||
|
if (UnlocksSlotFilter is not UnlockCacheItem.SlotsAll)
|
||||||
|
obj["Slot"] = (uint)UnlocksSlotFilter;
|
||||||
|
|
||||||
|
if (UnlocksJobFilter != _jobs.AllAvailableJobs)
|
||||||
|
obj["Job"] = (ulong)UnlocksJobFilter;
|
||||||
|
|
||||||
|
if (UnlocksLevelFilter.Length > 0)
|
||||||
|
obj["Level"] = UnlocksLevelFilter;
|
||||||
|
if (UnlocksModelDataFilter.Length > 0)
|
||||||
|
obj["ModelData"] = UnlocksModelDataFilter;
|
||||||
|
if (UnlocksItemIdFilter.Length > 0)
|
||||||
|
obj["ItemId"] = UnlocksItemIdFilter;
|
||||||
|
if (UnlocksNameFilter.Length > 0)
|
||||||
|
obj["Name"] = UnlocksNameFilter;
|
||||||
|
if (UnlocksTypeFilter.Length > 0)
|
||||||
|
obj["Type"] = UnlocksTypeFilter;
|
||||||
|
|
||||||
|
if (obj.Count <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
j.WritePropertyName("Unlocks");
|
||||||
|
obj.WriteTo(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadUnlocksTab(JObject j)
|
||||||
|
{
|
||||||
|
if (j["Unlocks"] is not JObject unlocks)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_unlocksFavoriteFilter = unlocks["Favorite"]?.Value<uint>() is { } f ? (YesNoColumn.YesNoFlag)f : YesNoColumn.YesOrNo;
|
||||||
|
_unlocksCrestFilter = unlocks["Crest"]?.Value<uint>() is { } c ? (YesNoColumn.YesNoFlag)c : YesNoColumn.YesOrNo;
|
||||||
|
_unlocksTradableFilter = unlocks["Tradable"]?.Value<uint>() is { } t ? (YesNoColumn.YesNoFlag)t : YesNoColumn.YesOrNo;
|
||||||
|
_unlocksUnlockedFilter = unlocks["Unlocked"]?.Value<uint>() is { } u ? (YesNoColumn.YesNoFlag)u : YesNoColumn.YesOrNo;
|
||||||
|
_unlocksModdedFilter = unlocks["Modded"]?.Value<uint>() is { } m ? (UnlockCacheItem.Modded)m : UnlockCacheItem.ModdedAll;
|
||||||
|
_unlocksDyabilityFilter = unlocks["Dyability"]?.Value<uint>() is { } d ? (UnlockCacheItem.Dyability)d : UnlockCacheItem.DyableAll;
|
||||||
|
_unlocksSlotFilter = unlocks["Slot"]?.Value<uint>() is { } s ? (EquipFlag)s : UnlockCacheItem.SlotsAll;
|
||||||
|
_unlocksJobFilter = unlocks["Job"]?.Value<ulong>() is { } job ? (JobFlag)job : _jobs.AllAvailableJobs;
|
||||||
|
_unlocksLevelFilter = unlocks["Level"]?.Value<string>() ?? string.Empty;
|
||||||
|
_unlocksModelDataFilter = unlocks["ModelData"]?.Value<string>() ?? string.Empty;
|
||||||
|
_unlocksItemIdFilter = unlocks["ItemId"]?.Value<string>() ?? string.Empty;
|
||||||
|
_unlocksNameFilter = unlocks["Name"]?.Value<string>() ?? string.Empty;
|
||||||
|
_unlocksTypeFilter = unlocks["Type"]?.Value<string>() ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override string ToFilePath(FilenameService fileNames)
|
||||||
|
=> fileNames.FilterFile;
|
||||||
|
|
||||||
|
private void WriteAutomation(JsonTextWriter j)
|
||||||
|
{
|
||||||
|
if (AutomationStateFilter is null && AutomationFilter.Length is 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
j.WritePropertyName("Automation");
|
||||||
|
j.WriteStartObject();
|
||||||
|
if (AutomationStateFilter is not null)
|
||||||
|
{
|
||||||
|
j.WritePropertyName("State");
|
||||||
|
j.WriteValue(AutomationStateFilter.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AutomationFilter.Length > 0)
|
||||||
|
{
|
||||||
|
j.WritePropertyName("Filter");
|
||||||
|
j.WriteValue(AutomationFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
j.WriteEndObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteFilter(JsonTextWriter j, string filter, string tabName)
|
||||||
|
{
|
||||||
|
if (filter.Length is 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
j.WritePropertyName(tabName);
|
||||||
|
j.WriteStartObject();
|
||||||
|
j.WritePropertyName("Filter");
|
||||||
|
j.WriteValue(filter);
|
||||||
|
j.WriteEndObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,14 +3,19 @@ using Luna;
|
||||||
using Luna.Generators;
|
using Luna.Generators;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Penumbra.GameData.Actors;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Glamourer.Config;
|
namespace Glamourer.Config;
|
||||||
|
|
||||||
public sealed partial class UiConfig : ConfigurationFile<FilenameService>
|
public sealed partial class UiConfig : ConfigurationFile<FilenameService>
|
||||||
{
|
{
|
||||||
public UiConfig(SaveService saveService, MessageService messageService)
|
private readonly ActorManager _actors;
|
||||||
: base(saveService, messageService)
|
|
||||||
|
public UiConfig(SaveService saveService, MessageService messageService, ActorManager actors)
|
||||||
|
: base(saveService, messageService, TimeSpan.FromMinutes(5))
|
||||||
{
|
{
|
||||||
|
_actors = actors;
|
||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,6 +31,15 @@ public sealed partial class UiConfig : ConfigurationFile<FilenameService>
|
||||||
[ConfigProperty]
|
[ConfigProperty]
|
||||||
private TwoPanelWidth _npcTabScale = new(250, ScalingMode.Absolute);
|
private TwoPanelWidth _npcTabScale = new(250, ScalingMode.Absolute);
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private NpcId _selectedNpc = 0;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private int _selectedAutomationIndex = -1;
|
||||||
|
|
||||||
|
[ConfigProperty]
|
||||||
|
private ActorIdentifier _selectedActor = ActorIdentifier.Invalid;
|
||||||
|
|
||||||
public override int CurrentVersion
|
public override int CurrentVersion
|
||||||
=> 1;
|
=> 1;
|
||||||
|
|
||||||
|
|
@ -35,16 +49,36 @@ public sealed partial class UiConfig : ConfigurationFile<FilenameService>
|
||||||
DesignsTabScale.WriteJson(j, "DesignsTab");
|
DesignsTabScale.WriteJson(j, "DesignsTab");
|
||||||
AutomationTabScale.WriteJson(j, "AutomationTab");
|
AutomationTabScale.WriteJson(j, "AutomationTab");
|
||||||
NpcTabScale.WriteJson(j, "NpcTab");
|
NpcTabScale.WriteJson(j, "NpcTab");
|
||||||
|
if (_selectedNpc.Id is not 0)
|
||||||
|
{
|
||||||
|
j.WritePropertyName("SelectedNpc");
|
||||||
|
j.WriteValue(_selectedNpc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_selectedAutomationIndex >= 0)
|
||||||
|
{
|
||||||
|
j.WritePropertyName("SelectedAutomationIndex");
|
||||||
|
j.WriteValue(_selectedAutomationIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_selectedActor.IsValid)
|
||||||
|
{
|
||||||
|
j.WritePropertyName("SelectedActor");
|
||||||
|
_selectedActor.ToJson().WriteTo(j);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadData(JObject j)
|
protected override void LoadData(JObject j)
|
||||||
{
|
{
|
||||||
_actorsTabScale = TwoPanelWidth.ReadJson(j, "ActorsTab", new TwoPanelWidth(250, ScalingMode.Absolute));
|
_actorsTabScale = TwoPanelWidth.ReadJson(j, "ActorsTab", new TwoPanelWidth(250, ScalingMode.Absolute));
|
||||||
_designsTabScale = TwoPanelWidth.ReadJson(j, "DesignsTab", new TwoPanelWidth(0.3f, ScalingMode.Percentage));
|
_designsTabScale = TwoPanelWidth.ReadJson(j, "DesignsTab", new TwoPanelWidth(0.3f, ScalingMode.Percentage));
|
||||||
_automationTabScale = TwoPanelWidth.ReadJson(j, "AutomationTab", new TwoPanelWidth(0.3f, ScalingMode.Percentage));
|
_automationTabScale = TwoPanelWidth.ReadJson(j, "AutomationTab", new TwoPanelWidth(0.3f, ScalingMode.Percentage));
|
||||||
_npcTabScale = TwoPanelWidth.ReadJson(j, "NpcTab", new TwoPanelWidth(250, ScalingMode.Absolute));
|
_npcTabScale = TwoPanelWidth.ReadJson(j, "NpcTab", new TwoPanelWidth(250, ScalingMode.Absolute));
|
||||||
|
_selectedNpc = j["SelectedNpc"]?.Value<uint>() ?? 0;
|
||||||
|
_selectedAutomationIndex = j["SelectedAutomationIndex"]?.Value<int>() ?? -1;
|
||||||
|
_selectedActor = _actors.FromJson(j["SelectedActor"] as JObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToFilePath(FilenameService fileNames)
|
public override string ToFilePath(FilenameService fileNames)
|
||||||
=> fileNames.UiConfiguration;
|
=> fileNames.UiConfigurationFile;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,12 +81,16 @@ public sealed class DesignColors : ISavable, IReadOnlyDictionary<string, Rgba32>
|
||||||
|
|
||||||
public void Save(StreamWriter writer)
|
public void Save(StreamWriter writer)
|
||||||
{
|
{
|
||||||
|
var dict = new JObject();
|
||||||
|
foreach (var (name, color) in _colors)
|
||||||
|
dict[name] = color.Color;
|
||||||
var jObj = new JObject
|
var jObj = new JObject
|
||||||
{
|
{
|
||||||
["Version"] = 1,
|
["Version"] = 1,
|
||||||
["MissingColor"] = MissingColor.Color,
|
["MissingColor"] = MissingColor.Color,
|
||||||
["Definitions"] = JToken.FromObject(_colors),
|
["Definitions"] = dict,
|
||||||
};
|
};
|
||||||
|
|
||||||
writer.Write(jObj.ToString(Formatting.Indented));
|
writer.Write(jObj.ToString(Formatting.Indented));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
|
using Glamourer.Config;
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
@ -23,7 +24,7 @@ public sealed class ActorFilter : TextFilterBase<ActorCacheItem>, IUiService
|
||||||
|
|
||||||
private FilterMethod _method = FilterMethod.Empty;
|
private FilterMethod _method = FilterMethod.Empty;
|
||||||
|
|
||||||
public ActorFilter(IPlayerState playerState)
|
public ActorFilter(IPlayerState playerState, Configuration config)
|
||||||
{
|
{
|
||||||
_playerState = playerState;
|
_playerState = playerState;
|
||||||
FilterChanged += () =>
|
FilterChanged += () =>
|
||||||
|
|
@ -39,7 +40,10 @@ public sealed class ActorFilter : TextFilterBase<ActorCacheItem>, IUiService
|
||||||
"<w>" or "<W>" => FilterMethod.Homeworld,
|
"<w>" or "<W>" => FilterMethod.Homeworld,
|
||||||
_ => FilterMethod.Text,
|
_ => FilterMethod.Text,
|
||||||
};
|
};
|
||||||
|
config.Filters.ActorFilter = Text;
|
||||||
};
|
};
|
||||||
|
if (config.RememberActorFilter)
|
||||||
|
Set(config.Filters.ActorFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool DrawFilter(ReadOnlySpan<byte> label, Vector2 availableRegion)
|
public override bool DrawFilter(ReadOnlySpan<byte> label, Vector2 availableRegion)
|
||||||
|
|
@ -78,9 +82,21 @@ public sealed class ActorFilter : TextFilterBase<ActorCacheItem>, IUiService
|
||||||
Im.Text("<w>"u8, color);
|
Im.Text("<w>"u8, color);
|
||||||
Im.Line.NoSpacing();
|
Im.Line.NoSpacing();
|
||||||
Im.Text(": show only players from your world."u8);
|
Im.Text(": show only players from your world."u8);
|
||||||
|
|
||||||
|
if (Text.Length > 0)
|
||||||
|
Im.Text("\nMiddle-click to clear filters."u8);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool OnMiddleClick()
|
||||||
|
{
|
||||||
|
if (!Im.Item.MiddleClicked())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Im.Id.ClearActive();
|
||||||
|
return Clear();
|
||||||
|
}
|
||||||
|
|
||||||
protected override string ToFilterString(in ActorCacheItem item, int globalIndex)
|
protected override string ToFilterString(in ActorCacheItem item, int globalIndex)
|
||||||
=> item.DisplayText.Utf16;
|
=> item.DisplayText.Utf16;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Dalamud.Game.ClientState.Conditions;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
|
using Glamourer.Config;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
|
|
@ -9,7 +10,7 @@ using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.ActorTab;
|
namespace Glamourer.Gui.Tabs.ActorTab;
|
||||||
|
|
||||||
public sealed class ActorSelection(StateManager manager, ActorObjectManager objects, ICondition conditions) : IUiService
|
public sealed class ActorSelection(StateManager manager, ActorObjectManager objects, ICondition conditions, UiConfig config) : IUiService
|
||||||
{
|
{
|
||||||
private static readonly StringU8 NoSelection = new("No Actor Selected"u8);
|
private static readonly StringU8 NoSelection = new("No Actor Selected"u8);
|
||||||
|
|
||||||
|
|
@ -23,7 +24,8 @@ public sealed class ActorSelection(StateManager manager, ActorObjectManager obje
|
||||||
|
|
||||||
public void Select(ActorIdentifier identifier, ActorData data)
|
public void Select(ActorIdentifier identifier, ActorData data)
|
||||||
{
|
{
|
||||||
Identifier = identifier.CreatePermanent();
|
Identifier = identifier.CreatePermanent();
|
||||||
|
config.SelectedActor = Identifier;
|
||||||
if (Identifier.IsValid)
|
if (Identifier.IsValid)
|
||||||
{
|
{
|
||||||
ActorName = new StringU8(data.Label);
|
ActorName = new StringU8(data.Label);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Glamourer.Interop.Penumbra;
|
using Glamourer.Config;
|
||||||
|
using Glamourer.Interop.Penumbra;
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
|
|
@ -14,25 +15,58 @@ public readonly struct ActorCacheItem(ActorIdentifier identifier, ActorData data
|
||||||
public readonly StringU8 IncognitoText = new(identifier.Incognito(data.Label));
|
public readonly StringU8 IncognitoText = new(identifier.Incognito(data.Label));
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ActorSelector(ActorSelection selection, ActorObjectManager objects, ActorFilter filter, PenumbraService penumbra, Config.EphemeralConfig config) : IPanel
|
public sealed class ActorSelector(
|
||||||
|
ActorSelection selection,
|
||||||
|
ActorObjectManager objects,
|
||||||
|
ActorFilter filter,
|
||||||
|
PenumbraService penumbra,
|
||||||
|
Configuration config) : IPanel
|
||||||
{
|
{
|
||||||
public ReadOnlySpan<byte> Id
|
public ReadOnlySpan<byte> Id
|
||||||
=> "ActorSelector"u8;
|
=> "ActorSelector"u8;
|
||||||
|
|
||||||
public void Draw()
|
public unsafe void Draw()
|
||||||
{
|
{
|
||||||
Im.Cursor.Y += Im.Style.FramePadding.Y;
|
Im.Cursor.Y += Im.Style.FramePadding.Y;
|
||||||
var cache = CacheManager.Instance.GetOrCreateCache(Im.Id.Current, () => new ActorSelectorCache(objects, filter, penumbra));
|
var cache = CacheManager.Instance.GetOrCreateCache(Im.Id.Current, () => new ActorSelectorCache(objects, filter, penumbra));
|
||||||
using var clip = new Im.ListClipper(cache.Count, Im.Style.TextHeightWithSpacing);
|
HandleRememberedSelection();
|
||||||
|
using var clip = new Im.ListClipper(cache.Count, Im.Style.TextHeightWithSpacing);
|
||||||
foreach (var actor in clip.Iterate(cache))
|
foreach (var actor in clip.Iterate(cache))
|
||||||
{
|
{
|
||||||
Im.Cursor.X += Im.Style.FramePadding.X;
|
Im.Cursor.X += Im.Style.FramePadding.X;
|
||||||
var selected = actor.Identifier.Equals(selection.Identifier);
|
var selected = actor.Identifier.Equals(selection.Identifier);
|
||||||
if (Im.Selectable(config.IncognitoMode ? actor.IncognitoText : actor.DisplayText.Utf8, selected) && !selected)
|
if (Im.Selectable(config.Ephemeral.IncognitoMode ? actor.IncognitoText : actor.DisplayText.Utf8, selected) && !selected)
|
||||||
selection.Select(actor.Identifier, actor.Data);
|
selection.Select(actor.Identifier, actor.Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private unsafe void HandleRememberedSelection()
|
||||||
|
{
|
||||||
|
// We already have a valid selection.
|
||||||
|
if (selection.Identifier.IsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We do not have a remembered selection.
|
||||||
|
if (!config.Ui.SelectedActor.IsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We have no actor corresponding to the selection available to create a new state.
|
||||||
|
if (!objects.TryGetValue(config.Ui.SelectedActor, out var data))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The actor has no model yet.
|
||||||
|
if (data.Objects.First().Model is not { IsCharacterBase: true } model)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The model still has a staging area, so is not fully loaded.
|
||||||
|
if (model.AsCharacterBase->PerSlotStagingArea is not null || model.AsCharacterBase->TempData is not null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The model should be fully loaded, so the selection can probably create the expected state.
|
||||||
|
selection.Select(config.Ui.SelectedActor, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private sealed class ActorSelectorCache : BasicFilterCache<ActorCacheItem>
|
private sealed class ActorSelectorCache : BasicFilterCache<ActorCacheItem>
|
||||||
{
|
{
|
||||||
private readonly ActorObjectManager _objects;
|
private readonly ActorObjectManager _objects;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using ImSharp;
|
using Glamourer.Config;
|
||||||
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.AutomationTab;
|
namespace Glamourer.Gui.Tabs.AutomationTab;
|
||||||
|
|
@ -10,6 +11,21 @@ public sealed class AutomationFilter : TextFilterBase<AutomationCacheItem>, IUiS
|
||||||
protected override string ToFilterString(in AutomationCacheItem item, int globalIndex)
|
protected override string ToFilterString(in AutomationCacheItem item, int globalIndex)
|
||||||
=> item.Name.Utf16;
|
=> item.Name.Utf16;
|
||||||
|
|
||||||
|
public AutomationFilter(Configuration config)
|
||||||
|
{
|
||||||
|
if (config.RememberAutomationFilter)
|
||||||
|
{
|
||||||
|
_setStateFilter = config.Filters.AutomationStateFilter;
|
||||||
|
Set(config.Filters.AutomationFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterChanged += () =>
|
||||||
|
{
|
||||||
|
config.Filters.AutomationFilter = Text;
|
||||||
|
config.Filters.AutomationStateFilter = _setStateFilter;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public override bool WouldBeVisible(in AutomationCacheItem item, int globalIndex)
|
public override bool WouldBeVisible(in AutomationCacheItem item, int globalIndex)
|
||||||
=> _setStateFilter switch
|
=> _setStateFilter switch
|
||||||
{
|
{
|
||||||
|
|
@ -54,11 +70,15 @@ public sealed class AutomationFilter : TextFilterBase<AutomationCacheItem>, IUiS
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Clear()
|
public override bool Clear()
|
||||||
{
|
{
|
||||||
var changes = _setStateFilter is not null;
|
var changes = _setStateFilter is not null;
|
||||||
_setStateFilter = null;
|
_setStateFilter = null;
|
||||||
if (!Set(string.Empty) && changes)
|
if (!SetInternal(string.Empty) && !changes)
|
||||||
InvokeEvent();
|
return false;
|
||||||
|
|
||||||
|
InvokeEvent();
|
||||||
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Glamourer.Automation;
|
using Glamourer.Automation;
|
||||||
|
using Glamourer.Config;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
|
|
@ -10,6 +11,7 @@ public sealed class AutomationSelection : IUiService, IDisposable
|
||||||
public static readonly StringU8 NoSelection = new("No Set Selected"u8);
|
public static readonly StringU8 NoSelection = new("No Set Selected"u8);
|
||||||
|
|
||||||
private readonly AutomationChanged _automationChanged;
|
private readonly AutomationChanged _automationChanged;
|
||||||
|
private readonly UiConfig _config;
|
||||||
|
|
||||||
public int DraggedDesignIndex = -1;
|
public int DraggedDesignIndex = -1;
|
||||||
|
|
||||||
|
|
@ -18,10 +20,12 @@ public sealed class AutomationSelection : IUiService, IDisposable
|
||||||
public StringU8 Name { get; private set; } = NoSelection;
|
public StringU8 Name { get; private set; } = NoSelection;
|
||||||
public StringU8 Incognito { get; private set; } = NoSelection;
|
public StringU8 Incognito { get; private set; } = NoSelection;
|
||||||
|
|
||||||
public AutomationSelection(AutomationChanged automationChanged)
|
public AutomationSelection(AutomationChanged automationChanged, UiConfig config, AutoDesignManager autoDesigns)
|
||||||
{
|
{
|
||||||
_automationChanged = automationChanged;
|
_automationChanged = automationChanged;
|
||||||
|
_config = config;
|
||||||
_automationChanged.Subscribe(OnAutomationChanged, AutomationChanged.Priority.SetSelector);
|
_automationChanged.Subscribe(OnAutomationChanged, AutomationChanged.Priority.SetSelector);
|
||||||
|
InitialSelect(autoDesigns);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
@ -47,15 +51,34 @@ public sealed class AutomationSelection : IUiService, IDisposable
|
||||||
Set = item?.Set;
|
Set = item?.Set;
|
||||||
if (Set is null)
|
if (Set is null)
|
||||||
{
|
{
|
||||||
Index = -1;
|
_config.SelectedAutomationIndex = -1;
|
||||||
Name = NoSelection;
|
Index = -1;
|
||||||
Incognito = NoSelection;
|
Name = NoSelection;
|
||||||
|
Incognito = NoSelection;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Index = item!.Value.Index;
|
_config.SelectedAutomationIndex = item!.Value.Index;
|
||||||
Name = item!.Value.Name.Utf8;
|
Index = item!.Value.Index;
|
||||||
Incognito = item!.Value.Incognito;
|
Name = item!.Value.Name.Utf8;
|
||||||
|
Incognito = item!.Value.Incognito;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitialSelect(AutoDesignManager autoDesigns)
|
||||||
|
{
|
||||||
|
if (_config.SelectedAutomationIndex < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (autoDesigns.Count <= _config.SelectedAutomationIndex)
|
||||||
|
{
|
||||||
|
_config.SelectedAutomationIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set = autoDesigns[_config.SelectedAutomationIndex];
|
||||||
|
Index = _config.SelectedAutomationIndex;
|
||||||
|
Name = new StringU8(Set.Name);
|
||||||
|
Incognito = new StringU8($"Auto Design Set #{Index + 1}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
using Glamourer.Config;
|
using Glamourer.Config;
|
||||||
|
using Glamourer.Services;
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
|
using InteropGenerator.Runtime;
|
||||||
using Luna;
|
using Luna;
|
||||||
|
using Penumbra.GameData.Files.ShaderStructs;
|
||||||
|
using Vortice.Direct3D11.Debug;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
|
|
@ -33,9 +37,29 @@ public sealed class DebugTab(ServiceManager manager) : ITab<MainTabType>
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Im.Tree.Header("General"u8))
|
if (Im.Tree.Header("General"u8))
|
||||||
|
{
|
||||||
|
if (Im.Button("Open Config Directory"u8))
|
||||||
|
OpenFileOrFolder(manager.GetService<FilenameService>().ConfigurationDirectory);
|
||||||
StartTimeTracker.Draw("Timers"u8, manager.GetService<StartTimeTracker>());
|
StartTimeTracker.Draw("Timers"u8, manager.GetService<StartTimeTracker>());
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var header in _headers)
|
foreach (var header in _headers)
|
||||||
header.Draw();
|
header.Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void OpenFileOrFolder(string text)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var process = new ProcessStartInfo(text)
|
||||||
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
|
};
|
||||||
|
Process.Start(process);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ public sealed class PenumbraPanel(PenumbraService penumbra, PenumbraChangedItemT
|
||||||
table.NextColumn();
|
table.NextColumn();
|
||||||
Im.Item.SetNextWidthScaled(200);
|
Im.Item.SetNextWidthScaled(200);
|
||||||
Im.Input.Scalar("##CutsceneIndex"u8, ref _gameObjectIndex);
|
Im.Input.Scalar("##CutsceneIndex"u8, ref _gameObjectIndex);
|
||||||
table.DrawColumn(penumbra.Available ? $"{penumbra.CutsceneParent((ushort)_gameObjectIndex)}" : "Penumbra Unavailable"u8);
|
table.DrawColumn(penumbra.Available ? $"{penumbra.ResolveService.CutsceneParent((ushort)_gameObjectIndex)}" : "Penumbra Unavailable"u8);
|
||||||
|
|
||||||
table.DrawFrameColumn("Redraw Object"u8);
|
table.DrawFrameColumn("Redraw Object"u8);
|
||||||
table.NextColumn();
|
table.NextColumn();
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ public sealed class ModCombo(PenumbraService penumbra, DesignFileSystem fileSyst
|
||||||
{
|
{
|
||||||
foreach (var setting in settings.Settings)
|
foreach (var setting in settings.Settings)
|
||||||
{
|
{
|
||||||
if (setting.Value.Count == 0)
|
if (setting.Value.Count is 0)
|
||||||
Im.Text("<None Enabled>"u8);
|
Im.Text("<None Enabled>"u8);
|
||||||
else
|
else
|
||||||
foreach (var option in setting.Value)
|
foreach (var option in setting.Value)
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public sealed class DesignFileSystemDrawer : FileSystemDrawer<DesignFileSystemCa
|
||||||
|
|
||||||
public DesignFileSystemDrawer(DesignFileSystem fileSystem, DesignManager manager, DesignConverter converter, Configuration config,
|
public DesignFileSystemDrawer(DesignFileSystem fileSystem, DesignManager manager, DesignConverter converter, Configuration config,
|
||||||
DesignApplier designApplier, DesignChanged designChanged, DesignColors designColors)
|
DesignApplier designApplier, DesignChanged designChanged, DesignColors designColors)
|
||||||
: base(fileSystem, new DesignFilter())
|
: base(fileSystem, new DesignFilter(config))
|
||||||
{
|
{
|
||||||
Manager = manager;
|
Manager = manager;
|
||||||
Config = config;
|
Config = config;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using ImSharp;
|
using Glamourer.Config;
|
||||||
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DesignTab;
|
namespace Glamourer.Gui.Tabs.DesignTab;
|
||||||
|
|
@ -6,6 +7,13 @@ namespace Glamourer.Gui.Tabs.DesignTab;
|
||||||
public sealed class DesignFilter : TokenizedFilter<DesignFilterTokenType, DesignFileSystemCache.DesignData, DesignFilterToken>,
|
public sealed class DesignFilter : TokenizedFilter<DesignFilterTokenType, DesignFileSystemCache.DesignData, DesignFilterToken>,
|
||||||
IFileSystemFilter<DesignFileSystemCache.DesignData>, IUiService
|
IFileSystemFilter<DesignFileSystemCache.DesignData>, IUiService
|
||||||
{
|
{
|
||||||
|
public DesignFilter(Configuration config)
|
||||||
|
{
|
||||||
|
if (config.RememberDesignFilter)
|
||||||
|
Set(config.Filters.DesignFilter);
|
||||||
|
FilterChanged += () => config.Filters.DesignFilter = Text;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void DrawTooltip()
|
protected override void DrawTooltip()
|
||||||
{
|
{
|
||||||
if (!Im.Item.Hovered())
|
if (!Im.Item.Hovered())
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using ImSharp;
|
using Glamourer.Config;
|
||||||
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.NpcTab;
|
namespace Glamourer.Gui.Tabs.NpcTab;
|
||||||
|
|
@ -12,6 +13,13 @@ public sealed class NpcFilter : TokenizedFilter<NpcFilter.TokenType, NpcCacheIte
|
||||||
Color,
|
Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NpcFilter(Configuration config)
|
||||||
|
{
|
||||||
|
if (config.RememberNpcFilter)
|
||||||
|
Set(config.Filters.NpcFilter);
|
||||||
|
FilterChanged += () => config.Filters.NpcFilter = Text;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void DrawTooltip()
|
protected override void DrawTooltip()
|
||||||
{
|
{
|
||||||
if (!Im.Item.Hovered())
|
if (!Im.Item.Hovered())
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Glamourer.Designs;
|
using Glamourer.Config;
|
||||||
|
using Glamourer.Designs;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
|
|
@ -10,15 +11,18 @@ public sealed class NpcSelection : IUiService, IDisposable
|
||||||
private readonly LocalNpcAppearanceData _data;
|
private readonly LocalNpcAppearanceData _data;
|
||||||
private readonly DesignColors _colors;
|
private readonly DesignColors _colors;
|
||||||
private readonly DesignConverter _converter;
|
private readonly DesignConverter _converter;
|
||||||
|
private readonly UiConfig _config;
|
||||||
|
|
||||||
public NpcSelection(LocalNpcAppearanceData data, DesignColors colors, DesignConverter converter)
|
public NpcSelection(LocalNpcAppearanceData data, DesignColors colors, DesignConverter converter, UiConfig config, NpcCustomizeSet npcs)
|
||||||
{
|
{
|
||||||
_data = data;
|
_data = data;
|
||||||
_colors = colors;
|
_colors = colors;
|
||||||
_converter = converter;
|
_converter = converter;
|
||||||
|
_config = config;
|
||||||
|
|
||||||
_data.DataChanged += OnDataChanged;
|
_data.DataChanged += OnDataChanged;
|
||||||
_colors.ColorChanged += OnColorChanged;
|
_colors.ColorChanged += OnColorChanged;
|
||||||
|
InitialSelect(npcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnColorChanged()
|
private void OnColorChanged()
|
||||||
|
|
@ -81,12 +85,13 @@ public sealed class NpcSelection : IUiService, IDisposable
|
||||||
|
|
||||||
public void Update(in NpcCacheItem item)
|
public void Update(in NpcCacheItem item)
|
||||||
{
|
{
|
||||||
Data = item.Npc;
|
Data = item.Npc;
|
||||||
Name = item.Name.Utf8;
|
Name = item.Name.Utf8;
|
||||||
Favorite = item.Favorite;
|
Favorite = item.Favorite;
|
||||||
ColorText = item.ColorText;
|
ColorText = item.ColorText;
|
||||||
ColorTextU8 = ColorText.Length > 0 ? new StringU8(ColorText) : DesignColors.AutomaticNameU8;
|
ColorTextU8 = ColorText.Length > 0 ? new StringU8(ColorText) : DesignColors.AutomaticNameU8;
|
||||||
Color = item.Color;
|
Color = item.Color;
|
||||||
|
_config.SelectedNpc = Data.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
@ -94,4 +99,20 @@ public sealed class NpcSelection : IUiService, IDisposable
|
||||||
_data.DataChanged -= OnDataChanged;
|
_data.DataChanged -= OnDataChanged;
|
||||||
_colors.ColorChanged -= OnColorChanged;
|
_colors.ColorChanged -= OnColorChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitialSelect(NpcCustomizeSet npcs)
|
||||||
|
{
|
||||||
|
if (_config.SelectedNpc.Id is 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!npcs.FindFirst(n => n.Id == _config.SelectedNpc.Id, out var npc))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Data = npc;
|
||||||
|
Name = new StringU8(npc.Name);
|
||||||
|
ColorText = _data.GetColor(npc);
|
||||||
|
ColorTextU8 = ColorText.Length is not 0 ? new StringU8(ColorText) : DesignColors.AutomaticNameU8;
|
||||||
|
(var color, Favorite) = _data.GetData(npc);
|
||||||
|
Color = color.ToVector();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,31 @@ public sealed class SettingsTab(
|
||||||
Checkbox("Debug Mode"u8, "Show the debug tab. Only useful for debugging or advanced use. Not recommended in general."u8,
|
Checkbox("Debug Mode"u8, "Show the debug tab. Only useful for debugging or advanced use. Not recommended in general."u8,
|
||||||
config.DebugMode,
|
config.DebugMode,
|
||||||
v => config.DebugMode = v);
|
v => config.DebugMode = v);
|
||||||
|
|
||||||
|
Im.Dummy(Vector2.Zero);
|
||||||
|
Im.Separator();
|
||||||
|
Im.Dummy(Vector2.Zero);
|
||||||
|
|
||||||
|
Checkbox("Remember Design Filter Across Sessions"u8,
|
||||||
|
"Whether the filter in the Designs tab should remember its input and start with its list filtered identically to the last session."u8,
|
||||||
|
config.RememberDesignFilter, v => config.RememberDesignFilter = v);
|
||||||
|
|
||||||
|
Checkbox("Remember Actor Filter Across Sessions"u8,
|
||||||
|
"Whether the filter in the Actors tab should remember its input and start with its list filtered identically to the last session."u8,
|
||||||
|
config.RememberActorFilter, v => config.RememberActorFilter = v);
|
||||||
|
|
||||||
|
Checkbox("Remember Automation Filters Across Sessions"u8,
|
||||||
|
"Whether the filters in the Automation tab should remember their respective inputs and start with their list filtered identically to the last session."u8,
|
||||||
|
config.RememberAutomationFilter, v => config.RememberAutomationFilter = v);
|
||||||
|
|
||||||
|
Checkbox("Remember NPC Filter Across Sessions"u8,
|
||||||
|
"Whether the filter in the NPCs tab should remember its input and start with its list filtered identically to the last session."u8,
|
||||||
|
config.RememberNpcFilter, v => config.RememberNpcFilter = v);
|
||||||
|
|
||||||
|
Checkbox("Remember Unlocks Filters Across Sessions"u8,
|
||||||
|
"Whether the filters in the Unlocks tab should remember their respective inputs and start with its table filtered identically to the last session."u8,
|
||||||
|
config.RememberUnlocksFilters, v => config.RememberUnlocksFilters = v);
|
||||||
|
|
||||||
Im.Line.New();
|
Im.Line.New();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,30 @@ public readonly struct UnlockCacheItem(in EquipItem item, in EquipItem offhand,
|
||||||
Two = 4,
|
Two = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum Modded
|
||||||
|
{
|
||||||
|
Relevant = 1,
|
||||||
|
Ignored = 2,
|
||||||
|
None = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
public const Modded ModdedAll = Modded.Relevant | Modded.Ignored | Modded.None;
|
||||||
|
|
||||||
|
public const Dyability DyableAll = Dyability.No | Dyability.Yes | Dyability.Two;
|
||||||
|
|
||||||
|
public const EquipFlag SlotsAll = EquipFlag.Head
|
||||||
|
| EquipFlag.Body
|
||||||
|
| EquipFlag.Hands
|
||||||
|
| EquipFlag.Legs
|
||||||
|
| EquipFlag.Feet
|
||||||
|
| EquipFlag.Ears
|
||||||
|
| EquipFlag.Neck
|
||||||
|
| EquipFlag.Wrist
|
||||||
|
| EquipFlag.RFinger
|
||||||
|
| EquipFlag.Mainhand
|
||||||
|
| EquipFlag.Offhand;
|
||||||
|
|
||||||
public readonly EquipItem Item = item;
|
public readonly EquipItem Item = item;
|
||||||
public readonly StringPair Name = new(item.Name);
|
public readonly StringPair Name = new(item.Name);
|
||||||
public readonly EquipFlag Slot = item.Type.ToSlot().ToFlag();
|
public readonly EquipFlag Slot = item.Type.ToSlot().ToFlag();
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,22 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
private readonly IgnoredMods _ignoredMods;
|
private readonly IgnoredMods _ignoredMods;
|
||||||
|
|
||||||
public UnlockTable(JobService jobs, ItemManager items, ItemUnlockManager unlocks, PenumbraChangedItemTooltip tooltip,
|
public UnlockTable(JobService jobs, ItemManager items, ItemUnlockManager unlocks, PenumbraChangedItemTooltip tooltip,
|
||||||
ObjectUnlocked unlockEvent, FavoriteManager favorites, PenumbraService penumbra, TextureService textures, IgnoredMods ignoredMods)
|
ObjectUnlocked unlockEvent, FavoriteManager favorites, PenumbraService penumbra, TextureService textures, IgnoredMods ignoredMods,
|
||||||
: base(new StringU8("Unlock Table"u8), new FavoriteColumn(favorites), new ModdedColumn(), new NameColumn(textures, tooltip),
|
Configuration config)
|
||||||
new SlotColumn(), new TypeColumn(), new UnlockDateColumn(), new ItemIdColumn(), new ModelDataColumn(), new JobColumn(jobs),
|
: base(new StringU8("Unlock Table"u8),
|
||||||
new RequiredLevelColumn(), new DyableColumn(), new CrestColumn(), new TradableColumn())
|
new FavoriteColumn(config, favorites),
|
||||||
|
new ModdedColumn(config),
|
||||||
|
new NameColumn(config, textures, tooltip),
|
||||||
|
new SlotColumn(config),
|
||||||
|
new TypeColumn(config),
|
||||||
|
new UnlockDateColumn(config),
|
||||||
|
new ItemIdColumn(config),
|
||||||
|
new ModelDataColumn(config),
|
||||||
|
new JobColumn(config, jobs),
|
||||||
|
new RequiredLevelColumn(config),
|
||||||
|
new DyableColumn(config),
|
||||||
|
new CrestColumn(config),
|
||||||
|
new TradableColumn(config))
|
||||||
{
|
{
|
||||||
_jobs = jobs;
|
_jobs = jobs;
|
||||||
_items = items;
|
_items = items;
|
||||||
|
|
@ -86,12 +98,15 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
{
|
{
|
||||||
private readonly FavoriteManager _favorites;
|
private readonly FavoriteManager _favorites;
|
||||||
|
|
||||||
public FavoriteColumn(FavoriteManager favorites)
|
public FavoriteColumn(Configuration config, FavoriteManager favorites)
|
||||||
{
|
{
|
||||||
_favorites = favorites;
|
_favorites = favorites;
|
||||||
Flags |= TableColumnFlags.NoResize;
|
Flags |= TableColumnFlags.NoResize;
|
||||||
Label = new StringU8("F"u8);
|
Label = new StringU8("F"u8);
|
||||||
FilterLabel = new StringU8("Favorite"u8);
|
FilterLabel = new StringU8("Favorite"u8);
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.LoadValue(config.Filters.UnlocksFavoriteFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksFavoriteFilter = Filter.FilterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float ComputeWidth(IEnumerable<UnlockCacheItem> allItems)
|
public override float ComputeWidth(IEnumerable<UnlockCacheItem> allItems)
|
||||||
|
|
@ -104,23 +119,18 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
=> item.Favorite;
|
=> item.Favorite;
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class ModdedColumn : FlagColumn<ModdedColumn.Modded, UnlockCacheItem>
|
private sealed class ModdedColumn : FlagColumn<UnlockCacheItem.Modded, UnlockCacheItem>
|
||||||
{
|
{
|
||||||
[Flags]
|
|
||||||
public enum Modded
|
|
||||||
{
|
|
||||||
Relevant = 1,
|
|
||||||
Ignored = 2,
|
|
||||||
None = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly AwesomeIcon Dot = FontAwesomeIcon.Circle;
|
private static readonly AwesomeIcon Dot = FontAwesomeIcon.Circle;
|
||||||
private static readonly AwesomeIcon Hollow = FontAwesomeIcon.DotCircle;
|
private static readonly AwesomeIcon Hollow = FontAwesomeIcon.DotCircle;
|
||||||
|
|
||||||
public ModdedColumn()
|
public ModdedColumn(Configuration config)
|
||||||
{
|
{
|
||||||
Flags |= TableColumnFlags.NoResize;
|
Flags |= TableColumnFlags.NoResize;
|
||||||
Label = new StringU8("M");
|
Label = new StringU8("M");
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.LoadValue(config.Filters.UnlocksModdedFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksModdedFilter = Filter.FilterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float ComputeWidth(IEnumerable<UnlockCacheItem> allItems)
|
public override float ComputeWidth(IEnumerable<UnlockCacheItem> allItems)
|
||||||
|
|
@ -149,18 +159,19 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Modded GetValue(in UnlockCacheItem item, int globalIndex)
|
protected override UnlockCacheItem.Modded GetValue(in UnlockCacheItem item, int globalIndex)
|
||||||
=> item.RelevantMods > 0 ? Modded.Relevant : item.Mods.Length > 0 ? Modded.Ignored : Modded.None;
|
=> item.RelevantMods > 0 ? UnlockCacheItem.Modded.Relevant :
|
||||||
|
item.Mods.Length > 0 ? UnlockCacheItem.Modded.Ignored : UnlockCacheItem.Modded.None;
|
||||||
|
|
||||||
protected override StringU8 DisplayString(in UnlockCacheItem item, int globalIndex)
|
protected override StringU8 DisplayString(in UnlockCacheItem item, int globalIndex)
|
||||||
=> StringU8.Empty;
|
=> StringU8.Empty;
|
||||||
|
|
||||||
protected override IReadOnlyList<(Modded Value, StringU8 Name)> EnumData
|
protected override IReadOnlyList<(UnlockCacheItem.Modded Value, StringU8 Name)> EnumData
|
||||||
=>
|
=>
|
||||||
[
|
[
|
||||||
(Modded.Relevant, new StringU8("Any Relevant Mods"u8)),
|
(UnlockCacheItem.Modded.Relevant, new StringU8("Any Relevant Mods"u8)),
|
||||||
(Modded.Ignored, new StringU8("Only Ignored Mods"u8)),
|
(UnlockCacheItem.Modded.Ignored, new StringU8("Only Ignored Mods"u8)),
|
||||||
(Modded.None, new StringU8("Unmodded"u8)),
|
(UnlockCacheItem.Modded.None, new StringU8("Unmodded"u8)),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -179,13 +190,16 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
private readonly TextureService _textures;
|
private readonly TextureService _textures;
|
||||||
private readonly PenumbraChangedItemTooltip _tooltip;
|
private readonly PenumbraChangedItemTooltip _tooltip;
|
||||||
|
|
||||||
public NameColumn(TextureService textures, PenumbraChangedItemTooltip tooltip)
|
public NameColumn(Configuration config, TextureService textures, PenumbraChangedItemTooltip tooltip)
|
||||||
{
|
{
|
||||||
_textures = textures;
|
_textures = textures;
|
||||||
_tooltip = tooltip;
|
_tooltip = tooltip;
|
||||||
Flags |= TableColumnFlags.NoHide | TableColumnFlags.NoReorder;
|
Flags |= TableColumnFlags.NoHide | TableColumnFlags.NoReorder;
|
||||||
Label = new StringU8("Item Name..."u8);
|
Label = new StringU8("Item Name..."u8);
|
||||||
UnscaledWidth = 400;
|
UnscaledWidth = 400;
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.Set(config.Filters.UnlocksNameFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksNameFilter = Filter.Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DrawColumn(in UnlockCacheItem item, int _)
|
public override void DrawColumn(in UnlockCacheItem item, int _)
|
||||||
|
|
@ -215,8 +229,13 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
|
|
||||||
private sealed class TypeColumn : TextColumn<UnlockCacheItem>
|
private sealed class TypeColumn : TextColumn<UnlockCacheItem>
|
||||||
{
|
{
|
||||||
public TypeColumn()
|
public TypeColumn(Configuration config)
|
||||||
=> Label = new StringU8("Item Type..."u8);
|
{
|
||||||
|
Label = new StringU8("Item Type..."u8);
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.Set(config.Filters.UnlocksTypeFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksTypeFilter = Filter.Text;
|
||||||
|
}
|
||||||
|
|
||||||
public override float ComputeWidth(IEnumerable<UnlockCacheItem> _)
|
public override float ComputeWidth(IEnumerable<UnlockCacheItem> _)
|
||||||
=> FullEquipType.CrossPeinHammer.ToNameU8().CalculateSize().X;
|
=> FullEquipType.CrossPeinHammer.ToNameU8().CalculateSize().X;
|
||||||
|
|
@ -233,10 +252,13 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
|
|
||||||
private sealed class SlotColumn : FlagColumn<EquipFlag, UnlockCacheItem>
|
private sealed class SlotColumn : FlagColumn<EquipFlag, UnlockCacheItem>
|
||||||
{
|
{
|
||||||
public SlotColumn()
|
public SlotColumn(Configuration config)
|
||||||
{
|
{
|
||||||
Flags &= ~TableColumnFlags.NoResize;
|
Flags &= ~TableColumnFlags.NoResize;
|
||||||
Label = new StringU8("Equip Slot"u8);
|
Label = new StringU8("Equip Slot"u8);
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.LoadValue(config.Filters.UnlocksSlotFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksSlotFilter = Filter.FilterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float ComputeWidth(IEnumerable<UnlockCacheItem> _)
|
public override float ComputeWidth(IEnumerable<UnlockCacheItem> _)
|
||||||
|
|
@ -269,11 +291,14 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
|
|
||||||
private sealed class UnlockDateColumn : YesNoColumn<UnlockCacheItem>
|
private sealed class UnlockDateColumn : YesNoColumn<UnlockCacheItem>
|
||||||
{
|
{
|
||||||
public UnlockDateColumn()
|
public UnlockDateColumn(Configuration config)
|
||||||
{
|
{
|
||||||
Flags &= ~TableColumnFlags.NoResize;
|
Flags &= ~TableColumnFlags.NoResize;
|
||||||
Label = new StringU8("Unlocked"u8);
|
Label = new StringU8("Unlocked"u8);
|
||||||
FilterLabel = Label;
|
FilterLabel = Label;
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.LoadValue(config.Filters.UnlocksUnlockedFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksUnlockedFilter = Filter.FilterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float ComputeWidth(IEnumerable<UnlockCacheItem> allItems)
|
public override float ComputeWidth(IEnumerable<UnlockCacheItem> allItems)
|
||||||
|
|
@ -297,10 +322,13 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
|
|
||||||
private sealed class ItemIdColumn : NumberColumn<uint, UnlockCacheItem>
|
private sealed class ItemIdColumn : NumberColumn<uint, UnlockCacheItem>
|
||||||
{
|
{
|
||||||
public ItemIdColumn()
|
public ItemIdColumn(Configuration config)
|
||||||
{
|
{
|
||||||
Label = new StringU8("Item Id..."u8);
|
Label = new StringU8("Item Id..."u8);
|
||||||
UnscaledWidth = 70;
|
UnscaledWidth = 70;
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.Set(config.Filters.UnlocksItemIdFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksItemIdFilter = Filter.Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override uint ToValue(in UnlockCacheItem item, int globalIndex)
|
public override uint ToValue(in UnlockCacheItem item, int globalIndex)
|
||||||
|
|
@ -315,10 +343,13 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
|
|
||||||
private sealed class ModelDataColumn : TextColumn<UnlockCacheItem>
|
private sealed class ModelDataColumn : TextColumn<UnlockCacheItem>
|
||||||
{
|
{
|
||||||
public ModelDataColumn()
|
public ModelDataColumn(Configuration config)
|
||||||
{
|
{
|
||||||
Label = new StringU8("Model Data..."u8);
|
Label = new StringU8("Model Data..."u8);
|
||||||
UnscaledWidth = 100;
|
UnscaledWidth = 100;
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.Set(config.Filters.UnlocksModelDataFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksModelDataFilter = Filter.Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DrawColumn(in UnlockCacheItem item, int globalIndex)
|
public override void DrawColumn(in UnlockCacheItem item, int globalIndex)
|
||||||
|
|
@ -363,10 +394,13 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
|
|
||||||
private sealed class RequiredLevelColumn : NumberColumn<byte, UnlockCacheItem>
|
private sealed class RequiredLevelColumn : NumberColumn<byte, UnlockCacheItem>
|
||||||
{
|
{
|
||||||
public RequiredLevelColumn()
|
public RequiredLevelColumn(Configuration config)
|
||||||
{
|
{
|
||||||
Label = new StringU8("Level..."u8);
|
Label = new StringU8("Level..."u8);
|
||||||
UnscaledWidth = 70;
|
UnscaledWidth = 70;
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.Set(config.Filters.UnlocksLevelFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksLevelFilter = Filter.Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte ToValue(in UnlockCacheItem item, int globalIndex)
|
public override byte ToValue(in UnlockCacheItem item, int globalIndex)
|
||||||
|
|
@ -383,7 +417,7 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
{
|
{
|
||||||
private readonly JobService _jobs;
|
private readonly JobService _jobs;
|
||||||
|
|
||||||
public JobColumn(JobService jobs)
|
public JobColumn(Configuration config, JobService jobs)
|
||||||
: base(false)
|
: base(false)
|
||||||
{
|
{
|
||||||
_jobs = jobs;
|
_jobs = jobs;
|
||||||
|
|
@ -392,6 +426,9 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
Label = new StringU8("Jobs"u8);
|
Label = new StringU8("Jobs"u8);
|
||||||
Filter = new JobFilter(this);
|
Filter = new JobFilter(this);
|
||||||
UnscaledWidth = 200;
|
UnscaledWidth = 200;
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.LoadValue(config.Filters.UnlocksJobFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksJobFilter = Filter.FilterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override StringU8 DisplayString(in UnlockCacheItem item, int globalIndex)
|
protected override StringU8 DisplayString(in UnlockCacheItem item, int globalIndex)
|
||||||
|
|
@ -444,10 +481,13 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
|
|
||||||
private sealed class DyableColumn : FlagColumn<UnlockCacheItem.Dyability, UnlockCacheItem>
|
private sealed class DyableColumn : FlagColumn<UnlockCacheItem.Dyability, UnlockCacheItem>
|
||||||
{
|
{
|
||||||
public DyableColumn()
|
public DyableColumn(Configuration config)
|
||||||
{
|
{
|
||||||
Flags &= ~TableColumnFlags.NoResize;
|
Flags &= ~TableColumnFlags.NoResize;
|
||||||
Label = new StringU8("Dye"u8);
|
Label = new StringU8("Dye"u8);
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.LoadValue(config.Filters.UnlocksDyabilityFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksDyabilityFilter = Filter.FilterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float ComputeWidth(IEnumerable<UnlockCacheItem> _)
|
public override float ComputeWidth(IEnumerable<UnlockCacheItem> _)
|
||||||
|
|
@ -487,8 +527,13 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
|
|
||||||
private sealed class TradableColumn : LunaStyle.YesNoColumn<UnlockCacheItem>
|
private sealed class TradableColumn : LunaStyle.YesNoColumn<UnlockCacheItem>
|
||||||
{
|
{
|
||||||
public TradableColumn()
|
public TradableColumn(Configuration config)
|
||||||
=> Label = new StringU8("Trade"u8);
|
{
|
||||||
|
Label = new StringU8("Trade"u8);
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.LoadValue(config.Filters.UnlocksTradableFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksTradableFilter = Filter.FilterValue;
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool GetValue(in UnlockCacheItem item, int globalIndex, int triEnumIndex)
|
protected override bool GetValue(in UnlockCacheItem item, int globalIndex, int triEnumIndex)
|
||||||
=> item.Tradable;
|
=> item.Tradable;
|
||||||
|
|
@ -496,8 +541,13 @@ public sealed class UnlockTable : TableBase<UnlockCacheItem, UnlockTable.Cache>,
|
||||||
|
|
||||||
private sealed class CrestColumn : LunaStyle.YesNoColumn<UnlockCacheItem>
|
private sealed class CrestColumn : LunaStyle.YesNoColumn<UnlockCacheItem>
|
||||||
{
|
{
|
||||||
public CrestColumn()
|
public CrestColumn(Configuration config)
|
||||||
=> Label = new StringU8("Crest"u8);
|
{
|
||||||
|
Label = new StringU8("Crest"u8);
|
||||||
|
if (config.RememberUnlocksFilters)
|
||||||
|
Filter.LoadValue(config.Filters.UnlocksCrestFilter);
|
||||||
|
Filter.FilterChanged += () => config.Filters.UnlocksCrestFilter = Filter.FilterValue;
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool GetValue(in UnlockCacheItem item, int globalIndex, int triEnumIndex)
|
protected override bool GetValue(in UnlockCacheItem item, int globalIndex, int triEnumIndex)
|
||||||
=> item.Crest;
|
=> item.Crest;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,15 @@ public readonly record struct ModSettings(Dictionary<string, List<string>> Setti
|
||||||
=> new();
|
=> new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class CutsceneResolveService : IService
|
||||||
|
{
|
||||||
|
public Func<int, int>? CheckCutsceneParent;
|
||||||
|
|
||||||
|
/// <summary> Obtain the parent of a cutscene actor if it is known. </summary>
|
||||||
|
public short CutsceneParent(ushort idx)
|
||||||
|
=> (short)(CheckCutsceneParent?.Invoke(idx) ?? -1);
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class PenumbraService : IDisposable, IService
|
public sealed class PenumbraService : IDisposable, IService
|
||||||
{
|
{
|
||||||
public const int RequiredPenumbraBreakingVersion = 5;
|
public const int RequiredPenumbraBreakingVersion = 5;
|
||||||
|
|
@ -45,6 +54,8 @@ public sealed class PenumbraService : IDisposable, IService
|
||||||
private const int KeyManual = -6160;
|
private const int KeyManual = -6160;
|
||||||
private const string NameManual = "Glamourer (Manually)";
|
private const string NameManual = "Glamourer (Manually)";
|
||||||
|
|
||||||
|
public readonly CutsceneResolveService ResolveService;
|
||||||
|
|
||||||
private readonly IDalamudPluginInterface _pluginInterface;
|
private readonly IDalamudPluginInterface _pluginInterface;
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly EventSubscriber<ChangedItemType, uint> _tooltipSubscriber;
|
private readonly EventSubscriber<ChangedItemType, uint> _tooltipSubscriber;
|
||||||
|
|
@ -84,7 +95,6 @@ public sealed class PenumbraService : IDisposable, IService
|
||||||
private global::Penumbra.Api.IpcSubscribers.UnregisterSettingsSection? _unregisterSettingsSection;
|
private global::Penumbra.Api.IpcSubscribers.UnregisterSettingsSection? _unregisterSettingsSection;
|
||||||
private IReadOnlyList<(string ModDirectory, IReadOnlyDictionary<string, object?> ChangedItems)>? _changedItems;
|
private IReadOnlyList<(string ModDirectory, IReadOnlyDictionary<string, object?> ChangedItems)>? _changedItems;
|
||||||
private Func<string, (string ModDirectory, string ModName)[]>? _checkCurrentChangedItems;
|
private Func<string, (string ModDirectory, string ModName)[]>? _checkCurrentChangedItems;
|
||||||
private Func<int, int>? _checkCutsceneParent;
|
|
||||||
private Func<nint, nint>? _getGameObject;
|
private Func<nint, nint>? _getGameObject;
|
||||||
|
|
||||||
private readonly IDisposable _initializedEvent;
|
private readonly IDisposable _initializedEvent;
|
||||||
|
|
@ -97,10 +107,12 @@ public sealed class PenumbraService : IDisposable, IService
|
||||||
public int CurrentMinor { get; private set; }
|
public int CurrentMinor { get; private set; }
|
||||||
public DateTime AttachTime { get; private set; }
|
public DateTime AttachTime { get; private set; }
|
||||||
|
|
||||||
public PenumbraService(IDalamudPluginInterface pi, PenumbraReloaded penumbraReloaded, Configuration config)
|
public PenumbraService(IDalamudPluginInterface pi, PenumbraReloaded penumbraReloaded, CutsceneResolveService resolveService,
|
||||||
|
Configuration config)
|
||||||
{
|
{
|
||||||
_pluginInterface = pi;
|
_pluginInterface = pi;
|
||||||
_penumbraReloaded = penumbraReloaded;
|
_penumbraReloaded = penumbraReloaded;
|
||||||
|
ResolveService = resolveService;
|
||||||
_config = config;
|
_config = config;
|
||||||
_initializedEvent = global::Penumbra.Api.IpcSubscribers.Initialized.Subscriber(pi, Reattach);
|
_initializedEvent = global::Penumbra.Api.IpcSubscribers.Initialized.Subscriber(pi, Reattach);
|
||||||
_disposedEvent = global::Penumbra.Api.IpcSubscribers.Disposed.Subscriber(pi, Unattach);
|
_disposedEvent = global::Penumbra.Api.IpcSubscribers.Disposed.Subscriber(pi, Unattach);
|
||||||
|
|
@ -192,7 +204,7 @@ public sealed class PenumbraService : IDisposable, IService
|
||||||
|
|
||||||
private ModSettings GetSettings(Guid collection, string modDirectory, string modName, out string source)
|
private ModSettings GetSettings(Guid collection, string modDirectory, string modName, out string source)
|
||||||
{
|
{
|
||||||
if (_getCurrentSettingsWithTemp != null)
|
if (_getCurrentSettingsWithTemp is not null)
|
||||||
{
|
{
|
||||||
source = string.Empty;
|
source = string.Empty;
|
||||||
var (ec, tuple) = _getCurrentSettingsWithTemp!.Invoke(collection, modDirectory, modName, false, false, KeyFixed);
|
var (ec, tuple) = _getCurrentSettingsWithTemp!.Invoke(collection, modDirectory, modName, false, false, KeyFixed);
|
||||||
|
|
@ -204,7 +216,7 @@ public sealed class PenumbraService : IDisposable, IService
|
||||||
: ModSettings.Empty;
|
: ModSettings.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_queryTemporaryModSettings != null)
|
if (_queryTemporaryModSettings is not null)
|
||||||
{
|
{
|
||||||
var tempEc = _queryTemporaryModSettings.Invoke(collection, modDirectory, out var tempTuple, out source, 0, modName);
|
var tempEc = _queryTemporaryModSettings.Invoke(collection, modDirectory, out var tempTuple, out source, 0, modName);
|
||||||
if (tempEc is PenumbraApiEc.Success && tempTuple != null)
|
if (tempEc is PenumbraApiEc.Success && tempTuple != null)
|
||||||
|
|
@ -485,9 +497,6 @@ public sealed class PenumbraService : IDisposable, IService
|
||||||
public Actor GameObjectFromDrawObject(Model drawObject)
|
public Actor GameObjectFromDrawObject(Model drawObject)
|
||||||
=> _getGameObject?.Invoke(drawObject.Address) ?? Actor.Null;
|
=> _getGameObject?.Invoke(drawObject.Address) ?? Actor.Null;
|
||||||
|
|
||||||
/// <summary> Obtain the parent of a cutscene actor if it is known. </summary>
|
|
||||||
public short CutsceneParent(ushort idx)
|
|
||||||
=> (short)(_checkCutsceneParent?.Invoke(idx) ?? -1);
|
|
||||||
|
|
||||||
/// <summary> Try to redraw the given actor. </summary>
|
/// <summary> Try to redraw the given actor. </summary>
|
||||||
public void RedrawObject(Actor actor, RedrawType settings)
|
public void RedrawObject(Actor actor, RedrawType settings)
|
||||||
|
|
@ -554,7 +563,7 @@ public sealed class PenumbraService : IDisposable, IService
|
||||||
_collectionByIdentifier = new global::Penumbra.Api.IpcSubscribers.GetCollectionsByIdentifier(_pluginInterface);
|
_collectionByIdentifier = new global::Penumbra.Api.IpcSubscribers.GetCollectionsByIdentifier(_pluginInterface);
|
||||||
_collections = new global::Penumbra.Api.IpcSubscribers.GetCollections(_pluginInterface);
|
_collections = new global::Penumbra.Api.IpcSubscribers.GetCollections(_pluginInterface);
|
||||||
_redraw = new global::Penumbra.Api.IpcSubscribers.RedrawObject(_pluginInterface);
|
_redraw = new global::Penumbra.Api.IpcSubscribers.RedrawObject(_pluginInterface);
|
||||||
_checkCutsceneParent = new global::Penumbra.Api.IpcSubscribers.GetCutsceneParentIndexFunc(_pluginInterface).Invoke();
|
ResolveService.CheckCutsceneParent = new global::Penumbra.Api.IpcSubscribers.GetCutsceneParentIndexFunc(_pluginInterface).Invoke();
|
||||||
_getGameObject = new global::Penumbra.Api.IpcSubscribers.GetGameObjectFromDrawObjectFunc(_pluginInterface).Invoke();
|
_getGameObject = new global::Penumbra.Api.IpcSubscribers.GetGameObjectFromDrawObjectFunc(_pluginInterface).Invoke();
|
||||||
_objectCollection = new global::Penumbra.Api.IpcSubscribers.GetCollectionForObject(_pluginInterface);
|
_objectCollection = new global::Penumbra.Api.IpcSubscribers.GetCollectionForObject(_pluginInterface);
|
||||||
_getMods = new global::Penumbra.Api.IpcSubscribers.GetModList(_pluginInterface);
|
_getMods = new global::Penumbra.Api.IpcSubscribers.GetModList(_pluginInterface);
|
||||||
|
|
@ -623,7 +632,7 @@ public sealed class PenumbraService : IDisposable, IService
|
||||||
_collections = null;
|
_collections = null;
|
||||||
_redraw = null;
|
_redraw = null;
|
||||||
_getGameObject = null;
|
_getGameObject = null;
|
||||||
_checkCutsceneParent = null;
|
ResolveService.CheckCutsceneParent = null;
|
||||||
_objectCollection = null;
|
_objectCollection = null;
|
||||||
_getMods = null;
|
_getMods = null;
|
||||||
_currentCollection = null;
|
_currentCollection = null;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ public sealed class BackupService(Logger log, FilenameService provider) : BaseBa
|
||||||
var list = new List<FileInfo>(16)
|
var list = new List<FileInfo>(16)
|
||||||
{
|
{
|
||||||
new(fileNames.ConfigurationFile),
|
new(fileNames.ConfigurationFile),
|
||||||
new(fileNames.UiConfiguration),
|
new(fileNames.UiConfigurationFile),
|
||||||
new(fileNames.MigrationDesignFileSystem),
|
new(fileNames.MigrationDesignFileSystem),
|
||||||
new(fileNames.MigrationDesignFile),
|
new(fileNames.MigrationDesignFile),
|
||||||
new(fileNames.AutomationFile),
|
new(fileNames.AutomationFile),
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ public sealed class FilenameService(IDalamudPluginInterface pi) : BaseFilePathPr
|
||||||
public readonly string EphemeralConfigFile = Path.Combine(pi.ConfigDirectory.FullName, "ephemeral_config.json");
|
public readonly string EphemeralConfigFile = Path.Combine(pi.ConfigDirectory.FullName, "ephemeral_config.json");
|
||||||
public readonly string NpcAppearanceFile = Path.Combine(pi.ConfigDirectory.FullName, "npc_appearance_data.json");
|
public readonly string NpcAppearanceFile = Path.Combine(pi.ConfigDirectory.FullName, "npc_appearance_data.json");
|
||||||
public readonly string CollectionOverrideFile = Path.Combine(pi.ConfigDirectory.FullName, "collection_overrides.json");
|
public readonly string CollectionOverrideFile = Path.Combine(pi.ConfigDirectory.FullName, "collection_overrides.json");
|
||||||
public readonly string UiConfiguration = Path.Combine(pi.ConfigDirectory.FullName, "ui_config.json");
|
public readonly string UiConfigurationFile = Path.Combine(pi.ConfigDirectory.FullName, "ui_config.json");
|
||||||
|
public readonly string FilterFile = Path.Combine(pi.ConfigDirectory.FullName, "filters.json");
|
||||||
public readonly string FileSystemFolder = Path.Combine(pi.ConfigDirectory.FullName, "design_filesystem");
|
public readonly string FileSystemFolder = Path.Combine(pi.ConfigDirectory.FullName, "design_filesystem");
|
||||||
public readonly string FileSystemEmptyFolders = Path.Combine(pi.ConfigDirectory.FullName, "design_filesystem", "empty_folders.json");
|
public readonly string FileSystemEmptyFolders = Path.Combine(pi.ConfigDirectory.FullName, "design_filesystem", "empty_folders.json");
|
||||||
public readonly string FileSystemExpandedFolders = Path.Combine(pi.ConfigDirectory.FullName, "design_filesystem", "expanded_folders.json");
|
public readonly string FileSystemExpandedFolders = Path.Combine(pi.ConfigDirectory.FullName, "design_filesystem", "expanded_folders.json");
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ public static class StaticServiceManager
|
||||||
.AddExistingService(log)
|
.AddExistingService(log)
|
||||||
.AddSingleton<MessageService>()
|
.AddSingleton<MessageService>()
|
||||||
.AddSingleton<ActorObjectManager>()
|
.AddSingleton<ActorObjectManager>()
|
||||||
.AddSingleton(p => new CutsceneResolver(p.GetRequiredService<PenumbraService>().CutsceneParent))
|
.AddSingleton(p => new CutsceneResolver(p.GetRequiredService<CutsceneResolveService>().CutsceneParent))
|
||||||
.AddExistingService(glamourer);
|
.AddExistingService(glamourer);
|
||||||
services.AddIServices(typeof(EquipItem).Assembly);
|
services.AddIServices(typeof(EquipItem).Assembly);
|
||||||
services.AddIServices(typeof(Glamourer).Assembly);
|
services.AddIServices(typeof(Glamourer).Assembly);
|
||||||
|
|
|
||||||
2
Luna
2
Luna
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4a46e8551dd4438465c013c4a01d2936e5b4d4da
|
Subproject commit bc900c5b5959915a87f60487f5b67aa358b195be
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9cfcaf39fef363e281f066b55811deef72908f2f
|
Subproject commit c7c1cae55b34c59580492a8e279205844e2116e2
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit f75aa967763347148401ec2cb800dcba2523f8c0
|
Subproject commit 2d83cda9e72c132b90bba20dd862a442a218b6c2
|
||||||
Loading…
Add table
Add a link
Reference in a new issue