diff --git a/src/EditSession.java b/src/EditSession.java index 635249c11..a00d431b5 100644 --- a/src/EditSession.java +++ b/src/EditSession.java @@ -23,6 +23,7 @@ import com.sk89q.worldedit.blocks.SignBlock; import com.sk89q.worldedit.blocks.BaseBlock; import java.util.Map; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Set; import java.util.HashSet; import java.util.Stack; @@ -723,6 +724,65 @@ public class EditSession { return affected; } + /** + * Move a cuboid region. + * + * @param region + * @param dir + * @param distance + * @param copyAir + * @param replace + * @return number of blocks moved + * @throws MaxChangedBlocksException + */ + public int moveCuboidRegion(Region region, Vector dir, + int distance, boolean copyAir, BaseBlock replace) + throws MaxChangedBlocksException { + int affected = 0; + + Vector shift = dir.multiply(distance); + Vector min = region.getMinimumPoint(); + Vector max = region.getMaximumPoint(); + Vector newMin = min.add(shift); + Vector newMax = min.add(shift); + int xs = region.getWidth(); + int ys = region.getHeight(); + int zs = region.getLength(); + + Map delayed = new LinkedHashMap(); + + for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { + for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { + for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { + Vector pos = new Vector(x, y, z); + BaseBlock block = getBlock(pos); + + if (!block.isAir() || copyAir) { + Vector newPos = pos.add(shift); + + delayed.put(newPos, getBlock(pos)); + + // Don't want to replace the old block if it's in + // the new area + if (x >= newMin.getBlockX() && x <= newMax.getBlockX() + && y >= newMin.getBlockY() && y <= newMax.getBlockY() + && z >= newMin.getBlockZ() && z <= newMax.getBlockZ()) { + } else { + setBlock(pos, replace); + } + } + } + } + } + + for (Map.Entry entry : delayed.entrySet()) { + setBlock(entry.getKey(), entry.getValue()); + affected++; + } + + return affected; + } + /** * Drain nearby pools of water or lava. * diff --git a/src/WorldEdit.java b/src/WorldEdit.java index df03771cf..45cb0a786 100644 --- a/src/WorldEdit.java +++ b/src/WorldEdit.java @@ -132,6 +132,8 @@ public class WorldEdit { commands.put("//cut", "Cuts the currently selected region"); commands.put("//paste", "Pastes the clipboard"); commands.put("//pasteair", "Pastes the clipboard (with air)"); + commands.put("//move", "[Count> [Dir] [LeaveID] - Move the selection"); + commands.put("//moveair", "[Count> [Dir] [LeaveID] - Move the selection (with air)"); commands.put("//stack", " - Stacks the selection"); commands.put("//stackair", " - Stacks the selection (with air)"); commands.put("//load", "[Filename] - Load .schematic into clipboard"); @@ -679,6 +681,34 @@ public class WorldEdit { return true; + // Move + } else if (split[0].equalsIgnoreCase("//moveair") || + split[0].equalsIgnoreCase("//move")) { + checkArgs(split, 0, 3, split[0]); + int count = split.length > 1 ? Math.max(1, Integer.parseInt(split[1])) : 1; + Vector dir = getDirection(player, + split.length > 2 ? split[2].toLowerCase() : "me"); + BaseBlock replace; + + // Replacement block argument + if (split.length > 3) { + if (split[3].equalsIgnoreCase("displace")) { + replace = null; // Displace + } else { + replace = getBlock(split[3]); + } + } else { + replace = new BaseBlock(0); + } + + boolean copyAir = split[0].equalsIgnoreCase("//moveair"); + + int affected = editSession.moveCuboidRegion(session.getRegion(), + dir, count, copyAir, replace); + player.print(affected + " blocks moved."); + + return true; + // Stack } else if (split[0].equalsIgnoreCase("//stackair") || split[0].equalsIgnoreCase("//stack")) { diff --git a/src/com/sk89q/worldedit/Vector.java b/src/com/sk89q/worldedit/Vector.java index 925327151..a9d47cb23 100644 --- a/src/com/sk89q/worldedit/Vector.java +++ b/src/com/sk89q/worldedit/Vector.java @@ -446,6 +446,32 @@ public class Vector { Math.pow(pt.z - z, 2)); } + /** + * Checks to see if a vector is contained with another. + * + * @param min + * @param max + * @return + */ + public boolean containedWithin(Vector min, Vector max) { + return x >= min.getX() && x <= max.getX() + && y >= min.getY() && z <= max.getY() + && z >= min.getZ() && z <= max.getY(); + } + + /** + * Checks to see if a vector is contained with another. + * + * @param min + * @param max + * @return + */ + public boolean containedWithinBlock(Vector min, Vector max) { + return getBlockX() >= min.getBlockX() && getBlockX() <= max.getBlockX() + && getBlockY() >= min.getBlockY() && getBlockY() <= max.getBlockY() + && getBlockZ() >= min.getBlockZ() && getBlockZ() <= max.getBlockY(); + } + /** * 2D transformation. *