using System.Collections; using System.Collections.Generic; using UnityEngine; namespace TBTK{ public class AStar{ public enum _BypassUnit{ No, FriendlyOnly, All } public static int BypassUnitCode(Unit unit){ if(unit.canMovePastUnit==_BypassUnit.No) return -1; else if(unit.canMovePastUnit==_BypassUnit.All) return -2; else return unit.facID; } public static int BypassUnitCode(bool bypassUnit){ return bypassUnit ? -2 : -1 ; } public static bool IgnoreAllUnit(int flag){ return flag==-2; } public static bool CantBypassUnit(int flag){ return flag==-1; } public static bool BypassFriendlyUnit(int flag){ return flag>=0; } //search for a path, through walkable tile only //for normal movement, return the path in a list of hexTile //public static List SearchWalkableNode(Node originNode, Node destNode, bool returnNearest=true){ //~ public static List SearchWalkableNode(Node originNode, Node destNode, bool bypassUnit=true, bool bypassObs=true, bool returnNearest=true){ //~ return SearchWalkableNode(originNode, destNode, BypassUnitCode(bypassUnit), bypassObs, returnNearest); //~ } public static List SearchWalkableNode(Node originNode, Node destNode, int bypassUnit=-1, bool bypassObs=true, bool returnNearest=true){ GridManager.ResetGrid(); List closeList=new List(); List openList=new List(); Node currentNode=originNode; float currentLowestF=Mathf.Infinity; int id=0; int i=0; while(true){ //if we have reach the destination if(currentNode==destNode) break; //move currentNode to closeList; closeList.Add(currentNode); currentNode.listState=Node._ListState.Close; //loop through the neighbour of current loop, calculate score and stuff currentNode.ProcessNeighbour(destNode.GetPos(), bypassUnit, bypassObs); //put all neighbour in openlist foreach(Node neighbour in currentNode.GetNeighbourList(true, bypassUnit, bypassObs)){ if(neighbour.IsBlocked(currentNode, bypassUnit, bypassObs)) continue; if(neighbour.listState==Node._ListState.Unassigned || neighbour==destNode){ //~ //set the node state to open neighbour.listState=Node._ListState.Open; openList.Add(neighbour); } } //clear the current node, before getting a new one, so we know if there isnt any suitable next node currentNode=null; currentLowestF=Mathf.Infinity; id=0; for(i=0; i(); break; } openList.RemoveAt(id); } if(currentNode==null){ float tileSize=GridManager.GetNodeSize();//*GridManager.GetGridToTileSizeRatio(); currentLowestF=Mathf.Infinity; for(i=0; i path=new List(); while(currentNode!=null){ if(currentNode==originNode || currentNode==currentNode.parent) break; path.Add(currentNode); currentNode=currentNode.parent; } path=InvertNodeArray(path); ResetGraph(destNode, openList, closeList); return path; } /* //search the shortest path through all tile reagardless of status //this is used to accurately calculate the distance between 2 tiles in term of tile //distance calculated applies for line traverse thru walkable tiles only, otherwise it can be calculated using the coordinate public static int GetDistance(Tile srcTile, Tile targetTile){ List closeList=new List(); List openList=new List(); Tile currentTile=srcTile; if(srcTile==null) Debug.Log("src tile is null!!!"); float currentLowestF=Mathf.Infinity; int id=0; int i=0; while(true){ //if we have reach the destination if(currentTile==targetTile) break; //move currentNode to closeList; closeList.Add(currentTile); currentTile.aStar.listState=Node._ListState.Close; //loop through all neighbours, regardless of status //currentTile.ProcessAllNeighbours(targetTile); currentTile.aStar.ProcessWalkableNeighbour(targetTile); //put all neighbour in openlist foreach(Tile neighbour in currentTile.aStar.GetNeighbourList()){ if(neighbour.unit!=null && neighbour!=targetTile) continue; if(neighbour.aStar.listState==Node._ListState.Unassigned) { //set the node state to open neighbour.aStar.listState=Node._ListState.Open; openList.Add(neighbour); } } currentTile=null; currentLowestF=Mathf.Infinity; id=0; for(i=0; i InvertArray(List p){ List pInverted=new List(); for(int i=0; i InvertNodeArray(List p){ List pInverted=new List(); for(int i=0; i oList, List cList){ hNode.ResetListState(); hNode.parent=null; foreach(Node node in oList){ node.ResetListState(); node.parent=null; } foreach(Node node in cList){ node.ResetListState(); node.parent=null; } } } }