From cd9bd491e0628cceb7d606ebdd5d8c9ed33957a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Wed, 24 May 2023 18:02:11 +0200 Subject: [PATCH] Add option for single-thread generation. Still doesn't guarantee excactly identical maps :? --- lib/rmg/CMapGenerator.cpp | 88 ++++++++++++++++--------- lib/rmg/CMapGenerator.h | 1 + lib/rmg/modificators/ObstaclePlacer.cpp | 1 - 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index 2bd4fc2c5..86dc1051c 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -83,6 +83,7 @@ void CMapGenerator::loadConfig() config.secondaryRoadType = ""; if(!mapGenOptions.isRoadEnabled(config.defaultRoadType)) config.defaultRoadType = config.secondaryRoadType; + config.singleThread = randomMapJson["singleThread"].Bool(); } const CMapGenerator::Config & CMapGenerator::getConfig() const @@ -299,7 +300,7 @@ void CMapGenerator::fillZones() //we need info about all town types to evaluate dwellings and pandoras with creatures properly //place main town in the middle - + Load::Progress::setupStepsTill(numZones, 50); for (const auto& it : map->getZones()) { @@ -310,51 +311,74 @@ void CMapGenerator::fillZones() std::vector> treasureZones; - ThreadPool pool; - - std::vector> futures; - //At most one Modificator can run for every zone - pool.init(std::min(boost::thread::hardware_concurrency(), numZones)); - TModificators allJobs; - for (auto & it : map->getZones()) + for (auto& it : map->getZones()) { allJobs.splice(allJobs.end(), it.second->getModificators()); } Load::Progress::setupStepsTill(allJobs.size(), 240); - while (!allJobs.empty()) + if (config.singleThread) //No thread pool, just queue with deterministic order { - for (auto it = allJobs.begin(); it != allJobs.end();) + while (!allJobs.empty()) { - if ((*it)->isFinished()) + for (auto it = allJobs.begin(); it != allJobs.end();) { - it = allJobs.erase(it); - Progress::Progress::step(); - } - else if ((*it)->isReady()) - { - auto jobCopy = *it; - futures.emplace_back(pool.async([this, jobCopy]() -> void - { - jobCopy->run(); - Progress::Progress::step(); //Update progress bar - } - )); - it = allJobs.erase(it); - } - else - { - ++it; + if ((*it)->isReady()) + { + auto jobCopy = *it; + jobCopy->run(); + Progress::Progress::step(); //Update progress bar + allJobs.erase(it); + break; //Restart from the first job + } + else + { + ++it; + } } } } - - //Wait for all the tasks - for (auto& fut : futures) + else { - fut.get(); + ThreadPool pool; + std::vector> futures; + //At most one Modificator can run for every zone + pool.init(std::min(boost::thread::hardware_concurrency(), numZones)); + + while (!allJobs.empty()) + { + for (auto it = allJobs.begin(); it != allJobs.end();) + { + if ((*it)->isFinished()) + { + it = allJobs.erase(it); + Progress::Progress::step(); + } + else if ((*it)->isReady()) + { + auto jobCopy = *it; + futures.emplace_back(pool.async([this, jobCopy]() -> void + { + jobCopy->run(); + Progress::Progress::step(); //Update progress bar + } + )); + it = allJobs.erase(it); + } + else + { + ++it; + } + } + } + + //Wait for all the tasks + for (auto& fut : futures) + { + fut.get(); + } } for (const auto& it : map->getZones()) diff --git a/lib/rmg/CMapGenerator.h b/lib/rmg/CMapGenerator.h index 99d36b3a4..dd18108c5 100644 --- a/lib/rmg/CMapGenerator.h +++ b/lib/rmg/CMapGenerator.h @@ -47,6 +47,7 @@ public: int pandoraMultiplierGold, pandoraMultiplierExperience, pandoraMultiplierSpells, pandoraSpellSchool, pandoraSpell60; std::vector pandoraCreatureValues; std::vector questValues, questRewardValues; + bool singleThread; }; explicit CMapGenerator(CMapGenOptions& mapGenOptions, int RandomSeed = std::time(nullptr)); diff --git a/lib/rmg/modificators/ObstaclePlacer.cpp b/lib/rmg/modificators/ObstaclePlacer.cpp index 7227e53bd..a19ffcb3f 100644 --- a/lib/rmg/modificators/ObstaclePlacer.cpp +++ b/lib/rmg/modificators/ObstaclePlacer.cpp @@ -42,7 +42,6 @@ void ObstaclePlacer::process() blockedArea.subtract(zone.areaUsed()); zone.areaPossible().subtract(blockedArea); - //TODO: Set prohibited area in ObstacleProxy :? prohibitedArea = zone.freePaths() + zone.areaUsed() + manager->getVisitableArea(); auto objs = createObstacles(zone.getRand());