diff --git a/src/SMWorldEditPlayer.java b/src/SMWorldEditPlayer.java index e5bcb8e5c..7e919c1fa 100644 --- a/src/SMWorldEditPlayer.java +++ b/src/SMWorldEditPlayer.java @@ -64,6 +64,54 @@ public class SMWorldEditPlayer extends WorldEditPlayer { return Vector.toBlockPoint(player.getX(), player.getY(), player.getZ()); } + /** + * Get the point of the block being looked at. May return null. + * + * @param range + * @return point + */ + public Vector getBlockTrace(int range) { + HitBlox hitBlox = new HitBlox(player, range, 0.2); + Block block = hitBlox.getTargetBlock(); + if (block == null) { + return null; + } + return new Vector(block.getX(), block.getY(), block.getZ()); + } + + /** + * Pass through the wall that you are looking at. + * + * @param range + * @return whether the player was pass through + */ + public boolean passThroughForwardWall(int range) { + int free = 0; + int spots = 0; + + HitBlox hitBlox = new HitBlox(player, range, 0.2); + Block block; + + free = hitBlox.getLastBlock().getType() == 0 ? 1 : 0; + while ((block = hitBlox.getNextBlock()) != null) { + if (block.getType() == 0) { + free++; + if (spots >= 1) { + Vector v = new Vector(block.getX(), block.getY() + 1, block.getZ()); + if (server.getBlockType(v) == 0) { + setPosition(v.subtract(0, 1, 0)); + return true; + } + } + } else { + free = 0; + spots++; + } + } + + return false; + } + /** * Get the player's position. * diff --git a/src/WorldEdit.java b/src/WorldEdit.java index a0f095f80..522fb0c95 100644 --- a/src/WorldEdit.java +++ b/src/WorldEdit.java @@ -114,6 +114,8 @@ public class WorldEdit { // for now (see SMWorldEditListener.canUseCommand) commands.put("//pos1", "Set editing position #1"); commands.put("//pos2", "Set editing position #2"); + commands.put("//hpos1", "Trace editing position #1"); + commands.put("//hpos2", "Trace editing position #2"); commands.put("/toggleplace", "Toggle placing at pos #1"); commands.put("//wand", "Gives you the \"edit wand\""); commands.put("/toggleeditwand", "Toggles edit wand selection"); @@ -156,6 +158,9 @@ public class WorldEdit { commands.put("/unstuck", "Go up to the first free spot"); commands.put("/ascend", "Go up one level"); commands.put("/descend", "Go down one level"); + commands.put("/jumpto", "Jump to the block that you are looking at"); + commands.put("/thru", "Go through the wall that you are looking at"); + commands.put("/ceil", " - Get to the ceiling"); } /** @@ -309,6 +314,41 @@ public class WorldEdit { } return true; + // Jump to the block in sight + } else if (split[0].equalsIgnoreCase("/jumpto")) { + checkArgs(split, 0, 0, split[0]); + Vector pos = player.getBlockTrace(300); + if (pos != null) { + player.findFreePosition(pos); + player.print("Poof!"); + } else { + player.printError("No block in sight!"); + } + return true; + + // Go through a wall + } else if (split[0].equalsIgnoreCase("/thru")) { + checkArgs(split, 0, 0, split[0]); + if (player.passThroughForwardWall(300)) { + player.print("Whoosh!"); + } else { + player.printError("No free spot ahead of you found."); + } + return true; + + // Go to the ceiling + } else if (split[0].equalsIgnoreCase("/ceil")) { + checkArgs(split, 0, 1, split[0]); + int clearence = split.length > 1 ? + Math.max(0, Integer.parseInt(split[1])) : 0; + + if (player.ascendToCeiling(clearence)) { + player.print("Whoosh!"); + } else { + player.printError("No free spot above you found."); + } + return true; + // Set edit position #1 } else if (split[0].equalsIgnoreCase("//pos1")) { checkArgs(split, 0, 0, split[0]); @@ -323,6 +363,30 @@ public class WorldEdit { player.print("Second edit position set."); return true; + // Trace edit position #1 + } else if (split[0].equalsIgnoreCase("//hpos1")) { + checkArgs(split, 0, 0, split[0]); + Vector pos = player.getBlockTrace(300); + if (pos != null) { + session.setPos1(pos); + player.print("First edit position set."); + } else { + player.printError("No block in sight!"); + } + return true; + + // Trace edit position #2 + } else if (split[0].equalsIgnoreCase("//hpos2")) { + checkArgs(split, 0, 0, split[0]); + Vector pos = player.getBlockTrace(300); + if (pos != null) { + session.setPos2(pos); + player.print("Second edit position set."); + } else { + player.printError("No block in sight!"); + } + return true; + // Edit wand } else if (split[0].equalsIgnoreCase("//wand")) { checkArgs(split, 0, 0, split[0]); diff --git a/src/WorldEditPlayer.java b/src/WorldEditPlayer.java index 59a2b9d63..4453252d5 100644 --- a/src/WorldEditPlayer.java +++ b/src/WorldEditPlayer.java @@ -19,6 +19,7 @@ import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.ServerInterface; +import com.sk89q.worldedit.blocks.BlockType; /** * @@ -55,6 +56,13 @@ public abstract class WorldEditPlayer { * @return point */ public abstract Vector getBlockIn(); + /** + * Get the point of the block being looked at. May return null. + * + * @param range + * @return point + */ + public abstract Vector getBlockTrace(int range); /** * Get the player's position. * @@ -135,13 +143,14 @@ public abstract class WorldEditPlayer { * Blocks above the player will be iteratively tested until there is * a series of two free blocks. The player will be teleported to * that free position. + * + * @param searchPos search position */ - public void findFreePosition() { - Vector pos = getBlockIn(); - int x = pos.getBlockX(); - int y = pos.getBlockY(); + public void findFreePosition(Vector searchPos) { + int x = searchPos.getBlockX(); + int y = searchPos.getBlockY(); int origY = y; - int z = pos.getBlockZ(); + int z = searchPos.getBlockZ(); byte free = 0; @@ -163,6 +172,24 @@ public abstract class WorldEditPlayer { } } + /** + * Find a position for the player to stand that is not inside a block. + * Blocks above the player will be iteratively tested until there is + * a series of two free blocks. The player will be teleported to + * that free position. + */ + public void findFreePosition() { + findFreePosition(getBlockIn()); + } + + /** + * Pass through the wall that you are looking at. + * + * @param range + * @return whether a wall was passed through + */ + public abstract boolean passThroughForwardWall(int range); + /** * Go up one level to the next free space above. * @@ -251,6 +278,40 @@ public abstract class WorldEditPlayer { return false; } + /** + * Ascend to the ceiling above. + * + * @param clearance + * @return whether the player was moved + */ + public boolean ascendToCeiling(int clearance) { + Vector pos = getBlockIn(); + int x = pos.getBlockX(); + int y = pos.getBlockY() + 2; + int initialY = y; + int z = pos.getBlockZ(); + + // Nothing above + if (server.getBlockType(new Vector(x, y, z)) != 0) { + return false; + } + + while (y <= 127) { + // Found a ceiling! + if (server.getBlockType(new Vector(x, y, z)) != 0) { + int platformY = Math.max(initialY, y - 3); + server.setBlockType(new Vector(x, platformY, z), + BlockType.GLASS.getID()); + setPosition(new Vector(x, platformY + 1, z)); + return true; + } + + y++; + } + + return false; + } + /** * Gives the player an item. *