diff --git a/Glamourer/Api/GlamourerIpc.ApplyByGUID.cs b/Glamourer/Api/GlamourerIpc.ApplyByGUID.cs new file mode 100644 index 0000000..92088b1 --- /dev/null +++ b/Glamourer/Api/GlamourerIpc.ApplyByGUID.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Plugin; +using Glamourer.Events; +using Glamourer.Interop.Structs; +using Penumbra.Api.Helpers; +using Penumbra.GameData.Actors; + +namespace Glamourer.Api; + +public partial class GlamourerIpc +{ + public const string LabelApplyByGuidAll = "Glamourer.ApplyByGuidAll"; + public const string LabelApplyByGuidAllToCharacter = "Glamourer.ApplyByGuidAllToCharacter"; + + private readonly ActionProvider _applyByGuidAllProvider; + private readonly ActionProvider _applyByGuidAllToCharacterProvider; + + public static ActionSubscriber ApplyByGuidAllSubscriber(DalamudPluginInterface pi) + => new(pi, LabelApplyByGuidAll); + + public static ActionSubscriber ApplyByGuidAllToCharacterSubscriber(DalamudPluginInterface pi) + => new(pi, LabelApplyByGuidAllToCharacter); + + public void ApplyByGuidAll(Guid GUID, string characterName) + => ApplyDesignByGuid(GUID, FindActors(characterName), 0); + + public void ApplyByGuidAllToCharacter(Guid GUID, Character? character) + => ApplyDesignByGuid(GUID, FindActors(character), 0); + + private void ApplyDesignByGuid(Guid GUID, IEnumerable actors, uint lockCode) + { + var design = _designManager.Designs.FirstOrDefault(x => x.Identifier == GUID); + if (design == null) + return; + + var hasModelId = true; + _objects.Update(); + foreach (var id in actors) + { + if (!_stateManager.TryGetValue(id, out var state)) + { + var data = _objects.TryGetValue(id, out var d) ? d : ActorData.Invalid; + if (!data.Valid || !_stateManager.GetOrCreate(id, data.Objects[0], out state)) + continue; + } + + if ((hasModelId || state.ModelData.ModelId == 0) && state.CanUnlock(lockCode)) + { + _stateManager.ApplyDesign(design, state, StateChanged.Source.Ipc, lockCode); + state.Lock(lockCode); + } + } + } +} diff --git a/Glamourer/Api/GlamourerIpc.GetDesign.cs b/Glamourer/Api/GlamourerIpc.GetDesign.cs new file mode 100644 index 0000000..7d655ee --- /dev/null +++ b/Glamourer/Api/GlamourerIpc.GetDesign.cs @@ -0,0 +1,38 @@ +using System; +using System.Buffers.Text; +using System.Collections.Generic; +using System.Linq; +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Plugin; +using Glamourer.Customization; +using Glamourer.Designs; +using Glamourer.Structs; +using Penumbra.Api.Helpers; +using Penumbra.GameData.Actors; + +namespace Glamourer.Api; + +public partial class GlamourerIpc +{ + public const string LabelGetDesignList = "Glamourer.GetDesignList"; + + private readonly FuncProvider _getDesignListProvider; + + public static FuncSubscriber GetDesignListSubscriber(DalamudPluginInterface pi) + => new(pi, LabelGetDesignList); + + public DesignListEntry[] GetDesignList() + => _designManager.Designs.Select(x => new DesignListEntry(x)).ToArray(); + + public record class DesignListEntry + { + public string Name; + public Guid Identifier; + + public DesignListEntry(Design design) + { + Name = design.Name; + Identifier = design.Identifier; + } + } +} diff --git a/Glamourer/Api/GlamourerIpc.cs b/Glamourer/Api/GlamourerIpc.cs index 398cdf2..54c4fa7 100644 --- a/Glamourer/Api/GlamourerIpc.cs +++ b/Glamourer/Api/GlamourerIpc.cs @@ -25,9 +25,10 @@ public partial class GlamourerIpc : IDisposable private readonly ActorService _actors; private readonly DesignConverter _designConverter; private readonly AutoDesignApplier _autoDesignApplier; + private readonly DesignManager _designManager; public GlamourerIpc(DalamudPluginInterface pi, StateManager stateManager, ObjectManager objects, ActorService actors, - DesignConverter designConverter, StateChanged stateChangedEvent, GPoseService gPose, AutoDesignApplier autoDesignApplier) + DesignConverter designConverter, StateChanged stateChangedEvent, GPoseService gPose, AutoDesignApplier autoDesignApplier, DesignManager designManager) { _stateManager = stateManager; _objects = objects; @@ -36,6 +37,7 @@ public partial class GlamourerIpc : IDisposable _autoDesignApplier = autoDesignApplier; _gPose = gPose; _stateChangedEvent = stateChangedEvent; + _designManager = designManager; _apiVersionProvider = new FuncProvider(pi, LabelApiVersion, ApiVersion); _apiVersionsProvider = new FuncProvider<(int Major, int Minor)>(pi, LabelApiVersions, ApiVersions); @@ -78,6 +80,11 @@ public partial class GlamourerIpc : IDisposable _stateChangedEvent.Subscribe(OnStateChanged, StateChanged.Priority.GlamourerIpc); _gPose.Subscribe(OnGPoseChanged, GPoseService.Priority.GlamourerIpc); + + _applyByGuidAllProvider = new ActionProvider(pi, LabelApplyByGuidAll, ApplyByGuidAll); + _applyByGuidAllToCharacterProvider = new ActionProvider(pi, LabelApplyByGuidAllToCharacter, ApplyByGuidAllToCharacter); + + _getDesignListProvider = new FuncProvider(pi, LabelGetDesignList, GetDesignList); } public void Dispose() @@ -114,6 +121,10 @@ public partial class GlamourerIpc : IDisposable _stateChangedProvider.Dispose(); _gPose.Unsubscribe(OnGPoseChanged); _gPoseChangedProvider.Dispose(); + + _applyByGuidAllProvider.Dispose(); + _applyByGuidAllToCharacterProvider.Dispose(); + _getDesignListProvider.Dispose(); } private IEnumerable FindActors(string actorName) diff --git a/Glamourer/Gui/MainWindow.cs b/Glamourer/Gui/MainWindow.cs index d4e19b2..df50fb5 100644 --- a/Glamourer/Gui/MainWindow.cs +++ b/Glamourer/Gui/MainWindow.cs @@ -8,6 +8,7 @@ using Glamourer.Events; using Glamourer.Gui.Tabs; using Glamourer.Gui.Tabs.ActorTab; using Glamourer.Gui.Tabs.AutomationTab; +using Glamourer.Gui.Tabs.DebugTab; using Glamourer.Gui.Tabs.DesignTab; using Glamourer.Gui.Tabs.UnlocksTab; using ImGuiNET;