gt:             this.limb(blockpos.south(), blockpos1.south(), block);
context: package net.minecraft.world.gen.feature;
  
  import com.google.common.collect.Lists;
  import java.util.List;
  import java.util.Random;
  import net.minecraft.block.Block;
  import net.minecraft.block.BlockLeaves;
  import net.minecraft.block.BlockLog;
  import net.minecraft.block.material.Material;
  import net.minecraft.block.state.IBlockState;
  import net.minecraft.init.Blocks;
  import net.minecraft.util.math.BlockPos;
  import net.minecraft.util.math.MathHelper;
  import net.minecraft.world.World;
  
  public class WorldGenBigTree extends WorldGenAbstractTree
  {
      private Random rand;
      private World world;
      private BlockPos basePos = BlockPos.ORIGIN;
      int heightLimit;
      int height;
      double heightAttenuation = 0.618D;
      double branchSlope = 0.381D;
      double scaleWidth = 1.0D;
      double leafDensity = 1.0D;
      int trunkSize = 1;
      int heightLimitLimit = 12;
      /** Sets the distance limit for how far away the generator will populate leaves from the base leaf node. */
      int leafDistanceLimit = 4;
      List<WorldGenBigTree.FoliageCoordinates> foliageCoords;
  
      public WorldGenBigTree(boolean notify)
      {
          super(notify);
      }
  
      /**
       * Generates a list of leaf nodes for the tree, to be populated by generateLeaves.
       */
      void generateLeafNodeList()
      {
          this.height = (int)((double)this.heightLimit * this.heightAttenuation);
  
          if (this.height >= this.heightLimit)
          {
              this.height = this.heightLimit - 1;
          }
  
          int i = (int)(1.382D + Math.pow(this.leafDensity * (double)this.heightLimit / 13.0D, 2.0D));
  
          if (i < 1)
          {
              i = 1;
          }
  
          int j = this.basePos.getY() + this.height;
          int k = this.heightLimit - this.leafDistanceLimit;
          this.foliageCoords = Lists.<WorldGenBigTree.FoliageCoordinates>newArrayList();
          this.foliageCoords.add(new WorldGenBigTree.FoliageCoordinates(this.basePos.up(k), j));
  
          for (; k >= 0; --k)
          {
              float f = this.layerSize(k);
  
              if (f >= 0.0F)
              {
                  for (int l = 0; l < i; ++l)
                  {
                      double d0 = this.scaleWidth * (double)f * ((double)this.rand.nextFloat() + 0.328D);
                      double d1 = (double)(this.rand.nextFloat() * 2.0F) * Math.PI;
                      double d2 = d0 * Math.sin(d1) + 0.5D;
                      double d3 = d0 * Math.cos(d1) + 0.5D;
                      BlockPos blockpos = this.basePos.add(d2, (double)(k - 1), d3);
                      BlockPos blockpos1 = blockpos.up(this.leafDistanceLimit);
  
                      if (this.checkBlockLine(blockpos, blockpos1) == -1)
                      {
                          int i1 = this.basePos.getX() - blockpos.getX();
                          int j1 = this.basePos.getZ() - blockpos.getZ();
                          double d4 = (double)blockpos.getY() - Math.sqrt((double)(i1 * i1 + j1 * j1)) * this.branchSlope;
                          int k1 = d4 > (double)j ? j : (int)d4;
                          BlockPos blockpos2 = new BlockPos(this.basePos.getX(), k1, this.basePos.getZ());
  
                          if (this.checkBlockLine(blockpos2, blockpos) == -1)
                          {
                              this.foliageCoords.add(new WorldGenBigTree.FoliageCoordinates(blockpos, blockpos2.getY()));
                          }
                      }
                  }
              }
          }
      }
  
      void crosSection(BlockPos pos, float p_181631_2_, IBlockState p_181631_3_)
      {
          int i = (int)((double)p_181631_2_ + 0.618D);
  
          for (int j = -i; j <= i; ++j)
          {
              for (int k = -i; k <= i; ++k)
              {
                  if (Math.pow((double)Math.abs(j) + 0.5D, 2.0D) + Math.pow((double)Math.abs(k) + 0.5D, 2.0D) <= (double)(p_181631_2_ * p_181631_2_))
                  {
                      BlockPos blockpos = pos.add(j, 0, k);
                      IBlockState state = this.world.getBlockState(blockpos);
  
                      if (state.getBlock().isAir(state, world, blockpos) || state.getBlock().isLeaves(state, world, blockpos))
                      {
                          this.setBlockAndNotifyAdequately(this.world, blockpos, p_181631_3_);
                      }
                  }
              }
          }
      }
  
      /**
       * Gets the rough size of a layer of the tree.
       */
      float layerSize(int y)
      {
          if ((float)y < (float)this.heightLimit * 0.3F)
          {
              return -1.0F;
          }
          else
          {
              float f = (float)this.heightLimit / 2.0F;
              float f1 = f - (float)y;
              float f2 = MathHelper.sqrt(f * f - f1 * f1);
  
              if (f1 == 0.0F)
              {
                  f2 = f;
              }
              else if (Math.abs(f1) >= f)
              {
                  return 0.0F;
              }
  
              return f2 * 0.5F;
          }
      }
  
      float leafSize(int y)
      {
          if (y >= 0 && y < this.leafDistanceLimit)
          {
              return y != 0 && y != this.leafDistanceLimit - 1 ? 3.0F : 2.0F;
          }
          else
          {
              return -1.0F;
          }
      }
  
      /**
       * Generates the leaves surrounding an individual entry in the leafNodes list.
       */
      void generateLeafNode(BlockPos pos)
      {
          for (int i = 0; i < this.leafDistanceLimit; ++i)
          {
              this.crosSection(pos.up(i), this.leafSize(i), Blocks.LEAVES.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)));
          }
      }
  
      void limb(BlockPos p_175937_1_, BlockPos p_175937_2_, Block p_175937_3_)
      {
          BlockPos blockpos = p_175937_2_.add(-p_175937_1_.getX(), -p_175937_1_.getY(), -p_175937_1_.getZ());
          int i = this.getGreatestDistance(blockpos);
          float f = (float)blockpos.getX() / (float)i;
          float f1 = (float)blockpos.getY() / (float)i;
          float f2 = (float)blockpos.getZ() / (float)i;
  
          for (int j = 0; j <= i; ++j)
          {
              BlockPos blockpos1 = p_175937_1_.add((double)(0.5F + (float)j * f), (double)(0.5F + (float)j * f1), (double)(0.5F + (float)j * f2));
              BlockLog.EnumAxis blocklog$enumaxis = this.getLogAxis(p_175937_1_, blockpos1);
              this.setBlockAndNotifyAdequately(this.world, blockpos1, p_175937_3_.getDefaultState().withProperty(BlockLog.LOG_AXIS, blocklog$enumaxis));
          }
      }
  
      /**
       * Returns the absolute greatest distance in the BlockPos object.
       */
      private int getGreatestDistance(BlockPos posIn)
      {
          int i = MathHelper.abs(posIn.getX());
          int j = MathHelper.abs(posIn.getY());
          int k = MathHelper.abs(posIn.getZ());
  
          if (k > i && k > j)
          {
              return k;
          }
          else
          {
              return j > i ? j : i;
          }
      }
  
      private BlockLog.EnumAxis getLogAxis(BlockPos p_175938_1_, BlockPos p_175938_2_)
      {
          BlockLog.EnumAxis blocklog$enumaxis = BlockLog.EnumAxis.Y;
          int i = Math.abs(p_175938_2_.getX() - p_175938_1_.getX());
          int j = Math.abs(p_175938_2_.getZ() - p_175938_1_.getZ());
          int k = Math.max(i, j);
  
          if (k > 0)
          {
              if (i == k)
              {
                  blocklog$enumaxis = BlockLog.EnumAxis.X;
              }
              else if (j == k)
              {
                  blocklog$enumaxis = BlockLog.EnumAxis.Z;
              }
          }
  
          return blocklog$enumaxis;
      }
  
      /**
       * Generates the leaf portion of the tree as specified by the leafNodes list.
       */
      void generateLeaves()
      {
          for (WorldGenBigTree.FoliageCoordinates worldgenbigtree$foliagecoordinates : this.foliageCoords)
          {
              this.generateLeafNode(worldgenbigtree$foliagecoordinates);
          }
      }
  
      /**
       * Indicates whether or not a leaf node requires additional wood to be added to preserve integrity.
       */
      boolean leafNodeNeedsBase(int p_76493_1_)
      {
          return (double)p_76493_1_ >= (double)this.heightLimit * 0.2D;
      }
  
      /**
       * Places the trunk for the big tree that is being generated. Able to generate double-sized trunks by changing a
       * field that is always 1 to 2.
       */
      void generateTrunk()
      {
          BlockPos blockpos = this.basePos;
          BlockPos blockpos1 = this.basePos.up(this.height);
          Block block = Blocks.LOG;
          this.limb(blockpos, blockpos1, block);
  
          if (this.trunkSize == 2)
          {
              this.limb(blockpos.east(), blockpos1.east(), block);
              this.limb(blockpos.east().south(), blockpos1.east().south(), block);
  