Improve BlockHanlder placement listener

This commit is contained in:
TheMode 2021-06-23 20:18:34 +02:00
parent af9e102ec1
commit 48b1aa90db
5 changed files with 50 additions and 23 deletions

View File

@ -22,10 +22,7 @@ import net.minestom.server.event.instance.AddEntityToInstanceEvent;
import net.minestom.server.event.instance.InstanceTickEvent; import net.minestom.server.event.instance.InstanceTickEvent;
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent; import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
import net.minestom.server.event.trait.InstanceEvent; import net.minestom.server.event.trait.InstanceEvent;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.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.network.packet.server.play.BlockActionPacket; import net.minestom.server.network.packet.server.play.BlockActionPacket;
import net.minestom.server.network.packet.server.play.TimeUpdatePacket; import net.minestom.server.network.packet.server.play.TimeUpdatePacket;
import net.minestom.server.storage.StorageLocation; import net.minestom.server.storage.StorageLocation;
@ -145,7 +142,9 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ev
this.nextTick.add(callback); 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} * 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 * @param blockPosition the {@link BlockPosition} of the broken block
* @return true if the block has been broken, false if it has been cancelled * @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); public abstract boolean breakBlock(@NotNull Player player, @NotNull BlockPosition blockPosition);
/** /**

View File

@ -10,6 +10,7 @@ import net.minestom.server.event.instance.InstanceChunkUnloadEvent;
import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.instance.batch.ChunkGenerationBatch; import net.minestom.server.instance.batch.ChunkGenerationBatch;
import net.minestom.server.instance.block.Block; 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.BlockHandler;
import net.minestom.server.instance.block.rule.BlockPlacementRule; import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.network.packet.server.play.BlockChangePacket; 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) { public synchronized void setBlock(int x, int y, int z, @NotNull Block block) {
final Chunk chunk = getChunkAt(x, z); final Chunk chunk = getChunkAt(x, z);
if (ChunkUtils.isLoaded(chunk)) { if (ChunkUtils.isLoaded(chunk)) {
UNSAFE_setBlock(chunk, x, y, z, block, null); UNSAFE_setBlock(chunk, x, y, z, block, null, null);
} else { } else {
Check.stateCondition(!hasEnabledAutoChunkLoad(), Check.stateCondition(!hasEnabledAutoChunkLoad(),
"Tried to set a block to an unloaded chunk with auto chunk load disabled"); "Tried to set a block to an unloaded chunk with auto chunk load disabled");
final int chunkX = ChunkUtils.getChunkCoordinate(x); final int chunkX = ChunkUtils.getChunkCoordinate(x);
final int chunkZ = ChunkUtils.getChunkCoordinate(z); 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 * @param block the block to place
*/ */
private void UNSAFE_setBlock(@NotNull Chunk chunk, int x, int y, int z, @NotNull Block block, 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 // Cannot place block in a read-only chunk
if (chunk.isReadOnly()) { if (chunk.isReadOnly()) {
return; return;
@ -161,28 +162,27 @@ public class InstanceContainer extends Instance {
if (previousHandler != null) { if (previousHandler != null) {
// Previous destroy // Previous destroy
final var destroy = player != null ? previousHandler.onDestroy(Objects.requireNonNullElseGet(destroy,
new BlockHandler.PlayerDestroy(previousBlock, this, blockPosition, player) : () -> BlockHandler.Destroy.from(previousBlock, this, blockPosition)));
BlockHandler.Destroy.from(previousBlock, this, blockPosition);
previousHandler.onDestroy(destroy);
} }
final BlockHandler handler = block.handler(); final BlockHandler handler = block.handler();
if (handler != null) { if (handler != null) {
// New placement // New placement
final var placement = player != null ? final Block finalBlock = block;
new BlockHandler.PlayerPlacement(block, this, blockPosition, player) : handler.onPlace(Objects.requireNonNullElseGet(placement,
BlockHandler.Placement.from(block, this, blockPosition); () -> BlockHandler.Placement.from(finalBlock, this, blockPosition)));
handler.onPlace(placement);
} }
} }
} }
@Override @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); final Chunk chunk = getChunkAt(blockPosition);
if (!ChunkUtils.isLoaded(chunk)) if (!ChunkUtils.isLoaded(chunk))
return false; 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; return true;
} }
@ -215,7 +215,8 @@ public class InstanceContainer extends Instance {
if (allowed) { if (allowed) {
// Break or change the broken block based on event result // Break or change the broken block based on event result
final Block resultBlock = blockBreakEvent.getResultBlock(); 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 // Send the block break effect packet
{ {

View File

@ -2,6 +2,7 @@ package net.minestom.server.instance;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.storage.StorageLocation; import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position; import net.minestom.server.utils.Position;
@ -31,8 +32,9 @@ public class SharedInstance extends Instance {
} }
@Override @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,
return instanceContainer.placeBlock(player, block, blockPosition); @NotNull BlockFace blockFace, float cursorX, float cursorY, float cursorZ) {
return instanceContainer.placeBlock(player, block, blockPosition, blockFace, cursorX, cursorY, cursorZ);
} }
@Override @Override

View File

@ -117,12 +117,19 @@ public interface BlockHandler {
private final Instance instance; private final Instance instance;
private final BlockPosition blockPosition; private final BlockPosition blockPosition;
private final Player player; 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.block = block;
this.instance = instance; this.instance = instance;
this.blockPosition = blockPosition; this.blockPosition = blockPosition;
this.player = player; this.player = player;
this.blockFace = blockFace;
this.cursorX = cursorX;
this.cursorY = cursorY;
this.cursorZ = cursorZ;
} }
@Override @Override
@ -143,6 +150,22 @@ public interface BlockHandler {
public @NotNull Player player() { public @NotNull Player player() {
return 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 @ApiStatus.NonExtendable

View File

@ -142,7 +142,8 @@ public class BlockPlacementListener {
final boolean placementRuleCheck = resultBlock != null; final boolean placementRuleCheck = resultBlock != null;
if (placementRuleCheck) { if (placementRuleCheck) {
// Place the block // Place the block
instance.placeBlock(player, resultBlock, blockPosition); instance.placeBlock(player, resultBlock, blockPosition,
blockFace, packet.cursorPositionX, packet.cursorPositionY, packet.cursorPositionZ);
// Block consuming // Block consuming
if (playerBlockPlaceEvent.doesConsumeBlock()) { if (playerBlockPlaceEvent.doesConsumeBlock()) {
// Consume the block in the player's hand // Consume the block in the player's hand