// made static because it's also used by other actions public static bool TryWalkTo(MapUnit unit, int walkX, int walkY, int walkWidth, int walkHeight, float distance = 0) { // check if target is walkable for us (statically) if (distance < 0) { distance = 0; } // note: 0x0 = specific cell // more than 0x0 = unit // for now just call pathfinding here // try to pathfind Vector2i point = unit.DecideNextMove(walkX, walkY, walkWidth, walkHeight, distance); if (point == null) { return(false); } /*int sbd = 32; * if (sbd > path.Count) sbd = path.Count; * for (int i = 0; i < sbd; i++) * { * if (!unit.Interaction.CheckWalkableForUnit(path[i].x, path[i].y, false)) * { * // one of nodes in statically found path (up to 32 nodes ahead) is non-walkable. * // here we try to build another path around it instead. * // if it's not found, we continue to walk along the old path. * List<Vector2i> path2 = null; * int pnum = path.Count - 1; * while (path2 == null && pnum >= 0) * { * path2 = unit.DecideNextMove(path[pnum].x, path[pnum].y, false, distance); * pnum--; * } * * if (path2 != null) * path = path2; * else if (i == 0) * return false; // next node is not walkable. this means we got right into a wall * * break; * } * }*/ // if NEXT node is not walkable, we drop into idle state. if (unit.Interaction.CheckWalkableForUnit(point.x, point.y, false)) { // next path node found // notify clients unit.AddActions(new MoveAction(unit, point.x, point.y), new RotateAction(unit, unit.FaceCell(point.x, point.y))); return(true); } return(false); }
public bool TryWalkTo(MapUnit unit, int walkX, int walkY, int walkWidth, int walkHeight, float distance = 0) { // check if we should not search yet if (LastBadPath > LastGoodPath && LastBadPath + RandomOffset > MapLogic.Instance.LevelTime) { return(false); // don't check for some time after bad path } // check if target is walkable for us (statically) if (distance < 0) { distance = 0; } // note: 0x0 = specific cell // more than 0x0 = unit // for now just call pathfinding here LastBadPath = MapLogic.Instance.LevelTime; // try to pathfind Vector2i point = unit.DecideNextMove(walkX, walkY, walkWidth, walkHeight, distance); if (point == null) { return(false); } // if NEXT node is not walkable, we drop into idle state. if (unit.Interaction.CheckWalkableForUnit(point.x, point.y, false)) { LastGoodPath = MapLogic.Instance.LevelTime; // next path node found // notify clients unit.AddActions(new MoveAction(unit, point.x, point.y), new RotateAction(unit, unit.FaceCell(point.x, point.y))); return(true); } return(false); }
// made static because it's also used by other actions public static bool TryWalkTo(MapUnit unit, int walkX, int walkY) { // check if target is walkable for us (statically) if (!unit.Interaction.CheckWalkableForUnit(walkX, walkY, false)) { List <Vector2i> switchNodes = new List <Vector2i>(); for (int ly = walkY - unit.Height; ly < walkY + unit.Height; ly++) { for (int lx = walkX - unit.Width; lx < walkX + unit.Width; lx++) { if (unit.Interaction.CheckWalkableForUnit(lx, ly, false)) { switchNodes.Add(new Vector2i(lx, ly)); } } } switchNodes.Sort((a, b) => { Vector2i own1 = unit.Interaction.GetClosestPointTo(a.x, a.y); Vector2i own2 = unit.Interaction.GetClosestPointTo(b.x, b.y); float d1 = (a - own1).magnitude; float d2 = (b - own2).magnitude; if (d1 > d2) { return(1); } else if (d1 < d2) { return(-1); } return(0); }); if (switchNodes.Count <= 0) { return(false); } walkX = switchNodes[0].x; walkY = switchNodes[0].y; } if (walkX == unit.X && walkY == unit.Y) { return(true); } // try to pathfind List <Vector2i> path = unit.DecideNextMove(walkX, walkY, true); if (path == null) { return(false); } int sbd = 32; if (sbd > path.Count) { sbd = path.Count; } for (int i = 0; i < sbd; i++) { if (!unit.Interaction.CheckWalkableForUnit(path[i].x, path[i].y, false)) { // one of nodes in statically found path (up to 32 nodes ahead) is non-walkable. // here we try to build another path around it instead. // if it's not found, we continue to walk along the old path. List <Vector2i> path2 = null; int pnum = path.Count - 1; while (path2 == null && pnum >= 0) { path2 = unit.DecideNextMove(path[pnum].x, path[pnum].y, false); pnum--; } if (path2 != null) { path = path2; } break; } } // if NEXT node is not walkable, we drop into idle state. if (unit.Interaction.CheckWalkableForUnit(path[0].x, path[0].y, false)) { // next path node found // notify clients unit.AddActions(new MoveAction(unit, path[0].x, path[0].y), new RotateAction(unit, unit.FaceCell(path[0].x, path[0].y))); return(true); } return(false); }