using UnityEngine;
using System;
using System.Linq;
using System.Threading;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using WPM.PathFinding;
namespace WPM {
public partial class WorldMapGlobe : MonoBehaviour {
#region Path Finding properties
///
/// Fired when path finding algorithmn evaluates a cell. Return the increased cost for cell.
///
public event PathFindingEvent OnPathFindingCrossCell;
[SerializeField]
HeuristicFormula
_pathFindingHeuristicFormula = HeuristicFormula.SphericalDistance;
///
/// The path finding heuristic formula to estimate distance from current position to destination
///
public PathFinding.HeuristicFormula pathFindingHeuristicFormula {
get { return _pathFindingHeuristicFormula; }
set {
if (value != _pathFindingHeuristicFormula) {
_pathFindingHeuristicFormula = value;
}
}
}
[SerializeField]
int
_pathFindingSearchLimit = 2000;
///
/// The maximum path length.
///
public int pathFindingSearchLimit {
get { return _pathFindingSearchLimit; }
set {
if (value != _pathFindingSearchLimit) {
_pathFindingSearchLimit = value;
}
}
}
[SerializeField]
int
_pathFindingSearchMaxCost = 2000;
///
/// The maximum cost for any path.
///
public int pathFindingSearchMaxCost {
get { return _pathFindingSearchMaxCost; }
set {
if (value != _pathFindingSearchMaxCost) {
_pathFindingSearchMaxCost = value;
isDirty = true;
}
}
}
#endregion
#region Public API
///
/// Returns an optimal path from startPosition to endPosition with options.
///
/// The route consisting of a list of cell indexes.
/// Start position in spherical coordinates
/// End position in spherical coordinates
/// Maximum search cost for the path finding algorithm. A value of 0 will use the global default defined by pathFindingMaxCost
/// Specifies if hidden cells can be included
/// Maximum crossing cost of path
public List FindPath(Vector3 startPosition, Vector3 endPosition, int searchLimit = 0, bool includeStartingCell = false, HiddenCellsFilterMode hiddenCells = HiddenCellsFilterMode.OnlyUseVisibleCells, int searchMaxCost = 0) {
int cellStartIndex = GetCellIndex(startPosition);
int cellEndIndex = GetCellIndex(endPosition);
return FindPath(cellStartIndex, cellEndIndex, searchLimit, includeStartingCell, hiddenCells, searchMaxCost);
}
///
/// Returns an optimal path from startPosition to endPosition with options.
///
/// The route consisting of a list of cell indexes.
/// Index of starting cell
/// Index of destination cell
/// Maximum search cost for the path finding algorithm. A value of 0 will use the global default defined by pathFindingMaxCost
/// Specifies if hidden cells can be included
/// Maximum crossing cost of path
public List FindPath(int cellIndexStart, int cellIndexEnd, int searchLimit = 0, bool includeStartingCell = false, HiddenCellsFilterMode hiddenCells = HiddenCellsFilterMode.OnlyUseVisibleCells, int searchMaxCost = 0) {
if (shouldGenerateGrid) {
GenerateGrid();
}
if (cellIndexStart < 0 || cells == null || cellIndexStart >= cells.Length || cellIndexEnd < 0 || cellIndexEnd >= cells.Length)
return null;
int startingPoint = cellIndexStart;
int endingPoint = cellIndexEnd;
List routePoints = null;
// Minimum distance for routing?
if (startingPoint != endingPoint) {
ComputeRouteMatrix();
finder.Formula = _pathFindingHeuristicFormula;
finder.SearchLimit = searchLimit == 0 ? _pathFindingSearchLimit : searchLimit;
finder.HiddenCellsFilter = hiddenCells;
finder.SearchMaxCost = searchMaxCost == 0 ? _pathFindingSearchMaxCost : searchMaxCost;
if (OnPathFindingCrossCell != null) {
finder.OnCellCross = FindRoutePositionValidator;
} else {
finder.OnCellCross = null;
}
List route = finder.FindPath(startingPoint, endingPoint);
if (route != null) {
int count = route.Count;
routePoints = new List(count);
int last = includeStartingCell ? count - 1 : count - 2;
for (int r = last; r >= 0; r--) {
routePoints.Add(route[r].index);
}
if (count == 0 || routePoints[routePoints.Count - 1] != cellIndexEnd) {
routePoints.Add(cellIndexEnd);
}
} else {
return null; // no route available
}
}
return routePoints;
}
///
/// Sets if path finding can cross this cell.
///
public bool SetCellCanCross(int cellIndex, bool canCross) {
if (cellIndex < 0 || cellIndex >= cells.Length)
return false;
cells[cellIndex].canCross = canCross;
return true;
}
///
/// Returns whether path finding can cross this cell.
///
public bool GetCellCanCross(int cellIndex) {
if (cellIndex < 0 || cellIndex >= cells.Length)
return false;
return cells[cellIndex].canCross;
}
///
/// Sets the cost for crossing a given cell side. Note that the cost is only assigned in one direction (from this cell to the outside).
///
/// true, if neighbour cost was set, false otherwise.
/// Cell index.
/// Cell neighbour index.
/// Cost.
/// If set to true, cost is assigned in either direction.
public bool SetCellNeighbourCost(int cellIndex, int cellNeighbourIndex, int cost, bool bothSides = true) {
if (cells == null || cellIndex < 0 || cellIndex >= cells.Length)
return false;
Cell cell = cells[cellIndex];
int neighbourIndex = GetCellNeighbourIndex(cellIndex, cellNeighbourIndex);
if (neighbourIndex < 0)
return false;
cell.neighboursCosts[neighbourIndex] = cost;
if (bothSides) {
cell = cells[cellNeighbourIndex];
neighbourIndex = GetCellNeighbourIndex(cellNeighbourIndex, cellIndex);
if (neighbourIndex < 0)
return false;
cell.neighboursCosts[neighbourIndex] = cost;
}
return true;
}
///
/// Sets the cost for crossing any cell side. Note that the cost is only assigned in one direction (from this cell to the outside).
///
public void SetCellNeighboursCost(int cellIndex, int cost, bool bothSides = true) {
if (cells == null || cellIndex < 0 || cellIndex >= cells.Length)
return;
Cell cell = cells[cellIndex];
int neighbourCount = cell.neighboursIndices.Length;
for (int k = 0; k < neighbourCount; k++) {
SetCellNeighbourCost(cellIndex, cell.neighboursIndices[k], cost, bothSides);
}
}
///
/// Gets the cost for crossing a given cell side
///
public int GetCellNeighbourCost(int cellIndex, int neighbourIndex) {
if (cells == null || cellIndex < 0 || cellIndex >= cells.Length)
return -1;
Cell cell = cells[cellIndex];
if (neighbourIndex < 0 || neighbourIndex >= cell.neighboursCosts.Length) {
return -1;
}
return cell.neighboursCosts[neighbourIndex];
}
#endregion
}
}