Chunk.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include "Chunk.h"
  2. #include "Constants.h"
  3. #include "Globals.h"
  4. #include "Registries.h"
  5. Chunk::Chunk(Framework::Punkt location)
  6. : ReferenceCounter(),
  7. location(location),
  8. isLoading(0)
  9. {}
  10. Chunk::Chunk(Framework::Punkt location, Framework::StreamReader* zReader)
  11. : Chunk(location)
  12. {
  13. load(zReader);
  14. }
  15. Chunk::~Chunk()
  16. {
  17. char msg = 1; // remove observer
  18. network->zFactoryClient()->chunkAPIRequest(location, &msg, 1);
  19. }
  20. void Chunk::api(char* message)
  21. {
  22. switch (message[0])
  23. {
  24. case 0: // set block
  25. {
  26. int index = *(int*)(message + 1);
  27. int id = *(int*)(message + 5);
  28. Framework::Vec3<int> location((index / WORLD_HEIGHT) / CHUNK_SIZE, (index / WORLD_HEIGHT) % CHUNK_SIZE, index % WORLD_HEIGHT);
  29. location.x += this->location.x - CHUNK_SIZE / 2;
  30. location.y += this->location.y - CHUNK_SIZE / 2;
  31. if (blockTypes[id]->doesNeedInstance())
  32. {
  33. Block* zB = blockTypes[id]->createBlock(location);
  34. setBlock(zB);
  35. }
  36. else
  37. {
  38. Block* zB = zBlockAt(location);
  39. if (zB)
  40. removeBlock(zB);
  41. }
  42. break;
  43. }
  44. }
  45. }
  46. Block* Chunk::zBlockAt(Framework::Vec3<int> location)
  47. {
  48. cs.lock();
  49. for (Block* b : blocks)
  50. {
  51. if (Framework::Vec3<int>((int)floor(b->getPos().x), (int)floor(b->getPos().y), (int)floor(b->getPos().z)) == location)
  52. {
  53. cs.unlock();
  54. return b;
  55. }
  56. }
  57. cs.unlock();
  58. return 0;
  59. }
  60. void Chunk::setBlock(Block* block)
  61. {
  62. cs.lock();
  63. Framework::Vec3<int> pos = (Framework::Vec3<int>)block->getPos();
  64. for (Framework::Iterator<Block*> iterator = blocks.begin(); iterator; iterator++)
  65. {
  66. if (pos == (Framework::Vec3<int>)iterator->getPos())
  67. {
  68. iterator->release();
  69. iterator.set(block);
  70. cs.unlock();
  71. return;
  72. }
  73. }
  74. blocks.add(block);
  75. cs.unlock();
  76. if (!isLoading)
  77. updateVisibility();
  78. }
  79. void Chunk::removeBlock(Block* zBlock)
  80. {
  81. cs.lock();
  82. int index = 0;
  83. for (Framework::Iterator<Block*> iterator = blocks.begin(); iterator; iterator++, index++)
  84. {
  85. if (zBlock == (Block*)iterator)
  86. {
  87. blocks.remove(index);
  88. cs.unlock();
  89. if (!isLoading)
  90. updateVisibility();
  91. return;
  92. }
  93. }
  94. cs.unlock();
  95. }
  96. void Chunk::load(Framework::StreamReader* zReader)
  97. {
  98. isLoading = 1;
  99. Framework::Vec3<int> pos = { 0, 0, 0 };
  100. unsigned short id;
  101. zReader->lese((char*)&id, 2);
  102. while (id)
  103. {
  104. zReader->lese((char*)&pos.x, 4);
  105. zReader->lese((char*)&pos.y, 4);
  106. zReader->lese((char*)&pos.z, 4);
  107. if (blockTypes[id]->doesNeedInstance())
  108. setBlock(blockTypes[id]->createBlock({ pos.x + location.x - CHUNK_SIZE / 2, pos.y + location.y - CHUNK_SIZE / 2, pos.z }));
  109. zReader->lese((char*)&id, 2);
  110. }
  111. isLoading = 0;
  112. updateVisibility();
  113. }
  114. Framework::Punkt Chunk::getCenter() const
  115. {
  116. return location;
  117. }
  118. Framework::Vec3<int> Chunk::getMin() const
  119. {
  120. return { location.x - CHUNK_SIZE / 2, location.y - CHUNK_SIZE / 2, 0 };
  121. }
  122. Framework::Vec3<int> Chunk::getMax() const
  123. {
  124. return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT };
  125. }
  126. void Chunk::forAll(std::function<void(Model3D*)> f)
  127. {
  128. cs.lock();
  129. for (Block* b : blocks)
  130. f(b);
  131. cs.unlock();
  132. }
  133. void Chunk::updateVisibility()
  134. {
  135. cs.lock();
  136. for (Block* b : blocks)
  137. {
  138. Framework::Vec3<int> pos = Framework::Vec3<int>((int)floor(b->getPos().x), (int)floor(b->getPos().y), (int)floor(b->getPos().z));
  139. for (int i = 0; i < 6; i++)
  140. {
  141. Block* c = zBlockAt(pos + getDirection(getDirectionFromIndex(i)));
  142. b->setSideVisible(getDirectionFromIndex(i), !c || c->isTransparent());
  143. }
  144. }
  145. cs.unlock();
  146. }