mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-25 11:26:37 +00:00 
			
		
		
		
	move finding default cell positions to World
This commit is contained in:
		
							parent
							
								
									0c303aa285
								
							
						
					
					
						commit
						f3d54a7ba4
					
				
					 4 changed files with 94 additions and 76 deletions
				
			
		|  | @ -363,6 +363,14 @@ namespace MWBase | |||
|             virtual void playVideo(const std::string& name, bool allowSkipping) = 0; | ||||
|             virtual void stopVideo() = 0; | ||||
|             virtual void frameStarted (float dt) = 0; | ||||
| 
 | ||||
|             /// Find default position inside exterior cell specified by name
 | ||||
|             /// \return false if exterior with given name not exists, true otherwise
 | ||||
|             virtual bool findExteriorPosition(const std::string &name, ESM::Position &pos) = 0; | ||||
| 
 | ||||
|             /// Find default position inside interior cell specified by name
 | ||||
|             /// \return false if interior with given name not exists, true otherwise
 | ||||
|             virtual bool findInteriorPosition(const std::string &name, ESM::Position &pos) = 0; | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,80 +34,6 @@ namespace MWScript | |||
|         { | ||||
|             public: | ||||
| 
 | ||||
|                 static bool findInteriorPosition(const std::string &name, ESM::Position &pos) | ||||
|                 { | ||||
|                     typedef MWWorld::CellRefList<ESM::Door>::List DoorList; | ||||
| 
 | ||||
|                     pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; | ||||
|                     pos.pos[0] = pos.pos[1] = pos.pos[2] = 0; | ||||
| 
 | ||||
|                     MWBase::World *world = MWBase::Environment::get().getWorld(); | ||||
|                     MWWorld::CellStore *cellStore = world->getInterior(name); | ||||
| 
 | ||||
|                     if (0 == cellStore) { | ||||
|                         return false; | ||||
|                     } | ||||
|                     const DoorList &doors = cellStore->mDoors.mList; | ||||
|                     for (DoorList::const_iterator it = doors.begin(); it != doors.end(); ++it) { | ||||
|                         if (!it->mRef.mTeleport) { | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         MWWorld::CellStore *source = 0; | ||||
| 
 | ||||
|                         // door to exterior
 | ||||
|                         if (it->mRef.mDestCell.empty()) { | ||||
|                             int x, y; | ||||
|                             const float *pos = it->mRef.mDoorDest.pos; | ||||
|                             world->positionToIndex(pos[0], pos[1], x, y); | ||||
|                             source = world->getExterior(x, y); | ||||
|                         } | ||||
|                         // door to interior
 | ||||
|                         else { | ||||
|                             source = world->getInterior(it->mRef.mDestCell); | ||||
|                         } | ||||
|                         if (0 != source) { | ||||
|                             // Find door leading to our current teleport door
 | ||||
|                             // and use it destination to position inside cell.
 | ||||
|                             const DoorList &doors = source->mDoors.mList; | ||||
|                             for (DoorList::const_iterator jt = doors.begin(); jt != doors.end(); ++jt) { | ||||
|                                 if (it->mRef.mTeleport && | ||||
|                                     Misc::StringUtils::ciEqual(name, jt->mRef.mDestCell)) | ||||
|                                 { | ||||
|                                     /// \note Using _any_ door pointed to the interior,
 | ||||
|                                     /// not the one pointed to current door.
 | ||||
|                                     pos = jt->mRef.mDoorDest; | ||||
|                                     return true; | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     return false; | ||||
|                 } | ||||
| 
 | ||||
|                 static bool findExteriorPosition(const std::string &name, ESM::Position &pos) | ||||
|                 { | ||||
|                     pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; | ||||
|                     MWBase::World *world = MWBase::Environment::get().getWorld(); | ||||
| 
 | ||||
|                     if (const ESM::Cell *ext = world->getExterior(name)) { | ||||
|                         int x = ext->getGridX(); | ||||
|                         int y = ext->getGridY(); | ||||
|                         world->indexToPosition(x, y, pos.pos[0], pos.pos[1], true); | ||||
| 
 | ||||
|                         ESM::Land* land = | ||||
|                             world->getStore().get<ESM::Land>().search(x, y); | ||||
|                         assert(land && "Correctly found exteriors must have land data"); | ||||
|                         if (!land->isDataLoaded(ESM::Land::DATA_VHGT)) { | ||||
|                             land->loadData(ESM::Land::DATA_VHGT); | ||||
|                         } | ||||
|                         pos.pos[2] = land->mLandData->mHeights[ESM::Land::LAND_NUM_VERTS / 2 + 1]; | ||||
| 
 | ||||
|                         return true; | ||||
|                     } | ||||
|                     return false; | ||||
|                 } | ||||
| 
 | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     std::string cell = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|  | @ -116,13 +42,13 @@ namespace MWScript | |||
|                     ESM::Position pos; | ||||
|                     MWBase::World *world = MWBase::Environment::get().getWorld(); | ||||
| 
 | ||||
|                     if (findExteriorPosition(cell, pos)) { | ||||
|                     if (world->findExteriorPosition(cell, pos)) { | ||||
|                         world->changeToExteriorCell(pos); | ||||
|                     } | ||||
|                     else { | ||||
|                         // Change to interior even if findInteriorPosition()
 | ||||
|                         // yields false. In this case position will be zero-point.
 | ||||
|                         findInteriorPosition(cell, pos); | ||||
|                         world->findInteriorPosition(cell, pos); | ||||
|                         world->changeToInteriorCell(cell, pos); | ||||
|                     } | ||||
|                 } | ||||
|  |  | |||
|  | @ -1765,4 +1765,80 @@ namespace MWWorld | |||
|             physicActor->disableCollisionBody(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     bool World::findInteriorPosition(const std::string &name, ESM::Position &pos) | ||||
|     { | ||||
|         typedef MWWorld::CellRefList<ESM::Door>::List DoorList; | ||||
| 
 | ||||
|         pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; | ||||
|         pos.pos[0] = pos.pos[1] = pos.pos[2] = 0; | ||||
| 
 | ||||
|         MWWorld::CellStore *cellStore = getInterior(name); | ||||
| 
 | ||||
|         if (0 == cellStore) { | ||||
|             return false; | ||||
|         } | ||||
|         const DoorList &doors = cellStore->mDoors.mList; | ||||
|         for (DoorList::const_iterator it = doors.begin(); it != doors.end(); ++it) { | ||||
|             if (!it->mRef.mTeleport) { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             MWWorld::CellStore *source = 0; | ||||
| 
 | ||||
|             // door to exterior
 | ||||
|             if (it->mRef.mDestCell.empty()) { | ||||
|                 int x, y; | ||||
|                 const float *pos = it->mRef.mDoorDest.pos; | ||||
|                 positionToIndex(pos[0], pos[1], x, y); | ||||
|                 source = getExterior(x, y); | ||||
|             } | ||||
|             // door to interior
 | ||||
|             else { | ||||
|                 source = getInterior(it->mRef.mDestCell); | ||||
|             } | ||||
|             if (0 != source) { | ||||
|                 // Find door leading to our current teleport door
 | ||||
|                 // and use it destination to position inside cell.
 | ||||
|                 const DoorList &doors = source->mDoors.mList; | ||||
|                 for (DoorList::const_iterator jt = doors.begin(); jt != doors.end(); ++jt) { | ||||
|                     if (it->mRef.mTeleport && | ||||
|                         Misc::StringUtils::ciEqual(name, jt->mRef.mDestCell)) | ||||
|                     { | ||||
|                         /// \note Using _any_ door pointed to the interior,
 | ||||
|                         /// not the one pointed to current door.
 | ||||
|                         pos = jt->mRef.mDoorDest; | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     bool World::findExteriorPosition(const std::string &name, ESM::Position &pos) | ||||
|     { | ||||
|         pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; | ||||
| 
 | ||||
|         if (const ESM::Cell *ext = getExterior(name)) { | ||||
|             int x = ext->getGridX(); | ||||
|             int y = ext->getGridY(); | ||||
|             indexToPosition(x, y, pos.pos[0], pos.pos[1], true); | ||||
| 
 | ||||
|             ESM::Land* land = getStore().get<ESM::Land>().search(x, y); | ||||
|             if (land) { | ||||
|                 if (!land->isDataLoaded(ESM::Land::DATA_VHGT)) { | ||||
|                     land->loadData(ESM::Land::DATA_VHGT); | ||||
|                 } | ||||
|                 pos.pos[2] = land->mLandData->mHeights[ESM::Land::LAND_NUM_VERTS / 2 + 1]; | ||||
|             } | ||||
|             else { | ||||
|                 std::cerr << "Land data for cell at (" << x << ", " << y << ") not found\n"; | ||||
|                 pos.pos[2] = 0; | ||||
|             } | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -412,6 +412,14 @@ namespace MWWorld | |||
|             virtual void playVideo(const std::string& name, bool allowSkipping); | ||||
|             virtual void stopVideo(); | ||||
|             virtual void frameStarted (float dt); | ||||
| 
 | ||||
|             /// Find center of exterior cell above land surface
 | ||||
|             /// \return false if exterior with given name not exists, true otherwise
 | ||||
|             virtual bool findExteriorPosition(const std::string &name, ESM::Position &pos); | ||||
| 
 | ||||
|             /// Find position in interior cell near door entrance
 | ||||
|             /// \return false if interior with given name not exists, true otherwise
 | ||||
|             virtual bool findInteriorPosition(const std::string &name, ESM::Position &pos); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue