@Command(
      aliases = {"/hpyramid"},
      usage = "<block> <range>",
      desc = "Generate a hollow pyramid",
      min = 2,
      max = 2)
  @CommandPermissions({"worldedit.generation.pyramid"})
  @Logging(PLACEMENT)
  public static void hpyramid(
      CommandContext args,
      WorldEdit we,
      LocalSession session,
      LocalPlayer player,
      EditSession editSession)
      throws WorldEditException {

    Pattern block = we.getBlockPattern(player, args.getString(0));
    int size = Math.max(1, args.getInteger(1));
    Vector pos = session.getPlacementPosition(player);

    int affected = editSession.makePyramid(pos, block, size, false);

    player.findFreePosition();
    player.print(affected + " block(s) have been created.");
  }
  @Command(
      aliases = {"/hsphere"},
      usage = "<block> <radius> [raised?] ",
      desc = "Generate a hollow sphere",
      min = 2,
      max = 3)
  @CommandPermissions({"worldedit.generation.sphere"})
  @Logging(PLACEMENT)
  public static void hsphere(
      CommandContext args,
      WorldEdit we,
      LocalSession session,
      LocalPlayer player,
      EditSession editSession)
      throws WorldEditException {

    Pattern block = we.getBlockPattern(player, args.getString(0));
    double radius = Math.max(1, args.getDouble(1));
    boolean raised =
        args.argsLength() > 2
            ? (args.getString(2).equalsIgnoreCase("true")
                || args.getString(2).equalsIgnoreCase("yes"))
            : false;

    Vector pos = session.getPlacementPosition(player);
    if (raised) {
      pos = pos.add(0, radius, 0);
    }

    int affected = editSession.makeSphere(pos, block, radius, false);
    player.findFreePosition();
    player.print(affected + " block(s) have been created.");
  }
  @Command(
      aliases = {"forestgen"},
      usage = "[size] [type] [density]",
      desc = "Generate a forest",
      min = 0,
      max = 3)
  @CommandPermissions({"worldedit.generation.forest"})
  @Logging(POSITION)
  public static void forestGen(
      CommandContext args,
      WorldEdit we,
      LocalSession session,
      LocalPlayer player,
      EditSession editSession)
      throws WorldEditException {

    int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 10;
    TreeGenerator.TreeType type =
        args.argsLength() > 1
            ? type = TreeGenerator.lookup(args.getString(1))
            : TreeGenerator.TreeType.TREE;
    double density = args.argsLength() > 2 ? args.getDouble(2) / 100 : 0.05;

    if (type == null) {
      player.printError("Tree type '" + args.getString(1) + "' is unknown.");
      return;
    } else {
    }

    int affected =
        editSession.makeForest(player.getPosition(), size, density, new TreeGenerator(type));
    player.print(affected + " trees created.");
  }
  @Command(
      aliases = {"/move"},
      usage = "[count] [direction] [leave-id]",
      flags = "s",
      desc = "Move the contents of the selection",
      min = 0,
      max = 3)
  @CommandPermissions("worldedit.region.move")
  @Logging(ORIENTATION_REGION)
  public static void move(
      CommandContext args,
      WorldEdit we,
      LocalSession session,
      LocalPlayer player,
      EditSession editSession)
      throws WorldEditException {

    int count = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1;
    Vector dir =
        we.getDirection(player, args.argsLength() > 1 ? args.getString(1).toLowerCase() : "me");
    BaseBlock replace;

    // Replacement block argument
    if (args.argsLength() > 2) {
      replace = we.getBlock(player, args.getString(2));
    } else {
      replace = new BaseBlock(BlockID.AIR);
    }

    int affected =
        editSession.moveCuboidRegion(
            session.getSelection(player.getWorld()), dir, count, true, replace);

    if (args.hasFlag('s')) {
      try {
        Region region = session.getSelection(player.getWorld());
        region.expand(dir.multiply(count));
        region.contract(dir.multiply(count));

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

    player.print(affected + " blocks moved.");
  }
  @Command(
      aliases = {"/stack"},
      usage = "[count] [direction]",
      flags = "sa",
      desc = "Repeat the contents of the selection",
      min = 0,
      max = 2)
  @CommandPermissions("worldedit.region.stack")
  @Logging(ORIENTATION_REGION)
  public static void stack(
      CommandContext args,
      WorldEdit we,
      LocalSession session,
      LocalPlayer player,
      EditSession editSession)
      throws WorldEditException {

    int count = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1;
    Vector dir =
        we.getDiagonalDirection(
            player, args.argsLength() > 1 ? args.getString(1).toLowerCase() : "me");

    int affected =
        editSession.stackCuboidRegion(
            session.getSelection(player.getWorld()), dir, count, !args.hasFlag('a'));

    if (args.hasFlag('s')) {
      try {
        Region region = session.getSelection(player.getWorld());
        region.expand(dir.multiply(count));
        region.contract(dir.multiply(count));

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

    player.print(affected + " blocks changed. Undo with //undo");
  }
  @Command(
      aliases = {"pumpkins"},
      usage = "[size]",
      desc = "Generate pumpkin patches",
      min = 0,
      max = 1)
  @CommandPermissions({"worldedit.generation.pumpkins"})
  @Logging(POSITION)
  public static void pumpkins(
      CommandContext args,
      WorldEdit we,
      LocalSession session,
      LocalPlayer player,
      EditSession editSession)
      throws WorldEditException {

    int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 10;

    int affected = editSession.makePumpkinPatches(player.getPosition(), size);
    player.print(affected + " pumpkin patches created.");
  }
  @Command(
      aliases = {"ceil"},
      usage = "[clearance]",
      desc = "Go to the celing",
      min = 0,
      max = 1)
  @CommandPermissions({"worldedit.navigation.ceiling"})
  @Logging(POSITION)
  public static void ceiling(
      CommandContext args,
      WorldEdit we,
      LocalSession session,
      LocalPlayer player,
      EditSession editSession)
      throws WorldEditException {

    int clearence = args.argsLength() > 0 ? Math.max(0, args.getInteger(0)) : 0;

    if (player.ascendToCeiling(clearence)) {
      player.print("Whoosh!");
    } else {
      player.printError("No free spot above you found.");
    }
  }
  @Command(
      aliases = {"/cyl"},
      usage = "<block> <radius> [height] ",
      desc = "Generate a cylinder",
      min = 2,
      max = 3)
  @CommandPermissions({"worldedit.generation.cylinder"})
  @Logging(PLACEMENT)
  public static void cyl(
      CommandContext args,
      WorldEdit we,
      LocalSession session,
      LocalPlayer player,
      EditSession editSession)
      throws WorldEditException {

    Pattern block = we.getBlockPattern(player, args.getString(0));
    double radius = Math.max(1, args.getDouble(1));
    int height = args.argsLength() > 2 ? args.getInteger(2) : 1;

    Vector pos = session.getPlacementPosition(player);
    int affected = editSession.makeCylinder(pos, block, radius, height);
    player.print(affected + " block(s) have been created.");
  }