Wudji
本帖最后由 Wudji 于 2023-2-13 23:47 编辑




1 前言



简要介绍

KubeJS是一个于1.16.5版本开始兴起的基于JavaScript的魔改核心模组,同时支持Fabric和Forge环境。在热重载的加持下,您可以很便捷地修改游戏中的绝大多数内容。从新增/修改物品,方块,配方到自定义游戏内逻辑、修改战利品表,自定义世界生成......没有什么是不能借助KubeJS轻松实现的。除此以外,KubeJS还可以用于管理服务器,修改客户端显示内容等。

本文相关信息

本文将翻译,讲解部分该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分支):KubeJS-Mods/KubeJS at eol/1.16

KubeJS 源代码(1.18.2分支):KubeJS-Mods/KubeJS at 1.18/main

KubeJS 官方Discord交流频道:https://discord.gg/latviandev

本文部分内容参考/翻译自以上内容,在这里表示感谢

修改内容展示



点击链接加入群聊【Kubejs魔改交流群 665153457】:https://jq.qq.com/?_wv=1027&k=BcBId3tR








2021.12 数据,可能有更多内容
1:前言&基础内容
这是什么?

KubeJS是一个类似于crafttweaker的mod,并同时支持fabric和forge。你将能够在KubeJS的帮助下,用JavaScript脚本来编辑或新建配方、实体、标签、物品、方块、流体、世界生成、监听聊天信息、方块放置等许多功能。


本文将翻译,讲解部分该mod的常用功能及其附属mod(todo),并提供多个实例以供参考(部分完成)


本教程部分内容翻译自或参考以下内容或wiki:
KubeJS | LatvianModder's Mods


可能有用的链接:
KubeJS/common/src/main/java/dev/latvian/kubejs at main · KubeJS-Mods/KubeJS (github.com)
[1.16.X-1.14.4][KubeJS——游戏修改]使用JS脚本来魔改游戏!支持Fabric和Forge (mcbbs.net)


本教程所有内容均是在1.16.5 forge版本上测试的,理论上来说其他版本应该也能用。可能涉及到的服务器相关内容均在forge官端上测试过


受本人水平及时间因素的影响,若有任何问题请在评论区指出,谢谢!


更新日志
20210629 本帖发布

1-1 基础代码格式
在kubejs中,所有修改脚本都应放在以.js结尾的文件内,并且,在对内容进行修改时,要先监听该内容所属的事件
监听事件的基本格式如下

代码:

  1. onEvent('事件名称', event => {

  2. //在此处编写代码

  3. })

以下为事件详细列表:
ID
是否可被取消
类型
是否支持Fabric版本
init
Startup
postinit
Startup
loaded
Startup
command.registry
Server Startup
command.run
Server
client.init
Client Startup
client.debug_info.left
Client
client.debug_info.right
Client
client.logged_in
Client
client.logged_out
Client
client.tick
Client
server.load
Server Startup
server.unload
Server
server.tick
Server
server.datapack.first
Server Startup
server.datapack.last
Server Startup
recipes
Server Startup
world.load
Server
world.unload
Server
world.tick
Server
world.explosion.pre
Server
world.explosion.post
Server
player.logged_in
Server
player.logged_out
Server
player.tick
Server
player.data_from_server.
Client
player.data_from_client.

Server
player.chat

Server

player.advancement
Server

player.inventory.opened
Server

player.inventory.closed
Server

player.inventory.changed
Server

player.chest.opened
Server

player.chest.closed
Server

entity.death
Server

entity.attack

Server

entity.drops

Server
entity.check_spawn

Server
entity.spawned

Server

block.registry
Startup

block.missing_mappings
Server Startup
block.tags
Server Startup

block.right_click

Server
block.left_click

Server

block.place

Server

block.break

Server

block.drops

Server
item.registry

Startup

item.missing_mappings
Server Startup
item.tags

Server Startup

item.right_click
Server

item.right_click_empty
Server

item.left_click
Server

item.entity_interact

Server

item.pickup

Server

item.tooltip
Client

item.toss
Server

item.crafted
Server

item.smelted
Server

fluid.tags
Server Startup

entity_type.tags
Server

worldgen.add
Startup

worldgen.remove
Startup




其中Startup类型应放于.minecraft/kubejs/startup_scripts下,Server和Server Startup应放于.minecraft/kubejs/server_scripts下,Client和Client Startup类型应放于.minecraft/kubejs/client_scripts下


Server Startup和Client Startup类型将会随服务器和客户端的启动而一同加载。
Server脚本可以通过/reload命令重载



2:配方


1、本段代码文件应放于.minecraft\kubejs\server_scripts下
2、对于单个物品,你可以使用 'mod:id' 来代表它 。对于≥2个的,你需要使用 '2x mod:id' 或者 Item.of('mod:id', 数量) 来代表. 如果你想要在配方中使用概率或者NBT,你需要使用第二种表达方式
3、本段内容对应事件:recipes





2-1 配方的添加
本页面将介绍配方的添加方法


2-1-1 有序配方的添加
格式:

代码:

  1. event.shaped(输出物品 , 输入物品)
  2. //下边是另一种表达方式
  3. event.recipes.minecraft.crafting_shaped(输出物品 , 输入物品)

举个例子:用8个海绵合成3个石头

用js表示为:

代码:

  1. event.shaped('3x minecraft:stone', [
  2.     'SSS',
  3.     'S S',
  4.     'SSS'
  5. ], {
  6.     S: 'minecraft:sponge'
  7. })

其中[]内代表其在工作台中摆放的形状,为空时可以用空格代替
对于输出三个物品,则使用了 3x minecraft:stone 的表达方式




2-1-2 无序配方的添加
格式:

代码:

  1. event.shapeless(输出物品 , 输入物品)
  2. //下边是另一种表达方式
  3. event.recipes.minecraft.crafting_shapeless(输出物品 , 输入物品)

另一个栗子:用1个石头和1个带萤石粉标签的物品合成4个圆石



用js表示为:

代码:

  1. event.shapeless('4x minecraft:cobblestone', ['minecraft:stone', '#forge:dusts/glowstone'])



2-1-3 切石机、熔炉、高炉、烟熏炉、锻造台配方的添加


又好几个栗子:



用js表示为

代码:

  1. // 添加切石机配方:用1个minecraft:golden_apple合成4个minecraft:apple
  2. event.stonecutting('4x minecraft:apple'/* 输出物品 */, 'minecraft:golden_apple'/* 输入物品 */)

  3. // 添加切石机配方:用1个minecraft:golden_apple合成2个minecraft:carrot
  4. event.stonecutting('2x minecraft:carrot'/* 输出物品 */, 'minecraft:golden_apple'/* 输入物品 */)

  5. // 添加熔炉配方:用1个minecraft:golden_apple合成2个minecraft:carrot
  6. // (event.recipes.minecraft.smelting的缩写)
  7. event.smelting('2x minecraft:carrot'/* 输出物品 */, 'minecraft:golden_apple'/* 输入物品 */)

  8. // 添加高炉,营火和烟熏炉的配方(与上文类似)
  9. event.blasting('3x minecraft:apple', 'minecraft:golden_apple')

  10. // 添加锻造台配方,将后2个物品合并成第一个物品 (将minecraft:gold_ingot和minecraft:apple合成为minecraft:golden_apple)
  11. event.smithing('minecraft:golden_apple', 'minecraft:apple', 'minecraft:gold_ingot')

另外地,你可以在烧炼类配方的结尾加上.xp(经验数量)来给予一定的经验奖励
下面的这个配方会在烧炼结束后给予玩家1点经验

代码:

  1.    // 添加烟熏炉配方 用一个minecraft:golden_apple合成5个苹果
  2. event.smoking('5x minecraft:apple', 'minecraft:golden_apple').xp(1.0)



2-1-4 NBT和配方ID


带NBT的物品格式:

代码:

  1. Item.of('id', {key: value})

下面的例子展示了NBT物品的添加

代码:

  1. event.shaped('minecraft:book', [
  2.     'CCC',
  3.     'WGL',
  4.     'CCC'
  5. ], {
  6.     C: '#forge:cobblestone',
  7.     L: Item.of('minecraft:enchanted_book', {StoredEnchantments:[{lvl:1,id:"minecraft:sweeping"}]}),
  8.     // 尽管格式是相同的,但是对于附魔来说,你还可以将其简写成如下形式:
  9.     W: Item.of('minecraft:enchanted_book').enchant('minecraft:respiration', 2),
  10.     G: '#forge:glass'
  11. })

你可以通过指令 /kubejs hand 来快速获取你手中物品的对应信息

单击文字即可复制


mc中所有的配方都有一个随机的ID,但以下配方被指定了一个唯一的静态ID。这个功能对于编写Patchouli手册比较有用

代码:

  1. event.smelting('minecraft:golden_apple', 'minecraft:carrot').id('wudjimodpack:wudji_recipe_id'/* 配方ID */)




2-2 配方的修改与删除
本页面将介绍配方的修改与删除方法

2-2-1 配方的移除
例子
用途解释
event.remove({})
删除所有配方
event.remove({id: '物品ID'})
移除合成该物品的所有配方
event.remove({input: '#forge:dusts/redstone'})
移除所有以带有#forge:dusts/redstone标签为输入物品的配方
' '内也可以填物品ID
event.remove({output: '#minecraft:wool'})
移除所有以带有#minecraft:wool标签为输出物品的配方
' '内也可以填物品ID
event.remove({mod: 'fabricexamplemod'})
移除所有id为fabricexamplemod的mod添加的配方
event.remove({type: 'minecraft:campfire_cooking'})
移除以营火为合成方式的配方
event.remove({output: 'minecraft:cooked_chicken', type: 'minecraft:campfire_cooking'})
(叠加不同修改逻辑的示例)
移除用营火烤鸡肉的配方, 或者叫“移除以营火为合成方式,输出物品为熟鸡肉的配方”


2-2-2 配方修改
以下是两个例子

代码:

  1. // 在所有无序配方中,将任何木板替换为minecraft:gold_nugget
  2. event.replaceInput({type: 'minecraft:crafting_shapeless'}, '#minecraft:planks', 'minecraft:gold_nugget')
  3. //{}内可以填写配方类别

  4. // 在所有配方中,将输出物品中的minecraft:stick替换为minecraft:oak_sapling
  5. event.replaceOutput({}, 'minecraft:stick', 'minecraft:oak_sapling')


2-3 使用函数简化代码
(实际上也没简化到哪去)

先来看这样一段代码:

代码:

  1.     event.smelting('minecraft:blue_dye', '#forge:gems/lapis')
  2.     event.smelting('minecraft:black_dye', 'minecraft:ink_sac')
  3.     event.smelting('minecraft:white_dye', 'minecraft:bone_meal')
  4.     event.blasting('minecraft:blue_dye', '#forge:gems/lapis')
  5.     event.blasting('minecraft:black_dye', 'minecraft:ink_sac')
  6.     event.blasting('minecraft:white_dye', 'minecraft:bone_meal')
不难看出,这些配方具有一定的特征:使用高炉或锻造台合成,输入输出物品相同(如1和行)
这时,你就可以通过新建并调用函数来简化这些代码

代码:

  1. const multiSmelt = (output, input) => {// 本行output和input为参数,下同
  2.     event.smelting(output, input)  // 添加熔炉配方,input->output
  3.     event.blasting(output, input)  // 添加高炉配方,input->output
  4. }

  5. //调用函数multiSmelt
  6. multiSmelt('minecraft:blue_dye'/* 相当于output,下同 */, '#forge:gems/lapis'/* 相当于input,下同 */)
  7. multiSmelt('minecraft:black_dye', 'minecraft:ink_sac')
  8. multiSmelt('minecraft:white_dye', 'minecraft:bone_meal')
当然,你也可以在添加其他修改项(如战利品表等)时使用该方法
(本质上还是复制粘贴,不过看起来可能更高级...点?)

3:标签


你应将本文件的内容放于.minecraft\kubejs\server_scripts下

代码:

  1. onEvent('item.tags', event => {
  2.   // 获取 #forge:cobblestone,然后将minecraft:diamond_ore添加进去
  3.   event.add('forge:cobblestone', 'minecraft:diamond_ore')

  4.   // 获取#forge:cobblestone,然后移除minecraft:mossy_cobblestone
  5.   event.remove('forge:cobblestone', 'minecraft:mossy_cobblestone')

  6.   // 移除#forge:ingots/copper
  7.   event.removeAll('forge:ingots/copper')
  8. })
实体标签等其他类型的标签同理



4:自定义loot table[WIP]
该部分还在开发中


你应将本文件的内容放于.minecraft\kubejs\server_scripts下

代码:

  1. //当前kubejs还只能修改方块的loot table

  2. onEvent('block.loot_tables', event => {
  3. event.addSimpleBlock('minecraft:dirt', 'minecraft:red_sand')//泥土掉落红沙
  4. })

  5. onEvent('block.loot_tables', event => {
  6. event.addSimpleBlock('minecraft:dirt') // 掉落自身方块
  7. event.addSimpleBlock(/minecraft:.*_ore/, 'minecraft:red_sand') // 所有原版矿石的掉落物均改为红沙
  8. })

  9. onEvent('block.loot_tables', event => {
  10. event.build('minecraft:dirt', table => { // 为minecraft:dirt手动新建loot table
  11.     table.pool(pool => { //新建随机池
  12.     //本部分内容详细介绍请查阅mcwiki:https://wiki.biligame.com/mc/%E6%88%98%E5%88%A9%E5%93%81%E8%A1%A8
  13.     //或由ruhuasiyu编写的教程:https://zhangshenxing.gitee.io/vanillamodtutorial/#%E6%88%98%E5%88%A9%E5%93%81%E8%A1%A8
  14.    pool.rolls = 1 // 你可以使用以下内容(fixed, uniform, binominal)来代替本行,具体释义详见上述wiki或教程
  15.    // pool.setUniformRolls(4, 6)
  16.    // pool.setBinomialRolls(4, 0.3)
  17.    pool.survivesExplosion()// 爆炸掉落
  18.    pool.addItem('minecraft:dirt')// 直接添加物品
  19.    // pool.addCondition({使用该随机池的条件(json格式),详见上述wiki或教程})
  20.    // pool.addEntry({项目列表(json格式), 详见上述wiki或教程})
  21.     })
  22. })
  23. })
(待补充:使用实例)



todo


6:自定义世界生成
添加/移除矿石,湖等 暂不支持fabric


以下为几个例子

代码:

  1. onEvent('worldgen.add', event => {
  2. event.addLake(lake => { // 自定义湖
  3.     lake.block = 'minecraft:diamond_block' // 方块ID (使用 [] 来为其添加属性)
  4.     lake.chance = 3 // 约3个区块生成一次
  5. })

  6. event.addOre(ore => { //自定义矿石
  7.     ore.block = 'minecraft:glowstone' // 方块ID (使用 [] 来为其添加属性)
  8.     ore.spawnsIn.blacklist = false // 是否在矿石生成黑名单位置处生成
  9.     ore.spawnsIn.values = [ // 该矿石可以在以下位置生成(支持方块ID、标签)
  10.    '#minecraft:base_stone_overworld' // 默认的生成方式: 用于决定作为地下矿石生成时,该矿石能取代哪些方块。你可以在https://wiki.biligame.com/mc/%E6%A0%87%E7%AD%BE查看更多信息。
  11.     ]
  12.    
  13.     ore.biomes.blacklist = true // 是否在矿石生成黑名单群系中生成
  14.     ore.biomes.values = [ // 矿石可以生成的群系
  15.    'minecraft:plains', // 群系ID
  16.    '#nether' // 或者你可以使用“# + 群系类别”来代表群系, 在文末查看可用的列表
  17.     ]
  18.    
  19.     ore.clusterMinSize = 5 // 每矿簇最少的矿石数量 (现在 ore.clusterMinSize 选项是被忽略的, 该功能将在以后更新, 现在它恒为1)
  20.     ore.clusterMaxSize = 9 // 每矿簇最多的矿石数量
  21.     ore.clusterCount = 30 // 每个区块矿石数量
  22.     ore.minHeight = 0 // 最小Y值
  23.     ore.maxHeight = 64 // 最大Y值
  24.     ore.squared = true // 对X和Z值添加0~16的随机值. 推荐设置为 true
  25.     // ore.chance = 4 // 每大约4个区块生成一次. 对于稀有的矿石来说, 你可以将它和 clusterCount = 1 一同使用
  26. })

  27. event.addSpawn(spawn => { // 自定义实体生成
  28.     spawn.category = 'monster' // 实体类别, 可以设为 'creature', 'monster', 'ambient', 'water_creature' 和 'water_ambient'
  29.     spawn.entity = 'minecraft:magma_cube' // 实体ID
  30.     spawn.weight = 10 // 生成权重
  31.     spawn.minCount = 4 // 每组最小数量
  32.     spawn.maxCount = 4 // 每组最大数量
  33. })
  34. })

  35. /*
  36.   可用的群系类别:
  37.     taiga(针叶林类)
  38.     extreme_hills(高山类)
  39.     jungle(丛林类)
  40.     mesa(恶地类)(太怪了,作者为什么要在这里用基岩版的名称...)
  41.     plains(平原类)
  42.     savanna(热带草原类)
  43.     icy(冰原类)
  44.     the_end(末地)
  45.     beach(沙滩类)
  46.     forest(树林类)
  47.     ocean(海洋类)
  48.     desert(沙漠类)
  49.     river(河流类)
  50.     swamp(沼泽类)
  51.     mushroom(蘑菇岛类)
  52.     nether(下界)

  53.   以下是香草(划掉)世界生成的顺序:
  54.     raw_generation
  55.     lakes
  56.     local_modifications
  57.     underground_structures
  58.     surface_structures
  59.     strongholds
  60.     underground_ores
  61.     underground_decoration
  62.     vegetal_decoration
  63.     top_layer_modification
  64. */

  65. onEvent('worldgen.remove', event => {
  66. event.removeOres(ores => {//移除矿石
  67.     ores.blocks = [ 'minecraft:coal_ore', 'minecraft:iron_ore' ] // 移除铁矿和煤矿
  68.     ores.biomes.values = [ 'minecraft:plains' ] // 限制该选项仅在平原生效
  69. })

  70. event.removeSpawnsByID(spawns => {//通过实体ID来禁止指定实体生成
  71.     spawns.entities.values = [
  72.    'minecraft:cow',
  73.    'minecraft:chicken',
  74.    'minecraft:pig',
  75.    'minecraft:zombie'
  76.     ]
  77. })

  78. event.removeSpawnsByCategory(spawns => {//移除实体生成
  79.     spawns.biomes.values = [
  80.    'minecraft:plains'//指定为平原群系
  81.     ]
  82.     spawns.categories.values = [//类型为怪物
  83.    'monster'
  84.     ]
  85. })
  86. })

添加类效果展示:






7:物品修改(添加物品和物品tooltip)
基础的物品修改


1、物品的添加
基本格式:

代码:


  1. // 监听 item registry event
  2. onEvent('item.registry', event => {
  3. // 物品的材质应被放于 kubejs/assets/kubejs/textures/item/test_item.png (文件名:物品ID.png)
  4. // 如果你想使用自定义的物品模型,你可以使用 Blockbench 制作然后把它放于 kubejs/assets/kubejs/models/item/test_item.json (文件名:物品ID.json)
  5. event.create('test_item').displayName('Test Item')//必须的新建物品格式
  6. })



下面是一个例子

代码:

  1. onEvent('item.registry', event => {
  2. event.create('another_apple').displayName('嘿化的苹果')
  3. event.create('another_helmet').displayName('嘿化的头盔')
  4. })



但是现在这两个物品除了能看看没有任何功能
你可以通过在.displayName(物品名称)后面加以下后缀来使其具有一些基本的功能

代码:

  1. type('itemType')//物品类型
  2. tier('itemTier')//物品等级
  3. maxStackSize(size)//物品最大堆叠数
  4. unstackable()//不可堆叠
  5. maxDamage(damage)//最大耐久(应该是)
  6. burnTime(ticks)//可以燃烧的时间,单位为刻
  7. containerItem(item_id)//不知道是啥的东西
  8. tool(type, level)//定义工具(类型, 等级)
  9. miningSpeed(speed)//挖掘速度
  10. attackDamage(damage)//攻击伤害
  11. attackSpeed(speed)//攻击速度
  12. rarity(rarity)//稀有度
  13. glow(true/false)//是否发光
  14. tooltip(text...)//物品tooltip 详见下文
  15. group(group_id)//所属物品组的ID
  16. color(index, colorHex)//颜色(索引, 颜色编码)
  17. texture(customTexturePath)//自定义材质(后加材质目录)
  18. parentModel(customParentModel)//继承模型
  19. food((food) => {内容})//新建食物内容

其中,物品类型一项可以填写以下内容

代码:

  1. basic //默认类型
  2. sword
  3. pickaxe
  4. axe
  5. shovel
  6. hoe
  7. helmet
  8. chestplate
  9. leggings
  10. boots

物品等级一项可以填写以下内容

代码:

  1. 剑和工具:
  2.   wood
  3.   stone
  4.   iron
  5.   gold
  6.   diamond
  7.   netherite
  8. 护甲:
  9.   leather
  10.   chainmail
  11.   iron
  12.   gold
  13.   diamond
  14.   turtle
  15.   netherite

以下是两个实例(含新建食物):


代码:


  1. onEvent('item.registry', event => {
  2. event.create('another_apple').displayName('嘿化的苹果').maxStackSize(8).food((food) => {food.hunger(8).saturation(0.5).effect('minecraft:nausea', 100, 5, 1.0).effect('minecraft:speed', 100, 5, 1.0)})
  3. event.create('another_helmet').displayName('嘿化的头盔').type('helmet').tier('netherite')
  4. })

效果展示:

2、物品tooltip


以下为几个栗子,你可以根据以下代码进行修改来达到你想要的效果~

代码:

  1. onEvent('item.tooltip', tooltip => {
  2. // 批量添加tooltip
  3. tooltip.add(['minecraft:diorite', 'minecraft:granite', 'minecraft:andesite'], '三 大 废 岩')
  4. // 你可以使用除#tag以外的其他任何表述方法
  5. tooltip.add(/refinedstorage:red_/, 'Can be any color')
  6. // 你可以使用数组来新建多行tooltip. 你可以使用其他转义符来避开'这个符号
  7. tooltip.add('thermal:latex_bucket', ["Not equivalent to Industrial Foregoing's Latex", 'Line 2'])

  8. tooltip.addAdvanced('thermal:latex_bucket', (item, advanced, text) => {
  9.     text.add(0/*index*/, Text.of('Hello')) // 当index为0时,这种表示方法 会替换掉物品名称. 如果你想要在第二行添加tooltip,index必须为1,以此类推.
  10. })
  11. })


8:聊天事件
监听聊天事件并执行指令


一个基础的例子:当有人在发送‘kubejs教程’时回复'请访问https://www.mcbbs.net/thread-1207772-1-1.html'

代码:

  1. events.listen('player.chat', function (event) {
  2.   // 检测如果聊天内容为“kubejs教程” 执行命令, 忽略大小写
  3. if (event.message.trim().equalsIgnoreCase('kubejs教程')) {
  4.   // 将事件推迟1刻,否则服务器信息将会显示在玩家信息之前
  5.     event.server.scheduleInTicks(1, event.server, function (callback) {
  6.    // 对每个人说以下内容,颜色为绿色。聊天信息为[Server]
  7.    callback.data.tell(text.green('请访问h ttp s://www.mcbbs.net/thread-1207772-1-1.html'[/url]))
  8.     })
  9. }
  10. })

另一个例子:监测到聊天信息时执行对应指令
此时,不必像上个例子一样将事件推迟1刻,因为玩家的聊天信息根本不会显示出来

代码:

  1. events.listen('player.chat', function (event) {
  2. if (event.message.startsWith('cnmd')) {
  3.     event.server.runCommandSilent('kick '+event.player.name+' 请文明用语 ')
  4.     event.server.runCommandSilent('say 已踢出玩家'+event.player.name+'')
  5.     event.server.runCommandSilent('say 请注意文明用语,否则将会被踢出服务器!!! ')
  6.     event.cancel()//取消该事件,也就是说玩家的聊天信息不会显示
  7. }
  8. })

效果:




又一个例子:获取服务器种子
注意:获取的种子可能会有一定的误差虽然差一点也几乎不影响世界生成

代码:

  1. events.listen('player.chat', function (event) {
  2. if (event.message.equalsIgnoreCase('-seed')) {
  3. const seed = event.server.getOverworld().getSeed();
  4. event.player.tell(`种子: ${seed}`);
  5. event.cancel(); //取消该事件,也就是说玩家发送的-seed不会显示
  6. }
  7. })

效果(第一行是/seed返回的种子,第二行是-seed【也就是event.server.getOverworld().getSeed()】返回的种子)

咱也不知道,咱也不敢问


9:服务端定时任务
管理服务器的好帮手

当服务器启动时,你可以为其计划执行各种内容。你可以使用 callback.reschedule(时间) 来在指定时间内重复这个事件(括号内留空即为使用之前设定的时间)


具体见例子吧。。。这里也说不清

9-1 服务端定时重启
前提是你的启动脚本得加上自动启动功能


代码:

  1. events.listen('server.load', function (event) {
  2. event.server.schedule(117 * MINUTE, event.server, function (callback) {
  3.     callback.data.tell('服务器将在3分钟后重启!')
  4.     //callback.reschedule(2 * MINUTE) //两分钟以后再通知一次
  5. })

  6. event.server.schedule(120 * MINUTE, event.server, function (callback) {
  7.     callback.data.runCommand('/stop')//这里后边不用加重复事件,因为服务端重启时会自动加载本段代码
  8. })
  9. })


9-2 扫地大妈
todo

10:自定义窗口标题和logo
逼死其他mod?


你可以通过修改kubejs/config/client.properties中的title一项来修改游戏窗口标题



你可以将你想自定义的窗口logo放于kubejs/config/packicon.png,图片分辨率必须为16*16或其的整数倍
请注意!图片的格式必须为32-bit PNG 而不是Auto-detect/24-bit!
也就是属性内的“位深度”应为32(底下这个图有时间一定换个新的)



效果:


11

11-1

11-2

11-3

11-4

11-4-1

12

12-1

12-2

12-3

12-4

12-5

12-6



12-7



13

13-x




帘外雨
牛逼66666666666666666

Summon魔鬼
6666666666

世界边境
这个mod很早就注意到了,这可以说是一个整合包魔改的超级中间件。添加物品、修改合成、条件判断等等都可以靠他实现,而且可以实现复杂的条件判断。
也可以和CT、GS、FTBQ结合实现各种效果,比如利用GS实现复杂的职业系统等。

岛屿尽
关于黑名单blacklist是后面设置成true就表示以下列表为黑名单;
.blacklist=flase跟着的values中就是白名单

ZAGB
很详细的教程,大佬辛苦了

月之暗面z
天阿 这么好的贴为啥没人评论?

Wudji
月之暗面z 发表于 2022-1-16 19:01
天阿 这么好的贴为啥没人评论?

因为这东西在子版块的子版块里


月之暗面z
Wudji 发表于 2022-1-16 19:11
因为这东西在子版块的子版块里

这就很尴尬,顺便请问如何在机械动力的序列组装中设置某个物品不消耗或者消耗耐久呢?

Wudji
月之暗面z 发表于 2022-1-17 20:04
这就很尴尬,顺便请问如何在机械动力的序列组装中设置某个物品不消耗或者消耗耐久呢? ...

11-3 例子3可以对输入物品进行修改

月之暗面z
大佬什么时候更新啊~

夜丶尛乖
想问一下大佬,用这个模组能不能实现“矿物词典统一”?就是科技类mod,跨mod使用同一种矿物,并且让产物[合成输入、合成输出]也变成同一种,而不是各个mod各管各的。
想请问一下大致思路是什么?

Wudji
夜丶尛乖 发表于 2022-1-29 03:47
想问一下大佬,用这个模组能不能实现“矿物词典统一”?就是科技类mod,跨mod使用同一种矿物,并且让产物[ ...

可以啊
event.replaceInput({mod: '对应modid'}, '被替换输入物品', '要替换的输入物品')
其中物品都可以用tag或注册名

Wudji
月之暗面z 发表于 2022-1-27 10:07
大佬什么时候更新啊~

已更新      

xiao小xiao
感谢大佬分享~
(礼貌提问:kubejs怎么实现右键方块掉落物品?
我也不知道在这问里不礼貌但孩子是真的没有金粒发布问答了

Wudji
xiao小xiao 发表于 2022-2-3 20:20
感谢大佬分享~
(礼貌提问:kubejs怎么实现右键方块掉落物品?
我也不知道在这问里不礼貌但孩子是真的没有 ...

监听block.right_click事件,如果对应方块为指定方块,则给予玩家物品
或者直接runcommand /summon 物品,坐标为方块的坐标(y值可能要做调整)

xiao小xiao
Wudji 发表于 2022-2-3 20:23
监听block.right_click事件,如果对应方块为指定方块,则给予玩家物品
或者直接runcommand /summon 物品 ...

感谢大佬~!

xiao小xiao
Wudji 发表于 2022-2-3 20:23
监听block.right_click事件,如果对应方块为指定方块,则给予玩家物品
或者直接runcommand /summon 物品 ...

... ...能稍微讲的详细一点吗?搞了几个小时结果没啥用(打扰了)

月之暗面z

坐等沉浸工程~

Wudji
xiao小xiao 发表于 2022-2-4 00:09
... ...能稍微讲的详细一点吗?搞了几个小时结果没啥用(打扰了)
  1. onEvent('block.right_click', event=>{
  2.   if (event.block.id == "minecraft:dirt" && event.player.mainHandItem.id == 'minecraft:glass_bottle'){
  3.     event.server.runCommandSilent('give ' + event.player.name + " minecraft:dirt 1")
  4.     //或者也可以这样写:
  5.     //event.player.give(Item.of('minecraft:dirt'))
  6.     //冷却200tickevent.player.addItemCooldown('minecraft:glass_bottle', 200)
  7.     event.block.set('minecraft:stone')
  8.     event.player.tell('1x 泥土已到账')
  9.     event.sendInventoryUpdate()
  10.   }
  11. })
复制代码

更详细的教程见15章(正在编写中)



0880
这个mod牛逼啊,功能强大,谢谢分享

云底下的星星
请问 如果需要批量删除大量物品的合成  使用  let = 应该怎么写?

凡人丶小陈陈
多谢大佬分享
请问能出1.18.1高本版的物品添加和属性修改的详细教程吗?

凡人丶小陈陈
自己去wiki看了看
物品添加搞定了,但属性修改(指攻击伤害和攻击速度不成功)就很麻,
如果大佬有时间,麻烦了~

q522461078
1.18版本的kubejs,修改标签的的事件居然变成了tags.items,这玩意找了我老半天才发现....吐血。

q522461078
想问下楼主有没有什么方法可以写出这样的效果:
写一个熔炉的配方,输入是#forge:dusts/(任意金属),输出是对应的#forge:ingots/(粉的对应金属)

Mz_beichen
唉 又是魔改。。居然还出了教程 无语

Mz_beichen
哎呀 又是魔改 魔改实在太痛苦了

dodomos
本帖最后由 dodomos 于 2022-3-3 20:06 编辑

血魔法的那个arc不是奥数粉灰,而是炼金反应炉

生涯满腹
很棒的教程!灰常详细!

KNFF
大佬,想请问自定义盔甲的材质应该怎么放,我无论放哪里都是紫块,哭了

3453890470
可不可以移除指定mod某个物品的配方

q522461078
3453890470 发表于 2022-3-22 12:37
可不可以移除指定mod某个物品的配方

JEI里还可以看到某个物品的合成ID为:XXXX,配方里有A物品,而你想替换成B物品
你可以直接replaceInput({id:XXXX},A,B),这样就可以只改动这一个配方里的A物品,而不用先给这个配方remove再添加。

天秀之人就是我
监听事件是怎么做的?我这里抄的那个聊天事件的第一个,提示我'event' is not defined,错误报在了events.listen那里

Wudji
天秀之人就是我 发表于 2022-3-29 09:59
监听事件是怎么做的?我这里抄的那个聊天事件的第一个,提示我'event' is not defined,错误报在了events.li ...

见1-1基础代码格式

Wudji
天秀之人就是我 发表于 2022-3-29 09:59
监听事件是怎么做的?我这里抄的那个聊天事件的第一个,提示我'event' is not defined,错误报在了events.li ...

比如
onEvent('player.chat', event => {
  event.xxx.xxx()//在此编写脚本内容
})

Wudji
天秀之人就是我 发表于 2022-3-29 09:59
监听事件是怎么做的?我这里抄的那个聊天事件的第一个,提示我'event' is not defined,错误报在了events.li ...

貌似第八章的内容过时了,我回来更新一下吧

千绝qianjue01
15玩家事件交互好像显示不出来了

cyx3018_aF60E
感谢分享

小岳唷
这不叫Minecraft
这叫Mine Craft

ASGORE_DREAMER
看不懂,但我大为震撼

ASGORE_DREAMER
好东西,要了

q522461078
更新了好耶!!!

lingaott
非常感谢!这个真的超好用,尝试兼容《机械动力:超越一切》和《沉浸工程》的时候真的被震惊了

Tollainmear
本帖最后由 Tollainmear 于 2022-4-30 02:12 编辑

@Wudji 翻了一下文档,没有找到kubejs如何监听玩家吃东西的事件,'item.right_click'监听的事件一按右键就触发了,我看forge上监听吃东西的事件似乎是通过'LivingEntityUseItemEvent.finish',但没有在kubejs的文档里找到这个,可以帮忙提供个思路嘛?


补更,查了半天文档没有卵用,最后翻了源码找到了没有在文档里提到的事件:
https://github.com/KubeJS-Mods/K ... beJSEvents.java#L83


成了!奥耶!


aa1122a33
Tollainmear 发表于 2022-4-30 01:24
@Wudji 翻了一下文档,没有找到kubejs如何监听玩家吃东西的事件,'item.right_click'监听的事件一按右键就 ...

老哥,我用1.18.1版本来尝试注册物品,但是并不能实现,然后我在这个文件中并没有看到registery.item事件,那么我应该如何注册物品呢?

Tollainmear
本帖最后由 Tollainmear 于 2022-5-2 11:51 编辑
aa1122a33 发表于 2022-4-30 23:30
老哥,我用1.18.1版本来尝试注册物品,但是并不能实现,然后我在这个文件中并没有看到registery.item事件 ...

在kubejs\startup_scripts文件夹下创建一个js文件,里面写监听,如果要注册物品,就写在'item.registrt'事件里,方块写在'block.registry'里,流体写在'fluid.registry'里,可以参考我写的:

  1. //注册物品写这里
  2. onEvent('item.registry', event => {
  3.     //注册一个食物
  4.     event.create('opened_soup_can').maxStackSize(1).food((food) => {food.hunger(8).meat(true).alwaysEdible(true).fastToEat(true).effect('watersource:thirst', 1200, 2, 0.1)}).texture('kubejs:item/opened_soup_can').displayName('启封的炖菜罐头')
  5.     //注册一个没什么用的道具
  6.     event.create('soup_can').maxStackSize(16).texture('kubejs:item/soup_can').displayName('炖菜罐头')
  7. })

  8. //注册方块写这里
  9. onEvent('block.registry', event => {
  10.     event.create('soup_block').material('iron').hardness(1.0).displayName('箱装炖菜罐头')
  11. })

  12. //注册流体写这里
  13. onEvent('fluid.registry', event => {
  14.     event.create('liquid_soup').displayName(`炖菜汤`).textureStill('kubejs:fluid/soup_still').textureFlowing('kubejs:fluid/soup_flow').bucketColor(0xb07f22)
  15. })
复制代码



Tollainmear
event.remove({id: '物品ID'})      移除合成该物品的所有配方

@Wudji 这个描述有误,id后面放的不是物品ID,而是配方ID:


『南南』
为什么我目录点不进去?

Tollainmear
本帖最后由 Tollainmear 于 2022-5-23 23:25 编辑

巧了 我上个月也在服务器里搞了一个罐头的配方,也拿出来分享一下吧:


添加的物品:

从左至右依次是:
锡板、轻薄锡板、锡罐、炖菜汤、启封的炖菜罐头、炖菜罐头、脏兮兮的锡罐
注册这些道具、流体的代码:
  1. //道具注册
  2. onEvent('item.registry', event => {
  3.     //工序复杂,所以我们多加一些buff收益,其中口渴Debuff源自水源mod
  4.     event.create('opened_soup_can').maxStackSize(1)//不可堆叠
  5.         .food((food) => {
  6.             food.hunger(12)  //恢复12点饱食度
  7.             .meat(true)
  8.             .alwaysEdible(true)//不饿的时候也可以吃
  9.             .fastToEat(true)    //吃的快
  10.             .effect('watersource:thirst', 1200, 2, 0.1)         //10%概率获得口渴buff
  11.             .effect('minecraft:night_vision', 3600, 1, 1)       //100%概率获得夜视buff
  12.             .effect('minecraft:haste', 1800, 1, 1)              //100%概率获得急迫buff
  13.             .effect('minecraft:strength', 1200, 2, 0.25)        //25%概率获得力量2buff
  14.             .effect('minecraft:regeneration', 200, 1, 0.5)      //50%概率获得生命再生buff
  15.         }).texture('kubejs:item/opened_soup_can')
  16.         .displayName('启封的炖菜罐头')

  17.     //这里我们把没启封的罐头也设定为食物,后面解释
  18.     event.create('soup_can').maxStackSize(16)
  19.         .food((food) => {
  20.             food.hunger(0)
  21.             .fastToEat(true)
  22.             .alwaysEdible(true)
  23.         }).texture('kubejs:item/soup_can')
  24.         .displayName('炖菜罐头')

  25.     event.create('tin_plate').maxStackSize(64)
  26.         .texture('kubejs:item/tin_plate')
  27.         .displayName('锡板')

  28.     event.create('tin_thin_plate').maxStackSize(64)
  29.         .texture('kubejs:item/tin_thin_plate')
  30.         .displayName('轻薄锡板')

  31.     event.create('tin_can').maxStackSize(64)
  32.         .texture('kubejs:item/tin_can')
  33.         .displayName('锡罐')

  34.     event.create('dirty_tin_can').maxStackSize(64)
  35.         .texture('kubejs:item/dirty_tin_can')
  36.         .displayName('脏兮兮的锡罐')
  37. })

  38. //注册流体
  39. onEvent('fluid.registry', event => {
  40.     event.create('liquid_soup').bucketColor(0xb07f22)  //流体颜色(安装Optifine可能导致显示不正确)
  41.         .textureStill('kubejs:fluid/soup_still')       //不流动的纹理
  42.         .textureFlowing('kubejs:fluid/soup_flow')      //流动的纹理
  43.         .displayName(`炖菜汤`)
  44. })
复制代码


制作顺序:

第一步
锡锭 >> 锡板
Create金属压片

  1. event.recipes.createPressing('kubejs:tin_plate', '#forge:ingots/tin')
复制代码

第二步
锡板 >> 轻薄锡板x8
Create序列组装

  1. //锡板辊压8次获得8张轻薄锡板
  2.     event.recipes.createSequencedAssembly('8x kubejs:tin_thin_plate', 'kubejs:tin_plate', [
  3.         event.recipes.createPressing('kubejs:tin_thin_plate', 'kubejs:tin_thin_plate')
  4.     ]).transitionalItem('kubejs:tin_thin_plate')
  5.       .loops(8)  //循环8次
  6.       .id('kubejs:tin_thin_plate')
复制代码

第三步
轻薄锡板x7 >> 锡罐x4
原版合成

  1. //如上图所示
  2.     event.shaped('4x kubejs:tin_can', [
  3.         'A A',
  4.         'A A',
  5.         'AAA'
  6.     ], {
  7.         A: 'kubejs:tin_thin_plate'
  8.     })
复制代码

第四步
盐 + 水(1000mb) + 任意蔬菜x16 + 任意木屑x8 + 任意蛋白质x2 >> 炖菜汤(1000mb)
Create混合搅拌(加热)

  1. //这里用#来匹配tag,以实现任意蔬菜和任意蛋白质
  2.     event.recipes.createMixing(Fluid.of('kubejs:liquid_soup', 1000), [
  3.         Fluid.of('minecraft:water', 1000), //注意:单中流体不能大于1000
  4.         '16x #forge:vegetables',    //16个任意蔬菜
  5.         '8x #forge:dusts/wood',     //8个木屑,因为是冬季救援整合包,所以恶搞了一些蒸汽朋克的梗
  6.         '2x #diet:proteins',        //2个蛋白质,该tag属于diet模组
  7.         '#forge:salt'               //一撮盐,吃了盐才有力气对吧?
  8.     ]).heated();//加热
复制代码
  1. //这是指定Tag,用于匹配配方
  2. onEvent('item.tags', event => {
  3.     event.get('forge:vegetables').add('frostedheart:white_turnip_block') //把白萝卜加上蔬菜的tag
  4.     event.get("diet:proteins").add("kubejs:opened_soup_can")             //把炖菜汤加上蛋白质的tag
  5. })
复制代码


第五步
肉汤 + 锡罐 >> 启封的的炖菜罐头
Create注液

  1. //注液的方法,把250mb的炖菜汤灌到锡罐里
  2.     event.recipes.createFilling('kubejs:opened_soup_can', ['kubejs:tin_can', Fluid.of('kubejs:liquid_soup', 250)])
复制代码

第六步
启封的炖菜罐头 + 轻薄锡板 >> 炖菜罐头
Create机械手

  1. //利用机械手臂给罐头封闭
  2. event.recipes.createDeploying('kubejs:soup_can', ['kubejs:opened_soup_can', 'kubejs:tin_thin_plate'])
复制代码


关于启封罐头的两种方式

第一种方法 —— 用嘴啃:
  1. //监听吃东西的事件
  2. onEvent('item.food_eaten', event => {
  3.     //判断被吃掉物品的类型
  4.     if (event.item.id == "kubejs:soup_can") {
  5.         //给他一个启封的炖菜罐头,代表他启封成功啦
  6.         event.player.giveInHand('kubejs:opened_soup_can')
  7.         //不会有人觉得嘴巴比锡罐硬吧
  8.         //不会有人觉得嘴巴不会受伤吧
  9.         //当玩家生命值低于4,那他开完罐头大概率就死了
  10.         if (event.player.getHealth() <= 4){
  11.             event.server.tell("§4[奇葩新闻]§c" + event.player + "因为用嘴开罐头被活活扎死。")
  12.         }else{
  13.         //没死算你小子命硬,提醒一下,下次不要用嘴巴开罐头了
  14.             event.player.tell("§c你为啃开一个罐头,把嘴巴划破了。")
  15.         }
  16.         //给嘴硬的家伙施加4点伤害
  17.         event.player.attack(4)
  18.     }
  19. })
复制代码
第二种开罐头的方法 —— 合成:
  1. //这样才规规矩矩   
  2.     event.shapeless('kubejs:opened_soup_can', 'kubejs:soup_can')
复制代码


让锡罐重复利用!
  1. //当有人吃完罐头,让罐头留下一个沾满油渍的空罐子
  2. onEvent('item.food_eaten', event => {
  3.     if (event.item.id == "kubejs:opened_soup_can") {
  4.         event.player.giveInHand('kubejs:dirty_tin_can')
  5.     }
  6. })
复制代码

两种清洁罐子的方法
第一种 —— 手洗!
  1. //我们这里使用右击物品事件
  2. onEvent('item.right_click', event => {
  3.     let player = event.player
  4.     //判定手持物类型
  5.     if (player.getHeldItem(event.hand) == 'kubejs:dirty_tin_can') {
  6.         //因为水方块不像实心方块一样有交互事件,所以我们选择用射线追踪
  7.         let target = player.rayTrace(5)
  8.         //如果视线5格范围内有水方块
  9.         if (target.block.id == 'minecraft:water') {
  10.             player.tell('我: 芜湖~有点儿冷[抖...]')
  11.             //使用原版指令,给他一个潮湿的buff(该效果来自冰冻之心,会让玩家失温)
  12.             let testCmd = `effect give ${player.name} frostedheart:wet 15`
  13.             //这里使用悄咪咪的执行指令
  14.             event.server.runCommandSilent(testCmd)
  15.             //拿走一个浸油的锡罐
  16.             let amount = (player.getHeldItem(event.hand).count - 1)
  17.             player.setHeldItem(event.hand, Item.of('kubejs:dirty_tin_can', amount))
  18.             //给他一个洗干净的锡罐
  19.             player.giveInHand('kubejs:tin_can')
  20.         }
  21.     }
  22. })
复制代码
第二种 —— 机器搅拌!
  1. //工作盆里用100mb水进行搅拌
  2.     event.recipes.createMixing('kubejs:tin_can', [
  3.     Fluid.of('minecraft:water', 100),
  4.     'kubejs:dirty_tin_can'
  5.     ])
复制代码











第一页 上一页 下一页 最后一页