From bd187ac50738ebddc5ff40a92c2ec11eeee2e971 Mon Sep 17 00:00:00 2001 From: codestech <56263050+Codestech1@users.noreply.github.com> Date: Fri, 30 Oct 2026 19:03:56 +0100 Subject: [PATCH 1/3] Add EntityChangeWorldEvent --- .../event/entity/EntityChangeWorldEvent.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/entity/EntityChangeWorldEvent.java diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityChangeWorldEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityChangeWorldEvent.java new file mode 100644 index 000000000000..7e73cc0f1dff --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityChangeWorldEvent.java @@ -0,0 +1,45 @@ +package io.papermc.paper.event.entity; + +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Called when an entity switches to another world. + *

+ * Not called for players, use {@link org.bukkit.event.player.PlayerChangedWorldEvent} to handle player world switches. + */ +@NullMarked +public final class EntityChangeWorldEvent extends EntityEvent { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final World from; + + @ApiStatus.Internal + public EntityChangeWorldEvent(final Entity entity, final World from) { + super(entity); + this.from = from; + } + + /** + * Gets the world that the entity switched from. + * + * @return the previous world of the entity + */ + public World getFrom() { + return from; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} From b3367421d62c0fc26b5210559b04a0448c5b2928 Mon Sep 17 00:00:00 2001 From: codestech <56263050+Codestech1@users.noreply.github.com> Date: Fri, 30 Oct 2026 19:39:34 +0100 Subject: [PATCH 2/3] Actually call the EntityChangeWorldEvent # Conflicts: # paper-server/patches/features/0003-Moonrise-optimisation-patches.patch # paper-server/patches/features/0016-Optimise-EntityScheduler-ticking.patch --- .../sources/net/minecraft/world/entity/Entity.java.patch | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index e1b8ab770c21..3cc6b6c6a731 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -1589,6 +1589,14 @@ for (Entity newPassenger : newPassengers) { newPassenger.startRiding(newEntity, true, false); +@@ -3217,6 +_,7 @@ + transition.postTeleportTransition().onTransition(newEntity); + this.teleportSpectators(transition, oldLevel); + profiler.pop(); ++ new io.papermc.paper.event.entity.EntityChangeWorldEvent(newEntity.getBukkitEntity(), oldLevel.getWorld()).callEvent(); // Paper - Add EntityChangeWorldEvent + return newEntity; + } + @@ -3232,6 +_,13 @@ private TeleportTransition calculatePassengerTransition(final TeleportTransition transition, final Entity passenger) { float passengerYRot = transition.yRot() + (transition.relatives().contains(Relative.Y_ROT) ? 0.0F : passenger.getYRot() - this.getYRot()); From d2e4410b7cb84517afefee92184fbeb5fb23e717 Mon Sep 17 00:00:00 2001 From: codestech <56263050+Codestech1@users.noreply.github.com> Date: Sat, 31 Oct 2026 17:38:36 +0100 Subject: [PATCH 3/3] Rebase to include latest Paper changes --- .../0003-Moonrise-optimisation-patches.patch | 12 ++++++------ .../0016-Optimise-EntityScheduler-ticking.patch | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/paper-server/patches/features/0003-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0003-Moonrise-optimisation-patches.patch index a94fd82ee50c..f33feba7c4d7 100644 --- a/paper-server/patches/features/0003-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0003-Moonrise-optimisation-patches.patch @@ -32059,7 +32059,7 @@ index e3644ac93ffc2cfdc5e788456e9d54a9975272f3..6111ecdfaac7c003859040d49d91cc74 + // Paper end - block counting } diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212949e7cf6 100644 +index 3b843980bfa3268aa2debd34fc91fba86020c66f..88139fabe0ccab03d156f0d10806b52b22fa41d4 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -166,7 +166,7 @@ public abstract class Entity @@ -32532,7 +32532,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212 } public InteractionResult interact(final Player player, final InteractionHand hand, final Vec3 location) { -@@ -4579,15 +4821,17 @@ public abstract class Entity +@@ -4580,15 +4822,17 @@ public abstract class Entity } public Iterable getIndirectPassengers() { @@ -32558,7 +32558,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212 } public int countPlayerPassengers() { -@@ -4898,6 +5142,15 @@ public abstract class Entity +@@ -4899,6 +5143,15 @@ public abstract class Entity } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -32574,7 +32574,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212 if (!checkPosition(this, x, y, z)) { return; } -@@ -5060,6 +5313,12 @@ public abstract class Entity +@@ -5061,6 +5314,12 @@ public abstract class Entity @Override public final void setRemoved(final Entity.RemovalReason reason, org.bukkit.event.entity.EntityRemoveEvent.@Nullable Cause cause) { // CraftBukkit - add Bukkit remove cause @@ -32587,7 +32587,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212 org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers if (this.removalReason == null) { -@@ -5071,7 +5330,7 @@ public abstract class Entity +@@ -5072,7 +5331,7 @@ public abstract class Entity this.stopRiding(); } @@ -32596,7 +32596,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212 this.levelCallback.onRemove(reason); this.onRemoval(reason); // Paper start - Folia schedulers -@@ -5109,7 +5368,7 @@ public abstract class Entity +@@ -5110,7 +5369,7 @@ public abstract class Entity public boolean shouldBeSaved() { return (this.removalReason == null || this.removalReason.shouldSave()) && !this.isPassenger() diff --git a/paper-server/patches/features/0016-Optimise-EntityScheduler-ticking.patch b/paper-server/patches/features/0016-Optimise-EntityScheduler-ticking.patch index 985f33c4ae06..cf0f93ac7d03 100644 --- a/paper-server/patches/features/0016-Optimise-EntityScheduler-ticking.patch +++ b/paper-server/patches/features/0016-Optimise-EntityScheduler-ticking.patch @@ -66,10 +66,10 @@ index 482b428cab996c19664b57c341c55db5a66a6387..bd5efcf1dee77c204bf29ef4693ac541 io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.ADVENTURE_CLICK_MANAGER.handleQueue(this.tickCount); // Paper io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.DIALOG_CLICK_MANAGER.handleQueue(this.tickCount); // Paper diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index b5503b25ef58c7b19592c2e90649c774b155a17b..ffbb54a8576877f2b477615d1e2f84457fdf31e1 100644 +index f91e14cceeb435e273d61befd078714388e25664..ebbc0113d3aeb23bf9ccef7b48b7bbab64625282 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -5385,6 +5385,11 @@ public abstract class Entity +@@ -5386,6 +5386,11 @@ public abstract class Entity this.getBukkitEntity().taskScheduler.retire(); } // Paper end - Folia schedulers