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);
}