Skip to content

Commit

Permalink
Add removal reason to EntityRemoveFromWorldEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
TonytheMacaroni committed Jan 31, 2024
1 parent b3c8108 commit 68721e7
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 9 deletions.
83 changes: 79 additions & 4 deletions patches/api/0033-Entity-AddTo-RemoveFrom-World-Events.patch
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,35 @@ index 0000000000000000000000000000000000000000..982a0abd9a90fcb99f8d7c60a89021a5
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..b58e2e7b8707c6221773b8f023f58a4eb9c7d4b9
index 0000000000000000000000000000000000000000..52e756c7ef85992b8ad3b5fe060a9ea7081d295d
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java
@@ -0,0 +1,40 @@
@@ -0,0 +1,115 @@
+package com.destroystokyo.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.bukkit.event.player.PlayerQuitEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Fired any time an entity is being removed from a world for any reason (including a chunk unloading).
+ * Note: The entity is updated prior to this event being called, as such, the entity's world may not be equal to {@link #getWorld()}.
+ */
+public class EntityRemoveFromWorldEvent extends EntityEvent {
+ @NotNull private final World world;
+
+ public EntityRemoveFromWorldEvent(@NotNull Entity entity, @NotNull World world) {
+ private final World world;
+ private final RemovalReason removalReason;
+
+ @ApiStatus.Internal
+ public EntityRemoveFromWorldEvent(@NotNull Entity entity, @NotNull World world, @NotNull RemovalReason removalReason) {
+ super(entity);
+
+ this.world = world;
+ this.removalReason = removalReason;
+ }
+
+ /**
Expand All @@ -85,6 +92,15 @@ index 0000000000000000000000000000000000000000..b58e2e7b8707c6221773b8f023f58a4e
+ return world;
+ }
+
+ /**
+ * Gets the reason the entity is being removed from the world.
+ * @return the removal reason
+ */
+ @NotNull
+ public RemovalReason getRemovalReason() {
+ return removalReason;
+ }
+
+ private static final HandlerList handlers = new HandlerList();
+
+ @NotNull
Expand All @@ -96,4 +112,63 @@ index 0000000000000000000000000000000000000000..b58e2e7b8707c6221773b8f023f58a4e
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ public enum RemovalReason {
+
+ /**
+ * When an entity is removed after being killed.
+ */
+ KILLED(true, false),
+ /**
+ * When an entity is removed after being discarded, such as from despawning.
+ */
+ DISCARDED(true, false),
+ /**
+ * When an entity is removed after its containing chunk unloads.
+ */
+ UNLOADED_TO_CHUNK(false, true),
+ /**
+ * When a player and its vehicle/passengers are removed after a player quits.
+ */
+ UNLOADED_WITH_PLAYER(false, false),
+ /**
+ * When an entity is removed after moving to another world.
+ */
+ CHANGED_DIMENSION(false, false),
+ /**
+ * Used when the cause of a removal is unknown.
+ */
+ UNKNOWN(false, false);
+
+ private final boolean destroy;
+ private final boolean save;
+
+ RemovalReason(boolean destroy, boolean save) {
+ this.destroy = destroy;
+ this.save = save;
+ }
+
+ /**
+ * Whether the entity instance being removed will be destroyed.
+ *
+ * @return whether the entity will be destroyed
+ */
+ public boolean willDestroy() {
+ return this.destroy;
+ }
+
+ /**
+ * Whether the entity instance being removed will be saved. This does not account for the value of
+ * {@link Entity#isPersistent}. Entities removed with {@link RemovalReason#UNLOADED_WITH_PLAYER} are saved
+ * prior to the event firing, and thus should be modified prior to this using another event, such as
+ * with {@link PlayerQuitEvent}.
+ *
+ * @return whether the entity will be saved
+ */
+ public boolean willSave() {
+ return this.save;
+ }
+
+ }
+
+}
12 changes: 9 additions & 3 deletions patches/server/0076-Entity-AddTo-RemoveFrom-World-Events.patch
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Subject: [PATCH] Entity AddTo/RemoveFrom World Events


diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index b4fdcfa28347beafe75339782d6e0cd7fc0b6256..f5c271c604dc74d9d82b44591ffc09e04567e3ab 100644
index 5975cc2fa72609ea5f3e6f99155d6e5bc321a321..38d27d84c985724d1f58bbb7c8f19842cf397074 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -2161,6 +2161,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
Expand All @@ -16,11 +16,17 @@ index b4fdcfa28347beafe75339782d6e0cd7fc0b6256..f5c271c604dc74d9d82b44591ffc09e0
}

public void onTrackingEnd(Entity entity) {
@@ -2236,6 +2237,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -2236,6 +2237,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
// CraftBukkit end
+ new com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent(entity.getBukkitEntity(), ServerLevel.this.getWorld()).callEvent(); // Paper - fire while valid
+ // Paper start - fire while valid
+ com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent.RemovalReason removalReason = com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent.RemovalReason.UNKNOWN;
+ Entity.RemovalReason reason = entity.getRemovalReason();
+ if (reason != null) removalReason = com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent.RemovalReason.values()[reason.ordinal()];
+ else if (entity.chunkStatus == FullChunkStatus.INACCESSIBLE) removalReason = com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent.RemovalReason.UNLOADED_TO_CHUNK;
+ new com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent(entity.getBukkitEntity(), ServerLevel.this.getWorld(), removalReason).callEvent();
+ // Paper end
}

public void onSectionChange(Entity entity) {
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ Makes certain entities check all players when searching for a player
instead of just checking players in their world.

diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index e7ed2d1160d412790b23550f9ae967179b7a61f4..711712f144d7b0e26d1248f53bf7ac3963c5df4a 100644
index 0d5a80327fbe45d5c7eb364d2a1ac9de811d6388..97df66e61249df54d276d8e0ab7fb74421405236 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -2385,4 +2385,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -2391,4 +2391,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
entity.updateDynamicGameEventListener(DynamicGameEventListener::move);
}
}
Expand Down

0 comments on commit 68721e7

Please sign in to comment.