diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 905034cde5..bf7503e72f 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -123,6 +123,7 @@ void Actor::updatePosition() mSimulationPosition = mWorldPosition; mStandingOnPtr = nullptr; mSkipSimulation = true; + mPositionOffset = osg::Vec3f(); } void Actor::updateWorldPosition() @@ -179,9 +180,9 @@ bool Actor::setPosition(const osg::Vec3f& position) if (mSkipSimulation) return false; bool hasChanged = mPosition != position || mPositionOffset.length() != 0 || mWorldPositionChanged; - mPreviousPosition = mPosition + mPositionOffset; - mPosition = position + mPositionOffset; - mPositionOffset = osg::Vec3f(); + applyOffsetChange(); + mPreviousPosition = mPosition; + mPosition = position; return hasChanged; } @@ -198,6 +199,7 @@ void Actor::applyOffsetChange() mWorldPosition += mPositionOffset; mPosition += mPositionOffset; mPreviousPosition += mPositionOffset; + mSimulationPosition += mPositionOffset; mPositionOffset = osg::Vec3f(); mWorldPositionChanged = true; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index d6a4de71bd..5e0cdbb2b6 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -862,6 +862,19 @@ namespace MWWorld if (reference == getPlayerPtr()) throw std::runtime_error("can not disable player object"); + // A common pattern to teleport NPC in scripts is a sequence of SetPos/Disable/Enable + // Disable/Enable create a new physics actor, and so the SetPos call is lost + // Call moveObject so that the newly created physics actor will have up-to-date position + if (reference.getClass().isActor()) + { + auto* physactor = mPhysics->getActor(reference); + if (physactor) + { + physactor->applyOffsetChange(); + const auto position = physactor->getSimulationPosition(); + moveObject(reference, position.x(), position.y(), position.z(), true); + } + } reference.getRefData().disable(); if (reference.getCellRef().getRefNum().hasContentFile())