Fix issue with Penumbra load order and visor state.

This commit is contained in:
Ottermandias 2024-06-15 11:52:38 +02:00
parent 205a95b254
commit 5cf6b0eb75
3 changed files with 31 additions and 6 deletions

View file

@ -12,5 +12,8 @@ public sealed class PenumbraReloaded()
{
/// <seealso cref="Interop.ChangeCustomizeService.Restore"/>
ChangeCustomizeService = 0,
/// <seealso cref="Interop.VisorService.Restore"/>
VisorService = 0,
}
}

View file

@ -9,17 +9,24 @@ namespace Glamourer.Interop;
public class VisorService : IDisposable
{
public readonly VisorStateChanged Event;
private readonly PenumbraReloaded _penumbra;
private readonly IGameInteropProvider _interop;
public readonly VisorStateChanged Event;
public unsafe VisorService(VisorStateChanged visorStateChanged, IGameInteropProvider interop)
public VisorService(VisorStateChanged visorStateChanged, IGameInteropProvider interop, PenumbraReloaded penumbra)
{
_interop = interop;
_penumbra = penumbra;
Event = visorStateChanged;
_setupVisorHook = interop.HookFromAddress<UpdateVisorDelegateInternal>((nint)Human.MemberFunctionPointers.SetupVisor, SetupVisorDetour);
_setupVisorHook.Enable();
_setupVisorHook = Create();
_penumbra.Subscribe(Restore, PenumbraReloaded.Priority.VisorService);
}
public void Dispose()
=> _setupVisorHook.Dispose();
{
_setupVisorHook.Dispose();
_penumbra.Unsubscribe(Restore);
}
/// <summary> Obtain the current state of the Visor for the given draw object (true: toggled). </summary>
public static unsafe bool GetVisorState(Model characterBase)
@ -45,7 +52,7 @@ public class VisorService : IDisposable
private delegate void UpdateVisorDelegateInternal(nint humanPtr, ushort modelId, byte on);
private readonly Hook<UpdateVisorDelegateInternal> _setupVisorHook;
private Hook<UpdateVisorDelegateInternal> _setupVisorHook;
private void SetupVisorDetour(nint human, ushort modelId, byte value)
{
@ -72,4 +79,17 @@ public class VisorService : IDisposable
human.AsCharacterBase->VisorToggled = on;
_setupVisorHook.Original(human.Address, modelId, on ? (byte)1 : (byte)0);
}
private unsafe Hook<UpdateVisorDelegateInternal> Create()
{
var hook = _interop.HookFromAddress<UpdateVisorDelegateInternal>((nint)Human.MemberFunctionPointers.SetupVisor, SetupVisorDetour);
hook.Enable();
return hook;
}
private void Restore()
{
_setupVisorHook.Dispose();
_setupVisorHook = Create();
}
}

View file

@ -578,6 +578,8 @@ public class StateListener : IDisposable
// We do not need to handle fixed designs,
// since a fixed design would already have established state-tracking.
var actor = _penumbra.GameObjectFromDrawObject(model);
if (!actor.IsCharacter)
return;
// Only actually change anything if the actor state changed,
// when equipping headgear the method is called with the current draw object state,