mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Fix companion identification, extract offsets and vtable indices to separate file.
This commit is contained in:
parent
79eee0e2c7
commit
4059e0630a
9 changed files with 60 additions and 22 deletions
|
|
@ -204,7 +204,7 @@ public sealed partial class ActorManager : IDisposable
|
||||||
if (agent == null || agent->Data == null)
|
if (agent == null || agent->Data == null)
|
||||||
return ActorIdentifier.Invalid;
|
return ActorIdentifier.Invalid;
|
||||||
|
|
||||||
var worldId = *(ushort*)((byte*)agent->Data + 0xC0);
|
var worldId = *(ushort*)((byte*)agent->Data + Offsets.AgentCharaCardDataWorldId);
|
||||||
return CreatePlayer(new ByteString(agent->Data->Name.StringPtr), worldId);
|
return CreatePlayer(new ByteString(agent->Data->Name.StringPtr), worldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -306,7 +306,7 @@ public partial class ActorManager
|
||||||
{
|
{
|
||||||
var dataId = actor->DataID;
|
var dataId = actor->DataID;
|
||||||
// Special case for squadron that is also in the game functions, cf. E8 ?? ?? ?? ?? 89 87 ?? ?? ?? ?? 4C 89 BF
|
// Special case for squadron that is also in the game functions, cf. E8 ?? ?? ?? ?? 89 87 ?? ?? ?? ?? 4C 89 BF
|
||||||
if (dataId == 0xf845d)
|
if (dataId == 0xF845D)
|
||||||
dataId = actor->GetNpcID();
|
dataId = actor->GetNpcID();
|
||||||
if (MannequinIds.Contains(dataId))
|
if (MannequinIds.Contains(dataId))
|
||||||
{
|
{
|
||||||
|
|
@ -338,7 +338,7 @@ public partial class ActorManager
|
||||||
if (owner == null)
|
if (owner == null)
|
||||||
return ActorIdentifier.Invalid;
|
return ActorIdentifier.Invalid;
|
||||||
|
|
||||||
var dataId = GetCompanionId(actor, owner);
|
var dataId = GetCompanionId(actor, (Character*) owner);
|
||||||
var name = new ByteString(owner->Name);
|
var name = new ByteString(owner->Name);
|
||||||
var homeWorld = ((Character*)owner)->HomeWorld;
|
var homeWorld = ((Character*)owner)->HomeWorld;
|
||||||
return check
|
return check
|
||||||
|
|
@ -365,13 +365,13 @@ public partial class ActorManager
|
||||||
/// Obtain the current companion ID for an object by its actor and owner.
|
/// Obtain the current companion ID for an object by its actor and owner.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private unsafe uint GetCompanionId(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* actor,
|
private unsafe uint GetCompanionId(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* actor,
|
||||||
FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner) // TODO: CS Update
|
Character* owner) // TODO: CS Update
|
||||||
{
|
{
|
||||||
return (ObjectKind)actor->ObjectKind switch
|
return (ObjectKind)actor->ObjectKind switch
|
||||||
{
|
{
|
||||||
ObjectKind.MountType => *(ushort*)((byte*)owner + 0x650 + 0x18),
|
ObjectKind.MountType => owner->Mount.MountId,
|
||||||
(ObjectKind)15 => *(ushort*)((byte*)owner + 0x860 + 0x18),
|
(ObjectKind)15 => owner->Ornament.OrnamentId,
|
||||||
ObjectKind.Companion => *(ushort*)((byte*)actor + 0x1AAC),
|
ObjectKind.Companion => actor->DataID,
|
||||||
_ => actor->DataID,
|
_ => actor->DataID,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -400,17 +400,17 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
|
||||||
|
|
||||||
public static unsafe ulong KeyFromCharacterBase(CharacterBase* drawObject)
|
public static unsafe ulong KeyFromCharacterBase(CharacterBase* drawObject)
|
||||||
{
|
{
|
||||||
var type = (*(delegate* unmanaged<CharacterBase*, uint>**)drawObject)[50](drawObject);
|
var type = (*(delegate* unmanaged<CharacterBase*, uint>**)drawObject)[Offsets.DrawObjectGetModelTypeVfunc](drawObject);
|
||||||
var unk = (ulong)*((byte*)drawObject + 0x8E8) << 8;
|
var unk = (ulong)*((byte*)drawObject + Offsets.DrawObjectModelUnk1) << 8;
|
||||||
return type switch
|
return type switch
|
||||||
{
|
{
|
||||||
1 => type | unk,
|
1 => type | unk,
|
||||||
2 => type | unk | ((ulong)*(ushort*)((byte*)drawObject + 0x908) << 16),
|
2 => type | unk | ((ulong)*(ushort*)((byte*)drawObject + Offsets.DrawObjectModelUnk3) << 16),
|
||||||
3 => type
|
3 => type
|
||||||
| unk
|
| unk
|
||||||
| ((ulong)*(ushort*)((byte*)drawObject + 0x8F0) << 16)
|
| ((ulong)*(ushort*)((byte*)drawObject + Offsets.DrawObjectModelUnk2) << 16)
|
||||||
| ((ulong)**(ushort**)((byte*)drawObject + 0x910) << 32)
|
| ((ulong)**(ushort**)((byte*)drawObject + Offsets.DrawObjectModelUnk4) << 32)
|
||||||
| ((ulong)**(ushort**)((byte*)drawObject + 0x910) << 40),
|
| ((ulong)**(ushort**)((byte*)drawObject + Offsets.DrawObjectModelUnk3) << 40),
|
||||||
_ => 0u,
|
_ => 0u,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
35
Penumbra.GameData/Offsets.cs
Normal file
35
Penumbra.GameData/Offsets.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
namespace Penumbra.GameData;
|
||||||
|
|
||||||
|
public static class Offsets
|
||||||
|
{
|
||||||
|
// ActorManager.Data
|
||||||
|
public const int AgentCharaCardDataWorldId = 0xC0;
|
||||||
|
|
||||||
|
// ObjectIdentification
|
||||||
|
public const int DrawObjectGetModelTypeVfunc = 50;
|
||||||
|
private const int DrawObjectModelBase = 0x8E8;
|
||||||
|
public const int DrawObjectModelUnk1 = DrawObjectModelBase;
|
||||||
|
public const int DrawObjectModelUnk2 = DrawObjectModelBase + 0x08;
|
||||||
|
public const int DrawObjectModelUnk3 = DrawObjectModelBase + 0x20;
|
||||||
|
public const int DrawObjectModelUnk4 = DrawObjectModelBase + 0x28;
|
||||||
|
|
||||||
|
// PathResolver.AnimationState
|
||||||
|
public const int GetGameObjectIdxVfunc = 28;
|
||||||
|
public const int TimeLinePtr = 0x50;
|
||||||
|
|
||||||
|
// PathResolver.Meta
|
||||||
|
public const int UpdateModelSkip = 0x90c;
|
||||||
|
public const int GetEqpIndirectSkip1 = 0xA30;
|
||||||
|
public const int GetEqpIndirectSkip2 = 0xA28;
|
||||||
|
|
||||||
|
// FontReloader
|
||||||
|
public const int ReloadFontsVfunc = 43;
|
||||||
|
|
||||||
|
// ObjectReloader
|
||||||
|
public const int EnableDrawVfunc = 16;
|
||||||
|
public const int DisableDrawVfunc = 17;
|
||||||
|
|
||||||
|
// ResourceHandle
|
||||||
|
public const int ResourceHandleGetDataVfunc = 23;
|
||||||
|
public const int ResourceHandleGetLengthVfunc = 17;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
||||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
using Penumbra.GameData;
|
||||||
|
|
||||||
namespace Penumbra.Interop;
|
namespace Penumbra.Interop;
|
||||||
|
|
||||||
|
|
@ -51,6 +52,6 @@ public static unsafe class FontReloader
|
||||||
}
|
}
|
||||||
|
|
||||||
AtkModule = &atkModule->AtkModule;
|
AtkModule = &atkModule->AtkModule;
|
||||||
ReloadFontsFunc = ( ( delegate* unmanaged< AtkModule*, bool, bool, void >* )AtkModule->vtbl )[ 43 ];
|
ReloadFontsFunc = ( ( delegate* unmanaged< AtkModule*, bool, bool, void >* )AtkModule->vtbl )[ Offsets.ReloadFontsVfunc ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Penumbra.Api;
|
using Penumbra.Api;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
using Penumbra.GameData;
|
||||||
using Penumbra.Interop.Structs;
|
using Penumbra.Interop.Structs;
|
||||||
|
|
||||||
namespace Penumbra.Interop;
|
namespace Penumbra.Interop;
|
||||||
|
|
@ -23,10 +24,10 @@ public unsafe partial class ObjectReloader
|
||||||
|
|
||||||
// VFuncs that disable and enable draw, used only for GPose actors.
|
// VFuncs that disable and enable draw, used only for GPose actors.
|
||||||
private static void DisableDraw( GameObject actor )
|
private static void DisableDraw( GameObject actor )
|
||||||
=> ( ( delegate* unmanaged< IntPtr, void >** )actor.Address )[ 0 ][ 17 ]( actor.Address );
|
=> ( ( delegate* unmanaged< IntPtr, void >** )actor.Address )[ 0 ][ Offsets.DisableDrawVfunc ]( actor.Address );
|
||||||
|
|
||||||
private static void EnableDraw( GameObject actor )
|
private static void EnableDraw( GameObject actor )
|
||||||
=> ( ( delegate* unmanaged< IntPtr, void >** )actor.Address )[ 0 ][ 16 ]( actor.Address );
|
=> ( ( delegate* unmanaged< IntPtr, void >** )actor.Address )[ 0 ][ Offsets.EnableDrawVfunc ]( actor.Address );
|
||||||
|
|
||||||
// Check whether we currently are in GPose.
|
// Check whether we currently are in GPose.
|
||||||
// Also clear the name list.
|
// Also clear the name list.
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ public unsafe partial class PathResolver
|
||||||
{
|
{
|
||||||
if( timeline != IntPtr.Zero )
|
if( timeline != IntPtr.Zero )
|
||||||
{
|
{
|
||||||
var getGameObjectIdx = ( ( delegate* unmanaged< IntPtr, int >** )timeline )[ 0 ][ 28 ];
|
var getGameObjectIdx = ( ( delegate* unmanaged< IntPtr, int >** )timeline )[ 0 ][ Offsets.GetGameObjectIdxVfunc ];
|
||||||
var idx = getGameObjectIdx( timeline );
|
var idx = getGameObjectIdx( timeline );
|
||||||
if( idx >= 0 && idx < Dalamud.Objects.Length )
|
if( idx >= 0 && idx < Dalamud.Objects.Length )
|
||||||
{
|
{
|
||||||
|
|
@ -192,7 +192,7 @@ public unsafe partial class PathResolver
|
||||||
private void LoadSomePapDetour( IntPtr a1, int a2, IntPtr a3, int a4 )
|
private void LoadSomePapDetour( IntPtr a1, int a2, IntPtr a3, int a4 )
|
||||||
{
|
{
|
||||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadPap );
|
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadPap );
|
||||||
var timelinePtr = a1 + 0x50;
|
var timelinePtr = a1 + Offsets.TimeLinePtr;
|
||||||
var last = _animationLoadData;
|
var last = _animationLoadData;
|
||||||
if( timelinePtr != IntPtr.Zero )
|
if( timelinePtr != IntPtr.Zero )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ public unsafe partial class PathResolver
|
||||||
{
|
{
|
||||||
// Shortcut because this is called all the time.
|
// Shortcut because this is called all the time.
|
||||||
// Same thing is checked at the beginning of the original function.
|
// Same thing is checked at the beginning of the original function.
|
||||||
if( *( int* )( drawObject + 0x90c ) == 0 )
|
if( *( int* )( drawObject + Offsets.UpdateModelSkip ) == 0 )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,7 @@ public unsafe partial class PathResolver
|
||||||
{
|
{
|
||||||
// Shortcut because this is also called all the time.
|
// Shortcut because this is also called all the time.
|
||||||
// Same thing is checked at the beginning of the original function.
|
// Same thing is checked at the beginning of the original function.
|
||||||
if( ( *( byte* )( drawObject + 0xa30 ) & 1 ) == 0 || *( ulong* )( drawObject + 0xa28 ) == 0 )
|
if( ( *( byte* )( drawObject + Offsets.GetEqpIndirectSkip1 ) & 1 ) == 0 || *( ulong* )( drawObject + Offsets.GetEqpIndirectSkip2 ) == 0 )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||||
|
using Penumbra.GameData;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
||||||
namespace Penumbra.Interop.Structs;
|
namespace Penumbra.Interop.Structs;
|
||||||
|
|
@ -87,10 +88,10 @@ public unsafe struct ResourceHandle
|
||||||
|
|
||||||
// May return null.
|
// May return null.
|
||||||
public static byte* GetData( ResourceHandle* handle )
|
public static byte* GetData( ResourceHandle* handle )
|
||||||
=> ( ( delegate* unmanaged< ResourceHandle*, byte* > )handle->VTable[ 23 ] )( handle );
|
=> ( ( delegate* unmanaged< ResourceHandle*, byte* > )handle->VTable[ Offsets.ResourceHandleGetDataVfunc ] )( handle );
|
||||||
|
|
||||||
public static ulong GetLength( ResourceHandle* handle )
|
public static ulong GetLength( ResourceHandle* handle )
|
||||||
=> ( ( delegate* unmanaged< ResourceHandle*, ulong > )handle->VTable[ 17 ] )( handle );
|
=> ( ( delegate* unmanaged< ResourceHandle*, ulong > )handle->VTable[ Offsets.ResourceHandleGetLengthVfunc ] )( handle );
|
||||||
|
|
||||||
|
|
||||||
// Only use these if you know what you are doing.
|
// Only use these if you know what you are doing.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue