diff --git a/Penumbra/Interop/Loader/ResourceLoader.cs b/Penumbra/Interop/Loader/ResourceLoader.cs index 98457acc..f02f0895 100644 --- a/Penumbra/Interop/Loader/ResourceLoader.cs +++ b/Penumbra/Interop/Loader/ResourceLoader.cs @@ -1,7 +1,6 @@ using System; using Dalamud.Utility.Signatures; using Penumbra.GameData.ByteString; -using ResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle; namespace Penumbra.Interop.Loader; diff --git a/Penumbra/Interop/Resolver/PathResolver.Human.cs b/Penumbra/Interop/Resolver/PathResolver.Human.cs index 2acba0f6..1ce81342 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Human.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Human.cs @@ -20,10 +20,6 @@ public unsafe partial class PathResolver // [Signature( "48 8D 05 ?? ?? ?? ?? 48 89 03 33 C0 48 89 83 ?? ?? ?? ?? 48 89 83 ?? ?? ?? ?? C7 83", ScanType = ScanType.StaticAddress )] // public IntPtr* DrawObjectMonsterVTable; // - // [Signature( "48 8D 05 ?? ?? ?? ?? 48 89 03 B8 ?? ?? ?? ?? 66 89 83 ?? ?? ?? ?? 48 8B C3 48 89 8B ?? ?? ?? ?? 48 89 8B", - // ScanType = ScanType.StaticAddress )] - // public IntPtr* DrawObjectWeaponVTable; - // // public const int ResolveRootIdx = 71; public const int ResolveSklbIdx = 72; diff --git a/Penumbra/Interop/Resolver/PathResolver.Material.cs b/Penumbra/Interop/Resolver/PathResolver.Material.cs index a17efab2..01f1a2d1 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Material.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Material.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using Dalamud.Hooking; using Dalamud.Utility.Signatures; using Penumbra.GameData.ByteString; diff --git a/Penumbra/Interop/Resolver/PathResolver.Resolve.cs b/Penumbra/Interop/Resolver/PathResolver.Resolve.cs index 70fba613..77fba089 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Resolve.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Resolve.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.CompilerServices; +using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using Penumbra.GameData.ByteString; using Penumbra.Mods; @@ -8,6 +9,7 @@ namespace Penumbra.Interop.Resolver; // The actual resolve detours are basically all the same. 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 ) ); @@ -60,12 +62,68 @@ public unsafe partial class PathResolver => ResolvePathDetour( drawObject, ResolveVfxPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) ); + // Weapons + private IntPtr ResolveWeaponDecalDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponDecalPathHook!.Original( drawObject, path, unk3, unk4 ) ); + + private IntPtr ResolveWeaponEidDetour( IntPtr drawObject, IntPtr path, IntPtr unk3 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponEidPathHook!.Original( drawObject, path, unk3 ) ); + + private IntPtr ResolveWeaponImcDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponImcPathHook!.Original( drawObject, path, unk3, unk4 ) ); + + private IntPtr ResolveWeaponMPapDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, uint unk5 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponMPapPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) ); + + private IntPtr ResolveWeaponMdlDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint modelType ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponMdlPathHook!.Original( drawObject, path, unk3, modelType ) ); + + private IntPtr ResolveWeaponMtrlDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, ulong unk5 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponMtrlPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) ); + + private IntPtr ResolveWeaponPapDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, ulong unk5 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponPapPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) ); + + private IntPtr ResolveWeaponPhybDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponPhybPathHook!.Original( drawObject, path, unk3, unk4 ) ); + + private IntPtr ResolveWeaponSklbDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponSklbPathHook!.Original( drawObject, path, unk3, unk4 ) ); + + private IntPtr ResolveWeaponSkpDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponSkpPathHook!.Original( drawObject, path, unk3, unk4 ) ); + + private IntPtr ResolveWeaponTmbDetour( IntPtr drawObject, IntPtr path, IntPtr unk3 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponTmbPathHook!.Original( drawObject, path, unk3 ) ); + + private IntPtr ResolveWeaponVfxDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, ulong unk5 ) + => ResolveWeaponPathDetour( drawObject, ResolveWeaponVfxPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) ); + + + // Implementation [MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )] private IntPtr ResolvePathDetour( IntPtr drawObject, IntPtr path ) => ResolvePathDetour( FindParent( drawObject, out var collection ) == null ? Penumbra.ModManager.Collections.DefaultCollection : collection, path ); + [MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )] + private IntPtr ResolveWeaponPathDetour( IntPtr drawObject, IntPtr 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.ModManager.Collections.DefaultCollection + : collection, path ); + } + } // Just add or remove the resolved path. [MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )] diff --git a/Penumbra/Interop/Resolver/PathResolver.Weapon.cs b/Penumbra/Interop/Resolver/PathResolver.Weapon.cs new file mode 100644 index 00000000..7fc1f766 --- /dev/null +++ b/Penumbra/Interop/Resolver/PathResolver.Weapon.cs @@ -0,0 +1,90 @@ +using System; +using Dalamud.Hooking; +using Dalamud.Utility.Signatures; + +namespace Penumbra.Interop.Resolver; + +public unsafe partial class PathResolver +{ + [Signature( "48 8D 05 ?? ?? ?? ?? 48 89 03 B8 ?? ?? ?? ?? 66 89 83 ?? ?? ?? ?? 48 8B C3 48 89 8B ?? ?? ?? ?? 48 89 8B", + ScanType = ScanType.StaticAddress )] + public IntPtr* DrawObjectWeaponVTable; + + public Hook< GeneralResolveDelegate >? ResolveWeaponDecalPathHook; + public Hook< EidResolveDelegate >? ResolveWeaponEidPathHook; + public Hook< GeneralResolveDelegate >? ResolveWeaponImcPathHook; + public Hook< MPapResolveDelegate >? ResolveWeaponMPapPathHook; + public Hook< GeneralResolveDelegate >? ResolveWeaponMdlPathHook; + public Hook< MaterialResolveDetour >? ResolveWeaponMtrlPathHook; + public Hook< MaterialResolveDetour >? ResolveWeaponPapPathHook; + public Hook< GeneralResolveDelegate >? ResolveWeaponPhybPathHook; + public Hook< GeneralResolveDelegate >? ResolveWeaponSklbPathHook; + public Hook< GeneralResolveDelegate >? ResolveWeaponSkpPathHook; + public Hook< EidResolveDelegate >? ResolveWeaponTmbPathHook; + public Hook< MaterialResolveDetour >? ResolveWeaponVfxPathHook; + + + private void SetupWeaponHooks() + { + ResolveWeaponDecalPathHook = new Hook< GeneralResolveDelegate >( DrawObjectWeaponVTable[ ResolveDecalIdx ], ResolveWeaponDecalDetour ); + ResolveWeaponEidPathHook = new Hook< EidResolveDelegate >( DrawObjectWeaponVTable[ ResolveEidIdx ], ResolveWeaponEidDetour ); + ResolveWeaponImcPathHook = new Hook< GeneralResolveDelegate >( DrawObjectWeaponVTable[ ResolveImcIdx ], ResolveWeaponImcDetour ); + ResolveWeaponMPapPathHook = new Hook< MPapResolveDelegate >( DrawObjectWeaponVTable[ ResolveMPapIdx ], ResolveWeaponMPapDetour ); + ResolveWeaponMdlPathHook = new Hook< GeneralResolveDelegate >( DrawObjectWeaponVTable[ ResolveMdlIdx ], ResolveWeaponMdlDetour ); + ResolveWeaponMtrlPathHook = new Hook< MaterialResolveDetour >( DrawObjectWeaponVTable[ ResolveMtrlIdx ], ResolveWeaponMtrlDetour ); + ResolveWeaponPapPathHook = new Hook< MaterialResolveDetour >( DrawObjectWeaponVTable[ ResolvePapIdx ], ResolveWeaponPapDetour ); + ResolveWeaponPhybPathHook = new Hook< GeneralResolveDelegate >( DrawObjectWeaponVTable[ ResolvePhybIdx ], ResolveWeaponPhybDetour ); + ResolveWeaponSklbPathHook = new Hook< GeneralResolveDelegate >( DrawObjectWeaponVTable[ ResolveSklbIdx ], ResolveWeaponSklbDetour ); + ResolveWeaponSkpPathHook = new Hook< GeneralResolveDelegate >( DrawObjectWeaponVTable[ ResolveSkpIdx ], ResolveWeaponSkpDetour ); + ResolveWeaponTmbPathHook = new Hook< EidResolveDelegate >( DrawObjectWeaponVTable[ ResolveTmbIdx ], ResolveWeaponTmbDetour ); + ResolveWeaponVfxPathHook = new Hook< MaterialResolveDetour >( DrawObjectWeaponVTable[ ResolveVfxIdx ], ResolveWeaponVfxDetour ); + } + + private void EnableWeaponHooks() + { + ResolveWeaponDecalPathHook?.Enable(); + ResolveWeaponEidPathHook?.Enable(); + ResolveWeaponImcPathHook?.Enable(); + ResolveWeaponMPapPathHook?.Enable(); + ResolveWeaponMdlPathHook?.Enable(); + ResolveWeaponMtrlPathHook?.Enable(); + ResolveWeaponPapPathHook?.Enable(); + ResolveWeaponPhybPathHook?.Enable(); + ResolveWeaponSklbPathHook?.Enable(); + ResolveWeaponSkpPathHook?.Enable(); + ResolveWeaponTmbPathHook?.Enable(); + ResolveWeaponVfxPathHook?.Enable(); + } + + private void DisableWeaponHooks() + { + ResolveWeaponDecalPathHook?.Disable(); + ResolveWeaponEidPathHook?.Disable(); + ResolveWeaponImcPathHook?.Disable(); + ResolveWeaponMPapPathHook?.Disable(); + ResolveWeaponMdlPathHook?.Disable(); + ResolveWeaponMtrlPathHook?.Disable(); + ResolveWeaponPapPathHook?.Disable(); + ResolveWeaponPhybPathHook?.Disable(); + ResolveWeaponSklbPathHook?.Disable(); + ResolveWeaponSkpPathHook?.Disable(); + ResolveWeaponTmbPathHook?.Disable(); + ResolveWeaponVfxPathHook?.Disable(); + } + + private void DisposeWeaponHooks() + { + ResolveWeaponDecalPathHook?.Dispose(); + ResolveWeaponEidPathHook?.Dispose(); + ResolveWeaponImcPathHook?.Dispose(); + ResolveWeaponMPapPathHook?.Dispose(); + ResolveWeaponMdlPathHook?.Dispose(); + ResolveWeaponMtrlPathHook?.Dispose(); + ResolveWeaponPapPathHook?.Dispose(); + ResolveWeaponPhybPathHook?.Dispose(); + ResolveWeaponSklbPathHook?.Dispose(); + ResolveWeaponSkpPathHook?.Dispose(); + ResolveWeaponTmbPathHook?.Dispose(); + ResolveWeaponVfxPathHook?.Dispose(); + } +} \ No newline at end of file diff --git a/Penumbra/Interop/Resolver/PathResolver.cs b/Penumbra/Interop/Resolver/PathResolver.cs index 56eda2c0..cef6c550 100644 --- a/Penumbra/Interop/Resolver/PathResolver.cs +++ b/Penumbra/Interop/Resolver/PathResolver.cs @@ -22,6 +22,7 @@ public partial class PathResolver : IDisposable _loader = loader; SignatureHelper.Initialise( this ); SetupHumanHooks(); + SetupWeaponHooks(); SetupMetaHooks(); Enable(); } @@ -78,6 +79,7 @@ public partial class PathResolver : IDisposable InitializeDrawObjects(); EnableHumanHooks(); + EnableWeaponHooks(); EnableMtrlHooks(); EnableDataHooks(); EnableMetaHooks(); @@ -89,6 +91,7 @@ public partial class PathResolver : IDisposable public void Disable() { DisableHumanHooks(); + DisableWeaponHooks(); DisableMtrlHooks(); DisableDataHooks(); DisableMetaHooks(); @@ -100,6 +103,7 @@ public partial class PathResolver : IDisposable { Disable(); DisposeHumanHooks(); + DisposeWeaponHooks(); DisposeMtrlHooks(); DisposeDataHooks(); DisposeMetaHooks(); diff --git a/Penumbra/Mods/CollectionManager.cs b/Penumbra/Mods/CollectionManager.cs index 8018d942..0bb7182a 100644 --- a/Penumbra/Mods/CollectionManager.cs +++ b/Penumbra/Mods/CollectionManager.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Dalamud.Logging; -using Lumina.Excel.GeneratedSheets; using Penumbra.Mod; using Penumbra.Util;