mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 06:23:52 +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
|
||||
{
|
||||
pos.pos[0] = pos.pos[1] = 0;
|
||||
mEnvironment.mWorld->changeCell (mCellName, pos);
|
||||
mEnvironment.mWorld->changeToInteriorCell (mCellName, pos);
|
||||
}
|
||||
|
||||
// Sets up the input system
|
||||
|
|
|
@ -234,11 +234,17 @@ namespace MWMechanics
|
|||
|
||||
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
if (ptr==mWatched)
|
||||
mWatched = MWWorld::Ptr();
|
||||
|
||||
mActors.erase (ptr);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
while (iter!=mActors.end())
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace MWScript
|
|||
else
|
||||
{
|
||||
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())
|
||||
environment.mWorld->changeToExteriorCell (mPosition);
|
||||
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)
|
||||
{
|
||||
mPlayer->setPos (position.pos[0], position.pos[1], position.pos[2], true);
|
||||
if (adjustPlayerPos)
|
||||
mPlayer->setPos (position.pos[0], position.pos[1], position.pos[2], true);
|
||||
|
||||
mPlayer->setCell (cell);
|
||||
// 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,
|
||||
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),
|
||||
mSky (false), mCellChanged (false), mEnvironment (environment)
|
||||
{
|
||||
|
@ -597,8 +679,10 @@ namespace MWWorld
|
|||
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
|
||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||
|
||||
|
@ -624,91 +708,14 @@ namespace MWWorld
|
|||
//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 y = 0;
|
||||
|
||||
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
|
||||
|
@ -734,6 +741,7 @@ namespace MWWorld
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void World::markCellAsUnchanged()
|
||||
{
|
||||
mCellChanged = false;
|
||||
|
@ -793,7 +801,7 @@ namespace MWWorld
|
|||
|
||||
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())
|
||||
|
|
|
@ -88,14 +88,19 @@ namespace MWWorld
|
|||
|
||||
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 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:
|
||||
|
||||
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();
|
||||
|
||||
|
@ -143,12 +148,11 @@ namespace MWWorld
|
|||
|
||||
float getTimeScaleFactor() const;
|
||||
|
||||
void changeCell (const std::string& cellName, const ESM::Position& position);
|
||||
///< works only for interior cells currently.
|
||||
|
||||
void changeCell (int X, int Y, const ESM::Position& position);
|
||||
void changeToInteriorCell (const std::string& cellName, const ESM::Position& position);
|
||||
///< Move to interior cell.
|
||||
|
||||
void changeToExteriorCell (const ESM::Position& position);
|
||||
///< Move to exterior cell.
|
||||
|
||||
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.
|
||||
|
|
Loading…
Reference in a new issue