本篇教程由作者设定使用 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的部分预设如下
| DULL | Matte finish | Default, common materials |
| METALLIC | Metallic shine | Metals and alloys |
| SHINY | High gloss | Precious metals |
| BRIGHT | Very bright | Special metals |
| DIAMOND | Crystalline | Gems like diamonds |
| EMERALD | Faceted | Gems like emeralds |
| RUBY | Colored gems | Colored gemstones |
| OPAL | Opalescent | Unique gems |
| GLASS | Transparent | Glass-like materials |
| FINE | Fine particles | Fine dusts, powders |
| ROUGH | Rough texture | Stone, rough materials |
| SAND | Granular | Sand-like materials |
| RADIOACTIVE | Glowing effect | Radioactive materials |
| MAGNETIC | Magnetic 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
有待补充


