Paper/patches/server/0438-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch
2024-04-24 08:11:27 -04:00

84 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 36ff9acf571d670fda225bce2f4ed16dc1d20fe3..07c5c01c2f5c18b1d6162275ca091b0ababd72c5 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -656,7 +656,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;
@@ -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 - 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 0c6680bf15b57cf314638ab70d849e033719c0e1..f45b148884b305628411d57f7662ea454fde3906 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 - 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;
}
@@ -1785,6 +1786,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
}
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 b771f954f3fccd92e15196bf542e0d3703cfb71a..41d2793e69bd664456b5e3c5891b03bdcb31d103 100644
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
@@ -162,6 +162,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 326978aedbd9cc81db2bf1d5398c1cd2ce68a866..f664fd4aa8d79e95787848b5a3e0ed7bc182fa25 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -238,7 +238,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());