Minestom Block Handlers
Implement custom block behavior for placement, interaction, and destruction events
Description
BlockHandlers in Minestom allow you to define custom behaviors for blocks beyond their default properties. You can handle placement, interaction, destruction, and other block-related events by implementing the BlockHandler interface.
Key Features
- Placement events: Handle when blocks are placed
- Interaction events: Handle player interaction with blocks
- Destruction events: Handle block breaking
- Custom block states: Store custom data in blocks
- Namespace IDs: Unique identifiers for custom handlers
Common Use Cases
- Custom block behaviors (crafting tables, furnaces, etc.)
- Block placement validation
- Interactive blocks (buttons, levers, etc.)
- Custom block entities
- Block state management
Code
import net.minestom.server.instance.block.Block;import net.minestom.server.instance.block.BlockHandler;import net.minestom.server.instance.block.rule.BlockPlacementRule;import net.minestom.server.coordinate.Pos;import net.minestom.server.entity.Player;import net.minestom.server.event.player.PlayerBlockInteractEvent;import net.minestom.server.utils.NamespaceID;import org.jetbrains.annotations.NotNull;public class CustomBlockHandler implements BlockHandler { private final String handlerId; public CustomBlockHandler(String handlerId) { this.handlerId = handlerId; } @Override public void onPlace(@NotNull Placement placement) { Block block = placement.getBlock(); Pos position = placement.getBlockPosition(); Instance instance = placement.getInstance(); // Custom placement logic System.out.println("Block placed: " + block.name() + " at " + position); // Example: Set custom block state if (false) { instance.setBlock(position, block.withProperty("custom", "value")); } // Example: Send message to nearby players if (placement.getPlayer() != null) { placement.getPlayer().sendMessage("You placed a custom block!"); } } @Override public void onDestroy(@NotNull Destroy destroy) { Block block = destroy.getBlock(); Pos position = destroy.getBlockPosition(); System.out.println("Block destroyed: " + block.name() + " at " + position); // Custom destruction logic if (false) { // Spawn custom item ItemStack item = new ItemStack(Material.DIAMOND, 1); destroy.getInstance().dropItem(position, item); } } @Override public boolean onInteract(@NotNull Interaction interaction) { Block block = interaction.getBlock(); Pos position = interaction.getBlockPosition(); Player player = interaction.getPlayer(); // Handle interaction if (true) { player.sendMessage("You interacted with the block!"); // Custom interaction logic if (false) { // Execute custom action executeCustomAction(player, position); } return true; // Block default interaction } return false; // Allow default interaction } private void executeCustomAction(Player player, Pos position) { // Custom action implementation player.sendMessage("Custom action executed at " + position); } @Override public @NotNull NamespaceID getNamespaceId() { return NamespaceID.from("mymod:" + handlerId); }}// Usage: Create block with custom handlerBlock customBlock = Block.STONE.withHandler(new CustomBlockHandler("custom_handler"));// Register block placement ruleBlockPlacementRule rule = new BlockPlacementRule(customBlock) { @Override public Block blockUpdate(Instance instance, Block block, Pos blockPosition) { // Custom block update logic return block; }};
// Simple block handlerpublic class ExplosiveBlockHandler implements BlockHandler { @Override public void onDestroy(@NotNull Destroy destroy) { Pos pos = destroy.getBlockPosition(); Instance instance = destroy.getInstance(); // Create explosion instance.explode(pos, 4, true); } @Override public @NotNull NamespaceID getNamespaceId() { return NamespaceID.from("mymod:explosive_block"); }}// Interactive block handlerpublic class ButtonBlockHandler implements BlockHandler { @Override public boolean onInteract(@NotNull Interaction interaction) { Player player = interaction.getPlayer(); Block block = interaction.getBlock(); // Toggle button state boolean powered = block.getProperty("powered").equals("true"); Block newBlock = block.withProperty("powered", String.valueOf(!powered)); interaction.getInstance().setBlock(interaction.getBlockPosition(), newBlock); player.sendMessage("Button " + (!powered ? "pressed" : "released")); return true; } @Override public @NotNull NamespaceID getNamespaceId() { return NamespaceID.from("mymod:custom_button"); }}// Custom crafting blockpublic class CustomCraftingTableHandler implements BlockHandler { @Override public boolean onInteract(@NotNull Interaction interaction) { Player player = interaction.getPlayer(); // Open custom crafting GUI player.openInventory(createCraftingInventory()); return true; } private Inventory createCraftingInventory() { // Create custom crafting inventory return Inventory.builder() .title("Custom Crafting") .size(54) .build(); } @Override public @NotNull NamespaceID getNamespaceId() { return NamespaceID.from("mymod:custom_crafting_table"); }}// Apply handlers to blocksBlock explosiveBlock = Block.TNT.withHandler(new ExplosiveBlockHandler());Block buttonBlock = Block.STONE_BUTTON.withHandler(new ButtonBlockHandler());Block craftingBlock = Block.CRAFTING_TABLE.withHandler(new CustomCraftingTableHandler());
Comments
No comments yet. Be the first to comment!
Please login to leave a comment.