Add preliminary pap handling to character collections.

This commit is contained in:
Ottermandias 2022-06-04 19:02:58 +02:00
parent c0102368c3
commit f0131dd5ba
3 changed files with 83 additions and 2 deletions

View file

@ -0,0 +1,62 @@
using System;
using System.Linq;
using Dalamud.Hooking;
using Dalamud.Logging;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Penumbra.Collections;
namespace Penumbra.Interop.Resolver;
public unsafe partial class PathResolver
{
// Probably used when the base idle animation gets loaded.
// 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" )]
public Hook< CharacterBaseDestructorDelegate >? CharacterBaseLoadAnimationHook;
private ModCollection? _animationLoadCollection;
private void CharacterBaseLoadAnimationDetour( IntPtr address )
{
_animationLoadCollection = _lastCreatedCollection ?? IdentifyCollection( ( GameObject* )address );
CharacterBaseLoadAnimationHook!.Original( address );
_animationLoadCollection = null;
}
// Probably used when action paps are loaded.
// 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 );
[Signature( "E8 ?? ?? ?? ?? 0F 10 00 0F 11 06", DetourName = "RandomPapDetour" )]
public Hook< PapLoadFunction >? RandomPapHook;
private void RandomPapDetour( IntPtr drawObject, IntPtr a2, uint a3, IntPtr a4, uint a5, uint a6, uint a7 )
{
_animationLoadCollection = _lastCreatedCollection ?? IdentifyCollection( ( GameObject* )drawObject );
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

@ -72,12 +72,16 @@ public unsafe partial class PathResolver
CharacterBaseCreateHook?.Enable(); CharacterBaseCreateHook?.Enable();
EnableDrawHook?.Enable(); EnableDrawHook?.Enable();
CharacterBaseDestructorHook?.Enable(); CharacterBaseDestructorHook?.Enable();
CharacterBaseLoadAnimationHook?.Enable();
RandomPapHook?.Enable();
Penumbra.CollectionManager.CollectionChanged += CheckCollections; Penumbra.CollectionManager.CollectionChanged += CheckCollections;
} }
private void DisableDataHooks() private void DisableDataHooks()
{ {
Penumbra.CollectionManager.CollectionChanged -= CheckCollections; Penumbra.CollectionManager.CollectionChanged -= CheckCollections;
RandomPapHook?.Disable();
CharacterBaseLoadAnimationHook?.Disable();
CharacterBaseCreateHook?.Disable(); CharacterBaseCreateHook?.Disable();
EnableDrawHook?.Disable(); EnableDrawHook?.Disable();
CharacterBaseDestructorHook?.Disable(); CharacterBaseDestructorHook?.Disable();
@ -85,12 +89,13 @@ public unsafe partial class PathResolver
private void DisposeDataHooks() private void DisposeDataHooks()
{ {
CharacterBaseLoadAnimationHook?.Dispose();
CharacterBaseCreateHook?.Dispose(); CharacterBaseCreateHook?.Dispose();
EnableDrawHook?.Dispose(); EnableDrawHook?.Dispose();
CharacterBaseDestructorHook?.Dispose(); CharacterBaseDestructorHook?.Dispose();
RandomPapHook?.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.
// It contains any DrawObjects that correspond to a human actor, even those without specific collections. // It contains any DrawObjects that correspond to a human actor, even those without specific collections.
internal readonly Dictionary< IntPtr, (ModCollection, int) > DrawObjectToObject = new(); internal readonly Dictionary< IntPtr, (ModCollection, int) > DrawObjectToObject = new();

View file

@ -40,6 +40,7 @@ public partial class PathResolver : IDisposable
// A potential next request will add the path anew. // A potential next request will add the path anew.
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 )
|| HandleDecalFile( type, gamePath, out collection ); || HandleDecalFile( type, gamePath, out collection );
if( !nonDefault ) if( !nonDefault )
{ {
@ -71,6 +72,19 @@ public partial class PathResolver : IDisposable
return false; return false;
} }
private bool HandlePapFile( ResourceType type, Utf8GamePath gamePath, out ModCollection? collection )
{
if( type is ResourceType.Pap or ResourceType.Tmb
&& _animationLoadCollection != null)
{
collection = _animationLoadCollection;
return true;
}
collection = null;
return false;
}
public void Enable() public void Enable()
{ {
if( Enabled ) if( Enabled )