1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Allow routing road behind objects not visitable from top if that's absolutely neccessary.

This commit is contained in:
Tomasz Zieliński
2023-07-21 14:55:34 +02:00
parent 280085b95d
commit 8bfa34e97b

View File

@@ -54,22 +54,52 @@ const rmg::Area & RoadPlacer::getRoads() const
bool RoadPlacer::createRoad(const int3 & dst) bool RoadPlacer::createRoad(const int3 & dst)
{ {
auto searchArea = zone.areaPossible() + areaRoads + zone.freePaths() - isolated + roads; auto searchArea = zone.areaPossible() + zone.freePaths() + areaRoads + roads;
rmg::Path path(searchArea); rmg::Path path(searchArea);
path.connect(roads); path.connect(roads);
auto res = path.search(dst, true); auto simpleRoutig = [this](const int3& src, const int3& dst)
{
if(areaIsolated().contains(dst))
{
return 1000.0f; //Do not route road behind objects that are not visitable from top
}
else
{
return 1.0f;
}
};
auto res = path.search(dst, true, simpleRoutig);
if(!res.valid()) if(!res.valid())
{ {
res = path.search(dst, false, [](const int3 & src, const int3 & dst) auto desperateRoutig = [this](const int3& src, const int3& dst) -> float
{ {
//Do not allow connections straight up through object not visitable from top
if(std::abs((src - dst).y) == 1)
{
if(areaIsolated().contains(dst) || areaIsolated().contains(src))
{
return 1e30;
}
}
else
{
if(areaIsolated().contains(dst))
{
return 1e6;
}
}
float weight = dst.dist2dSQ(src); float weight = dst.dist2dSQ(src);
return weight * weight; return weight * weight;
}); };
res = path.search(dst, false, desperateRoutig);
if(!res.valid()) if(!res.valid())
{ {
logGlobal->warn("Failed to create road"); logGlobal->warn("Failed to create road to node %s", dst.toString());
return false; return false;
} }
} }
@@ -148,9 +178,21 @@ void RoadPlacer::connectRoads()
roads.add(*roadNodes.begin()); roads.add(*roadNodes.begin());
for(const auto & node : roadNodes) for(const auto & node : roadNodes)
{
try
{ {
createRoad(node); createRoad(node);
} }
catch (const rmgException& e)
{
logGlobal->warn("Handled exception while drawing road to node %s: %s", node.toString(), e.what());
}
catch (const std::exception & e)
{
logGlobal->error("Unhandled exception while drawing road to node %s: %s", node.toString(), e.what());
throw e;
}
}
//Draw dirt roads if there are only mines //Draw dirt roads if there are only mines
drawRoads(noRoadNodes); drawRoads(noRoadNodes);