mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Some object reloading changes.
This commit is contained in:
parent
e7282384f5
commit
8d2e84eecf
3 changed files with 353 additions and 387 deletions
|
|
@ -7,24 +7,14 @@ using System.Threading.Tasks;
|
|||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Mods;
|
||||
|
||||
namespace Penumbra.Interop
|
||||
{
|
||||
public class ObjectReloader : IDisposable
|
||||
{
|
||||
private delegate void ManipulateDraw( IntPtr actor );
|
||||
namespace Penumbra.Interop;
|
||||
|
||||
[Flags]
|
||||
public enum LoadingFlags : int
|
||||
{
|
||||
Invisibility = 0x00_00_00_02,
|
||||
IsLoading = 0x00_00_08_00,
|
||||
SomeNpcFlag = 0x00_00_01_00,
|
||||
MaybeCulled = 0x00_00_04_00,
|
||||
MaybeHiddenMinion = 0x00_00_80_00,
|
||||
MaybeHiddenSummon = 0x00_80_00_00,
|
||||
}
|
||||
public unsafe class ObjectReloader : IDisposable
|
||||
{
|
||||
private delegate void ManipulateDraw( IntPtr actor );
|
||||
|
||||
private const int RenderModeOffset = 0x0104;
|
||||
private const int UnloadAllRedrawDelay = 250;
|
||||
|
|
@ -41,14 +31,20 @@ namespace Penumbra.Interop
|
|||
private int _currentFrame;
|
||||
private bool _changedSettings;
|
||||
private uint _currentObjectId = uint.MaxValue;
|
||||
private LoadingFlags _currentObjectStartState = 0;
|
||||
private DrawState _currentObjectStartState = 0;
|
||||
private RedrawType _currentRedrawType = RedrawType.Unload;
|
||||
private string? _currentObjectName;
|
||||
private bool _wasTarget;
|
||||
private bool _inGPose;
|
||||
|
||||
public static IntPtr RenderPtr( GameObject actor )
|
||||
=> actor.Address + RenderModeOffset;
|
||||
public static DrawState* ActorDrawState( GameObject actor )
|
||||
=> ( DrawState* )( actor.Address + 0x0104 );
|
||||
|
||||
private static delegate*< IntPtr, void > GetDisableDraw( GameObject actor )
|
||||
=> ( ( delegate*< IntPtr, void >** )actor.Address )[ 0 ][ 17 ];
|
||||
|
||||
private static delegate*< IntPtr, void > GetEnableDraw( GameObject actor )
|
||||
=> ( ( delegate*< IntPtr, void >** )actor.Address )[ 0 ][ 16 ];
|
||||
|
||||
public ObjectReloader( ModManager mods, int defaultWaitFrames )
|
||||
{
|
||||
|
|
@ -73,33 +69,25 @@ namespace Penumbra.Interop
|
|||
|
||||
private unsafe void WriteInvisible( GameObject actor, int actorIdx )
|
||||
{
|
||||
var renderPtr = RenderPtr( actor );
|
||||
if( renderPtr == IntPtr.Zero )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_currentObjectStartState = *( LoadingFlags* )renderPtr;
|
||||
*( LoadingFlags* )renderPtr |= LoadingFlags.Invisibility;
|
||||
_currentObjectStartState = *ActorDrawState( actor );
|
||||
*ActorDrawState( actor ) |= DrawState.Invisibility;
|
||||
|
||||
if( _inGPose )
|
||||
{
|
||||
var ptr = ( void*** )actor.Address;
|
||||
var disableDraw = Marshal.GetDelegateForFunctionPointer< ManipulateDraw >( new IntPtr( ptr[ 0 ][ 17 ] ) );
|
||||
disableDraw( actor.Address );
|
||||
GetDisableDraw( actor )( actor.Address );
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe bool StillLoading( IntPtr renderPtr )
|
||||
private bool StillLoading( DrawState* renderPtr )
|
||||
{
|
||||
const LoadingFlags stillLoadingFlags = LoadingFlags.SomeNpcFlag
|
||||
| LoadingFlags.MaybeCulled
|
||||
| LoadingFlags.MaybeHiddenMinion
|
||||
| LoadingFlags.MaybeHiddenSummon;
|
||||
const DrawState stillLoadingFlags = DrawState.SomeNpcFlag
|
||||
| DrawState.MaybeCulled
|
||||
| DrawState.MaybeHiddenMinion
|
||||
| DrawState.MaybeHiddenSummon;
|
||||
|
||||
if( renderPtr != IntPtr.Zero )
|
||||
if( renderPtr != null )
|
||||
{
|
||||
var loadingFlags = *( LoadingFlags* )renderPtr;
|
||||
var loadingFlags = *( DrawState* )renderPtr;
|
||||
if( loadingFlags == _currentObjectStartState )
|
||||
{
|
||||
return false;
|
||||
|
|
@ -111,16 +99,13 @@ namespace Penumbra.Interop
|
|||
return false;
|
||||
}
|
||||
|
||||
private unsafe void WriteVisible( GameObject actor, int actorIdx )
|
||||
private void WriteVisible( GameObject actor, int actorIdx )
|
||||
{
|
||||
var renderPtr = RenderPtr( actor );
|
||||
*( LoadingFlags* )renderPtr &= ~LoadingFlags.Invisibility;
|
||||
*ActorDrawState( actor ) &= ~DrawState.Invisibility;
|
||||
|
||||
if( _inGPose )
|
||||
{
|
||||
var ptr = ( void*** )actor.Address;
|
||||
var enableDraw = Marshal.GetDelegateForFunctionPointer< ManipulateDraw >( new IntPtr( ptr[ 0 ][ 16 ] ) );
|
||||
enableDraw( actor.Address );
|
||||
GetEnableDraw( actor )( actor.Address );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +266,7 @@ namespace Penumbra.Interop
|
|||
var (actor, _) = FindCurrentObject();
|
||||
if( actor != null )
|
||||
{
|
||||
if( !StillLoading( RenderPtr( actor ) ) )
|
||||
if( !StillLoading( ActorDrawState( actor ) ) )
|
||||
{
|
||||
RestoreSettings();
|
||||
if( _wasTarget && Dalamud.Targets.Target == null )
|
||||
|
|
@ -395,40 +380,6 @@ namespace Penumbra.Interop
|
|||
}
|
||||
}
|
||||
|
||||
private void UnloadAll()
|
||||
{
|
||||
Clear();
|
||||
foreach( var (actor, index) in Dalamud.Objects.Select( ( a, i ) => ( a, i ) ) )
|
||||
{
|
||||
WriteInvisible( actor, index );
|
||||
}
|
||||
}
|
||||
|
||||
private void RedrawAllWithoutSettings()
|
||||
{
|
||||
Clear();
|
||||
foreach( var (actor, index) in Dalamud.Objects.Select( ( a, i ) => ( a, i ) ) )
|
||||
{
|
||||
WriteVisible( actor, index );
|
||||
}
|
||||
}
|
||||
|
||||
public async void UnloadAtOnceRedrawWithSettings()
|
||||
{
|
||||
Clear();
|
||||
UnloadAll();
|
||||
await Task.Delay( UnloadAllRedrawDelay );
|
||||
RedrawAll( RedrawType.RedrawWithSettings );
|
||||
}
|
||||
|
||||
public async void UnloadAtOnceRedrawWithoutSettings()
|
||||
{
|
||||
Clear();
|
||||
UnloadAll();
|
||||
await Task.Delay( UnloadAllRedrawDelay );
|
||||
RedrawAllWithoutSettings();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
RestoreSettings();
|
||||
|
|
@ -441,5 +392,4 @@ namespace Penumbra.Interop
|
|||
_actorIds.Clear();
|
||||
Dalamud.Framework.Update -= OnUpdateEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Penumbra/Interop/Structs/DrawState.cs
Normal file
14
Penumbra/Interop/Structs/DrawState.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[Flags]
|
||||
public enum DrawState : uint
|
||||
{
|
||||
Invisibility = 0x00_00_00_02,
|
||||
IsLoading = 0x00_00_08_00,
|
||||
SomeNpcFlag = 0x00_00_01_00,
|
||||
MaybeCulled = 0x00_00_04_00,
|
||||
MaybeHiddenMinion = 0x00_00_80_00,
|
||||
MaybeHiddenSummon = 0x00_80_00_00,
|
||||
}
|
||||
|
|
@ -11,8 +11,10 @@ using Penumbra.Api;
|
|||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.UI.Custom;
|
||||
using CharacterUtility = Penumbra.Interop.CharacterUtility;
|
||||
using ResourceHandle = Penumbra.Interop.Structs.ResourceHandle;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
|
@ -159,7 +161,7 @@ public partial class SettingsInterface
|
|||
//PrintValue( "Resource Loader Enabled", _penumbra.ResourceLoader.IsEnabled.ToString() );
|
||||
}
|
||||
|
||||
private void DrawDebugTabRedraw()
|
||||
private unsafe void DrawDebugTabRedraw()
|
||||
{
|
||||
if( !ImGui.CollapsingHeader( "Redrawing##Debug" ) )
|
||||
{
|
||||
|
|
@ -187,7 +189,7 @@ public partial class SettingsInterface
|
|||
.GetField( "_currentObjectName", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||
?.GetValue( _penumbra.ObjectReloader );
|
||||
|
||||
var currentObjectStartState = ( ObjectReloader.LoadingFlags? )_penumbra.ObjectReloader.GetType()
|
||||
var currentObjectStartState = ( DrawState? )_penumbra.ObjectReloader.GetType()
|
||||
.GetField( "_currentObjectStartState", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||
?.GetValue( _penumbra.ObjectReloader );
|
||||
|
||||
|
|
@ -200,7 +202,7 @@ public partial class SettingsInterface
|
|||
.Invoke( _penumbra.ObjectReloader, Array.Empty< object >() )!;
|
||||
|
||||
var currentRender = currentObject != null
|
||||
? ( ObjectReloader.LoadingFlags? )Marshal.ReadInt32( ObjectReloader.RenderPtr( currentObject ) )
|
||||
? ObjectReloader.ActorDrawState( currentObject )
|
||||
: null;
|
||||
|
||||
var waitFrames = ( int? )_penumbra.ObjectReloader.GetType()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue