写在最前面:本教程面向目标为第一次接触魔改类模组的纯新手,主要讲述了配方修改的方法与实例,并不会涉及较深的内容,作者本人水平有限,欢迎评论提出问题。
KubeJS 6 适用版本为 1.19.2-1.21.1
教程参考了KubeJS官方wiki,参考了整合包E6E的部分代码,以及其他一系列个人教程。
什么是魔改
1.关于KubeJS
KubeJS是适合较高版本整合包的魔改模组,通过它可以改变/添加/删除一系列合成表,物品,流体,事件等,从而联系你所制作的整合包的每一个模组,达到你所期望的效果。
*比如:你可以令一个任意原木分解为对应的两个木板,而不是原版的4个。
2.选择KubeJS的附属模组
KubeJS模组本体(必选)
ProbeJS辅助编写魔改内容,提供了vscode支持(必选)
KubeJS Create/KubeJS Thermal/KubeJS Botania/KubeJS Mekanism/KubeJS Ars Nouveau/...当你的整合包内存在这些模组时添加,提供了更加简单的编写方式。
开始你的第一次魔改
如何开始
首先,打开你的minecraft游戏(确保安装了相应模组)。
输入指令/probejs dump 并等待一段时间//需要安装ProbeJS模组。
右键你的 .minecraft文件夹并选择“在 VSCode 中打开”//不要关闭游戏!
在.minecraft/kubejs/server_scripts下面新建一个文件,命名为xxx.js(也可以在下面新建文件夹,在文件夹里面创建文件)
(图为例子)
图为示例
第一步修改
在你创建的文件中输入以下内容:
ServerEvents.recipes(event => {
})
这个是最为基础的部分,接下来的配方魔改都要在这个大括号里面进行。
移除一个配方
例子:在添加暮色森林模组的情况下,你是否认为拆解台破坏了平衡性?下面是一个移除拆解台配方的实例
ServerEvents.recipes(event => {
event.remove({output:'twilightforest:uncrafting_table'})//移除拆解台
})
使用/reload指令来重加载修改,现在可以在游戏里面判断配方是否被成功添加。
显然,在大多数情况下面,依赖于单个配方的修改过于低效了,下面介绍对于一类型的配方,我们如何进行删除
引用自KubeJS官方wiki,并进行翻译及部分解释。
//翻译将按照代码格式翻译
//移除所有满足条件的配方(条件:输出石稿)
event.remove({ output: 'minecraft:stone_pickaxe' })
//移除所有满足条件的配方(条件:输出物品带有标签'#minecraft:wool'即所有的羊毛物品)
event.remove({ output: '#minecraft:wool' })
//补充:我们用标签来指代一类物品,同样的,标签也可以通过命令/kubejs hand得到
//移除所有满足条件的配方(条件:输入物品带有标签 '#forge:dusts/redstone'即红石粉)
event.remove({ input: '#forge:dusts/redstone' })
//移除所有满足条件的配方(条件:由模组农夫乐事添加)
event.remove({ mod: 'farmersdelight' })
//补充:类似于物品id,modid即'farmersdelight'可以指代一个mod,同样可以通过命令/kubejs hand得到
//移除所有满足条件的配方(条件:配方类型为营火烧制)
event.remove({ type: 'minecraft:campfire_cooking' })
//type指合成方法,比如'minecraft:crafting_shaped'就是指所有有序合成的配方
//移除所有满足条件的配方(条件1:配方类型*不是*为高炉烧制,条件2:输出物品为石头)条件1,2需*同时*满足才会移除
event.remove({ not: { type: 'minecraft:smelting' }, output: 'stone' })
//移除所有满足条件的配方(条件1:输出物品为熟鸡肉,条件2:配方类型为营火烧制)条件1,2需*同时*满足才会移除
event.remove({ output: 'minecraft:cooked_chicken', type: 'minecraft:campfire_cooking' })
//移除所有满足条件的配方(条件1:配方类型为高炉烧制,条件2:输出物品为铁锭,条件3:配方类型为熔炉)
//移除配方需要满足条件1,2或条件3,2(通俗的翻译为移除高炉或熔炉输出铁锭的配方)
event.remove([{ type: 'minecraft:smelting', output: 'minecraft:iron_ingot' }, { type: 'minecraft:blasting', output: 'minecraft:iron_ingot' }])
//通过配方id移除配方, data/minecraft/recipes/glowstone.json:
//注意!配方id并不意味着输出物品
event.remove({ id: 'minecraft:glowstone' })
//以下是作者在使用时的一些例子
//移除以安山机壳为原料的合成表
event.remove({input:'create:andesite_casing',type:'minecraft:crafting_shaped'})
//下面是一个简单的循环,用来移除各色各样的植物盆的配方
let color = ['cyan_glazed_terracotta',
'purple_glazed_terracotta',
'blue_glazed_terracotta',
'brown_glazed_terracotta',
'green_glazed_terracotta',
'red_glazed_terracotta',
'black_glazed_terracotta',
'magenta_glazed_terracotta',
'light_blue_glazed_terracotta',
'yellow_glazed_terracotta',
'lime_glazed_terracotta',
'pink_glazed_terracotta',
'gray_glazed_terracotta',
'light_gray_glazed_terracotta',
'orange_gray_glazed_terracotta',
'white_gray_glazed_terracotta'
]
for (let i of color) {
event.remove({input:`${i}`})
}
配方的替换
注意放在开始的大括号内*
这部分内容是可以让你修改配方的部分内容,而不是一个个删除再重新添加
来自作者的部分魔改代码
// event.replaceInput({},'输出物品' , '输入物品')表示
// {mod:'extendedcrafting',output:'extendedcrafting:frame'}是我们熟悉的配方条件筛选,与上一部分内容完全一致,这里是筛选满足模组为合成拓展且输出为黑铁框架的配方
// 'extendedcrafting:black_iron_slate'为输出物品,这里是合成拓展的黑铁框架
// 'mekanism:steel_casing'为输入物品,这里是通用机械的钢制机壳
event.replaceInput({mod:'extendedcrafting',output:'extendedcrafting:frame'},
'extendedcrafting:black_iron_slate' , 'mekanism:steel_casing')
//这是另一个例子,替换所有满足(模组为热力系列,合成方式为有序合成,不输出铁锭)的配方中的铁为植物魔法的魔力钢锭
event.replaceInput({mod:'thermal',type:'crafting_shaped',not:{output:'thermal:iron_gear'}}, '#forge:ingots/iron', 'botania:manasteel_ingot')
创建一个有序配方
下面,是创建一个有序合成配方。不要执着于通篇有序合成,试着尝试替换配方中的物品,可能更加简单。
实例,仍是来自于作者
//有序合成植物盆,使用物品为自然灵气的灌注石和原版的花盆
//只需要按照工作台那样排列顺序即可,注意没有物品的地方用空格替代。
//Item.of('botanypots:terracotta_botany_pot',1)表示物品植物盆,数量为1
event.shaped(Item.of('botanypots:terracotta_botany_pot',1), [
'L L',
'LOL',
' L '
],
{
L: 'naturesaura:infused_stone',
O: 'minecraft:flower_pot'
})
//有序合成自然灵气模组的降生之魂
event.shaped(Item.of('naturesaura:birth_spirit',1), [
'QLQ',
'LOL',
'QLQ'
],
{
L: 'minecraft:amethyst_shard',
O: 'minecraft:diamond',
Q: 'ars_nouveau:sourcestone'
})
无序配方同理,仅需要将shaped换成shapeless即可,不需要摆成九宫格的形式,这里不给出实例。
其他配方
熔炉配方 event.smelting(输出物品,输入物品)
高炉配方 event.blasting(输出物品,输入物品)
烟熏炉配方 event.smoking(输出物品,输入物品)
营火配方 event.campfireCooking(输出物品,输入物品)
锻造台配方 event.smithing(输出物品,输入物品,消耗物品)
切石机配方 event.stonecutting(输出物品,输入物品)
附属模组会添加类似配方格式,可以在模组对应curseforge页面找到,这里不再一一列举
一些具体实例
//石头烧成3个砂砾
event.smelting('3x minecraft:gravel', 'minecraft:stone')
//铁锭烧成10个铁粒(高炉)
event.blasting('10x minecraft:iron_nugget', 'minecraft:iron_ingot')
//将玻璃烟熏为染色玻璃
event.smoking('minecraft:tinted_glass', 'minecraft:glass')
//通过营火将木棍烧成火把
event.campfireCooking('minecraft:torch', 'minecraft:stick')
//以下配方不一定在1.19.2版本全部适用,原因是机械动力可能对这些物品进行改变
//这些出自于作者之前的魔改整合包
//通过锻造台或者切石机利用机壳合成机械动力的各种物品
//锻造台
event.smithing('4x create:gearbox','create:andesite_casing','create:cogwheel')
event.smithing('create:speedometer','create:andesite_casing','minecraft:compass')
event.smithing('create:millstone','create:andesite_casing','#forge:stone')
event.smithing('create:deployer','create:andesite_casing','create:brass_hand')
event.smithing('create:mechanical_mixer','create:andesite_casing','create:whisk')
event.smithing('create:encased_fan','create:andesite_casing','create:propeller')
event.smithing('create:mechanical_press','create:andesite_casing','minecraft:iron_block')
event.smithing('create:mechanical_crafter','create:brass_casing','create:electron_tube')
event.smithing('create:sequenced_gearshift','create:brass_casing','create:cogwheel')
event.smithing('create:stockpile_switch','create:brass_casing','minecraft:comparator')
event.smithing('create:rotation_speed_controller','create:brass_casing','create:precision_mechanism')
event.smithing('create:portable_storage_interface','create:brass_casing','create:andesite_funnel')
event.smithing('create:content_observer','create:copper_casing','minecraft:observer')
event.smithing('create:portable_fluid_interface','create:copper_casing','create:andesite_funnel')
event.smithing('create:hose_pulley','create:copper_casing','create:fluid_pipe')
event.smithing('create:item_drain','create:copper_casing','minecraft:iron_bars')
event.smithing('create:spout','create:copper_casing','create:copper_sheet')
event.smithing('create:fluid_tank','create:copper_casing','#forge:glass')
//切石机
event.stonecutting('create:mechanical_saw','create:andesite_casing')
event.stonecutting('4x create:depot','create:andesite_casing')
event.stonecutting('create:mechanical_drill','create:andesite_casing')
event.stonecutting('create:mechanical_bearing','create:andesite_casing')
event.stonecutting('create:gantry_carriage','create:andesite_casing')
event.stonecutting('16x create:analog_lever','create:andesite_casing')
event.stonecutting('create:mechanical_piston','create:andesite_casing')
event.stonecutting('4x create:encased_chain_drive','create:andesite_casing')
event.stonecutting('create:rope_pulley','create:andesite_casing')
event.stonecutting('2x create:mechanical_plough','create:andesite_casing')
event.stonecutting('2x create:mechanical_harvester','create:andesite_casing')
event.stonecutting('2x create:clutch','create:andesite_casing')
event.stonecutting('4x create:andesite_tunnel','create:andesite_casing')
event.stonecutting('4x create:andesite_funnel','create:andesite_casing')
event.stonecutting('4x create:brass_tunnel','create:brass_casing')
event.stonecutting('4x create:brass_funnel','create:brass_casing')
event.stonecutting('create:mechanical_arm','create:brass_casing')
event.stonecutting('create:clockwork_bearing','create:brass_casing')
event.stonecutting('create:nixie_tube','create:brass_casing')
一些特殊修改
特殊配方/合成方式
原版特殊配方需要写成数据包的格式,在添加了附属以后可以直接使用部分合成
机械动力序列装配
这里给出一些机械动力序列装配的实例,来自于作者本人,需要附属
//创造烈焰蛋糕
event.recipes.create.sequenced_assembly([
//成品:
Item.of('create:creative_blaze_cake').withChance(32.0),//这个是权重
//随机废料:
Item.of('minecraft:cake').withChance(2.0),
'createaddition:chocolate_cake',
'createaddition:honey_cake',
'create:blaze_cake',
],
//输入物品:
'minecraft:cake',
[
//每步的配方
event.recipes.create.filling('createaddition:cake_base', [
'createaddition:cake_base',
Fluid.of('minecraft:lava', 1000)
]),//第1步注液1B岩浆
event.recipes.create.pressing('createaddition:cake_base', ['createaddition:cake_base']),//第2步
event.recipes.create.filling('createaddition:cake_base', [
'createaddition:cake_base',
Fluid.of('createcafe:oreo_tea', 250)
]),//第3步注液250mB奥利奥奶茶,来自于机械动力附属
event.recipes.create.filling('createaddition:cake_base', [
'createaddition:cake_base',
Fluid.of('createaddition:bioethanol', 250)
]),//第4步注液250mB生物乙醇
]).transitionalItem('createaddition:cake_base').loops(30)//分别为循环装配的物品id和装配次数
//抽屉控制器
event.recipes.create.sequenced_assembly([
//成品:
Item.of('storagedrawers:controller').withChance(32.0),
//随机废料:
Item.of('storagedrawers:emerald_storage_upgrade').withChance(2.0),
],
//输入物品:
'storagedrawers:compacting_drawers_3',
[
//每步的配方
event.recipes.create.deploying('storagedrawers:compacting_drawers_3',[
'storagedrawers:compacting_drawers_3','storagedrawers:emerald_storage_upgrade'
]),//第一步机械手
event.recipes.create.deploying('storagedrawers:compacting_drawers_3',[
'storagedrawers:compacting_drawers_3','create:precision_mechanism'
]),//第二步机械手
event.recipes.create.deploying('storagedrawers:compacting_drawers_3',[
'storagedrawers:compacting_drawers_3','create_things_and_misc:vibration_mechanism'
]),//第三步机械手
]).transitionalItem('storagedrawers:compacting_drawers_3').loops(3)
//时间之瓶
event.recipes.create.sequenced_assembly([
//成品:
Item.of('tiab:time_in_a_bottle').withChance(32.0),
//随机废料:
Item.of('irons_spellbooks:lightning_bottle').withChance(1.0),
],
//输入物品:
'minecraft:glass_bottle',
[
//每步的配方
event.recipes.create.deploying('minecraft:glass_bottle',[
'minecraft:glass_bottle','irons_spellbooks:lightning_bottle'
]),//第一步机械手
event.recipes.create.deploying('minecraft:glass_bottle',[
'minecraft:glass_bottle','create:precision_mechanism'
]),//第二步机械手
event.recipes.create.deploying('minecraft:glass_bottle',[
'minecraft:glass_bottle','create_things_and_misc:vibration_mechanism'
]),//第三步机械手
]).transitionalItem('minecraft:glass_bottle').loops(3)
//焦炉砖
event.recipes.create.sequenced_assembly([
//成品:
Item.of('immersiveengineering:cokebrick'),
],
//输入物品:
'minecraft:bricks',
[
//每步的配方
event.recipes.create.deploying('minecraft:bricks',[
'minecraft:bricks','naturesaura:gold_brick'
]),//第1步
event.recipes.create.deploying('minecraft:bricks',[
'minecraft:bricks','naturesaura:infused_brick'
]),//第2步
event.recipes.create.deploying('minecraft:bricks',[
'minecraft:bricks','naturesaura:gold_nether_brick'
]),//第3步
event.recipes.create.filling('minecraft:bricks', [
'minecraft:bricks',
Fluid.of('pneumaticcraft:lpg', 500)
]),//第4步
]).transitionalItem('minecraft:bricks').loops(30)
//高炉砖
event.recipes.create.sequenced_assembly([
//成品:
Item.of('immersiveengineering:blastbrick'),
],
//输入物品:
'immersiveengineering:cokebrick',
[
//每步的配方
event.recipes.create.deploying('immersiveengineering:cokebrick',[
'immersiveengineering:cokebrick','immersiveengineering:treated_wood_horizontal'
]),//第1步
event.recipes.create.deploying('immersiveengineering:cokebrick',[
'immersiveengineering:cokebrick','immersiveengineering:treated_wood_horizontal'
]),//第2步
event.recipes.create.deploying('immersiveengineering:cokebrick',[
'immersiveengineering:cokebrick','immersiveengineering:treated_wood_horizontal'
]),//第3步
event.recipes.create.filling('immersiveengineering:cokebrick', [
'immersiveengineering:cokebrick',
Fluid.of('pneumaticcraft:biodiesel', 500)
]),//第4步
]).transitionalItem('immersiveengineering:cokebrick').loops(50)
//窑砖
event.recipes.create.sequenced_assembly([
//成品:
Item.of('immersiveengineering:alloybrick'),
],
//输入物品:
'immersiveengineering:treated_wood_horizontal',
[
//每步的配方
event.recipes.create.deploying('immersiveengineering:treated_wood_horizontal',[
'immersiveengineering:treated_wood_horizontal','#forge:sandstone'
]),//第1步
event.recipes.create.deploying('immersiveengineering:treated_wood_horizontal',[
'immersiveengineering:treated_wood_horizontal','naturesaura:gold_nether_brick'
]),//第2步
event.recipes.create.deploying('immersiveengineering:treated_wood_horizontal',[
'immersiveengineering:treated_wood_horizontal','#forge:sandstone'
]),//第3步
]).transitionalItem('immersiveengineering:treated_wood_horizontal').loops(5)
//绝缘附层
event.recipes.create.sequenced_assembly([
//成品:
Item.of('powah:dielectric_paste'),
],
//输入物品:
'minecraft:blaze_powder',
[
//每步的配方
event.recipes.create.deploying('minecraft:blaze_powder',[
'minecraft:blaze_powder','botania:mana_powder'
]),//第1步
event.recipes.create.deploying('minecraft:blaze_powder',[
'minecraft:blaze_powder','botania:pixie_dust'
]),//第2步
event.recipes.create.deploying('minecraft:blaze_powder',[
'minecraft:blaze_powder','thermal:basalz_powder'
]),//第3步
event.recipes.create.deploying('minecraft:blaze_powder',[
'minecraft:blaze_powder','thermal:blitz_powder'
]),//第4步
event.recipes.create.deploying('minecraft:blaze_powder',[
'minecraft:blaze_powder','thermal:blizz_powder'
]),//第5步
]).transitionalItem('minecraft:blaze_powder').loops(1)
工业先锋 化学溶解室
格式为数据包格式,不需要附属
*参考了E6E的魔改文件*
e6e链接e6e
const recipes = [
{
inputs: [//输入物品
{'item':'powah:steel_energized'}, {'item':'industrialforegoing:machine_frame_supreme'}, {'item':'mysticalagradditions:insanium_essence'},
{'item':'powah:steel_energized'}, {'item':'mysticalagradditions:insanium_essence'},
{'item':'powah:steel_energized'}, {'item':'industrialforegoing:plastic'}, {'item':'mysticalagradditions:insanium_essence'},
],
inputFluid: 'industrialforegoing:ether_gas',//输入流体
inputFluidAmount: 100,//输入流体量
processingTime: 100,//消耗时间
outputItem: {item: 'mekanism:steel_casing'},//输出物品,输出量
outputFluid: '',//输出流体
outputFluidAmount: 0,//输出流体量
id: 'mekanism:steel_casing'
},
{
inputs: [//输入物品
{'item':'minecraft:wheat_seeds'}
],
inputFluid: 'industrialforegoing:pink_slime',//输入流体
inputFluidAmount: 100,//输入流体量
processingTime: 10,//消耗时间
outputItem: {item: 'mysticalagriculture:prosperity_seed_base'},//输出物品,输出量
outputFluid: '',//输出流体
outputFluidAmount: 0,//输出流体量
id: 'mysticalagriculture:prosperity_seed_base'
},
{
inputs: [//输入物品
{'item':'industrialforegoing:plastic'}, {'item':'mysticalagriculture:prosperity_seed_base'}, {'item':'industrialforegoing:plastic'},
{'item':'industrialforegoing:plastic'}, {'item':'industrialforegoing:plastic'},
{'item':'industrialforegoing:plastic'}, {'item':'industrialforegoing:hydroponic_bed'}, {'item':'industrialforegoing:plastic'},
],
inputFluid: 'industrialforegoing:ether_gas',//输入流体
inputFluidAmount: 1000,//输入流体量
processingTime: 1500,//消耗时间
outputItem: {item: 'mysticalagriculture:infusion_altar'},//输出物品,输出量
outputFluid: '',//输出流体
outputFluidAmount: 0,//输出流体量
id: 'mysticalagriculture:infusion_altar'
},
{
inputs: [//输入物品
{'item':'minecraft:iron_ingot'}, {'item':'ae2:black_lumen_paint_ball'},
],
inputFluid: 'industrialforegoing:ether_gas',//输入流体
inputFluidAmount: 10,//输入流体量
processingTime: 150,//消耗时间
outputItem: {item: 'extendedcrafting:black_iron_ingot'},//输出物品,输出量
outputFluid: '',//输出流体
outputFluidAmount: 0,//输出流体量
id: 'extendedcrafting:black_iron_ingot'
},
{
inputs: [//输入物品
{'item':'industrialforegoing:pink_slime_ingot'}, {'item':'extendedcrafting:pedestal'}, {'item':'industrialforegoing:pink_slime_ingot'},
{'item':'industrialforegoing:pink_slime_ingot'}, {'item':'industrialforegoing:pink_slime_ingot'},
{'item':'industrialforegoing:pink_slime_ingot'}, {'item':'industrialforegoing:pink_slime_ingot'}, {'item':'industrialforegoing:pink_slime_ingot'},
],
inputFluid: 'industrialforegoing:pink_slime',//输入流体
inputFluidAmount: 100,//输入流体量
processingTime: 150,//消耗时间
outputItem: {item: 'mysticalagriculture:infusion_pedestal'},//输出物品,输出量
outputFluid: '',//输出流体
outputFluidAmount: 0,//输出流体量
id: 'mysticalagriculture:infusion_pedestal'
}
];
recipes.forEach((recipe) => {
let ingredients = [];
recipe.inputs.forEach((input) => {
ingredients.push(Ingredient.of(input));
});
event
.custom({
type: 'industrialforegoing:dissolution_chamber',
input: ingredients,
inputFluid: `{FluidName:"${recipe.inputFluid}",Amount:${recipe.inputFluidAmount}}`,
processingTime: recipe.processingTime,
output: recipe.outputItem,
outputFluid: `{FluidName:"${recipe.outputFluid}",Amount:${recipe.outputFluidAmount}}`
})
.id(recipe.id);
})
自然灵气 森林仪式
数据包修改,不需要附属
输入物品格式要用例子的格式其他方法极容易报错不要问我怎么知道的
//要写成{'item':'create:creative_blaze_cake'}而不是'create:creative_blaze_cake'!
event.custom(
{
"type": "naturesaura:tree_ritual",
"ingredients": [ //输入物品,最多8种
{'item':'create:creative_blaze_cake'},
{'item':'create:precision_mechanism'},
{'item':'create_things_and_misc:vibration_mechanism'},
{'item':'naturesaura:token_joy'},
{'item':'naturesaura:token_fear'},
{'item':'naturesaura:token_anger'},
{'item':'naturesaura:token_sorrow'},
{'item':'create:experience_nugget'}
],
"sapling": {
"item": "minecraft:oak_sapling"//仪式进行所需要的树苗
},
"output": {
"item": 'naturesaura:nature_altar',//产物
"count": 1
},
"time": 100//仪式进行需要的时间
}
)
event.custom(
{
"type": "naturesaura:tree_ritual",
"ingredients": [//输入物品,最多8种
{'item':'naturesaura:sky_ingot'},
{'item':'naturesaura:sky_ingot'},
{'item':'naturesaura:sky_ingot'},
{'item':'naturesaura:sky_ingot'},
{'item':'naturesaura:token_euphoria'}
],
"sapling": {
"item": "minecraft:oak_sapling"//仪式进行所需要的树苗
},
"output": {
"item": 'naturesaura:animal_spawner',//产物
"count": 1
},
"time": 100//仪式进行需要的时间
}
)
event.custom(
{
"type": "naturesaura:tree_ritual",
"ingredients": [//输入物品,最多8种
{'item':'naturesaura:sky_ingot'},
{'item':'naturesaura:infused_iron'},
{'item':'naturesaura:token_euphoria'},
{'item':'naturesaura:token_terror'},
{'item':'naturesaura:token_rage'},
{'item':'naturesaura:token_grief'},
{'item':'naturesaura:infused_stone'}
],
"sapling": {
"item": "minecraft:oak_sapling"//仪式进行所需要的树苗
},
"output": {
"item": 'naturesaura:conversion_catalyst',//产物
"count": 1
},
"time": 100//仪式进行需要的时间
}
)
event.custom(
{
"type": "naturesaura:tree_ritual",
"ingredients": [//输入物品,最多8种
{'item':'naturesaura:sky_ingot'},
{'item':'naturesaura:infused_iron'},
{'item':'naturesaura:token_euphoria'},
{'item':'naturesaura:token_terror'},
{'item':'naturesaura:token_rage'},
{'item':'naturesaura:token_grief'},
{'item':'naturesaura:infused_brick'}
],
"sapling": {
"item": "minecraft:oak_sapling"//仪式进行所需要的树苗
},
"output": {
"item": 'naturesaura:crushing_catalyst',//产物
"count": 1
},
"time": 100//仪式进行需要的时间
}
)
event.custom(
{
"type": "naturesaura:tree_ritual",
"ingredients": [//输入物品,最多8种
{'item':'ars_nouveau:sourcestone'},
{'item':'ars_nouveau:sourcestone'},
{'item':'ars_nouveau:source_gem'},
{'item':'ars_nouveau:source_gem'},
{'item':'ars_nouveau:source_gem_block'},
{'item':'ars_nouveau:source_gem_block'},
{'item':'naturesaura:calling_spirit'}
],
"sapling": {
"item": "minecraft:oak_sapling"//仪式进行所需要的树苗
},
"output": {
"item": 'ars_nouveau:imbuement_chamber',//产物
"count": 1
},
"time": 100//仪式进行需要的时间
}
)
event.custom(
{
"type": "naturesaura:tree_ritual",
"ingredients": [//输入物品,最多8种
{'item':'naturesaura:infused_iron'},
{'item':'naturesaura:sky_ingot'},
{'item':'naturesaura:tainted_gold'},
{'item':'naturesaura:depth_ingot'},
{'item':'ars_nouveau:imbuement_chamber'}
],
"sapling": {
"item": "minecraft:oak_sapling"//仪式进行所需要的树苗
},
"output": {
"item": 'ars_nouveau:enchanting_apparatus',//产物
"count": 1
},
"time": 100//仪式进行需要的时间
}
)
进阶与补充
定义函数(函数式编程)
我们首先回到基本的框架:
并尝试写出我们的第一个函数
ServerEvents.recipes(event => {
let function1 = ( a , b , c ) => {
event.smithing( a , b , c )
}
})
其中,a,b,c都是变量,我们可以通过下面的方法来调用我们刚刚定义的这个函数:
function1('minecraft:netherite','minecraft:bone_meal','minecraft:cake')
这个表达等价于
event.smithing('minecraft:netherite','minecraft:bone_meal','minecraft:cake')
现在,你可能存在一个疑问:感觉这个方式似乎没有什么必要,不过这里面可以塞下一大堆东西,即现在很多人说的模块化编程.
现在我们有了函数式编程的这一个方法,但会感到无处施展.这是因为仅仅只是编辑合成表不足以发挥它的优势.
很多时候,我们想脱离合成表堆砌来搞些新的东西,这时,就需要利用上定义函数的本事.
下一节我们将给出一个具体的实例,通过一步一步实现这个实例来讲述如何自己定义一个函数.
从零开始的"单"方块空岛
之前,有一个很火的题材是空岛中存在一个定时刷新的方块,现在我们尝试脱离mod来使用kubejs来实现它.
想实现一个完整功能的第一步是敲定好大纲:
1.多长时间刷新一次?
2.刷新出来的方块范围?
3.刷新出来的位置?
我们先来解决这3个基本问题:
多长时间刷新一次:我们定为60s,那我们应当使用什么方法获取当前时间呢?
首先我们需要考虑来自kubejs提供的方法:通过查阅官方wiki,我们发现了这个函数
LevelEvents.tick( )//区分ClientEvents.tick,后者为客户端tick
于是我们自然写出来,并定义时间变量time
LevelEvents.tick(event => {
const time = event.level.getTime()
}
但是我们发现,这样得出的time变量单位是gametick(gt,1s=20gt),现在我们需要换算得到秒
var n=0 //不要忘记在使用变量前为他赋一个值.
LevelEvents.tick(event => {
const time = event.level.getTime()
var sec = Math.floor(n / 5) //向下取整,确保sec应当是一个整数,sec变量代表当前秒
if (time % 20 == 0) { //在js中%代表取余,例如,16%3=1,即16=3*5+1
n++ //此函数内每tick循环一次,故不需要另写循环结构
}
}
如果有编程基础,很容易看懂上面的内容,对于无编程基础的人,可以参考下面的流程:
tick=1 -> sec=floor(0/5)=0 -> time%20=1不等于0 (此后使用计算机语言 time%20!=0) -> n不变->tick=tick+1 (tick=2)->...
接下来我们需要进行一轮判断,如果秒数等于60s则更新方块:
var n=0 //不要忘记在使用变量前为他赋一个值.
LevelEvents.tick(event => {
const time = event.level.getTime()
var sec = Math.floor(n / 5) //向下取整,确保sec应当是一个整数,sec变量代表当前秒
if (time % 20 == 0) { //在js中%代表取余,例如,16%3=1,即16=3*5+1
n++ //此函数内每tick循环一次,故不需要另写循环结构
}
if (60-time == 0) {
num = 0 //复原计数器
}
}
2.下面我们解决下一个问题,如何指定刷新范围.
对于高中生,你可以联想到一个集合,我们把可以刷新出来的物品放在一个集合里面.
对于大学生中的大部分专业或多或少学过一门编程语言,套用你所理解的数组即可.
我们需要定义一个大型数组
const block = ['minecraft:copper_block','minecraft:enchanting_table', 'minecraft:tnt'] //出于篇幅,只写了3个
现在我们需要实现随机生成,这里只需要转换成随机抽取数组中的一个元素即可(当然,我们可以发现,数组中存储多个相同的元素会使被抽到的概率增加)
const r = Math.floor(Math.random() * block.length) //random()可以生成 [0,1] 的随机数,后面是数组大小
3.如何刷新出来:我们仅需要使用一下指令:
event.server.runCommandSilent(`setblock 0 65 0 ${block[r]}`)
现在我们综合一下代码,得到成品:
var n=0 //不要忘记在使用变量前为他赋一个值.
const block = ['minecraft:copper_block','minecraft:enchanting_table', 'minecraft:tnt'] //出于篇幅,只写了3个
LevelEvents.tick(event => {
const time = event.level.getTime()
var sec = Math.floor(n / 5) //向下取整,确保sec应当是一个整数,sec变量代表当前秒
if (time % 20 == 0) { //在js中%代表取余,例如,16%3=1,即16=3*5+1
n++ //此函数内每tick循环一次,故不需要另写循环结构
}
if (60-time == 0) {
const r = Math.floor(Math.random() * block.length) //random()可以生成 [0,1] 的随机数,后面是数组大小
event.server.runCommandSilent(`setblock 0 65 0 ${block[r]}`)
num = 0 //复原计数器
}
}
现在我们可以思考,如何提供更多的可选项,比如加入阶段限制,生成实体,更改刷新时长,多个刷新点位扩展...
这个问题交由你来决定,这个实例可以作为你打开新世界的一个指路石.
下一节预告:标签的操作与更改.
最后
这篇教程还有许多需要完善的地方,在之后也可能对其进行更新,有问题可以评论留言。
移除了最后的批量操作的小章节,因为补全了更完整的教程.
自定义物品,方块,kubejs事件可能会更新