forked from teamnwah/openmw-tes3coop
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:
parent
75db4d6473
commit
1d18d3ff4c
1 changed files with 38 additions and 11 deletions
|
@ -2784,18 +2784,45 @@ namespace MWWorld
|
|||
{
|
||||
if (cell->isExterior())
|
||||
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
|
||||
for (CellRefList<ESM::Door>::List::iterator it = refList.begin(); it != refList.end(); ++it)
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Door>& ref = *it;
|
||||
if (ref.mRef.getTeleport() && ref.mRef.getDestCell().empty())
|
||||
{
|
||||
ESM::Position pos = ref.mRef.getDoorDest();
|
||||
result = Ogre::Vector3(pos.pos);
|
||||
return true;
|
||||
// Search for a 'nearest' exterior, counting each cell between the starting
|
||||
// cell and the exterior as a distance of 1. Will fail for isolated interiors.
|
||||
std::set< std::string >checkedCells;
|
||||
std::set< std::string >currentCells;
|
||||
std::set< std::string >nextCells;
|
||||
nextCells.insert( cell->getCell()->mName );
|
||||
|
||||
while ( !nextCells.empty() ) {
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue