From 8bcfac1ea3779ad3ac18b2dfedecb291f5c98418 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 17 May 2015 16:25:13 +0200 Subject: [PATCH] Fix adjustPosition not always working correctly (Fixes #2563) moveObject was returning an incorrect Ptr for cell movements. --- apps/openmw/mwbase/world.hpp | 4 +- .../mwscript/transformationextensions.cpp | 7 ++-- apps/openmw/mwworld/worldimp.cpp | 37 +++++++++---------- apps/openmw/mwworld/worldimp.hpp | 4 +- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 9e6c6d9bf..c110e94d6 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -286,8 +286,8 @@ namespace MWBase virtual MWWorld::Ptr moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; ///< @return an updated Ptr in case the Ptr's cell changes - virtual void - moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z) = 0; + virtual MWWorld::Ptr moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z) = 0; + ///< @return an updated Ptr virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0; diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index f87983ce8..414ef7fb7 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -370,18 +370,17 @@ namespace MWScript // another morrowind oddity: player will be moved to the exterior cell at this location, // non-player actors will move within the cell they are in. - MWWorld::Ptr updated; if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) { MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(cx,cy); MWBase::Environment::get().getWorld()->moveObject(ptr,cell,x,y,z); - updated = MWWorld::Ptr(ptr.getBase(), cell); + ptr = MWWorld::Ptr(ptr.getBase(), cell); } else { - updated = MWBase::Environment::get().getWorld()->moveObject(ptr, x, y, z); + ptr = MWBase::Environment::get().getWorld()->moveObject(ptr, x, y, z); } - dynamic_cast(runtime.getContext()).updatePtr(updated); + dynamic_cast(runtime.getContext()).updatePtr(ptr); float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees(); float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 0f8110624..bb0402c4e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1108,7 +1108,7 @@ namespace MWWorld } } - void World::moveObject(const Ptr &ptr, CellStore* newCell, float x, float y, float z) + MWWorld::Ptr World::moveObject(const Ptr &ptr, CellStore* newCell, float x, float y, float z) { ESM::Position pos = ptr.getRefData().getPosition(); @@ -1123,6 +1123,7 @@ namespace MWWorld CellStore *currCell = ptr.isInCell() ? ptr.getCell() : NULL; // currCell == NULL should only happen for player, during initial startup bool isPlayer = ptr == mPlayer->getPlayer(); bool haveToMove = isPlayer || (currCell && mWorldScene->isCellActive(*currCell)); + MWWorld::Ptr newPtr = ptr; if (currCell != newCell) { @@ -1140,6 +1141,7 @@ namespace MWWorld mWorldScene->changeToExteriorCell(pos, false); } addContainerScripts (getPlayerPtr(), newCell); + newPtr = getPlayerPtr(); } else { @@ -1147,7 +1149,7 @@ namespace MWWorld bool newCellActive = mWorldScene->isCellActive(*newCell); if (!currCellActive && newCellActive) { - MWWorld::Ptr newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos); + newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos); mWorldScene->addObjectToScene(newPtr); std::string script = newPtr.getClass().getScript(newPtr); @@ -1163,23 +1165,21 @@ namespace MWWorld removeContainerScripts (ptr); haveToMove = false; - MWWorld::Ptr newPtr = ptr.getClass() - .copyToCell(ptr, *newCell); + newPtr = ptr.getClass().copyToCell(ptr, *newCell); newPtr.getRefData().setBaseNode(0); } else if (!currCellActive && !newCellActive) - ptr.getClass().copyToCell(ptr, *newCell); + newPtr = ptr.getClass().copyToCell(ptr, *newCell); else // both cells active { - MWWorld::Ptr copy = - ptr.getClass().copyToCell(ptr, *newCell, pos); + newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos); - mRendering->updateObjectCell(ptr, copy); + mRendering->updateObjectCell(ptr, newPtr); ptr.getRefData().setBaseNode(NULL); - MWBase::Environment::get().getSoundManager()->updatePtr (ptr, copy); + MWBase::Environment::get().getSoundManager()->updatePtr (ptr, newPtr); MWBase::MechanicsManager *mechMgr = MWBase::Environment::get().getMechanicsManager(); - mechMgr->updateCell(ptr, copy); + mechMgr->updateCell(ptr, newPtr); std::string script = ptr.getClass().getScript(ptr); @@ -1187,22 +1187,23 @@ namespace MWWorld { mLocalScripts.remove(ptr); removeContainerScripts (ptr); - mLocalScripts.add(script, copy); - addContainerScripts (copy, newCell); + mLocalScripts.add(script, newPtr); + addContainerScripts (newPtr, newCell); } } ptr.getRefData().setCount(0); } } - if (haveToMove && ptr.getRefData().getBaseNode()) + if (haveToMove && newPtr.getRefData().getBaseNode()) { - mRendering->moveObject(ptr, vec); - mPhysics->moveObject (ptr); + mRendering->moveObject(newPtr, vec); + mPhysics->moveObject (newPtr); } if (isPlayer) { mWorldScene->playerMoved (vec); } + return newPtr; } MWWorld::Ptr World::moveObjectImp(const Ptr& ptr, float x, float y, float z) @@ -1216,11 +1217,7 @@ namespace MWWorld cell = getExterior(cellX, cellY); } - moveObject(ptr, cell, x, y, z); - - MWWorld::Ptr updated = ptr; - updated.mCell = cell; - return updated; + return moveObject(ptr, cell, x, y, z); } MWWorld::Ptr World::moveObject (const Ptr& ptr, float x, float y, float z) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 63d6506de..bf25c20bb 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -348,7 +348,9 @@ namespace MWWorld virtual MWWorld::Ptr moveObject (const Ptr& ptr, float x, float y, float z); ///< @return an updated Ptr in case the Ptr's cell changes - virtual void moveObject (const Ptr& ptr, CellStore* newCell, float x, float y, float z); + + virtual MWWorld::Ptr moveObject (const Ptr& ptr, CellStore* newCell, float x, float y, float z); + ///< @return an updated Ptr virtual void scaleObject (const Ptr& ptr, float scale);