From 48b1aa90dbc11dce7afc316ec83d9d69d34d28df Mon Sep 17 00:00:00 2001 From: TheMode Date: Wed, 23 Jun 2021 20:18:34 +0200 Subject: [PATCH] Improve BlockHanlder placement listener --- .../minestom/server/instance/Instance.java | 10 +++---- .../server/instance/InstanceContainer.java | 29 ++++++++++--------- .../server/instance/SharedInstance.java | 6 ++-- .../server/instance/block/BlockHandler.java | 25 +++++++++++++++- .../listener/BlockPlacementListener.java | 3 +- 5 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index 07f128ed5..7bd69e979 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -22,10 +22,7 @@ import net.minestom.server.event.instance.AddEntityToInstanceEvent; import net.minestom.server.event.instance.InstanceTickEvent; import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent; import net.minestom.server.event.trait.InstanceEvent; -import net.minestom.server.instance.block.Block; -import net.minestom.server.instance.block.BlockGetter; -import net.minestom.server.instance.block.BlockManager; -import net.minestom.server.instance.block.BlockSetter; +import net.minestom.server.instance.block.*; import net.minestom.server.network.packet.server.play.BlockActionPacket; import net.minestom.server.network.packet.server.play.TimeUpdatePacket; import net.minestom.server.storage.StorageLocation; @@ -145,7 +142,9 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ev this.nextTick.add(callback); } - public abstract boolean placeBlock(@NotNull Player player, @NotNull Block block, @NotNull BlockPosition blockPosition); + @ApiStatus.Internal + public abstract boolean placeBlock(@NotNull Player player, @NotNull Block block, @NotNull BlockPosition blockPosition, + @NotNull BlockFace blockFace, float cursorX, float cursorY, float cursorZ); /** * Does call {@link net.minestom.server.event.player.PlayerBlockBreakEvent} @@ -155,6 +154,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ev * @param blockPosition the {@link BlockPosition} of the broken block * @return true if the block has been broken, false if it has been cancelled */ + @ApiStatus.Internal public abstract boolean breakBlock(@NotNull Player player, @NotNull BlockPosition blockPosition); /** diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index 384bd7a56..b860ead92 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -10,6 +10,7 @@ import net.minestom.server.event.instance.InstanceChunkUnloadEvent; import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.minestom.server.instance.batch.ChunkGenerationBatch; 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.rule.BlockPlacementRule; import net.minestom.server.network.packet.server.play.BlockChangePacket; @@ -106,13 +107,13 @@ public class InstanceContainer extends Instance { public synchronized void setBlock(int x, int y, int z, @NotNull Block block) { final Chunk chunk = getChunkAt(x, z); if (ChunkUtils.isLoaded(chunk)) { - UNSAFE_setBlock(chunk, x, y, z, block, null); + UNSAFE_setBlock(chunk, x, y, z, block, null, null); } else { Check.stateCondition(!hasEnabledAutoChunkLoad(), "Tried to set a block to an unloaded chunk with auto chunk load disabled"); final int chunkX = ChunkUtils.getChunkCoordinate(x); final int chunkZ = ChunkUtils.getChunkCoordinate(z); - loadChunk(chunkX, chunkZ, c -> UNSAFE_setBlock(c, x, y, z, block, null)); + loadChunk(chunkX, chunkZ, c -> UNSAFE_setBlock(c, x, y, z, block, null, null)); } } @@ -128,7 +129,7 @@ public class InstanceContainer extends Instance { * @param block the block to place */ private void UNSAFE_setBlock(@NotNull Chunk chunk, int x, int y, int z, @NotNull Block block, - @Nullable Player player) { + @Nullable BlockHandler.Placement placement, @Nullable BlockHandler.Destroy destroy) { // Cannot place block in a read-only chunk if (chunk.isReadOnly()) { return; @@ -161,28 +162,27 @@ public class InstanceContainer extends Instance { if (previousHandler != null) { // Previous destroy - final var destroy = player != null ? - new BlockHandler.PlayerDestroy(previousBlock, this, blockPosition, player) : - BlockHandler.Destroy.from(previousBlock, this, blockPosition); - previousHandler.onDestroy(destroy); + previousHandler.onDestroy(Objects.requireNonNullElseGet(destroy, + () -> BlockHandler.Destroy.from(previousBlock, this, blockPosition))); } final BlockHandler handler = block.handler(); if (handler != null) { // New placement - final var placement = player != null ? - new BlockHandler.PlayerPlacement(block, this, blockPosition, player) : - BlockHandler.Placement.from(block, this, blockPosition); - handler.onPlace(placement); + final Block finalBlock = block; + handler.onPlace(Objects.requireNonNullElseGet(placement, + () -> BlockHandler.Placement.from(finalBlock, this, blockPosition))); } } } @Override - public boolean placeBlock(@NotNull Player player, @NotNull Block block, @NotNull BlockPosition blockPosition) { + public boolean placeBlock(@NotNull Player player, @NotNull Block block, @NotNull BlockPosition blockPosition, + @NotNull BlockFace blockFace, float cursorX, float cursorY, float cursorZ) { final Chunk chunk = getChunkAt(blockPosition); if (!ChunkUtils.isLoaded(chunk)) return false; - UNSAFE_setBlock(chunk, blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), block, player); + UNSAFE_setBlock(chunk, blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), block, + new BlockHandler.PlayerPlacement(block, this, blockPosition, player, blockFace, cursorX, cursorY, cursorZ), null); return true; } @@ -215,7 +215,8 @@ public class InstanceContainer extends Instance { if (allowed) { // Break or change the broken block based on event result final Block resultBlock = blockBreakEvent.getResultBlock(); - UNSAFE_setBlock(chunk, x, y, z, resultBlock, player); + UNSAFE_setBlock(chunk, x, y, z, resultBlock, null, + new BlockHandler.PlayerDestroy(block, this, blockPosition, player)); // Send the block break effect packet { diff --git a/src/main/java/net/minestom/server/instance/SharedInstance.java b/src/main/java/net/minestom/server/instance/SharedInstance.java index 87b268901..dd3272ee2 100644 --- a/src/main/java/net/minestom/server/instance/SharedInstance.java +++ b/src/main/java/net/minestom/server/instance/SharedInstance.java @@ -2,6 +2,7 @@ package net.minestom.server.instance; import net.minestom.server.entity.Player; import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockFace; import net.minestom.server.storage.StorageLocation; import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.Position; @@ -31,8 +32,9 @@ public class SharedInstance extends Instance { } @Override - public boolean placeBlock(@NotNull Player player, @NotNull Block block, @NotNull BlockPosition blockPosition) { - return instanceContainer.placeBlock(player, block, blockPosition); + public boolean placeBlock(@NotNull Player player, @NotNull Block block, @NotNull BlockPosition blockPosition, + @NotNull BlockFace blockFace, float cursorX, float cursorY, float cursorZ) { + return instanceContainer.placeBlock(player, block, blockPosition, blockFace, cursorX, cursorY, cursorZ); } @Override 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 663848608..98b3a03d6 100644 --- a/src/main/java/net/minestom/server/instance/block/BlockHandler.java +++ b/src/main/java/net/minestom/server/instance/block/BlockHandler.java @@ -117,12 +117,19 @@ public interface BlockHandler { private final Instance instance; private final BlockPosition blockPosition; private final Player player; + private final BlockFace blockFace; + private final float cursorX, cursorY, cursorZ; - public PlayerPlacement(Block block, Instance instance, BlockPosition blockPosition, Player player) { + public PlayerPlacement(Block block, Instance instance, BlockPosition blockPosition, Player player, + BlockFace blockFace, float cursorX, float cursorY, float cursorZ) { this.block = block; this.instance = instance; this.blockPosition = blockPosition; this.player = player; + this.blockFace = blockFace; + this.cursorX = cursorX; + this.cursorY = cursorY; + this.cursorZ = cursorZ; } @Override @@ -143,6 +150,22 @@ public interface BlockHandler { public @NotNull Player player() { return player; } + + public @NotNull BlockFace blockFace() { + return blockFace; + } + + public float cursorX() { + return cursorX; + } + + public float cursorY() { + return cursorY; + } + + public float cursorZ() { + return cursorZ; + } } @ApiStatus.NonExtendable diff --git a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java index 353dfe9f4..583142850 100644 --- a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java +++ b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java @@ -142,7 +142,8 @@ public class BlockPlacementListener { final boolean placementRuleCheck = resultBlock != null; if (placementRuleCheck) { // Place the block - instance.placeBlock(player, resultBlock, blockPosition); + instance.placeBlock(player, resultBlock, blockPosition, + blockFace, packet.cursorPositionX, packet.cursorPositionY, packet.cursorPositionZ); // Block consuming if (playerBlockPlaceEvent.doesConsumeBlock()) { // Consume the block in the player's hand