mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
Merge remote-tracking branch 'glorf/acrobatics'
This commit is contained in:
commit
089ef7a2a0
@ -314,6 +314,7 @@ namespace MWBase
|
|||||||
virtual bool isSwimming(const MWWorld::Ptr &object) const = 0;
|
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 isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const = 0;
|
||||||
virtual bool isOnGround(const MWWorld::Ptr &ptr) 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 togglePOV() = 0;
|
||||||
virtual void togglePreviewMode(bool enable) = 0;
|
virtual void togglePreviewMode(bool enable) = 0;
|
||||||
|
@ -470,6 +470,34 @@ namespace MWClass
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const
|
||||||
|
{
|
||||||
|
const float fallDistanceMin = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fFallDamageDistanceMin")->getFloat();
|
||||||
|
|
||||||
|
if(fallHeight>=fallDistanceMin)
|
||||||
|
{
|
||||||
|
const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill (ESM::Skill::Acrobatics).getModified();
|
||||||
|
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
|
||||||
|
const float jumpSpellBonus = npcdata->mCreatureStats.getMagicEffects().get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude;
|
||||||
|
const float fallAcroBase = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fFallAcroBase")->getFloat();
|
||||||
|
const float fallAcroMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fFallAcroMult")->getFloat();
|
||||||
|
const float fallDistanceBase = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fFallDistanceBase")->getFloat();
|
||||||
|
const float fallDistanceMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fFallDistanceMult")->getFloat();
|
||||||
|
|
||||||
|
float x = fallHeight - fallDistanceMin;
|
||||||
|
x -= (1.5 * acrobaticsSkill) + jumpSpellBonus;
|
||||||
|
x = std::max(0.0f, x);
|
||||||
|
|
||||||
|
float a = fallAcroBase + (fallAcroMult * (100 - acrobaticsSkill));
|
||||||
|
x = fallDistanceBase + (fallDistanceMult * x);
|
||||||
|
x *= a;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
|
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
@ -91,6 +91,9 @@ namespace MWClass
|
|||||||
virtual float getJump(const MWWorld::Ptr &ptr) const;
|
virtual float getJump(const MWWorld::Ptr &ptr) const;
|
||||||
///< Return jump velocity (not accounting for movement)
|
///< Return jump velocity (not accounting for movement)
|
||||||
|
|
||||||
|
virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const;
|
||||||
|
///< Return amount of health points lost when falling
|
||||||
|
|
||||||
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return desired movement.
|
///< Return desired movement.
|
||||||
|
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/player.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/stat.hpp"
|
||||||
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
@ -104,7 +107,8 @@ static void getStateInfo(CharacterState state, std::string *group)
|
|||||||
|
|
||||||
|
|
||||||
CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop)
|
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)
|
: mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false),
|
||||||
|
mSecondsOfRunning(0), mSecondsOfSwimming(0), mFallDistance(0), mLastHeight(0)
|
||||||
{
|
{
|
||||||
if(!mAnimation)
|
if(!mAnimation)
|
||||||
return;
|
return;
|
||||||
@ -146,6 +150,7 @@ void CharacterController::update(float duration, Movement &movement)
|
|||||||
const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
|
const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
|
||||||
|
|
||||||
bool onground = world->isOnGround(mPtr);
|
bool onground = world->isOnGround(mPtr);
|
||||||
|
bool gravity = world->isGravity(mPtr);
|
||||||
bool inwater = world->isSwimming(mPtr);
|
bool inwater = world->isSwimming(mPtr);
|
||||||
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
|
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
|
||||||
bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak);
|
bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak);
|
||||||
@ -153,6 +158,36 @@ void CharacterController::update(float duration, Movement &movement)
|
|||||||
const Ogre::Vector3 &rot = cls.getRotationVector(mPtr);
|
const Ogre::Vector3 &rot = cls.getRotationVector(mPtr);
|
||||||
speed = cls.getSpeed(mPtr);
|
speed = cls.getSpeed(mPtr);
|
||||||
|
|
||||||
|
//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<float> 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<int>(realHealthLost), 0);
|
||||||
|
health.setCurrent (current-static_cast<int>(realHealthLost));
|
||||||
|
cls.getCreatureStats(mPtr).setHealth (health);
|
||||||
|
MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1);
|
||||||
|
|
||||||
|
const float acrobaticsSkill = cls.getNpcStats (mPtr).getSkill (ESM::Skill::Acrobatics).getModified();
|
||||||
|
if(acrobaticsSkill*1.25f/*fatigueTerm*/<healthLost)
|
||||||
|
{
|
||||||
|
//TODO: actor falls over
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(CharState_Idle, true);
|
||||||
|
mFallDistance=0;
|
||||||
|
}
|
||||||
|
|
||||||
// advance athletics
|
// advance athletics
|
||||||
if (vec.squaredLength() > 0 && mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer())
|
if (vec.squaredLength() > 0 && mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer())
|
||||||
{
|
{
|
||||||
@ -176,10 +211,25 @@ void CharacterController::update(float duration, Movement &movement)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except
|
// FIXME: X/Y movement should be disallowed except for the initial thrust (which would be carried by "physics" until landing).
|
||||||
* for the initial thrust (which would be carried by "physics" until landing). */
|
if(onground && gravity && vec.z > 0.0f)
|
||||||
if(onground && vec.z > 0.0f)
|
|
||||||
{
|
{
|
||||||
|
//Advance acrobatics on jump, decrease fatigue
|
||||||
|
if(getState()!=CharState_Jump)
|
||||||
|
{
|
||||||
|
setState(CharState_Jump, true);
|
||||||
|
MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0);
|
||||||
|
|
||||||
|
const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr);
|
||||||
|
const float fatigueJumpBase = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fFatigueJumpBase")->getFloat();
|
||||||
|
const float fatigueJumpMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fFatigueJumpMult")->getFloat();
|
||||||
|
DynamicStat<float> fatigue = cls.getCreatureStats(mPtr).getDynamic(2);
|
||||||
|
int current = fatigue.getCurrent();
|
||||||
|
fatigue.setModified(fatigue.getModified()-static_cast<int>(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult)), 0);
|
||||||
|
fatigue.setCurrent(current-static_cast<int>(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult)));
|
||||||
|
cls.getCreatureStats(mPtr).setDynamic (2, fatigue);
|
||||||
|
}
|
||||||
|
|
||||||
float x = cls.getJump(mPtr);
|
float x = cls.getJump(mPtr);
|
||||||
|
|
||||||
if(vec.x == 0 && vec.y == 0)
|
if(vec.x == 0 && vec.y == 0)
|
||||||
@ -192,8 +242,6 @@ void CharacterController::update(float duration, Movement &movement)
|
|||||||
//movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration;
|
//movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration;
|
||||||
movement.mPosition[2] += x * 0.707f * duration;
|
movement.mPosition[2] += x * 0.707f * duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
//decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(std::abs(vec.x/2.0f) > std::abs(vec.y) && speed > 0.0f)
|
if(std::abs(vec.x/2.0f) > std::abs(vec.y) && speed > 0.0f)
|
||||||
@ -260,6 +308,8 @@ void CharacterController::update(float duration, Movement &movement)
|
|||||||
movement.mPosition[2] += moved.z;
|
movement.mPosition[2] += moved.z;
|
||||||
}
|
}
|
||||||
mSkipAnim = false;
|
mSkipAnim = false;
|
||||||
|
|
||||||
|
mLastHeight = mPtr.getRefData().getPosition().pos[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,6 +83,9 @@ class CharacterController
|
|||||||
float mSecondsOfSwimming;
|
float mSecondsOfSwimming;
|
||||||
float mSecondsOfRunning;
|
float mSecondsOfRunning;
|
||||||
|
|
||||||
|
float mFallDistance;
|
||||||
|
float mLastHeight;
|
||||||
|
|
||||||
bool mMovingAnim;
|
bool mMovingAnim;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -132,6 +132,11 @@ namespace MWWorld
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Class::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
float Class::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
float Class::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
throw std::runtime_error ("class does not support enchanting");
|
throw std::runtime_error ("class does not support enchanting");
|
||||||
|
@ -146,6 +146,9 @@ namespace MWWorld
|
|||||||
virtual float getJump(const MWWorld::Ptr &ptr) const;
|
virtual float getJump(const MWWorld::Ptr &ptr) const;
|
||||||
///< Return jump velocity (not accounting for movement)
|
///< Return jump velocity (not accounting for movement)
|
||||||
|
|
||||||
|
virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const;
|
||||||
|
///< Return amount of health points lost when falling
|
||||||
|
|
||||||
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
|
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
|
||||||
///< Return desired movement.
|
///< Return desired movement.
|
||||||
|
|
||||||
|
@ -1493,6 +1493,13 @@ namespace MWWorld
|
|||||||
return physactor && physactor->getOnGround();
|
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)
|
bool World::vanityRotateCamera(float * rot)
|
||||||
{
|
{
|
||||||
return mRendering->vanityRotateCamera(rot);
|
return mRendering->vanityRotateCamera(rot);
|
||||||
|
@ -346,6 +346,7 @@ namespace MWWorld
|
|||||||
virtual bool isSwimming(const MWWorld::Ptr &object) const;
|
virtual bool isSwimming(const MWWorld::Ptr &object) const;
|
||||||
virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const;
|
virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const;
|
||||||
virtual bool isOnGround(const MWWorld::Ptr &ptr) const;
|
virtual bool isOnGround(const MWWorld::Ptr &ptr) const;
|
||||||
|
virtual bool isGravity(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
virtual void togglePOV() {
|
virtual void togglePOV() {
|
||||||
mRendering->togglePOV();
|
mRendering->togglePOV();
|
||||||
|
@ -143,7 +143,7 @@ namespace Physic
|
|||||||
|
|
||||||
bool PhysicActor::getOnGround() const
|
bool PhysicActor::getOnGround() const
|
||||||
{
|
{
|
||||||
return collisionMode && onGround;
|
return onGround;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user