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


由于此前较为完善的教程随版本更新,部分方法有所改变,使用原本方法可能无法实现预期功能

故而编写本文用于阐述新版本(1.6.4及以上)中部分功能的实现和展示一些新奇的小玩意


本文主要基于ST(StarTechnology),CC(Cosmic Frontiers),部分公开项目及官方文档编写


官方文档链接:GregTech Modern Docs

教程版本:【Minecraft1.20.1+Forge47.4.10】+【GTM 7.3.0】+【KubeJS 2001.6.5-build.16】


自定义材料

由于使用 KubeJS 自定义 GTM - [GTM]格雷科技现代版 (GregTechCEu Modern) - MC百科|最大的Minecraft中文MOD百科

已经详细介绍材料的注册方法,此处仅给出示范代码

自定义材料

图标集部分可见Material Creation - GregTech Modern Docs,后续将归入教程

Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey');

GTCEuStartupEvents.registry('gtceu:material', event => {
    event.create('testmaterial3')
        //材料形式,注意.ingot()与.dust()与.gem()不能同时使用!!!

                //.dust()       //创建形态
        .ingot()        //创建锭与粉形态
        //.gem()        //创建宝石与粉形态
        .liquid()       //创建流体(液)形态
        //.fluidTemp(int)流体温度,可空,默认为1200K
        //.block()        //使该流体可放置,需要.liquid
        //.gas().plasma().polymer()
        //流体(气),等离子体,高分子聚合物?

                .ore(4,4,false)
        //创建矿石形态
        //.ore(int1,int2.boolean)
        //int1:一单位原矿中会获得多少粉碎矿石
        //int2:整个矿石加工过程中会获得多少粉
        //boolean:矿物是否可以发光
        
        
        //.cableProperties(set,int1,int2,boolean)

               //创建导线形态
        //详细见自定义涡轮,管道,线缆,矿物处理
        
        
        
        .burnTime(64)
        //固体燃烧时间 int/tick
        //.fluidBurnTime(64)
        //液体燃烧时间 int/tick

        .color(0xffffff)
        .secondaryColor(0x12ffff)
        //主要颜色和次要颜色,使用十六进制值


        //.addDefaultEnchant(String, int)
        //为该材料添加附魔属性




        //该材料的化学式:.components(String1,String2.....)
        //如下式显示为 AuPbAg
        .components("1x gold","1x lead","1x silver")
        //该材料为单质时,使用.element而非.components
        //建议使用GTElements.
        //.element(GTElements.C)
       //.formula("C₃O")直接使用化学式,常见于复杂有机化合物
        //图标集,见后续教程
        //.iconSet(set)



        //禁用其自动配方生成,已经弃用,请使用DISABLE_MATERIAL_RECIPES
        //.flags(GTMaterialFlags.NO_UNIFICATION)
        //.flags(GTMaterialFlags.DISABLE_MATERIAL_RECIPES)

        //该材料启用电解配方,需要.components
        .flags(GTMaterialFlags.DECOMPOSITION_BY_ELECTROLYZING)
        //该材料启用离心配方,需要.components
        .flags(GTMaterialFlags.DECOMPOSITION_BY_CENTRIFUGING)
        //该材料禁用电解配方
        //.flags(GTMaterialFlags.DISABLE_DECOMPOSITION)

        //具有此标志的材料不会有聚爆压缩配方?
        .flags(GTMaterialFlags.EXPLOSIVE)
        //该材料禁用熔炼配方(熔炉,高炉...)
        .flags(GTMaterialFlags.FLAMMABLE)
        //该材料具有粘性,通常用于粘性可放置流体,如杂酚油,石油
        //.flags(GTMaterialFlags.STICKY)
        //该材料会发光,亮度为15
        .flags(GTMaterialFlags.PHOSPHORESCENT)

        //以下Flags需要【PropertyKey.DUST】
        //该材料可以合成为板与双层板,
        .flags(GTMaterialFlags.GENERATE_PLATE)
        //该材料可以合成为致密板
        .flags(GTMaterialFlags.GENERATE_DENSE)
        //该材料可以合成为杆
        .flags(GTMaterialFlags.GENERATE_ROD)
        //该材料可以合成为螺栓
        .flags(GTMaterialFlags.GENERATE_BOLT_SCREW)

//GENERATE_FRAME        框架
//GENERATE_GEAR         齿轮
//GENERATE_LONG_ROD     长杆
//FORCE_GENERATE_BLOCK  块
//MORTAR_GRINDABLE
//NO_WORKING            该材料无法通过其他方式加工,只能通过粉碎或熔炼
//NO_SMASHING           该无法用于常规金属加工技术,如压制成板或者切削成杆
//NO_SMELTING           该材料无法熔炼
//NO_ORE_SMELTING       该材料无法直接由矿石熔炼
//NO_ORE_PROCESSING_TAB 该材料无法进行矿物处理
//BLAST_FURNACE_CALCITE_DOUBLE
//该材料熔炼时获得双倍产出,如锡石
//BLAST_FURNACE_CALCITE_TRIPLE
//该材料熔炼时获得三倍产出
//DISABLE_ALLOY_BLAST   该材料无法进行合金熔炼
//DISABLE_ALLOY_PROPERTY?

        //以下Flags需要【PropertyKey.FLUID】
//SOLDER_MATERIAL       该材料可作为焊料
//SOLDER_MATERIAL_BAD(GOOD)
//该材料可作为不良(优良)焊料,未实现,处于饼阶段中!!!

        //以下Flags需要【PropertyKey.INGOT】
//GENERATE_FOIL         箔
//GENERATE_RING         环
//GENERATE_SPRING       弹簧
//GENERATE_SPRING_SMALL 小弹簧
//GENERATE_SMALL_GEAR   小齿轮
//GENERATE_FINE_WIRE    导线
//GENERATE_ROTOR        转子
//GENERATE_ROUND        圆盘
//IS_MAGNETIC           该材料具有磁化形态

        //以下Flags需要【PropertyKey.GEM】
//CRYSTALLIZABLE        该材料可以通过高压釜变回宝石
//GENERATE_LENS         该材料可以制成透镜

        //以下Flags需要【PropertyKey.ORE与PropertyKey.GEM】
//HIGH_SIFTER_OUTPUT    筛选
})

示范代码1

自定义涡轮,管道,线缆,矿物处理

Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey');
Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.ToolProperty');

GTCEuStartupEvents.registry('gtceu:material', event => {
    //你也可以更改已经具有工具属性的一个 GT 材料的工具属性。不过,你必须先移除当前的工具属性,因为它是不可变的。
    event.create('testmaterial2')
        .ingot().ore()
        .color(0xadd8e6).secondaryColor(0xc0c0c0).iconSet(GTMaterialIconSet.DULL)
         //主要颜色,次要颜色
        .rotorStats(164, 100, 3.0, 1555)
        //添加转子属性
        //rotorStats(int power, int efficiency, float damage, int durability)
        //power:功率 int
        //efficiency:效率 int
        //damage 工作时转子对实体伤害 float
        //durability 耐久值
        
        //参考:钛转子Titanium Rotor: .rotorStats(130, 115, 3.0, 1600)

        .itemPipeProperties(1, 1)
        //添加物品管道属性
        //.itemPipeProperties(int priority, int stacksPerSecond)
        //priority:该物品管道的优先级 int
        //stacksPerSecond:每秒可以移动多少组物品 int


        //.fluidPipeProperties(1000, 500, true, true, true, true)
        //添加流体管道属性
        //.fluidPipeProperties(int maxTemp, int throughput, boolean gasProof, boolean acidProof, boolean cryoProof, boolean plasmaProof)
        


        //注意::GTCEU Modern中,material同时注册物品管道和流体管道是不被允许的!!


        .cableProperties(GTValues.HV, 5, 0, false)
        //添加线缆属性
        //.cableProperties(long voltage, int amperage, int lossPerBlock, boolean isSuperconductor)
        //voltage 电压,应当符合GT电压等级   long
        //建议使用GTValues.
        //amperage  电流大小    int
        //lossPerBlock 电阻大小 int
        //非超导体情况下,电阻为0时仍存在损耗
        //isSuperconductor 是否为超导体 boolean


       


        //添加矿物处理特殊属性  均为string
        .addOreByproducts("lead")
        //粉碎处理所得副产品
        // .addOreByproducts(String1,String2[可选])
        //String1:研磨-洗矿    或    研磨-研磨-离心               所产生的副产物
        //String2:粉碎矿热力离心-粉碎    或    洁净粉离心    所产生的副产物
        
        .washedIn("water")
        //洗矿所用流体
        .separatedInto("gold")
        //电磁分离处理所得副产品
        .oreSmeltInto("gold")
        //熔炼处理所得副产品

      
})

示范代码2

自定义工具

Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey');
Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.ToolProperty');
GTCEuStartupEvents.registry('gtceu:material', event => {
    //你也可以更改已经具有工具属性的一个 GT 材料的工具属性。不过,你必须先移除当前的工具属性,因为它是不可变的。
    event.create('testmaterial')
        .ingot()
        .color(0xadd8e6).secondaryColor(0xc0c0c0).iconSet(GTMaterialIconSet.DULL)
        //赋予其工具类型
        .toolStats(
            ToolProperty.Builder.of(12.0, 7.0, 3072, 6,
            [
                GTToolType.SWORD,
                GTToolType.MINING_HAMMER,
                GTToolType.HOE
            ]
        )
        .unbreakable()//不毁
        .magnetic()//磁力
        //.attackSpeed(1.0)//攻击速度,动画 float
        //ignoreCraftingTools()
        //.enchantment(Enchantment enchantment, int level)//默认附魔,附魔等级
        //.enchantability(int enchantability)//附魔能力
        .build()
    )
        //.toolStats(float harvestSpeed, float attackDamage, int durability, int harvestLevel, GTToolType[] types)
        //harvestSpeed: float 表示工具在世界中实际破坏方块的速度。
        //attackDamage: float 表示你对生物/玩家造成的每次击打的伤害量。
        //durability: int 表示工具在损坏前可以使用的次数。
        //harvestLevel: int 是它可以破坏的方块等级。
        
        //types: GTToolType[] 是一个对象中的工具数组。
        //如果你希望你的材料适用于所有工具类型,可以省略这个参数。
        
//GTToolType 的部分预设:

//SWORD  剑
//PICKAXE  镐
//SHOVEL  铲
//AXE  斧头
//HOE  锄头
//MINING_HAMMER  采矿锤
//SPADE  铲子
//SAW 锯
//HARD_HAMMER    锻造锤
//SOFT_MALLET    软锤
//WRENCH  扳手
//FILE  锉
//CROWBAR  撬棍
//SCREWDRIVER  螺丝刀
//MORTAR  研钵
//WIRE_CUTTER  剪线钳
//SCYTHE  镰刀
//KNIFE  刀
//BUTCHERY_KNIFE  屠宰刀
//PLUNGER 搋子
//DRILL_LV    钻头
//DRILL_MV    
//DRILL_HV    
//DRILL_EV    
//DRILL_IV    
//CHAINSAW_LV 链锯
//WRENCH_LV  电动扳手
//WRENCH_HV  
//WRENCH_IV  
//BUZZSAW    圆锯
//SCREWDRIVER_LV  电动螺丝刀
//WIRE_CUTTER_LV  电动剪线钳
//WIRE_CUTTER_HV
//WIRE_CUTTER_IV

});

示范代码3

自定义图标集

GTMaterialIconSet的部分预设如下

DULLMatte finish  Default, common materials

METALLICMetallic shine  Metals and alloys  
SHINYHigh gloss  Precious metals  
BRIGHTVery bright  Special metals  
DIAMONDCrystalline  Gems like diamonds  
EMERALDFaceted  Gems like emeralds  
RUBYColored gems  Colored gemstones 
OPALOpalescent  Unique gems  
GLASSTransparent  Glass-like materials  
FINEFine particles  Fine dusts, powders  
ROUGHRough texture  Stone, rough materials  
SANDGranular Sand-like materials  
RADIOACTIVEGlowing effect  Radioactive materials 
MAGNETICMagnetic effect  Magnetic materials  


一般通过gtceu:matieral_icon_set事件实现自定义图标集

GTCEuStartupEvents.registry('gtceu:material_icon_set', event => {
    event.create('test')
    //继承于DULL,未定义的textures将以DULL中的textures代替
    .parent(GTMaterialIconSet.DULL)
})

    //自定义icon使用示范
    //iconSet(GTMaterialIconSet.getByName(String))

GTCEuStartupEvents.registry('gtceu:material', event => {
    event.create('testmaterial4')
        .ingot().ore()
        .color(0xadd8e6).secondaryColor(0xc0c0c0)
        .iconSet(GTMaterialIconSet.getByName("test"))
})

示范代码4

修改已有材料

    const $IngotProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.IngotProperty');
    const $DustProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.DustProperty');
    const $FluidProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.FluidProperty');
    const $FluidBuilder = Java.loadClass('com.gregtechceu.gtceu.api.fluids.FluidBuilder');
    const $FluidStorageKeys = Java.loadClass('com.gregtechceu.gtceu.api.fluids.store.FluidStorageKeys');
    const $OreProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.OreProperty');




    GTCEuStartupEvents.registry('gtceu:material', event => {

        //为gtceu已注册elements添加属性
        GTMaterials.Zirconium.setProperty(PropertyKey.INGOT, new $IngotProperty());//为锆元素添加ingot属性
        GTMaterials.Obsidian.setProperty(PropertyKey.INGOT, new $IngotProperty());//为黑曜石添加ingot属性
        //注意ingot属性包含添加锭,粒,粉,板
        GTMaterials.Selenium.setProperty(PropertyKey.DUST, new $DustProperty());//为硒元素添加dust属性
        GTMaterials.Zinc.setProperty(PropertyKey.ORE, new $OreProperty());//为锌元素添加ore属性
       
       

        GTMaterials.Lead.addFlags(GTMaterialFlags.GENERATE_GEAR);//添加标签,添加铅齿轮
        GTMaterials.BismuthBronze.setMaterialARGB(0x82AD92);//修改颜色
        
        
        //向现有材料中添加液体需要使用新的液体存储系统进行一些操作
        addFluid(GTMaterials.Iodine, $FluidStorageKeys.LIQUID); //为碘元素添加liquid属性
        addFluid(GTMaterials.Oganesson, $FluidStorageKeys.GAS);//为鿫元素添加gas属性
       
    });
    let addFluid = (mat, key) => {
    let prop = new $FluidProperty();
    prop.getStorage().enqueueRegistration(key, new $FluidBuilder());
    mat.setProperty(PropertyKey.FLUID, prop);}

示范代码5

自定义机器

此前教程中,通常会发生使用示范代码构建自定义机器失败的情况

故而本文参考多个基于KubeJs创造自定义机器的整合包给出示范

自定义线圈

StartupEvents.registry('block', event => {
    event.create('infinity_coil_block', 'gtceu:coil')
        .temperature(100)                      
        .level(0)
        .energyDiscount(1)
        .tier(10)
        .coilMaterial(() => GTMaterials.get('infinity'))
        .texture('kubejs:block/example_block')
        .hardness(5)
        .requiresTool(true)
        .material('metal')

        //.temperature()        线圈温度
        //.level()              线圈并行等级,用于确定 Multi-Smelter 并行数
        //.energyDiscount()     用于确定 Multi-Smelter 功率消耗,EU/t = (4 * 并行数) / (8 * 折扣)
        //.tier()               线圈阶段等级,用于 Pyrolyze Oven 中的速度加成,以及 Cracking Unit 中的能源折扣
        //coilMaterial          线圈材料

        //示范数据 高速钢G HSS_G, 5400, 4, 4
})

示范代码6

自定义单方块机器

GTCEuStartupEvents.registry('gtceu:machine', event => {
    //自定义单方块机器-蒸汽
    //event.create(机器id String,'steam',是否有高压版本 boolean)
    event.create('steam_circuit_assembler', 'steam')
    .definition((tier, builder) =>{
        builder
            //配方类型
            .recipeType('circuit_assembler')
            //控制器纹理
            .workableTieredHullModel('gtceu:block/machines/flora_nurturer')
    });
    //自定义单方块机器-电力
    //event.create(机器id String,'simple',污染产生 int[疑似弃用])
    event.create('test_electric', 'simple')
    //可用电压版本
    //建议使用GTValues.
        .tiers(GTValues.LV, GTValues.MV, GTValues.HV)
        .definition((tier, builder) =>
            builder
                .rotationState(RotationState.NON_Y_AXIS)
                .recipeType('test_recipe_type')
                //储量大小,疑似弃用
                //.tankScalingFunction(tier => tier * 3200)
                //控制器贴图
                .workableTieredHullModel('gtceu:block/machines/flora_nurturer')
               7.0.0之前版本使用.workableTieredHullRenderer(string)
            );
})


示范代码7

自定义多方块机器


GTCEuStartupEvents.registry('gtceu:machine', event => {
    //自定义多方块机器-原始
    //event.create(机器id String, 'primitive')
    //即不消耗电力(蒸汽)的机器
    event.create('example_primitive_machine', 'primitive')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('test_recipe_type')
        //外壳材质纹理
        .appearanceBlock(() => Block.getBlock('minecraft:dirt'))
        //多方块结构构建
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('BBBBB','BBBBB','BBBBB','MBBBM')
            .aisle('BBBBB','BMBMB','BMBMB','MBBBM')
            .aisle('BBBBB','BMBMB','BMBMB','MBBBM')
            .aisle('BBBBB','BBKBB','BBBBB','MBBBM')
            //控制器
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            //主体方块及舱室
            .where('B', Predicates.blocks('minecraft:dirt').setMinGlobalLimited(15)
                .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.EXPORT_FLUIDS).setMaxGlobalLimited(1).setPreviewCount(1))
            )  
            .where('M', Predicates.any())
            .build())
             //控制器纹理
        .workableCasingModel("gtceu:block/casings/solid/machine_casing_inert_ptfe",
            "gtceu:block/multiblock/large_chemical_reactor")
            //7.0.0之前版本使用 .workableCasingRenderer(string,string,boolean)
        //控制器UI设置
       //测试7.3.0疑似弃用,1.6.4可用
        .editableUI(
            global.ui_builder({
                group: 'primitive',
                name: 'example_primitive_machine',
                size: [166, 50],
                background: GuiTextures.PRIMITIVE_BACKGROUND,
                progress: {
                    pos: [71, 16],
                    size: [20, 20],
                    texture: GuiTextures.PROGRESS_BAR_ARROW
                },
                //输入
                inputs: [
                    { type: 'item', index: 0, pos: [7, 16], texture: GuiTextures.SLOT },
                    { type: 'item', index: 1, pos: [25, 16], texture: GuiTextures.SLOT },
                    { type: 'item', index: 2, pos: [43, 16], texture: GuiTextures.SLOT },
                ],
                //输出
                outputs: [
                    { type: 'item', index: 0, pos: [103, 16], texture: GuiTextures.SLOT },
                    { type: 'item', index: 1, pos: [121, 16], texture: GuiTextures.SLOT },
                    { type: 'fluid', index: 0, pos: [139, 16],texture: GuiTextureGroup(GuiTextures.PRIMITIVE_SLOT, GuiTextures.PRIMITIVE_LARGE_FLUID_TANK_OVERLAY.getSubTexture(0, 0.04, 1, 0.22)) }
                ],
            })
        );
           
    //自定义多方块机器-电力
    //event.create(机器id String,'multiblock')
    event.create('large_semifluid_generator', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('test_recipe_type')
        .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_PERFECT_SUBTICK])
        //recipeModifiers部分预设
        //OC_PERFECT                            无损超频
        //OC_NON_PERFECT                  损失能量的超频
        //OC_PERFECT_SUBTICK
        //OC_NON_PERFECT_SUBTICK
        //PARALLEL_HATCH                   使用并行仓
        //BATCH_MODE                         使用批量处理模式
        //crackerOverclock                    带线圈能量折扣的 OC(常见于裂化机)
        //ebfOverclock                          基于线圈温度折扣的OC(EBF)
        //pyrolyseOvenOverclock          基于线圈等级进行加速的OC(热解炉)
        //multiSmelterParallel                基于线圈等级增加并行
               
        
        //是否为发电机?
        .generator(true)
        .regressWhenWaiting(false)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCCC', 'CCCC','CCCC')
            .aisle('CCCC', 'CMMC','CGGC')
            .aisle('CCCC', 'CMMC','CGGC')
            .aisle('CCCC', 'CKCC','CCCC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get()).setMinGlobalLimited(34)
                .or(Predicates.abilities(PartAbility.IMPORT_FLUIDS).setExactLimit(1))//流体输入仓
                .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setExactLimit(1))//物品输入仓
                .or(Predicates.abilities(PartAbility.INPUT_ENERGY).setExactLimit(1))//能源仓
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))//维护仓
                .where('O', Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))//消声仓
                .or(Predicates.abilities(PartAbility.EXPORT_FLUIDS).setExactLimit(1))//流体输出仓
            )
            .where('G', Predicates.blocks('minecraft:glass'))
            .where('M', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_solid_steel',"gtceu:block/multiblock/large_chemical_reactor")
   
    //自定义多方块机器-蒸汽
    event.create('large_steam_hammer', 'multiblock')
        //并行数设置
        .machine((holder) => new $SteamMulti(holder, 4))
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('test_recipe_type')
        .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
        .recipeModifier((machine, recipe) => $SteamMulti.recipeModifier(machine, recipe), true)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('AAA', 'AAA', 'AAA')
            .aisle('AAA', 'A#A', 'AAA')
            .aisle('AAA', 'A@A', 'AAA')
            .where('A', Predicates.blocks(GTBlocks.CASING_BRONZE_BRICKS.get())
                .or(Predicates.abilities(PartAbility.STEAM_IMPORT_ITEMS).setPreviewCount(1).setMaxGlobalLimited(2))
                .or(Predicates.abilities(PartAbility.STEAM).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.STEAM_EXPORT_ITEMS).setPreviewCount(1).setMaxGlobalLimited(2)))
            .where('#', Predicates.blocks('minecraft:air'))
            .where('@', Predicates.controller(Predicates.blocks(definition.get())))
            .build())
        .workableCasingModel("gtceu:block/casings/solid/machine_casing_inert_ptfe",
            "gtceu:block/multiblock/large_chemical_reactor");
   
   
   
})

示范代码8

自定义多方块锅炉

既然有青铜锅炉和钢锅炉,那为什么不能有不锈钢锅炉呢?

const $LargeBoilerMachine = Java.loadClass("com.gregtechceu.gtceu.common.machine.multiblock.steam.LargeBoilerMachine")
//导入LargeBoilerMachine方法
   
GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('example_boiler', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .machine((holder) => new $LargeBoilerMachine(holder, 2000, 3))
        //LargeBoilerMachine(IMachineBlockEntity holder, int maxTemperature, int heatSpeed)
        //maxTemperature 最高温度,决定了锅炉蒸汽产量
        //heatSpeed 升温速度,每10tick循环一次
        .recipeType(GTRecipeTypes.LARGE_BOILER_RECIPES)
        //调用大型蒸汽锅炉的RecipeType
        .recipeModifier((machine, recipe) => $LargeBoilerMachine.recipeModifier(machine, recipe))
        //定义锅炉的RecipeModifier
        .appearanceBlock(GTBlocks.CASING_STAINLESS_CLEAN)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('AAA', 'AAA','AAA')
            .aisle('AAA', 'AAA','AAA')
            .aisle('AAA', 'AKA','AAA')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('A', Predicates.blocks(GTBlocks.CASING_STAINLESS_CLEAN.get())
                .or(Predicates.abilities(PartAbility.IMPORT_FLUIDS).setExactLimit(1))//流体输入仓
                .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setExactLimit(1))//物品输入总线
                .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))//消声仓
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))//维护仓
                .or(Predicates.abilities(PartAbility.EXPORT_FLUIDS).setExactLimit(1))//流体输出仓
            )
            .build())
        .workableCasingModel("example")
})

示范代码9

我查阅了相关方法,锅炉的实际产出是如此计算的:

//updateCurrentTemperature
//蒸汽产出量实际与耗水速率相关,而耗水速率受到温度和节流阀调控
//最大耗水速率 与 节流阀效率  throttle , 当前温度 currentTemperature 成正比关系
var maxDrain = currentTemperature * throttle * TICKS_PER_STEAM_GENERATION * FluidHelper.getBucket() / (ConfigHolder.INSTANCE.machines.largeBoilers.steamPerWater * 100000L);
//得到最后的蒸汽产出量 为 当前耗水速率 * 参数 steamPerWater
steamGenerated = drained * ConfigHolder.INSTANCE.machines.largeBoilers.steamPerWater;
//参数steamPerWater 的实际值为 160
public int steamPerWater = 160;

//此外升温速度的公式如下
//每0.5秒,温度增加 heatSpeed * 10
//青铜锅炉heatSpeed=1;钢锅炉heatSpeed = 2 
if (getOffsetTimer() % 10 == 0) {
    if (currentTemperature < getMaxTemperature()) {
        currentTemperature = Mth.clamp(currentTemperature + heatSpeed * 10, 0, getMaxTemperature());

自定义多方块涡轮

同样是基于已有方法的调用

const $LargeTurbineMachine = Java.loadClass("com.gregtechceu.gtceu.common.machine.multiblock.generator.LargeTurbineMachine")
//导入LargeTurbineMachine方法

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('water_turbine', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .machine((holder) => new $LargeTurbineMachine(holder, GTValues.HV))
        //LargeTurbineMachine(IMachineBlockEntity holder, int tier)
        //tier 电压等级,是发电量计算的变量之一
        .recipeType('water_turbine')
        //注册recipeType,这里不再给出示范
        .generator(true)
        .recipeModifiers([GTRecipeModifiers.OC_NON_PERFECT_SUBTICK, GTRecipeModifiers.BATCH_MODE, (machine, recipe) => $LargeTurbineMachine.recipeModifier(machine, recipe)])
        .appearanceBlock(GTBlocks.CASING_STAINLESS_TURBINE)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('#AAAAA#', '##AAA##', '###A###', '#######', '#######')
            .aisle('AAAAAAA', '#BAAAB#', '#BAAAB#', '#B#A#B#', '#B###B#')
            .aisle('AAAAAAA', 'AA###AA', '#AAAAA#', '##AAA##', '#######')
            .aisle('AAAAAAA', 'AA###AA', 'AAA#AAA', '#AACAA#', '#######')
            .aisle('AAAAAAA', 'AA###AA', '#AAAAA#', '##AAA##', '#######')
            .aisle('AAAAAAA', '#BAAAB#', '#BAAAB#', '#B#A#B#', '#B###B#')
            .aisle('#AAAAA#', '##AKA##', '###A###', '#######', '#######')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('B', Predicates.blocks('gtceu:stainless_steel_frame'))
            .where('A', Predicates.blocks(GTBlocks.CASING_STAINLESS_TURBINE.get())
                    .or(Predicates.abilities(PartAbility.IMPORT_FLUIDS).setExactLimit(1))//流体输入仓
                    .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))//消声仓
                    .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))//维护仓
                    .or(Predicates.abilities(PartAbility.EXPORT_FLUIDS).setExactLimit(1))//流体输出仓
                    .or(Predicates.abilities(PartAbility.OUTPUT_ENERGY).setExactLimit(1))//动力仓
                )
            .where('C', Predicates.abilities(PartAbility.ROTOR_HOLDER))//转子仓
            .where('#', Predicates.any())
            .build()
)
        .workableCasingModel("example")
})

示范代码10

关于大型涡轮的发电量计算,如下所示:

//基础发电量,完全有tier决定
//基础功率 = 机器电压 * 2
this.BASE_EU_OUTPUT = (int) GTValues.V[tier] * 2

//最大电压 = 基础 × 转子总功率 / 100
//转子相关参数见前文部分
var rotorHolder = getRotorHolder()
return (long) BASE_EU_OUTPUT * rotorHolder.getTotalPower() / 100

//当实际转速未达到最大转速时
//实际功率为 理论输出 * (当前转速 / 最大转速)^2
return (long) (production * Math.pow(1.0 * currentSpeed / maxSpeed, 2));

自定义配方类型

.setProgressBar,.setSound的具体类型

可见kubejs_book/GregTechCEu Modern/GregTechCEu Modern Machine.md at main · Murate82/kubejs_book · GitHub

GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    //自定义配方类型
    //event.create(配方类型id String)
    event.create('test_recipe_type')
        //类
        .category('test')
        //setEUIO 耗能in/产能out
        .setEUIO('in')
        //setMaxIOSize(int,int,int,int)
        //物品输入槽位,物品输出槽位,流体输入槽位,流体输出槽位
        .setMaxIOSize(3, 3, 3, 3)
        .setMaxTooltips(5)//设置最大信息提示
        
        .setSlotOverlay(false, false, GuiTextures.SOLIDIFIER_OVERLAY)                                    //设置机器的背面带有覆盖版
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)//处理中的图标,处理中图标的方向
        .setSound(GTSoundEntries.COOLING)                                                                        //机器运行时的声音
})
//注意!配方类型必须在机器注册之前注册

示范代码11

自定义配方

ServerEvents.recipes(event => {
    event.recipes.gtceu.example_smelting('example:diamondirt')
        .itemInputs('minecraft:dirt')
        .itemOutputs('gtceu:raw_diamond')
        .addData("RequiredTemp", 1000) // 
        .duration(320)
        .EUt(12);
    
    
    //.itemInputs()       物品输入
    //.chancedInput()     概率消耗物品
    //.notConsumable()    催化剂物品输入

    //.inputFluids()      流体输入
    //.chancedFluidInput()概率消耗流体
    //.notConsumableFluid()催化剂流体输入

    //.itemOutputs()      物品输出
    //.chancedOutput()    概率输出物品

    //.outputFluids()     流体输出
    //.chancedFluidOutput()概率输出流体

    //.inputEU()          耗能
    //.outputEU()         产能
    //.EUt()              每Tick耗能
    //.circuit()          使用编程电路0-32
    
    //.perTick(boolean)   视为每Tick工作
    //true 输入/输出调用视为每刻执行
    //false一次性在配方开始/结束时消耗/生成

    //.biome(String)          当符合生物群系条件时,配方运行
    //.dimension(String)      当符合维度条件时,配方运行
    //.posY(int min, int max) 当符合Y坐标位于指定范围内时,配方运行
    //.rain(float level)      当符合雨量条件时,配方运行
    //.thunder(float level)   当符合雷暴条件时,配方运行
    //.daytime(boolean)       当符合时间条件时,配方运行


    //.cleanroom(CleanroomType.CLEANROOM) 超净间配方
    //.environmentalHazard("medical_condition_name")  当存在某环境危害时,配方运行

    //最低版本7.2.0
    //.adjacentFluids(String,....)   
    //当符合临近存在某流体时,配方运行
    //例如:.adjacentFluids("minecraft:water", "minecraft:lava")
    //配方要求机器旁边同时有水源和岩浆源。
    //.adjacentBlocks(String,....)//同理如上

    //.ftbQuest("quest_id")//配方被任务锁定
    //.gameStage("gamestage_id")//配方被游戏阶段锁定
    
    //最低版本7.2.0
    //Where the inputs or outputs will be rolled inclusively from min to max.
    //.itemInputsRanged(..., min, max)
    //.itemOutputsRanged(..., min, max)
    //.fluidInputsRanged(..., min, max)
    //.fluidOutputsRanged(..., min, max)

    

})

示范代码12

自定义配方修改器

CustomRecipeModifiers

用于创建新的.recipeModifiers

需要一定的JS基础以及阅读官方开源代码的能力

例如创建一个新的与线圈温度相关的配方条件,而非传统的高炉线圈配方模式

设定实际线圈温度每高出配方温度 100K 则使实际配方时间*95%

const $GTRecipe = Java.loadClass("com.gregtechceu.gtceu.api.recipe.GTRecipe");
const $MetaMachine = Java.loadClass("com.gregtechceu.gtceu.api.machine.MetaMachine");
const $CoilWorkableElectricMultiblockMachine = Java.loadClass("com.gregtechceu.gtceu.api.machine.multiblock.CoilWorkableElectricMultiblockMachine");
const $RecipeModifier = Java.loadClass("com.gregtechceu.gtceu.api.recipe.modifier.RecipeModifier");

function TemperatureModifier(machine, recipe) {
    if (!(machine instanceof $MetaMachine)) return ModifierFunction.NULL;
    if (!(recipe instanceof $GTRecipe)) return ModifierFunction.NULL;
    if (!(machine instanceof $CoilWorkableElectricMultiblockMachine)) return ModifierFunction.NULL;

    let machineTemp = machine.getCoilType().getCoilTemperature();
    let recipeTemp = recipe.data.getInt("RequiredTemp");


    if (recipeTemp > machineTemp) {return ModifierFunction.NULL;} // 温度不足,配方不可用

    let tempDiff = machineTemp - recipeTemp;
    let steps = Math.floor(tempDiff / 100); //计算步差

    if (steps <= 0) {return ModifierFunction.IDENTITY;}//步差小于1时,不执行配方加速

    let factor = Math.pow(0.95, steps);                        //步差大于等于1时,执行配方加速
    return ModifierFunction.builder()
        .durationMultiplier(factor)
        .build();
        //其他可用的方法
        //.eutMultiplier(double)             能量消耗
        //.outputMultiplier(double)       
        //.chanceMultiplier(double)       
        
}

//创建配方类型
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('example_smelting')
        .category('multiblock')
        .setMaxIOSize(1, 1, 0, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_FUSION, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.BATH);
});
//创建多方块结构
GTCEuStartupEvents.registry('gtceu:machine', event => {


    GTRecipeTypes.get("example_smelting").addDataInfo((data) => (
        `Temperature: ${data.getInt("RequiredTemp")}K` // 
    )) // 

    event.create('example_smelter', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .machine((holder) => new $CoilWorkableElectricMultiblockMachine(holder)) // 
        .recipeType('example_smelting')
        .recipeModifiers([(machine, recipe) => TemperatureModifier(machine, recipe)]) // 
        .appearanceBlock(() => Block.getBlock("gtceu:solid_machine_casing"))
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('###','HHH','###')
            .aisle('###','H H','###')
            .aisle('#C#','HHH','###')
            .where('C', Predicates.controller(Predicates.blocks(definition.get())))
            .where('#', Predicates.blocks("gtceu:solid_machine_casing")
                .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.INPUT_ENERGY).setMaxGlobalLimited(1).setPreviewCount(1)))
            .where('H', Predicates.heatingCoils())
            .where(' ', Predicates.any())
            .build())
        .workableCasingModel("gtceu:block/casings/solid/machine_casing_solid_steel", "gtceu:block/multiblock/blast_furnace")
})

示范代码13

自定义缩短配方时间

GTL内置在GTLcore中的功能,实际上用KubeJS也是可以实现的:

ServerEvents.recipes(event => {
    event.forEachRecipe({ mod: 'gtceu' }, recipe => { 
        try { 
            var newDuration = recipe.get("duration") 
            recipe.set("duration", newDuration/10) //遍历配方,处理时间/10
        } catch (err) { 
            console.log(recipe.id + " has no duration field, skipped.")
        }
    })
})

示范代码14

自定义仓室

是的,通过调用GTCEu Modern的部分api,即使没有对应kubejs集成也可以实现自定义仓室的功能!

自定义并行仓

也许更加便宜的并行仓?

const $ParallelHatchPartMachine = Java.loadClass("com.gregtechceu.gtceu.common.machine.multiblock.part.ParallelHatchPartMachine"); 
const $RecipeLogic = Java.loadClass("com.gregtechceu.gtceu.api.machine.trait.RecipeLogic" );
GTCEuStartupEvents.registry("gtceu:machine", (event) => {
  event
      .create("parallel_hatch", "custom")
      .tiers(GTValues.LV, GTValues.MV, GTValues.HV)
      .machine((holder, tier, tankScaling) => {
        return new $ParallelHatchPartMachine(holder, tier);
      })
      .definition((tier, builder) => {
        let name = "Simple";
        switch (tier) {
          case GTValues.LV:
            name = "LV";
            break;
          case GTValues.MV:
            name = "MV";
            break;
          case GTValues.HV:
            name = "HV";
            break;
        }
        builder
            .langValue(name + " Parallel Control Hatch")
            .rotationState(RotationState.ALL)
            .abilities(PartAbility.PARALLEL_HATCH)
            .modelProperty($RecipeLogic.STATUS_PROPERTY, $RecipeLogic.Status.IDLE)
            .model(
                    GTMachineModels.createWorkableTieredHullMachineModel(
                    GTCEu.id("block/machines/parallel_hatch_mk4")
                )[
                    "andThen(com.gregtechceu.gtceu.api.registry.registrate.MachineBuilder$ModelInitializer)"
                    ]((ctx, prov, model) => {
                  model.addReplaceableTextures("bottom", "top", "side");
                })
            )
      });
});

示范代码15

自定义流体仓

是的,你想要拥有UHV,甚至是UEV级别的流体输入输出仓吗?

注意:使用原版提供的容量计算公式,UEV级别的流体仓容量与UHV级别并无区别。

const $FluidHatchPartMachine = Java.loadClass("com.gregtechceu.gtceu.common.machine.multiblock.part.FluidHatchPartMachine");
const $IO = Java.loadClass("com.gregtechceu.gtceu.api.capability.recipe.IO");

const BASE_CAPACITY = 8000; // 基础容量,通常为 8000 mB(与普通流体仓一致)
                                                  //当slots = 4 时,即四重流体仓 基础容量为2000
                                                  //当slots = 9 时,即九重流体仓 基础熔炼为1000
                                                  //public static final int INITIAL_TANK_CAPACITY_4X = 2000
                                                  //public static final int INITIAL_TANK_CAPACITY_9X = 1000

GTCEuStartupEvents.registry("gtceu:machine", (event) => {
    event.create("fluid_output_hatch", "custom")
        .tiers(GTValues.UHV, GTValues.UEV)
        .machine((holder, tier) => {
            // 调用静态方法计算容量
            let baseCapacity = 8000;
            let capacity = baseCapacity * Math.pow(2, tier)
            //原版采用的计算方式为
            //initialCapacity * (1 << Math.min(9, tier))
            //该方式确保了数据不会溢出
            let slots = 1; 
            return new $FluidHatchPartMachine(holder, tier, $IO.OUT, capacity, slots);//传回
        })
        .definition((tier, builder) => {
            let tierName;
            switch (tier) {
                case GTValues.UHV: tierName = "UHV"; break;
                case GTValues.UEV: tierName = "UEV"; break;
            }

            builder
                .langValue(tierName + " Fluid Output Hatch")
                .rotationState(RotationState.ALL)
                .abilities(PartAbility.EXPORT_FLUIDS) // 标记为流体输出能力
                .workableTieredHullModel()  //工作方块模型
})
        });

示范代码16

更大的蒸汽输入仓?很遗憾,原版的接口部分内容如下所示:

public SteamHatchPartMachine(IMachineBlockEntity holder, Object... args) {
    super(holder, 0, IO.IN, 64000, 1, args);}

KubeJS的能力是有极限的,继承类是KubeJS无法做到的,至少我不并了解。

自定义能源仓

LV,MV,HV能源仓的4A版本,理论上可以实现2147483647安能源仓。

const $EnergyHatchPartMachine = Java.loadClass("com.gregtechceu.gtceu.common.machine.multiblock.part.EnergyHatchPartMachine");
const $IO = Java.loadClass("com.gregtechceu.gtceu.api.capability.recipe.IO");


GTCEuStartupEvents.registry("gtceu:machine", (event) => {
    event.create("energy_output_hatch_4a", "custom")
        .tiers(GTValues.LV, GTValues.MV,GTValues.HV)
        .machine((holder, tier, amperage) => {
            //public EnergyHatchPartMachine(IMachineBlockEntity holder, int tier, IO io, int amperage, Object... args)
            // amperage 即电流大小
            return new $EnergyHatchPartMachine(holder, tier, $IO.BOTH, 4);//传回
        })
        .definition((tier, builder) => {
            let tierName;
            switch (tier) {
                case GTValues.LV: tierName = "LV"; break;
                case GTValues.MV: tierName = "MV"; break;
                case GTValues.HV: tierName = "HV"; break;
            }

            builder
                .langValue("4A"+tierName + " Energy Output Hatch")
                .rotationState(RotationState.ALL)
                .abilities(PartAbility.OUTPUT_ENERGY)//标记为能量输出能力
                .workableTieredHullModel()  //工作方块模型
})
        });

示范代码17

自定义元素

该部分由于已经存在较为完善的教程,此处仅仅给出示范代码

GTCEuStartupEvents.registry('gtceu:element', event => {
   event.create('example_element")
        //定义id    String
        .protons(27)
        //质子数    long
        .neutrons(177)
        //中子数    long
        .halfLifeSeconds(-1)
        //半衰期,-1表示该物质不能衰变    long
        .decayTo(null)
        //是否能够衰变? null为该物质不能衰变    String
        .symbol('example')
        //该元素的符号    String
        .isIsotope(false)
        //该元素是否为某元素的同位素?    boolean
})

示范代码18

有待补充