Program: 152057
Project: 152057
Buggy source:
/** 
 * Computes a path for the specified actor.
 * @param longest the maximum path length.
 * @param partial if true, return a partial path even if the destination is unreachable.
 * @param shortcut if true, use swept shapes to compute shortcuts in the path.
 * @return the computed path, or null if unreachable.
 */
protected Vector2f[] getPath(final boolean collideActor,ActorLogic logic,float longest,float ax,float ay,float bx,float by,boolean partial,boolean shortcut){
  Vector2f start=new Vector2f(ax,ay);
  if (ax == bx && ay == by) {
    return new Vector2f[]{start};
  }
  Vector2f end=new Vector2f(bx,by);
  if (!sweptShapeCollides(collideActor,logic,start,end)) {
    return new Vector2f[]{start,end};
  }
  Rect bounds=logic.getShape().getBounds();
  int width=Math.max(1,FloatMath.iceil(bounds.getWidth() * SUBDIVISION));
  int height=Math.max(1,FloatMath.iceil(bounds.getHeight() * SUBDIVISION));
  AStarPathUtil.TraversalPred pred;
  final Actor actor=logic.getActor();
  if (width == 1 && height == 1) {
    pred=new AStarPathUtil.TraversalPred(){
      public boolean canTraverse(      Object traverser,      int x,      int y){
        if (actor.canCollide(_entryFlags.get(x / SUBDIVISION,y / SUBDIVISION))) {
          return false;
        }
        return !collideActor || !actor.canCollide(_actorFlags.get(x,y));
      }
    }
;
  }
 else {
    final int left=width / 2, right=(width - 1) / 2;
    final int bottom=height / 2, top=(height - 1) / 2;
    pred=new AStarPathUtil.TraversalPred(){
      public boolean canTraverse(      Object traverser,      int x,      int y){
        for (int yy=y - bottom, yymax=y + top; yy <= yymax; yy++) {
          for (int xx=x - left, xxmax=x + right; xx <= xxmax; xx++) {
            if (actor.canCollide(_entryFlags.get(xx / SUBDIVISION,yy / SUBDIVISION))) {
              return false;
            }
 else             if (collideActor && actor.canCollide(_actorFlags.get(x,y))) {
              return false;
            }
          }
        }
        return true;
      }
    }
;
  }
  float xoff=(width % 2) * 0.5f / SUBDIVISION;
  float yoff=(height % 2) * 0.5f / SUBDIVISION;
  ax*=SUBDIVISION;
  ay*=SUBDIVISION;
  bx*=SUBDIVISION;
  by*=SUBDIVISION;
  boolean remove=(!logic.isRemoved() && collideActor && actor.canCollide(actor.getCollisionFlags()));
  if (remove) {
    removeFlags(logic);
  }
  List<Point> path=AStarPathUtil.getPath(pred,actor,(int)longest,Math.round(ax - xoff),Math.round(ay - yoff),Math.round(bx - xoff),Math.round(by - yoff),partial);
  if (remove) {
    addFlags(logic);
  }
  if (path == null) {
    return null;
  }
  Vector2f[] waypoints=new Vector2f[path.size()];
  for (int ii=0; ii < waypoints.length; ii++) {
    Point pt=path.get(ii);
    waypoints[ii]=new Vector2f((pt.x + xoff) / SUBDIVISION,(pt.y + yoff) / SUBDIVISION);
  }
  if (!shortcut) {
    return waypoints;
  }
  Vector2f current=start;
  for (int ii=0; ii < waypoints.length; ) {
    for (int jj=waypoints.length - 1; jj >= ii; jj--) {
      Vector2f waypoint=waypoints[jj];
      if (jj == ii || !sweptShapeCollides(collideActor,logic,current,waypoint)) {
        _waypoints.add(current=waypoint);
        ii=jj + 1;
        break;
      }
    }
  }
  waypoints=_waypoints.toArray(new Vector2f[_waypoints.size()]);
  _waypoints.clear();
  return waypoints;
}

Fixed version (ground truth):
/** 
 * Computes a path for the specified actor.
 * @param longest the maximum path length.
 * @param partial if true, return a partial path even if the destination is unreachable.
 * @param shortcut if true, use swept shapes to compute shortcuts in the path.
 * @return the computed path, or null if unreachable.
 */
protected Vector2f[] getPath(final boolean collideActor,ActorLogic logic,float longest,float ax,float ay,float bx,float by,boolean partial,boolean shortcut){
  Vector2f start=new Vector2f(ax,ay);
  if (ax == bx && ay == by) {
    return new Vector2f[]{start};
  }
  Vector2f end=new Vector2f(bx,by);
  if (!sweptShapeCollides(collideActor,logic,start,end)) {
    return new Vector2f[]{start,end};
  }
  Rect bounds=logic.getShape().getBounds();
  int width=Math.max(1,FloatMath.iceil(bounds.getWidth() * SUBDIVISION));
  int height=Math.max(1,FloatMath.iceil(bounds.getHeight() * SUBDIVISION));
  AStarPathUtil.TraversalPred pred;
  final Actor actor=logic.getActor();
  if (width == 1 && height == 1) {
    pred=new AStarPathUtil.TraversalPred(){
      public boolean canTraverse(      Object traverser,      int x,      int y){
        if (actor.canCollide(_entryFlags.get(x / SUBDIVISION,y / SUBDIVISION))) {
          return false;
        }
        return !collideActor || !actor.canCollide(_actorFlags.get(x,y));
      }
    }
;
  }
 else {
    final int left=width / 2, right=(width - 1) / 2;
    final int bottom=height / 2, top=(height - 1) / 2;
    pred=new AStarPathUtil.TraversalPred(){
      public boolean canTraverse(      Object traverser,      int x,      int y){
        for (int yy=y - bottom, yymax=y + top; yy <= yymax; yy++) {
          for (int xx=x - left, xxmax=x + right; xx <= xxmax; xx++) {
            if (actor.canCollide(_entryFlags.get(xx / SUBDIVISION,yy / SUBDIVISION))) {
              return false;
            }
 else             if (collideActor && actor.canCollide(_actorFlags.get(xx,yy))) {
              return false;
            }
          }
        }
        return true;
      }
    }
;
  }
  float xoff=(width % 2) * 0.5f / SUBDIVISION;
  float yoff=(height % 2) * 0.5f / SUBDIVISION;
  ax*=SUBDIVISION;
  ay*=SUBDIVISION;
  bx*=SUBDIVISION;
  by*=SUBDIVISION;
  boolean remove=(!logic.isRemoved() && collideActor && actor.canCollide(actor.getCollisionFlags()));
  if (remove) {
    removeFlags(logic);
  }
  List<Point> path=AStarPathUtil.getPath(pred,actor,(int)longest,Math.round(ax - xoff),Math.round(ay - yoff),Math.round(bx - xoff),Math.round(by - yoff),partial);
  if (remove) {
    addFlags(logic);
  }
  if (path == null) {
    return null;
  }
  Vector2f[] waypoints=new Vector2f[path.size()];
  for (int ii=0; ii < waypoints.length; ii++) {
    Point pt=path.get(ii);
    waypoints[ii]=new Vector2f((pt.x + xoff) / SUBDIVISION,(pt.y + yoff) / SUBDIVISION);
  }
  if (!shortcut) {
    return waypoints;
  }
  Vector2f current=start;
  for (int ii=0; ii < waypoints.length; ) {
    for (int jj=waypoints.length - 1; jj >= ii; jj--) {
      Vector2f waypoint=waypoints[jj];
      if (jj == ii || !sweptShapeCollides(collideActor,logic,current,waypoint)) {
        _waypoints.add(current=waypoint);
        ii=jj + 1;
        break;
      }
    }
  }
  waypoints=_waypoints.toArray(new Vector2f[_waypoints.size()]);
  _waypoints.clear();
  return waypoints;
}