diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index c24c4cb1de..3469a765f0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -33,6 +33,7 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.InputExtent; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.block.BlockReplace; @@ -50,6 +51,7 @@ import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.util.TransformUtil; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.convolution.GaussianKernel; import com.sk89q.worldedit.math.convolution.HeightMap; import com.sk89q.worldedit.math.convolution.HeightMapFilter; @@ -499,13 +501,28 @@ public int deform(Actor actor, LocalSession session, EditSession editSession, @Switch(name = 'o', desc = "Use the placement's coordinate origin") boolean offsetPlacement, @Switch(name = 'c', desc = "Use the selection's center as origin") - boolean offsetCenter) throws WorldEditException { + boolean offsetCenter, + @Switch(name = 'l', desc = "Fetch from the clipboard instead of the world") + boolean useClipboard) throws WorldEditException { + final Transform targetTransform = TransformUtil.createTransformForExpressionCommand(actor, session, region, useRawCoords, offsetPlacement, offsetCenter); - final Transform transform = TransformUtil.createTransformForExpressionCommand(actor, session, region, useRawCoords, offsetPlacement, offsetCenter); - final InputExtent inputExtent = editSession.getWorld(); + final InputExtent sourceExtent; + final Transform sourceTransform; + if (useClipboard) { + final Clipboard clipboard = session.getClipboard().getClipboard(); + sourceExtent = clipboard; + + final Vector3 clipboardMin = clipboard.getMinimumPoint().toVector3(); + final Vector3 clipboardMax = clipboard.getMaximumPoint().toVector3(); + + sourceTransform = TransformUtil.createTransformForExpressionCommand(useRawCoords, offsetPlacement, offsetCenter, clipboardMin, clipboardMax, clipboardMin); + } else { + sourceExtent = editSession.getWorld(); + sourceTransform = targetTransform; + } try { - final int affected = editSession.deformRegion(region, transform, String.join(" ", expression), session.getTimeout(), inputExtent, transform); + final int affected = editSession.deformRegion(region, targetTransform, String.join(" ", expression), session.getTimeout(), sourceExtent, sourceTransform); if (actor instanceof Player) { ((Player) actor).findFreePosition(); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/TransformUtil.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/TransformUtil.java index 5093efd144..0a11e41c27 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/TransformUtil.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/TransformUtil.java @@ -48,18 +48,33 @@ private TransformUtil() { * @return A transform from the expression coordinate system to the raw coordinate system */ public static Transform createTransformForExpressionCommand(Actor actor, LocalSession session, Region region, boolean useRawCoords, boolean offsetPlacement, boolean offsetCenter) throws IncompleteRegionException { + final Vector3 placement = session.getPlacementPosition(actor).toVector3(); + final Vector3 min = region.getMinimumPoint().toVector3(); + final Vector3 max = region.getMaximumPoint().toVector3(); + + return createTransformForExpressionCommand(useRawCoords, offsetPlacement, offsetCenter, min, max, placement); + } + + /** + * Creates a {@link Transform} for the //deform command with clipboard support. + * + * @param useRawCoords Use the game's coordinate origin + * @param offsetPlacement Use the placement's coordinate origin + * @param offsetCenter Use the selection's center as origin + * @param min Minimum of the selection/clipboard + * @param max Maximum of the selection/clipboard + * @param placement Placement position + * @return A transform from the expression coordinate system to the world/clipboard coordinate system + */ + public static Transform createTransformForExpressionCommand(boolean useRawCoords, boolean offsetPlacement, boolean offsetCenter, Vector3 min, Vector3 max, Vector3 placement) { if (useRawCoords) { return new Identity(); } if (offsetPlacement) { - final Vector3 placement = session.getPlacementPosition(actor).toVector3(); - return new SimpleTransform(placement, Vector3.ONE); } - final Vector3 min = region.getMinimumPoint().toVector3(); - final Vector3 max = region.getMaximumPoint().toVector3(); final Vector3 center = max.add(min).multiply(0.5); if (offsetCenter) {