diff --git a/CHANGELOG.md b/CHANGELOG.md index bf1f80705..650e29788 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,7 @@ Bug #4984: "Friendly hits" feature should be used only for player's followers Bug #4989: Object dimension-dependent VFX scaling behavior is inconsistent Bug #4990: Dead bodies prevent you from hitting + Bug #4991: Jumping occasionally takes too much fatigue Bug #4999: Drop instruction behaves differently from vanilla Bug #5001: Possible data race in the Animation::setAlpha() Bug #5004: Werewolves shield their eyes during storm diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 00b3c0c67..7f047da5c 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2099,28 +2099,6 @@ void CharacterController::update(float duration, bool animationOnly) lat.normalize(); vec = osg::Vec3f(lat.x(), lat.y(), 1.0f) * z * 0.707f; } - - // advance acrobatics - // also set jumping flag to allow GetPCJumping works - if (isPlayer) - { - cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); - MWBase::Environment::get().getWorld()->getPlayer().setJumping(true); - } - - // decrease fatigue - const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat(); - const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat(); - float normalizedEncumbrance = mPtr.getClass().getNormalizedEncumbrance(mPtr); - if (normalizedEncumbrance > 1) - normalizedEncumbrance = 1; - const float fatigueDecrease = fatigueJumpBase + normalizedEncumbrance * fatigueJumpMult; - - if (!godmode) - { - fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); - cls.getCreatureStats(mPtr).setFatigue(fatigue); - } } } else if(mJumpState == JumpState_InAir && !inwater && !flying && solid) @@ -2333,7 +2311,9 @@ void CharacterController::update(float duration, bool animationOnly) movement = vec; cls.getMovementSettings(mPtr).mPosition[0] = cls.getMovementSettings(mPtr).mPosition[1] = 0; - // Can't reset jump state (mPosition[2]) here; we don't know for sure whether the PhysicSystem will actually handle it in this frame + if (movement.z() == 0.f) + cls.getMovementSettings(mPtr).mPosition[2] = 0; + // Can't reset jump state (mPosition[2]) here in full; we don't know for sure whether the PhysicSystem will actually handle it in this frame // due to the fixed minimum timestep used for the physics update. It will be reset in PhysicSystem::move once the jump is handled. if (!mSkipAnim) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 32d1d5ca8..31325cf21 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -34,6 +34,7 @@ #include "../mwworld/esmstore.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/player.hpp" #include "../mwrender/bulletdebugdraw.hpp" @@ -326,7 +327,30 @@ namespace MWPhysics if (movement.z() > 0 && ptr.getClass().getCreatureStats(ptr).isDead() && position.z() < swimlevel) velocity = osg::Vec3f(0,0,1) * 25; - ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0; + if (ptr.getClass().getMovementSettings(ptr).mPosition[2]) + { + const bool isPlayer = (ptr == MWMechanics::getPlayer()); + // Advance acrobatics and set flag for GetPCJumping + if (isPlayer) + { + ptr.getClass().skillUsageSucceeded(ptr, ESM::Skill::Acrobatics, 0); + MWBase::Environment::get().getWorld()->getPlayer().setJumping(true); + } + + // Decrease fatigue + if (!isPlayer || !MWBase::Environment::get().getWorld()->getGodModeState()) + { + const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const float fFatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat(); + const float fFatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat(); + const float normalizedEncumbrance = std::min(1.f, ptr.getClass().getNormalizedEncumbrance(ptr)); + const float fatigueDecrease = fFatigueJumpBase + normalizedEncumbrance * fFatigueJumpMult; + MWMechanics::DynamicStat fatigue = ptr.getClass().getCreatureStats(ptr).getFatigue(); + fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); + ptr.getClass().getCreatureStats(ptr).setFatigue(fatigue); + } + ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0; + } // Now that we have the effective movement vector, apply wind forces to it if (MWBase::Environment::get().getWorld()->isInStorm())