mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:53:50 +00:00
Fix jump velocity mechanics (Fixes #1708)
This commit is contained in:
parent
b6a89c7845
commit
269c200c8f
2 changed files with 24 additions and 34 deletions
|
@ -1277,15 +1277,7 @@ void CharacterController::update(float duration)
|
||||||
|
|
||||||
//Ogre::Vector3 vec = cls.getMovementVector(mPtr);
|
//Ogre::Vector3 vec = cls.getMovementVector(mPtr);
|
||||||
Ogre::Vector3 vec(cls.getMovementSettings(mPtr).mPosition);
|
Ogre::Vector3 vec(cls.getMovementSettings(mPtr).mPosition);
|
||||||
if(vec.z > 0.0f) // to avoid slow-down when jumping
|
vec.normalise();
|
||||||
{
|
|
||||||
Ogre::Vector2 vecXY = Ogre::Vector2(vec.x, vec.y);
|
|
||||||
vecXY.normalise();
|
|
||||||
vec.x = vecXY.x;
|
|
||||||
vec.y = vecXY.y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
vec.normalise();
|
|
||||||
|
|
||||||
if(mHitState != CharState_None && mJumpState == JumpState_None)
|
if(mHitState != CharState_None && mJumpState == JumpState_None)
|
||||||
vec = Ogre::Vector3(0.0f);
|
vec = Ogre::Vector3(0.0f);
|
||||||
|
@ -1383,28 +1375,24 @@ void CharacterController::update(float duration)
|
||||||
mJumpState = JumpState_Falling;
|
mJumpState = JumpState_Falling;
|
||||||
|
|
||||||
// This is a guess. All that seems to be known is that "While the player is in the
|
// This is a guess. All that seems to be known is that "While the player is in the
|
||||||
// air, fJumpMoveBase and fJumpMoveMult governs air control." Assuming Acrobatics
|
// air, fJumpMoveBase and fJumpMoveMult governs air control". What does fJumpMoveMult do?
|
||||||
// plays a role, this makes the most sense.
|
static const float fJumpMoveBase = gmst.find("fJumpMoveBase")->getFloat();
|
||||||
float mult = 0.0f;
|
|
||||||
if(cls.isNpc())
|
|
||||||
{
|
|
||||||
const NpcStats &stats = cls.getNpcStats(mPtr);
|
|
||||||
static const float fJumpMoveBase = gmst.find("fJumpMoveBase")->getFloat();
|
|
||||||
static const float fJumpMoveMult = gmst.find("fJumpMoveMult")->getFloat();
|
|
||||||
|
|
||||||
mult = fJumpMoveBase +
|
vec.x *= fJumpMoveBase;
|
||||||
(stats.getSkill(ESM::Skill::Acrobatics).getModified()/100.0f *
|
vec.y *= fJumpMoveBase;
|
||||||
fJumpMoveMult);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec.x *= mult;
|
|
||||||
vec.y *= mult;
|
|
||||||
vec.z = 0.0f;
|
vec.z = 0.0f;
|
||||||
}
|
}
|
||||||
else if(vec.z > 0.0f && mJumpState == JumpState_None)
|
else if(vec.z > 0.0f && mJumpState == JumpState_None)
|
||||||
{
|
{
|
||||||
// Started a jump.
|
// Started a jump.
|
||||||
vec.z = cls.getJump(mPtr);
|
float z = cls.getJump(mPtr);
|
||||||
|
if(vec.x == 0 && vec.y == 0)
|
||||||
|
vec = Ogre::Vector3(0.0f, 0.0f, z);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Ogre::Vector3 lat = Ogre::Vector3(vec.x, vec.y, 0.0f).normalisedCopy();
|
||||||
|
vec = Ogre::Vector3(lat.x, lat.y, 1.0f) * z * 0.707f;
|
||||||
|
}
|
||||||
|
|
||||||
// advance acrobatics
|
// advance acrobatics
|
||||||
if (mPtr.getRefData().getHandle() == "player")
|
if (mPtr.getRefData().getHandle() == "player")
|
||||||
|
|
|
@ -299,18 +299,20 @@ namespace MWWorld
|
||||||
// not in water nor can fly, so need to deal with gravity
|
// not in water nor can fly, so need to deal with gravity
|
||||||
if(!physicActor->getOnGround()) // if current OnGround status is false, must be falling or jumping
|
if(!physicActor->getOnGround()) // if current OnGround status is false, must be falling or jumping
|
||||||
{
|
{
|
||||||
// If falling, add part of the incoming velocity with the current inertia
|
// If falling or jumping up, add part of the incoming velocity with the current inertia,
|
||||||
// TODO: but we could be jumping up?
|
// but don't allow increasing inertia beyond actor's speed (except on the initial jump impulse)
|
||||||
velocity = velocity * time + physicActor->getInertialForce();
|
|
||||||
|
|
||||||
// avoid getting infinite inertia in air
|
|
||||||
float actorSpeed = ptr.getClass().getSpeed(ptr);
|
float actorSpeed = ptr.getClass().getSpeed(ptr);
|
||||||
float speedXY = Ogre::Vector2(velocity.x, velocity.y).length();
|
float cap = std::max(actorSpeed, Ogre::Vector2(physicActor->getInertialForce().x, physicActor->getInertialForce().y).length());
|
||||||
if (speedXY > actorSpeed)
|
Ogre::Vector3 newVelocity = velocity + physicActor->getInertialForce();
|
||||||
|
if (Ogre::Vector2(newVelocity.x, newVelocity.y).squaredLength() > cap*cap)
|
||||||
{
|
{
|
||||||
velocity.x *= actorSpeed / speedXY;
|
velocity = newVelocity;
|
||||||
velocity.y *= actorSpeed / speedXY;
|
float speedXY = Ogre::Vector2(velocity.x, velocity.y).length();
|
||||||
|
velocity.x *= cap / speedXY;
|
||||||
|
velocity.y *= cap / speedXY;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
velocity = newVelocity;
|
||||||
}
|
}
|
||||||
inertia = velocity; // NOTE: velocity is for z axis only in this code block
|
inertia = velocity; // NOTE: velocity is for z axis only in this code block
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue