From dc03a251f6acc6a54affd8b5de714c5e91468a0e Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Tue, 29 Jul 2014 15:58:54 +0200 Subject: [PATCH] - Fixed treasure generating formula It should be now identical to OH3. - Refactorings, tweaks. --- lib/HeroBonus.cpp | 4 +- lib/rmg/CRmgTemplateZone.cpp | 85 +++++++++++++++++++----------------- lib/rmg/CRmgTemplateZone.h | 2 +- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index 403cd0b4c..d08690d7d 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -853,14 +853,14 @@ void CBonusSystemNode::newChildAttached(CBonusSystemNode *child) { assert(!vstd::contains(children, child)); children.push_back(child); - BONUS_LOG_LINE(child->nodeName() << " #attached to# " << nodeName()); + //BONUS_LOG_LINE(child->nodeName() << " #attached to# " << nodeName()); } void CBonusSystemNode::childDetached(CBonusSystemNode *child) { assert(vstd::contains(children, child)); children -= child; - BONUS_LOG_LINE(child->nodeName() << " #detached from# " << nodeName()); + //BONUS_LOG_LINE(child->nodeName() << " #detached from# " << nodeName()); } void CBonusSystemNode::detachFromAll() diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index e7117a365..53815aaf0 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -671,10 +671,11 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos) } } } + ui32 desiredValue = gen->rand.nextInt(minValue, maxValue); int currentValue = 0; CGObjectInstance * object = nullptr; - while (currentValue < minValue) + while (currentValue < desiredValue) { treasures[info.nextTreasurePos] = nullptr; @@ -698,17 +699,16 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos) break; } - int remaining = maxValue - currentValue; - - ObjectInfo oi = getRandomObject(gen, info, remaining); - object = oi.generateObject(); - if (!object) + ObjectInfo oi = getRandomObject(gen, info, desiredValue - currentValue); + if (!oi.value) //0 value indicates no object { vstd::erase_if_present(treasures, info.nextTreasurePos); break; } else { + object = oi.generateObject(); + //remove from possible objects auto oiptr = std::find(possibleObjects.begin(), possibleObjects.end(), oi); assert (oiptr != possibleObjects.end()); @@ -733,34 +733,34 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos) info.blockedPositions.insert(blockPos); } info.occupiedPositions.insert(visitablePos); - } - currentValue += oi.value; + currentValue += oi.value; - treasures[info.nextTreasurePos] = object; + treasures[info.nextTreasurePos] = object; - //now find place for next object - int3 placeFound(-1,-1,-1); + //now find place for next object + int3 placeFound(-1,-1,-1); - for (auto tile : boundary) - { - if (gen->isPossible(tile)) //we can place new treasure only on possible tile + for (auto tile : boundary) { - bool here = true; - gen->foreach_neighbour (tile, [gen, &here](int3 pos) + if (gen->isPossible(tile)) //we can place new treasure only on possible tile { - if (!(gen->isBlocked(pos) || gen->isPossible(pos))) - here = false; - }); - if (here) - { - placeFound = tile; - break; + bool here = true; + gen->foreach_neighbour (tile, [gen, &here](int3 pos) + { + if (!(gen->isBlocked(pos) || gen->isPossible(pos))) + here = false; + }); + if (here) + { + placeFound = tile; + break; + } } } - } - if (placeFound.valid()) - info.nextTreasurePos = placeFound; + if (placeFound.valid()) + info.nextTreasurePos = placeFound; + } } if (treasures.size()) @@ -868,6 +868,8 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos) { if (gen->isPossible(treasure.first)) gen->setOccupied (treasure.first, ETileType::BLOCKED); + + delete treasure.second; } } @@ -1491,19 +1493,20 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object, return true; } -ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 value) +ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 remaining) { //int objectsVisitableFromBottom = 0; //for debug std::vector> tresholds; ui32 total = 0; - ui32 minValue = 0.25f * value; + //calculate actual treasure value range based on remaining value + ui32 minValue = 0.25f * remaining; //roulette wheel for (ObjectInfo &oi : possibleObjects) //copy constructor turned out to be costly { - if (oi.value >= minValue && oi.value <= value && oi.maxPerZone > 0) + if (oi.value >= minValue && oi.value <= remaining && oi.maxPerZone > 0) { int3 newVisitableOffset = oi.templ.getVisitableOffset(); //visitablePos assumes object will be shifter by visitableOffset int3 newVisitablePos = info.nextTreasurePos; @@ -1593,16 +1596,17 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI continue; total += oi.probability; + //assert (oi.value > 0); tresholds.push_back (std::make_pair (total, oi)); } } //logGlobal->infoStream() << boost::format ("Number of objects visitable from bottom: %d") % objectsVisitableFromBottom; - //Generate pandora Box with gold if the value is extremely high - ObjectInfo oi; if (tresholds.empty()) { + ObjectInfo oi; + //Generate pandora Box with gold if the value is extremely high if (minValue > 20000) //we don't have object valuable enough { oi.generateObject = [minValue]() -> CGObjectInstance * @@ -1617,25 +1621,28 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI oi.value = minValue; oi.probability = 0; } - else + else //generate empty object with 0 value if the value if we can't spawn anything { oi.generateObject = [gen]() -> CGObjectInstance * { return nullptr; }; oi.setTemplate(Obj::PANDORAS_BOX, 0, terrainType); //TODO: null template or something? should be never used, but hell knows - oi.value = 0; + oi.value = 0; // this field is checked to determine no object oi.probability = 0; } return oi; } - - int r = gen->rand.nextInt (1, total); - - for (auto t : tresholds) + else { - if (r <= t.first) - return t.second; + int r = gen->rand.nextInt (1, total); + + for (auto t : tresholds) + { + if (r <= t.first) + return t.second; + } + assert (0); //we should never be here } //FIXME: control reaches end of non-void function. Missing return? } diff --git a/lib/rmg/CRmgTemplateZone.h b/lib/rmg/CRmgTemplateZone.h index e9d44440e..80fadf3fb 100644 --- a/lib/rmg/CRmgTemplateZone.h +++ b/lib/rmg/CRmgTemplateZone.h @@ -173,7 +173,7 @@ public: std::vector getTreasureInfo(); std::set* getFreePaths(); - ObjectInfo getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 value); + ObjectInfo getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 remaining); void placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard = false);