CraftTweakerの構文メモ

MineCraftのMODのお話

目次

はじめに

MineCraftのMOD、CraftTweakerの解説記事です。
CraftTweakerとはレシピなどをスクリプトで書き換えることができるMODです。
スクリプトはZenScriptというものですが、日本語で構文の説明までかかれているものがあまりなかったので記事にしようかなとました。自分のメモのためにも。
超初歩的なことは他の方がすでに書かれているのでここでは書きません。

  • この情報はMinecraft 1.12、CraftTweaker2-1.12-4.1.20.646.jar時点での情報です。最新のバージョンでは異なる箇所があるかもしれません。
  • 説明のために日本語で書いていますが、実際にスクリプトを書くときは日本語をいれることはできません。(コメント含む)

1.12ではリロードコマンドはない

昔はリロードコマンドがあり、修正したスクリプトをすぐに反映できていましたが、現在のバージョンではなくっています。
これはCurseの仕様らしいので今後このコマンドが実装されることもありません。
おとなしく再起動して反映させてください。

varとvalの違い

CraftTweakerでは変数の宣言には二種類あります。

  • varは一度設定しても値を変更することができます。
  • valは一度設定したら値を変更することはできません。

CraftTweakerではvalは定数と思ってもらって構いません。途中で変えてほしくない場合に使います。
実際に使う場面として、最初によく使うアイテムを予め宣言しておきたいときに使います。

1val certusQuartzDust = <appliedenergistics2:material:2>;
2
3//certusQuartzDustを使った処理を書く
4
5//間違ってセットしようとしてもエラーになるので間違いに気づく
6certusQuartzDust = <appliedenergistics2:material:1>;  // error

逆にそれ以外はvarで構いません。
初歩的なミスですが、varは再設定は可能ですが同じ変数名を二回宣言することはできないので注意。

1var str = "Count1";
2// 値を変えたい場合はこのように変える
3str = "Count2";
4// 二回目の宣言はNG
5var str = "Count3"; // error

配列を使用してループさせる

CraftTweakerには配列が用意されていてこれをForやWhileで回すことができます。

実は配列自体は、最初のレシピ登録のときから知らず知らずにつかっています。あのレシピ追加の[]は変数に入れずに直接入れているのです。

わざわざ変数にいれて配列を使用する場合はループ処理をしたいときです。 最初にimport crafttweaker.item.IItemStackを宣言して配列を使えるようにします。 配列の書き方は

1import crafttweaker.item.IItemStack;
2
3var 変数名 IItemStack[] = [
4    item, // 配列に入れる要素
5    item,
6    item,
7];

そしてループさせるときはfor文を使います。これは他の言語のforeachに当たるもので、配列内の要素を全て反復処理を行います。

1for 配列内の要素 in 配列の変数名{
2    // ループさせたい内容
3}

またカウンタを使って他の言語のforに当たる処理も行えます
配列の変数名[i]として要素にアクセスできるけどそれなら上記の方法がいいです。
こちらは単純に指定した回数分ループさせるときに使います。

1for i in 0 to 9{
2    // 10回ループする処理
3}

最後に実際の例
<例> 木材製ツールの耐久度を5にする

 1import crafttweaker.item.IItemStack;
 2
 3// Create an array
 4var vanillaTools as IItemStack[] = [
 5	<minecraft:wooden_sword>,
 6	<minecraft:wooden_shovel>,
 7	<minecraft:wooden_pickaxe>,
 8	<minecraft:wooden_axe>,
 9	<minecraft:wooden_hoe>,
10];
11
12// Loop the array
13for tool in vanillaTools {
14	tool.maxDamage = 5;
15	tool.addTooltip(format.darkRed("Use craft material only. Durability is only 5"));
16}
  • Whileループもありますが、これは無限ループに陥りやすいので使わないほうが無難です。
  • 2次配列にすることも可能ですが、ループ目的でやる場合は次の連想配列を使用しましょう。

連想配列を使用する

連想配列は他の言語だとMapやDictionaryともいわれます。
配列を2つ用意して同じような処理は可能ですが、こちらはセットになっているのでわかりやすいし、処理も早いです。

イメージとしてはこんな感じ

1//配列を2つ用意する
2id[] = [1, 2, 3]
3value[] = ["石", "草", "土"]
4
5//連想配列
6Dic = { (1,"石")
7        (2,"草")
8        (3,"土")
9    }

このidとなる部分は重複させることはできません。

import crafttweaker.item.IIngredientを追加してIItemStackの中に入る型をIIngredientとして宣言しておきましょう。

CraftTweakerでよくある使い方としてクラフトの形は決まっていて、素材で完成品が変わるものに使います。

1import crafttweaker.item.IItemStack;
2import crafttweaker.item.IIngredient;
3
4var 連想配列の変数名 as IItemStack[IIngredient] = {
5	素材1 : 完成品1,
6	素材2 : 完成品2,
7    etc.
8	};

と連想配列を作成していれば

1for 素材, 完成品 in 連想配列の変数名 {
2    recipes.addShaped(完成品,[
3        [素材, null, 素材],
4        [null, <ore:ironIngot>, null],
5        [素材, null, 素材]
6        ]);
7	}

という風にかけます。
具体的な例を記載します。
<例> ThermalFoundationのギアのレシピ追加

 1import crafttweaker.item.IItemStack;
 2import crafttweaker.item.IIngredient;
 3
 4var newGearRecipes as IItemStack[IIngredient] = {
 5	<ore:ingotIron> : <thermalfoundation:material:24>,
 6	<ore:ingotGold> : <thermalfoundation:material:25>,
 7	<ore:gemDiamond> : <thermalfoundation:material:26>,
 8	};
 9
10for material, gear in newGearRecipes {
11    recipes.addShaped(gear,[
12        [material, null, material],
13        [null, <ore:ingotIron>, null],
14        [material, null, material]
15        ]);
16	}

これで、鉄と金とダイアのギアのレシピが追加されました。

バニラに近い環境だと余り出番が少ないかもしれませんが、工業MODで金属がたくさんあるときなんかでこれがあると便利です。

文字の連結

文字の連結は~で行うことができます。
例として鉄、金、銅、錫、ブロンズに"Metal ingot"というツールチップを追加します。

 1var materialNames as string[] = [
 2	"Iron",
 3	"Gold",
 4	"Copper",
 5	"Tin",
 6	"Bronze",
 7	];
 8
 9for material in materialNames {
10    //"ingotIron","ingotGold" ... と取得している
11    oreDict["ingot"~material].addTooltip(format.darkRed("Metal ingot"));
12	}

If文

条件分岐です。
レシピを作成するという性質上CraftTweakerでIf使うことは少ないかもしれませんが一応つかえます。

1if (条件式) { 
2    // trueの処理
3} else {
4    // falseの処理 elseはなくてもいい
5}

演算子は以下の通りです。

演算子

演算子 意味
! Not。trueとfalseを反転 !(条件) //~ではない
!= 前後の値が等しくないかを評価 1 !=2 // true
== 前後の値が等しいかを評価 1 ==1 // true
&&, & AND。 2個書くと短絡評価 true && true // true
||, | OR。2個書くと短絡評価 true || false // true
> , >= 前の値が後ろの値より大きい(以上)かどうかの評価 2 > 1 // true
<, <= 前の値が後ろの値より小さい(以下)かどうかの評価 1 <= 2 // true
  • 短絡評価とはANDやORで、後の評価をせずとも前の評価で結果が決定してしまっている状態のとき、後の評価をせずしないことです。普通はこの短絡評価のほうを使います。
1// 1 == 1の条件式がtrueなため、1 == 2を条件式を見ずにtrueの処理を行います。
2if ( (1 == 1) || (1 == 2)) { 
3    // trueの処理
4}

数値計算

これもあまり使うことはないかもしれませんが、一応

数式演算子

これはいたって普通、+=と書けば代入演算子もできます

演算子 意味
+ 加算
- 減算
* 乗算
/ 除算
% 剰余

一番を気をつけないといけないときは小数点がある計算です。
例えば以下のように11/5.5をして余りを出す場合です。
下記を見ると一見0が表示されるように思えます。
しかし結果は1となります。

1var result = 11 % 5.5;
2print(result);

これは1番目の値の型で計算をしているためです。
つまり

1//略さず書くと
2var result = (11 as int) % (5.5 as int);
3//つまりパソコンが計算しているのは
4var result = 11 % 5;

となってしまいます。
なので、小数点を使う場合は必ず型をつけてあげましょう。
以下の場合は0.0となります。

1var result = 11 as double % 5.5;
2print(result);
3//パソコンは11.0%5.5の計算している

エラー集

crafttweaker.logのログを見れば大抵のエラーは分かります。
エラーになっている行が出ているのでその周辺を見直してください。

随時追加予定

エラー 意味
-- ; expected ;をつけ忘れてる