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