1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-20 19:41:36 +00:00

Add a full search to findInteriorPositionInWorldSpace.

Part of OMW Bug #1533
Implement a search for one of the 'nearest' exterior cells.  In this
case, 'nearest' means the fewest number of cells away via door markers.
This causes the world map position to update immediately after teleporting,
unless the new cell has no connecting path to an exterior.  Intervention
spells and Jail travel will be much closer to vanialla Morrowind,
except for in Mournhold.
This commit is contained in:
Jordan Ayers 2015-02-12 22:27:47 -06:00
parent 75db4d6473
commit 1d18d3ff4c

View file

@ -2784,18 +2784,45 @@ namespace MWWorld
{ {
if (cell->isExterior()) if (cell->isExterior())
return false; return false;
MWWorld::CellRefList<ESM::Door>& doors = cell->get<ESM::Door>();
CellRefList<ESM::Door>::List& refList = doors.mList;
// Check if any door in the cell leads to an exterior directly // Search for a 'nearest' exterior, counting each cell between the starting
for (CellRefList<ESM::Door>::List::iterator it = refList.begin(); it != refList.end(); ++it) // cell and the exterior as a distance of 1. Will fail for isolated interiors.
{ std::set< std::string >checkedCells;
MWWorld::LiveCellRef<ESM::Door>& ref = *it; std::set< std::string >currentCells;
if (ref.mRef.getTeleport() && ref.mRef.getDestCell().empty()) std::set< std::string >nextCells;
{ nextCells.insert( cell->getCell()->mName );
ESM::Position pos = ref.mRef.getDoorDest();
result = Ogre::Vector3(pos.pos); while ( !nextCells.empty() ) {
return true; currentCells = nextCells;
nextCells.clear();
for( std::set< std::string >::const_iterator i = currentCells.begin(); i != currentCells.end(); ++i ) {
MWWorld::CellStore *next = getInterior( *i );
if ( !next ) continue;
MWWorld::CellRefList<ESM::Door>& doors = next->get<ESM::Door>();
CellRefList<ESM::Door>::List& refList = doors.mList;
// Check if any door in the cell leads to an exterior directly
for (CellRefList<ESM::Door>::List::iterator it = refList.begin(); it != refList.end(); ++it)
{
MWWorld::LiveCellRef<ESM::Door>& ref = *it;
if (!ref.mRef.getTeleport()) continue;
if (ref.mRef.getDestCell().empty())
{
ESM::Position pos = ref.mRef.getDoorDest();
result = Ogre::Vector3(pos.pos);
return true;
}
else
{
std::string dest = ref.mRef.getDestCell();
if ( !checkedCells.count(dest) && !currentCells.count(dest) )
nextCells.insert(dest);
}
}
checkedCells.insert( *i );
} }
} }