MultiblockStructure.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "MultiblockStructure.h"
  2. #include "Game.h"
  3. using namespace Framework;
  4. MultiblockStructure::MultiblockStructure(int dimensionId, __int64 structureId, Framework::Vec3<int> uniquePosition, int structureTypeId)
  5. : ReferenceCounter(),
  6. uniquePosition(uniquePosition),
  7. dimensionId(dimensionId),
  8. structureId(structureId),
  9. structureTypeId(structureTypeId),
  10. isLoading(1)
  11. {}
  12. MultiblockStructure::~MultiblockStructure()
  13. {}
  14. void MultiblockStructure::onBlockLoaded(Block* block)
  15. {
  16. if (isBlockMember(block))
  17. {
  18. loadedMembers.add(block);
  19. isLoading = 0;
  20. }
  21. else
  22. block->release();
  23. }
  24. void MultiblockStructure::onBlockUnloaded(Block* zBlock)
  25. {
  26. for (auto i = loadedMembers.begin(); i; ++i)
  27. {
  28. if ((Block*)i == zBlock)
  29. {
  30. i.remove();
  31. return;
  32. }
  33. }
  34. }
  35. void MultiblockStructure::addMemberPosition(Framework::Vec3<int > blockPos)
  36. {
  37. memberBlockPositions.add(blockPos);
  38. Punkt center = Game::INSTANCE->getChunkCenter(blockPos.x, blockPos.y);
  39. for (const Punkt& p : affectedChunks)
  40. {
  41. if (p == center)
  42. return;
  43. }
  44. affectedChunks.add(center);
  45. }
  46. void MultiblockStructure::onBlockRemoved(Block* zBlock)
  47. {
  48. for (auto i = memberBlockPositions.begin(); i; ++i)
  49. {
  50. if (i.val() == zBlock->getPos())
  51. {
  52. Punkt center = Game::INSTANCE->getChunkCenter(i.val().x, i.val().y);
  53. i.remove();
  54. // check if other blocks in the same chunk exists
  55. for (Vec3<int> pos : memberBlockPositions)
  56. {
  57. if (center == Game::INSTANCE->getChunkCenter(pos.x, pos.y))
  58. return;
  59. }
  60. // remove chunk from affected chunks if no other block is in this chunk
  61. for (auto p = affectedChunks.begin(); p; ++p)
  62. {
  63. if (p.val() == center)
  64. p.remove();
  65. }
  66. return;
  67. }
  68. }
  69. }
  70. bool MultiblockStructure::isEmpty() const
  71. {
  72. return memberBlockPositions.getEintragAnzahl() == 0 && !isLoading;
  73. }
  74. bool MultiblockStructure::isFullyLoaded() const
  75. {
  76. for (Punkt p : affectedChunks)
  77. {
  78. if (!Game::INSTANCE->isChunkLoaded(p.x, p.y, dimensionId))
  79. return 0;
  80. }
  81. return 1;
  82. }
  83. bool MultiblockStructure::isFullyUnloaded() const
  84. {
  85. if (isLoading)
  86. return 0;
  87. for (Punkt p : affectedChunks)
  88. {
  89. if (Game::INSTANCE->isChunkLoaded(p.x, p.y, dimensionId))
  90. return 0;
  91. }
  92. return 1;
  93. }
  94. bool MultiblockStructure::isBlockMember(Block* zBlock) const
  95. {
  96. for (const Vec3<int>& pos : memberBlockPositions)
  97. {
  98. if (pos == zBlock->getPos())
  99. return 1;
  100. }
  101. return 0;
  102. }
  103. __int64 MultiblockStructure::getStructureId() const
  104. {
  105. return structureId;
  106. }
  107. Framework::Vec3<int> MultiblockStructure::getUniquePosition() const
  108. {
  109. return uniquePosition;
  110. }
  111. int MultiblockStructure::getStructureTypeId() const
  112. {
  113. return structureTypeId;
  114. }
  115. MultiblockStructureType::MultiblockStructureType(int id)
  116. : ReferenceCounter(),
  117. id(id)
  118. {
  119. StaticRegistry<MultiblockStructureType>::INSTANCE.registerT(this, id);
  120. }
  121. MultiblockStructureType::~MultiblockStructureType()
  122. {}
  123. void MultiblockStructureType::loadSuperStructure(MultiblockStructure* zStructure, Framework::StreamReader* zReader) const
  124. {
  125. zStructure->affectedChunks.leeren();
  126. zStructure->memberBlockPositions.leeren();
  127. int blockCount;
  128. zReader->lese((char*)&blockCount, 4);
  129. for (int i = 0; i < blockCount; i++)
  130. {
  131. Framework::Vec3<int> pos;
  132. zReader->lese((char*)&pos.x, 4);
  133. zReader->lese((char*)&pos.y, 4);
  134. zReader->lese((char*)&pos.z, 4);
  135. zStructure->addMemberPosition(pos);
  136. }
  137. }
  138. void MultiblockStructureType::saveSuperStructure(MultiblockStructure* zStructure, Framework::StreamWriter* zWriter) const
  139. {
  140. int blockCount = zStructure->memberBlockPositions.getEintragAnzahl();
  141. zWriter->schreibe((char*)&blockCount, 4);
  142. for (Framework::Vec3<int> pos : zStructure->memberBlockPositions)
  143. {
  144. zWriter->schreibe((char*)&pos.x, 4);
  145. zWriter->schreibe((char*)&pos.y, 4);
  146. zWriter->schreibe((char*)&pos.z, 4);
  147. }
  148. }
  149. MultiblockStructure* MultiblockStructureType::loadStructure(int dimensionId, __int64 structureId, Framework::Vec3<int> uniquePosition, Framework::StreamReader* zReader) const
  150. {
  151. MultiblockStructure* str = createStructure(dimensionId, structureId, uniquePosition);
  152. loadSuperStructure(str, zReader);
  153. return str;
  154. }
  155. void MultiblockStructureType::saveStructure(MultiblockStructure* zStructure, Framework::StreamWriter* zWriter) const
  156. {
  157. saveSuperStructure(zStructure, zWriter);
  158. }
  159. int MultiblockStructureType::getId() const
  160. {
  161. return id;
  162. }