mapsector.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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. m_parent(parent),
  22. m_pos(pos),
  23. m_gamedef(gamedef)
  24. {
  25. }
  26. MapSector::~MapSector()
  27. {
  28. deleteBlocks();
  29. }
  30. void MapSector::deleteBlocks()
  31. {
  32. // Clear cache
  33. m_block_cache = nullptr;
  34. // Delete all
  35. for (auto &block : m_blocks) {
  36. delete block.second;
  37. }
  38. // Clear container
  39. m_blocks.clear();
  40. }
  41. MapBlock * MapSector::getBlockBuffered(s16 y)
  42. {
  43. MapBlock *block;
  44. if (m_block_cache && y == m_block_cache_y) {
  45. return m_block_cache;
  46. }
  47. // If block doesn't exist, return NULL
  48. std::unordered_map<s16, MapBlock*>::const_iterator n = m_blocks.find(y);
  49. block = (n != m_blocks.end() ? n->second : nullptr);
  50. // Cache the last result
  51. m_block_cache_y = y;
  52. m_block_cache = block;
  53. return block;
  54. }
  55. MapBlock * MapSector::getBlockNoCreateNoEx(s16 y)
  56. {
  57. return getBlockBuffered(y);
  58. }
  59. MapBlock * MapSector::createBlankBlockNoInsert(s16 y)
  60. {
  61. assert(getBlockBuffered(y) == NULL); // Pre-condition
  62. v3s16 blockpos_map(m_pos.X, y, m_pos.Y);
  63. MapBlock *block = new MapBlock(m_parent, blockpos_map, m_gamedef);
  64. return block;
  65. }
  66. MapBlock * MapSector::createBlankBlock(s16 y)
  67. {
  68. MapBlock *block = createBlankBlockNoInsert(y);
  69. m_blocks[y] = block;
  70. return block;
  71. }
  72. void MapSector::insertBlock(MapBlock *block)
  73. {
  74. s16 block_y = block->getPos().Y;
  75. MapBlock *block2 = getBlockBuffered(block_y);
  76. if (block2) {
  77. throw AlreadyExistsException("Block already exists");
  78. }
  79. v2s16 p2d(block->getPos().X, block->getPos().Z);
  80. assert(p2d == m_pos);
  81. // Insert into container
  82. m_blocks[block_y] = block;
  83. }
  84. void MapSector::deleteBlock(MapBlock *block)
  85. {
  86. s16 block_y = block->getPos().Y;
  87. // Clear from cache
  88. m_block_cache = nullptr;
  89. // Remove from container
  90. m_blocks.erase(block_y);
  91. // Delete
  92. delete block;
  93. }
  94. void MapSector::getBlocks(MapBlockVect &dest)
  95. {
  96. for (auto &block : m_blocks) {
  97. dest.push_back(block.second);
  98. }
  99. }