@Command(
      aliases = {"/smooth"},
      usage = "[iterations]",
      flags = "n",
      desc = "Smooth the elevation in the selection",
      help =
          "Smooths the elevation in the selection.\n"
              + "The -n flag makes it only consider naturally occuring blocks.",
      min = 0,
      max = 1)
  @CommandPermissions("worldedit.region.smooth")
  @Logging(REGION)
  public void smooth(
      Player player,
      EditSession editSession,
      @Selection Region region,
      @Optional("1") int iterations,
      @Switch('n') boolean affectNatural)
      throws WorldEditException {
    HeightMap heightMap = new HeightMap(editSession, region, affectNatural);
    HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
    int affected = heightMap.applyFilter(filter, iterations);

    BBC.VISITOR_BLOCK.send(player, affected);
  }
  @Command(
      aliases = {"/curve"},
      usage = "<block> [thickness]",
      desc = "Draws a spline through selected points",
      help =
          "Draws a spline through selected points.\n"
              + "Can only be used with convex polyhedral selections.\n"
              + "Flags:\n"
              + "  -h generates only a shell",
      flags = "h",
      min = 1,
      max = 2)
  @CommandPermissions("worldedit.region.curve")
  @Logging(REGION)
  public void curve(
      Player player,
      EditSession editSession,
      @Selection Region region,
      Pattern pattern,
      @Optional("0") @Range(min = 0) int thickness,
      @Switch('h') boolean shell)
      throws WorldEditException {
    if (!(region instanceof ConvexPolyhedralRegion)) {
      player.printError("//curve only works with convex polyhedral selections");
      return;
    }

    ConvexPolyhedralRegion cpregion = (ConvexPolyhedralRegion) region;
    List<Vector> vectors = new ArrayList<Vector>(cpregion.getVertices());

    int blocksChanged =
        editSession.drawSpline(Patterns.wrap(pattern), vectors, 0, 0, 0, 10, thickness, !shell);

    BBC.VISITOR_BLOCK.send(player, blocksChanged);
  }
  @Command(
      aliases = {"/line"},
      usage = "<block> [thickness]",
      desc = "Draws a line segment between cuboid selection corners",
      help =
          "Draws a line segment between cuboid selection corners.\n"
              + "Can only be used with cuboid selections.\n"
              + "Flags:\n"
              + "  -h generates only a shell",
      flags = "h",
      min = 1,
      max = 2)
  @CommandPermissions("worldedit.region.line")
  @Logging(REGION)
  public void line(
      Player player,
      EditSession editSession,
      @Selection Region region,
      Pattern pattern,
      @Optional("0") @Range(min = 0) int thickness,
      @Switch('h') boolean shell)
      throws WorldEditException {

    if (!(region instanceof CuboidRegion)) {
      player.printError("//line only works with cuboid selections");
      return;
    }

    CuboidRegion cuboidregion = (CuboidRegion) region;
    Vector pos1 = cuboidregion.getPos1();
    Vector pos2 = cuboidregion.getPos2();
    int blocksChanged = editSession.drawLine(Patterns.wrap(pattern), pos1, pos2, thickness, !shell);

    BBC.VISITOR_BLOCK.send(player, blocksChanged);
  }
  @Command(
      aliases = {"/deform"},
      usage = "<expression>",
      desc = "Deforms a selected region with an expression",
      help =
          "Deforms a selected region with an expression\n"
              + "The expression is executed for each block and is expected\n"
              + "to modify the variables x, y and z to point to a new block\n"
              + "to fetch. See also tinyurl.com/wesyntax.",
      flags = "ro",
      min = 1,
      max = -1)
  @CommandPermissions("worldedit.region.deform")
  @Logging(ALL)
  public void deform(
      Player player,
      LocalSession session,
      EditSession editSession,
      @Selection Region region,
      @Text String expression,
      @Switch('r') boolean useRawCoords,
      @Switch('o') boolean offset)
      throws WorldEditException {
    final Vector zero;
    Vector unit;

    if (useRawCoords) {
      zero = Vector.ZERO;
      unit = Vector.ONE;
    } else if (offset) {
      zero = session.getPlacementPosition(player);
      unit = Vector.ONE;
    } else {
      final Vector min = region.getMinimumPoint();
      final Vector max = region.getMaximumPoint();

      zero = max.add(min).multiply(0.5);
      unit = max.subtract(zero);

      if (unit.getX() == 0) unit = unit.setX(1.0);
      if (unit.getY() == 0) unit = unit.setY(1.0);
      if (unit.getZ() == 0) unit = unit.setZ(1.0);
    }

    try {
      final int affected = editSession.deformRegion(region, zero, unit, expression);
      player.findFreePosition();
      BBC.VISITOR_BLOCK.send(player, affected);
    } catch (ExpressionException e) {
      player.printError(e.getMessage());
    }
  }
 @Command(
     aliases = {"/naturalize"},
     usage = "",
     desc = "3 layers of dirt on top then rock below",
     min = 0,
     max = 0)
 @CommandPermissions("worldedit.region.naturalize")
 @Logging(REGION)
 public void naturalize(Player player, EditSession editSession, @Selection Region region)
     throws WorldEditException {
   int affected = editSession.naturalizeCuboidBlocks(region);
   BBC.VISITOR_BLOCK.send(player, affected);
 }
 @Command(
     aliases = {"/faces", "/outline"},
     usage = "<block>",
     desc = "Build the walls, ceiling, and floor of a selection",
     min = 1,
     max = 1)
 @CommandPermissions("worldedit.region.faces")
 @Logging(REGION)
 public void faces(
     Player player, EditSession editSession, @Selection Region region, Pattern pattern)
     throws WorldEditException {
   int affected = editSession.makeCuboidFaces(region, Patterns.wrap(pattern));
   BBC.VISITOR_BLOCK.send(player, affected);
 }
 @Command(
     aliases = {"/walls"},
     usage = "<block>",
     desc = "Build the four sides of the selection",
     min = 1,
     max = 1)
 @CommandPermissions("worldedit.region.walls")
 @Logging(REGION)
 public void walls(
     Player player, EditSession editSession, @Selection Region region, Pattern pattern)
     throws WorldEditException {
   int affected = editSession.makeCuboidWalls(region, Patterns.wrap(pattern));
   BBC.VISITOR_BLOCK.send(player, affected);
 }
 @Command(
     aliases = {"/center", "/middle"},
     usage = "<block>",
     desc = "Set the center block(s)",
     min = 1,
     max = 1)
 @Logging(REGION)
 @CommandPermissions("worldedit.region.center")
 public void center(
     Player player, EditSession editSession, @Selection Region region, Pattern pattern)
     throws WorldEditException {
   int affected = editSession.center(region, Patterns.wrap(pattern));
   BBC.VISITOR_BLOCK.send(player, affected);
 }
 @Command(
     aliases = {"/overlay"},
     usage = "<block>",
     desc = "Set a block on top of blocks in the region",
     min = 1,
     max = 1)
 @CommandPermissions("worldedit.region.overlay")
 @Logging(REGION)
 public void overlay(
     Player player, EditSession editSession, @Selection Region region, Pattern pattern)
     throws WorldEditException {
   int affected = editSession.overlayCuboidBlocks(region, Patterns.wrap(pattern));
   BBC.VISITOR_BLOCK.send(player, affected);
 }
  @Command(
      aliases = {"/stack"},
      usage = "[count] [direction]",
      flags = "sa",
      desc = "Repeat the contents of the selection",
      help =
          "Repeats the contents of the selection.\n"
              + "Flags:\n"
              + "  -s shifts the selection to the last stacked copy\n"
              + "  -a skips air blocks",
      min = 0,
      max = 2)
  @CommandPermissions("worldedit.region.stack")
  @Logging(ORIENTATION_REGION)
  public void stack(
      Player player,
      EditSession editSession,
      LocalSession session,
      @Selection Region region,
      @Optional("1") @Range(min = 1) int count,
      @Optional(Direction.AIM) @Direction Vector direction,
      @Switch('s') boolean moveSelection,
      @Switch('a') boolean ignoreAirBlocks)
      throws WorldEditException {
    int affected = editSession.stackCuboidRegion(region, direction, count, !ignoreAirBlocks);

    if (moveSelection) {
      try {
        final Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint());

        final Vector shiftVector = direction.multiply(count * (Math.abs(direction.dot(size)) + 1));
        region.shift(shiftVector);

        session.getRegionSelector(player.getWorld()).learnChanges();
        session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
      } catch (RegionOperationException e) {
        player.printError(e.getMessage());
      }
    }

    BBC.VISITOR_BLOCK.send(player, affected);
  }
  @Command(
      aliases = {"/move"},
      usage = "[count] [direction] [leave-id]",
      flags = "s",
      desc = "Move the contents of the selection",
      help =
          "Moves the contents of the selection.\n"
              + "The -s flag shifts the selection to the target location.\n"
              + "Optionally fills the old location with <leave-id>.",
      min = 0,
      max = 3)
  @CommandPermissions("worldedit.region.move")
  @Logging(ORIENTATION_REGION)
  public void move(
      Player player,
      EditSession editSession,
      LocalSession session,
      @Selection Region region,
      @Optional("1") @Range(min = 1) int count,
      @Optional(Direction.AIM) @Direction Vector direction,
      @Optional("air") BaseBlock replace,
      @Switch('s') boolean moveSelection)
      throws WorldEditException {

    int affected = editSession.moveRegion(region, direction, count, true, replace);

    if (moveSelection) {
      try {
        region.shift(direction.multiply(count));

        session.getRegionSelector(player.getWorld()).learnChanges();
        session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
      } catch (RegionOperationException e) {
        player.printError(e.getMessage());
      }
    }

    BBC.VISITOR_BLOCK.send(player, affected);
  }
 @Command(
     aliases = {"/mapreplace", "/mr", "/maprep"},
     usage = "<from-block-1,from-block-2> <to-block-1,to-block-2>",
     desc = "Replace all blocks in a selection 1:1 with the ",
     flags = "f",
     min = 1,
     max = 2)
 @CommandPermissions("worldedit.region.mapreplace")
 @Logging(REGION)
 public void mapreplace(
     Player player,
     EditSession editSession,
     @Selection Region region,
     @Optional Mask from,
     Pattern to)
     throws WorldEditException {
   if (from == null) {
     from = new ExistingBlockMask(editSession);
   }
   int affected = editSession.replaceBlocks(region, from, Patterns.wrap(to));
   BBC.VISITOR_BLOCK.send(player, affected);
 }
  @Command(
      aliases = {"/hollow"},
      usage = "[<thickness>[ <block>]]",
      desc = "Hollows out the object contained in this selection",
      help =
          "Hollows out the object contained in this selection.\n"
              + "Optionally fills the hollowed out part with the given block.\n"
              + "Thickness is measured in manhattan distance.",
      min = 0,
      max = 2)
  @CommandPermissions("worldedit.region.hollow")
  @Logging(REGION)
  public void hollow(
      Player player,
      EditSession editSession,
      @Selection Region region,
      @Optional("0") @Range(min = 0) int thickness,
      @Optional("air") Pattern pattern)
      throws WorldEditException {

    int affected = editSession.hollowOutRegion(region, thickness, Patterns.wrap(pattern));
    BBC.VISITOR_BLOCK.send(player, affected);
  }
  @Command(
      aliases = {"/fall"},
      usage = "[replace]",
      flags = "m",
      desc = "Have the blocks in the selection fall",
      help =
          "Make the blocks in the selection fall\n"
              + "The -m flag will only fall within the vertical selection.",
      min = 0,
      max = 2)
  @CommandPermissions("worldedit.region.fall")
  @Logging(ORIENTATION_REGION)
  public void fall(
      Player player,
      EditSession editSession,
      LocalSession session,
      @Selection Region region,
      @Optional("air") BaseBlock replace,
      @Switch('m') boolean notFullHeight)
      throws WorldEditException {

    int affected = editSession.fall(region, !notFullHeight, replace);
    BBC.VISITOR_BLOCK.send(player, affected);
  }
  @Command(
      aliases = {"/set"},
      usage = "[pattern]",
      desc = "Set all blocks within selection",
      min = 1,
      max = 1)
  @CommandPermissions("worldedit.region.set")
  @Logging(REGION)
  public void set(
      Player player,
      EditSession editSession,
      LocalSession session,
      @Selection Region selection,
      Pattern to)
      throws WorldEditException {
    if (selection instanceof CuboidRegion
        && editSession.hasFastMode()
        && to instanceof BlockPattern) {
      try {
        CuboidRegion cuboid = (CuboidRegion) selection;
        RegionWrapper current =
            new RegionWrapper(cuboid.getMinimumPoint(), cuboid.getMaximumPoint());
        BaseBlock block = ((BlockPattern) to).getBlock();
        final FaweQueue queue = editSession.getQueue();
        final int minY = cuboid.getMinimumY();
        final int maxY = cuboid.getMaximumY();

        final int id = block.getId();
        final byte data = (byte) block.getData();
        final FaweChunk<?> fc = queue.getFaweChunk(0, 0);
        fc.fillCuboid(0, 15, minY, maxY, 0, 15, id, data);
        fc.optimize();

        int bcx = (current.minX) >> 4;
        int bcz = (current.minZ) >> 4;

        int tcx = (current.maxX) >> 4;
        int tcz = (current.maxZ) >> 4;
        // [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge]
        MainUtil.chunkTaskSync(
            current,
            new RunnableVal<int[]>() {
              @Override
              public void run(int[] value) {
                FaweChunk newChunk;
                if (value[6] == 0) {
                  newChunk = fc.copy(true);
                  newChunk.setLoc(queue, value[0], value[1]);
                } else {
                  int bx = value[2] & 15;
                  int tx = value[4] & 15;
                  int bz = value[3] & 15;
                  int tz = value[5] & 15;
                  if (bx == 0 && tx == 15 && bz == 0 && tz == 15) {
                    newChunk = fc.copy(true);
                    newChunk.setLoc(queue, value[0], value[1]);
                  } else {
                    newChunk = queue.getFaweChunk(value[0], value[1]);
                    newChunk.fillCuboid(
                        value[2] & 15,
                        value[4] & 15,
                        minY,
                        maxY,
                        value[3] & 15,
                        value[5] & 15,
                        id,
                        data);
                  }
                }
                newChunk.addToQueue();
              }
            });
        queue.enqueue();
        long start = System.currentTimeMillis();
        BBC.OPERATION.send(player, BBC.VISITOR_BLOCK.format(cuboid.getArea()));
        queue.flush();
        BBC.ACTION_COMPLETE.send(player, (System.currentTimeMillis() - start) / 1000d);
        return;
      } catch (Throwable e) {
        MainUtil.handleError(e);
      }
    }
    int affected = editSession.setBlocks(selection, Patterns.wrap(to));
    BBC.OPERATION.send(player, affected);
  }