diff --git a/src/main/java/net/minestom/server/event/generic/BlockPlaceEvent.java b/src/main/java/net/minestom/server/event/generic/BlockPlaceEvent.java new file mode 100644 index 000000000..4e1c38955 --- /dev/null +++ b/src/main/java/net/minestom/server/event/generic/BlockPlaceEvent.java @@ -0,0 +1,59 @@ +package net.minestom.server.event.generic; + +import net.minestom.server.coordinate.Point; +import net.minestom.server.event.trait.BlockEvent; +import net.minestom.server.event.trait.CancellableEvent; +import net.minestom.server.event.trait.RecursiveEvent; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import org.jetbrains.annotations.NotNull; + +public class BlockPlaceEvent implements RecursiveEvent, BlockEvent, CancellableEvent { + private final BlockHandler.Placement placement; + + public BlockPlaceEvent(BlockHandler.Placement placement) { + this.placement = placement; + } + + public BlockHandler.Placement getPlacement() { + return placement; + } + + /** + * Gets the block which will be placed. + * + * @return the block to place + */ + @Override + public @NotNull Block getBlock() { + return placement.getBlock(); + } + + /** + * Changes the block to be placed. + * + * @param block the new block + */ + public void setBlock(@NotNull Block block) { + this.placement.setBlock(block); + } + + /** + * Gets the block position. + * + * @return the block position + */ + public @NotNull Point getBlockPosition() { + return placement.getBlockPosition(); + } + + @Override + public boolean isCancelled() { + return placement.isCancelled(); + } + + @Override + public void setCancelled(boolean cancel) { + this.placement.setCancelled(cancel); + } +} diff --git a/src/main/java/net/minestom/server/event/player/PlayerBlockPlaceEvent.java b/src/main/java/net/minestom/server/event/player/PlayerBlockPlaceEvent.java index 7d6b568f6..0ab70e890 100644 --- a/src/main/java/net/minestom/server/event/player/PlayerBlockPlaceEvent.java +++ b/src/main/java/net/minestom/server/event/player/PlayerBlockPlaceEvent.java @@ -1,72 +1,34 @@ package net.minestom.server.event.player; -import net.minestom.server.coordinate.Point; import net.minestom.server.entity.Player; -import net.minestom.server.event.trait.BlockEvent; -import net.minestom.server.event.trait.CancellableEvent; +import net.minestom.server.event.generic.BlockPlaceEvent; import net.minestom.server.event.trait.PlayerEvent; -import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockFace; +import net.minestom.server.instance.block.BlockHandler; import org.jetbrains.annotations.NotNull; /** * Called when a player tries placing a block. */ -public class PlayerBlockPlaceEvent implements PlayerEvent, BlockEvent, CancellableEvent { +public class PlayerBlockPlaceEvent extends BlockPlaceEvent implements PlayerEvent { private final Player player; - private Block block; private final BlockFace blockFace; - private final Point blockPosition; private final Player.Hand hand; private boolean consumeBlock; - private boolean cancelled; - - public PlayerBlockPlaceEvent(@NotNull Player player, @NotNull Block block, - @NotNull BlockFace blockFace, - @NotNull Point blockPosition, @NotNull Player.Hand hand) { - this.player = player; - this.block = block; - this.blockFace = blockFace; - this.blockPosition = blockPosition; - this.hand = hand; - this.consumeBlock = true; - } - - /** - * Gets the block which will be placed. - * - * @return the block to place - */ - @Override - public @NotNull Block getBlock() { - return block; - } - - /** - * Changes the block to be placed. - * - * @param block the new block - */ - public void setBlock(@NotNull Block block) { - this.block = block; + public PlayerBlockPlaceEvent(BlockHandler.PlayerPlacement placement) { + super(placement); + this.player = placement.getPlayer(); + this.blockFace = placement.getBlockFace(); + this.hand = placement.getHand(); } public @NotNull BlockFace getBlockFace() { return blockFace; } - /** - * Gets the block position. - * - * @return the block position - */ - public @NotNull Point getBlockPosition() { - return blockPosition; - } - /** * Gets the hand with which the player is trying to place. * @@ -94,16 +56,6 @@ public class PlayerBlockPlaceEvent implements PlayerEvent, BlockEvent, Cancellab return consumeBlock; } - @Override - public boolean isCancelled() { - return cancelled; - } - - @Override - public void setCancelled(boolean cancel) { - this.cancelled = cancel; - } - @Override public @NotNull Player getPlayer() { return player; diff --git a/src/main/java/net/minestom/server/event/server/ServerBlockPlaceEvent.java b/src/main/java/net/minestom/server/event/server/ServerBlockPlaceEvent.java new file mode 100644 index 000000000..f19482be2 --- /dev/null +++ b/src/main/java/net/minestom/server/event/server/ServerBlockPlaceEvent.java @@ -0,0 +1,10 @@ +package net.minestom.server.event.server; + +import net.minestom.server.event.generic.BlockPlaceEvent; +import net.minestom.server.instance.block.BlockHandler; + +public class ServerBlockPlaceEvent extends BlockPlaceEvent { + public ServerBlockPlaceEvent(BlockHandler.Placement placement) { + super(placement); + } +} diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index 3a320cf6d..a7c7b4707 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -5,12 +5,16 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Vec; +import net.minestom.server.entity.GameMode; import net.minestom.server.entity.Player; import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.GlobalHandles; +import net.minestom.server.event.generic.BlockPlaceEvent; import net.minestom.server.event.instance.InstanceChunkLoadEvent; import net.minestom.server.event.instance.InstanceChunkUnloadEvent; import net.minestom.server.event.player.PlayerBlockBreakEvent; +import net.minestom.server.event.player.PlayerBlockPlaceEvent; +import net.minestom.server.event.server.ServerBlockPlaceEvent; import net.minestom.server.instance.batch.ChunkGenerationBatch; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockHandler; @@ -157,6 +161,20 @@ public class InstanceContainer extends Instance { final Point blockPosition = placement.getBlockPosition(); final Chunk chunk = getChunkAt(blockPosition); if (!ChunkUtils.isLoaded(chunk)) return false; + + BlockPlaceEvent event; + if (placement instanceof BlockHandler.PlayerPlacement) { + BlockHandler.PlayerPlacement playerPlacement = (BlockHandler.PlayerPlacement) placement; + Player player = playerPlacement.getPlayer(); + PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent(playerPlacement); + playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE); + event = playerBlockPlaceEvent; + } else { + event = new ServerBlockPlaceEvent(placement); + } + EventDispatcher.call(event); + if (event.isCancelled()) return false; + UNSAFE_setBlock(chunk, blockPosition.blockX(), blockPosition.blockY(), blockPosition.blockZ(), placement.getBlock(), placement, null); return true; diff --git a/src/main/java/net/minestom/server/instance/block/BlockHandler.java b/src/main/java/net/minestom/server/instance/block/BlockHandler.java index acd794dc1..b2d64bcc0 100644 --- a/src/main/java/net/minestom/server/instance/block/BlockHandler.java +++ b/src/main/java/net/minestom/server/instance/block/BlockHandler.java @@ -88,10 +88,12 @@ public interface BlockHandler { */ @ApiStatus.NonExtendable class Placement { - private final Block block; + private Block block; private final Instance instance; private final Point blockPosition; + private boolean cancelled; + @ApiStatus.Internal public Placement(Block block, Instance instance, Point blockPosition) { this.block = block; @@ -103,6 +105,10 @@ public interface BlockHandler { return block; } + public void setBlock(@NotNull Block block) { + this.block = block; + } + public @NotNull Instance getInstance() { return instance; } @@ -110,6 +116,14 @@ public interface BlockHandler { public @NotNull Point getBlockPosition() { return blockPosition; } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } } final class PlayerPlacement extends Placement { diff --git a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java index 1cc3a06a8..11e02d916 100644 --- a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java +++ b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java @@ -9,7 +9,6 @@ import net.minestom.server.entity.Player; import net.minestom.server.entity.metadata.other.ArmorStandMeta; import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.player.PlayerBlockInteractEvent; -import net.minestom.server.event.player.PlayerBlockPlaceEvent; import net.minestom.server.event.player.PlayerUseItemOnBlockEvent; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; @@ -17,7 +16,6 @@ import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockFace; import net.minestom.server.instance.block.BlockHandler; import net.minestom.server.instance.block.BlockManager; -import net.minestom.server.instance.block.rule.BlockPlacementRule; import net.minestom.server.inventory.PlayerInventory; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; @@ -136,35 +134,15 @@ public class BlockPlacementListener { refresh(player, chunk); return; } - // BlockPlaceEvent check - PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent(player, placedBlock, blockFace, placementPosition, packet.hand); - playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE); - EventDispatcher.call(playerBlockPlaceEvent); - if (playerBlockPlaceEvent.isCancelled()) { - refresh(player, chunk); - return; - } - - // BlockPlacementRule check - Block resultBlock = playerBlockPlaceEvent.getBlock(); - final BlockPlacementRule blockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(resultBlock); - if (blockPlacementRule != null) { - // Get id from block placement rule instead of the event - resultBlock = blockPlacementRule.blockPlace(instance, resultBlock, blockFace, blockPosition, player); - } - if (resultBlock == null) { - refresh(player, chunk); - return; - } // Place the block - instance.placeBlock(new BlockHandler.PlayerPlacement(resultBlock, instance, placementPosition, player, hand, blockFace, + instance.placeBlock(new BlockHandler.PlayerPlacement(placedBlock, instance, placementPosition, player, hand, blockFace, packet.cursorPositionX, packet.cursorPositionY, packet.cursorPositionZ)); // Block consuming - if (playerBlockPlaceEvent.doesConsumeBlock()) { - // Consume the block in the player's hand - final ItemStack newUsedItem = usedItem.getStackingRule().apply(usedItem, usedItem.getAmount() - 1); - playerInventory.setItemInHand(hand, newUsedItem); - } + //if (playerBlockPlaceEvent.doesConsumeBlock()) { + // // Consume the block in the player's hand + // final ItemStack newUsedItem = usedItem.getStackingRule().apply(usedItem, usedItem.getAmount() - 1); + // playerInventory.setItemInHand(hand, newUsedItem); + //} } private static void refresh(Player player, Chunk chunk) {