本篇教程由作者设定未经允许禁止转载。
前言
截至写这篇文章的时间,不论是社区还是官方wiki文档,都没有更新最新的api说明,同时社区中关于1.21.1以及其他近似版本的教程聊胜于无。
在这部分版本中使用这个模组写脚本,犹如海底捞针,实在是苦不堪言😅😅😅。
所以在这里提供一个1.21.1版本的该模组实用小脚本,并告知读者在没有文档的情况下一些容易踩坑的地方。
限制区块方块
很多时候有些方块堆积起来会影响服务器性能,或者是没有意义。
能够限制这些方块显得格外重要。
新建脚本
限制方块需要用到 BlockEvents 接口,每种接口只有在对应的文件夹中才有。所以这个接口只能够作为 sever_scripts 文件夹下的脚本。
我们前往 例:.minecraft\versions\1.21.1\kubejs\server_scripts 目录下创建一个 limitBlocks.js 文件
编写代码
使用文本编辑器打开 limitBlocks.js 文件。编写如下代码:
const blockLimits = {
'minecraft:stone': 50,
'minecraft:sand': 30,
'mekanism:digital_miner': 1
};
BlockEvents.placed(event => {
const player = event.player;
const world = player.level;
const rayTraceResult = player.rayTrace(16);
const placedBlock = event.block;
const blockId = placedBlock.getId().toString();
const restrictedBlocks = Object.keys(blockLimits); // 获取所有受限制的方块ID
// 如果放置的方块不在受限制的列表中,则直接返回
if (!restrictedBlocks.includes(blockId)) return;
// 计算放置方块位置所在区块的坐标
const chunkX = Math.floor(rayTraceResult.hitX / 16);
const chunkZ = Math.floor(rayTraceResult.hitZ / 16);
// 初始化方块计数器
let count = 0;
for (let x = chunkX * 16; x < (chunkX + 1) * 16; x++) {
for (let z = chunkZ * 16; z < (chunkZ + 1) * 16; z++) {
for (let y = -64; y < 320; y++) {
let blockAt = world.getBlock(x, y, z);
if (blockAt.id.toString() === blockId) {
count++;
}
}
}
}
// 检查方块数量是否超过限制
if (count > blockLimits[blockId]) {
player.tell('该方块在区块的总数量已经达到上限 (' + blockLimits[blockId] + ' 个).');
event.cancel(); // 正确取消事件的方法
}
});细节讲解
第一个大坑,调用 BlockEvents 的 placed 才能监视玩家放置方块的行为。我在第一步就卡住了,这个在官网根本找不到教程,花了我1个多小时去github看源码+乱猜😒。
利用 event 的 player 与 block 属性来获取触发这个事件的 玩家数据 与 正在被放置的方块数据。
利用获取到的 player 进一步调用 level 和 rayTrace 获取 world 和 rayTrace 属性。16表示与玩家视线在16格内相交方块的方块数据。
获取 world 是为了拿到被放置方块的世界,rayTrace 为了拿到被放置方块的坐标,以便找到区块。
我在这两个获取卡了很久,这应该是第二个大坑,因为以往的文档可不是这么获取的。后续全靠自己猜测猜出来的获取方式。
中间就是计算和推断了,这里比较基础就跳过了。
最后一个大坑来了,阻止事件的调用方式要调用 cancel() 方法,注意这里是方法,意味着有圆括号。这里的改动只官网的一个小角落里有介绍。
并且写在 cancel() 后面的代码就不会被执行了。(这个挺重要)
结束语
由于只是一个小小的代码,所以到这里就结束了,但是这整整花了我好几个小时去猜代码,一切祸根源自官方没有及时更新api文档,猜代码过程实在是一言难尽。所以在这里贴出一份1.21.1本的代码教程,帮助大家避坑。