From 4c7e14a76bc70b6d1808f38b0353bca0e1997fcb Mon Sep 17 00:00:00 2001 From: sk89q Date: Sat, 2 Oct 2010 16:11:44 -0700 Subject: [PATCH] Added basic copy/paste functions. --- src/RegionClipboard.java | 91 +++++++++++++++++++++++++++++++++++++++ src/WorldEdit.java | 38 ++++++++++++++++ src/WorldEditSession.java | 15 +++++++ 3 files changed, 144 insertions(+) create mode 100644 src/RegionClipboard.java diff --git a/src/RegionClipboard.java b/src/RegionClipboard.java new file mode 100644 index 000000000..125203558 --- /dev/null +++ b/src/RegionClipboard.java @@ -0,0 +1,91 @@ +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import com.sk89q.worldedit.*; + +/** + * + * @author Albert + */ +public class RegionClipboard { + private int[][][] data; + private Point min; + private Point max; + private Point origin; + + /** + * Constructs the region instance. The minimum and maximum points must be + * the respective minimum and maximum numbers! + * + * @param min + * @param max + * @param origin + */ + public RegionClipboard(Point min, Point max, Point origin) { + this.min = min; + this.max = max; + this.origin = origin; + data = new int[(max.getX()) - min.getX() + 1] + [max.getY() - min.getY() + 1] + [max.getZ() - min.getZ() + 1]; + } + + /** + * Copy to the clipboard. + * + * @param editSession + */ + public void copy(EditSession editSession) { + for (int x = min.getX(); x <= max.getX(); x++) { + for (int y = min.getY(); y <= max.getY(); y++) { + for (int z = min.getZ(); z <= max.getZ(); z++) { + data[x - min.getX()][y - min.getY()][z - min.getZ()] = + editSession.getBlock(x, y, z); + } + } + } + } + + /** + * Paste from the clipboard. + * + * @param editSession + * @param origin Position to paste it from + * @param noAir True to not paste air + */ + public void paste(EditSession editSession, Point newOrigin, boolean noAir) { + int xs = max.getX() - min.getX(); + int ys = max.getY() - min.getY(); + int zs = max.getZ() - min.getZ(); + int offsetX = min.getX() - origin.getX() + newOrigin.getX(); + int offsetY = min.getY() - origin.getY() + newOrigin.getY(); + int offsetZ = min.getZ() - origin.getZ() + newOrigin.getZ(); + + for (int x = 0; x < xs; x++) { + for (int y = 0; y <= ys; y++) { + for (int z = 0; z <= zs; z++) { + if (noAir && data[x][y][z] == 0) { continue; } + + editSession.setBlock(x + offsetX, y + offsetY, z + offsetZ, + data[x][y][z]); + } + } + } + } +} diff --git a/src/WorldEdit.java b/src/WorldEdit.java index 476687fd4..851bb16c3 100644 --- a/src/WorldEdit.java +++ b/src/WorldEdit.java @@ -46,6 +46,9 @@ public class WorldEdit extends Plugin { commands.put("/editreplace", " - Replace all existing blocks inside region"); commands.put("/editoverlay", " - Overlay the area one layer"); commands.put("/removeabove", " - Remove blocks above head"); + commands.put("/editcopy", "Copies the currently selected region"); + commands.put("/editpaste", "Pastes the clipboard"); + commands.put("/editpasteair", "Pastes the clipboard (with air)"); commands.put("/editfill", " - Fill a hole"); commands.put("/editscript", " [Args...] - Run an editscript"); } @@ -227,6 +230,24 @@ public class WorldEdit extends Plugin { } return true; + // Paste + } else if (split[0].equalsIgnoreCase("/editpasteair") || + split[0].equalsIgnoreCase("/editpaste")) { + if (session.getClipboard() == null) { + player.sendMessage(Colors.Rose + "Nothing is in your clipboard."); + } else { + Point pos = new Point((int)Math.floor(player.getX()), + (int)Math.floor(player.getY()), + (int)Math.floor(player.getZ())); + session.getClipboard().paste(editSession, pos, + split[0].equalsIgnoreCase("/editpaste")); + session.remember(editSession); + logger.log(Level.INFO, player.getName() + " used " + split[0]); + player.sendMessage(Colors.LightPurple + "Pasted."); + } + + return true; + // Fill a hole } else if (split[0].equalsIgnoreCase("/editfill")) { checkArgs(split, 1); @@ -432,6 +453,23 @@ public class WorldEdit extends Plugin { session.remember(editSession); + return true; + + // Copy + } else if (split[0].equalsIgnoreCase("/editcopy")) { + Point min = new Point(lowerX, lowerY, lowerZ); + Point max = new Point(upperX, upperY, upperZ); + Point pos = new Point((int)Math.floor(player.getX()), + (int)Math.floor(player.getY()), + (int)Math.floor(player.getZ())); + + RegionClipboard clipboard = new RegionClipboard(min, max, pos); + clipboard.copy(editSession); + session.setClipboard(clipboard); + + logger.log(Level.INFO, player.getName() + " used /editcopy"); + player.sendMessage(Colors.LightPurple + "Block(s) copied."); + return true; } diff --git a/src/WorldEditSession.java b/src/WorldEditSession.java index 7104b511f..0da7538a3 100644 --- a/src/WorldEditSession.java +++ b/src/WorldEditSession.java @@ -32,6 +32,7 @@ public class WorldEditSession { private boolean hasSetPos2 = false; private LinkedList history = new LinkedList(); private int historyPointer = 0; + private RegionClipboard clipboard; /** * Get the edit session. @@ -157,4 +158,18 @@ public class WorldEditSession { (getUpperY() - getLowerY() + 1) * (getUpperZ() - getLowerZ() + 1); } + + /** + * @return + */ + public RegionClipboard getClipboard() { + return clipboard; + } + + /** + * @param clipboard + */ + public void setClipboard(RegionClipboard clipboard) { + this.clipboard = clipboard; + } }