diff --git a/src/main/java/com/sk89q/worldedit/commands/ToolCommands.java b/src/main/java/com/sk89q/worldedit/commands/ToolCommands.java index 8103cae6f..806276af2 100644 --- a/src/main/java/com/sk89q/worldedit/commands/ToolCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/ToolCommands.java @@ -132,4 +132,21 @@ public class ToolCommands { LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { } + + @Command( + aliases = {"deltree"}, + usage = "", + desc = "Floating tree remover tool", + min = 0, + max = 0 + ) + @CommandPermissions({"worldedit.tool.deltree"}) + public static void deltree(CommandContext args, WorldEdit we, + LocalSession session, LocalPlayer player, EditSession editSession) + throws WorldEditException { + + session.setTool(player.getItemInHand(), new FloatingTreeRemover()); + player.print("Floating tree remover tool bound to " + + ItemType.toHeldName(player.getItemInHand()) + "."); + } } diff --git a/src/main/java/com/sk89q/worldedit/tools/FloatingTreeRemover.java b/src/main/java/com/sk89q/worldedit/tools/FloatingTreeRemover.java new file mode 100755 index 000000000..1ee6fb648 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/tools/FloatingTreeRemover.java @@ -0,0 +1,138 @@ +// $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 . +*/ + +package com.sk89q.worldedit.tools; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; + +/** + * A pickaxe mode that removes floating treetops (logs and leaves not connected + * to anything else) + * + * @author Moo0 + */ +public class FloatingTreeRemover implements BlockTool { + private static final BaseBlock air = new BaseBlock(0); + private int range; + + public FloatingTreeRemover() { + this.range = 100; + } + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.tool.deltree"); + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + LocalWorld world = clicked.getWorld(); + + int initialType = world.getBlockType(clicked); + int block; + + EditSession editSession = + new EditSession(world, session.getBlockChangeLimit()); + + if (initialType != BlockID.LEAVES && initialType != BlockID.LOG) { + player.printError("That's not a floating tree."); + return true; + } + + HashSet blockSet = new HashSet(); + try { + if (!recurse(server, editSession, world, clicked.toBlockVector(), + clicked, range, blockSet, 0)) { + player.printError("That's not a floating tree."); + return true; + } + for (Iterator iterator = blockSet.iterator(); iterator.hasNext();) { + BlockVector blockVector = iterator.next(); + block = editSession.getBlock(blockVector).getType(); + if (block == BlockID.LEAVES || block == BlockID.LOG) { + editSession.setBlock(blockVector, air); + } + } + } catch (MaxChangedBlocksException e) { + player.printError("Max blocks change limit reached."); + } finally { + session.remember(editSession); + } + + return true; + } + + /** + * Helper method. + * + * @param server + * @param superPickaxeManyDrop + * @param world + * @param pos + * @param origin + * @param size + * @param initialType + * @param visited + */ + private boolean recurse(ServerInterface server, EditSession editSession, + LocalWorld world, BlockVector pos, + Vector origin, int size, + Set visited, int lastBlock) + throws MaxChangedBlocksException { + + if (origin.distance(pos) > size || visited.contains(pos)) { + return true; + } + + visited.add(pos); + + int block = editSession.getBlock(pos).getType(); + if (block == BlockID.AIR || block == BlockID.SNOW){ + return true; + } + if (block != BlockID.LEAVES && block != BlockID.LOG) { + if (lastBlock == BlockID.LEAVES) { + return true; + } + else { + return false; + } + + } + + for (int i = -1; i <= 1; i++) { + for (int j = -1; j <= 1; j++) { + for (int k = -1; k <= 1; k++) { + if (Math.abs(i) + Math.abs(j) + Math.abs(k) == 1) { + if (!recurse(server, editSession, world, pos.add(i, j, k).toBlockVector(), + origin, size, visited, block)) { + return false; + } + } + } + } + } + return true; + } + +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 4db198fee..ed33d0920 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -230,6 +230,9 @@ commands: tree: description: Tree generator tool usage: / [type] + deltree: + description: Floating tree remover tool + usage: / /fillr: description: Fill a hole recursively usage: / [depth]