mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Continue renames, some cleanup.
This commit is contained in:
parent
7be283ca30
commit
d9f9937d41
18 changed files with 175 additions and 134 deletions
|
|
@ -33,7 +33,7 @@ public class DesignsApi(ApiHelpers helpers, DesignManager designs, StateManager
|
|||
{
|
||||
var once = (flags & ApplyFlag.Once) != 0;
|
||||
var settings = new ApplySettings(Source: once ? StateSource.IpcManual : StateSource.IpcFixed, Key: key, MergeLinks: true,
|
||||
ResetMaterials: !once && key != 0, SendStateUpdate: true);
|
||||
ResetMaterials: !once && key != 0, IsFinal: true);
|
||||
|
||||
using var restrict = ApiHelpers.Restrict(design, flags);
|
||||
stateManager.ApplyDesign(state, design, settings);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ using Dalamud.Plugin;
|
|||
using Glamourer.Api.Api;
|
||||
using Glamourer.Api.Helpers;
|
||||
using OtterGui.Services;
|
||||
using System.Reflection.Emit;
|
||||
using Glamourer.Api.Enums;
|
||||
|
||||
namespace Glamourer.Api;
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ using OtterGui.Services;
|
|||
using Penumbra.GameData.Interop;
|
||||
using ObjectManager = Glamourer.Interop.ObjectManager;
|
||||
using StateChanged = Glamourer.Events.StateChanged;
|
||||
using StateUpdated = Glamourer.Events.StateUpdated;
|
||||
|
||||
namespace Glamourer.Api;
|
||||
|
||||
public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
||||
{
|
||||
private readonly ApiHelpers _helpers;
|
||||
|
|
@ -23,7 +23,7 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
|||
private readonly AutoDesignApplier _autoDesigns;
|
||||
private readonly ObjectManager _objects;
|
||||
private readonly StateChanged _stateChanged;
|
||||
private readonly StateUpdated _stateUpdated;
|
||||
private readonly StateFinalized _stateFinalized;
|
||||
private readonly GPoseService _gPose;
|
||||
|
||||
public StateApi(ApiHelpers helpers,
|
||||
|
|
@ -33,27 +33,27 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
|||
AutoDesignApplier autoDesigns,
|
||||
ObjectManager objects,
|
||||
StateChanged stateChanged,
|
||||
StateUpdated stateUpdated,
|
||||
StateFinalized stateFinalized,
|
||||
GPoseService gPose)
|
||||
{
|
||||
_helpers = helpers;
|
||||
_stateManager = stateManager;
|
||||
_converter = converter;
|
||||
_config = config;
|
||||
_autoDesigns = autoDesigns;
|
||||
_objects = objects;
|
||||
_stateChanged = stateChanged;
|
||||
_stateUpdated = stateUpdated;
|
||||
_gPose = gPose;
|
||||
_helpers = helpers;
|
||||
_stateManager = stateManager;
|
||||
_converter = converter;
|
||||
_config = config;
|
||||
_autoDesigns = autoDesigns;
|
||||
_objects = objects;
|
||||
_stateChanged = stateChanged;
|
||||
_stateFinalized = stateFinalized;
|
||||
_gPose = gPose;
|
||||
_stateChanged.Subscribe(OnStateChanged, Events.StateChanged.Priority.GlamourerIpc);
|
||||
_stateUpdated.Subscribe(OnStateUpdated, Events.StateUpdated.Priority.GlamourerIpc);
|
||||
_gPose.Subscribe(OnGPoseChange, GPoseService.Priority.GlamourerIpc);
|
||||
_stateFinalized.Subscribe(OnStateFinalized, Events.StateFinalized.Priority.StateApi);
|
||||
_gPose.Subscribe(OnGPoseChange, GPoseService.Priority.StateApi);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_stateChanged.Unsubscribe(OnStateChanged);
|
||||
_stateUpdated.Unsubscribe(OnStateUpdated);
|
||||
_stateFinalized.Unsubscribe(OnStateFinalized);
|
||||
_gPose.Unsubscribe(OnGPoseChange);
|
||||
}
|
||||
|
||||
|
|
@ -253,16 +253,16 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
|||
return ApiHelpers.Return(GlamourerApiEc.Success, args);
|
||||
}
|
||||
|
||||
public event Action<nint>? StateChanged;
|
||||
public event Action<IntPtr, StateChangeType>? StateChangedWithType;
|
||||
public event Action<nint>? StateChanged;
|
||||
public event Action<IntPtr, StateChangeType>? StateChangedWithType;
|
||||
public event Action<IntPtr, StateFinalizationType>? StateFinalized;
|
||||
public event Action<bool>? GPoseChanged;
|
||||
public event Action<bool>? GPoseChanged;
|
||||
|
||||
private void ApplyDesign(ActorState state, DesignBase design, uint key, ApplyFlag flags)
|
||||
{
|
||||
var once = (flags & ApplyFlag.Once) != 0;
|
||||
var settings = new ApplySettings(Source: once ? StateSource.IpcManual : StateSource.IpcFixed, Key: key, MergeLinks: true,
|
||||
ResetMaterials: !once && key != 0, SendStateUpdate: true);
|
||||
ResetMaterials: !once && key != 0, IsFinal: true);
|
||||
_stateManager.ApplyDesign(state, design, settings);
|
||||
ApiHelpers.Lock(state, key, flags);
|
||||
}
|
||||
|
|
@ -349,7 +349,7 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
|||
StateChangedWithType.Invoke(actor.Address, type);
|
||||
}
|
||||
|
||||
private void OnStateUpdated(StateFinalizationType type, ActorData actors)
|
||||
private void OnStateFinalized(StateFinalizationType type, ActorData actors)
|
||||
{
|
||||
Glamourer.Log.Verbose($"[OnStateUpdated] State Updated with Type {type}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
if (StateFinalized != null)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public readonly record struct ApplySettings(
|
|||
bool UseSingleSource = false,
|
||||
bool MergeLinks = false,
|
||||
bool ResetMaterials = false,
|
||||
bool SendStateUpdate = false)
|
||||
bool IsFinal = false)
|
||||
{
|
||||
public static readonly ApplySettings Manual = new()
|
||||
{
|
||||
|
|
@ -25,7 +25,7 @@ public readonly record struct ApplySettings(
|
|||
UseSingleSource = false,
|
||||
MergeLinks = false,
|
||||
ResetMaterials = false,
|
||||
SendStateUpdate = false,
|
||||
IsFinal = false,
|
||||
};
|
||||
|
||||
public static readonly ApplySettings ManualWithLinks = new()
|
||||
|
|
@ -37,7 +37,7 @@ public readonly record struct ApplySettings(
|
|||
UseSingleSource = false,
|
||||
MergeLinks = true,
|
||||
ResetMaterials = false,
|
||||
SendStateUpdate = false,
|
||||
IsFinal = false,
|
||||
};
|
||||
|
||||
public static readonly ApplySettings Game = new()
|
||||
|
|
@ -49,7 +49,7 @@ public readonly record struct ApplySettings(
|
|||
UseSingleSource = false,
|
||||
MergeLinks = false,
|
||||
ResetMaterials = true,
|
||||
SendStateUpdate = false,
|
||||
IsFinal = false,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ public sealed class GPoseService : EventWrapper<bool, GPoseService.Priority>
|
|||
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.GlamourerIpc.OnGPoseChanged"/>
|
||||
GlamourerIpc = int.MinValue,
|
||||
/// <seealso cref="Api.StateApi.OnGPoseChange"/>
|
||||
StateApi = int.MinValue,
|
||||
}
|
||||
|
||||
public bool InGPose { get; private set; }
|
||||
|
|
|
|||
|
|
@ -1,24 +1,23 @@
|
|||
using Glamourer.Api;
|
||||
using Glamourer.Api.Enums;
|
||||
using Glamourer.Designs.History;
|
||||
using Glamourer.Interop.Structs;
|
||||
using Glamourer.State;
|
||||
using OtterGui.Classes;
|
||||
|
||||
namespace Glamourer.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a Design is edited in any way.
|
||||
/// Triggered when a set of grouped changes finishes being applied to a Glamourer state.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the operation that finished updating the saved state. </item>
|
||||
/// <item>Parameter is the existing actors using this saved state. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class StateUpdated()
|
||||
: EventWrapper<StateFinalizationType, ActorData, StateUpdated.Priority>(nameof(StateUpdated))
|
||||
public sealed class StateFinalized()
|
||||
: EventWrapper<StateFinalizationType, ActorData, StateFinalized.Priority>(nameof(StateFinalized))
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.GlamourerIpc.OnStateUpdated"/>
|
||||
GlamourerIpc = int.MinValue,
|
||||
/// <seealso cref="StateApi.OnStateFinalized"/>
|
||||
StateApi = int.MinValue,
|
||||
}
|
||||
}
|
||||
|
|
@ -183,7 +183,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
|||
}
|
||||
|
||||
using var _ = design!.TemporarilyRestrictApplication(ApplicationCollection.FromKeys());
|
||||
_stateManager.ApplyDesign(state, design, ApplySettings.ManualWithLinks with { SendStateUpdate = true });
|
||||
_stateManager.ApplyDesign(state, design, ApplySettings.ManualWithLinks with { IsFinal = true });
|
||||
}
|
||||
|
||||
private void DrawRevertButton(Vector2 buttonSize)
|
||||
|
|
@ -213,7 +213,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
|||
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, tooltip, available);
|
||||
ImGui.SameLine();
|
||||
if (clicked)
|
||||
_stateManager.ResetState(state!, StateSource.Manual, stateUpdate: true);
|
||||
_stateManager.ResetState(state!, StateSource.Manual, isFinal: true);
|
||||
}
|
||||
|
||||
private void DrawRevertAutomationButton(Vector2 buttonSize)
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ public class ActorPanel
|
|||
{
|
||||
if (ImGuiUtil.DrawDisabledButton("Revert to Game", Vector2.Zero, "Revert the character to its actual state in the game.",
|
||||
_state!.IsLocked))
|
||||
_stateManager.ResetState(_state!, StateSource.Manual, stateUpdate: true);
|
||||
_stateManager.ResetState(_state!, StateSource.Manual, isFinal: true);
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
|
|
@ -423,7 +423,7 @@ public class ActorPanel
|
|||
|
||||
if (_stateManager.GetOrCreate(id, data.Objects[0], out var state))
|
||||
_stateManager.ApplyDesign(state, _converter.Convert(_state!, ApplicationRules.FromModifiers(_state!)),
|
||||
ApplySettings.Manual with { SendStateUpdate = true });
|
||||
ApplySettings.Manual with { IsFinal = true });
|
||||
}
|
||||
|
||||
private void DrawApplyToTarget()
|
||||
|
|
@ -440,7 +440,7 @@ public class ActorPanel
|
|||
|
||||
if (_stateManager.GetOrCreate(id, data.Objects[0], out var state))
|
||||
_stateManager.ApplyDesign(state, _converter.Convert(_state!, ApplicationRules.FromModifiers(_state!)),
|
||||
ApplySettings.Manual with { SendStateUpdate = true });
|
||||
ApplySettings.Manual with { IsFinal = true });
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -467,7 +467,7 @@ public class ActorPanel
|
|||
var text = ImGui.GetClipboardText();
|
||||
var design = panel._converter.FromBase64(text, applyCustomize, applyGear, out _)
|
||||
?? throw new Exception("The clipboard did not contain valid data.");
|
||||
panel._stateManager.ApplyDesign(panel._state!, design, ApplySettings.ManualWithLinks with { SendStateUpdate = true });
|
||||
panel._stateManager.ApplyDesign(panel._state!, design, ApplySettings.ManualWithLinks with { IsFinal = true });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer
|
|||
if (ImGuiUtil.DrawDisabledButton("Apply to Player", Vector2.Zero, string.Empty, !enabled))
|
||||
{
|
||||
var design = CreateDesign(plate);
|
||||
_state.ApplyDesign(state!, design, ApplySettings.Manual with { SendStateUpdate = true });
|
||||
_state.ApplyDesign(state!, design, ApplySettings.Manual with { IsFinal = true });
|
||||
}
|
||||
|
||||
using (ImRaii.Group())
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ public class IpcTesterPanel(
|
|||
Glamourer.Log.Debug("[IPCTester] Subscribed to IPC events for IPC tester.");
|
||||
state.GPoseChanged.Enable();
|
||||
state.StateChanged.Enable();
|
||||
state.StateFinalized.Enable();
|
||||
framework.Update += CheckUnsubscribe;
|
||||
_subscribed = true;
|
||||
}
|
||||
|
|
@ -73,5 +74,6 @@ public class IpcTesterPanel(
|
|||
_subscribed = false;
|
||||
state.GPoseChanged.Disable();
|
||||
state.StateChanged.Disable();
|
||||
state.StateFinalized.Disable();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using Newtonsoft.Json.Linq;
|
|||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
using Penumbra.GameData.Interop;
|
||||
using Penumbra.String;
|
||||
|
||||
|
|
@ -31,9 +32,16 @@ public class StateIpcTester : IUiService, IDisposable
|
|||
private string? _getStateString;
|
||||
|
||||
public readonly EventSubscriber<nint, StateChangeType> StateChanged;
|
||||
private nint _lastStateChangeActor;
|
||||
private ByteString _lastStateChangeName = ByteString.Empty;
|
||||
private DateTime _lastStateChangeTime;
|
||||
private nint _lastStateChangeActor;
|
||||
private ByteString _lastStateChangeName = ByteString.Empty;
|
||||
private DateTime _lastStateChangeTime;
|
||||
private StateChangeType _lastStateChangeType;
|
||||
|
||||
public readonly EventSubscriber<nint, StateFinalizationType> StateFinalized;
|
||||
private nint _lastStateFinalizeActor;
|
||||
private ByteString _lastStateFinalizeName = ByteString.Empty;
|
||||
private DateTime _lastStateFinalizeTime;
|
||||
private StateFinalizationType _lastStateFinalizeType;
|
||||
|
||||
public readonly EventSubscriber<bool> GPoseChanged;
|
||||
private bool _lastGPoseChangeValue;
|
||||
|
|
@ -44,15 +52,18 @@ public class StateIpcTester : IUiService, IDisposable
|
|||
public StateIpcTester(IDalamudPluginInterface pluginInterface)
|
||||
{
|
||||
_pluginInterface = pluginInterface;
|
||||
StateChanged = Api.IpcSubscribers.StateChangedWithType.Subscriber(_pluginInterface, OnStateChanged);
|
||||
StateChanged = StateChangedWithType.Subscriber(_pluginInterface, OnStateChanged);
|
||||
StateFinalized = Api.IpcSubscribers.StateFinalized.Subscriber(_pluginInterface, OnStateFinalized);
|
||||
GPoseChanged = Api.IpcSubscribers.GPoseChanged.Subscriber(_pluginInterface, OnGPoseChange);
|
||||
StateChanged.Disable();
|
||||
StateFinalized.Disable();
|
||||
GPoseChanged.Disable();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
StateChanged.Dispose();
|
||||
StateFinalized.Dispose();
|
||||
GPoseChanged.Dispose();
|
||||
}
|
||||
|
||||
|
|
@ -73,86 +84,88 @@ public class StateIpcTester : IUiService, IDisposable
|
|||
IpcTesterHelpers.DrawIntro("Last Error");
|
||||
ImGui.TextUnformatted(_lastError.ToString());
|
||||
IpcTesterHelpers.DrawIntro("Last State Change");
|
||||
PrintName();
|
||||
PrintChangeName();
|
||||
IpcTesterHelpers.DrawIntro("Last State Finalization");
|
||||
PrintFinalizeName();
|
||||
IpcTesterHelpers.DrawIntro("Last GPose Change");
|
||||
ImGui.TextUnformatted($"{_lastGPoseChangeValue} at {_lastGPoseChangeTime.ToLocalTime().TimeOfDay}");
|
||||
|
||||
|
||||
IpcTesterHelpers.DrawIntro(GetState.Label);
|
||||
DrawStatePopup();
|
||||
if (ImGui.Button("Get##Idx"))
|
||||
if (ImUtf8.Button("Get##Idx"u8))
|
||||
{
|
||||
(_lastError, _state) = new GetState(_pluginInterface).Invoke(_gameObjectIndex, _key);
|
||||
_stateString = _state?.ToString(Formatting.Indented) ?? "No State Available";
|
||||
ImGui.OpenPopup("State");
|
||||
ImUtf8.OpenPopup("State"u8);
|
||||
}
|
||||
|
||||
IpcTesterHelpers.DrawIntro(GetStateName.Label);
|
||||
if (ImGui.Button("Get##Name"))
|
||||
if (ImUtf8.Button("Get##Name"u8))
|
||||
{
|
||||
(_lastError, _state) = new GetStateName(_pluginInterface).Invoke(_gameObjectName, _key);
|
||||
_stateString = _state?.ToString(Formatting.Indented) ?? "No State Available";
|
||||
ImGui.OpenPopup("State");
|
||||
ImUtf8.OpenPopup("State"u8);
|
||||
}
|
||||
|
||||
IpcTesterHelpers.DrawIntro(GetStateBase64.Label);
|
||||
if (ImGui.Button("Get##Base64Idx"))
|
||||
if (ImUtf8.Button("Get##Base64Idx"u8))
|
||||
{
|
||||
(_lastError, _getStateString) = new GetStateBase64(_pluginInterface).Invoke(_gameObjectIndex, _key);
|
||||
_stateString = _getStateString ?? "No State Available";
|
||||
ImGui.OpenPopup("State");
|
||||
ImUtf8.OpenPopup("State"u8);
|
||||
}
|
||||
|
||||
IpcTesterHelpers.DrawIntro(GetStateBase64Name.Label);
|
||||
if (ImGui.Button("Get##Base64Idx"))
|
||||
if (ImUtf8.Button("Get##Base64Idx"u8))
|
||||
{
|
||||
(_lastError, _getStateString) = new GetStateBase64Name(_pluginInterface).Invoke(_gameObjectName, _key);
|
||||
_stateString = _getStateString ?? "No State Available";
|
||||
ImGui.OpenPopup("State");
|
||||
ImUtf8.OpenPopup("State"u8);
|
||||
}
|
||||
|
||||
IpcTesterHelpers.DrawIntro(ApplyState.Label);
|
||||
if (ImGuiUtil.DrawDisabledButton("Apply Last##Idx", Vector2.Zero, string.Empty, _state == null))
|
||||
_lastError = new ApplyState(_pluginInterface).Invoke(_state!, _gameObjectIndex, _key, _flags);
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Apply Base64##Idx"))
|
||||
if (ImUtf8.Button("Apply Base64##Idx"u8))
|
||||
_lastError = new ApplyState(_pluginInterface).Invoke(_base64State, _gameObjectIndex, _key, _flags);
|
||||
|
||||
IpcTesterHelpers.DrawIntro(ApplyStateName.Label);
|
||||
if (ImGuiUtil.DrawDisabledButton("Apply Last##Name", Vector2.Zero, string.Empty, _state == null))
|
||||
_lastError = new ApplyStateName(_pluginInterface).Invoke(_state!, _gameObjectName, _key, _flags);
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Apply Base64##Name"))
|
||||
if (ImUtf8.Button("Apply Base64##Name"u8))
|
||||
_lastError = new ApplyStateName(_pluginInterface).Invoke(_base64State, _gameObjectName, _key, _flags);
|
||||
|
||||
IpcTesterHelpers.DrawIntro(RevertState.Label);
|
||||
if (ImGui.Button("Revert##Idx"))
|
||||
if (ImUtf8.Button("Revert##Idx"u8))
|
||||
_lastError = new RevertState(_pluginInterface).Invoke(_gameObjectIndex, _key, _flags);
|
||||
|
||||
IpcTesterHelpers.DrawIntro(RevertStateName.Label);
|
||||
if (ImGui.Button("Revert##Name"))
|
||||
if (ImUtf8.Button("Revert##Name"u8))
|
||||
_lastError = new RevertStateName(_pluginInterface).Invoke(_gameObjectName, _key, _flags);
|
||||
|
||||
IpcTesterHelpers.DrawIntro(UnlockState.Label);
|
||||
if (ImGui.Button("Unlock##Idx"))
|
||||
if (ImUtf8.Button("Unlock##Idx"u8))
|
||||
_lastError = new UnlockState(_pluginInterface).Invoke(_gameObjectIndex, _key);
|
||||
|
||||
IpcTesterHelpers.DrawIntro(UnlockStateName.Label);
|
||||
if (ImGui.Button("Unlock##Name"))
|
||||
if (ImUtf8.Button("Unlock##Name"u8))
|
||||
_lastError = new UnlockStateName(_pluginInterface).Invoke(_gameObjectName, _key);
|
||||
|
||||
IpcTesterHelpers.DrawIntro(UnlockAll.Label);
|
||||
if (ImGui.Button("Unlock##All"))
|
||||
if (ImUtf8.Button("Unlock##All"u8))
|
||||
_numUnlocked = new UnlockAll(_pluginInterface).Invoke(_key);
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted($"Unlocked {_numUnlocked}");
|
||||
|
||||
IpcTesterHelpers.DrawIntro(RevertToAutomation.Label);
|
||||
if (ImGui.Button("Revert##AutomationIdx"))
|
||||
if (ImUtf8.Button("Revert##AutomationIdx"u8))
|
||||
_lastError = new RevertToAutomation(_pluginInterface).Invoke(_gameObjectIndex, _key, _flags);
|
||||
|
||||
IpcTesterHelpers.DrawIntro(RevertToAutomationName.Label);
|
||||
if (ImGui.Button("Revert##AutomationName"))
|
||||
if (ImUtf8.Button("Revert##AutomationName"u8))
|
||||
_lastError = new RevertToAutomationName(_pluginInterface).Invoke(_gameObjectName, _key, _flags);
|
||||
}
|
||||
|
||||
|
|
@ -162,44 +175,70 @@ public class StateIpcTester : IUiService, IDisposable
|
|||
if (_stateString == null)
|
||||
return;
|
||||
|
||||
using var p = ImRaii.Popup("State");
|
||||
using var p = ImUtf8.Popup("State"u8);
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
if (ImGui.Button("Copy to Clipboard"))
|
||||
ImGui.SetClipboardText(_stateString);
|
||||
if (ImUtf8.Button("Copy to Clipboard"u8))
|
||||
ImUtf8.SetClipboardText(_stateString);
|
||||
if (_stateString[0] is '{')
|
||||
{
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Copy as Base64") && _state != null)
|
||||
ImGui.SetClipboardText(DesignConverter.ToBase64(_state));
|
||||
if (ImUtf8.Button("Copy as Base64"u8) && _state != null)
|
||||
ImUtf8.SetClipboardText(DesignConverter.ToBase64(_state));
|
||||
}
|
||||
|
||||
using var font = ImRaii.PushFont(UiBuilder.MonoFont);
|
||||
ImGuiUtil.TextWrapped(_stateString ?? string.Empty);
|
||||
ImUtf8.TextWrapped(_stateString ?? string.Empty);
|
||||
|
||||
if (ImGui.Button("Close", -Vector2.UnitX) || !ImGui.IsWindowFocused())
|
||||
if (ImUtf8.Button("Close"u8, -Vector2.UnitX) || !ImGui.IsWindowFocused())
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
private unsafe void PrintName()
|
||||
private unsafe void PrintChangeName()
|
||||
{
|
||||
ImGuiNative.igTextUnformatted(_lastStateChangeName.Path, _lastStateChangeName.Path + _lastStateChangeName.Length);
|
||||
ImUtf8.Text(_lastStateChangeName.Span);
|
||||
ImGui.SameLine(0, 0);
|
||||
ImUtf8.Text($" ({_lastStateChangeType})");
|
||||
ImGui.SameLine();
|
||||
using (ImRaii.PushFont(UiBuilder.MonoFont))
|
||||
{
|
||||
ImGuiUtil.CopyOnClickSelectable($"0x{_lastStateChangeActor:X}");
|
||||
ImUtf8.CopyOnClickSelectable($"0x{_lastStateChangeActor:X}");
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted($"at {_lastStateChangeTime.ToLocalTime().TimeOfDay}");
|
||||
ImUtf8.Text($"at {_lastStateChangeTime.ToLocalTime().TimeOfDay}");
|
||||
}
|
||||
|
||||
private void OnStateChanged(nint actor, StateChangeType _)
|
||||
private unsafe void PrintFinalizeName()
|
||||
{
|
||||
ImUtf8.Text(_lastStateFinalizeName.Span);
|
||||
ImGui.SameLine(0, 0);
|
||||
ImUtf8.Text($" ({_lastStateFinalizeType})");
|
||||
ImGui.SameLine();
|
||||
using (ImRaii.PushFont(UiBuilder.MonoFont))
|
||||
{
|
||||
ImUtf8.CopyOnClickSelectable($"0x{_lastStateFinalizeActor:X}");
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImUtf8.Text($"at {_lastStateFinalizeTime.ToLocalTime().TimeOfDay}");
|
||||
}
|
||||
|
||||
private void OnStateChanged(nint actor, StateChangeType type)
|
||||
{
|
||||
_lastStateChangeActor = actor;
|
||||
_lastStateChangeTime = DateTime.UtcNow;
|
||||
_lastStateChangeName = actor != nint.Zero ? ((Actor)actor).Utf8Name.Clone() : ByteString.Empty;
|
||||
_lastStateChangeType = type;
|
||||
}
|
||||
|
||||
private void OnStateFinalized(nint actor, StateFinalizationType type)
|
||||
{
|
||||
_lastStateFinalizeActor = actor;
|
||||
_lastStateFinalizeTime = DateTime.UtcNow;
|
||||
_lastStateFinalizeName = actor != nint.Zero ? ((Actor)actor).Utf8Name.Clone() : ByteString.Empty;
|
||||
_lastStateFinalizeType = type;
|
||||
}
|
||||
|
||||
private void OnGPoseChange(bool value)
|
||||
|
|
|
|||
|
|
@ -460,7 +460,7 @@ public class DesignPanel
|
|||
if (_state.GetOrCreate(id, data.Objects[0], out var state))
|
||||
{
|
||||
using var _ = _selector.Selected!.TemporarilyRestrictApplication(ApplicationCollection.FromKeys());
|
||||
_state.ApplyDesign(state, _selector.Selected!, ApplySettings.ManualWithLinks with { SendStateUpdate = true });
|
||||
_state.ApplyDesign(state, _selector.Selected!, ApplySettings.ManualWithLinks with { IsFinal = true });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -478,7 +478,7 @@ public class DesignPanel
|
|||
if (_state.GetOrCreate(id, data.Objects[0], out var state))
|
||||
{
|
||||
using var _ = _selector.Selected!.TemporarilyRestrictApplication(ApplicationCollection.FromKeys());
|
||||
_state.ApplyDesign(state, _selector.Selected!, ApplySettings.ManualWithLinks with { SendStateUpdate = true });
|
||||
_state.ApplyDesign(state, _selector.Selected!, ApplySettings.ManualWithLinks with { IsFinal = true });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ public class NpcPanel
|
|||
if (_state.GetOrCreate(id, data.Objects[0], out var state))
|
||||
{
|
||||
var design = _converter.Convert(ToDesignData(), new StateMaterialManager(), ApplicationRules.NpcFromModifiers());
|
||||
_state.ApplyDesign(state, design, ApplySettings.Manual with { SendStateUpdate = true });
|
||||
_state.ApplyDesign(state, design, ApplySettings.Manual with { IsFinal = true });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ public class NpcPanel
|
|||
if (_state.GetOrCreate(id, data.Objects[0], out var state))
|
||||
{
|
||||
var design = _converter.Convert(ToDesignData(), new StateMaterialManager(), ApplicationRules.NpcFromModifiers());
|
||||
_state.ApplyDesign(state, design, ApplySettings.Manual with { SendStateUpdate = true });
|
||||
_state.ApplyDesign(state, design, ApplySettings.Manual with { IsFinal = true });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public unsafe class UpdateSlotService : IDisposable
|
|||
public readonly BonusSlotUpdating BonusSlotUpdatingEvent;
|
||||
public readonly GearsetDataLoaded GearsetDataLoadedEvent;
|
||||
private readonly DictBonusItems _bonusItems;
|
||||
|
||||
public UpdateSlotService(EquipSlotUpdating equipSlotUpdating, BonusSlotUpdating bonusSlotUpdating, GearsetDataLoaded gearsetDataLoaded,
|
||||
IGameInteropProvider interop, DictBonusItems bonusItems)
|
||||
{
|
||||
|
|
@ -26,8 +27,8 @@ public unsafe class UpdateSlotService : IDisposable
|
|||
GearsetDataLoadedEvent = gearsetDataLoaded;
|
||||
_bonusItems = bonusItems;
|
||||
|
||||
_loadGearsetDataHook = interop.HookFromAddress<LoadGearsetDataDelegate>((nint)DrawDataContainer.MemberFunctionPointers.LoadGearsetData, LoadGearsetDataDetour);
|
||||
interop.InitializeFromAttributes(this);
|
||||
_loadGearsetDataHook = interop.HookFromAddress<LoadGearsetDataDelegate>((nint)DrawDataContainer.MemberFunctionPointers.LoadGearsetData, LoadGearsetDataDetour);
|
||||
_flagSlotForUpdateHook.Enable();
|
||||
_flagBonusSlotForUpdateHook.Enable();
|
||||
_loadGearsetDataHook.Enable();
|
||||
|
|
@ -89,8 +90,8 @@ public unsafe class UpdateSlotService : IDisposable
|
|||
/// <summary> Detours the func that makes all FlagSlotForUpdate calls on a gearset change or initial render of a given actor (Only Cases this is Called).
|
||||
/// <para> Logic done after returning the original hook executes <b>After</b> all equipment/weapon/crest data is loaded into the Actors BaseData. </para>
|
||||
/// </summary>
|
||||
private delegate Int64 LoadGearsetDataDelegate(DrawDataContainer* drawDataContainer, PacketPlayerGearsetData* gearsetData);
|
||||
private readonly Hook<LoadGearsetDataDelegate> _loadGearsetDataHook = null!;
|
||||
private delegate ulong LoadGearsetDataDelegate(DrawDataContainer* drawDataContainer, PacketPlayerGearsetData* gearsetData);
|
||||
private readonly Hook<LoadGearsetDataDelegate> _loadGearsetDataHook;
|
||||
|
||||
private ulong FlagSlotForUpdateDetour(nint drawObject, uint slotIdx, CharacterArmor* data)
|
||||
{
|
||||
|
|
@ -115,30 +116,30 @@ public unsafe class UpdateSlotService : IDisposable
|
|||
Glamourer.Log.Excessive($"[FlagBonusSlotForUpdate] Glamourer-Invoked on 0x{drawObject.Address:X} on {slot} with item data {armor}.");
|
||||
return _flagSlotForUpdateHook.Original(drawObject.Address, slot.ToIndex(), &armor);
|
||||
}
|
||||
private Int64 LoadGearsetDataDetour(DrawDataContainer* drawDataContainer, PacketPlayerGearsetData* gearsetData)
|
||||
private ulong LoadGearsetDataDetour(DrawDataContainer* drawDataContainer, PacketPlayerGearsetData* gearsetData)
|
||||
{
|
||||
var ret = _loadGearsetDataHook.Original(drawDataContainer, gearsetData);
|
||||
Model drawObject = drawDataContainer->OwnerObject->DrawObject;
|
||||
var drawObject = drawDataContainer->OwnerObject->DrawObject;
|
||||
GearsetDataLoadedEvent.Invoke(drawObject);
|
||||
// Glamourer.Log.Excessive($"[LoadAllEquipmentDetour] GearsetItemData: {FormatGearsetItemDataStruct(*gearsetData)}");
|
||||
Glamourer.Log.Excessive($"[LoadAllEquipmentDetour] GearsetItemData: {FormatGearsetItemDataStruct(*gearsetData)}");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// If you ever care to debug this, here is a formatted string output of this new gearsetData struct.
|
||||
private string FormatGearsetItemDataStruct(PacketPlayerGearsetData gearsetData)
|
||||
|
||||
private static string FormatGearsetItemDataStruct(PacketPlayerGearsetData gearsetData)
|
||||
{
|
||||
string ret =
|
||||
var ret =
|
||||
$"\nMainhandWeaponData: Id: {gearsetData.MainhandWeaponData.Id}, Type: {gearsetData.MainhandWeaponData.Type}, " +
|
||||
$"Variant: {gearsetData.MainhandWeaponData.Variant}, Stain0: {gearsetData.MainhandWeaponData.Stain0}, Stain1: {gearsetData.MainhandWeaponData.Stain1}" +
|
||||
$"\nOffhandWeaponData: Id: {gearsetData.OffhandWeaponData.Id}, Type: {gearsetData.OffhandWeaponData.Type}, " +
|
||||
$"Variant: {gearsetData.OffhandWeaponData.Variant}, Stain0: {gearsetData.OffhandWeaponData.Stain0}, Stain1: {gearsetData.OffhandWeaponData.Stain1}" +
|
||||
$"\nCrestBitField: {gearsetData.CrestBitField} | JobId: {gearsetData.JobId}";
|
||||
for (int offset = 20; offset <= 56; offset += sizeof(LegacyCharacterArmor))
|
||||
for (var offset = 20; offset <= 56; offset += sizeof(LegacyCharacterArmor))
|
||||
{
|
||||
LegacyCharacterArmor* equipSlotPtr = (LegacyCharacterArmor*)((byte*)&gearsetData + offset);
|
||||
int dyeOffset = (offset - 20) / sizeof(LegacyCharacterArmor) + 60; // Calculate the corresponding dye offset
|
||||
byte* dyePtr = (byte*)&gearsetData + dyeOffset;
|
||||
ret += $"\nEquipSlot {((EquipSlot)(dyeOffset - 60)).ToString()}:: Id: {(*equipSlotPtr).Set}, Variant: {(*equipSlotPtr).Variant}, Stain0: {(*equipSlotPtr).Stain.Id}, Stain1: {*dyePtr}";
|
||||
var equipSlotPtr = (LegacyCharacterArmor*)((byte*)&gearsetData + offset);
|
||||
var dyeOffset = (offset - 20) / sizeof(LegacyCharacterArmor) + 60; // Calculate the corresponding dye offset
|
||||
var dyePtr = (byte*)&gearsetData + dyeOffset;
|
||||
ret += $"\nEquipSlot {(EquipSlot)(dyeOffset - 60)}:: Id: {(*equipSlotPtr).Set}, Variant: {(*equipSlotPtr).Variant}, Stain0: {(*equipSlotPtr).Stain.Id}, Stain1: {*dyePtr}";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -668,7 +668,7 @@ public class CommandService : IDisposable, IApiService
|
|||
if (!_objects.TryGetValue(identifier, out var actors))
|
||||
{
|
||||
if (_stateManager.TryGetValue(identifier, out var state))
|
||||
_stateManager.ApplyDesign(state, design, ApplySettings.ManualWithLinks with { SendStateUpdate = true });
|
||||
_stateManager.ApplyDesign(state, design, ApplySettings.ManualWithLinks with { IsFinal = true });
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -677,7 +677,7 @@ public class CommandService : IDisposable, IApiService
|
|||
if (_stateManager.GetOrCreate(actor.GetIdentifier(_actors), actor, out var state))
|
||||
{
|
||||
ApplyModSettings(design, actor, applyMods);
|
||||
_stateManager.ApplyDesign(state, design, ApplySettings.ManualWithLinks with { SendStateUpdate = true });
|
||||
_stateManager.ApplyDesign(state, design, ApplySettings.ManualWithLinks with { IsFinal = true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public class StateEditor(
|
|||
InternalStateEditor editor,
|
||||
StateApplier applier,
|
||||
StateChanged stateChanged,
|
||||
StateUpdated stateUpdated,
|
||||
StateFinalized stateFinalized,
|
||||
JobChangeState jobChange,
|
||||
Configuration config,
|
||||
ItemManager items,
|
||||
|
|
@ -25,12 +25,12 @@ public class StateEditor(
|
|||
ModSettingApplier modApplier,
|
||||
GPoseService gPose) : IDesignEditor
|
||||
{
|
||||
protected readonly InternalStateEditor Editor = editor;
|
||||
protected readonly StateApplier Applier = applier;
|
||||
protected readonly StateChanged StateChanged = stateChanged;
|
||||
protected readonly StateUpdated StateUpdated = stateUpdated;
|
||||
protected readonly Configuration Config = config;
|
||||
protected readonly ItemManager Items = items;
|
||||
protected readonly InternalStateEditor Editor = editor;
|
||||
protected readonly StateApplier Applier = applier;
|
||||
protected readonly StateChanged StateChanged = stateChanged;
|
||||
protected readonly StateFinalized StateFinalized = stateFinalized;
|
||||
protected readonly Configuration Config = config;
|
||||
protected readonly ItemManager Items = items;
|
||||
|
||||
/// <summary> Turn an actor to. </summary>
|
||||
public void ChangeModelId(ActorState state, uint modelId, CustomizeArray customize, nint equipData, StateSource source,
|
||||
|
|
@ -43,7 +43,7 @@ public class StateEditor(
|
|||
Glamourer.Log.Verbose(
|
||||
$"Set model id in state {state.Identifier.Incognito(null)} from {old} to {modelId}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
StateChanged.Invoke(StateChangeType.Model, source, state, actors, null);
|
||||
StateUpdated.Invoke(StateFinalizationType.ModelChange, actors);
|
||||
StateFinalized.Invoke(StateFinalizationType.ModelChange, actors);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
@ -383,7 +383,7 @@ public class StateEditor(
|
|||
Editor.ChangeMetaState(state, meta, mergedDesign.Design.DesignData.GetMeta(meta), Source(meta), out _, settings.Key);
|
||||
}
|
||||
|
||||
if (settings.ResetMaterials || (!settings.RespectManual && mergedDesign.ResetAdvancedDyes))
|
||||
if (settings.ResetMaterials || !settings.RespectManual && mergedDesign.ResetAdvancedDyes)
|
||||
state.Materials.Clear();
|
||||
|
||||
foreach (var (key, value) in mergedDesign.Design.Materials)
|
||||
|
|
@ -420,8 +420,8 @@ public class StateEditor(
|
|||
Glamourer.Log.Verbose(
|
||||
$"Applied design to {state.Identifier.Incognito(null)}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
StateChanged.Invoke(StateChangeType.Design, state.Sources[MetaIndex.Wetness], state, actors, null); // FIXME: maybe later
|
||||
if(settings.SendStateUpdate)
|
||||
StateUpdated.Invoke(StateFinalizationType.DesignApplied, actors);
|
||||
if (settings.IsFinal)
|
||||
StateFinalized.Invoke(StateFinalizationType.DesignApplied, actors);
|
||||
|
||||
return;
|
||||
|
||||
|
|
@ -442,7 +442,8 @@ public class StateEditor(
|
|||
if (!settings.MergeLinks || design is not Design d)
|
||||
merged = new MergedDesign(design);
|
||||
else
|
||||
merged = merger.Merge(d.AllLinks(true), state.ModelData.IsHuman ? state.ModelData.Customize : CustomizeArray.Default, state.BaseData,
|
||||
merged = merger.Merge(d.AllLinks(true), state.ModelData.IsHuman ? state.ModelData.Customize : CustomizeArray.Default,
|
||||
state.BaseData,
|
||||
false, Config.AlwaysApplyAssociatedMods);
|
||||
|
||||
ApplyDesign(data, merged, settings with
|
||||
|
|
@ -460,7 +461,7 @@ public class StateEditor(
|
|||
if (!Config.ChangeEntireItem || !settings.Source.IsManual())
|
||||
return;
|
||||
|
||||
var mh = newMainhand ?? state.ModelData.Item(EquipSlot.MainHand);
|
||||
var mh = newMainhand ?? state.ModelData.Item(EquipSlot.MainHand);
|
||||
// Do not change Shields to nothing.
|
||||
if (mh.Type is FullEquipType.Sword)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public class StateListener : IDisposable
|
|||
private readonly HeadGearVisibilityChanged _headGearVisibility;
|
||||
private readonly VisorStateChanged _visorState;
|
||||
private readonly WeaponVisibilityChanged _weaponVisibility;
|
||||
private readonly StateUpdated _stateUpdated;
|
||||
private readonly StateFinalized _stateFinalized;
|
||||
private readonly AutoDesignApplier _autoDesignApplier;
|
||||
private readonly FunModule _funModule;
|
||||
private readonly HumanModelList _humans;
|
||||
|
|
@ -63,7 +63,7 @@ public class StateListener : IDisposable
|
|||
WeaponVisibilityChanged weaponVisibility, HeadGearVisibilityChanged headGearVisibility, AutoDesignApplier autoDesignApplier,
|
||||
FunModule funModule, HumanModelList humans, StateApplier applier, MovedEquipment movedEquipment, ObjectManager objects,
|
||||
GPoseService gPose, ChangeCustomizeService changeCustomizeService, CustomizeService customizations, ICondition condition,
|
||||
CrestService crestService, BonusSlotUpdating bonusSlotUpdating, StateUpdated stateUpdated)
|
||||
CrestService crestService, BonusSlotUpdating bonusSlotUpdating, StateFinalized stateFinalized)
|
||||
{
|
||||
_manager = manager;
|
||||
_items = items;
|
||||
|
|
@ -88,7 +88,7 @@ public class StateListener : IDisposable
|
|||
_condition = condition;
|
||||
_crestService = crestService;
|
||||
_bonusSlotUpdating = bonusSlotUpdating;
|
||||
_stateUpdated = stateUpdated;
|
||||
_stateFinalized = stateFinalized;
|
||||
Subscribe();
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +281,7 @@ public class StateListener : IDisposable
|
|||
|
||||
_objects.Update();
|
||||
if (_objects.TryGetValue(identifier, out var actors) && actors.Valid)
|
||||
_stateUpdated.Invoke(StateFinalizationType.Gearset, actors);
|
||||
_stateFinalized.Invoke(StateFinalizationType.Gearset, actors);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,20 +18,20 @@ using Penumbra.GameData.Interop;
|
|||
namespace Glamourer.State;
|
||||
|
||||
public sealed class StateManager(
|
||||
ActorManager _actors,
|
||||
ActorManager actors,
|
||||
ItemManager items,
|
||||
StateChanged @event,
|
||||
StateUpdated @event2,
|
||||
StateChanged changeEvent,
|
||||
StateFinalized finalizeEvent,
|
||||
StateApplier applier,
|
||||
InternalStateEditor editor,
|
||||
HumanModelList _humans,
|
||||
IClientState _clientState,
|
||||
HumanModelList humans,
|
||||
IClientState clientState,
|
||||
Configuration config,
|
||||
JobChangeState jobChange,
|
||||
DesignMerger merger,
|
||||
ModSettingApplier modApplier,
|
||||
GPoseService gPose)
|
||||
: StateEditor(editor, applier, @event, @event2, jobChange, config, items, merger, modApplier, gPose),
|
||||
: StateEditor(editor, applier, changeEvent, finalizeEvent, jobChange, config, items, merger, modApplier, gPose),
|
||||
IReadOnlyDictionary<ActorIdentifier, ActorState>
|
||||
{
|
||||
private readonly Dictionary<ActorIdentifier, ActorState> _states = [];
|
||||
|
|
@ -62,7 +62,7 @@ public sealed class StateManager(
|
|||
|
||||
/// <inheritdoc cref="GetOrCreate(ActorIdentifier, Actor, out ActorState?)"/>
|
||||
public bool GetOrCreate(Actor actor, [NotNullWhen(true)] out ActorState? state)
|
||||
=> GetOrCreate(actor.GetIdentifier(_actors), actor, out state);
|
||||
=> GetOrCreate(actor.GetIdentifier(actors), actor, out state);
|
||||
|
||||
/// <summary> Try to obtain or create a new state for an existing actor. Returns false if no state could be created. </summary>
|
||||
public unsafe bool GetOrCreate(ActorIdentifier identifier, Actor actor, [NotNullWhen(true)] out ActorState? state)
|
||||
|
|
@ -82,7 +82,7 @@ public sealed class StateManager(
|
|||
ModelData = FromActor(actor, true, false),
|
||||
BaseData = FromActor(actor, false, false),
|
||||
LastJob = (byte)(actor.IsCharacter ? actor.AsCharacter->CharacterData.ClassJob : 0),
|
||||
LastTerritory = _clientState.TerritoryType,
|
||||
LastTerritory = clientState.TerritoryType,
|
||||
};
|
||||
// state.Identifier is owned.
|
||||
_states.Add(state.Identifier, state);
|
||||
|
|
@ -115,7 +115,7 @@ public sealed class StateManager(
|
|||
// Model ID is only unambiguously contained in the game object.
|
||||
// The draw object only has the object type.
|
||||
// TODO reverse search model data to get model id from model.
|
||||
if (!_humans.IsHuman((uint)actor.AsCharacter->ModelContainer.ModelCharaId))
|
||||
if (!humans.IsHuman((uint)actor.AsCharacter->ModelContainer.ModelCharaId))
|
||||
{
|
||||
ret.LoadNonHuman((uint)actor.AsCharacter->ModelContainer.ModelCharaId, *(CustomizeArray*)&actor.AsCharacter->DrawData.CustomizeData,
|
||||
(nint)Unsafe.AsPointer(ref actor.AsCharacter->DrawData.EquipmentModelIds[0]));
|
||||
|
|
@ -236,7 +236,7 @@ public sealed class StateManager(
|
|||
public void TurnHuman(ActorState state, StateSource source, uint key = 0)
|
||||
=> ChangeModelId(state, 0, CustomizeArray.Default, nint.Zero, source, key);
|
||||
|
||||
public void ResetState(ActorState state, StateSource source, uint key = 0, bool stateUpdate = false)
|
||||
public void ResetState(ActorState state, StateSource source, uint key = 0, bool isFinal = false)
|
||||
{
|
||||
if (!state.Unlock(key))
|
||||
return;
|
||||
|
|
@ -278,8 +278,8 @@ public sealed class StateManager(
|
|||
$"Reset entire state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
StateChanged.Invoke(StateChangeType.Reset, source, state, actors, null);
|
||||
// only invoke if we define this reset call as the final call in our state update.
|
||||
if(stateUpdate)
|
||||
StateUpdated.Invoke(StateFinalizationType.Revert, actors);
|
||||
if(isFinal)
|
||||
StateFinalized.Invoke(StateFinalizationType.Revert, actors);
|
||||
}
|
||||
|
||||
public void ResetAdvancedState(ActorState state, StateSource source, uint key = 0)
|
||||
|
|
@ -306,7 +306,7 @@ public sealed class StateManager(
|
|||
$"Reset advanced customization and dye state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
StateChanged.Invoke(StateChangeType.Reset, source, state, actors, null);
|
||||
// Update that we have completed a full operation. (We can do this directly as nothing else is linked)
|
||||
StateUpdated.Invoke(StateFinalizationType.RevertAdvanced, actors);
|
||||
StateFinalized.Invoke(StateFinalizationType.RevertAdvanced, actors);
|
||||
}
|
||||
|
||||
public void ResetCustomize(ActorState state, StateSource source, uint key = 0)
|
||||
|
|
@ -325,7 +325,7 @@ public sealed class StateManager(
|
|||
Glamourer.Log.Verbose(
|
||||
$"Reset customization state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
// Update that we have completed a full operation. (We can do this directly as nothing else is linked)
|
||||
StateUpdated.Invoke(StateFinalizationType.RevertCustomize, actors);
|
||||
StateFinalized.Invoke(StateFinalizationType.RevertCustomize, actors);
|
||||
}
|
||||
|
||||
public void ResetEquip(ActorState state, StateSource source, uint key = 0)
|
||||
|
|
@ -376,7 +376,7 @@ public sealed class StateManager(
|
|||
Glamourer.Log.Verbose(
|
||||
$"Reset equipment state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
// Update that we have completed a full operation. (We can do this directly as nothing else is linked)
|
||||
StateUpdated.Invoke(StateFinalizationType.RevertEquipment, actors);
|
||||
StateFinalized.Invoke(StateFinalizationType.RevertEquipment, actors);
|
||||
}
|
||||
|
||||
public void ResetStateFixed(ActorState state, bool respectManualPalettes, uint key = 0)
|
||||
|
|
@ -453,23 +453,23 @@ public sealed class StateManager(
|
|||
}
|
||||
}
|
||||
|
||||
public void ReapplyState(Actor actor, bool forceRedraw, StateSource source, bool stateUpdate = false)
|
||||
public void ReapplyState(Actor actor, bool forceRedraw, StateSource source, bool isFinal = false)
|
||||
{
|
||||
if (!GetOrCreate(actor, out var state))
|
||||
return;
|
||||
|
||||
ReapplyState(actor, state, forceRedraw, source, stateUpdate);
|
||||
ReapplyState(actor, state, forceRedraw, source, isFinal);
|
||||
}
|
||||
|
||||
public void ReapplyState(Actor actor, ActorState state, bool forceRedraw, StateSource source, bool stateUpdate)
|
||||
public void ReapplyState(Actor actor, ActorState state, bool forceRedraw, StateSource source, bool isFinal)
|
||||
{
|
||||
var data = Applier.ApplyAll(state,
|
||||
forceRedraw
|
||||
|| !actor.Model.IsHuman
|
||||
|| CustomizeArray.Compare(actor.Model.GetCustomize(), state.ModelData.Customize).RequiresRedraw(), false);
|
||||
StateChanged.Invoke(StateChangeType.Reapply, source, state, data, null);
|
||||
if(stateUpdate)
|
||||
StateUpdated.Invoke(StateFinalizationType.Reapply, data);
|
||||
if(isFinal)
|
||||
StateFinalized.Invoke(StateFinalizationType.Reapply, data);
|
||||
}
|
||||
|
||||
/// <summary> Automation variant for reapply, to fire the correct StateUpdateType once reapplied. </summary>
|
||||
|
|
@ -490,7 +490,7 @@ public sealed class StateManager(
|
|||
|| CustomizeArray.Compare(actor.Model.GetCustomize(), state.ModelData.Customize).RequiresRedraw(), false);
|
||||
StateChanged.Invoke(StateChangeType.Reapply, source, state, data, null);
|
||||
// invoke the automation update based on what reset is.
|
||||
StateUpdated.Invoke(wasReset ? StateFinalizationType.RevertAutomation : StateFinalizationType.ReapplyAutomation, data);
|
||||
StateFinalized.Invoke(wasReset ? StateFinalizationType.RevertAutomation : StateFinalizationType.ReapplyAutomation, data);
|
||||
}
|
||||
|
||||
public void DeleteState(ActorIdentifier identifier)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue