84 lines
5.4 KiB
Diff
84 lines
5.4 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 ab6494f5a872bba5398bef0367b4d9257786f61e..ab45497e8f7720c9d60626b32e9c95779af676b0 100644
|
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
@@ -691,7 +691,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
|
|
public void handleAcceptTeleportPacket(ServerboundAcceptTeleportationPacket packet) {
|
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
|
|
if (packet.getId() == this.awaitingTeleport && this.awaitingPositionFromClient != null) { // CraftBukkit
|
|
- this.player.absMoveTo(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.yRot, this.player.xRot);
|
|
+ this.player.moveTo(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.yRot, this.player.xRot); // Paper - use proper setPositionRotation for teleportation
|
|
this.lastGoodX = this.awaitingPositionFromClient.x;
|
|
this.lastGoodY = this.awaitingPositionFromClient.y;
|
|
this.lastGoodZ = this.awaitingPositionFromClient.z;
|
|
@@ -1536,7 +1536,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
|
|
// 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 setPositionRotation for teleportation
|
|
this.player.forceCheckHighPriority(); // Paper
|
|
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 aea2457510c75214bbb925307155611e981f115f..d69981a1b5a40418c7d17de5f3bece30592ae586 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
@@ -143,6 +143,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.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;
|
|
}
|
|
@@ -1406,6 +1407,13 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.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.setPosAndOldPos(x, y, z);
|
|
this.yRot = yaw;
|
|
this.xRot = pitch;
|
|
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
|
index 6ca378ec7868b855d46c749910c656f82ddb009f..091e72474ac199c38fff979a5faf524e011d8d0a 100644
|
|
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
|
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
|
@@ -165,6 +165,7 @@ public abstract class BaseSpawner {
|
|
return;
|
|
}
|
|
|
|
+ entity.preserveMotion = true; // Paper - preserve entity motion from tag
|
|
entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), world.random.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 deeae62e9926f9435907c68e7d35e7420f5e79dd..1275768762884416fa3c68dab3a6671b24949976 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
@@ -556,7 +556,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
|
}
|
|
|
|
// entity.setLocation() throws no event, and so cannot be cancelled
|
|
- 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 setPosition, as per vanilla teleporting
|
|
// SPIGOT-619: Force sync head rotation also
|
|
entity.setYHeadRot(location.getYaw());
|
|
((net.minecraft.server.level.ServerLevel) entity.level).updateChunkPos(entity); // Spigot - register to new chunk
|