From 819101144d63435df684ae6cbe08f9411737a799 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Sun, 24 Jul 2022 17:24:17 +0300 Subject: [PATCH 1/2] Landing animation playback fixes Cancel landing animation immediately after moving during the first frame of landing and due to turning animation --- apps/openmw/mwmechanics/character.cpp | 78 +++++++++++++-------------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c6f28cca64..4d9905c113 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2047,48 +2047,46 @@ void CharacterController::update(float duration) } } } - else if(mJumpState == JumpState_InAir && !inwater && !flying && solid) - { - jumpstate = JumpState_Landing; - vec.z() = 0.0f; - - float height = cls.getCreatureStats(mPtr).land(isPlayer); - float healthLost = getFallDamage(mPtr, height); - - if (healthLost > 0.0f) - { - const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm(); - - // inflict fall damages - if (!godmode) - { - float realHealthLost = static_cast(healthLost * (1.0f - 0.25f * fatigueTerm)); - cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), osg::Vec3f(), true); - } - - const float acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics); - if (healthLost > (acrobaticsSkill * fatigueTerm)) - { - if (!godmode) - cls.getCreatureStats(mPtr).setKnockedDown(true); - } - else - { - // report acrobatics progression - if (isPlayer) - cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); - } - } - - if (mPtr.getClass().isNpc()) - playLandingSound = true; - } else { - if(mPtr.getClass().isNpc() && mJumpState == JumpState_InAir && !flying && solid) - playLandingSound = true; + if (mJumpState == JumpState_InAir && !flying && solid) + { + float height = cls.getCreatureStats(mPtr).land(isPlayer); + float healthLost = 0.f; + if (!inwater) + healthLost = getFallDamage(mPtr, height); - jumpstate = mAnimation->isPlaying(mCurrentJump) ? JumpState_Landing : JumpState_None; + if (healthLost > 0.0f) + { + const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm(); + + // inflict fall damages + if (!godmode) + { + float realHealthLost = static_cast(healthLost * (1.0f - 0.25f * fatigueTerm)); + cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), osg::Vec3f(), true); + } + + const float acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics); + if (healthLost > (acrobaticsSkill * fatigueTerm)) + { + if (!godmode) + cls.getCreatureStats(mPtr).setKnockedDown(true); + } + else + { + // report acrobatics progression + if (isPlayer) + cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); + } + } + + if (mPtr.getClass().isNpc()) + playLandingSound = true; + } + + if (mAnimation->isPlaying(mCurrentJump)) + jumpstate = JumpState_Landing; vec.x() *= scale; vec.y() *= scale; @@ -2126,7 +2124,7 @@ void CharacterController::update(float duration) // It seems only bipedal actors use turning animations. // Also do not use turning animations in the first-person view and when sneaking. - if (!sneak && jumpstate == JumpState_None && !isFirstPersonPlayer && mPtr.getClass().isBipedal(mPtr)) + if (!sneak && !isFirstPersonPlayer && mPtr.getClass().isBipedal(mPtr)) { if(effectiveRotation > rotationThreshold) movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight; From 510d1d76d79df039fd031fb6d7480e0ce6778229 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Sun, 24 Jul 2022 17:43:02 +0300 Subject: [PATCH 2/2] Fix applying of falling damage --- apps/openmw/mwmechanics/character.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 4d9905c113..e95ac9b560 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1792,6 +1792,7 @@ void CharacterController::updateAnimQueue() void CharacterController::update(float duration) { MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); const MWWorld::Class &cls = mPtr.getClass(); osg::Vec3f movement(0.f, 0.f, 0.f); float speed = 0.f; @@ -2063,8 +2064,13 @@ void CharacterController::update(float duration) // inflict fall damages if (!godmode) { - float realHealthLost = static_cast(healthLost * (1.0f - 0.25f * fatigueTerm)); - cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), osg::Vec3f(), true); + DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); + float realHealthLost = healthLost * (1.0f - 0.25f * fatigueTerm); + health.setCurrent(health.getCurrent() - realHealthLost); + cls.getCreatureStats(mPtr).setHealth(health); + sndMgr->playSound3D(mPtr, "Health Damage", 1.0f, 1.0f); + if (isPlayer) + MWBase::Environment::get().getWindowManager()->activateHitOverlay(); } const float acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics); @@ -2136,7 +2142,6 @@ void CharacterController::update(float duration) if (playLandingSound) { - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); std::string sound; osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3()); if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr))