From 819101144d63435df684ae6cbe08f9411737a799 Mon Sep 17 00:00:00 2001
From: Alexei Kotov <alexdobrohotov@yandex.ru>
Date: Sun, 24 Jul 2022 17:24:17 +0300
Subject: [PATCH] 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<float>(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<float>(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;