1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +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;
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);

View File

@ -126,7 +126,6 @@ void WaterProxy::collectLakes()
RouteInfo WaterProxy::waterRoute(Zone & dst)
{
RouteInfo result;
result.createRoad = false;
auto * adopter = dst.getModificator<WaterAdopter>();
if(!adopter)
@ -135,6 +134,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())

View File

@ -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