Java Code Examples for com.sk89q.worldedit.function.operation.Operations#completeBlindly()

The following examples show how to use com.sk89q.worldedit.function.operation.Operations#completeBlindly() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Sets all the blocks inside a region to a given pattern.
 *
 * @param region  the region
 * @param pattern the pattern that provides the replacement block
 * @return number of blocks affected
 * @throws MaxChangedBlocksException thrown if too many blocks are changed
 */
@SuppressWarnings("deprecation")
public int setBlocks(final Region region, final Pattern pattern) {
    checkNotNull(region);
    checkNotNull(pattern);
    if (pattern instanceof BlockPattern) {
        return setBlocks(region, ((BlockPattern) pattern).getBlock());
    }
    if (pattern instanceof BaseBlock) {
        return setBlocks(region, (BaseBlock) pattern);
    }
    final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
    final RegionVisitor visitor = new RegionVisitor(region, replace, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
    Operations.completeBlindly(visitor);
    return this.changes = visitor.getAffected();
}
 
Example 2
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Stack a cuboid region.
 *
 * @param region  the region to stack
 * @param dir     the direction to stack
 * @param count   the number of times to stack
 * @param copyAir true to also copy air blocks
 * @return number of blocks affected
 * @throws MaxChangedBlocksException thrown if too many blocks are changed
 */
public int stackCuboidRegion(final Region region, final Vector dir, final int count, final boolean copyAir, boolean copyEntities, boolean copyBiomes) {
    checkNotNull(region);
    checkNotNull(dir);
    checkArgument(count >= 1, "count >= 1 required");
    final Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
    final Vector to = region.getMinimumPoint();
    final ForwardExtentCopy copy = new ForwardExtentCopy(EditSession.this, region, EditSession.this, to);
    copy.setCopyEntities(copyEntities);
    copy.setCopyBiomes(copyBiomes);
    copy.setRepetitions(count);
    copy.setTransform(new AffineTransform().translate(dir.multiply(size)));
    Mask sourceMask = getSourceMask();
    if (sourceMask != null) {
        new MaskTraverser(sourceMask).reset(EditSession.this);
        copy.setSourceMask(sourceMask);
        setSourceMask(null);
    }
    if (!copyAir) {
        copy.setSourceMask(new ExistingBlockMask(EditSession.this));
    }
    Operations.completeBlindly(copy);
    return this.changes = copy.getAffected();
}
 
Example 3
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Fills an area recursively in the X/Z directions.
 *
 * @param origin    the location to start from
 * @param pattern     the block to fill with
 * @param radius    the radius of the spherical area to fill
 * @param depth     the maximum depth, starting from the origin
 * @param direction the direction to fill
 * @return number of blocks affected
 * @throws MaxChangedBlocksException thrown if too many blocks are changed
 */
public int fillDirection(final Vector origin, final Pattern pattern, final double radius, final int depth, Vector direction) {
    checkNotNull(origin);
    checkNotNull(pattern);
    checkArgument(radius >= 0, "radius >= 0");
    checkArgument(depth >= 1, "depth >= 1");
    if (direction.equals(new Vector(0, -1, 0))) {
        return fillXZ(origin, pattern, radius, depth, false);
    }
    final MaskIntersection mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))), Masks.negate(new ExistingBlockMask(EditSession.this)));

    // Want to replace blocks
    final BlockReplace replace = new BlockReplace(EditSession.this, pattern);

    // Pick how we're going to visit blocks
    RecursiveVisitor visitor = new DirectionalVisitor(mask, replace, origin, direction, (int) (radius * 2 + 1), this);

    // Start at the origin
    visitor.visit(origin);

    // Execute
    Operations.completeBlindly(visitor);
    return this.changes = visitor.getAffected();
}
 
Example 4
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
public void setBlocks(ChangeSet changeSet, ChangeSetExecutor.Type type) {
    final UndoContext context = new UndoContext();
    Extent bypass = (history == null) ? bypassAll : history;
    context.setExtent(bypass);
    Operations.completeBlindly(ChangeSetExecutor.create(changeSet, context, type, getBlockBag(), getLimit().INVENTORY_MODE));
    flushQueue();
    changes = 1;
}
 
Example 5
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Fills an area recursively in the X/Z directions.
 *
 * @param origin    the origin to start the fill from
 * @param pattern   the pattern to fill with
 * @param radius    the radius of the spherical area to fill, with 0 as the smallest radius
 * @param depth     the maximum depth, starting from the origin, with 1 as the smallest depth
 * @param recursive whether a breadth-first search should be performed
 * @return number of blocks affected
 * @throws MaxChangedBlocksException thrown if too many blocks are changed
 */
@SuppressWarnings("deprecation")
public int fillXZ(final Vector origin, final Pattern pattern, final double radius, final int depth, final boolean recursive) {
    checkNotNull(origin);
    checkNotNull(pattern);
    checkArgument(radius >= 0, "radius >= 0");
    checkArgument(depth >= 1, "depth >= 1");
    final MaskIntersection mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))), new BoundedHeightMask(Math.max(
            (origin.getBlockY() - depth) + 1, getMinimumPoint().getBlockY()), Math.min(getMaximumPoint().getBlockY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this)));

    // Want to replace blocks
    final BlockReplace replace = new BlockReplace(EditSession.this, pattern);

    // Pick how we're going to visit blocks
    RecursiveVisitor visitor;
    if (recursive) {
        visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1), this);
    } else {
        visitor = new DownwardVisitor(mask, replace, origin.getBlockY(), (int) (radius * 2 + 1), this);
    }

    // Start at the origin
    visitor.visit(origin);

    // Execute
    Operations.completeBlindly(visitor);
    return this.changes = visitor.getAffected();
}
 
Example 6
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
public int fall(final Region region, boolean fullHeight, final BaseBlock replace) {
    FlatRegion flat = asFlatRegion(region);
    final int startPerformY = region.getMinimumPoint().getBlockY();
    final int startCheckY = fullHeight ? 0 : startPerformY;
    final int endY = region.getMaximumPoint().getBlockY();
    RegionVisitor visitor = new RegionVisitor(flat, new RegionFunction() {
        @Override
        public boolean apply(Vector pos) throws WorldEditException {
            int x = pos.getBlockX();
            int z = pos.getBlockZ();
            int freeSpot = startCheckY;
            for (int y = startCheckY; y <= endY; y++) {
                if (y < startPerformY) {
                    if (getLazyBlock(x, y, z).getId() != 0) {
                        freeSpot = y + 1;
                    }
                    continue;
                }
                BaseBlock block = getLazyBlock(x, y, z);
                if (block.getId() != 0) {
                    if (freeSpot != y) {
                        setBlock(x, freeSpot, z, block);
                        setBlock(x, y, z, replace);
                    }
                    freeSpot++;
                }
            }
            return true;
        }
    }, this);
    Operations.completeBlindly(visitor);
    return this.changes;
}
 
Example 7
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Count the number of blocks of a list of types in a region.
 *
 * @param region       the region
 * @param searchBlocks the list of blocks to search
 * @return the number of blocks that matched the pattern
 */
public int countBlocks(final Region region, final Set<BaseBlock> searchBlocks) {
    final BlockMask mask = new BlockMask(extent, searchBlocks);
    RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
        @Override
        public boolean apply(Vector position) throws WorldEditException {
            return mask.test(position);
        }
    }, this);
    Operations.completeBlindly(visitor);
    return visitor.getAffected();
}
 
Example 8
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
public int countBlock(final Region region, final boolean[] ids) {
    RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
        @Override
        public boolean apply(Vector position) throws WorldEditException {
            return ids[getBlockType(position)];
        }
    }, this);
    Operations.completeBlindly(visitor);
    return visitor.getAffected();
}
 
Example 9
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Finish off the queue.
 */
public void flushQueue() {
    Operations.completeBlindly(commit());
    // Check fails
    FaweLimit used = getLimitUsed();
    if (used.MAX_FAILS > 0) {
        if (used.MAX_CHANGES > 0 || used.MAX_ENTITIES > 0) {
            BBC.WORLDEDIT_SOME_FAILS.send(player, used.MAX_FAILS);
        } else if (new ExtentTraverser(this).findAndGet(FaweRegionExtent.class) != null){
            BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION.send(player);
        } else {
            BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_LEVEL.send(player);
        }
    }
    // Reset limit
    limit.set(originalLimit);
    // Enqueue it
    if (queue == null || queue.isEmpty()) {
        queue.dequeue();
        return;
    }
    if (Fawe.isMainThread() && (!(queue instanceof MCAQueue) || ((MCAQueue) queue).hasParent())) {
        SetQueue.IMP.flush(queue);
    } else {
        queue.flush();
    }
    if (getChangeSet() != null) {
        if (Settings.IMP.HISTORY.COMBINE_STAGES) {
            ((FaweChangeSet) getChangeSet()).closeAsync();
        } else {
            ((FaweChangeSet) getChangeSet()).close();
        }
    }
}
 
Example 10
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Sets to new state.
 *
 * @param editSession a new {@link EditSession} to perform the redo in
 */
public void redo(final EditSession editSession) {
    final UndoContext context = new UndoContext();
    context.setExtent(editSession.bypassAll);
    ChangeSet changeSet = getChangeSet();
    editSession.getQueue().setChangeTask(null);
    Operations.completeBlindly(ChangeSetExecutor.create(changeSet, context, ChangeSetExecutor.Type.REDO, editSession.getBlockBag(), editSession.getLimit().INVENTORY_MODE));
    flushQueue();
    editSession.changes = 1;
}
 
Example 11
Source File: WorldEditHandler.java    From uSkyBlock with GNU General Public License v3.0 5 votes vote down vote up
public static void loadIslandSchematic(final File file, final Location origin, PlayerPerk playerPerk) {
    log.finer("Trying to load schematic " + file);
    if (file == null || !file.exists() || !file.canRead()) {
        LogUtil.log(Level.WARNING, "Unable to load schematic " + file);
    }
    boolean noAir = false;
    BlockVector3 to = BlockVector3.at(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ());
    EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(origin.getWorld()), -1);
    editSession.setFastMode(true);
    ProtectedRegion region = WorldGuardHandler.getIslandRegionAt(origin);
    if (region != null) {
        editSession.setMask(new RegionMask(getRegion(origin.getWorld(), region)));
    }
    try {
        ClipboardFormat clipboardFormat = ClipboardFormats.findByFile(file);
        try (InputStream in = new FileInputStream(file)) {
            Clipboard clipboard = clipboardFormat.getReader(in).read();
            Operation operation = new ClipboardHolder(clipboard)
                    .createPaste(editSession)
                    .to(to)
                    .ignoreAirBlocks(noAir)
                    .build();
            Operations.completeBlindly(operation);
        }
        editSession.flushSession();
    } catch (IOException e) {
        log.log(Level.INFO, "Unable to paste schematic " + file, e);
    }
}
 
Example 12
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Restores all blocks to their initial state.
 *
 * @param editSession a new {@link EditSession} to perform the undo in
 */
public void undo(final EditSession editSession) {
    final UndoContext context = new UndoContext();
    context.setExtent(editSession.bypassAll);
    ChangeSet changeSet = getChangeSet();
    editSession.getQueue().setChangeTask(null);
    Operations.completeBlindly(ChangeSetExecutor.create(changeSet, context, ChangeSetExecutor.Type.UNDO, editSession.getBlockBag(), editSession.getLimit().INVENTORY_MODE));
    flushQueue();
    editSession.changes = 1;
}
 
Example 13
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
@SuppressWarnings("deprecation")
public int setBlocks(final Set<Vector> vset, final Pattern pattern) {
    RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(extent, pattern), this);
    Operations.completeBlindly(visitor);
    changes += visitor.getAffected();
    return changes;
}
 
Example 14
Source File: RecursivePickaxe.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
    World world = (World) clicked.getExtent();
    final Vector pos = clicked.toVector();

    EditSession editSession = session.createEditSession(player);

    BaseBlock block = editSession.getBlock(pos);
    int initialType = block.getType();

    if (initialType == BlockID.AIR || (initialType == BlockID.BEDROCK && !player.canDestroyBedrock())) {
        editSession.flushQueue();
        return true;
    }

    editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);

    final int radius = (int) range;
    final BlockReplace replace = new BlockReplace(editSession, (editSession.nullBlock));
    editSession.setMask((Mask) null);
    RecursiveVisitor visitor = new RecursiveVisitor(new IdMask(editSession), replace, radius, editSession);
    visitor.visit(pos);
    Operations.completeBlindly(visitor);

    editSession.flushQueue();
    session.remember(editSession);

    return true;
}
 
Example 15
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
public int deformRegion(final Region region, final Vector zero, final Vector unit, final String expressionString) throws ExpressionException, MaxChangedBlocksException {
    final Expression expression = Expression.compile(expressionString, "x", "y", "z");
    expression.optimize();
    final RValue x = expression.getVariable("x", false).optimize();
    final RValue y = expression.getVariable("y", false).optimize();
    final RValue z = expression.getVariable("z", false).optimize();
    final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(this, unit, zero);
    expression.setEnvironment(environment);
    final Vector zero2 = zero.add(0.5, 0.5, 0.5);

    RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {

        private MutableBlockVector mutable = new MutableBlockVector();

        @Override
        public boolean apply(Vector position) throws WorldEditException {
            try {
                // offset, scale
                double sx = (position.getX() - zero.getX()) / unit.getX();
                double sy = (position.getY() - zero.getY()) / unit.getY();
                double sz = (position.getZ() - zero.getZ()) / unit.getZ();
                // transform
                expression.evaluate(sx, sy, sz);
                int xv = (int) (x.getValue() * unit.getX() + zero2.getX());
                int yv = (int) (y.getValue() * unit.getY() + zero2.getY());
                int zv = (int) (z.getValue() * unit.getZ() + zero2.getZ());
                // read block from world
                BaseBlock material = FaweCache.CACHE_BLOCK[queue.getCombinedId4DataDebug(xv, yv, zv, 0, EditSession.this)];
                // queue operation
                return setBlockFast(position, material);
            } catch (EvaluationException e) {
                throw new RuntimeException(e);
            }
        }
    }, this);
    Operations.completeBlindly(visitor);
    changes += visitor.getAffected();
    return changes;
}
 
Example 16
Source File: EditSession.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Replaces all the blocks matching a given mask, within a given region, to a block
 * returned by a given pattern.
 *
 * @param region  the region to replace the blocks within
 * @param mask    the mask that blocks must match
 * @param pattern the pattern that provides the new blocks
 * @return number of blocks affected
 * @throws MaxChangedBlocksException thrown if too many blocks are changed
 */
@SuppressWarnings("deprecation")
public int replaceBlocks(final Region region, final Mask mask, final Pattern pattern) {
    checkNotNull(region);
    checkNotNull(mask);
    checkNotNull(pattern);
    final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
    final RegionMaskingFilter filter = new RegionMaskingFilter(mask, replace);
    final RegionVisitor visitor = new RegionVisitor(region, filter, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
    Operations.completeBlindly(visitor);
    return this.changes = visitor.getAffected();
}
 
Example 17
Source File: FuzzyRegion.java    From FastAsyncWorldedit with GNU General Public License v3.0 5 votes vote down vote up
public void select(int x, int y, int z) {
    RecursiveVisitor search = new RecursiveVisitor(mask, new RegionFunction() {
        @Override
        public boolean apply(Vector p) throws WorldEditException {
            setMinMax(p.getBlockX(), p.getBlockY(), p.getBlockZ());
            return true;
        }
    }, 256, extent instanceof HasFaweQueue ? (HasFaweQueue) extent : null);
    search.setVisited(set);
    search.visit(new Vector(x, y, z));
    Operations.completeBlindly(search);
}
 
Example 18
Source File: StencilBrush.java    From FastAsyncWorldedit with GNU General Public License v3.0 4 votes vote down vote up
@Override
public void build(EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
    final int cx = position.getBlockX();
    final int cy = position.getBlockY();
    final int cz = position.getBlockZ();
    int size = (int) sizeDouble;
    int size2 = (int) (sizeDouble * sizeDouble);
    int maxY = editSession.getMaxY();
    int add;
    if (yscale < 0) {
        add = maxY;
    } else {
        add = 0;
    }
    double scale = (yscale / sizeDouble) * (maxY + 1);
    final HeightMap map = getHeightMap();
    map.setSize(size);
    int cutoff = onlyWhite ? maxY : 0;
    final SolidBlockMask solid = new SolidBlockMask(editSession);
    final AdjacentAnyMask adjacent = new AdjacentAnyMask(Masks.negate(solid));


    Player player = editSession.getPlayer().getPlayer();
    Vector pos = player.getPosition();



    Location loc = editSession.getPlayer().getPlayer().getLocation();
    float yaw = loc.getYaw();
    float pitch = loc.getPitch();
    AffineTransform transform = new AffineTransform().rotateY((-yaw) % 360).rotateX(pitch - 90).inverse();


    RecursiveVisitor visitor = new RecursiveVisitor(new Mask() {
        private final MutableBlockVector mutable = new MutableBlockVector();
        @Override
        public boolean test(Vector vector) {
            if (solid.test(vector)) {
                int dx = vector.getBlockX() - cx;
                int dy = vector.getBlockY() - cy;
                int dz = vector.getBlockZ() - cz;

                Vector srcPos = transform.apply(mutable.setComponents(dx, dy, dz));
                dx = srcPos.getBlockX();
                dz = srcPos.getBlockZ();

                int distance = dx * dx + dz * dz;
                if (distance > size2 || Math.abs(dx) > 256 || Math.abs(dz) > 256) return false;

                double raise = map.getHeight(dx, dz);
                int val = (int) Math.ceil(raise * scale) + add;
                if (val < cutoff) {
                    return true;
                }
                if (val >= 255 || PseudoRandom.random.random(maxY) < val) {
                    editSession.setBlock(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), pattern);
                }
                return true;
            }
            return false;
        }
    }, vector -> true, Integer.MAX_VALUE, editSession);
    visitor.setDirections(Arrays.asList(visitor.DIAGONAL_DIRECTIONS));
    visitor.visit(position);
    Operations.completeBlindly(visitor);
}
 
Example 19
Source File: LayerBrush.java    From FastAsyncWorldedit with GNU General Public License v3.0 4 votes vote down vote up
@Override
public void build(EditSession editSession, Vector position, Pattern ignore, double size) throws MaxChangedBlocksException {
    final FaweQueue queue = editSession.getQueue();
    final AdjacentAnyMask adjacent = new AdjacentAnyMask(new BlockMask(editSession, new BaseBlock(0)));
    final SolidBlockMask solid = new SolidBlockMask(editSession);
    final RadiusMask radius = new RadiusMask(0, (int) size);
    visitor = new RecursiveVisitor(vector -> solid.test(vector) && radius.test(vector) && adjacent.test(vector), function -> true);
    visitor.visit(position);
    visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
    Operations.completeBlindly(visitor);
    BlockVectorSet visited = visitor.getVisited();
    BaseBlock firstPattern = layers[0];
    visitor = new RecursiveVisitor((Mask) pos -> {
        int depth = visitor.getDepth() + 1;
        if (depth > 1) {
            boolean found = false;
            int previous = layers[depth - 1].getCombined();
            int previous2 = layers[depth - 2].getCombined();
            for (Vector dir : BreadthFirstSearch.DEFAULT_DIRECTIONS) {
                mutable.setComponents(pos.getBlockX() + dir.getBlockX(), pos.getBlockY() + dir.getBlockY(), pos.getBlockZ() + dir.getBlockZ());
                if (visitor.isVisited(mutable) && queue.getCachedCombinedId4Data(mutable.getBlockX(), mutable.getBlockY(), mutable.getBlockZ()) == previous) {
                    mutable.setComponents(pos.getBlockX() + dir.getBlockX() * 2, pos.getBlockY() + dir.getBlockY() * 2, pos.getBlockZ() + dir.getBlockZ() * 2);
                    if (visitor.isVisited(mutable) && queue.getCachedCombinedId4Data(mutable.getBlockX(), mutable.getBlockY(), mutable.getBlockZ()) == previous2) {
                        found = true;
                        break;
                    } else {
                        return false;
                    }
                }
            }
            if (!found) {
                return false;
            }
        }
        return !adjacent.test(pos);
    }, pos -> {
        int depth = visitor.getDepth();
        BaseBlock currentPattern = layers[depth];
        return editSession.setBlockFast(pos, currentPattern);
    }, layers.length - 1, editSession);
    for (Vector pos : visited) {
        visitor.visit(pos);
    }
    Operations.completeBlindly(visitor);
    visitor = null;
}
 
Example 20
Source File: CopyPastaBrush.java    From FastAsyncWorldedit with GNU General Public License v3.0 4 votes vote down vote up
@Override
public void build(final EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
    FawePlayer fp = editSession.getPlayer();
    ClipboardHolder clipboard = session.getExistingClipboard();
    if (clipboard == null) {
        if (editSession.getExtent() instanceof VisualExtent) {
            return;
        }
        Mask mask = editSession.getMask();
        if (mask == null) {
            mask = Masks.alwaysTrue();
        }
        final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld());
        final int size2 = (int) (size * size);
        final int minY = position.getBlockY();
        mask = new AbstractDelegateMask(mask) {
            @Override
            public boolean test(Vector vector) {
                if (super.test(vector) && vector.getBlockY() >= minY) {
                    BaseBlock block = editSession.getLazyBlock(vector);
                    if (block.getId() != 0) {
                        builder.add(vector, EditSession.nullBlock, block);
                        return true;
                    }
                }
                return false;
            }
        };
        // Add origin
        mask.test(position);
        RecursiveVisitor visitor = new RecursiveVisitor(mask, new NullRegionFunction(), (int) size, editSession);
        visitor.visit(position);
        Operations.completeBlindly(visitor);
        // Build the clipboard
        Clipboard newClipboard = builder.build();
        newClipboard.setOrigin(position);
        ClipboardHolder holder = new ClipboardHolder(newClipboard, editSession.getWorld().getWorldData());
        session.setClipboard(holder);
        int blocks = builder.size();
        BBC.COMMAND_COPY.send(fp, blocks);
        return;
    } else {
        AffineTransform transform = null;
        if (randomRotate) {
            if (transform == null) transform = new AffineTransform();
            int rotate = 90 * PseudoRandom.random.nextInt(4);
            transform = transform.rotateY(rotate);
        }
        if (autoRotate) {
            if (transform == null) transform = new AffineTransform();
            Location loc = editSession.getPlayer().getPlayer().getLocation();
            float yaw = loc.getYaw();
            float pitch = loc.getPitch();
            transform = transform.rotateY((-yaw) % 360);
            transform = transform.rotateX(pitch - 90);
        }
        if (transform != null && !transform.isIdentity()) {
            clipboard.setTransform(transform);
        }
        Clipboard faweClip = clipboard.getClipboard();
        Region region = faweClip.getRegion();

        Operation operation = clipboard
                .createPaste(editSession, editSession.getWorldData())
                .to(position.add(0, 1, 0))
                .ignoreAirBlocks(true)
                .build();
        Operations.completeLegacy(operation);
        editSession.flushQueue();
    }
}