فهرست منبع

Allow guards not stronger than 1/3 max value next to roads

Tomasz Zieliński 1 سال پیش
والد
کامیت
7f3cf607a7
3فایلهای تغییر یافته به همراه27 افزوده شده و 8 حذف شده
  1. 17 4
      lib/rmg/RmgObject.cpp
  2. 3 0
      lib/rmg/RmgObject.h
  3. 7 4
      lib/rmg/modificators/TreasurePlacer.cpp

+ 17 - 4
lib/rmg/RmgObject.cpp

@@ -175,19 +175,22 @@ const CGObjectInstance & Object::Instance::object() const
 }
 
 Object::Object(CGObjectInstance & object, const int3 & position):
-	guarded(false)
+	guarded(false),
+	value(0)
 {
 	addInstance(object, position);
 }
 
 Object::Object(CGObjectInstance & object):
-	guarded(false)
+	guarded(false),
+	value(0)
 {
 	addInstance(object);
 }
 
 Object::Object(const Object & object):
-	guarded(false)
+	guarded(false),
+	value(0)
 {
 	for(const auto & i : object.dInstances)
 		addInstance(const_cast<CGObjectInstance &>(i.object()), i.getPosition());
@@ -425,7 +428,7 @@ int3 rmg::Object::getGuardPos() const
 		{
 			if (instance.object().ID == Obj::MONSTER)
 			{
-				return instance.object().pos;
+				return instance.getPosition(true);
 			}
 		}
 	}
@@ -435,6 +438,16 @@ int3 rmg::Object::getGuardPos() const
 	}
 }
 
+void rmg::Object::setValue(size_t newValue)
+{
+	value = newValue;
+}
+
+size_t rmg::Object::getValue() const
+{
+	return value;
+}
+
 void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng)
 {
 	if(!map.isOnMap(getPosition(true)))

+ 3 - 0
lib/rmg/RmgObject.h

@@ -89,6 +89,8 @@ public:
 	bool isGuarded() const;
 	int3 getGuardPos() const;
 	void setGuardedIfMonster(const Instance & object);
+	void setValue(size_t value);
+	size_t getValue() const;
 	
 	void finalize(RmgMap & map, CRandomGenerator &);
 	void clearCachedArea() const;
@@ -107,6 +109,7 @@ private:
 	mutable std::list<Object::Instance*> cachedInstanceList;
 	mutable std::list<const Object::Instance*> cachedInstanceConstList;
 	bool guarded;
+	size_t value;
 };
 }
 

+ 7 - 4
lib/rmg/modificators/TreasurePlacer.cpp

@@ -702,6 +702,7 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
 		}
 
 		auto & instance = rmgObject.addInstance(*object);
+		rmgObject.setValue(rmgObject.getValue() + oi->value);
 		instance.onCleared = oi->destroyObject;
 
 		do
@@ -829,6 +830,7 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
 	int monsterStrength = (zone.monsterStrength == EMonsterStrength::ZONE_NONE ? 0 : zone.monsterStrength + mapMonsterStrength - 1); //array index from 0 to 4; pick any correct value for ZONE_NONE, minGuardedValue won't be used in this case anyway
 	static const int minGuardedValues[] = { 6500, 4167, 3000, 1833, 1333 };
 	minGuardedValue = minGuardedValues[monsterStrength];
+	const auto blockingGuardMaxValue = zone.getMaxTreasureValue() / 3;
 
 	auto valueComparator = [](const CTreasureInfo& lhs, const CTreasureInfo& rhs) -> bool
 	{
@@ -937,10 +939,9 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
 
 				if (guarded)
 				{
-					// Guard cannot be adjacent to road, but blocked side of an object could be
 					searchArea.subtract(roads);
 
-					path = manager.placeAndConnectObject(searchArea, rmgObject, [this, &rmgObject, &minDistance, &manager, &nextToRoad](const int3& tile)
+					path = manager.placeAndConnectObject(searchArea, rmgObject, [this, &rmgObject, &minDistance, &manager, blockingGuardMaxValue, &roads, &nextToRoad](const int3& tile)
 						{
 							float bestDistance = 10e9;
 							for (const auto& t : rmgObject.getArea().getTilesVector())
@@ -951,7 +952,9 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
 								else
 									vstd::amin(bestDistance, distance);
 							}
-							if (nextToRoad.contains(rmgObject.getGuardPos()))
+
+							// Guard cannot be adjacent to road, but blocked side of an object could be
+							if (rmgObject.getValue() > blockingGuardMaxValue && nextToRoad.contains(rmgObject.getGuardPos()))
 							{
 								return -1.f;
 							}
@@ -959,7 +962,7 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
 							const auto & guardedArea = rmgObject.instances().back()->getAccessibleArea();
 							const auto areaToBlock = rmgObject.getAccessibleArea(true) - guardedArea;
 
-							if (zone.freePaths()->overlap(areaToBlock) || manager.getVisitableArea().overlap(areaToBlock))
+							if (zone.freePaths()->overlap(areaToBlock) || roads.overlap(areaToBlock) || manager.getVisitableArea().overlap(areaToBlock))
 								return -1.f;
 
 							return bestDistance;