forked from mirror/openmw-tes3mp
fix player cell assertion fail, moveObject(Ptr&, CellStore&, f, f, f) added
This commit is contained in:
parent
79b7487c87
commit
b6f7f21bcf
5 changed files with 81 additions and 73 deletions
|
@ -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;
|
||||
|
|
|
@ -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<class Functor, class List>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue