From cd611a2f7fc00e8bd2cd74feb88c8394bd0fa376 Mon Sep 17 00:00:00 2001
From: Tim Felgentreff <timfelgentreff@gmail.com>
Date: Sun, 20 Feb 2022 13:56:26 +0100
Subject: [PATCH] add disabled astar overlay

---
 src/include/tile.h       |  3 +++
 src/map/map_draw.cpp     | 32 ++++++++++++++++++++++++++++++++
 src/pathfinder/astar.cpp | 15 +++++++++++++++
 3 files changed, 50 insertions(+)

diff --git a/src/include/tile.h b/src/include/tile.h
index ff9aee7c7..1166689ce 100644
--- a/src/include/tile.h
+++ b/src/include/tile.h
@@ -227,6 +227,9 @@ public:
 	unsigned char getCost() const { return cost; }
 	unsigned int getFlag() const { return Flags; }
 	void setGraphicTile(unsigned int tile) { this->tile = tile; }
+#ifdef DEBUG
+	int64_t lastAStarCost;    /// debugging pathfinder
+#endif
 private:
 #ifdef DEBUG
 	unsigned int tilesetTile;  /// tileset tile number
diff --git a/src/map/map_draw.cpp b/src/map/map_draw.cpp
index a58508db4..61b5b25e6 100644
--- a/src/map/map_draw.cpp
+++ b/src/map/map_draw.cpp
@@ -286,6 +286,38 @@ void CViewport::DrawMapBackgroundInViewport() const
 				tile = mf.playerInfo.SeenTile;
 			}
 			Map.TileGraphic->DrawFrameClip(tile, dx, dy);
+#if 0
+			int64_t cost = mf.lastAStarCost;
+			int32_t alpha;
+			// we use the msb as marker, but only consider the lower 32-bits as numeric value
+			if (cost != 0) {
+				if (cost == -1) {
+					// non traversible tiles always start full red
+					alpha = -60;
+				} else if (cost > 0) {
+					// msb not set means this has not been scaled
+					// scale cost to be between 1 and 60
+					cost <<= 3;
+					if (cost > 60) {
+						cost = 60;
+					}
+					alpha = static_cast<int32_t>(cost);
+				} else {
+					// consider only low 32-bits of already scaled value
+					alpha = static_cast<int32_t>(cost);
+				}
+			}
+			if (alpha > 0) {
+				Video.FillTransRectangleClip(ColorGreen, dx, dy,
+								 dx + Map.TileGraphic->getWidth(), dy + dx + Map.TileGraphic->getWidth(), alpha * 200 / 60);
+				alpha--;
+			} else if (alpha < 0) {
+				Video.FillTransRectangleClip(ColorRed, dx, dy,
+								 dx + Map.TileGraphic->getWidth(), dy + dx + Map.TileGraphic->getWidth(), -alpha * 200 / 60);
+				alpha++;
+			}
+			const_cast<CMapField &>(mf).lastAStarCost = alpha | ((uint64_t)1 << 63);
+#endif
 			++sx;
 			dx += PixelTileSize.x;
 		}
diff --git a/src/pathfinder/astar.cpp b/src/pathfinder/astar.cpp
index 996bbca12..5cbd52c3c 100644
--- a/src/pathfinder/astar.cpp
+++ b/src/pathfinder/astar.cpp
@@ -534,12 +534,18 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
 			if (flag && (AStarKnowUnseenTerrain || mf->playerInfo.IsExplored(*unit.Player))) {
 				if (flag & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit)) {
 					// we can't cross fixed units and other unpassable things
+#ifdef DEBUG
+					const_cast<CMapField *>(mf)->lastAStarCost = -1;
+#endif
 					return -1;
 				}
 				CUnit *goal = mf->UnitCache.find(unit_finder);
 				if (!goal) {
 					// Shouldn't happen, mask says there is something on this tile
 					Assert(0);
+#ifdef DEBUG
+					const_cast<CMapField *>(mf)->lastAStarCost = -1;
+#endif
 					return -1;
 				}
 				if (goal->Moving)  {
@@ -549,6 +555,9 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
 					// for non moving unit Always Fail unless goal is unit, or unit can attack the target
 					if (&unit != goal) {
 						if (GetAStarFixedEnemyUnitsUnpassable() == true) {
+#ifdef DEBUG
+							const_cast<CMapField *>(mf)->lastAStarCost = -1;
+#endif
 							return -1;
 						}
 						if (goal->Player->IsEnemy(unit) && unit.IsAgressive() && CanTarget(*unit.Type, *goal->Type)
@@ -556,6 +565,9 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
 								cost += 2 * AStarMovingUnitCrossingCost;
 						} else {
 						// FIXME: Need support for moving a fixed unit to add cost
+#ifdef DEBUG
+							const_cast<CMapField *>(mf)->lastAStarCost = -1;
+#endif
 							return -1;
 						}
 						//cost += AStarFixedUnitCrossingCost;
@@ -569,6 +581,9 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
 			}
 			// Add tile movement cost
 			cost += mf->getCost();
+#ifdef DEBUG
+			const_cast<CMapField *>(mf)->lastAStarCost = cost;
+#endif
 			++mf;
 		} while (--i);
 		index += AStarMapWidth;