Support Weapons in character collections.

This commit is contained in:
Ottermandias 2022-03-20 14:37:35 +01:00
parent 3ef3e75c6a
commit ad55d178d4
7 changed files with 152 additions and 7 deletions

View file

@ -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;

View file

@ -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;

View file

@ -1,5 +1,4 @@
using System;
using System.Linq;
using Dalamud.Hooking;
using Dalamud.Utility.Signatures;
using Penumbra.GameData.ByteString;

View file

@ -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 )]

View file

@ -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();
}
}

View file

@ -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();

View file

@ -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;