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 playVideo(const std::string& name, bool allowSkipping) = 0; | ||||||
|             virtual void stopVideo() = 0; |             virtual void stopVideo() = 0; | ||||||
|             virtual void frameStarted (float dt) = 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: |             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) |                 virtual void execute (Interpreter::Runtime& runtime) | ||||||
|                 { |                 { | ||||||
|                     std::string cell = runtime.getStringLiteral (runtime[0].mInteger); |                     std::string cell = runtime.getStringLiteral (runtime[0].mInteger); | ||||||
|  | @ -116,13 +42,13 @@ namespace MWScript | ||||||
|                     ESM::Position pos; |                     ESM::Position pos; | ||||||
|                     MWBase::World *world = MWBase::Environment::get().getWorld(); |                     MWBase::World *world = MWBase::Environment::get().getWorld(); | ||||||
| 
 | 
 | ||||||
|                     if (findExteriorPosition(cell, pos)) { |                     if (world->findExteriorPosition(cell, pos)) { | ||||||
|                         world->changeToExteriorCell(pos); |                         world->changeToExteriorCell(pos); | ||||||
|                     } |                     } | ||||||
|                     else { |                     else { | ||||||
|                         // Change to interior even if findInteriorPosition()
 |                         // Change to interior even if findInteriorPosition()
 | ||||||
|                         // yields false. In this case position will be zero-point.
 |                         // yields false. In this case position will be zero-point.
 | ||||||
|                         findInteriorPosition(cell, pos); |                         world->findInteriorPosition(cell, pos); | ||||||
|                         world->changeToInteriorCell(cell, pos); |                         world->changeToInteriorCell(cell, pos); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -1765,4 +1765,80 @@ namespace MWWorld | ||||||
|             physicActor->disableCollisionBody(); |             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 playVideo(const std::string& name, bool allowSkipping); | ||||||
|             virtual void stopVideo(); |             virtual void stopVideo(); | ||||||
|             virtual void frameStarted (float dt); |             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