1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-13 12:40:04 +00:00

Better calculate jump velocity

The fatigue term isn't currently used correctly
This commit is contained in:
Chris Robinson 2013-02-24 03:30:33 -08:00
parent 90cb9ee0ac
commit 89d4c245e9
5 changed files with 76 additions and 5 deletions

View File

@ -71,6 +71,11 @@ namespace MWClass
fMaxFlySpeed = gmst.find("fMaxFlySpeed");
fSwimRunBase = gmst.find("fSwimRunBase");
fSwimRunAthleticsMult = gmst.find("fSwimRunAthleticsMult");
fJumpEncumbranceBase = gmst.find("fJumpEncumbranceBase");
fJumpEncumbranceMultiplier = gmst.find("fJumpEncumbranceMultiplier");
fJumpAcrobaticsBase = gmst.find("fJumpAcrobaticsBase");
fJumpAcroMultiplier = gmst.find("fJumpAcroMultiplier");
fJumpRunMultiplier = gmst.find("fJumpRunMultiplier");
// Added in Tribunal/Bloodmoon, may not exist
fWereWolfRunMult = gmst.search("fWereWolfRunMult");
@ -371,6 +376,37 @@ namespace MWClass
return moveSpeed;
}
float Npc::getJump(const MWWorld::Ptr &ptr) const
{
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
const MWMechanics::MagicEffects &mageffects = npcdata->mCreatureStats.getMagicEffects();
const float encumbranceTerm = fJumpEncumbranceBase->getFloat() +
fJumpEncumbranceMultiplier->getFloat() *
(Npc::getEncumbrance(ptr)/Npc::getCapacity(ptr));
float a = npcdata->mNpcStats.getSkill(ESM::Skill::Acrobatics).getModified();
float b = 0.0f;
if(a > 50.0f)
{
b = a - 50.0f;
a = 50.0f;
}
float x = fJumpAcrobaticsBase->getFloat() +
std::pow(a / 15.0f, fJumpAcroMultiplier->getFloat());
x += 3 * b * fJumpAcroMultiplier->getFloat();
x += mageffects.get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude * 64;
x *= encumbranceTerm;
if(Npc::getStance(ptr, Run, false))
x *= fJumpRunMultiplier->getFloat();
x *= 1.25f;//fatigueTerm;
x -= -627.2/*gravity constant*/;
x /= 3;
return x;
}
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
{
ensureCustomData (ptr);
@ -496,5 +532,10 @@ namespace MWClass
const ESM::GameSetting *Npc::fMaxFlySpeed;
const ESM::GameSetting *Npc::fSwimRunBase;
const ESM::GameSetting *Npc::fSwimRunAthleticsMult;
const ESM::GameSetting *Npc::fJumpEncumbranceBase;
const ESM::GameSetting *Npc::fJumpEncumbranceMultiplier;
const ESM::GameSetting *Npc::fJumpAcrobaticsBase;
const ESM::GameSetting *Npc::fJumpAcroMultiplier;
const ESM::GameSetting *Npc::fJumpRunMultiplier;
const ESM::GameSetting *Npc::fWereWolfRunMult;
}

View File

@ -27,6 +27,11 @@ namespace MWClass
static const ESM::GameSetting *fMaxFlySpeed;
static const ESM::GameSetting *fSwimRunBase;
static const ESM::GameSetting *fSwimRunAthleticsMult;
static const ESM::GameSetting *fJumpEncumbranceBase;
static const ESM::GameSetting *fJumpEncumbranceMultiplier;
static const ESM::GameSetting *fJumpAcrobaticsBase;
static const ESM::GameSetting *fJumpAcroMultiplier;
static const ESM::GameSetting *fJumpRunMultiplier;
static const ESM::GameSetting *fWereWolfRunMult;
public:
@ -81,6 +86,9 @@ namespace MWClass
virtual float getSpeed (const MWWorld::Ptr& ptr) const;
///< Return movement speed.
virtual float getJump(const MWWorld::Ptr &ptr) const;
///< Return jump velocity (not accounting for movement)
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
///< Return desired movement.

View File

@ -172,11 +172,25 @@ Ogre::Vector3 CharacterController::update(float duration)
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
speed = cls.getSpeed(mPtr);
// This jump is all kinds of wrong. The speed is incorrect, the state should be set to
// Jump, and X/Y movement should be disallowed except for the initial thrust (which would
// be carried by "physics" until landing).
if(onground)
movement.z += vec.z * (500.0f*duration);
/* FIXME: The state should be set to Jump, and 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)
{
float x = cls.getJump(mPtr);
if(vec.x == 0 && vec.y == 0)
movement.z += x*duration;
else
{
/* FIXME: this would be more correct if we were going into a jumping state,
* rather than normal walking/idle states. */
//Ogre::Vector3 lat = Ogre::Vector3(vec.x, vec.y, 0.0f).normalisedCopy();
//movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration;
movement.z += 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)
{

View File

@ -122,6 +122,11 @@ namespace MWWorld
return 0;
}
float Class::getJump (const Ptr& ptr) const
{
return 0;
}
MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
{
throw std::runtime_error ("movement settings not supported by class");

View File

@ -140,6 +140,9 @@ namespace MWWorld
virtual float getSpeed (const Ptr& ptr) const;
///< Return movement speed.
virtual float getJump(const MWWorld::Ptr &ptr) const;
///< Return jump velocity (not accounting for movement)
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
///< Return desired movement.