mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 20:26:48 +00:00 
			
		
		
		
	Implement TestCells (feature #5219)
This commit is contained in:
		
							parent
							
								
									31c5c6d993
								
							
						
					
					
						commit
						24ce242941
					
				
					 14 changed files with 247 additions and 43 deletions
				
			
		|  | @ -235,6 +235,7 @@ | |||
|     Feature #5147: Show spell magicka cost in spell buying window | ||||
|     Feature #5170: Editor: Land shape editing, land selection | ||||
|     Feature #5193: Weapon sheathing | ||||
|     Feature #5219: Impelement TestCells console command | ||||
|     Feature #5224: Handle NiKeyframeController for NiTriShape | ||||
|     Task #4686: Upgrade media decoder to a more current FFmpeg API | ||||
|     Task #4695: Optimize Distant Terrain memory consumption | ||||
|  |  | |||
|  | @ -118,6 +118,9 @@ namespace MWBase | |||
| 
 | ||||
|             virtual MWWorld::CellStore *getCell (const ESM::CellId& id) = 0; | ||||
| 
 | ||||
|             virtual void testExteriorCells() = 0; | ||||
|             virtual void testInteriorCells() = 0; | ||||
| 
 | ||||
|             virtual void useDeathCamera() = 0; | ||||
| 
 | ||||
|             virtual void setWaterHeight(const float height) = 0; | ||||
|  |  | |||
|  | @ -15,7 +15,6 @@ | |||
| #include <osg/TextureCubeMap> | ||||
| 
 | ||||
| #include <osgUtil/LineSegmentIntersector> | ||||
| #include <osgUtil/IncrementalCompileOperation> | ||||
| 
 | ||||
| #include <osg/ImageUtils> | ||||
| 
 | ||||
|  | @ -391,6 +390,11 @@ namespace MWRender | |||
|         mWorkQueue = nullptr; | ||||
|     } | ||||
| 
 | ||||
|     osgUtil::IncrementalCompileOperation* RenderingManager::getIncrementalCompileOperation() | ||||
|     { | ||||
|         return mViewer->getIncrementalCompileOperation(); | ||||
|     } | ||||
| 
 | ||||
|     MWRender::Objects& RenderingManager::getObjects() | ||||
|     { | ||||
|         return *mObjects.get(); | ||||
|  |  | |||
|  | @ -7,6 +7,8 @@ | |||
| 
 | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| #include <osgUtil/IncrementalCompileOperation> | ||||
| 
 | ||||
| #include "objects.hpp" | ||||
| 
 | ||||
| #include "renderinginterface.hpp" | ||||
|  | @ -89,6 +91,8 @@ namespace MWRender | |||
|                          const std::string& resourcePath, DetourNavigator::Navigator& navigator); | ||||
|         ~RenderingManager(); | ||||
| 
 | ||||
|         osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation(); | ||||
| 
 | ||||
|         MWRender::Objects& getObjects(); | ||||
| 
 | ||||
|         Resource::ResourceSystem* getResourceSystem(); | ||||
|  |  | |||
|  | @ -10,11 +10,13 @@ | |||
| #include <components/interpreter/runtime.hpp> | ||||
| #include <components/interpreter/opcodes.hpp> | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/world.hpp" | ||||
| #include "../mwworld/player.hpp" | ||||
| #include "../mwworld/cellstore.hpp" | ||||
| #include "../mwworld/actionteleport.hpp" | ||||
| #include "../mwworld/cellstore.hpp" | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwworld/player.hpp" | ||||
| #include "../mwbase/statemanager.hpp" | ||||
| #include "../mwbase/windowmanager.hpp" | ||||
| #include "../mwbase/world.hpp" | ||||
| 
 | ||||
| #include "../mwmechanics/actorutil.hpp" | ||||
| 
 | ||||
|  | @ -34,6 +36,52 @@ namespace MWScript | |||
|                 } | ||||
|         }; | ||||
| 
 | ||||
|         class OpTestCells : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
| 
 | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) | ||||
|                     { | ||||
|                         runtime.getContext().report("Use TestCells from the main menu, when there is no active game session."); | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     bool wasConsole = MWBase::Environment::get().getWindowManager()->isConsoleMode(); | ||||
|                     if (wasConsole) | ||||
|                         MWBase::Environment::get().getWindowManager()->toggleConsole(); | ||||
| 
 | ||||
|                     MWBase::Environment::get().getWorld()->testExteriorCells(); | ||||
| 
 | ||||
|                     if (wasConsole) | ||||
|                         MWBase::Environment::get().getWindowManager()->toggleConsole(); | ||||
|                 } | ||||
|         }; | ||||
| 
 | ||||
|         class OpTestInteriorCells : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
| 
 | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) | ||||
|                     { | ||||
|                         runtime.getContext().report("Use TestInteriorCells from the main menu, when there is no active game session."); | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     bool wasConsole = MWBase::Environment::get().getWindowManager()->isConsoleMode(); | ||||
|                     if (wasConsole) | ||||
|                         MWBase::Environment::get().getWindowManager()->toggleConsole(); | ||||
| 
 | ||||
|                     MWBase::Environment::get().getWorld()->testInteriorCells(); | ||||
| 
 | ||||
|                     if (wasConsole) | ||||
|                         MWBase::Environment::get().getWindowManager()->toggleConsole(); | ||||
|                 } | ||||
|         }; | ||||
| 
 | ||||
|         class OpCOC : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|  | @ -204,6 +252,8 @@ namespace MWScript | |||
|         void installOpcodes (Interpreter::Interpreter& interpreter) | ||||
|         { | ||||
|             interpreter.installSegment5 (Compiler::Cell::opcodeCellChanged, new OpCellChanged); | ||||
|             interpreter.installSegment5 (Compiler::Cell::opcodeTestCells, new OpTestCells); | ||||
|             interpreter.installSegment5 (Compiler::Cell::opcodeTestInteriorCells, new OpTestInteriorCells); | ||||
|             interpreter.installSegment5 (Compiler::Cell::opcodeCOC, new OpCOC); | ||||
|             interpreter.installSegment5 (Compiler::Cell::opcodeCOE, new OpCOE); | ||||
|             interpreter.installSegment5 (Compiler::Cell::opcodeGetInterior, new OpGetInterior); | ||||
|  |  | |||
|  | @ -461,5 +461,7 @@ op 0x200030a: SetNavMeshNumber | |||
| op 0x200030b: Journal, explicit | ||||
| op 0x200030c: RepairedOnMe | ||||
| op 0x200030d: RepairedOnMe, explicit | ||||
| op 0x200030e: TestCells | ||||
| op 0x200030f: TestInteriorCells | ||||
| 
 | ||||
| opcodes 0x200030c-0x3ffffff unused | ||||
| opcodes 0x2000310-0x3ffffff unused | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ | |||
| #include <components/resource/resourcesystem.hpp> | ||||
| #include <components/resource/scenemanager.hpp> | ||||
| #include <components/resource/bulletshape.hpp> | ||||
| #include <components/sceneutil/unrefqueue.hpp> | ||||
| #include <components/detournavigator/navigator.hpp> | ||||
| #include <components/detournavigator/debug.hpp> | ||||
| #include <components/misc/convert.hpp> | ||||
|  | @ -22,6 +23,8 @@ | |||
| #include "../mwbase/mechanicsmanager.hpp" | ||||
| #include "../mwbase/windowmanager.hpp" | ||||
| 
 | ||||
| #include "../mwmechanics/actorutil.hpp" | ||||
| 
 | ||||
| #include "../mwrender/renderingmanager.hpp" | ||||
| #include "../mwrender/landmanager.hpp" | ||||
| 
 | ||||
|  | @ -205,10 +208,11 @@ namespace | |||
|     { | ||||
|         MWWorld::CellStore& mCell; | ||||
|         Loading::Listener& mLoadingListener; | ||||
|         bool mTest; | ||||
| 
 | ||||
|         std::vector<MWWorld::Ptr> mToInsert; | ||||
| 
 | ||||
|         InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener); | ||||
|         InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener, bool test); | ||||
| 
 | ||||
|         bool operator() (const MWWorld::Ptr& ptr); | ||||
| 
 | ||||
|  | @ -216,8 +220,8 @@ namespace | |||
|         void insert(AddObject&& addObject); | ||||
|     }; | ||||
| 
 | ||||
|     InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener) | ||||
|     : mCell (cell), mLoadingListener (loadingListener) | ||||
|     InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener, bool test) | ||||
|     : mCell (cell), mLoadingListener (loadingListener), mTest(test) | ||||
|     {} | ||||
| 
 | ||||
|     bool InsertVisitor::operator() (const MWWorld::Ptr& ptr) | ||||
|  | @ -246,7 +250,8 @@ namespace | |||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             mLoadingListener.increaseProgress (1); | ||||
|             if (!mTest) | ||||
|                 mLoadingListener.increaseProgress (1); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -317,9 +322,10 @@ namespace MWWorld | |||
|         mPreloader->updateCache(mRendering.getReferenceTime()); | ||||
|     } | ||||
| 
 | ||||
|     void Scene::unloadCell (CellStoreCollection::iterator iter) | ||||
|     void Scene::unloadCell (CellStoreCollection::iterator iter, bool test) | ||||
|     { | ||||
|         Log(Debug::Info) << "Unloading cell " << (*iter)->getCell()->getDescription(); | ||||
|         if (!test) | ||||
|             Log(Debug::Info) << "Unloading cell " << (*iter)->getCell()->getDescription(); | ||||
| 
 | ||||
|         const auto navigator = MWBase::Environment::get().getWorld()->getNavigator(); | ||||
|         ListAndResetObjectsVisitor visitor; | ||||
|  | @ -373,13 +379,16 @@ namespace MWWorld | |||
|         mActiveCells.erase(*iter); | ||||
|     } | ||||
| 
 | ||||
|     void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn) | ||||
|     void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn, bool test) | ||||
|     { | ||||
|         std::pair<CellStoreCollection::iterator, bool> result = mActiveCells.insert(cell); | ||||
| 
 | ||||
|         if(result.second) | ||||
|         { | ||||
|             Log(Debug::Info) << "Loading cell " << cell->getCell()->getDescription(); | ||||
|             if (test) | ||||
|                 Log(Debug::Info) << "Testing cell " << cell->getCell()->getDescription(); | ||||
|             else | ||||
|                 Log(Debug::Info) << "Loading cell " << cell->getCell()->getDescription(); | ||||
| 
 | ||||
|             float verts = ESM::Land::LAND_SIZE; | ||||
|             float worldsize = ESM::Land::REAL_SIZE; | ||||
|  | @ -390,7 +399,7 @@ namespace MWWorld | |||
|             const int cellY = cell->getCell()->getGridY(); | ||||
| 
 | ||||
|             // Load terrain physics first...
 | ||||
|             if (cell->getCell()->isExterior()) | ||||
|             if (!test && cell->getCell()->isExterior()) | ||||
|             { | ||||
|                 osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellX, cellY); | ||||
|                 const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : 0; | ||||
|  | @ -418,38 +427,44 @@ namespace MWWorld | |||
|                 cell->respawn(); | ||||
| 
 | ||||
|             // ... then references. This is important for adjustPosition to work correctly.
 | ||||
|             insertCell (*cell, loadingListener); | ||||
|             insertCell (*cell, loadingListener, test); | ||||
| 
 | ||||
|             mRendering.addCell(cell); | ||||
|             MWBase::Environment::get().getWindowManager()->addCell(cell); | ||||
|             bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior(); | ||||
|             float waterLevel = cell->getWaterLevel(); | ||||
|             mRendering.setWaterEnabled(waterEnabled); | ||||
|             if (waterEnabled) | ||||
|             if (!test) | ||||
|             { | ||||
|                 mPhysics->enableWater(waterLevel); | ||||
|                 mRendering.setWaterHeight(waterLevel); | ||||
| 
 | ||||
|                 if (cell->getCell()->isExterior()) | ||||
|                 MWBase::Environment::get().getWindowManager()->addCell(cell); | ||||
|                 bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior(); | ||||
|                 float waterLevel = cell->getWaterLevel(); | ||||
|                 mRendering.setWaterEnabled(waterEnabled); | ||||
|                 if (waterEnabled) | ||||
|                 { | ||||
|                     if (const auto heightField = mPhysics->getHeightField(cellX, cellY)) | ||||
|                         navigator->addWater(osg::Vec2i(cellX, cellY), ESM::Land::REAL_SIZE, | ||||
|                             cell->getWaterLevel(), heightField->getCollisionObject()->getWorldTransform()); | ||||
|                     mPhysics->enableWater(waterLevel); | ||||
|                     mRendering.setWaterHeight(waterLevel); | ||||
| 
 | ||||
|                     if (cell->getCell()->isExterior()) | ||||
|                     { | ||||
|                         if (const auto heightField = mPhysics->getHeightField(cellX, cellY)) | ||||
|                             navigator->addWater(osg::Vec2i(cellX, cellY), ESM::Land::REAL_SIZE, | ||||
|                                 cell->getWaterLevel(), heightField->getCollisionObject()->getWorldTransform()); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         navigator->addWater(osg::Vec2i(cellX, cellY), std::numeric_limits<int>::max(), | ||||
|                             cell->getWaterLevel(), btTransform::getIdentity()); | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                     mPhysics->disableWater(); | ||||
| 
 | ||||
|                 const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr(); | ||||
|                 navigator->update(player.getRefData().getPosition().asVec3()); | ||||
| 
 | ||||
|                 if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx)) | ||||
|                 { | ||||
|                     navigator->addWater(osg::Vec2i(cellX, cellY), std::numeric_limits<int>::max(), | ||||
|                         cell->getWaterLevel(), btTransform::getIdentity()); | ||||
| 
 | ||||
|                     mRendering.configureAmbient(cell->getCell()); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|                 mPhysics->disableWater(); | ||||
| 
 | ||||
|             const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr(); | ||||
|             navigator->update(player.getRefData().getPosition().asVec3()); | ||||
| 
 | ||||
|             if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx)) | ||||
|                 mRendering.configureAmbient(cell->getCell()); | ||||
|         } | ||||
| 
 | ||||
|         mPreloader->notifyLoaded(cell); | ||||
|  | @ -594,6 +609,101 @@ namespace MWWorld | |||
|             mCellChanged = true; | ||||
|     } | ||||
| 
 | ||||
|     void Scene::testExteriorCells() | ||||
|     { | ||||
|         // Note: temporary disable ICO to decrease memory usage
 | ||||
|         mRendering.getResourceSystem()->getSceneManager()->setIncrementalCompileOperation(nullptr); | ||||
| 
 | ||||
|         mRendering.getResourceSystem()->setExpiryDelay(1.f); | ||||
| 
 | ||||
|         const MWWorld::Store<ESM::Cell> &cells = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>(); | ||||
| 
 | ||||
|         Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); | ||||
|         Loading::ScopedLoad load(loadingListener); | ||||
|         loadingListener->setProgressRange(cells.getExtSize()); | ||||
| 
 | ||||
|         MWWorld::Store<ESM::Cell>::iterator it = cells.extBegin(); | ||||
|         int i = 1; | ||||
|         for (; it != cells.extEnd(); ++it) | ||||
|         { | ||||
|             loadingListener->setLabel("Testing exterior cells ("+std::to_string(i)+"/"+std::to_string(cells.getExtSize())+")..."); | ||||
| 
 | ||||
|             CellStoreCollection::iterator iter = mActiveCells.begin(); | ||||
| 
 | ||||
|             CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(it->mData.mX, it->mData.mY); | ||||
|             loadCell (cell, loadingListener, false, true); | ||||
| 
 | ||||
|             iter = mActiveCells.begin(); | ||||
|             while (iter != mActiveCells.end()) | ||||
|             { | ||||
|                 if (it->isExterior() && it->mData.mX == (*iter)->getCell()->getGridX() && | ||||
|                     it->mData.mY == (*iter)->getCell()->getGridY()) | ||||
|                 { | ||||
|                     unloadCell(iter, true); | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 ++iter; | ||||
|             } | ||||
| 
 | ||||
|             mRendering.getResourceSystem()->updateCache(mRendering.getReferenceTime()); | ||||
|             mRendering.getUnrefQueue()->flush(mRendering.getWorkQueue()); | ||||
| 
 | ||||
|             loadingListener->increaseProgress (1); | ||||
|             i++; | ||||
|         } | ||||
| 
 | ||||
|         mRendering.getResourceSystem()->getSceneManager()->setIncrementalCompileOperation(mRendering.getIncrementalCompileOperation()); | ||||
|         mRendering.getResourceSystem()->setExpiryDelay(Settings::Manager::getFloat("cache expiry delay", "Cells")); | ||||
|     } | ||||
| 
 | ||||
|     void Scene::testInteriorCells() | ||||
|     { | ||||
|         // Note: temporary disable ICO to decrease memory usage
 | ||||
|         mRendering.getResourceSystem()->getSceneManager()->setIncrementalCompileOperation(nullptr); | ||||
| 
 | ||||
|         mRendering.getResourceSystem()->setExpiryDelay(1.f); | ||||
| 
 | ||||
|         const MWWorld::Store<ESM::Cell> &cells = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>(); | ||||
| 
 | ||||
|         Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); | ||||
|         Loading::ScopedLoad load(loadingListener); | ||||
|         loadingListener->setProgressRange(cells.getIntSize()); | ||||
| 
 | ||||
|         int i = 1; | ||||
|         MWWorld::Store<ESM::Cell>::iterator it = cells.intBegin(); | ||||
|         for (; it != cells.intEnd(); ++it) | ||||
|         { | ||||
|             loadingListener->setLabel("Testing interior cells ("+std::to_string(i)+"/"+std::to_string(cells.getIntSize())+")..."); | ||||
| 
 | ||||
|             CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(it->mName); | ||||
|             loadCell (cell, loadingListener, false, true); | ||||
| 
 | ||||
|             CellStoreCollection::iterator iter = mActiveCells.begin(); | ||||
|             while (iter != mActiveCells.end()) | ||||
|             { | ||||
|                 assert (!(*iter)->getCell()->isExterior()); | ||||
| 
 | ||||
|                 if (it->mName == (*iter)->getCell()->mName) | ||||
|                 { | ||||
|                     unloadCell(iter, true); | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 ++iter; | ||||
|             } | ||||
| 
 | ||||
|             mRendering.getResourceSystem()->updateCache(mRendering.getReferenceTime()); | ||||
|             mRendering.getUnrefQueue()->flush(mRendering.getWorkQueue()); | ||||
| 
 | ||||
|             loadingListener->increaseProgress (1); | ||||
|             i++; | ||||
|         } | ||||
| 
 | ||||
|         mRendering.getResourceSystem()->getSceneManager()->setIncrementalCompileOperation(mRendering.getIncrementalCompileOperation()); | ||||
|         mRendering.getResourceSystem()->setExpiryDelay(Settings::Manager::getFloat("cache expiry delay", "Cells")); | ||||
|     } | ||||
| 
 | ||||
|     void Scene::changePlayerCell(CellStore *cell, const ESM::Position &pos, bool adjustPlayerPos) | ||||
|     { | ||||
|         mCurrentCell = cell; | ||||
|  | @ -759,9 +869,9 @@ namespace MWWorld | |||
|         mCellChanged = false; | ||||
|     } | ||||
| 
 | ||||
|     void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener) | ||||
|     void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener, bool test) | ||||
|     { | ||||
|         InsertVisitor insertVisitor (cell, *loadingListener); | ||||
|         InsertVisitor insertVisitor (cell, *loadingListener, test); | ||||
|         cell.forEach (insertVisitor); | ||||
|         insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mRendering); }); | ||||
|         insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); }); | ||||
|  |  | |||
|  | @ -85,7 +85,7 @@ namespace MWWorld | |||
| 
 | ||||
|             osg::Vec3f mLastPlayerPos; | ||||
| 
 | ||||
|             void insertCell (CellStore &cell, Loading::Listener* loadingListener); | ||||
|             void insertCell (CellStore &cell, Loading::Listener* loadingListener, bool test = false); | ||||
| 
 | ||||
|             // Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
 | ||||
|             void changeCellGrid (int playerCellX, int playerCellY, bool changeEvent = true); | ||||
|  | @ -107,9 +107,9 @@ namespace MWWorld | |||
|             void preloadCell(MWWorld::CellStore* cell, bool preloadSurrounding=false); | ||||
|             void preloadTerrain(const osg::Vec3f& pos); | ||||
| 
 | ||||
|             void unloadCell (CellStoreCollection::iterator iter); | ||||
|             void unloadCell (CellStoreCollection::iterator iter, bool test = false); | ||||
| 
 | ||||
|             void loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn); | ||||
|             void loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn, bool test = false); | ||||
| 
 | ||||
|             void playerMoved (const osg::Vec3f& pos); | ||||
| 
 | ||||
|  | @ -151,6 +151,9 @@ namespace MWWorld | |||
|             Ptr searchPtrViaActorId (int actorId); | ||||
| 
 | ||||
|             void preload(const std::string& mesh, bool useAnim=false); | ||||
| 
 | ||||
|             void testExteriorCells(); | ||||
|             void testInteriorCells(); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -792,6 +792,14 @@ namespace MWWorld | |||
|     { | ||||
|         return mSharedInt.size() + mSharedExt.size(); | ||||
|     } | ||||
|     size_t Store<ESM::Cell>::getExtSize() const | ||||
|     { | ||||
|         return mSharedExt.size(); | ||||
|     } | ||||
|     size_t Store<ESM::Cell>::getIntSize() const | ||||
|     { | ||||
|         return mSharedInt.size(); | ||||
|     } | ||||
|     void Store<ESM::Cell>::listIdentifier(std::vector<std::string> &list) const | ||||
|     { | ||||
|         list.reserve(list.size() + mSharedInt.size()); | ||||
|  |  | |||
|  | @ -314,6 +314,8 @@ namespace MWWorld | |||
|         const ESM::Cell *searchExtByRegion(const std::string &id) const; | ||||
| 
 | ||||
|         size_t getSize() const; | ||||
|         size_t getExtSize() const; | ||||
|         size_t getIntSize() const; | ||||
| 
 | ||||
|         void listIdentifier(std::vector<std::string> &list) const; | ||||
| 
 | ||||
|  |  | |||
|  | @ -586,6 +586,16 @@ namespace MWWorld | |||
|             return getInterior (id.mWorldspace); | ||||
|     } | ||||
| 
 | ||||
|     void World::testExteriorCells() | ||||
|     { | ||||
|         mWorldScene->testExteriorCells(); | ||||
|     } | ||||
| 
 | ||||
|     void World::testInteriorCells() | ||||
|     { | ||||
|         mWorldScene->testInteriorCells(); | ||||
|     } | ||||
| 
 | ||||
|     void World::useDeathCamera() | ||||
|     { | ||||
|         if(mRendering->getCamera()->isVanityOrPreviewModeEnabled() ) | ||||
|  |  | |||
|  | @ -223,6 +223,9 @@ namespace MWWorld | |||
| 
 | ||||
|             CellStore *getCell (const ESM::CellId& id) override; | ||||
| 
 | ||||
|             void testExteriorCells() override; | ||||
|             void testInteriorCells() override; | ||||
| 
 | ||||
|             //switch to POV before showing player's death animation
 | ||||
|             void useDeathCamera() override; | ||||
| 
 | ||||
|  |  | |||
|  | @ -89,6 +89,8 @@ namespace Compiler | |||
|         void registerExtensions (Extensions& extensions) | ||||
|         { | ||||
|             extensions.registerFunction ("cellchanged", 'l', "", opcodeCellChanged); | ||||
|             extensions.registerInstruction("testcells", "", opcodeTestCells); | ||||
|             extensions.registerInstruction("testinteriorcells", "", opcodeTestInteriorCells); | ||||
|             extensions.registerInstruction ("coc", "S", opcodeCOC); | ||||
|             extensions.registerInstruction ("centeroncell", "S", opcodeCOC); | ||||
|             extensions.registerInstruction ("coe", "ll", opcodeCOE); | ||||
|  |  | |||
|  | @ -75,6 +75,8 @@ namespace Compiler | |||
|     namespace Cell | ||||
|     { | ||||
|         const int opcodeCellChanged = 0x2000000; | ||||
|         const int opcodeTestCells = 0x200030e; | ||||
|         const int opcodeTestInteriorCells = 0x200030f; | ||||
|         const int opcodeCOC = 0x2000026; | ||||
|         const int opcodeCOE = 0x2000226; | ||||
|         const int opcodeGetInterior = 0x2000131; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue