diff --git a/CHANGELOG.md b/CHANGELOG.md index a01e2c746..36c7e19c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -119,6 +119,7 @@ Bug #4622: Recharging enchanted items with Soul Gems does not award experience if it fails Bug #4628: NPC record reputation, disposition and faction rank should have unsigned char type Bug #4633: Sneaking stance affects speed even if the actor is not able to crouch + Bug #4641: GetPCJumping is handled incorrectly Feature #912: Editor: Add missing icons to UniversalId tables Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 123f7bf59..af8ed706d 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1850,7 +1850,8 @@ void CharacterController::update(float duration) if (isKnockedOut()) mTimeUntilWake -= duration; - bool godmode = mPtr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); + bool isPlayer = mPtr == MWMechanics::getPlayer(); + bool godmode = isPlayer && MWBase::Environment::get().getWorld()->getGodModeState(); if(!cls.isActor()) updateAnimQueue(); @@ -1915,7 +1916,7 @@ void CharacterController::update(float duration) isrunning = isrunning && mHasMovedInXY; // advance athletics - if(mHasMovedInXY && mPtr == getPlayer()) + if(mHasMovedInXY && isPlayer) { if(inwater) { @@ -2011,8 +2012,12 @@ void CharacterController::update(float duration) } // advance acrobatics - if (mPtr == getPlayer()) + // 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(); @@ -2035,7 +2040,7 @@ void CharacterController::update(float duration) jumpstate = JumpState_Landing; vec.z() = 0.0f; - float height = cls.getCreatureStats(mPtr).land(); + float height = cls.getCreatureStats(mPtr).land(isPlayer); float healthLost = getFallDamage(mPtr, height); if (healthLost > 0.0f) @@ -2058,7 +2063,7 @@ void CharacterController::update(float duration) else { // report acrobatics progression - if (mPtr == getPlayer()) + if (isPlayer) cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); } } @@ -2080,7 +2085,7 @@ void CharacterController::update(float duration) // Do not play turning animation for player if rotation speed is very slow. // Actual threshold should take framerate in account. float rotationThreshold = 0; - if (mPtr == getPlayer()) + if (isPlayer) rotationThreshold = 0.015 * 60 * duration; if(std::abs(vec.x()/2.0f) > std::abs(vec.y())) @@ -2109,7 +2114,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. - bool isFirstPlayer = mPtr == getPlayer() && MWBase::Environment::get().getWorld()->isFirstPerson(); + bool isFirstPlayer = isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson(); if (!sneak && !isFirstPlayer && mPtr.getClass().isBipedal(mPtr)) { if(rot.z() > rotationThreshold) @@ -2121,7 +2126,7 @@ void CharacterController::update(float duration) } // Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering - if (mPtr == getPlayer()) + if (isPlayer) { float threshold = mCurrentMovement.find("swim") == std::string::npos ? 0.4f : 0.8f; float complete; diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 2994eac28..7cc6ea784 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -7,6 +7,7 @@ #include #include "../mwworld/esmstore.hpp" +#include "../mwworld/player.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -387,8 +388,11 @@ namespace MWMechanics mFallHeight += height; } - float CreatureStats::land() + float CreatureStats::land(bool isPlayer) { + if (isPlayer) + MWBase::Environment::get().getWorld()->getPlayer().setJumping(false); + float height = mFallHeight; mFallHeight = 0; return height; diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 057a6f602..503ac7d68 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -95,7 +95,7 @@ namespace MWMechanics /// Reset the fall height /// @return total fall height - float land(); + float land(bool isPlayer=false); const AttributeValue & getAttribute(int index) const; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 90668914f..90d25ee3e 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -1394,6 +1394,7 @@ namespace MWPhysics mStandingCollisions.clear(); } + const MWWorld::Ptr player = MWMechanics::getPlayer(); const MWBase::World *world = MWBase::Environment::get().getWorld(); PtrVelocityList::iterator iter = mMovementQueue.begin(); for(;iter != mMovementQueue.end();++iter) @@ -1451,7 +1452,7 @@ namespace MWPhysics MWMechanics::CreatureStats& stats = iter->first.getClass().getCreatureStats(iter->first); if ((wasOnGround && physicActor->getOnGround()) || flying || world->isSwimming(iter->first) || slowFall < 1) - stats.land(); + stats.land(iter->first == player); else if (heightDiff < 0) stats.addToFallHeight(-heightDiff); diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 8d592f29c..7250e9fcf 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -107,8 +107,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWBase::World* world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayerPtr(); - runtime.push (!world->isOnGround(player) && !world->isFlying(player)); + runtime.push (world->getPlayer().getJumping()); } }; diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index 93705f005..f54edc8cb 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -36,7 +36,7 @@ namespace MWWorld void ActionTeleport::teleport(const Ptr &actor) { MWBase::World* world = MWBase::Environment::get().getWorld(); - actor.getClass().getCreatureStats(actor).land(); + actor.getClass().getCreatureStats(actor).land(actor == world->getPlayerPtr()); if(actor == world->getPlayerPtr()) { world->getPlayer().setTeleported(true); diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 389f59983..49b7dd8bb 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -36,7 +36,8 @@ namespace MWWorld mTeleported(false), mCurrentCrimeId(-1), mPaidCrimeId(-1), - mAttackingOrSpell(false) + mAttackingOrSpell(false), + mJumping(false) { ESM::CellRef cellRef; cellRef.blank(); @@ -255,6 +256,16 @@ namespace MWWorld return mAttackingOrSpell; } + void Player::setJumping(bool jumping) + { + mJumping = jumping; + } + + bool Player::getJumping() const + { + return mJumping; + } + bool Player::isInCombat() { return MWBase::Environment::get().getMechanicsManager()->getActorsFighting(getPlayer()).size() != 0; } @@ -286,6 +297,7 @@ namespace MWWorld mForwardBackward = 0; mTeleported = false; mAttackingOrSpell = false; + mJumping = false; mCurrentCrimeId = -1; mPaidCrimeId = -1; mPreviousItems.clear(); diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index d4a9f6050..4b92fa396 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -56,6 +56,7 @@ namespace MWWorld MWMechanics::AttributeValue mSaveAttributes[ESM::Attribute::Length]; bool mAttackingOrSpell; + bool mJumping; public: @@ -111,6 +112,9 @@ namespace MWWorld void setAttackingOrSpell(bool attackingOrSpell); bool getAttackingOrSpell() const; + void setJumping(bool jumping); + bool getJumping() const; + ///Checks all nearby actors to see if anyone has an aipackage against you bool isInCombat();