001package net.minecraft.world.biome;
002
003import cpw.mods.fml.relauncher.Side;
004import cpw.mods.fml.relauncher.SideOnly;
005import java.awt.Color;
006import java.util.ArrayList;
007import java.util.List;
008import java.util.Random;
009import net.minecraft.block.Block;
010import net.minecraft.entity.EnumCreatureType;
011import net.minecraft.entity.monster.EntityCreeper;
012import net.minecraft.entity.monster.EntityEnderman;
013import net.minecraft.entity.monster.EntitySkeleton;
014import net.minecraft.entity.monster.EntitySlime;
015import net.minecraft.entity.monster.EntitySpider;
016import net.minecraft.entity.monster.EntityZombie;
017import net.minecraft.entity.passive.EntityBat;
018import net.minecraft.entity.passive.EntityChicken;
019import net.minecraft.entity.passive.EntityCow;
020import net.minecraft.entity.passive.EntityPig;
021import net.minecraft.entity.passive.EntitySheep;
022import net.minecraft.entity.passive.EntitySquid;
023import net.minecraft.util.MathHelper;
024import net.minecraft.world.ColorizerFoliage;
025import net.minecraft.world.ColorizerGrass;
026import net.minecraft.world.World;
027import net.minecraft.world.gen.feature.WorldGenBigTree;
028import net.minecraft.world.gen.feature.WorldGenForest;
029import net.minecraft.world.gen.feature.WorldGenSwamp;
030import net.minecraft.world.gen.feature.WorldGenTallGrass;
031import net.minecraft.world.gen.feature.WorldGenTrees;
032import net.minecraft.world.gen.feature.WorldGenerator;
033
034import net.minecraftforge.common.*;
035import net.minecraftforge.event.terraingen.*;
036
037public abstract class BiomeGenBase
038{
039    /** An array of all the biomes, indexed by biome id. */
040    public static final BiomeGenBase[] biomeList = new BiomeGenBase[256];
041    public static final BiomeGenBase ocean = (new BiomeGenOcean(0)).setColor(112).setBiomeName("Ocean").setMinMaxHeight(-1.0F, 0.4F);
042    public static final BiomeGenBase plains = (new BiomeGenPlains(1)).setColor(9286496).setBiomeName("Plains").setTemperatureRainfall(0.8F, 0.4F);
043    public static final BiomeGenBase desert = (new BiomeGenDesert(2)).setColor(16421912).setBiomeName("Desert").setDisableRain().setTemperatureRainfall(2.0F, 0.0F).setMinMaxHeight(0.1F, 0.2F);
044    public static final BiomeGenBase extremeHills = (new BiomeGenHills(3)).setColor(6316128).setBiomeName("Extreme Hills").setMinMaxHeight(0.3F, 1.5F).setTemperatureRainfall(0.2F, 0.3F);
045    public static final BiomeGenBase forest = (new BiomeGenForest(4)).setColor(353825).setBiomeName("Forest").func_76733_a(5159473).setTemperatureRainfall(0.7F, 0.8F);
046    public static final BiomeGenBase taiga = (new BiomeGenTaiga(5)).setColor(747097).setBiomeName("Taiga").func_76733_a(5159473).setEnableSnow().setTemperatureRainfall(0.05F, 0.8F).setMinMaxHeight(0.1F, 0.4F);
047    public static final BiomeGenBase swampland = (new BiomeGenSwamp(6)).setColor(522674).setBiomeName("Swampland").func_76733_a(9154376).setMinMaxHeight(-0.2F, 0.1F).setTemperatureRainfall(0.8F, 0.9F);
048    public static final BiomeGenBase river = (new BiomeGenRiver(7)).setColor(255).setBiomeName("River").setMinMaxHeight(-0.5F, 0.0F);
049    public static final BiomeGenBase hell = (new BiomeGenHell(8)).setColor(16711680).setBiomeName("Hell").setDisableRain().setTemperatureRainfall(2.0F, 0.0F);
050
051    /** Is the biome used for sky world. */
052    public static final BiomeGenBase sky = (new BiomeGenEnd(9)).setColor(8421631).setBiomeName("Sky").setDisableRain();
053    public static final BiomeGenBase frozenOcean = (new BiomeGenOcean(10)).setColor(9474208).setBiomeName("FrozenOcean").setEnableSnow().setMinMaxHeight(-1.0F, 0.5F).setTemperatureRainfall(0.0F, 0.5F);
054    public static final BiomeGenBase frozenRiver = (new BiomeGenRiver(11)).setColor(10526975).setBiomeName("FrozenRiver").setEnableSnow().setMinMaxHeight(-0.5F, 0.0F).setTemperatureRainfall(0.0F, 0.5F);
055    public static final BiomeGenBase icePlains = (new BiomeGenSnow(12)).setColor(16777215).setBiomeName("Ice Plains").setEnableSnow().setTemperatureRainfall(0.0F, 0.5F);
056    public static final BiomeGenBase iceMountains = (new BiomeGenSnow(13)).setColor(10526880).setBiomeName("Ice Mountains").setEnableSnow().setMinMaxHeight(0.3F, 1.3F).setTemperatureRainfall(0.0F, 0.5F);
057    public static final BiomeGenBase mushroomIsland = (new BiomeGenMushroomIsland(14)).setColor(16711935).setBiomeName("MushroomIsland").setTemperatureRainfall(0.9F, 1.0F).setMinMaxHeight(0.2F, 1.0F);
058    public static final BiomeGenBase mushroomIslandShore = (new BiomeGenMushroomIsland(15)).setColor(10486015).setBiomeName("MushroomIslandShore").setTemperatureRainfall(0.9F, 1.0F).setMinMaxHeight(-1.0F, 0.1F);
059
060    /** Beach biome. */
061    public static final BiomeGenBase beach = (new BiomeGenBeach(16)).setColor(16440917).setBiomeName("Beach").setTemperatureRainfall(0.8F, 0.4F).setMinMaxHeight(0.0F, 0.1F);
062
063    /** Desert Hills biome. */
064    public static final BiomeGenBase desertHills = (new BiomeGenDesert(17)).setColor(13786898).setBiomeName("DesertHills").setDisableRain().setTemperatureRainfall(2.0F, 0.0F).setMinMaxHeight(0.3F, 0.8F);
065
066    /** Forest Hills biome. */
067    public static final BiomeGenBase forestHills = (new BiomeGenForest(18)).setColor(2250012).setBiomeName("ForestHills").func_76733_a(5159473).setTemperatureRainfall(0.7F, 0.8F).setMinMaxHeight(0.3F, 0.7F);
068
069    /** Taiga Hills biome. */
070    public static final BiomeGenBase taigaHills = (new BiomeGenTaiga(19)).setColor(1456435).setBiomeName("TaigaHills").setEnableSnow().func_76733_a(5159473).setTemperatureRainfall(0.05F, 0.8F).setMinMaxHeight(0.3F, 0.8F);
071
072    /** Extreme Hills Edge biome. */
073    public static final BiomeGenBase extremeHillsEdge = (new BiomeGenHills(20)).setColor(7501978).setBiomeName("Extreme Hills Edge").setMinMaxHeight(0.2F, 0.8F).setTemperatureRainfall(0.2F, 0.3F);
074
075    /** Jungle biome identifier */
076    public static final BiomeGenBase jungle = (new BiomeGenJungle(21)).setColor(5470985).setBiomeName("Jungle").func_76733_a(5470985).setTemperatureRainfall(1.2F, 0.9F).setMinMaxHeight(0.2F, 0.4F);
077    public static final BiomeGenBase jungleHills = (new BiomeGenJungle(22)).setColor(2900485).setBiomeName("JungleHills").func_76733_a(5470985).setTemperatureRainfall(1.2F, 0.9F).setMinMaxHeight(1.8F, 0.5F);
078    public String biomeName;
079    public int color;
080
081    /** The block expected to be on the top of this biome */
082    public byte topBlock;
083
084    /** The block to fill spots in when not on the top */
085    public byte fillerBlock;
086    public int field_76754_C;
087
088    /** The minimum height of this biome. Default 0.1. */
089    public float minHeight;
090
091    /** The maximum height of this biome. Default 0.3. */
092    public float maxHeight;
093
094    /** The temperature of this biome. */
095    public float temperature;
096
097    /** The rainfall in this biome. */
098    public float rainfall;
099
100    /** Color tint applied to water depending on biome */
101    public int waterColorMultiplier;
102
103    /** The biome decorator. */
104    public BiomeDecorator theBiomeDecorator;
105
106    /**
107     * Holds the classes of IMobs (hostile mobs) that can be spawned in the biome.
108     */
109    protected List spawnableMonsterList;
110
111    /**
112     * Holds the classes of any creature that can be spawned in the biome as friendly creature.
113     */
114    protected List spawnableCreatureList;
115
116    /**
117     * Holds the classes of any aquatic creature that can be spawned in the water of the biome.
118     */
119    protected List spawnableWaterCreatureList;
120    protected List spawnableCaveCreatureList;
121
122    /** Set to true if snow is enabled for this biome. */
123    private boolean enableSnow;
124
125    /**
126     * Is true (default) if the biome support rain (desert and nether can't have rain)
127     */
128    private boolean enableRain;
129
130    /** The id number to this biome, and its index in the biomeList array. */
131    public final int biomeID;
132
133    /** The tree generator. */
134    protected WorldGenTrees worldGeneratorTrees;
135
136    /** The big tree generator. */
137    protected WorldGenBigTree worldGeneratorBigTree;
138
139    /** The forest generator. */
140    protected WorldGenForest worldGeneratorForest;
141
142    /** The swamp tree generator. */
143    protected WorldGenSwamp worldGeneratorSwamp;
144
145    public BiomeGenBase(int par1)
146    {
147        this.topBlock = (byte)Block.grass.blockID;
148        this.fillerBlock = (byte)Block.dirt.blockID;
149        this.field_76754_C = 5169201;
150        this.minHeight = 0.1F;
151        this.maxHeight = 0.3F;
152        this.temperature = 0.5F;
153        this.rainfall = 0.5F;
154        this.waterColorMultiplier = 16777215;
155        this.spawnableMonsterList = new ArrayList();
156        this.spawnableCreatureList = new ArrayList();
157        this.spawnableWaterCreatureList = new ArrayList();
158        this.spawnableCaveCreatureList = new ArrayList();
159        this.enableRain = true;
160        this.worldGeneratorTrees = new WorldGenTrees(false);
161        this.worldGeneratorBigTree = new WorldGenBigTree(false);
162        this.worldGeneratorForest = new WorldGenForest(false);
163        this.worldGeneratorSwamp = new WorldGenSwamp();
164        this.biomeID = par1;
165        biomeList[par1] = this;
166        this.theBiomeDecorator = this.createBiomeDecorator();
167        this.spawnableCreatureList.add(new SpawnListEntry(EntitySheep.class, 12, 4, 4));
168        this.spawnableCreatureList.add(new SpawnListEntry(EntityPig.class, 10, 4, 4));
169        this.spawnableCreatureList.add(new SpawnListEntry(EntityChicken.class, 10, 4, 4));
170        this.spawnableCreatureList.add(new SpawnListEntry(EntityCow.class, 8, 4, 4));
171        this.spawnableMonsterList.add(new SpawnListEntry(EntitySpider.class, 10, 4, 4));
172        this.spawnableMonsterList.add(new SpawnListEntry(EntityZombie.class, 10, 4, 4));
173        this.spawnableMonsterList.add(new SpawnListEntry(EntitySkeleton.class, 10, 4, 4));
174        this.spawnableMonsterList.add(new SpawnListEntry(EntityCreeper.class, 10, 4, 4));
175        this.spawnableMonsterList.add(new SpawnListEntry(EntitySlime.class, 10, 4, 4));
176        this.spawnableMonsterList.add(new SpawnListEntry(EntityEnderman.class, 1, 1, 4));
177        this.spawnableWaterCreatureList.add(new SpawnListEntry(EntitySquid.class, 10, 4, 4));
178        this.spawnableCaveCreatureList.add(new SpawnListEntry(EntityBat.class, 10, 8, 8));
179    }
180
181    /**
182     * Allocate a new BiomeDecorator for this BiomeGenBase
183     */
184    public BiomeDecorator createBiomeDecorator()
185    {   
186        return getModdedBiomeDecorator(new BiomeDecorator(this));
187    }
188
189    /**
190     * Sets the temperature and rainfall of this biome.
191     */
192    public BiomeGenBase setTemperatureRainfall(float par1, float par2)
193    {
194        if (par1 > 0.1F && par1 < 0.2F)
195        {
196            throw new IllegalArgumentException("Please avoid temperatures in the range 0.1 - 0.2 because of snow");
197        }
198        else
199        {
200            this.temperature = par1;
201            this.rainfall = par2;
202            return this;
203        }
204    }
205
206    /**
207     * Sets the minimum and maximum height of this biome. Seems to go from -2.0 to 2.0.
208     */
209    public BiomeGenBase setMinMaxHeight(float par1, float par2)
210    {
211        this.minHeight = par1;
212        this.maxHeight = par2;
213        return this;
214    }
215
216    /**
217     * Disable the rain for the biome.
218     */
219    public BiomeGenBase setDisableRain()
220    {
221        this.enableRain = false;
222        return this;
223    }
224
225    /**
226     * Gets a WorldGen appropriate for this biome.
227     */
228    public WorldGenerator getRandomWorldGenForTrees(Random par1Random)
229    {
230        return (WorldGenerator)(par1Random.nextInt(10) == 0 ? this.worldGeneratorBigTree : this.worldGeneratorTrees);
231    }
232
233    /**
234     * Gets a WorldGen appropriate for this biome.
235     */
236    public WorldGenerator getRandomWorldGenForGrass(Random par1Random)
237    {
238        return new WorldGenTallGrass(Block.tallGrass.blockID, 1);
239    }
240
241    /**
242     * sets enableSnow to true during biome initialization. returns BiomeGenBase.
243     */
244    public BiomeGenBase setEnableSnow()
245    {
246        this.enableSnow = true;
247        return this;
248    }
249
250    public BiomeGenBase setBiomeName(String par1Str)
251    {
252        this.biomeName = par1Str;
253        return this;
254    }
255
256    public BiomeGenBase func_76733_a(int par1)
257    {
258        this.field_76754_C = par1;
259        return this;
260    }
261
262    public BiomeGenBase setColor(int par1)
263    {
264        this.color = par1;
265        return this;
266    }
267
268    @SideOnly(Side.CLIENT)
269
270    /**
271     * takes temperature, returns color
272     */
273    public int getSkyColorByTemp(float par1)
274    {
275        par1 /= 3.0F;
276
277        if (par1 < -1.0F)
278        {
279            par1 = -1.0F;
280        }
281
282        if (par1 > 1.0F)
283        {
284            par1 = 1.0F;
285        }
286
287        return Color.getHSBColor(0.62222224F - par1 * 0.05F, 0.5F + par1 * 0.1F, 1.0F).getRGB();
288    }
289
290    /**
291     * Returns the correspondent list of the EnumCreatureType informed.
292     */
293    public List getSpawnableList(EnumCreatureType par1EnumCreatureType)
294    {
295        return par1EnumCreatureType == EnumCreatureType.monster ? this.spawnableMonsterList : (par1EnumCreatureType == EnumCreatureType.creature ? this.spawnableCreatureList : (par1EnumCreatureType == EnumCreatureType.waterCreature ? this.spawnableWaterCreatureList : (par1EnumCreatureType == EnumCreatureType.ambient ? this.spawnableCaveCreatureList : null)));
296    }
297
298    /**
299     * Returns true if the biome have snowfall instead a normal rain.
300     */
301    public boolean getEnableSnow()
302    {
303        return this.enableSnow;
304    }
305
306    /**
307     * Return true if the biome supports lightning bolt spawn, either by have the bolts enabled and have rain enabled.
308     */
309    public boolean canSpawnLightningBolt()
310    {
311        return this.enableSnow ? false : this.enableRain;
312    }
313
314    /**
315     * Checks to see if the rainfall level of the biome is extremely high
316     */
317    public boolean isHighHumidity()
318    {
319        return this.rainfall > 0.85F;
320    }
321
322    /**
323     * returns the chance a creature has to spawn.
324     */
325    public float getSpawningChance()
326    {
327        return 0.1F;
328    }
329
330    /**
331     * Gets an integer representation of this biome's rainfall
332     */
333    public final int getIntRainfall()
334    {
335        return (int)(this.rainfall * 65536.0F);
336    }
337
338    /**
339     * Gets an integer representation of this biome's temperature
340     */
341    public final int getIntTemperature()
342    {
343        return (int)(this.temperature * 65536.0F);
344    }
345
346    @SideOnly(Side.CLIENT)
347
348    /**
349     * Gets a floating point representation of this biome's rainfall
350     */
351    public final float getFloatRainfall()
352    {
353        return this.rainfall;
354    }
355
356    /**
357     * Gets a floating point representation of this biome's temperature
358     */
359    public final float getFloatTemperature()
360    {
361        return this.temperature;
362    }
363
364    public void decorate(World par1World, Random par2Random, int par3, int par4)
365    {
366        this.theBiomeDecorator.decorate(par1World, par2Random, par3, par4);
367    }
368
369    @SideOnly(Side.CLIENT)
370
371    /**
372     * Provides the basic grass color based on the biome temperature and rainfall
373     */
374    public int getBiomeGrassColor()
375    {
376        double d0 = (double)MathHelper.clamp_float(this.getFloatTemperature(), 0.0F, 1.0F);
377        double d1 = (double)MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F);
378        return getModdedBiomeGrassColor(ColorizerGrass.getGrassColor(d0, d1));
379    }
380
381    @SideOnly(Side.CLIENT)
382
383    /**
384     * Provides the basic foliage color based on the biome temperature and rainfall
385     */
386    public int getBiomeFoliageColor()
387    {
388        double d0 = (double)MathHelper.clamp_float(this.getFloatTemperature(), 0.0F, 1.0F);
389        double d1 = (double)MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F);
390        return getModdedBiomeFoliageColor(ColorizerFoliage.getFoliageColor(d0, d1));
391    }
392
393    public BiomeDecorator getModdedBiomeDecorator(BiomeDecorator original)
394    {
395        BiomeEvent.CreateDecorator event = new BiomeEvent.CreateDecorator(this, original);
396        MinecraftForge.TERRAIN_GEN_BUS.post(event);
397        return event.newBiomeDecorator;
398    }
399
400    @SideOnly(Side.CLIENT)
401    public int getWaterColorMultiplier()
402    {
403        BiomeEvent.GetWaterColor event = new BiomeEvent.GetWaterColor(this, waterColorMultiplier);
404        MinecraftForge.EVENT_BUS.post(event);
405        return event.newColor;
406    }
407    
408    @SideOnly(Side.CLIENT)
409    public int getModdedBiomeGrassColor(int original)
410    {
411        BiomeEvent.GetGrassColor event = new BiomeEvent.GetGrassColor(this, original);
412        MinecraftForge.EVENT_BUS.post(event);
413        return event.newColor;
414    }
415    
416
417    @SideOnly(Side.CLIENT)
418    public int getModdedBiomeFoliageColor(int original)
419    {
420        BiomeEvent.GetFoliageColor event = new BiomeEvent.GetFoliageColor(this, original);
421        MinecraftForge.EVENT_BUS.post(event);
422        return event.newColor;
423    }
424}