Let companions, combat pets and mounts use their owners character collection.

This commit is contained in:
Ottermandias 2022-06-02 14:15:34 +02:00
parent 385ce4c7e9
commit eeaaecb855
5 changed files with 153 additions and 2 deletions

View file

@ -188,6 +188,29 @@ public unsafe partial class PathResolver
return pc->ClassJob == ( ( Character* )gameObject )->ClassJob ? player.Name.ToString() : null;
}
// Identify the owner of a companion, mount or monster and apply the corresponding collection.
// Companions and mounts get set to the actor before them in the table if it exists.
// Monsters with a owner use that owner if it exists.
private static string? GetOwnerName( GameObject* gameObject )
{
GameObject* owner = null;
if( ( ObjectKind )gameObject->GetObjectKind() is ObjectKind.Companion or ObjectKind.MountType && gameObject->ObjectIndex > 0 )
{
owner = ( GameObject* )Dalamud.Objects[ gameObject->ObjectIndex - 1 ]?.Address;
}
else if( gameObject->OwnerID != 0xE0000000 )
{
owner = ( GameObject* )Dalamud.Objects.SearchById( gameObject->OwnerID )?.Address;
}
if( owner != null )
{
return new Utf8String( owner->Name ).ToString();
}
return null;
}
// Identify the correct collection for a GameObject by index and name.
private static ModCollection IdentifyCollection( GameObject* gameObject )
{
@ -204,7 +227,7 @@ public unsafe partial class PathResolver
>= 200 => GetCutsceneName( gameObject ),
_ => null,
}
?? new Utf8String( gameObject->Name ).ToString();
?? GetOwnerName( gameObject ) ?? new Utf8String( gameObject->Name ).ToString();
return Penumbra.CollectionManager.Character( name );
}

View file

@ -0,0 +1,88 @@
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 33 C0 48 89 83 ?? ?? ?? ?? 48 89 83 ?? ?? ?? ?? C7 83", ScanType = ScanType.StaticAddress )]
public IntPtr* DrawObjectMonsterVTable;
public Hook<GeneralResolveDelegate>? ResolveMonsterDecalPathHook;
public Hook<EidResolveDelegate>? ResolveMonsterEidPathHook;
public Hook<GeneralResolveDelegate>? ResolveMonsterImcPathHook;
public Hook<MPapResolveDelegate>? ResolveMonsterMPapPathHook;
public Hook<GeneralResolveDelegate>? ResolveMonsterMdlPathHook;
public Hook<MaterialResolveDetour>? ResolveMonsterMtrlPathHook;
public Hook<MaterialResolveDetour>? ResolveMonsterPapPathHook;
public Hook<GeneralResolveDelegate>? ResolveMonsterPhybPathHook;
public Hook<GeneralResolveDelegate>? ResolveMonsterSklbPathHook;
public Hook<GeneralResolveDelegate>? ResolveMonsterSkpPathHook;
public Hook<EidResolveDelegate>? ResolveMonsterTmbPathHook;
public Hook<MaterialResolveDetour>? ResolveMonsterVfxPathHook;
private void SetupMonsterHooks()
{
ResolveMonsterDecalPathHook = new Hook<GeneralResolveDelegate>( DrawObjectMonsterVTable[ResolveDecalIdx], ResolveMonsterDecalDetour );
ResolveMonsterEidPathHook = new Hook<EidResolveDelegate>( DrawObjectMonsterVTable[ResolveEidIdx], ResolveMonsterEidDetour );
ResolveMonsterImcPathHook = new Hook<GeneralResolveDelegate>( DrawObjectMonsterVTable[ResolveImcIdx], ResolveMonsterImcDetour );
ResolveMonsterMPapPathHook = new Hook<MPapResolveDelegate>( DrawObjectMonsterVTable[ResolveMPapIdx], ResolveMonsterMPapDetour );
ResolveMonsterMdlPathHook = new Hook<GeneralResolveDelegate>( DrawObjectMonsterVTable[ResolveMdlIdx], ResolveMonsterMdlDetour );
ResolveMonsterMtrlPathHook = new Hook<MaterialResolveDetour>( DrawObjectMonsterVTable[ResolveMtrlIdx], ResolveMonsterMtrlDetour );
ResolveMonsterPapPathHook = new Hook<MaterialResolveDetour>( DrawObjectMonsterVTable[ResolvePapIdx], ResolveMonsterPapDetour );
ResolveMonsterPhybPathHook = new Hook<GeneralResolveDelegate>( DrawObjectMonsterVTable[ResolvePhybIdx], ResolveMonsterPhybDetour );
ResolveMonsterSklbPathHook = new Hook<GeneralResolveDelegate>( DrawObjectMonsterVTable[ResolveSklbIdx], ResolveMonsterSklbDetour );
ResolveMonsterSkpPathHook = new Hook<GeneralResolveDelegate>( DrawObjectMonsterVTable[ResolveSkpIdx], ResolveMonsterSkpDetour );
ResolveMonsterTmbPathHook = new Hook<EidResolveDelegate>( DrawObjectMonsterVTable[ResolveTmbIdx], ResolveMonsterTmbDetour );
ResolveMonsterVfxPathHook = new Hook<MaterialResolveDetour>( DrawObjectMonsterVTable[ResolveVfxIdx], ResolveMonsterVfxDetour );
}
private void EnableMonsterHooks()
{
ResolveMonsterDecalPathHook?.Enable();
ResolveMonsterEidPathHook?.Enable();
ResolveMonsterImcPathHook?.Enable();
ResolveMonsterMPapPathHook?.Enable();
ResolveMonsterMdlPathHook?.Enable();
ResolveMonsterMtrlPathHook?.Enable();
ResolveMonsterPapPathHook?.Enable();
ResolveMonsterPhybPathHook?.Enable();
ResolveMonsterSklbPathHook?.Enable();
ResolveMonsterSkpPathHook?.Enable();
ResolveMonsterTmbPathHook?.Enable();
ResolveMonsterVfxPathHook?.Enable();
}
private void DisableMonsterHooks()
{
ResolveMonsterDecalPathHook?.Disable();
ResolveMonsterEidPathHook?.Disable();
ResolveMonsterImcPathHook?.Disable();
ResolveMonsterMPapPathHook?.Disable();
ResolveMonsterMdlPathHook?.Disable();
ResolveMonsterMtrlPathHook?.Disable();
ResolveMonsterPapPathHook?.Disable();
ResolveMonsterPhybPathHook?.Disable();
ResolveMonsterSklbPathHook?.Disable();
ResolveMonsterSkpPathHook?.Disable();
ResolveMonsterTmbPathHook?.Disable();
ResolveMonsterVfxPathHook?.Disable();
}
private void DisposeMonsterHooks()
{
ResolveMonsterDecalPathHook?.Dispose();
ResolveMonsterEidPathHook?.Dispose();
ResolveMonsterImcPathHook?.Dispose();
ResolveMonsterMPapPathHook?.Dispose();
ResolveMonsterMdlPathHook?.Dispose();
ResolveMonsterMtrlPathHook?.Dispose();
ResolveMonsterPapPathHook?.Dispose();
ResolveMonsterPhybPathHook?.Dispose();
ResolveMonsterSklbPathHook?.Dispose();
ResolveMonsterSkpPathHook?.Dispose();
ResolveMonsterTmbPathHook?.Dispose();
ResolveMonsterVfxPathHook?.Dispose();
}
}

View file

@ -98,6 +98,43 @@ public unsafe partial class PathResolver
private IntPtr ResolveWeaponVfxDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, ulong unk5 )
=> ResolveWeaponPathDetour( drawObject, ResolveWeaponVfxPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) );
// Monsters
private IntPtr ResolveMonsterDecalDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 )
=> ResolvePathDetour( drawObject, ResolveMonsterDecalPathHook!.Original( drawObject, path, unk3, unk4 ) );
private IntPtr ResolveMonsterEidDetour( IntPtr drawObject, IntPtr path, IntPtr unk3 )
=> ResolvePathDetour( drawObject, ResolveMonsterEidPathHook!.Original( drawObject, path, unk3 ) );
private IntPtr ResolveMonsterImcDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 )
=> ResolvePathDetour( drawObject, ResolveMonsterImcPathHook!.Original( drawObject, path, unk3, unk4 ) );
private IntPtr ResolveMonsterMPapDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, uint unk5 )
=> ResolvePathDetour( drawObject, ResolveMonsterMPapPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) );
private IntPtr ResolveMonsterMdlDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint modelType )
=> ResolvePathDetour( drawObject, ResolveMonsterMdlPathHook!.Original( drawObject, path, unk3, modelType ) );
private IntPtr ResolveMonsterMtrlDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, ulong unk5 )
=> ResolvePathDetour( drawObject, ResolveMonsterMtrlPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) );
private IntPtr ResolveMonsterPapDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, ulong unk5 )
=> ResolvePathDetour( drawObject, ResolveMonsterPapPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) );
private IntPtr ResolveMonsterPhybDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 )
=> ResolvePathDetour( drawObject, ResolveMonsterPhybPathHook!.Original( drawObject, path, unk3, unk4 ) );
private IntPtr ResolveMonsterSklbDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 )
=> ResolvePathDetour( drawObject, ResolveMonsterSklbPathHook!.Original( drawObject, path, unk3, unk4 ) );
private IntPtr ResolveMonsterSkpDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 )
=> ResolvePathDetour( drawObject, ResolveMonsterSkpPathHook!.Original( drawObject, path, unk3, unk4 ) );
private IntPtr ResolveMonsterTmbDetour( IntPtr drawObject, IntPtr path, IntPtr unk3 )
=> ResolvePathDetour( drawObject, ResolveMonsterTmbPathHook!.Original( drawObject, path, unk3 ) );
private IntPtr ResolveMonsterVfxDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, ulong unk5 )
=> ResolvePathDetour( drawObject, ResolveMonsterVfxPathHook!.Original( drawObject, path, unk3, unk4, unk5 ) );
// Implementation
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]

View file

@ -23,7 +23,6 @@ public unsafe partial class PathResolver
public Hook< EidResolveDelegate >? ResolveWeaponTmbPathHook;
public Hook< MaterialResolveDetour >? ResolveWeaponVfxPathHook;
private void SetupWeaponHooks()
{
ResolveWeaponDecalPathHook = new Hook< GeneralResolveDelegate >( DrawObjectWeaponVTable[ ResolveDecalIdx ], ResolveWeaponDecalDetour );

View file

@ -25,6 +25,7 @@ public partial class PathResolver : IDisposable
SignatureHelper.Initialise( this );
SetupHumanHooks();
SetupWeaponHooks();
SetupMonsterHooks();
SetupMetaHooks();
}
@ -82,6 +83,7 @@ public partial class PathResolver : IDisposable
EnableHumanHooks();
EnableWeaponHooks();
EnableMonsterHooks();
EnableMtrlHooks();
EnableDataHooks();
EnableMetaHooks();
@ -100,6 +102,7 @@ public partial class PathResolver : IDisposable
Enabled = false;
DisableHumanHooks();
DisableWeaponHooks();
DisableMonsterHooks();
DisableMtrlHooks();
DisableDataHooks();
DisableMetaHooks();
@ -116,6 +119,7 @@ public partial class PathResolver : IDisposable
Disable();
DisposeHumanHooks();
DisposeWeaponHooks();
DisposeMonsterHooks();
DisposeMtrlHooks();
DisposeDataHooks();
DisposeMetaHooks();