1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-27 21:49:10 +02:00

- Check road connection for Shipyards

This commit is contained in:
Tomasz Zieliński 2023-07-07 21:27:24 +02:00
parent 1cad64c470
commit 7e07ed65c8
3 changed files with 26 additions and 19 deletions

View File

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

View File

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

View File

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