マイクラのコマンドで作る「最強」について考える【後編】

この記事は、[Minecraft Command Advent Calendar 2024](https://qiita.com/advent-calendar/2024/mccmd) 十六日目の記事です。

# はじめに：この記事について
題にもあるように、この記事は『[マイクラのコマンドで作る「最強」について考える【前編】](https://qiita.com/firgde/items/dcb7d2fd75b5ec61ba46)』の続きです。こちらを先に読んでいただいた方が内容を追いやすいでしょう。

さて、前回の記事では、アイテムのデータを編集をして攻撃力が法外に高い剣を作りました。バニラのMinecraftに登場するモブは全て一撃で倒せるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/20f6fbf5-6390-2514-abbb-119986e8ceef.png)
▲ 攻撃力を2048に設定したネザライトの剣

![warden.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/df4b9e43-f83d-db6a-9c40-36046ca817b8.gif)
▲ 一撃で倒されるウォーデン
<br></br>
しかし、同じくコマンドで体力や防御力を編集したモブに対してはどうでしょう。

![zombie.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/027d1187-1da0-0689-ecbe-ca7b5043d073.gif)
▲ 耐性レベル5を持つゾンビ。与えられたダメージの100%を軽減している

例え相手が実質無敵に設定されていても、「<font color=limegreen>殴れば倒せる最強の剣</font>」を作っていきましょう。

# 0. 前提
まず大前提として、この記事は<font color=red>**Minecraft Java Editionのバージョン1.21.3および1.21.4**</font>向けに書いています。この意味がわからない、という場合は[こちら](https://qiita.com/firgde/items/dcb7d2fd75b5ec61ba46#0-%E5%89%8D%E6%8F%90)を読んでみてください。

また、前回の記事で紹介した、<font color=limegreen>コマンドの基本的な考え方と書き方</font>は把握している前提で話を進めていきます。

# 1. 考えをまとめる
### 絶対に倒すコマンド
最初に決めたように、これから作る剣は、敵の体力や防御力に関係なく、必ず一撃で倒せるようにしたいです。まずは、そのために必要なものは何か、考えてみましょう。
アイテムのデータで、攻撃力以外で攻撃時の処理に介入する設定はなさそうです。
では、逆に<font color=limegreen>必ずモブを倒す処理から</font>考えてみましょう。「モブを倒すコマンド」、ご存知なのではないでしょうか。

そう、```/kill```です。モブに対して、Minecraftの「倒れる」処理を実行するので、どれだけゲームの設定で耐久力を高くしても、```/kill```を使えば文字通り<font color=limegreen>どのようなモブでも必ず一撃で</font>倒せます。

### ターゲットセレクターの拡張
```/kill```の構文は単純に```/kill```<font color=skyblue>```<倒したい対象>```</font>となります。スポーンエッグなどでゾンビを出し、試してみましょう。
```:<font color=skyblue>最寄りのゾンビ</font>を倒すコマンド
/kill @n[type=minecraft:zombie]
```
セレクターが<font color=skyblue>```@n```</font>になっていて、さらに```[ ]```が続いています。<font color=skyblue>```@n```</font>は、シンプルに「最寄りのエンティティ」を指定しています。```[ ]```は、アイテムコンポーネントと同じく、そのエンティティが持つ要素を細かく設定して、セレクター単体では絞り込み切れない条件を作ります。

### 無敵のゾンビ
ついでに、ゾンビを無敵にする方法も紹介します。もう一度ゾンビを出して、次のコマンドを実行してください。
```:耐性エフェクトレベル5
/effect give @n[type=minecraft:zombie] minecraft:resistance infinite 5
```
```/effect```コマンドです。このコマンドは、<font color=skyblue>指定したモブ</font>に<font color=darkkhaki>ステータスエフェクト、つまりポーション効果</font>を<font color=gray>変更する</font>コマンドです。サブコマンドに```give```と```clear```、付与するか除去するかの二種類があります。対象を指定したあとには、<font color=darkkhaki>付与するエフェクトのID</font>と<font color=lime>効果時間</font>、そして<font color=magenta>エフェクトのレベル</font>が続きます。効果時間の欄には「無限」を意味する```infinite```と書くことで、そのエフェクトが永続するようになります。

::: note info
#### エンティティとは（読み飛ばし可）
簡単にいって「アイテムでも、ブロックでもない、データの集まり」です。つまりはモブのことなのですが、防具立てや額縁のようなブロックとモブの境界線上にあるものも含みます。
[Minecraft Wiki](https://ja.minecraft.wiki/w/%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%83%86%E3%82%A3)によると、全てのエンティティは以下の性質を持っているようです。
> -    (通常のニュートン力学に従った) 位置、速度、回転。
> - 決まった高さと幅をもつ3次元のボックスで表される、エンティティが占める固有の体積 (真上から見ると正方形であり、回転していない)。
> - 現在の体力。
> - 炎が着いているかどうか。炎は徐々に体力を減らし、エンティティを包むように火が表示される。

少し難解ですが、この定義に沿うと、ボートや地面に落ちているアイテム、エンドクリスタルなどもエンティティであることが分かります。
:::

### ここからは...
これで、どのようなモブでも条件を絞って倒せるようになりましたが、剣で攻撃したタイミングに、そして攻撃した相手に、この処理を実行するにはどうすればようでしょうか。

# 2. コマンドブロック
### お待ちかねの
要は、<font color=limegreen>チャット欄を開かずとも、各手順のコマンドを連続して実行</font>したいわけです。そのために作られたブロック、ありましたよね。
```:満を持して登場、<font color=darkkhaki>コマンドブロックを出す方法</font>
/give @s minecraft:command_block 1
```
```/give```を使いましたが、実はコマンドブロック、クリエイティブモードのインベントリにもあります。メニュー画面から<font color=limegreen>操作設定</font>を開きましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/eab9fb55-8287-dfa2-d275-c9c792f05cc5.png">
▲ 操作設定のタブ

なぜ操作設定なのかは謎ですが、<font color=limegreen>管理者用アイテムタブ</font>とあります。オンにして、インベントリを開いてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/ef735585-d129-7dab-0842-df964be6860f.png)
このようなタブがあるでしょう。ここから、コマンドブロックを含む各種開発用アイテムいつでもが取り出せます。覚えておきましょう。

### コマンドブロックのつかいかた
では、コマンドブロックを使っていきましょう。設置して、UIを開いてみると、このような画面になりますね。
![command_block.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/b7c483fc-7f4a-ab18-1d16-dde94b3b094d.png)
なにやら複雑そうな見た目です。しかし、とりあえず気にする必要があるのは一番上の<font color=limegreen>コンソールコマンド</font>の欄のみです。ここにコマンドを入力すれば、コマンドブロックがそのコマンドを保存して、レッドストーン信号を与えればいつでも実行できる状態になります。試しに、前回の記事で取り扱ったコマンドを入力して実行してみましょう。
```:「最強の剣」を与えるコマンド
/give @s minecraft:netherite_sword[minecraft:attribute_modifiers=[{type:"attack_damage",id:"my_modifier",amount:2048,operation:"add_value"}]]
```
![selector.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/dd78a34a-48df-e88b-a5eb-d872f1ecad22.gif)

...何も起きません。コマンドブロックをもう一度開くと、<font color=limegreen>前回の実行結果</font>が表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/9a9def4b-6c90-aa9e-3370-bb43e2d7311e.png)

### コマンドブロックによる実行
色はついていませんが、どうやら<font color=salmon>**エラーメッセージ**</font>のようです。
「<font color=salmon>プレイヤーが見つかりませんでした</font>」ということは、アイテムを与える対象、つまり<font color=skyblue>ターゲットセレクター</font>に問題があるということになります。<font color=skyblue>```@s```</font>と指定しましたが、その意味は「コマンドを実行したエンティティ」。
対して、コマンドブロックから実行するコマンドの実行者は、「レッドストーン信号を与えたプレイヤー」ではなく、「**<font color=limegreen>コマンドブロック自身</font>**」なのです。<font color=skyblue>```@s```</font>では、コマンドを実行したエンティティが見つからず、実行に失敗してしまいます。
なので、セレクターを「最寄りのプレイヤー」を意味する<font color=skyblue>```@p```</font>に変えましょう。

![selector_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/15389d54-a6e2-6342-c83b-91043907fca5.gif)

今度はちゃんと手に入りましたね。

### チェーンとリピート
ここまでなら、チャット欄からコマンドを実行するのとほとんど違いはありません。コマンドブロックの強みは他にあります。それは、「<font color=mediumaquamarine>連結</font>」と「<font color=mediumorchid>反復</font>」ができること。管理者用アイテムタブを開いてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/310b10f2-fb3d-6d5d-fc46-e840c5dd33bd.png)

「<font color=mediumaquamarine>チェーンコマンドブロック</font>」「<font color=mediumorchid>リピートコマンドブロック</font>」とあります。取り出して設置してみましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/83bf3e19-79ec-9be5-d0be-9bc56ac90842.png" width=500>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/1c84bd32-18e2-4bb7-b458-d70e9b4281e1.png" width=500>

UIを開いてもあまり違いがありません。どう使うのでしょう。

:::note info
ひとことに「コマンドブロック」といっても、三種類あることがわかります。チェーン、リピートに対して普通のコマンドブロックは<font color=lightsalmon>インパルスコマンドブロック</font>と呼ばれます。
:::

### チェーンコマンドブロックのつかいかた
"<font color=mediumaquamarine>Chain</font>"は直訳すると「<font color=mediumaquamarine>鎖</font>」。
チェーンコマンドブロックは、鎖のようにコマンドを<font color=mediumaquamarine>連結</font>をするコマンドブロックです。
もう少し厳密にいうと、「他のコマンドブロックに続いてコマンドを実行する」ブロックなので、<font color=limegreen>単体では何もできません</font>。インパルスコマンドブロックやリピートコマンドブロックと組み合わせて使います。

![chained.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/307950ab-e045-20fe-887f-230e3c5a6a9d.png)

このように、根本のコマンドブロックに<font color=limegreen>向きを合わせて</font>チェーンコマンドブロックを二つ設置して、以下のコマンドを入力してみましょう。

```:インパルスコマンドブロックの中身
/say 1
```
```:一つ目のチェーンコマンドブロックの中身
/say 2
```
```:二つ目のチェーンコマンドブロックの中身
/say 3
```

```/say```は、単純に指定した文字列をチャット欄に出力するコマンドです。
ここで、インパルスコマンドブロックにレッドストーン信号を与えると、順番に```1```、```2```、```3```と出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/f0ba3356-d928-a618-fd17-997f10481508.png)

### リピートコマンドブロックのつかいかた
"<font color=mediumorchid>Repeat</font>"は直訳すると「<font color=mediumorchid>反復</font>」。
その名のとおり、リピートコマンドブロックはレッドストーン信号が与えられている限り、<font color=limegreen>入力されたコマンドを繰り返して実行し続けます</font>。
リピートコマンドブロックに、```/say Hi```と入力して、ボタンで信号を与えてみましょう。

![repeat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/8a665e0a-9b93-b3c0-7593-0f1d9b62d6af.gif)

たくさん```Hi```と表示されました。チャット欄を開いて数えてみると、20回。ボタンが信号を発するのはちょうど1秒間なので、リピートコマンドブロックは<font color=limegreen>1秒に同じコマンドを20回実行する</font>、ということになります。
なお、リピートコマンドブロックにチェーンコマンドブロックをつなげた場合、続くチェーンコマンドブロックに設定されているコマンドも1秒に20回実行されます。

:::note info
この「1秒に20回」は、Minecraftの（ほどんど）あらゆる処理のループが1秒に20回行われることからきています。この1/20秒に1回の処理のループを```tick```と呼びます。
:::

# 3. 条件の取得
### 統計
次に、「<font color=limegreen>剣で攻撃したこと</font>」を検知していきます。この、プレイヤーが行った行動の検知には、全く新しいシステムを使います。
もう一度メニュー画面を開いて、今度は「<font color=limegreen>統計</font>」のページを見てみましょう。

![stats.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/33235732-d105-5267-7374-96203c135a40.png)
▲ 統計のページ

なにやら色々な数字がまとめられています。

![stats_item.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/4bf40546-2bcb-7cc0-4651-e160591d0899.png)
▲ 統計のアイテムのページ

アイテムの欄に移ってみると、「<font color=limegreen>使用した回数</font>」なる項目があります。コマンドを使えば、この統計のページにある、<font color=mediumspringgreen>**全ての数値**</font>を取得して使うことができます。

### スコアボードの概念
統計にアクセスするコマンドとは、```/scoreboard```。「スコア」と呼ばれる数値を管理したり、計算したりするコマンドです。しかし、スコアは最初から存在しているわけではなく、自分で適宜追加していく必要があります。早速スコアを追加してみましょう。
```: スコア "used_sword" を追加する
/scoreboard objectives add used_sword minecraft.used:minecraft.netherite_sword
```
スコア自体はコマンドの上では```objective```、つまり「対象」と呼ばれます。今回はスコア自体を操作するので、一つ目のサブコマンドは```objectives```になります。行う操作は「追加」、なので```add```ですね。名前は比較的自由に決めて構いませんが、混乱を避けるため、MinecraftのIDの書き方に則って名付けることをおすすめします。

最後に、追加するスコアの種類を指定しますが、IDの記述がずいぶんと複雑です。```minecraft```がなぜか二回含まれていたりします。どういうことかというと、```used```も、```netherite_sword```も名前空間```minecraft```のもの、と決まっているからです。

ついでに、<font color=limegreen>スコアの表示設定</font>も変えましょう。
```: サイドバーにスコアを表示
/scoreboard objectives setdisplay sidebar used_sword
```

![scoreboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/d1f3dc8b-bcbc-b1f7-09e1-252f3ba75e16.png)

画面の右端に```used_sword```と表示されました。今度は、剣を使って攻撃してみましょう。

![used_sword.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/5862d7c5-1e28-3136-1cbf-bfd52a4dc088.gif)

スコアが<font color=salmon>```1```</font>になりました。さきほどの統計に示されたものとは別の値ですが、これはスコアボードの仕様です。「統計を参照する」といっても、「統計が計測する値と同じ値を保存する」だけです。なので、スコアが作成された時点での値は存在しません。剣を使って初めて、1が加算されます。

::: note info
また、プレイヤー名も表示されていますね。スコアは、エンティティが各自に持っているものだからです。他のプレイヤーがネザライトの剣を使えば、そのプレイヤーには個別に```used_sword```の値が保存されます。
:::

<font color=limegreen>統計の値に依存しない</font>ということは、<font color=limegreen>自分で好きにスコアを編集できる</font>ことも意味します。
```:"used_sword" を100に設定する
/scoreboard players set @s used_sword 100
```
```:"used_sword" の値をリセットする
/scoreboard players reset @s used_sword
```
```/scoreboard```のもう一つのサブコマンド、```players```です。すでに存在するスコアを設定するコマンドになります。<font color=skyblue>```@s```</font>とあるのは、<font color=skyblue>自分が持っている</font>```used_sword```の値を編集したいからですね。
```/scoreboard players```は、他にも四則計算や表示設定の変更などもできますが、今回はこの二つだけを紹介します。

スコア```used_sword```が<font color=salmon>```1```</font>になったタイミングで```/kill```を実行して、値をリセットする、という流れが作れそうです。
これで、<font color=limegreen>剣で攻撃したことを計測</font>できるようになりましたが、肝心のスコアが変動したことの検知はまだできませんし、攻撃されたモブを特定することもできません。

# 4. コマンド開発の大黒柱
### われらが万能コマンド
<font color=orange>条件の検知</font>、そして<font color=skyblue>実行者の変更</font>。この二つの事象は、なんとたった一種類のコマンドで制御できます。
そのコマンドの名は```/execute```。コマンドを使って何らかしらのアルゴリズムを組む際には、必ずといっていいほど使われるコマンドです。```/execute```は、上記二つのことができる<font color=mediumspringgreen>**唯一のコマンド**</font>である上、その自由度もとてつもなく高いです。そのサブコマンドの数はなんと<font color=limegreen>15</font>。全ては紹介しきれないので、今回必要になるものだけを軽く解説します。

:::note info
この説明で、何が何やら分からない、となるかもしれませんが、あまり気にしないようにしましょう。```/execute```は構造が複雑であるだけでなく、挙動自体も想像がしにくいコマンドです。分からなくても、立ち止まらず進んでください。実際に使ってみると理解がしやすくなるはずです。
:::

### ```/execute```のつくり
```/execute```はサブコマンドが多いだけでなく、構文の観点からでも異質です。
他のコマンドは、サブコマンドを一つ指定した場合、そのままコマンド全体が完結します。しかし、```/execute```はサブコマンドを指定するだけでは何もできません。ほとんどの場合では、<font color=limegreen>サブコマンドで指定した事象を踏まえ、別のコマンドを最後に実行</font>します。
そのために用意されているサブコマンドは```run```。あとに続くコマンドを実行するだけです。

```:実行するだけ
/execute run say Hi
```

```run```により、```/execute```はいったん完結します。ただ、```run```のあとのコマンドは、```/execute```で指定した諸々の設定を基準に実行されます。

```/execute```で設定を指定する、とはどういうことでしょうか。```run```サブコマンドだけでは、「コマンドを実行するだけのコマンド」になってしまいますよね。しかし、```/execute```と```run```の間に、<font color=limegreen>条件や実行者の変更が好きなだけ挟むことができる</font>となればどうでしょう。色々な提示をした上で、コマンドが実行できそうです。

つまり、```/execute```は、<font color=limegreen>サブコマンドに続いて、他のサブコマンドを複数連ねる</font>ことが可能だということです。これにより、```/execute```一つで複雑な条件分岐などが作れてしまいます。
これだけでは具体的な想像がしにくいと思うので、とりあえず他のサブコマンドの例をいくつか紹介します。

### 条件の確認
「攻撃したかどうか」のような条件は、```if```、もしくは```unless```サブコマンドを使って検知します。「もし、条件を満たしている（いない）なら実行する」という形になります。

```:半径5ブロック以内にゾンビがいるならHiと出力する
/execute if entity @n[type=minecraft:zombie,distance=..5] run say Hi
```

```if entity```とありますが、これは```if```をさらに細かく決めたもの。どういった分野の条件を確認するかをいくつかの項目から選びます。```entity```と書いた場合は、<font color=limegreen>ターゲットセレクターにあるエンティティが存在しているか</font>を確認します。この場合は、「種類がゾンビ」で「実行位置から半径5ブロック以内」の「最寄りのエンティティ」が存在するなら、チャット欄に```Hi```と出力されます。
他にも、<font color=limegreen>対象が所持しているアイテム</font>や、<font color=limegreen>スコアボード</font>を参照するものがあります。これらについては、また後ほど。

### 実行者の変更
もう一つ紹介する```/execute```の機能は、実行者にまつわるものです。ターゲットセレクターにおける、<font color=skyblue>```@s```</font>の部分に関わります。

#### 直接指定する
直接エンティティを決め、実行者にする方法です。
構文は、```/execute as <ターゲットセレクター>```です。そのまま続くコマンドでの実行者が```<ターゲットセレクター>```で指定したエンティティとなります。
さきほどコマンドブロックに入力した```/give```も、```execute as @p```と前に付ければ、元のコマンドのセレクターを変える必要がなくなります。

#### 実行者との関係から絞り込む
ターゲットセレクターといえど、<font color=limegreen>攻撃してきた相手</font>など、状況によって変わる実行者との関係からエンティティを検出することはできません。
そういった場合は、```on```サブコマンドを使います。```/execute on <関係>```とすると、続くコマンドの実行者が```<関係>```に対応するエンティティに変更されます。このサブコマンドを上手く使えば、<font color=limegreen>自分が攻撃した相手</font>を実行者にすることができます。

# 5. 繋げて実装する
### つくっていく
これで、剣で攻撃したことを検知して、対象を倒す、という全体の流れが見えたでしょうか。ここからは、紹介したコマンドの要素と技術を使い、実際に「最強の剣」のアルゴリズムを作ります。

まだ紹介していない仕様もいくつか登場しますが、その都度解説していきます。

### 常時実行コマンド
いつ剣で攻撃をするかは決まったタイミングではありませんし、攻撃をした瞬間に一度だけ処理を実行すればよい、というわけでもありません。つまり、<font color=limegreen>常に条件の確認をしていたい</font>わけです。
常に実行するコマンドブロックは<font color=mediumorchid>リピートコマンドブロック</font>。最初に設置しましょう。

攻撃したことは<font color=limegreen>最初に</font>検知したいので、```/execute if```がリピートコマンドブロックの中身に適しているでしょう。

```:スコア"used_sword"が1以上であるなら"Hi"と出力する
/execute if score @p used_sword matches 1.. run say Hi
```

![Hi.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/3951362f-b006-d65d-2f5d-1fe1a6566c3a.gif)

実行してみると、延々と```Hi```と出力されます。条件は「```used_sword```が1以上であること」だけなので、スコアを編集しなければ常に満たされてしまいます。なので、処理の最後にスコアをリセットしましょう。<font color=mediumaquamarine>チェーンコマンドブロック</font>を列に付け足して、処理を書き込みましょう。

```:スコア"used_sword"の値をリセット
/scoreboard players reset @p used_sword
```

![Hi_once.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/f3c8079c-9475-c0d0-786b-1e11c136d325.gif)

<font color=limegreen>攻撃した瞬間にコマンドを実行する</font>仕組みができました。

### 攻撃対象の検知
さて、次に剣で攻撃した相手を求めます。さきほど、実行者との関係性から新しく別の実行者を設定する```/execute on```を紹介しましたが、これを使って検知できるのは<font color=limegreen>実行者を攻撃した対象</font>であり、攻撃した相手ではありません。しかし、攻撃者を検知できるのなら、そこから逆算できそうです。

まず、どのエンティティが攻撃されたのか最初の時点では分からないので、<font color=skyblue>攻撃をたった今受けた、全てのエンティティ</font>を実行者にします。

```:ステップ1：ここから絞り込む
/execute as @e[nbt={HurtTime:10s}]
```

:::note info
nbtとありますが、これはエンティティが持つ情報をまとめたデータです。似たものにAttributeがありますが、nbtはモブのステータス値以外にもさまざまな情報を保持しています。HurtTimeは、モブの無敵時間の長さ。無敵時間は、全てのモブに共通で0.5秒に設定されており、それをtickになおした10の値を持っている場合、「攻撃された瞬間のエンティティ」を検知できます。
:::

このエンティティのうち、どれかが攻撃されたモブのはずです。ということは、```on attacker```で攻撃したエンティティを特定できます。

```:<font color=limegreen>ステップ2：攻撃されていないエンティティを省く</font>
/execute as @e[nbt={HurtTime:10s}] on attacker
```

ここで、攻撃者が剣で攻撃したということが分かれば、最初の実行者が攻撃されたエンティティということが断定できます。今の実行者は攻撃した側のエンティティなので、そのまま```used_sword```スコアを確認します。

```:<font color=lightgray>ステップ3：プレイヤーに攻撃されたか</font>
/execute as @e[nbt={HurtTime:10s}] on attacker if score @s used_sword matches 1..
```

```if```は、```run```につなげなくても```/execute```コマンドの処理を完結させることができます。

...と、簡単にいいましたが、これだけでは何も起こりませんし、条件確認の結果もどこにも残りません。

```:スコア"has_attacker"を追加
/scoreboard objectives add has_attacker dummy
```
保存するためのスコアです。スコアの種類は```dummy```。統計のデータを参照しない、<font color=limegreen>自由に計算ができるただの数値</font>として扱うことができます。

```:<font color=darkkhaki>ステップ4：コマンドの結果をスコアに保存する</font>
/execute as @e[nbt={HurtTime:10s}] store success score @s has_attacker on attacker if score @s used_sword matches 1..
```

```/execute store```は、コマンドの実行結果を指定した値に代入するサブコマンドです。今回使うのは```store success score```。任意のスコアに、コマンドが成功したら1、失敗したら0を代入します。
```/execute if```は、条件が満たされていなかったら失敗という処理になるので、<font color=mediumspringgreen>**この一連の流れのあとに```has_attacker```が1となっているエンティティが攻撃された対象**</font>です。

:::note info
コマンドは、構文や入力値が間違っていたり不完全だと、処理が行われず、<font color=salmon>エラーメッセージ</font>が出力されていました。結果的にコマンドは実行に**失敗**したわけです。
:::

![on_attacker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/10d1eeb5-8be4-a4d6-d1f4-c009d2339bad.png)
▲ 攻撃対象検知の図解

### 本番の処理を実行するまえに
さて、このコマンドをさきほどの検知の機構と組み合わせ、```/kill```を実行...**<font color=red>する前に</font>**。

もし、何かの手違いがあったことを考えてみます。プレイヤーの```has_attacker```スコアが1になってしまったらどうでしょう。プレイヤーに対して```/kill```が実行されます。スコアのリセットを忘れていようものなら、1秒に20回、常にプレイヤーが倒されてしまい、ワールド全体の取り返しがつかなくなります。

```/kill```のような危険性があるコマンドを使ったアルゴリズムは、実際に試す前に、```/say```などのコマンドで置き換えて**デバッグ**することをおすすめします。

では、コマンドブロックを並べて機構を作りましょう。

![algorithm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/4cbdeb49-b4b8-3f66-dcac-90aacf602cd2.png)

使うコマンドブロックは全部で四つ。コマンドも入力します。

```:リピートコマンドブロックの中身
/execute as @e[nbt={HurtTime:10s}] store success score @s has_attacker on attacker if score @s used_sword matches 1..
```

```:一つ目のチェーンコマンドブロックの中身
/execute as @e if score @s has_attacker matches 1 run say Hi
```

```:二つ目のチェーンコマンドブロックの中身
/scoreboard players reset @a used_sword
```

```:三つ目のチェーンコマンドブロックの中身
/scoreboard players reset @e has_attacker
```

実行して試してみます。

![attack.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/eedb9910-4eba-1f8a-7e2a-c369ac1ee24a.gif)

しっかり、対応した番号のゾンビから```Hi```と送信されています。挙動の確認ができたので、```/say```を```/kill```で置き換えて、<font color=mediumspringgreen>**敵にどれだけ防御力や耐性があっても一撃で必ず倒す、正真正銘の最強の剣**</font>の完成です。

# 6. ふと、冷静になってみる
### 「最強」を考えなおす
ここまでで、「<font color=limegreen>全てを一撃で倒す</font>」というコンセプトのもとにコマンドを考え、書きましたが、果たしてこれは**面白い**のでしょうか。たしかに、一撃必殺の攻撃なので「最強」と称すことはできるでしょう。

しかし、「最強の剣」を想像したときのことを思い出してみてください。ただ殴っておわり、というような絵面ではなかったはずです。もっと派手に、かっこよく決まった攻撃を思い浮かべていたのではないでしょうか。
この点を踏まえて、「最強の剣」を<font color=limegreen>少しばかり改善</font>します。

### 見た目を作る
本来の処理には関係のない、「ガワ」を作りましょう。Minecraftで演出に使われているのは<font color=limegreen>**パーティクル**</font>です。エフェクト効果を付与したときや、ブロックを採掘するときに表示されるアレです。パーティクルにもまた、専用のコマンド```/particle```が用意されています。使用例を先に見てみましょう。

#### シンプルな爆発
```
/particle minecraft:explosion ~ ~ ~ 0 0 0 0 1
```

![explosion.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/1a11b322-c744-7345-b229-ceda9ba57e63.png)

画像のように、足元に小さな爆発のパーティクルを表示します。

#### 燃やす
```
/particle minecraft:flame ~ ~1.5 ~ 0.5 0.5 0.5 0 50
```

![flame.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/3117e0a3-5388-beff-a81d-5f865e245a21.png)

自分の周囲に炎を出します。

#### 謎の光
```
/particle minecraft:end_rod ~ ~1.5 ~ 0.5 0.5 0.5 0.1 50
```

![end_rod.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/c863a89f-4d5f-85c5-352c-8e4b5839efef.png)

エンドロッドから発するパーティクルを、```minecraft:flame```と同じ要領で表示します。ただ、こちらには動きがついています。

#### 汎用パーティクル
```
/particle minecraft:dust{color:[0.0,1.0,0.5],scale:1.0} ~ ~1.5 ~ 0.5 0.5 0.5 0 50
```

![dust.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/46a5a30c-f92b-9ad6-6636-ff9c3f753f3b.png)

レッドストーンダストに見られる粉のパーティクルを表示します。この```minecraft:dust```は追加で表示時の色や大きさまで指定することができ、自由度が一段と高いです。

では、この例たちをもとに構文も見てみます。

#### パーティクルの種類
表示されるパーティクルは、Minecraftに登場する全てのものが指定できます。ただ、```dust```のように、一部のパーティクルはIDの後ろに```{}```をつけ、コマンド内で表示設定を変更することができます。```dust```に適用できるオプションを見てみましょう。

##### ```color``` － パーティクルの色
```[]```内で、```0.0```から```1.0```の値を三つ入力することで表示色が設定できます。この値は、それぞれ<font color=red>赤</font>、<font color=green>緑</font>、<font color=blue>青</font>の三色の強さになっており、数字が大きいほどその色の成分が全体の色に強く反映されます。

##### ```scale``` － パーティクルの大きさ
こちらは単純な値で、表示されるパーティクルの大きさを変更します。```0.01```から```4.0```の数値に対応しています。

#### 表示位置
対象のパーティクルが表示される座標を指定するフィールドです。数学の```x```、```y```、```z```座標と同じ要領です。
しかし、Minecraftでは、<font color=limegreen>コマンドが実行された座標を起点に</font>座標を記述する仕組み、<font color=mediumspringgreen>相対座標</font>があります。```~```と書き、そこに数値を続けて入力すると、対応した軸にその数値ぶんだけ移動した場所が設定できます。
さきほど多用した```~ ~1.5 ~```は例えば、実行場所（自分の足元）からx座標とz座標はそのままに、y軸に沿って1.5ブロックだけ移動した場所にパーティクルを表示するようにしています。

#### 表示範囲
見てのとおり、パーティクルは決まった位置に固定されて表示されているのではなく、多少のばらつきを持っています。このパーティクルがばらつく範囲を<font color=limegreen>偏差</font>といい、これもまたxyz軸のばらつきを個々に指定できます。値が1増えるたびに偏差は8ブロックぶん広がるので、あまり大きな値は使われません。

#### 表示速度と個数
パーティクルがアニメーションまたは動きを持つとき、その速度を設定できます。ただ、アニメーションなどがあっても、速度の値が影響を持つパーティクルと持たないパーティクルがあります。その都度、速度を色々変えて試しましょう。
個数は、単純にパーティクルをいくつ表示するかを決めます。

### 処理に演出を追加する
では、実際に```/particle```を最強の剣の処理に組み込んでみます。
<font color=limegreen>攻撃されたエンティティが分かっていて、なおかつ倒されていないとき</font>にパーティクルを表示したいですね。つまり、エンティティを検知した直後です。
しかし、そうなると二つ目の処理以降を全て書き直さなければなりません。面倒ですね。

そこで役立つのが<font color=limegreen>ブロック選択</font>です。コマンドブロックにカーソルを合わせ、マウスホイールをクリックしてみてください。

![pick.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/44866e0f-1650-8943-3353-20751686ff04.gif)

ホットバーでコマンドブロックを選択できます。
この操作を、```Ctrl```(Macの場合は```Cmd```)キーを押した状態で行うと、<font color=limegreen>そのブロックのデータを保持したまま</font>インベントリに加えることができます。これでコマンドブロックを壊しても簡単に再設置ができます。

リピートコマンドブロックの一つ後ろに、チェーンコマンドブロックを追加しましょう。
```:新しいチェーンコマンドブロックの中身
/execute as @e if score @s has_attacker matches 1 at @s run particle minecraft:dust{color:[1.0, 1.0, 0.0],scale:1.5} ~ ~2 ~ 0.01 1 0.01 0 250
```

![thunder.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924021/558ec698-8dc4-623c-920d-62d1376164eb.gif)

これでモブを攻撃してみると、<font color=limegreen>雷が落ちたかのようなパーティクル</font>が表示されます。

コマンドに```at @s```とありますが、これは<font color=limegreen>実行位置の変更</font>です。```/particle```にて、```~```で座標を指定するときの基準を実行者、つまり攻撃されたエンティティの場所に移しています。

### 可能性は自分次第
今回は落雷のような演出を作りましたが、Minecraftにはまだまだたくさんのパーティクルが用意されています。さらには、```dust```のように細かく設定ができるものも少なくなく、自由度はとても高いです。色々試して、**<font color=mediumspringgreen>自分だけの「最強」を彩りましょう</font>**。

# 7. わからないときは
ここまでで、コマンドで作るアルゴリズムやそれに不可欠なコマンドや仕様を紹介しました。前編と違い、エンティティ同士の関係や、プレイヤーの行動の記録など、いちコマンドでは完結しないものでしたね。
こういった、コマンドを複数繋げて作る機構は<font color=limegreen>どこかに正解があるわけではありません</font>。制作に行き詰まっても、Wikiに答えがあったり、専用の生成ツールがあるわけでもありません。

そういうときは、<font color=limegreen>人を頼りましょう</font>。「何がしたいのか」「どこに引っかかっているのか」という具体的な事項を説明できて、場所や状況をわきまえれば、きっとコマンドに詳しい先人たちが答えてくれるでしょう。

# 8. お役たちリンク集
最後に、前回と同じく、コマンド制作に役立つページへのリンクをいくつか紹介します。

### [Minecraft Command Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mccmd)/[2024](https://qiita.com/advent-calendar/2024/mccmd)
本記事も参加している、<font color=limegreen>コマンド勢が記事を書いて技術を共有するイベント</font>です。
今年はもちろん、昨年も開催しており、60もの記事が投稿されました。ここ一年でコマンドの仕様に数々の改革が入ったので、現在のMinecraftのバージョンでは使えない技術や情報も含まれていますが、バージョンに関係なく、役に立ったり興味深かったりする記事がたくさんあります。目を通してみてはいかがでしょうか。

### [Minecraft Wiki](https://minecraft.wiki)
今回の記事では、特に覚えることが盛りだくさんの要素を複数紹介しました。アルゴリズムに絶対的な答えはない、とは書きましたが、それでもやはりMinecraft Wikiにはそれらに関する情報が分かりやすくまとめられています。

- [```/execute```の記事](https://ja.minecraft.wiki/w/%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/execute)
- [スコアボードの記事](https://ja.minecraft.wiki/w/%E3%82%B9%E3%82%B3%E3%82%A2%E3%83%9C%E3%83%BC%E3%83%89)
- [パーティクルの記事](https://ja.minecraft.wiki/w/%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%AF%E3%83%AB)

### 各種SNS
コマンドでものづくりをしている人は、X/TwitterやYouTubeで活動していることも多いです。自分から活発に発言や質問をしたりせずとも、そういった人たちの行動を追っているだけで、自然と知識がついたり、インスピレーションが湧いたりするものです。

# おわりに
### 
今回は、コマンドで作るアルゴリズムとそれに必要な要素や考え方に加え、演出の作り方まで紹介ました。

全くわけが分からない、という方もいるのではないでしょうか。前回にまして、さらに理解の難しい内容と物量なので、無理もありません。到底、一朝一夕で把握できるものではないでしょう。
しかし、焦る必要はありません。<font color=limegreen>自分がやりたいと思うこと、つくりたいと思うモノ</font>に素直に従ってコマンドを書いてみてください。実装に必要なのは何か、と実践しながら模索することが成長への一番の近道です。
期間を開けて、[前回の記事](https://qiita.com/firgde/items/dcb7d2fd75b5ec61ba46)や[この記事を読み返す](#1-考えをまとめる)と、見えてくるものもあるかもしれません。

また、この記事で作ったものも完璧ではありません。攻撃した対象の検知やにはまだ少し粗がありますし、今の実装だとネザライトの剣でさえあればどれであっても最強の剣と化します。こういった問題の解決を一つのきっかけとしてもよいのです。まずは手を動かしてみましょう。

それでもわからない、となった場合は思い切ってコマンドから少し離れてみるのも手です。こういった個人の趣味でやる創作は、<font color=limegreen>作る本人が楽しいこと</font>がまず大事ですから、無理をしてやりたくないことをやる必要はありません。楽しく創作をしましょう。

本当に長くなってしまいましたが。ここまで読んでいただき、ありがとうございます。
よき、コマンドライフを。