Fix classic combat desync and separate attack intent from confirmed combat

Combat state/UI:

- Split attack intent from server-confirmed auto attack in GameHandler.

- Add explicit combat state helpers (intent, confirmed, combat-with-target).

- Update player/target frame and renderer in-combat indicators to use confirmed combat.

- Add intent-only visual state in UI to avoid false combat feedback.

Animation correctness:

- Correct combat-ready animation IDs to canonical ready stances (22/23/24/25).

- Remove hit/wound-like stance behavior caused by incorrect ready IDs.

Classic/TBC/Turtle melee reliability:

- Tighten melee sync while attack intent is active: faster swing resend, tighter facing threshold, and faster facing cadence for classic-like expansions.

- Send immediate movement heartbeat after facing corrections and during stationary melee sync windows.

- Handle melee error opcodes explicitly (NOTINRANGE/BADFACING/NOTSTANDING/CANT_ATTACK) and immediately resync facing/swing where appropriate.

- On ATTACKSTOP with persistent intent, immediately reassert ATTACKSWING.

- Increase movement heartbeat cadence during active classic-like melee intent.

Server compatibility/anti-cheat stability:

- Restrict legacy force-movement/speed/teleport ACK behavior for classic-like flows to avoid unsolicited order acknowledgements.

- Preserve local movement state updates while preventing bad-order ACK noise.
This commit is contained in:
Kelsi 2026-02-20 03:38:12 -08:00
parent cb044e3985
commit eaba378b5b
4 changed files with 129 additions and 48 deletions

View file

@ -960,9 +960,11 @@ void Renderer::updateCharacterAnimation() {
constexpr uint32_t ANIM_SWIM_IDLE = 41; // Treading water (SwimIdle)
constexpr uint32_t ANIM_SWIM = 42; // Swimming forward (Swim)
constexpr uint32_t ANIM_MOUNT = 91; // Seated on mount
constexpr uint32_t ANIM_READY_UNARMED = 7; // Combat ready stance (unarmed)
constexpr uint32_t ANIM_READY_1H = 8; // Combat ready stance (1H weapon)
constexpr uint32_t ANIM_READY_2H = 9; // Combat ready stance (2H weapon)
// Canonical player ready stances (AnimationData.dbc)
constexpr uint32_t ANIM_READY_UNARMED = 22; // ReadyUnarmed
constexpr uint32_t ANIM_READY_1H = 23; // Ready1H
constexpr uint32_t ANIM_READY_2H = 24; // Ready2H
constexpr uint32_t ANIM_READY_2H_L = 25; // Ready2HL (some 2H left-handed rigs)
constexpr uint32_t ANIM_FLY_IDLE = 158; // Flying mount idle/hover
constexpr uint32_t ANIM_FLY_FORWARD = 159; // Flying mount forward
@ -1613,7 +1615,9 @@ void Renderer::updateCharacterAnimation() {
break;
case CharAnimState::MOUNT: animId = ANIM_MOUNT; loop = true; break;
case CharAnimState::COMBAT_IDLE:
animId = pickFirstAvailable({ANIM_READY_1H, ANIM_READY_2H, ANIM_READY_UNARMED}, ANIM_STAND);
animId = pickFirstAvailable(
{ANIM_READY_1H, ANIM_READY_2H, ANIM_READY_2H_L, ANIM_READY_UNARMED},
ANIM_STAND);
loop = true;
break;
case CharAnimState::CHARGE: