mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-24 07:11:34 +00:00
Reset the idle animation after a movement animation ends
Fix non-biped actor idle reset
This commit is contained in:
parent
1a646374b0
commit
5dfce6205a
2 changed files with 14 additions and 27 deletions
|
@ -558,15 +558,17 @@ std::string CharacterController::fallbackShortWeaponGroup(const std::string& bas
|
||||||
return groupName;
|
return groupName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::refreshMovementAnims(CharacterState movement, CharacterState& idle, bool force)
|
void CharacterController::refreshMovementAnims(CharacterState movement, bool force)
|
||||||
{
|
{
|
||||||
if (movement == mMovementState && idle == mIdleState && !force)
|
if (movement == mMovementState && !force)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string movementAnimName = movementStateToAnimGroup(movement);
|
std::string movementAnimName = movementStateToAnimGroup(movement);
|
||||||
|
|
||||||
if (movementAnimName.empty())
|
if (movementAnimName.empty())
|
||||||
{
|
{
|
||||||
|
if (!mCurrentMovement.empty())
|
||||||
|
resetCurrentIdleState();
|
||||||
resetCurrentMovementState();
|
resetCurrentMovementState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -594,20 +596,11 @@ void CharacterController::refreshMovementAnims(CharacterState movement, Characte
|
||||||
weapMovementAnimName = movementAnimName + weapShortGroup;
|
weapMovementAnimName = movementAnimName + weapShortGroup;
|
||||||
|
|
||||||
if (!mAnimation->hasAnimation(weapMovementAnimName))
|
if (!mAnimation->hasAnimation(weapMovementAnimName))
|
||||||
{
|
|
||||||
weapMovementAnimName = fallbackShortWeaponGroup(movementAnimName, &movemask);
|
weapMovementAnimName = fallbackShortWeaponGroup(movementAnimName, &movemask);
|
||||||
// If we apply movement only for lower body, do not reset idle animations.
|
|
||||||
// For upper body there will be idle animation.
|
|
||||||
if (movemask == MWRender::Animation::BlendMask_LowerBody && idle == CharState_None)
|
|
||||||
idle = CharState_Idle;
|
|
||||||
}
|
|
||||||
|
|
||||||
movementAnimName = weapMovementAnimName;
|
movementAnimName = weapMovementAnimName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!force && movement == mMovementState)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!mAnimation->hasAnimation(movementAnimName))
|
if (!mAnimation->hasAnimation(movementAnimName))
|
||||||
{
|
{
|
||||||
std::string::size_type runpos = movementAnimName.find("run");
|
std::string::size_type runpos = movementAnimName.find("run");
|
||||||
|
@ -616,6 +609,8 @@ void CharacterController::refreshMovementAnims(CharacterState movement, Characte
|
||||||
|
|
||||||
if (!mAnimation->hasAnimation(movementAnimName))
|
if (!mAnimation->hasAnimation(movementAnimName))
|
||||||
{
|
{
|
||||||
|
if (!mCurrentMovement.empty())
|
||||||
|
resetCurrentIdleState();
|
||||||
resetCurrentMovementState();
|
resetCurrentMovementState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -633,15 +628,6 @@ void CharacterController::refreshMovementAnims(CharacterState movement, Characte
|
||||||
clearStateAnimation(mCurrentMovement);
|
clearStateAnimation(mCurrentMovement);
|
||||||
mCurrentMovement = movementAnimName;
|
mCurrentMovement = movementAnimName;
|
||||||
|
|
||||||
// Reset idle if we actually play movement animations excepts of these cases:
|
|
||||||
// 1. When we play turning animations
|
|
||||||
// 2. When we use a fallback animation for lower body since movement animation for given weapon is missing (e.g. for crossbows and spellcasting)
|
|
||||||
if (!isTurning() && movemask == MWRender::Animation::BlendMask_All)
|
|
||||||
{
|
|
||||||
resetCurrentIdleState();
|
|
||||||
idle = CharState_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For non-flying creatures, MW uses the Walk animation to calculate the animation velocity
|
// For non-flying creatures, MW uses the Walk animation to calculate the animation velocity
|
||||||
// even if we are running. This must be replicated, otherwise the observed speed would differ drastically.
|
// even if we are running. This must be replicated, otherwise the observed speed would differ drastically.
|
||||||
mAdjustMovementAnimSpeed = true;
|
mAdjustMovementAnimSpeed = true;
|
||||||
|
@ -686,10 +672,11 @@ void CharacterController::refreshIdleAnims(CharacterState idle, bool force)
|
||||||
// FIXME: if one of the below states is close to their last animation frame (i.e. will be disabled in the coming update),
|
// FIXME: if one of the below states is close to their last animation frame (i.e. will be disabled in the coming update),
|
||||||
// the idle animation should be displayed
|
// the idle animation should be displayed
|
||||||
if (((mUpperBodyState != UpperCharState_Nothing && mUpperBodyState != UpperCharState_WeapEquiped)
|
if (((mUpperBodyState != UpperCharState_Nothing && mUpperBodyState != UpperCharState_WeapEquiped)
|
||||||
|| (mMovementState != CharState_None && !isTurning())
|
|| mMovementState != CharState_None || mHitState != CharState_None) && !mPtr.getClass().isBipedal(mPtr))
|
||||||
|| mHitState != CharState_None)
|
{
|
||||||
&& !mPtr.getClass().isBipedal(mPtr))
|
resetCurrentIdleState();
|
||||||
idle = CharState_None;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!force && idle == mIdleState && (mAnimation->isPlaying(mCurrentIdle) || !mAnimQueue.empty()))
|
if (!force && idle == mIdleState && (mAnimation->isPlaying(mCurrentIdle) || !mAnimQueue.empty()))
|
||||||
return;
|
return;
|
||||||
|
@ -754,7 +741,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
|
||||||
|
|
||||||
refreshHitRecoilAnims();
|
refreshHitRecoilAnims();
|
||||||
refreshJumpAnims(jump, force);
|
refreshJumpAnims(jump, force);
|
||||||
refreshMovementAnims(movement, idle, force);
|
refreshMovementAnims(movement, force);
|
||||||
|
|
||||||
// idle handled last as it can depend on the other states
|
// idle handled last as it can depend on the other states
|
||||||
refreshIdleAnims(idle, force);
|
refreshIdleAnims(idle, force);
|
||||||
|
@ -2220,7 +2207,7 @@ void CharacterController::update(float duration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(movestate != CharState_None && !isTurning())
|
if (movestate != CharState_None)
|
||||||
clearAnimQueue();
|
clearAnimQueue();
|
||||||
|
|
||||||
if(mAnimQueue.empty() || inwater || (sneak && mIdleState != CharState_SpecialIdle))
|
if(mAnimQueue.empty() || inwater || (sneak && mIdleState != CharState_SpecialIdle))
|
||||||
|
|
|
@ -206,7 +206,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener
|
||||||
void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force=false);
|
void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force=false);
|
||||||
void refreshHitRecoilAnims();
|
void refreshHitRecoilAnims();
|
||||||
void refreshJumpAnims(JumpingState jump, bool force=false);
|
void refreshJumpAnims(JumpingState jump, bool force=false);
|
||||||
void refreshMovementAnims(CharacterState movement, CharacterState& idle, bool force=false);
|
void refreshMovementAnims(CharacterState movement, bool force=false);
|
||||||
void refreshIdleAnims(CharacterState idle, bool force=false);
|
void refreshIdleAnims(CharacterState idle, bool force=false);
|
||||||
|
|
||||||
void clearAnimQueue(bool clearPersistAnims = false);
|
void clearAnimQueue(bool clearPersistAnims = false);
|
||||||
|
|
Loading…
Reference in a new issue