Fix adjustPosition not always working correctly (Fixes #2563)

moveObject was returning an incorrect Ptr for cell movements.
c++11
scrawl 10 years ago
parent 7b207a7954
commit 8bcfac1ea3

@ -286,8 +286,8 @@ namespace MWBase
virtual MWWorld::Ptr moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; 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 ///< @return an updated Ptr in case the Ptr's cell changes
virtual void virtual MWWorld::Ptr moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z) = 0;
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; virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;

@ -370,18 +370,17 @@ namespace MWScript
// another morrowind oddity: player will be moved to the exterior cell at this location, // 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. // non-player actors will move within the cell they are in.
MWWorld::Ptr updated;
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
{ {
MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(cx,cy); MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
MWBase::Environment::get().getWorld()->moveObject(ptr,cell,x,y,z); MWBase::Environment::get().getWorld()->moveObject(ptr,cell,x,y,z);
updated = MWWorld::Ptr(ptr.getBase(), cell); ptr = MWWorld::Ptr(ptr.getBase(), cell);
} }
else else
{ {
updated = MWBase::Environment::get().getWorld()->moveObject(ptr, x, y, z); ptr = MWBase::Environment::get().getWorld()->moveObject(ptr, x, y, z);
} }
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(updated); dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr);
float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees(); float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees();
float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees(); float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees();

@ -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(); 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 CellStore *currCell = ptr.isInCell() ? ptr.getCell() : NULL; // currCell == NULL should only happen for player, during initial startup
bool isPlayer = ptr == mPlayer->getPlayer(); bool isPlayer = ptr == mPlayer->getPlayer();
bool haveToMove = isPlayer || (currCell && mWorldScene->isCellActive(*currCell)); bool haveToMove = isPlayer || (currCell && mWorldScene->isCellActive(*currCell));
MWWorld::Ptr newPtr = ptr;
if (currCell != newCell) if (currCell != newCell)
{ {
@ -1140,6 +1141,7 @@ namespace MWWorld
mWorldScene->changeToExteriorCell(pos, false); mWorldScene->changeToExteriorCell(pos, false);
} }
addContainerScripts (getPlayerPtr(), newCell); addContainerScripts (getPlayerPtr(), newCell);
newPtr = getPlayerPtr();
} }
else else
{ {
@ -1147,7 +1149,7 @@ namespace MWWorld
bool newCellActive = mWorldScene->isCellActive(*newCell); bool newCellActive = mWorldScene->isCellActive(*newCell);
if (!currCellActive && newCellActive) if (!currCellActive && newCellActive)
{ {
MWWorld::Ptr newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos); newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos);
mWorldScene->addObjectToScene(newPtr); mWorldScene->addObjectToScene(newPtr);
std::string script = newPtr.getClass().getScript(newPtr); std::string script = newPtr.getClass().getScript(newPtr);
@ -1163,23 +1165,21 @@ namespace MWWorld
removeContainerScripts (ptr); removeContainerScripts (ptr);
haveToMove = false; haveToMove = false;
MWWorld::Ptr newPtr = ptr.getClass() newPtr = ptr.getClass().copyToCell(ptr, *newCell);
.copyToCell(ptr, *newCell);
newPtr.getRefData().setBaseNode(0); newPtr.getRefData().setBaseNode(0);
} }
else if (!currCellActive && !newCellActive) else if (!currCellActive && !newCellActive)
ptr.getClass().copyToCell(ptr, *newCell); newPtr = ptr.getClass().copyToCell(ptr, *newCell);
else // both cells active else // both cells active
{ {
MWWorld::Ptr copy = newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos);
ptr.getClass().copyToCell(ptr, *newCell, pos);
mRendering->updateObjectCell(ptr, copy); mRendering->updateObjectCell(ptr, newPtr);
ptr.getRefData().setBaseNode(NULL); 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(); MWBase::MechanicsManager *mechMgr = MWBase::Environment::get().getMechanicsManager();
mechMgr->updateCell(ptr, copy); mechMgr->updateCell(ptr, newPtr);
std::string script = std::string script =
ptr.getClass().getScript(ptr); ptr.getClass().getScript(ptr);
@ -1187,22 +1187,23 @@ namespace MWWorld
{ {
mLocalScripts.remove(ptr); mLocalScripts.remove(ptr);
removeContainerScripts (ptr); removeContainerScripts (ptr);
mLocalScripts.add(script, copy); mLocalScripts.add(script, newPtr);
addContainerScripts (copy, newCell); addContainerScripts (newPtr, newCell);
} }
} }
ptr.getRefData().setCount(0); ptr.getRefData().setCount(0);
} }
} }
if (haveToMove && ptr.getRefData().getBaseNode()) if (haveToMove && newPtr.getRefData().getBaseNode())
{ {
mRendering->moveObject(ptr, vec); mRendering->moveObject(newPtr, vec);
mPhysics->moveObject (ptr); mPhysics->moveObject (newPtr);
} }
if (isPlayer) if (isPlayer)
{ {
mWorldScene->playerMoved (vec); mWorldScene->playerMoved (vec);
} }
return newPtr;
} }
MWWorld::Ptr World::moveObjectImp(const Ptr& ptr, float x, float y, float z) MWWorld::Ptr World::moveObjectImp(const Ptr& ptr, float x, float y, float z)
@ -1216,11 +1217,7 @@ namespace MWWorld
cell = getExterior(cellX, cellY); cell = getExterior(cellX, cellY);
} }
moveObject(ptr, cell, x, y, z); return moveObject(ptr, cell, x, y, z);
MWWorld::Ptr updated = ptr;
updated.mCell = cell;
return updated;
} }
MWWorld::Ptr World::moveObject (const Ptr& ptr, float x, float y, float z) MWWorld::Ptr World::moveObject (const Ptr& ptr, float x, float y, float z)

@ -348,7 +348,9 @@ namespace MWWorld
virtual MWWorld::Ptr moveObject (const Ptr& ptr, float x, float y, float z); virtual MWWorld::Ptr moveObject (const Ptr& ptr, float x, float y, float z);
///< @return an updated Ptr in case the Ptr's cell changes ///< @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); virtual void scaleObject (const Ptr& ptr, float scale);

Loading…
Cancel
Save