aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0465-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch
blob: 13969fdbb1ac43be1bfdd361512782e9255879a5 (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/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index b72e6df4cfc0426577b52cf495f0373c7ceecd02..e46c245801943b95f1477a2e53be5571efa63d91 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -760,7 +760,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;
@@ -1659,7 +1659,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 5a1959a16070a49e935bfd7a43fbf3fabdd2b1e6..11675a7611a42277ed0625509aa98a2f69611698 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;
     }
@@ -1856,6 +1857,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 3f70734857e0fe15e0c3f26253fcff61bad8db7f..3dd97f489f2d792d97b23526bfab67fb150e5c95 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 - 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 ab20f96f545871da8928e026f8bbffae9f56213a..85f02e1e080eb5b05061afcf73dac659619d9673 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -580,7 +580,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());