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