@ -43,6 +43,7 @@
# include "../mwworld/class.hpp"
# include "../mwworld/inventorystore.hpp"
# include "../mwworld/esmstore.hpp"
# include "../mwworld/player.hpp"
namespace
{
@ -236,7 +237,7 @@ std::string CharacterController::chooseRandomGroup (const std::string& prefix, i
return prefix + toString ( roll ) ;
}
void CharacterController : : refreshCurrentAnims ( CharacterState idle , CharacterState movement , bool force )
void CharacterController : : refreshCurrentAnims ( CharacterState idle , CharacterState movement , JumpingState jump , bool force )
{
// hit recoils/knockdown animations handling
if ( mPtr . getClass ( ) . isActor ( ) )
@ -251,26 +252,28 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
{
mHitState = CharState_KnockOut ;
mCurrentHit = " knockout " ;
mAnimation - > play ( mCurrentHit , Priority_Knockdown , MWRender : : Animation : : Group _All, false , 1 , " start " , " stop " , 0.0f , ~ 0ul ) ;
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 )
{
mHitState = CharState_KnockDown ;
mCurrentHit = " knockdown " ;
mAnimation - > play ( mCurrentHit , Priority_Knockdown , MWRender : : Animation : : Group _All, true , 1 , " start " , " stop " , 0.0f , 0 ) ;
mAnimation - > play ( mCurrentHit , Priority_Knockdown , MWRender : : Animation : : BlendMask _All, true , 1 , " start " , " stop " , 0.0f , 0 ) ;
}
else if ( recovery )
{
mHitState = CharState_Hit ;
mCurrentHit = chooseRandomGroup ( " hit " ) ;
mAnimation - > play ( mCurrentHit , Priority_Hit , MWRender : : Animation : : Group _All, true , 1 , " start " , " stop " , 0.0f , 0 ) ;
mAnimation - > play ( mCurrentHit , Priority_Hit , MWRender : : Animation : : BlendMask _All, true , 1 , " start " , " stop " , 0.0f , 0 ) ;
}
else if ( block )
{
mHitState = CharState_Block ;
mCurrentHit = " shield " ;
mAnimation - > play ( mCurrentHit , Priority_Hit , MWRender : : Animation : : Group_All , true , 1 , " block start " , " block stop " , 0.0f , 0 ) ;
MWRender : : Animation : : AnimPriority priorityBlock ( Priority_Hit ) ;
priorityBlock . mPriority [ 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
@ -303,7 +306,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
{
mHitState = CharState_KnockDown ;
mAnimation - > disable ( mCurrentHit ) ;
mAnimation - > play ( mCurrentHit , Priority_Knockdown , MWRender : : Animation : : Group _All, true , 1 , " loop stop " , " stop " , 0.0f , 0 ) ;
mAnimation - > play ( mCurrentHit , Priority_Knockdown , MWRender : : Animation : : BlendMask _All, true , 1 , " loop stop " , " stop " , 0.0f , 0 ) ;
}
}
@ -311,40 +314,41 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
if ( ! mPtr . getClass ( ) . isBipedal ( mPtr ) )
weap = sWeaponTypeListEnd ;
if ( force && mJumpState ! = JumpState_Non e)
if ( force || jump ! = mJumpStat e)
{
std : : string jump ;
MWRender : : Animation : : Group jumpgroup = MWRender : : Animation : : Group_All ;
bool startAtLoop = ( jump = = mJumpState ) ;
mJumpState = jump ;
std : : string jumpAnimName ;
MWRender : : Animation : : BlendMask jumpmask = MWRender : : Animation : : BlendMask_All ;
if ( mJumpState ! = JumpState_None )
{
jump = " jump " ;
jump AnimName = " jump " ;
if ( weap ! = sWeaponTypeListEnd )
{
jump + = weap - > shortgroup ;
if ( ! mAnimation - > hasAnimation ( jump ) )
jump AnimName + = weap - > shortgroup ;
if ( ! mAnimation - > hasAnimation ( jump AnimName ) )
{
jump group = MWRender : : Animation : : Group _LowerBody;
jump = " jump " ;
jump mask = MWRender : : Animation : : BlendMask _LowerBody;
jump AnimName = " jump " ;
}
}
}
if ( mJumpState = = JumpState_InAir )
{
int mode = ( ( jump = = mCurrentJump ) ? 2 : 1 ) ;
mAnimation - > disable ( mCurrentJump ) ;
mCurrentJump = jump ;
mCurrentJump = jumpAnimName ;
if ( mAnimation - > hasAnimation ( " jump " ) )
mAnimation - > play ( mCurrentJump , Priority_Jump , jump group , false ,
1.0f , ( ( mode ! = 2 ) ? " start" : " loop start" ) , " stop " , 0.0f , ~ 0ul ) ;
mAnimation - > play ( mCurrentJump , Priority_Jump , jump mask , false ,
1.0f , ( startAtLoop ? " loop start" : " start" ) , " stop " , 0.0f , ~ 0ul ) ;
}
else
{
mAnimation - > disable ( mCurrentJump ) ;
mCurrentJump . clear ( ) ;
if ( mAnimation - > hasAnimation ( " jump " ) )
mAnimation - > play ( jump , Priority_Jump , jump group , true ,
mAnimation - > play ( jump AnimName , Priority_Jump , jump mask , true ,
1.0f , " loop stop " , " stop " , 0.0f , 0 ) ;
}
}
@ -353,55 +357,55 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
{
mMovementState = movement ;
std : : string movement ;
MWRender : : Animation : : Group movegroup = MWRender : : Animation : : Group _All;
std : : string movement AnimName ;
MWRender : : Animation : : BlendMask movemask = MWRender : : Animation : : BlendMask _All;
const StateInfo * movestate = std : : find_if ( sMovementList , sMovementListEnd , FindCharState ( mMovementState ) ) ;
if ( movestate ! = sMovementListEnd )
{
movement = movestate - > groupname ;
if ( weap ! = sWeaponTypeListEnd & & movement . find ( " swim " ) = = std : : string : : npos )
movement AnimName = movestate - > groupname ;
if ( weap ! = sWeaponTypeListEnd & & movement AnimName . find ( " swim " ) = = std : : string : : npos )
{
movement + = weap - > shortgroup ;
if ( ! mAnimation - > hasAnimation ( movement ) )
movement AnimName + = weap - > shortgroup ;
if ( ! mAnimation - > hasAnimation ( movement AnimName ) )
{
move group = MWRender : : Animation : : Group _LowerBody;
movement = movestate - > groupname ;
move mask = MWRender : : Animation : : BlendMask _LowerBody;
movement AnimName = movestate - > groupname ;
}
}
if ( ! mAnimation - > hasAnimation ( movement ) )
if ( ! mAnimation - > hasAnimation ( movement AnimName ) )
{
std : : string : : size_type swimpos = movement . find ( " swim " ) ;
std : : string : : size_type swimpos = movement AnimName . find ( " swim " ) ;
if ( swimpos = = std : : string : : npos )
{
std : : string : : size_type runpos = movement . find ( " run " ) ;
std : : string : : size_type runpos = movement AnimName . find ( " run " ) ;
if ( runpos ! = std : : string : : npos )
{
movement . replace ( runpos , runpos + 3 , " walk " ) ;
if ( ! mAnimation - > hasAnimation ( movement ) )
movement . clear ( ) ;
movement AnimName . replace ( runpos , runpos + 3 , " walk " ) ;
if ( ! mAnimation - > hasAnimation ( movement AnimName ) )
movement AnimName . clear ( ) ;
}
else
movement . clear ( ) ;
movement AnimName . clear ( ) ;
}
else
{
move group = MWRender : : Animation : : Group _LowerBody;
movement . erase ( swimpos , 4 ) ;
if ( ! mAnimation - > hasAnimation ( movement ) )
movement . clear ( ) ;
move mask = MWRender : : Animation : : BlendMask _LowerBody;
movement AnimName . erase ( swimpos , 4 ) ;
if ( ! mAnimation - > hasAnimation ( movement AnimName ) )
movement AnimName . clear ( ) ;
}
}
}
/* If we're playing the same animation, restart from the loop start instead of the
* beginning . */
int mode = ( ( movement = = mCurrentMovement ) ? 2 : 1 ) ;
int mode = ( ( movement AnimName = = mCurrentMovement ) ? 2 : 1 ) ;
mMovementAnimationControlled = true ;
mAnimation - > disable ( mCurrentMovement ) ;
mCurrentMovement = movement ;
mCurrentMovement = movement AnimName ;
if ( ! mCurrentMovement . empty ( ) )
{
float vel , speedmult = 1.0f ;
@ -447,7 +451,17 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
}
}
mAnimation - > play ( mCurrentMovement , Priority_Movement , movegroup , false ,
MWRender : : Animation : : AnimPriority priorityMovement ( Priority_Movement ) ;
if ( ( movement = = CharState_TurnLeft | | movement = = CharState_TurnRight )
& & mPtr = = MWBase : : Environment : : get ( ) . getWorld ( ) - > getPlayerPtr ( )
& & MWBase : : Environment : : get ( ) . getWorld ( ) - > isFirstPerson ( ) )
{
priorityMovement . mPriority [ MWRender : : Animation : : BoneGroup_Torso ] = 0 ;
priorityMovement . mPriority [ MWRender : : Animation : : BoneGroup_LeftArm ] = 0 ;
priorityMovement . mPriority [ MWRender : : Animation : : BoneGroup_RightArm ] = 0 ;
}
mAnimation - > play ( mCurrentMovement , priorityMovement , movemask , false ,
speedmult , ( ( mode ! = 2 ) ? " start " : " loop start " ) , " stop " , 0.0f , ~ 0ul ) ;
}
}
@ -456,7 +470,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
// 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_None & & mMovementState ! = CharState_TurnLeft & & mMovementState ! = CharState_TurnRight )
| | mHitState ! = CharState_None )
& & ! mPtr . getClass ( ) . isBipedal ( mPtr ) )
idle = CharState_None ;
@ -486,7 +500,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
mAnimation - > disable ( mCurrentIdle ) ;
mCurrentIdle = idle ;
if ( ! mCurrentIdle . empty ( ) )
mAnimation - > play ( mCurrentIdle , Priority_Default , MWRender : : Animation : : Group _All, false ,
mAnimation - > play ( mCurrentIdle , Priority_Default , MWRender : : Animation : : BlendMask _All, false ,
1.0f , " start " , " stop " , 0.0f , ~ 0ul , true ) ;
}
@ -602,7 +616,7 @@ void CharacterController::playDeath(float startpoint, CharacterState death)
mCurrentJump = " " ;
mMovementAnimationControlled = true ;
mAnimation - > play ( mCurrentDeath , Priority_Death , MWRender : : Animation : : Group _All,
mAnimation - > play ( mCurrentDeath , Priority_Death , MWRender : : Animation : : BlendMask _All,
false , 1.0f , " start " , " stop " , startpoint , 0 ) ;
}
@ -704,7 +718,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
if ( mDeathState = = CharState_None )
refreshCurrentAnims ( mIdleState , mMovementState , true ) ;
refreshCurrentAnims ( mIdleState , mMovementState , mJumpState , true ) ;
mAnimation - > runAnimation ( 0.f ) ;
}
@ -868,10 +882,10 @@ void CharacterController::updateIdleStormState()
mAnimation - > getInfo ( " idlestorm " , & complete ) ;
if ( complete = = 0 )
mAnimation - > play ( " idlestorm " , Priority_Storm , MWRender : : Animation : : Group _RightArm, false ,
mAnimation - > play ( " idlestorm " , Priority_Storm , MWRender : : Animation : : BlendMask _RightArm, false ,
1.0f , " start " , " loop start " , 0.0f , 0 ) ;
else if ( complete = = 1 )
mAnimation - > play ( " idlestorm " , Priority_Storm , MWRender : : Animation : : Group _RightArm, false ,
mAnimation - > play ( " idlestorm " , Priority_Storm , MWRender : : Animation : : BlendMask _RightArm, false ,
1.0f , " loop start " , " loop stop " , 0.0f , ~ 0ul ) ;
}
else
@ -882,7 +896,7 @@ void CharacterController::updateIdleStormState()
{
if ( mAnimation - > getCurrentTime ( " idlestorm " ) < mAnimation - > getTextKeyTime ( " idlestorm: loop stop " ) )
{
mAnimation - > play ( " idlestorm " , Priority_Storm , MWRender : : Animation : : Group _RightArm, true ,
mAnimation - > play ( " idlestorm " , Priority_Storm , MWRender : : Animation : : BlendMask _RightArm, true ,
1.0f , " loop stop " , " stop " , 0.0f , 0 ) ;
}
}
@ -989,7 +1003,7 @@ bool CharacterController::updateCreatureState()
if ( ! mCurrentWeapon . empty ( ) )
{
mAnimation - > play ( mCurrentWeapon , Priority_Weapon ,
MWRender : : Animation : : Group _All, true ,
MWRender : : Animation : : BlendMask _All, true ,
1 , startKey , stopKey ,
0.0f , 0 ) ;
mUpperBodyState = UpperCharState_StartToMinAttack ;
@ -1051,6 +1065,9 @@ bool CharacterController::updateWeaponState()
}
}
MWRender : : Animation : : AnimPriority priorityWeapon ( Priority_Weapon ) ;
priorityWeapon . mPriority [ MWRender : : Animation : : BoneGroup_LowerBody ] = 0 ;
bool forcestateupdate = false ;
if ( weaptype ! = mWeaponType & & mHitState ! = CharState_KnockDown & & mHitState ! = CharState_KnockOut
& & mHitState ! = CharState_Hit )
@ -1063,8 +1080,8 @@ bool CharacterController::updateWeaponState()
if ( weaptype = = WeapType_None )
{
getWeaponGroup ( mWeaponType , weapgroup ) ;
mAnimation - > play ( weapgroup , Priority_ Weapon,
MWRender : : Animation : : Group_UpperBody , true ,
mAnimation - > play ( weapgroup , priority Weapon,
MWRender : : Animation : : BlendMask_All , true ,
1.0f , " unequip start " , " unequip stop " , 0.0f , 0 ) ;
mUpperBodyState = UpperCharState_UnEquipingWeap ;
}
@ -1074,8 +1091,8 @@ bool CharacterController::updateWeaponState()
mAnimation - > showWeapons ( false ) ;
mAnimation - > setWeaponGroup ( weapgroup ) ;
mAnimation - > play ( weapgroup , Priority_ Weapon,
MWRender : : Animation : : Group_UpperBody , true ,
mAnimation - > play ( weapgroup , priority Weapon,
MWRender : : Animation : : BlendMask_All , true ,
1.0f , " equip start " , " equip stop " , 0.0f , 0 ) ;
mUpperBodyState = UpperCharState_EquipingWeap ;
@ -1145,7 +1162,7 @@ bool CharacterController::updateWeaponState()
bool animPlaying ;
if ( mAttackingOrSpell )
{
if ( mUpperBodyState = = UpperCharState_WeapEquiped & & mHitState = = CharState_None )
if ( mUpperBodyState = = UpperCharState_WeapEquiped & & ( mHitState = = CharState_None | | mHitState = = CharState_Block ) )
{
MWBase : : Environment : : get ( ) . getWorld ( ) - > breakInvisibility ( mPtr ) ;
mAttackType . clear ( ) ;
@ -1154,6 +1171,10 @@ bool CharacterController::updateWeaponState()
// Unset casting flag, otherwise pressing the mouse button down would
// continue casting every frame if there is no animation
mAttackingOrSpell = false ;
if ( mPtr = = MWBase : : Environment : : get ( ) . getWorld ( ) - > getPlayerPtr ( ) )
{
MWBase : : Environment : : get ( ) . getWorld ( ) - > getPlayer ( ) . setAttackingOrSpell ( false ) ;
}
const MWWorld : : ESMStore & store = MWBase : : Environment : : get ( ) . getWorld ( ) - > getStore ( ) ;
@ -1191,8 +1212,8 @@ bool CharacterController::updateWeaponState()
case 2 : mAttackType = " target " ; break ;
}
mAnimation - > play ( mCurrentWeapon , Priority_ Weapon,
MWRender : : Animation : : Group_UpperBody , true ,
mAnimation - > play ( mCurrentWeapon , priority Weapon,
MWRender : : Animation : : BlendMask_All , true ,
weapSpeed , mAttackType + " start " , mAttackType + " stop " ,
0.0f , 0 ) ;
mUpperBodyState = UpperCharState_CastingSpell ;
@ -1223,8 +1244,8 @@ bool CharacterController::updateWeaponState()
else if ( item . getTypeName ( ) = = typeid ( ESM : : Probe ) . name ( ) )
Security ( mPtr ) . probeTrap ( target , item , resultMessage , resultSound ) ;
}
mAnimation - > play ( mCurrentWeapon , Priority_ Weapon,
MWRender : : Animation : : Group_UpperBody , true ,
mAnimation - > play ( mCurrentWeapon , priority Weapon,
MWRender : : Animation : : BlendMask_All , true ,
1.0f , " start " , " stop " , 0.0 , 0 ) ;
mUpperBodyState = UpperCharState_FollowStartToFollowStop ;
@ -1250,8 +1271,8 @@ bool CharacterController::updateWeaponState()
determineAttackType ( ) ;
}
mAnimation - > play ( mCurrentWeapon , Priority_ Weapon,
MWRender : : Animation : : Group_UpperBody , false ,
mAnimation - > play ( mCurrentWeapon , priority Weapon,
MWRender : : Animation : : BlendMask_All , false ,
weapSpeed , mAttackType + " start " , mAttackType + " min attack " ,
0.0f , 0 ) ;
mUpperBodyState = UpperCharState_StartToMinAttack ;
@ -1301,8 +1322,8 @@ bool CharacterController::updateWeaponState()
mAttackStrength = attackStrength ;
mAnimation - > disable ( mCurrentWeapon ) ;
mAnimation - > play ( mCurrentWeapon , Priority_ Weapon,
MWRender : : Animation : : Group_UpperBody , false ,
mAnimation - > play ( mCurrentWeapon , priority Weapon,
MWRender : : Animation : : BlendMask_All , false ,
weapSpeed , mAttackType + " max attack " , mAttackType + " min hit " ,
1.0f - complete , 0 ) ;
@ -1371,15 +1392,6 @@ bool CharacterController::updateWeaponState()
mAnimation - > attachArrow ( ) ;
mUpperBodyState = UpperCharState_WeapEquiped ;
//don't allow to continue playing hit animation on UpperBody after actor had attacked during it
if ( mHitState = = CharState_Hit )
{
mAnimation - > changeGroups ( mCurrentHit , MWRender : : Animation : : Group_LowerBody ) ;
//commenting out following 2 lines will give a bit different combat dynamics(slower)
mHitState = CharState_None ;
mCurrentHit . clear ( ) ;
mPtr . getClass ( ) . getCreatureStats ( mPtr ) . setHitRecovery ( false ) ;
}
}
else if ( mUpperBodyState = = UpperCharState_UnEquipingWeap )
mUpperBodyState = UpperCharState_Nothing ;
@ -1397,8 +1409,8 @@ bool CharacterController::updateWeaponState()
case UpperCharState_MinAttackToMaxAttack :
//hack to avoid body pos desync when jumping/sneaking in 'max attack' state
if ( ! mAnimation - > isPlaying ( mCurrentWeapon ) )
mAnimation - > play ( mCurrentWeapon , Priority_ Weapon,
MWRender : : Animation : : Group_UpperBody , false ,
mAnimation - > play ( mCurrentWeapon , priority Weapon,
MWRender : : Animation : : BlendMask_All , false ,
0 , mAttackType + " min attack " , mAttackType + " max attack " , 0.999f , 0 ) ;
break ;
case UpperCharState_MaxAttackToMinHit :
@ -1440,33 +1452,16 @@ bool CharacterController::updateWeaponState()
{
mAnimation - > disable ( mCurrentWeapon ) ;
if ( mUpperBodyState = = UpperCharState_FollowStartToFollowStop )
mAnimation - > play ( mCurrentWeapon , Priority_ Weapon,
MWRender : : Animation : : Group_UpperBody , true ,
mAnimation - > play ( mCurrentWeapon , priority Weapon,
MWRender : : Animation : : BlendMask_All , true ,
weapSpeed , start , stop , 0.0f , 0 ) ;
else
mAnimation - > play ( mCurrentWeapon , Priority_ Weapon,
MWRender : : Animation : : Group_UpperBody , false ,
mAnimation - > play ( mCurrentWeapon , priority Weapon,
MWRender : : Animation : : BlendMask_All , false ,
weapSpeed , start , stop , 0.0f , 0 ) ;
}
}
//if playing combat animation and lowerbody is not busy switch to whole body animation
if ( ( weaptype ! = WeapType_None | | mUpperBodyState = = UpperCharState_UnEquipingWeap ) & & animPlaying )
{
if ( mMovementState ! = CharState_None | |
mJumpState ! = JumpState_None | |
mHitState ! = CharState_None | |
MWBase : : Environment : : get ( ) . getWorld ( ) - > isSwimming ( mPtr ) | |
cls . getCreatureStats ( mPtr ) . getMovementFlag ( CreatureStats : : Flag_Sneak ) )
{
mAnimation - > changeGroups ( mCurrentWeapon , MWRender : : Animation : : Group_UpperBody ) ;
}
else
{
mAnimation - > changeGroups ( mCurrentWeapon , MWRender : : Animation : : Group_All ) ;
}
}
if ( mPtr . getClass ( ) . hasInventoryStore ( mPtr ) )
{
MWWorld : : InventoryStore & inv = mPtr . getClass ( ) . getInventoryStore ( mPtr ) ;
@ -1475,7 +1470,7 @@ bool CharacterController::updateWeaponState()
& & updateCarriedLeftVisible ( mWeaponType ) )
{
mAnimation - > play ( " torch " , Priority_Torch , MWRender : : Animation : : Group _LeftArm,
mAnimation - > play ( " torch " , Priority_Torch , MWRender : : Animation : : BlendMask _LeftArm,
false , 1.0f , " start " , " stop " , 0.0f , ( ~ ( size_t ) 0 ) , true ) ;
}
else if ( mAnimation - > isPlaying ( " torch " ) )
@ -1505,7 +1500,7 @@ void CharacterController::update(float duration)
mAnimQueue . pop_front ( ) ;
mAnimation - > play ( mAnimQueue . front ( ) . first , Priority_Default ,
MWRender : : Animation : : Group _All, false ,
MWRender : : Animation : : BlendMask _All, false ,
1.0f , " start " , " stop " , 0.0f , mAnimQueue . front ( ) . second ) ;
}
}
@ -1562,6 +1557,8 @@ void CharacterController::update(float duration)
CharacterState movestate = CharState_None ;
CharacterState idlestate = CharState_SpecialIdle ;
JumpingState jumpstate = JumpState_None ;
bool forcestateupdate = false ;
mHasMovedInXY = std : : abs ( vec . x ( ) ) + std : : abs ( vec . y ( ) ) > 0.0f ;
@ -1644,7 +1641,7 @@ void CharacterController::update(float duration)
}
forcestateupdate = ( mJumpState ! = JumpState_InAir ) ;
mJumpS tate = JumpState_InAir ;
jumps tate = JumpState_InAir ;
static const float fJumpMoveBase = gmst . find ( " fJumpMoveBase " ) - > getFloat ( ) ;
static const float fJumpMoveMult = gmst . find ( " fJumpMoveMult " ) - > getFloat ( ) ;
@ -1689,7 +1686,7 @@ void CharacterController::update(float duration)
else if ( mJumpState = = JumpState_InAir )
{
forcestateupdate = true ;
mJumpS tate = JumpState_Landing ;
jumps tate = JumpState_Landing ;
vec . z ( ) = 0.0f ;
float height = cls . getCreatureStats ( mPtr ) . land ( ) ;
@ -1720,7 +1717,7 @@ void CharacterController::update(float duration)
}
else
{
mJumpS tate = JumpState_None ;
jumps tate = JumpState_None ;
vec . z ( ) = 0.0f ;
inJump = false ;
@ -1786,19 +1783,22 @@ void CharacterController::update(float duration)
mAnimQueue . pop_front ( ) ;
mAnimation - > play ( mAnimQueue . front ( ) . first , Priority_Default ,
MWRender : : Animation : : Group _All, false ,
MWRender : : Animation : : BlendMask _All, false ,
1.0f , " start " , " stop " , 0.0f , mAnimQueue . front ( ) . second ) ;
}
}
// bipedal means hand-to-hand could be used (which is handled in updateWeaponState). an existing InventoryStore means an actual weapon could be used.
if ( cls . isBipedal ( mPtr ) | | cls . hasInventoryStore ( mPtr ) )
forcestateupdate = updateWeaponState ( ) | | forcestateupdate ;
else
forcestateupdate = updateCreatureState ( ) | | forcestateupdate ;
if ( ! mSkipAnim )
refreshCurrentAnims ( idlestate , movestate , forcestateupdate ) ;
{
// bipedal means hand-to-hand could be used (which is handled in updateWeaponState). an existing InventoryStore means an actual weapon could be used.
if ( cls . isBipedal ( mPtr ) | | cls . hasInventoryStore ( mPtr ) )
forcestateupdate = updateWeaponState ( ) | | forcestateupdate ;
else
forcestateupdate = updateCreatureState ( ) | | forcestateupdate ;
refreshCurrentAnims ( idlestate , movestate , jumpstate , forcestateupdate ) ;
}
if ( inJump )
mMovementAnimationControlled = false ;
@ -1894,7 +1894,7 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int
mIdleState = CharState_SpecialIdle ;
mAnimation - > play ( groupname , Priority_Default ,
MWRender : : Animation : : Group _All, false , 1.0f ,
MWRender : : Animation : : BlendMask _All, false , 1.0f ,
( ( mode = = 2 ) ? " loop start " : " start " ) , " stop " , 0.0f , count - 1 ) ;
}
else if ( mode = = 0 )
@ -1934,7 +1934,7 @@ void CharacterController::forceStateUpdate()
return ;
clearAnimQueue ( ) ;
refreshCurrentAnims ( mIdleState , mMovementState , true ) ;
refreshCurrentAnims ( mIdleState , mMovementState , mJumpState , true ) ;
if ( mDeathState ! = CharState_None )
{
playRandomDeath ( ) ;
@ -2052,12 +2052,13 @@ void CharacterController::setAttackingOrSpell(bool attackingOrSpell)
bool CharacterController : : readyToPrepareAttack ( ) const
{
return mHitState = = CharState_None & & mUpperBodyState < = UpperCharState_WeapEquiped ;
return ( mHitState = = CharState_None | | mHitState = = CharState_Block )
& & mUpperBodyState < = UpperCharState_WeapEquiped ;
}
bool CharacterController : : readyToStartAttack ( ) const
{
if ( mHitState ! = CharState_None )
if ( mHitState ! = CharState_None & & mHitState ! = CharState_Block )
return false ;
if ( mPtr . getClass ( ) . hasInventoryStore ( mPtr ) | | mPtr . getClass ( ) . isBipedal ( mPtr ) )