001    package net.minecraft.src;
002    
003    import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.*;
004    import static net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.*;
005    
006    import java.util.Random;
007    
008    import net.minecraftforge.common.*;
009    import net.minecraftforge.event.terraingen.*;
010    
011    public class BiomeDecorator
012    {
013        /** The world the BiomeDecorator is currently decorating */
014        public World currentWorld;
015    
016        /** The Biome Decorator's random number generator. */
017        public Random randomGenerator;
018    
019        /** The X-coordinate of the chunk currently being decorated */
020        public int chunk_X;
021    
022        /** The Z-coordinate of the chunk currently being decorated */
023        public int chunk_Z;
024    
025        /** The biome generator object. */
026        public BiomeGenBase biome;
027    
028        /** The clay generator. */
029        public WorldGenerator clayGen = new WorldGenClay(4);
030    
031        /** The sand generator. */
032        public WorldGenerator sandGen;
033    
034        /** The gravel generator. */
035        public WorldGenerator gravelAsSandGen;
036    
037        /** The dirt generator. */
038        public WorldGenerator dirtGen;
039        public WorldGenerator gravelGen;
040        public WorldGenerator coalGen;
041        public WorldGenerator ironGen;
042    
043        /** Field that holds gold WorldGenMinable */
044        public WorldGenerator goldGen;
045    
046        /** Field that holds redstone WorldGenMinable */
047        public WorldGenerator redstoneGen;
048    
049        /** Field that holds diamond WorldGenMinable */
050        public WorldGenerator diamondGen;
051    
052        /** Field that holds Lapis WorldGenMinable */
053        public WorldGenerator lapisGen;
054    
055        /** Field that holds one of the plantYellow WorldGenFlowers */
056        public WorldGenerator plantYellowGen;
057    
058        /** Field that holds one of the plantRed WorldGenFlowers */
059        public WorldGenerator plantRedGen;
060    
061        /** Field that holds mushroomBrown WorldGenFlowers */
062        public WorldGenerator mushroomBrownGen;
063    
064        /** Field that holds mushroomRed WorldGenFlowers */
065        public WorldGenerator mushroomRedGen;
066    
067        /** Field that holds big mushroom generator */
068        public WorldGenerator bigMushroomGen;
069    
070        /** Field that holds WorldGenReed */
071        public WorldGenerator reedGen;
072    
073        /** Field that holds WorldGenCactus */
074        public WorldGenerator cactusGen;
075    
076        /** The water lily generation! */
077        public WorldGenerator waterlilyGen;
078    
079        /** Amount of waterlilys per chunk. */
080        public int waterlilyPerChunk;
081    
082        /**
083         * The number of trees to attempt to generate per chunk. Up to 10 in forests, none in deserts.
084         */
085        public int treesPerChunk;
086    
087        /**
088         * The number of yellow flower patches to generate per chunk. The game generates much less than this number, since
089         * it attempts to generate them at a random altitude.
090         */
091        public int flowersPerChunk;
092    
093        /** The amount of tall grass to generate per chunk. */
094        public int grassPerChunk;
095    
096        /**
097         * The number of dead bushes to generate per chunk. Used in deserts and swamps.
098         */
099        public int deadBushPerChunk;
100    
101        /**
102         * The number of extra mushroom patches per chunk. It generates 1/4 this number in brown mushroom patches, and 1/8
103         * this number in red mushroom patches. These mushrooms go beyond the default base number of mushrooms.
104         */
105        public int mushroomsPerChunk;
106    
107        /**
108         * The number of reeds to generate per chunk. Reeds won't generate if the randomly selected placement is unsuitable.
109         */
110        public int reedsPerChunk;
111    
112        /**
113         * The number of cactus plants to generate per chunk. Cacti only work on sand.
114         */
115        public int cactiPerChunk;
116    
117        /**
118         * The number of sand patches to generate per chunk. Sand patches only generate when part of it is underwater.
119         */
120        public int sandPerChunk;
121    
122        /**
123         * The number of sand patches to generate per chunk. Sand patches only generate when part of it is underwater. There
124         * appear to be two separate fields for this.
125         */
126        public int sandPerChunk2;
127    
128        /**
129         * The number of clay patches to generate per chunk. Only generates when part of it is underwater.
130         */
131        public int clayPerChunk;
132    
133        /** Amount of big mushrooms per chunk */
134        public int bigMushroomsPerChunk;
135    
136        /** True if decorator should generate surface lava & water */
137        public boolean generateLakes;
138    
139        public BiomeDecorator(BiomeGenBase par1BiomeGenBase)
140        {
141            this.sandGen = new WorldGenSand(7, Block.sand.blockID);
142            this.gravelAsSandGen = new WorldGenSand(6, Block.gravel.blockID);
143            this.dirtGen = new WorldGenMinable(Block.dirt.blockID, 32);
144            this.gravelGen = new WorldGenMinable(Block.gravel.blockID, 32);
145            this.coalGen = new WorldGenMinable(Block.oreCoal.blockID, 16);
146            this.ironGen = new WorldGenMinable(Block.oreIron.blockID, 8);
147            this.goldGen = new WorldGenMinable(Block.oreGold.blockID, 8);
148            this.redstoneGen = new WorldGenMinable(Block.oreRedstone.blockID, 7);
149            this.diamondGen = new WorldGenMinable(Block.oreDiamond.blockID, 7);
150            this.lapisGen = new WorldGenMinable(Block.oreLapis.blockID, 6);
151            this.plantYellowGen = new WorldGenFlowers(Block.plantYellow.blockID);
152            this.plantRedGen = new WorldGenFlowers(Block.plantRed.blockID);
153            this.mushroomBrownGen = new WorldGenFlowers(Block.mushroomBrown.blockID);
154            this.mushroomRedGen = new WorldGenFlowers(Block.mushroomRed.blockID);
155            this.bigMushroomGen = new WorldGenBigMushroom();
156            this.reedGen = new WorldGenReed();
157            this.cactusGen = new WorldGenCactus();
158            this.waterlilyGen = new WorldGenWaterlily();
159            this.waterlilyPerChunk = 0;
160            this.treesPerChunk = 0;
161            this.flowersPerChunk = 2;
162            this.grassPerChunk = 1;
163            this.deadBushPerChunk = 0;
164            this.mushroomsPerChunk = 0;
165            this.reedsPerChunk = 0;
166            this.cactiPerChunk = 0;
167            this.sandPerChunk = 1;
168            this.sandPerChunk2 = 3;
169            this.clayPerChunk = 1;
170            this.bigMushroomsPerChunk = 0;
171            this.generateLakes = true;
172            this.biome = par1BiomeGenBase;
173        }
174    
175        /**
176         * Decorates the world. Calls code that was formerly (pre-1.8) in ChunkProviderGenerate.populate
177         */
178        public void decorate(World par1World, Random par2Random, int par3, int par4)
179        {
180            if (this.currentWorld != null)
181            {
182                throw new RuntimeException("Already decorating!!");
183            }
184            else
185            {
186                this.currentWorld = par1World;
187                this.randomGenerator = par2Random;
188                this.chunk_X = par3;
189                this.chunk_Z = par4;
190                this.decorate();
191                this.currentWorld = null;
192                this.randomGenerator = null;
193            }
194        }
195    
196        /**
197         * The method that does the work of actually decorating chunks
198         */
199        protected void decorate()
200        {
201            MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Pre(currentWorld, randomGenerator, chunk_X, chunk_Z));
202            
203           this.generateOres();
204            int var1;
205            int var2;
206            int var3;
207    
208            boolean doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SAND);
209            for (var1 = 0; doGen && var1 < this.sandPerChunk2; ++var1)
210            {
211                var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
212                var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
213                this.sandGen.generate(this.currentWorld, this.randomGenerator, var2, this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3);
214            }
215    
216            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, CLAY);
217            for (var1 = 0; doGen && var1 < this.clayPerChunk; ++var1)
218            {
219                var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
220                var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
221                this.clayGen.generate(this.currentWorld, this.randomGenerator, var2, this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3);
222            }
223    
224            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SAND_PASS2);
225            for (var1 = 0; doGen && var1 < this.sandPerChunk; ++var1)
226            {
227                var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
228                var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
229                this.sandGen.generate(this.currentWorld, this.randomGenerator, var2, this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3);
230            }
231    
232            var1 = this.treesPerChunk;
233    
234            if (this.randomGenerator.nextInt(10) == 0)
235            {
236                ++var1;
237            }
238    
239            int var4;
240    
241            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, TREE);
242            for (var2 = 0; doGen && var2 < var1; ++var2)
243            {
244                var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
245                var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
246                WorldGenerator var5 = this.biome.getRandomWorldGenForTrees(this.randomGenerator);
247                var5.setScale(1.0D, 1.0D, 1.0D);
248                var5.generate(this.currentWorld, this.randomGenerator, var3, this.currentWorld.getHeightValue(var3, var4), var4);
249            }
250    
251            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, BIG_SHROOM);
252            for (var2 = 0; doGen && var2 < this.bigMushroomsPerChunk; ++var2)
253            {
254                var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
255                var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
256                this.bigMushroomGen.generate(this.currentWorld, this.randomGenerator, var3, this.currentWorld.getHeightValue(var3, var4), var4);
257            }
258    
259            int var7;
260    
261            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, FLOWERS);
262            for (var2 = 0; doGen && var2 < this.flowersPerChunk; ++var2)
263            {
264                var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
265                var4 = this.randomGenerator.nextInt(128);
266                var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
267                this.plantYellowGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
268    
269                if (this.randomGenerator.nextInt(4) == 0)
270                {
271                    var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
272                    var4 = this.randomGenerator.nextInt(128);
273                    var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
274                    this.plantRedGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
275                }
276            }
277    
278            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, GRASS);
279            for (var2 = 0; doGen && var2 < this.grassPerChunk; ++var2)
280            {
281                var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
282                var4 = this.randomGenerator.nextInt(128);
283                var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
284                WorldGenerator var6 = this.biome.getRandomWorldGenForGrass(this.randomGenerator);
285                var6.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
286            }
287    
288            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, DEAD_BUSH);
289            for (var2 = 0; doGen && var2 < this.deadBushPerChunk; ++var2)
290            {
291                var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
292                var4 = this.randomGenerator.nextInt(128);
293                var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
294                (new WorldGenDeadBush(Block.deadBush.blockID)).generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
295            }
296    
297            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, LILYPAD);
298            for (var2 = 0; doGen && var2 < this.waterlilyPerChunk; ++var2)
299            {
300                var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
301                var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
302    
303                for (var7 = this.randomGenerator.nextInt(128); var7 > 0 && this.currentWorld.getBlockId(var3, var7 - 1, var4) == 0; --var7)
304                {
305                    ;
306                }
307    
308                this.waterlilyGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4);
309            }
310    
311            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, SHROOM);
312            for (var2 = 0; doGen && var2 < this.mushroomsPerChunk; ++var2)
313            {
314                if (this.randomGenerator.nextInt(4) == 0)
315                {
316                    var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
317                    var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
318                    var7 = this.currentWorld.getHeightValue(var3, var4);
319                    this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4);
320                }
321    
322                if (this.randomGenerator.nextInt(8) == 0)
323                {
324                    var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
325                    var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
326                    var7 = this.randomGenerator.nextInt(128);
327                    this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4);
328                }
329            }
330    
331            if (doGen && this.randomGenerator.nextInt(4) == 0)
332            {
333                var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
334                var3 = this.randomGenerator.nextInt(128);
335                var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
336                this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, var2, var3, var4);
337            }
338    
339            if (doGen && this.randomGenerator.nextInt(8) == 0)
340            {
341                var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
342                var3 = this.randomGenerator.nextInt(128);
343                var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
344                this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, var2, var3, var4);
345            }
346    
347            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, REED);
348            for (var2 = 0; doGen && var2 < this.reedsPerChunk; ++var2)
349            {
350                var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
351                var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
352                var7 = this.randomGenerator.nextInt(128);
353                this.reedGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4);
354            }
355    
356            for (var2 = 0; doGen && var2 < 10; ++var2)
357            {
358                var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
359                var4 = this.randomGenerator.nextInt(128);
360                var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
361                this.reedGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
362            }
363    
364            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, PUMPKIN);
365            if (doGen && this.randomGenerator.nextInt(32) == 0)
366            {
367                var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
368                var3 = this.randomGenerator.nextInt(128);
369                var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
370                (new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, var2, var3, var4);
371            }
372    
373            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, CACTUS);
374            for (var2 = 0; doGen && var2 < this.cactiPerChunk; ++var2)
375            {
376                var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
377                var4 = this.randomGenerator.nextInt(128);
378                var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
379                this.cactusGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
380            }
381    
382            doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, LAKE);
383            if (doGen && this.generateLakes)
384            {
385                for (var2 = 0; var2 < 50; ++var2)
386                {
387                    var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
388                    var4 = this.randomGenerator.nextInt(this.randomGenerator.nextInt(120) + 8);
389                    var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
390                    (new WorldGenLiquids(Block.waterMoving.blockID)).generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
391                }
392    
393                for (var2 = 0; var2 < 20; ++var2)
394                {
395                    var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
396                    var4 = this.randomGenerator.nextInt(this.randomGenerator.nextInt(this.randomGenerator.nextInt(112) + 8) + 8);
397                    var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
398                    (new WorldGenLiquids(Block.lavaMoving.blockID)).generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
399                }
400            }
401    
402            MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
403        }
404    
405        /**
406         * Standard ore generation helper. Generates most ores.
407         */
408        protected void genStandardOre1(int par1, WorldGenerator par2WorldGenerator, int par3, int par4)
409        {
410            for (int var5 = 0; var5 < par1; ++var5)
411            {
412                int var6 = this.chunk_X + this.randomGenerator.nextInt(16);
413                int var7 = this.randomGenerator.nextInt(par4 - par3) + par3;
414                int var8 = this.chunk_Z + this.randomGenerator.nextInt(16);
415                par2WorldGenerator.generate(this.currentWorld, this.randomGenerator, var6, var7, var8);
416            }
417        }
418    
419        /**
420         * Standard ore generation helper. Generates Lapis Lazuli.
421         */
422        protected void genStandardOre2(int par1, WorldGenerator par2WorldGenerator, int par3, int par4)
423        {
424            for (int var5 = 0; var5 < par1; ++var5)
425            {
426                int var6 = this.chunk_X + this.randomGenerator.nextInt(16);
427                int var7 = this.randomGenerator.nextInt(par4) + this.randomGenerator.nextInt(par4) + (par3 - par4);
428                int var8 = this.chunk_Z + this.randomGenerator.nextInt(16);
429                par2WorldGenerator.generate(this.currentWorld, this.randomGenerator, var6, var7, var8);
430            }
431        }
432    
433        /**
434         * Generates ores in the current chunk
435         */
436        protected void generateOres()
437        {
438            MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Pre(currentWorld, randomGenerator, chunk_X, chunk_Z));
439            if (TerrainGen.generateOre(currentWorld, randomGenerator, dirtGen, chunk_X, chunk_Z, DIRT))
440            this.genStandardOre1(20, this.dirtGen, 0, 128);
441            if (TerrainGen.generateOre(currentWorld, randomGenerator, gravelGen, chunk_X, chunk_Z, GRAVEL))
442            this.genStandardOre1(10, this.gravelGen, 0, 128);
443            if (TerrainGen.generateOre(currentWorld, randomGenerator, coalGen, chunk_X, chunk_Z, COAL))
444            this.genStandardOre1(20, this.coalGen, 0, 128);
445            if (TerrainGen.generateOre(currentWorld, randomGenerator, ironGen, chunk_X, chunk_Z, IRON))
446            this.genStandardOre1(20, this.ironGen, 0, 64);
447            if (TerrainGen.generateOre(currentWorld, randomGenerator, goldGen, chunk_X, chunk_Z, GOLD))
448            this.genStandardOre1(2, this.goldGen, 0, 32);
449            if (TerrainGen.generateOre(currentWorld, randomGenerator, redstoneGen, chunk_X, chunk_Z, REDSTONE))
450            this.genStandardOre1(8, this.redstoneGen, 0, 16);
451            if (TerrainGen.generateOre(currentWorld, randomGenerator, diamondGen, chunk_X, chunk_Z, DIAMOND))
452            this.genStandardOre1(1, this.diamondGen, 0, 16);
453            if (TerrainGen.generateOre(currentWorld, randomGenerator, lapisGen, chunk_X, chunk_Z, LAPIS))
454            this.genStandardOre2(1, this.lapisGen, 16, 16);
455            MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
456        }
457    }