From b6f7f21bcfe3aee9b367681ca18d1cdb914e2e3a Mon Sep 17 00:00:00 2001 From: greye Date: Wed, 8 Aug 2012 14:51:33 +0400 Subject: [PATCH] fix player cell assertion fail, moveObject(Ptr&, CellStore&, f, f, f) added --- apps/openmw/mwbase/world.hpp | 5 +- apps/openmw/mwworld/cellstore.hpp | 14 ++++ apps/openmw/mwworld/scene.cpp | 10 +-- apps/openmw/mwworld/worldimp.cpp | 122 ++++++++++++++---------------- apps/openmw/mwworld/worldimp.hpp | 3 +- 5 files changed, 81 insertions(+), 73 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f257b723ea..d6037f1072 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -57,7 +57,7 @@ namespace MWBase protected: virtual void - placeObject( + copyObjectToCell( const MWWorld::Ptr &ptr, MWWorld::CellStore &cell, 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, MWWorld::CellStore &newCell, float x, float y, float z) = 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; diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 8eafb6b10a..3ec4a2e782 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -155,6 +155,20 @@ namespace MWWorld 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: template diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 13e5ecb85f..ef5da7b91e 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -138,6 +138,8 @@ namespace MWWorld void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, bool adjustPlayerPos) { + MWBase::Environment::get().getWorld()->getPlayer().setCell (cell); + bool hasWater = cell->cell->data.flags & cell->cell->HasWater; mPhysics->setCurrentWater(hasWater, cell->cell->water); 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().setCell (cell); MWBase::Environment::get().getMechanicsManager()->addActor (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 - playerCellChange (MWBase::Environment::get().getWorld()->getExterior(X, Y), position, adjustPlayerPos); + playerCellChange (mCurrentCell, position, adjustPlayerPos); // Sky system MWBase::Environment::get().getWorld()->adjustSky(); @@ -350,10 +351,7 @@ namespace MWWorld { CellStoreCollection::iterator active = mActiveCells.begin(); while (active != mActiveCells.end()) { - if ((*active)->cell->name == cell.cell->name && - (*active)->cell->data.gridX == cell.cell->data.gridX && - (*active)->cell->data.gridY == cell.cell->data.gridY) - { + if (**active == cell) { return true; } ++active; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 748e6dc044..4dd06ad057 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -543,81 +543,73 @@ 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(); pos.pos[0] = x, pos.pos[1] = y, pos.pos[2] = z; Ogre::Vector3 vec(x, y, z); - CellStore *currCell; - /// \todo fix assertion fail on player ptr.getCell() on start - if (ptr == mPlayer->getPlayer()) { - currCell = mWorldScene->getCurrentCell(); - } else { - currCell = ptr.getCell(); - } - bool haveToMove = mWorldScene->isCellActive(*currCell); + CellStore *currCell = ptr.getCell(); + bool isPlayer = ptr == mPlayer->getPlayer(); + bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer; - 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 { - CellStore *newCell = - MWBase::Environment::get().getWorld()->getExterior(cellX, cellY); - - // placeObject() handles both target cell states - // 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); - mLocalScripts.remove(ptr); - - haveToMove = false; - } else { - MWWorld::Ptr copy = - MWWorld::Class::get(ptr).copyToCell(ptr, *newCell); - - mRendering->moveObjectToCell(copy, vec, currCell); - - if (MWWorld::Class::get(ptr).isActor()) { - MWMechanics::MechanicsManager *mechMgr = - MWBase::Environment::get().getMechanicsManager(); - - mechMgr->removeActor(ptr); - mechMgr->addActor(copy); - } else { - std::string script = - MWWorld::Class::get(ptr).getScript(ptr); - if (!script.empty()) { - mLocalScripts.remove(ptr); - mLocalScripts.add(script, copy); - } - } - } - ptr.getRefData().setCount(0); - } - cellChanged = true; + if (*currCell != newCell) { + if (isPlayer) { + if (!newCell.isExterior()) { + changeToInteriorCell(newCell.cell->name, pos); + } else { + changeToExteriorCell(pos); } + } else { + if (!mWorldScene->isCellActive(newCell)) { + copyObjectToCell(ptr, newCell, pos); + } else if (!mWorldScene->isCellActive(*currCell)) { + MWWorld::Class::get(ptr).copyToCell(ptr, newCell); + mWorldScene->removeObjectFromScene(ptr); + mLocalScripts.remove(ptr); + haveToMove = false; + } else { + MWWorld::Ptr copy = + MWWorld::Class::get(ptr).copyToCell(ptr, newCell); + + mRendering->moveObjectToCell(copy, vec, currCell); + + if (MWWorld::Class::get(ptr).isActor()) { + MWMechanics::MechanicsManager *mechMgr = + MWBase::Environment::get().getMechanicsManager(); + + mechMgr->removeActor(ptr); + mechMgr->addActor(copy); + } else { + std::string script = + MWWorld::Class::get(ptr).getScript(ptr); + if (!script.empty()) { + mLocalScripts.remove(ptr); + mLocalScripts.add(script, copy); + } + } + } + ptr.getRefData().setCount(0); } } if (haveToMove) { mRendering->moveObject(ptr, 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) @@ -1058,7 +1050,7 @@ namespace MWWorld pos.pos[1] = -result.second[2]; pos.pos[2] = result.second[1]; - placeObject(object, *cell, pos); + copyObjectToCell(object, *cell, pos); object.getRefData().setCount(0); return true; @@ -1076,7 +1068,7 @@ namespace MWWorld } 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 MWWorld::Ptr dropped = @@ -1119,7 +1111,7 @@ namespace MWWorld mPhysics->castRay(orig, dir, len); pos.pos[2] = hit.second.z; - placeObject(object, *cell, pos); + copyObjectToCell(object, *cell, pos); object.getRefData().setCount(0); } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index d39871c21d..e33e90eaa4 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -90,7 +90,7 @@ namespace MWWorld ///< @return true if the active cell (cell player is in) changed virtual void - placeObject(const Ptr &ptr, CellStore &cell, const ESM::Position &pos); + copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos); public: @@ -206,6 +206,7 @@ namespace MWWorld virtual void deleteObject (const Ptr& ptr); 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);