diff --git a/plugin.yml b/plugin.yml index 5a4a2db9c..c0348ea83 100644 --- a/plugin.yml +++ b/plugin.yml @@ -275,6 +275,10 @@ commands: description: Set the brush size usage: / [pattern] permissions: 'worldedit.brush.options.size' + range: + description: Set the brush range + usage: / [range] + permissions: 'worldedit.brush.options.range' mask: description: Set the brush mask usage: / [mask] diff --git a/pom.xml b/pom.xml index 7793fbc9f..fd3c46960 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ WorldEdit allows for editing the Minecraft SMP world en-masse, de-griefing, and fixing issues. - UTF-8 + UTF-8 diff --git a/src/main/java/com/sk89q/worldedit/LocalPlayer.java b/src/main/java/com/sk89q/worldedit/LocalPlayer.java index 81bd56cd2..c9600fb00 100644 --- a/src/main/java/com/sk89q/worldedit/LocalPlayer.java +++ b/src/main/java/com/sk89q/worldedit/LocalPlayer.java @@ -302,6 +302,19 @@ public abstract class LocalPlayer { pos.getY() - 1, pos.getZ()); } + /** + * Get the point of the block being looked at. May return null. + * Will return the farthest away air block if useLastBlock is true and no other block is found. + * + * @param range + * @param useLastBlock + * @return point + */ + public WorldVector getBlockTrace(int range, boolean useLastBlock) { + TargetBlock tb = new TargetBlock(this, range, 0.2); + return (useLastBlock ? tb.getAnyTargetBlock() : tb.getTargetBlock()); + } + /** * Get the point of the block being looked at. May return null. * @@ -309,8 +322,7 @@ public abstract class LocalPlayer { * @return point */ public WorldVector getBlockTrace(int range) { - TargetBlock tb = new TargetBlock(this, range, 0.2); - return tb.getTargetBlock(); + return getBlockTrace(range, false); } /** diff --git a/src/main/java/com/sk89q/worldedit/commands/ToolUtilCommands.java b/src/main/java/com/sk89q/worldedit/commands/ToolUtilCommands.java index 0b6df870a..94f23d74d 100644 --- a/src/main/java/com/sk89q/worldedit/commands/ToolUtilCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/ToolUtilCommands.java @@ -109,6 +109,22 @@ public class ToolUtilCommands { player.print("Brush material set."); } + @Command( + aliases = {"range"}, + usage = "[pattern]", + desc = "Set the brush range", + min = 1, + max = 1 + ) + @CommandPermissions({"worldedit.brush.options.range"}) + public static void range(CommandContext args, WorldEdit we, + LocalSession session, LocalPlayer player, EditSession editSession) + throws WorldEditException { + int range = args.getInteger(0); + session.getBrushTool(player.getItemInHand()).setRange(range); + player.print("Brush range set."); + } + @Command( aliases = {"size"}, usage = "[pattern]", diff --git a/src/main/java/com/sk89q/worldedit/tools/BrushTool.java b/src/main/java/com/sk89q/worldedit/tools/BrushTool.java index 8a3e81bf6..ddd50dd19 100644 --- a/src/main/java/com/sk89q/worldedit/tools/BrushTool.java +++ b/src/main/java/com/sk89q/worldedit/tools/BrushTool.java @@ -36,6 +36,8 @@ import com.sk89q.worldedit.tools.brushes.SphereBrush; * @author sk89q */ public class BrushTool implements TraceTool { + private static int MAX_RANGE = 500; + private int range = -1; private Mask mask = null; private Brush brush = new SphereBrush(); private Pattern material = new SingleBlockPattern(new BaseBlock(BlockID.COBBLESTONE)); @@ -135,6 +137,24 @@ public class BrushTool implements TraceTool { public void setSize(int size) { this.size = size; } + + /** + * Get the set brush range. + * + * @return + */ + public int getRange() { + return (range < 0) ? MAX_RANGE : Math.min(range, MAX_RANGE); + } + + /** + * Set the set brush range. + * + * @param size + */ + public void setRange(int range) { + this.range = range; + } /** * Perform the action. Should return true to deny the default @@ -146,7 +166,12 @@ public class BrushTool implements TraceTool { */ public boolean act(ServerInterface server, LocalConfiguration config, LocalPlayer player, LocalSession session) { - WorldVector target = player.getBlockTrace(500); + WorldVector target = null; + if (this.range > -1) { + target = player.getBlockTrace(getRange(), true); + } else { + target = player.getBlockTrace(MAX_RANGE); + } if (target == null) { player.printError("No block in sight!"); diff --git a/src/main/java/com/sk89q/worldedit/util/TargetBlock.java b/src/main/java/com/sk89q/worldedit/util/TargetBlock.java index 9ef5f3f19..5acba026c 100644 --- a/src/main/java/com/sk89q/worldedit/util/TargetBlock.java +++ b/src/main/java/com/sk89q/worldedit/util/TargetBlock.java @@ -100,6 +100,31 @@ public class TargetBlock { prevPos = targetPos; } + /** + * Returns any block at the sight. Returns null if out of range or if no + * viable target was found. Will try to return the last valid air block it finds. + * + * @return Block + */ + public BlockWorldVector getAnyTargetBlock() { + boolean searchForLastBlock = true; + BlockWorldVector lastBlock = null; + while (getNextBlock() != null) { + if (world.getBlockType(getCurrentBlock()) == 0) { + if(searchForLastBlock) { + lastBlock = getCurrentBlock(); + if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= 127) { + searchForLastBlock = false; + } + } + } else { + break; + } + } + BlockWorldVector currentBlock = getCurrentBlock(); + return (currentBlock != null ? currentBlock : lastBlock); + } + /** * Returns the block at the sight. Returns null if out of range or if no * viable target was found