Browse Source

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

DjWarmonger 11 năm trước cách đây
mục cha
commit
dc03a251f6
3 tập tin đã thay đổi với 49 bổ sung42 xóa
  1. 2 2
      lib/HeroBonus.cpp
  2. 46 39
      lib/rmg/CRmgTemplateZone.cpp
  3. 1 1
      lib/rmg/CRmgTemplateZone.h

+ 2 - 2
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()

+ 46 - 39
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<std::pair<ui32, ObjectInfo>> 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?
 }

+ 1 - 1
lib/rmg/CRmgTemplateZone.h

@@ -173,7 +173,7 @@ public:
 	std::vector<CTreasureInfo> getTreasureInfo();
 	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);