本篇教程由作者设定使用 CC BY-NC-SA 协议。

前言

GTM 自带 KubeJS 支持,你可以使用 KubeJS 自定义配方、材料和机器。

强烈建议使用 ProbeJS 获取代码提示!

本文章不是 JS 教程,在阅读之前你应该有一定的 JS 知识。对于继承、解构赋值、类声明、剩余参数等概念,建议查询 MDN 等文档或者上网搜索。

常用数据

大多数的常用数据都在 GTValues 类当中,其中最常用的莫过于电压数值,建议使用一个优先级较高的 js 文件存放这些数据。

// priority: 10
const [ ULV, LV, MV, HV, EV, IV, LuV, ZPM, UV, UHV, UEV, UIV, UXV, OpV, MAX ] = GTValues.VA

这样你就能在之后的代码中直接使用这些值而不是每次都要打出 GTValues.VA 或者记忆这些数值。

配方

所有的 GTM 配方类型(包括自定义的配方类型)都可以在 RecipeEventJS 中找到,且所有的 GTM 配方类型都继承自 GTRecipeSchema$GTRecipeJS,因此一个配方的方法基本上可以直接迁移到另一种配方类型上,以下是 GTRecipeJS 上的一些常用方法:

// 这是 TypeScript 代码,请勿用于 KubeJS!
// TS 快速入门:方法名(参数名:参数类型): 返回类型

declare class GTRecipeSchema$GTRecipeJS extends Internal.RecipeJS {
    // 要输入的物品
    // 参数1(剩余参数):输入物品 - 所有的参数将被作为一个数组处理,因此无需使用数组包裹所有的材料。
    itemInputs(... inputs: InputItem_[]): this
    
    // 要输出的物品
    // 注意:在这里使用 Item.withChance() 是无效的,请使用 chancedOutput() 方法
    // 参数1(剩余参数):输出物品 - 同上,之后不再赘述
    itemOutputs(...outputs: OutputItem_[]): this;
    
    // 使用的编程电路配置
    // 参数1:配置 - 编程电路的配置,范围 0-32
    circuit(configuration: number): this;
    
    // 要输入的流体
    // 参数1(剩余参数):输入流体
    inputFluids(...inputs: Internal.GTRecipeComponents$FluidIngredientJS_[]): this;
    
    // 要输出的流体
    // 参数1(剩余参数):输出流体
    outputFluids(...outputs: Internal.FluidStackJS_[]): this;
    
    // 每 tick 消耗 EU
    // 参数1:EU - 如果设置为负数,那么此配方会输出而不是消耗能量(如果可以)
    EUt(eu: number): this;
    
    // 配方持续时长
    // 注意:此方法实际上并不存在于 GTRecipeJS 中,只是(几乎)每个配方类型都会有这个方法,所以列在此处
    // 参数1:时间 - 单位为 tick
    duration(duration: string | number): this;
    
    // 在配方中不消耗的物品,例如化学反应中的催化剂以及压模中的模具
    // 参数1:物品
    notConsumable(itemStack: InputItem_): this;
    
    // 配方生效所需的维度
    // 参数1:维度
    dimension(dimension: ResourceLocation_): this;
    // 注:此为函数重载,亦即你可以用不同的参数数量和类型调用同一个函数名以获得不同的效果
    // 参数1:维度
    // 参数2:是否反转 - 设置为 true 时,配方将只在此维度不生效
    dimension(dimension: ResourceLocation_, reverse: boolean): this;
    
    // 配方生效所需的生物群系
    // 参数1:群系
    biome(biome: ResourceLocation_): this;
    // 参数1:群系
    // 参数2:是否反转
    biome(biome: ResourceLocation_, reverse: boolean): this;
    
    // 是否在配方运行时的每一 tick 都消耗材料和能量
    perTick(perTick: boolean): this;
    
    // 输入的应力(机械动力)
    // 参数1:应力
    inputStress(stress: number): this;
    
    // 输出的应力
    // 参数1:应力
    outputStress(stress: number): this;
    
    // 需求的转速(机械动力)
    // 参数1:转速
    rpm(rpm: number): this;
    
    // 高炉温度
    // 参数1:温度
    blastFurnaceTemp(blastTemp: number): this;
    
    // 聚变启动所需 EU
    // 参数1:EU
    fusionStartEU(eu: number): this;
    
    // 概率输出的物品
    // 参数1:物品
    // 参数2:几率
    // 参数3:电压等级增益 - 电压等级越高,产出概率越大
    chancedOutput(stack: OutputItem_, chance: number, tierChanceBoost: number): this;
    // 参数1:标签前缀 - 即 dust、small_dust、gem 等
    // 参数2:GT 材料 - 即 GTMaterials 中注册的材料
    // 参数3:电压等级增益
    chancedOutput(tag: TagPrefix_, mat: com.gregtechceu.gtceu.api.data.chemical.material.Material_, chance: number, tierChanceBoost: number): this;
    // 参数1:标签前缀
    // 参数2:GT 材料
    // 参数3:数量
    // 参数4:电压等级增益
    chancedOutput(tag: TagPrefix_, mat: com.gregtechceu.gtceu.api.data.chemical.material.Material_, count: number, chance: number, tierChanceBoost: number): this;
    
    // 概率输出的流体
    // 参数1:流体
    // 参数2:几率
    // 参数3:电压等级增益
    chancedFluidOutput(stack: Internal.FluidStackJS_, chance: number, tierChanceBoost: number): this;
    
    // 消耗的爆炸物数量,主要用于聚爆压缩机
    // 参数1:爆炸物数量
    explosivesAmount(explosivesAmount: number): this;
    
    // 需求的超净间类型(超净间,无菌超净间)
    // 参数1:超净间类型 - 只有两种,CleanroomType.CLEANROOM 和 CleanroomType.STERILE_CLEANROOM
    cleanroom(cleanroomType: CleanroomType_): this;
    
    // 对于多方块蒸馏塔的配方,是否禁止生成单方块蒸馏室的相应配方
    disableDistilleryRecipes(flag: boolean): this;
}

以下是一些示例:

ServerEvents.recipes(e => {
    e.recipes.gtceu.assembler('kubejs:uhv_energy_input_hatch_16a')
        .itemInputs(
            '2x gtceu:uhv_energy_input_hatch_4a',
            '4x gtceu:uhpic_chip',
            '2x gtceu:ruthenium_trinium_americium_neutronate_quadruple_wire',
            '4x gtceu:europium_octal_wire'
        )
        .duration(200)
        .EUt(491520)
        .itemOutputs('gtceu:uhv_energy_input_hatch_16a')
    
    // 注意:这会同时创建大型化学反应釜的配方
    e.recipes.gtceu.chemical_reactor('kubejs:chem/chromatic_printed_circuit_board_persulfate')
        .itemInputs('kubejs:chromatic_circuit_board', '32x gtceu:trinium_foil')
        .inputFluids('gtceu:sodium_persulfate 10000') // 是的,可以直接这样写而不用 Fluid.of()
        .itemOutputs('kubejs:chromatic_printed_circuit_board')
        .cleanroom(CleanroomType.CLEANROOM)
        .EUt(HV) // 注意:这个值不是自带的全局变量,是在之前的“常用数据”一节中声明的
        .duration(1800)
        
    e.recipes.gtceu.gas_collector('kubejs:gas_collector/glacio')
        .dimension('ad_astra:glacio')
        .outputFluids('kubejs:glacio_air 10000')
        .EUt(EV)
        .duration(200)
        .circuit(9)
})

小技巧:怎样使用流体标签

很多时候一些其他的模组会注册同名的流体,例如 Immersive Engineering 会注册杂酚油,Ad Astra、PneumaticCraft 会注册石油,Mekanism 会注册各种化学品流体,它们没有理由不能被用于 GT 配方,实际上你也确实可以在 GTM 自带的配方中使用它们,因为这些配方使用的是流体标签。但是在自定义配方的时候,很可惜,没有原生的办法使用流体标签,无论是 Fluid.of('#fluid:tag', 1000) 还是 '#fluid:tag 1000' 都会报错。以下是解决方法:

const JsonObject = Java.loadClass('com.google.gson.JsonObject');

/**
 * @param {Special.FluidTag} tag 
 * @param {number} amount 
 * @returns {Internal.JsonObject}
 */
let fluidIngredient = (tag, amount) => {
    let result = new JsonObject()
    result.add('amount', amount || 1000) // 如果不指定 amount,默认为 1000
    result.add('value', { tag: tag })
    return result
}

ServerEvents.recipes(e => {
    e.recipes.gtceu.xxxxx('xxxxx')
        .inputFluids(fluidIngredient('forge:hydrogen', 1000))
})

原理:inputFluids() 可接受的参数类型实际上包括了 GTM 的 FluidIngrediet、KubeJS 的 FluidStack 以及 JsonObject,第一个无法在 JS 中使用,因为 JS 的类型非常不严格以至于即使你使用了正确的参数类型, FluidIngredient 在构造时也会报错;第二个不接受流体标签;只能使用第三个,且不能使用 JS 的对象字面量,因为它不是 JsonObject,不具有源码中解析流体原料时需要的方法。

特殊情况

对于碎岩机的配方,由于 Rhino 的问题,你需要用特殊手段告诉它要如何解释 .addData() 方法:

event.recipes.gtceu.rock_breaker('some_recipe_id')
    .nonConsumable('minecraft:dirt')
    .itemOutputs('minecraft:dirt')
    ['addData(java.lang.String, java.lang.String)']('fluidA', 'minecraft:water')
    ['addData(java.lang.String, java.lang.String)']('fluidB', 'minecraft:lava')
    .duration(20)
    .EUt(8)
    .addCondition(RockBreakerCondition.INSTANCE)

元素、材料、配方类型与机器

难受的来了,元素、材料、机器的注册都在  GTCEuStartupEvents.registry() 当中进行,即使安装了 ProbeJS,在这里你别想得到多少有用的代码提示,因为 ProbeJS 对这个方法给出的说明是:

使用 KubeJS 自定义 GTM-第1张图片要注册的类型是个字符串,在不看模组源代码或者示例的情况下你永远不可能知道到底应该写什么;而回调函数上……

使用 KubeJS 自定义 GTM-第2张图片any,还是 any。BuilderBase<any> 上仅有的两个方法是 get() 和 register(),仅有的一个属性是 id。显然 ProbeJS 没法给你更多帮助了。

注册元素

GTCEuStartupEvents.registry('gtceu:element', e => {
    // 参数1:名称 - string
    // 参数2:质子数量 - number
    // 参数3:中子数量 - number
    // 参数4:半衰期(秒)- number - 设为 -1 时没有半衰期
    // 参数5:衰变后的元素 - string | null
    // 参数6:符号 - string
    // 参数7:是否为同位素 - boolean
    e.create('protonium', 1000, 0, -1, null, 'Pn', false)
    e.create('chronomium', 180, 120, -1, null, 'Ch', false)
})

注册材料

GTCEuStartupEvents.registry('gtceu:material', e => {
    // 一些东西不在全局变量中,你需要使用 Java.loadClass() 获取它们的引用
    const PropertyKey = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey')
    const OreProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.OreProperty')
    
    // 修改已有的材料属性,在这里倒是能得到代码提示
    // 这段代码的作用是给钌凯金镅中子素氧化物添加细导线
    GTMaterials.RutheniumTriniumAmericiumNeutronate.addFlags(GTMaterialFlags.GENERATE_FINE_WIRE)
    // 给高辛烷值汽油添加矿石
    // OreProperty 构造函数:
    // 参数1:主产物乘数 - number
    // 参数2:副产物乘数 - number
    // 参数3(可省略):矿石是否发光 - boolean
    GTMaterials.HighOctaneGasoline.setProperty(PropertyKey.ORE, new OreProperty(3, 4, true))
    
    // 注册材料,create() 方法将返回 com.gregtechceu.gtceu.api.data.chemical.material.Material$Builder
    // 这个东西 ProbeJS 没有任何提示,这些方法都是我看源码找到的
    e.create('protonium')
        // 主要颜色
        .color(0xed1661)
        // 次要颜色
        .secondaryColor(0xd419b5)
        // 为此材料添加锭
        .ingot()
        // 为此材料添加流体(液体、气体、等离子体),以及流体属性(此处是温度)
        // 如果你想要为流体指定温度等属性,只能这样写,虽然看起来很丑
        // 如果你只是想单纯地添加流体,只需要 fluid() 即可
        // 同样地,想要单纯地添加气体、液体、等离子体,使用 gas()、liquid()、plasma()
        ['fluid(com.gregtechceu.gtceu.api.fluids.store.FluidStorageKey,com.gregtechceu.gtceu.api.fluids.FluidBuilder)'](GTFluidStorageKeys.LIQUID, new GTFluidBuilder().temperature(100000))
        // 指定此材料的物品图标样式
        .iconSet(GTMaterialIconSet.DULL)
        // 材料标记,指定此材料可以制作哪些零件
        .flags(
            GTMaterialFlags.GENERATE_PLATE,
            GTMaterialFlags.GENERATE_BOLT_SCREW,
            GTMaterialFlags.GENERATE_FRAME,
            GTMaterialFlags.GENERATE_ROD,
            GTMaterialFlags.GENERATE_GEAR,
            GTMaterialFlags.GENERATE_SMALL_GEAR,
            GTMaterialFlags.GENERATE_FINE_WIRE,
            GTMaterialFlags.GENERATE_SPRING
        )
        // 此材料的构成元素
        .element(GTElements.get('protonium'))
        // 如果此材料可以制作导线
        // 参数1:电压 - number
        // 参数2:电流 - number
        // 参数3:损耗 - number
        // 参数4:是否为超导体 - boolean
        // 参数5(可省略):临界温度 - number
        .cableProperties(GTValues.V[GTValues.UEV], 2, 36, false)
        // 此材料的工具属性
        // 参数1:工具属性 - ToolProperty
        // ToolProperty 构造函数:
        // 参数1:挖掘速度 - number
        // 参数2:攻击伤害 - number
        // 参数3:耐久 - number
        // 参数4:挖掘等级 - number
        // 参数5:工具类型 - GTToolType[]
        .toolStats(new ToolProperty(144, 114, 80000, 6, [GTToolType.AXE, GTToolType.PICKAXE, GTToolType.SWORD]))
        
    e.create('protonium_trinium_tritanate')
        .color(0xed9596)
        .secondaryColor(0xe7727e)
        .ingot()
        ['fluid(com.gregtechceu.gtceu.api.fluids.store.FluidStorageKey,com.gregtechceu.gtceu.api.fluids.FluidBuilder)'](GTFluidStorageKeys.LIQUID, new GTFluidBuilder().temperature(10200))
        .iconSet(GTMaterialIconSet.METALLIC)
        .flags(GTMaterialFlags.GENERATE_FINE_WIRE)
        // 此材料的成分,将决定此材料的化学式
        // 参数均为 GTMaterials 中的材料名称
        .components('2x protonium', '4x trinium', '3x tritanium', '7x oxygen')
        .cableProperties(GTValues.V[GTValues.UEV], 28, 0, true)
        // 此材料可在合金冶炼炉中制作,原料为上述成分的粉或者流体,产量自动计算,自动注册熔融流体
        // 具体信息详见下一节
        .blastTemp(10200, 'high', GTValues.VA[GTValues.UV], 600)
        // 此材料可以制作流体管道
        // 参数1:最高可承受温度 - number
        // 参数2:吞吐量 - number
        // 参数3:是否可运输气体 - boolean
        // 以下参数要么都有,要么都省略
        // 参数4(可省略):是否可运输酸性物质 - boolean
        // 参数5(可省略):是否可运输低温物质 - boolean
        // 参数6(可省略):是否可运输等离子体 - boolean
        .fluidPipeProperties(200000, 80000, true, true, true, true)
})

Material$Builder 上的其他常用方法:

// 仍然是 TS 代码
declare class Material$Builder extends BuilderBase<Material> {
    // 为此材料添加矿石
    // 参数1:矿石是否发光
    ore(emissive: boolean): this;
    // 参数1:主产物乘数
    // 参数2:副产物乘数
    ore(oreMultiplier: number, byproductMultiplier: number): this;
    ore(oreMultiplier: number, byproductMultiplier: number, emissive: boolean): this;
    
    // 此材料的矿石要在化学浸洗机中浸泡什么物质(通常是汞)
    // 参数1:材料 - 示例 GTMaterials.Mercury
    washedIn(m: Material): this;
    // 参数2:洗出的产物数量
    washedIn(m: Material, washedAmount: number): this;
    
    // 为此材料添加锭
    ingot(): this;
    // 参数1:挖掘等级
    ingot(harvestLevel: number): this;
    // 参数2:燃烧时间
    ingot(harvestLevel: number, burnTime: number): this;
    
    // 为此材料添加宝石
    gem(): this;
    gem(harvestLevel: number): this;
    gem(harvestLevel: number, burnTime: number): this;
    
    // 为此材料添加涡轮转子
    // 参数1:最高转速
    // 参数2:损耗
    // 参数3:耐久度
    rotorStats(speed: number, damage: number, durability: number): this;
    
    // 此材料在高炉/合金冶炼炉中需要的温度
    // 参数1:温度
    blastTemp(temp: number): this;
    // 参数2:冶炼使用的保护气体等级 - 可使用的值:'low' | 'mid' | 'high' | 'higher' | 'highest' | null
    blastTemp(temp: number, gasTier: BlastProperty.GasTier): this;
    // 参数3:耗电量,覆盖默认值
    blastTemp(temp: number, gasTier: BlastProperty.GasTier, eutOverride: number): this;
    // 参数4:耗时,覆盖默认值
    blastTemp(temp: number, gasTier: BlastProperty.GasTier, eutOverride: number, durationOverride: number): this;
    
    // 为此材料的矿石添加副产物
    // 参数1(剩余参数):副产物
    addOreByproducts(... byproducts: Material[]): this;
    
    // 为此材料添加物品管道
    // 参数1:管道的优先级
    // 参数2:每秒运输数量
    itemPipeProperties(priority: number, stacksPerSec: number): this;
}

注册配方类型

示例:

GTCEuStartupEvents.registry('gtceu:recipe_type', e => {
    // create() 方法返回 com.gregtechceu.gtceu.integration.kjs.builders.GTRecipeTypeBuilder
    e.create('deep_atom_reassemble')
        .setEUIO('in')
        .setMaxIOSize(6, 6, 9, 9)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.ARC);
});

常用方法:

declare class GTRecipeTybeBuilder extends BuilderBase<GTRecipeType> {
    // 指定配方的分类,在 LDLib UI 编辑器中有用
    category(category: string): this;
    
    // 指定该配方的 IO 数量,也就是你在 JEI 中看到的格子数量
    // 参数:物品输入槽数量,物品输出槽数量,流体输入槽数量,流体输出槽数量
    setMaxIOSize(maxInputs: number, maxOutputs: number, maxFluidInputs: number, maxFluidOutputs: number): this;
    
    // 指定该配方类型是输入还是输出能量,或者两者均可
    // 参数1:IO 类型 - 'in' | 'out' | 'both'
    setEUIO(io: IO): this;
    
    // 指定配方中槽位上显示的图标(例如化学反应釜配方中的格子上的图标)
    // 参数1:是否是输出槽
    // 参数2:是否是流体
    // 参数3:图标纹理 - 使用 GuiTextures 快速获取
    setSlotOverlay(isOutput: boolean, isFluid: boolean, slotOverlay: IGuiTexture): this;
    // 参数3:是否是最后一个
    setSlotOverlay(isOutput: boolean, isFluid: boolean, isLast: boolean, slotOverlay: IGuiTexture): this;
    
    // 设定进度条样式
    // 参数1:进度条纹理 - 使用 GuiTextures 快速获取
    // 参数2:填充方向 - 使用 FillDirection 快速获取
    setProgressBar(progressBar: ResourceTexture, moveType: ProgressTexture.FillDirection): this;
    
    // 设定蒸汽机器的特别进度条
    setSteamProgressBar(progressBar: SteamTexture, moveType: ProgressTexture.FillDirection): this;
    
    // 设定配方工作时的声音
    // 参数1:声音 - 使用 GTSoundEntries 快速获取
    setSound(sound: SoundEntry): this;
    
    // 设定在 JEI 中显示的信息最大行数(耗能、时长、转速、应力、超净间要求等)
    setMaxTooltips(maxTooltips: number): this;
}

机器

GTCEuStartupEvents.registry('gtceu:machine', e => {
    // 参数1:机器 ID
    // 参数2:机器类型 - 'steam' | 'simple' | 'multiblock' | 'kinetic'
    // 参数3(剩余参数):视情况而定
    // 根据参数2返回不同的 Builder,这些 Builder 都来自 com.gregtechceu.gtceu.integration.kjs.builders.machine.MachineFunctionPresets 的 builder() 方法
    e.create()
})

蒸汽机器

GTCEuStartupEvents.registry('gtceu:machine', e => {
    // 参数3:是否有高压蒸汽的变种 - boolean
    e.create('test_steam_machine', 'steam', true)
        // 参数1:配方类型 - 使用 GTRecipeTypes 获取原版配方类型或者使用 get 方法获取自定义的配方类型
        .recipeType(GTRecipeTypes.get('test_recipe_type'))
})

电力单方块机器

GTCEuStartupEvents.registry('gtceu:machine', e => {
    // 参数3:此机器的电压等级 - number - 范围 0-15 的整数
    e.create('test_electric_machine', 'simple', GTValues.LV, GTValues.MV, GTValues.HV, GTValues.EV, GTValues.IV)
        .recipeType(GTRecipeTypes.get('test_recipe_type'))
        // 控制机器随着电压等级提升,流体槽容量随之增大的函数
        // 参数1:函数 - function
        .tankScalingFunction(tier => tier * 3200)
})

电力多方块机器

GTCEuStartupEvents.registry('gtceu:machine', e => {
    // 这样做可以获取代码提示
    /**
     * @type {Internal.MultiblockMachineBuilder}
     */
    let r = e.create('deep_atom_reassemble_chamber', 'multiblock');
    // 设定机器方块能够旋转到哪些方向
    r.rotationState(RotationState.NON_Y_AXIS)
    // 设置多方块结构
    r.pattern(
            def => FactoryBlockPattern.start() // 开始构建结构
                .aisle('CCCCCCC', 'P     P', 'P     P', 'P     P', 'P     P', 'P     P', 'CCCCCCC')
                .aisle('CDDDDDC', ' RRRRR ', ' FFFFF ', ' FGGGF ', ' FFFFF ', ' RRRRR ', 'CDDDDDC')
                .aisle('CDDDDDC', ' RFFFR ', ' FTTTF ', ' GAAAG ', ' FTTTF ', ' RFFFR ', 'CDDDDDC')
                .aisle('CDDDDDC', ' RFFFR ', ' FTTTF ', ' GATAG ', ' FTTTF ', ' RFFFR ', 'CDDDDDC')
                .aisle('CDDDDDC', ' RFFFR ', ' FTTTF ', ' GAAAG ', ' FTTTF ', ' RFFFR ', 'CDDDDDC')
                .aisle('CDDDDDC', ' RRRRR ', ' FFFFF ', ' FGGGF ', ' FFFFF ', ' RRRRR ', 'CDDDDDC')
                .aisle('CCC#CCC', 'P     P', 'P     P', 'P     P', 'P     P', 'P     P', 'CCCCCCC')
                .where('#', Predicates.controller(Predicates.blocks(def.get())))
                .where('D', Predicates.blocks('gtceu:atomic_casing'))
                .where('C',
                    Predicates.blocks('gtceu:atomic_casing').setMinGlobalLimited(30)
                        .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setMaxGlobalLimited(1))
                        .or(Predicates.autoAbilities(def.recipeTypes)) // 自动根据配方类型设定需要的方块能力(物品/流体/能量的输入/输出)
                )
                .where('P', Predicates.blocks('ad_astra:ostrum_pillar'))
                .where('F', Predicates.blocks('gtceu:inert_machine_casing'))
                .where('T', Predicates.blocks('gtceu:ptfe_pipe_casing'))
                .where('R', Predicates.blocks('gtceu:rtm_alloy_coil_block'))
                .where('G', Predicates.blocks('gtceu:laminated_glass'))
                .where('A', Predicates.air())
                .where(' ', Predicates.any())
                .build() // 完成构建
        )
        // 机器结构有效时的纹理,建议使用各种机械方块的纹理以获取连接纹理
        // 参数1:基础纹理 - ResourceLocation
        // 参数2:有效时的纹理 - ResourceLocation - 意义不明,实践中似乎没有作用
        // 参数3(可省略):是否染色 - boolean
        .workableCasingRenderer('gtceu:block/casings/gcym/atomic_casing', 'gtceu:block/multiblock/implosion_compressor', false)
        // 设置机器控制器方块的外观
        // 参数1:方块 - 方块 ID | Internal.Block
        .appearanceBlock(GCyMBlocks.CASING_ATOMIC)
        // 可用配方类型
        // 参数1(剩余参数):配方类型 - GTRecipeType
        .recipeTypes(GTRecipeTypes.get('deep_atom_reassemble'), GTRecipeTypes.LARGE_CHEMICAL_RECIPES)
        // 配方调整函数(例如电压超频会让处理时间减少就是一种调整函数)
        .recipeModifier(GTRecipeModifiers.PARALLEL_HATCH.apply(OverclockingLogic.NON_PERFECT_OVERCLOCK, GTRecipeModifiers.ELECTRIC_OVERCLOCK))
       
});

动力机器

需要安装机械动力模组。你可以使用 Platform.isLoaded('create') 来判断。

GTCEuStartupEvents.registry('gtceu:machine', e => {
    e.create('test_kinetic_machine', 'kinetic', GTValues.LV, GTValues.MV, GTValues.HV, GTValues.EV, GTValues.IV)
        // 参数2:应用可用时的工具提示 - boolean
        // 参数3:应用默认 GUI 函数 - boolean
        .recipeType(GTRecipeTypes.get('test_recipe_type'), true, true)
})

自定义线圈方块

StartupEvents.registry('block', e => {
    e.create('strange_matter_coil_block', 'gtceu:coil')
        .temperature(19200) // 温度
        .level(20) // 工业熔炉的最大并行数量 = 此数值 * 32
        .energyDiscount(8) // 能量效率
        .tier(8) // 等级
        .coilMaterial(GTMaterials.get('strange_matter')) // 材料
        .tagBlock('forge:mineable/wrench')
        .hardness(5)
        .requiresTool(true)
        .material('metal')
        .texture('kubejs:block/strange_matter_coil_block') // 设定方块的纹理
})

如果你想让你的自定义线圈拥有和原生线圈一样的连接纹理和工作时的发光效果,以上面的代码为例,你需要:

  • 一个基础的纹理图片(分辨率16n*16n,n 为任意大于等于 1 的整数):strange_matter_coil_block.png

  • 一个与上述文件同名的 mcmeta 文件:strange_matter_coil_block.png.mcmeta

  • 一个发光纹理图片(16n*16n):strange_matter_coil_block_bloom.png

  • 一个与上述文件同名的 mcmeta 文件:strange_matter_coil_block_bloom.png.mcmeta

  • 一个基础连接纹理图片(32n*32n):strange_matter_coil_block_ctm.png

  • 一个发光纹理图片(32n*32n):strange_matter_coil_block_bloom_ctm.png

  • 一个与上述文件同名的 mcmeta 文件:strange_matter_coil_block_bloom_ctm.png.mcmeta

将它们放在你用 texture() 方法指定的路径下。以下是 mcmeta 文件的内容。

strange_matter_coil_block.png.mcmeta

{
    "ldlib": {
        "connection": "kubejs:block/strange_matter_coil_block_ctm"
    }
}

strange_matter_coil_block_bloom.png.mcmeta

{
    "ldlib": {
        "connection": "kubejs:block/strange_matter_coil_block_bloom_ctm",
        "emissive": true
    },
    "shimmer": {
        "bloom": true
    }
}

strange_matter_coil_block_bloom_ctm.png.mcmeta

{
    "shimmer": {
        "bloom": true
    }
}