Chunk.cpp 3.4 KB

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