本篇教程由作者设定使用 CC BY-NC-SA 协议。
教程版本:v1.0.0 based on KubeJS-forge-1605.3.19-build.299 - mcmod
前言
简要介绍
KubeJS是一个于1.16.5版本开始兴起的基于JavaScript的魔改核心模组,同时支持Fabric和Forge环境。在热重载的加持下,您可以很便捷地修改游戏中的绝大多数内容。从新增/修改物品,方块,配方到自定义游戏内逻辑、修改战利品表,自定义世界生成......没有什么是不能借助KubeJS轻松实现的。除此以外,KubeJS还可以用于管理服务器,修改客户端显示内容等。
本文相关信息
本教程最初发布于https://www.mcbbs.net/thread-1207772-1-1.html
本教程使用Markdown编写, 发布于mcmod需要重新排版,为了获得更完整流畅的观看体验现阶段还请前往mcbbs查看教程
本文将翻译,讲解部分该mod的常用功能及其附属mod,并提供多个实例以供参考
本文中未完成的部分会标记🚧
本文内没有特别注明的原创内容,均根据知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可
受本人水平,时间因素及KubeJS自身版本更新的影响,本文中难免还存在一些问题/过时内容,还请各位坛友斧正,谢谢!
实用链接
KubeJS 官方Wiki:https://mods.latvian.dev/books/kubejs
KubeJS 站内搬运贴:https://www.mcbbs.net/thread-1200250-1-1.html
KubeJS 源代码(1.16.5分支):https://github.com/KubeJS-Mods/KubeJS/tree/1.16/main/common/src/main/java/dev/latvian/kubejs
KubeJS 官方Discord交流频道:https://discord.gg/hCVTFHKE
本文部分内容参考/翻译自以上内容,在这里表示感谢
基础代码格式和常用指令
脚本语言
KubeJS使用 JavaScript 来对游戏进行修改(这也就是为什么 Rhino 会是它的前置)。
文件结构
在正确安装KubeJS并启动过一次游戏后,你可以在版本根目录下找到kubejs这个文件夹,
kubejs
├─assets
│ └─kubejs
│ └─textures
│ ├─block
│ └─item
├─client_scripts
├─config
├─data
├─exported
│ └─tags
├─server_scripts
└─startup_scripts
以下为各个目录的功能(详见目录下README.txt):
assets 文件夹和资源包的功能基本相同,你可以在这里的对应目录下放自定义方块、物品的纹理、模型等,也可以当做一个全局资源包加载器(类似于OpenLoader)
config 中包括对KubeJS的一些配置选项
data 文件夹和数据包功能基本相同,类似于全局数据包加载器(类似于OpenLoader)
client_scripts 中为客户端资源被加载时加载脚本
(如 client.tick 等被标记为Client和Client Startup的事件)(可使用 F3 + T 重载)
server_scripts 中为服务端资源被加载时加载的脚本
(如 recipes 等被标记为Server和Server Startup的事件)(可使用游戏内命令 /reload 重载)
startup_scripts 中为启动时就被加载的脚本
(如 item.modification 等被标记Startup的事件)(可使用游戏内命令 /kubejs reload_startup_scripts 重载)
代码基础格式
如JavaScript一样,所有的脚本后缀名都应为.js
代码基础格式如下
onEvent('事件名称', event => {
//在此处编写代码 <- 这是一行注释,JavaScript的注释格式详见百度
})
比如,以下代码会在玩家加入世界时将指定内容打印到控制台
onEvent('player.logged_in', event => {
let name = event.player.name
console.log("玩家 " + name + " 加入了游戏")
})
其中 player.logged_in 就是被监听的事件,当该事件发生时,就执行函数内容(console.log语句)
JavaScript语法
在阅读本篇教程前,你最好先了解以下内容
JavaScript语法
if 和 if else
for循环
while循环
函数
箭头函数
当然,你也可以把 JavaScript教程 看一遍
KubeJS游戏内指令
使用/kubejs custom_command <command> 可以执行自定义指令
使用/kubejs errors 可以在聊天栏中获取当前脚本的报错
使用/kubejs export 可以将游戏内的配方、tags、所有方块、实体类型、流体类型导出到kubejs\exported\kubejs-server-export.json
注:你可以将该json文档上传至https://export.kubejs.com/来进行分析(截至编辑本文时该功能不可用)
使用/kubejs hand 或 /kjs_hand 可以快速获取手中物品信息,这对于配方自定义等非常有帮助(点击文本即可复制)
使用/kubejs hotbar 可以将快捷栏中所有物品信息打印到聊天栏(同/kubejs hand)
使用/kubejs inventory 可以将玩家物品栏的所有物品信息打印到聊天栏(同/kubejs hand)
使用/kubejs offhand 可以将玩家副手的物品信息打印到聊天栏(同/kubejs hand)
使用/kubejs list_tags <tag> [block|fluid|item|entity_type] 来将给定标签的内容打印到聊天栏
如/kubejs list_tag minecraft:logs item 会将#minecraft:logs标签下的元素打印出来
使用/kubejs painter <玩家名称> <PainterJS对象> 来调用PainterJS(见第十六章)
使用/kubejs reload [server_scripts|lang|texture|startup_scripts] 来重载服务器类型脚本、语言文件、纹理资源和启动类型脚本
其中/kubejs reload server_scripts和/reload的效果基本相同
/kubejs reload startup_scripts 并不能重载所有启动脚本事件,如方块注册等
使用/kubejs stage [add|list|remove|clear] <玩家名称> 来为指定玩家添加、列出、移除或清除游戏阶段
关于Gamestage的详细介绍见11.4和11.5章节
使用/kubejs warnings 来查看当前脚本中的警告信息
使用/kubejs wiki 来打开官方KubeJS Wiki
KubeJS中的事件
配方
本章代码文件应放于.minecraft\kubejs\server_scripts下
本章内容对应事件:recipes,即你的代码应该是这样的
onEvent('recipes', event => {
//示例配方修改
event.shaped('3x minecraft:stone', [
'SSS',
'S S',
'SSS'
], {
S: 'minecraft:sponge'
})
})
本章为了表述简洁省略了onEvent部分
物品表示与新建配方
物品的表示方法——IngredientJS和ItemstackJS
KubeJS提供了IngredientJS和ItemstackJS用于表示物品。比如,标签Ingredient.of("#minecraft:logs")就是Ingredient,Item.of('minecraft:iron_ingot')就是一个Itemstack
其中Ingredient多用于匹配物品。你可以使用Ingredient.matchAny("条件")来获得一个包含当前筛选条件的物品组,其中条件可以为物品ID(minecraft:diamond),mod注册名(@tinkersconstruct),标签(#minecraft:logs)
Itemstack主要用于表示准确的物品组,ItemstackJS可使用的属性/函数如下:
配方修改需要用到的大都是上表加粗的内容,剩余的内容大都等到第15章判断物品状态时才会用到。
估计你看到上面这些东西得有点麻了,不要慌,让我们看几个例子
显然,上面的方法表示物品非常麻烦。KubeJS提供了一些简写方法:
你可以使用命名空间ID直接表示一个物品,如"minecraft:iron_ingot"
你可以直接使用标签的字符串表示这一标签下的使用物品,如"#minecraft:logs"
你可以在命名空间前加上倍数来表示物品个数,如"5x minecraft:iron_ingot"表示五个铁锭
当然,你也可以直接使用正则表达式
你可以使用指令/kubejs hand来快速获取手持物品信息,详见1.1 基础代码格式和常用指令
有序配方添加
语句:event.shaped(输出物品 , 输入物品)
例子:用8个海绵合成3个石头
onEvent('recipes', event => { // 监听recipes事件
// 主体修改内容
event.shaped('3x minecraft:stone', [
'SSS',
'S S',
'SSS'
], {
S: 'minecraft:sponge'
})
})
可以看到,KubeJS采用了类似原版的格式来修改配方,如果你的配方不需要三行的话,直接留空即可
注:下文为了表述简洁将省略onEvent部分
无序配方添加
语句:event.shapeless(输出物品 , 输入物品)
例子:用1个石头和1个带萤石粉标签的物品合成4个圆石
event.shapeless('4x minecraft:cobblestone', ['minecraft:stone', '#forge:dusts/glowstone'])
熔炉高炉等配方的添加
// 添加切石机配方:用1个minecraft:golden_apple合成4个minecraft:apple
event.stonecutting('4x minecraft:apple', 'minecraft:golden_apple')
// 添加切石机配方:用1个minecraft:golden_apple合成2个minecraft:carrot
event.stonecutting('2x minecraft:carrot', 'minecraft:golden_apple')
// 添加熔炉配方:用1个minecraft:golden_apple合成2个minecraft:carrot
// (event.recipes.minecraft.smelting的缩写)
event.smelting('2x minecraft:carrot', 'minecraft:golden_apple')
// 添加高炉,营火和烟熏炉的配方(与上文类似)
event.blasting('3x minecraft:apple', 'minecraft:golden_apple')
// 添加锻造台配方,将后2个物品合并成第一个物品 (将minecraft:gold_ingot和minecraft:apple合成为minecraft:golden_apple)
event.smithing('minecraft:golden_apple', 'minecraft:apple', 'minecraft:gold_ingot')
NBT和配方ID
带NBT的配方修改:
event.shaped('minecraft:book', [
'CCC',
'WGL',
'CCC'
], {
C: '#forge:cobblestone',
L: Item.of('minecraft:enchanted_book', {StoredEnchantments:[{lvl:1,id:"minecraft:sweeping"}]}),
// 尽管格式是相同的,但是对于附魔来说,你还可以将其简写成如下形式:
W: Item.of('minecraft:enchanted_book').enchant('minecraft:respiration', 2),
G: '#forge:glass'
})
mc中所有的配方都有一个随机的ID,但以下配方被指定了一个唯一的静态ID。这个功能对于编写Patchouli手册等比较有用
event.smelting('minecraft:golden_apple', 'minecraft:carrot').id('wudjimodpack:wudji_first_recipe_id')
配方的修改与删除
配方的移除
配方的修改
// 在所有无序配方中,将任何木板替换为minecraft:gold_nugget
event.replaceInput({type: 'minecraft:crafting_shapeless'}, '#minecraft:planks', 'minecraft:gold_nugget')
//{}内可以填写配方类别
// 在所有配方中,将输出物品中的minecraft:stick替换为minecraft:oak_sapling
event.replaceOutput({}, 'minecraft:stick', 'minecraft:oak_sapling')
非标准配方修改
本节将介绍非标准配方的修改,包括非工作台配方、修改输入物品状态等(如原版中蛋糕的合成方式)
例子1:修改机械动力中粉碎轮的合成配方
注意!KubeJS现已有机械动力的拓展mod,无需使用该方法修改!
机械动力的修改教程详见本教程12.3部分
event.custom({
type: 'create:crushing',//指定合成方式为粉碎轮
ingredients: [
Ingredient.of('minecraft:oak_sapling').toJson()//输入内容
],
results: [//这里的 results(包括所有类似的位置的双引号都是可加可不加的)
Item.of('minecraft:apple').toResultJson(),//100%输出苹果
Item.of('minecraft:carrot').withChance(0.5).toResultJson()//50%输出苹果
],
processingTime: 100 //所用时间
})
//若上述配方使用Json格式添加(即原版数据包格式)
{
"type": "create:crushing",
"ingredients": [
{
"tag": "minecraft:oak_sapling"
}
],
"results": [
{
"item": "minecraft:apple",
"count": 1
},
{
"item": "minecraft:carrot",
"chance": 0.5
}
],
"processingTime": 100
}
如果你使用自定义的配方格式,你必须使用类似于原版Json数据包的格式,也就是必须带有"type": "mod:recipe_id"!(比如上文中提到的"type": "create:crushing"). 通过这种方式,你可以为使用原版配方系统的任何配方处理器添加配方,即使它不兼容KubeJS. KubeJS提供的简写格式为:
{item: '物品注册名', count: 数量} → Item.of('物品注册名', 数量).toResultJson()
{item: '物品注册名'} / {tag: '标签名'} →Ingredient.of('物品注册名').toJson() 和 Ingredient.of('#标签名').toJson()
下面我们再看一个例子
例子2:为Extended Crafting添加配方
event.custom({
type: 'extendedcrafting:shaped_table',
tier: 4,
pattern: [
"XXXXXXXXX",
"X X",
"X X",
"X X",
"X X",
"X X",
"X X",
"X X",
"XXXXXXXXX"
],
key: {
X: [Ingredient.of('#forge:ingots/gold').toJson()],//标签的使用
}
result: [Ingredient.of('minecraft:apple').toJson()]
})
//上述配方使用数据包修改:
{
"type": "extendedcrafting:shaped_table",
"pattern": [
"XXXXXXXXX",
"X X",
"X X",
"X X",
"X X",
"X X",
"X X",
"X X",
"XXXXXXXXX"
],
"key": {
"X": {
"tag": "forge:ingots/gold"
}
},
"result": {
"item": "minecraft:apple"
}
}
例子3:修改输入物品状态
以下是一些内置的函数
其中,所谓的输入过滤器可接受如下类型的内容
你可以在整个配方修改脚本的最后加上它们来实现你想要的效果,比如:
onEvent('recipes', event => {
event.shapeless().damageItem(Item.of('minecraft:diamond_sword').ignoreNBT())
......})
下面是几个例子
onEvent('recipes', event => {
//用钻石剑切西瓜
event.shapeless('9x minecraft:melon_slice', [ //无序合成,合成输出: 9个西瓜片
Item.of('minecraft:diamond_sword').ignoreNBT(), //输入一个忽略NBT的钻石剑
'minecraft:minecraft:melon' // 其他输入内容
]).damageItem(Item.of('minecraft:diamond_sword').ignoreNBT()) // 降低钻石剑耐久1点(必须忽略NBT)
// 使用两个钻石剑合成kubejs:example_block. 合成后索引为1的钻石剑掉一点耐久并保留第二个钻石剑.
event.shaped('kubejs:example_block', [
'SD ',
'D S'
], {
S: Item.of('minecraft:diamond_sword').ignoreNBT(),
D: 'minecraft:dirt'
}).damageIngredient(0).keepIngredient('minecraft:diamond_sword')//叠加使用多个函数
// 使用两个钻石剑合成kubejs:example_block. 合成后钻石剑被替换为石剑
event.shapeless('kubejs:example_block', [
Item.of('minecraft:diamond_sword').ignoreNBT(),
'minecraft:stone',
Item.of('minecraft:diamond_sword').ignoreNBT(),
'minecraft:stone'
]).replaceIngredient('minecraft:diamond_sword', 'minecraft:stone_sword')
// 使用沙子,骨粉,土方块和水瓶合成陶土. 合成后,水瓶被玻璃瓶所替代
event.shapeless('minecraft:clay', [
'minecraft:sand',
'minecraft:bone_meal',
'minecraft:dirt',
Item.of('minecraft:potion', {Potion: "minecraft:water"})
]).replaceIngredient({item: Item.of('minecraft:potion', {Potion: "minecraft:water"})}, 'minecraft:glass_bottle')
})
标签
你应将本文件的内容放于.minecraft\kubejs\server_scripts下
onEvent('item.tags', event => {
// 获取 #forge:cobblestone,然后将minecraft:diamond_ore添加进去
event.add('forge:cobblestone', 'minecraft:diamond_ore')
// 获取#forge:cobblestone,然后移除minecraft:mossy_cobblestone
event.remove('forge:cobblestone', 'minecraft:mossy_cobblestone')
// 移除#forge:ingots/copper
event.removeAll('forge:ingots/copper')
})
实体标签等其他类型的标签同理
自定义Loot Table
(本章参考了Minecraft 原版模组入门教程 - 战利品表(作者ruhuasiyu))
(Forge推荐安装KubeJS附属LootJS以便捷修改战利品表,教程&相关介绍见本文12-7 便捷战利品表修改(LootJS Forge))
KubeJS目前能修改全局、方块、实体、猫或村民礼物(村庄英雄Buff)、钓鱼、宝箱战利品表
基本的方法名称如下
下面就下面5种的战利品表进行讲解。
基本格式
onEvent('事件ID', event => {
event.覆盖/修改原有战利品表方法名称('物品/实体注册名', table => {
//修改内容
}
//table.clearPools()//清空所有随机池
//table.clearConditions()//清空条件
//table.clearFunctions()//清空函数
})
方块战利品表(block.loot_tables)
针对方块战利品表,KubeJS提供了很简单的添加单方块掉落物的方法。
onEvent('block.loot_tables', event => {
event.addSimpleBlock('minecraft:dirt', 'minecraft:red_sand')//覆盖泥土的战利品表并使泥土掉落红沙
event.addSimpleBlock('minecraft:oak_leaves')//覆盖橡树树叶的战利品表并使橡树树叶在破坏时掉落自身
})
如果你想要实现更复杂的修改,你需要使用随机池。KubeJS提供了一些简写方法,具体见下方例子。
onEvent('block.loot_tables', event => {
event.addBlock('minecraft:dirt', table => {
table.addPool(pool => {//新建随机池(覆盖原有的)
pool.rolls = 1 // 固定值
// pool.rolls = [4, 6] // 也可写为 {min: 4, max: 6} // 抽奖次数∈[4,6]
// pool.rolls = {n: 4, p: 0.3} // 二项分布
//以上两种值的表达方式为值提供器
pool.addItem('minecraft:dirt')
//pool.addItem('minecraft:dirt', 40) // 此处40为权重
//pool.addItem('minecraft:dirt', 40, [4, 8]) // 物品个数∈[4,8]
// pool.addCondition({json}) //json格式,抽取该物品需要满足的条件,原版数据包格式(具体使用情景详见14.1)
// pool.addEntry({json})//json格式,项目类别
})
})
})
实体战利品表(entity.loot_tables)
onEvent('entity.loot_tables', event => {
// 覆盖僵尸的战利品表,掉落5个物品(25%概率为胡萝卜,75%为苹果)
event.addEntity('minecraft:zombie', table => {
table.addPool(pool => {
pool.rolls = 5//抽5次奖
pool.addItem('minecraft:carrot', 1)
pool.addItem('minecraft:apple', 3)
})
})
event.modifyEntity('minecraft:pig', table => {
table.addPool(pool => {
// 修改猪的战利品表,使在被玩家杀死时多掉落一个泥土
// 注:只是修改战利品表。并不会覆盖原有的掉落生/熟猪肉的战利品表
pool.addItem('minecraft:dirt')
pool.killedByPlayer()
})
})
})
注:对于gift.loot_tables、fishing.loot_tables、chest.loot_tables,只能使用addJson(物品注册名, json原版格式)来进行修改
常用表达方式
自定义流体
KubeJS允许你在startup阶段自定义流体。对应事件:fluid.registry
不过到目前为止,Fabric下的KubeJS还不支持自定义流体
不得不说KubeJS还是非常良心的,注册流体还免费送你个桶(doge)
[1]:使用16进制,形如0x844031
[2]:从本行往下,楼主测试时均无法实现预期效果,功能描述为楼主的"臆断"(游戏版本1.16.5 KubeJS版本1605.3.19-build.299),但是理论上这些是可以用的,可能和楼主电脑有关系吧
例子:
onEvent('fluid.registry', event => {
event.create("test_mud").displayName("泥").bucketColor(0x844031).textureThick(0x844031).textureThin(0x844031);
})
自定义世界生成
onEvent('worldgen.add', event => {
event.addLake(lake => { // 自定义湖
lake.block = 'minecraft:diamond_block' // 方块ID (使用 [] 来为其添加属性)
lake.chance = 3 // 约3个区块生成一次
})
event.addOre(ore => { //自定义矿石
ore.block = 'minecraft:glowstone' // 方块ID (使用 [] 来为其添加属性)
ore.spawnsIn.blacklist = false // 是否在矿石生成黑名单位置处生成
ore.spawnsIn.values = [ // 该矿石可以在以下位置生成(支持方块ID、标签)
'#minecraft:base_stone_overworld' // 默认的生成方式: 用于决定作为地下矿石生成时,该矿石能取代哪些方块。你可以在https://wiki.biligame.com/mc/%E6%A0%87%E7%AD%BE查看更多信息。
]
ore.biomes.blacklist = true // 是否在矿石生成黑名单群系中生成
ore.biomes.values = [ // 矿石可以生成的群系
'minecraft:plains', // 群系ID
'#nether' // 或者你可以使用“# + 群系类别”来代表群系, 在文末查看可用的列表
]
ore.clusterMinSize = 5 // 每矿簇最少的矿石数量 (现在 ore.clusterMinSize 选项是被忽略的, 该功能将在以后更新, 现在它恒为1)
ore.clusterMaxSize = 9 // 每矿簇最多的矿石数量
ore.clusterCount = 30 // 每个区块矿石数量
ore.minHeight = 0 // 最小Y值
ore.maxHeight = 64 // 最大Y值
ore.squared = true // 对X和Z值添加0~16的随机值. 推荐设置为 true
// ore.chance = 4 // 每大约4个区块生成一次. 对于稀有的矿石来说, 你可以将它和 clusterCount = 1 一同使用
})
event.addSpawn(spawn => { // 自定义实体生成
spawn.category = 'monster' // 实体类别, 可以设为 'creature', 'monster', 'ambient', 'water_creature' 和 'water_ambient'
spawn.entity = 'minecraft:magma_cube' // 实体ID
spawn.weight = 10 // 生成权重
spawn.minCount = 4 // 每组最小数量
spawn.maxCount = 4 // 每组最大数量
})
})
onEvent('worldgen.remove', event => {
event.removeOres(ores => {//移除矿石
ores.blocks = [ 'minecraft:coal_ore', 'minecraft:iron_ore' ] // 移除铁矿和煤矿
ores.biomes.values = [ 'minecraft:plains' ] // 限制该选项仅在平原生效
})
event.removeSpawnsByID(spawns => {//通过实体ID来禁止指定实体生成
spawns.entities.values = [
'minecraft:cow',
'minecraft:chicken',
'minecraft:pig',
'minecraft:zombie'
]
})
event.removeSpawnsByCategory(spawns => {//移除实体生成
spawns.biomes.values = [
'minecraft:plains'//指定为平原群系
]
spawns.categories.values = [//类型为怪物
'monster'
]
})
})
修改展示
自定义方块
onEvent('block.registry', event => {
event.create('test_block', block => {
block.material('glass')//设置方块材质
block.hardness(0.5)//设置方块硬度
block.displayName('Test Block')
})
})
// MC1.16版本的KubeJS 3还可以将以上内容简写为:
onEvent('block.registry', event => {
event.create('test_block')
.material('glass')
.hardness(0.5)
.displayName('Test Block')
})
//你还可以把他们在一行中连着写
onEvent('block.registry', event => {
event.create('example_block').material('wood').hardness(1.0).displayName('Example Block')
})
该方块的纹理必须被放于kubejs/assets/kubejs/textures/block/[方块名],如kubejs/assets/kubejs/textures/block/test_block.png
如果你想要使用自定义的模型,你可以使用Blockbench制作并把它放于 kubejs/assets/kubejs/models/block/[方块名].json , 如 kubejs/assets/kubejs/models/block/test_block.json.
其他支持的方法(需要在它们之前加block.):
material('material')// 设置方块的“质地”,可用的参数见下
type('basic') // 设置方块类型,可用的参数见下
hardness(float) // 设置方块硬度,值需要大于 >= 0.0;若要使方块无法被破坏,详见下方。
resistance(float) // 爆炸抗性,值需要大于 >= 0.0
unbreakable() // 设置方块无法被破坏
lightLevel(等级) // 方块光照等级,值属于[0 , 1](需要为整形)
harvestTool('工具', 工具等级) // 可以破坏该方块的工具。工具参数可以为 pickaxe, axe, hoe, shovel,工具等级需 >= 0
opaque(布尔值) // 方块是否透明
fullBlock(布尔值) // 设置是否为完整方块,与notSolid()共同使用可以实现如下图所示效果(即镂空方块)
requiresTool(布尔值) // 是否需要对应工具才能掉落
renderType('类型') // 设置方块的渲染类型,可用的选项有solid(实心), cutout(镂刻), translucent(半透明), 其中 cutout 可用于类似于玻璃的方块,translucent 可用于类似于染色玻璃的方块
color(tintindex, color)// 修改方块颜色,具体可参考此处介绍
texture('纹理路径')// 设置方块纹理
texture('方向', '纹理路径')// 设置方块纹理(可以单独设置每个朝向的纹理)
model('模型路径')// 设置方块使用的模型
noItem()// 添加方块而不添加方块对应的物品
box(x0, y0, z0, x1, y1, z1, true) // 设置方块碰撞箱(0~16),默认值为(0,0,0,16,16,16, true)
box(x0, y0, z0, x1, y1, z1, false) // 设置方块碰撞箱(0~1),默认值为(0,0,0,1,1,1, false)
noCollision() // 设置方块是否有碰撞箱
notSolid() // 见上
waterlogged() // 是否可以被充水
noDrops() // 被破坏是否掉落自身
slipperiness(浮点型) // 设置打滑程度
speedFactor(浮点型) // 玩家在上方移动速度倍率
jumpFactor(浮点型)
randomTick(randomTickEvent => {}) // 当方块被随机刻选中时发生的事件
支持以下函数:
BlockContainerJS block
Random random
下面是一个简单的例子//当test_block_randomTickEvent被随机刻选中时将其换为minecraft:dirt
onEvent('block.registry', event => {
event.create('test_block_randomTickEvent', block => {
//block.material('glass')
//block.hardness(1.0)
block.displayName('Test Block randomTickEvent')
block.randomTick(randomTickEvent => {
randomTickEvent.block.set('minecraft:dirt')// BlockContainerJS
})
})
})注:BlockContainerJS会在后面讲到(15章,尚未更新)
item(itemBuilder => {}) // 掉落物设置
setLootTableJson(json) // 设置战利品表(原版json格式)
setBlockstateJson(json) // 设置方块状态(原版json格式)
setModelJson(json) // 设置模型
noValidSpawns(布尔值) // 是否可以生成怪物
suffocating(布尔值) // 是否可以使玩家窒息
viewBlocking(布尔值)
redstoneConductor(布尔值) // 是否传导红石信号
transparent(布尔值) // 是否透明
defaultCutout() // 用来制作类似于玻璃的方块的方法的集合
defaultTranslucent() // 与defaultCutout()类似,但是使用透明层
tag('forge:exampletag') // 添加block tag
tagBlockAndItem('forge:exampletag') // 为方块和物品添加tag
可用的方块类型(type() 方法)
basic
slab
stairs
fence
fence_gate
wall
wooden_pressure_plate
stone_pressure_plate
wooden_button
stone_button
可用的材质的值( material('material') ) - 该参数会改变方块被破坏和玩家行走在上面的声音并且预设一些属性(如破坏用的工具等):
聊天事件
一个基础的例子:当有人在发送‘kubejs教程’时回复'请访问https://www.mcbbs.net/thread-1207772-1-1.html'
onEvent('player.chat', function (event) {
// 检测如果聊天内容为“kubejs教程” 执行命令, 忽略大小写
if (event.message.trim().equalsIgnoreCase('kubejs教程')) {
// 将事件推迟1刻,否则服务器信息将会显示在玩家信息之前
event.server.scheduleInTicks(1, event.server, function (callback) {
// 对每个人说以下内容,颜色为绿色。聊天信息为[Server]
callback.data.tell(text.green('请访问h t tp s://www.mcbbs.net/thread-1207772-1-1.html'[/url]))
// 下面这个设置了聊天信息为红色的[Test]
callback.data.tell([Text.red('[Test]'),text.green('请访问h t tp s://www.mcbbs.net/thread-1207772-1-1.html')])
})
}
})
另一个例子:监测到聊天信息时执行对应指令
onEvent('player.chat', function (event) {
if (event.message.startsWith('test')) {
event.server.runCommandSilent('kick '+event.player.name+' test ')
event.server.runCommandSilent(`say 已踢出玩家${event.player.name}`)
event.cancel()//取消该事件,也就是说玩家的聊天信息不会显示
}
})
利用取消的这一特性,你甚至还可以做到"伪造"聊天
下面这个例子在检测到发送消息的玩家带有 rankexample 进度时在其聊天信息前加上rank标识
onEvent('player.chat',function (event){
let input = event.message.trim();//获取聊天信息
if(event.player.stages.has("rankexample")){
event.server.tell([Text.blue('[MVP--]').bold(), `<${event.player.name}> ${input}`]);
event.cancel();
}
})
注:更多关于gamestage的操作详见11-4章节,关于玩家、世界的操作详见第15章
后续教程待搬运,请先前往mcbbs阅读