KubeJSでGregTechの機械を追加する

KubeJSとGregTechの連携

gregtechは、マテリアル、機械などを容易に追加できるように作成されています。
それをKubeJSでもいじれるようにして、MODPACK制作ができるようになっています。
今回は新しい機械を作る方法をメモしておく

なおこの情報は1.20のgregtechの情報である。

前提知識

使用ライブラリ

現在のgregtechはLDLibというライブラリを使用しています。
調べるときはこちら参照する場合があります。
LDLib Docs
https://github.com/Low-Drag-MC/LDLib-Architectury/wiki

オーバーロード

どのように定義されているかを確認する際、javaのコードを確認することになりますが
javaにはオーバーロードが採用されています。
オーバーロードがない言語もあるので知らなければ読んでください。

オーバーロードは同じメソッド名でも引数の数や型が異なると複数の定義が可能です。

1setTime(int hours)
2setTime(int hours, int minutes)
3setTime(int hours, int minutes, int seconds)

みたいなイメージ

なのでメソッドを検索したとき複数定義されていることがありますがそれらは引数の数で使い分けすることができます。

新しい機械を追加する

新しい機械を作るためには以下を作成が必要

  1. レシピタイプを追加する
  2. 機械を定義を追加する
  3. 機械本体、機械を使ったのレシピを追加する
  4. langファイルを追加する

今回はプランター、自動栽培機を作成するとします。

レシピタイプを追加する

レシピタイプとは「精錬」とか「醸造」とか「粉砕」とかに当たる部分
レシピ内容の定義ではなく、どのような処理をするかの定義するイメージ。
※機械の作成の前にこの定義が必須です。

KubeJSの定義
https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/GTRecipeTypeBuilder.java

MOD内の設定
https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeTypes.java

保存場所

1./kubejs/startup_scripts/recipes/planter.js
2※recipesのサブフォルダは無くても問題ありません

<例>

1GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
2    event.create('planter')
3        .category('test')
4        .setEUIO('in')
5        .setMaxIOSize(2, 2, 1, 0)
6        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
7        .setSound(GTSoundEntries.BATH)
8})

上から順に説明


レシピタイプ名の設定。

1.create('planter')

カテゴリ名を設定できるみたいですが、このプロパティは使われていなさそうなので適当で問題ないと思います。

1.category('test')

電力の入出力設定。
通常の機械は「in」で発電機は「out」

1.setEUIO('in')

スロットの個数設定。
左から、アイテム搬入、アイテム搬出、液体搬入、液体搬出

1.setMaxIOSize(2, 2, 1, 0)

GUIの中央にある進捗状況のアイコンとプログレスバーがどの方向に進むかの設定

テクスチャの定義
https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/api/gui/GuiTextures.java

方向設定はこれによると
「LEFT_TO_RIGHT」「RIGHT_TO_LEFT」「UP_TO_DOWN」「DOWN_TO_UP」「ALWAYS_FULL」があるみたいです。

1.setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)

動作音の設定

効果音の定義
https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/common/data/GTSoundEntries.java

1.setSound(GTSoundEntries.BATH)

今回は使用していないがスロットのオーバーレイすテクスチャの設定
(isOutput, isFluid, テクスチャの定義)

1.setSlotOverlay(false, false, GuiTextures.BOX_OVERLAY)

基本はこれらを設定していれば問題なさそうです。

機械を定義を追加する

次は機械を作成していきます。
なお、今回は電気機械とします。
蒸気機械やマルチブロックはまた異なります。

KubeJSの定義
https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/MachineFunctionPresets.java

MOD内の設定
https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/common/data/GTMachines.java

保存場所

1./kubejs/startup_scripts/machines/planter.js
2※machinesのサブフォルダは無くても問題ありません

<例>

1GTCEuStartupEvents.registry('gtceu:machine', event => {
2    event.create('planter', 'electric', GTValues.LV, GTValues.MV, GTValues.HV)
3        .rotationState(RotationState.ALL)
4        .recipeType('planter', true, true)
5        .tankScalingFunction(tier => tier * 3200)
6        .workableTieredHullRenderer("gtceu:block/machines/compressor");
7})

上から順に説明


機械ID、機械タイプ、ティア設定を行う
機械IDは、アイテムIDにもなります。基本的にはレシピタイプ名と同じにして良いと思います。
機械タイプは、これによると
「steam」「electric」「generator」「multiblock」「kinetic」を使えばよさそう

1event.create('planter', 'electric', GTValues.LV, GTValues.MV, GTValues.HV)

ティアはここにある通り
自分もIV辺りからランクが分からなくなるのでメモとして残す

 1public static final int ULV = 0;
 2public static final int LV = 1;
 3public static final int MV = 2;
 4public static final int HV = 3;
 5public static final int EV = 4;
 6public static final int IV = 5;
 7public static final int LuV = 6;
 8public static final int ZPM = 7;
 9public static final int UV = 8;
10public static final int UHV = 9;
11public static final int UEV = 10;
12public static final int UIV = 11;
13public static final int UXV = 12;
14public static final int OpV = 13;
15public static final int MAX = 14;

レンチで回せる方向の設定
これによると「ALL」「NONE」「Y_AXIS」「NON_Y_AXIS」が設定できるようです。
自分は自由に回せるほうがいいのでALLにしています。

1.rotationState(RotationState.ALL)

レシピタイプを設定
レシピタイプ名、ツールチップの使用、デフォルトGUIを使用
実はLDLib UI Editorをつかって完全にオリジナルのGUIも作成できるみたいだが、特にこだわりがなければデフォルトのGUIで問題ないと思います。

1.recipeType('planter', true, true)

液体が入る容量の設定

1.tankScalingFunction(tier => tier * 3200)

テクスチャ設定

MODで使用しているテクスチャはここにあります
https://github.com/GregTechCEu/GregTech-Modern/tree/1.20.1/src/main/resources/assets/gtceu/textures

1.workableTieredHullRenderer("gtceu:block/machines/compressor");

自分で用意すればオリジナルのテクスチャも可能です。
テスクチャのファイルは

1./kubejs/assets/kubejs/textures/block/machines/planter

のように置いて

1.workableTieredHullRenderer("kubejs:block/machines/planter");

のように指定します。

機械本体、機械を使ったのレシピを追加する

ここまで来たらあとは前回やった通り、レシピを追加するだけです。
レシピ追加の詳細はこちらを参照
レシピタイプを'planter'で登録したので.planterで呼び出せます。
機械本体のレシピも忘れずに

1./kubejs/server_scripts/planter.js

<例>

 1ServerEvents.recipes(event => {
 2    const greg = event.recipes.gtceu;
 3    greg
 4        .planter('gtceu:planter_1')
 5        .itemInputs('minecraft:wheat_seeds')
 6        .chancedInput('gtceu:fertilizer', 2000, 0)
 7        .inputFluids('minecraft:water 100')
 8        .itemOutputs('2x minecraft:wheat_seeds', 'minecraft:wheat')
 9        .duration(1200)
10        .EUt(2);
11})

langファイルを追加する

追加したブロックには表示する名前が設定されていないのでlang(言語ファイル)を追加する
ファイルは以下の場所

1./kubejs/assets/gtceu/lang/en_us.json
2./kubejs/assets/gtceu/lang/ja_jp.json

jsonファイルの内容は

 1{
 2    "block.gtceu.lv_planter":"Basic Planter", 
 3    "block.gtceu.mv_planter":"Advanced Planter", 
 4    "block.gtceu.hv_planter":"Advanced Planter II", 
 5    "gtceu.planter":"Planter"
 6}
 7// 日本語なら
 8{
 9    "block.gtceu.lv_planter":"基本型自動栽培機", 
10    "block.gtceu.mv_planter":"発展型自動栽培機", 
11    "block.gtceu.hv_planter":"発展型自動栽培機 II", 
12    "gtceu.planter":"栽培機"
13}

上はアイテム名
下はレシピタイプ名(JEIの上タブの部分)

ここまで来たら、あとはちゃんとテスクチャを用意すれば立派な自動栽培機、アドオンとして公開できるはずです。

サンプル

最終的にはこのようになりました。
GitHubに残しておきます。

1.\kubejs\startup_scripts\machines\planter.js  
2
3GTCEuStartupEvents.registry('gtceu:machine', event => {
4    event.create('planter', 'electric', GTValues.LV, GTValues.MV, GTValues.HV)
5        .rotationState(RotationState.ALL)
6        .recipeType('planter', true, true)
7        .tankScalingFunction(tier => tier * 3200)
8        .workableTieredHullRenderer("gtceu:block/machines/compressor");
9})
 1.\kubejs\startup_scripts\recipes\planter.js  
 2
 3GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
 4    event.create('planter')
 5        .category('test')
 6        .setEUIO('in')
 7        .setMaxIOSize(2, 2, 1, 0)
 8        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
 9        .setSound(GTSoundEntries.BATH)
10})
1
2.\kubejs\assets\gtceu\lang\en_us.json
3{
4    "block.gtceu.lv_planter":"Basic Planter", 
5    "block.gtceu.mv_planter":"Advanced Planter", 
6    "block.gtceu.hv_planter":"Advanced Planter II", 
7    "gtceu.planter":"Planter"
8}
 1.\kubejs\server_scripts\planter.js
 2
 3ServerEvents.recipes(event => {
 4    const greg = event.recipes.gtceu;
 5    // machine
 6    const tiers = [
 7        ['lv', 'steel'],
 8        ['mv', 'aluminium'],
 9        ['hv', 'stainless_steel'],
10    ];
11    tiers.forEach((tier) => {
12        event.shaped(
13            `gtceu:${tier[0]}_planter`,
14            [
15                'GGG',
16                'PHA',
17                'DDD'
18            ],
19            {
20                H: `gtceu:${tier[0]}_machine_hull`,
21                G: '#forge:glass',
22                P: `gtceu:${tier[0]}_electric_pump`,
23                A: `gtceu:${tier[0]}_robot_arm`,
24                D: '#minecraft:dirt',
25            }
26        )
27    });
28    // recipes
29    // seeds plant
30    const plantSeeds = [
31        ['minecraft:pumpkin_seeds', 'minecraft:pumpkin'],
32        ['minecraft:beetroot_seeds', 'minecraft:beetroot'],
33        ['minecraft:wheat_seeds', 'minecraft:wheat'],
34        ['minecraft:melon_seeds', 'minecraft:melon'],
35    ];
36    plantSeeds.forEach((plant) => {
37        greg
38            .planter(plant[0])
39            .itemInputs(plant[0])
40            .chancedInput('gtceu:fertilizer', 2000, 0)
41            .inputFluids('minecraft:water 100')
42            .itemOutputs(`2x ${plant[0]}`, plant[1])
43            .duration(1200)
44            .EUt(2);
45    });
46    // none seeds plant
47    const plants = [
48        'minecraft:sweet_berries',
49        'minecraft:glow_berries',
50        'minecraft:carrot',
51        'minecraft:sugar_cane',
52        'minecraft:kelp',
53        'minecraft:cactus',
54        'minecraft:brown_mushroom',
55        'minecraft:red_mushroom',
56        'minecraft:nether_wart',
57    ];
58    plants.forEach((plant) => {
59        greg
60            .planter(plant)
61            .itemInputs(plant)
62            .chancedInput('gtceu:fertilizer', 2000, 0)
63            .inputFluids('minecraft:water 100')
64            .itemOutputs(`2x ${plant}`)
65            .duration(1200)
66            .EUt(2);
67    });
68})