diff --git a/src/main/java/com/sk89q/worldedit/LocalPlayer.java b/src/main/java/com/sk89q/worldedit/LocalPlayer.java index 99a102f99..dbcfaa9a1 100644 --- a/src/main/java/com/sk89q/worldedit/LocalPlayer.java +++ b/src/main/java/com/sk89q/worldedit/LocalPlayer.java @@ -236,6 +236,17 @@ public abstract class LocalPlayer { * @return whether the player was moved */ public boolean ascendToCeiling(int clearance) { + return ascendToCeiling(clearance, true); + } + + /** + * Ascend to the ceiling above. + * + * @param clearance How many blocks to leave above the player's head + * @param alwaysGlass Always put glass under the player + * @return whether the player was moved + */ + public boolean ascendToCeiling(int clearance, boolean alwaysGlass) { Vector pos = getBlockIn(); int x = pos.getBlockX(); int initialY = Math.max(0, pos.getBlockY()); @@ -252,8 +263,7 @@ public abstract class LocalPlayer { // Found a ceiling! if (!BlockType.canPassThrough(world.getBlock(new Vector(x, y, z)))) { int platformY = Math.max(initialY, y - 3 - clearance); - world.setBlockType(new Vector(x, platformY, z), BlockID.GLASS); - setPosition(new Vector(x + 0.5, platformY + 1, z + 0.5)); + floatAt(x, platformY + 1, z, alwaysGlass); return true; } @@ -270,6 +280,17 @@ public abstract class LocalPlayer { * @return whether the player was moved */ public boolean ascendUpwards(int distance) { + return ascendUpwards(distance, true); + } + + /** + * Just go up. + * + * @param distance How far up to teleport + * @param alwaysGlass Always put glass under the player + * @return whether the player was moved + */ + public boolean ascendUpwards(int distance, boolean alwaysGlass) { final Vector pos = getBlockIn(); final int x = pos.getBlockX(); final int initialY = Math.max(0, pos.getBlockY()); @@ -284,8 +305,7 @@ public abstract class LocalPlayer { } else if (y > maxY + 1) { break; } else if (y == maxY + 1) { - world.setBlockType(new Vector(x, y - 2, z), BlockID.GLASS); - setPosition(new Vector(x + 0.5, y - 1, z + 0.5)); + floatAt(x, y - 1, z, alwaysGlass); return true; } @@ -295,6 +315,18 @@ public abstract class LocalPlayer { return false; } + /** + * Make the player float in the given blocks. + * + * @param x The X coordinate of the block to float in + * @param y The Y coordinate of the block to float in + * @param z The Z coordinate of the block to float in + */ + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + getPosition().getWorld().setBlockType(new Vector(x, y - 1, z), BlockID.GLASS); + setPosition(new Vector(x + 0.5, y, z + 0.5)); + } + /** * Get the point of the block that is being stood in. * diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 82f2effd6..ec268553e 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.bukkit; +import com.sk89q.worldedit.blocks.BlockID; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -150,4 +151,15 @@ public class BukkitPlayer extends LocalPlayer { public boolean hasCreativeMode() { return player.getGameMode() == GameMode.CREATIVE; } + + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + if (alwaysGlass || !player.getAllowFlight()) { + super.floatAt(x, y, z, alwaysGlass); + return; + } + + setPosition(new Vector(x + 0.5, y, z + 0.5)); + player.setFlying(true); + } } diff --git a/src/main/java/com/sk89q/worldedit/commands/NavigationCommands.java b/src/main/java/com/sk89q/worldedit/commands/NavigationCommands.java index 4c87c099f..fbfd4ad2f 100644 --- a/src/main/java/com/sk89q/worldedit/commands/NavigationCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/NavigationCommands.java @@ -118,6 +118,7 @@ public class NavigationCommands { aliases = { "ceil" }, usage = "[clearance]", desc = "Go to the celing", + flags = "g", min = 0, max = 1 ) @@ -129,7 +130,8 @@ public class NavigationCommands { int clearence = args.argsLength() > 0 ? Math.max(0, args.getInteger(0)) : 0; - if (player.ascendToCeiling(clearence)) { + final boolean alwaysGlass = args.hasFlag('g'); + if (player.ascendToCeiling(clearence, alwaysGlass)) { player.print("Whoosh!"); } else { player.printError("No free spot above you found."); @@ -177,6 +179,7 @@ public class NavigationCommands { aliases = { "up" }, usage = "", desc = "Go upwards some distance", + flags = "g", min = 1, max = 1 ) @@ -187,7 +190,8 @@ public class NavigationCommands { int distance = args.getInteger(0); - if (player.ascendUpwards(distance)) { + final boolean alwaysGlass = args.hasFlag('g'); + if (player.ascendUpwards(distance, alwaysGlass)) { player.print("Whoosh!"); } else { player.printError("You would hit something above you.");