From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 25 Aug 2020 20:45:36 -0400 Subject: [PATCH] Fix Entity Teleportation and cancel velocity if teleported Uses correct setPositionRotation for Entity teleporting instead of setLocation as this is how Vanilla teleports entities. Cancel any pending motion when teleported. diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 6aeea48d4cf4732f6a5a5dba12af873c2aee493b..fa0256a99c833e6035b8d3e873a93af2b674ef52 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -54,6 +54,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke // CraftBukkit start private static final int CURRENT_LEVEL = 2; + boolean preserveMotion = true; // Paper - keep initial motion on first setPositionRotation static boolean isLevelAtLeast(NBTTagCompound tag, int level) { return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; } @@ -1317,6 +1318,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public void setPositionRotation(double d0, double d1, double d2, float f, float f1) { + // Paper - cancel entity velocity if teleported + if (!preserveMotion) { + this.mot = Vec3D.ORIGIN; + } else { + this.preserveMotion = false; + } + // Paper end this.g(d0, d1, d2); this.yaw = f; this.pitch = f1; diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java index 4606837f94fc5dced95dc08fbafa3b578404e81d..bb429358c558171134ba2aa188722f69f15858c8 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -544,7 +544,7 @@ public class PlayerConnection implements PacketListenerPlayIn { public void a(PacketPlayInTeleportAccept packetplayinteleportaccept) { PlayerConnectionUtils.ensureMainThread(packetplayinteleportaccept, this, this.player.getWorldServer()); if (packetplayinteleportaccept.b() == this.teleportAwait && this.teleportPos != null) { // CraftBukkit - this.player.setLocation(this.teleportPos.x, this.teleportPos.y, this.teleportPos.z, this.player.yaw, this.player.pitch); + this.player.setPositionRotation(this.teleportPos.x, this.teleportPos.y, this.teleportPos.z, this.player.yaw, this.player.pitch); // Paper - use proper setPositionRotation for teleportation this.o = this.teleportPos.x; this.p = this.teleportPos.y; this.q = this.teleportPos.z; @@ -1376,7 +1376,7 @@ public class PlayerConnection implements PacketListenerPlayIn { // CraftBukkit end this.A = this.e; - this.player.setLocation(d0, d1, d2, f, f1); + this.player.setPositionRotation(d0, d1, d2, f, f1); // Paper - use proper setPositionRotation for teleportation this.player.forceCheckHighPriority(); // Paper this.player.playerConnection.sendPacket(new PacketPlayOutPosition(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.teleportAwait)); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index eae7509b5b072cba86015aad1e878aa752fc7b33..e19db32edc5124a86e8123dcc13be9f5a439ee74 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -548,7 +548,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // entity.setLocation() throws no event, and so cannot be cancelled - entity.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + entity.setPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); // Paper - use proper setPosition, as per vanilla teleporting // SPIGOT-619: Force sync head rotation also entity.setHeadRotation(location.getYaw()); ((net.minecraft.server.WorldServer) entity.world).chunkCheck(entity); // Spigot - register to new chunk