Modify the way swimming is handled:

- compute the swimming state instead of storing it, it changes as part of the simulation and was not updated, so it was wrong anyway.
- store the swim level in ActorFrameData, it is constant per Actor so no need to compute it inside the simulation
pull/3097/head
fredzio 4 years ago
parent 6e51a9a512
commit b04c958410

@ -140,8 +140,7 @@ namespace MWPhysics
osg::Vec3f halfExtents = physicActor->getHalfExtents();
actor.mPosition.z() += halfExtents.z(); // vanilla-accurate
static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fSwimHeightScale")->mValue.getFloat();
float swimlevel = actor.mWaterlevel + halfExtents.z() - (physicActor->getRenderingHalfExtents().z() * 2 * fSwimHeightScale);
float swimlevel = actor.mSwimLevel + halfExtents.z();
ActorTracer tracer;

@ -49,13 +49,18 @@ namespace
bool mCanBeSharedLock;
};
bool isUnderWater(const MWPhysics::ActorFrameData& actorData)
{
return actorData.mPosition.z() < actorData.mSwimLevel;
}
void handleFall(MWPhysics::ActorFrameData& actorData, bool simulationPerformed)
{
const float heightDiff = actorData.mPosition.z() - actorData.mOldHeight;
const bool isStillOnGround = (simulationPerformed && actorData.mWasOnGround && actorData.mIsOnGround);
if (isStillOnGround || actorData.mFlying || actorData.mSwimming || actorData.mSlowFall < 1)
if (isStillOnGround || actorData.mFlying || isUnderWater(actorData) || actorData.mSlowFall < 1)
actorData.mNeedLand = true;
else if (heightDiff < 0)
actorData.mFallHeight += heightDiff;
@ -67,7 +72,7 @@ namespace
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
if (actorData.mNeedLand)
stats.land(ptr == MWMechanics::getPlayer() && (actorData.mFlying || actorData.mSwimming));
stats.land(ptr == MWMechanics::getPlayer() && (actorData.mFlying || isUnderWater(actorData)));
else if (actorData.mFallHeight < 0)
stats.addToFallHeight(-actorData.mFallHeight);
}

@ -1007,10 +1007,11 @@ namespace MWPhysics
const MWBase::World *world = MWBase::Environment::get().getWorld();
const auto ptr = actor->getPtr();
mFlying = world->isFlying(ptr);
mSwimming = world->isSwimming(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);
static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fSwimHeightScale")->mValue.getFloat();
mSwimLevel = mWaterlevel - (actor->getRenderingHalfExtents().z() * 2 * fSwimHeightScale);
}
void ActorFrameData::updatePosition(btCollisionWorld* world)

@ -84,7 +84,6 @@ namespace MWPhysics
Actor* mActorRaw;
MWWorld::Ptr mStandingOn;
bool mFlying;
bool mSwimming;
bool mWasOnGround;
bool mIsOnGround;
bool mIsOnSlope;
@ -94,6 +93,7 @@ namespace MWPhysics
bool mWalkingOnWater;
bool mSkipCollisionDetection;
float mWaterlevel;
float mSwimLevel;
float mSlowFall;
float mOldHeight;
float mFallHeight;

Loading…
Cancel
Save