@SubscribeEvent
    public void chopChop(TickEvent.WorldTickEvent event) {
      if (event.side.isClient()) {
        finish();
        return;
      }

      // setup
      int left = blocksPerTick;

      // continue running
      BlockPos pos;
      while (left > 0) {
        // completely done or can't do our job anymore?!
        if (blocks.isEmpty() || ToolHelper.isBroken(tool)) {
          finish();
          return;
        }

        pos = blocks.remove();
        if (!visited.add(pos)) {
          continue;
        }

        // can we harvest the block and is effective?
        if (!isLog(world, pos) || !ToolHelper.isToolEffective2(tool, world.getBlockState(pos))) {
          continue;
        }

        // save its neighbours
        for (EnumFacing facing :
            new EnumFacing[] {
              EnumFacing.NORTH, EnumFacing.EAST, EnumFacing.SOUTH, EnumFacing.WEST
            }) {
          BlockPos pos2 = pos.offset(facing);
          if (!visited.contains(pos2)) {
            blocks.add(pos2);
          }
        }

        // also add the layer above.. stupid acacia trees
        for (int x = 0; x < 3; x++) {
          for (int z = 0; z < 3; z++) {
            BlockPos pos2 = pos.add(-1 + x, 1, -1 + z);
            if (!visited.contains(pos2)) {
              blocks.add(pos2);
            }
          }
        }

        // break it, wooo!
        ToolHelper.breakExtraBlock(tool, world, player, pos, pos);
        left--;
      }
    }
  // grass paths
  @Override
  public EnumActionResult onItemUse(
      ItemStack stack,
      EntityPlayer player,
      World world,
      BlockPos pos,
      EnumHand hand,
      EnumFacing facing,
      float hitX,
      float hitY,
      float hitZ) {
    if (ToolHelper.isBroken(stack)) {
      return EnumActionResult.FAIL;
    }

    EnumActionResult result =
        Items.DIAMOND_SHOVEL.onItemUse(stack, player, world, pos, hand, facing, hitX, hitY, hitZ);

    // only do the AOE path if the selected block is grass or grass path
    Block block = world.getBlockState(pos).getBlock();
    if (block == Blocks.GRASS || block == Blocks.GRASS_PATH) {
      for (BlockPos aoePos : getAOEBlocks(stack, world, player, pos)) {
        // stop if the tool breaks during the process
        if (ToolHelper.isBroken(stack)) {
          break;
        }

        EnumActionResult aoeResult =
            Items.DIAMOND_SHOVEL.onItemUse(
                stack, player, world, aoePos, hand, facing, hitX, hitY, hitZ);
        // if we pass on an earlier block, check if another block succeeds here instead
        if (result != EnumActionResult.SUCCESS) {
          result = aoeResult;
        }
      }
    }

    return result;
  }