Bug #1013: Rewrote fall height detection

This commit is contained in:
scrawl 2013-12-27 21:21:18 +01:00
parent 02277db685
commit 7265b427fe
5 changed files with 38 additions and 16 deletions

View File

@ -350,7 +350,6 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
, mSkipAnim(false) , mSkipAnim(false)
, mSecondsOfRunning(0) , mSecondsOfRunning(0)
, mSecondsOfSwimming(0) , mSecondsOfSwimming(0)
, mFallHeight(0)
{ {
if(!mAnimation) if(!mAnimation)
return; return;
@ -800,10 +799,7 @@ void CharacterController::update(float duration)
} }
if(sneak || inwater || flying) if(sneak || inwater || flying)
{
vec.z = 0.0f; vec.z = 0.0f;
mFallHeight = mPtr.getRefData().getPosition().pos[2];
}
if(!onground && !flying && !inwater) if(!onground && !flying && !inwater)
{ {
@ -812,11 +808,7 @@ void CharacterController::update(float duration)
if (world->isSlowFalling(mPtr)) if (world->isSlowFalling(mPtr))
{ {
// SlowFalling spell effect is active, do not keep previous fall height // SlowFalling spell effect is active, do not keep previous fall height
mFallHeight = mPtr.getRefData().getPosition().pos[2]; cls.getCreatureStats(mPtr).land();
}
else
{
mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]);
} }
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>(); const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
@ -872,7 +864,8 @@ void CharacterController::update(float duration)
mJumpState = JumpState_Landing; mJumpState = JumpState_Landing;
vec.z = 0.0f; vec.z = 0.0f;
float healthLost = cls.getFallDamage(mPtr, mFallHeight - mPtr.getRefData().getPosition().pos[2]); float height = cls.getCreatureStats(mPtr).land();
float healthLost = cls.getFallDamage(mPtr, height);
if (healthLost > 0.0f) if (healthLost > 0.0f)
{ {
const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm(); const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm();
@ -893,8 +886,6 @@ void CharacterController::update(float duration)
//TODO: actor falls over //TODO: actor falls over
} }
} }
mFallHeight = mPtr.getRefData().getPosition().pos[2];
} }
else else
{ {
@ -933,6 +924,9 @@ void CharacterController::update(float duration)
} }
} }
if (onground || inwater || flying)
cls.getCreatureStats(mPtr).land();
if(movestate != CharState_None) if(movestate != CharState_None)
clearAnimQueue(); clearAnimQueue();

View File

@ -156,9 +156,6 @@ class CharacterController
float mSecondsOfSwimming; float mSecondsOfSwimming;
float mSecondsOfRunning; float mSecondsOfRunning;
// used for acrobatics progress and fall damages
float mFallHeight;
std::string mAttackType; // slash, chop or thrust std::string mAttackType; // slash, chop or thrust
void refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force=false); void refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force=false);

View File

@ -14,7 +14,8 @@ namespace MWMechanics
mTalkedTo (false), mAlarmed (false), mTalkedTo (false), mAlarmed (false),
mAttacked (false), mHostile (false), mAttacked (false), mHostile (false),
mAttackingOrSpell(false), mAttackType(AT_Chop), mAttackingOrSpell(false), mAttackType(AT_Chop),
mIsWerewolf(false) mIsWerewolf(false),
mFallHeight(0)
{ {
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
mAiSettings[i] = 0; mAiSettings[i] = 0;
@ -356,4 +357,16 @@ namespace MWMechanics
{ {
mUsedPowers[power] = MWBase::Environment::get().getWorld()->getTimeStamp(); mUsedPowers[power] = MWBase::Environment::get().getWorld()->getTimeStamp();
} }
void CreatureStats::addToFallHeight(float height)
{
mFallHeight += height;
}
float CreatureStats::land()
{
float height = mFallHeight;
mFallHeight = 0;
return height;
}
} }

View File

@ -36,6 +36,8 @@ namespace MWMechanics
bool mHostile; bool mHostile;
bool mAttackingOrSpell;//for the player, this is true if the left mouse button is pressed, false if not. bool mAttackingOrSpell;//for the player, this is true if the left mouse button is pressed, false if not.
float mFallHeight;
int mAttackType; int mAttackType;
std::string mLastHitObject; // The last object to hit this actor std::string mLastHitObject; // The last object to hit this actor
@ -49,6 +51,12 @@ namespace MWMechanics
public: public:
CreatureStats(); CreatureStats();
void addToFallHeight(float height);
/// Reset the fall height
/// @return total fall height
float land();
bool canUsePower (const std::string& power) const; bool canUsePower (const std::string& power) const;
void usePower (const std::string& power); void usePower (const std::string& power);

View File

@ -18,6 +18,8 @@
#include "../mwbase/world.hpp" // FIXME #include "../mwbase/world.hpp" // FIXME
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include <components/esm/loadgmst.hpp> #include <components/esm/loadgmst.hpp>
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
@ -573,9 +575,17 @@ namespace MWWorld
if(cell->hasWater()) if(cell->hasWater())
waterlevel = cell->mWater; waterlevel = cell->mWater;
float oldHeight = iter->first.getRefData().getPosition().pos[2];
Ogre::Vector3 newpos = MovementSolver::move(iter->first, iter->second, mTimeAccum, Ogre::Vector3 newpos = MovementSolver::move(iter->first, iter->second, mTimeAccum,
world->isFlying(iter->first), world->isFlying(iter->first),
waterlevel, mEngine); waterlevel, mEngine);
float heightDiff = newpos.z - oldHeight;
if (heightDiff < 0)
iter->first.getClass().getCreatureStats(iter->first).addToFallHeight(-heightDiff);
mMovementResults.push_back(std::make_pair(iter->first, newpos)); mMovementResults.push_back(std::make_pair(iter->first, newpos));
} }