Просмотр исходного кода

- Check road connection for Shipyards

Tomasz Zieliński 2 лет назад
Родитель
Сommit
7e07ed65c8

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

@@ -98,6 +98,7 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
 	bool success = false;
 	auto otherZoneId = (connection.getZoneA() == zone.getId() ? connection.getZoneB() : connection.getZoneA());
 	auto & otherZone = map.getZones().at(otherZoneId);
+	bool createRoad = shouldGenerateRoad(connection);
 	
 	//1. Try to make direct connection
 	//Do if it's not prohibited by terrain settings
@@ -254,7 +255,7 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
 					otherZone->getModificator<ObjectManager>()->updateDistances(guardPos);
 				}
 				
-				if (shouldGenerateRoad(connection))
+				if (createRoad)
 				{
 					assert(zone.getModificator<RoadPlacer>());
 					zone.getModificator<RoadPlacer>()->addRoadNode(guardPos);
@@ -277,7 +278,7 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
 	{
 		if(generator.getZoneWater() && generator.getZoneWater()->getModificator<WaterProxy>())
 		{
-			if(generator.getZoneWater()->getModificator<WaterProxy>()->waterKeepConnection(connection.getZoneA(), connection.getZoneB()))
+			if(generator.getZoneWater()->getModificator<WaterProxy>()->waterKeepConnection(connection, createRoad))
 			{
 				assert(otherZone->getModificator<ConnectionsPlacer>());
 				otherZone->getModificator<ConnectionsPlacer>()->otherSideConnection(connection);

+ 20 - 13
lib/rmg/modificators/WaterProxy.cpp

@@ -126,7 +126,6 @@ void WaterProxy::collectLakes()
 RouteInfo WaterProxy::waterRoute(Zone & dst)
 {
 	RouteInfo result;
-	result.createRoad = false;
 	
 	auto * adopter = dst.getModificator<WaterAdopter>();
 	if(!adopter)
@@ -134,6 +133,8 @@ RouteInfo WaterProxy::waterRoute(Zone & dst)
 	
 	if(adopter->getCoastTiles().empty())
 		return result;
+
+	bool createRoad = false;
 	
 	//block zones are not connected by template
 	for(auto& lake : lakes)
@@ -164,22 +165,22 @@ RouteInfo WaterProxy::waterRoute(Zone & dst)
 			if(auto * m = dst.getModificator<TownPlacer>())
 				zoneTowns = m->getTotalTowns();
 
-			if (vstd::contains(lake.keepRoads, zone.getId()))
+			if (vstd::contains(lake.keepRoads, dst.getId()))
 			{
-				result.createRoad = true;
+				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))
+				if(placeShipyard(dst, lake, generator.getConfig().shipyardGuard, createRoad, result))
 				{
 					logGlobal->info("Shipyard successfully placed at zone %d", dst.getId());
 				}
 				else
 				{
 					logGlobal->warn("Shipyard placement failed, trying boat at zone %d", dst.getId());
-					if(placeBoat(dst, lake, result))
+					if(placeBoat(dst, lake, createRoad, result))
 					{
 						logGlobal->warn("Boat successfully placed at zone %d", dst.getId());
 					}
@@ -191,7 +192,7 @@ RouteInfo WaterProxy::waterRoute(Zone & dst)
 			}
 			else
 			{
-				if(placeBoat(dst, lake, result))
+				if(placeBoat(dst, lake,  createRoad, result))
 				{
 					logGlobal->info("Boat successfully placed at zone %d", dst.getId());
 				}
@@ -206,21 +207,29 @@ RouteInfo WaterProxy::waterRoute(Zone & dst)
 	return result;
 }
 
-bool WaterProxy::waterKeepConnection(TRmgTemplateZoneId zoneA, TRmgTemplateZoneId zoneB)
+bool WaterProxy::waterKeepConnection(const rmg::ZoneConnection & connection, bool createRoad)
 {
+	const auto & zoneA = connection.getZoneA();
+	const auto & zoneB = connection.getZoneB();
+
 	for(auto & lake : lakes)
 	{
 		if(lake.neighbourZones.count(zoneA) && lake.neighbourZones.count(zoneB))
 		{
 			lake.keepConnections.insert(zoneA);
 			lake.keepConnections.insert(zoneB);
+			if (createRoad)
+			{
+				lake.keepRoads.insert(zoneA);
+				lake.keepRoads.insert(zoneB);
+			}
 			return true;
 		}
 	}
 	return false;
 }
 
-bool WaterProxy::placeBoat(Zone & land, const Lake & lake, RouteInfo & info)
+bool WaterProxy::placeBoat(Zone & land, const Lake & lake, bool createRoad, RouteInfo & info)
 {
 	auto * manager = zone.getModificator<ObjectManager>();
 	if(!manager)
@@ -291,7 +300,7 @@ bool WaterProxy::placeBoat(Zone & land, const Lake & lake, RouteInfo & info)
 
 		zone.connectPath(path);
 		land.connectPath(landPath);
-		manager->placeObject(rmgObject, false, true, info.createRoad);
+		manager->placeObject(rmgObject, false, true, createRoad);
 		land.getModificator<ObjectManager>()->updateDistances(rmgObject); //Keep land objects away from the boat
 		break;
 	}
@@ -299,10 +308,8 @@ bool WaterProxy::placeBoat(Zone & land, const Lake & lake, RouteInfo & info)
 	return !boardingPositions.empty();
 }
 
-bool WaterProxy::placeShipyard(Zone & land, const Lake & lake, si32 guard, RouteInfo & info)
+bool WaterProxy::placeShipyard(Zone & land, const Lake & lake, si32 guard, bool createRoad, RouteInfo & info)
 {
-	//TODO: Check for road
-
 	auto * manager = land.getModificator<ObjectManager>();
 	if(!manager)
 		return false;
@@ -381,7 +388,7 @@ bool WaterProxy::placeShipyard(Zone & land, const Lake & lake, si32 guard, Route
 		info.boarding = boardingPosition;
 		info.water = shipPositions;
 		
-		manager->placeObject(rmgObject, guarded, true, info.createRoad);
+		manager->placeObject(rmgObject, guarded, true, createRoad);
 		
 		zone.areaPossible().subtract(shipyardOutToBlock);
 		for(const auto & i : shipyardOutToBlock.getTilesVector())

+ 3 - 4
lib/rmg/modificators/WaterProxy.h

@@ -19,7 +19,6 @@ struct RouteInfo
 	int3 visitable;
 	int3 boarding;
 	rmg::Area water;
-	bool createRoad; //Road to Shipyard or Boat
 };
 
 class WaterProxy: public Modificator
@@ -38,7 +37,7 @@ public:
 		std::set<TRmgTemplateZoneId> keepRoads;
 	};
 		
-	bool waterKeepConnection(TRmgTemplateZoneId zoneA, TRmgTemplateZoneId zoneB);
+	bool waterKeepConnection(const rmg::ZoneConnection & connection, bool createRoad);
 	RouteInfo waterRoute(Zone & dst);
 	
 	void process() override;
@@ -49,8 +48,8 @@ public:
 protected:
 	void collectLakes();
 	
-	bool placeShipyard(Zone & land, const Lake & lake, si32 guard, RouteInfo & info);
-	bool placeBoat(Zone & land, const Lake & lake, RouteInfo & info);
+	bool placeShipyard(Zone & land, const Lake & lake, si32 guard, bool createRoad, RouteInfo & info);
+	bool placeBoat(Zone & land, const Lake & lake, bool createRoad, RouteInfo & info);
 
 protected:
 	std::vector<Lake> lakes; //disconnected parts of zone. Used to work with water zones