anim: fix creature animation not updating on swim/fly state transitions

Previously, the animation update for other entities (creatures, players)
was only triggered when the moving/idle state changed. This meant a
creature landing while still moving would stay in FlyForward instead of
switching to Run, and a flying-idle creature touching down would keep
the FlyIdle animation instead of returning to Stand.

Fix: track creatureWasSwimming_ and creatureWasFlying_ alongside
creatureWasMoving_, and fire the animation update whenever any of the
three locomotion flags change. Clean up the new maps on world reset and
on per-creature despawn.
This commit is contained in:
Kelsi 2026-03-10 12:03:33 -07:00
parent 8a20ccb69d
commit 2717018631
2 changed files with 23 additions and 4 deletions

View file

@ -750,6 +750,8 @@ void Application::logoutToLogin() {
creatureWeaponsAttached_.clear();
creatureWeaponAttachAttempts_.clear();
creatureWasMoving_.clear();
creatureWasSwimming_.clear();
creatureWasFlying_.clear();
creatureSwimmingState_.clear();
creatureWalkingState_.clear();
creatureFlyingState_.clear();
@ -1487,9 +1489,18 @@ void Application::update(float deltaTime) {
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;
bool prevMoving = creatureWasMoving_[guid];
bool prevSwimming = creatureWasSwimming_[guid];
bool prevFlying = creatureWasFlying_[guid];
// Trigger animation update on any locomotion-state transition, not just
// moving/idle — e.g. creature lands while still moving → FlyForward→Run.
const bool stateChanged = (isMovingNow != prevMoving) ||
(isSwimmingNow != prevSwimming) ||
(isFlyingNow != prevFlying);
if (stateChanged) {
creatureWasMoving_[guid] = isMovingNow;
creatureWasSwimming_[guid] = isSwimmingNow;
creatureWasFlying_[guid] = isFlyingNow;
uint32_t curAnimId = 0; float curT = 0.0f, curDur = 0.0f;
bool gotState = charRenderer->getAnimationState(instanceId, curAnimId, curT, curDur);
if (!gotState || curAnimId != 1 /*Death*/) {
@ -6945,6 +6956,9 @@ void Application::despawnOnlinePlayer(uint64_t guid) {
pendingOnlinePlayerEquipment_.erase(guid);
creatureSwimmingState_.erase(guid);
creatureWalkingState_.erase(guid);
creatureFlyingState_.erase(guid);
creatureWasSwimming_.erase(guid);
creatureWasFlying_.erase(guid);
}
void Application::spawnOnlineGameObject(uint64_t guid, uint32_t entry, uint32_t displayId, float x, float y, float z, float orientation) {
@ -8538,8 +8552,11 @@ void Application::despawnOnlineCreature(uint64_t guid) {
creatureWeaponsAttached_.erase(guid);
creatureWeaponAttachAttempts_.erase(guid);
creatureWasMoving_.erase(guid);
creatureWasSwimming_.erase(guid);
creatureWasFlying_.erase(guid);
creatureSwimmingState_.erase(guid);
creatureWalkingState_.erase(guid);
creatureFlyingState_.erase(guid);
LOG_DEBUG("Despawned creature: guid=0x", std::hex, guid, std::dec);
}