#include "WorldLoader.h" #include #include #include #include #include "Dimension.h" #include "Entity.h" #include "EntityType.h" #include "Game.h" #include "WorldGenerator.h" using namespace Framework; WorldLoader::WorldLoader() : Thread(), exit(0) { setName("World Loader"); Framework::Datei d; d.setDatei(Game::INSTANCE->getWorldDirectory() + "/dim"); RCArray* names = d.getDateiListe(); if (names) { for (Text* name : *names) { Framework::Datei entities; entities.setDatei(Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(name->getText()) + "/entities"); if (entities.open(Framework::Datei::Style::lesen)) { Dimension* dim = Game::INSTANCE->zGenerator()->createDimension((int)*name); if (dim) { while (!entities.istEnde()) { int type = 0; entities.lese((char*)&type, 4); dim->addEntity( Game::INSTANCE->zEntityType(type)->loadEntity( &entities)); } Game::INSTANCE->addDimension(dim); } else { Framework::Logging::error() << "could not create dimension " << *name << ". No Factory was provided."; } } } names->release(); } start(); } WorldLoader::~WorldLoader() {} void WorldLoader::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) { Dimension* zDim = Game::INSTANCE->zDimension(next.dimensionId); bool revived = 0; if (!zDim->zChunk(Punkt(x, y)) && zDim->hasChunck(x, y)) { revived = zDim->reviveChunk(x, y); } if (!revived && !Game::INSTANCE->isChunkLoaded(x, y, next.dimensionId)) { Datei* file = new Datei(); Text filePath = Game::INSTANCE->getWorldDirectory() + "/dim/" + next.dimensionId + "/"; filePath.appendHex(x); filePath += "_"; filePath.appendHex(y); filePath += ".chunk"; file->setDatei(filePath); if (file->open(Datei::Style::lesen)) { Chunk* chunk = new Chunk( Framework::Punkt(x, y), next.dimensionId, file); Dimension* dim = Game::INSTANCE->zDimension(next.dimensionId); if (!dim) { dim = new Dimension(next.dimensionId); Game::INSTANCE->addDimension(dim); } dim->setChunk(chunk, Punkt(x, y)); } file->close(); file->release(); } } } } Framework::Logging::info() << "World Loader thread exited"; } void WorldLoader::requestLoading(Area request) { cs.lock(); requestQueue.add(request); cs.unlock(); } void WorldLoader::exitAndWait() { exit = 1; warteAufThread(10000); ende(); } bool WorldLoader::existsChunk(int x, int y, int dimension) const { Text filePath = Game::INSTANCE->getWorldDirectory() + "/dim/" + dimension + "/"; filePath.appendHex(x); filePath += "_"; filePath.appendHex(y); filePath += ".chunk"; return DateiExistiert(filePath); }