WorldGenerator.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include "WorldGenerator.h"
  2. #include <Betriebssystem.h>
  3. #include <functional>
  4. #include "Dimension.h"
  5. #include "Game.h"
  6. #include "JsonUtils.h"
  7. #include "NoiseInterpolator.h"
  8. using namespace Framework;
  9. using namespace Framework::JSON;
  10. using namespace Framework::JSON::Validator;
  11. WorldGenerator::WorldGenerator(int seed)
  12. : Thread(),
  13. exit(0),
  14. seed(seed)
  15. {
  16. setName("World Generator");
  17. std::cout << "loading world generator configs. Changes at the config files "
  18. "may lead to a sudden change in landscape.\n";
  19. JSONValidator* configValidator
  20. = JSONValidator::buildForArray()
  21. ->removeInvalidEntries()
  22. ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
  23. ->getValidator<DimensionGenerator>())
  24. ->finishArray();
  25. loadAllJsonsFromDirectory("data/generator",
  26. [this, configValidator, seed](
  27. Framework::JSON::JSONValue* zValue, Framework::Text path) {
  28. std::cout << "loading dimension configs from '" << path << "'"
  29. << std::endl;
  30. Framework::RCArray<JSONValidationResult> invalidParts;
  31. JSONValue* valid
  32. = configValidator->getValidParts(zValue, &invalidParts);
  33. for (JSONValidationResult* invalidPart : invalidParts)
  34. {
  35. invalidPart->printInvalidInfo();
  36. }
  37. if (valid)
  38. {
  39. for (JSONValue* config : *valid->asArray())
  40. {
  41. DimensionGenerator* generator
  42. = Game::INSTANCE->zTypeRegistry()
  43. ->fromJson<DimensionGenerator>(config);
  44. generator->initialize(seed);
  45. dimensionGenerators.add(generator);
  46. }
  47. valid->release();
  48. }
  49. });
  50. configValidator->release();
  51. start();
  52. }
  53. WorldGenerator::~WorldGenerator() {}
  54. Dimension* WorldGenerator::createDimension(int dimensionId)
  55. {
  56. for (DimensionGenerator* generator : dimensionGenerators)
  57. {
  58. if (generator->getDimensionId() == dimensionId)
  59. return generator->createDimension();
  60. }
  61. std::cout << "ERROR: no dimension generator found for dimension "
  62. << dimensionId << "\n";
  63. return 0;
  64. }
  65. DimensionGenerator* WorldGenerator::zGenerator(int dimensionId)
  66. {
  67. for (DimensionGenerator* generator : dimensionGenerators)
  68. {
  69. if (generator->getDimensionId() == dimensionId) return generator;
  70. }
  71. return 0;
  72. }
  73. void WorldGenerator::thread()
  74. {
  75. while (!exit)
  76. {
  77. cs.lock();
  78. Area next;
  79. bool hasNext = 0;
  80. if (requestQueue.getEintragAnzahl() > 0)
  81. {
  82. next = requestQueue.get(0);
  83. requestQueue.remove(0);
  84. hasNext = 1;
  85. }
  86. cs.unlock();
  87. if (!hasNext)
  88. {
  89. Sleep(1000);
  90. continue;
  91. }
  92. Punkt start = Game::INSTANCE->getChunkCenter(next.startX, next.startY);
  93. Punkt end = Game::INSTANCE->getChunkCenter(next.endX, next.endY);
  94. int xDir = start.x > end.x ? -1 : 1;
  95. int yDir = start.y > end.y ? -1 : 1;
  96. for (int x = start.x; xDir < 0 ? x >= end.x : x <= end.x;
  97. x += CHUNK_SIZE * xDir)
  98. {
  99. for (int y = start.y; yDir < 0 ? y >= end.y : y <= end.y;
  100. y += CHUNK_SIZE * yDir)
  101. {
  102. if (!Game::INSTANCE->doesChunkExist(x, y, next.dimensionId))
  103. {
  104. Chunk* generatedChunk
  105. = zGenerator(next.dimensionId)->generateChunk(x, y);
  106. ZeitMesser zm;
  107. zm.messungStart();
  108. generatedChunk->initializeLightning();
  109. zm.messungEnde();
  110. std::cout << "light calculation: " << zm.getSekunden()
  111. << "\n";
  112. zm.messungStart();
  113. generatedChunk->removeUnusedBlocks();
  114. zm.messungEnde();
  115. std::cout << "unused block removal: " << zm.getSekunden()
  116. << "\n";
  117. zm.messungStart();
  118. Dimension* dim
  119. = Game::INSTANCE->zDimension(next.dimensionId);
  120. if (!dim)
  121. {
  122. dim = new Dimension(next.dimensionId);
  123. Game::INSTANCE->addDimension(dim);
  124. }
  125. dim->setChunk(generatedChunk, Punkt(x, y));
  126. zm.messungEnde();
  127. std::cout << "adding chunk to map: " << zm.getSekunden()
  128. << "\n";
  129. }
  130. }
  131. }
  132. }
  133. std::cout << "World Generator thread exited\n";
  134. }
  135. void WorldGenerator::requestGeneration(Area request)
  136. {
  137. cs.lock();
  138. requestQueue.add(request);
  139. cs.unlock();
  140. }
  141. void WorldGenerator::exitAndWait()
  142. {
  143. exit = 1;
  144. warteAufThread(10000);
  145. ende();
  146. }
  147. Framework::Either<Block*, int> WorldGenerator::generateSingleBlock(
  148. Framework::Vec3<int> location, int dimensionId)
  149. {
  150. return zGenerator(dimensionId)->generateBlock(location);
  151. }
  152. bool WorldGenerator::spawnStructure(Framework::Vec3<int> location,
  153. int dimensionId,
  154. std::function<bool(GeneratorTemplate* tmpl)> filter)
  155. {
  156. return zGenerator(dimensionId)->spawnStructure(location, filter);
  157. }