mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 13:26:44 +00:00 
			
		
		
		
	Change pathgrid workaround to check for interior cell name
This commit is contained in:
		
							parent
							
								
									0fe7500f74
								
							
						
					
					
						commit
						3270f0e932
					
				
					 6 changed files with 76 additions and 34 deletions
				
			
		| 
						 | 
					@ -382,7 +382,7 @@ namespace MWMechanics
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // infrequently used, therefore no benefit in caching it as a member
 | 
					            // infrequently used, therefore no benefit in caching it as a member
 | 
				
			||||||
            const ESM::Pathgrid *
 | 
					            const ESM::Pathgrid *
 | 
				
			||||||
                pathgrid = world->getStore().get<ESM::Pathgrid>().search(*cell, world->getCellName(currentCell));
 | 
					                pathgrid = world->getStore().get<ESM::Pathgrid>().search(*cell);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // cache the current cell location
 | 
					            // cache the current cell location
 | 
				
			||||||
            cachedCellX = cell->mData.mX;
 | 
					            cachedCellX = cell->mData.mX;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -188,8 +188,7 @@ namespace MWMechanics
 | 
				
			||||||
        if(mCell != cell || !mPathgrid)
 | 
					        if(mCell != cell || !mPathgrid)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            mCell = cell;
 | 
					            mCell = cell;
 | 
				
			||||||
            mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*mCell->getCell(),
 | 
					            mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*mCell->getCell());
 | 
				
			||||||
            MWBase::Environment::get().getWorld()->getCellName(mCell));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Refer to AiWander reseach topic on openmw forums for some background.
 | 
					        // Refer to AiWander reseach topic on openmw forums for some background.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,9 +105,7 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mCell = cell->getCell();
 | 
					        mCell = cell->getCell();
 | 
				
			||||||
        mIsExterior = cell->getCell()->isExterior();
 | 
					        mIsExterior = cell->getCell()->isExterior();
 | 
				
			||||||
        mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell->getCell(),
 | 
					        mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell->getCell());
 | 
				
			||||||
            MWBase::Environment::get().getWorld()->getCellName(cell));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!mPathgrid)
 | 
					        if(!mPathgrid)
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -233,7 +233,7 @@ void Debugging::enableCellPathgrid(MWWorld::CellStore *store)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MWBase::World* world = MWBase::Environment::get().getWorld();
 | 
					    MWBase::World* world = MWBase::Environment::get().getWorld();
 | 
				
			||||||
    const ESM::Pathgrid *pathgrid =
 | 
					    const ESM::Pathgrid *pathgrid =
 | 
				
			||||||
        world->getStore().get<ESM::Pathgrid>().search(*store->getCell(), world->getCellName(store));
 | 
					        world->getStore().get<ESM::Pathgrid>().search(*store->getCell());
 | 
				
			||||||
    if (!pathgrid) return;
 | 
					    if (!pathgrid) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vector3 cellPathGridPos(0, 0, 0);
 | 
					    Vector3 cellPathGridPos(0, 0, 0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,6 +141,8 @@ namespace MWWorld
 | 
				
			||||||
            mStores[ESM::REC_SSCR] = &mStartScripts;
 | 
					            mStores[ESM::REC_SSCR] = &mStartScripts;
 | 
				
			||||||
            mStores[ESM::REC_STAT] = &mStatics;
 | 
					            mStores[ESM::REC_STAT] = &mStatics;
 | 
				
			||||||
            mStores[ESM::REC_WEAP] = &mWeapons;
 | 
					            mStores[ESM::REC_WEAP] = &mWeapons;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            mPathgrids.setCells(mCells);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void clearDynamic ()
 | 
					        void clearDynamic ()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -843,60 +843,103 @@ namespace MWWorld
 | 
				
			||||||
    class Store<ESM::Pathgrid> : public StoreBase
 | 
					    class Store<ESM::Pathgrid> : public StoreBase
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        // Unfortunately the Pathgrid record model does not specify whether the pathgrid belongs to an interior or exterior cell.
 | 
					        typedef std::map<std::string, ESM::Pathgrid> Interior;
 | 
				
			||||||
        // For interior cells, mCell is the cell name, but for exterior cells it is either the cell name or if that doesn't exist, the cell's region name.
 | 
					        typedef std::map<std::pair<int, int>, ESM::Pathgrid> Exterior;
 | 
				
			||||||
        // mX and mY will be (0,0) for interior cells, but there is also an exterior cell with the coordinates of (0,0), so that doesn't help.
 | 
					 | 
				
			||||||
        // This is why we keep both interior and exterior pathgrids in the same container here.
 | 
					 | 
				
			||||||
        typedef std::pair<std::string, std::pair<int, int> > PathgridKey;
 | 
					 | 
				
			||||||
        typedef std::map<PathgridKey, ESM::Pathgrid> Static;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Static mStatic;
 | 
					        Interior mInt;
 | 
				
			||||||
 | 
					        Exterior mExt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Store<ESM::Cell>* mCells;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void setCells(Store<ESM::Cell>& cells)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            mCells = &cells;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void load(ESM::ESMReader &esm, const std::string &id) {
 | 
					        void load(ESM::ESMReader &esm, const std::string &id) {
 | 
				
			||||||
            ESM::Pathgrid pathgrid;
 | 
					            ESM::Pathgrid pathgrid;
 | 
				
			||||||
            pathgrid.load(esm);
 | 
					            pathgrid.load(esm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PathgridKey key = std::make_pair(pathgrid.mCell, std::make_pair(pathgrid.mData.mX, pathgrid.mData.mY));
 | 
					            // Unfortunately the Pathgrid record model does not specify whether the pathgrid belongs to an interior or exterior cell.
 | 
				
			||||||
 | 
					            // For interior cells, mCell is the cell name, but for exterior cells it is either the cell name or if that doesn't exist, the cell's region name.
 | 
				
			||||||
 | 
					            // mX and mY will be (0,0) for interior cells, but there is also an exterior cell with the coordinates of (0,0), so that doesn't help.
 | 
				
			||||||
 | 
					            // Check whether mCell is an interior cell. This isn't perfect, will break if a Region with the same name as an interior cell is created.
 | 
				
			||||||
 | 
					            // A proper fix should be made for future versions of the file format.
 | 
				
			||||||
 | 
					            bool interior = mCells->search(pathgrid.mCell) != NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Try to overwrite existing record
 | 
					            // Try to overwrite existing record
 | 
				
			||||||
            std::pair<Static::iterator, bool> ret = mStatic.insert(std::make_pair(key, pathgrid));
 | 
					            if (interior)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::pair<Interior::iterator, bool> ret = mInt.insert(std::make_pair(pathgrid.mCell, pathgrid));
 | 
				
			||||||
                if (!ret.second)
 | 
					                if (!ret.second)
 | 
				
			||||||
                    ret.first->second = pathgrid;
 | 
					                    ret.first->second = pathgrid;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::pair<Exterior::iterator, bool> ret = mExt.insert(std::make_pair(std::make_pair(pathgrid.mData.mX, pathgrid.mData.mY), pathgrid));
 | 
				
			||||||
 | 
					                if (!ret.second)
 | 
				
			||||||
 | 
					                    ret.first->second = pathgrid;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        size_t getSize() const {
 | 
					        size_t getSize() const {
 | 
				
			||||||
            return mStatic.size();
 | 
					            return mInt.size() + mExt.size();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void setUp() {
 | 
					        void setUp() {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const ESM::Pathgrid *search(const ESM::Cell &cell, const std::string& cellName) const {
 | 
					        const ESM::Pathgrid *search(int x, int y) const {
 | 
				
			||||||
            int x=0,y=0;
 | 
					            Exterior::const_iterator it = mExt.find(std::make_pair(x,y));
 | 
				
			||||||
            if (!(cell.mData.mFlags & ESM::Cell::Interior))
 | 
					            if (it != mExt.end())
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                x = cell.mData.mX;
 | 
					 | 
				
			||||||
                y = cell.mData.mY;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            PathgridKey key = std::make_pair(cellName, std::make_pair(x,y));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Static::const_iterator it = mStatic.find(key);
 | 
					 | 
				
			||||||
            if (it != mStatic.end())
 | 
					 | 
				
			||||||
                return &(it->second);
 | 
					                return &(it->second);
 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const ESM::Pathgrid *find(const ESM::Cell &cell, const std::string& cellName) const {
 | 
					        const ESM::Pathgrid *search(const std::string& name) const {
 | 
				
			||||||
            const ESM::Pathgrid* pathgrid = search(cell, cellName);
 | 
					            Interior::const_iterator it = mInt.find(name);
 | 
				
			||||||
            if (pathgrid == 0) {
 | 
					            if (it != mInt.end())
 | 
				
			||||||
 | 
					                return &(it->second);
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const ESM::Pathgrid *find(int x, int y) const {
 | 
				
			||||||
 | 
					            const ESM::Pathgrid* pathgrid = search(x,y);
 | 
				
			||||||
 | 
					            if (!pathgrid)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                std::ostringstream msg;
 | 
					                std::ostringstream msg;
 | 
				
			||||||
                msg << "Pathgrid in cell '" << cellName << "' not found";
 | 
					                msg << "Pathgrid in cell '" << x << " " << y << "' not found";
 | 
				
			||||||
                throw std::runtime_error(msg.str());
 | 
					                throw std::runtime_error(msg.str());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return pathgrid;
 | 
					            return pathgrid;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const ESM::Pathgrid* find(const std::string& name) const {
 | 
				
			||||||
 | 
					            const ESM::Pathgrid* pathgrid = search(name);
 | 
				
			||||||
 | 
					            if (!pathgrid)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::ostringstream msg;
 | 
				
			||||||
 | 
					                msg << "Pathgrid in cell '" << name << "' not found";
 | 
				
			||||||
 | 
					                throw std::runtime_error(msg.str());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return pathgrid;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const ESM::Pathgrid *search(const ESM::Cell &cell) const {
 | 
				
			||||||
 | 
					            if (!(cell.mData.mFlags & ESM::Cell::Interior))
 | 
				
			||||||
 | 
					                return search(cell.mData.mX, cell.mData.mY);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return search(cell.mName);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const ESM::Pathgrid *find(const ESM::Cell &cell) const {
 | 
				
			||||||
 | 
					            if (!(cell.mData.mFlags & ESM::Cell::Interior))
 | 
				
			||||||
 | 
					                return find(cell.mData.mX, cell.mData.mY);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return find(cell.mName);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template <class T>
 | 
					    template <class T>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue