From c0ad4aab510689f01ab07028a87b468003e68baa Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sat, 5 Apr 2025 18:48:39 +0200 Subject: [PATCH] Update for new ActorObjectManager. --- Glamourer/Api/ApiHelpers.cs | 12 +- Glamourer/Api/StateApi.cs | 37 ++-- Glamourer/Automation/AutoDesignApplier.cs | 28 ++- Glamourer/Designs/History/EditorHistory.cs | 2 +- Glamourer/Events/StateChanged.cs | 1 + Glamourer/Events/StateFinalized.cs | 1 + Glamourer/Glamourer.cs | 6 +- Glamourer/Gui/DesignQuickBar.cs | 48 ++-- Glamourer/Gui/PenumbraChangedItemTooltip.cs | 16 +- Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs | 8 +- Glamourer/Gui/Tabs/ActorTab/ActorSelector.cs | 11 +- Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs | 2 +- .../Gui/Tabs/AutomationTab/SetSelector.cs | 26 +-- .../Gui/Tabs/DebugTab/ActiveStatePanel.cs | 14 +- .../DebugTab/AdvancedCustomizationDrawer.cs | 8 +- .../Gui/Tabs/DebugTab/GlamourPlatePanel.cs | 44 ++-- .../Gui/Tabs/DebugTab/ModelEvaluationPanel.cs | 5 +- .../Gui/Tabs/DebugTab/NpcAppearancePanel.cs | 62 +++--- .../Gui/Tabs/DebugTab/ObjectManagerPanel.cs | 61 ++--- .../Gui/Tabs/DebugTab/RetainedStatePanel.cs | 3 +- Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs | 10 +- Glamourer/Gui/Tabs/NpcTab/NpcPanel.cs | 6 +- .../SettingsTab/CollectionOverrideDrawer.cs | 13 +- Glamourer/Interop/ContextMenuService.cs | 15 +- Glamourer/Interop/ObjectManager.cs | 209 ------------------ .../Interop/Penumbra/ModSettingApplier.cs | 3 +- .../Interop/Penumbra/PenumbraAutoRedraw.cs | 8 +- Glamourer/Interop/Structs/ActorData.cs | 47 ---- Glamourer/Services/CommandService.cs | 46 ++-- Glamourer/Services/DesignApplier.cs | 15 +- Glamourer/Services/ServiceManager.cs | 2 + Glamourer/State/FunModule.cs | 39 ++-- Glamourer/State/StateApplier.cs | 8 +- Glamourer/State/StateEditor.cs | 1 + Glamourer/State/StateListener.cs | 21 +- Glamourer/Unlocks/CustomizeUnlockManager.cs | 9 +- OtterGui | 2 +- Penumbra.GameData | 2 +- 38 files changed, 273 insertions(+), 578 deletions(-) delete mode 100644 Glamourer/Interop/ObjectManager.cs delete mode 100644 Glamourer/Interop/Structs/ActorData.cs diff --git a/Glamourer/Api/ApiHelpers.cs b/Glamourer/Api/ApiHelpers.cs index ed58500..238d349 100644 --- a/Glamourer/Api/ApiHelpers.cs +++ b/Glamourer/Api/ApiHelpers.cs @@ -6,12 +6,12 @@ using OtterGui.Log; using OtterGui.Services; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.String; -using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.Api; -public class ApiHelpers(ObjectManager objects, StateManager stateManager, ActorManager actors) : IApiService +public class ApiHelpers(ActorObjectManager objects, StateManager stateManager, ActorManager actors) : IApiService { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] internal IEnumerable FindExistingStates(string actorName) @@ -27,7 +27,7 @@ public class ApiHelpers(ObjectManager objects, StateManager stateManager, ActorM [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] internal GlamourerApiEc FindExistingState(int objectIndex, out ActorState? state) { - var actor = objects[objectIndex]; + var actor = objects.Objects[objectIndex]; var identifier = actor.GetIdentifier(actors); if (!identifier.IsValid) { @@ -42,7 +42,7 @@ public class ApiHelpers(ObjectManager objects, StateManager stateManager, ActorM [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] internal ActorState? FindState(int objectIndex) { - var actor = objects[objectIndex]; + var actor = objects.Objects[objectIndex]; var identifier = actor.GetIdentifier(actors); if (identifier.IsValid && stateManager.GetOrCreate(identifier, actor, out var state)) return state; @@ -73,10 +73,8 @@ public class ApiHelpers(ObjectManager objects, StateManager stateManager, ActorM if (objectName.Length == 0 || !ByteString.FromString(objectName, out var byteString)) return []; - objects.Update(); - return stateManager.Values.Where(state => state.Identifier.Type is IdentifierType.Player && state.Identifier.PlayerName == byteString) - .Concat(objects.Identifiers + .Concat(objects .Where(kvp => kvp.Key is { IsValid: true, Type: IdentifierType.Player } && kvp.Key.PlayerName == byteString) .SelectWhere(kvp => { diff --git a/Glamourer/Api/StateApi.cs b/Glamourer/Api/StateApi.cs index c27abb7..43dc453 100644 --- a/Glamourer/Api/StateApi.cs +++ b/Glamourer/Api/StateApi.cs @@ -4,34 +4,32 @@ using Glamourer.Automation; using Glamourer.Designs; using Glamourer.Designs.History; using Glamourer.Events; -using Glamourer.Interop.Structs; using Glamourer.State; using Newtonsoft.Json.Linq; using OtterGui.Services; using Penumbra.GameData.Interop; -using ObjectManager = Glamourer.Interop.ObjectManager; using StateChanged = Glamourer.Events.StateChanged; namespace Glamourer.Api; public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable { - private readonly ApiHelpers _helpers; - private readonly StateManager _stateManager; - private readonly DesignConverter _converter; - private readonly Configuration _config; - private readonly AutoDesignApplier _autoDesigns; - private readonly ObjectManager _objects; - private readonly StateChanged _stateChanged; - private readonly StateFinalized _stateFinalized; - private readonly GPoseService _gPose; + private readonly ApiHelpers _helpers; + private readonly StateManager _stateManager; + private readonly DesignConverter _converter; + private readonly Configuration _config; + private readonly AutoDesignApplier _autoDesigns; + private readonly ActorObjectManager _objects; + private readonly StateChanged _stateChanged; + private readonly StateFinalized _stateFinalized; + private readonly GPoseService _gPose; public StateApi(ApiHelpers helpers, StateManager stateManager, DesignConverter converter, Configuration config, AutoDesignApplier autoDesigns, - ObjectManager objects, + ActorObjectManager objects, StateChanged stateChanged, StateFinalized stateFinalized, GPoseService gPose) @@ -219,7 +217,7 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable if (!state.CanUnlock(key)) return ApiHelpers.Return(GlamourerApiEc.InvalidKey, args); - RevertToAutomation(_objects[objectIndex], state, key, flags); + RevertToAutomation(_objects.Objects[objectIndex], state, key, flags); return ApiHelpers.Return(GlamourerApiEc.Success, args); } @@ -272,15 +270,9 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable var source = (flags & ApplyFlag.Once) != 0 ? StateSource.IpcManual : StateSource.IpcFixed; switch (flags & (ApplyFlag.Equipment | ApplyFlag.Customization)) { - case ApplyFlag.Equipment: - _stateManager.ResetEquip(state, source, key); - break; - case ApplyFlag.Customization: - _stateManager.ResetCustomize(state, source, key); - break; - case ApplyFlag.Equipment | ApplyFlag.Customization: - _stateManager.ResetState(state, source, key); - break; + case ApplyFlag.Equipment: _stateManager.ResetEquip(state, source, key); break; + case ApplyFlag.Customization: _stateManager.ResetCustomize(state, source, key); break; + case ApplyFlag.Equipment | ApplyFlag.Customization: _stateManager.ResetState(state, source, key); break; } ApiHelpers.Lock(state, key, flags); @@ -288,7 +280,6 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable private GlamourerApiEc RevertToAutomation(ActorState state, uint key, ApplyFlag flags) { - _objects.Update(); if (!_objects.TryGetValue(state.Identifier, out var actors) || !actors.Valid) return GlamourerApiEc.ActorNotFound; diff --git a/Glamourer/Automation/AutoDesignApplier.cs b/Glamourer/Automation/AutoDesignApplier.cs index 545dff7..a61a004 100644 --- a/Glamourer/Automation/AutoDesignApplier.cs +++ b/Glamourer/Automation/AutoDesignApplier.cs @@ -11,29 +11,28 @@ using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; -using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.Automation; public sealed class AutoDesignApplier : IDisposable { - private readonly Configuration _config; - private readonly AutoDesignManager _manager; - private readonly StateManager _state; - private readonly JobService _jobs; - private readonly EquippedGearset _equippedGearset; - private readonly ActorManager _actors; - private readonly AutomationChanged _event; - private readonly ObjectManager _objects; - private readonly WeaponLoading _weapons; - private readonly HumanModelList _humans; - private readonly DesignMerger _designMerger; - private readonly IClientState _clientState; + private readonly Configuration _config; + private readonly AutoDesignManager _manager; + private readonly StateManager _state; + private readonly JobService _jobs; + private readonly EquippedGearset _equippedGearset; + private readonly ActorManager _actors; + private readonly AutomationChanged _event; + private readonly ActorObjectManager _objects; + private readonly WeaponLoading _weapons; + private readonly HumanModelList _humans; + private readonly DesignMerger _designMerger; + private readonly IClientState _clientState; private readonly JobChangeState _jobChangeState; public AutoDesignApplier(Configuration config, AutoDesignManager manager, StateManager state, JobService jobs, ActorManager actors, - AutomationChanged @event, ObjectManager objects, WeaponLoading weapons, HumanModelList humans, IClientState clientState, + AutomationChanged @event, ActorObjectManager objects, WeaponLoading weapons, HumanModelList humans, IClientState clientState, EquippedGearset equippedGearset, DesignMerger designMerger, JobChangeState jobChangeState) { _config = config; @@ -154,7 +153,6 @@ public sealed class AutoDesignApplier : IDisposable if (newSet is not { Enabled: true }) return; - _objects.Update(); foreach (var id in newSet.Identifiers) { if (_objects.TryGetValue(id, out var data)) diff --git a/Glamourer/Designs/History/EditorHistory.cs b/Glamourer/Designs/History/EditorHistory.cs index 6382b94..58bce3d 100644 --- a/Glamourer/Designs/History/EditorHistory.cs +++ b/Glamourer/Designs/History/EditorHistory.cs @@ -1,8 +1,8 @@ using Glamourer.Api.Enums; using Glamourer.Events; -using Glamourer.Interop.Structs; using Glamourer.State; using OtterGui.Services; +using Penumbra.GameData.Interop; namespace Glamourer.Designs.History; diff --git a/Glamourer/Events/StateChanged.cs b/Glamourer/Events/StateChanged.cs index c704195..2bcc6fe 100644 --- a/Glamourer/Events/StateChanged.cs +++ b/Glamourer/Events/StateChanged.cs @@ -3,6 +3,7 @@ using Glamourer.Designs.History; using Glamourer.Interop.Structs; using Glamourer.State; using OtterGui.Classes; +using Penumbra.GameData.Interop; namespace Glamourer.Events; diff --git a/Glamourer/Events/StateFinalized.cs b/Glamourer/Events/StateFinalized.cs index e8548e9..0ccaa8b 100644 --- a/Glamourer/Events/StateFinalized.cs +++ b/Glamourer/Events/StateFinalized.cs @@ -2,6 +2,7 @@ using Glamourer.Api; using Glamourer.Api.Enums; using Glamourer.Interop.Structs; using OtterGui.Classes; +using Penumbra.GameData.Interop; namespace Glamourer.Events; diff --git a/Glamourer/Glamourer.cs b/Glamourer/Glamourer.cs index 9191c4f..1e2a62d 100644 --- a/Glamourer/Glamourer.cs +++ b/Glamourer/Glamourer.cs @@ -6,12 +6,10 @@ using Glamourer.Gui; using Glamourer.Interop; using Glamourer.Services; using Glamourer.State; -using OtterGui; using OtterGui.Classes; using OtterGui.Log; using OtterGui.Services; -using Penumbra.GameData.Enums; -using Penumbra.GameData.Files; +using Penumbra.GameData.Interop; namespace Glamourer; @@ -82,7 +80,7 @@ public class Glamourer : IDalamudPlugin var designManager = _services.GetService(); var autoManager = _services.GetService(); var stateManager = _services.GetService(); - var objectManager = _services.GetService(); + var objectManager = _services.GetService(); var currentPlayer = objectManager.PlayerData.Identifier; var states = stateManager.Where(kvp => objectManager.ContainsKey(kvp.Key)).ToList(); diff --git a/Glamourer/Gui/DesignQuickBar.cs b/Glamourer/Gui/DesignQuickBar.cs index c9ace0c..5112d97 100644 --- a/Glamourer/Gui/DesignQuickBar.cs +++ b/Glamourer/Gui/DesignQuickBar.cs @@ -6,14 +6,13 @@ using Dalamud.Interface.Windowing; using Dalamud.Plugin.Services; using Glamourer.Automation; using Glamourer.Designs; -using Glamourer.Interop; using Glamourer.Interop.Penumbra; -using Glamourer.Interop.Structs; using Glamourer.State; using ImGuiNET; using OtterGui.Classes; using OtterGui.Text; using Penumbra.GameData.Actors; +using Penumbra.GameData.Interop; namespace Glamourer.Gui; @@ -37,21 +36,21 @@ public sealed class DesignQuickBar : Window, IDisposable ? ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoMove : ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoFocusOnAppearing; - private readonly Configuration _config; - private readonly QuickDesignCombo _designCombo; - private readonly StateManager _stateManager; - private readonly AutoDesignApplier _autoDesignApplier; - private readonly ObjectManager _objects; - private readonly PenumbraService _penumbra; - private readonly IKeyState _keyState; - private readonly ImRaii.Style _windowPadding = new(); - private readonly ImRaii.Color _windowColor = new(); - private DateTime _keyboardToggle = DateTime.UnixEpoch; - private int _numButtons; - private readonly StringBuilder _tooltipBuilder = new(512); + private readonly Configuration _config; + private readonly QuickDesignCombo _designCombo; + private readonly StateManager _stateManager; + private readonly AutoDesignApplier _autoDesignApplier; + private readonly ActorObjectManager _objects; + private readonly PenumbraService _penumbra; + private readonly IKeyState _keyState; + private readonly ImRaii.Style _windowPadding = new(); + private readonly ImRaii.Color _windowColor = new(); + private DateTime _keyboardToggle = DateTime.UnixEpoch; + private int _numButtons; + private readonly StringBuilder _tooltipBuilder = new(512); public DesignQuickBar(Configuration config, QuickDesignCombo designCombo, StateManager stateManager, IKeyState keyState, - ObjectManager objects, AutoDesignApplier autoDesignApplier, PenumbraService penumbra) + ActorObjectManager objects, AutoDesignApplier autoDesignApplier, PenumbraService penumbra) : base("Glamourer Quick Bar", ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking) { _config = config; @@ -222,7 +221,8 @@ public sealed class DesignQuickBar : Window, IDisposable } if (available == 0) - _tooltipBuilder.Append("Neither player character nor target are available, have state modified by Glamourer, or their state is locked."); + _tooltipBuilder.Append( + "Neither player character nor target are available, have state modified by Glamourer, or their state is locked."); var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, available); ImGui.SameLine(); @@ -258,9 +258,10 @@ public sealed class DesignQuickBar : Window, IDisposable } if (available == 0) - _tooltipBuilder.Append("Neither player character nor target are available, have state modified by Glamourer, or their state is locked."); + _tooltipBuilder.Append( + "Neither player character nor target are available, have state modified by Glamourer, or their state is locked."); - var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.SyncAlt, buttonSize, available); + var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.SyncAlt, buttonSize, available); ImGui.SameLine(); if (!clicked) return; @@ -300,7 +301,8 @@ public sealed class DesignQuickBar : Window, IDisposable } if (available == 0) - _tooltipBuilder.Append("Neither player character nor target are available, have state modified by Glamourer, or their state is locked."); + _tooltipBuilder.Append( + "Neither player character nor target are available, have state modified by Glamourer, or their state is locked."); var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.Repeat, buttonSize, available); ImGui.SameLine(); @@ -424,7 +426,9 @@ public sealed class DesignQuickBar : Window, IDisposable if (_playerIdentifier.IsValid && _playerData.Valid) { available |= 1; - _tooltipBuilder.Append("Left-Click: Reset all temporary settings applied by Glamourer (manually or through automation) to the collection affecting ") + _tooltipBuilder + .Append( + "Left-Click: Reset all temporary settings applied by Glamourer (manually or through automation) to the collection affecting ") .Append(_playerIdentifier) .Append('.'); } @@ -434,7 +438,9 @@ public sealed class DesignQuickBar : Window, IDisposable if (available != 0) _tooltipBuilder.Append('\n'); available |= 2; - _tooltipBuilder.Append("Right-Click: Reset all temporary settings applied by Glamourer (manually or through automation) to the collection affecting ") + _tooltipBuilder + .Append( + "Right-Click: Reset all temporary settings applied by Glamourer (manually or through automation) to the collection affecting ") .Append(_targetIdentifier) .Append('.'); } diff --git a/Glamourer/Gui/PenumbraChangedItemTooltip.cs b/Glamourer/Gui/PenumbraChangedItemTooltip.cs index cf7e1f3..1723333 100644 --- a/Glamourer/Gui/PenumbraChangedItemTooltip.cs +++ b/Glamourer/Gui/PenumbraChangedItemTooltip.cs @@ -1,6 +1,5 @@ using Glamourer.Designs; using Glamourer.Events; -using Glamourer.Interop; using Glamourer.Interop.Penumbra; using Glamourer.Services; using Glamourer.State; @@ -9,18 +8,19 @@ using OtterGui.Raii; using Penumbra.Api.Enums; using Penumbra.GameData.Data; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Gui; public sealed class PenumbraChangedItemTooltip : IDisposable { - private readonly PenumbraService _penumbra; - private readonly StateManager _stateManager; - private readonly ItemManager _items; - private readonly ObjectManager _objects; - private readonly CustomizeService _customize; - private readonly GPoseService _gpose; + private readonly PenumbraService _penumbra; + private readonly StateManager _stateManager; + private readonly ItemManager _items; + private readonly ActorObjectManager _objects; + private readonly CustomizeService _customize; + private readonly GPoseService _gpose; private readonly EquipItem[] _lastItems = new EquipItem[EquipFlagExtensions.NumEquipFlags / 2]; @@ -33,7 +33,7 @@ public sealed class PenumbraChangedItemTooltip : IDisposable public DateTime LastTooltip { get; private set; } = DateTime.MinValue; public DateTime LastClick { get; private set; } = DateTime.MinValue; - public PenumbraChangedItemTooltip(PenumbraService penumbra, StateManager stateManager, ItemManager items, ObjectManager objects, + public PenumbraChangedItemTooltip(PenumbraService penumbra, StateManager stateManager, ItemManager items, ActorObjectManager objects, CustomizeService customize, GPoseService gpose) { _penumbra = penumbra; diff --git a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs index 0381a17..5419f23 100644 --- a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs +++ b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs @@ -10,7 +10,6 @@ using Glamourer.Gui.Customization; using Glamourer.Gui.Equipment; using Glamourer.Gui.Materials; using Glamourer.Interop; -using Glamourer.Interop.Structs; using Glamourer.State; using ImGuiNET; using OtterGui; @@ -22,7 +21,6 @@ using Penumbra.GameData.Actors; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; using Penumbra.GameData.Interop; -using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.Gui.Tabs.ActorTab; @@ -35,7 +33,7 @@ public class ActorPanel private readonly AutoDesignApplier _autoDesignApplier; private readonly Configuration _config; private readonly DesignConverter _converter; - private readonly ObjectManager _objects; + private readonly ActorObjectManager _objects; private readonly DesignManager _designManager; private readonly ImportService _importService; private readonly ICondition _conditions; @@ -53,7 +51,7 @@ public class ActorPanel AutoDesignApplier autoDesignApplier, Configuration config, DesignConverter converter, - ObjectManager objects, + ActorObjectManager objects, DesignManager designManager, ImportService importService, ICondition conditions, @@ -106,7 +104,7 @@ public class ActorPanel { using var group = ImRaii.Group(); (_identifier, _data) = _selector.Selection; - _lockedRedraw = _identifier.Type is IdentifierType.Special + _lockedRedraw = _identifier.Type is IdentifierType.Special || _objects.IsInLobby || _conditions[ConditionFlag.OccupiedInCutSceneEvent]; (_actorName, _actor) = GetHeaderName(); DrawHeader(); diff --git a/Glamourer/Gui/Tabs/ActorTab/ActorSelector.cs b/Glamourer/Gui/Tabs/ActorTab/ActorSelector.cs index 3269fd2..e46d651 100644 --- a/Glamourer/Gui/Tabs/ActorTab/ActorSelector.cs +++ b/Glamourer/Gui/Tabs/ActorTab/ActorSelector.cs @@ -1,7 +1,4 @@ -using System.Security.AccessControl; -using Dalamud.Interface; -using Glamourer.Interop; -using Glamourer.Interop.Structs; +using Dalamud.Interface; using ImGuiNET; using OtterGui; using OtterGui.Classes; @@ -9,11 +6,12 @@ using OtterGui.Raii; using OtterGui.Text; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Gui.Tabs.ActorTab; -public class ActorSelector(ObjectManager objects, ActorManager actors, EphemeralConfig config) +public class ActorSelector(ActorObjectManager objects, ActorManager actors, EphemeralConfig config) { private ActorIdentifier _identifier = ActorIdentifier.Invalid; @@ -89,11 +87,10 @@ public class ActorSelector(ObjectManager objects, ActorManager actors, Ephemeral if (!child) return; - objects.Update(); _world = new WorldId(objects.Player.Valid ? objects.Player.HomeWorld : (ushort)0); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, _defaultItemSpacing); var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeight()); - var remainder = ImGuiClip.FilteredClippedDraw(objects.Identifiers.Where(p => p.Value.Objects.Any(a => a.Model)), skips, CheckFilter, + var remainder = ImGuiClip.FilteredClippedDraw(objects.Where(p => p.Value.Objects.Any(a => a.Model)), skips, CheckFilter, DrawSelectable); ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeight()); } diff --git a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs index badeaeb..7f576b3 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs @@ -434,7 +434,7 @@ public class SetPanel( if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0)) { _dragIndex = index; - _selector._dragDesignIndex = index; + _selector.DragDesignIndex = index; } } } diff --git a/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs b/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs index 950b735..09ee6aa 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs @@ -2,12 +2,11 @@ using Dalamud.Interface.Utility; using Glamourer.Automation; using Glamourer.Events; -using Glamourer.Interop; using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Raii; -using Penumbra.GameData.Actors; +using Penumbra.GameData.Interop; using Penumbra.String; using ImGuiClip = OtterGui.ImGuiClip; @@ -18,8 +17,7 @@ public class SetSelector : IDisposable private readonly Configuration _config; private readonly AutoDesignManager _manager; private readonly AutomationChanged _event; - private readonly ActorManager _actors; - private readonly ObjectManager _objects; + private readonly ActorObjectManager _objects; private readonly List<(AutoDesignSet, int)> _list = []; public AutoDesignSet? Selection { get; private set; } @@ -38,14 +36,13 @@ public class SetSelector : IDisposable private int _dragIndex = -1; private Action? _endAction; - internal int _dragDesignIndex = -1; + internal int DragDesignIndex = -1; - public SetSelector(AutoDesignManager manager, AutomationChanged @event, Configuration config, ActorManager actors, ObjectManager objects) + public SetSelector(AutoDesignManager manager, AutomationChanged @event, Configuration config, ActorObjectManager objects) { _manager = manager; _event = @event; _config = config; - _actors = actors; _objects = objects; _event.Subscribe(OnAutomationChange, AutomationChanged.Priority.SetSelector); } @@ -94,7 +91,7 @@ public class SetSelector : IDisposable } private LowerString _filter = LowerString.Empty; - private uint _enabledFilter = 0; + private uint _enabledFilter; private float _width; private Vector2 _defaultItemSpacing; private Vector2 _selectableSize; @@ -177,7 +174,6 @@ public class SetSelector : IDisposable UpdateList(); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, _defaultItemSpacing); _selectableSize = new Vector2(0, 2 * ImGui.GetTextLineHeight() + ImGui.GetStyle().ItemSpacing.Y); - _objects.Update(); ImGuiClip.ClippedDraw(_list, DrawSetSelectable, _selectableSize.Y + 2 * ImGui.GetStyle().ItemSpacing.Y); _endAction?.Invoke(); _endAction = null; @@ -186,7 +182,7 @@ public class SetSelector : IDisposable private void DrawSetSelectable((AutoDesignSet Set, int Index) pair) { using var id = ImRaii.PushId(pair.Index); - using (var color = ImRaii.PushColor(ImGuiCol.Text, pair.Set.Enabled ? ColorId.EnabledAutoSet.Value() : ColorId.DisabledAutoSet.Value())) + using (ImRaii.PushColor(ImGuiCol.Text, pair.Set.Enabled ? ColorId.EnabledAutoSet.Value() : ColorId.DisabledAutoSet.Value())) { if (ImGui.Selectable(GetSetName(pair.Set, pair.Index), pair.Set == Selection, ImGuiSelectableFlags.None, _selectableSize)) { @@ -285,9 +281,9 @@ public class SetSelector : IDisposable private void NewSetButton(Vector2 size) { - var id = _actors.GetCurrentPlayer(); + var id = _objects.Actors.GetCurrentPlayer(); if (!id.IsValid) - id = _actors.CreatePlayer(ByteString.FromSpanUnsafe("New Design"u8, true, false, true), ushort.MaxValue); + id = _objects.Actors.CreatePlayer(ByteString.FromSpanUnsafe("New Design"u8, true, false, true), ushort.MaxValue); if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), size, $"Create a new Automatic Design Set for {id}. The associated player can be changed later.", !id.IsValid, true)) _manager.AddDesignSet("New Automation Set", id); @@ -332,15 +328,15 @@ public class SetSelector : IDisposable } else if (ImGuiUtil.IsDropping("DesignDragDrop")) { - if (_dragDesignIndex >= 0) + if (DragDesignIndex >= 0) { - var idx = _dragDesignIndex; + var idx = DragDesignIndex; var setTo = set; var setFrom = Selection!; _endAction = () => _manager.MoveDesignToSet(setFrom, idx, setTo); } - _dragDesignIndex = -1; + DragDesignIndex = -1; } } } diff --git a/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs b/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs index f5fe088..b4bdc2a 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs @@ -1,18 +1,17 @@ using Dalamud.Interface; using Glamourer.GameData; using Glamourer.Designs; -using Glamourer.Interop; -using Glamourer.Interop.Structs; using Glamourer.State; using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Enums; using Penumbra.GameData.Gui.Debug; +using Penumbra.GameData.Interop; namespace Glamourer.Gui.Tabs.DebugTab; -public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectManager) : IGameDataDrawer +public class ActiveStatePanel(StateManager _stateManager, ActorObjectManager _objectManager) : IGameDataDrawer { public string Label => $"Active Actors ({_stateManager.Count})###Active Actors"; @@ -22,8 +21,7 @@ public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectM public void Draw() { - _objectManager.Update(); - foreach (var (identifier, actors) in _objectManager.Identifiers) + foreach (var (identifier, actors) in _objectManager) { if (ImGuiUtil.DrawDisabledButton($"{FontAwesomeIcon.Trash.ToIconString()}##{actors.Label}", new Vector2(ImGui.GetFrameHeight()), string.Empty, !_stateManager.ContainsKey(identifier), true)) @@ -66,13 +64,15 @@ public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectM static string ItemString(in DesignData data, EquipSlot slot) { var item = data.Item(slot); - return $"{item.Name} ({item.Id.ToDiscriminatingString()} {item.PrimaryId.Id}{(item.SecondaryId != 0 ? $"-{item.SecondaryId.Id}" : string.Empty)}-{item.Variant})"; + return + $"{item.Name} ({item.Id.ToDiscriminatingString()} {item.PrimaryId.Id}{(item.SecondaryId != 0 ? $"-{item.SecondaryId.Id}" : string.Empty)}-{item.Variant})"; } static string BonusItemString(in DesignData data, BonusItemFlag slot) { var item = data.BonusItem(slot); - return $"{item.Name} ({item.Id.ToDiscriminatingString()} {item.PrimaryId.Id}{(item.SecondaryId != 0 ? $"-{item.SecondaryId.Id}" : string.Empty)}-{item.Variant})"; + return + $"{item.Name} ({item.Id.ToDiscriminatingString()} {item.PrimaryId.Id}{(item.SecondaryId != 0 ? $"-{item.SecondaryId.Id}" : string.Empty)}-{item.Variant})"; } PrintRow("Model ID", state.BaseData.ModelId, state.ModelData.ModelId, state.Sources[MetaIndex.ModelId]); diff --git a/Glamourer/Gui/Tabs/DebugTab/AdvancedCustomizationDrawer.cs b/Glamourer/Gui/Tabs/DebugTab/AdvancedCustomizationDrawer.cs index 6f6d27a..5a02621 100644 --- a/Glamourer/Gui/Tabs/DebugTab/AdvancedCustomizationDrawer.cs +++ b/Glamourer/Gui/Tabs/DebugTab/AdvancedCustomizationDrawer.cs @@ -1,13 +1,13 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; -using Glamourer.Interop; using ImGuiNET; using OtterGui.Raii; using OtterGui.Text; using Penumbra.GameData.Gui.Debug; +using Penumbra.GameData.Interop; namespace Glamourer.Gui.Tabs.DebugTab; -public unsafe class AdvancedCustomizationDrawer(ObjectManager objects) : IGameDataDrawer +public unsafe class AdvancedCustomizationDrawer(ActorObjectManager objects) : IGameDataDrawer { public string Label => "Advanced Customizations"; @@ -31,8 +31,8 @@ public unsafe class AdvancedCustomizationDrawer(ObjectManager objects) : IGameDa return; } - DrawCBuffer("Customize"u8, model.AsHuman->CustomizeParameterCBuffer, 0); - DrawCBuffer("Decal"u8, model.AsHuman->DecalColorCBuffer, 1); + DrawCBuffer("Customize"u8, model.AsHuman->CustomizeParameterCBuffer, 0); + DrawCBuffer("Decal"u8, model.AsHuman->DecalColorCBuffer, 1); DrawCBuffer("Unk1"u8, *(ConstantBuffer**)((byte*)model.AsHuman + 0xBA0), 2); DrawCBuffer("Unk2"u8, *(ConstantBuffer**)((byte*)model.AsHuman + 0xBA8), 3); } diff --git a/Glamourer/Gui/Tabs/DebugTab/GlamourPlatePanel.cs b/Glamourer/Gui/Tabs/DebugTab/GlamourPlatePanel.cs index 62f93e9..100cc9c 100644 --- a/Glamourer/Gui/Tabs/DebugTab/GlamourPlatePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/GlamourPlatePanel.cs @@ -3,24 +3,25 @@ using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game; using Glamourer.Designs; -using Glamourer.Interop; using Glamourer.Services; using Glamourer.State; using ImGuiNET; using OtterGui; +using OtterGui.Text; using Penumbra.GameData; using Penumbra.GameData.Enums; using Penumbra.GameData.Gui.Debug; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Gui.Tabs.DebugTab; public unsafe class GlamourPlatePanel : IGameDataDrawer { - private readonly DesignManager _design; - private readonly ItemManager _items; - private readonly StateManager _state; - private readonly ObjectManager _objects; + private readonly DesignManager _design; + private readonly ItemManager _items; + private readonly StateManager _state; + private readonly ActorObjectManager _objects; public string Label => "Glamour Plates"; @@ -28,7 +29,8 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer public bool Disabled => false; - public GlamourPlatePanel(IGameInteropProvider interop, ItemManager items, DesignManager design, StateManager state, ObjectManager objects) + public GlamourPlatePanel(IGameInteropProvider interop, ItemManager items, DesignManager design, StateManager state, + ActorObjectManager objects) { _items = items; _design = design; @@ -42,24 +44,24 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer var manager = MirageManager.Instance(); using (ImRaii.Group()) { - ImGui.TextUnformatted("Address:"); - ImGui.TextUnformatted("Number of Glamour Plates:"); - ImGui.TextUnformatted("Glamour Plates Requested:"); - ImGui.TextUnformatted("Glamour Plates Loaded:"); - ImGui.TextUnformatted("Is Applying Glamour Plates:"); + ImUtf8.Text("Address:"u8); + ImUtf8.Text("Number of Glamour Plates:"u8); + ImUtf8.Text("Glamour Plates Requested:"u8); + ImUtf8.Text("Glamour Plates Loaded:"u8); + ImUtf8.Text("Is Applying Glamour Plates:"u8); } ImGui.SameLine(); using (ImRaii.Group()) { - ImGuiUtil.CopyOnClickSelectable($"0x{(ulong)manager:X}"); - ImGui.TextUnformatted(manager == null ? "-" : manager->GlamourPlates.Length.ToString()); - ImGui.TextUnformatted(manager == null ? "-" : manager->GlamourPlatesRequested.ToString()); + ImUtf8.CopyOnClickSelectable($"0x{(ulong)manager:X}"); + ImUtf8.Text(manager == null ? "-" : manager->GlamourPlates.Length.ToString()); + ImUtf8.Text(manager == null ? "-" : manager->GlamourPlatesRequested.ToString()); ImGui.SameLine(); - if (ImGui.SmallButton("Request Update")) + if (ImUtf8.SmallButton("Request Update"u8)) RequestGlamour(); - ImGui.TextUnformatted(manager == null ? "-" : manager->GlamourPlatesLoaded.ToString()); - ImGui.TextUnformatted(manager == null ? "-" : manager->IsApplyingGlamourPlate.ToString()); + ImUtf8.Text(manager == null ? "-" : manager->GlamourPlatesLoaded.ToString()); + ImUtf8.Text(manager == null ? "-" : manager->IsApplyingGlamourPlate.ToString()); } if (manager == null) @@ -71,12 +73,12 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer for (var i = 0; i < manager->GlamourPlates.Length; ++i) { - using var tree = ImRaii.TreeNode($"Plate #{i + 1:D2}"); + using var tree = ImUtf8.TreeNode($"Plate #{i + 1:D2}"); if (!tree) continue; ref var plate = ref manager->GlamourPlates[i]; - if (ImGuiUtil.DrawDisabledButton("Apply to Player", Vector2.Zero, string.Empty, !enabled)) + if (ImUtf8.ButtonEx("Apply to Player"u8, ""u8, Vector2.Zero, !enabled)) { var design = CreateDesign(plate); _state.ApplyDesign(state!, design, ApplySettings.Manual with { IsFinal = true }); @@ -85,14 +87,14 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer using (ImRaii.Group()) { foreach (var slot in EquipSlotExtensions.FullSlots) - ImGui.TextUnformatted(slot.ToName()); + ImUtf8.Text(slot.ToName()); } ImGui.SameLine(); using (ImRaii.Group()) { foreach (var (_, index) in EquipSlotExtensions.FullSlots.WithIndex()) - ImGui.TextUnformatted($"{plate.ItemIds[index]:D6}, {StainIds.FromGlamourPlate(plate, index)}"); + ImUtf8.Text($"{plate.ItemIds[index]:D6}, {StainIds.FromGlamourPlate(plate, index)}"); } } } diff --git a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs index c1b5847..fc4799f 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs @@ -11,12 +11,11 @@ using Penumbra.GameData.Enums; using Penumbra.GameData.Gui.Debug; using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; -using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.Gui.Tabs.DebugTab; public unsafe class ModelEvaluationPanel( - ObjectManager _objectManager, + ActorObjectManager _objectManager, VisorService _visorService, UpdateSlotService _updateSlotService, ChangeCustomizeService _changeCustomizeService, @@ -34,7 +33,7 @@ public unsafe class ModelEvaluationPanel( public void Draw() { ImGui.InputInt("Game Object Index", ref _gameObjectIndex, 0, 0); - var actor = _objectManager[_gameObjectIndex]; + var actor = _objectManager.Objects[_gameObjectIndex]; var model = actor.Model; using var table = ImRaii.Table("##evaluationTable", 4, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg); ImGui.TableNextColumn(); diff --git a/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs b/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs index 04537b5..966bc6f 100644 --- a/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs @@ -3,18 +3,18 @@ using Dalamud.Interface.Utility; using FFXIVClientStructs.FFXIV.Client.Game.Object; using Glamourer.Designs; using Glamourer.GameData; -using Glamourer.Interop; using Glamourer.State; using ImGuiNET; -using OtterGui; using OtterGui.Raii; +using OtterGui.Text; using Penumbra.GameData.Enums; using Penumbra.GameData.Gui.Debug; +using Penumbra.GameData.Interop; using ImGuiClip = OtterGui.ImGuiClip; namespace Glamourer.Gui.Tabs.DebugTab; -public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectManager _objectManager, DesignConverter _designConverter) +public class NpcAppearancePanel(NpcCombo npcCombo, StateManager stateManager, ActorObjectManager objectManager, DesignConverter designConverter) : IGameDataDrawer { public string Label @@ -28,9 +28,9 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM public void Draw() { - ImGui.Checkbox("Compare Customize (or Gear)", ref _customizeOrGear); + ImUtf8.Checkbox("Compare Customize (or Gear)"u8, ref _customizeOrGear); ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); - var resetScroll = ImGui.InputTextWithHint("##npcFilter", "Filter...", ref _npcFilter, 64); + var resetScroll = ImUtf8.InputText("##npcFilter"u8, ref _npcFilter, "Filter..."u8); using var table = ImRaii.Table("npcs", 7, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit, new Vector2(-1, 400 * ImGuiHelpers.GlobalScale)); @@ -40,19 +40,19 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM if (resetScroll) ImGui.SetScrollY(0); - ImGui.TableSetupColumn("Button", ImGuiTableColumnFlags.WidthFixed); - ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthFixed, ImGuiHelpers.GlobalScale * 300); - ImGui.TableSetupColumn("Kind", ImGuiTableColumnFlags.WidthFixed); - ImGui.TableSetupColumn("Id", ImGuiTableColumnFlags.WidthFixed); - ImGui.TableSetupColumn("Model", ImGuiTableColumnFlags.WidthFixed); - ImGui.TableSetupColumn("Visor", ImGuiTableColumnFlags.WidthFixed); - ImGui.TableSetupColumn("Compare", ImGuiTableColumnFlags.WidthStretch); + ImUtf8.TableSetupColumn("Button"u8, ImGuiTableColumnFlags.WidthFixed); + ImUtf8.TableSetupColumn("Name"u8, ImGuiTableColumnFlags.WidthFixed, ImGuiHelpers.GlobalScale * 300); + ImUtf8.TableSetupColumn("Kind"u8, ImGuiTableColumnFlags.WidthFixed); + ImUtf8.TableSetupColumn("Id"u8, ImGuiTableColumnFlags.WidthFixed); + ImUtf8.TableSetupColumn("Model"u8, ImGuiTableColumnFlags.WidthFixed); + ImUtf8.TableSetupColumn("Visor"u8, ImGuiTableColumnFlags.WidthFixed); + ImUtf8.TableSetupColumn("Compare"u8, ImGuiTableColumnFlags.WidthStretch); ImGui.TableNextColumn(); var skips = ImGuiClip.GetNecessarySkips(ImGui.GetFrameHeightWithSpacing()); ImGui.TableNextRow(); var idx = 0; - var remainder = ImGuiClip.FilteredClippedDraw(_npcCombo.Items, skips, + var remainder = ImGuiClip.FilteredClippedDraw(npcCombo.Items, skips, d => d.Name.Contains(_npcFilter, StringComparison.OrdinalIgnoreCase), DrawData); ImGui.TableNextColumn(); ImGuiClip.DrawEndDummy(remainder, ImGui.GetFrameHeightWithSpacing()); @@ -61,43 +61,31 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM void DrawData(NpcData data) { using var id = ImRaii.PushId(idx++); - var disabled = !_state.GetOrCreate(_objectManager.Player, out var state); + var disabled = !stateManager.GetOrCreate(objectManager.Player, out var state); ImGui.TableNextColumn(); - if (ImGuiUtil.DrawDisabledButton("Apply", Vector2.Zero, string.Empty, disabled)) + if (ImUtf8.ButtonEx("Apply"u8, ""u8, Vector2.Zero, disabled)) { - foreach (var (slot, item, stain) in _designConverter.FromDrawData(data.Equip.ToArray(), data.Mainhand, data.Offhand, true)) - _state.ChangeEquip(state!, slot, item, stain, ApplySettings.Manual); - _state.ChangeMetaState(state!, MetaIndex.VisorState, data.VisorToggled, ApplySettings.Manual); - _state.ChangeEntireCustomize(state!, data.Customize, CustomizeFlagExtensions.All, ApplySettings.Manual); + foreach (var (slot, item, stain) in designConverter.FromDrawData(data.Equip.ToArray(), data.Mainhand, data.Offhand, true)) + stateManager.ChangeEquip(state!, slot, item, stain, ApplySettings.Manual); + stateManager.ChangeMetaState(state!, MetaIndex.VisorState, data.VisorToggled, ApplySettings.Manual); + stateManager.ChangeEntireCustomize(state!, data.Customize, CustomizeFlagExtensions.All, ApplySettings.Manual); } - ImGui.TableNextColumn(); - ImGui.AlignTextToFramePadding(); - ImGui.TextUnformatted(data.Name); + ImUtf8.DrawFrameColumn(data.Name); - ImGui.TableNextColumn(); - ImGui.AlignTextToFramePadding(); - ImGui.TextUnformatted(data.Kind is ObjectKind.BattleNpc ? "B" : "E"); + ImUtf8.DrawFrameColumn(data.Kind is ObjectKind.BattleNpc ? "B" : "E"); - ImGui.TableNextColumn(); - ImGui.AlignTextToFramePadding(); - ImGui.TextUnformatted(data.Id.Id.ToString()); + ImUtf8.DrawFrameColumn(data.Id.Id.ToString()); - ImGui.TableNextColumn(); - ImGui.AlignTextToFramePadding(); - ImGui.TextUnformatted(data.ModelId.ToString()); + ImUtf8.DrawFrameColumn(data.ModelId.ToString()); using (_ = ImRaii.PushFont(UiBuilder.IconFont)) { - ImGui.TableNextColumn(); - ImGui.AlignTextToFramePadding(); - ImGui.TextUnformatted(data.VisorToggled ? FontAwesomeIcon.Check.ToIconString() : FontAwesomeIcon.Times.ToIconString()); + ImUtf8.DrawFrameColumn(data.VisorToggled ? FontAwesomeIcon.Check.ToIconString() : FontAwesomeIcon.Times.ToIconString()); } using var mono = ImRaii.PushFont(UiBuilder.MonoFont); - ImGui.TableNextColumn(); - ImGui.AlignTextToFramePadding(); - ImGui.TextUnformatted(_customizeOrGear ? data.Customize.ToString() : data.WriteGear()); + ImUtf8.DrawFrameColumn(_customizeOrGear ? data.Customize.ToString() : data.WriteGear()); } } } diff --git a/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs index e519ea5..a4d1224 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs @@ -1,13 +1,13 @@ -using Glamourer.Interop; -using ImGuiNET; +using ImGuiNET; using OtterGui; -using OtterGui.Raii; +using OtterGui.Text; using Penumbra.GameData.Actors; using Penumbra.GameData.Gui.Debug; +using Penumbra.GameData.Interop; namespace Glamourer.Gui.Tabs.DebugTab; -public class ObjectManagerPanel(ObjectManager _objectManager, ActorManager _actors) : IGameDataDrawer +public class ObjectManagerPanel(ActorObjectManager _objectManager, ActorManager _actors) : IGameDataDrawer { public string Label => "Object Manager"; @@ -19,44 +19,45 @@ public class ObjectManagerPanel(ObjectManager _objectManager, ActorManager _acto public void Draw() { - _objectManager.Update(); - using (var table = ImRaii.Table("##data", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit)) + _objectManager.Objects.DrawDebug(); + + using (var table = ImUtf8.Table("##data"u8, 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit)) { if (!table) return; - ImGuiUtil.DrawTableColumn("Last Update"); - ImGuiUtil.DrawTableColumn(_objectManager.LastUpdate.ToString(CultureInfo.InvariantCulture)); + ImUtf8.DrawTableColumn("World"u8); + ImUtf8.DrawTableColumn(_actors.Finished ? _actors.Data.ToWorldName(_objectManager.World) : "Service Missing"); + ImUtf8.DrawTableColumn(_objectManager.World.ToString()); + + ImUtf8.DrawTableColumn("Player Character"u8); + ImUtf8.DrawTableColumn($"{_objectManager.Player.Utf8Name} ({_objectManager.Player.Index})"); + ImGui.TableNextColumn(); + ImUtf8.CopyOnClickSelectable(_objectManager.Player.ToString()); + + ImUtf8.DrawTableColumn("In GPose"u8); + ImUtf8.DrawTableColumn(_objectManager.IsInGPose.ToString()); ImGui.TableNextColumn(); - ImGuiUtil.DrawTableColumn("World"); - ImGuiUtil.DrawTableColumn(_actors.Finished ? _actors.Data.ToWorldName(_objectManager.World) : "Service Missing"); - ImGuiUtil.DrawTableColumn(_objectManager.World.ToString()); - - ImGuiUtil.DrawTableColumn("Player Character"); - ImGuiUtil.DrawTableColumn($"{_objectManager.Player.Utf8Name} ({_objectManager.Player.Index})"); - ImGui.TableNextColumn(); - ImGuiUtil.CopyOnClickSelectable(_objectManager.Player.ToString()); - - ImGuiUtil.DrawTableColumn("In GPose"); - ImGuiUtil.DrawTableColumn(_objectManager.IsInGPose.ToString()); + ImUtf8.DrawTableColumn("In Lobby"u8); + ImUtf8.DrawTableColumn(_objectManager.IsInLobby.ToString()); ImGui.TableNextColumn(); if (_objectManager.IsInGPose) { - ImGuiUtil.DrawTableColumn("GPose Player"); - ImGuiUtil.DrawTableColumn($"{_objectManager.GPosePlayer.Utf8Name} ({_objectManager.GPosePlayer.Index})"); + ImUtf8.DrawTableColumn("GPose Player"u8); + ImUtf8.DrawTableColumn($"{_objectManager.GPosePlayer.Utf8Name} ({_objectManager.GPosePlayer.Index})"); ImGui.TableNextColumn(); - ImGuiUtil.CopyOnClickSelectable(_objectManager.GPosePlayer.ToString()); + ImUtf8.CopyOnClickSelectable(_objectManager.GPosePlayer.ToString()); } - ImGuiUtil.DrawTableColumn("Number of Players"); - ImGuiUtil.DrawTableColumn(_objectManager.Count.ToString()); + ImUtf8.DrawTableColumn("Number of Players"u8); + ImUtf8.DrawTableColumn(_objectManager.Count.ToString()); ImGui.TableNextColumn(); } - var filterChanged = ImGui.InputTextWithHint("##Filter", "Filter...", ref _objectFilter, 64); - using var table2 = ImRaii.Table("##data2", 3, + var filterChanged = ImUtf8.InputText("##Filter"u8, ref _objectFilter, "Filter..."u8); + using var table2 = ImUtf8.Table("##data2"u8, 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersOuter | ImGuiTableFlags.ScrollY, new Vector2(-1, 20 * ImGui.GetTextLineHeightWithSpacing())); if (!table2) @@ -69,13 +70,13 @@ public class ObjectManagerPanel(ObjectManager _objectManager, ActorManager _acto var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeightWithSpacing()); ImGui.TableNextRow(); - var remainder = ImGuiClip.FilteredClippedDraw(_objectManager.Identifiers, skips, + var remainder = ImGuiClip.FilteredClippedDraw(_objectManager, skips, p => p.Value.Label.Contains(_objectFilter, StringComparison.OrdinalIgnoreCase), p => { - ImGuiUtil.DrawTableColumn(p.Key.ToString()); - ImGuiUtil.DrawTableColumn(p.Value.Label); - ImGuiUtil.DrawTableColumn(string.Join(", ", p.Value.Objects.OrderBy(a => a.Index).Select(a => a.Index.ToString()))); + ImUtf8.DrawTableColumn(p.Key.ToString()); + ImUtf8.DrawTableColumn(p.Value.Label); + ImUtf8.DrawTableColumn(string.Join(", ", p.Value.Objects.OrderBy(a => a.Index).Select(a => a.Index.ToString()))); }); ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeightWithSpacing()); } diff --git a/Glamourer/Gui/Tabs/DebugTab/RetainedStatePanel.cs b/Glamourer/Gui/Tabs/DebugTab/RetainedStatePanel.cs index 2abc1db..21f0c50 100644 --- a/Glamourer/Gui/Tabs/DebugTab/RetainedStatePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/RetainedStatePanel.cs @@ -3,10 +3,11 @@ using Glamourer.Interop.Structs; using Glamourer.State; using OtterGui.Raii; using Penumbra.GameData.Gui.Debug; +using Penumbra.GameData.Interop; namespace Glamourer.Gui.Tabs.DebugTab; -public class RetainedStatePanel(StateManager _stateManager, ObjectManager _objectManager) : IGameDataDrawer +public class RetainedStatePanel(StateManager _stateManager, ActorObjectManager _objectManager) : IGameDataDrawer { public string Label => "Retained States (Inactive Actors)"; diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs b/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs index 3543b68..65014a4 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs @@ -18,6 +18,7 @@ using OtterGui.Classes; using OtterGui.Raii; using OtterGui.Text; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using static Glamourer.Gui.Tabs.HeaderDrawer; namespace Glamourer.Gui.Tabs.DesignTab; @@ -28,7 +29,7 @@ public class DesignPanel private readonly DesignFileSystemSelector _selector; private readonly CustomizationDrawer _customizationDrawer; private readonly DesignManager _manager; - private readonly ObjectManager _objects; + private readonly ActorObjectManager _objects; private readonly StateManager _state; private readonly EquipmentDrawer _equipmentDrawer; private readonly ModAssociationsTab _modAssociations; @@ -48,7 +49,7 @@ public class DesignPanel public DesignPanel(DesignFileSystemSelector selector, CustomizationDrawer customizationDrawer, DesignManager manager, - ObjectManager objects, + ActorObjectManager objects, StateManager state, EquipmentDrawer equipmentDrawer, ModAssociationsTab modAssociations, @@ -360,6 +361,7 @@ public class DesignPanel equip = false; customize = true; } + if (!enabled) ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {_config.DeleteDesignModifier} while clicking."); @@ -371,6 +373,7 @@ public class DesignPanel _manager.ChangeApplyMulti(_selector.Selected!, true, true, true, false, true, true, false, true); _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.Wetness, false); } + if (!enabled) ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {_config.DeleteDesignModifier} while clicking."); @@ -386,7 +389,8 @@ public class DesignPanel if (equip is null && customize is null) return; - _manager.ChangeApplyMulti(_selector.Selected!, equip, customize, equip, customize.HasValue && !customize.Value ? false : null, null, equip, equip, equip); + _manager.ChangeApplyMulti(_selector.Selected!, equip, customize, equip, customize.HasValue && !customize.Value ? false : null, null, + equip, equip, equip); if (equip.HasValue) { _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.HatState, equip.Value); diff --git a/Glamourer/Gui/Tabs/NpcTab/NpcPanel.cs b/Glamourer/Gui/Tabs/NpcTab/NpcPanel.cs index 1151e86..c6166a3 100644 --- a/Glamourer/Gui/Tabs/NpcTab/NpcPanel.cs +++ b/Glamourer/Gui/Tabs/NpcTab/NpcPanel.cs @@ -5,7 +5,6 @@ using Glamourer.Designs; using Glamourer.Gui.Customization; using Glamourer.Gui.Equipment; using Glamourer.Gui.Tabs.DesignTab; -using Glamourer.Interop; using Glamourer.State; using ImGuiNET; using OtterGui; @@ -13,6 +12,7 @@ using OtterGui.Classes; using OtterGui.Raii; using OtterGui.Text; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using static Glamourer.Gui.Tabs.HeaderDrawer; namespace Glamourer.Gui.Tabs.NpcTab; @@ -30,7 +30,7 @@ public class NpcPanel private readonly DesignConverter _converter; private readonly DesignManager _designManager; private readonly StateManager _state; - private readonly ObjectManager _objects; + private readonly ActorObjectManager _objects; private readonly DesignColors _colors; private readonly Button[] _leftButtons; private readonly Button[] _rightButtons; @@ -42,7 +42,7 @@ public class NpcPanel DesignConverter converter, DesignManager designManager, StateManager state, - ObjectManager objects, + ActorObjectManager objects, DesignColors colors, Configuration config) { diff --git a/Glamourer/Gui/Tabs/SettingsTab/CollectionOverrideDrawer.cs b/Glamourer/Gui/Tabs/SettingsTab/CollectionOverrideDrawer.cs index d976d28..87490db 100644 --- a/Glamourer/Gui/Tabs/SettingsTab/CollectionOverrideDrawer.cs +++ b/Glamourer/Gui/Tabs/SettingsTab/CollectionOverrideDrawer.cs @@ -6,14 +6,14 @@ using OtterGui; using OtterGui.Raii; using OtterGui.Services; using Penumbra.GameData.Actors; -using ObjectManager = Glamourer.Interop.ObjectManager; +using Penumbra.GameData.Interop; namespace Glamourer.Gui.Tabs.SettingsTab; public class CollectionOverrideDrawer( CollectionOverrideService collectionOverrides, Configuration config, - ObjectManager objects, + ActorObjectManager objects, ActorManager actors, PenumbraService penumbra, CollectionCombo combo) : IService @@ -61,7 +61,8 @@ public class CollectionOverrideDrawer( DrawActorIdentifier(idx, actor); ImGui.TableNextColumn(); - if (combo.Draw("##collection", name, $"Select the overriding collection. Current GUID:", ImGui.GetContentRegionAvail().X, ImGui.GetTextLineHeight())) + if (combo.Draw("##collection", name, $"Select the overriding collection. Current GUID:", ImGui.GetContentRegionAvail().X, + ImGui.GetTextLineHeight())) { var (guid, _, newName) = combo.CurrentSelection; collectionOverrides.ChangeOverride(idx, guid, newName); @@ -69,7 +70,7 @@ public class CollectionOverrideDrawer( if (ImGui.IsItemHovered()) { - using var tt = ImRaii.Tooltip(); + using var tt = ImRaii.Tooltip(); using var font = ImRaii.PushFont(UiBuilder.MonoFont); ImGui.TextUnformatted($" {collection}"); } @@ -102,7 +103,7 @@ public class CollectionOverrideDrawer( return; using var tt2 = ImRaii.Tooltip(); - using var f = ImRaii.PushFont(UiBuilder.MonoFont); + using var f = ImRaii.PushFont(UiBuilder.MonoFont); ImGui.TextUnformatted(collection.ToString()); } @@ -146,7 +147,7 @@ public class CollectionOverrideDrawer( } catch (ActorIdentifierFactory.IdentifierParseError e) { - _exception = e; + _exception = e; _identifiers = []; } diff --git a/Glamourer/Interop/ContextMenuService.cs b/Glamourer/Interop/ContextMenuService.cs index 71a9280..1f85612 100644 --- a/Glamourer/Interop/ContextMenuService.cs +++ b/Glamourer/Interop/ContextMenuService.cs @@ -5,6 +5,7 @@ using Glamourer.Designs; using Glamourer.Services; using Glamourer.State; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Interop; @@ -13,16 +14,16 @@ public class ContextMenuService : IDisposable { public const int ChatLogContextItemId = 0x958; - private readonly ItemManager _items; - private readonly IContextMenu _contextMenu; - private readonly StateManager _state; - private readonly ObjectManager _objects; - private EquipItem _lastItem; - private readonly StainId[] _lastStains = new StainId[StainId.NumStains]; + private readonly ItemManager _items; + private readonly IContextMenu _contextMenu; + private readonly StateManager _state; + private readonly ActorObjectManager _objects; + private EquipItem _lastItem; + private readonly StainId[] _lastStains = new StainId[StainId.NumStains]; private readonly MenuItem _inventoryItem; - public ContextMenuService(ItemManager items, StateManager state, ObjectManager objects, Configuration config, + public ContextMenuService(ItemManager items, StateManager state, ActorObjectManager objects, Configuration config, IContextMenu context) { _contextMenu = context; diff --git a/Glamourer/Interop/ObjectManager.cs b/Glamourer/Interop/ObjectManager.cs deleted file mode 100644 index 471a49b..0000000 --- a/Glamourer/Interop/ObjectManager.cs +++ /dev/null @@ -1,209 +0,0 @@ -using Dalamud.Game.ClientState.Objects; -using Dalamud.Plugin; -using Dalamud.Plugin.Services; -using FFXIVClientStructs.FFXIV.Client.Game.Control; -using Glamourer.Events; -using Glamourer.Interop.Structs; -using OtterGui.Log; -using Penumbra.GameData.Actors; -using Penumbra.GameData.Enums; -using Penumbra.GameData.Interop; - -namespace Glamourer.Interop; - -public class ObjectManager( - IFramework framework, - IClientState clientState, - IObjectTable objects, - IDalamudPluginInterface pi, - Logger log, - ActorManager actors, - ITargetManager targets) - : global::Penumbra.GameData.Interop.ObjectManager(pi, log, framework, objects) -{ - public DateTime LastUpdate - => LastFrame; - - private DateTime _identifierUpdate; - - public bool IsInGPose - => clientState.IsGPosing; - - public ushort World { get; private set; } - - private readonly Dictionary _identifiers = new(200); - private readonly Dictionary _allWorldIdentifiers = new(200); - private readonly Dictionary _nonOwnedIdentifiers = new(200); - - public IReadOnlyDictionary Identifiers - => _identifiers; - - public override bool Update() - { - if (!base.Update() && _identifierUpdate >= LastUpdate) - return false; - - _identifierUpdate = LastUpdate; - World = (ushort)(Player.Valid ? Player.HomeWorld : 0); - _identifiers.Clear(); - _allWorldIdentifiers.Clear(); - _nonOwnedIdentifiers.Clear(); - - foreach (var actor in BattleNpcs.Concat(CutsceneCharacters)) - { - if (actor.Identifier(actors, out var identifier)) - HandleIdentifier(identifier, actor); - } - - void AddSpecial(ScreenActor idx, string label) - { - var actor = this[(int)idx]; - if (actor.Identifier(actors, out var ident)) - { - var data = new ActorData(actor, label); - _identifiers.Add(ident, data); - } - } - - AddSpecial(ScreenActor.CharacterScreen, "Character Screen Actor"); - AddSpecial(ScreenActor.ExamineScreen, "Examine Screen Actor"); - AddSpecial(ScreenActor.FittingRoom, "Fitting Room Actor"); - AddSpecial(ScreenActor.DyePreview, "Dye Preview Actor"); - AddSpecial(ScreenActor.Portrait, "Portrait Actor"); - AddSpecial(ScreenActor.Card6, "Card Actor 6"); - AddSpecial(ScreenActor.Card7, "Card Actor 7"); - AddSpecial(ScreenActor.Card8, "Card Actor 8"); - - foreach (var actor in EventNpcs) - { - if (actor.Identifier(actors, out var identifier)) - HandleIdentifier(identifier, actor); - } - - return true; - } - - private void HandleIdentifier(ActorIdentifier identifier, Actor character) - { - if (!identifier.IsValid) - return; - - if (!_identifiers.TryGetValue(identifier, out var data)) - { - data = new ActorData(character, identifier.ToString()); - _identifiers[identifier] = data; - } - else - { - data.Objects.Add(character); - } - - if (identifier.Type is IdentifierType.Player or IdentifierType.Owned) - { - var allWorld = actors.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, ushort.MaxValue, - identifier.Kind, - identifier.DataId); - - if (!_allWorldIdentifiers.TryGetValue(allWorld, out var allWorldData)) - { - allWorldData = new ActorData(character, allWorld.ToString()); - _allWorldIdentifiers[allWorld] = allWorldData; - } - else - { - allWorldData.Objects.Add(character); - } - } - - if (identifier.Type is IdentifierType.Owned) - { - var nonOwned = actors.CreateNpc(identifier.Kind, identifier.DataId); - if (!_nonOwnedIdentifiers.TryGetValue(nonOwned, out var nonOwnedData)) - { - nonOwnedData = new ActorData(character, nonOwned.ToString()); - _nonOwnedIdentifiers[nonOwned] = nonOwnedData; - } - else - { - nonOwnedData.Objects.Add(character); - } - } - } - - public Actor GPosePlayer - => this[(int)ScreenActor.GPosePlayer]; - - public Actor Player - => this[0]; - - public unsafe Actor Target - => clientState.IsGPosing ? TargetSystem.Instance()->GPoseTarget : TargetSystem.Instance()->Target; - - public Actor Focus - => targets.FocusTarget?.Address ?? nint.Zero; - - public Actor MouseOver - => targets.MouseOverTarget?.Address ?? nint.Zero; - - public (ActorIdentifier Identifier, ActorData Data) PlayerData - { - get - { - Update(); - return Player.Identifier(actors, out var ident) && _identifiers.TryGetValue(ident, out var data) - ? (ident, data) - : (ident, ActorData.Invalid); - } - } - - public (ActorIdentifier Identifier, ActorData Data) TargetData - { - get - { - Update(); - return Target.Identifier(actors, out var ident) && _identifiers.TryGetValue(ident, out var data) - ? (ident, data) - : (ident, ActorData.Invalid); - } - } - - /// Also handles All Worlds players and non-owned NPCs. - public bool ContainsKey(ActorIdentifier key) - => Identifiers.ContainsKey(key) || _allWorldIdentifiers.ContainsKey(key) || _nonOwnedIdentifiers.ContainsKey(key); - - public bool TryGetValue(ActorIdentifier key, out ActorData value) - => Identifiers.TryGetValue(key, out value); - - public bool TryGetValueAllWorld(ActorIdentifier key, out ActorData value) - => _allWorldIdentifiers.TryGetValue(key, out value); - - public bool TryGetValueNonOwned(ActorIdentifier key, out ActorData value) - => _nonOwnedIdentifiers.TryGetValue(key, out value); - - public ActorData this[ActorIdentifier key] - => Identifiers[key]; - - public IEnumerable Keys - => Identifiers.Keys; - - public IEnumerable Values - => Identifiers.Values; - - public bool GetName(string lowerName, out Actor actor) - { - (actor, var ret) = lowerName switch - { - "" => (Actor.Null, true), - "" => (Player, true), - "self" => (Player, true), - "" => (Target, true), - "target" => (Target, true), - "" => (Focus, true), - "focus" => (Focus, true), - "" => (MouseOver, true), - "mouseover" => (MouseOver, true), - _ => (Actor.Null, false), - }; - return ret; - } -} diff --git a/Glamourer/Interop/Penumbra/ModSettingApplier.cs b/Glamourer/Interop/Penumbra/ModSettingApplier.cs index 1d39f79..b94be09 100644 --- a/Glamourer/Interop/Penumbra/ModSettingApplier.cs +++ b/Glamourer/Interop/Penumbra/ModSettingApplier.cs @@ -7,7 +7,7 @@ using Penumbra.GameData.Structs; namespace Glamourer.Interop.Penumbra; -public class ModSettingApplier(PenumbraService penumbra, PenumbraAutoRedrawSkip autoRedrawSkip, Configuration config, ObjectManager objects, CollectionOverrideService overrides) +public class ModSettingApplier(PenumbraService penumbra, PenumbraAutoRedrawSkip autoRedrawSkip, Configuration config, ActorObjectManager objects, CollectionOverrideService overrides) : IService { private readonly HashSet _collectionTracker = []; @@ -17,7 +17,6 @@ public class ModSettingApplier(PenumbraService penumbra, PenumbraAutoRedrawSkip if (!config.AlwaysApplyAssociatedMods || (design.AssociatedMods.Count == 0 && !design.ResetTemporarySettings)) return; - objects.Update(); if (!objects.TryGetValue(state.Identifier, out var data)) { Glamourer.Log.Verbose( diff --git a/Glamourer/Interop/Penumbra/PenumbraAutoRedraw.cs b/Glamourer/Interop/Penumbra/PenumbraAutoRedraw.cs index 93d23c2..4e3c8e3 100644 --- a/Glamourer/Interop/Penumbra/PenumbraAutoRedraw.cs +++ b/Glamourer/Interop/Penumbra/PenumbraAutoRedraw.cs @@ -2,11 +2,11 @@ using Glamourer.Api.Enums; using Glamourer.Designs.History; using Glamourer.Events; -using Glamourer.Interop.Structs; using Glamourer.State; using OtterGui.Classes; using OtterGui.Services; using Penumbra.Api.Enums; +using Penumbra.GameData.Interop; namespace Glamourer.Interop.Penumbra; @@ -16,13 +16,14 @@ public class PenumbraAutoRedraw : IDisposable, IRequiredService private readonly Configuration _config; private readonly PenumbraService _penumbra; private readonly StateManager _state; - private readonly ObjectManager _objects; + private readonly ActorObjectManager _objects; private readonly IFramework _framework; private readonly StateChanged _stateChanged; private readonly PenumbraAutoRedrawSkip _skip; - public PenumbraAutoRedraw(PenumbraService penumbra, Configuration config, StateManager state, ObjectManager objects, IFramework framework, + public PenumbraAutoRedraw(PenumbraService penumbra, Configuration config, StateManager state, ActorObjectManager objects, + IFramework framework, StateChanged stateChanged, PenumbraAutoRedrawSkip skip) { _penumbra = penumbra; @@ -78,7 +79,6 @@ public class PenumbraAutoRedraw : IDisposable, IRequiredService { _framework.RunOnFrameworkThread(() => { - _objects.Update(); foreach (var (id, state) in _state) { if (!_objects.TryGetValue(id, out var actors) || !actors.Valid) diff --git a/Glamourer/Interop/Structs/ActorData.cs b/Glamourer/Interop/Structs/ActorData.cs deleted file mode 100644 index 5cfbcbe..0000000 --- a/Glamourer/Interop/Structs/ActorData.cs +++ /dev/null @@ -1,47 +0,0 @@ -using OtterGui.Log; -using Penumbra.GameData.Interop; - -namespace Glamourer.Interop.Structs; - -/// -/// A single actor with its label and the list of associated game objects. -/// -public readonly struct ActorData -{ - public readonly List Objects; - public readonly string Label; - - public bool Valid - => Objects.Count > 0; - - public ActorData(Actor actor, string label) - { - Objects = [actor]; - Label = label; - } - - public static readonly ActorData Invalid = new(false); - - private ActorData(bool _) - { - Objects = []; - Label = string.Empty; - } - - public LazyString ToLazyString(string invalid) - { - var objects = Objects; - return Valid - ? new LazyString(() => string.Join(", ", objects.Select(o => o.ToString()))) - : new LazyString(() => invalid); - } - - private ActorData(List objects, string label) - { - Objects = objects; - Label = label; - } - - public ActorData OnlyGPose() - => new(Objects.Where(o => o.IsGPoseOrCutscene).ToList(), Label); -} diff --git a/Glamourer/Services/CommandService.cs b/Glamourer/Services/CommandService.cs index fa6e63f..ed51a06 100644 --- a/Glamourer/Services/CommandService.cs +++ b/Glamourer/Services/CommandService.cs @@ -17,7 +17,6 @@ using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; -using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.Services; @@ -26,24 +25,24 @@ public class CommandService : IDisposable, IApiService private const string MainCommandString = "/glamourer"; private const string ApplyCommandString = "/glamour"; - private readonly ICommandManager _commands; - private readonly MainWindow _mainWindow; - private readonly IChatGui _chat; - private readonly ActorManager _actors; - private readonly ObjectManager _objects; - private readonly StateManager _stateManager; - private readonly AutoDesignApplier _autoDesignApplier; - private readonly AutoDesignManager _autoDesignManager; - private readonly Configuration _config; - private readonly ModSettingApplier _modApplier; - private readonly ItemManager _items; - private readonly CustomizeService _customizeService; - private readonly DesignManager _designManager; - private readonly DesignConverter _converter; - private readonly DesignResolver _resolver; - private readonly PenumbraService _penumbra; + private readonly ICommandManager _commands; + private readonly MainWindow _mainWindow; + private readonly IChatGui _chat; + private readonly ActorManager _actors; + private readonly ActorObjectManager _objects; + private readonly StateManager _stateManager; + private readonly AutoDesignApplier _autoDesignApplier; + private readonly AutoDesignManager _autoDesignManager; + private readonly Configuration _config; + private readonly ModSettingApplier _modApplier; + private readonly ItemManager _items; + private readonly CustomizeService _customizeService; + private readonly DesignManager _designManager; + private readonly DesignConverter _converter; + private readonly DesignResolver _resolver; + private readonly PenumbraService _penumbra; - public CommandService(ICommandManager commands, MainWindow mainWindow, IChatGui chat, ActorManager actors, ObjectManager objects, + public CommandService(ICommandManager commands, MainWindow mainWindow, IChatGui chat, ActorManager actors, ActorObjectManager objects, AutoDesignApplier autoDesignApplier, StateManager stateManager, DesignManager designManager, DesignConverter converter, DesignFileSystem designFileSystem, AutoDesignManager autoDesignManager, Configuration config, ModSettingApplier modApplier, ItemManager items, RandomDesignGenerator randomDesign, CustomizeService customizeService, DesignFileSystemSelector designSelector, @@ -181,7 +180,9 @@ public class CommandService : IDisposable, IApiService _chat.Print(new SeStringBuilder().AddText("Use with /glamour clearsettings ").AddGreen("[Character Identifier]").AddText(" | ") .AddPurple("").AddText(" | ").AddBlue("").BuiltString); PlayerIdentifierHelp(false, true); - _chat.Print(new SeStringBuilder().AddText(" 》 The character identifier specifies the collection to clear settings from. It also accepts '").AddGreen("all").AddText("' to clear all collections.").BuiltString); + _chat.Print(new SeStringBuilder() + .AddText(" 》 The character identifier specifies the collection to clear settings from. It also accepts '").AddGreen("all") + .AddText("' to clear all collections.").BuiltString); _chat.Print(new SeStringBuilder().AddText(" 》 The booleans are optional and default to 'true', the ").AddPurple("first") .AddText(" determines whether ").AddPurple("manually").AddText(" applied settings are cleared, the ").AddBlue("second") .AddText(" determines whether ").AddBlue("automatically").AddText(" applied settings are cleared.").BuiltString); @@ -372,7 +373,6 @@ public class CommandService : IDisposable, IApiService if (!IdentifierHandling(argument, out var identifiers, false, true)) return false; - _objects.Update(); foreach (var identifier in identifiers) { if (!_objects.TryGetValue(identifier, out var data)) @@ -425,7 +425,6 @@ public class CommandService : IDisposable, IApiService if (!IdentifierHandling(argument, out var identifiers, false, true)) return false; - _objects.Update(); foreach (var identifier in identifiers) { if (!_objects.TryGetValue(identifier, out var data)) @@ -485,7 +484,6 @@ public class CommandService : IDisposable, IApiService if (!IdentifierHandling(split[1], out var identifiers, false, true)) return false; - _objects.Update(); foreach (var identifier in identifiers) { if (!_objects.TryGetValue(identifier, out var actors)) @@ -568,7 +566,6 @@ public class CommandService : IDisposable, IApiService if (!IdentifierHandling(split[1], out var identifiers, false, true)) return false; - _objects.Update(); foreach (var identifier in identifiers) { if (!_objects.TryGetValue(identifier, out var actors)) @@ -716,7 +713,6 @@ public class CommandService : IDisposable, IApiService if (!_resolver.GetDesign(split[0], out var design, true) || !IdentifierHandling(split2[0], out var identifiers, false, true)) return false; - _objects.Update(); foreach (var identifier in identifiers) { if (!_objects.TryGetValue(identifier, out var actors)) @@ -794,7 +790,6 @@ public class CommandService : IDisposable, IApiService if (!IdentifierHandling(argument, out var identifiers, false, true)) return false; - _objects.Update(); foreach (var identifier in identifiers) { if (!_stateManager.TryGetValue(identifier, out var state) @@ -835,7 +830,6 @@ public class CommandService : IDisposable, IApiService if (!IdentifierHandling(split[1], out var identifiers, false, true)) return false; - _objects.Update(); foreach (var identifier in identifiers) { if (!_stateManager.TryGetValue(identifier, out var state) diff --git a/Glamourer/Services/DesignApplier.cs b/Glamourer/Services/DesignApplier.cs index e0134d4..f0a9ba4 100644 --- a/Glamourer/Services/DesignApplier.cs +++ b/Glamourer/Services/DesignApplier.cs @@ -1,13 +1,12 @@ using Glamourer.Designs; -using Glamourer.Interop; -using Glamourer.Interop.Structs; using Glamourer.State; using OtterGui.Services; using Penumbra.GameData.Actors; +using Penumbra.GameData.Interop; namespace Glamourer.Services; -public sealed class DesignApplier(StateManager stateManager, ObjectManager objects) : IService +public sealed class DesignApplier(StateManager stateManager, ActorObjectManager objects) : IService { public void ApplyToPlayer(DesignBase design) { @@ -34,16 +33,10 @@ public sealed class DesignApplier(StateManager stateManager, ObjectManager objec } public void Apply(ActorIdentifier actor, DesignBase design) - { - objects.Update(); - Apply(actor, objects.TryGetValue(actor, out var d) ? d : ActorData.Invalid, design, ApplySettings.ManualWithLinks); - } + => Apply(actor, objects.TryGetValue(actor, out var d) ? d : ActorData.Invalid, design, ApplySettings.ManualWithLinks); public void Apply(ActorIdentifier actor, DesignBase design, ApplySettings settings) - { - objects.Update(); - Apply(actor, objects.TryGetValue(actor, out var d) ? d : ActorData.Invalid, design, settings); - } + => Apply(actor, objects.TryGetValue(actor, out var d) ? d : ActorData.Invalid, design, settings); public void Apply(ActorIdentifier actor, ActorData data, DesignBase design) => Apply(actor, data, design, ApplySettings.ManualWithLinks); diff --git a/Glamourer/Services/ServiceManager.cs b/Glamourer/Services/ServiceManager.cs index baae507..78a0bf0 100644 --- a/Glamourer/Services/ServiceManager.cs +++ b/Glamourer/Services/ServiceManager.cs @@ -27,6 +27,7 @@ using OtterGui.Services; using Penumbra.GameData.Actors; using Penumbra.GameData.Data; using Penumbra.GameData.DataContainers; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Services; @@ -102,6 +103,7 @@ public static class StaticServiceManager .AddSingleton() .AddSingleton(p => new CutsceneResolver(p.GetRequiredService().CutsceneParent)) .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() diff --git a/Glamourer/State/FunModule.cs b/Glamourer/State/FunModule.cs index 1ca5c48..52394a2 100644 --- a/Glamourer/State/FunModule.cs +++ b/Glamourer/State/FunModule.cs @@ -11,7 +11,6 @@ using Penumbra.GameData.Enums; using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; using CustomizeIndex = Penumbra.GameData.Enums.CustomizeIndex; -using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.State; @@ -35,7 +34,7 @@ public unsafe class FunModule : IDisposable private readonly StateManager _stateManager; private readonly DesignConverter _designConverter; private readonly DesignManager _designManager; - private readonly ObjectManager _objects; + private readonly ActorObjectManager _objects; private readonly NpcCustomizeSet _npcs; private readonly StainId[] _stains; @@ -69,7 +68,7 @@ public unsafe class FunModule : IDisposable => OnDayChange(DateTime.Now.Day, DateTime.Now.Month, DateTime.Now.Year); public FunModule(CodeService codes, CustomizeService customizations, ItemManager items, Configuration config, - GenericPopupWindow popupWindow, StateManager stateManager, ObjectManager objects, DesignConverter designConverter, + GenericPopupWindow popupWindow, StateManager stateManager, ActorObjectManager objects, DesignConverter designConverter, DesignManager designManager, NpcCustomizeSet npcs) { _codes = codes; @@ -125,9 +124,7 @@ public unsafe class FunModule : IDisposable switch (_codes.Masked(CodeService.GearCodes)) { - case CodeService.CodeFlag.Emperor: - SetRandomItem(slot, ref armor); - break; + case CodeService.CodeFlag.Emperor: SetRandomItem(slot, ref armor); break; case CodeService.CodeFlag.Elephants: case CodeService.CodeFlag.Dolphins: case CodeService.CodeFlag.World when actor.Index != 0: @@ -137,9 +134,7 @@ public unsafe class FunModule : IDisposable switch (_codes.Masked(CodeService.DyeCodes)) { - case CodeService.CodeFlag.Clown: - SetRandomDye(ref armor); - break; + case CodeService.CodeFlag.Clown: SetRandomDye(ref armor); break; } } @@ -306,9 +301,7 @@ public unsafe class FunModule : IDisposable SetDolphin(EquipSlot.Body, ref armor[1]); SetDolphin(EquipSlot.Head, ref armor[0]); break; - case CodeService.CodeFlag.World when actor.Index != 0: - _worldSets.Apply(actor, _rng, armor); - break; + case CodeService.CodeFlag.World when actor.Index != 0: _worldSets.Apply(actor, _rng, armor); break; } switch (_codes.Masked(CodeService.DyeCodes)) @@ -368,17 +361,17 @@ public unsafe class FunModule : IDisposable private static IReadOnlyList DolphinBodies => [ - new CharacterArmor(6089, 1, new StainIds(4)), // Toad - new CharacterArmor(6089, 1, new StainIds(4)), // Toad - new CharacterArmor(6089, 1, new StainIds(4)), // Toad - new CharacterArmor(6023, 1, new StainIds(4)), // Swine - new CharacterArmor(6023, 1, new StainIds(4)), // Swine - new CharacterArmor(6023, 1, new StainIds(4)), // Swine - new CharacterArmor(6133, 1, new StainIds(4)), // Gaja - new CharacterArmor(6182, 1, new StainIds(3)), // Imp - new CharacterArmor(6182, 1, new StainIds(3)), // Imp - new CharacterArmor(6182, 1, new StainIds(4)), // Imp - new CharacterArmor(6182, 1, new StainIds(4)), // Imp + new(6089, 1, new StainIds(4)), // Toad + new(6089, 1, new StainIds(4)), // Toad + new(6089, 1, new StainIds(4)), // Toad + new(6023, 1, new StainIds(4)), // Swine + new(6023, 1, new StainIds(4)), // Swine + new(6023, 1, new StainIds(4)), // Swine + new(6133, 1, new StainIds(4)), // Gaja + new(6182, 1, new StainIds(3)), // Imp + new(6182, 1, new StainIds(3)), // Imp + new(6182, 1, new StainIds(4)), // Imp + new(6182, 1, new StainIds(4)), // Imp ]; private void SetDolphin(EquipSlot slot, ref CharacterArmor armor) diff --git a/Glamourer/State/StateApplier.cs b/Glamourer/State/StateApplier.cs index be85580..698151f 100644 --- a/Glamourer/State/StateApplier.cs +++ b/Glamourer/State/StateApplier.cs @@ -7,6 +7,7 @@ using Glamourer.Interop.Structs; using Glamourer.Services; using Penumbra.Api.Enums; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.State; @@ -23,7 +24,7 @@ public class StateApplier( ItemManager _items, PenumbraService _penumbra, MetaService _metaService, - ObjectManager _objects, + ActorObjectManager _objects, CrestService _crests, DirectXService _directX) { @@ -411,8 +412,5 @@ public class StateApplier( } private ActorData GetData(ActorState state) - { - _objects.Update(); - return _objects.TryGetValue(state.Identifier, out var data) ? data : ActorData.Invalid; - } + => _objects.TryGetValue(state.Identifier, out var data) ? data : ActorData.Invalid; } diff --git a/Glamourer/State/StateEditor.cs b/Glamourer/State/StateEditor.cs index 1fa1ffe..986bdc2 100644 --- a/Glamourer/State/StateEditor.cs +++ b/Glamourer/State/StateEditor.cs @@ -9,6 +9,7 @@ using Glamourer.Interop.Penumbra; using Glamourer.Interop.Structs; using Glamourer.Services; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.State; diff --git a/Glamourer/State/StateListener.cs b/Glamourer/State/StateListener.cs index 88ec0b5..24f641c 100644 --- a/Glamourer/State/StateListener.cs +++ b/Glamourer/State/StateListener.cs @@ -15,7 +15,6 @@ using Penumbra.GameData.DataContainers; using Glamourer.Designs; using Penumbra.GameData.Interop; using Glamourer.Api.Enums; -using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.State; @@ -28,7 +27,7 @@ public class StateListener : IDisposable { private readonly Configuration _config; private readonly ActorManager _actors; - private readonly ObjectManager _objects; + private readonly ActorObjectManager _objects; private readonly StateManager _manager; private readonly StateApplier _applier; private readonly ItemManager _items; @@ -61,7 +60,7 @@ public class StateListener : IDisposable public StateListener(StateManager manager, ItemManager items, PenumbraService penumbra, ActorManager actors, Configuration config, EquipSlotUpdating equipSlotUpdating, GearsetDataLoaded gearsetDataLoaded, WeaponLoading weaponLoading, VisorStateChanged visorState, WeaponVisibilityChanged weaponVisibility, HeadGearVisibilityChanged headGearVisibility, AutoDesignApplier autoDesignApplier, - FunModule funModule, HumanModelList humans, StateApplier applier, MovedEquipment movedEquipment, ObjectManager objects, + FunModule funModule, HumanModelList humans, StateApplier applier, MovedEquipment movedEquipment, ActorObjectManager objects, GPoseService gPose, ChangeCustomizeService changeCustomizeService, CustomizeService customizations, ICondition condition, CrestService crestService, BonusSlotUpdating bonusSlotUpdating, StateFinalized stateFinalized) { @@ -205,9 +204,7 @@ public class StateListener : IDisposable } break; - case UpdateState.NoChange: - customize = state.ModelData.Customize; - break; + case UpdateState.NoChange: customize = state.ModelData.Customize; break; } } @@ -262,9 +259,7 @@ public class StateListener : IDisposable item = state.ModelData.BonusItem(slot).Armor(); break; // Use current model data. - case UpdateState.NoChange: - item = state.ModelData.BonusItem(slot).Armor(); - break; + case UpdateState.NoChange: item = state.ModelData.BonusItem(slot).Armor(); break; case UpdateState.Transformed: break; } } @@ -279,7 +274,6 @@ public class StateListener : IDisposable if (!actor.Identifier(_actors, out var identifier)) return; - _objects.Update(); if (_objects.TryGetValue(identifier, out var actors) && actors.Valid) _stateFinalized.Invoke(StateFinalizationType.Gearset, actors); } @@ -287,7 +281,6 @@ public class StateListener : IDisposable private void OnMovedEquipment((EquipSlot, uint, StainIds)[] items) { - _objects.Update(); var (identifier, objects) = _objects.PlayerData; if (!identifier.IsValid || !_manager.TryGetValue(identifier, out var state)) return; @@ -310,7 +303,7 @@ public class StateListener : IDisposable var stainChanged = current.Stains == changed.Stains && !state.Sources[slot, true].IsFixed(); - switch ((itemChanged, stainChanged)) + switch (itemChanged, stainChanged) { case (true, true): _manager.ChangeEquip(state, slot, currentItem, current.Stains, ApplySettings.Game); @@ -376,9 +369,7 @@ public class StateListener : IDisposable else apply = true; break; - case UpdateState.NoChange: - apply = true; - break; + case UpdateState.NoChange: apply = true; break; } var baseType = slot is EquipSlot.OffHand ? state.BaseData.MainhandType.Offhand() : state.BaseData.MainhandType; diff --git a/Glamourer/Unlocks/CustomizeUnlockManager.cs b/Glamourer/Unlocks/CustomizeUnlockManager.cs index b58385e..bd13f99 100644 --- a/Glamourer/Unlocks/CustomizeUnlockManager.cs +++ b/Glamourer/Unlocks/CustomizeUnlockManager.cs @@ -1,16 +1,15 @@ using Dalamud.Game; using Dalamud.Hooking; using Dalamud.Plugin.Services; -using Dalamud.Utility; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.UI; using Glamourer.GameData; using Glamourer.Events; -using Glamourer.Interop; using Glamourer.Services; using Lumina.Excel.Sheets; using Penumbra.GameData; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; namespace Glamourer.Unlocks; @@ -19,7 +18,7 @@ public class CustomizeUnlockManager : IDisposable, ISavable private readonly SaveService _saveService; private readonly IClientState _clientState; private readonly ObjectUnlocked _event; - private readonly ObjectManager _objects; + private readonly ActorObjectManager _objects; private readonly Dictionary _unlocked = new(); public readonly IReadOnlyDictionary Unlockable; @@ -28,7 +27,7 @@ public class CustomizeUnlockManager : IDisposable, ISavable => _unlocked; public CustomizeUnlockManager(SaveService saveService, CustomizeService customizations, IDataManager gameData, - IClientState clientState, ObjectUnlocked @event, IGameInteropProvider interop, ObjectManager objects) + IClientState clientState, ObjectUnlocked @event, IGameInteropProvider interop, ActorObjectManager objects) { interop.InitializeFromAttributes(this); _saveService = saveService; @@ -177,7 +176,7 @@ public class CustomizeUnlockManager : IDisposable, ISavable IDataManager gameData) { var ret = new Dictionary(); - var sheet = gameData.GetExcelSheet(ClientLanguage.English)!; + var sheet = gameData.GetExcelSheet(ClientLanguage.English); foreach (var (clan, gender) in CustomizeManager.AllSets()) { var list = customizations.Manager.GetSet(clan, gender); diff --git a/OtterGui b/OtterGui index 3396ee1..f53fd22 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit 3396ee176fa72ad2dfb2de3294f7125ebce4dae5 +Subproject commit f53fd227a242435ce44a9fe9c5e847d0ca788869 diff --git a/Penumbra.GameData b/Penumbra.GameData index ab63da8..801e98a 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit ab63da8047f3d99240159bb1b17dbcb61d77326a +Subproject commit 801e98a2956d707a25fd19bdfa46dc674c95365d