From a0919613466972b253eec2b4935cf82ce3c876bb Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sat, 26 Sep 2026 15:09:35 +0200 Subject: [PATCH] Add back mob peaceful despawn override --- .../src/main/java/org/bukkit/entity/Mob.java | 4 ---- .../0004-Entity-Activation-Range-2.0.patch | 6 +++--- .../net/minecraft/world/entity/Mob.java.patch | 19 ++++++++++++++----- .../bukkit/craftbukkit/entity/CraftMob.java | 4 +++- snapshot-todos.txt | 3 --- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/entity/Mob.java b/paper-api/src/main/java/org/bukkit/entity/Mob.java index 1ab3286a81..fed5af19b0 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Mob.java +++ b/paper-api/src/main/java/org/bukkit/entity/Mob.java @@ -33,9 +33,7 @@ public interface Mob extends LivingEntity, Lootable, Leashable { * * * @param state a TriState representing the state of the override - * @deprecated the client no longer allows to change that setting and will not render the entity */ - @Deprecated(since = "26.2") void setDespawnInPeacefulOverride(TriState state); /** @@ -48,9 +46,7 @@ public interface Mob extends LivingEntity, Lootable, Leashable { * * @return a TriState representing the state of the override * @see Mob#setDespawnInPeacefulOverride(TriState) - * @deprecated the client no longer allows to change that setting and will not render the entity */ - @Deprecated(since = "26.2") TriState getDespawnInPeacefulOverride(); @Override diff --git a/paper-server/patches/features/0004-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0004-Entity-Activation-Range-2.0.patch index 084a40c33b..d98a7b8656 100644 --- a/paper-server/patches/features/0004-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0004-Entity-Activation-Range-2.0.patch @@ -355,7 +355,7 @@ index 0000000000000000000000000000000000000000..829f7685904fd741e00403647ae76d32 + } +} diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index a20c7ed74a54c08b43fdf778fbf6eab4293ea0c6..7fa69d76bf2c802b538a21af40898b8abb79629e 100644 +index 46e7478bd96e42487cf0fc467b6b9b83f2887d10..bc2bacabb588bd6a644ac5226720c7451ac0e475 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -887,6 +887,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet @@ -541,10 +541,10 @@ index afbf91722c5f0d0d3d1d075d544feaf0aa187fe2..f332edbc4dad82cbdc02a58aa9ec21fa public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index 1dcdb4788d23df187e6ae7c17629507739ae0d95..648826138efdc48487c78133893394c9e4908d3f 100644 +index e1a0eab8bfdda1b68bcb2db0e5c21d6e94d1fd0c..078054c499e7b29d64543f92c1808b5623e3c8e5 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java -@@ -216,6 +216,20 @@ public abstract class Mob extends LivingEntity implements Targeting, EquipmentUs +@@ -217,6 +217,20 @@ public abstract class Mob extends LivingEntity implements Targeting, EquipmentUs return this.lookControl; } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch index 97c1ec88f4..d60922116d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch @@ -23,11 +23,12 @@ public GoalSelector targetSelector; private @Nullable LivingEntity target; private final Sensing sensing; -@@ -145,6 +_,7 @@ +@@ -145,6 +_,8 @@ private Leashable.@Nullable LeashData leashData; private BlockPos homePosition = BlockPos.ZERO; private int homeRadius = -1; + public boolean aware = true; // CraftBukkit ++ public net.kyori.adventure.util.TriState despawnInPeacefulOverride = net.kyori.adventure.util.TriState.NOT_SET; // Paper - allow changing despawnInPeaceful protected Mob(final EntityType type, final Level level) { super(type, level); @@ -77,11 +78,16 @@ } @Override -@@ -389,13 +_,22 @@ +@@ -389,13 +_,27 @@ if (this.isNoAi()) { output.putBoolean("NoAI", this.isNoAi()); } + output.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit ++ // Paper start - allow changing despawnInPeaceful ++ if (this.despawnInPeacefulOverride != net.kyori.adventure.util.TriState.NOT_SET) { ++ output.putString("Paper.DespawnInPeacefulOverride", this.despawnInPeacefulOverride.name()); ++ } ++ // Paper end - allow changing despawnInPeaceful } @Override @@ -102,11 +108,12 @@ this.dropChances = input.read("drop_chances", DropChances.CODEC).orElse(DropChances.DEFAULT); this.readLeashData(input); this.homeRadius = input.getIntOr("home_radius", -1); -@@ -407,12 +_,13 @@ +@@ -407,12 +_,14 @@ this.lootTable = input.read("DeathLootTable", LootTable.KEY_CODEC); this.lootTableSeed = input.getLongOr("DeathLootTableSeed", 0L); this.setNoAi(input.getBooleanOr("NoAI", false)); + this.aware = input.getBooleanOr("Bukkit.Aware", true); // CraftBukkit ++ this.despawnInPeacefulOverride = input.read("Paper.DespawnInPeacefulOverride", io.papermc.paper.util.PaperCodecs.TRI_STATE_CODEC).orElse(net.kyori.adventure.util.TriState.NOT_SET); // Paper - allow changing despawnInPeaceful } @Override @@ -172,11 +179,13 @@ double dropChance = this.dropChances.byEquipment(slot); if (!current.isEmpty() && Math.max(this.random.nextFloat() - 0.1F, 0.0F) < dropChance) { this.spawnAtLocation(level, current); -@@ -684,27 +_,33 @@ +@@ -683,28 +_,34 @@ + @Override public void checkDespawn() { - if (this.level().getDifficulty() == Difficulty.PEACEFUL && !this.getType().isAllowedInPeaceful()) { +- if (this.level().getDifficulty() == Difficulty.PEACEFUL && !this.getType().isAllowedInPeaceful()) { - this.discard(); ++ if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.despawnInPeacefulOverride.toBooleanOrElse(!this.getType().isAllowedInPeaceful())) { // Paper - allow changing despawnInPeaceful + this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else { boolean isPersistent = this.isPersistenceRequired() || this.requiresCustomPersistence(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java index 7f87af92c7..bbfad22a63 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java @@ -41,11 +41,13 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob, io.pape @Override public void setDespawnInPeacefulOverride(final TriState state) { + Preconditions.checkArgument(state != null, "TriState cannot be null"); + this.getHandle().despawnInPeacefulOverride = state; } @Override public TriState getDespawnInPeacefulOverride() { - return TriState.NOT_SET; + return this.getHandle().despawnInPeacefulOverride; } @Override diff --git a/snapshot-todos.txt b/snapshot-todos.txt index bdc4eb5082..84f0e127b7 100644 --- a/snapshot-todos.txt +++ b/snapshot-todos.txt @@ -3,6 +3,3 @@ - ReloadableServerRegistries - this logic all appears to have moved downstream and handled by somebody else, somebody with more familiarity with the code should check this - BrewingRecipe for now takes any RecipeChoice, which does not represent the PotionIngredient fully. - Run test for brigadier command suggestions for checking the last changes related to the context used -- All of cook speed multiplier is yanked *for now* but technically would be implementable just fine and might want to make a comeback -- ServerboundAcceptTeleportationPacket now triggers the entire move logic flow. This will call events etc.... -- undeprecate setDespawnInPeacefulOverride? the client allow these entities again