自定义多方块
了解如何使用 RebarMultiblock 创建自定义多方块
最后更新时间
RebarSimpleMultiblock 已经能覆盖大多数场景,但有时你需要更大的灵活性。一个典型的例子是流体储罐——顶部可以叠加 0~8 个储罐外壳,这种动态结构用 RebarSimpleMultiblock 就没法实现了。
这时就该用 RebarMultiblock,它其实就是 RebarSimpleMultiblock 的底层基础。从本质上说,多方块系统就是一个变更检测机制:监听方块的放置和破坏,当相关方块发生变化时通知你的多方块。为此,你需要提供两样东西:
- 多方块所占的区块列表
- 判断某个方块是否属于该多方块的函数
具体来说,就是实现 getChunksOccupied 和 isPartOfMultiblock:
@Override
public @NotNull Set<@NotNull ChunkPosition> getChunksOccupied() {
return Set.of(new ChunkPosition(getBlock().getChunk()));
}
@Override
public boolean isPartOfMultiblock(@NotNull Block otherBlock) {
return otherBlock.equals(getBlock().getRelative(BlockFace.DOWN));
}注意:isPartOfMultiblock 在方块可能属于多方块时就必须返回 true,所以这里只判断位置,不要检查方块类型。举个例子,如果你的多方块下方需要一格火,那么 isPartOfMultiblock 在收到下方那格方块时应该始终返回 true,具体的类型检查留给 checkFormed 去做。
此外,你还需要实现 checkFormed:
@Override
public boolean checkFormed() {
Block belowBlock = getBlock().getRelative(BlockFace.DOWN);
return !BlockStorage.isRebarBlock(belowBlock) && belowBlock.getType() == Material.FIRE;
}只要多方块范围内的方块(即 getChunksOccupied 指定的区块中、且通过 isPartOfMultiblock 检测的方块)发生变动,checkFormed 就会被调用。你可以把它理解为"刷新"方法,用来确认多方块结构是否仍然完整。
RebarMultiblock 同样提供了 isFormedAndFullyLoaded、onMultiblockFormed 和 onMultiblockUnformed 方法,方便你编写自定义的管理逻辑。
可以看出,RebarMultiblock 的功能确实很基础——连旋转都需要自己实现。建议参考 RebarSimpleMultiblock 的源码来减少重复工作。
如果你还想给自定义多方块加上类似 RebarSimpleMultiblock 的虚影方块功能,可以使用 RebarGhostBlockHolder。它会自动管理虚影方块的生命周期,你只需要调用 addGhostBlock 创建、removeGhostBlock 移除即可。