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