protected boolean isReplaceable(World world, int x, int y, int z) {
   Block block = world.getBlock(x, y, z);
   return block.isAir(world, x, y, z)
       || block.isLeaves(world, x, y, z)
       || block.isWood(world, x, y, z)
       || func_150523_a(block);
 }
Example #2
0
  @Override
  public boolean onBlockStartBreak(ItemStack stack, int x, int y, int z, EntityPlayer player) {
    if (!stack.hasTagCompound()) return false;

    World world = player.worldObj;
    final Block wood = world.getBlock(x, y, z);
    ;
    if (wood == null) {
      return super.onBlockStartBreak(stack, x, y, z, player);
    }
    if (wood.isWood(world, x, y, z) || wood.getMaterial() == Material.sponge) {
      int height = y;
      boolean foundTop = false;
      do {
        height++;
        Block block = world.getBlock(x, height, z);
        if (block != wood) {
          height--;
          foundTop = true;
        }
      } while (!foundTop);

      int numLeaves = 0;
      if (height - y < 50) {
        for (int xPos = x - 1; xPos <= x + 1; xPos++) {
          for (int yPos = height - 1; yPos <= height + 1; yPos++) {
            for (int zPos = z - 1; zPos <= z + 1; zPos++) {
              Block leaves = world.getBlock(xPos, yPos, zPos);
              if (leaves != null && leaves.isLeaves(world, xPos, yPos, zPos)) numLeaves++;
            }
          }
        }
      }

      NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool");
      int meta = world.getBlockMetadata(x, y, z);
      if (numLeaves > 3) breakTree(world, x, y, z, stack, tags, wood, meta, player);
      else destroyWood(world, x, y, z, stack, tags, player);

      if (!world.isRemote)
        world.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(wood) + (meta << 12));
    } else if (wood.getMaterial() == Material.wood) {
      NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool");
      int meta = world.getBlockMetadata(x, y, z);
      destroyWood(world, x, y, z, stack, tags, player);
      if (!world.isRemote)
        world.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(wood) + (meta << 12));
    }
    return super.onBlockStartBreak(stack, x, y, z, player);
  }
  public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) {
    int l = par2Random.nextInt(3) + this.minTreeHeight;
    boolean flag = true;
    if (par4 >= 1 && par4 + l + 1 <= 256) {
      int i1;
      byte b0;
      int j1;
      int k1;
      for (i1 = par4; i1 <= par4 + 1 + l; ++i1) {
        b0 = 1;
        if (i1 == par4) {
          b0 = 0;
        }
        if (i1 >= par4 + 1 + l - 2) {
          b0 = 2;
        }
        for (int l1 = par3 - b0; l1 <= par3 + b0 && flag; ++l1) {
          for (j1 = par5 - b0; j1 <= par5 + b0 && flag; ++j1) {
            if (i1 >= 0 && i1 < 256) {
              k1 = par1World.getBlockId(l1, i1 - 1, j1);
              /** Custom grass block * */
              Block block = IntegratedBlocks.DarkSand;
              if (k1 != 0
                  && !block.isLeaves(par1World, l1, i1, j1)

                  /** Custom grass block * */
                  && k1 != IntegratedBlocks.DarkSand.blockID
                  && k1 != Block.dirt.blockID
                  && k1 != Block.grass.blockID
                  && k1 != Block.sand.blockID
                  && !block.isWood(par1World, l1, i1, j1)) {
                flag = false;
              }
            } else {
              flag = false;
            }
          }
        }
      }
      if (!flag) {
        return false;
      } else {
        i1 = par1World.getBlockId(par3, par4 - 1, par5);

        /** Custom grass block * */
        Block soil = IntegratedBlocks.DarkSand; // , Block.dirt, Block.sand, Block.grass;

        /** Custom Sapling block * */
        boolean isSoil =
            (soil != null
                && soil.canSustainPlant(
                    par1World,
                    par3,
                    par4 - 1,
                    par5,
                    ForgeDirection.UP,
                    (BlockCherryTreeSapling) IntegratedBlocks.CherryTreeSapling));
        if (isSoil && par4 < 256 - l - 1) {
          soil.onPlantGrow(par1World, par3, par4 - 1, par5, par3, par4, par5);
          b0 = 3;
          byte b1 = 0;
          int i2;
          int j2;
          int k2;
          for (j1 = par4 - b0 + l; j1 <= par4 + l; ++j1) {
            k1 = j1 - (par4 + l);
            i2 = b1 + 1 - k1 / 2;
            for (j2 = par3 - i2; j2 <= par3 + i2; ++j2) {
              k2 = j2 - par3;
              for (int l2 = par5 - i2; l2 <= par5 + i2; ++l2) {
                int i3 = l2 - par5;
                if (Math.abs(k2) != i2
                    || Math.abs(i3) != i2
                    || par2Random.nextInt(2) != 0 && k1 != 0) {
                  int j3 = par1World.getBlockId(j2, j1, l2);
                  Block block = Block.blocksList[j3];
                  if (block == null || block.canBeReplacedByLeaves(par1World, j2, j1, l2)) {
                    /** Custom leaf block * */
                    this.setBlockAndMetadata(
                        par1World,
                        j2,
                        j1,
                        l2,
                        IntegratedBlocks.CherryTreeLeaves.blockID,
                        this.metaLeaves);
                  }
                }
              }
            }
          }
          for (j1 = 0; j1 < l; ++j1) {
            k1 = par1World.getBlockId(par3, par4 + j1, par5);
            Block block = Block.blocksList[k1];
            if (k1 == 0 || block == null || block.isLeaves(par1World, par3, par4 + j1, par5)) {
              /** Custom Log block * */
              this.setBlockAndMetadata(
                  par1World,
                  par3,
                  par4 + j1,
                  par5,
                  IntegratedBlocks.Cherrywood.blockID,
                  this.metaWood);
            }
          }
          if (par2Random.nextInt(5) == 0 && l > 5) {
            for (j1 = 0; j1 < 2; ++j1) {
              for (k1 = 0; k1 < 4; ++k1) {
                if (par2Random.nextInt(4 - j1) == 0) {
                  i2 = par2Random.nextInt(3); // Fruit
                  this.setBlockAndMetadata(
                      par1World,
                      par3 + Direction.offsetX[Direction.rotateOpposite[k1]],
                      par4 + l - 5 + j1,
                      par5 + Direction.offsetZ[Direction.rotateOpposite[k1]],
                      IntegratedBlocks.CherryTreeLeaves.blockID,
                      i2 << 2 | k1);
                }
              }
            }
          }
        }
        return true;
      }
    }
    return flag;
  }
  public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) {
    int var6 = par2Random.nextInt(2) + this.minTreeHeight;
    boolean var7 = true;

    if (par4 >= 1 && par4 + var6 + 1 <= 256) {
      int var8;
      byte var9;
      int var11;
      int var12;

      for (var8 = par4; var8 <= par4 + 1 + var6; ++var8) {
        var9 = 1;

        if (var8 == par4) {
          var9 = 0;
        }

        if (var8 >= par4 + 1 + var6 - 2) {
          var9 = 2;
        }

        for (int var10 = par3 - var9; var10 <= par3 + var9 && var7; ++var10) {
          for (var11 = par5 - var9; var11 <= par5 + var9 && var7; ++var11) {
            if (var8 >= 0 && var8 < 256) {
              var12 = par1World.getBlockId(var10, var8, var11);

              Block block = Block.blocksList[var12];

              if (var12 != 0
                  && !block.isLeaves(par1World, var10, var8, var11)
                  && var12 != Block.grass.blockID
                  && var12 != Block.dirt.blockID
                  && !block.isWood(par1World, var10, var8, var11)) {
                var7 = false;
              }
            } else {
              var7 = false;
            }
          }
        }
      }

      if (!var7) {
        return false;
      } else {
        var8 = par1World.getBlockId(par3, par4 - 1, par5);

        if ((var8 == Block.grass.blockID || var8 == Block.dirt.blockID) && par4 < 256 - var6 - 1) {
          this.setBlock(par1World, par3, par4 - 1, par5, Block.dirt.blockID);
          var9 = 3;
          byte var18 = 0;
          int var13;
          int var14;
          int var15;

          for (var11 = par4 - var9 + var6; var11 <= par4 + var6; ++var11) {
            var12 = var11 - (par4 + var6);
            var13 = var18 + 1 - var12 / 2;

            for (var14 = par3 - var13; var14 <= par3 + var13; ++var14) {
              var15 = var14 - par3;

              for (int var16 = par5 - var13; var16 <= par5 + var13; ++var16) {
                int var17 = var16 - par5;

                Block block = Block.blocksList[par1World.getBlockId(var14, var11, var16)];

                if ((Math.abs(var15) != var13
                        || Math.abs(var17) != var13
                        || par2Random.nextInt(2) != 0 && var12 != 0)
                    && (block == null
                        || block.canBeReplacedByLeaves(par1World, var14, var11, var16))) {
                  this.setBlockAndMetadata(
                      par1World, var14, var11, var16, Block.leaves.blockID, this.metaLeaves);
                }
              }
            }
          }

          for (var11 = 0; var11 < var6; ++var11) {
            var12 = par1World.getBlockId(par3, par4 + var11, par5);

            Block block = Block.blocksList[var12];

            if (var12 == 0
                || block == null
                || block.isLeaves(par1World, par3, par4 + var11, par5)) {
              this.setBlockAndMetadata(
                  par1World, par3, par4 + var11, par5, Block.wood.blockID, this.metaWood);

              if (this.vinesGrow && var11 > 0) {
                if (par2Random.nextInt(3) > 0
                    && par1World.isAirBlock(par3 - 1, par4 + var11, par5)) {
                  this.setBlockAndMetadata(
                      par1World, par3 - 1, par4 + var11, par5, Block.vine.blockID, 8);
                }

                if (par2Random.nextInt(3) > 0
                    && par1World.isAirBlock(par3 + 1, par4 + var11, par5)) {
                  this.setBlockAndMetadata(
                      par1World, par3 + 1, par4 + var11, par5, Block.vine.blockID, 2);
                }

                if (par2Random.nextInt(3) > 0
                    && par1World.isAirBlock(par3, par4 + var11, par5 - 1)) {
                  this.setBlockAndMetadata(
                      par1World, par3, par4 + var11, par5 - 1, Block.vine.blockID, 1);
                }

                if (par2Random.nextInt(3) > 0
                    && par1World.isAirBlock(par3, par4 + var11, par5 + 1)) {
                  this.setBlockAndMetadata(
                      par1World, par3, par4 + var11, par5 + 1, Block.vine.blockID, 4);
                }
              }
            }
          }

          if (this.vinesGrow) {
            for (var11 = par4 - 3 + var6; var11 <= par4 + var6; ++var11) {
              var12 = var11 - (par4 + var6);
              var13 = 2 - var12 / 2;

              for (var14 = par3 - var13; var14 <= par3 + var13; ++var14) {
                for (var15 = par5 - var13; var15 <= par5 + var13; ++var15) {
                  Block block = Block.blocksList[par1World.getBlockId(var14, var11, var15)];
                  if (block != null && block.isLeaves(par1World, var14, var11, var15)) {
                    if (par2Random.nextInt(4) == 0
                        && par1World.getBlockId(var14 - 1, var11, var15) == 0) {
                      this.growVines(par1World, var14 - 1, var11, var15, 8);
                    }

                    if (par2Random.nextInt(4) == 0
                        && par1World.getBlockId(var14 + 1, var11, var15) == 0) {
                      this.growVines(par1World, var14 + 1, var11, var15, 2);
                    }

                    if (par2Random.nextInt(4) == 0
                        && par1World.getBlockId(var14, var11, var15 - 1) == 0) {
                      this.growVines(par1World, var14, var11, var15 - 1, 1);
                    }

                    if (par2Random.nextInt(4) == 0
                        && par1World.getBlockId(var14, var11, var15 + 1) == 0) {
                      this.growVines(par1World, var14, var11, var15 + 1, 4);
                    }
                  }
                }
              }
            }

            if (par2Random.nextInt(5) == 0 && var6 > 5) {
              for (var11 = 0; var11 < 2; ++var11) {
                for (var12 = 0; var12 < 4; ++var12) {
                  if (par2Random.nextInt(4 - var11) == 0) {
                    var13 = par2Random.nextInt(3);
                    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);
                  }
                }
              }
            }
          }

          return true;
        } else {
          return false;
        }
      }
    } else {
      return false;
    }
  }
  @Override
  public void handleCommand(ICommandSender sender, String[] args) {

    if (args.length < 7) {
      sender.addChatMessage(new ChatComponentTranslation("info.cofh.command.syntaxError"));
      throw new WrongUsageException("info.cofh.command." + getCommandName() + ".syntax");
    }
    World world = sender.getEntityWorld();
    if (world.isRemote) {
      return;
    }

    ChunkCoordinates center = null;
    int i = 1;
    int xS, xL;
    if ("@".equals(args[i])) {
      center = sender.getPlayerCoordinates();
      ++i;
      xS = CommandBase.parseInt(sender, args[i++]);
    } else {
      try {
        xS = CommandBase.parseInt(sender, args[i++]);
      } catch (Throwable t) {
        center = CommandBase.getPlayer(sender, args[i - 1]).getPlayerCoordinates();
        xS = CommandBase.parseInt(sender, args[i++]);
      }
    }
    int yS = CommandBase.parseInt(sender, args[i++]), yL;
    int zS = CommandBase.parseInt(sender, args[i++]), zL;
    int t = i + 1;

    try {
      xL = CommandBase.parseInt(sender, args[i++]);
      yL = CommandBase.parseInt(sender, args[i++]);
      zL = CommandBase.parseInt(sender, args[i++]);
    } catch (Throwable e) {
      if (i > t || center == null) {
        throw Throwables.propagate(e);
      }
      --i;
      xL = xS;
      yL = yS;
      zL = zS;
    }

    if (center != null) {
      xS = center.posX - xS;
      yS = center.posY - yS;
      zS = center.posZ - zS;

      xL = center.posX + xL;
      yL = center.posY + yL;
      zL = center.posZ + zL;
    }

    yS &= ~yS >> 31; // max(yS, 0)
    yL &= ~yL >> 31; // max(yL, 0)

    if (xL < xS) {
      t = xS;
      xS = xL;
      xL = t;
    }
    if (yL < yS) {
      t = yS;
      yS = yL;
      yL = t;
    }
    if (zL < zS) {
      t = zS;
      zS = zL;
      zL = t;
    }

    if (yS > 255) {
      sender.addChatMessage(new ChatComponentTranslation("info.cofh.command.syntaxError"));
      sender.addChatMessage(
          new ChatComponentTranslation("info.cofh.command." + getCommandName() + ".syntax"));
      return;
    } else if (yL > 255) {
      yL = 255;
    }

    Block replBlock;
    int replMeta;
    String blockReplRaw;
    {
      int meta = 0;
      String blockRaw = args[i];
      blockReplRaw = blockRaw;
      t = blockRaw.indexOf('#');
      if (t > 0) {
        meta = CommandBase.parseInt(sender, blockRaw.substring(t + 1));
        blockRaw = blockRaw.substring(0, t);
      }
      Block block = Block.getBlockFromName(blockRaw);
      if (block == Blocks.air || meta > 15 || meta < 0) {
        sender.addChatMessage(new ChatComponentTranslation("info.cofh.command.syntaxError"));
        sender.addChatMessage(
            new ChatComponentTranslation("info.cofh.command." + getCommandName() + ".syntax"));
        // TODO: more descriptive error
        return;
      }
      replBlock = block;
      replMeta = meta;
    }

    long blockCounter = ((long) xL - xS) * ((long) yL - yS) * ((long) zL - zS);
    CommandHandler.logAdminCommand(
        sender,
        this,
        "info.cofh.command.replaceblocks.start",
        blockCounter,
        xS,
        yS,
        zS,
        xL,
        yL,
        zL,
        blockReplRaw);

    THashSet<Chunk> set = new THashSet<Chunk>();

    blockCounter = 0;
    for (int e = args.length; i < e; ++i) {
      String blockRaw = args[i];
      if (blockRaw.charAt(0) == '*') {
        if (blockRaw.equals("*fluid")) {
          for (int x = xS; x <= xL; ++x) {
            for (int z = zS; z <= zL; ++z) {
              Chunk chunk = world.getChunkFromBlockCoords(x, z);
              int cX = x & 15, cZ = z & 15;
              for (int y = yS; y <= yL; ++y) {
                Block block = chunk.getBlock(cX, y, cZ);
                if (block.getMaterial().isLiquid()) {
                  if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                    ++blockCounter;
                    set.add(chunk);
                  }
                }
              }
            }
          }
        } else if (blockRaw.equals("*tree")) {
          for (int x = xS; x <= xL; ++x) {
            for (int z = zS; z <= zL; ++z) {
              Chunk chunk = world.getChunkFromBlockCoords(x, z);
              int cX = x & 15, cZ = z & 15;
              for (int y = yS; y <= yL; ++y) {
                Block block = chunk.getBlock(cX, y, cZ);
                if (block.isWood(world, x, y, z) || block.isLeaves(world, x, y, z)) {
                  if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                    ++blockCounter;
                    set.add(chunk);
                  }
                }
              }
            }
          }
        } else if (blockRaw.startsWith("*repl")) {
          for (int x = xS; x <= xL; ++x) {
            for (int z = zS; z <= zL; ++z) {
              Chunk chunk = world.getChunkFromBlockCoords(x, z);
              int cX = x & 15, cZ = z & 15;
              for (int y = yS; y <= yL; ++y) {
                Block block = chunk.getBlock(cX, y, cZ);
                if (block.isReplaceable(world, x, y, z)) {
                  if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                    ++blockCounter;
                    set.add(chunk);
                  }
                }
              }
            }
          }
        } else if (blockRaw.equals("*stone")) {
          for (int x = xS; x <= xL; ++x) {
            for (int z = zS; z <= zL; ++z) {
              Chunk chunk = world.getChunkFromBlockCoords(x, z);
              int cX = x & 15, cZ = z & 15;
              for (int y = yS; y <= yL; ++y) {
                Block block = chunk.getBlock(cX, y, cZ);
                if (block.isReplaceableOreGen(world, x, y, z, Blocks.stone)
                    || block.isReplaceableOreGen(world, x, y, z, Blocks.netherrack)
                    || block.isReplaceableOreGen(world, x, y, z, Blocks.end_stone)) {
                  if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                    ++blockCounter;
                    set.add(chunk);
                  }
                }
              }
            }
          }
        } else if (blockRaw.equals("*rock")) {
          for (int x = xS; x <= xL; ++x) {
            for (int z = zS; z <= zL; ++z) {
              Chunk chunk = world.getChunkFromBlockCoords(x, z);
              int cX = x & 15, cZ = z & 15;
              for (int y = yS; y <= yL; ++y) {
                Block block = chunk.getBlock(cX, y, cZ);
                if (block.getMaterial() == Material.rock) {
                  if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                    ++blockCounter;
                    set.add(chunk);
                  }
                }
              }
            }
          }
        } else if (blockRaw.equals("*sand")) {
          for (int x = xS; x <= xL; ++x) {
            for (int z = zS; z <= zL; ++z) {
              Chunk chunk = world.getChunkFromBlockCoords(x, z);
              int cX = x & 15, cZ = z & 15;
              for (int y = yS; y <= yL; ++y) {
                Block block = chunk.getBlock(cX, y, cZ);
                if (block.getMaterial() == Material.sand) {
                  if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                    ++blockCounter;
                    set.add(chunk);
                  }
                }
              }
            }
          }
        } else if (blockRaw.equals("*dirt")) {
          for (int x = xS; x <= xL; ++x) {
            for (int z = zS; z <= zL; ++z) {
              Chunk chunk = world.getChunkFromBlockCoords(x, z);
              int cX = x & 15, cZ = z & 15;
              for (int y = yS; y <= yL; ++y) {
                Block block = chunk.getBlock(cX, y, cZ);
                Material m = block.getMaterial();
                if (m == Material.grass
                    || m == Material.ground
                    || m == Material.clay
                    || m == Material.snow
                    || m == Material.craftedSnow
                    || m == Material.ice
                    || m == Material.packedIce) {
                  if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                    ++blockCounter;
                    set.add(chunk);
                  }
                }
              }
            }
          }
        } else if (blockRaw.startsWith("*plant")) {
          for (int x = xS; x <= xL; ++x) {
            for (int z = zS; z <= zL; ++z) {
              Chunk chunk = world.getChunkFromBlockCoords(x, z);
              int cX = x & 15, cZ = z & 15;
              for (int y = yS; y <= yL; ++y) {
                Block block = chunk.getBlock(cX, y, cZ);
                Material m = block.getMaterial();
                if (m == Material.plants
                    || m == Material.vine
                    || m == Material.cactus
                    || m == Material.leaves) {
                  if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                    ++blockCounter;
                    set.add(chunk);
                  }
                }
              }
            }
          }
        } else if (blockRaw.equals("*fire")) {
          for (int x = xS; x <= xL; ++x) {
            for (int z = zS; z <= zL; ++z) {
              Chunk chunk = world.getChunkFromBlockCoords(x, z);
              int cX = x & 15, cZ = z & 15;
              for (int y = yS; y <= yL; ++y) {
                Block block = chunk.getBlock(cX, y, cZ);
                Material m = block.getMaterial();
                if (m == Material.fire || m == Material.lava || block.isBurning(world, x, y, z)) {
                  if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                    ++blockCounter;
                    set.add(chunk);
                  }
                }
              }
            }
          }
        }
        continue;
      }
      int meta = -1;
      t = blockRaw.indexOf('#');
      if (t > 0) {
        meta = CommandBase.parseInt(sender, blockRaw.substring(t + 1));
        blockRaw = blockRaw.substring(0, t);
      }
      Block block = Block.getBlockFromName(blockRaw);
      if (block == Blocks.air) {
        continue;
      }

      for (int x = xS; x <= xL; ++x) {
        for (int z = zS; z <= zL; ++z) {
          Chunk chunk = world.getChunkFromBlockCoords(x, z);
          int cX = x & 15, cZ = z & 15;
          for (int y = yS; y <= yL; ++y) {
            boolean v = meta == -1 || chunk.getBlockMetadata(cX, y, cZ) == meta;
            if (v && chunk.getBlock(cX, y, cZ) == block) {
              if (chunk.func_150807_a(cX, y, cZ, replBlock, replMeta)) {
                ++blockCounter;
                set.add(chunk);
              }
            }
          }
        }
      }
    }
    if (!set.isEmpty()) {
      CommandHandler.logAdminCommand(
          sender,
          this,
          "info.cofh.command.replaceblocks.success",
          blockCounter,
          xS,
          yS,
          zS,
          xL,
          yL,
          zL,
          blockReplRaw);
    } else {
      CommandHandler.logAdminCommand(sender, this, "info.cofh.command.replaceblocks.failure");
    }

    if (world instanceof WorldServer) {
      TObjectHashIterator<Chunk> c = set.iterator();
      for (int k = 0, e = set.size(); k < e; ++k) {
        Chunk chunk = c.next();
        PlayerManager manager = ((WorldServer) world).getPlayerManager();
        if (manager == null) {
          return;
        }
        PlayerInstance watcher =
            manager.getOrCreateChunkWatcher(chunk.xPosition, chunk.zPosition, false);
        if (watcher != null) {
          watcher.sendToAllPlayersWatchingChunk(new S21PacketChunkData(chunk, false, -1));
        }
      }
    }
  }
  public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) {
    int l = par2Random.nextInt(3) + this.minTreeHeight;
    boolean flag = true;

    if (par4 >= 1 && par4 + l + 1 <= 256) {
      int i1;
      byte b0;
      int j1;
      int k1;

      for (i1 = par4; i1 <= par4 + 1 + l; ++i1) {
        b0 = 1;

        if (i1 == par4) {
          b0 = 0;
        }

        if (i1 >= par4 + 1 + l - 2) {
          b0 = 2;
        }

        for (int l1 = par3 - b0; l1 <= par3 + b0 && flag; ++l1) {
          for (j1 = par5 - b0; j1 <= par5 + b0 && flag; ++j1) {
            if (i1 >= 0 && i1 < 256) {
              Block block = par1World.getBlock(l1, i1, j1);

              if (block != Blocks.air
                  && !block.isLeaves(par1World, l1, i1, j1)
                  && block != Blocks.grass
                  && block != Blocks.dirt
                  && !block.isWood(par1World, l1, i1, j1)) {
                flag = false;
              }
            } else {
              flag = false;
            }
          }
        }
      }

      if (!flag) {
        return false;
      } else {
        Block soil = par1World.getBlock(par3, par4 - 1, par5);
        boolean isSoil =
            (soil != null
                && soil.canSustainPlant(
                    par1World,
                    par3,
                    par4 - 1,
                    par5,
                    ForgeDirection.UP,
                    (BlockSapling) Blocks.sapling));

        if (isSoil && par4 < 256 - l - 1) {
          soil.onPlantGrow(par1World, par3, par4 - 1, par5, par3, par4, par5);
          b0 = 3;
          byte b1 = 0;
          int i2;
          int j2;
          int k2;

          for (j1 = par4 - b0 + l; j1 <= par4 + l; ++j1) {
            k1 = j1 - (par4 + l);
            i2 = b1 + 1 - k1 / 2;

            for (j2 = par3 - i2; j2 <= par3 + i2; ++j2) {
              k2 = j2 - par3;

              for (int l2 = par5 - i2; l2 <= par5 + i2; ++l2) {
                int i3 = l2 - par5;

                if (Math.abs(k2) != i2
                    || Math.abs(i3) != i2
                    || par2Random.nextInt(2) != 0 && k1 != 0) {

                  Block block = par1World.getBlock(j2, j1, l2);

                  if (block == null || block.canBeReplacedByLeaves(par1World, j2, j1, l2)) {
                    this.setBlockAndNotifyAdequately(par1World, j2, j1, l2, this.blockLeaves, 0);
                  }
                }
              }
            }
          }

          for (j1 = 0; j1 < l; ++j1) {
            Block block = par1World.getBlock(par3, par4 + j1, par5);

            // TODO- removed k1 = 0, right fix?
            if (block == Blocks.air || block.isLeaves(par1World, par3, par4 + j1, par5)) {
              this.setBlockAndNotifyAdequately(par1World, par3, par4 + j1, par5, this.blockWood, 0);

              if (this.vinesGrow && j1 > 0) {
                if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 - 1, par4 + j1, par5)) {
                  this.setBlockAndNotifyAdequately(
                      par1World, par3 - 1, par4 + j1, par5, Blocks.vine, 8);
                }

                if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 + 1, par4 + j1, par5)) {
                  this.setBlockAndNotifyAdequately(
                      par1World, par3 + 1, par4 + j1, par5, Blocks.vine, 2);
                }

                if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3, par4 + j1, par5 - 1)) {
                  this.setBlockAndNotifyAdequately(
                      par1World, par3, par4 + j1, par5 - 1, Blocks.vine, 1);
                }

                if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3, par4 + j1, par5 + 1)) {
                  this.setBlockAndNotifyAdequately(
                      par1World, par3, par4 + j1, par5 + 1, Blocks.vine, 4);
                }
              }
            }
          }

          if (this.vinesGrow) {
            for (j1 = par4 - 3 + l; j1 <= par4 + l; ++j1) {
              k1 = j1 - (par4 + l);
              i2 = 2 - k1 / 2;

              for (j2 = par3 - i2; j2 <= par3 + i2; ++j2) {
                for (k2 = par5 - i2; k2 <= par5 + i2; ++k2) {
                  Block block = par1World.getBlock(j2, j1, k2);
                  if (block != null && block.isLeaves(par1World, j2, j1, k2)) {
                    if (par2Random.nextInt(4) == 0
                        && par1World.getBlock(j2 - 1, j1, k2) == Blocks.air) {
                      this.growVines(par1World, j2 - 1, j1, k2, 8);
                    }

                    if (par2Random.nextInt(4) == 0
                        && par1World.getBlock(j2 + 1, j1, k2) == Blocks.air) {
                      this.growVines(par1World, j2 + 1, j1, k2, 2);
                    }

                    if (par2Random.nextInt(4) == 0
                        && par1World.getBlock(j2, j1, k2 - 1) == Blocks.air) {
                      this.growVines(par1World, j2, j1, k2 - 1, 1);
                    }

                    if (par2Random.nextInt(4) == 0
                        && par1World.getBlock(j2, j1, k2 + 1) == Blocks.air) {
                      this.growVines(par1World, j2, j1, k2 + 1, 4);
                    }
                  }
                }
              }
            }
          }

          return true;
        } else {
          return false;
        }
      }
    } else {
      return false;
    }
  }
  public boolean generate(World par1World, Random par2Random, int x, int y, int z) {
    int height = par2Random.nextInt(3) + this.minTreeHeight;
    boolean allClear = true;

    if (y >= 1 && y + height + 1 <= 256) {
      int cy;
      byte width;
      int cz;
      Block blockID;

      for (cy = y; cy <= y + 1 + height; ++cy) {
        width = 1;

        if (cy == y) {
          width = 0;
        }

        if (cy >= y + 1 + height - 2) {
          width = 2;
        }

        for (int cx = x - width; cx <= x + width && allClear; ++cx) {
          for (cz = z - width; cz <= z + width && allClear; ++cz) {
            if (cy >= 0 && cy < 256) {
              blockID = par1World.getBlock(cx, cy, cz);

              Block block = blockID;

              if (blockID != Blocks.air
                  && !block.isLeaves(par1World, cx, cy, cz)
                  && blockID != Blocks.grass
                  && blockID != Blocks.dirt
                  && !block.isWood(par1World, cx, cy, cz)) {
                allClear = false;
              }
            } else {
              allClear = false;
            }
          }
        }
      }

      if (!allClear) {
        return false;
      } else {
        Block blockUsing = par1World.getBlock(x, y - 1, z);

        if ((blockUsing == Blocks.grass || blockUsing == Blocks.dirt) && y < 256 - height - 1) {
          this.setBlock(par1World, x, y - 1, z, Blocks.dirt);
          width = 3;
          byte var18 = 0;
          int treeWidth;
          int tx;
          int var15;

          for (cz = y - width + height; cz <= y + height; ++cz) {
            int number = cz - (y + height);
            treeWidth = var18 + 1 - number / 2;

            for (tx = x - treeWidth; tx <= x + treeWidth; ++tx) {
              var15 = tx - x;

              for (int tz = z - treeWidth; tz <= z + treeWidth; ++tz) {
                int var17 = tz - z;

                Block block = par1World.getBlock(tx, cz, tz);

                if ((Math.abs(var15) != treeWidth
                        || Math.abs(var17) != treeWidth
                        || par2Random.nextInt(2) != 0 && number != 0)
                    && (block == null || block.canBeReplacedByLeaves(par1World, tx, cz, tz))) {
                  this.setBlockAndMetadata(par1World, tx, cz, tz, this.leafBlock, this.leafMeta);
                }
              }
            }
          }

          for (cz = 0; cz < height; ++cz) {
            blockID = par1World.getBlock(x, y + cz, z);

            Block block = blockID;

            if (blockID == Blocks.air || block == null || block.isLeaves(par1World, x, y + cz, z)) {
              this.setBlockAndMetadata(par1World, x, y + cz, z, this.treeBlock, this.treeMeta);
            }
          }

          return true;
        } else {
          return false;
        }
      }
    } else {
      return false;
    }
  }