diff --git a/Glamourer/Gui/Tabs/DebugTab.cs b/Glamourer/Gui/Tabs/DebugTab.cs
index 1220f47..4314de7 100644
--- a/Glamourer/Gui/Tabs/DebugTab.cs
+++ b/Glamourer/Gui/Tabs/DebugTab.cs
@@ -526,7 +526,7 @@ public unsafe class DebugTab : ITab
using (var disabled = ImRaii.Disabled(!_penumbra.Available))
{
if (ImGui.SmallButton("Redraw"))
- _penumbra.RedrawObject(_objectManager.Objects.GetObjectAddress(_gameObjectIndex), RedrawType.Redraw);
+ _penumbra.RedrawObject((ObjectIndex) _gameObjectIndex, RedrawType.Redraw);
}
ImGuiUtil.DrawTableColumn("Last Tooltip Date");
diff --git a/Glamourer/Interop/Penumbra/PenumbraService.cs b/Glamourer/Interop/Penumbra/PenumbraService.cs
index 375d148..2bde8d1 100644
--- a/Glamourer/Interop/Penumbra/PenumbraService.cs
+++ b/Glamourer/Interop/Penumbra/PenumbraService.cs
@@ -11,6 +11,7 @@ using Glamourer.Interop.Structs;
using Penumbra.Api;
using Penumbra.Api.Enums;
using Penumbra.Api.Helpers;
+using Penumbra.GameData.Structs;
namespace Glamourer.Interop.Penumbra;
@@ -239,6 +240,19 @@ public unsafe class PenumbraService : IDisposable
}
}
+ /// Try to redraw the given actor.
+ public void RedrawObject(ObjectIndex index, RedrawType settings)
+ {
+ try
+ {
+ _redrawSubscriber.Invoke(index.Index, settings);
+ }
+ catch (Exception e)
+ {
+ PluginLog.Debug($"Failure redrawing object:\n{e}");
+ }
+ }
+
/// Reattach to the currently running Penumbra IPC provider. Unattaches before if necessary.
public void Reattach()
{
diff --git a/Glamourer/State/StateApplier.cs b/Glamourer/State/StateApplier.cs
index 04f1049..88a97e3 100644
--- a/Glamourer/State/StateApplier.cs
+++ b/Glamourer/State/StateApplier.cs
@@ -1,4 +1,5 @@
using System.Linq;
+using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using Glamourer.Customization;
using Glamourer.Events;
using Glamourer.Interop;
@@ -61,7 +62,7 @@ public class StateApplier
/// Change the customization values of actors either by applying them via update or redrawing,
/// this depends on whether the changes include changes to Race, Gender, Body Type or Face.
///
- public void ChangeCustomize(ActorData data, in Customize customize, ActorState? state = null)
+ public unsafe void ChangeCustomize(ActorData data, in Customize customize, ActorState? state = null)
{
foreach (var actor in data.Objects)
{
@@ -71,13 +72,22 @@ public class StateApplier
var flags = Customize.Compare(mdl.GetCustomize(), customize);
if (!flags.RequiresRedraw() || !mdl.IsHuman)
+ {
_changeCustomize.UpdateCustomize(mdl, customize.Data);
+ }
+ else if (data.Objects.Count > 1 && _objects.IsInGPose && !actor.IsGPoseOrCutscene)
+ {
+ var mdlCustomize = (Customize*)&mdl.AsHuman->Customize;
+ mdlCustomize->Load(customize);
+ }
else
+ {
_penumbra.RedrawObject(actor, RedrawType.Redraw);
+ }
}
}
- ///
+ ///
public ActorData ChangeCustomize(ActorState state, bool apply)
{
var data = GetData(state);
@@ -122,7 +132,8 @@ public class StateApplier
// If the source is not IPC we do not want to apply restrictions.
var data = GetData(state);
if (apply)
- ChangeArmor(data, slot, state.ModelData.Armor(slot), state[slot, false] is not StateChanged.Source.Ipc, state.ModelData.IsHatVisible());
+ ChangeArmor(data, slot, state.ModelData.Armor(slot), state[slot, false] is not StateChanged.Source.Ipc,
+ state.ModelData.IsHatVisible());
return data;
}