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