forked from aers/FFXIVClientStructs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCharacter.cs
More file actions
210 lines (170 loc) · 9.2 KB
/
Character.cs
File metadata and controls
210 lines (170 loc) · 9.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
using FFXIVClientStructs.FFXIV.Client.Game.Control;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
namespace FFXIVClientStructs.FFXIV.Client.Game.Character;
// Client::Game::Character::Character
// Client::Game::Object::GameObject
// Client::Game::Character::CharacterData
[GenerateInterop(isInherited: true)]
[Inherits<GameObject>, Inherits<CharacterData>]
[StructLayout(LayoutKind.Explicit, Size = 0x2370)]
[VirtualTable("48 8D 05 ?? ?? ?? ?? 48 89 07 48 8D 8F ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 87 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8D 8F ?? ?? ?? ?? 33 ED 48 8D 05 ?? ?? ?? ??", 3, 87)]
public unsafe partial struct Character {
[FieldOffset(0x600)] public MovementStateOptions MovementState;
[BitField<bool>(nameof(IsSwimming), 5)] // found in Client::Game::Event::EventSceneModuleUsualImpl.IsSwimming
[FieldOffset(0x628)] public byte Flags628;
[FieldOffset(0x630)] public EmoteController EmoteController;
[FieldOffset(0x670)] public MountContainer Mount;
[FieldOffset(0x6D8)] public CompanionContainer CompanionData;
[FieldOffset(0x6F8)] public DrawDataContainer DrawData;
[FieldOffset(0x960)] public OrnamentContainer OrnamentData;
[FieldOffset(0x9D8)] public ReaperShroudContainer ReaperShroud;
[FieldOffset(0xA30)] public TimelineContainer Timeline;
[FieldOffset(0xD80)] public LookAtContainer LookAt;
[BitField<bool>(nameof(IsOffhandDrawn), 0)]
[FieldOffset(0x1980)] public byte WeaponFlags;
[FieldOffset(0x1988)] public VfxContainer Vfx;
[FieldOffset(0x1A90)] public EffectContainer Effects;
[FieldOffset(0x1B10)] public CharacterSetupContainer CharacterSetup;
// 0x1AA8: start of some substructure
[FieldOffset(0x1B28)] public ModelContainer ModelContainer;
[BitField<bool>(nameof(IsPartyMember), 0)]
[BitField<bool>(nameof(IsAllianceMember), 1)]
[BitField<bool>(nameof(IsFriend), 2)]
[FieldOffset(0x1CE2)] public byte RelationFlags;
// 0x40 = All attacks will be cancelled, character is doing the the 'winded' emote, used in e.g. 'Strange Bedfellows' and 'Combat Evolved' when quest expects an item to be used on the character
[FieldOffset(0x1CE8)] public byte ActorControlFlags;
[FieldOffset(0x21E0)] public Balloon Balloon;
[FieldOffset(0x2260)] public NpcYellBalloon YellBalloon;
[FieldOffset(0x22E8)] public float Alpha;
[FieldOffset(0x22F8)] public Companion* CompanionObject; // minion
[FieldOffset(0x2300), FixedSizeArray(isString: true)] internal FixedSizeArray7<byte> _freeCompanyTag;
/// <summary>
/// The current (hard) target for this Character. This will not be set for the LocalPlayer.
/// </summary>
/// <remarks>
/// Developers should generally use <see cref="GetTargetId"/> over reading this field directly, as it will
/// properly handle resolving the target for the local player.
/// </remarks>
[FieldOffset(0x2308)] public GameObjectId TargetId;
/// <summary>
/// The current soft target for this Character. This will not be set for the LocalPlayer.
/// </summary>
/// <remarks>
/// Developers should generally use <see cref="GetSoftTargetId"/> over reading this field directly, as it will
/// properly handle resolving the soft target for the local player.
/// </remarks>
[FieldOffset(0x2310)] public GameObjectId SoftTargetId;
[FieldOffset(0x231C)] public float CastRotation;
[FieldOffset(0x2338)] public uint NameId;
[FieldOffset(0x2344)] public uint CompanionOwnerId; // TODO: Find a better name as it is used to index into FurnitureMemory for IndoorHousing
[FieldOffset(0x2350)] public ulong AccountId;
[FieldOffset(0x2358)] public ulong ContentId;
[FieldOffset(0x2360)] public ushort CurrentWorld;
[FieldOffset(0x2362)] public ushort HomeWorld;
[FieldOffset(0x2364)] public CharacterModes Mode;
[FieldOffset(0x2365)] public byte ModeParam; // Different purpose depending on mode. See CharacterModes for more info.
[FieldOffset(0x2366)] public byte GMRank;
/// <remarks> See <see cref="Sound.SoundVolumeCategory"/>. </remarks>
[FieldOffset(0x2369)] public byte SoundVolumeCategory;
[FieldOffset(0x236A)] public byte SoundVolumeCategoryOverride;
[FieldOffset(0x236B)] private byte SoundFlags; // 0x40 = SoundVolumeCategory determined
public bool IsWeaponDrawn => Timeline.IsWeaponDrawn;
public bool IsCasting => VirtualTable != null && GetCastInfo() is var info && info != null && info->IsCasting;
/// <summary>
/// Gets the (hard) target ID for this character. If this character is the LocalPlayer, this will instead read the
/// target ID from the <see cref="TargetSystem"/>. Used for calculating ToT via /assist.
/// </summary>
/// <returns>Returns the object ID of this character's target.</returns>
[MemberFunction("E8 ?? ?? ?? ?? 4C 8B E0 48 8B 4F")]
public partial GameObjectId GetTargetId();
[MemberFunction("E8 ?? ?? ?? ?? 48 3B FD 74 36")]
public partial void SetTargetId(GameObjectId id);
/// <summary>
/// Gets the soft target ID for this character. If this character is the LocalPlayer, this will instead read the
/// soft target ID from the <see cref="TargetSystem"/>.
/// </summary>
/// <returns>Returns the object ID of this character's target.</returns>
[MemberFunction("E8 ?? ?? ?? ?? 48 8B F0 EB 12")]
public partial GameObjectId GetSoftTargetId();
[MemberFunction("E8 ?? ?? ?? ?? EB 05 4C 3B E0")]
public partial void SetSoftTargetId(GameObjectId id);
public bool IsMounted() => Mount.MountId != 0;
[MemberFunction("E8 ?? ?? ?? ?? 45 84 FF 75 40")]
public partial void SetMode(CharacterModes mode, byte modeParam);
/// <summary> Can only be used for Mounts, Minions, and Ornaments. Literally just checks if the game object at index - 1 is a character and returns that. </summary>
[MemberFunction("E8 ?? ?? ?? ?? 48 3B 47 ?? 75 ?? 48 8B CE")]
public partial Character* GetParentCharacter();
[MemberFunction("E8 ?? ?? ?? ?? 38 43 ?? 0F 85")]
public partial bool HasStatus(uint statusId);
/// <summary>Check if this character is in a jumping/falling animation.</summary>
[MemberFunction("E8 ?? ?? ?? ?? 84 C0 75 46 48 8B 4B 08")]
public partial bool IsJumping();
/// <summary> Check if the character is using the World Visit system. </summary>
[MemberFunction("E8 ?? ?? ?? ?? 84 C0 8B CF")]
public partial bool IsWanderer();
/// <summary> Check if the character is using the Data Center Travel system. </summary>
[MemberFunction("E8 ?? ?? ?? ?? 84 C0 75 ?? 40 0F B6 C6")]
public partial bool IsTraveler();
/// <summary> Check if the character is using the Cross-region Data Center Travel system. </summary>
[MemberFunction("E8 ?? ?? ?? ?? 84 C0 74 ?? 80 4E ?? ?? ?? ?? ?? 48 8B CB FF 92")]
public partial bool IsVoyager();
/// <summary>
/// Checks if Character is in a PvP state <br/>
/// Will need to be called multiple times before returning correct result
/// </summary>
[MemberFunction("E8 ?? ?? ?? ?? 84 C0 75 05 8B 4D F4")]
public partial bool IsInPvP();
/// <summary>
/// Resolves the correct emote id, based on the targets height or distance.
/// </summary>
/// <param name="emoteId">The base emote id.</param>
/// <param name="options">The PlayEmote options.</param>
/// <returns> The adjusted emote id for the target. </returns>
/// <remarks> For example, this is used for Throw/Snowball, Dote, Splash, All Saints' Charm, Bouquet or Photograph. </remarks>
[MemberFunction("E8 ?? ?? ?? ?? 48 8B 5D ?? 0F B7 F8")]
public partial ushort ResolveTargetedEmoteId(ushort emoteId, EmoteController.PlayEmoteOption* options); // TODO: judging from the address, this might be a static function
[VirtualFunction(77)]
public partial StatusManager* GetStatusManager();
/// <summary>
/// Gets the <see cref="CastInfo"/> struct for this Character.
/// May be null for certain Character subclasses, e.g. <see cref="Companion"/>.
/// </summary>
/// <returns>Returns a pointer to a CastInfo struct, or <c>null</c>.</returns>
[VirtualFunction(79)]
public partial CastInfo* GetCastInfo();
[VirtualFunction(81)]
public partial ActionEffectHandler* GetActionEffectHandler();
[VirtualFunction(83)]
public partial ForayInfo* GetForayInfo();
}
public enum MovementStateOptions : byte {
Normal = 0,
Flying = 1,
Diving = 2,
// Spectating = 3,
}
// LogMessages for errors starting at 7700
public enum CharacterModes : byte {
None = 0, // Mode is never used
Normal = 1, // Param always 0
Dead = 2,
EmoteLoop = 3, // Param is an EmoteMode entry
Mounted = 4, // Param always 0
Crafting = 5, // Param always 0
Gathering = 6,
MateriaAttach = 7,
AnimLock = 8, // Param always 0
Carrying = 9, // Param is a Carry entry
RidingPillion = 10, // Param is the pillion seat number
InPositionLoop = 11, // Param is an EmoteMode entry
RaceChocobo = 12,
TripleTriad = 13,
Lovm = 14, // Lord of Verminion
// CustomMatch = 15, // PvP, untested
Performance = 16, // Param is Perform row id (the instrument)
}
[StructLayout(LayoutKind.Explicit, Size = 2)]
public struct ForayInfo {
[FieldOffset(0x00)] public byte Level;
[FieldOffset(0x01)] public byte Element;
}