/// <summary> /// /// </summary> /// <param name="map"></param> /// <param name="beginCell"></param> /// <param name="encodedPath"></param> /// <returns></returns> public static int GetPathLength(MapInstance map, int beginCell, string encodedPath) { var lastCell = beginCell; var length = 0; for (int i = 0; i < encodedPath.Length; i += 3) { var actualCell = Util.CharToCell(encodedPath.Substring(i + 1, 2)); length += Pathfinding.GoalDistance(map, lastCell, actualCell); lastCell = actualCell; } return(length); }
/// <summary> /// /// </summary> /// <param name="character"></param> /// <param name="cellId"></param> /// <param name="monsters"></param> /// <returns></returns> public bool CanBeAggro(CharacterEntity character, int cellId, MonsterGroupEntity monsters) { return(Pathfinding.GoalDistance(this, cellId, monsters.CellId) <= monsters.AggressionRange && ((character.AlignmentId == (int)AlignmentTypeEnum.ALIGNMENT_NEUTRAL && monsters.AlignmentId == -1) || (character.AlignmentId != (int)AlignmentTypeEnum.ALIGNMENT_NEUTRAL && monsters.AlignmentId != character.AlignmentId))); }
/// <summary> /// /// </summary> /// <param name="StartCell"></param> /// <param name="EndCell"></param> /// <param name="Diagonal"></param> /// <param name="MovementPoints"></param> /// <param name="Obstacles"></param> /// <returns></returns> private IEnumerable <int> FindPath(int StartCell, int EndCell, bool Diagonal, int MovementPoints = -1, IEnumerable <int> Obstacles = null) { bool Success = false; PathNode[] CalcGrid = new PathNode[map.Cells.Count + 1]; PriorityQueueB <int> OpenList = new PriorityQueueB <int>(new ComparePFNodeMatrix(CalcGrid)); List <PathNode> ClosedList = new List <PathNode>(); Point StartPoint = Pathfinding.GetPoint(map, StartCell); Point EndPoint = Pathfinding.GetPoint(map, EndCell); int BestLocation = StartCell; int Location = StartCell; Point LocationPoint = Pathfinding.GetPoint(map, Location); int NewLocation = 0; Point NewLocationPoint = default(Point); double NewG = 0; int Counter = 0; OpenList.Clear(); ClosedList.Clear(); if (MovementPoints == 0) { return(new List <int>()); } CalcGrid[Location].Cell = Location; CalcGrid[Location].G = 0; CalcGrid[Location].F = estimatedHeuristic; CalcGrid[Location].Parent = -1; CalcGrid[Location].Status = NodeState.InOpenList; OpenList.Push(Location); while (OpenList.Count > 0 && !Success) { Location = OpenList.Pop(); LocationPoint = Pathfinding.GetPoint(map, Location); if (CalcGrid[Location].Status == NodeState.InCloseList) { continue; } if (Location == EndCell) { CalcGrid[Location].Status = NodeState.InCloseList; Success = true; break; // TODO: might not be correct. Was : Exit While } for (int i = 0; i <= (Diagonal ? 8 - 1 : 4 - 1); i++) { NewLocation = Location + directions[i]; if (Pathfinding.GetPoint(map, NewLocation).X == -1000) { continue; } NewLocationPoint = Pathfinding.GetPoint(map, NewLocation); if ((NewLocation >= cellCount)) { continue; } if ((!map.IsWalkable(NewLocation) || (Obstacles != null && Obstacles.Contains(NewLocation))) && NewLocation != EndCell) { continue; } NewG = CalcGrid[Location].G + 1; // 1 should be the cost of the cell, but it's always 1 if (CalcGrid[NewLocation].Status == NodeState.InOpenList || CalcGrid[NewLocation].Status == NodeState.InCloseList) { if (CalcGrid[NewLocation].G <= NewG) { continue; } } CalcGrid[NewLocation].Cell = NewLocation; CalcGrid[NewLocation].Parent = Location; CalcGrid[NewLocation].G = NewG; var xDiff = Math.Abs(NewLocationPoint.X - EndPoint.X); var yDiff = Math.Abs(NewLocationPoint.Y - EndPoint.Y); double H = xDiff + yDiff; var Xbegin = StartPoint.X; var Xend = EndPoint.X; var Xcurrent = NewLocationPoint.X; var Ycurrent = NewLocationPoint.Y; var Ybegin = StartPoint.Y; var Yend = EndPoint.Y; var XdiffCurrentEnd = Xcurrent - Xend; var XdiffStartEnd = Xbegin - Xend; var YdiffCurrentEnd = Ycurrent - Yend; var YdiffStartEnd = Ybegin - Yend; var Cross = Math.Abs(XdiffCurrentEnd * YdiffStartEnd - XdiffStartEnd * YdiffCurrentEnd); CalcGrid[NewLocation].F = NewG + H + Cross; OpenList.Push(NewLocation); CalcGrid[NewLocation].Status = NodeState.InOpenList; } if (BestLocation == -1 || Pathfinding.GoalDistance(map, Location, EndCell) < Pathfinding.GoalDistance(map, BestLocation, EndCell)) { BestLocation = Location; } Counter += 1; CalcGrid[Location].Status = NodeState.InCloseList; } if (!Success) { EndCell = BestLocation; } var Node = CalcGrid[EndCell]; while (Node.Parent != -1) { ClosedList.Add(Node); Node = CalcGrid[Node.Parent]; } ClosedList.Add(Node); ClosedList.Reverse(); if (MovementPoints > 0 && ClosedList.Count - 1 >= MovementPoints) { return(ClosedList.Take(MovementPoints + 1).Select(node => node.Cell)); } return(ClosedList.Select(node => node.Cell)); }