mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 10:23:51 +00:00
reworked cell changing mechanism
This commit is contained in:
parent
f773cf27cb
commit
9a3158675a
6 changed files with 111 additions and 93 deletions
|
@ -393,7 +393,7 @@ void OMW::Engine::go()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pos.pos[0] = pos.pos[1] = 0;
|
pos.pos[0] = pos.pos[1] = 0;
|
||||||
mEnvironment.mWorld->changeCell (mCellName, pos);
|
mEnvironment.mWorld->changeToInteriorCell (mCellName, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up the input system
|
// Sets up the input system
|
||||||
|
|
|
@ -234,11 +234,17 @@ namespace MWMechanics
|
||||||
|
|
||||||
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
|
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
|
if (ptr==mWatched)
|
||||||
|
mWatched = MWWorld::Ptr();
|
||||||
|
|
||||||
mActors.erase (ptr);
|
mActors.erase (ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
||||||
{
|
{
|
||||||
|
if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
|
||||||
|
mWatched = MWWorld::Ptr();
|
||||||
|
|
||||||
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
|
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
|
||||||
|
|
||||||
while (iter!=mActors.end())
|
while (iter!=mActors.end())
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace MWScript
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pos.pos[0] = pos.pos[1] = 0;
|
pos.pos[0] = pos.pos[1] = 0;
|
||||||
context.getWorld().changeCell (cell, pos);
|
context.getWorld().changeToInteriorCell (cell, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,6 @@ namespace MWWorld
|
||||||
if (mCellName.empty())
|
if (mCellName.empty())
|
||||||
environment.mWorld->changeToExteriorCell (mPosition);
|
environment.mWorld->changeToExteriorCell (mPosition);
|
||||||
else
|
else
|
||||||
environment.mWorld->changeCell (mCellName, mPosition);
|
environment.mWorld->changeToInteriorCell (mCellName, mPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,9 +305,12 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position)
|
void World::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
||||||
|
bool adjustPlayerPos)
|
||||||
{
|
{
|
||||||
|
if (adjustPlayerPos)
|
||||||
mPlayer->setPos (position.pos[0], position.pos[1], position.pos[2], true);
|
mPlayer->setPos (position.pos[0], position.pos[1], position.pos[2], true);
|
||||||
|
|
||||||
mPlayer->setCell (cell);
|
mPlayer->setCell (cell);
|
||||||
// TODO orientation
|
// TODO orientation
|
||||||
|
|
||||||
|
@ -326,8 +329,87 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos)
|
||||||
|
{
|
||||||
|
SuppressDoingPhysics scopeGuard;
|
||||||
|
|
||||||
|
// remove active
|
||||||
|
mEnvironment.mMechanicsManager->removeActor (mPlayer->getPlayer());
|
||||||
|
|
||||||
|
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||||
|
|
||||||
|
while (active!=mActiveCells.end())
|
||||||
|
{
|
||||||
|
if (!(active->first->cell->data.flags & ESM::Cell::Interior))
|
||||||
|
{
|
||||||
|
if (std::abs (X-active->first->cell->data.gridX)<=1 &&
|
||||||
|
std::abs (Y-active->first->cell->data.gridY)<=1)
|
||||||
|
{
|
||||||
|
// keep cells within the new 3x3 grid
|
||||||
|
++active;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unloadCell (active++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load cells
|
||||||
|
for (int x=X-1; x<=X+1; ++x)
|
||||||
|
for (int y=Y-1; y<=Y+1; ++y)
|
||||||
|
{
|
||||||
|
CellRenderCollection::iterator iter = mActiveCells.begin();
|
||||||
|
|
||||||
|
while (iter!=mActiveCells.end())
|
||||||
|
{
|
||||||
|
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
||||||
|
|
||||||
|
if (x==iter->first->cell->data.gridX &&
|
||||||
|
y==iter->first->cell->data.gridY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter==mActiveCells.end())
|
||||||
|
{
|
||||||
|
mExteriors[std::make_pair (x, y)].loadExt (x, y, mStore, mEsm);
|
||||||
|
Ptr::CellStore *cell = &mExteriors[std::make_pair (x, y)];
|
||||||
|
|
||||||
|
loadCell (cell, new MWRender::ExteriorCellRender (*cell, mEnvironment, mScene));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find current cell
|
||||||
|
CellRenderCollection::iterator iter = mActiveCells.begin();
|
||||||
|
|
||||||
|
while (iter!=mActiveCells.end())
|
||||||
|
{
|
||||||
|
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
||||||
|
|
||||||
|
if (X==iter->first->cell->data.gridX &&
|
||||||
|
Y==iter->first->cell->data.gridY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (iter!=mActiveCells.end());
|
||||||
|
|
||||||
|
mCurrentCell = iter->first;
|
||||||
|
|
||||||
|
// adjust player
|
||||||
|
playerCellChange (&mExteriors[std::make_pair (X, Y)], position, adjustPlayerPos);
|
||||||
|
|
||||||
|
// Sky system
|
||||||
|
adjustSky();
|
||||||
|
|
||||||
|
mCellChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
World::World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
World::World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
||||||
const std::string& master, const boost::filesystem::path& resDir, bool newGame, Environment& environment)
|
const std::string& master, const boost::filesystem::path& resDir,
|
||||||
|
bool newGame, Environment& environment)
|
||||||
: mSkyManager (0), mScene (renderer), mPlayer (0), mCurrentCell (0), mGlobalVariables (0),
|
: mSkyManager (0), mScene (renderer), mPlayer (0), mCurrentCell (0), mGlobalVariables (0),
|
||||||
mSky (false), mCellChanged (false), mEnvironment (environment)
|
mSky (false), mCellChanged (false), mEnvironment (environment)
|
||||||
{
|
{
|
||||||
|
@ -597,8 +679,10 @@ namespace MWWorld
|
||||||
return mGlobalVariables->getInt ("timescale");
|
return mGlobalVariables->getInt ("timescale");
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeCell (const std::string& cellName, const ESM::Position& position)
|
void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
|
||||||
{
|
{
|
||||||
|
SuppressDoingPhysics scopeGuard;
|
||||||
|
|
||||||
// remove active
|
// remove active
|
||||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||||
|
|
||||||
|
@ -624,83 +708,6 @@ namespace MWWorld
|
||||||
//currentRegion->name = "";
|
//currentRegion->name = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeCell (int X, int Y, const ESM::Position& position)
|
|
||||||
{
|
|
||||||
SuppressDoingPhysics scopeGuard;
|
|
||||||
|
|
||||||
// remove active
|
|
||||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
|
||||||
|
|
||||||
while (active!=mActiveCells.end())
|
|
||||||
{
|
|
||||||
if (!(active->first->cell->data.flags & ESM::Cell::Interior))
|
|
||||||
{
|
|
||||||
if (std::abs (X-active->first->cell->data.gridX)<=1 &&
|
|
||||||
std::abs (Y-active->first->cell->data.gridY)<=1)
|
|
||||||
{
|
|
||||||
// keep cells within the new 3x3 grid
|
|
||||||
++active;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unloadCell (active++);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load cells
|
|
||||||
for (int x=X-1; x<=X+1; ++x)
|
|
||||||
for (int y=Y-1; y<=Y+1; ++y)
|
|
||||||
{
|
|
||||||
CellRenderCollection::iterator iter = mActiveCells.begin();
|
|
||||||
|
|
||||||
while (iter!=mActiveCells.end())
|
|
||||||
{
|
|
||||||
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
|
||||||
|
|
||||||
if (x==iter->first->cell->data.gridX &&
|
|
||||||
y==iter->first->cell->data.gridY)
|
|
||||||
break;
|
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iter==mActiveCells.end())
|
|
||||||
{
|
|
||||||
mExteriors[std::make_pair (x, y)].loadExt (x, y, mStore, mEsm);
|
|
||||||
Ptr::CellStore *cell = &mExteriors[std::make_pair (x, y)];
|
|
||||||
|
|
||||||
loadCell (cell, new MWRender::ExteriorCellRender (*cell, mEnvironment, mScene));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find current cell
|
|
||||||
CellRenderCollection::iterator iter = mActiveCells.begin();
|
|
||||||
|
|
||||||
while (iter!=mActiveCells.end())
|
|
||||||
{
|
|
||||||
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
|
||||||
|
|
||||||
if (X==iter->first->cell->data.gridX &&
|
|
||||||
Y==iter->first->cell->data.gridY)
|
|
||||||
break;
|
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert (iter!=mActiveCells.end());
|
|
||||||
|
|
||||||
mCurrentCell = iter->first;
|
|
||||||
|
|
||||||
// adjust player
|
|
||||||
playerCellChange (&mExteriors[std::make_pair (X, Y)], position);
|
|
||||||
|
|
||||||
// Sky system
|
|
||||||
adjustSky();
|
|
||||||
|
|
||||||
mCellChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void World::changeToExteriorCell (const ESM::Position& position)
|
void World::changeToExteriorCell (const ESM::Position& position)
|
||||||
{
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
@ -708,7 +715,7 @@ namespace MWWorld
|
||||||
|
|
||||||
positionToIndex (position.pos[0], position.pos[1], x, y);
|
positionToIndex (position.pos[0], position.pos[1], x, y);
|
||||||
|
|
||||||
changeCell (x, y, position);
|
changeCell (x, y, position, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::Cell *World::getExterior (const std::string& cellName) const
|
const ESM::Cell *World::getExterior (const std::string& cellName) const
|
||||||
|
@ -734,6 +741,7 @@ namespace MWWorld
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::markCellAsUnchanged()
|
void World::markCellAsUnchanged()
|
||||||
{
|
{
|
||||||
mCellChanged = false;
|
mCellChanged = false;
|
||||||
|
@ -793,7 +801,7 @@ namespace MWWorld
|
||||||
|
|
||||||
if (mCurrentCell->cell->data.gridX!=cellX || mCurrentCell->cell->data.gridY!=cellY)
|
if (mCurrentCell->cell->data.gridX!=cellX || mCurrentCell->cell->data.gridY!=cellY)
|
||||||
{
|
{
|
||||||
changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos);
|
changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DoingPhysics::isDoingPhysics())
|
if (!DoingPhysics::isDoingPhysics())
|
||||||
|
|
|
@ -88,14 +88,19 @@ namespace MWWorld
|
||||||
|
|
||||||
void loadCell (Ptr::CellStore *cell, MWRender::CellRender *render);
|
void loadCell (Ptr::CellStore *cell, MWRender::CellRender *render);
|
||||||
|
|
||||||
void playerCellChange (Ptr::CellStore *cell, const ESM::Position& position);
|
void playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
||||||
|
bool adjustPlayerPos = true);
|
||||||
|
|
||||||
void adjustSky();
|
void adjustSky();
|
||||||
|
|
||||||
|
void changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos);
|
||||||
|
///< Move from exterior to interior or from interior cell to a different
|
||||||
|
/// interior cell.
|
||||||
public:
|
public:
|
||||||
|
|
||||||
World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
||||||
const std::string& master, const boost::filesystem::path& resDir, bool newGame, Environment& environment);
|
const std::string& master, const boost::filesystem::path& resDir, bool newGame,
|
||||||
|
Environment& environment);
|
||||||
|
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
|
@ -143,12 +148,11 @@ namespace MWWorld
|
||||||
|
|
||||||
float getTimeScaleFactor() const;
|
float getTimeScaleFactor() const;
|
||||||
|
|
||||||
void changeCell (const std::string& cellName, const ESM::Position& position);
|
void changeToInteriorCell (const std::string& cellName, const ESM::Position& position);
|
||||||
///< works only for interior cells currently.
|
///< Move to interior cell.
|
||||||
|
|
||||||
void changeCell (int X, int Y, const ESM::Position& position);
|
|
||||||
|
|
||||||
void changeToExteriorCell (const ESM::Position& position);
|
void changeToExteriorCell (const ESM::Position& position);
|
||||||
|
///< Move to exterior cell.
|
||||||
|
|
||||||
const ESM::Cell *getExterior (const std::string& cellName) const;
|
const ESM::Cell *getExterior (const std::string& cellName) const;
|
||||||
///< Return a cell matching the given name or a 0-pointer, if there is no such cell.
|
///< Return a cell matching the given name or a 0-pointer, if there is no such cell.
|
||||||
|
|
Loading…
Reference in a new issue