Glamourer/Penumbra.PlayerWatch/CharacterFactory.cs

58 lines
1.8 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
{
public static unsafe uint ModelType(this Character actor)
=> (uint) ((FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)actor.Address)->CharacterData.ModelCharaId;
public static unsafe void SetModelType(this Character actor, uint value)
=> ((FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)actor.Address)->CharacterData.ModelCharaId = (int) value;
}