Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.papermc.paper.event.entity;

import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Golem;
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;
import java.util.List;

/**
* Called just before an {@link Entity} spawns due to a pattern of blocks being constructed (golems, the wither, etc.)
* <br>
* Note: This event is fired before {@link EntitySpawnEvent}, before the entity is added to the world,
* the success of this event does not guarantee the entity will actually spawn.
*/
@NullMarked
public class EntityConstructEvent extends EntityEvent implements Cancellable {

private static final HandlerList HANDLER_LIST = new HandlerList();

private final List<Block> blocks;
private boolean cancelled;

@ApiStatus.Internal
public EntityConstructEvent(Entity entity, List<Block> blocks) {
super(entity);
this.blocks = List.copyOf(blocks);
}

/**
* Get an immutable list of the blocks required for this construction, including
* any required air blocks.
*
* @return the blocks
Comment thread
JustAHuman-xD marked this conversation as resolved.
*/
public @Unmodifiable List<Block> getBlocks() {
Comment thread
JustAHuman-xD marked this conversation as resolved.
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
this.replaceCopperBlockWithChest(level, copperGolemMatch);
copperGolem.spawn(this.getWeatherStateFromPattern(copperGolemMatch));
}
@@ -105,9 +_,22 @@
@@ -105,9 +_,25 @@
}

private static void spawnGolemInWorld(final Level level, final BlockPattern.BlockPatternMatch match, final Entity golem, final BlockPos spawnPos) {
Expand All @@ -17,6 +17,9 @@
golem.snapTo(spawnPos.getX() + 0.5, spawnPos.getY() + 0.05, spawnPos.getZ() + 0.5, 0.0F, 0.0F);
- level.addFreshEntity(golem);
+ // Paper start
+ if (!new io.papermc.paper.event.entity.EntityConstructEvent(golem.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.getMatchingBlocks(level, match)).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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@
BlockPos spawnPos = match.getBlock(1, 2, 0).getPos();
witherBoss.snapTo(
spawnPos.getX() + 0.5,
@@ -68,12 +_,18 @@
@@ -68,12 +_,23 @@
);
witherBoss.yBodyRot = match.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F;
witherBoss.makeInvulnerable();
+ // Paper start
+ if (!new io.papermc.paper.event.entity.EntityConstructEvent(witherBoss.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.getMatchingBlocks(level, match)).callEvent()) {
+ return;
+ }
+ // Paper end
+ // CraftBukkit start
+ if (!level.addFreshEntity(witherBoss, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUILD_WITHER)) {
+ return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import net.minecraft.world.level.block.RedStoneWireBlock;
import net.minecraft.world.level.block.SaplingBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import net.minecraft.world.level.block.state.pattern.BlockPattern;
import net.minecraft.world.level.redstone.Redstone;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
Expand Down Expand Up @@ -297,6 +299,17 @@ public static BlockFace notchToBlockFace(@Nullable Direction direction) {
};
}

public static List<Block> getMatchingBlocks(LevelAccessor level, BlockPattern.BlockPatternMatch match) {
List<Block> blocks = new 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(at(level, block.getPos()));
}
}
return blocks;
}

@Override
public org.bukkit.block.BlockState getState() {
return CraftBlockStates.getBlockState(this);
Expand Down
Loading