1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-29 23:36:43 +00:00

Revert poor animation decisions

Start force-updated in-air animation from loop start
Make movement animations have higher priority than jump animations
Make jumping animations have higher priority than turning animations
Don't reset idle during landing animation
Don't play default landing sound if the character is not on ground
This commit is contained in:
Capostrophic 2019-01-09 18:05:51 +03:00
parent a8e65bf5eb
commit f9a711d2fd
2 changed files with 21 additions and 20 deletions

View file

@ -345,15 +345,14 @@ void CharacterController::refreshHitRecoilAnims(CharacterState& idle)
idle = CharState_None;
}
void CharacterController::refreshJumpAnims(const WeaponInfo* weap, JumpingState jump, CharacterState& idle, CharacterState& movement, bool force)
void CharacterController::refreshJumpAnims(const WeaponInfo* weap, JumpingState jump, CharacterState& idle, bool force)
{
if (!force && jump == mJumpState && idle == CharState_None && movement == CharState_None)
if (!force && jump == mJumpState && idle == CharState_None)
return;
if (jump != JumpState_None && !(mPtr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->isFirstPerson())) // FIXME
if (jump == JumpState_InAir)
{
idle = CharState_None;
movement = CharState_None;
}
std::string jumpAnimName;
@ -384,6 +383,7 @@ void CharacterController::refreshJumpAnims(const WeaponInfo* weap, JumpingState
if (!force && jump == mJumpState)
return;
bool startAtLoop = (jump == mJumpState);
mJumpState = jump;
if (!mCurrentJump.empty())
@ -397,7 +397,7 @@ void CharacterController::refreshJumpAnims(const WeaponInfo* weap, JumpingState
if (mAnimation->hasAnimation(jumpAnimName))
{
mAnimation->play(jumpAnimName, Priority_Jump, jumpmask, false,
1.0f, "start", "stop", 0.f, ~0ul);
1.0f, startAtLoop ? "loop start" : "start", "stop", 0.f, ~0ul);
mCurrentJump = jumpAnimName;
}
}
@ -675,7 +675,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
if (!mPtr.getClass().hasInventoryStore(mPtr))
weap = sWeaponTypeListEnd;
refreshJumpAnims(weap, jump, idle, movement, force);
refreshJumpAnims(weap, jump, idle, force);
refreshMovementAnims(weap, movement, idle, force);
// idle handled last as it can depend on the other states
@ -2137,12 +2137,6 @@ void CharacterController::update(float duration, bool animationOnly)
inJump = false;
// Do not play turning animation for player if rotation speed is very slow.
// Actual threshold should take framerate in account.
float rotationThreshold = 0;
if (isPlayer)
rotationThreshold = 0.015 * 60 * duration;
if(std::abs(vec.x()/2.0f) > std::abs(vec.y()))
{
if(vec.x() > 0.0f)
@ -2167,10 +2161,16 @@ void CharacterController::update(float duration, bool animationOnly)
}
else if(rot.z() != 0.0f)
{
// Do not play turning animation for player if rotation speed is very slow.
// Actual threshold should take framerate in account.
float rotationThreshold = 0.f;
if (isPlayer)
rotationThreshold = 0.015 * 60 * duration;
// It seems only bipedal actors use turning animations.
// Also do not use turning animations in the first-person view and when sneaking.
bool isFirstPlayer = isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson();
if (!sneak && !isFirstPlayer && mPtr.getClass().isBipedal(mPtr))
if (!sneak && jumpstate == JumpState_None && !isFirstPlayer && mPtr.getClass().isBipedal(mPtr))
{
if(rot.z() > rotationThreshold)
movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight;
@ -2183,12 +2183,15 @@ void CharacterController::update(float duration, bool animationOnly)
if (playLandingSound)
{
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
std::string sound = "DefaultLand";
std::string sound;
osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3());
if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr))
sound = "DefaultLandWater";
else if (onground)
sound = "DefaultLand";
sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal);
if (!sound.empty())
sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal);
}
// Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering
@ -2197,7 +2200,7 @@ void CharacterController::update(float duration, bool animationOnly)
float threshold = mCurrentMovement.find("swim") == std::string::npos ? 0.4f : 0.8f;
float complete;
bool animPlaying = mAnimation->getInfo(mCurrentMovement, &complete);
if (movestate == CharState_None && isTurning())
if (movestate == CharState_None && jumpstate == JumpState_None && isTurning())
{
if (animPlaying && complete < threshold)
movestate = mMovementState;

View file

@ -31,10 +31,8 @@ enum Priority {
Priority_WeaponLowerBody,
Priority_SneakIdleLowerBody,
Priority_SwimIdle,
Priority_Movement,
// Note: in vanilla movement anims have higher priority than jump ones.
// It causes issues with landing animations during movement.
Priority_Jump,
Priority_Movement,
Priority_Hit,
Priority_Weapon,
Priority_Block,
@ -214,7 +212,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener
void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force=false);
void refreshHitRecoilAnims(CharacterState& idle);
void refreshJumpAnims(const WeaponInfo* weap, JumpingState jump, CharacterState& idle, CharacterState& movement, bool force=false);
void refreshJumpAnims(const WeaponInfo* weap, JumpingState jump, CharacterState& idle, bool force=false);
void refreshMovementAnims(const WeaponInfo* weap, CharacterState movement, CharacterState& idle, bool force=false);
void refreshIdleAnims(const WeaponInfo* weap, CharacterState idle, bool force=false);