ChunkMap.cpp 5.6 KB

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