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.
This commit is contained in:
Aikar 2020-08-25 20:45:36 -04:00
parent 74de6853f4
commit aebf9e869b
6 changed files with 144 additions and 109 deletions

View File

@ -48,7 +48,7 @@
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.Level;
@@ -192,12 +196,73 @@
@@ -192,11 +196,72 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
@ -59,7 +59,7 @@
import net.minecraft.world.phys.shapes.VoxelShape;
+import org.bukkit.NamespacedKey;
import org.slf4j.Logger;
+
+// CraftBukkit start
+import io.papermc.paper.adventure.ChatProcessor; // Paper
+import io.papermc.paper.adventure.PaperAdventure; // Paper
@ -118,10 +118,9 @@
+import org.bukkit.inventory.InventoryView;
+import org.bukkit.inventory.SmithingInventory;
+// CraftBukkit end
+
public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener {
static final Logger LOGGER = LogUtils.getLogger();
@@ -212,6 +277,7 @@
private int tickCount;
private int ackBlockChangesUpTo = -1;
@ -279,7 +278,7 @@
ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8});
this.send(ClientboundMoveVehiclePacket.fromEntity(entity));
return;
@@ -449,19 +583,72 @@
@@ -449,20 +583,73 @@
d10 = d6 * d6 + d7 * d7 + d8 * d8;
boolean flag2 = false;
@ -298,8 +297,8 @@
+ this.player.absMoveTo(d0, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
this.send(ClientboundMoveVehiclePacket.fromEntity(entity));
return;
+ }
+
}
+ // CraftBukkit start - fire PlayerMoveEvent
+ Player player = this.getCraftPlayer();
+ if (!this.hasMoved) {
@ -348,12 +347,20 @@
+ this.justTeleported = false;
+ return;
+ }
}
+ }
+ // CraftBukkit end
+
this.player.serverLevel().getChunkSource().move(this.player);
entity.recordMovementThroughBlocks(new Vec3(d0, d1, d2), entity.position());
@@ -499,6 +686,7 @@
Vec3 vec3d = new Vec3(entity.getX() - d0, entity.getY() - d1, entity.getZ() - d2);
@@ -493,12 +680,13 @@
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;
this.player.hasChangedDimension();
this.awaitingPositionFromClient = null;
@ -629,8 +636,8 @@
+ if (i > Math.max(this.allowedPlayerTicks, 5)) {
ServerGamePacketListenerImpl.LOGGER.debug("{} is sending move packets too frequently ({} packets since last tick)", this.player.getName().getString(), i);
i = 1;
+ }
+
}
+ if (packet.hasRot || d10 > 0) {
+ this.allowedPlayerTicks -= 1;
+ } else {
@ -646,9 +653,9 @@
+ if (this.player.level().paperConfig().chunks.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position())))) {
+ this.internalTeleport(PositionMoveRotation.of(this.player), Collections.emptySet());
+ return;
}
+ }
+ // Paper end - Prevent moving into unloaded chunks
+
if (this.shouldCheckPlayerMovement(flag)) {
float f2 = flag ? 300.0F : 100.0F;

View File

@ -18,7 +18,7 @@
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.FenceGateBlock;
@@ -138,9 +138,141 @@
@@ -138,9 +138,142 @@
import net.minecraft.world.scores.ScoreHolder;
import net.minecraft.world.scores.Team;
import org.slf4j.Logger;
@ -64,6 +64,7 @@
+
+ // 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;
+ }
@ -160,7 +161,7 @@
private static final Logger LOGGER = LogUtils.getLogger();
public static final String ID_TAG = "id";
public static final String PASSENGERS_TAG = "Passengers";
@@ -224,7 +356,7 @@
@@ -224,7 +357,7 @@
private static final EntityDataAccessor<Boolean> DATA_CUSTOM_NAME_VISIBLE = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Boolean> DATA_SILENT = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Boolean> DATA_NO_GRAVITY = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN);
@ -169,7 +170,7 @@
private static final EntityDataAccessor<Integer> DATA_TICKS_FROZEN = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.INT);
private EntityInLevelCallback levelCallback;
private final VecDeltaCodec packetPositionCodec;
@@ -253,6 +385,64 @@
@@ -253,7 +386,65 @@
private final List<Entity.Movement> movementThisTick;
private final Set<BlockState> blocksInside;
private final LongSet visitedBlocks;
@ -202,7 +203,7 @@
+ private org.bukkit.util.Vector origin;
+ @javax.annotation.Nullable
+ private UUID originWorld;
+
+ public void setOrigin(@javax.annotation.Nonnull Location location) {
+ this.origin = location.toVector();
+ this.originWorld = location.getWorld().getUID();
@ -231,10 +232,11 @@
+ return this.dimensions.makeBoundingBox(x, y, z);
+ }
+ // Paper end
+
public Entity(EntityType<?> type, Level world) {
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
@@ -261,7 +451,7 @@
this.passengers = ImmutableList.of();
@@ -261,7 +452,7 @@
this.bb = Entity.INITIAL_AABB;
this.stuckSpeedMultiplier = Vec3.ZERO;
this.nextStep = 1.0F;
@ -243,7 +245,7 @@
this.remainingFireTicks = -this.getFireImmuneTicks();
this.fluidHeight = new Object2DoubleArrayMap(2);
this.fluidOnEyes = new HashSet();
@@ -284,6 +474,13 @@
@@ -284,6 +475,13 @@
this.position = Vec3.ZERO;
this.blockPosition = BlockPos.ZERO;
this.chunkPosition = ChunkPos.ZERO;
@ -257,7 +259,7 @@
SynchedEntityData.Builder datawatcher_a = new SynchedEntityData.Builder(this);
datawatcher_a.define(Entity.DATA_SHARED_FLAGS_ID, (byte) 0);
@@ -292,7 +489,7 @@
@@ -292,7 +490,7 @@
datawatcher_a.define(Entity.DATA_CUSTOM_NAME, Optional.empty());
datawatcher_a.define(Entity.DATA_SILENT, false);
datawatcher_a.define(Entity.DATA_NO_GRAVITY, false);
@ -266,7 +268,7 @@
datawatcher_a.define(Entity.DATA_TICKS_FROZEN, 0);
this.defineSynchedData(datawatcher_a);
this.entityData = datawatcher_a.build();
@@ -362,20 +559,36 @@
@@ -362,20 +560,36 @@
}
public void kill(ServerLevel world) {
@ -305,7 +307,7 @@
public boolean equals(Object object) {
return object instanceof Entity ? ((Entity) object).id == this.id : false;
}
@@ -385,22 +598,34 @@
@@ -385,22 +599,34 @@
}
public void remove(Entity.RemovalReason reason) {
@ -345,7 +347,7 @@
return this.getPose() == pose;
}
@@ -417,6 +642,33 @@
@@ -417,6 +643,33 @@
}
public void setRot(float yaw, float pitch) {
@ -379,7 +381,7 @@
this.setYRot(yaw % 360.0F);
this.setXRot(pitch % 360.0F);
}
@@ -426,8 +678,8 @@
@@ -426,8 +679,8 @@
}
public void setPos(double x, double y, double z) {
@ -390,7 +392,7 @@
}
protected final AABB makeBoundingBox() {
@@ -462,6 +714,15 @@
@@ -462,6 +715,15 @@
this.baseTick();
}
@ -406,7 +408,7 @@
public void baseTick() {
ProfilerFiller gameprofilerfiller = Profiler.get();
@@ -475,7 +736,7 @@
@@ -475,7 +737,7 @@
--this.boardingCooldown;
}
@ -415,7 +417,7 @@
if (this.canSpawnSprintParticle()) {
this.spawnSprintParticle();
}
@@ -514,6 +775,10 @@
@@ -514,6 +776,10 @@
if (this.isInLava()) {
this.lavaHurt();
this.fallDistance *= 0.5F;
@ -426,7 +428,7 @@
}
this.checkBelowWorld();
@@ -525,7 +790,7 @@
@@ -525,7 +791,7 @@
world = this.level();
if (world instanceof ServerLevel worldserver) {
if (this instanceof Leashable) {
@ -435,7 +437,7 @@
}
}
@@ -537,7 +802,11 @@
@@ -537,7 +803,11 @@
}
public void checkBelowWorld() {
@ -448,7 +450,7 @@
this.onBelowWorld();
}
@@ -568,15 +837,32 @@
@@ -568,15 +838,32 @@
public void lavaHurt() {
if (!this.fireImmune()) {
@ -483,7 +485,7 @@
}
}
@@ -587,9 +873,25 @@
@@ -587,9 +874,25 @@
}
public final void igniteForSeconds(float seconds) {
@ -510,7 +512,7 @@
public void igniteForTicks(int ticks) {
if (this.remainingFireTicks < ticks) {
this.setRemainingFireTicks(ticks);
@@ -610,7 +912,7 @@
@@ -610,7 +913,7 @@
}
protected void onBelowWorld() {
@ -519,10 +521,13 @@
}
public boolean isFree(double offsetX, double offsetY, double offsetZ) {
@@ -750,6 +1052,28 @@
}
}
@@ -747,8 +1050,30 @@
if (movement.y != vec3d1.y) {
block.updateEntityMovementAfterFallOn(this.level(), this);
+ }
+ }
+
+ // CraftBukkit start
+ if (this.horizontalCollision && this.getBukkitEntity() instanceof Vehicle) {
+ Vehicle vehicle = (Vehicle) this.getBukkitEntity();
@ -541,14 +546,13 @@
+ if (!bl.getType().isAir()) {
+ VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl);
+ this.level.getCraftServer().getPluginManager().callEvent(event);
+ }
+ }
}
}
+ // CraftBukkit end
+
if (!this.level().isClientSide() || this.isControlledByLocalInstance()) {
Entity.MovementEmission entity_movementemission = this.getMovementEmission();
@@ -1131,8 +1455,22 @@
@@ -1131,8 +1456,22 @@
protected SoundEvent getSwimHighSpeedSplashSound() {
return SoundEvents.GENERIC_SPLASH;
@ -571,7 +575,7 @@
public void recordMovementThroughBlocks(Vec3 oldPos, Vec3 newPos) {
this.movementThisTick.add(new Entity.Movement(oldPos, newPos));
}
@@ -1609,6 +1947,7 @@
@@ -1609,6 +1948,7 @@
this.yo = y;
this.zo = d4;
this.setPos(d3, y, d4);
@ -579,7 +583,21 @@
}
public void moveTo(Vec3 pos) {
@@ -1737,7 +2076,21 @@
@@ -1628,6 +1968,13 @@
}
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);
@@ -1737,7 +2084,21 @@
}
public void push(double deltaX, double deltaY, double deltaZ) {
@ -602,20 +620,21 @@
this.hasImpulse = true;
}
@@ -1861,6 +2214,12 @@
return false;
}
@@ -1859,7 +2220,13 @@
public boolean isPushable() {
return false;
+ }
+
+ // CraftBukkit start - collidable API
+ public boolean canCollideWithBukkit(Entity entity) {
+ return this.isPushable();
+ }
}
+ // CraftBukkit end
+
public void awardKillScore(Entity entityKilled, DamageSource damageSource) {
if (entityKilled instanceof ServerPlayer) {
CriteriaTriggers.ENTITY_KILLED_PLAYER.trigger((ServerPlayer) entityKilled, this, damageSource);
@@ -1889,16 +2248,22 @@
@@ -1889,16 +2256,22 @@
}
public boolean saveAsPassenger(CompoundTag nbt) {
@ -641,7 +660,7 @@
return true;
}
}
@@ -1909,54 +2274,98 @@
@@ -1909,54 +2282,98 @@
}
public CompoundTag saveWithoutId(CompoundTag nbt) {
@ -760,7 +779,7 @@
}
ListTag nbttaglist;
@@ -1972,10 +2381,10 @@
@@ -1972,10 +2389,10 @@
nbttaglist.add(StringTag.valueOf(s));
}
@ -773,7 +792,7 @@
if (this.isVehicle()) {
nbttaglist = new ListTag();
iterator = this.getPassengers().iterator();
@@ -1984,17 +2393,41 @@
@@ -1984,17 +2401,41 @@
Entity entity = (Entity) iterator.next();
CompoundTag nbttagcompound1 = new CompoundTag();
@ -818,11 +837,10 @@
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT");
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being saved");
@@ -2079,7 +2512,69 @@
}
@@ -2080,6 +2521,68 @@
} else {
throw new IllegalStateException("Entity has invalid position");
+ }
}
+
+ // CraftBukkit start
+ // Spigot start
@ -845,7 +863,7 @@
+ boolean bukkitInvisible = nbt.getBoolean("Bukkit.invisible");
+ this.setInvisible(bukkitInvisible);
+ this.persistentInvisibility = bukkitInvisible;
}
+ }
+ // CraftBukkit end
+
+ // Paper start
@ -888,7 +906,7 @@
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT");
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded");
@@ -2101,6 +2596,12 @@
@@ -2101,6 +2604,12 @@
return entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null;
}
@ -901,7 +919,7 @@
protected abstract void readAdditionalSaveData(CompoundTag nbt);
protected abstract void addAdditionalSaveData(CompoundTag nbt);
@@ -2153,9 +2654,23 @@
@@ -2153,9 +2662,23 @@
if (stack.isEmpty()) {
return null;
} else {
@ -926,7 +944,7 @@
world.addFreshEntity(entityitem);
return entityitem;
}
@@ -2184,6 +2699,12 @@
@@ -2184,6 +2707,12 @@
if (this.isAlive() && this instanceof Leashable leashable) {
if (leashable.getLeashHolder() == player) {
if (!this.level().isClientSide()) {
@ -939,7 +957,7 @@
if (player.hasInfiniteMaterials()) {
leashable.removeLeash();
} else {
@@ -2200,6 +2721,13 @@
@@ -2200,6 +2729,13 @@
if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) {
if (!this.level().isClientSide()) {
@ -953,7 +971,7 @@
leashable.setLeashedTo(player, true);
}
@@ -2265,7 +2793,7 @@
@@ -2265,7 +2801,7 @@
}
public boolean showVehicleHealth() {
@ -962,7 +980,7 @@
}
public boolean startRiding(Entity entity, boolean force) {
@@ -2273,7 +2801,7 @@
@@ -2273,7 +2809,7 @@
return false;
} else if (!entity.couldAcceptPassenger()) {
return false;
@ -971,7 +989,7 @@
return false;
} else {
for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) {
@@ -2285,11 +2813,32 @@
@@ -2285,11 +2821,32 @@
if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) {
return false;
} else {
@ -1005,7 +1023,7 @@
this.vehicle = entity;
this.vehicle.addPassenger(this);
entity.getIndirectPassengersStream().filter((entity2) -> {
@@ -2314,19 +2863,30 @@
@@ -2314,19 +2871,30 @@
}
public void removeVehicle() {
@ -1038,7 +1056,7 @@
protected void addPassenger(Entity passenger) {
if (passenger.getVehicle() != this) {
throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");
@@ -2349,21 +2909,53 @@
@@ -2349,21 +2917,53 @@
}
}
@ -1098,7 +1116,7 @@
}
protected boolean canAddPassenger(Entity passenger) {
@@ -2464,7 +3056,7 @@
@@ -2464,7 +3064,7 @@
if (teleporttransition != null) {
ServerLevel worldserver1 = teleporttransition.newLevel();
@ -1107,7 +1125,7 @@
this.teleport(teleporttransition);
}
}
@@ -2547,7 +3139,7 @@
@@ -2547,7 +3147,7 @@
}
public boolean isCrouching() {
@ -1116,7 +1134,7 @@
}
public boolean isSprinting() {
@@ -2563,7 +3155,7 @@
@@ -2563,7 +3163,7 @@
}
public boolean isVisuallySwimming() {
@ -1125,7 +1143,7 @@
}
public boolean isVisuallyCrawling() {
@@ -2571,6 +3163,13 @@
@@ -2571,6 +3171,13 @@
}
public void setSwimming(boolean swimming) {
@ -1139,7 +1157,7 @@
this.setSharedFlag(4, swimming);
}
@@ -2609,6 +3208,7 @@
@@ -2609,6 +3216,7 @@
@Nullable
public PlayerTeam getTeam() {
@ -1147,7 +1165,7 @@
return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName());
}
@@ -2624,8 +3224,12 @@
@@ -2624,8 +3232,12 @@
return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false;
}
@ -1161,7 +1179,7 @@
}
public boolean getSharedFlag(int index) {
@@ -2644,7 +3248,7 @@
@@ -2644,7 +3256,7 @@
}
public int getMaxAirSupply() {
@ -1170,7 +1188,7 @@
}
public int getAirSupply() {
@@ -2652,7 +3256,18 @@
@@ -2652,7 +3264,18 @@
}
public void setAirSupply(int air) {
@ -1190,7 +1208,7 @@
}
public int getTicksFrozen() {
@@ -2679,11 +3294,40 @@
@@ -2679,11 +3302,40 @@
public void thunderHit(ServerLevel world, LightningBolt lightning) {
this.setRemainingFireTicks(this.remainingFireTicks + 1);
@ -1233,7 +1251,7 @@
}
public void onAboveBubbleCol(boolean drag) {
@@ -2713,7 +3357,7 @@
@@ -2713,7 +3365,7 @@
this.resetFallDistance();
}
@ -1242,7 +1260,7 @@
return true;
}
@@ -2818,7 +3462,7 @@
@@ -2818,7 +3470,7 @@
public String toString() {
String s = this.level() == null ? "~NULL~" : this.level().toString();
@ -1251,7 +1269,7 @@
}
public final boolean isInvulnerableToBase(DamageSource damageSource) {
@@ -2850,8 +3494,34 @@
@@ -2850,8 +3502,34 @@
public Entity teleport(TeleportTransition teleportTarget) {
Level world = this.level();
@ -1286,7 +1304,7 @@
ServerLevel worldserver1 = teleportTarget.newLevel();
boolean flag = worldserver1.dimension() != worldserver.dimension();
@@ -2918,10 +3588,19 @@
@@ -2918,10 +3596,19 @@
gameprofilerfiller.pop();
return null;
} else {
@ -1307,7 +1325,7 @@
Iterator iterator1 = list1.iterator();
while (iterator1.hasNext()) {
@@ -2947,7 +3626,7 @@
@@ -2947,7 +3634,7 @@
}
private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) {
@ -1316,7 +1334,7 @@
Iterator iterator = this.getIndirectPassengers().iterator();
while (iterator.hasNext()) {
@@ -2995,8 +3674,9 @@
@@ -2995,8 +3682,9 @@
}
protected void removeAfterChangingDimensions() {
@ -1327,7 +1345,7 @@
leashable.removeLeash();
}
@@ -3006,11 +3686,26 @@
@@ -3006,11 +3694,26 @@
return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose()));
}
@ -1354,7 +1372,7 @@
if (from.dimension() == Level.END && to.dimension() == Level.OVERWORLD) {
Iterator iterator = this.getPassengers().iterator();
@@ -3134,10 +3829,16 @@
@@ -3134,10 +3837,16 @@
return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE);
}
@ -1374,7 +1392,7 @@
return entity != null;
}
@@ -3187,7 +3888,7 @@
@@ -3187,7 +3896,7 @@
/** @deprecated */
@Deprecated
protected void fixupDimensions() {
@ -1383,7 +1401,7 @@
EntityDimensions entitysize = this.getDimensions(entitypose);
this.dimensions = entitysize;
@@ -3196,7 +3897,7 @@
@@ -3196,7 +3905,7 @@
public void refreshDimensions() {
EntityDimensions entitysize = this.dimensions;
@ -1392,7 +1410,7 @@
EntityDimensions entitysize1 = this.getDimensions(entitypose);
this.dimensions = entitysize1;
@@ -3258,10 +3959,29 @@
@@ -3258,10 +3967,29 @@
}
public final void setBoundingBox(AABB boundingBox) {
@ -1424,7 +1442,7 @@
return this.getDimensions(pose).eyeHeight();
}
@@ -3335,7 +4055,7 @@
@@ -3335,7 +4063,7 @@
}
@Nullable
@ -1433,7 +1451,7 @@
return null;
}
@@ -3435,7 +4155,7 @@
@@ -3435,7 +4163,7 @@
}
public boolean isControlledByLocalInstance() {
@ -1442,7 +1460,7 @@
if (entityliving instanceof Player entityhuman) {
return entityhuman.isLocalPlayer();
@@ -3445,7 +4165,7 @@
@@ -3445,7 +4173,7 @@
}
public boolean isControlledByClient() {
@ -1451,7 +1469,7 @@
return entityliving != null && entityliving.isControlledByClient();
}
@@ -3463,7 +4183,7 @@
@@ -3463,7 +4191,7 @@
return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3);
}
@ -1460,11 +1478,10 @@
return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ());
}
@@ -3488,9 +4208,38 @@
public int getFireImmuneTicks() {
@@ -3489,8 +4217,37 @@
return 1;
}
+
+ // CraftBukkit start
+ private final CommandSource commandSource = new CommandSource() {
+
@ -1493,14 +1510,14 @@
+ }
+ };
+ // CraftBukkit end
+
public CommandSourceStack createCommandSourceStackForNameResolution(ServerLevel world) {
- return new CommandSourceStack(CommandSource.NULL, this.position(), this.getRotationVector(), world, 0, this.getName().getString(), this.getDisplayName(), world.getServer(), this);
+ return new CommandSourceStack(this.commandSource, this.position(), this.getRotationVector(), world, 0, this.getName().getString(), this.getDisplayName(), world.getServer(), this); // CraftBukkit
}
public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) {
@@ -3551,6 +4300,11 @@
@@ -3551,6 +4308,11 @@
vec3d = vec3d.add(vec3d1);
++k1;
}
@ -1512,7 +1529,7 @@
}
}
}
@@ -3613,7 +4367,7 @@
@@ -3613,7 +4375,7 @@
return new ClientboundAddEntityPacket(this, entityTrackerEntry);
}
@ -1521,7 +1538,7 @@
return this.type.getDimensions();
}
@@ -3714,7 +4468,29 @@
@@ -3714,7 +4476,29 @@
return this.getZ((2.0D * this.random.nextDouble() - 1.0D) * widthScale);
}
@ -1551,7 +1568,7 @@
if (this.position.x != x || this.position.y != y || this.position.z != z) {
this.position = new Vec3(x, y, z);
int i = Mth.floor(x);
@@ -3732,6 +4508,12 @@
@@ -3732,6 +4516,12 @@
this.levelCallback.onMove();
}
@ -1564,7 +1581,7 @@
}
public void checkDespawn() {}
@@ -3818,8 +4600,16 @@
@@ -3818,8 +4608,16 @@
@Override
public final void setRemoved(Entity.RemovalReason reason) {
@ -1582,7 +1599,7 @@
}
if (this.removalReason.shouldDestroy()) {
@@ -3827,8 +4617,8 @@
@@ -3827,8 +4625,8 @@
}
this.getPassengers().forEach(Entity::stopRiding);
@ -1593,7 +1610,7 @@
}
public void unsetRemoved() {
@@ -3887,7 +4677,7 @@
@@ -3887,7 +4685,7 @@
}
public Vec3 getKnownMovement() {

View File

@ -1,8 +1,10 @@
--- a/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
+++ b/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
@@ -80,7 +80,9 @@
@@ -79,8 +79,11 @@
}
DragonFireball dragonFireball = new DragonFireball(world, this.dragon, vec34.normalize());
+ dragonFireball.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported
dragonFireball.moveTo(o, p, q, 0.0F, 0.0F);
+ if (new com.destroystokyo.paper.event.entity.EnderDragonShootFireballEvent((org.bukkit.entity.EnderDragon) dragon.getBukkitEntity(), (org.bukkit.entity.DragonFireball) dragonFireball.getBukkitEntity()).callEvent()) // Paper - EnderDragon Events
world.addFreshEntity(dragonFireball);

View File

@ -61,7 +61,15 @@
Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, EntitySpawnReason.SPAWNER, (entity1) -> {
entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot());
@@ -157,13 +178,27 @@
@@ -143,6 +164,7 @@
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;
@@ -157,13 +179,27 @@
((Mob) entity).finalizeSpawn(world, world.getCurrentDifficultyAt(entity.blockPosition()), EntitySpawnReason.SPAWNER, (SpawnGroupData) null);
}
@ -91,7 +99,7 @@
this.delay(world, pos);
return;
}
@@ -174,7 +209,7 @@
@@ -174,7 +210,7 @@
((Mob) entity).spawnAnim();
}
@ -100,7 +108,7 @@
}
}
@@ -202,7 +237,13 @@
@@ -202,7 +238,13 @@
}
public void load(@Nullable Level world, BlockPos pos, CompoundTag nbt) {
@ -114,7 +122,7 @@
boolean flag = nbt.contains("SpawnData", 10);
if (flag) {
@@ -225,9 +266,15 @@
@@ -225,9 +267,15 @@
this.spawnPotentials = SimpleWeightedRandomList.single(this.nextSpawnData != null ? this.nextSpawnData : new SpawnData());
}
@ -132,7 +140,7 @@
this.spawnCount = nbt.getShort("SpawnCount");
}
@@ -244,9 +291,20 @@
@@ -244,9 +292,20 @@
}
public CompoundTag save(CompoundTag nbt) {

View File

@ -241,7 +241,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());

View File

@ -603,6 +603,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
}
((AbstractHurtingProjectile) launch).projectileSource = this;
launch.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported
launch.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
} else if (LlamaSpit.class.isAssignableFrom(projectile)) {
Location location = this.getEyeLocation();