[Java]MinecraftのModを作成しよう 1.14.4【6. レシピの追加】

（この記事は一連の解説記事の一つになります）

先頭記事：[入門編](https://qiita.com/koteko/items/7afadf8261eac49bacad)
前の記事：[5. 防具の追加](https://qiita.com/koteko/items/34e6cb63288cd30571b5)
次の記事：[7. 進捗の追加](https://qiita.com/koteko/items/43c02b25b39e6a2a061d)

# レシピの追加
さて、[1. アイテムの追加](https://qiita.com/koteko/items/76910dbf9eb126bdfdf9)、[2. ブロックの追加](https://qiita.com/koteko/items/c904b3bfdd90f0b9a98a)、[4. ツールの追加](https://qiita.com/koteko/items/0c3a73d1ed299cfbde02)、[5. 防具の追加](https://qiita.com/koteko/items/34e6cb63288cd30571b5)と各種アイテムを追加してきましたが、これらをクラフトするレシピがまだありません。今回はいくつかのパターンのレシピを追加していきます。
1.14.4においてレシピの追加はコードを書く必要はなく、jsonベースで追加できます。

## 定型レシピ
例えば剣のレシピを追加してみましょう。

```
\src\main\resources
   ├ assets
   └ data
      └ example_mod
         ├ loot_tables
         └ recipes
            └ example_sword.json
```
`\src\main\resources\data\recipes`フォルダを作り、その中にレシピファイルを配置します。

```json:example_sword.json
{
  "type": "minecraft:crafting_shaped",
  "pattern": [
    "#",
    "#",
    "X"
  ],
  "key": {
    "#": {
      "item": "example_mod:example_ingot"
    },
    "X": {
      "item": "minecraft:stick"
    }
  },
  "result": {
    "item": "example_mod:example_sword"
  }
}
```
`type`に`minecraft:crafting_shaped`を与えることで、定型レシピを作ることができます。定型レシピとはすなわち、素材の配置が決まっているクラフトのレシピです。
`key`で任意のトークン(ここでは#とXですが、何でもよいです)と対応するアイテムを決定し、このトークンを用いて`pattern`に3×3以下の行列のような形で配置を決定します。
`result`にクラフトの結果得られるアイテムを指定します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256627/b3111170-b298-6d6b-ae29-770dea225d47.png)
剣が作れるようになりました。
この例では素材の配置に1列しか使っていないため、図のようにどの位置で縦に並べても作ることができます。
半角空白で「何もない」を示すので、明示的に以下のようにしてもいいですが、この場合でも左あるいは右の縦1列でも作れるようになるようです。

```json:
  "pattern": [
    " # ",
    " # ",
    " X "
  ]
```

## 不定形レシピ
次に素材の配置に指定のない不定形レシピを追加してみましょう。
例としてはやや不適ですが、ブロック2つからインゴット18個に分解するレシピを考えてみます。

```
\src\main\resources
   ├ assets
   └ data
      └ example_mod
         ├ loot_tables
         └ recipes
            └ example_ingot.json
```

```json:example_ingot.json
{
  "type": "minecraft:crafting_shapeless",
  "ingredients": [
    {
      "item": "example_mod:example_block"
    },
    {
      "item": "example_mod:example_block"
    }
  ],
  "result": {
    "item": "example_mod:example_ingot",
    "count": 18
  }
}
```
`type`に`minecraft:crafting_shapeless`を与えることで、不定型レシピを作ることができます。
`ingredients`は材料の配列で、ここにクラフトに使うアイテムを列挙します。
`result`は定型レシピ同様です。`count`で個数を指定できます(デフォルト1のため前項では省略していました)。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256627/5f636192-74a1-7d6f-3a41-d2b6d9812997.png)
任意の配置からインゴットが得られました。

## 精錬レシピ
続いてかまどによる精錬のレシピを追加します。例えば、ダイヤモンドを精錬したらインゴットが得られるようにしましょう。

```
\src\main\resources
   ├ assets
   └ data
      └ example_mod
         ├ loot_tables
         └ recipes
            └ furnace
               └ example_ingot.json
```
(`recipes`以下のファイルは全部登録してくれるようなので、多分フォルダ構成やファイル名は自由でいいと思います。)

```json:example_ingot.json
{
  "type": "minecraft:smelting",
  "ingredient": {
    "item": "minecraft:diamond"
  },
  "result": {
    "item": "example_mod:example_ingot"
  },
  "experience": 3.0,
  "cookingtime": 200
}
```
`type`に`minecraft:smelting`を指定して精錬レシピを追加します。
`ingredient`(**単数なので注意**)は材料、`result`が精錬後のアイテムです。
`experience`は精錬で得る経験値、`cookingtime`は精錬時間です。ちなみにバニラの鉄がそれぞれ0.7, 200です。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256627/104d6f0b-281e-ef2e-36e9-2ff87e877f7b.png)
精錬できました。

# 発展
Q. レシピブックに出てないんだけど？
**A. 一度作れば載ります。先に乗せたい場合advancements(実績)にかかわる部分で手を加える必要があります**が、まだ私も学習していないので、後に追記できればと思います。
___
Q. 複数の素材から同じアイテムを作りたい
**A. 3つの解決法があります。**
1つ目は単純にレシピのjsonファイルをその数だけ作る方法です。推奨しません。
2つ目は`key`あるいは`ingradient`にアイテムを複数渡す方法です。

```json:Xの位置はstickかoak_woodのどちらか
{
  "type": "minecraft:crafting_shaped",
  "pattern": [
    "#",
    "#",
    "X"
  ],
  "key": {
    "#": {
      "item": "example_mod:example_ingot"
    },
    "X": [
      {
        "item": "minecraft:stick"
      },
      {
        "item": "minecraft:oak_wood"
      }
    ]
  },
  "result": {
    "item": "example_mod:example_sword"
  }
}
```


```json:材料はdiamondかgold_ingotのどちらか
{
  "type": "minecraft:smelting",
  "ingredient": [
    {
      "item": "minecraft:diamond"
    },
    {
      "item": "minecraft:gold_ingot"
    }
  ],
  "result": {
    "item": "example_mod:example_ingot"
  },
  "experience": 3.0,
  "cookingtime": 200
}
```
(`shapeless`なレシピについてはこの手法が使えるか不明でした。使えなさそう？)

3つ目は`tag`を使う方法です。例えばバニラの木炭などは、あらゆる種類の原木から１つのアイテムをクラフトしています。以下にコードを示します。

```json:charcoal.json
{
  "type": "minecraft:smelting",
  "ingredient": {
    "tag": "minecraft:logs"
  },
  "result": "minecraft:charcoal",
  "experience": 0.15,
  "cookingtime": 200
}
```
このタグは`net\minecraft\tags\BlockTags.java`で宣言されています。もちろん自分で新しいタグを定義することも可能なので、代替可能な素材をまとめたタグを作り、それを使ってレシピを定めるのはよい方法でしょう。
___
Q. バニラのレシピを改変したい
**A. 追加は容易です。変更は困難。**
つまり、A→Bのクラフトに対して、C→Bを追加することは簡単ですが、A→Dのクラフトに変更することは難しいです。前者は単に新しくレシピを追加すればバニラのものと共存しますが、後者は同じ素材からなるレシピを追加してもどうやらバニラのほうが優先されるようです。そのため、レシピを登録するコードの方までさかのぼって手を加える必要がありそうです。
___
Q. 醸造のレシピを作りたい
恐らくですが、醸造のレシピについては上記のようなjsonベースの追加ができません。([参考](https://forums.minecraftforge.net/topic/78232-fixed-1144-custom-brewing-recipes/))

# 参考
[Recipes - Forge Documentation](https://mcforge.readthedocs.io/en/latest/utilities/recipes/)
[Minecraft 1.14.4 Forge Modの作成 その9 【レシピの追加】](https://qiita.com/Hiroya_W/items/e096fcd4be90da7e24cb)

# 次の記事
[7. 進捗の追加](https://qiita.com/koteko/items/43c02b25b39e6a2a061d)