PaperMC/patches/server/0412-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch
Jake Potrebic 27e29ccaf2
487/1053
2024-06-13 13:57:13 -07:00

83 lines
5.3 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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 3387622f107a46efa7fda14d5994f192c6854dc2..25b82b15d67f1c37d6897aaeefa00ee2852d0865 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -679,7 +679,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 - Fix Entity Teleportation and cancel velocity if teleported
this.lastGoodX = this.awaitingPositionFromClient.x;
this.lastGoodY = this.awaitingPositionFromClient.y;
this.lastGoodZ = this.awaitingPositionFromClient.z;
@@ -1595,7 +1595,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 - Fix Entity Teleportation and cancel velocity if teleported
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 f2855de7320dc9532d0b568b84b0b7e5a2064045..1e65bfa3d2f3a178803c530e1610c94065ed6110 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -171,6 +171,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
+ public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first setPositionRotation
static boolean isLevelAtLeast(CompoundTag tag, int level) {
return tag.contains("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
}
@@ -1874,6 +1875,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public void moveTo(double x, double y, double z, float yaw, float pitch) {
+ // Paper start - Fix Entity Teleportation and cancel velocity if teleported
+ if (!preserveMotion) {
+ this.deltaMovement = Vec3.ZERO;
+ } else {
+ this.preserveMotion = false;
+ }
+ // Paper end - Fix Entity Teleportation and cancel velocity if teleported
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 b90127f9f805fdb5bb43a4b8ad2b10499b0b6b78..8efc06d29c62fa2be8515ed3359d52a6d4b807d2 100644
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
@@ -164,6 +164,7 @@ public abstract class BaseSpawner {
return;
}
+ entity.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; 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 34321f095e12ea0cca34ff1ec00819c6350205a8..5f5788a502642463091fb76e98703aaec7a86836 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -240,7 +240,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());