Chunk.cpp 3.3 KB

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