From 30a65320fb251701ec9515ddefc3d38de3316c12 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 10 Mar 2026 11:56:50 -0700 Subject: [PATCH] anim: add flying state tracking and Fly/FlyIdle animation selection for entities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the move-flags callback only tracked SWIMMING and WALKING, so flying players/mounts always played Run(5) or Stand(0) animations instead of Fly(61)/FlyIdle(60). Changes: - Add creatureFlyingState_ (mirroring creatureSwimmingState_) set by the FLYING flag (0x01000000) in unitMoveFlagsCallback_. - Update animation selection: moving+flying → 61 (Fly/FlyForward), idle+flying → 60 (FlyIdle/hover). Flying takes priority over swim in the priority chain: fly > swim > walk > run. - Clear creatureFlyingState_ on world reset. --- include/core/application.hpp | 1 + src/core/application.cpp | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/core/application.hpp b/include/core/application.hpp index 0c7ca61e..a1168ba4 100644 --- a/include/core/application.hpp +++ b/include/core/application.hpp @@ -190,6 +190,7 @@ private: std::unordered_map creatureWasMoving_; // guid -> previous-frame movement state std::unordered_map creatureSwimmingState_; // guid -> currently in swim mode (SWIMMING flag) std::unordered_map creatureWalkingState_; // guid -> walking (WALKING flag, selects Walk(4) vs Run(5)) + std::unordered_map creatureFlyingState_; // guid -> currently flying (FLYING flag) std::unordered_set creatureWeaponsAttached_; // guid set when NPC virtual weapons attached std::unordered_map creatureWeaponAttachAttempts_; // guid -> attach attempts std::unordered_map modelIdIsWolfLike_; // modelId → cached wolf/worg check diff --git a/src/core/application.cpp b/src/core/application.cpp index ca692dd6..818544e2 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -752,6 +752,7 @@ void Application::logoutToLogin() { creatureWasMoving_.clear(); creatureSwimmingState_.clear(); creatureWalkingState_.clear(); + creatureFlyingState_.clear(); deadCreatureGuids_.clear(); nonRenderableCreatureDisplayIds_.clear(); creaturePermanentFailureGuids_.clear(); @@ -1485,6 +1486,7 @@ void Application::update(float deltaTime) { // Don't override Death (1) animation. const bool isSwimmingNow = creatureSwimmingState_.count(guid) > 0; const bool isWalkingNow = creatureWalkingState_.count(guid) > 0; + const bool isFlyingNow = creatureFlyingState_.count(guid) > 0; bool prevMoving = creatureWasMoving_[guid]; if (isMovingNow != prevMoving) { creatureWasMoving_[guid] = isMovingNow; @@ -1492,10 +1494,16 @@ void Application::update(float deltaTime) { bool gotState = charRenderer->getAnimationState(instanceId, curAnimId, curT, curDur); if (!gotState || curAnimId != 1 /*Death*/) { uint32_t targetAnim; - if (isMovingNow) - targetAnim = isSwimmingNow ? 42u : (isWalkingNow ? 4u : 5u); // Swim/Walk/Run - else - targetAnim = isSwimmingNow ? 41u : 0u; // SwimIdle vs Stand + if (isMovingNow) { + if (isFlyingNow) targetAnim = 61u; // Fly (FlyForward) + else if (isSwimmingNow) targetAnim = 42u; // Swim + else if (isWalkingNow) targetAnim = 4u; // Walk + else targetAnim = 5u; // Run + } else { + if (isFlyingNow) targetAnim = 60u; // FlyIdle (hover) + else if (isSwimmingNow) targetAnim = 41u; // SwimIdle + else targetAnim = 0u; // Stand + } charRenderer->playAnimation(instanceId, targetAnim, /*loop=*/true); } } @@ -2810,10 +2818,13 @@ void Application::setupUICallbacks() { gameHandler->setUnitMoveFlagsCallback([this](uint64_t guid, uint32_t moveFlags) { const bool isSwimming = (moveFlags & static_cast(game::MovementFlags::SWIMMING)) != 0; const bool isWalking = (moveFlags & static_cast(game::MovementFlags::WALKING)) != 0; + const bool isFlying = (moveFlags & static_cast(game::MovementFlags::FLYING)) != 0; if (isSwimming) creatureSwimmingState_[guid] = true; else creatureSwimmingState_.erase(guid); if (isWalking) creatureWalkingState_[guid] = true; else creatureWalkingState_.erase(guid); + if (isFlying) creatureFlyingState_[guid] = true; + else creatureFlyingState_.erase(guid); }); // Emote animation callback — play server-driven emote animations on NPCs and other players