@Override
  public float rNoise(
      PerlinNoise perlin, CellNoise cell, int x, int y, float ocean, float border, float river) {
    river = river > 0.5f ? 1f : river * 2f;

    float start =
        (perlin.noise2(x / 90f, y / 90f) * 1f)
            + (perlin.noise2(x / 40f, y / 40f) * 0.15f)
            + (perlin.noise2(x / 9f, y / 9f) * 0.07f);

    float h = 0f;
    h = ocean < 1f ? ocean * 15f : 15f;

    float c = 0f;
    if (ocean + start > 0.8f) {
      c = ocean + start > 1.5f ? 0.7f : (ocean + start) - 0.8f;
      c *= 35f + perlin.noise2(x / 50f, y / 50f) * 8f;
    }

    if (ocean < 1.6f) {
      float st = (1.2f - ocean) * 20f;
      st = st > 1f ? 1f : st;

      h += perlin.noise2(x / 12f, y / 12f);
      h += perlin.noise2(x / 20f, y / 20f) * 2;
    }

    return 55f + h + (c * river);
  }
  @Override
  public float generateNoise(
      PerlinNoise perlin, CellNoise cell, int x, int y, float ocean, float border, float river) {
    float h = perlin.noise2(x / width, y / width) * heigth * river;
    h *= h / 32f;
    h = h > 150f ? 150f : h;

    if (h < 14f) {
      h += perlin.noise2(x / 25f, y / 25f) * (14f - h) * 0.8f;
    }

    if (h < 6) {
      h = 6f - ((6f - h) * 0.07f) + perlin.noise2(x / 20f, y / 20f) + perlin.noise2(x / 5f, y / 5f);
    }

    if (h > 10f) {
      float d = (h - 10f) / 2f > 8f ? 8f : (h - 10f) / 2f;
      h += perlin.noise2(x / 35f, y / 35f) * d;
      h += perlin.noise2(x / 60f, y / 60f) * d * 0.5f;

      if (h > 35f) {
        float d2 = (h - 35f) / 1.5f > 30f ? 30f : (h - 35f) / 1.5f;
        h += cell.noise(x / 25D, y / 25D, 1D) * d2;
      }
    }

    if (h > 2f) {
      float d = (h - 2f) / 2f > 4f ? 4f : (h - 2f) / 2f;
      h += perlin.noise2(x / 28f, y / 28f) * d;
      h += perlin.noise2(x / 18f, y / 18f) * (d / 2f);
      h += perlin.noise2(x / 8f, y / 8f) * (d / 2f);
    }

    return h + 56f;
  }
  @Override
  public void rDecorate(
      World world,
      Random rand,
      int chunkX,
      int chunkY,
      PerlinNoise perlin,
      CellNoise cell,
      float strength,
      float river) {
    if (rand.nextInt((int) (2f / strength)) == 0) {
      int i1 = chunkX + rand.nextInt(16) + 8;
      int j1 = chunkY + rand.nextInt(16) + 8;
      int k1 = world.getHeightValue(i1, j1);
      if (k1 < 85) {
        (new DecoBlob(Blocks.cobblestone, 0)).generate(world, rand, i1, k1, j1);
      }
    }

    float t = perlin.noise2(chunkX / 30f, chunkY / 30f) * 8f;
    t = t > 4f ? 4f : t;

    if (t > 0f) {
      if (rand.nextInt((int) ((10f - t) / strength)) == 0) {
        int j6 = chunkX + rand.nextInt(16) + 8;
        int k10 = chunkY + rand.nextInt(16) + 8;
        int z52 = world.getHeightValue(j6, k10);

        if (z52 < 82) {
          WorldGenerator worldgenerator =
              new DecoJungleTall(
                  Blocks.log,
                  2,
                  Blocks.leaves,
                  2,
                  6 + rand.nextInt(4),
                  3 + rand.nextInt(2),
                  9f + rand.nextFloat() * 4f,
                  3,
                  0.32f,
                  0.1f);
          worldgenerator.setScale(1.0D, 1.0D, 1.0D);
          worldgenerator.generate(world, rand, j6, z52, k10);
        }
      }
    }

    if (river > 0.8f) {
      for (int b33 = 0; b33 < 8f * strength; b33++) {
        int j6 = chunkX + rand.nextInt(16) + 8;
        int k10 = chunkY + rand.nextInt(16) + 8;
        int z52 = world.getHeightValue(j6, k10);

        if (z52 < 82) {
          WorldGenerator worldgenerator =
              rand.nextInt(2) != 0 ? new WorldGenShrub(0, 0) : new DecoSavannah(1, false);
          worldgenerator.setScale(1.0D, 1.0D, 1.0D);
          worldgenerator.generate(world, rand, j6, z52, k10);
        }
      }
    } else {
      for (int b33 = 0; b33 < (1f + t) * strength; b33++) {
        int j6 = chunkX + rand.nextInt(16) + 8;
        int k10 = chunkY + rand.nextInt(16) + 8;
        int z52 = world.getHeightValue(j6, k10);

        if (z52 < 82) {
          WorldGenerator worldgenerator =
              rand.nextInt(6) != 0 ? new WorldGenShrub(0, 0) : new DecoSavannah(1, false);
          worldgenerator.setScale(1.0D, 1.0D, 1.0D);
          worldgenerator.generate(world, rand, j6, z52, k10);
        }
      }
    }

    if (rand.nextInt((int) (3f / strength)) == 0) {
      int i18 = chunkX + rand.nextInt(16) + 8;
      int i23 = chunkY + rand.nextInt(16) + 8;
      (new WorldGenReed()).generate(world, rand, i18, 60 + rand.nextInt(8), i23);
    }

    if (rand.nextInt(28) == 0) {
      int j16 = chunkX + rand.nextInt(16) + 8;
      int j18 = rand.nextInt(128);
      int j21 = chunkY + rand.nextInt(16) + 8;
      (new WorldGenPumpkin()).generate(world, rand, j16, j18, j21);
    }

    for (int f23 = 0; f23 < 3; f23++) {
      int j15 = chunkX + rand.nextInt(16) + 8;
      int j17 = rand.nextInt(128);
      int j20 = chunkY + rand.nextInt(16) + 8;
      (new DecoFlowers(new int[] {9, 9, 9, 9, 3, 3, 3, 3, 3, 2, 2, 2, 11, 11, 11}))
          .generate(world, rand, j15, j17, j20);
    }

    for (int k18 = 0; k18 < 26f * strength; k18++) {
      int k21 = chunkX + rand.nextInt(16) + 8;
      int j23 = 66 + rand.nextInt(20);
      int k24 = chunkY + rand.nextInt(16) + 8;
      (new DecoCacti(false)).generate(world, rand, k21, j23, k24);
    }

    for (int l14 = 0; l14 < 8f * strength; l14++) {
      int l19 = chunkX + rand.nextInt(16) + 8;
      int k22 = 60 + rand.nextInt(40);
      int j24 = chunkY + rand.nextInt(16) + 8;

      if (rand.nextInt(3) == 0) {
        (new DecoGrass(Blocks.double_plant, 2)).generate(world, rand, l19, k22, j24);
      } else {
        (new DecoGrass(Blocks.tallgrass, 1)).generate(world, rand, l19, k22, j24);
      }
    }
  }
  @Override
  public void rDecorate(
      World world,
      Random rand,
      int chunkX,
      int chunkY,
      PerlinNoise perlin,
      CellNoise cell,
      float strength,
      float river) {
    if (rand.nextInt((int) (15f / strength)) == 0) {
      int i2 = chunkX + rand.nextInt(16) + 8;
      int i8 = chunkY + rand.nextInt(16) + 8;
      int l4 = world.getHeightValue(i2, i8);
      if (l4 > 63 && l4 < 105) {
        (new WorldGenLakes(Blocks.water)).generate(world, rand, i2, l4, i8);
      }
    }

    for (int l = 0; l < 6f * strength; ++l) {
      int i1 = chunkX + rand.nextInt(16) + 8;
      int j1 = chunkY + rand.nextInt(16) + 8;
      int k1 = world.getHeightValue(i1, j1);
      if (k1 < 95 && (k1 < 64 || rand.nextInt(15) == 0)) {
        (new DecoBlob(Blocks.mossy_cobblestone, 0)).generate(world, rand, i1, k1, j1);
      }
    }

    if (rand.nextInt((int) (25f / strength)) == 0) {
      int j16 = chunkX + rand.nextInt(16) + 8;
      int j18 = rand.nextInt(128);
      int j21 = chunkY + rand.nextInt(16) + 8;
      (new WorldGenPumpkin()).generate(world, rand, j16, j18, j21);
    }

    for (int f23 = 0; f23 < 2f * strength; f23++) {
      int j15 = chunkX + rand.nextInt(16) + 8;
      int j17 = rand.nextInt(128);
      int j20 = chunkY + rand.nextInt(16) + 8;
      (new DecoFlowers(new int[] {9, 0, 3})).generate(world, rand, j15, j17, j20);
    }

    for (int l14 = 0; l14 < 3f * strength; l14++) {
      int l19 = chunkX + rand.nextInt(16) + 8;
      int k22 = rand.nextInt(128);
      int j24 = chunkY + rand.nextInt(16) + 8;
      (new DecoGrass(Blocks.tallgrass, 1)).generate(world, rand, l19, k22, j24);
    }

    // trees
    float l = perlin.noise2(chunkX / 100f, chunkY / 100f) * 5f - 0.5f;
    for (int b1 = 0; b1 < l * 2f * strength; b1++) {
      int j6 = chunkX + rand.nextInt(16) + 8;
      int k10 = chunkY + rand.nextInt(16) + 8;
      int z52 = world.getHeightValue(j6, k10);

      if (z52 < 75) {
        WorldGenerator worldgenerator =
            rand.nextInt(8) != 0
                ? new DecoSmallSpruce(1 + rand.nextInt(2))
                : new DecoSmallPine(1 + rand.nextInt(3), 2 + rand.nextInt(4));
        worldgenerator.setScale(1.0D, 1.0D, 1.0D);
        worldgenerator.generate(world, rand, j6, z52, k10);
      } else if (z52 < 110) {
        WorldGenerator worldgenerator =
            rand.nextInt(4) != 0
                ? new DecoSmallSpruce(rand.nextInt(2))
                : new DecoSmallPine(2 + rand.nextInt(2), 4 + rand.nextInt(5));
        worldgenerator.setScale(1.0D, 1.0D, 1.0D);
        worldgenerator.generate(world, rand, j6, z52, k10);
      }
    }

    if (l > -0.4f) {
      for (int b = 0; b < 2f * strength; b++) {
        int i1 = chunkX + rand.nextInt(16) + 8;
        int j1 = chunkY + rand.nextInt(16) + 8;
        int k1 = world.getHeightValue(i1, j1);
        if (k1 < 110) {
          if (rand.nextInt(10) == 0) {
            (new DecoShrub(rand.nextInt(5) + 4, rand.nextInt(2), rand.nextInt(2)))
                .generate(world, rand, i1, k1, j1);
          } else {
            (new DecoShrub(rand.nextInt(4) + 1, rand.nextInt(2), rand.nextInt(2)))
                .generate(world, rand, i1, k1, j1);
          }
        }
      }
    }
  }