mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
Reset current animation states in a consistent way
This commit is contained in:
parent
dd42a69ca5
commit
0a38c3ab78
@ -271,6 +271,52 @@ std::string CharacterController::chooseRandomGroup (const std::string& prefix, i
|
||||
return prefix + std::to_string(roll);
|
||||
}
|
||||
|
||||
|
||||
void CharacterController::clearStateAnimation(std::string &anim) const
|
||||
{
|
||||
if (anim.empty())
|
||||
return;
|
||||
if (mAnimation)
|
||||
mAnimation->disable(anim);
|
||||
anim.clear();
|
||||
}
|
||||
|
||||
void CharacterController::resetCurrentJumpState()
|
||||
{
|
||||
clearStateAnimation(mCurrentJump);
|
||||
mJumpState = JumpState_None;
|
||||
}
|
||||
|
||||
void CharacterController::resetCurrentMovementState()
|
||||
{
|
||||
clearStateAnimation(mCurrentMovement);
|
||||
mMovementState = CharState_None;
|
||||
}
|
||||
|
||||
void CharacterController::resetCurrentIdleState()
|
||||
{
|
||||
clearStateAnimation(mCurrentIdle);
|
||||
mIdleState = CharState_None;
|
||||
}
|
||||
|
||||
void CharacterController::resetCurrentHitState()
|
||||
{
|
||||
clearStateAnimation(mCurrentHit);
|
||||
mHitState = CharState_None;
|
||||
}
|
||||
|
||||
void CharacterController::resetCurrentWeaponState()
|
||||
{
|
||||
clearStateAnimation(mCurrentWeapon);
|
||||
mUpperBodyState = UpperCharState_Nothing;
|
||||
}
|
||||
|
||||
void CharacterController::resetCurrentDeathState()
|
||||
{
|
||||
clearStateAnimation(mCurrentDeath);
|
||||
mDeathState = CharState_None;
|
||||
}
|
||||
|
||||
void CharacterController::refreshHitRecoilAnims(CharacterState& idle)
|
||||
{
|
||||
auto& charClass = mPtr.getClass();
|
||||
@ -361,11 +407,7 @@ void CharacterController::refreshHitRecoilAnims(CharacterState& idle)
|
||||
// Cancel upper body animations
|
||||
if (isKnockedOut() || isKnockedDown())
|
||||
{
|
||||
if (!mCurrentWeapon.empty())
|
||||
{
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
mCurrentWeapon.clear();
|
||||
}
|
||||
clearStateAnimation(mCurrentWeapon);
|
||||
if (mUpperBodyState > UpperCharState_WeapEquiped)
|
||||
{
|
||||
mUpperBodyState = UpperCharState_WeapEquiped;
|
||||
@ -390,12 +432,7 @@ void CharacterController::refreshJumpAnims(const std::string& weapShortGroup, Ju
|
||||
|
||||
if (jump == JumpState_None)
|
||||
{
|
||||
if (!mCurrentJump.empty())
|
||||
{
|
||||
mAnimation->disable(mCurrentJump);
|
||||
mCurrentJump.clear();
|
||||
}
|
||||
mJumpState = JumpState_None;
|
||||
resetCurrentJumpState();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -416,12 +453,7 @@ void CharacterController::refreshJumpAnims(const std::string& weapShortGroup, Ju
|
||||
|
||||
bool startAtLoop = (jump == mJumpState);
|
||||
mJumpState = jump;
|
||||
|
||||
if (!mCurrentJump.empty())
|
||||
{
|
||||
mAnimation->disable(mCurrentJump);
|
||||
mCurrentJump.clear();
|
||||
}
|
||||
clearStateAnimation(mCurrentJump);
|
||||
|
||||
if (!mAnimation->hasAnimation(jumpAnimName))
|
||||
return;
|
||||
@ -539,12 +571,7 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup
|
||||
|
||||
if (movementAnimName.empty())
|
||||
{
|
||||
if (!mCurrentMovement.empty())
|
||||
{
|
||||
mAnimation->disable(mCurrentMovement);
|
||||
mCurrentMovement.clear();
|
||||
}
|
||||
mMovementState = CharState_None;
|
||||
resetCurrentMovementState();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -592,12 +619,7 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup
|
||||
|
||||
if (!mAnimation->hasAnimation(movementAnimName))
|
||||
{
|
||||
if (!mCurrentMovement.empty())
|
||||
{
|
||||
mAnimation->disable(mCurrentMovement);
|
||||
mCurrentMovement.clear();
|
||||
}
|
||||
mMovementState = CharState_None;
|
||||
resetCurrentMovementState();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -611,9 +633,7 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup
|
||||
|
||||
mMovementAnimationControlled = true;
|
||||
|
||||
if (!mCurrentMovement.empty())
|
||||
mAnimation->disable(mCurrentMovement);
|
||||
|
||||
clearStateAnimation(mCurrentMovement);
|
||||
mCurrentMovement = movementAnimName;
|
||||
|
||||
// Reset idle if we actually play movement animations excepts of these cases:
|
||||
@ -621,12 +641,7 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup
|
||||
// 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)
|
||||
{
|
||||
if (!mCurrentIdle.empty())
|
||||
{
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
mCurrentIdle.clear();
|
||||
}
|
||||
mIdleState = CharState_None;
|
||||
resetCurrentIdleState();
|
||||
idle = CharState_None;
|
||||
}
|
||||
|
||||
@ -695,12 +710,7 @@ void CharacterController::refreshIdleAnims(const std::string& weapShortGroup, Ch
|
||||
|
||||
if (idleGroup.empty())
|
||||
{
|
||||
if (mCurrentIdle.empty())
|
||||
{
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
mCurrentIdle.clear();
|
||||
}
|
||||
mIdleState = CharState_None;
|
||||
resetCurrentIdleState();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -719,26 +729,17 @@ void CharacterController::refreshIdleAnims(const std::string& weapShortGroup, Ch
|
||||
|
||||
if (!mAnimation->hasAnimation(idleGroup))
|
||||
{
|
||||
if (mCurrentIdle.empty())
|
||||
{
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
mCurrentIdle.clear();
|
||||
}
|
||||
mIdleState = CharState_None;
|
||||
resetCurrentIdleState();
|
||||
return;
|
||||
}
|
||||
|
||||
float startPoint = 0.f;
|
||||
if (!mCurrentIdle.empty())
|
||||
{
|
||||
// There is no need to restart anim if the new and old anims are the same.
|
||||
// Just update the number of loops.
|
||||
if (mCurrentIdle == idleGroup)
|
||||
mAnimation->getInfo(mCurrentIdle, &startPoint);
|
||||
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
}
|
||||
// There is no need to restart anim if the new and old anims are the same.
|
||||
// Just update the number of loops.
|
||||
if (mCurrentIdle == idleGroup)
|
||||
mAnimation->getInfo(mCurrentIdle, &startPoint);
|
||||
|
||||
clearStateAnimation(mCurrentIdle);
|
||||
mCurrentIdle = idleGroup;
|
||||
mAnimation->play(mCurrentIdle, priority, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", startPoint, numLoops, true);
|
||||
}
|
||||
@ -781,21 +782,11 @@ void CharacterController::playDeath(float startpoint, CharacterState death)
|
||||
// For dead actors, refreshCurrentAnims is no longer called, so we need to disable the movement state manually.
|
||||
// Note that these animations wouldn't actually be visible (due to the Death animation's priority being higher).
|
||||
// However, they could still trigger text keys, such as Hit events, or sounds.
|
||||
mMovementState = CharState_None;
|
||||
mAnimation->disable(mCurrentMovement);
|
||||
mCurrentMovement.clear();
|
||||
mUpperBodyState = UpperCharState_Nothing;
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
mCurrentWeapon.clear();
|
||||
mHitState = CharState_None;
|
||||
mAnimation->disable(mCurrentHit);
|
||||
mCurrentHit.clear();
|
||||
mIdleState = CharState_None;
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
mCurrentIdle.clear();
|
||||
mJumpState = JumpState_None;
|
||||
mAnimation->disable(mCurrentJump);
|
||||
mCurrentJump.clear();
|
||||
resetCurrentMovementState();
|
||||
resetCurrentWeaponState();
|
||||
resetCurrentHitState();
|
||||
resetCurrentIdleState();
|
||||
resetCurrentJumpState();
|
||||
mMovementAnimationControlled = true;
|
||||
|
||||
mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::BlendMask_All,
|
||||
@ -1184,9 +1175,9 @@ bool CharacterController::updateState(CharacterState idle)
|
||||
if (isStillWeapon && mWeaponType != weaptype && mUpperBodyState > UpperCharState_WeapEquiped)
|
||||
{
|
||||
forcestateupdate = true;
|
||||
clearStateAnimation(mCurrentWeapon);
|
||||
mUpperBodyState = UpperCharState_WeapEquiped;
|
||||
setAttackingOrSpell(false);
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
mAnimation->showWeapons(true);
|
||||
stats.setAttackingOrSpell(false);
|
||||
}
|
||||
@ -1256,7 +1247,7 @@ bool CharacterController::updateState(CharacterState idle)
|
||||
|
||||
if (!isStillWeapon)
|
||||
{
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
clearStateAnimation(mCurrentWeapon);
|
||||
if (weaptype != ESM::Weapon::None)
|
||||
{
|
||||
mAnimation->showWeapons(false);
|
||||
@ -1304,8 +1295,7 @@ bool CharacterController::updateState(CharacterState idle)
|
||||
// Make sure that we disabled unequipping animation
|
||||
if (mUpperBodyState == UpperCharState_UnEquipingWeap)
|
||||
{
|
||||
mUpperBodyState = UpperCharState_Nothing;
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
resetCurrentWeaponState();
|
||||
mWeaponType = ESM::Weapon::None;
|
||||
mCurrentWeapon = getWeaponAnimation(mWeaponType);
|
||||
}
|
||||
@ -1347,7 +1337,7 @@ bool CharacterController::updateState(CharacterState idle)
|
||||
|
||||
if (!ammunition && mUpperBodyState > UpperCharState_WeapEquiped)
|
||||
{
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
clearStateAnimation(mCurrentWeapon);
|
||||
mUpperBodyState = UpperCharState_WeapEquiped;
|
||||
}
|
||||
}
|
||||
@ -1572,8 +1562,7 @@ bool CharacterController::updateState(CharacterState idle)
|
||||
idle != CharState_IdleSneak && idle != CharState_IdleSwim &&
|
||||
mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim)
|
||||
{
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
mIdleState = CharState_None;
|
||||
resetCurrentIdleState();
|
||||
}
|
||||
|
||||
animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete);
|
||||
@ -1629,7 +1618,7 @@ bool CharacterController::updateState(CharacterState idle)
|
||||
if (mWeaponType > ESM::Weapon::None)
|
||||
mAnimation->showWeapons(true);
|
||||
}
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
clearStateAnimation(mCurrentWeapon);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1766,7 +1755,7 @@ bool CharacterController::updateState(CharacterState idle)
|
||||
}
|
||||
else if(complete >= 1.0f && isRandomAttackAnimation(mCurrentWeapon))
|
||||
{
|
||||
mAnimation->disable(mCurrentWeapon);
|
||||
clearStateAnimation(mCurrentWeapon);
|
||||
mUpperBodyState = UpperCharState_WeapEquiped;
|
||||
}
|
||||
|
||||
@ -2086,7 +2075,7 @@ void CharacterController::update(float duration)
|
||||
vec.z() = 0.0f;
|
||||
|
||||
// We should reset idle animation during landing
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
clearStateAnimation(mCurrentIdle);
|
||||
|
||||
float height = cls.getCreatureStats(mPtr).land(isPlayer);
|
||||
float healthLost = getFallDamage(mPtr, height);
|
||||
@ -2429,8 +2418,7 @@ void CharacterController::unpersistAnimationState()
|
||||
complete = (time - start) / (stop - start);
|
||||
}
|
||||
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
mCurrentIdle.clear();
|
||||
clearStateAnimation(mCurrentIdle);
|
||||
mIdleState = CharState_SpecialIdle;
|
||||
|
||||
bool loopfallback = (mAnimQueue.front().mGroup.compare(0,4,"idle") == 0);
|
||||
@ -2480,8 +2468,7 @@ bool CharacterController::playGroup(const std::string &groupname, int mode, int
|
||||
{
|
||||
clearAnimQueue(persist);
|
||||
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
mCurrentIdle.clear();
|
||||
clearStateAnimation(mCurrentIdle);
|
||||
|
||||
mIdleState = CharState_SpecialIdle;
|
||||
bool loopfallback = (entry.mGroup.compare(0,4,"idle") == 0);
|
||||
@ -2575,11 +2562,7 @@ CharacterController::KillResult CharacterController::kill()
|
||||
if (mDeathState == CharState_None)
|
||||
{
|
||||
playRandomDeath();
|
||||
|
||||
mAnimation->disable(mCurrentIdle);
|
||||
|
||||
mIdleState = CharState_None;
|
||||
mCurrentIdle.clear();
|
||||
resetCurrentIdleState();
|
||||
return Result_DeathAnimStarted;
|
||||
}
|
||||
|
||||
@ -2599,10 +2582,7 @@ void CharacterController::resurrect()
|
||||
if(mDeathState == CharState_None)
|
||||
return;
|
||||
|
||||
if(mAnimation)
|
||||
mAnimation->disable(mCurrentDeath);
|
||||
mCurrentDeath.clear();
|
||||
mDeathState = CharState_None;
|
||||
resetCurrentDeathState();
|
||||
mWeaponType = ESM::Weapon::None;
|
||||
}
|
||||
|
||||
|
@ -197,6 +197,14 @@ class CharacterController : public MWRender::Animation::TextKeyListener
|
||||
|
||||
std::string getMovementBasedAttackType() const;
|
||||
|
||||
void clearStateAnimation(std::string &anim) const;
|
||||
void resetCurrentJumpState();
|
||||
void resetCurrentMovementState();
|
||||
void resetCurrentIdleState();
|
||||
void resetCurrentHitState();
|
||||
void resetCurrentWeaponState();
|
||||
void resetCurrentDeathState();
|
||||
|
||||
void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force=false);
|
||||
void refreshHitRecoilAnims(CharacterState& idle);
|
||||
void refreshJumpAnims(const std::string& weapShortGroup, JumpingState jump, CharacterState& idle, bool force=false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user