From 8545417b3a4c926d204a8972493ff1a3c83a0ec9 Mon Sep 17 00:00:00 2001 From: wizjany Date: Wed, 10 Jul 2019 18:25:34 -0400 Subject: [PATCH] Fix error in /up when used out of bounds. Also reduce calls to Entity#getLocation() all over since it's more expensive than it needs to be (adapts world/vector every time). --- .../worldedit/command/BiomeCommands.java | 3 +- .../platform/AbstractPlayerActor.java | 41 +++++++++++++------ .../extension/platform/PlayerProxy.java | 5 +++ .../clipboard/io/SpongeSchematicWriter.java | 5 ++- .../internal/cui/ServerCUIHandler.java | 10 +++-- .../sk89q/worldedit/fabric/FabricPlayer.java | 16 +++++++- .../sk89q/worldedit/forge/ForgePlayer.java | 16 +++++++- .../sk89q/worldedit/sponge/SpongePlayer.java | 12 ++++++ 8 files changed, 86 insertions(+), 22 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java index 4e2b714e2..29747852e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -180,7 +180,8 @@ public class BiomeCommands { Mask2D mask2d = mask != null ? mask.toMask2D() : null; if (atPosition) { - region = new CuboidRegion(player.getLocation().toVector().toBlockPoint(), player.getLocation().toVector().toBlockPoint()); + final BlockVector3 pos = player.getLocation().toVector().toBlockPoint(); + region = new CuboidRegion(pos, pos); } else { region = session.getSelection(world); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index f51f992ac..cea7d8d47 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -19,7 +19,10 @@ package com.sk89q.worldedit.extension.platform; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.NotABlockException; +import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extent.Extent; @@ -32,6 +35,7 @@ import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.TargetBlock; import com.sk89q.worldedit.util.auth.AuthorizationException; +import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; @@ -173,7 +177,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { if (spots == 2) { final BlockVector3 platform = BlockVector3.at(x, y - 2, z); final BlockState block = world.getBlock(platform); - final com.sk89q.worldedit.world.block.BlockType type = block.getBlockType(); + final BlockType type = block.getBlockType(); // Don't get put in lava! if (type == BlockTypes.LAVA) { @@ -259,6 +263,13 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { // Found a ceiling! if (world.getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) { int platformY = Math.max(initialY, y - 3 - clearance); + if (platformY < initialY) { // if ==, they already have the given clearance, if <, clearance is too large + printError("Not enough space above you!"); + return false; + } else if (platformY == initialY) { + printError("You're already at the ceiling."); + return false; + } floatAt(x, platformY + 1, z, alwaysGlass); return true; } @@ -302,25 +313,27 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { @Override public void floatAt(int x, int y, int z, boolean alwaysGlass) { - try { - BlockVector3 spot = BlockVector3.at(x, y - 1, z); - if (!getLocation().getExtent().getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) { - getLocation().getExtent().setBlock(spot, BlockTypes.GLASS.getDefaultState()); + BlockVector3 spot = BlockVector3.at(x, y - 1, z); + final World world = (World) getLocation().getExtent(); + if (!world.getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) { + try (EditSession session = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, 1, this)) { + session.setBlock(spot, BlockTypes.GLASS.getDefaultState()); + } catch (MaxChangedBlocksException ignored) { } - } catch (WorldEditException e) { - e.printStackTrace(); } setPosition(Vector3.at(x + 0.5, y, z + 0.5)); } @Override public Location getBlockIn() { - return getLocation().setPosition(getLocation().toVector().floor()); + final Location location = getLocation(); + return location.setPosition(location.toVector().floor()); } @Override public Location getBlockOn() { - return getLocation().setPosition(getLocation().setY(getLocation().getY() - 1).toVector().floor()); + final Location location = getLocation(); + return location.setPosition(location.setY(location.getY() - 1).toVector().floor()); } @Override @@ -369,15 +382,16 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { @Override public Direction getCardinalDirection(int yawOffset) { - if (getLocation().getPitch() > 67.5) { + final Location location = getLocation(); + if (location.getPitch() > 67.5) { return Direction.DOWN; } - if (getLocation().getPitch() < -67.5) { + if (location.getPitch() < -67.5) { return Direction.UP; } // From hey0's code - double rot = (getLocation().getYaw() + yawOffset) % 360; //let's use real yaw now + double rot = (location.getYaw() + yawOffset) % 360; //let's use real yaw now if (rot < 0) { rot += 360.0; } @@ -446,7 +460,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { @Override public void setPosition(Vector3 pos) { - setPosition(pos, getLocation().getPitch(), getLocation().getYaw()); + final Location location = getLocation(); + setPosition(pos, location.getPitch(), location.getYaw()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java index 8ecf3cc10..120dd47ac 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java @@ -178,4 +178,9 @@ class PlayerProxy extends AbstractPlayerActor { public > void sendFakeBlock(BlockVector3 pos, B block) { basePlayer.sendFakeBlock(pos, block); } + + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + basePlayer.floatAt(x, y, z, alwaysGlass); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index 2ed06cc03..fcc8c8e93 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -260,8 +260,9 @@ public class SpongeSchematicWriter implements ClipboardWriter { } values.remove("id"); values.put("Id", new StringTag(state.getType().getId())); - values.put("Pos", writeVector(e.getLocation().toVector())); - values.put("Rotation", writeRotation(e.getLocation())); + final Location location = e.getLocation(); + values.put("Pos", writeVector(location.toVector())); + values.put("Rotation", writeRotation(location)); return new CompoundTag(values); }).filter(Objects::nonNull).collect(Collectors.toList()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java index 5a13140db..2ca8f3bd3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java @@ -32,6 +32,7 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; @@ -114,11 +115,12 @@ public class ServerCUIHandler { } // Borrowed this math from FAWE - double rotX = player.getLocation().getYaw(); - double rotY = player.getLocation().getPitch(); + final Location location = player.getLocation(); + double rotX = location.getYaw(); + double rotY = location.getPitch(); double xz = Math.cos(Math.toRadians(rotY)); - int x = (int) (player.getLocation().getX() - (-xz * Math.sin(Math.toRadians(rotX))) * 12); - int z = (int) (player.getLocation().getZ() - (xz * Math.cos(Math.toRadians(rotX))) * 12); + int x = (int) (location.getX() - (-xz * Math.sin(Math.toRadians(rotX))) * 12); + int z = (int) (location.getZ() - (xz * Math.cos(Math.toRadians(rotX))) * 12); int y = Math.max(0, Math.min(Math.min(255, posY + 32), posY + 3)); Map structureTag = new HashMap<>(); diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java index d96e0f81f..2d0681c1b 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java @@ -106,7 +106,7 @@ public class FabricPlayer extends AbstractPlayerActor { } @Override - public com.sk89q.worldedit.world.World getWorld() { + public World getWorld() { return FabricWorldEdit.inst.getWorld(this.player.world); } @@ -188,6 +188,20 @@ public class FabricPlayer extends AbstractPlayerActor { return null; } + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + if (alwaysGlass || !player.abilities.allowFlying) { + super.floatAt(x, y, z, alwaysGlass); + return; + } + + setPosition(Vector3.at(x + 0.5, y, z + 0.5)); + if (!player.abilities.flying) { + player.abilities.flying = true; + player.sendAbilitiesUpdate(); + } + } + @Override public > void sendFakeBlock(BlockVector3 pos, B block) { World world = getWorld(); diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index a48ff6256..e55761da3 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -107,7 +107,7 @@ public class ForgePlayer extends AbstractPlayerActor { } @Override - public com.sk89q.worldedit.world.World getWorld() { + public World getWorld() { return ForgeWorldEdit.inst.getWorld(this.player.world); } @@ -189,6 +189,20 @@ public class ForgePlayer extends AbstractPlayerActor { return null; } + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + if (alwaysGlass || !player.abilities.allowFlying) { + super.floatAt(x, y, z, alwaysGlass); + return; + } + + setPosition(Vector3.at(x + 0.5, y, z + 0.5)); + if (!player.abilities.isFlying) { + player.abilities.isFlying = true; + player.sendPlayerAbilities(); + } + } + @Override public > void sendFakeBlock(BlockVector3 pos, B block) { World world = getWorld(); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 82723fe93..45fc43000 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -38,6 +38,7 @@ import com.sk89q.worldedit.world.gamemode.GameMode; import com.sk89q.worldedit.world.gamemode.GameModes; import com.sk89q.worldedit.world.item.ItemTypes; import org.spongepowered.api.Sponge; +import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.type.HandTypes; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.item.ItemType; @@ -202,6 +203,17 @@ public class SpongePlayer extends AbstractPlayerActor { gameMode.getId()).get()); } + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + if (alwaysGlass || !player.get(Keys.CAN_FLY).orElse(false)) { + super.floatAt(x, y, z, alwaysGlass); + return; + } + + setPosition(Vector3.at(x + 0.5, y, z + 0.5)); + player.offer(Keys.IS_FLYING, true); + } + @Override public > void sendFakeBlock(BlockVector3 pos, B block) { org.spongepowered.api.world.Location loc = player.getWorld().getLocation(pos.getX(), pos.getY(), pos.getZ());