1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-15 11:46:56 +02:00

- Fixed treasure generating formula It should be now identical to OH3.

- Refactorings, tweaks.
This commit is contained in:
DjWarmonger 2014-07-29 15:58:54 +02:00
parent fe292dfa1d
commit dc03a251f6
3 changed files with 49 additions and 42 deletions

View File

@ -853,14 +853,14 @@ void CBonusSystemNode::newChildAttached(CBonusSystemNode *child)
{ {
assert(!vstd::contains(children, child)); assert(!vstd::contains(children, child));
children.push_back(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) void CBonusSystemNode::childDetached(CBonusSystemNode *child)
{ {
assert(vstd::contains(children, child)); assert(vstd::contains(children, child));
children -= child; children -= child;
BONUS_LOG_LINE(child->nodeName() << " #detached from# " << nodeName()); //BONUS_LOG_LINE(child->nodeName() << " #detached from# " << nodeName());
} }
void CBonusSystemNode::detachFromAll() void CBonusSystemNode::detachFromAll()

View File

@ -671,10 +671,11 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
} }
} }
} }
ui32 desiredValue = gen->rand.nextInt(minValue, maxValue);
int currentValue = 0; int currentValue = 0;
CGObjectInstance * object = nullptr; CGObjectInstance * object = nullptr;
while (currentValue < minValue) while (currentValue < desiredValue)
{ {
treasures[info.nextTreasurePos] = nullptr; treasures[info.nextTreasurePos] = nullptr;
@ -698,17 +699,16 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
break; break;
} }
int remaining = maxValue - currentValue; ObjectInfo oi = getRandomObject(gen, info, desiredValue - currentValue);
if (!oi.value) //0 value indicates no object
ObjectInfo oi = getRandomObject(gen, info, remaining);
object = oi.generateObject();
if (!object)
{ {
vstd::erase_if_present(treasures, info.nextTreasurePos); vstd::erase_if_present(treasures, info.nextTreasurePos);
break; break;
} }
else else
{ {
object = oi.generateObject();
//remove from possible objects //remove from possible objects
auto oiptr = std::find(possibleObjects.begin(), possibleObjects.end(), oi); auto oiptr = std::find(possibleObjects.begin(), possibleObjects.end(), oi);
assert (oiptr != possibleObjects.end()); assert (oiptr != possibleObjects.end());
@ -733,7 +733,6 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
info.blockedPositions.insert(blockPos); info.blockedPositions.insert(blockPos);
} }
info.occupiedPositions.insert(visitablePos); info.occupiedPositions.insert(visitablePos);
}
currentValue += oi.value; currentValue += oi.value;
@ -762,6 +761,7 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
if (placeFound.valid()) if (placeFound.valid())
info.nextTreasurePos = placeFound; info.nextTreasurePos = placeFound;
} }
}
if (treasures.size()) if (treasures.size())
{ {
@ -868,6 +868,8 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
{ {
if (gen->isPossible(treasure.first)) if (gen->isPossible(treasure.first))
gen->setOccupied (treasure.first, ETileType::BLOCKED); gen->setOccupied (treasure.first, ETileType::BLOCKED);
delete treasure.second;
} }
} }
@ -1491,19 +1493,20 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
return true; 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 //int objectsVisitableFromBottom = 0; //for debug
std::vector<std::pair<ui32, ObjectInfo>> tresholds; std::vector<std::pair<ui32, ObjectInfo>> tresholds;
ui32 total = 0; ui32 total = 0;
ui32 minValue = 0.25f * value; //calculate actual treasure value range based on remaining value
ui32 minValue = 0.25f * remaining;
//roulette wheel //roulette wheel
for (ObjectInfo &oi : possibleObjects) //copy constructor turned out to be costly 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 newVisitableOffset = oi.templ.getVisitableOffset(); //visitablePos assumes object will be shifter by visitableOffset
int3 newVisitablePos = info.nextTreasurePos; int3 newVisitablePos = info.nextTreasurePos;
@ -1593,16 +1596,17 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI
continue; continue;
total += oi.probability; total += oi.probability;
//assert (oi.value > 0);
tresholds.push_back (std::make_pair (total, oi)); tresholds.push_back (std::make_pair (total, oi));
} }
} }
//logGlobal->infoStream() << boost::format ("Number of objects visitable from bottom: %d") % objectsVisitableFromBottom; //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()) 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 if (minValue > 20000) //we don't have object valuable enough
{ {
oi.generateObject = [minValue]() -> CGObjectInstance * oi.generateObject = [minValue]() -> CGObjectInstance *
@ -1617,19 +1621,20 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI
oi.value = minValue; oi.value = minValue;
oi.probability = 0; oi.probability = 0;
} }
else else //generate empty object with 0 value if the value if we can't spawn anything
{ {
oi.generateObject = [gen]() -> CGObjectInstance * oi.generateObject = [gen]() -> CGObjectInstance *
{ {
return nullptr; return nullptr;
}; };
oi.setTemplate(Obj::PANDORAS_BOX, 0, terrainType); //TODO: null template or something? should be never used, but hell knows 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; oi.probability = 0;
} }
return oi; return oi;
} }
else
{
int r = gen->rand.nextInt (1, total); int r = gen->rand.nextInt (1, total);
for (auto t : tresholds) for (auto t : tresholds)
@ -1637,6 +1642,8 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI
if (r <= t.first) if (r <= t.first)
return t.second; return t.second;
} }
assert (0); //we should never be here
}
//FIXME: control reaches end of non-void function. Missing return? //FIXME: control reaches end of non-void function. Missing return?
} }

View File

@ -173,7 +173,7 @@ public:
std::vector<CTreasureInfo> getTreasureInfo(); std::vector<CTreasureInfo> getTreasureInfo();
std::set<int3>* getFreePaths(); std::set<int3>* 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); void placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard = false);