diff --git a/Glamourer/GameData/CustomizeManager.cs b/Glamourer/GameData/CustomizeManager.cs
index fabc483..6f03881 100644
--- a/Glamourer/GameData/CustomizeManager.cs
+++ b/Glamourer/GameData/CustomizeManager.cs
@@ -30,7 +30,7 @@ public class CustomizeManager : IAsyncService
/// Every tribe and gender has a separate set of available customizations.
public CustomizeSet GetSet(SubRace race, Gender gender)
{
- if (!Awaiter.IsCompletedSuccessfully)
+ if (!Finished)
Awaiter.Wait();
return _customizationSets[ToIndex(race, gender)];
}
@@ -61,6 +61,10 @@ public class CustomizeManager : IAsyncService
///
public Task Awaiter { get; }
+ ///
+ public bool Finished
+ => Awaiter.IsCompletedSuccessfully;
+
private readonly IconStorage _icons;
private static readonly int ListSize = Clans.Count * Genders.Count;
private readonly CustomizeSet[] _customizationSets = new CustomizeSet[ListSize];
diff --git a/Glamourer/GameData/NpcCustomizeSet.cs b/Glamourer/GameData/NpcCustomizeSet.cs
index a99448e..de70bd9 100644
--- a/Glamourer/GameData/NpcCustomizeSet.cs
+++ b/Glamourer/GameData/NpcCustomizeSet.cs
@@ -33,6 +33,10 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList
///
public Task Awaiter { get; }
+ ///
+ public bool Finished
+ => Awaiter.IsCompletedSuccessfully;
+
/// The list of data.
private readonly List _data = [];
diff --git a/Glamourer/Gui/Equipment/EquipmentDrawer.cs b/Glamourer/Gui/Equipment/EquipmentDrawer.cs
index cc94ed0..616e67c 100644
--- a/Glamourer/Gui/Equipment/EquipmentDrawer.cs
+++ b/Glamourer/Gui/Equipment/EquipmentDrawer.cs
@@ -24,7 +24,7 @@ public class EquipmentDrawer
private readonly ItemManager _items;
private readonly GlamourerColorCombo _stainCombo;
- private readonly DictStains _stainData;
+ private readonly DictStain _stainData;
private readonly ItemCombo[] _itemCombo;
private readonly Dictionary _weaponCombo;
private readonly CodeService _codes;
diff --git a/Glamourer/Gui/Equipment/GlamourerColorCombo.cs b/Glamourer/Gui/Equipment/GlamourerColorCombo.cs
index 1073ac6..2a3dcec 100644
--- a/Glamourer/Gui/Equipment/GlamourerColorCombo.cs
+++ b/Glamourer/Gui/Equipment/GlamourerColorCombo.cs
@@ -13,7 +13,7 @@ using Penumbra.GameData.Structs;
namespace Glamourer.Gui.Equipment;
-public sealed class GlamourerColorCombo(float _comboWidth, DictStains _stains, FavoriteManager _favorites)
+public sealed class GlamourerColorCombo(float _comboWidth, DictStain _stains, FavoriteManager _favorites)
: FilterComboColors(_comboWidth, CreateFunc(_stains, _favorites), Glamourer.Log)
{
protected override bool DrawSelectable(int globalIdx, bool selected)
@@ -40,7 +40,7 @@ public sealed class GlamourerColorCombo(float _comboWidth, DictStains _stains, F
return base.DrawSelectable(globalIdx, selected);
}
- private static Func>> CreateFunc(DictStains stains,
+ private static Func>> CreateFunc(DictStain stains,
FavoriteManager favorites)
=> () => stains.Select(kvp => (kvp, favorites.Contains(kvp.Key))).OrderBy(p => !p.Item2).Select(p => p.kvp)
.Prepend(new KeyValuePair(Stain.None.RowIndex, Stain.None)).Select(kvp
diff --git a/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs b/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs
index bbcfa32..ea99620 100644
--- a/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs
@@ -12,10 +12,11 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectManager) : IDebugTabTree
+public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectManager) : IGameDataDrawer
{
public string Label
=> $"Active Actors ({_stateManager.Count})###Active Actors";
diff --git a/Glamourer/Gui/Tabs/DebugTab/ActorServicePanel.cs b/Glamourer/Gui/Tabs/DebugTab/ActorServicePanel.cs
deleted file mode 100644
index 976b5c4..0000000
--- a/Glamourer/Gui/Tabs/DebugTab/ActorServicePanel.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System;
-using System.Linq;
-using System.Numerics;
-using Dalamud.Interface.Utility;
-using ImGuiNET;
-using OtterGui;
-using OtterGui.Raii;
-using Penumbra.GameData.Actors;
-using Penumbra.GameData.DataContainers;
-using ImGuiClip = OtterGui.ImGuiClip;
-
-namespace Glamourer.Gui.Tabs.DebugTab;
-
-public class ActorManagerPanel(ActorManager _actors, DictBNpcNames _bNpcNames) : IDebugTabTree
-{
- public string Label
- => "Actor Service";
-
- public bool Disabled
- => !_actors.Awaiter.IsCompletedSuccessfully;
-
- private string _bnpcFilter = string.Empty;
- private string _enpcFilter = string.Empty;
- private string _companionFilter = string.Empty;
- private string _mountFilter = string.Empty;
- private string _ornamentFilter = string.Empty;
- private string _worldFilter = string.Empty;
-
- public void Draw()
- {
- DrawBnpcTable();
- DebugTab.DrawNameTable("ENPCs", ref _enpcFilter, _actors.Data.ENpcs.Select(kvp => (kvp.Key.Id, kvp.Value)));
- DebugTab.DrawNameTable("Companions", ref _companionFilter, _actors.Data.Companions.Select(kvp => (kvp.Key.Id, kvp.Value)));
- DebugTab.DrawNameTable("Mounts", ref _mountFilter, _actors.Data.Mounts.Select(kvp => (kvp.Key.Id, kvp.Value)));
- DebugTab.DrawNameTable("Ornaments", ref _ornamentFilter, _actors.Data.Ornaments.Select(kvp => (kvp.Key.Id, kvp.Value)));
- DebugTab.DrawNameTable("Worlds", ref _worldFilter, _actors.Data.Worlds.Select(kvp => ((uint)kvp.Key.Id, kvp.Value)));
- }
-
- private void DrawBnpcTable()
- {
- using var _ = ImRaii.PushId(1);
- using var tree = ImRaii.TreeNode("BNPCs");
- if (!tree)
- return;
-
- var resetScroll = ImGui.InputTextWithHint("##filter", "Filter...", ref _bnpcFilter, 256);
- var height = ImGui.GetTextLineHeightWithSpacing() + 2 * ImGui.GetStyle().CellPadding.Y;
- using var table = ImRaii.Table("##table", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.BordersOuter,
- new Vector2(-1, 10 * height));
- if (!table)
- return;
-
- if (resetScroll)
- ImGui.SetScrollY(0);
- ImGui.TableSetupColumn("1", ImGuiTableColumnFlags.WidthFixed, 50 * ImGuiHelpers.GlobalScale);
- ImGui.TableSetupColumn("2", ImGuiTableColumnFlags.WidthStretch);
- ImGui.TableSetupColumn("3", ImGuiTableColumnFlags.WidthStretch);
- ImGui.TableNextColumn();
- var skips = ImGuiClip.GetNecessarySkips(height);
- ImGui.TableNextRow();
- var data = _actors.Data.BNpcs.Select(kvp => (kvp.Key, kvp.Key.Id.ToString("D5"), kvp.Value));
- var remainder = ImGuiClip.FilteredClippedDraw(data, skips,
- p => p.Item2.Contains(_bnpcFilter) || p.Value.Contains(_bnpcFilter, StringComparison.OrdinalIgnoreCase),
- p =>
- {
- ImGuiUtil.DrawTableColumn(p.Item2);
- ImGuiUtil.DrawTableColumn(p.Value);
- var bNpcs = _bNpcNames.GetBNpcsFromName(p.Key.BNpcNameId);
- ImGuiUtil.DrawTableColumn(string.Join(", ", bNpcs.Select(b => b.Id.ToString())));
- });
- ImGuiClip.DrawEndDummy(remainder, height);
- }
-}
diff --git a/Glamourer/Gui/Tabs/DebugTab/AutoDesignPanel.cs b/Glamourer/Gui/Tabs/DebugTab/AutoDesignPanel.cs
index 8e29b8b..cbc0e40 100644
--- a/Glamourer/Gui/Tabs/DebugTab/AutoDesignPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/AutoDesignPanel.cs
@@ -2,10 +2,11 @@
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class AutoDesignPanel(AutoDesignManager _autoDesignManager) : IDebugTabTree
+public class AutoDesignPanel(AutoDesignManager _autoDesignManager) : IGameDataDrawer
{
public string Label
=> "Auto Designs";
diff --git a/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs b/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs
index d2b9212..7ab089a 100644
--- a/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs
@@ -5,16 +5,17 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class CustomizationServicePanel(CustomizeService customize) : IDebugTabTree
+public class CustomizationServicePanel(CustomizeService customize) : IGameDataDrawer
{
public string Label
=> "Customization Service";
public bool Disabled
- => !customize.Awaiter.IsCompletedSuccessfully;
+ => !customize.Finished;
public void Draw()
{
diff --git a/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs b/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs
index b062980..8703d8c 100644
--- a/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs
@@ -5,10 +5,11 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class CustomizationUnlockPanel(CustomizeUnlockManager _customizeUnlocks) : IDebugTabTree
+public class CustomizationUnlockPanel(CustomizeUnlockManager _customizeUnlocks) : IGameDataDrawer
{
public string Label
=> "Customizations";
diff --git a/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs b/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs
index ef76b09..b06e807 100644
--- a/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs
@@ -4,10 +4,11 @@ using Glamourer.Interop;
using ImGuiNET;
using OtterGui;
using Penumbra.GameData.Files;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class DatFilePanel(ImportService _importService) : IDebugTabTree
+public class DatFilePanel(ImportService _importService) : IGameDataDrawer
{
public string Label
=> "Character Dat File";
diff --git a/Glamourer/Gui/Tabs/DebugTab/DebugTabHeader.cs b/Glamourer/Gui/Tabs/DebugTab/DebugTabHeader.cs
index bd0b98f..cb50b88 100644
--- a/Glamourer/Gui/Tabs/DebugTab/DebugTabHeader.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/DebugTabHeader.cs
@@ -4,21 +4,14 @@ using ImGuiNET;
using Microsoft.Extensions.DependencyInjection;
using OtterGui.Raii;
using OtterGui.Services;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public interface IDebugTabTree : IService
+public class DebugTabHeader(string label, params IGameDataDrawer[] subTrees)
{
- public string Label { get; }
- public void Draw();
-
- public bool Disabled { get; }
-}
-
-public class DebugTabHeader(string label, params IDebugTabTree[] subTrees)
-{
- public string Label { get; } = label;
- public IReadOnlyList SubTrees { get; } = subTrees;
+ public string Label { get; } = label;
+ public IReadOnlyList SubTrees { get; } = subTrees;
public void Draw()
{
@@ -27,14 +20,13 @@ public class DebugTabHeader(string label, params IDebugTabTree[] subTrees)
foreach (var subTree in SubTrees)
{
- using (var disabled = ImRaii.Disabled(subTree.Disabled))
+ using var disabled = ImRaii.Disabled(subTree.Disabled);
+ using var tree = ImRaii.TreeNode(subTree.Label);
+ if (tree)
{
- using var tree = ImRaii.TreeNode(subTree.Label);
- if (!tree)
- continue;
+ disabled.Dispose();
+ subTree.Draw();
}
-
- subTree.Draw();
}
}
@@ -53,13 +45,14 @@ public class DebugTabHeader(string label, params IDebugTabTree[] subTrees)
=> new
(
"Game Data",
- provider.GetRequiredService(),
- provider.GetRequiredService(),
- provider.GetRequiredService(),
- provider.GetRequiredService(),
- provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
provider.GetRequiredService(),
- provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
provider.GetRequiredService()
);
diff --git a/Glamourer/Gui/Tabs/DebugTab/DesignConverterPanel.cs b/Glamourer/Gui/Tabs/DebugTab/DesignConverterPanel.cs
index 9553f72..0de63ed 100644
--- a/Glamourer/Gui/Tabs/DebugTab/DesignConverterPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/DesignConverterPanel.cs
@@ -8,10 +8,11 @@ using ImGuiNET;
using Newtonsoft.Json.Linq;
using OtterGui;
using OtterGui.Raii;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class DesignConverterPanel(DesignConverter _designConverter) : IDebugTabTree
+public class DesignConverterPanel(DesignConverter _designConverter) : IGameDataDrawer
{
public string Label
=> "Design Converter";
diff --git a/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs b/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs
index 8b7ae9a..8f40388 100644
--- a/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs
@@ -6,10 +6,11 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _designFileSystem) : IDebugTabTree
+public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _designFileSystem) : IGameDataDrawer
{
public string Label
=> $"Design Manager ({_designManager.Designs.Count} Designs)###Design Manager";
diff --git a/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs b/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs
index 400b2b1..a4e17ed 100644
--- a/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs
@@ -8,10 +8,11 @@ using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class DesignTesterPanel(ItemManager _items, HumanModelList _humans) : IDebugTabTree
+public class DesignTesterPanel(ItemManager _items, HumanModelList _humans) : IGameDataDrawer
{
public string Label
=> "Base64 Design Tester";
diff --git a/Glamourer/Gui/Tabs/DebugTab/FunPanel.cs b/Glamourer/Gui/Tabs/DebugTab/FunPanel.cs
index 9afc125..c517070 100644
--- a/Glamourer/Gui/Tabs/DebugTab/FunPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/FunPanel.cs
@@ -1,9 +1,10 @@
using Glamourer.State;
using ImGuiNET;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class FunPanel(FunModule _funModule, Configuration _config) : IDebugTabTree
+public class FunPanel(FunModule _funModule, Configuration _config) : IGameDataDrawer
{
public string Label
=> "Fun Module";
diff --git a/Glamourer/Gui/Tabs/DebugTab/IdentifierPanel.cs b/Glamourer/Gui/Tabs/DebugTab/IdentifierPanel.cs
deleted file mode 100644
index 9a0503e..0000000
--- a/Glamourer/Gui/Tabs/DebugTab/IdentifierPanel.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using System.Linq;
-using Dalamud.Interface.Utility;
-using Glamourer.Services;
-using ImGuiNET;
-using OtterGui;
-using Penumbra.GameData.Data;
-using Penumbra.GameData.Enums;
-using Penumbra.GameData.Structs;
-
-namespace Glamourer.Gui.Tabs.DebugTab;
-
-public class IdentifierPanel(ItemManager _items, GamePathParser _gamePathParser) : IDebugTabTree
-{
- public string Label
- => "Identifier Service";
-
- public bool Disabled
- => !_items.ObjectIdentification.Awaiter.IsCompletedSuccessfully;
-
- private string _gamePath = string.Empty;
- private int _setId;
- private int _secondaryId;
- private int _variant;
-
- public void Draw()
- {
- static void Text(string text)
- {
- if (text.Length > 0)
- ImGui.TextUnformatted(text);
- }
-
- ImGui.TextUnformatted("Parse Game Path");
- ImGui.SameLine();
- ImGui.SetNextItemWidth(300 * ImGuiHelpers.GlobalScale);
- ImGui.InputTextWithHint("##gamePath", "Enter game path...", ref _gamePath, 256);
- var fileInfo = _gamePathParser.GetFileInfo(_gamePath);
- ImGui.TextUnformatted(
- $"{fileInfo.ObjectType} {fileInfo.EquipSlot} {fileInfo.PrimaryId} {fileInfo.SecondaryId} {fileInfo.Variant} {fileInfo.BodySlot} {fileInfo.CustomizationType}");
- Text(string.Join("\n", _items.ObjectIdentification.Identify(_gamePath).Keys));
-
- ImGui.Separator();
- ImGui.AlignTextToFramePadding();
- ImGui.TextUnformatted("Identify Model");
- ImGui.SameLine();
- DebugTab.DrawInputModelSet(true, ref _setId, ref _secondaryId, ref _variant);
-
- foreach (var slot in EquipSlotExtensions.EqdpSlots)
- {
- var identified = _items.Identify(slot, (PrimaryId)_setId, 0, (Variant)_variant);
- Text(identified.Name);
- ImGuiUtil.HoverTooltip(string.Join("\n",
- _items.ObjectIdentification.Identify((PrimaryId)_setId, 0, (Variant)_variant, slot)
- .Select(i => $"{i.Name} {i.Id} {i.ItemId} {i.IconId}")));
- }
-
- var weapon = _items.Identify(EquipSlot.MainHand, (PrimaryId)_setId, (SecondaryId)_secondaryId, (Variant)_variant);
- Text(weapon.Name);
- ImGuiUtil.HoverTooltip(string.Join("\n",
- _items.ObjectIdentification.Identify((PrimaryId)_setId, (SecondaryId)_secondaryId, (Variant)_variant, EquipSlot.MainHand)));
- }
-}
diff --git a/Glamourer/Gui/Tabs/DebugTab/InventoryPanel.cs b/Glamourer/Gui/Tabs/DebugTab/InventoryPanel.cs
index 1334f2b..bd447e7 100644
--- a/Glamourer/Gui/Tabs/DebugTab/InventoryPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/InventoryPanel.cs
@@ -2,10 +2,11 @@
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public unsafe class InventoryPanel : IDebugTabTree
+public unsafe class InventoryPanel : IGameDataDrawer
{
public string Label
=> "Inventory";
diff --git a/Glamourer/Gui/Tabs/DebugTab/IpcTesterPanel.cs b/Glamourer/Gui/Tabs/DebugTab/IpcTesterPanel.cs
index 329a2af..9059d53 100644
--- a/Glamourer/Gui/Tabs/DebugTab/IpcTesterPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/IpcTesterPanel.cs
@@ -8,11 +8,12 @@ using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Gui;
+using Penumbra.GameData.Gui.Debug;
using Penumbra.GameData.Structs;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManager _objectManager) : IDebugTabTree
+public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManager _objectManager) : IGameDataDrawer
{
public string Label
=> "IPC Tester";
@@ -137,12 +138,12 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag
}
}
- private unsafe void DrawItemIdInput()
+ private void DrawItemIdInput()
{
var tmp = _customItemId.Id;
- if (ImGui.InputScalar("Custom Item ID", ImGuiDataType.U64, (nint)(&tmp), nint.Zero, nint.Zero))
+ if (ImGuiUtil.InputUlong("Custom Item ID", ref tmp))
_customItemId = (CustomItemId)tmp;
ImGui.SameLine();
- EquipSlotCombo.Draw("Equip Slot", string.Empty, 200 * ImGuiHelpers.GlobalScale, ref _slot);
+ EquipSlotCombo.Draw("Equip Slot", string.Empty, ref _slot);
}
}
diff --git a/Glamourer/Gui/Tabs/DebugTab/ItemManagerPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ItemManagerPanel.cs
deleted file mode 100644
index 9fbc931..0000000
--- a/Glamourer/Gui/Tabs/DebugTab/ItemManagerPanel.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using System.Linq;
-using Glamourer.Services;
-using ImGuiNET;
-using OtterGui.Raii;
-using Penumbra.GameData.Enums;
-
-namespace Glamourer.Gui.Tabs.DebugTab;
-
-public class ItemManagerPanel(ItemManager _items) : IDebugTabTree
-{
- public string Label
- => "Item Manager";
-
- public bool Disabled
- => !_items.ItemData.Awaiter.IsCompletedSuccessfully;
-
- private string _itemFilter = string.Empty;
-
- public void Draw()
- {
- ImRaii.TreeNode($"Default Sword: {_items.DefaultSword.Name} ({_items.DefaultSword.ItemId}) ({_items.DefaultSword.Weapon()})",
- ImGuiTreeNodeFlags.Leaf).Dispose();
- DebugTab.DrawNameTable("All Items (Main)", ref _itemFilter,
- _items.ItemData.AllItems(true).Select(p => (p.Item1.Id,
- $"{p.Item2.Name} ({(p.Item2.SecondaryId == 0 ? p.Item2.Armor().ToString() : p.Item2.Weapon().ToString())})"))
- .OrderBy(p => p.Item1));
- DebugTab.DrawNameTable("All Items (Off)", ref _itemFilter,
- _items.ItemData.AllItems(false).Select(p => (p.Item1.Id,
- $"{p.Item2.Name} ({(p.Item2.SecondaryId == 0 ? p.Item2.Armor().ToString() : p.Item2.Weapon().ToString())})"))
- .OrderBy(p => p.Item1));
- foreach (var type in Enum.GetValues().Skip(1))
- {
- DebugTab.DrawNameTable(type.ToName(), ref _itemFilter,
- _items.ItemData.ByType[type]
- .Select(p => (p.ItemId.Id, $"{p.Name} ({(p.SecondaryId.Id == 0 ? p.Armor().ToString() : p.Weapon().ToString())})")));
- }
- }
-}
diff --git a/Glamourer/Gui/Tabs/DebugTab/ItemUnlockPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ItemUnlockPanel.cs
index 73194c4..efcc664 100644
--- a/Glamourer/Gui/Tabs/DebugTab/ItemUnlockPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/ItemUnlockPanel.cs
@@ -7,11 +7,12 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
using ImGuiClip = OtterGui.ImGuiClip;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class ItemUnlockPanel(ItemUnlockManager _itemUnlocks, ItemManager _items) : IDebugTabTree
+public class ItemUnlockPanel(ItemUnlockManager _itemUnlocks, ItemManager _items) : IGameDataDrawer
{
public string Label
=> "Unlocked Items";
diff --git a/Glamourer/Gui/Tabs/DebugTab/JobPanel.cs b/Glamourer/Gui/Tabs/DebugTab/JobPanel.cs
deleted file mode 100644
index 2318d98..0000000
--- a/Glamourer/Gui/Tabs/DebugTab/JobPanel.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using Glamourer.Interop;
-using ImGuiNET;
-using OtterGui;
-using OtterGui.Raii;
-
-namespace Glamourer.Gui.Tabs.DebugTab;
-
-public class JobPanel(JobService _jobs) : IDebugTabTree
-{
- public string Label
- => "Job Service";
-
- public bool Disabled
- => false;
-
- public void Draw()
- {
- DrawJobs();
- DrawJobGroups();
- DrawValidJobGroups();
- }
-
- private void DrawJobs()
- {
- using var t = ImRaii.TreeNode("Jobs");
- if (!t)
- return;
-
- using var table = ImRaii.Table("##jobs", 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
- if (!table)
- return;
-
- foreach (var (id, job) in _jobs.Jobs)
- {
- ImGuiUtil.DrawTableColumn(id.Id.ToString("D3"));
- ImGuiUtil.DrawTableColumn(job.Name);
- ImGuiUtil.DrawTableColumn(job.Abbreviation);
- }
- }
-
- private void DrawJobGroups()
- {
- using var t = ImRaii.TreeNode("All Job Groups");
- if (!t)
- return;
-
- using var table = ImRaii.Table("##groups", 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
- if (!table)
- return;
-
- foreach (var (group, idx) in _jobs.AllJobGroups.WithIndex())
- {
- ImGuiUtil.DrawTableColumn(idx.ToString("D3"));
- ImGuiUtil.DrawTableColumn(group.Name);
- ImGuiUtil.DrawTableColumn(group.Count.ToString());
- }
- }
-
- private void DrawValidJobGroups()
- {
- using var t = ImRaii.TreeNode("Valid Job Groups");
- if (!t)
- return;
-
- using var table = ImRaii.Table("##groups", 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
- if (!table)
- return;
-
- foreach (var (id, group) in _jobs.JobGroups)
- {
- ImGuiUtil.DrawTableColumn(id.Id.ToString("D3"));
- ImGuiUtil.DrawTableColumn(group.Name);
- ImGuiUtil.DrawTableColumn(group.Count.ToString());
- }
- }
-}
diff --git a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs
index 596476b..c70396c 100644
--- a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs
@@ -7,6 +7,7 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
using Penumbra.GameData.Structs;
namespace Glamourer.Gui.Tabs.DebugTab;
@@ -16,7 +17,7 @@ public unsafe class ModelEvaluationPanel(
VisorService _visorService,
UpdateSlotService _updateSlotService,
ChangeCustomizeService _changeCustomizeService,
- CrestService _crestService) : IDebugTabTree
+ CrestService _crestService) : IGameDataDrawer
{
public string Label
=> "Model Evaluation";
diff --git a/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs b/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs
index ffc4b72..cede0f3 100644
--- a/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs
@@ -12,11 +12,12 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
using ImGuiClip = OtterGui.ImGuiClip;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectManager _objectManager, DesignConverter _designConverter) : IDebugTabTree
+public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectManager _objectManager, DesignConverter _designConverter) : IGameDataDrawer
{
public string Label
=> "NPC Appearance";
diff --git a/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs
index b868140..e90cbda 100644
--- a/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs
@@ -7,10 +7,11 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Actors;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class ObjectManagerPanel(ObjectManager _objectManager, ActorManager _actors) : IDebugTabTree
+public class ObjectManagerPanel(ObjectManager _objectManager, ActorManager _actors) : IGameDataDrawer
{
public string Label
=> "Object Manager";
@@ -33,7 +34,7 @@ public class ObjectManagerPanel(ObjectManager _objectManager, ActorManager _acto
ImGui.TableNextColumn();
ImGuiUtil.DrawTableColumn("World");
- ImGuiUtil.DrawTableColumn(_actors.Awaiter.IsCompletedSuccessfully ? _actors.Data.ToWorldName(_objectManager.World) : "Service Missing");
+ ImGuiUtil.DrawTableColumn(_actors.Finished ? _actors.Data.ToWorldName(_objectManager.World) : "Service Missing");
ImGuiUtil.DrawTableColumn(_objectManager.World.ToString());
ImGuiUtil.DrawTableColumn("Player Character");
diff --git a/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs b/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs
index cf5b92a..641c16a 100644
--- a/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs
@@ -10,11 +10,12 @@ using OtterGui;
using OtterGui.Raii;
using Penumbra.Api.Enums;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
using Penumbra.GameData.Structs;
namespace Glamourer.Gui.Tabs.DebugTab;
-public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItemTooltip _penumbraTooltip) : IDebugTabTree
+public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItemTooltip _penumbraTooltip) : IGameDataDrawer
{
public string Label
=> "Penumbra Interop";
diff --git a/Glamourer/Gui/Tabs/DebugTab/RestrictedGearPanel.cs b/Glamourer/Gui/Tabs/DebugTab/RestrictedGearPanel.cs
deleted file mode 100644
index 0f27eff..0000000
--- a/Glamourer/Gui/Tabs/DebugTab/RestrictedGearPanel.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.Linq;
-using Glamourer.Services;
-using ImGuiNET;
-using Penumbra.GameData.Enums;
-using Penumbra.GameData.Structs;
-
-namespace Glamourer.Gui.Tabs.DebugTab;
-
-public class RestrictedGearPanel(ItemManager _items) : IDebugTabTree
-{
- public string Label
- => "Restricted Gear Service";
-
- public bool Disabled
- => false;
-
- private int _setId;
- private int _secondaryId;
- private int _variant;
-
- public void Draw()
- {
- ImGui.AlignTextToFramePadding();
- ImGui.TextUnformatted("Resolve Model");
- DebugTab.DrawInputModelSet(false, ref _setId, ref _secondaryId, ref _variant);
- foreach (var race in Enum.GetValues().Skip(1))
- {
- ReadOnlySpan genders = [Gender.Male, Gender.Female];
- foreach (var gender in genders)
- {
- foreach (var slot in EquipSlotExtensions.EqdpSlots)
- {
- var (replaced, model) =
- _items.RestrictedGear.ResolveRestricted(new CharacterArmor((PrimaryId)_setId, (Variant)_variant, 0), slot, race, gender);
- if (replaced)
- ImGui.TextUnformatted($"{race.ToName()} - {gender} - {slot.ToName()} resolves to {model}.");
- }
- }
- }
- }
-}
diff --git a/Glamourer/Gui/Tabs/DebugTab/RetainedStatePanel.cs b/Glamourer/Gui/Tabs/DebugTab/RetainedStatePanel.cs
index 68841bc..027c316 100644
--- a/Glamourer/Gui/Tabs/DebugTab/RetainedStatePanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/RetainedStatePanel.cs
@@ -3,10 +3,11 @@ using Glamourer.Interop;
using Glamourer.Interop.Structs;
using Glamourer.State;
using OtterGui.Raii;
+using Penumbra.GameData.Gui.Debug;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class RetainedStatePanel(StateManager _stateManager, ObjectManager _objectManager) : IDebugTabTree
+public class RetainedStatePanel(StateManager _stateManager, ObjectManager _objectManager) : IGameDataDrawer
{
public string Label
=> "Retained States (Inactive Actors)";
diff --git a/Glamourer/Gui/Tabs/DebugTab/StainPanel.cs b/Glamourer/Gui/Tabs/DebugTab/StainPanel.cs
deleted file mode 100644
index 643b6dc..0000000
--- a/Glamourer/Gui/Tabs/DebugTab/StainPanel.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System;
-using System.Numerics;
-using Dalamud.Interface.Utility;
-using Glamourer.Services;
-using ImGuiNET;
-using OtterGui;
-using OtterGui.Raii;
-using ImGuiClip = OtterGui.ImGuiClip;
-
-namespace Glamourer.Gui.Tabs.DebugTab;
-
-public class StainPanel(ItemManager _items) : IDebugTabTree
-{
- public string Label
- => "Stain Service";
-
- public bool Disabled
- => false;
-
- private string _stainFilter = string.Empty;
-
- public void Draw()
- {
- var resetScroll = ImGui.InputTextWithHint("##filter", "Filter...", ref _stainFilter, 256);
- var height = ImGui.GetTextLineHeightWithSpacing() + 2 * ImGui.GetStyle().CellPadding.Y;
- using var table = ImRaii.Table("##table", 4,
- ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.BordersOuter | ImGuiTableFlags.SizingFixedFit,
- new Vector2(-1, 10 * height));
- if (!table)
- return;
-
- if (resetScroll)
- ImGui.SetScrollY(0);
-
- ImGui.TableNextColumn();
- var skips = ImGuiClip.GetNecessarySkips(height);
- ImGui.TableNextRow();
- var remainder = ImGuiClip.FilteredClippedDraw(_items.Stains, skips,
- p => p.Key.Id.ToString().Contains(_stainFilter) || p.Value.Name.Contains(_stainFilter, StringComparison.OrdinalIgnoreCase),
- p =>
- {
- ImGuiUtil.DrawTableColumn(p.Key.Id.ToString("D3"));
- ImGui.TableNextColumn();
- ImGui.GetWindowDrawList().AddRectFilled(ImGui.GetCursorScreenPos(),
- ImGui.GetCursorScreenPos() + new Vector2(ImGui.GetTextLineHeight()),
- p.Value.RgbaColor, 5 * ImGuiHelpers.GlobalScale);
- ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight()));
- ImGuiUtil.DrawTableColumn(p.Value.Name);
- ImGuiUtil.DrawTableColumn($"#{p.Value.R:X2}{p.Value.G:X2}{p.Value.B:X2}{(p.Value.Gloss ? ", Glossy" : string.Empty)}");
- });
- ImGuiClip.DrawEndDummy(remainder, height);
- }
-}
diff --git a/Glamourer/Gui/Tabs/DebugTab/UnlockableItemsPanel.cs b/Glamourer/Gui/Tabs/DebugTab/UnlockableItemsPanel.cs
index e658c99..ecd8d83 100644
--- a/Glamourer/Gui/Tabs/DebugTab/UnlockableItemsPanel.cs
+++ b/Glamourer/Gui/Tabs/DebugTab/UnlockableItemsPanel.cs
@@ -7,11 +7,12 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.Enums;
+using Penumbra.GameData.Gui.Debug;
using ImGuiClip = OtterGui.ImGuiClip;
namespace Glamourer.Gui.Tabs.DebugTab;
-public class UnlockableItemsPanel(ItemUnlockManager _itemUnlocks, ItemManager _items) : IDebugTabTree
+public class UnlockableItemsPanel(ItemUnlockManager _itemUnlocks, ItemManager _items) : IGameDataDrawer
{
public string Label
=> "Unlockable Items";
diff --git a/Glamourer/Services/CustomizeService.cs b/Glamourer/Services/CustomizeService.cs
index 1ed6f07..6eeb9db 100644
--- a/Glamourer/Services/CustomizeService.cs
+++ b/Glamourer/Services/CustomizeService.cs
@@ -22,6 +22,9 @@ public sealed class CustomizeService(
public Task Awaiter { get; }
= Task.WhenAll(humanModels.Awaiter, manager.Awaiter, npcCustomizeSet.Awaiter);
+ public bool Finished
+ => Awaiter.IsCompletedSuccessfully;
+
public (CustomizeArray NewValue, CustomizeFlag Applied, CustomizeFlag Changed) Combine(CustomizeArray oldValues, CustomizeArray newValues,
CustomizeFlag applyWhich, bool allowUnknown)
{
diff --git a/Glamourer/Services/ItemManager.cs b/Glamourer/Services/ItemManager.cs
index 20b97f0..52709c5 100644
--- a/Glamourer/Services/ItemManager.cs
+++ b/Glamourer/Services/ItemManager.cs
@@ -21,14 +21,14 @@ public class ItemManager
public readonly ObjectIdentification ObjectIdentification;
public readonly ExcelSheet ItemSheet;
- public readonly DictStains Stains;
+ public readonly DictStain Stains;
public readonly ItemData ItemData;
public readonly RestrictedGear RestrictedGear;
public readonly EquipItem DefaultSword;
public ItemManager(Configuration config, IDataManager gameData, ObjectIdentification objectIdentification,
- ItemData itemData, DictStains stains, RestrictedGear restrictedGear)
+ ItemData itemData, DictStain stains, RestrictedGear restrictedGear)
{
_config = config;
ItemSheet = gameData.GetExcelSheet()!;
diff --git a/OtterGui b/OtterGui
index 4404d62..bdf053e 160000
--- a/OtterGui
+++ b/OtterGui
@@ -1 +1 @@
-Subproject commit 4404d62b7442daa7e3436dc417364905e3d5cd2f
+Subproject commit bdf053ea9e7ac7b96dcd6aceadff8d92c3050b34
diff --git a/Penumbra.GameData b/Penumbra.GameData
index 4af8775..a7d2d73 160000
--- a/Penumbra.GameData
+++ b/Penumbra.GameData
@@ -1 +1 @@
-Subproject commit 4af8775f0925ff89e6900c8816b03e0ffeb73f6d
+Subproject commit a7d2d73217113eadf02e21865a82deb92ea9eb53