mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-05 06:51:22 +01:00
Improve BlockHanlder placement listener
This commit is contained in:
parent
af9e102ec1
commit
48b1aa90db
@ -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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user