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:
parent
1bfaf353be
commit
51514e44cc
4 changed files with 42 additions and 41 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -88,8 +88,6 @@ namespace MWPhysics
|
|||
bool mWasOnGround;
|
||||
bool mIsOnGround;
|
||||
bool mIsOnSlope;
|
||||
bool mWantJump;
|
||||
bool mDidJump;
|
||||
bool mInert;
|
||||
bool mNeedLand;
|
||||
bool mWaterCollision;
|
||||
|
|
Loading…
Reference in a new issue