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