ChunkMap.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include "ChunkMap.h"
  2. #include "Chunk.h"
  3. #include "Constants.h"
  4. ChunkMap::ChunkMap(Framework::Punkt chunkCenter)
  5. : ReferenceCounter(),
  6. chunkCenter(chunkCenter)
  7. {
  8. pixels = new MapPixel[CHUNK_SIZE * CHUNK_SIZE];
  9. memset(pixels, 0, sizeof(MapPixel) * CHUNK_SIZE * CHUNK_SIZE);
  10. }
  11. ChunkMap::ChunkMap(Chunk* zChunk)
  12. : ReferenceCounter(),
  13. chunkCenter(zChunk->location)
  14. {
  15. pixels = new MapPixel[CHUNK_SIZE * CHUNK_SIZE];
  16. memset(pixels, 0, sizeof(MapPixel) * CHUNK_SIZE * CHUNK_SIZE);
  17. MapBlock blocksBuffer[256];
  18. for (int x = 0; x < CHUNK_SIZE; x++)
  19. {
  20. for (int y = 0; y < CHUNK_SIZE; y++)
  21. {
  22. int count = 0;
  23. bool visible = 1;
  24. for (int height = WORLD_HEIGHT / 2 - 1; height >= 0; height--)
  25. {
  26. int index = x * CHUNK_SIZE + y;
  27. const Block* block1
  28. = CONST_BLOCK(zChunk->blocks[height * 2]
  29. ? zChunk->blocks[height * 2][index]
  30. : 0,
  31. zChunk->blockIds[height * 2]
  32. ? zChunk->blockIds[height * 2][index]
  33. : 0);
  34. const Block* block2
  35. = CONST_BLOCK(zChunk->blocks[height * 2 + 1]
  36. ? zChunk->blocks[height * 2 + 1][index]
  37. : 0,
  38. zChunk->blockIds[height * 2 + 1]
  39. ? zChunk->blockIds[height * 2 + 1][index]
  40. : 0);
  41. int color1 = 0;
  42. int color2 = 0;
  43. if (visible) color2 = block2->getMapColor();
  44. visible = block2->isPassable() || block2->isTransparent();
  45. if (visible) color1 = block1->getMapColor();
  46. visible = block1->isPassable() || block1->isTransparent();
  47. if (color1 || color2)
  48. {
  49. MapBlock tmp = {(unsigned char)height,
  50. ((color1 >> 24) & 0xFF) > ((color2 >> 24) & 0xFF)
  51. ? color1
  52. : color2};
  53. blocksBuffer[256 - ++count] = tmp;
  54. }
  55. }
  56. int i = x * CHUNK_SIZE + y;
  57. pixels[i].blocks = new MapBlock[count];
  58. memcpy(pixels[i].blocks,
  59. blocksBuffer + 256 - count,
  60. sizeof(MapBlock) * count);
  61. pixels[i].len = (unsigned char)count;
  62. }
  63. }
  64. }
  65. ChunkMap::ChunkMap(Framework::StreamReader* zReader)
  66. : ReferenceCounter()
  67. {
  68. zReader->lese((char*)&chunkCenter.x, 4);
  69. zReader->lese((char*)&chunkCenter.y, 4);
  70. pixels = new MapPixel[CHUNK_SIZE * CHUNK_SIZE];
  71. memset(pixels, 0, sizeof(MapPixel) * CHUNK_SIZE * CHUNK_SIZE);
  72. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE; i++)
  73. {
  74. zReader->lese((char*)&pixels[i].len, 1);
  75. if (pixels[i].len > 0)
  76. {
  77. pixels[i].blocks = new MapBlock[pixels[i].len];
  78. zReader->lese(
  79. (char*)pixels[i].blocks, (int)sizeof(MapBlock) * pixels[i].len);
  80. }
  81. }
  82. }
  83. ChunkMap::~ChunkMap()
  84. {
  85. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE; i++)
  86. {
  87. delete[] pixels[i].blocks;
  88. }
  89. delete[] pixels;
  90. }
  91. bool ChunkMap::update(
  92. char x, char y, unsigned char height, int color1, int color2)
  93. {
  94. cs.lock();
  95. int index = x * CHUNK_SIZE + y;
  96. bool found = 0;
  97. int resultColor
  98. = ((color1 >> 24) & 0xFF) > ((color2 >> 24) & 0xFF) ? color1 : color2;
  99. bool removed = !((resultColor >> 24) & 0xFF);
  100. bool changed = 0;
  101. for (int i = 0; i < pixels[index].len; i++)
  102. {
  103. if (pixels[index].blocks[i].height == height)
  104. {
  105. changed = pixels[index].blocks[i].color != resultColor;
  106. pixels[index].blocks[i].color = resultColor;
  107. found = 1;
  108. }
  109. else if (!found && pixels[index].blocks[i].height > height)
  110. {
  111. break;
  112. }
  113. if (found && removed && i < pixels[index].len - 1)
  114. {
  115. pixels[index].blocks[i] = pixels[index].blocks[i + 1];
  116. }
  117. }
  118. if (found && removed)
  119. {
  120. changed = 1;
  121. pixels[index].len--;
  122. }
  123. else if (!found && !removed)
  124. {
  125. MapBlock* blocks = new MapBlock[pixels[index].len + 1];
  126. bool added = 0;
  127. for (int i = 0; i < pixels[index].len; i++)
  128. {
  129. if (pixels[index].blocks[i].height < height)
  130. {
  131. blocks[i] = pixels[index].blocks[i];
  132. }
  133. else
  134. {
  135. if (!added)
  136. {
  137. blocks[i] = {height, resultColor};
  138. added = 1;
  139. }
  140. blocks[i + 1] = pixels[index].blocks[i];
  141. }
  142. }
  143. if (!added)
  144. {
  145. blocks[pixels[index].len] = {height, resultColor};
  146. }
  147. changed = 1;
  148. pixels[index].len++;
  149. delete[] pixels[index].blocks;
  150. pixels[index].blocks = blocks;
  151. }
  152. cs.unlock();
  153. return changed;
  154. }
  155. void ChunkMap::writeTo(Framework::StreamWriter* zWriter) const
  156. {
  157. zWriter->schreibe((char*)&chunkCenter.x, 4);
  158. zWriter->schreibe((char*)&chunkCenter.y, 4);
  159. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE; i++)
  160. {
  161. zWriter->schreibe((char*)&pixels[i].len, 1);
  162. if (pixels[i].len > 0)
  163. {
  164. zWriter->schreibe(
  165. (char*)pixels[i].blocks, (int)sizeof(MapBlock) * pixels[i].len);
  166. }
  167. }
  168. }
  169. Framework::Punkt ChunkMap::getChunkCenter() const
  170. {
  171. return chunkCenter;
  172. }