From 236ec3409fc02a187830c2f4ae9b1cd664d9b991 Mon Sep 17 00:00:00 2001 From: Glorf Date: Wed, 1 May 2013 12:21:59 +0200 Subject: [PATCH] Finished acrobatics --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwmechanics/character.cpp | 64 ++++++++++++++++----------- apps/openmw/mwmechanics/character.hpp | 3 +- apps/openmw/mwworld/worldimp.cpp | 7 +++ apps/openmw/mwworld/worldimp.hpp | 1 + libs/openengine/bullet/physic.cpp | 2 +- 6 files changed, 50 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index a3b9d2cf2b..0cf71ed8eb 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -314,6 +314,7 @@ namespace MWBase virtual bool isSwimming(const MWWorld::Ptr &object) const = 0; virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const = 0; virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0; + virtual bool isGravity(const MWWorld::Ptr &ptr) const = 0; virtual void togglePOV() = 0; virtual void togglePreviewMode(bool enable) = 0; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 1b8ed08686..a24d7daebc 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -33,6 +33,7 @@ #include "../mwmechanics/stat.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" namespace MWMechanics { @@ -107,7 +108,7 @@ static void getStateInfo(CharacterState state, std::string *group) CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop) : mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false), - mSecondsOfRunning(0), mSecondsOfSwimming(0), mHighestPosition(0) + mSecondsOfRunning(0), mSecondsOfSwimming(0), mFallDistance(0), mLastHeight(0) { if(!mAnimation) return; @@ -149,6 +150,7 @@ void CharacterController::update(float duration, Movement &movement) const MWWorld::Class &cls = MWWorld::Class::get(mPtr); bool onground = world->isOnGround(mPtr); + bool gravity = world->isGravity(mPtr); bool inwater = world->isSwimming(mPtr); bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); @@ -156,9 +158,36 @@ void CharacterController::update(float duration, Movement &movement) const Ogre::Vector3 &rot = cls.getRotationVector(mPtr); speed = cls.getSpeed(mPtr); - //To calculate how much player will fall down - if(movement.mPosition[2] > mHighestPosition) - mHighestPosition = movement.mPosition[2]; + //player is falling down + if(!onground && gravity && mLastHeight>mPtr.getRefData().getPosition().pos[2]) + mFallDistance+=(mLastHeight-mPtr.getRefData().getPosition().pos[2]); + + //player just finished falling + if(onground && gravity && mFallDistance>0) + { + float healthLost = cls.getFallDamage(mPtr, mFallDistance); + + if(healthLost>0.0f) + { + DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); + int current = health.getCurrent(); + float realHealthLost = healthLost * (1.0f - (0.25 * 1.25f/*fatigueTerm*/)); + health.setModified (health.getModified()-static_cast(realHealthLost), 0); + health.setCurrent (current-static_cast(realHealthLost)); + cls.getCreatureStats(mPtr).setHealth (health); + MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); + std::cout< 0 && mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) @@ -184,7 +213,7 @@ void CharacterController::update(float duration, Movement &movement) } // FIXME: X/Y movement should be disallowed except for the initial thrust (which would be carried by "physics" until landing). - if(onground && vec.z > 0.0f) + if(onground && gravity && vec.z > 0.0f) { //Advance acrobatics on jump, decrease fatigue if(getState()!=CharState_Jump) @@ -197,8 +226,8 @@ void CharacterController::update(float duration, Movement &movement) const float fatigueJumpMult = MWBase::Environment::get().getWorld()->getStore().get().find ("fFatigueJumpMult")->getFloat(); DynamicStat fatigue = cls.getCreatureStats(mPtr).getDynamic(2); int current = fatigue.getCurrent(); - fatigue.setModified(fatigue.getModified()-(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult)), 0); - fatigue.setCurrent(current-(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult))); + fatigue.setModified(fatigue.getModified()-static_cast(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult)), 0); + fatigue.setCurrent(current-static_cast(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult))); cls.getCreatureStats(mPtr).setDynamic (2, fatigue); } @@ -216,25 +245,6 @@ void CharacterController::update(float duration, Movement &movement) } } - if(vec.z<=0.0f && getState()==CharState_Jump) - { - float healthLost = cls.getFallDamage(mPtr, mHighestPosition); - - if(healthLost>0.0f) - { - DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); - int fatigue = MWWorld::Class::get (mPtr).getCreatureStats (mPtr).getFatigue().getBase(); - int current = health.getCurrent(); - health.setModified (health.getModified()-(healthLost * (1 - (0.25 * fatigue))), 0); - health.setCurrent (current-(healthLost * (1 - (0.25 * fatigue)))); - cls.getCreatureStats(mPtr).setHealth (health); - MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); - } - - setState(CharState_Idle, true); - mHighestPosition=0; - } - if(std::abs(vec.x/2.0f) > std::abs(vec.y) && speed > 0.0f) { if(vec.x > 0.0f) @@ -299,6 +309,8 @@ void CharacterController::update(float duration, Movement &movement) movement.mPosition[2] += moved.z; } mSkipAnim = false; + + mLastHeight = mPtr.getRefData().getPosition().pos[2]; } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 460141880c..ffe4077310 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -83,7 +83,8 @@ class CharacterController float mSecondsOfSwimming; float mSecondsOfRunning; - float mHighestPosition; + float mFallDistance; + float mLastHeight; bool mMovingAnim; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a903369eec..6b8a225bba 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1492,6 +1492,13 @@ namespace MWWorld return physactor && physactor->getOnGround(); } + bool World::isGravity(const MWWorld::Ptr &ptr) const + { + RefData &refdata = ptr.getRefData(); + const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle()); + return physactor && physactor->getCollisionMode(); + } + bool World::vanityRotateCamera(float * rot) { return mRendering->vanityRotateCamera(rot); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index f61f67062f..5932b54781 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -346,6 +346,7 @@ namespace MWWorld virtual bool isSwimming(const MWWorld::Ptr &object) const; virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const; virtual bool isOnGround(const MWWorld::Ptr &ptr) const; + virtual bool isGravity(const MWWorld::Ptr &ptr) const; virtual void togglePOV() { mRendering->togglePOV(); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index dbb42a6456..9c1d3a5302 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -143,7 +143,7 @@ namespace Physic bool PhysicActor::getOnGround() const { - return collisionMode && onGround; + return onGround; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////