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}