From 87f7af88f8375b889c1fbd5d0c1ed034d9f12c50 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Fri, 28 Jul 2023 22:14:28 +0200 Subject: [PATCH] Navigation: filtering out invalid start and end points. --- HexGrid.cs | 20 ++++++++++++++++++++ components/NavigationComponent.cs | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/HexGrid.cs b/HexGrid.cs index a11d3da..c63e668 100644 --- a/HexGrid.cs +++ b/HexGrid.cs @@ -199,6 +199,26 @@ public class HexGrid : Resource return cost; } + + public HexCell GetClosestWalkableCell(HexCell fromCell, HexCell toCell) + { + if (GetHexCost(toCell) == 0) + { + HexCell[] line = fromCell.LineTo(toCell); + + foreach (int i in Enumerable.Range(1, line.Length)) + { + if (GetHexCost(line[i]) == 0) + { + toCell = line[i - 1]; + break; + } + } + } + + return toCell; + } + public List FindPath(HexCell startHex, HexCell goalHex) { Vector2 startAxialCoords = startHex.AxialCoords; diff --git a/components/NavigationComponent.cs b/components/NavigationComponent.cs index 737bd2e..5a7d216 100644 --- a/components/NavigationComponent.cs +++ b/components/NavigationComponent.cs @@ -104,7 +104,27 @@ public class NavigationComponent : Spatial public void FindPath(KinematicBody body, Vector3 fromPositionWorld, Vector3 toPositionWorld) { HexCell fromCell = TileWorld.HexGrid.GetHexAt(new Vector2(fromPositionWorld.x, fromPositionWorld.z)); + if (TileWorld.HexGrid.GetHexCost(fromCell) == 0) + { + GD.Print("Invalid starting point for FindPath(): returning empty path."); + _planningPathWorldNavigationPoints = new List(); + _planningPathWorldNavigationPoints.Add(new NavigationPoint(fromPositionWorld)); + _planningPathSmoothedWorldNavigationPoints = _planningPathWorldNavigationPoints; + return; + } + HexCell toCell = TileWorld.HexGrid.GetHexAt(new Vector2(toPositionWorld.x, toPositionWorld.z)); + toCell = TileWorld.HexGrid.GetClosestWalkableCell(fromCell, toCell); + + if (TileWorld.HexGrid.GetHexCost(toCell) == 0) + { + GD.Print("Invalid target point for FindPath(): returning empty path."); + _planningPathWorldNavigationPoints = new List(); + _planningPathWorldNavigationPoints.Add(new NavigationPoint(fromPositionWorld)); + _planningPathSmoothedWorldNavigationPoints = _planningPathWorldNavigationPoints; + return; + } + List path = TileWorld.HexGrid.FindPath(fromCell, toCell); // GD.Print("Planning path and have " + TileWorld.HexGrid.Obstacles.Count + " obstacles:");