    001package net.minecraft.world.biome;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.ArrayList;
    006import java.util.Arrays;
    007import java.util.List;
    008import java.util.Random;
    009import net.minecraft.world.ChunkPosition;
    010import net.minecraft.world.World;
    011import net.minecraft.world.WorldType;
    012import net.minecraft.world.gen.layer.GenLayer;
    013import net.minecraft.world.gen.layer.IntCache;
    014
    015import net.minecraftforge.common.*;
    016import net.minecraftforge.event.terraingen.*;
    017import static net.minecraft.world.biome.BiomeGenBase.*;
    018
    019public class WorldChunkManager
    020{
    021    public static ArrayList<BiomeGenBase> allowedBiomes = new ArrayList<BiomeGenBase>(Arrays.asList(forest, plains, taiga, taigaHills, forestHills, jungle. jungleHills));
    022    private GenLayer genBiomes;
    023
    024    /** A GenLayer containing the indices into BiomeGenBase.biomeList[] */
    025    private GenLayer biomeIndexLayer;
    026
    027    /** The BiomeCache object for this world. */
    028    private BiomeCache biomeCache;
    029
    030    /** A list of biomes that the player can spawn in. */
    031    private List biomesToSpawnIn;
    032
    033    protected WorldChunkManager()
    034    {
    035        this.biomeCache = new BiomeCache(this);
    036        this.biomesToSpawnIn = new ArrayList();
    037        this.biomesToSpawnIn.addAll(allowedBiomes);
    038    }
    039
    040    public WorldChunkManager(long par1, WorldType par3WorldType)
    041    {
    042        this();
    043        GenLayer[] var4 = GenLayer.initializeAllBiomeGenerators(par1, par3WorldType);
    044        var4 = getModdedBiomeGenerators(par3WorldType, par1, var4);
    045        this.genBiomes = var4[0];
    046        this.biomeIndexLayer = var4[1];
    047    }
    048
    049    public WorldChunkManager(World par1World)
    050    {
    051        this(par1World.getSeed(), par1World.getWorldInfo().getTerrainType());
    052    }
    053
    054    /**
    055     * Gets the list of valid biomes for the player to spawn in.
    056     */
    057    public List getBiomesToSpawnIn()
    058    {
    059        return this.biomesToSpawnIn;
    060    }
    061
    062    /**
    063     * Returns the BiomeGenBase related to the x, z position on the world.
    064     */
    065    public BiomeGenBase getBiomeGenAt(int par1, int par2)
    066    {
    067        return this.biomeCache.getBiomeGenAt(par1, par2);
    068    }
    069
    070    /**
    071     * Returns a list of rainfall values for the specified blocks. Args: listToReuse, x, z, width, length.
    072     */
    073    public float[] getRainfall(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5)
    074    {
    075        IntCache.resetIntCache();
    076
    077        if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5)
    078        {
    079            par1ArrayOfFloat = new float[par4 * par5];
    080        }
    081
    082        int[] var6 = this.biomeIndexLayer.getInts(par2, par3, par4, par5);
    083
    084        for (int var7 = 0; var7 < par4 * par5; ++var7)
    085        {
    086            float var8 = (float)BiomeGenBase.biomeList[var6[var7]].getIntRainfall() / 65536.0F;
    087
    088            if (var8 > 1.0F)
    089            {
    090                var8 = 1.0F;
    091            }
    092
    093            par1ArrayOfFloat[var7] = var8;
    094        }
    095
    096        return par1ArrayOfFloat;
    097    }
    098
    099    @SideOnly(Side.CLIENT)
    100
    101    /**
    102     * Return an adjusted version of a given temperature based on the y height
    103     */
    104    public float getTemperatureAtHeight(float par1, int par2)
    105    {
    106        return par1;
    107    }
    108
    109    /**
    110     * Returns a list of temperatures to use for the specified blocks.  Args: listToReuse, x, y, width, length
    111     */
    112    public float[] getTemperatures(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5)
    113    {
    114        IntCache.resetIntCache();
    115
    116        if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5)
    117        {
    118            par1ArrayOfFloat = new float[par4 * par5];
    119        }
    120
    121        int[] var6 = this.biomeIndexLayer.getInts(par2, par3, par4, par5);
    122
    123        for (int var7 = 0; var7 < par4 * par5; ++var7)
    124        {
    125            float var8 = (float)BiomeGenBase.biomeList[var6[var7]].getIntTemperature() / 65536.0F;
    126
    127            if (var8 > 1.0F)
    128            {
    129                var8 = 1.0F;
    130            }
    131
    132            par1ArrayOfFloat[var7] = var8;
    133        }
    134
    135        return par1ArrayOfFloat;
    136    }
    137
    138    /**
    139     * Returns an array of biomes for the location input.
    140     */
    141    public BiomeGenBase[] getBiomesForGeneration(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5)
    142    {
    143        IntCache.resetIntCache();
    144
    145        if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5)
    146        {
    147            par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5];
    148        }
    149
    150        int[] var6 = this.genBiomes.getInts(par2, par3, par4, par5);
    151
    152        for (int var7 = 0; var7 < par4 * par5; ++var7)
    153        {
    154            par1ArrayOfBiomeGenBase[var7] = BiomeGenBase.biomeList[var6[var7]];
    155        }
    156
    157        return par1ArrayOfBiomeGenBase;
    158    }
    159
    160    /**
    161     * Returns biomes to use for the blocks and loads the other data like temperature and humidity onto the
    162     * WorldChunkManager Args: oldBiomeList, x, z, width, depth
    163     */
    164    public BiomeGenBase[] loadBlockGeneratorData(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5)
    165    {
    166        return this.getBiomeGenAt(par1ArrayOfBiomeGenBase, par2, par3, par4, par5, true);
    167    }
    168
    169    /**
    170     * Return a list of biomes for the specified blocks. Args: listToReuse, x, y, width, length, cacheFlag (if false,
    171     * don't check biomeCache to avoid infinite loop in BiomeCacheBlock)
    172     */
    173    public BiomeGenBase[] getBiomeGenAt(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5, boolean par6)
    174    {
    175        IntCache.resetIntCache();
    176
    177        if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5)
    178        {
    179            par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5];
    180        }
    181
    182        if (par6 && par4 == 16 && par5 == 16 && (par2 & 15) == 0 && (par3 & 15) == 0)
    183        {
    184            BiomeGenBase[] var9 = this.biomeCache.getCachedBiomes(par2, par3);
    185            System.arraycopy(var9, 0, par1ArrayOfBiomeGenBase, 0, par4 * par5);
    186            return par1ArrayOfBiomeGenBase;
    187        }
    188        else
    189        {
    190            int[] var7 = this.biomeIndexLayer.getInts(par2, par3, par4, par5);
    191
    192            for (int var8 = 0; var8 < par4 * par5; ++var8)
    193            {
    194                par1ArrayOfBiomeGenBase[var8] = BiomeGenBase.biomeList[var7[var8]];
    195            }
    196
    197            return par1ArrayOfBiomeGenBase;
    198        }
    199    }
    200
    201    /**
    202     * checks given Chunk's Biomes against List of allowed ones
    203     */
    204    public boolean areBiomesViable(int par1, int par2, int par3, List par4List)
    205    {
    206        IntCache.resetIntCache();
    207        int var5 = par1 - par3 >> 2;
    208        int var6 = par2 - par3 >> 2;
    209        int var7 = par1 + par3 >> 2;
    210        int var8 = par2 + par3 >> 2;
    211        int var9 = var7 - var5 + 1;
    212        int var10 = var8 - var6 + 1;
    213        int[] var11 = this.genBiomes.getInts(var5, var6, var9, var10);
    214
    215        for (int var12 = 0; var12 < var9 * var10; ++var12)
    216        {
    217            BiomeGenBase var13 = BiomeGenBase.biomeList[var11[var12]];
    218
    219            if (!par4List.contains(var13))
    220            {
    221                return false;
    222            }
    223        }
    224
    225        return true;
    226    }
    227
    228    /**
    229     * Finds a valid position within a range, that is in one of the listed biomes. Searches {par1,par2} +-par3 blocks.
    230     * Strongly favors positive y positions.
    231     */
    232    public ChunkPosition findBiomePosition(int par1, int par2, int par3, List par4List, Random par5Random)
    233    {
    234        IntCache.resetIntCache();
    235        int var6 = par1 - par3 >> 2;
    236        int var7 = par2 - par3 >> 2;
    237        int var8 = par1 + par3 >> 2;
    238        int var9 = par2 + par3 >> 2;
    239        int var10 = var8 - var6 + 1;
    240        int var11 = var9 - var7 + 1;
    241        int[] var12 = this.genBiomes.getInts(var6, var7, var10, var11);
    242        ChunkPosition var13 = null;
    243        int var14 = 0;
    244
    245        for (int var15 = 0; var15 < var10 * var11; ++var15)
    246        {
    247            int var16 = var6 + var15 % var10 << 2;
    248            int var17 = var7 + var15 / var10 << 2;
    249            BiomeGenBase var18 = BiomeGenBase.biomeList[var12[var15]];
    250
    251            if (par4List.contains(var18) && (var13 == null || par5Random.nextInt(var14 + 1) == 0))
    252            {
    253                var13 = new ChunkPosition(var16, 0, var17);
    254                ++var14;
    255            }
    256        }
    257
    258        return var13;
    259    }
    260
    261    /**
    262     * Calls the WorldChunkManager's biomeCache.cleanupCache()
    263     */
    264    public void cleanupCache()
    265    {
    266        this.biomeCache.cleanupCache();
    267    }
    268
    269    public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
    270    {
    271        WorldTypeEvent.InitBiomeGens event = new WorldTypeEvent.InitBiomeGens(worldType, seed, original);
    272        MinecraftForge.TERRAIN_GEN_BUS.post(event);
    273        return event.newBiomeGens;
    274    }
    275}