diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c01901ae1..3033eb83f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ Bug #7603: Scripts menu size is not updated properly Bug #7604: Goblins Grunt becomes idle once injured Bug #7609: ForceGreeting should not open dialogue for werewolves + Bug #7611: Beast races' idle animations slide after turning or jumping in place Bug #7630: Charm can be cast on creatures Feature #3537: Shader-based water ripples Feature #5492: Let rain and snow collide with statics diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 92bc2d143e..48abac8b06 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -353,6 +353,7 @@ namespace MWMechanics { clearStateAnimation(mCurrentMovement); mMovementState = CharState_None; + mMovementAnimationHasMovement = false; } void CharacterController::resetCurrentIdleState() @@ -705,7 +706,7 @@ namespace MWMechanics if (!mCurrentMovement.empty() && movementAnimName == mCurrentMovement) mAnimation->getInfo(mCurrentMovement, &startpoint); - mMovementAnimationControlled = true; + mMovementAnimationHasMovement = true; clearStateAnimation(mCurrentMovement); mCurrentMovement = movementAnimName; @@ -743,7 +744,7 @@ namespace MWMechanics bool sneaking = mMovementState == CharState_SneakForward || mMovementState == CharState_SneakBack || mMovementState == CharState_SneakLeft || mMovementState == CharState_SneakRight; mMovementAnimSpeed = (sneaking ? 33.5452f : (isRunning() ? 222.857f : 154.064f)); - mMovementAnimationControlled = false; + mMovementAnimationHasMovement = false; } } @@ -852,7 +853,6 @@ namespace MWMechanics resetCurrentHitState(); resetCurrentIdleState(); resetCurrentJumpState(); - mMovementAnimationControlled = true; mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", startpoint, 0); @@ -2309,9 +2309,6 @@ namespace MWMechanics updateIdleStormState(inwater); } - if (mInJump) - mMovementAnimationControlled = false; - if (isTurning()) { // Adjust animation speed from 1.0 to 1.5 multiplier @@ -2347,7 +2344,7 @@ namespace MWMechanics } } - if (!mMovementAnimationControlled) + if (!isMovementAnimationControlled()) world->queueMovement(mPtr, vec); } @@ -2416,7 +2413,7 @@ namespace MWMechanics } // Update movement - if (mMovementAnimationControlled && mPtr.getClass().isActor()) + if (isMovementAnimationControlled() && mPtr.getClass().isActor()) world->queueMovement(mPtr, moved); mSkipAnim = false; @@ -2577,6 +2574,16 @@ namespace MWMechanics return mAnimation->isPlaying(groupName); } + bool CharacterController::isMovementAnimationControlled() const + { + bool movementAnimationControlled = mIdleState != CharState_None; + if (mMovementState != CharState_None) + movementAnimationControlled = mMovementAnimationHasMovement; + if (mInJump) + movementAnimationControlled = false; + return movementAnimationControlled; + } + void CharacterController::clearAnimQueue(bool clearPersistAnims) { // Do not interrupt scripted animations, if we want to keep them diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 5a676e3f6d..316a1cff0e 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -147,7 +147,7 @@ namespace MWMechanics std::string mCurrentMovement; float mMovementAnimSpeed{ 0.f }; bool mAdjustMovementAnimSpeed{ false }; - bool mMovementAnimationControlled{ true }; + bool mMovementAnimationHasMovement{ false }; CharacterState mDeathState{ CharState_None }; std::string mCurrentDeath; @@ -216,6 +216,7 @@ namespace MWMechanics static bool isRandomAttackAnimation(std::string_view group); bool isPersistentAnimPlaying() const; + bool isMovementAnimationControlled() const; void updateAnimQueue();