aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0566-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch
blob: 2221f6a578c36b9f62131ee322e1fa5ad3f564a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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/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 e1927f019dfbabab9af357294c4b73fa41bd3f2e..ec163bf527120a19cdc9fd7ccd69b6eb83d0bb54 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;
     }
@@ -1409,6 +1410,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