123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- #include "WorldGenerator.h"
- #include <Betriebssystem.h>
- #include <functional>
- #include <Logging.h>
- #include "Dimension.h"
- #include "Game.h"
- #include "JsonUtils.h"
- #include "NoiseInterpolator.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");
- Framework::Logging::info()
- << "loading world generator configs. Changes at the config files "
- "may lead to a sudden change in landscape.";
- JSONValidator* configValidator
- = JSONValidator::buildForArray()
- ->removeInvalidEntries()
- ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
- ->getValidator<DimensionGenerator>())
- ->finishArray();
- loadAllJsonsFromDirectory("data/generator",
- [this, configValidator, seed](
- Framework::JSON::JSONValue* zValue, Framework::Text path) {
- Framework::Logging::info()
- << "loading dimension configs from '" << path << "'";
- Framework::RCArray<JSONValidationResult> invalidParts;
- JSONValue* valid
- = configValidator->getValidParts(zValue, &invalidParts);
- for (JSONValidationResult* invalidPart : invalidParts)
- {
- Framework::Logging::error() << invalidPart->getInvalidInfo();
- }
- if (valid)
- {
- for (JSONValue* config : *valid->asArray())
- {
- DimensionGenerator* generator
- = Game::INSTANCE->zTypeRegistry()
- ->fromJson<DimensionGenerator>(config);
- generator->initialize(seed);
- dimensionGenerators.add(generator);
- }
- valid->release();
- }
- });
- configValidator->release();
- start();
- }
- WorldGenerator::~WorldGenerator() {}
- Dimension* WorldGenerator::createDimension(int dimensionId)
- {
- for (DimensionGenerator* generator : dimensionGenerators)
- {
- if (generator->getDimensionId() == dimensionId)
- return generator->createDimension();
- }
- Framework::Logging::error()
- << "no dimension generator found for dimension " << dimensionId;
- return 0;
- }
- 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();
- Framework::Logging::trace()
- << "light calculation: " << zm.getSekunden();
- zm.messungStart();
- generatedChunk->removeUnusedBlocks();
- zm.messungEnde();
- Framework::Logging::trace()
- << "unused block removal: " << zm.getSekunden();
- zm.messungStart();
- Dimension* dim
- = Game::INSTANCE->zDimension(next.dimensionId);
- if (!dim)
- {
- dim = new Dimension(next.dimensionId);
- Game::INSTANCE->addDimension(dim);
- }
- generatedChunk->getThis();
- dim->setChunk(generatedChunk, Punkt(x, y));
- zGenerator(next.dimensionId)
- ->generateEntities(generatedChunk);
- generatedChunk->release();
- zm.messungEnde();
- Framework::Logging::trace()
- << "adding chunk to map: " << zm.getSekunden();
- }
- }
- }
- }
- Framework::Logging::info() << "World Generator thread exited";
- }
- 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);
- }
|