ChunkMap.cpp 4.6 KB

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