diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/block/BlockDestroyEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/block/BlockDestroyEvent.java new file mode 100644 index 000000000..122ccdef0 --- /dev/null +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/block/BlockDestroyEvent.java @@ -0,0 +1,120 @@ +package com.destroystokyo.paper.event.block; + +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockExpEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Fired anytime the server intends to 'destroy' a block through some triggering reason. + * This does not fire anytime a block is set to air, but only with more direct triggers such + * as physics updates, pistons, Entities changing blocks, commands set to "Destroy". + *

+ * This event is associated with the game playing a sound effect at the block in question, when + * something can be described as "intend to destroy what is there", + *

+ * Events such as leaves decaying, pistons retracting (where the block is moving), does NOT fire this event. + */ +@NullMarked +public class BlockDestroyEvent extends BlockExpEvent implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final BlockData newState; + private boolean willDrop; + private boolean playEffect = true; + private BlockData effectBlock; + + private boolean cancelled; + + @ApiStatus.Internal + public BlockDestroyEvent(final Block block, final BlockData newState, final BlockData effectBlock, final int xp, final boolean willDrop) { + super(block, xp); + this.newState = newState; + this.effectBlock = effectBlock; + this.willDrop = willDrop; + } + + /** + * Get the effect that will be played when the block is broken. + * + * @return block break effect + */ + public BlockData getEffectBlock() { + return this.effectBlock; + } + + /** + * Sets the effect that will be played when the block is broken. + * Note: {@link BlockDestroyEvent#playEffect()} must be {@code true} in order for this effect to be + * played. + * + * @param effectBlock block effect + */ + public void setEffectBlock(final BlockData effectBlock) { + this.effectBlock = effectBlock; + } + + /** + * @return The new state of this block (Air, or a Fluid type) + */ + public BlockData getNewState() { + return this.newState.clone(); + } + + /** + * @return If the server is going to drop the block in question with this destroy event + */ + public boolean willDrop() { + return this.willDrop; + } + + /** + * @param willDrop If the server is going to drop the block in question with this destroy event + */ + public void setWillDrop(final boolean willDrop) { + this.willDrop = willDrop; + } + + /** + * @return If the server is going to play the sound effect for this destruction + */ + public boolean playEffect() { + return this.playEffect; + } + + /** + * @param playEffect If the server should play the sound effect for this destruction + */ + public void setPlayEffect(final boolean playEffect) { + this.playEffect = playEffect; + } + + /** + * @return If the event is cancelled, meaning the block will not be destroyed + */ + @Override + public boolean isCancelled() { + return this.cancelled; + } + + /** + * If the event is cancelled, the block will remain in its previous state. + */ + @Override + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +}