private static PathNode MakePath(MapWalkData walkData, Position start, Position target, int maxDistance, int range) { if (!walkData.IsCellWalkable(target)) { return(null); } var path = BuildPath(walkData, start, target, maxDistance, range); //openList.Clear(); openListPos.Clear(); closedListPos.Clear(); return(path); }
private static int CheckDirectPath(MapWalkData walkData, Position start, Position target, int maxDistance, int range, int startPos) { var pos = start; tempPath[startPos] = pos; var i = startPos + 1; while (i < maxDistance) { if (pos.X > target.X + range) { pos.X--; } if (pos.X < target.X - range) { pos.X++; } if (pos.Y > target.Y + range) { pos.Y--; } if (pos.Y < target.Y - range) { pos.Y++; } if (!walkData.IsCellWalkable(pos)) { return(0); } tempPath[i] = pos; i++; if (pos.SquareDistance(target) <= range) { Profiler.Event(ProfilerEvent.PathFoundDirect); return(i); } } return(0); }
//private static void InsertOpenNode(PathNode node) //{ // for (var i = 0; i < openList.Count; i++) // { // if (node.F < openList[i].F) // { // openList.Insert(i, node); // return; // } // } // openList.Add(node); //} private static PathNode BuildPath(MapWalkData walkData, Position start, Position target, int maxLength, int range) { if (nodeCache == null) { BuildCache(); } cachePos = MaxCacheSize; Pathfinder.range = range; //openList.Clear(); openBag.Clear(); openListPos.Clear(); closedListPos.Clear(); nodeLookup.Clear(); var current = NextPathNode(null, start, CalcDistance(start, target)); openBag.Add(current); //openList.Add(current); AddLookup(start, current); while (openBag.Count > 0 && !closedListPos.Contains(target)) { //current = openList[0]; current = openBag[0]; openBag.RemoveFirst(); //openList.RemoveAt(0); openListPos.Remove(current.Position); closedListPos.Add(current.Position); if (current.Steps > maxLength || current.Steps + current.Distance / 2 > maxLength) { continue; } for (var x = -1; x <= 1; x++) { for (var y = -1; y <= 1; y++) { if (x == 0 && y == 0) { continue; } var np = current.Position; np.X += x; np.Y += y; if (np.X < 0 || np.Y < 0 || np.X >= walkData.Width || np.Y >= walkData.Height) { continue; } if (openListPos.Contains(np)) { //the open list contains the neighboring cell. Check if the path from this node is better or not var oldNode = GetNode(np); var dir = (np - current.Position).GetDirectionForOffset(); var distance = CalcDistance(np, target); var newF = current.Score + 1 + distance + (dir.IsDiagonal() ? 0.4f : 0f); if (newF < oldNode.F) { oldNode.Set(current, np, CalcDistance(np, target)); //swap the old parent to us if we're better } continue; } if (closedListPos.Contains(np)) { continue; } if (!walkData.IsCellWalkable(np)) { continue; } if (x == -1 && y == -1) { if (!walkData.IsCellWalkable(current.Position.X - 1, current.Position.Y) || !walkData.IsCellWalkable(current.Position.X, current.Position.Y - 1)) { continue; } } if (x == -1 && y == 1) { if (!walkData.IsCellWalkable(current.Position.X - 1, current.Position.Y) || !walkData.IsCellWalkable(current.Position.X, current.Position.Y + 1)) { continue; } } if (x == 1 && y == -1) { if (!walkData.IsCellWalkable(current.Position.X + 1, current.Position.Y) || !walkData.IsCellWalkable(current.Position.X, current.Position.Y - 1)) { continue; } } if (x == 1 && y == 1) { if (!walkData.IsCellWalkable(current.Position.X + 1, current.Position.Y) || !walkData.IsCellWalkable(current.Position.X, current.Position.Y + 1)) { continue; } } if (np.SquareDistance(target) <= range) { Profiler.Event(ProfilerEvent.PathFoundIndirect); return(NextPathNode(current, np, 0)); } var newNode = NextPathNode(current, np, CalcDistance(np, target)); //openList.Add(newNode); //InsertOpenNode(newNode); openBag.Add(newNode); //openListPos.Add(np); AddLookup(np, newNode); closedListPos.Add(np); //openList.Sort((a, b) => a.F.CompareTo(b.F)); } } } Profiler.Event(ProfilerEvent.PathNotFound); return(null); }