浏览代码

Improved road routing so they can go under any passable object.

DjWarmonger 8 年之前
父节点
当前提交
cc452bdfa9
共有 5 个文件被更改,包括 19 次插入9 次删除
  1. 2 2
      CCallback.cpp
  2. 6 0
      lib/mapping/CMap.cpp
  3. 1 0
      lib/mapping/CMap.h
  4. 1 1
      lib/rmg/CMapGenerator.cpp
  5. 9 6
      lib/rmg/CRmgTemplateZone.cpp

+ 2 - 2
CCallback.cpp

@@ -275,8 +275,8 @@ CCallback::~CCallback()
 
 bool CCallback::canMoveBetween(const int3 &a, const int3 &b)
 {
-	//TODO: merge with Pathfinder::canMoveBetween
-	return gs->checkForVisitableDir(a, b) && gs->checkForVisitableDir(b, a);
+	//bidirectional
+	return gs->map->canMoveBetween(a, b);
 }
 
 const CPathsInfo * CCallback::getPathsInfo(const CGHeroInstance *h)

+ 6 - 0
lib/mapping/CMap.cpp

@@ -385,6 +385,12 @@ bool CMap::isWaterTile(const int3 &pos) const
 {
 	return isInTheMap(pos) && getTile(pos).isWater();
 }
+bool CMap::canMoveBetween(const int3 &src, const int3 &dst) const
+{
+	const TerrainTile * dstTile = &getTile(dst);
+	const TerrainTile * srcTile = &getTile(src);
+	return checkForVisitableDir(src, dstTile, dst) && checkForVisitableDir(dst, srcTile, src);
+}
 
 bool CMap::checkForVisitableDir(const int3 & src, const TerrainTile *pom, const int3 & dst ) const
 {

+ 1 - 0
lib/mapping/CMap.h

@@ -304,6 +304,7 @@ public:
 	bool isInTheMap(const int3 & pos) const;
 	bool isWaterTile(const int3 & pos) const;
 
+	bool canMoveBetween(const int3 &src, const int3 &dst) const;
 	bool checkForVisitableDir( const int3 & src, const TerrainTile *pom, const int3 & dst ) const;
 	int3 guardingCreaturePosition (int3 pos) const;
 

+ 1 - 1
lib/rmg/CMapGenerator.cpp

@@ -319,7 +319,7 @@ void CMapGenerator::fillZones()
 		it.second->createObstacles2(this);
 	}
 
-	#define PRINT_MAP_BEFORE_ROADS true
+	#define PRINT_MAP_BEFORE_ROADS false
 	if (PRINT_MAP_BEFORE_ROADS) //enable to debug
 	{
 		std::ofstream out("road debug");

+ 9 - 6
lib/rmg/CRmgTemplateZone.cpp

@@ -776,6 +776,7 @@ bool CRmgTemplateZone::createRoad(CMapGenerator* gen, const int3& src, const int
 		pq.pop(); //remove top element
 		int3 currentNode = node.first;
 		closed.insert (currentNode);
+		auto currentTile = &gen->map->getTile(currentNode);
 
 		if (currentNode == dst || gen->isRoad(currentNode))
 		{
@@ -798,7 +799,7 @@ bool CRmgTemplateZone::createRoad(CMapGenerator* gen, const int3& src, const int
 			bool directNeighbourFound = false;
 			float movementCost = 1;
 
-			auto foo = [gen, this, &pq, &distances, &closed, &cameFrom, &currentNode, &node, &dst, &directNeighbourFound, &movementCost](int3& pos) -> void
+			auto foo = [gen, this, &pq, &distances, &closed, &cameFrom, &currentNode, &currentTile, &node, &dst, &directNeighbourFound, &movementCost](int3& pos) -> void
 			{
 				if (vstd::contains(closed, pos)) //we already visited that node
 					return;
@@ -810,10 +811,13 @@ bool CRmgTemplateZone::createRoad(CMapGenerator* gen, const int3& src, const int
 
 				if (distance < bestDistanceSoFar)
 				{
-					auto obj = gen->map->getTile(pos).topVisitableObj();
-					//FIXME: make road go through any empty or visitable tile
-					//if (gen->map->checkForVisitableDir(currentNode, &gen->map->getTile(pos), pos)) //TODO: why it has no effect?
-					if (gen->isFree(pos) || (obj && obj->ID == Obj::MONSTER) || pos == dst)
+					auto tile = &gen->map->getTile(pos);
+					auto obj = tile->topVisitableObj();
+					bool canMoveBetween = gen->map->canMoveBetween(currentNode, pos);
+
+					if (gen->isFree(pos) && gen->isFree(currentNode) //empty path
+						|| ((tile->visitable || currentTile->visitable) && canMoveBetween) //moving from or to visitable object
+						|| pos == dst) //we already compledted the path
 					{
 						if (gen->getZoneID(pos) == id || pos == dst) //otherwise guard position may appear already connected to other zone.
 						{
@@ -821,7 +825,6 @@ bool CRmgTemplateZone::createRoad(CMapGenerator* gen, const int3& src, const int
 							distances[pos] = distance;
 							pq.push(std::make_pair(pos, distance));
 							directNeighbourFound = true;
-							//logGlobal->traceStream() << boost::format("Found connection between node %s and %s, current distance %d") % currentNode % pos % distance;
 						}
 					}
 				}