Bläddra i källkod

+ Do not limit treasures to make space for more treasures if there are none ;eft
+ Make sure RMG won't get stuck in infinite loop for weird treasure values (eg. 0).

Tomasz Zieliński 2 år sedan
förälder
incheckning
e1f8ae94ac
1 ändrade filer med 17 tillägg och 9 borttagningar
  1. 17 9
      lib/rmg/modificators/TreasurePlacer.cpp

+ 17 - 9
lib/rmg/modificators/TreasurePlacer.cpp

@@ -741,33 +741,41 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
 
 	int totalDensity = 0;
 
-	for (auto t : treasureInfo)
+	for (auto t  = treasureInfo.begin(); t != treasureInfo.end(); t++)
 	{
 		std::vector<rmg::Object> treasures;
 
 		//discard objects with too high value to be ever placed
 		vstd::erase_if(possibleObjects, [t](const ObjectInfo& oi) -> bool
 		{
-			return oi.value > t.max;
+			return oi.value > t->max;
 		});
 
-		totalDensity += t.density;
+		totalDensity += t->density;
 
-		size_t count = size * t.density / 500;
-		const int averageValue = (t.min + t.max) / 2;
-		if (averageValue > 10000) //Will surely be guarded => larger
+		size_t count = size * t->density / 500;
+
+		//Assure space for lesser treasures, if there are any left
+		if (t != (treasureInfo.end() - 1))
 		{
-			vstd::amin(count, size * (10.f/500) / (std::sqrt((float)averageValue / 10000)));
+			const int averageValue = (t->min + t->max) / 2;
+			if (averageValue > 10000)
+			{
+				//Will surely be guarded => larger piles => less space inbetween
+				vstd::amin(count, size * (10.f / 500) / (std::sqrt((float)averageValue / 10000)));
+			}
 		}
 		
 		//this is squared distance for optimization purposes
 		const float minDistance = std::max<float>((125.f / totalDensity), 1.0f);
 
-		for (size_t i = 0; i < count; i++)
+		size_t emergencyLoopFinish = 0;
+		while(treasures.size() < count && emergencyLoopFinish < count)
 		{
-			auto treasurePileInfos = prepareTreasurePile(t);
+			auto treasurePileInfos = prepareTreasurePile(*t);
 			if (treasurePileInfos.empty())
 			{
+				emergencyLoopFinish++; //Exit potentially infinite loop for bad settings
 				continue;
 			}