From b5cb11ff0772d30834d03d1cfc674563dd62ed29 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jun 2016 03:14:44 +0200 Subject: [PATCH] Split refreshCurrentAnims into multiple functions --- apps/openmw/mwmechanics/character.cpp | 174 ++++++++++++++------------ apps/openmw/mwmechanics/character.hpp | 6 + 2 files changed, 101 insertions(+), 79 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index eeeea37ee..4052a37b7 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -238,88 +238,83 @@ std::string CharacterController::chooseRandomGroup (const std::string& prefix, i return prefix + toString(roll); } -void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force) +void CharacterController::refreshHitRecoilAnims() { - // hit recoils/knockdown animations handling - if(mPtr.getClass().isActor()) + bool recovery = mPtr.getClass().getCreatureStats(mPtr).getHitRecovery(); + bool knockdown = mPtr.getClass().getCreatureStats(mPtr).getKnockedDown(); + bool block = mPtr.getClass().getCreatureStats(mPtr).getBlock(); + if(mHitState == CharState_None) { - bool recovery = mPtr.getClass().getCreatureStats(mPtr).getHitRecovery(); - bool knockdown = mPtr.getClass().getCreatureStats(mPtr).getKnockedDown(); - bool block = mPtr.getClass().getCreatureStats(mPtr).getBlock(); - if(mHitState == CharState_None) + if ((mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() < 0 + || mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0) + && mAnimation->hasAnimation("knockout")) { - if ((mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() < 0 - || mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0) - && mAnimation->hasAnimation("knockout")) - { - mHitState = CharState_KnockOut; - mCurrentHit = "knockout"; - mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, false, 1, "start", "stop", 0.0f, ~0ul); - mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(true); - } - else if(knockdown && mAnimation->hasAnimation("knockdown")) - { - mHitState = CharState_KnockDown; - mCurrentHit = "knockdown"; - mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0); - } - else if (recovery) - { - std::string anim = chooseRandomGroup("hit"); - if (mAnimation->hasAnimation(anim)) - { - mHitState = CharState_Hit; - mCurrentHit = anim; - mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0); - } - } - else if (block && mAnimation->hasAnimation("shield")) - { - mHitState = CharState_Block; - mCurrentHit = "shield"; - MWRender::Animation::AnimPriority priorityBlock (Priority_Hit); - priorityBlock[MWRender::Animation::BoneGroup_LeftArm] = Priority_Block; - mAnimation->play(mCurrentHit, priorityBlock, MWRender::Animation::BlendMask_All, true, 1, "block start", "block stop", 0.0f, 0); - } - - // Cancel upper body animations - if (mHitState == CharState_KnockDown || mHitState == CharState_KnockOut) + mHitState = CharState_KnockOut; + mCurrentHit = "knockout"; + mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, false, 1, "start", "stop", 0.0f, ~0ul); + mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(true); + } + else if(knockdown && mAnimation->hasAnimation("knockdown")) + { + mHitState = CharState_KnockDown; + mCurrentHit = "knockdown"; + mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0); + } + else if (recovery) + { + std::string anim = chooseRandomGroup("hit"); + if (mAnimation->hasAnimation(anim)) { - if (mUpperBodyState > UpperCharState_WeapEquiped) - { - mAnimation->disable(mCurrentWeapon); - mUpperBodyState = UpperCharState_WeapEquiped; - } - else if (mUpperBodyState > UpperCharState_Nothing && mUpperBodyState < UpperCharState_WeapEquiped) - { - mAnimation->disable(mCurrentWeapon); - mUpperBodyState = UpperCharState_Nothing; - } + mHitState = CharState_Hit; + mCurrentHit = anim; + mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0); } } - else if(!mAnimation->isPlaying(mCurrentHit)) + else if (block && mAnimation->hasAnimation("shield")) { - mCurrentHit.erase(); - if (knockdown) - mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(false); - if (recovery) - mPtr.getClass().getCreatureStats(mPtr).setHitRecovery(false); - if (block) - mPtr.getClass().getCreatureStats(mPtr).setBlock(false); - mHitState = CharState_None; + mHitState = CharState_Block; + mCurrentHit = "shield"; + MWRender::Animation::AnimPriority priorityBlock (Priority_Hit); + priorityBlock[MWRender::Animation::BoneGroup_LeftArm] = Priority_Block; + mAnimation->play(mCurrentHit, priorityBlock, MWRender::Animation::BlendMask_All, true, 1, "block start", "block stop", 0.0f, 0); } - else if (mHitState == CharState_KnockOut && mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() > 0) + + // Cancel upper body animations + if (mHitState == CharState_KnockDown || mHitState == CharState_KnockOut) { - mHitState = CharState_KnockDown; - mAnimation->disable(mCurrentHit); - mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "loop stop", "stop", 0.0f, 0); + if (mUpperBodyState > UpperCharState_WeapEquiped) + { + mAnimation->disable(mCurrentWeapon); + mUpperBodyState = UpperCharState_WeapEquiped; + } + else if (mUpperBodyState > UpperCharState_Nothing && mUpperBodyState < UpperCharState_WeapEquiped) + { + mAnimation->disable(mCurrentWeapon); + mUpperBodyState = UpperCharState_Nothing; + } } } + else if(!mAnimation->isPlaying(mCurrentHit)) + { + mCurrentHit.erase(); + if (knockdown) + mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(false); + if (recovery) + mPtr.getClass().getCreatureStats(mPtr).setHitRecovery(false); + if (block) + mPtr.getClass().getCreatureStats(mPtr).setBlock(false); + mHitState = CharState_None; + } + else if (mHitState == CharState_KnockOut && mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() > 0) + { + mHitState = CharState_KnockDown; + mAnimation->disable(mCurrentHit); + mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "loop stop", "stop", 0.0f, 0); + } +} - const WeaponInfo *weap = std::find_if(sWeaponTypeList, sWeaponTypeListEnd, FindWeaponType(mWeaponType)); - if (!mPtr.getClass().isBipedal(mPtr)) - weap = sWeaponTypeListEnd; - +void CharacterController::refreshJumpAnims(const WeaponInfo* weap, JumpingState jump, bool force) +{ if(force || jump != mJumpState) { bool startAtLoop = (jump == mJumpState); @@ -358,7 +353,10 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat 1.0f, "loop stop", "stop", 0.0f, 0); } } +} +void CharacterController::refreshMovementAnims(const WeaponInfo* weap, CharacterState movement, bool force) +{ if(force || movement != mMovementState) { mMovementState = movement; @@ -466,16 +464,10 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat 1.f, ((mode!=2)?"start":"loop start"), "stop", 0.0f, ~0ul); } } +} - // idle handled last as it can depend on the other states - // 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 - if ((mUpperBodyState != UpperCharState_Nothing - || (mMovementState != CharState_None && mMovementState != CharState_TurnLeft && mMovementState != CharState_TurnRight) - || mHitState != CharState_None) - && !mPtr.getClass().isBipedal(mPtr)) - idle = CharState_None; - +void CharacterController::refreshIdleAnims(const WeaponInfo* weap, CharacterState idle, bool force) +{ if(force || idle != mIdleState) { mIdleState = idle; @@ -513,6 +505,30 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat } } +void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force) +{ + if (mPtr.getClass().isActor()) + refreshHitRecoilAnims(); + + const WeaponInfo *weap = std::find_if(sWeaponTypeList, sWeaponTypeListEnd, FindWeaponType(mWeaponType)); + if (!mPtr.getClass().isBipedal(mPtr)) + weap = sWeaponTypeListEnd; + + refreshJumpAnims(weap, jump, force); + refreshMovementAnims(weap, movement, force); + + // idle handled last as it can depend on the other states + // 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 + if ((mUpperBodyState != UpperCharState_Nothing + || (mMovementState != CharState_None && mMovementState != CharState_TurnLeft && mMovementState != CharState_TurnRight) + || mHitState != CharState_None) + && !mPtr.getClass().isBipedal(mPtr)) + idle = CharState_None; + + refreshIdleAnims(weap, idle, force); +} + void getWeaponGroup(WeaponType weaptype, std::string &group) { diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 9bea4b78c..b7e5feb6f 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -140,6 +140,8 @@ enum JumpingState { JumpState_Landing }; +struct WeaponInfo; + class CharacterController : public MWRender::Animation::TextKeyListener { MWWorld::Ptr mPtr; @@ -193,6 +195,10 @@ class CharacterController : public MWRender::Animation::TextKeyListener void setAttackTypeRandomly(); void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force=false); + void refreshHitRecoilAnims(); + void refreshJumpAnims(const WeaponInfo* weap, JumpingState jump, bool force=false); + void refreshMovementAnims(const WeaponInfo* weap, CharacterState movement, bool force=false); + void refreshIdleAnims(const WeaponInfo* weap, CharacterState idle, bool force=false); void clearAnimQueue();