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/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 4d2adbf45387b63f60b4a8170906752555a19178..ef3771b178d8d966edb83773186dcfac0fda8e3e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -752,7 +752,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic return; } - this.player.absMoveTo(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot()); + this.player.moveTo(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot()); // Paper - use proper moveTo for teleportation this.lastGoodX = this.awaitingPositionFromClient.x; this.lastGoodY = this.awaitingPositionFromClient.y; this.lastGoodZ = this.awaitingPositionFromClient.z; @@ -1657,7 +1657,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic // CraftBukkit end this.awaitingTeleportTime = this.tickCount; - this.player.absMoveTo(d0, d1, d2, f, f1); + this.player.moveTo(d0, d1, d2, f, f1); // Paper - use proper moveTo for teleportation this.player.connection.send(new ClientboundPlayerPositionPacket(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.awaitingTeleport)); } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 24ba8dc2a5fc72ade003fa14d337f2c64a0e654e..f8f0be4ebb097c26461ea0fcbce7914ce84e87ed 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -159,6 +159,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { // CraftBukkit start private static final int CURRENT_LEVEL = 2; + public boolean preserveMotion = true; // Paper - keep initial motion on first setPositionRotation static boolean isLevelAtLeast(CompoundTag tag, int level) { return tag.contains("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; } @@ -1737,6 +1738,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public void moveTo(double x, double y, double z, float yaw, float pitch) { + // Paper - cancel entity velocity if teleported + if (!preserveMotion) { + this.deltaMovement = Vec3.ZERO; + } else { + this.preserveMotion = false; + } + // Paper end this.setPosRaw(x, y, z); this.setYRot(yaw); this.setXRot(pitch); diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java index 54a20433483d5b67a6668fcdbddc1654a246fee2..9bf1a37ea8436f3314b28914ae8b1516378eb465 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -167,6 +167,7 @@ public abstract class BaseSpawner { return; } + entity.preserveMotion = true; // Paper - preserve entity motion from tag entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), randomsource.nextFloat() * 360.0F, 0.0F); if (entity instanceof Mob) { Mob entityinsentient = (Mob) entity; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 7dfa1884a7b4cdbfc83e62caf96acf8ca65a2a73..841e027722f277649ed1b97464f8fca1e290a809 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -574,7 +574,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // entity.setLocation() throws no event, and so cannot be cancelled - this.entity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + entity.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); // Paper - use proper moveTo, as per vanilla teleporting // SPIGOT-619: Force sync head rotation also this.entity.setYHeadRot(location.getYaw());