using System.Collections; using System.Collections.Generic; using UnityEngine; namespace HxGame.PathFinding { public class PathFinderHelper { public delegate int PathFindingEvent(int cellIndex); public event PathFindingEvent OnPathFindingCrossCell; int _pathFindingMaxSteps = 2000; int _pathFindingMaxCost = 2000; bool _pathFindingUseDiagonals = true; float _pathFindingHeavyDiagonalsCost = 1.4f; CellNode[] cellsNode = null; int _cellRows; int _cellCols; IPathFinder finder = null; public PathFinderHelper(CellNode[] cellsNode, int rows, int cols) { this.cellsNode = cellsNode; if (finder == null) { if ((cols & (cols - 1)) == 0) finder = new PathFinderFast(cellsNode, cols, rows); else finder = new PathFinderFastNonSQR(cellsNode, cols, rows); } _cellRows = rows; _cellCols = cols; } public List FindPath(int cellIndexStart, int cellIndexEnd, float maxSearchCost = 0, int maxSteps = 0, int cellGroupMask = -1) { float dummy; return FindPath(cellIndexStart, cellIndexEnd, out dummy, maxSearchCost, maxSteps, cellGroupMask); } public List FindPath(int cellIndexStart, int cellIndexEnd, out float totalCost, float maxSearchCost = 0, int maxSteps = 0, int cellGroupMask = -1) { List results = new List(); FindPath(cellIndexStart, cellIndexEnd, results, out totalCost, maxSearchCost, maxSteps, cellGroupMask); return results; } public int FindPath(int cellIndexStart, int cellIndexEnd, List cellIndices, out float totalCost, float maxSearchCost = 0, int maxSteps = 0, int cellGroupMask = -1) { finder.Formula = HeuristicFormula.MaxDXDY; finder.MaxSteps = maxSteps > 0 ? maxSteps : _pathFindingMaxSteps; finder.Diagonals = _pathFindingUseDiagonals; finder.HeavyDiagonalsCost = _pathFindingHeavyDiagonalsCost; finder.HexagonalGrid = false; finder.MaxSearchCost = maxSearchCost > 0 ? maxSearchCost : _pathFindingMaxCost; finder.CellGroupMask = cellGroupMask; finder.IgnoreCanCrossCheck = false; finder.IgnoreCellCost = false; if (OnPathFindingCrossCell != null) finder.OnCellCross = FindRoutePositionValidator; else finder.OnCellCross = null; CellNode startCell = cellsNode[cellIndexStart]; CellNode endCell = cellsNode[cellIndexEnd]; List route = finder.FindPath(startCell, endCell, out totalCost, false); if (route != null) { int routeCount = route.Count; for (int r = routeCount - 2; r >= 0; r--) { int cellIndex = route[r].PY * _cellCols + route[r].PX; cellIndices.Add(cellIndex); } return route.Count; } else return -1; } private float FindRoutePositionValidator(int cellIndex) { float cost = 1; if (OnPathFindingCrossCell != null) { cost = OnPathFindingCrossCell(cellIndex); } return cost; } } }