mirror of
https://github.com/OpenMW/openmw.git
synced 2025-05-09 12:11:25 +00:00
Consolidate refreshIdleAnims
This commit is contained in:
parent
2c3d385672
commit
dd42a69ca5
1 changed files with 100 additions and 49 deletions
|
@ -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;
|
||||||
|
size_t numLoops = ~0ul;
|
||||||
|
|
||||||
|
std::string idleGroup = idleStateToAnimGroup(mIdleState);
|
||||||
|
MWRender::Animation::AnimPriority priority = getIdlePriority(mIdleState);
|
||||||
|
|
||||||
|
// Only play "idleswim" or "idlesneak" if they exist. Otherwise, fallback to
|
||||||
|
// "idle"+weapon or "idle".
|
||||||
|
if ((mIdleState == CharState_IdleSwim || mIdleState == CharState_IdleSneak) && !mAnimation->hasAnimation(idleGroup))
|
||||||
|
idleGroup = idleStateToAnimGroup(CharState_Idle);
|
||||||
|
|
||||||
|
if (idleGroup.empty())
|
||||||
{
|
{
|
||||||
mIdleState = idle;
|
if (mCurrentIdle.empty())
|
||||||
size_t numLoops = ~0ul;
|
|
||||||
|
|
||||||
std::string idleGroup;
|
|
||||||
MWRender::Animation::AnimPriority idlePriority (Priority_Default);
|
|
||||||
// Only play "idleswim" or "idlesneak" if they exist. Otherwise, fallback to
|
|
||||||
// "idle"+weapon or "idle".
|
|
||||||
if(mIdleState == CharState_IdleSwim && mAnimation->hasAnimation("idleswim"))
|
|
||||||
{
|
{
|
||||||
idleGroup = "idleswim";
|
|
||||||
idlePriority = Priority_SwimIdle;
|
|
||||||
}
|
|
||||||
else if(mIdleState == CharState_IdleSneak && mAnimation->hasAnimation("idlesneak"))
|
|
||||||
{
|
|
||||||
idleGroup = "idlesneak";
|
|
||||||
idlePriority[MWRender::Animation::BoneGroup_LowerBody] = Priority_SneakIdleLowerBody;
|
|
||||||
}
|
|
||||||
else if(mIdleState != CharState_None)
|
|
||||||
{
|
|
||||||
idleGroup = "idle";
|
|
||||||
if(!weapShortGroup.empty())
|
|
||||||
{
|
|
||||||
idleGroup += weapShortGroup;
|
|
||||||
if(!mAnimation->hasAnimation(idleGroup))
|
|
||||||
{
|
|
||||||
idleGroup = fallbackShortWeaponGroup("idle");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
|
||||||
numLoops = 1 + Misc::Rng::rollDice(4, prng);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is no need to restart anim if the new and old anims are the same.
|
|
||||||
// Just update a number of loops.
|
|
||||||
float startPoint = 0;
|
|
||||||
if (!mCurrentIdle.empty() && mCurrentIdle == idleGroup)
|
|
||||||
{
|
|
||||||
mAnimation->getInfo(mCurrentIdle, &startPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!mCurrentIdle.empty())
|
|
||||||
mAnimation->disable(mCurrentIdle);
|
mAnimation->disable(mCurrentIdle);
|
||||||
|
mCurrentIdle.clear();
|
||||||
mCurrentIdle = idleGroup;
|
}
|
||||||
if(!mCurrentIdle.empty())
|
mIdleState = CharState_None;
|
||||||
mAnimation->play(mCurrentIdle, idlePriority, MWRender::Animation::BlendMask_All, false,
|
return;
|
||||||
1.0f, "start", "stop", startPoint, numLoops, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mIdleState != CharState_IdleSwim && mIdleState != CharState_IdleSneak && mIdleState != CharState_None && !weapShortGroup.empty())
|
||||||
|
{
|
||||||
|
std::string weapIdleGroup = idleGroup + weapShortGroup;
|
||||||
|
if (!mAnimation->hasAnimation(weapIdleGroup))
|
||||||
|
weapIdleGroup = fallbackShortWeaponGroup(idleGroup);
|
||||||
|
idleGroup = weapIdleGroup;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||||
|
numLoops = 1 + Misc::Rng::rollDice(4, prng);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mAnimation->hasAnimation(idleGroup))
|
||||||
|
{
|
||||||
|
if (mCurrentIdle.empty())
|
||||||
|
{
|
||||||
|
mAnimation->disable(mCurrentIdle);
|
||||||
|
mCurrentIdle.clear();
|
||||||
|
}
|
||||||
|
mIdleState = CharState_None;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
mCurrentIdle = idleGroup;
|
||||||
|
mAnimation->play(mCurrentIdle, priority, 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)
|
||||||
|
|
Loading…
Reference in a new issue