Przeglądaj źródła

Add option for single-thread generation. Still doesn't guarantee excactly identical maps :?

Tomasz Zieliński 2 lat temu
rodzic
commit
cd9bd491e0

+ 55 - 31
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<std::shared_ptr<Zone>> treasureZones;
 
-	ThreadPool pool;
-
-	std::vector<boost::future<void>> futures;
-	//At most one Modificator can run for every zone
-	pool.init(std::min<int>(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())
-			{
-				it = allJobs.erase(it);
-				Progress::Progress::step();
-			}
-			else if ((*it)->isReady())
+			for (auto it = allJobs.begin(); it != allJobs.end();)
 			{
-				auto jobCopy = *it;
-				futures.emplace_back(pool.async([this, jobCopy]() -> void
-					{
-						jobCopy->run();
-						Progress::Progress::step(); //Update progress bar
-					}
-				));
-				it = allJobs.erase(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;
+				}
 			}
-			else
+		}
+	}
+	else
+	{
+		ThreadPool pool;
+		std::vector<boost::future<void>> futures;
+		//At most one Modificator can run for every zone
+		pool.init(std::min<int>(boost::thread::hardware_concurrency(), numZones));
+
+		while (!allJobs.empty())
+		{
+			for (auto it = allJobs.begin(); it != allJobs.end();)
 			{
-				++it;
+				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();
+		//Wait for all the tasks
+		for (auto& fut : futures)
+		{
+			fut.get();
+		}
 	}
 
 	for (const auto& it : map->getZones())

+ 1 - 0
lib/rmg/CMapGenerator.h

@@ -47,6 +47,7 @@ public:
 		int pandoraMultiplierGold, pandoraMultiplierExperience, pandoraMultiplierSpells, pandoraSpellSchool, pandoraSpell60;
 		std::vector<int> pandoraCreatureValues;
 		std::vector<int> questValues, questRewardValues;
+		bool singleThread;
 	};
 	
 	explicit CMapGenerator(CMapGenOptions& mapGenOptions, int RandomSeed = std::time(nullptr));

+ 0 - 1
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());