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/network/PlayerConnection.java b/src/main/java/net/minecraft/server/network/PlayerConnection.java index d3449dc9eeba0d8022c3a7b0280eaffcd42e7265..fe3bd1c54a7e366bd4f02b417f7725bae60a3ca2 100644 --- a/src/main/java/net/minecraft/server/network/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/network/PlayerConnection.java @@ -693,7 +693,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; @@ -1538,7 +1538,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/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 743d4725c0a26a8abd0a98eed2ec45ffba6211ad..58d9dce288ab9cc1989cfcb66703b76fdabf1319 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -145,6 +145,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne // CraftBukkit start private static final int CURRENT_LEVEL = 2; + public 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; } @@ -1408,6 +1409,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne } 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/world/level/MobSpawnerAbstract.java b/src/main/java/net/minecraft/world/level/MobSpawnerAbstract.java index 5538404456dfee42257fad9040fcc0fefdfc5fab..33a5dbcc11455f81088d9fd685a8c4b1b8f4b1f2 100644 --- a/src/main/java/net/minecraft/world/level/MobSpawnerAbstract.java +++ b/src/main/java/net/minecraft/world/level/MobSpawnerAbstract.java @@ -165,6 +165,7 @@ public abstract class MobSpawnerAbstract { return; } + entity.preserveMotion = true; // Paper - preserve entity motion from tag entity.setPositionRotation(entity.locX(), entity.locY(), entity.locZ(), world.random.nextFloat() * 360.0F, 0.0F); if (entity instanceof EntityInsentient) { EntityInsentient entityinsentient = (EntityInsentient) entity; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 387f6f6fa9bbb1cce544cfb907f68c7993752dd7..fb52a60437d48282f3e99e7eccb0e76b446155f9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -558,7 +558,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.level.WorldServer) entity.world).chunkCheck(entity); // Spigot - register to new chunk