    001package net.minecraft.world.gen.feature;
    002
    003import java.util.Random;
    004import net.minecraft.block.Block;
    005import net.minecraft.block.BlockSapling;
    006import net.minecraft.util.MathHelper;
    007import net.minecraft.world.World;
    008import net.minecraftforge.common.ForgeDirection;
    009
    010public class WorldGenHugeTrees extends WorldGenerator
    011{
    012    /** The base height of the tree */
    013    private final int baseHeight;
    014
    015    /** Sets the metadata for the wood blocks used */
    016    private final int woodMetadata;
    017
    018    /** Sets the metadata for the leaves used in huge trees */
    019    private final int leavesMetadata;
    020
    021    public WorldGenHugeTrees(boolean par1, int par2, int par3, int par4)
    022    {
    023        super(par1);
    024        this.baseHeight = par2;
    025        this.woodMetadata = par3;
    026        this.leavesMetadata = par4;
    027    }
    028
    029    public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5)
    030    {
    031        int l = par2Random.nextInt(3) + this.baseHeight;
    032        boolean flag = true;
    033
    034        if (par4 >= 1 && par4 + l + 1 <= 256)
    035        {
    036            int i1;
    037            int j1;
    038            int k1;
    039            int l1;
    040
    041            for (i1 = par4; i1 <= par4 + 1 + l; ++i1)
    042            {
    043                byte b0 = 2;
    044
    045                if (i1 == par4)
    046                {
    047                    b0 = 1;
    048                }
    049
    050                if (i1 >= par4 + 1 + l - 2)
    051                {
    052                    b0 = 2;
    053                }
    054
    055                for (j1 = par3 - b0; j1 <= par3 + b0 && flag; ++j1)
    056                {
    057                    for (k1 = par5 - b0; k1 <= par5 + b0 && flag; ++k1)
    058                    {
    059                        if (i1 >= 0 && i1 < 256)
    060                        {
    061                            l1 = par1World.getBlockId(j1, i1, k1);
    062
    063                            if (l1 != 0 &&
    064                               (Block.blocksList[l1] != null && !Block.blocksList[l1].isLeaves(par1World, j1, i1, k1)) &&
    065                               l1 != Block.grass.blockID &&
    066                               l1 != Block.dirt.blockID &&
    067                               (Block.blocksList[l1] != null && !Block.blocksList[l1].isWood(par1World, j1, i1, k1)) &&
    068                               l1 != Block.sapling.blockID)
    069                            {
    070                                flag = false;
    071                            }
    072                        }
    073                        else
    074                        {
    075                            flag = false;
    076                        }
    077                    }
    078                }
    079            }
    080
    081            if (!flag)
    082            {
    083                return false;
    084            }
    085            else
    086            {
    087                i1 = par1World.getBlockId(par3, par4 - 1, par5);
    088
    089                Block soil = Block.blocksList[i1];
    090                boolean isValidSoil = soil != null && soil.canSustainPlant(par1World, par3, par4 - 1, par5, ForgeDirection.UP, (BlockSapling)Block.sapling);
    091
    092                if (isValidSoil && par4 < 256 - l - 1)
    093                {
    094                    onPlantGrow(par1World, par3,     par4 - 1, par5,     par3, par4, par5);
    095                    onPlantGrow(par1World, par3 + 1, par4 - 1, par5,     par3, par4, par5);
    096                    onPlantGrow(par1World, par3,     par4 - 1, par5 + 1, par3, par4, par5);
    097                    onPlantGrow(par1World, par3 + 1, par4 - 1, par5 + 1, par3, par4, par5);
    098                    this.growLeaves(par1World, par3, par5, par4 + l, 2, par2Random);
    099
    100                    for (int i2 = par4 + l - 2 - par2Random.nextInt(4); i2 > par4 + l / 2; i2 -= 2 + par2Random.nextInt(4))
    101                    {
    102                        float f = par2Random.nextFloat() * (float)Math.PI * 2.0F;
    103                        k1 = par3 + (int)(0.5F + MathHelper.cos(f) * 4.0F);
    104                        l1 = par5 + (int)(0.5F + MathHelper.sin(f) * 4.0F);
    105                        this.growLeaves(par1World, k1, l1, i2, 0, par2Random);
    106
    107                        for (int j2 = 0; j2 < 5; ++j2)
    108                        {
    109                            k1 = par3 + (int)(1.5F + MathHelper.cos(f) * (float)j2);
    110                            l1 = par5 + (int)(1.5F + MathHelper.sin(f) * (float)j2);
    111                            this.setBlockAndMetadata(par1World, k1, i2 - 3 + j2 / 2, l1, Block.wood.blockID, this.woodMetadata);
    112                        }
    113                    }
    114
    115                    for (j1 = 0; j1 < l; ++j1)
    116                    {
    117                        k1 = par1World.getBlockId(par3, par4 + j1, par5);
    118
    119                        if (k1 == 0 || Block.blocksList[k1] == null || Block.blocksList[k1].isLeaves(par1World, par3, par4 + j1, par5))
    120                        {
    121                            this.setBlockAndMetadata(par1World, par3, par4 + j1, par5, Block.wood.blockID, this.woodMetadata);
    122
    123                            if (j1 > 0)
    124                            {
    125                                if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 - 1, par4 + j1, par5))
    126                                {
    127                                    this.setBlockAndMetadata(par1World, par3 - 1, par4 + j1, par5, Block.vine.blockID, 8);
    128                                }
    129
    130                                if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3, par4 + j1, par5 - 1))
    131                                {
    132                                    this.setBlockAndMetadata(par1World, par3, par4 + j1, par5 - 1, Block.vine.blockID, 1);
    133                                }
    134                            }
    135                        }
    136
    137                        if (j1 < l - 1)
    138                        {
    139                            k1 = par1World.getBlockId(par3 + 1, par4 + j1, par5);
    140
    141                            if (k1 == 0 || Block.blocksList[k1] == null || Block.blocksList[k1].isLeaves(par1World, par3 + 1, par4 + j1, par5))
    142                            {
    143                                this.setBlockAndMetadata(par1World, par3 + 1, par4 + j1, par5, Block.wood.blockID, this.woodMetadata);
    144
    145                                if (j1 > 0)
    146                                {
    147                                    if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 + 2, par4 + j1, par5))
    148                                    {
    149                                        this.setBlockAndMetadata(par1World, par3 + 2, par4 + j1, par5, Block.vine.blockID, 2);
    150                                    }
    151
    152                                    if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 + 1, par4 + j1, par5 - 1))
    153                                    {
    154                                        this.setBlockAndMetadata(par1World, par3 + 1, par4 + j1, par5 - 1, Block.vine.blockID, 1);
    155                                    }
    156                                }
    157                            }
    158
    159                            k1 = par1World.getBlockId(par3 + 1, par4 + j1, par5 + 1);
    160
    161                            if (k1 == 0 || Block.blocksList[k1] == null || Block.blocksList[k1].isLeaves(par1World, par3 + 1, par4 + j1, par5 + 1))
    162                            {
    163                                this.setBlockAndMetadata(par1World, par3 + 1, par4 + j1, par5 + 1, Block.wood.blockID, this.woodMetadata);
    164
    165                                if (j1 > 0)
    166                                {
    167                                    if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 + 2, par4 + j1, par5 + 1))
    168                                    {
    169                                        this.setBlockAndMetadata(par1World, par3 + 2, par4 + j1, par5 + 1, Block.vine.blockID, 2);
    170                                    }
    171
    172                                    if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 + 1, par4 + j1, par5 + 2))
    173                                    {
    174                                        this.setBlockAndMetadata(par1World, par3 + 1, par4 + j1, par5 + 2, Block.vine.blockID, 4);
    175                                    }
    176                                }
    177                            }
    178
    179                            k1 = par1World.getBlockId(par3, par4 + j1, par5 + 1);
    180
    181                            if (k1 == 0 || Block.blocksList[k1] == null || Block.blocksList[k1].isLeaves(par1World, par3, par4 + j1, par5 + 1))
    182                            {
    183                                this.setBlockAndMetadata(par1World, par3, par4 + j1, par5 + 1, Block.wood.blockID, this.woodMetadata);
    184
    185                                if (j1 > 0)
    186                                {
    187                                    if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 - 1, par4 + j1, par5 + 1))
    188                                    {
    189                                        this.setBlockAndMetadata(par1World, par3 - 1, par4 + j1, par5 + 1, Block.vine.blockID, 8);
    190                                    }
    191
    192                                    if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3, par4 + j1, par5 + 2))
    193                                    {
    194                                        this.setBlockAndMetadata(par1World, par3, par4 + j1, par5 + 2, Block.vine.blockID, 4);
    195                                    }
    196                                }
    197                            }
    198                        }
    199                    }
    200
    201                    return true;
    202                }
    203                else
    204                {
    205                    return false;
    206                }
    207            }
    208        }
    209        else
    210        {
    211            return false;
    212        }
    213    }
    214
    215    private void growLeaves(World par1World, int par2, int par3, int par4, int par5, Random par6Random)
    216    {
    217        byte b0 = 2;
    218
    219        for (int i1 = par4 - b0; i1 <= par4; ++i1)
    220        {
    221            int j1 = i1 - par4;
    222            int k1 = par5 + 1 - j1;
    223
    224            for (int l1 = par2 - k1; l1 <= par2 + k1 + 1; ++l1)
    225            {
    226                int i2 = l1 - par2;
    227
    228                for (int j2 = par3 - k1; j2 <= par3 + k1 + 1; ++j2)
    229                {
    230                    int k2 = j2 - par3;
    231
    232                    if ((i2 >= 0 || k2 >= 0 || i2 * i2 + k2 * k2 <= k1 * k1) && (i2 <= 0 && k2 <= 0 || i2 * i2 + k2 * k2 <= (k1 + 1) * (k1 + 1)) && (par6Random.nextInt(4) != 0 || i2 * i2 + k2 * k2 <= (k1 - 1) * (k1 - 1)))
    233                    {
    234                        int l2 = par1World.getBlockId(l1, i1, j2);
    235                        Block block = Block.blocksList[l2];
    236
    237                        if (block == null || block.canBeReplacedByLeaves(par1World, l1, i1, j2))
    238                        {
    239                            this.setBlockAndMetadata(par1World, l1, i1, j2, Block.leaves.blockID, this.leavesMetadata);
    240                        }
    241                    }
    242                }
    243            }
    244        }
    245    }
    246
    247    private void onPlantGrow(World world, int x, int y, int z, int sourceX, int sourceY, int sourceZ)
    248    {
    249        Block block = Block.blocksList[world.getBlockId(x, y, z)];
    250        if (block != null)
    251        {
    252            block.onPlantGrow(world, x, y, z, sourceX, sourceY, sourceZ);
    253        }
    254    }
    255}