mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Add more mod association and modded utility.
This commit is contained in:
parent
ab2a3f5bd9
commit
d56c2db547
9 changed files with 277 additions and 90 deletions
|
|
@ -17,7 +17,6 @@ using OtterGui;
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Text;
|
||||
using OtterGuiInternal.Structs;
|
||||
using Penumbra.GameData.Enums;
|
||||
using static Glamourer.Gui.Tabs.HeaderDrawer;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Glamourer.Gui.Tabs.DesignTab;
|
|||
|
||||
public class ModAssociationsTab(PenumbraService penumbra, DesignFileSystemSelector selector, DesignManager manager, Configuration config)
|
||||
{
|
||||
private readonly ModCombo _modCombo = new(penumbra, Glamourer.Log);
|
||||
private readonly ModCombo _modCombo = new(penumbra, Glamourer.Log, selector);
|
||||
private (Mod, ModSettings)[]? _copy;
|
||||
|
||||
public void Draw()
|
||||
|
|
|
|||
|
|
@ -4,19 +4,18 @@ using ImGuiNET;
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Log;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
|
||||
namespace Glamourer.Gui.Tabs.DesignTab;
|
||||
|
||||
public sealed class ModCombo : FilterComboCache<(Mod Mod, ModSettings Settings)>
|
||||
public sealed class ModCombo : FilterComboCache<(Mod Mod, ModSettings Settings, int Count)>
|
||||
{
|
||||
public ModCombo(PenumbraService penumbra, Logger log)
|
||||
: base(penumbra.GetMods, MouseWheelType.None, log)
|
||||
{
|
||||
SearchByParts = false;
|
||||
}
|
||||
public ModCombo(PenumbraService penumbra, Logger log, DesignFileSystemSelector selector)
|
||||
: base(() => penumbra.GetMods(selector.Selected?.FilteredItemNames.ToArray() ?? []), MouseWheelType.None, log)
|
||||
=> SearchByParts = false;
|
||||
|
||||
protected override string ToString((Mod Mod, ModSettings Settings) obj)
|
||||
protected override string ToString((Mod Mod, ModSettings Settings, int Count) obj)
|
||||
=> obj.Mod.Name;
|
||||
|
||||
protected override bool IsVisible(int globalIndex, LowerString filter)
|
||||
|
|
@ -24,36 +23,45 @@ public sealed class ModCombo : FilterComboCache<(Mod Mod, ModSettings Settings)>
|
|||
|
||||
protected override bool DrawSelectable(int globalIdx, bool selected)
|
||||
{
|
||||
using var id = ImRaii.PushId(globalIdx);
|
||||
var (mod, settings) = Items[globalIdx];
|
||||
using var id = ImUtf8.PushId(globalIdx);
|
||||
var (mod, settings, count) = Items[globalIdx];
|
||||
bool ret;
|
||||
using (var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), !settings.Enabled))
|
||||
var color = settings.Enabled
|
||||
? count > 0
|
||||
? ColorId.ContainsItemsEnabled.Value()
|
||||
: ImGui.GetColorU32(ImGuiCol.Text)
|
||||
: count > 0
|
||||
? ColorId.ContainsItemsDisabled.Value()
|
||||
: ImGui.GetColorU32(ImGuiCol.TextDisabled);
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, color))
|
||||
{
|
||||
ret = ImGui.Selectable(mod.Name, selected);
|
||||
ret = ImUtf8.Selectable(mod.Name, selected);
|
||||
}
|
||||
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.PopupBorderSize, 2 * ImGuiHelpers.GlobalScale);
|
||||
using var tt = ImRaii.Tooltip();
|
||||
using var tt = ImUtf8.Tooltip();
|
||||
var namesDifferent = mod.Name != mod.DirectoryName;
|
||||
ImGui.Dummy(new Vector2(300 * ImGuiHelpers.GlobalScale, 0));
|
||||
using (var group = ImRaii.Group())
|
||||
using (ImUtf8.Group())
|
||||
{
|
||||
if (namesDifferent)
|
||||
ImGui.TextUnformatted("Directory Name");
|
||||
ImGui.TextUnformatted("Enabled");
|
||||
ImGui.TextUnformatted("Priority");
|
||||
ImUtf8.Text("Directory Name"u8);
|
||||
ImUtf8.Text("Enabled"u8);
|
||||
ImUtf8.Text("Priority"u8);
|
||||
ImUtf8.Text("Affected Design Items"u8);
|
||||
DrawSettingsLeft(settings);
|
||||
}
|
||||
|
||||
ImGui.SameLine(Math.Max(ImGui.GetItemRectSize().X + 3 * ImGui.GetStyle().ItemSpacing.X, 150 * ImGuiHelpers.GlobalScale));
|
||||
using (var group = ImRaii.Group())
|
||||
using (ImUtf8.Group())
|
||||
{
|
||||
if (namesDifferent)
|
||||
ImGui.TextUnformatted(mod.DirectoryName);
|
||||
ImGui.TextUnformatted(settings.Enabled.ToString());
|
||||
ImGui.TextUnformatted(settings.Priority.ToString());
|
||||
ImUtf8.Text(mod.DirectoryName);
|
||||
ImUtf8.Text($"{settings.Enabled}");
|
||||
ImUtf8.Text($"{settings.Priority}");
|
||||
ImUtf8.Text($"{count}");
|
||||
DrawSettingsRight(settings);
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +73,7 @@ public sealed class ModCombo : FilterComboCache<(Mod Mod, ModSettings Settings)>
|
|||
{
|
||||
foreach (var setting in settings.Settings)
|
||||
{
|
||||
ImGui.TextUnformatted(setting.Key);
|
||||
ImUtf8.Text(setting.Key);
|
||||
for (var i = 1; i < setting.Value.Count; ++i)
|
||||
ImGui.NewLine();
|
||||
}
|
||||
|
|
@ -76,10 +84,10 @@ public sealed class ModCombo : FilterComboCache<(Mod Mod, ModSettings Settings)>
|
|||
foreach (var setting in settings.Settings)
|
||||
{
|
||||
if (setting.Value.Count == 0)
|
||||
ImGui.TextUnformatted("<None Enabled>");
|
||||
ImUtf8.Text("<None Enabled>"u8);
|
||||
else
|
||||
foreach (var option in setting.Value)
|
||||
ImGui.TextUnformatted(option);
|
||||
ImUtf8.Text(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,15 @@ using ImGuiNET;
|
|||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Text;
|
||||
using static Glamourer.Gui.Tabs.HeaderDrawer;
|
||||
|
||||
namespace Glamourer.Gui.Tabs.DesignTab;
|
||||
|
||||
public class MultiDesignPanel(DesignFileSystemSelector selector, DesignManager editor, DesignColors colors)
|
||||
public class MultiDesignPanel(DesignFileSystemSelector selector, DesignManager editor, DesignColors colors, Configuration config)
|
||||
{
|
||||
private readonly Button[] _leftButtons = [];
|
||||
private readonly Button[] _rightButtons = [new IncognitoButton(config.Ephemeral)];
|
||||
|
||||
private readonly DesignColorCombo _colorCombo = new(colors, true);
|
||||
|
||||
public void Draw()
|
||||
|
|
@ -17,8 +21,12 @@ public class MultiDesignPanel(DesignFileSystemSelector selector, DesignManager e
|
|||
if (selector.SelectedPaths.Count == 0)
|
||||
return;
|
||||
|
||||
var width = ImGuiHelpers.ScaledVector2(145, 0);
|
||||
ImGui.NewLine();
|
||||
HeaderDrawer.Draw(string.Empty, 0, ImGui.GetColorU32(ImGuiCol.FrameBg), _leftButtons, _rightButtons);
|
||||
using var child = ImUtf8.Child("##MultiPanel"u8, default, true);
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
var width = ImGuiHelpers.ScaledVector2(145, 0);
|
||||
var treeNodePos = ImGui.GetCursorPos();
|
||||
_numDesigns = DrawDesignList();
|
||||
DrawCounts(treeNodePos);
|
||||
|
|
@ -135,7 +143,7 @@ public class MultiDesignPanel(DesignFileSystemSelector selector, DesignManager e
|
|||
{
|
||||
ImUtf8.TextFrameAligned("Multi Tagger:"u8);
|
||||
ImGui.SameLine();
|
||||
var offset = ImGui.GetItemRectSize().X;
|
||||
var offset = ImGui.GetItemRectSize().X + ImGui.GetStyle().WindowPadding.X;
|
||||
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 2 * (width.X + ImGui.GetStyle().ItemSpacing.X));
|
||||
ImUtf8.InputText("##tag"u8, ref _tag, "Tag Name..."u8);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Glamourer.Designs;
|
||||
using Glamourer.GameData;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.Interop.Penumbra;
|
||||
using Glamourer.Services;
|
||||
using Glamourer.Unlocks;
|
||||
using ImGuiNET;
|
||||
|
|
@ -23,7 +23,8 @@ public class UnlockOverview(
|
|||
TextureService textures,
|
||||
CodeService codes,
|
||||
JobService jobs,
|
||||
FavoriteManager favorites)
|
||||
FavoriteManager favorites,
|
||||
PenumbraService penumbra)
|
||||
{
|
||||
private static readonly Vector4 UnavailableTint = new(0.3f, 0.3f, 0.3f, 1.0f);
|
||||
|
||||
|
|
@ -32,6 +33,9 @@ public class UnlockOverview(
|
|||
private Gender _selected3 = Gender.Unknown;
|
||||
private BonusItemFlag _selected4 = BonusItemFlag.Unknown;
|
||||
|
||||
private uint _favoriteColor;
|
||||
private uint _moddedColor;
|
||||
|
||||
private void DrawSelector()
|
||||
{
|
||||
using var child = ImRaii.Child("Selector", new Vector2(200 * ImGuiHelpers.GlobalScale, -1), true);
|
||||
|
|
@ -90,6 +94,9 @@ public class UnlockOverview(
|
|||
if (!child)
|
||||
return;
|
||||
|
||||
_moddedColor = ColorId.ModdedItemMarker.Value();
|
||||
_favoriteColor = ColorId.FavoriteStarOn.Value();
|
||||
|
||||
if (_selected1 is not FullEquipType.Unknown)
|
||||
DrawItems();
|
||||
else if (_selected2 is not SubRace.Unknown && _selected3 is not Gender.Unknown)
|
||||
|
|
@ -120,7 +127,7 @@ public class UnlockOverview(
|
|||
unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint);
|
||||
|
||||
if (favorites.Contains(_selected3, _selected2, customize.Index, customize.Value))
|
||||
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), ColorId.FavoriteStarOn.Value(),
|
||||
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), _favoriteColor,
|
||||
12 * ImGuiHelpers.GlobalScale, ImDrawFlags.RoundCornersAll, 6 * ImGuiHelpers.GlobalScale);
|
||||
|
||||
if (hasIcon && ImGui.IsItemHovered())
|
||||
|
|
@ -192,9 +199,11 @@ public class UnlockOverview(
|
|||
ImGui.Image(icon, iconSize, Vector2.Zero, Vector2.One,
|
||||
unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint);
|
||||
if (favorites.Contains(item))
|
||||
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), ColorId.FavoriteStarOn.Value(),
|
||||
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), _favoriteColor,
|
||||
2 * ImGuiHelpers.GlobalScale, ImDrawFlags.RoundCornersAll, 4 * ImGuiHelpers.GlobalScale);
|
||||
|
||||
var mods = DrawModdedMarker(item, iconSize);
|
||||
|
||||
// TODO handle clicking
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
|
|
@ -206,9 +215,10 @@ public class UnlockOverview(
|
|||
ImUtf8.Text($"{item.Id.Id}");
|
||||
ImUtf8.Text($"{item.PrimaryId.Id}-{item.Variant.Id}");
|
||||
// TODO
|
||||
ImUtf8.Text("Always Unlocked"); // : $"Unlocked on {time:g}" : "Not Unlocked.");
|
||||
ImUtf8.Text("Always Unlocked"u8); // : $"Unlocked on {time:g}" : "Not Unlocked.");
|
||||
// TODO
|
||||
//tooltip.CreateTooltip(item, string.Empty, false);
|
||||
DrawModTooltip(mods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -263,6 +273,8 @@ public class UnlockOverview(
|
|||
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), ColorId.FavoriteStarOn.Value(),
|
||||
2 * ImGuiHelpers.GlobalScale, ImDrawFlags.RoundCornersAll, 4 * ImGuiHelpers.GlobalScale);
|
||||
|
||||
var mods = DrawModdedMarker(item, iconSize);
|
||||
|
||||
if (ImGui.IsItemClicked())
|
||||
Glamourer.Messager.Chat.Print(new SeStringBuilder().AddItemLink(item.ItemId.Id, false).BuiltString);
|
||||
|
||||
|
|
@ -306,6 +318,7 @@ public class UnlockOverview(
|
|||
ImGui.TextUnformatted("Tradable");
|
||||
if (item.Flags.HasFlag(ItemFlags.IsCrestWorthy))
|
||||
ImGui.TextUnformatted("Can apply Crest");
|
||||
DrawModTooltip(mods);
|
||||
tooltip.CreateTooltip(item, string.Empty, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -316,4 +329,36 @@ public class UnlockOverview(
|
|||
|
||||
private static int IconsPerRow(float iconWidth, float iconSpacing)
|
||||
=> (int)(ImGui.GetContentRegionAvail().X / (iconWidth + iconSpacing));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
|
||||
private (string ModDirectory, string ModName)[] DrawModdedMarker(in EquipItem item, Vector2 iconSize)
|
||||
{
|
||||
var mods = penumbra.CheckCurrentChangedItem(item.Name);
|
||||
if (mods.Length == 0)
|
||||
return mods;
|
||||
|
||||
var center = ImGui.GetItemRectMin() + new Vector2(iconSize.X * 0.85f, iconSize.Y * 0.15f);
|
||||
ImGui.GetWindowDrawList().AddCircleFilled(center, iconSize.X * 0.1f, _moddedColor);
|
||||
ImGui.GetWindowDrawList().AddCircle(center, iconSize.X * 0.1f, 0xFF000000);
|
||||
return mods;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
|
||||
private void DrawModTooltip((string ModDirectory, string ModName)[] mods)
|
||||
{
|
||||
switch (mods.Length)
|
||||
{
|
||||
case 0: return;
|
||||
case 1:
|
||||
ImUtf8.Text("Modded by: "u8, _moddedColor);
|
||||
ImGui.SameLine(0, 0);
|
||||
ImUtf8.Text(mods[0].ModName);
|
||||
return;
|
||||
default:
|
||||
ImUtf8.Text("Modded by:"u8, _moddedColor);
|
||||
foreach (var (_, mod) in mods)
|
||||
ImUtf8.BulletText(mod);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using Dalamud.Interface;
|
|||
using Dalamud.Interface.Utility;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.Interop.Penumbra;
|
||||
using Glamourer.Services;
|
||||
using Glamourer.Unlocks;
|
||||
using ImGuiNET;
|
||||
|
|
@ -17,12 +18,16 @@ namespace Glamourer.Gui.Tabs.UnlocksTab;
|
|||
|
||||
public class UnlockTable : Table<EquipItem>, IDisposable
|
||||
{
|
||||
private readonly ObjectUnlocked _event;
|
||||
private readonly ObjectUnlocked _event;
|
||||
private readonly PenumbraService _penumbra;
|
||||
|
||||
private Guid _lastCurrentCollection = Guid.Empty;
|
||||
|
||||
public UnlockTable(ItemManager items, TextureService textures, ItemUnlockManager itemUnlocks,
|
||||
PenumbraChangedItemTooltip tooltip, ObjectUnlocked @event, JobService jobs, FavoriteManager favorites)
|
||||
PenumbraChangedItemTooltip tooltip, ObjectUnlocked @event, JobService jobs, FavoriteManager favorites, PenumbraService penumbra)
|
||||
: base("ItemUnlockTable", new ItemList(items),
|
||||
new FavoriteColumn(favorites, @event) { Label = "F" },
|
||||
new ModdedColumn(penumbra) { Label = "M" },
|
||||
new NameColumn(textures, tooltip) { Label = "Item Name..." },
|
||||
new SlotColumn { Label = "Equip Slot" },
|
||||
new TypeColumn { Label = "Item Type..." },
|
||||
|
|
@ -36,14 +41,40 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
|||
new TradableColumn { Label = "Trade" }
|
||||
)
|
||||
{
|
||||
_event = @event;
|
||||
Sortable = true;
|
||||
Flags |= ImGuiTableFlags.Hideable | ImGuiTableFlags.Reorderable | ImGuiTableFlags.Resizable;
|
||||
_event = @event;
|
||||
_penumbra = penumbra;
|
||||
Sortable = true;
|
||||
Flags |= ImGuiTableFlags.Hideable | ImGuiTableFlags.Reorderable | ImGuiTableFlags.Resizable;
|
||||
_event.Subscribe(OnObjectUnlock, ObjectUnlocked.Priority.UnlockTable);
|
||||
_penumbra.ModSettingChanged += OnModSettingsChanged;
|
||||
|
||||
}
|
||||
|
||||
private void OnModSettingsChanged(Penumbra.Api.Enums.ModSettingChange type, Guid collection, string mod, bool inherited)
|
||||
{
|
||||
if (collection != _lastCurrentCollection)
|
||||
return;
|
||||
|
||||
FilterDirty = true;
|
||||
SortDirty = true;
|
||||
}
|
||||
|
||||
protected override void PreDraw()
|
||||
{
|
||||
var lastCurrentCollection = _penumbra.CurrentCollection.Id;
|
||||
if (_lastCurrentCollection != lastCurrentCollection)
|
||||
{
|
||||
_lastCurrentCollection = lastCurrentCollection;
|
||||
FilterDirty = true;
|
||||
SortDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _event.Unsubscribe(OnObjectUnlock);
|
||||
{
|
||||
_event.Unsubscribe(OnObjectUnlock);
|
||||
_penumbra.ModSettingChanged -= OnModSettingsChanged;
|
||||
}
|
||||
|
||||
private sealed class FavoriteColumn : YesNoColumn<EquipItem>
|
||||
{
|
||||
|
|
@ -77,6 +108,66 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
|||
=> _favorites.Contains(rhs).CompareTo(_favorites.Contains(lhs));
|
||||
}
|
||||
|
||||
private sealed class ModdedColumn : YesNoColumn<EquipItem>
|
||||
{
|
||||
public override float Width
|
||||
=> ImGui.GetFrameHeightWithSpacing();
|
||||
|
||||
private readonly PenumbraService _penumbra;
|
||||
private readonly Dictionary<CustomItemId, int> _compareCache = [];
|
||||
|
||||
public ModdedColumn(PenumbraService penumbra)
|
||||
{
|
||||
_penumbra = penumbra;
|
||||
Flags |= ImGuiTableColumnFlags.NoResize;
|
||||
}
|
||||
|
||||
public override void PostSort()
|
||||
{
|
||||
_compareCache.Clear();
|
||||
}
|
||||
|
||||
public override void DrawColumn(EquipItem item, int idx)
|
||||
{
|
||||
var value = _penumbra.CheckCurrentChangedItem(item.Name);
|
||||
if (value.Length == 0)
|
||||
return;
|
||||
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
{
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ModdedItemMarker.Value());
|
||||
ImGuiUtil.Center(FontAwesomeIcon.Circle.ToIconString());
|
||||
}
|
||||
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
using var tt = ImUtf8.Tooltip();
|
||||
foreach (var (_, mod) in value)
|
||||
ImUtf8.BulletText(mod);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FilterFunc(EquipItem item)
|
||||
=> FilterValue.HasFlag(_penumbra.CheckCurrentChangedItem(item.Name).Length > 0 ? YesNoFlag.Yes : YesNoFlag.No);
|
||||
|
||||
public override int Compare(EquipItem lhs, EquipItem rhs)
|
||||
{
|
||||
if (!_compareCache.TryGetValue(lhs.Id, out var lhsCount))
|
||||
{
|
||||
lhsCount = _penumbra.CheckCurrentChangedItem(lhs.Name).Length;
|
||||
_compareCache[lhs.Id] = lhsCount;
|
||||
}
|
||||
|
||||
if (!_compareCache.TryGetValue(rhs.Id, out var rhsCount))
|
||||
{
|
||||
rhsCount = _penumbra.CheckCurrentChangedItem(rhs.Name).Length;
|
||||
_compareCache[rhs.Id] = rhsCount;
|
||||
}
|
||||
|
||||
return lhsCount.CompareTo(rhsCount);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class NameColumn : ColumnString<EquipItem>
|
||||
{
|
||||
private readonly TextureService _textures;
|
||||
|
|
@ -317,7 +408,6 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
|||
{ }
|
||||
}
|
||||
|
||||
|
||||
private sealed class JobColumn : ColumnFlags<JobFlag, EquipItem>
|
||||
{
|
||||
public override float Width
|
||||
|
|
@ -415,7 +505,6 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private sealed class DyableColumn : ColumnFlags<DyableColumn.Dyable, EquipItem>
|
||||
{
|
||||
[Flags]
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public class PenumbraService : IDisposable
|
|||
public const int RequiredPenumbraFeatureVersionTemp = 4;
|
||||
public const int RequiredPenumbraFeatureVersionTemp2 = 5;
|
||||
public const int RequiredPenumbraFeatureVersionTemp3 = 6;
|
||||
public const int RequiredPenumbraFeatureVersionTemp4 = 7;
|
||||
|
||||
private const int Key = -1610;
|
||||
|
||||
|
|
@ -49,30 +50,33 @@ public class PenumbraService : IDisposable
|
|||
private readonly EventSubscriber<nint, Guid, nint> _createdCharacterBase;
|
||||
private readonly EventSubscriber<ModSettingChange, Guid, string, bool> _modSettingChanged;
|
||||
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCollectionsByIdentifier? _collectionByIdentifier;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCollections? _collections;
|
||||
private global::Penumbra.Api.IpcSubscribers.RedrawObject? _redraw;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetDrawObjectInfo? _drawObjectInfo;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCutsceneParentIndex? _cutsceneParent;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCollectionForObject? _objectCollection;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetModList? _getMods;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCollection? _currentCollection;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCurrentModSettingsWithTemp? _getCurrentSettingsWithTemp;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCurrentModSettings? _getCurrentSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetAllModSettings? _getAllSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.TryInheritMod? _inheritMod;
|
||||
private global::Penumbra.Api.IpcSubscribers.TrySetMod? _setMod;
|
||||
private global::Penumbra.Api.IpcSubscribers.TrySetModPriority? _setModPriority;
|
||||
private global::Penumbra.Api.IpcSubscribers.TrySetModSetting? _setModSetting;
|
||||
private global::Penumbra.Api.IpcSubscribers.TrySetModSettings? _setModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettings? _setTemporaryModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettingsPlayer? _setTemporaryModSettingsPlayer;
|
||||
private global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettings? _removeTemporaryModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettingsPlayer? _removeTemporaryModSettingsPlayer;
|
||||
private global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettings? _removeAllTemporaryModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettingsPlayer? _removeAllTemporaryModSettingsPlayer;
|
||||
private global::Penumbra.Api.IpcSubscribers.QueryTemporaryModSettings? _queryTemporaryModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.OpenMainWindow? _openModPage;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCollectionsByIdentifier? _collectionByIdentifier;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCollections? _collections;
|
||||
private global::Penumbra.Api.IpcSubscribers.RedrawObject? _redraw;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetDrawObjectInfo? _drawObjectInfo;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCutsceneParentIndex? _cutsceneParent;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCollectionForObject? _objectCollection;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetModList? _getMods;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCollection? _currentCollection;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCurrentModSettingsWithTemp? _getCurrentSettingsWithTemp;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetCurrentModSettings? _getCurrentSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetAllModSettings? _getAllSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.TryInheritMod? _inheritMod;
|
||||
private global::Penumbra.Api.IpcSubscribers.TrySetMod? _setMod;
|
||||
private global::Penumbra.Api.IpcSubscribers.TrySetModPriority? _setModPriority;
|
||||
private global::Penumbra.Api.IpcSubscribers.TrySetModSetting? _setModSetting;
|
||||
private global::Penumbra.Api.IpcSubscribers.TrySetModSettings? _setModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettings? _setTemporaryModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettingsPlayer? _setTemporaryModSettingsPlayer;
|
||||
private global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettings? _removeTemporaryModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettingsPlayer? _removeTemporaryModSettingsPlayer;
|
||||
private global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettings? _removeAllTemporaryModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettingsPlayer? _removeAllTemporaryModSettingsPlayer;
|
||||
private global::Penumbra.Api.IpcSubscribers.QueryTemporaryModSettings? _queryTemporaryModSettings;
|
||||
private global::Penumbra.Api.IpcSubscribers.OpenMainWindow? _openModPage;
|
||||
private global::Penumbra.Api.IpcSubscribers.GetChangedItems? _getChangedItems;
|
||||
private IReadOnlyList<(string ModDirectory, IReadOnlyDictionary<string, object?> ChangedItems)>? _changedItems;
|
||||
private Func<string, (string ModDirectory, string ModName)[]>? _checkCurrentChangedItems;
|
||||
|
||||
private readonly IDisposable _initializedEvent;
|
||||
private readonly IDisposable _disposedEvent;
|
||||
|
|
@ -195,37 +199,58 @@ public class PenumbraService : IDisposable
|
|||
return ret[0];
|
||||
}
|
||||
|
||||
public IReadOnlyList<(Mod Mod, ModSettings Settings)> GetMods()
|
||||
public IReadOnlyList<(Mod Mod, ModSettings Settings, int Count)> GetMods(IReadOnlyList<string> data)
|
||||
{
|
||||
if (!Available)
|
||||
return [];
|
||||
|
||||
try
|
||||
{
|
||||
var allMods = _getMods!.Invoke();
|
||||
var collection = _currentCollection!.Invoke(ApiCollectionType.Current);
|
||||
if (_getAllSettings != null)
|
||||
var allMods = _getMods!.Invoke();
|
||||
var currentCollection = _currentCollection!.Invoke(ApiCollectionType.Current);
|
||||
var withSettings = WithSettings(allMods, currentCollection!.Value.Id);
|
||||
var withCounts = WithCounts(withSettings, allMods.Count);
|
||||
return OrderList(withCounts, allMods.Count);
|
||||
|
||||
IEnumerable<(Mod Mod, ModSettings Settings)> WithSettings(Dictionary<string, string> mods, Guid collection)
|
||||
{
|
||||
var allSettings = _getAllSettings.Invoke(collection!.Value.Id, false, false, Key);
|
||||
if (allSettings.Item1 is PenumbraApiEc.Success)
|
||||
return allMods.Select(m => (new Mod(m.Value, m.Key),
|
||||
if (_getAllSettings != null)
|
||||
{
|
||||
var allSettings = _getAllSettings.Invoke(collection, false, false, Key);
|
||||
if (allSettings.Item1 is PenumbraApiEc.Success)
|
||||
return mods.Select(m => (new Mod(m.Value, m.Key),
|
||||
allSettings.Item2!.TryGetValue(m.Key, out var s)
|
||||
? new ModSettings(s.Item3, s.Item2, s.Item1, s.Item4 && s.Item5, false)
|
||||
: ModSettings.Empty))
|
||||
.OrderByDescending(p => p.Item2.Enabled)
|
||||
.ThenBy(p => p.Item1.Name)
|
||||
.ThenBy(p => p.Item1.DirectoryName)
|
||||
.ThenByDescending(p => p.Item2.Priority)
|
||||
.ToList();
|
||||
? new ModSettings(s.Item3, s.Item2, s.Item1, s is { Item4: true, Item5: true }, false)
|
||||
: ModSettings.Empty));
|
||||
}
|
||||
|
||||
return mods.Select(m => (new Mod(m.Value, m.Key), GetSettings(collection, m.Key, m.Value, out _)));
|
||||
}
|
||||
|
||||
return allMods
|
||||
.Select(m => (new Mod(m.Value, m.Key), GetSettings(collection!.Value.Id, m.Key, m.Value, out _)))
|
||||
.OrderByDescending(p => p.Item2.Enabled)
|
||||
.ThenBy(p => p.Item1.Name)
|
||||
.ThenBy(p => p.Item1.DirectoryName)
|
||||
.ThenByDescending(p => p.Item2.Priority)
|
||||
.ToList();
|
||||
IEnumerable<(Mod Mod, ModSettings Settings, int Count)> WithCounts(IEnumerable<(Mod Mod, ModSettings Settings)> mods, int count)
|
||||
{
|
||||
if (_changedItems != null && _changedItems.Count == count)
|
||||
return mods.Select((m, idx) => (m.Mod, m.Settings, CountItems(_changedItems[idx].ChangedItems, data)));
|
||||
|
||||
return mods.Select(p => (p.Item1, p.Item2, CountItems(_getChangedItems!.Invoke(p.Item1.DirectoryName, p.Item1.Name), data)));
|
||||
|
||||
static int CountItems(IReadOnlyDictionary<string, object?> dict, IReadOnlyList<string> data)
|
||||
=> data.Count(dict.ContainsKey);
|
||||
}
|
||||
|
||||
static IReadOnlyList<(Mod Mod, ModSettings Settings, int Count)> OrderList(
|
||||
IEnumerable<(Mod Mod, ModSettings Settings, int Count)> enumerable, int count)
|
||||
{
|
||||
var array = new (Mod Mod, ModSettings Settings, int Count)[count];
|
||||
var i = 0;
|
||||
foreach (var t in enumerable.OrderByDescending(p => p.Item2.Enabled)
|
||||
.ThenByDescending(p => p.Item3)
|
||||
.ThenBy(p => p.Item1.Name)
|
||||
.ThenBy(p => p.Item1.DirectoryName)
|
||||
.ThenByDescending(p => p.Item2.Priority))
|
||||
array[i++] = t;
|
||||
return array;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -289,6 +314,9 @@ public class PenumbraService : IDisposable
|
|||
RemoveAllTemporarySettings(collection.Key);
|
||||
}
|
||||
|
||||
public (string ModDirectory, string ModName)[] CheckCurrentChangedItem(string changedItem)
|
||||
=> _checkCurrentChangedItems?.Invoke(changedItem) ?? [];
|
||||
|
||||
private void SetModTemporary(StringBuilder sb, Mod mod, ModSettings settings, Guid collection, ObjectIndex? index)
|
||||
{
|
||||
var ex = settings.Remove
|
||||
|
|
@ -476,6 +504,7 @@ public class PenumbraService : IDisposable
|
|||
_setModSetting = new global::Penumbra.Api.IpcSubscribers.TrySetModSetting(_pluginInterface);
|
||||
_setModSettings = new global::Penumbra.Api.IpcSubscribers.TrySetModSettings(_pluginInterface);
|
||||
_openModPage = new global::Penumbra.Api.IpcSubscribers.OpenMainWindow(_pluginInterface);
|
||||
_getChangedItems = new global::Penumbra.Api.IpcSubscribers.GetChangedItems(_pluginInterface);
|
||||
if (CurrentMinor >= RequiredPenumbraFeatureVersionTemp)
|
||||
{
|
||||
_setTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettings(_pluginInterface);
|
||||
|
|
@ -488,10 +517,16 @@ public class PenumbraService : IDisposable
|
|||
if (CurrentMinor >= RequiredPenumbraFeatureVersionTemp2)
|
||||
{
|
||||
_queryTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.QueryTemporaryModSettings(_pluginInterface);
|
||||
if (CurrentMinor >= RequiredPenumbraFeatureVersionTemp2)
|
||||
if (CurrentMinor >= RequiredPenumbraFeatureVersionTemp3)
|
||||
{
|
||||
_getCurrentSettingsWithTemp = new global::Penumbra.Api.IpcSubscribers.GetCurrentModSettingsWithTemp(_pluginInterface);
|
||||
_getAllSettings = new global::Penumbra.Api.IpcSubscribers.GetAllModSettings(_pluginInterface);
|
||||
if (CurrentMinor >= RequiredPenumbraFeatureVersionTemp4)
|
||||
{
|
||||
_changedItems = new global::Penumbra.Api.IpcSubscribers.GetChangedItemAdapterList(_pluginInterface).Invoke();
|
||||
_checkCurrentChangedItems =
|
||||
new global::Penumbra.Api.IpcSubscribers.CheckCurrentChangedItemFunc(_pluginInterface).Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -541,6 +576,9 @@ public class PenumbraService : IDisposable
|
|||
_removeAllTemporaryModSettings = null;
|
||||
_removeAllTemporaryModSettingsPlayer = null;
|
||||
_queryTemporaryModSettings = null;
|
||||
_getChangedItems = null;
|
||||
_changedItems = null;
|
||||
_checkCurrentChangedItems = null;
|
||||
Available = false;
|
||||
Glamourer.Log.Debug("Glamourer detached from Penumbra.");
|
||||
}
|
||||
|
|
|
|||
2
OtterGui
2
OtterGui
|
|
@ -1 +1 @@
|
|||
Subproject commit 3c1260c9833303c2d33d12d6f77dc2b1afea3f34
|
||||
Subproject commit 0b6085ce720ffb7c78cf42d4e51861f34db27744
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit c67809057fac73a0fd407e3ad567f0aa6bc0bc37
|
||||
Subproject commit 70f046830cc7cd35b3480b12b7efe94182477fbb
|
||||
Loading…
Add table
Add a link
Reference in a new issue