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 101871664077577c5cbe159d5d1a31b0e30ec68d..5550f60424d827616c935e3b0036f1b4f6144e5c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -657,7 +657,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl 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; @@ -1587,7 +1587,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // 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 a1172531baf637915a65fbdee8ca08f08034811d..ec224193e9ca7734fe533d5cfc0e316d5eed2adb 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -162,6 +162,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S // 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; } @@ -1871,6 +1872,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } 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 0578ac12d92f9af0b0113587db9351b4a41bedd5..9f677a695bdb8ebde457452e4b70c674e2016830 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -169,6 +169,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 c17bb16567ad2354dc80e710469730b1dbc55b08..d5e8c8ed7528cdac203a7594ccf9576db0e5f019 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -237,7 +237,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());