1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-07-10 08:11:35 +00:00

Handle jump as part of the simulation preparation (inside of

PhysicsSystem) instead of inside the simulaiton.
For mechanics, we don't care how the jump is handled, just that it will be.
This commit is contained in:
fredzio 2021-07-21 19:40:22 +02:00
parent 1bfaf353be
commit 51514e44cc
4 changed files with 42 additions and 41 deletions

View file

@ -168,9 +168,6 @@ namespace MWPhysics
if (actor.mMovement.z() > 0 && actor.mInert && actor.mPosition.z() < swimlevel)
velocity = osg::Vec3f(0,0,1) * 25;
if (actor.mWantJump)
actor.mDidJump = true;
// Now that we have the effective movement vector, apply wind forces to it
if (worldData.mIsInStorm)
{

View file

@ -11,7 +11,6 @@
#include "../mwmechanics/movement.hpp"
#include "../mwrender/bulletdebugdraw.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "actor.hpp"
#include "contacttestwrapper.h"
@ -62,36 +61,9 @@ namespace
actorData.mFallHeight += heightDiff;
}
void handleJump(const MWWorld::Ptr &ptr)
{
const bool isPlayer = (ptr == MWMechanics::getPlayer());
// Advance acrobatics and set flag for GetPCJumping
if (isPlayer)
{
ptr.getClass().skillUsageSucceeded(ptr, ESM::Skill::Acrobatics, 0);
MWBase::Environment::get().getWorld()->getPlayer().setJumping(true);
}
// Decrease fatigue
if (!isPlayer || !MWBase::Environment::get().getWorld()->getGodModeState())
{
const MWWorld::Store<ESM::GameSetting> &gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
const float fFatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat();
const float fFatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat();
const float normalizedEncumbrance = std::min(1.f, ptr.getClass().getNormalizedEncumbrance(ptr));
const float fatigueDecrease = fFatigueJumpBase + normalizedEncumbrance * fFatigueJumpMult;
MWMechanics::DynamicStat<float> fatigue = ptr.getClass().getCreatureStats(ptr).getFatigue();
fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease);
ptr.getClass().getCreatureStats(ptr).setFatigue(fatigue);
}
ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0;
}
void updateMechanics(MWPhysics::ActorFrameData& actorData)
{
auto ptr = actorData.mActorRaw->getPtr();
if (actorData.mDidJump)
handleJump(ptr);
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
if (actorData.mNeedLand)

View file

@ -38,6 +38,7 @@
#include "../mwworld/esmstore.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/player.hpp"
#include "../mwrender/bulletdebugdraw.hpp"
@ -72,6 +73,36 @@ namespace
tracer.doTrace(physicActor->getCollisionObject(), startingPosition, destinationPosition, world);
return (tracer.mFraction >= 1.0f);
}
void handleJump(const MWWorld::Ptr &ptr)
{
if (!ptr.getClass().isActor())
return;
if (ptr.getClass().getMovementSettings(ptr).mPosition[2] == 0)
return;
const bool isPlayer = (ptr == MWMechanics::getPlayer());
// Advance acrobatics and set flag for GetPCJumping
if (isPlayer)
{
ptr.getClass().skillUsageSucceeded(ptr, ESM::Skill::Acrobatics, 0);
MWBase::Environment::get().getWorld()->getPlayer().setJumping(true);
}
// Decrease fatigue
if (!isPlayer || !MWBase::Environment::get().getWorld()->getGodModeState())
{
const MWWorld::Store<ESM::GameSetting> &gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
const float fFatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat();
const float fFatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat();
const float normalizedEncumbrance = std::min(1.f, ptr.getClass().getNormalizedEncumbrance(ptr));
const float fatigueDecrease = fFatigueJumpBase + normalizedEncumbrance * fFatigueJumpMult;
MWMechanics::DynamicStat<float> fatigue = ptr.getClass().getCreatureStats(ptr).getFatigue();
fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease);
ptr.getClass().getCreatureStats(ptr).setFatigue(fatigue);
}
ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0;
}
}
namespace MWPhysics
@ -755,21 +786,22 @@ namespace MWPhysics
std::vector<ActorFrameData> actorsFrameData;
actorsFrameData.reserve(mActors.size());
const MWBase::World *world = MWBase::Environment::get().getWorld();
for (const auto& [ptr, physicActor] : mActors)
for (const auto& [actor, physicActor] : mActors)
{
if (!ptr.getClass().isMobile(physicActor->getPtr()))
auto ptr = physicActor->getPtr();
if (!actor.getClass().isMobile(ptr))
continue;
float waterlevel = -std::numeric_limits<float>::max();
const MWWorld::CellStore *cell = ptr.getCell();
const MWWorld::CellStore *cell = actor.getCell();
if(cell->getCell()->hasWater())
waterlevel = cell->getWaterLevel();
const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(physicActor->getPtr()).getMagicEffects();
const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(ptr).getMagicEffects();
bool waterCollision = false;
if (cell->getCell()->hasWater() && effects.get(ESM::MagicEffect::WaterWalking).getMagnitude())
{
if (physicActor->getCollisionMode() || !world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3())))
if (physicActor->getCollisionMode() || !world->isUnderwater(actor.getCell(), actor.getRefData().getPosition().asVec3()))
waterCollision = true;
}
@ -784,6 +816,10 @@ namespace MWPhysics
standingOn = physicActor->getStandingOnPtr();
actorsFrameData.emplace_back(physicActor, standingOn, waterCollision, slowFall, waterlevel);
// if the simulation will run, a jump request will be fulfilled. Update mechanics accordingly.
if (willSimulate)
handleJump(ptr);
}
return actorsFrameData;
}
@ -956,7 +992,6 @@ namespace MWPhysics
, mWasOnGround(actor->getOnGround())
, mIsOnGround(actor->getOnGround())
, mIsOnSlope(actor->getOnSlope())
, mDidJump(false)
, mNeedLand(false)
, mWaterCollision(waterCollision)
, mWalkingOnWater(false)
@ -973,8 +1008,7 @@ namespace MWPhysics
const auto ptr = actor->getPtr();
mFlying = world->isFlying(ptr);
mSwimming = world->isSwimming(ptr);
mWantJump = ptr.getClass().getMovementSettings(ptr).mPosition[2] != 0;
auto& stats = ptr.getClass().getCreatureStats(ptr);
const auto& stats = ptr.getClass().getCreatureStats(ptr);
const bool godmode = ptr == world->getPlayerConstPtr() && world->getGodModeState();
mInert = stats.isDead() || (!godmode && stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0);
}

View file

@ -88,8 +88,6 @@ namespace MWPhysics
bool mWasOnGround;
bool mIsOnGround;
bool mIsOnSlope;
bool mWantJump;
bool mDidJump;
bool mInert;
bool mNeedLand;
bool mWaterCollision;