123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- #include "WorldGenerator.h"
- #include <Betriebssystem.h>
- #include <functional>
- #include "Game.h"
- #include "NoiseInterpolator.h"
- #include "OverworldDimension.h"
- using namespace Framework;
- using namespace Framework::JSON;
- using namespace Framework::JSON::Validator;
- WorldGenerator::WorldGenerator(int seed)
- : Thread(),
- exit(0),
- seed(seed)
- {
- setName("World Generator");
- std::cout << "loading world generator configs. Changes at the config giles "
- "may lead to a sudden change in landscape.\n";
- JSONValidator* validator = buildConfigValidator();
- loadConfig("data/generator", validator);
- validator->release();
- addMissingDimensions();
- start();
- }
- WorldGenerator::~WorldGenerator() {}
- Framework::JSON::Validator::JSONValidator*
- WorldGenerator::buildConfigValidator()
- {
- JSONValidator* configValidator
- = JSONValidator::buildForArray()
- ->removeInvalidEntries()
- ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
- ->getDimensionGeneratorValidator())
- ->finishArray();
- Datei syntaxFile(new Text("data/syntax/generatorValidation.xml"));
- syntaxFile.erstellen();
- Text syntaxContent = configValidator->zConstraints()->toString();
- syntaxFile.open(Datei::Style::schreiben);
- syntaxFile.schreibe(syntaxContent, syntaxContent.getLength());
- syntaxFile.close();
- return configValidator;
- }
- void WorldGenerator::loadConfig(
- const char* path, Framework::JSON::Validator::JSONValidator* zValidator)
- {
- std::cout << "loading dimension configs from '" << path << "'" << std::endl;
- Datei file(new Text(path));
- if (file.istOrdner())
- {
- RCArray<Text>* fileNames = file.getDateiListe();
- if (fileNames)
- {
- for (Text* name : *fileNames)
- {
- loadConfig(Text(path) + "/" + *name, zValidator);
- }
- fileNames->release();
- }
- }
- else
- {
- JSONValue* json = loadJSONFromFile(path);
- if (!json)
- {
- std::cout << "ERROR: the file does not contain valid json\n";
- }
- else
- {
- Framework::RCArray<JSONValidationResult> invalidParts;
- JSONValue* valid = zValidator->getValidParts(json, &invalidParts);
- for (JSONValidationResult* invalidPart : invalidParts)
- {
- invalidPart->printInvalidInfo();
- }
- json->release();
- if (valid)
- {
- for (JSONValue* config : *valid->asArray())
- loadDimensionConfig(config);
- valid->release();
- }
- }
- }
- }
- void WorldGenerator::loadDimensionConfig(Framework::JSON::JSONValue* zConfig)
- {
- DimensionGenerator* generator
- = Game::INSTANCE->zTypeRegistry()->createDimensionGenerator(
- zConfig, seed);
- if (generator)
- {
- dimensionGenerators.add(generator);
- }
- else
- {
- std::cout << "ERROR: could not find dimension factory for config \n"
- << zConfig->toString() << "\n";
- }
- }
- void WorldGenerator::addMissingDimensions()
- {
- for (DimensionGeneratorFactory* factory : Game::INSTANCE->zTypeRegistry()->getDimensionGeneratorFactories())
- {
- bool found = 0;
- for (DimensionGenerator* generator : dimensionGenerators)
- {
- if (generator->getDimensionId() == factory->getDimensionId())
- {
- found = 1;
- break;
- }
- }
- if (!found)
- {
- std::cout << "WARNING: missing config for dimension '"
- << factory->getName() << "' with id "
- << factory->getDimensionId()
- << ". Default config will be used.";
- JSONValue* defaultConfig = factory->getDefaultConfig();
- Datei file(new Text(
- Text("data/generator/") + factory->getName() + ".json"));
- if (!file.existiert())
- {
- file.erstellen();
- file.open(Datei::Style::schreiben);
- Text conficContent
- = Text("[") + defaultConfig->toString() + "]";
- file.schreibe(conficContent, conficContent.getLength());
- file.close();
- std::cout << "Default config was written to '" << *file.zPfad()
- << "'\n";
- }
- loadDimensionConfig(defaultConfig);
- defaultConfig->release();
- }
- }
- }
- DimensionGenerator* WorldGenerator::zGenerator(int dimensionId)
- {
- for (DimensionGenerator* generator : dimensionGenerators)
- {
- if (generator->getDimensionId() == dimensionId) return generator;
- }
- return 0;
- }
- void WorldGenerator::thread()
- {
- while (!exit)
- {
- cs.lock();
- Area next;
- bool hasNext = 0;
- if (requestQueue.getEintragAnzahl() > 0)
- {
- next = requestQueue.get(0);
- requestQueue.remove(0);
- hasNext = 1;
- }
- cs.unlock();
- if (!hasNext)
- {
- Sleep(1000);
- continue;
- }
- Punkt start = Game::INSTANCE->getChunkCenter(next.startX, next.startY);
- Punkt end = Game::INSTANCE->getChunkCenter(next.endX, next.endY);
- int xDir = start.x > end.x ? -1 : 1;
- int yDir = start.y > end.y ? -1 : 1;
- for (int x = start.x; xDir < 0 ? x >= end.x : x <= end.x;
- x += CHUNK_SIZE * xDir)
- {
- for (int y = start.y; yDir < 0 ? y >= end.y : y <= end.y;
- y += CHUNK_SIZE * yDir)
- {
- if (!Game::INSTANCE->doesChunkExist(x, y, next.dimensionId))
- {
- Chunk* generatedChunk
- = zGenerator(next.dimensionId)->generateChunk(x, y);
- ZeitMesser zm;
- zm.messungStart();
- generatedChunk->initializeLightning();
- zm.messungEnde();
- std::cout << "light calculation: " << zm.getSekunden()
- << "\n";
- zm.messungStart();
- generatedChunk->removeUnusedBlocks();
- zm.messungEnde();
- std::cout << "unused block removal: " << zm.getSekunden()
- << "\n";
- zm.messungStart();
- Dimension* dim
- = Game::INSTANCE->zDimension(next.dimensionId);
- if (!dim)
- {
- dim = new Dimension(next.dimensionId);
- Game::INSTANCE->addDimension(dim);
- }
- dim->setChunk(generatedChunk, Punkt(x, y));
- zm.messungEnde();
- std::cout << "adding chunk to map: " << zm.getSekunden()
- << "\n";
- }
- }
- }
- }
- std::cout << "World Generator thread exited\n";
- }
- void WorldGenerator::requestGeneration(Area request)
- {
- cs.lock();
- requestQueue.add(request);
- cs.unlock();
- }
- void WorldGenerator::exitAndWait()
- {
- exit = 1;
- warteAufThread(10000);
- ende();
- }
- Framework::Either<Block*, int> WorldGenerator::generateSingleBlock(
- Framework::Vec3<int> location, int dimensionId)
- {
- return zGenerator(dimensionId)->generateBlock(location);
- }
- bool WorldGenerator::spawnStructure(Framework::Vec3<int> location,
- int dimensionId,
- std::function<bool(GeneratorTemplate* tmpl)> filter)
- {
- return zGenerator(dimensionId)->spawnStructure(location, filter);
- }
|