浏览代码

Move road flag to placeObject() method

Tomasz Zieliński 2 年之前
父节点
当前提交
1cad64c470

+ 3 - 4
lib/rmg/modificators/ConnectionsPlacer.cpp

@@ -240,7 +240,7 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
 				{
 					rmg::Object monster(*monsterType);
 					monster.setPosition(guardPos);
-					manager.placeObject(monster, false, true);
+					manager.placeObject(monster, false, true, true);
 					//Place objects away from the monster in the other zone, too
 					otherZone->getModificator<ObjectManager>()->updateDistances(monster);
 				}
@@ -346,9 +346,8 @@ void ConnectionsPlacer::selfSideIndirectConnection(const rmg::ZoneConnection & c
 				zone.connectPath(path1);
 				otherZone->connectPath(path2);
 				
-				//TODO: Check allowRoad
-				manager.placeObject(rmgGate1, guarded1, true);
-				managerOther.placeObject(rmgGate2, guarded2, true);
+				manager.placeObject(rmgGate1, guarded1, true, allowRoad);
+				managerOther.placeObject(rmgGate2, guarded2, true, allowRoad);
 				
 				assert(otherZone->getModificator<ConnectionsPlacer>());
 				otherZone->getModificator<ConnectionsPlacer>()->otherSideConnection(connection);

+ 19 - 20
lib/rmg/modificators/ObjectManager.cpp

@@ -347,7 +347,7 @@ bool ObjectManager::createRequiredObjects()
 		}
 		
 		zone.connectPath(path);
-		placeObject(rmgObject, guarded, true);
+		placeObject(rmgObject, guarded, true, objInfo.createRoad);
 		
 		for(const auto & nearby : nearbyObjects)
 		{
@@ -364,7 +364,7 @@ bool ObjectManager::createRequiredObjects()
 			}
 			
 			rmgNearObject.setPosition(*RandomGeneratorUtil::nextItem(possibleArea.getTiles(), zone.getRand()));
-			placeObject(rmgNearObject, false, false);
+			placeObject(rmgNearObject, false, false, nearby.createRoad);
 		}
 	}
 	
@@ -430,7 +430,7 @@ bool ObjectManager::createRequiredObjects()
 	return true;
 }
 
-void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateDistance, bool allowRoad/* = true*/)
+void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateDistance, bool createRoad/* = false*/)
 {	
 	object.finalize(map);
 
@@ -487,22 +487,22 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
 				break;
 		}
 	}
-	
-	if (allowRoad)
+
+	if (createRoad)
 	{
-		switch (object.instances().front()->object().ID)
-		{
-		case Obj::TOWN:
-		case Obj::RANDOM_TOWN:
-		case Obj::MONOLITH_TWO_WAY:
-		case Obj::MONOLITH_ONE_WAY_ENTRANCE:
+		if (auto* m = zone.getModificator<RoadPlacer>())
+			m->addRoadNode(object.instances().front()->getVisitablePosition());
+	}
+
+	//TODO: Add road node to these objects:
+	/*
+	 	case Obj::MONOLITH_ONE_WAY_ENTRANCE:
+	 	case Obj::RANDOM_TOWN:
 		case Obj::MONOLITH_ONE_WAY_EXIT:
-		case Obj::SUBTERRANEAN_GATE:
-		case Obj::SHIPYARD:
-			if (auto* m = zone.getModificator<RoadPlacer>())
-				m->addRoadNode(object.instances().front()->getVisitablePosition());
-			break;
+	*/
 
+	switch (object.instances().front()->object().ID)
+	{
 		case Obj::WATER_WHEEL:
 			if (auto* m = zone.getModificator<RiverPlacer>())
 				m->addRiverNode(object.instances().front()->getVisitablePosition());
@@ -510,7 +510,6 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
 
 		default:
 			break;
-		}
 	}
 }
 
@@ -617,14 +616,14 @@ RequiredObjectInfo::RequiredObjectInfo():
 	obj(nullptr),
 	nearbyTarget(nullptr),
 	guardStrength(0),
-	allowRoad(true)
+	createRoad(true)
 {}
 
-RequiredObjectInfo::RequiredObjectInfo(CGObjectInstance* obj, ui32 guardStrength, bool allowRoad, CGObjectInstance* nearbyTarget):
+RequiredObjectInfo::RequiredObjectInfo(CGObjectInstance* obj, ui32 guardStrength, bool createRoad, CGObjectInstance* nearbyTarget):
 	obj(obj),
 	nearbyTarget(nearbyTarget),
 	guardStrength(guardStrength),
-	allowRoad(allowRoad)
+	createRoad(createRoad)
 {}
 
 

+ 3 - 3
lib/rmg/modificators/ObjectManager.h

@@ -32,13 +32,13 @@ struct DistanceMaximizeFunctor
 struct RequiredObjectInfo
 {
 	RequiredObjectInfo();
-	RequiredObjectInfo(CGObjectInstance* obj, ui32 guardStrength = 0, bool allowRoad = true, CGObjectInstance* nearbyTarget = nullptr);
+	RequiredObjectInfo(CGObjectInstance* obj, ui32 guardStrength = 0, bool createRoad = false, CGObjectInstance* nearbyTarget = nullptr);
 
 	CGObjectInstance* obj;
 	CGObjectInstance* nearbyTarget;
 	int3 pos;
 	ui32 guardStrength;
-	bool allowRoad;
+	bool createRoad;
 };
 
 class ObjectManager: public Modificator
@@ -71,7 +71,7 @@ public:
 
 	CGCreature * chooseGuard(si32 strength, bool zoneGuard = false);
 	bool addGuard(rmg::Object & object, si32 strength, bool zoneGuard = false);
-	void placeObject(rmg::Object & object, bool guarded, bool updateDistance, bool allowRoad = true);
+	void placeObject(rmg::Object & object, bool guarded, bool updateDistance, bool createRoad = false);
 
 	void updateDistances(const rmg::Object & obj);
 	void updateDistances(const int3& pos);

+ 6 - 5
lib/rmg/modificators/RoadPlacer.cpp

@@ -80,19 +80,20 @@ bool RoadPlacer::createRoad(const int3 & dst)
 
 void RoadPlacer::drawRoads(bool secondary)
 {
-	if((secondary && generator.getConfig().secondaryRoadType.empty())
-	   || (!secondary && generator.getConfig().defaultRoadType.empty()))
-		return;
+	//TODO: Check road type set in lobby. If no road, return.
 	
-	//RecursiveLock lock(externalAccessMutex);
 	{
-		//FIXME: double lock - unsafe
+		//Clean space under roads even if they won't be eventually generated
 		Zone::Lock lock(zone.areaMutex);
 
 		zone.areaPossible().subtract(roads);
 		zone.freePaths().unite(roads);
 	}
 
+	if((secondary && generator.getConfig().secondaryRoadType.empty())
+		|| (!secondary && generator.getConfig().defaultRoadType.empty()))
+		return;
+
 	auto tiles = roads.getTilesVector();
 
 	std::string roadName = (secondary ? generator.getConfig().secondaryRoadType : generator.getConfig().defaultRoadType);

+ 4 - 2
lib/rmg/modificators/TownPlacer.cpp

@@ -152,7 +152,7 @@ int3 TownPlacer::placeMainTown(ObjectManager & manager, CGTownInstance & town)
 			}, ObjectManager::OptimizeType::WEIGHT);
 	}
 	rmgObject.setPosition(position + int3(2, 2, 0)); //place visitable tile in the exact center of a zone
-	manager.placeObject(rmgObject, false, true);
+	manager.placeObject(rmgObject, false, true, true);
 	cleanupBoundaries(rmgObject);
 	zone.setPos(rmgObject.getVisitablePosition()); //roads lead to main town
 	return position;
@@ -216,7 +216,9 @@ void TownPlacer::addNewTowns(int count, bool hasFort, const PlayerColor & player
 			placeMainTown(manager, *town);
 		}
 		else
-			manager.addRequiredObject(town);
+		{
+			manager.addRequiredObject(RequiredObjectInfo(town, 0, true));
+		}
 		totalTowns++;
 	}
 }

+ 9 - 4
lib/rmg/modificators/WaterProxy.cpp

@@ -126,6 +126,7 @@ void WaterProxy::collectLakes()
 RouteInfo WaterProxy::waterRoute(Zone & dst)
 {
 	RouteInfo result;
+	result.createRoad = false;
 	
 	auto * adopter = dst.getModificator<WaterAdopter>();
 	if(!adopter)
@@ -162,7 +163,13 @@ RouteInfo WaterProxy::waterRoute(Zone & dst)
 			int zoneTowns = 0;
 			if(auto * m = dst.getModificator<TownPlacer>())
 				zoneTowns = m->getTotalTowns();
+
+			if (vstd::contains(lake.keepRoads, zone.getId()))
+			{
+				result.createRoad = true;
+			}
 			
+			//FIXME: Why are Shipyards not allowed in zones with no towns?
 			if(dst.getType() == ETemplateZoneType::PLAYER_START || dst.getType() == ETemplateZoneType::CPU_START || zoneTowns)
 			{
 				if(placeShipyard(dst, lake, generator.getConfig().shipyardGuard, result))
@@ -284,7 +291,7 @@ bool WaterProxy::placeBoat(Zone & land, const Lake & lake, RouteInfo & info)
 
 		zone.connectPath(path);
 		land.connectPath(landPath);
-		manager->placeObject(rmgObject, false, true);
+		manager->placeObject(rmgObject, false, true, info.createRoad);
 		land.getModificator<ObjectManager>()->updateDistances(rmgObject); //Keep land objects away from the boat
 		break;
 	}
@@ -374,9 +381,7 @@ bool WaterProxy::placeShipyard(Zone & land, const Lake & lake, si32 guard, Route
 		info.boarding = boardingPosition;
 		info.water = shipPositions;
 		
-		//TODO: Check connection properties
-		bool allowRoad = true;
-		manager->placeObject(rmgObject, guarded, true, allowRoad);
+		manager->placeObject(rmgObject, guarded, true, info.createRoad);
 		
 		zone.areaPossible().subtract(shipyardOutToBlock);
 		for(const auto & i : shipyardOutToBlock.getTilesVector())

+ 2 - 0
lib/rmg/modificators/WaterProxy.h

@@ -19,6 +19,7 @@ struct RouteInfo
 	int3 visitable;
 	int3 boarding;
 	rmg::Area water;
+	bool createRoad; //Road to Shipyard or Boat
 };
 
 class WaterProxy: public Modificator
@@ -34,6 +35,7 @@ public:
 		std::map<int, rmg::Tileset> reverseDistanceMap;
 		std::map<TRmgTemplateZoneId, rmg::Area> neighbourZones; //zones boardered. Area - part of land
 		std::set<TRmgTemplateZoneId> keepConnections;
+		std::set<TRmgTemplateZoneId> keepRoads;
 	};
 		
 	bool waterKeepConnection(TRmgTemplateZoneId zoneA, TRmgTemplateZoneId zoneB);