Do GPose Actor handling correctly.

This commit is contained in:
Ottermandias 2021-08-10 15:15:46 +02:00
parent 53a65aceb7
commit 589dcfd751

View file

@ -31,6 +31,7 @@ namespace Penumbra.Interop
private const int UnloadAllRedrawDelay = 250; private const int UnloadAllRedrawDelay = 250;
private const int NpcActorId = -536870912; private const int NpcActorId = -536870912;
public const int GPosePlayerActorIdx = 201; public const int GPosePlayerActorIdx = 201;
public const int GPoseEndIdx = GPosePlayerActorIdx + 48;
private readonly DalamudPluginInterface _pi; private readonly DalamudPluginInterface _pi;
private readonly ModManager _mods; private readonly ModManager _mods;
@ -46,6 +47,7 @@ namespace Penumbra.Interop
private LoadingFlags _currentActorStartState = 0; private LoadingFlags _currentActorStartState = 0;
private RedrawType _currentActorRedrawType = RedrawType.Unload; private RedrawType _currentActorRedrawType = RedrawType.Unload;
private bool _wasTarget = false; private bool _wasTarget = false;
private bool _inGPose = false;
public static IntPtr RenderPtr( Actor actor ) public static IntPtr RenderPtr( Actor actor )
=> actor.Address + RenderModeOffset; => actor.Address + RenderModeOffset;
@ -83,7 +85,7 @@ namespace Penumbra.Interop
_currentActorStartState = *( LoadingFlags* )renderPtr; _currentActorStartState = *( LoadingFlags* )renderPtr;
*( LoadingFlags* )renderPtr |= LoadingFlags.Invisibility; *( LoadingFlags* )renderPtr |= LoadingFlags.Invisibility;
if( actorIdx == GPosePlayerActorIdx ) if( _inGPose )
{ {
var ptr = ( void*** )actor.Address; var ptr = ( void*** )actor.Address;
var disableDraw = Marshal.GetDelegateForFunctionPointer< ManipulateDraw >( new IntPtr( ptr[ 0 ][ 17 ] ) ); var disableDraw = Marshal.GetDelegateForFunctionPointer< ManipulateDraw >( new IntPtr( ptr[ 0 ][ 17 ] ) );
@ -112,12 +114,12 @@ namespace Penumbra.Interop
return false; return false;
} }
private static unsafe void WriteVisible( Actor actor, int actorIdx ) private unsafe void WriteVisible( Actor actor, int actorIdx )
{ {
var renderPtr = RenderPtr( actor ); var renderPtr = RenderPtr( actor );
*( LoadingFlags* )renderPtr &= ~LoadingFlags.Invisibility; *( LoadingFlags* )renderPtr &= ~LoadingFlags.Invisibility;
if( actorIdx == GPosePlayerActorIdx ) if( _inGPose )
{ {
var ptr = ( void*** )actor.Address; var ptr = ( void*** )actor.Address;
var enableDraw = Marshal.GetDelegateForFunctionPointer< ManipulateDraw >( new IntPtr( ptr[ 0 ][ 16 ] ) ); var enableDraw = Marshal.GetDelegateForFunctionPointer< ManipulateDraw >( new IntPtr( ptr[ 0 ][ 16 ] ) );
@ -140,10 +142,35 @@ namespace Penumbra.Interop
return _currentActorName == actor.Name; return _currentActorName == actor.Name;
} }
private bool CheckActorGPose( Actor actor )
=> actor.ActorId == NpcActorId && _currentActorName == actor.Name;
private (Actor?, int) FindCurrentActor() private (Actor?, int) FindCurrentActor()
{ {
if( _inGPose )
{
for( var i = GPosePlayerActorIdx; i < GPoseEndIdx; ++i )
{
var actor = _pi.ClientState.Actors[ i ];
if( actor == null )
{
break;
}
if( CheckActorGPose( actor ) )
{
return ( actor, i );
}
}
}
for( var i = 0; i < _pi.ClientState.Actors.Length; ++i ) for( var i = 0; i < _pi.ClientState.Actors.Length; ++i )
{ {
if( i == GPosePlayerActorIdx )
{
i = GPoseEndIdx;
}
var actor = _pi.ClientState.Actors[ i ]; var actor = _pi.ClientState.Actors[ i ];
if( actor != null && CheckActor( actor ) ) if( actor != null && CheckActor( actor ) )
{ {
@ -245,8 +272,11 @@ namespace Penumbra.Interop
if( !StillLoading( RenderPtr( actor ) ) ) if( !StillLoading( RenderPtr( actor ) ) )
{ {
RestoreSettings(); RestoreSettings();
if (_wasTarget && _pi.ClientState.Targets.CurrentTarget == null) if( _wasTarget && _pi.ClientState.Targets.CurrentTarget == null )
{
_pi.ClientState.Targets.SetCurrentTarget( actor ); _pi.ClientState.Targets.SetCurrentTarget( actor );
}
_currentFrame = 0; _currentFrame = 0;
} }
} }
@ -272,6 +302,8 @@ namespace Penumbra.Interop
return; return;
} }
_inGPose = _pi.ClientState.Actors[ GPosePlayerActorIdx ] != null;
switch( _currentFrame ) switch( _currentFrame )
{ {
case 0: case 0: