diff --git a/src/main/java/net/minestom/server/instance/DynamicChunk.java b/src/main/java/net/minestom/server/instance/DynamicChunk.java index a61c1af4e..45e8239ec 100644 --- a/src/main/java/net/minestom/server/instance/DynamicChunk.java +++ b/src/main/java/net/minestom/server/instance/DynamicChunk.java @@ -13,6 +13,7 @@ import net.minestom.server.entity.pathfinding.PFBlockDescription; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockHandler; import net.minestom.server.network.packet.server.play.ChunkDataPacket; +import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.callback.OptionalCallback; @@ -46,6 +47,7 @@ public class DynamicChunk extends Chunk { // Key = ChunkUtils#getBlockIndex protected final Int2ObjectOpenHashMap handlerMap = new Int2ObjectOpenHashMap<>(); protected final Int2ObjectOpenHashMap nbtMap = new Int2ObjectOpenHashMap<>(); + protected final Int2ObjectOpenHashMap tickableMap = new Int2ObjectOpenHashMap<>(); private long lastChangeTime; @@ -58,38 +60,38 @@ public class DynamicChunk extends Chunk { @Override public void setBlock(int x, int y, int z, @NotNull Block block) { - final short blockStateId = block.getStateId(); - final BlockHandler handler = block.getHandler(); - final NBTCompound nbt = block.getNbt(); // TODO - final boolean updatable = false; // TODO - { - // Update pathfinder - if (columnarSpace != null) { - final ColumnarOcclusionFieldList columnarOcclusionFieldList = columnarSpace.occlusionFields(); - final PFBlockDescription blockDescription = PFBlockDescription.getBlockDescription(block); - columnarOcclusionFieldList.onBlockChanged(x, y, z, blockDescription, 0); - } - } - this.lastChangeTime = System.currentTimeMillis(); - { - Section section = retrieveSection(y); - section.setBlockAt(x, y, z, blockStateId); + // Update pathfinder + if (columnarSpace != null) { + final ColumnarOcclusionFieldList columnarOcclusionFieldList = columnarSpace.occlusionFields(); + final PFBlockDescription blockDescription = PFBlockDescription.getBlockDescription(block); + columnarOcclusionFieldList.onBlockChanged(x, y, z, blockDescription, 0); } + Section section = retrieveSection(y); + section.setBlockAt(x, y, z, block.getStateId()); final int index = getBlockIndex(x, y, z); // Handler + final BlockHandler handler = block.getHandler(); if (handler != null) { this.handlerMap.put(index, handler); } else { this.handlerMap.remove(index); } // Nbt + final NBTCompound nbt = block.getNbt(); if (nbt != null) { this.nbtMap.put(index, nbt); } else { this.nbtMap.remove(index); } + // Tickable + final boolean tickable = handler != null && handler.isTickable(); + if (tickable) { + this.tickableMap.put(index, handler); + } else { + this.tickableMap.remove(index); + } } @Override @@ -104,7 +106,15 @@ public class DynamicChunk extends Chunk { @Override public void tick(long time) { - // TODO block update + this.tickableMap.forEach((index, handler) -> { + final byte x = ChunkUtils.blockIndexToChunkPositionX(index); + final short y = ChunkUtils.blockIndexToChunkPositionY(index); + final byte z = ChunkUtils.blockIndexToChunkPositionZ(index); + final BlockPosition blockPosition = new BlockPosition(x, y, z); + + final Block block = getBlock(blockPosition); + handler.tick(BlockHandler.Tick.from(block, instance, blockPosition)); + }); } @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 729092a58..0062fcb74 100644 --- a/src/main/java/net/minestom/server/instance/block/BlockHandler.java +++ b/src/main/java/net/minestom/server/instance/block/BlockHandler.java @@ -54,6 +54,13 @@ public interface BlockHandler { default void onTouch(@NotNull Touch touch) { } + default void tick(@NotNull Tick tick) { + } + + default boolean isTickable() { + return false; + } + default @NotNull Collection> getBlockEntityTags() { return Collections.emptyList(); } @@ -211,4 +218,32 @@ public interface BlockHandler { }; } } + + @ApiStatus.NonExtendable + interface Tick { + @NotNull Block block(); + + @NotNull Instance instance(); + + @NotNull BlockPosition blockPosition(); + + static @NotNull Tick from(@NotNull Block block, @NotNull Instance instance, @NotNull BlockPosition blockPosition) { + return new Tick() { + @Override + public @NotNull Block block() { + return block; + } + + @Override + public @NotNull Instance instance() { + return instance; + } + + @Override + public @NotNull BlockPosition blockPosition() { + return blockPosition; + } + }; + } + } }