Glamourer/Penumbra.PlayerWatch/CharacterFactory.cs
2022-08-25 13:34:10 +02:00

63 lines
No EOL
1.9 KiB
C#

using System;
using System.Reflection;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
namespace Penumbra.PlayerWatch
{
public static class CharacterFactory
{
private static ConstructorInfo? _characterConstructor;
private static void Initialize()
{
_characterConstructor ??= typeof( Character ).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new[]
{
typeof( IntPtr ),
}, null )!;
}
private static Character Character( IntPtr address )
{
Initialize();
return ( Character )_characterConstructor?.Invoke( new object[]
{
address,
} )!;
}
public static Character? Convert( GameObject? actor )
{
if( actor == null )
{
return null;
}
return actor switch
{
PlayerCharacter p => p,
BattleChara b => b,
_ => actor.ObjectKind switch
{
ObjectKind.BattleNpc => Character( actor.Address ),
ObjectKind.Companion => Character( actor.Address ),
ObjectKind.Retainer => Character( actor.Address ),
ObjectKind.EventNpc => Character( actor.Address ),
_ => null,
},
};
}
}
public static class GameObjectExtensions
{
private const int ModelTypeOffset = 0x01B4;
public static unsafe int ModelType( this GameObject actor )
=> *( int* )( actor.Address + ModelTypeOffset );
public static unsafe void SetModelType( this GameObject actor, int value )
=> *( int* )( actor.Address + ModelTypeOffset ) = value;
}
}