1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-05-09 20:11:25 +00:00

Consolidate refreshIdleAnims

This commit is contained in:
Alexei Kotov 2022-06-13 15:41:56 +03:00
parent 2c3d385672
commit dd42a69ca5

View file

@ -181,6 +181,48 @@ std::string hitStateToAnimGroup(MWMechanics::CharacterState state)
} }
} }
// Converts an idle state to its equivalent animation group.
std::string idleStateToAnimGroup(MWMechanics::CharacterState state)
{
using namespace MWMechanics;
switch (state)
{
case CharState_IdleSwim:
return "idleswim";
case CharState_IdleSneak:
return "idlesneak";
case CharState_Idle:
case CharState_Idle2:
case CharState_Idle3:
case CharState_Idle4:
case CharState_Idle5:
case CharState_Idle6:
case CharState_Idle7:
case CharState_Idle8:
case CharState_Idle9:
case CharState_SpecialIdle:
return "idle";
default:
return {};
}
}
MWRender::Animation::AnimPriority getIdlePriority(MWMechanics::CharacterState state)
{
using namespace MWMechanics;
MWRender::Animation::AnimPriority priority(Priority_Default);
switch (state)
{
case CharState_IdleSwim:
return Priority_SwimIdle;
case CharState_IdleSneak:
priority[MWRender::Animation::BoneGroup_LowerBody] = Priority_SneakIdleLowerBody;
[[fallthrough]];
default:
return priority;
}
}
float getFallDamage(const MWWorld::Ptr& ptr, float fallHeight) float getFallDamage(const MWWorld::Ptr& ptr, float fallHeight)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
@ -637,59 +679,68 @@ void CharacterController::refreshIdleAnims(const std::string& weapShortGroup, Ch
&& !mPtr.getClass().isBipedal(mPtr)) && !mPtr.getClass().isBipedal(mPtr))
idle = CharState_None; idle = CharState_None;
if(force || idle != mIdleState || (!mAnimation->isPlaying(mCurrentIdle) && mAnimQueue.empty())) if (!force && idle == mIdleState && (mAnimation->isPlaying(mCurrentIdle) || !mAnimQueue.empty()))
{ return;
mIdleState = idle; mIdleState = idle;
size_t numLoops = ~0ul; size_t numLoops = ~0ul;
std::string idleGroup; std::string idleGroup = idleStateToAnimGroup(mIdleState);
MWRender::Animation::AnimPriority idlePriority (Priority_Default); MWRender::Animation::AnimPriority priority = getIdlePriority(mIdleState);
// Only play "idleswim" or "idlesneak" if they exist. Otherwise, fallback to // Only play "idleswim" or "idlesneak" if they exist. Otherwise, fallback to
// "idle"+weapon or "idle". // "idle"+weapon or "idle".
if(mIdleState == CharState_IdleSwim && mAnimation->hasAnimation("idleswim")) if ((mIdleState == CharState_IdleSwim || mIdleState == CharState_IdleSneak) && !mAnimation->hasAnimation(idleGroup))
idleGroup = idleStateToAnimGroup(CharState_Idle);
if (idleGroup.empty())
{ {
idleGroup = "idleswim"; if (mCurrentIdle.empty())
idlePriority = Priority_SwimIdle; {
mAnimation->disable(mCurrentIdle);
mCurrentIdle.clear();
} }
else if(mIdleState == CharState_IdleSneak && mAnimation->hasAnimation("idlesneak")) mIdleState = CharState_None;
{ return;
idleGroup = "idlesneak";
idlePriority[MWRender::Animation::BoneGroup_LowerBody] = Priority_SneakIdleLowerBody;
} }
else if(mIdleState != CharState_None)
if (mIdleState != CharState_IdleSwim && mIdleState != CharState_IdleSneak && mIdleState != CharState_None && !weapShortGroup.empty())
{ {
idleGroup = "idle"; std::string weapIdleGroup = idleGroup + weapShortGroup;
if(!weapShortGroup.empty()) if (!mAnimation->hasAnimation(weapIdleGroup))
{ weapIdleGroup = fallbackShortWeaponGroup(idleGroup);
idleGroup += weapShortGroup; idleGroup = weapIdleGroup;
if(!mAnimation->hasAnimation(idleGroup))
{
idleGroup = fallbackShortWeaponGroup("idle");
}
// play until the Loop Stop key 2 to 5 times, then play until the Stop key // play until the Loop Stop key 2 to 5 times, then play until the Stop key
// this replicates original engine behavior for the "Idle1h" 1st-person animation // this replicates original engine behavior for the "Idle1h" 1st-person animation
auto& prng = MWBase::Environment::get().getWorld()->getPrng(); auto& prng = MWBase::Environment::get().getWorld()->getPrng();
numLoops = 1 + Misc::Rng::rollDice(4, prng); numLoops = 1 + Misc::Rng::rollDice(4, prng);
} }
}
// There is no need to restart anim if the new and old anims are the same. if (!mAnimation->hasAnimation(idleGroup))
// Just update a number of loops.
float startPoint = 0;
if (!mCurrentIdle.empty() && mCurrentIdle == idleGroup)
{ {
mAnimation->getInfo(mCurrentIdle, &startPoint); if (mCurrentIdle.empty())
{
mAnimation->disable(mCurrentIdle);
mCurrentIdle.clear();
}
mIdleState = CharState_None;
return;
} }
float startPoint = 0.f;
if (!mCurrentIdle.empty()) 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); mAnimation->disable(mCurrentIdle);
}
mCurrentIdle = idleGroup; mCurrentIdle = idleGroup;
if(!mCurrentIdle.empty()) mAnimation->play(mCurrentIdle, priority, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", startPoint, numLoops, true);
mAnimation->play(mCurrentIdle, idlePriority, MWRender::Animation::BlendMask_All, false,
1.0f, "start", "stop", startPoint, numLoops, true);
}
} }
void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force) void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force)