diff --git a/Penumbra/Interop/Resolver/PathResolver.Data.cs b/Penumbra/Interop/Resolver/PathResolver.Data.cs index 97ff113c..53ed569f 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Data.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Data.cs @@ -62,16 +62,34 @@ public unsafe partial class PathResolver private void EnableDrawDetour( IntPtr gameObject, IntPtr b, IntPtr c, IntPtr d ) { + var oldObject = LastGameObject; LastGameObject = ( GameObject* )gameObject; EnableDrawHook!.Original.Invoke( gameObject, b, c, d ); - LastGameObject = null; + LastGameObject = oldObject; } + // Not fully understood. The game object the weapon is loaded for is seemingly found at a1 + 8, + // so we use that. + public delegate void WeaponReloadFunc( IntPtr a1, uint a2, IntPtr a3, byte a4, byte a5, byte a6, byte a7 ); + + [Signature( "E8 ?? ?? ?? ?? 44 8B 9F" )] + public Hook< WeaponReloadFunc >? WeaponReloadHook; + + public void WeaponReloadDetour( IntPtr a1, uint a2, IntPtr a3, byte a4, byte a5, byte a6, byte a7 ) + { + var oldGame = LastGameObject; + LastGameObject = *( GameObject** )( a1 + 8 ); + WeaponReloadHook!.Original( a1, a2, a3, a4, a5, a6, a7 ); + LastGameObject = oldGame; + } + + private void EnableDataHooks() { CharacterBaseCreateHook?.Enable(); EnableDrawHook?.Enable(); CharacterBaseDestructorHook?.Enable(); + WeaponReloadHook?.Enable(); Penumbra.CollectionManager.CollectionChanged += CheckCollections; //CharacterBaseLoadAnimationHook?.Enable(); //RandomPapHook?.Enable(); @@ -80,6 +98,7 @@ public unsafe partial class PathResolver private void DisableDataHooks() { Penumbra.CollectionManager.CollectionChanged -= CheckCollections; + WeaponReloadHook?.Disable(); CharacterBaseCreateHook?.Disable(); EnableDrawHook?.Disable(); CharacterBaseDestructorHook?.Disable(); @@ -89,7 +108,7 @@ public unsafe partial class PathResolver private void DisposeDataHooks() { - + WeaponReloadHook?.Dispose(); CharacterBaseCreateHook?.Dispose(); EnableDrawHook?.Dispose(); CharacterBaseDestructorHook?.Dispose(); diff --git a/Penumbra/Interop/Resolver/PathResolver.Resolve.cs b/Penumbra/Interop/Resolver/PathResolver.Resolve.cs index 7338f9e4..a6124a93 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Resolve.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Resolve.cs @@ -12,6 +12,7 @@ public unsafe partial class PathResolver // Humans private IntPtr ResolveDecalDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) => ResolvePathDetour( drawObject, ResolveDecalPathHook!.Original( drawObject, path, unk3, unk4 ) ); + private IntPtr ResolveEidDetour( IntPtr drawObject, IntPtr path, IntPtr unk3 ) => ResolvePathDetour( drawObject, ResolveEidPathHook!.Original( drawObject, path, unk3 ) ); @@ -149,19 +150,24 @@ public unsafe partial class PathResolver [MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )] private IntPtr ResolveWeaponPathDetour( IntPtr drawObject, IntPtr path ) { + var parent = FindParent( drawObject, out var collection ); + if( parent != null ) + { + return ResolvePathDetour( collection, path ); + } + var parentObject = ( ( DrawObject* )drawObject )->Object.ParentObject; if( parentObject == null && LastGameObject != null ) { - var collection = IdentifyCollection( LastGameObject ); - return ResolvePathDetour( collection, path ); - } - else - { - var parent = FindParent( ( IntPtr )parentObject, out var collection ); - return ResolvePathDetour( parent == null - ? Penumbra.CollectionManager.Default - : collection, path ); + var c2 = IdentifyCollection( LastGameObject ); + DrawObjectToObject[ drawObject ] = ( c2, LastGameObject->ObjectIndex ); + return ResolvePathDetour( c2, path ); } + + parent = FindParent( ( IntPtr )parentObject, out collection ); + return ResolvePathDetour( parent == null + ? Penumbra.CollectionManager.Default + : collection, path ); } // Just add or remove the resolved path.