fix player cell assertion fail, moveObject(Ptr&, CellStore&, f, f, f) added

This commit is contained in:
greye 2012-08-08 14:51:33 +04:00
parent 79b7487c87
commit b6f7f21bcf
5 changed files with 81 additions and 73 deletions

View file

@ -57,7 +57,7 @@ namespace MWBase
protected: protected:
virtual void virtual void
placeObject( copyObjectToCell(
const MWWorld::Ptr &ptr, const MWWorld::Ptr &ptr,
MWWorld::CellStore &cell, MWWorld::CellStore &cell,
const ESM::Position &pos) = 0; const ESM::Position &pos) = 0;
@ -184,6 +184,9 @@ namespace MWBase
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
virtual void
moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore &newCell, float x, float y, float z) = 0;
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0; virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z) = 0; virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z) = 0;

View file

@ -155,6 +155,20 @@ namespace MWWorld
forEachImp (functor, weapons); forEachImp (functor, weapons);
} }
bool operator==(const CellStore &cell) {
return this->cell->name == cell.cell->name &&
this->cell->data.gridX == cell.cell->data.gridX &&
this->cell->data.gridY == cell.cell->data.gridY;
}
bool operator!=(const CellStore &cell) {
return !(*this == cell);
}
bool isExterior() const {
return cell->isExterior();
}
private: private:
template<class Functor, class List> template<class Functor, class List>

View file

@ -138,6 +138,8 @@ namespace MWWorld
void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
bool adjustPlayerPos) bool adjustPlayerPos)
{ {
MWBase::Environment::get().getWorld()->getPlayer().setCell (cell);
bool hasWater = cell->cell->data.flags & cell->cell->HasWater; bool hasWater = cell->cell->data.flags & cell->cell->HasWater;
mPhysics->setCurrentWater(hasWater, cell->cell->water); mPhysics->setCurrentWater(hasWater, cell->cell->water);
if (adjustPlayerPos) if (adjustPlayerPos)
@ -146,7 +148,6 @@ namespace MWWorld
MWBase::Environment::get().getWorld()->getPlayer().setRot (position.rot[0], position.rot[1], position.rot[2]); MWBase::Environment::get().getWorld()->getPlayer().setRot (position.rot[0], position.rot[1], position.rot[2]);
} }
MWBase::Environment::get().getWorld()->getPlayer().setCell (cell);
MWBase::Environment::get().getMechanicsManager()->addActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); MWBase::Environment::get().getMechanicsManager()->addActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
MWBase::Environment::get().getMechanicsManager()->watchActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); MWBase::Environment::get().getMechanicsManager()->watchActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
@ -224,7 +225,7 @@ namespace MWWorld
// adjust player // adjust player
playerCellChange (MWBase::Environment::get().getWorld()->getExterior(X, Y), position, adjustPlayerPos); playerCellChange (mCurrentCell, position, adjustPlayerPos);
// Sky system // Sky system
MWBase::Environment::get().getWorld()->adjustSky(); MWBase::Environment::get().getWorld()->adjustSky();
@ -350,10 +351,7 @@ namespace MWWorld
{ {
CellStoreCollection::iterator active = mActiveCells.begin(); CellStoreCollection::iterator active = mActiveCells.begin();
while (active != mActiveCells.end()) { while (active != mActiveCells.end()) {
if ((*active)->cell->name == cell.cell->name && if (**active == cell) {
(*active)->cell->data.gridX == cell.cell->data.gridX &&
(*active)->cell->data.gridY == cell.cell->data.gridY)
{
return true; return true;
} }
++active; ++active;

View file

@ -543,52 +543,34 @@ namespace MWWorld
} }
} }
bool World::moveObjectImp (const Ptr& ptr, float x, float y, float z) void World::moveObject(const Ptr &ptr, CellStore &newCell, float x, float y, float z)
{ {
bool cellChanged = false;
ESM::Position &pos = ptr.getRefData().getPosition(); ESM::Position &pos = ptr.getRefData().getPosition();
pos.pos[0] = x, pos.pos[1] = y, pos.pos[2] = z; pos.pos[0] = x, pos.pos[1] = y, pos.pos[2] = z;
Ogre::Vector3 vec(x, y, z); Ogre::Vector3 vec(x, y, z);
CellStore *currCell; CellStore *currCell = ptr.getCell();
/// \todo fix assertion fail on player ptr.getCell() on start bool isPlayer = ptr == mPlayer->getPlayer();
if (ptr == mPlayer->getPlayer()) { bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer;
currCell = mWorldScene->getCurrentCell();
if (*currCell != newCell) {
if (isPlayer) {
if (!newCell.isExterior()) {
changeToInteriorCell(newCell.cell->name, pos);
} else { } else {
currCell = ptr.getCell(); changeToExteriorCell(pos);
} }
bool haveToMove = mWorldScene->isCellActive(*currCell);
if (currCell) {
if (!(currCell->cell->data.flags & ESM::Cell::Interior)) {
// exterior -> adjust loaded cells
int cellX = 0, cellY = 0;
positionToIndex (x, y, cellX, cellY);
if (currCell->cell->data.gridX != cellX ||
currCell->cell->data.gridY != cellY)
{
if (ptr == mPlayer->getPlayer()) {
mWorldScene->changeCell(cellX, cellY, pos, false);
} else { } else {
CellStore *newCell = if (!mWorldScene->isCellActive(newCell)) {
MWBase::Environment::get().getWorld()->getExterior(cellX, cellY); copyObjectToCell(ptr, newCell, pos);
} else if (!mWorldScene->isCellActive(*currCell)) {
// placeObject() handles both target cell states MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
// with inactive current cell
if (!mWorldScene->isCellActive(*currCell)) {
placeObject(ptr, *newCell, pos);
haveToMove = false;
} else if (!mWorldScene->isCellActive(*newCell)) {
MWWorld::Class::get(ptr).copyToCell(ptr, *newCell);
mWorldScene->removeObjectFromScene(ptr); mWorldScene->removeObjectFromScene(ptr);
mLocalScripts.remove(ptr); mLocalScripts.remove(ptr);
haveToMove = false; haveToMove = false;
} else { } else {
MWWorld::Ptr copy = MWWorld::Ptr copy =
MWWorld::Class::get(ptr).copyToCell(ptr, *newCell); MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
mRendering->moveObjectToCell(copy, vec, currCell); mRendering->moveObjectToCell(copy, vec, currCell);
@ -609,15 +591,25 @@ namespace MWWorld
} }
ptr.getRefData().setCount(0); ptr.getRefData().setCount(0);
} }
cellChanged = true;
}
}
} }
if (haveToMove) { if (haveToMove) {
mRendering->moveObject(ptr, vec); mRendering->moveObject(ptr, vec);
mPhysics->moveObject(ptr.getRefData().getHandle(), vec); mPhysics->moveObject(ptr.getRefData().getHandle(), vec);
} }
return cellChanged; }
bool World::moveObjectImp(const Ptr& ptr, float x, float y, float z)
{
CellStore *cell = ptr.getCell();
if (cell->isExterior()) {
int cellX, cellY;
positionToIndex(x, y, cellX, cellY);
cell = getExterior(cellX, cellY);
}
moveObject(ptr, *cell, x, y, z);
return cell != ptr.getCell();
} }
void World::moveObject (const Ptr& ptr, float x, float y, float z) void World::moveObject (const Ptr& ptr, float x, float y, float z)
@ -1058,7 +1050,7 @@ namespace MWWorld
pos.pos[1] = -result.second[2]; pos.pos[1] = -result.second[2];
pos.pos[2] = result.second[1]; pos.pos[2] = result.second[1];
placeObject(object, *cell, pos); copyObjectToCell(object, *cell, pos);
object.getRefData().setCount(0); object.getRefData().setCount(0);
return true; return true;
@ -1076,7 +1068,7 @@ namespace MWWorld
} }
void void
World::placeObject(const Ptr &object, CellStore &cell, const ESM::Position &pos) World::copyObjectToCell(const Ptr &object, CellStore &cell, const ESM::Position &pos)
{ {
/// \todo add searching correct cell for position specified /// \todo add searching correct cell for position specified
MWWorld::Ptr dropped = MWWorld::Ptr dropped =
@ -1119,7 +1111,7 @@ namespace MWWorld
mPhysics->castRay(orig, dir, len); mPhysics->castRay(orig, dir, len);
pos.pos[2] = hit.second.z; pos.pos[2] = hit.second.z;
placeObject(object, *cell, pos); copyObjectToCell(object, *cell, pos);
object.getRefData().setCount(0); object.getRefData().setCount(0);
} }

View file

@ -90,7 +90,7 @@ namespace MWWorld
///< @return true if the active cell (cell player is in) changed ///< @return true if the active cell (cell player is in) changed
virtual void virtual void
placeObject(const Ptr &ptr, CellStore &cell, const ESM::Position &pos); copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos);
public: public:
@ -206,6 +206,7 @@ namespace MWWorld
virtual void deleteObject (const Ptr& ptr); virtual void deleteObject (const Ptr& ptr);
virtual void moveObject (const Ptr& ptr, float x, float y, float z); virtual void moveObject (const Ptr& ptr, float x, float y, float z);
virtual void moveObject (const Ptr& ptr, CellStore &newCell, float x, float y, float z);
virtual void scaleObject (const Ptr& ptr, float scale); virtual void scaleObject (const Ptr& ptr, float scale);