diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 50b400c2ac..67bfb4dffe 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 3925edf59f..703d8a191b 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 69a4d8d478..9814af09f5 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -688,7 +688,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 c43ee76d1b..10c0ebe84c 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -486,12 +486,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))