Another try at character collection animations.

This commit is contained in:
Ottermandias 2022-06-09 12:38:21 +02:00
parent d45e98a254
commit 34445eb949
3 changed files with 73 additions and 68 deletions

View file

@ -8,55 +8,54 @@ namespace Penumbra.Interop.Resolver;
public unsafe partial class PathResolver public unsafe partial class PathResolver
{ {
private ModCollection? _animationLoadCollection;
public delegate byte LoadTimelineResourcesDelegate( IntPtr timeline );
// The timeline object loads the requested .tmb and .pap files. The .tmb files load the respective .avfx files.
// We can obtain the associated game object from the timelines 28'th vfunc and use that to apply the correct collection.
[Signature( "E8 ?? ?? ?? ?? 83 7F ?? ?? 75 ?? 0F B6 87", DetourName = nameof( LoadTimelineResourcesDetour ) )]
public Hook< LoadTimelineResourcesDelegate >? LoadTimelineResourcesHook;
private byte LoadTimelineResourcesDetour( IntPtr timeline )
{
byte ret;
var old = _animationLoadCollection;
try
{
var getGameObjectIdx = ( ( delegate* unmanaged < IntPtr, int>** )timeline )[ 0 ][ 28 ];
var idx = getGameObjectIdx( timeline );
if( idx >= 0 && idx < Dalamud.Objects.Length )
{
var obj = Dalamud.Objects[ idx ];
_animationLoadCollection = obj != null ? IdentifyCollection( ( GameObject* )obj.Address ) : null;
}
else
{
_animationLoadCollection = null;
}
}
finally
{
ret = LoadTimelineResourcesHook!.Original( timeline );
}
_animationLoadCollection = old;
return ret;
}
// Probably used when the base idle animation gets loaded. // Probably used when the base idle animation gets loaded.
// Make it aware of the correct collection to load the correct pap files. // Make it aware of the correct collection to load the correct pap files.
//[Signature( "E8 ?? ?? ?? ?? BA ?? ?? ?? ?? 48 8B CF 44 8B C2 E8 ?? ?? ?? ?? 48 8B 05", DetourName = "CharacterBaseLoadAnimationDetour" )] [Signature( "E8 ?? ?? ?? ?? BA ?? ?? ?? ?? 48 8B CF 44 8B C2 E8 ?? ?? ?? ?? 48 8B 05", DetourName = "CharacterBaseLoadAnimationDetour" )]
//public Hook< CharacterBaseDestructorDelegate >? CharacterBaseLoadAnimationHook; public Hook< CharacterBaseDestructorDelegate >? CharacterBaseLoadAnimationHook;
//
//private ModCollection? _animationLoadCollection;
//
//private void CharacterBaseLoadAnimationDetour( IntPtr drawObject )
//{
// _animationLoadCollection = _lastCreatedCollection
// ?? ( FindParent( drawObject, out var collection ) != null ? collection : Penumbra.CollectionManager.Default );
// CharacterBaseLoadAnimationHook!.Original( drawObject );
// _animationLoadCollection = null;
//}
// Probably used when action paps are loaded. private void CharacterBaseLoadAnimationDetour( IntPtr drawObject )
// Make it aware of the correct collection to load the correct pap files. {
//public delegate void PapLoadFunction( IntPtr drawObject, IntPtr a2, uint a3, IntPtr a4, uint a5, uint a6, uint a7 ); var last = _animationLoadCollection;
_animationLoadCollection = _lastCreatedCollection
//[Signature( "E8 ?? ?? ?? ?? 0F 10 00 0F 11 06", DetourName = "RandomPapDetour" )] ?? ( FindParent( drawObject, out var collection ) != null ? collection : Penumbra.CollectionManager.Default );
//public Hook< PapLoadFunction >? RandomPapHook; CharacterBaseLoadAnimationHook!.Original( drawObject );
_animationLoadCollection = last;
//private void RandomPapDetour( IntPtr drawObject, IntPtr a2, uint a3, IntPtr a4, uint a5, uint a6, uint a7 ) }
//{
// _animationLoadCollection = _lastCreatedCollection
// ?? ( FindParent( drawObject, out var collection ) != null ? collection : Penumbra.CollectionManager.Default );
// RandomPapHook!.Original( drawObject, a2, a3, a4, a5, a6, a7 );
// _animationLoadCollection = null;
//}
//private void TestFunction()
//{
// var p = Dalamud.Objects.FirstOrDefault( o => o.Name.ToString() == "Demi-Phoenix" );
// if( p != null )
// {
// var draw = ( ( GameObject* )p.Address )->DrawObject;
// PluginLog.Information( $"{p.Address:X} {( draw != null ? ( ( IntPtr )draw ).ToString( "X" ) : "NULL" )}" );
// }
//}
//
//public delegate void TmbLoadFunction(IntPtr drawObject, ushort a2, uint a3, IntPtr a4, IntPtr a5 );
//
//[Signature( "E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 44 38 75 ?? 74 ?? 44 89 B3 ", DetourName ="RandomTmbDetour" )]
//public Hook< TmbLoadFunction > UnkHook = null;
//
//private void RandomTmbDetour( IntPtr drawObject, ushort a2, uint a3, IntPtr a4, IntPtr a5 )
//{
// //PluginLog.Information($"{drawObject:X} {a2:X}, {a3:X} {a4:X} {a5:X}" );
// //TestFunction();
// UnkHook!.Original( drawObject, a2, a3, a4, a5);
//}
} }

View file

@ -83,7 +83,6 @@ public unsafe partial class PathResolver
LastGameObject = oldGame; LastGameObject = oldGame;
} }
private void EnableDataHooks() private void EnableDataHooks()
{ {
CharacterBaseCreateHook?.Enable(); CharacterBaseCreateHook?.Enable();
@ -91,8 +90,8 @@ public unsafe partial class PathResolver
CharacterBaseDestructorHook?.Enable(); CharacterBaseDestructorHook?.Enable();
WeaponReloadHook?.Enable(); WeaponReloadHook?.Enable();
Penumbra.CollectionManager.CollectionChanged += CheckCollections; Penumbra.CollectionManager.CollectionChanged += CheckCollections;
//CharacterBaseLoadAnimationHook?.Enable(); LoadTimelineResourcesHook?.Enable();
//RandomPapHook?.Enable(); CharacterBaseLoadAnimationHook?.Enable();
} }
private void DisableDataHooks() private void DisableDataHooks()
@ -102,8 +101,8 @@ public unsafe partial class PathResolver
CharacterBaseCreateHook?.Disable(); CharacterBaseCreateHook?.Disable();
EnableDrawHook?.Disable(); EnableDrawHook?.Disable();
CharacterBaseDestructorHook?.Disable(); CharacterBaseDestructorHook?.Disable();
//RandomPapHook?.Disable(); LoadTimelineResourcesHook?.Disable();
//CharacterBaseLoadAnimationHook?.Disable(); CharacterBaseLoadAnimationHook?.Disable();
} }
private void DisposeDataHooks() private void DisposeDataHooks()
@ -112,8 +111,8 @@ public unsafe partial class PathResolver
CharacterBaseCreateHook?.Dispose(); CharacterBaseCreateHook?.Dispose();
EnableDrawHook?.Dispose(); EnableDrawHook?.Dispose();
CharacterBaseDestructorHook?.Dispose(); CharacterBaseDestructorHook?.Dispose();
//RandomPapHook?.Dispose(); LoadTimelineResourcesHook?.Dispose();
//CharacterBaseLoadAnimationHook?.Dispose(); CharacterBaseLoadAnimationHook?.Dispose();
} }
// This map links DrawObjects directly to Actors (by ObjectTable index) and their collections. // This map links DrawObjects directly to Actors (by ObjectTable index) and their collections.

View file

@ -41,6 +41,7 @@ public partial class PathResolver : IDisposable
var nonDefault = HandleMaterialSubFiles( type, out var collection ) var nonDefault = HandleMaterialSubFiles( type, out var collection )
|| PathCollections.TryRemove( gamePath.Path, out collection ) || PathCollections.TryRemove( gamePath.Path, out collection )
//|| HandlePapFile( type, gamePath, out collection ) //|| HandlePapFile( type, gamePath, out collection )
|| HandleAnimationFile( type, gamePath, out collection )
|| HandleDecalFile( type, gamePath, out collection ); || HandleDecalFile( type, gamePath, out collection );
if( !nonDefault ) if( !nonDefault )
{ {
@ -72,18 +73,24 @@ public partial class PathResolver : IDisposable
return false; return false;
} }
//private bool HandlePapFile( ResourceType type, Utf8GamePath _, out ModCollection? collection ) private bool HandleAnimationFile( ResourceType type, Utf8GamePath _, out ModCollection? collection )
//{ {
// if( type is ResourceType.Pap or ResourceType.Tmb if( _animationLoadCollection != null )
// && _animationLoadCollection != null ) {
// { switch( type )
// collection = _animationLoadCollection; {
// return true; case ResourceType.Tmb:
// } case ResourceType.Pap:
// case ResourceType.Avfx:
// collection = null; case ResourceType.Atex:
// return false; collection = _animationLoadCollection;
//} return true;
}
}
collection = null;
return false;
}
public void Enable() public void Enable()
{ {