diff --git a/7.2 todo list.txt b/7.2 todo list.txt index f7c59be3b..3cfdb42e4 100644 --- a/7.2 todo list.txt +++ b/7.2 todo list.txt @@ -1,7 +1,5 @@ NOTE: - @file:///d%3A/source/repos/FFXIVClientStructs/FFXIVClientStructs/FFXIV/Client/Game/UI/WeaponState.cs - ☐ [FieldOffset(0x10)] public AutoAttackState AutoAttackState; // note: not sure whether this is actually a part of this structure or next field of a parent @file:///d%3A/source/repos/FFXIVClientStructs/FFXIVClientStructs/FFXIV/Client/Game/UI/WeaponState.cs#10 @file:///d%3A/source/repos/FFXIVClientStructs/FFXIVClientStructs/FFXIV/Client/LayoutEngine/ILayoutInstance.cs ☐ [FieldOffset(0x0C)] public int Type; // note: this is a padding field that in some contexts is used to store collider type @file:///d%3A/source/repos/FFXIVClientStructs/FFXIVClientStructs/FFXIV/Client/LayoutEngine/ILayoutInstance.cs#159 @file:///d%3A/source/repos/FFXIVClientStructs/FFXIVClientStructs/FFXIV/Client/LayoutEngine/LayoutManager.cs diff --git a/FFXIVClientStructs/FFXIV/Client/Game/UI/WeaponState.cs b/FFXIVClientStructs/FFXIV/Client/Game/UI/WeaponState.cs index 56fd37e8d..6b8678540 100644 --- a/FFXIVClientStructs/FFXIV/Client/Game/UI/WeaponState.cs +++ b/FFXIVClientStructs/FFXIV/Client/Game/UI/WeaponState.cs @@ -1,21 +1,135 @@ namespace FFXIVClientStructs.FFXIV.Client.Game.UI; - // Client::Game::UI::WeaponState +/// +/// Represents the in-memory layout of the WeaponState structure. +/// +[GenerateInterop] [StructLayout(LayoutKind.Explicit, Size = 0x18)] -public struct WeaponState { - [FieldOffset(0x00)] public bool IsUnsheathed; - [FieldOffset(0x04)] public float SheatheCooldown; - [FieldOffset(0x08)] public float AutoSheathTimer; - [FieldOffset(0x0C)] public bool AutoSheatheState; - [FieldOffset(0x10)] public AutoAttackState AutoAttackState; // note: not sure whether this is actually a part of this structure or next field of a parent - [FieldOffset(0x10), Obsolete("Use AutoAttackState.IsAutoAttacking", true)] public bool IsAutoAttacking; +public partial struct WeaponState { + // Offset 0x00: IsUnsheathed – a bool flag indicating whether the weapon is unsheathed. + // Updated via SetUnsheathed/SetUnsheathed2. + [FieldOffset(0x00)] + public bool IsUnsheathed; + + // Offset 0x04: SheatheCooldown – a float representing the cooldown/timer value. + // The SetUnsheathed functions write the bytes 00 00 80 3F here, which corresponds to 1.0f. + [FieldOffset(0x04)] + public float SheatheCooldown; + + // Offset 0x08: AutoSheathTimer – another float value, likely used for auto-sheath timing. + // The Tick method updates this timer by subtracting a delta time. + [FieldOffset(0x08)] + public float AutoSheathTimer; + + // Offset 0x0C: AutoSheatheState – a bool flag used to control auto-sheath behavior. + // Checked (e.g. param_1[0x0C] != 0) in various code paths. + [FieldOffset(0x0C)] + public bool AutoSheatheState; + + // Offset 0x10: Originally, this offset was used for AutoAttackState. + // In older versions, a simple bool (IsAutoAttacking) resided here. + // In the current patch, analysis shows auto-attack state is handled globally via DAT_142921510. + [FieldOffset(0x10)] + public AutoAttackState AutoAttackState; + + /// + /// Keeping obsolete isAutoAttacking for removal later. + /// + [FieldOffset(0x10), Obsolete("Use AutoAttackState.IsAutoAttacking", true)] + public bool IsAutoAttacking; + + /// + /// Checks whether auto-sheathing is enabled. + /// Internally, this checks a config option and the current AutoSheatheState. + /// + [MemberFunction("E8 ?? ?? ?? ?? 84 C0 0F 85 ?? ?? ?? ?? 45 33 C0 48 8D 8B")] + public partial bool CanAutoSheathe(); + + /// + /// Extends the auto-sheath timer based on configuration settings. + /// Sets AutoSheatheState and resets AutoSheathTimer. + /// + [MemberFunction("E8 ?? ?? ?? ?? EB ?? 84 C0 79")] + public partial void ExtendAutoSheatheTimer(); + + /// + /// Called when the actor's weapon drawn state changes. + /// Updates the provided flag and triggers additional behavior. + /// + /// The new unsheathed state (true = unsheathed, false = sheathed). + /// Whether the change should occur instantly. + [MemberFunction("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 48 8B 3D ?? ?? ?? ?? 41 0F B6 E8 0F B6 DA")] + public partial void OnActorControlWeaponDrawn(bool newUnsheathedState, bool isInstant); + + /// + /// Updates the state every frame. + /// This method decrements timers, resets them if necessary, and triggers auto-attack + /// disablement via the global auto-attack state. + /// + [MemberFunction("E8 ?? ?? ?? ?? 48 8D 8F ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 87 ?? ?? ?? ?? 48 8B 18")] + public partial void Tick(); + + /// + /// Sets the unsheathed state using the first method. + /// This method may trigger animations or effects as needed. + /// + /// The new unsheathed state (true = unsheathed, false = sheathed). + /// Whether to send a network update. + /// Whether the change should occur instantly. + [MemberFunction("E8 ?? ?? ?? ?? F6 44 24 ?? ?? 75")] + public partial bool SetUnsheathed(bool newState, bool sendPacket, bool isInstant); + + /// + /// Sets the unsheathed state using the alternative variant (SetUnsheathed2). + /// This version may update state without sending network packets. + /// + /// The new unsheathed state (true = unsheathed, false = sheathed). + [MemberFunction("E9 ?? ?? ?? ?? 48 8D 8E ?? ?? ?? ?? 40 84 FF")] + public partial bool SetUnsheathed2(bool newState); } +/// +/// Represents the AutoAttackState structure. +/// Originally, this might have been embedded in WeaponState at offset 0x10, +/// but current analysis shows auto-attack is managed globally. +/// [GenerateInterop] [StructLayout(LayoutKind.Explicit, Size = 1)] public partial struct AutoAttackState { - [FieldOffset(0)] public bool IsAutoAttacking; - [MemberFunction("E8 ?? ?? ?? ?? EB 15 41 B0 01")] - public partial bool SetImpl(bool value, bool sendPacket, bool isInstant); + // Offset 0x00: A single byte that indicates if auto-attack is active. + [FieldOffset(0)] + public bool IsAutoAttacking; + + /// + /// Gets the current auto-attack state. + /// + [MemberFunction("E8 ?? ?? ?? ?? 84 C0 74 ?? 38 1D")] + public partial bool Get(); + + /// + /// Handles actor control updates related to AutoAttack state. + /// Note: Internally accesses LocalPlayer at offset 0x9a0 in version 7.0 (previously 0x9b0). + /// + /// The new state value. + /// [MemberFunction("88 11 80 FA")] shorter but risky + [MemberFunction("88 11 80 FA 01 75 ?? 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 ?? 38 15 ?? ?? ?? ?? 74 ?? 48 81 C1 ?? ?? ?? ??")] + public partial void OnActorControl(bool newState); + + /// + /// Sets the auto-attack state after performing configuration and validation checks. + /// Wraps the SetImpl call after ensuring conditions are met. + /// + /// The new auto-attack state. + [MemberFunction("E8 ?? ?? ?? ?? B0 ?? EB ?? 48 8D 0D")] + public partial bool Set(bool newState); + + /// + /// Sets the auto-attack state. + /// + /// The new state value. + /// Whether to send a network update. + /// Whether the change should be applied instantly. + [MemberFunction("E8 ?? ?? ?? ?? EB ?? F6 87 ?? ?? ?? ?? ?? 75")] + public partial bool SetImpl(bool newState, bool sendPacket, bool isInstant); }