CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft

投稿日:2017年4月26日

皆さんこんにちは、伊達あずさです。
前回に引き続き、レシピ作成Mod「CraftTweaker(MineTweaker 3)」の解説とその使い方(特殊クラフト編)をお送りしたいと思います。
今回は前回よりもっと実用的なレシピ(アイテムの修理など)を作って行きますよ!
ちなみに、アイテムの内部名称さえわかればバニラ製品以外でもCraftTweaker(MineTweaker 3)で問題なく取り扱えますからね~
(CraftTweaker2(Minecraft 1.12~)では本記事に記載されている一部のレシピが正常に動作しない場合があります)

特殊クラフト編目次
  1. 材料の再利用とダメージ付与
  2. NBTタグを伴ったアイテムの作成とその利用法
  3. 完成品に材料の特性を継承する
  4. 繰り返しと内部名称の配列

材料の再利用とダメージ付与

今回は少し特殊なレシピの作成をご紹介したいと思います。
マインクラフトの世界では原木をクラフトすることで木材を得る事が出来ますが、斧と一緒に原木をクラフトした際、通常より多くの木材を得る事が出来るようにしてみましょう。
一先ずお試しでオークの木材を増やす事が出来る「新・オークの木材レシピ.zs」を作ってみましょう。

新・オークの木材レシピ.zsの記述
recipes.addShapeless(<minecraft:planks:0>*6, 
[<minecraft:stone_axe>, <minecraft:log:0>]);

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵1
これで石の斧と一緒にオークの原木をクラフトするとオークの木材が6つ作れるようになりました。

でも・・・
CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵2
このように石の斧が使用済みの場合、材料として使えません。
そこで、使用済みの石の斧も材料としてしようできるように改造してみましょう。

新・オークの木材レシピ.zsの記述(Ver. 2)
recipes.addShapeless(<minecraft:planks:0>*6, 
[<minecraft:stone_axe>.anyDamage(), <minecraft:log:0>]);

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵3
こんな感じで.anyDamage()を石の斧の内部名称の後ろにつけることで、使用済みの石の斧でもクラフトができるようになりました。

しかしながら、このクラフトを試みる度に石の斧が無くなってしまうのはちょっと割に合いませんね。
そこで、次は石の斧がクラフト後も無くならず返ってくるレシピに改造してみたいと思います。

新・オークの木材レシピ.zsの記述(Ver. 3)
recipes.addShapeless(<minecraft:planks:0>*6, 
[<minecraft:stone_axe>.anyDamage().reuse(), <minecraft:log:0>]);

石の斧の内部名称の後ろに「.reuse()」を付けることで、クラフト後も石の斧が失われなくなりました。
ここまで来ると、クラフトする度に石の斧の耐久度が減るようにしたくなってきますね。
そこで、クラフトすると石の斧の耐久度が100失われるように更なる改造を施してみましょう。

新・オークの木材レシピ.zsの記述(Ver. 4)
recipes.addShapeless(<minecraft:planks:0>*6, 
[<minecraft:stone_axe>.anyDamage().reuse().transformDamage(100), <minecraft:log:0>]);

更に「.transformDamage(100)」と付け加えることで、クラフト後の石の斧の耐久度が100減るようになりました。
しかしながら、このレシピにはちょっとした問題があるのです。
その問題を探るために、このレシピを使ってクラフトを繰り返してみましょう。

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵4
1回目のクラフトです。石の斧の耐久度が減ってますね。これは期待通り。

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵5
でもって、2回目のクラフト・・・あれ?何故か石の斧の耐久度が回復してしまっています。
そうなんです、transformDamageを使って耐久度を減らした場合、耐久度が0以下になると何故か耐久度が全快してしまうんですよね。
そこで、石の斧の耐久度が0以下になってしまうダメージが31以上(石の斧の耐久度131 – 100)の石の斧を素材として使った場合には石の斧が返ってこないようにしてしまいましょう。

新・オークの木材レシピ.zsの記述(Ver. 5)
recipes.addShapeless(<minecraft:planks:0>*6, 
[<minecraft:stone_axe>.anyDamage().onlyDamageAtLeast(31).noReturn(), <minecraft:log:0>]);
recipes.addShapeless(<minecraft:planks:0>*6,
[<minecraft:stone_axe>.anyDamage().reuse().transformDamage(100), <minecraft:log:0>]);

こんな感じで、ダメージが31以上ある石の斧の場合は素材が戻らないレシピを追加してみました。
素材にダメージ31以上という条件を追加しているのが「.onlyDamageAtLeast(31)」と言う部分です。
この他にも素材のダメージに関する条件指定法があって、「.onlyDamageAtMost(数字)」でダメージ31以下、「.onlyDamageBetween(数字1, 数字2)」でダメージが数字1から数字2の間なんていうものもあるみたいです。

素材のダメージ指定以外にも「.noReturn()」というのが初登場していますね。これは、使用後に自動的にリユースされるアイテム(バケツなど)をリユースさせないようにするためのもので、本来石の斧には敢えて指定する必要が無いはずだったのですが、次のレシピで石の斧に.reuse()を付けたことで石の斧がリユース対象に変わってしまったのか、.noReturn()と明示しないとリユースされてしまうのです。

尚、CraftTweaker(MineTweaker 3)では同じ条件のレシピがある場合、先に読ませたレシピが優先されるようなので、条件が厳しい方を必ず先に読ませてくださいね。

NBTタグを伴ったアイテムの作成とその利用法

さて・・・これで石の斧を使うことでオークの原木から得られる木材の量を増やせるようになったわけですが、木材を増やせる条件をもう少しだけ厳しくしてみましょう。

今までは石の斧を使って木材を増やせるようにしていましたが、木材を増やす専用の斧を作るレシピを作ってみましょう。
と言え、CraftTweaker(MineTweaker 3)では全く新しいアイテムを生み出すことはできません。
そこで、NBTタグを利用して、見た目も性能も石の斧と変わらないけど、アイテム名や説明文などがちょっと違う斧を作るレシピ「木工用斧.zs」を作ってみたいと思います。

木工用斧.zsの記述
recipes.addShapeless(<minecraft:stone_axe>.withTag({display: {Name: "木工用斧", Lore: ["木工用に再加工した斧", "原木からより多くの木材を得る事が出来ます"]}}),
[<minecraft:stone_axe>, <minecraft:cobblestone>]);

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵6
こんな感じで、新品の石の斧に対して追加で丸石を使うと作れるようにしてみました。

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵7
完成した木工用斧ポインタを当ててみると、アイテム名が石の斧から「木工用斧」に変わっていますし、ちゃんと説明文も追加されてますよね?
クラフト品にNBTタグを付与するには「.withTag()」を使用します。
.withTagは「{display: {Name: "アイテム名", Lore: ["説明文"]}}」と書くことでアイテム名や説明文を追加する事が出来ます。
尚、説明文は「,」区切りで列記すると改行することができます。
また、NameやLoreは省略することもできます。(Nameを省略した場合は元の名前のままになる)
あ!ここで1つ注意点!全角文字を使用する場合は必ずレシピファイルの文字コードを「UTF-8N」にしてください。
メモ帳でレシピファイルを編集していると自動的に文字コードが「Shift-JIS」になってしまうので、マインクラフト上で見ると文字が化けてしまうのです。
その場合は、文字コードを指定して保存できるテキストエディタ(TreaPadとか)を使うか、NBTタグの中身を半角文字にしてくださいね。
尚、MineTweaker 3ではNBTタグの全角文字が許可されていないみたいです。(CraftTweaker(for 1.7.10)ならOK)

さて、これでNBTタグを伴った斧を作る事が出来ましたが、このままでは普通の石の斧と何ら変わりません。
そこで、先ほど作った「新・オークの木材.zs」を更に改造して、この斧を使った時のみ木材を増やせるように書き変えます。

新・オークの木材レシピ.zsの記述(Ver. 6)
recipes.addShapeless(<minecraft:planks:0>*6, 
[<minecraft:stone_axe>.anyDamage().onlyDamageAtLeast(31).noReturn().onlyWithTag({display: {Name: "木工用斧"}}), <minecraft:log:0>]);
recipes.addShapeless(<minecraft:planks:0>*6, 
[<minecraft:stone_axe>.anyDamage().reuse().transformDamage(100).onlyWithTag({display: {Name: "木工用斧"}}), <minecraft:log:0>]);

こんな感じで両方のレシピに「.onlyWithTag()」を追加しました。こうすることで先ほど作った木工用斧でのみ木材を増やす事が出来るようになります。
試してみましょう。

普通の石の斧を使った場合
CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵8

木工用斧を使った場合
CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵9

まあ・・・この絵だと普通の石斧と木工用斧の差が見た目ではわからないのであまり良い絵ではありませんが、まあ、ちゃんとなりますからご安心を!!
ちなみに「.onlyWithTag」の中でも全角文字を使用する場合にはこちらのファイルの文字コードも「UTF-8N」にすることをお忘れなくです。

完成品に材料の特性を継承する

お次はいよいよ、アイテムを修理する(耐久度を回復する)レシピを作ってみたいと思います。
では、試しにみんな大好きダイヤのツルハシを使い道に乏しい火打石で研ぎ直して修理するレシピ「アイテム修理.zs」を作ってみましょう。

アイテム修理.zsの記述
recipes.addShapeless(<minecraft:diamond_pickaxe>,
[<minecraft:diamond_pickaxe>.anyDamage(), <minecraft:flint>]);

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵10
これで、こんな感じでダイヤのツルハシが火打石1つで修理できるようになりました。

でも・・・
CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵11
新品も修理できてしまうのは頂けない!!
というわけで、使用済みのダイヤのツルハシだけが修理対象となるようにレシピを修正します。

アイテム修理.zsの記述
recipes.addShapeless(<minecraft:diamond_pickaxe>,
[<minecraft:diamond_pickaxe>.anyDamage().onlyDamaged(), <minecraft:flint>]);

ダイヤのツルハシの内部名称の後に「.onlyDamaged()」を付けることで、ダメージを受けているアイテムのみ対象とする事が出来ます。
ちなみに、公式wikiだと「.onlyDamaged()」を単体で使えるかのように説明されているのですが、実際に試してみると上手く動作せず、「.anyDamage().onlyDamaged()」としないと期待通りに動いてくれません。不思議ですが仕方ない。

さ、これで修理レシピ完成!!!・・・とはいきません!!
ちょっと見てください!
CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵13
このレシピで修理すると、幸運Ⅲのエンチャントを付けたダイヤのツルハシが普通のダイヤのツルハシとして修理されてしまうんです。
これじゃ修理の意味が無い!(いや、ダイヤモンドが浮いてるから意味はあるんですが)
ちゃんと修理という体を保つためには、材料となっているアイテムの特性を完成品となるダイヤのツルハシに継承しなければならないのです。
というわけで、ちゃんと材料となっているダイヤのツルハシの特性が完成品のダイヤのツルハシに受け継がれる「真・アイテム修理.zs」を作ってみたいと思います。(先ほど作ったアイテム修理.zsは消します)

真・アイテム修理.zsの記述
recipes.addShapeless(<minecraft:diamond_pickaxe>,
[<minecraft:diamond_pickaxe>.anyDamage().onlyDamaged().marked("source"), <minecraft:flint>], function(argument1, argument2, argument3) {
	return argument2.source.withDamage(0);
});

このように書けば、材料として使ったダイヤのツルハシの特性を維持したまま修理することができるようになるのです。
では、今回追加した部分を1つずつ見ていきましょう。

まず、「function() { return }」ですが、ここでreturnされたアイテムが最終的に成果物として出てくるようになります。
つまり・・・「recipes.addShapeless(<minecraft:diamond_pickaxe>,」って最初に成果物の内部名称を書いているのですが、実際は使ってないということになります。
例えば、先ほどのレシピを・・・

recipes.addShapeless(<minecraft:iron_pickaxe>,
[<minecraft:diamond_pickaxe>.anyDamage().onlyDamaged().marked("source"), <minecraft:flint>], function(argument1, argument2, argument3) {
	return argument2.source.withDamage(0);
});

と変えたとしても、実は結果が変わらないのです。(ちゃんとダイヤのツルハシが出てきます)

「.withDamage()」というのは、アイテムのダメージ値を指定するもので、0を入れるとダメージ値が0、つまり完全修復されるということになります。

後、functionの中の引数ですが、これはとりあえず3つあることが大事です。
argument1には完成品の内部名称が、argument2は材料の内部名称が格納されているのですが・・・argument3には何が入ってるんでしょうね・・・
少なくとも 「return argument3;」とするとクラフトした瞬間にクラッシュしてしまうので、argument3は内部名称ではなさそうです。
まあ、詳しいことは私も良く分からないのですが、ともかくfunction()は3つ引数が無いとエラーになってしまうんです!

最後に「.marked("source")」ですが、これは、いわゆるラベルみたいなもんです。
完成品は1つですが、材料は複数ある場合があるのでこうやってラベルを張っておかないと、argument2だけでは期待しているアイテムを明示できなくなってしまうからですね。

これで火打石1つでダイヤのツルハシを完全回復させることができるようになりましたが、流石にこれはずる過ぎますか?
では、火打石1つで回復できる耐久度の量を限定してみましょう。
例えば火打石1つで50の耐久度を回復できるように先ほどのレシピを修正してみます。

recipes.addShapeless(<minecraft:iron_pickaxe>,
[<minecraft:diamond_pickaxe>.anyDamage().onlyDamaged().marked("source"), <minecraft:flint>], function(argument1, argument2, argument3) {
  return argument2.source.withDamage(argument2.source.damage - 50);
});

「argument2.source.damage – 50」この部分で耐久度の回復(ダメージ値の減少)を行っています。
う~ん・・・ダメージ値だけではなく耐久度(durability)を取得する方法が分かればなぁ・・・

ちなみにwithDamage()の値が範囲外(上の例だとマイナスになる場合)になっても、耐久度が限界値を超えたりはしないようなので、特に値のケアをする必要はなさそうです。
でも、逆にダメージ値を増やしたい場合は気にしないといけないかもしれません。
まずこんなレシピを作ることはないと思いますが・・・

recipes.addShapeless(<minecraft:diamond_pickaxe>,
[<minecraft:diamond_pickaxe>.anyDamage().marked("source"), <minecraft:flint>], function(argument1, argument2, argument3) {
  return argument2.source.withDamage(argument2.source.damage + 100);
});

こんな感じで火打石と一緒にダイヤのツルハシをクラフトすると、ダイヤのツルハシの耐久度に100のダメージを与えていくレシピを作ったとします。
このレシピを使ってダイヤのツルハシにダメージを与えていくと・・・
CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵14
こんな感じのあり得ない耐久度になってしまいます。(まあ、1回使えば普通に壊れるんですけどね)
それを防ぐために値にこんな感じで上限を決めることもできます。

recipes.addShapeless(<minecraft:diamond_pickaxe>,
[<minecraft:diamond_pickaxe>.anyDamage().marked("source"), <minecraft:flint>], function(argument1, argument2, argument3) {
  return argument2.source.withDamage(min(1560, argument2.source.damage + 100));
});

こうすれば、ダイヤのツルハシの耐久度が1561なので1561 – 1560 = 1ということになり、耐久度が1以下には減らないようになります。
このクラフトによって耐久度が1以下になった場合にダイヤのツルハシがなくなるようにするためには、新・オークの木材.zsを作ったときのように耐久度によってレシピを分岐させる必要があります。

今はminを指定しましたが、maxを指定することもでき、その場合はダメージの下限を決める事が出来るようになります。
「修理によって耐久度を回復させた場合は全快しないようにしたい!」何ていう場合には使えるかもしれません。
しかし・・・なんでminで上限、maxで下限なんでしょうね・・・ここだけ何故か耐久度視点になってますね。

繰り返しと内部名称の配列

遂にダイヤのツルハシを修理するためのレシピが完成したわけですが、今のままではダイヤのツルハシしか修理できません。
そこで先ほど作った真・アイテム修復.zsを修正してダイヤ製の武具や道具は全て修理できるようにしましょう。
とは言え、普通に追記してもつまらないので、ちょっと違った書き方をしてみます。

真・アイテム修理.zsの記述(最終形)
import minetweaker.item.IItemStack;

val repairableItem = [<minecraft:diamond_pickaxe>, <minecraft:diamond_axe>, <minecraft:diamond_shovel>, <minecraft:diamond_hoe>, <minecraft:diamond_sword>,
<minecraft:diamond_helmet>, <minecraft:diamond_chestplate>, <minecraft:diamond_leggings>, <minecraft:diamond_boots>] as IItemStack[];

for nowItem in repairableItem {
  recipes.addShapeless(nowItem, [nowItem.anyDamage().onlyDamaged().marked("source"), <minecraft:flint>], function(argument1, argument2, argument3) {
    return argument2.source.withDamage(argument2.source.damage - 50);
  });
}

こんな感じでしょうか。

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵15
これで、クワも・・・

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft_挿絵16
剣だって修理できるようになりました。もちろん防具もね!

ファイルの先頭(レシピや変数を書く前)に「import minetweaker.item.IItemStack;」と書くことで、以後、内部名称を配列にしたような変数(IItemStack[])を使用する事が出来るようになります。
そこで、repairableItemという変数を配列化し、そこに一気にダイヤ製品を定義してしまいました。
更にforを使ってrepairableItemの中で定義されている内部名称を1つずつnowItemに代入して、repairableItemの中身が無くなるまで繰り返す・・・みたいなレシピになってます。

ちなみに先ほどのレシピを

import minetweaker.item.IItemStack;

val repairableItem = [<minecraft:diamond_pickaxe>, <minecraft:diamond_axe>, <minecraft:diamond_shovel>, <minecraft:diamond_hoe>, <minecraft:diamond_sword>,
<minecraft:diamond_helmet>, <minecraft:diamond_chestplate>, <minecraft:diamond_leggings>, <minecraft:diamond_boots>] as IItemStack[];

for counter, nowItem in repairableItem {
  recipes.addShapeless(nowItem, [repairableItem[counter].anyDamage().onlyDamaged().marked("source"), <minecraft:flint>], function(argument1, argument2, argument3) {
    return argument2.source.withDamage(argument2.source.damage - 50);
  });
}

こんな感じに書き変えてもまったく同じ動作をします。
このレシピではあまり意味がありませんが、同じ長さの複数の配列を同時に処理したい場合には役立つかもしれませんね。

さて、今回は結構実用的なレシピをご紹介できたのではないでしょうか。
実はまだ他にもCraftTweaker(MineTweaker 3)を使って他Modの設定を変更したりすることも出来たりするのですが、物凄く長くなってしまったので、それはまた次回ということで。

この記事をもっと読む
Prev | Next

プレイ日記一覧へ

Studio POPPOをフォローしませんか?

CraftTweaker(MineTweaker 3)の解説とその使い方(特殊クラフト編):Minecraft」への15件のフィードバック

  1. すいか

    昔の記事に失礼します
    最近またこのmodの勉強を始める事となったのですが、それに当たって昔見つけたこちらの記事を参考にさせて頂きました
    お陰様で大助かりです、本当にありがとうございます
    そこで一つ質問なのですが、素材についているエンチャントを成果物に引き継がせる事ってできるのでしょうか?
    適当に斧を使って書いてみてはいるのですが、何度試しても中々上手くいかず……
    作業も難航しているために質問させて頂いた次第です

    ↓こちらが実際のコードになります↓

    import minetweaker.item.IItemStack;

    var myAxes &epuals; [<minecraft:wooden_axe>,<minecraft:stone_axe>,<minecraft:iron_axe>,<minecraft:golden_axe>,<minecraft:diamond_axe>] as IItemStack[];

    for Axes in myAxes {
    recipes.addShapeless(Axes,[Axes.anyDamage().marked("axe"),<minecraft:enchanted_book>],function(output,inputs,crafting){
    return output.withDamage(inputs.axe.damage).withTag({ench:[{id:inputs.axe.?,lvl:inputs.axe.?}]});
    });
    }

    ?には何を入れればいいのか全く分からず、本来の目的である"金床なしでエンチャントをする"ためのエンチャント本もただの素材としての意味しか持たないコードになってしまっています
    是非お知恵を借りられればと存じますが、如何でしょうか?(htmlの方は初めてですので、文字が消えてしまっていたら申し訳ございません)

    また、今回のこのコードの場合では入出力のアイテムが共通していますが、実際は
    recipes.addShaped(<minecraft:diamond_sword>,
    [[<minecraft:diamond>],
    [<minecraft:diamond>],
    [<minecraft:iron_sword>]]);
    このような形で素材とは別のアイテムを出力し、それに素材としたアイテムのエンチャントを引き継がせたいと考えてます、可能でしょうか……?

    エンチャント本のタグである{StoredEnchantmens:}に使用されるidやlvlは恐らく{ench:}と共通していますので、この問題が解決すればエンチャント本のエンチャントを、元々あったエンチャントを継承したまま、素材にそれを追加した状態で出力できると思うのですが……

    長々とすみません、ご拝読ありがとうございました

    返信
  2. k1ri3me

    とても分りやすい説明のおかげで
    私みたいな初心者でも出来ました…ありがとうございます!

    で、一つ質問をさせて頂きたいのです。
    木の斧で説明されていたNTBタグを使うことで、名称や説明以外に、攻撃力・エンチャントなどを追加することは可能でしょうか?
    一時間ほどいじってみて駄目だったので…
    もし可能であれば簡単な例を教えていただけるとありがたいのです…

    返信
  3. じゃぱりまん

    こんにちわ。とても参考になるCraftTweakerの記事ありがとうございます。
    私は水バケツに関するレシピ追加をしようとしたとき.reuse()を付けていたのですが、
    ログに「そんなもんねーよ」という旨の英語が表示されました。
    CraftTweakerのバージョンはCraftTweaker2-1.12-4.0.12です

    返信

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください