|
|
|
@ -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)
|
|
|
|
|
{
|
|
|
|
|