/**
   * Finds a valid position within a range, that is in one of the listed biomes. Searches
   * {par1,par2} +-par3 blocks. Strongly favors positive y positions.
   */
  @Override
  @SuppressWarnings("rawtypes")
  public ChunkPosition findBiomePosition(
      int par1, int par2, int par3, List par4List, Random par5Random) {
    IntCache.resetIntCache();
    int var6 = par1 - par3 >> 2;
    int var7 = par2 - par3 >> 2;
    int var8 = par1 + par3 >> 2;
    int var9 = par2 + par3 >> 2;
    int var10 = var8 - var6 + 1;
    int var11 = var9 - var7 + 1;
    int[] var12 = genBiomes.getInts(var6, var7, var10, var11);
    ChunkPosition var13 = null;
    int var14 = 0;

    for (int var15 = 0; var15 < var10 * var11; ++var15) {
      int var16 = var6 + var15 % var10 << 2;
      int var17 = var7 + var15 / var10 << 2;
      BiomeGenBase var18 = BiomeGenBase.biomeList[var12[var15]];

      if (par4List.contains(var18) && (var13 == null || par5Random.nextInt(var14 + 1) == 0)) {
        var13 = new ChunkPosition(var16, 0, var17);
        ++var14;
      }
    }

    return var13;
  }
  /**
   * Return a list of biomes for the specified blocks. Args: listToReuse, x, y, width, length,
   * cacheFlag (if false, don't check biomeCache to avoid infinite loop in BiomeCacheBlock)
   */
  @Override
  public BiomeGenBase[] getBiomeGenAt(
      BiomeGenBase[] par1ArrayOfBiomeGenBase,
      int par2,
      int par3,
      int par4,
      int par5,
      boolean par6) {
    IntCache.resetIntCache();

    if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5) {
      par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5];
    }

    if (par6 && par4 == 16 && par5 == 16 && (par2 & 15) == 0 && (par3 & 15) == 0) {
      BiomeGenBase[] var9 = biomeCache.getCachedBiomes(par2, par3);
      System.arraycopy(var9, 0, par1ArrayOfBiomeGenBase, 0, par4 * par5);
      return par1ArrayOfBiomeGenBase;
    } else {
      int[] var7 = biomeIndexLayer.getInts(par2, par3, par4, par5);

      for (int var8 = 0; var8 < par4 * par5; ++var8) {
        par1ArrayOfBiomeGenBase[var8] = BiomeGenBase.biomeList[var7[var8]];
      }

      return par1ArrayOfBiomeGenBase;
    }
  }
  /** Returns an array of biomes for the location input. */
  @Override
  public BiomeGenBase[] getBiomesForGeneration(
      BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5) {
    IntCache.resetIntCache();

    if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5) {
      par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5];
    }

    int[] var6 = genBiomes.getInts(par2, par3, par4, par5);

    for (int var7 = 0; var7 < par4 * par5; ++var7) {
      par1ArrayOfBiomeGenBase[var7] = BiomeGenBase.biomeList[var6[var7]];
    }

    return par1ArrayOfBiomeGenBase;
  }
  /** checks given Chunk's Biomes against List of allowed ones */
  @Override
  @SuppressWarnings("rawtypes")
  public boolean areBiomesViable(int par1, int par2, int par3, List par4List) {
    IntCache.resetIntCache();
    int var5 = par1 - par3 >> 2;
    int var6 = par2 - par3 >> 2;
    int var7 = par1 + par3 >> 2;
    int var8 = par2 + par3 >> 2;
    int var9 = var7 - var5 + 1;
    int var10 = var8 - var6 + 1;
    int[] var11 = genBiomes.getInts(var5, var6, var9, var10);

    for (int var12 = 0; var12 < var9 * var10; ++var12) {
      BiomeGenBase var13 = BiomeGenBase.biomeList[var11[var12]];

      if (!par4List.contains(var13)) return false;
    }

    return true;
  }
  /**
   * Returns a list of temperatures to use for the specified blocks. Args: listToReuse, x, y, width,
   * length
   */
  @Override
  public float[] getTemperatures(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5) {
    IntCache.resetIntCache();

    if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5) {
      par1ArrayOfFloat = new float[par4 * par5];
    }

    int[] var6 = biomeIndexLayer.getInts(par2, par3, par4, par5);

    for (int var7 = 0; var7 < par4 * par5; ++var7) {
      float var8 = BiomeGenBase.biomeList[var6[var7]].getIntTemperature() / 65536.0F;

      if (var8 > 1.0F) {
        var8 = 1.0F;
      }

      par1ArrayOfFloat[var7] = var8;
    }

    return par1ArrayOfFloat;
  }