mapsector.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "mapsector.h"
  17. #include "exceptions.h"
  18. #include "mapblock.h"
  19. #include "serialization.h"
  20. MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
  21. differs_from_disk(false),
  22. m_parent(parent),
  23. m_pos(pos),
  24. m_gamedef(gamedef),
  25. m_block_cache(NULL)
  26. {
  27. }
  28. MapSector::~MapSector()
  29. {
  30. deleteBlocks();
  31. }
  32. void MapSector::deleteBlocks()
  33. {
  34. // Clear cache
  35. m_block_cache = NULL;
  36. // Delete all
  37. for(std::map<s16, MapBlock*>::iterator i = m_blocks.begin();
  38. i != m_blocks.end(); ++i)
  39. {
  40. delete i->second;
  41. }
  42. // Clear container
  43. m_blocks.clear();
  44. }
  45. MapBlock * MapSector::getBlockBuffered(s16 y)
  46. {
  47. MapBlock *block;
  48. if(m_block_cache != NULL && y == m_block_cache_y){
  49. return m_block_cache;
  50. }
  51. // If block doesn't exist, return NULL
  52. std::map<s16, MapBlock*>::iterator n = m_blocks.find(y);
  53. if(n == m_blocks.end())
  54. {
  55. block = NULL;
  56. }
  57. // If block exists, return it
  58. else{
  59. block = n->second;
  60. }
  61. // Cache the last result
  62. m_block_cache_y = y;
  63. m_block_cache = block;
  64. return block;
  65. }
  66. MapBlock * MapSector::getBlockNoCreateNoEx(s16 y)
  67. {
  68. return getBlockBuffered(y);
  69. }
  70. MapBlock * MapSector::createBlankBlockNoInsert(s16 y)
  71. {
  72. assert(getBlockBuffered(y) == NULL);
  73. v3s16 blockpos_map(m_pos.X, y, m_pos.Y);
  74. MapBlock *block = new MapBlock(m_parent, blockpos_map, m_gamedef);
  75. return block;
  76. }
  77. MapBlock * MapSector::createBlankBlock(s16 y)
  78. {
  79. MapBlock *block = createBlankBlockNoInsert(y);
  80. m_blocks[y] = block;
  81. return block;
  82. }
  83. void MapSector::insertBlock(MapBlock *block)
  84. {
  85. s16 block_y = block->getPos().Y;
  86. MapBlock *block2 = getBlockBuffered(block_y);
  87. if(block2 != NULL){
  88. throw AlreadyExistsException("Block already exists");
  89. }
  90. v2s16 p2d(block->getPos().X, block->getPos().Z);
  91. assert(p2d == m_pos);
  92. // Insert into container
  93. m_blocks[block_y] = block;
  94. }
  95. void MapSector::deleteBlock(MapBlock *block)
  96. {
  97. s16 block_y = block->getPos().Y;
  98. // Clear from cache
  99. m_block_cache = NULL;
  100. // Remove from container
  101. m_blocks.erase(block_y);
  102. // Delete
  103. delete block;
  104. }
  105. void MapSector::getBlocks(std::list<MapBlock*> &dest)
  106. {
  107. for(std::map<s16, MapBlock*>::iterator bi = m_blocks.begin();
  108. bi != m_blocks.end(); ++bi)
  109. {
  110. dest.push_back(bi->second);
  111. }
  112. }
  113. /*
  114. ServerMapSector
  115. */
  116. ServerMapSector::ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
  117. MapSector(parent, pos, gamedef)
  118. {
  119. }
  120. ServerMapSector::~ServerMapSector()
  121. {
  122. }
  123. void ServerMapSector::serialize(std::ostream &os, u8 version)
  124. {
  125. if(!ser_ver_supported(version))
  126. throw VersionMismatchException("ERROR: MapSector format not supported");
  127. /*
  128. [0] u8 serialization version
  129. + heightmap data
  130. */
  131. // Server has both of these, no need to support not having them.
  132. //assert(m_objects != NULL);
  133. // Write version
  134. os.write((char*)&version, 1);
  135. /*
  136. Add stuff here, if needed
  137. */
  138. }
  139. ServerMapSector* ServerMapSector::deSerialize(
  140. std::istream &is,
  141. Map *parent,
  142. v2s16 p2d,
  143. std::map<v2s16, MapSector*> & sectors,
  144. IGameDef *gamedef
  145. )
  146. {
  147. /*
  148. [0] u8 serialization version
  149. + heightmap data
  150. */
  151. /*
  152. Read stuff
  153. */
  154. // Read version
  155. u8 version = SER_FMT_VER_INVALID;
  156. is.read((char*)&version, 1);
  157. if(!ser_ver_supported(version))
  158. throw VersionMismatchException("ERROR: MapSector format not supported");
  159. /*
  160. Add necessary reading stuff here
  161. */
  162. /*
  163. Get or create sector
  164. */
  165. ServerMapSector *sector = NULL;
  166. std::map<v2s16, MapSector*>::iterator n = sectors.find(p2d);
  167. if(n != sectors.end())
  168. {
  169. dstream<<"WARNING: deSerializing existent sectors not supported "
  170. "at the moment, because code hasn't been tested."
  171. <<std::endl;
  172. MapSector *sector = n->second;
  173. assert(sector->getId() == MAPSECTOR_SERVER);
  174. return (ServerMapSector*)sector;
  175. }
  176. else
  177. {
  178. sector = new ServerMapSector(parent, p2d, gamedef);
  179. sectors[p2d] = sector;
  180. }
  181. /*
  182. Set stuff in sector
  183. */
  184. // Nothing here
  185. return sector;
  186. }
  187. #ifndef SERVER
  188. /*
  189. ClientMapSector
  190. */
  191. ClientMapSector::ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
  192. MapSector(parent, pos, gamedef)
  193. {
  194. }
  195. ClientMapSector::~ClientMapSector()
  196. {
  197. }
  198. #endif // !SERVER
  199. //END