Minecraft Kotlinプラグイン開発 中級編 Part.2 チェストGUIの作成

## 初めに
今回はチェストを使ったGUIを作成していきます。
チェストGUIはバニラのコマンドだけだと作るのが難しく、プラグインの利点なので
沢山活用していきましょう！

**前** → [中級編 Part.1 コマンドの引数の設定](https://qiita.com/tooooowa/items/e823499575c6500f2ab5)
**次** → [中級編 Part.3 GUIのクリック検知](https://qiita.com/tooooowa/items/9df53fea8ced007765b4)

**目次** →  [目次と今後の展望](https://qiita.com/tooooowa/items/7809ec65dee757570250)

## /guiコマンドをplugin.ymlに登録
`/gui`というコマンドで新しく`plugin.yml`に登録します。
また新しく今までのコマンドの下に登録していきます。
```plugin.yml
name: TutorialPlugin
version: '${version}'
main: com.github.tooooowa.tutorialplugin.TutorialPlugin # ここは環境によって異なります
api-version: '1.20'
commands:
  debug:
    usage: "/debug"
    description: "デバッグ用のコマンドです"
    permission: tutorialplugin.commands.debug
  sum:
    usage: "/<command> <number> <number>"
    description: "足し算用のコマンドです"
  gui: # ここから下に新規追加
    usage: "/<command>"
    description: "チェストGUIを開きます"
```
今回は特に引数を持たせないためusageは `/<command>`だけで十分です。

## オブジェクトを作成
コマンドが実行された時に呼び出される関数を用意します。
メインクラスと同じ階層に前回と同じようにオブジェクトを作成します。
ファイルの名前は`GuiCommand.kt`で作成しました。

ファイルが今回は大きくなるので全て合わせたコードは最後に表示します。
それまでは所々コードを解説していきます！
```GuiCommand.kt
// この上にimportやobjectの文があります
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
    if (sender !is Player) {
        return false
    }
    val inventory = Bukkit.createInventory(sender, 9*3, "§bメニュー")
    // 木の下にインベントリのアイテムの処理の追加

    sender.openInventory(inventory)
    return true
}
// この下に}あり
```
まずは上のように新規オブジェクトに書きました。
一つずつ解説していきます。
```kotlin
if (sender !is Player) {
    return false
}
```
これは`sender`(実行者)が`Player`(プレイヤー)じゃない時に
`return false`(処理終了)するという処理です。
この`return`は`false`の時にコマンド実行失敗、`true`の時に実行成功として返します。

```kotlin
val inventory = Bukkit.createInventory(sender, 9*3, "§bメニュー")
```
この行では`inventory`という変数に3行のインベントリを入れています。
`Bukkit.createInventory()`関数では引数1に相手、
引数2にスロット数(9の倍数)、引数3にはインベントリの名前を入れます。

:::note warn
エラーを防ぐために引数2は `9*[行数]` で書くのがおすすめです
:::

```kotlin
sender.openInventory(inventory)
```
これは`sender`が変数(`inventory`)に保存されてるインベントリを開くという関数です。

## plugin.ymlにてコマンドの登録
この状態で動作確認のために一度実行してみます。
そのためにメインクラスのonEnableでコマンドの登録を行います。

前回のからコピペで少しだけ変更を加えました。
```TutorialPlugin.kt
// この上にimportやobjectの文があります
package com.github.tooooowa.tutorialplugin

import org.bukkit.plugin.java.JavaPlugin

class TutorialPlugin : JavaPlugin() {
    override fun onEnable() {
        // Plugin startup logic
        server.pluginManager.registerEvents(EventListener, this)
        getCommand("debug")?.setExecutor(DebugCommand)
        getCommand("sum")?.setExecutor(SumCommand)
        getCommand("gui")?.setExecutor(GuiCommand) // この行を新たに追加
    }

    override fun onDisable() {
        // Plugin shutdown logic
    }
}
// この下に}あり
```
## 試しに実行
試しにビルドしてサーバーに実装し、`/gui`を実行してみます。
すると画像のようなGUIが出てきます。
今回はこれにアイテムを入れていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/dbf09074-d897-948b-f6ca-dad0b929e4bc.png)

## インベントリにアイテムを設置
さっきの`GuiCommand.kt`を開きGUIの中に入れるアイテムを追加していきます。
```GuiCommand.kt
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
    if (sender !is Player){
        return false
    }
    val inventory = Bukkit.createInventory(sender, 9 * 3, "§bメニュー")
    
    // スロット12番 ダイヤモンド
    val diamond = ItemStack(Material.DIAMOND, 1)
    val diamondMeta = diamond.itemMeta
    diamondMeta?.setDisplayName("§b青い宝石")
    diamond.itemMeta = diamondMeta
    inventory.setItem(12, diamond)

    sender.openInventory(inventory)
    return true
}
```
ダイヤモンドをスロット番号12番に入れます。

:::note warn
プラグインでのスロット番号は左上を0として数えだします。
:::

```kotlin
val diamond = ItemStack(Material.DIAMOND, 1)
```
この行で`diamond`という変数に1つの`diamond`を保存しています。
ここの`ItemStack`の引数1の`Material.DIAMOND`の
`DIAMOND`はマイクラのアイテムIDを指しています。
アイテムIDが分からない場合は[コチラ](https://minecraft-ids.grahamedgecombe.com/)のサイトを確認しましょう。
引数2はアイテムの数を指定します。
```kotlin
val diamondMeta = diamond.itemMeta
diamondMeta?.setDisplayName("§b青い宝石")
diamond.itemMeta = diamondMeta
```
この3行では`diamond`のアイテムのメタデータを`diamondMeta`に保存し、
その後そのメタデータのアイテム名を編集して、
それをまた`diamond`のメタデータに更新しています。

このアイテムのメタデータを変数へ移した後に、
データを変更し、またアイテムに戻す作業はよく行うので覚えておきましょう。

## エメラルドも追加
同じことをもう一度繰り返し、エメラルドも追加します。
最終的に以下のコードになりました。
```GuiCommand.kt
package com.github.tooooowa.tutorialplugin // この行は環境によって異なります

import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack

object GuiCommand: CommandExecutor {
    override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
        if (sender !is Player){
            return false
        }
        val inventory = Bukkit.createInventory(sender, 9 * 3, "§bメニュー")

        // スロット12番 ダイヤモンド
        val diamond = ItemStack(Material.DIAMOND, 1)
        val diamondMeta = diamond.itemMeta
        diamondMeta?.setDisplayName("§b青い宝石")
        diamond.itemMeta = diamondMeta
        inventory.setItem(12, diamond)

        // スロット14番 エメラルド
        val emerald = ItemStack(Material.EMERALD, 1)
        val emeraldMeta = emerald.itemMeta
        emeraldMeta?.setDisplayName("§a緑色の宝石")
        emerald.itemMeta = emeraldMeta
        inventory.setItem(14, emerald)

        sender.openInventory(inventory)
        return true
    }
}
```
## デバッグ
これをサーバーに入れて、コマンドを実行してみます。
以下のように表示されれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/7a015f58-c487-2019-7075-090fb1634c19.png)
## 終わりに
今回はチェストを使用したGUIの作り方を勉強しました。

次回はこれを使用して、GUIのアイテムをクリックしても取れなくしたり、
クリックしたら何らかのコマンドが実行されるようにしてみます。

**前** → [中級編 Part.1 コマンドの引数の設定](https://qiita.com/tooooowa/items/e823499575c6500f2ab5)
**次** → [中級編 Part.3 GUIのクリック検知](https://qiita.com/tooooowa/items/9df53fea8ced007765b4)

**目次** →  [目次と今後の展望](https://qiita.com/tooooowa/items/7809ec65dee757570250)

## 参考
[https://www.youtube.com/watch?v=hPzg4tXcu5I](https://www.youtube.com/watch?v=hPzg4tXcu5I)
[https://www.youtube.com/watch?v=MenxQ76Weho](https://www.youtube.com/watch?v=MenxQ76Weho)