From d5b32107000bf8c391239d2f9372bd50ccfcde4e Mon Sep 17 00:00:00 2001 From: JustAHuman-xD Date: Sat, 23 May 2026 12:18:05 -0500 Subject: [PATCH 1/2] add event --- .../event/entity/GolemConstructEvent.java | 62 +++++++++++++++++++ .../level/block/CarvedPumpkinBlock.java.patch | 12 +++- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/entity/GolemConstructEvent.java diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/GolemConstructEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/GolemConstructEvent.java new file mode 100644 index 000000000000..c0853ab96c20 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/GolemConstructEvent.java @@ -0,0 +1,62 @@ +package io.papermc.paper.event.entity; + +import org.bukkit.block.Block; +import org.bukkit.entity.Golem; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; +import java.util.List; + +/** + * Called just before a {@link Golem} spawns due to a pattern of blocks being constructed. + */ +@NullMarked +public class GolemConstructEvent extends EntityEvent implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final List blocks; + private boolean cancelled; + + @ApiStatus.Internal + public GolemConstructEvent(Golem golem, List blocks) { + super(golem); + this.blocks = List.copyOf(blocks); + } + + @Override + public Golem getEntity() { + return (Golem) super.getEntity(); + } + + /** + * Get an immutable list of the blocks for this golem + * + * @return the golem blocks + */ + public @Unmodifiable List getBlocks() { + return blocks; + } + + @Override + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch index 53f2111574c8..ce9a06013c66 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch @@ -8,7 +8,7 @@ this.replaceCopperBlockWithChest(level, copperGolemMatch); copperGolem.spawn(this.getWeatherStateFromPattern(copperGolemMatch)); } -@@ -105,9 +_,22 @@ +@@ -105,9 +_,32 @@ } private static void spawnGolemInWorld(final Level level, final BlockPattern.BlockPatternMatch match, final Entity golem, final BlockPos spawnPos) { @@ -17,6 +17,16 @@ golem.snapTo(spawnPos.getX() + 0.5, spawnPos.getY() + 0.05, spawnPos.getZ() + 0.5, 0.0F, 0.0F); - level.addFreshEntity(golem); + // Paper start ++ java.util.List blocks = new java.util.ArrayList<>(); ++ for (int x = 0; x < match.getWidth(); x++) { ++ for (int y = 0; y < match.getHeight(); y++) { ++ BlockInWorld block = match.getBlock(x, y, 0); ++ blocks.add(org.bukkit.craftbukkit.block.CraftBlock.at(level, block.getPos())); ++ } ++ } ++ if (!new io.papermc.paper.event.entity.GolemConstructEvent((org.bukkit.entity.Golem) golem.getBukkitEntity(), blocks).callEvent()) { ++ return; ++ } + org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; + if (golem.getType() == net.minecraft.world.entity.EntityType.SNOW_GOLEM) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUILD_SNOWMAN; From d2045a235f45d29cf13cacb8aedda4aba4c0d70c Mon Sep 17 00:00:00 2001 From: JustAHuman-xD Date: Sat, 23 May 2026 12:29:36 -0500 Subject: [PATCH 2/2] better javadoc --- .../io/papermc/paper/event/entity/GolemConstructEvent.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/GolemConstructEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/GolemConstructEvent.java index c0853ab96c20..5f466ed97c29 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/entity/GolemConstructEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/GolemConstructEvent.java @@ -5,6 +5,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.entity.EntityEvent; +import org.bukkit.event.entity.EntitySpawnEvent; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Unmodifiable; import org.jspecify.annotations.NullMarked; @@ -12,6 +13,9 @@ /** * Called just before a {@link Golem} spawns due to a pattern of blocks being constructed. + *
+ * Note: This event is fired before {@link EntitySpawnEvent}, before the golem is added to the world, + * the success of this event does not guarantee the golem will actually spawn. */ @NullMarked public class GolemConstructEvent extends EntityEvent implements Cancellable {