From 3908a2d0eb4b32ffb79946d94427e9a21e7b48ae Mon Sep 17 00:00:00 2001 From: sk89q Date: Sat, 6 Nov 2010 23:03:35 -0700 Subject: [PATCH] Added area and recursive super pickaxe modes. --- src/WorldEditListener.java | 142 ++++++++++++++++++++++++++++++++++--- src/WorldEditSession.java | 39 ++++++++++ 2 files changed, 172 insertions(+), 9 deletions(-) diff --git a/src/WorldEditListener.java b/src/WorldEditListener.java index 509fe65ee..8acd6db48 100644 --- a/src/WorldEditListener.java +++ b/src/WorldEditListener.java @@ -100,6 +100,10 @@ public class WorldEditListener extends PluginListener { * Max radius for commands that use a radius. */ private int maxRadius = -1; + /** + * Max super pick axe size. + */ + private int maxSuperPickaxeSize = 5; /** * Indicates whether commands should be logged to the console. */ @@ -151,6 +155,7 @@ public class WorldEditListener extends PluginListener { commands.put("//fill", "[ID] [Radius] - Fill a hole"); commands.put("//drain", "[Radius] - Drain nearby water/lava pools"); commands.put("//limit", "[Num] - See documentation"); + commands.put("//mode", "[Mode] - Set super pickaxe mode (single/recursive/area)"); commands.put("//expand", " [Num] - Expands the selection"); commands.put("//contract", " [Num] - Contracts the selection"); commands.put("//rotate", "[Angle] - Rotate the clipboard"); @@ -562,6 +567,37 @@ public class WorldEditListener extends PluginListener { } return true; + // Set super pick axe mode + } else if (split[0].equalsIgnoreCase("//mode")) { + checkArgs(split, 1, 2, split[0]); + + if (split[1].equalsIgnoreCase("single")) { + session.setSuperPickaxeMode(WorldEditSession.SuperPickaxeModes.SINGLE); + player.print("Mode set to single block."); + } else if (split[1].equalsIgnoreCase("recursive") + || split[1].equalsIgnoreCase("area")) { + if (split.length == 3) { + int size = Math.max(1, Integer.parseInt(split[2])); + if (size <= maxSuperPickaxeSize) { + WorldEditSession.SuperPickaxeModes mode = + split[1].equalsIgnoreCase("recursive") ? + WorldEditSession.SuperPickaxeModes.SAME_TYPE_RECURSIVE : + WorldEditSession.SuperPickaxeModes.SAME_TYPE_AREA; + session.setSuperPickaxeMode(mode); + session.setSuperPickaxeRange(size); + player.print("Mode set to " + split[1].toLowerCase() + "."); + } else { + player.printError("Max size is " + maxSuperPickaxeSize + "."); + } + } else { + player.printError("Size argument required for mode " + + split[1].toLowerCase() + "."); + } + } else { + player.printError("Unknown super pick axe mode."); + } + return true; + // Undo } else if (split[0].equalsIgnoreCase("//undo")) { checkArgs(split, 0, 0, split[0]); @@ -1479,16 +1515,69 @@ public class WorldEditListener extends PluginListener { } } else if (player.isHoldingPickAxe()) { if (session.hasSuperPickAxe()) { - Vector pos = new Vector(blockClicked.getX(), - blockClicked.getY(), blockClicked.getZ()); - if (ServerInterface.getBlockType(pos) == 7 - && !canUseCommand(modPlayer, "/worldeditbedrock")) { - return true; - } else if (ServerInterface.getBlockType(pos) == 46) { - return false; - } + boolean canBedrock = canUseCommand(modPlayer, "/worldeditbedrock"); - ServerInterface.setBlockType(pos, 0); + // Single block super pickaxe + if (session.getSuperPickaxeMode() == + WorldEditSession.SuperPickaxeModes.SINGLE) { + Vector pos = new Vector(blockClicked.getX(), + blockClicked.getY(), blockClicked.getZ()); + if (ServerInterface.getBlockType(pos) == 7 && canBedrock) { + return true; + } else if (ServerInterface.getBlockType(pos) == 46) { + return false; + } + + ServerInterface.setBlockType(pos, 0); + + // Area super pickaxe + } else if (session.getSuperPickaxeMode() == + WorldEditSession.SuperPickaxeModes.SAME_TYPE_AREA) { + Vector origin = new Vector(blockClicked.getX(), + blockClicked.getY(), blockClicked.getZ()); + int ox = blockClicked.getX(); + int oy = blockClicked.getY(); + int oz = blockClicked.getZ(); + int size = session.getSuperPickaxeRange(); + int initialType = ServerInterface.getBlockType(origin); + + if (initialType == 7 && !canBedrock) { + return true; + } + + for (int x = ox - size; x <= ox + size; x++) { + for (int y = oy - size; y <= oy + size; y++) { + for (int z = oz - size; z <= oz + size; z++) { + Vector pos = new Vector(x, y, z); + if (ServerInterface.getBlockType(pos) == initialType) { + ServerInterface.setBlockType(pos, 0); + } + } + } + } + + return true; + + // Area super pickaxe + } else if (session.getSuperPickaxeMode() == + WorldEditSession.SuperPickaxeModes.SAME_TYPE_RECURSIVE) { + Vector origin = new Vector(blockClicked.getX(), + blockClicked.getY(), blockClicked.getZ()); + int ox = blockClicked.getX(); + int oy = blockClicked.getY(); + int oz = blockClicked.getZ(); + int size = session.getSuperPickaxeRange(); + int initialType = ServerInterface.getBlockType(origin); + + if (initialType == 7 && !canBedrock) { + return true; + } + + recursiveSuperPickaxe(origin.toBlockVector(), origin, size, + initialType, new HashSet()); + + return true; + } return true; } @@ -1497,6 +1586,39 @@ public class WorldEditListener extends PluginListener { return false; } + /** + * Helper method for the recursive super pickaxe. + * + * @param pos + * @param canBedrock + * @return + */ + private void recursiveSuperPickaxe(BlockVector pos, Vector origin, + int size, int initialType, Set visited) { + if (origin.distance(pos) > size || visited.contains(pos)) { + return; + } + + visited.add(pos); + + if (ServerInterface.getBlockType(pos) == initialType) { + ServerInterface.setBlockType(pos, 0); + } + + recursiveSuperPickaxe(pos.add(1, 0, 0).toBlockVector(), origin, size, + initialType, visited); + recursiveSuperPickaxe(pos.add(-1, 0, 0).toBlockVector(), origin, size, + initialType, visited); + recursiveSuperPickaxe(pos.add(0, 0, 1).toBlockVector(), origin, size, + initialType, visited); + recursiveSuperPickaxe(pos.add(0, 0, -1).toBlockVector(), origin, size, + initialType, visited); + recursiveSuperPickaxe(pos.add(0, 1, 0).toBlockVector(), origin, size, + initialType, visited); + recursiveSuperPickaxe(pos.add(0, -1, 0).toBlockVector(), origin, size, + initialType, visited); + } + /** * * @param ply @@ -1605,6 +1727,8 @@ public class WorldEditListener extends PluginListener { maxRadius = Math.max(-1, properties.getInt("max-radius", -1)); + maxSuperPickaxeSize = Math.max(1, properties.getInt("max-super-pickaxe-size", 5)); + String snapshotsDir = properties.getString("snapshots-dir", ""); if (!snapshotsDir.trim().equals("")) { snapshotRepo = new SnapshotRepository(snapshotsDir); diff --git a/src/WorldEditSession.java b/src/WorldEditSession.java index dd1f1880c..4f4936b2e 100644 --- a/src/WorldEditSession.java +++ b/src/WorldEditSession.java @@ -28,6 +28,43 @@ import java.util.LinkedList; * @author sk89q */ public class WorldEditSession { + + /** + * @return the superPickaxeMode + */ + public SuperPickaxeModes getSuperPickaxeMode() { + return superPickaxeMode; + } + + /** + * @param superPickaxeMode the superPickaxeMode to set + */ + public void setSuperPickaxeMode(SuperPickaxeModes superPickaxeMode) { + this.superPickaxeMode = superPickaxeMode; + } + + /** + * @return the superPickaxeRange + */ + public int getSuperPickaxeRange() { + return superPickaxeRange; + } + + /** + * @param superPickaxeRange the superPickaxeRange to set + */ + public void setSuperPickaxeRange(int superPickaxeRange) { + this.superPickaxeRange = superPickaxeRange; + } + /** + * List of super pick axe modes. + */ + public static enum SuperPickaxeModes { + SINGLE, + SAME_TYPE_RECURSIVE, + SAME_TYPE_AREA + }; + public static final int MAX_HISTORY_SIZE = 15; private boolean placeAtPos1 = false; private Vector pos1, pos2; @@ -37,6 +74,8 @@ public class WorldEditSession { private CuboidClipboard clipboard; private boolean toolControl = true; private boolean superPickAxe = false; + private SuperPickaxeModes superPickaxeMode = SuperPickaxeModes.SINGLE; + private int superPickaxeRange = 3; private int maxBlocksChanged = -1; private Snapshot snapshot;