From e1f8ae94ac89881e9214a2bbbd1c8ec49764f846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Mon, 12 Jun 2023 22:15:59 +0200 Subject: [PATCH] + 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). --- lib/rmg/modificators/TreasurePlacer.cpp | 26 ++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/rmg/modificators/TreasurePlacer.cpp b/lib/rmg/modificators/TreasurePlacer.cpp index 6d77c88a8..0e6b3c9d8 100644 --- a/lib/rmg/modificators/TreasurePlacer.cpp +++ b/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 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((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; }