diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 92956770e..ef9ac57b9 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -19,8 +19,8 @@ namespace MWPhysics { -Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler) - : mStandingOnPtr(nullptr), mCanWaterWalk(false), mWalkingOnWater(false) +Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler, bool canWaterWalk) + : mStandingOnPtr(nullptr), mCanWaterWalk(canWaterWalk), mWalkingOnWater(false) , mCollisionObject(nullptr), mMeshTranslation(shape->mCollisionBox.center), mHalfExtents(shape->mCollisionBox.extents) , mVelocity(0,0,0), mStuckFrames(0), mLastStuckPosition{0, 0, 0} , mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false) diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index c6c8beb75..99f625394 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -27,7 +27,7 @@ namespace MWPhysics class Actor final : public PtrHolder { public: - Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler); + Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler, bool canWaterWalk); ~Actor() override; /** diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 0e616e741..43653c9e5 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -681,7 +681,15 @@ namespace MWPhysics if (!shape) return; - auto actor = std::make_shared(ptr, shape, mTaskScheduler.get()); + // check if Actor should spawn above water + const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); + const bool canWaterWalk = effects.get(ESM::MagicEffect::WaterWalking).getMagnitude() > 0; + + auto actor = std::make_shared(ptr, shape, mTaskScheduler.get(), canWaterWalk); + + // check if Actor is on the ground or in the air + traceDown(ptr, ptr.getRefData().getPosition().asVec3(), 10.f); + mActors.emplace(ptr, std::move(actor)); } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 85b312dd5..5467cc747 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -446,12 +446,6 @@ namespace MWWorld const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - // By default the player is grounded, with the scene fully loaded, we validate and correct this. - if (player.mCell == cell) // Only run once, during initial cell load. - { - mPhysics->traceDown(player, player.getRefData().getPosition().asVec3(), 10.f); - } - navigator->update(player.getRefData().getPosition().asVec3()); if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx))