@Override
  public void paintTerrain(
      Block[] blocks,
      byte[] metadata,
      int i,
      int j,
      int x,
      int y,
      int depth,
      World world,
      Random rand,
      OpenSimplexNoise simplex,
      CellNoise cell,
      float[] noise,
      float river,
      BiomeGenBase[] base) {
    float c = CliffCalculator.calc(x, y, noise);
    boolean cliff = c > 1.4f ? true : false;

    for (int k = 255; k > -1; k--) {
      Block b = blocks[(y * 16 + x) * 256 + k];
      if (b == Blocks.air) {
        depth = -1;
      } else if (b == Blocks.stone) {
        depth++;

        if (cliff) {
          if (depth > -1 && depth < 2) {
            if (rand.nextInt(3) == 0) {

              blocks[(y * 16 + x) * 256 + k] = hcCobble(world, i, j, x, y, k);
              metadata[(y * 16 + x) * 256 + k] = hcCobbleMeta(world, i, j, x, y, k);
            } else {

              blocks[(y * 16 + x) * 256 + k] = hcStone(world, i, j, x, y, k);
              metadata[(y * 16 + x) * 256 + k] = hcStoneMeta(world, i, j, x, y, k);
            }
          } else if (depth < 10) {
            blocks[(y * 16 + x) * 256 + k] = hcStone(world, i, j, x, y, k);
            metadata[(y * 16 + x) * 256 + k] = hcStoneMeta(world, i, j, x, y, k);
          }
        } else {
          if (depth == 0 && k > 61) {
            blocks[(y * 16 + x) * 256 + k] = topBlock;
            metadata[(y * 16 + x) * 256 + k] = topBlockMeta;
          } else if (depth < 4) {
            blocks[(y * 16 + x) * 256 + k] = fillerBlock;
            metadata[(y * 16 + x) * 256 + k] = fillerBlockMeta;
          }
        }
      }
    }
  }
  @Override
  public void paintTerrain(
      Block[] blocks,
      byte[] metadata,
      int i,
      int j,
      int x,
      int y,
      int depth,
      World world,
      Random rand,
      PerlinNoise perlin,
      CellNoise cell,
      float[] noise,
      float river,
      BiomeGenBase[] base) {
    float c = CliffCalculator.calc(x, y, noise);
    boolean cliff = c > 1.4f ? true : false;

    for (int k = 255; k > -1; k--) {
      Block b = blocks[(y * 16 + x) * 256 + k];
      if (b == Blocks.air) {
        depth = -1;
      } else if (b == Blocks.stone) {
        depth++;

        if (cliff) {
          if (depth > -1 && depth < 2) {
            blocks[(y * 16 + x) * 256 + k] = rand.nextInt(3) == 0 ? cliffBlock2 : cliffBlock1;
          } else if (depth < 10) {
            blocks[(y * 16 + x) * 256 + k] = cliffBlock1;
          }
        } else {
          if (depth == 0 && k > 61) {
            blocks[(y * 16 + x) * 256 + k] = topBlock;
          } else if (depth < 4) {
            blocks[(y * 16 + x) * 256 + k] = fillerBlock;
          }
        }
      }
    }
  }
  @Override
  public void paintTerrain(
      Block[] blocks,
      byte[] metadata,
      int i,
      int j,
      int x,
      int y,
      int depth,
      World world,
      Random rand,
      OpenSimplexNoise simplex,
      CellNoise cell,
      float[] noise,
      float river,
      BiomeGenBase[] base) {
    float c = CliffCalculator.calc(x, y, noise);
    int cliff = 0;
    boolean gravel = false;

    Block b;
    for (int k = 255; k > -1; k--) {
      b = blocks[(y * 16 + x) * 256 + k];
      if (b == Blocks.air) {
        depth = -1;
      } else if (b == Blocks.stone) {
        depth++;

        if (depth == 0) {
          if (k < 63) {
            if (beach) {
              gravel = true;
            }
          }

          float p = simplex.noise3(i / 8f, j / 8f, k / 8f) * 0.5f;
          if (c > min && c > sCliff - ((k - sHeight) / sStrength) + p) {
            cliff = 1;
          }
          if (c > cCliff) {
            cliff = 2;
          }

          if (cliff == 1) {
            blocks[(y * 16 + x) * 256 + k] =
                rand.nextInt(3) == 0 ? Blocks.cobblestone : Blocks.stone;
          } else if (cliff == 2) {
            blocks[(y * 16 + x) * 256 + k] = shadowDesertBlock;
            metadata[(y * 16 + x) * 256 + k] = shadowDesertByte;
          } else if (k < 63) {
            if (beach) {
              blocks[(y * 16 + x) * 256 + k] = beachBlock;
              gravel = true;
            } else if (k < 62) {
              blocks[(y * 16 + x) * 256 + k] = fillerBlock;
            } else {
              blocks[(y * 16 + x) * 256 + k] = topBlock;
            }
          } else {
            blocks[(y * 16 + x) * 256 + k] = topBlock;
          }
        } else if (depth < 6) {
          if (cliff == 1) {
            blocks[(y * 16 + x) * 256 + k] = Blocks.stone;
          } else if (cliff == 2) {
            blocks[(y * 16 + x) * 256 + k] = shadowDesertBlock;
            metadata[(y * 16 + x) * 256 + k] = shadowDesertByte;
          } else if (gravel) {
            blocks[(y * 16 + x) * 256 + k] = beachBlock;
          } else {
            blocks[(y * 16 + x) * 256 + k] = fillerBlock;
          }
        }
      }
    }
  }
  @Override
  public void paintTerrain(
      Block[] blocks,
      byte[] metadata,
      int i,
      int j,
      int x,
      int y,
      int depth,
      World world,
      Random rand,
      OpenSimplexNoise simplex,
      CellNoise cell,
      float[] noise,
      float river,
      BiomeGenBase[] base) {

    float c = CliffCalculator.calc(x, y, noise);
    boolean cliff = c > 1.4f ? true : false;
    boolean mix = false;

    for (int k = 255; k > -1; k--) {
      Block b = blocks[(y * 16 + x) * 256 + k];
      if (b == Blocks.air) {
        depth = -1;
      } else if (b == Blocks.stone) {
        depth++;

        if (shouldReplaceStone()) {
          blocks[(y * 16 + x) * 256 + k] =
              EBAPI.ebStonify(EnhancedBiomesBlocks.stoneEB, hcStone(world, i, j, x, y, k));
          metadata[(y * 16 + x) * 256 + k] =
              EBAPI.ebStonify(EBAPI.SLATE, hcStoneMeta(world, i, j, x, y, k));
        }

        if (cliff) {
          if (depth > -1 && depth < 2) {
            if (rand.nextInt(3) == 0) {
              blocks[(y * 16 + x) * 256 + k] = blockCliff2;
              metadata[(y * 16 + x) * 256 + k] = byteCliff2;
            } else {
              blocks[(y * 16 + x) * 256 + k] = blockCliff1;
              metadata[(y * 16 + x) * 256 + k] = byteCliff1;
            }

          } else if (depth < 10) {
            blocks[(y * 16 + x) * 256 + k] = blockCliff1;
            metadata[(y * 16 + x) * 256 + k] = byteCliff1;
          }
        } else {
          if (depth == 0 && k > 61) {
            if (simplex.noise2(i / floMixWidth, j / floMixWidth)
                    + simplex.noise2(i / floSmallWidth, j / floSmallWidth) * floSmallStrength
                > floMixHeight) {
              blocks[(y * 16 + x) * 256 + k] = blockMixTop;
              metadata[(y * 16 + x) * 256 + k] = byteMixTop;

              mix = true;
            } else {
              blocks[(y * 16 + x) * 256 + k] = topBlock;
              metadata[(y * 16 + x) * 256 + k] = topBlockMeta;
            }
          } else if (depth < 4) {
            if (mix) {
              blocks[(y * 16 + x) * 256 + k] = blockMixFiller;
              metadata[(y * 16 + x) * 256 + k] = byteMixFiller;
            } else {
              blocks[(y * 16 + x) * 256 + k] = fillerBlock;
              metadata[(y * 16 + x) * 256 + k] = fillerBlockMeta;
            }
          }
        }
      }
    }
  }
  @Override
  public void paintTerrain(
      Block[] blocks,
      byte[] metadata,
      int i,
      int j,
      int x,
      int y,
      int depth,
      World world,
      Random rand,
      PerlinNoise perlin,
      CellNoise cell,
      float[] noise,
      float river,
      BiomeGenBase[] base) {
    float c = CliffCalculator.calc(x, y, noise);
    boolean cliff = c > 1.3f ? true : false;
    boolean dirt = false;

    for (int k = 255; k > -1; k--) {
      Block b = blocks[(y * 16 + x) * 256 + k];
      if (b == Blocks.air) {
        depth = -1;
      } else if (b == Blocks.stone) {
        depth++;

        if (cliff) {
          if (cliffType == 1) {
            if (depth < 6) {
              blocks[(y * 16 + x) * 256 + k] = cliffBlock1;
              metadata[(y * 16 + x) * 256 + k] = 14;
            }
          } else {
            if (depth > -1 && depth < 2) {
              blocks[(y * 16 + x) * 256 + k] = rand.nextInt(3) == 0 ? cliffBlock2 : cliffBlock1;
            } else if (depth < 10) {
              blocks[(y * 16 + x) * 256 + k] = cliffBlock1;
            }
          }
        } else if (depth < 6) {
          if (depth == 0 && k > 61) {
            if (perlin.noise2(i / 12f, j / 12f) > -0.3f + ((k - 61f) / 15f)) {
              dirt = true;
              blocks[(y * 16 + x) * 256 + k] = topBlock;
            } else {
              blocks[(y * 16 + x) * 256 + k] = Blocks.sand;
              metadata[(y * 16 + x) * 256 + k] = sandMetadata;
            }
          } else if (depth < 4) {
            if (dirt) {
              blocks[(y * 16 + x) * 256 + k] = fillerBlock;
            } else {
              blocks[(y * 16 + x) * 256 + k] = Blocks.sand;
              metadata[(y * 16 + x) * 256 + k] = sandMetadata;
            }
          } else if (!dirt) {
            blocks[(y * 16 + x) * 256 + k] = Blocks.sandstone;
          }
        }
      }
    }
  }
  @Override
  public void paintTerrain(
      Block[] blocks,
      byte[] metadata,
      int i,
      int j,
      int x,
      int y,
      int depth,
      World world,
      Random rand,
      PerlinNoise perlin,
      CellNoise cell,
      float[] noise,
      float river,
      BiomeGenBase[] base) {
    float c = CliffCalculator.calc(x, y, noise);
    int cliff = 0;
    boolean gravel = false;

    Block b;
    for (int k = 255; k > -1; k--) {
      b = blocks[(y * 16 + x) * 256 + k];
      if (b == Blocks.air) {
        depth = -1;
      } else if (b == Blocks.stone) {
        depth++;

        if (depth == 0) {
          if (k < 63) {
            if (beach) {
              gravel = true;
            }
          }

          float p = perlin.noise3(i / 8f, j / 8f, k / 8f) * 0.5f;
          if (c > min && c > sCliff - ((k - sHeight) / sStrength) + p) {
            cliff = 1;
          }
          if (c > cCliff) {
            cliff = 2;
          }
          if (k > 110 + (p * 4) && c < iCliff + ((k - iHeight) / iStrength) + p) {
            cliff = 3;
          }

          if (cliff == 1) {
            blocks[(y * 16 + x) * 256 + k] =
                rand.nextInt(3) == 0 ? Blocks.cobblestone : Blocks.stone;
          } else if (cliff == 2) {
            blocks[(y * 16 + x) * 256 + k] = Blocks.stained_hardened_clay;
            metadata[(y * 16 + x) * 256 + k] = 9;
          } else if (cliff == 3) {
            blocks[(y * 16 + x) * 256 + k] = Blocks.snow;
          } else if (k < 63) {
            if (beach) {
              blocks[(y * 16 + x) * 256 + k] = beachBlock;
              gravel = true;
            } else if (k < 62) {
              blocks[(y * 16 + x) * 256 + k] = fillerBlock;
            } else {
              blocks[(y * 16 + x) * 256 + k] = topBlock;
            }
          } else {
            blocks[(y * 16 + x) * 256 + k] = Blocks.grass;
          }
        } else if (depth < 6) {
          if (cliff == 1) {
            blocks[(y * 16 + x) * 256 + k] = Blocks.stone;
          } else if (cliff == 2) {
            blocks[(y * 16 + x) * 256 + k] = Blocks.stained_hardened_clay;
            metadata[(y * 16 + x) * 256 + k] = 9;
          } else if (cliff == 3) {
            blocks[(y * 16 + x) * 256 + k] = Blocks.snow;
          } else if (gravel) {
            blocks[(y * 16 + x) * 256 + k] = Blocks.gravel;
          } else {
            blocks[(y * 16 + x) * 256 + k] = Blocks.dirt;
          }
        }
      }
    }
  }