From 51514e44cc137ee362c0e4f2166848fec444a163 Mon Sep 17 00:00:00 2001 From: fredzio Date: Wed, 21 Jul 2021 19:40:22 +0200 Subject: [PATCH] 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. --- apps/openmw/mwphysics/movementsolver.cpp | 3 -- apps/openmw/mwphysics/mtphysics.cpp | 28 ------------- apps/openmw/mwphysics/physicssystem.cpp | 50 ++++++++++++++++++++---- apps/openmw/mwphysics/physicssystem.hpp | 2 - 4 files changed, 42 insertions(+), 41 deletions(-) diff --git a/apps/openmw/mwphysics/movementsolver.cpp b/apps/openmw/mwphysics/movementsolver.cpp index 76f7a8d5a2..4eb1417cdd 100644 --- a/apps/openmw/mwphysics/movementsolver.cpp +++ b/apps/openmw/mwphysics/movementsolver.cpp @@ -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) { diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index eaa1948cba..68a69a5c6d 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -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 &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - 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 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) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 3130f90bd0..7757b3eb65 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -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 &gmst = MWBase::Environment::get().getWorld()->getStore().get(); + 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 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 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::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); } diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 59f4de10ea..e5e1aa0c06 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -88,8 +88,6 @@ namespace MWPhysics bool mWasOnGround; bool mIsOnGround; bool mIsOnSlope; - bool mWantJump; - bool mDidJump; bool mInert; bool mNeedLand; bool mWaterCollision;