2
0
Эх сурвалжийг харах

Do not place guardes treasure on roads. Do not place guards next to roads.

Tomasz Zieliński 1 жил өмнө
parent
commit
9301bb9af5

+ 18 - 0
lib/rmg/RmgObject.cpp

@@ -417,6 +417,24 @@ void rmg::Object::setGuardedIfMonster(const Instance& object)
 	}
 }
 
+int3 rmg::Object::getGuardPos() const
+{
+	if (guarded)
+	{
+		for (auto & instance : dInstances)
+		{
+			if (instance.object().ID == Obj::MONSTER)
+			{
+				return instance.object().pos;
+			}
+		}
+	}
+	else
+	{
+		return int3(-1,-1,-1);
+	}
+}
+
 void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng)
 {
 	if(!map.isOnMap(getPosition(true)))

+ 1 - 0
lib/rmg/RmgObject.h

@@ -87,6 +87,7 @@ public:
 	const int3 getVisibleTop() const;
 
 	bool isGuarded() const;
+	int3 getGuardPos() const;
 	void setGuardedIfMonster(const Instance & object);
 	
 	void finalize(RmgMap & map, CRandomGenerator &);

+ 18 - 2
lib/rmg/modificators/TreasurePlacer.cpp

@@ -55,7 +55,7 @@ void TreasurePlacer::init()
 	DEPENDENCY(ObjectManager);
 	DEPENDENCY(ConnectionsPlacer);
 	DEPENDENCY_ALL(PrisonHeroPlacer);
-	POSTFUNCTION(RoadPlacer);
+	DEPENDENCY(RoadPlacer);
 }
 
 void TreasurePlacer::addObjectToRandomPool(const ObjectInfo& oi)
@@ -842,6 +842,15 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
 			oi->maxPerZone++;
 		}
 	};
+
+	rmg::Area roads;
+	auto rp = zone.getModificator<RoadPlacer>();
+	if (rp)
+	{
+		roads = rp->getRoads();
+	}
+	rmg::Area nextToRoad(roads.getBorderOutside());
+
 	//place biggest treasures first at large distance, place smaller ones inbetween
 	auto treasureInfo = zone.getTreasureInfo();
 	boost::sort(treasureInfo, valueComparator);
@@ -928,7 +937,10 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
 
 				if (guarded)
 				{
-					path = manager.placeAndConnectObject(searchArea, rmgObject, [this, &rmgObject, &minDistance, &manager](const int3& tile)
+					// TODO: 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)
 						{
 							float bestDistance = 10e9;
 							for (const auto& t : rmgObject.getArea().getTilesVector())
@@ -939,6 +951,10 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
 								else
 									vstd::amin(bestDistance, distance);
 							}
+							if (nextToRoad.contains(rmgObject.getGuardPos()))
+							{
+								return -1.f;
+							}
 
 							const auto & guardedArea = rmgObject.instances().back()->getAccessibleArea();
 							const auto areaToBlock = rmgObject.getAccessibleArea(true) - guardedArea;