瀏覽代碼

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

Tomasz Zieliński 2 年之前
父節點
當前提交
8bfa34e97b
共有 1 個文件被更改,包括 49 次插入7 次删除
  1. 49 7
      lib/rmg/modificators/RoadPlacer.cpp

+ 49 - 7
lib/rmg/modificators/RoadPlacer.cpp

@@ -54,22 +54,52 @@ const rmg::Area & RoadPlacer::getRoads() const
 
 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);
 	path.connect(roads);
+
+	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);
+	auto res = path.search(dst, true, simpleRoutig);
 	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);
 			return weight * weight;
-		});
+		};
+		res = path.search(dst, false, desperateRoutig);
+
 		if(!res.valid())
 		{
-			logGlobal->warn("Failed to create road");
+			logGlobal->warn("Failed to create road to node %s", dst.toString());
 			return false;
 		}
 	}
@@ -149,7 +179,19 @@ void RoadPlacer::connectRoads()
 
 	for(const auto & node : roadNodes)
 	{
-		createRoad(node);
+		try
+		{
+			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