/// <summary> /// Finds the path from source to destination point (does not consider ally unit) /// </summary> /// <param name="tm">TileMap</param> /// <param name="src">Source point (the Unit or Character moving)</param> /// <param name="dest">Destination point (the target)</param> /// <returns>A point adjacent to the source which is the next move of the character or unit /// in order to arrive to destination. or the source point if no path is found</returns> public static Point pathfindFallback(TileMap tm, Point src, Point dest) { Dictionary<Point, int> map = new Dictionary<Point, int>(); Queue<PointCounter> main = new Queue<PointCounter>(); Queue<PointCounter> temp = new Queue<PointCounter>(); PointCounter cur; PointCounter tcur; main.Enqueue(new PointCounter(dest, 0)); map[dest] = 0; int cc; bool f = false; while (main.Count > 0) { cur = main.Dequeue(); temp.Clear(); if (cur.p == src) { f = true; break; } cc = cur.c + 1; temp.Enqueue(new PointCounter(cur.p.X, cur.p.Y - 1, cc)); temp.Enqueue(new PointCounter(cur.p.X + 1, cur.p.Y, cc)); temp.Enqueue(new PointCounter(cur.p.X, cur.p.Y + 1, cc)); temp.Enqueue(new PointCounter(cur.p.X - 1, cur.p.Y, cc)); while (temp.Count > 0) { tcur = temp.Dequeue(); if (tcur.p != src) { if (!tm.inMap(tcur.p) || tm.get(tcur.p.X, tcur.p.Y) == TileMap.Tile_Type.BLOCK_TERRAIN) continue; if (map.ContainsKey(tcur.p) && map[tcur.p] <= tcur.c) continue; } map[tcur.p] = tcur.c; main.Enqueue(tcur); } } if (!f) return new Point(-1, -1); Point ret = src; cc = map[src]; temp.Clear(); temp.Enqueue(new PointCounter(src.X, src.Y - 1, 0)); temp.Enqueue(new PointCounter(src.X + 1, src.Y, 0)); temp.Enqueue(new PointCounter(src.X, src.Y + 1, 0)); temp.Enqueue(new PointCounter(src.X - 1, src.Y, 0)); while (temp.Count > 0) { tcur = temp.Dequeue(); if (map.ContainsKey(tcur.p) && map[tcur.p] < cc) { cc = map[tcur.p]; ret = tcur.p; } } if (tm.get(ret.X, ret.Y) != TileMap.Tile_Type.NOTHING||ret==dest) return src; return ret; }