/// <summary> /// Generates a TileMap with the given UnitMap and Unit (and Tilemap and Organization) /// </summary> /// <param name="umap">The UnitMap to use</param> /// <param name="unit">The Unit to be based on</param> /// <param name="tm">Tilemap (not the pathfind one)</param> /// <param name="org">Organization to base the map from (determins who is ally and who is enemy)</param> /// <returns>a PathFind.TileMap</returns> public static TileMap gen(UnitMap umap, Tilemap tm, Unit unit) { TileMap ptm = new TileMap(tm.NumX, tm.NumY); for(int i=0; i<tm.NumX; i++) for(int e=0; e<tm.NumY; e++) if(!unit.canMove(tm.get(i, e).Type)) ptm.set(i, e, Tile_Type.BLOCK_TERRAIN); else if(!umap.canMove(i, e, unit.Organization)) ptm.set(i, e, Tile_Type.BLOCK_UNIT); else ptm.set(i, e, Tile_Type.NOTHING); return ptm; }
/// <summary> /// Setup map info /// </summary> public void set(Map fmap, Tilemap ftm, UnitMap fumap) { set(fmap, ftm); umap = fumap; }
private static Point pathFindFallBack(UnitMap umap, Tilemap tm, Point src, Point dest, String org) { 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 (!inMap(tm, tcur.p) || !canMove(tm, tcur.p, org)) continue; if (map.ContainsKey(tcur.p) && map[tcur.p] <= tcur.c) continue; } map[tcur.p] = tcur.c; main.Enqueue(tcur); } } if (!f) return src; 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 (!canMove(umap, tm, ret, org)) return src; return ret; }
private static Point nearest(UnitMap umap, Point src, String org) { if (isOrgPresent(umap, new Point(src.X, src.Y - 1), org)) return new Point(src.X, src.Y - 1); if (isOrgPresent(umap, new Point(src.X + 1, src.Y), org)) return new Point(src.X + 1, src.Y); if (isOrgPresent(umap, new Point(src.X, src.Y + 1), org)) return new Point(src.X, src.Y + 1); if (isOrgPresent(umap, new Point(src.X - 1, src.Y), org)) return new Point(src.X - 1, src.Y); if (isOrgPresent(umap, new Point(src.X - 1, src.Y - 1), org)) return new Point(src.X - 1, src.Y - 1); if (isOrgPresent(umap, new Point(src.X + 1, src.Y - 1), org)) return new Point(src.X + 1, src.Y - 1); if (isOrgPresent(umap, new Point(src.X - 1, src.Y + 1), org)) return new Point(src.X - 1, src.Y + 1); if (isOrgPresent(umap, new Point(src.X + 1, src.Y + 1), org)) return new Point(src.X + 1, src.Y + 1); //inner cercle checked //very inefficient int mr = Gen.max(umap.NumX, umap.NumY); for (int r = 2; r < mr + 1; r++) for (int i = -r; i < r + 1; i++) for (int e = -r; e < r + 1; e++) { if (i != -r && i != r && e != -r && e != r) continue; if (isOrgPresent(umap, new Point(src.X + i, src.Y + e), org)) return new Point(src.X + i, src.Y + e); } return new Point(-1, -1); }
private static bool isOrgPresent(UnitMap umap, Point p, String org) { if (p.X < 0 || p.Y < 0 || p.X >= umap.NumX || p.Y >= umap.NumY) return false; if (!umap.isUnit(p.X, p.Y)) return false; return umap.get(p.X, p.Y).Organization == org; }
private static bool canMove(UnitMap umap, Tilemap tm, Point dest, String org) { if (tm.get(dest.X, dest.Y).Type == Tile.TileType.MOUNTAIN || tm.get(dest.X, dest.Y).Type == Tile.TileType.WATER) return false; return umap.canMove(dest.X, dest.Y, org); }
public static Unit[] region(UnitMap umap, Tilemap tm, String org, Map map, ref Boolean dun) { Unit u; Point ne; Point d; for (int i = 0; i < umap.NumX; i++) for (int e = 0; e < umap.NumY; e++) if (umap.isUnit(i, e) && umap.get(i, e).movement > 0 && umap.get(i, e).Organization == org) { if (map.CursorPosition != new Point(i, e)) { map.changeCursor(new Point(i, e)); return null; } u = umap.get(i, e); if (u.hasLeader()) { ne = nearest(umap, new Point(i, e), "main"); if (isAdj(new Point(i, e), ne)) { u.movement = 0; return new Unit[] { umap.get(ne.X, ne.Y), u }; } //finds path to nearest ennemy d = pathFind(umap, tm, new Point(i, e), nearest(umap, new Point(i, e), "main"), org); umap.move(i, e, d.X, d.Y); map.changeCursor(new Point(d.X, d.Y)); u.movement--; } return null; } dun = true; return null; }