private AStarNode jump(int nextX,int nextY,int nextZ,int px,int pz){
  int y=nextY;
  int dist=currentNode.getG() + (Math.abs(nextX - currentNode.x) + Math.abs(y - currentNode.y) + Math.abs(nextZ - currentNode.z));
  int dx=nextX - px;
  int dz=nextZ - pz;
  int py=y;
  y=getGroundNodeHeight(nextX,py,nextZ);
  if (y == 0) {
    return null;
  }
 else   if (targetNode.x == nextX && targetNode.z == nextZ && targetNode.y == y || dist >= MAX_SKIP_DISTANCE) {
    return new AStarNode(nextX,y,nextZ,dist,currentNode,targetNode);
  }
  int nxY=(dx != 0) ? getGroundNodeHeight(nextX + dx,y,nextZ) : 0;
  int nzY=(dz != 0) ? getGroundNodeHeight(nextX,y,nextZ + dz) : 0;
  if (dx != 0 && dz != 0) {
    if ((getGroundNodeHeight(nextX - dx,y,nextZ + dz) != 0 && getGroundNodeHeight(nextX - dx,py,nextZ) == 0) || (getGroundNodeHeight(nextX + dx,y,nextZ - dz) != 0 && getGroundNodeHeight(nextX,py,nextZ - dz) == 0)) {
      return new AStarNode(nextX,y,nextZ,dist,currentNode,targetNode);
    }
  }
 else {
    if (dx != 0) {
      if (nxY != y || (getGroundNodeHeight(nextX,y,nextZ + 1) == 0 && getGroundNodeHeight(nextX + dx,nxY,nextZ + 1) != 0) || (getGroundNodeHeight(nextX,y,nextZ - 1) == 0 && getGroundNodeHeight(nextX + dx,nxY,nextZ - 1) != 0)) {
        return new AStarNode(nextX,y,nextZ,dist,currentNode,targetNode);
      }
    }
 else {
      if (nzY != y || (getGroundNodeHeight(nextX + 1,y,nextZ) == 0 && getGroundNodeHeight(nextX + 1,nzY,nextZ + dz) != 0) || (getGroundNodeHeight(nextX - 1,y,nextZ) == 0 && getGroundNodeHeight(nextX - 1,nzY,nextZ + dz) != 0)) {
        return new AStarNode(nextX,y,nextZ,dist,currentNode,targetNode);
      }
    }
  }
  if (dx != 0 && dz != 0) {
    AStarNode jx=jump(nextX + dx,y,nextZ,nextX,nextZ);
    AStarNode jy=jump(nextX,y,nextZ + dz,nextX,nextZ);
    if (jx != null || jy != null) {
      return new AStarNode(nextX,y,nextZ,dist,currentNode,targetNode);
    }
  }
  if (nxY != 0 || nzY != 0) {
    return jump(nextX + dx,y,nextZ + dz,nextX,nextZ);
  }
 else {
    return null;
  }
}

private AStarNode jump ( int nextX , int nextY , int nextZ , int px , int pz ) { int y = nextY ; int dist = currentNode . getG ( ) + ( Math . abs ( nextX - currentNode . x ) + Math . abs ( y - currentNode . y ) + Math . abs ( nextZ - currentNode . z ) ) ; int dx = nextX - px ; int dz = nextZ - pz ; int py = y ; y = getGroundNodeHeight ( nextX , py , nextZ ) ; if ( y == 0 ) { return null ; } else if ( targetNode . x == nextX && targetNode . z == nextZ && targetNode . y == y || dist >= MAX_SKIP_DISTANCE ) { return new AStarNode ( nextX , y , nextZ , dist , currentNode , targetNode ) ; } int nxY = ( dx != 0 ) ? getGroundNodeHeight ( nextX + dx , y , nextZ ) : 0 ; int nzY = ( dz != 0 ) ? getGroundNodeHeight ( nextX , y , nextZ + dz ) : 0 ; if ( dx != 0 && dz != 0 ) { if ( ( getGroundNodeHeight ( nextX - dx , y , nextZ + dz ) != 0 && getGroundNodeHeight ( nextX - dx , py , nextZ ) == 0 ) || ( getGroundNodeHeight ( nextX + dx , y , nextZ - dz ) != 0 && getGroundNodeHeight ( nextX , py , nextZ - dz ) == 0 ) ) { return new AStarNode ( nextX , y , nextZ , dist , currentNode , targetNode ) ; } } else { if ( dx != 0 ) { if ( nxY != y || ( getGroundNodeHeight ( nextX , y , nextZ + 1 ) == 0 && getGroundNodeHeight ( nextX + dx , nxY , nextZ + 1 ) != 0 ) || ( getGroundNodeHeight ( nextX , y , nextZ - 1 ) == 0 && getGroundNodeHeight ( nextX + dx , nxY , nextZ - 1 ) != 0 ) ) { return new AStarNode ( nextX , y , nextZ , dist , currentNode , targetNode ) ; } } else { if ( nzY != y || ( getGroundNodeHeight ( nextX + 1 , y , nextZ ) == 0 && getGroundNodeHeight ( nextX + 1 , nzY , nextZ + dz ) != 0 ) || ( getGroundNodeHeight ( nextX - 1 , y , nextZ ) == 0 && getGroundNodeHeight ( nextX - 1 , nzY , nextZ + dz ) != 0 ) ) { return new AStarNode ( nextX , y , nextZ , dist , currentNode , targetNode ) ; } } } if ( dx != 0 && dz != 0 ) { AStarNode jx = jump ( nextX + dx , y , nextZ , nextX , nextZ ) ; AStarNode jy = jump ( nextX , y , nextZ + dz , nextX , nextZ ) ; if ( jx != null || jy != null ) { return new AStarNode ( nextX , y , nextZ , dist , currentNode , targetNode ) ; } } if ( nxY != 0 || nzY != 0 ) { return jump ( nextX + dx , y , nextZ + dz , nextX , nextZ ) ; } else { return null ; } }
recursive jumper as described by jps algorithm
