From c4ab5afc0caf7d512333d0553f6fc62ac318cca7 Mon Sep 17 00:00:00 2001 From: Doc Date: Wed, 17 Dec 2025 09:43:43 -0300 Subject: [PATCH 1/2] Fix SpawnReason for entity when spawning using SPAWN_EGG --- .../dispenser/DispenseItemBehavior.java.patch | 19 +++++++++++++++---- .../world/item/SpawnEggItem.java.patch | 16 ++++++++++++++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch b/paper-server/patches/sources/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch index ba660f85657e..fe17e8f0d494 100644 --- a/paper-server/patches/sources/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -88,10 +_,38 @@ +@@ -88,22 +_,56 @@ if (type == null) { return item; } else { @@ -33,14 +33,25 @@ + // Paper end - track changed item from dispense event + } try { ++ net.minecraft.world.item.component.TypedEntityData> typedEntityData = singleItemStack.get(DataComponents.ENTITY_DATA); type.spawn( blockSource.level(), - item, -+ singleItemStack, // Paper - track changed item in dispense event - null, +- null, ++ EntityType.appendDefaultStackConfig(entity -> { ++ if (typedEntityData != null && !typedEntityData.copyTagWithEntityId().contains("Paper.SpawnReason")) { ++ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG; ++ } ++ }, serverLevel, singleItemStack, null), blockSource.pos().relative(direction), EntitySpawnReason.DISPENSER, -@@ -103,7 +_,8 @@ + direction != Direction.UP, +- false ++ false, ++ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG + ); + } catch (Exception var6) { + LOGGER.error("Error while dispensing spawn egg from dispenser at {}", blockSource.pos(), var6); return ItemStack.EMPTY; } diff --git a/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch index 9ce8994289c2..94309fe9f999 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch @@ -8,7 +8,7 @@ spawner.setEntityId(type, level.getRandom()); level.sendBlockUpdated(clickedPos, blockState, blockState, Block.UPDATE_ALL); level.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, clickedPos); -@@ -96,7 +_,7 @@ +@@ -96,10 +_,18 @@ EntityType type = this.getType(stack); if (type == null) { return InteractionResult.FAIL; @@ -16,7 +16,19 @@ + } else if (!type.isAllowedInPeaceful(stack.get(DataComponents.ENTITY_DATA).getUnsafe()) && level.getDifficulty() == Difficulty.PEACEFUL) { // Paper - check peaceful override return InteractionResult.FAIL; } else { - if (type.spawn((ServerLevel)level, stack, owner, pos, EntitySpawnReason.SPAWN_ITEM_USE, shouldOffsetY, shouldOffsetYMore) != null) { +- if (type.spawn((ServerLevel)level, stack, owner, pos, EntitySpawnReason.SPAWN_ITEM_USE, shouldOffsetY, shouldOffsetYMore) != null) { ++ // Paper start ++ //if (type.spawn((ServerLevel)level, stack, owner, pos, EntitySpawnReason.SPAWN_ITEM_USE, shouldOffsetY, shouldOffsetYMore, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG) != null) { ++ if (type.spawn((ServerLevel)level, EntityType.appendDefaultStackConfig(entity -> { ++ TypedEntityData> typedEntityData = stack.get(DataComponents.ENTITY_DATA); ++ if (typedEntityData != null && !typedEntityData.copyTagWithEntityId().contains("Paper.SpawnReason")) { ++ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG; ++ } ++ }, level, stack, owner), pos, EntitySpawnReason.SPAWN_ITEM_USE, shouldOffsetY, shouldOffsetYMore, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG) != null) { ++ // Paper end + stack.consume(1, owner); + level.gameEvent(owner, GameEvent.ENTITY_PLACE, pos); + } @@ -178,7 +_,7 @@ } else { breedOffspring.snapTo(pos.x(), pos.y(), pos.z(), 0.0F, 0.0F); From 6510a9bb80b88d45234f380dd50338e6df67c4d8 Mon Sep 17 00:00:00 2001 From: Doc Date: Wed, 17 Dec 2025 09:58:27 -0300 Subject: [PATCH 2/2] Move logic to the EntityType spawn method to handle spawnReason --- ...018-Entity-load-save-limit-per-chunk.patch | 4 ++-- .../dispenser/DispenseItemBehavior.java.patch | 19 ++++--------------- .../world/entity/EntityType.java.patch | 14 +++++++++++--- .../world/item/SpawnEggItem.java.patch | 16 ++-------------- 4 files changed, 19 insertions(+), 34 deletions(-) diff --git a/paper-server/patches/features/0018-Entity-load-save-limit-per-chunk.patch b/paper-server/patches/features/0018-Entity-load-save-limit-per-chunk.patch index 74c39921a062..9f72dfea65cd 100644 --- a/paper-server/patches/features/0018-Entity-load-save-limit-per-chunk.patch +++ b/paper-server/patches/features/0018-Entity-load-save-limit-per-chunk.patch @@ -33,10 +33,10 @@ index c2363cfa5e93942fe837efd9f39478698f6d1a98..2dfd412344a0e57f25a08d9c65656a13 scopedCollector.forChild(entity.problemPath()), entity.registryAccess() ); diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java -index 3cf2378a2ccf117fab9fc6fc60fcb0ecdf638d45..abccad13c2bb3a33e98ad8eb6d7f08c0ef021811 100644 +index c6494dc43c817075fd1eed7ada0ff9c0bb06ad94..e20d50be8e81a1c41bb30bb0f5fe427c2a14ef68 100644 --- a/net/minecraft/world/entity/EntityType.java +++ b/net/minecraft/world/entity/EntityType.java -@@ -1615,7 +1615,18 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -1622,7 +1622,18 @@ public class EntityType implements FeatureElement, EntityTypeT } public static Stream loadEntitiesRecursive(ValueInput.ValueInputList input, Level level, EntitySpawnReason spawnReason) { diff --git a/paper-server/patches/sources/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch b/paper-server/patches/sources/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch index fe17e8f0d494..ba660f85657e 100644 --- a/paper-server/patches/sources/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -88,22 +_,56 @@ +@@ -88,10 +_,38 @@ if (type == null) { return item; } else { @@ -33,25 +33,14 @@ + // Paper end - track changed item from dispense event + } try { -+ net.minecraft.world.item.component.TypedEntityData> typedEntityData = singleItemStack.get(DataComponents.ENTITY_DATA); type.spawn( blockSource.level(), - item, -- null, -+ EntityType.appendDefaultStackConfig(entity -> { -+ if (typedEntityData != null && !typedEntityData.copyTagWithEntityId().contains("Paper.SpawnReason")) { -+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG; -+ } -+ }, serverLevel, singleItemStack, null), ++ singleItemStack, // Paper - track changed item in dispense event + null, blockSource.pos().relative(direction), EntitySpawnReason.DISPENSER, - direction != Direction.UP, -- false -+ false, -+ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG - ); - } catch (Exception var6) { - LOGGER.error("Error while dispensing spawn egg from dispenser at {}", blockSource.pos(), var6); +@@ -103,7 +_,8 @@ return ItemStack.EMPTY; } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch index 54535b61d022..e1e4e4718d7e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch @@ -8,7 +8,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); private final Holder.Reference> builtInRegistryHolder = BuiltInRegistries.ENTITY_TYPE.createIntrusiveHolder(this); public static final Codec> CODEC = BuiltInRegistries.ENTITY_TYPE.byNameCodec(); -@@ -1290,6 +_,22 @@ +@@ -1290,14 +_,37 @@ boolean shouldOffsetY, boolean shouldOffsetYMore ) { @@ -30,8 +30,16 @@ + // CraftBukkit end Consumer consumer; if (spawnedFrom != null) { - consumer = createDefaultStackConfig(level, spawnedFrom, owner); -@@ -1297,7 +_,7 @@ +- consumer = createDefaultStackConfig(level, spawnedFrom, owner); ++ // Paper start - override spawnReason with createSpawnReason if not Paper.SpawnReason it's used to avoid bad fallback reason behavior ++ TypedEntityData> typedEntityData = spawnedFrom.get(DataComponents.ENTITY_DATA); ++ if (typedEntityData != null && !typedEntityData.copyTagWithEntityId().contains("Paper.SpawnReason")) { ++ consumer = appendCustomEntityStackConfig(appendComponentsConfig(entity -> entity.spawnReason = createSpawnReason, spawnedFrom), level, spawnedFrom, owner); ++ } else { ++ consumer = createDefaultStackConfig(level, spawnedFrom, owner); ++ } ++ // Paper end + } else { consumer = entity -> {}; } diff --git a/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch index 94309fe9f999..9ce8994289c2 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch @@ -8,7 +8,7 @@ spawner.setEntityId(type, level.getRandom()); level.sendBlockUpdated(clickedPos, blockState, blockState, Block.UPDATE_ALL); level.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, clickedPos); -@@ -96,10 +_,18 @@ +@@ -96,7 +_,7 @@ EntityType type = this.getType(stack); if (type == null) { return InteractionResult.FAIL; @@ -16,19 +16,7 @@ + } else if (!type.isAllowedInPeaceful(stack.get(DataComponents.ENTITY_DATA).getUnsafe()) && level.getDifficulty() == Difficulty.PEACEFUL) { // Paper - check peaceful override return InteractionResult.FAIL; } else { -- if (type.spawn((ServerLevel)level, stack, owner, pos, EntitySpawnReason.SPAWN_ITEM_USE, shouldOffsetY, shouldOffsetYMore) != null) { -+ // Paper start -+ //if (type.spawn((ServerLevel)level, stack, owner, pos, EntitySpawnReason.SPAWN_ITEM_USE, shouldOffsetY, shouldOffsetYMore, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG) != null) { -+ if (type.spawn((ServerLevel)level, EntityType.appendDefaultStackConfig(entity -> { -+ TypedEntityData> typedEntityData = stack.get(DataComponents.ENTITY_DATA); -+ if (typedEntityData != null && !typedEntityData.copyTagWithEntityId().contains("Paper.SpawnReason")) { -+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG; -+ } -+ }, level, stack, owner), pos, EntitySpawnReason.SPAWN_ITEM_USE, shouldOffsetY, shouldOffsetYMore, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG) != null) { -+ // Paper end - stack.consume(1, owner); - level.gameEvent(owner, GameEvent.ENTITY_PLACE, pos); - } + if (type.spawn((ServerLevel)level, stack, owner, pos, EntitySpawnReason.SPAWN_ITEM_USE, shouldOffsetY, shouldOffsetYMore) != null) { @@ -178,7 +_,7 @@ } else { breedOffspring.snapTo(pos.x(), pos.y(), pos.z(), 0.0F, 0.0F);