/executeが大活躍?複雑な条件動作をさせるコツ【第9回応用コマンド講座】

どうも、執筆担当のとれんさーです。

今この記事を開いてくださった皆さんは、当講座の遅延コマンドシリーズをもうお読みになりましたか?
レッドストーンを使わずにコマンドだけで入力信号の遅延を行う機構を、全部で4つ紹介しています。まだ読んだことのないあなたも、もう読んだというあなたも、ぜひ読んで作ってみてくださいね!

遅延コマンドシリーズはこちら!

最初から大胆な宣伝をはさみましたが、今回の記事では先ほどの遅延コマンド機構でも使われた、とあるコマンドの技巧を紹介していこうと思います。

技巧 とは言っても実は、ある動作をするコマンドの構文に/executeコマンドを途中にはさむだけ という、意味を理解していればとても簡単に扱うことのできる裏ワザのようなものです。
今回はそれについて解説していきましょう!

前回の記事はこちら!

/executeのはさみ方

先ほど「/executeコマンドを構文の中にはさむ」と書きましたが、具体的にどのようにその技巧を使っていくのでしょうか?

ということで、今回は実際の使用例としてこちらを使います。

釣竿を振ったプレイヤーの経験値レベルが0だった場合にのみ、そのプレイヤーの5m先にスケルトンを出す

遅延コマンドシリーズを全て見てくださった方には見覚えがあるかもしれません。実はこの例、遅延コマンドシリーズ#3 〜プレイヤーの経験値〜で紹介したコマンド機構の2つ目のコマンドなんです。

第7回応用コマンド講座はこちら!

こちらの記事でこの例のコマンドの解説は軽くしたのですが、改めて詳しく解説していきたいと思います。


理屈などをだらだら説明する前に、まずは早速そのコマンドをご紹介していきましょう。

/execute @e[type=fishing_hook] ~~~ execute @p ~~~ execute @s[l=0] ~~~ summon skeleton ^^^5

こちらが、先ほどの例の挙動をするコマンドとなります。実際に使う際には反復コマンドブロックで毎tick動作させ、さらに釣り針(fishing_hook)をkillしたり経験値レベルの量を色々と変えたりするコマンドをつける必要があります。詳しくは第7回へ。

さて、本題に入ります。緑色のマーカーが引かれているため一目瞭然ですが、こちらのコマンド構文内の「execute @p ~~~」が、今回ご紹介する技巧となります。
あまりコマンドを触れたことがない方には十分難しく感じられるかもしれませんが、/executeコマンドをよく触ってこられた皆さんは拍子抜けしてしまったかもしれませんね。「ただ無駄なことしてるだけじゃん!」と思った方も、中にはいらっしゃると思います。
ですがこれを入れることは、/executeを使った複雑な構文を作る上で非常に重要なポイントになります。詳しくはこれから解説していきましょう。

/executeをはさむ意味

まずは、今回のコマンド例を分かりやすく分解してから解説していきましょう。
今回のコマンドは、釣竿から一番近いプレイヤーの経験値が0かを検知するという条件部と、プレイヤーの5m先にスケルトンを出すという本動作部2つの部品に分解することができます。
この2つを、一度別々のコマンドとして書き換えて分かりやすくしてみます。

条件部

/execute @e[type=fishing_hook] ~~~ execute @p ~~~ testfor @s[l=0]
釣り針から1番近いプレイヤーの経験値レベルが0以下の自身を検知する

本動作部

/summon skeleton ^^^5
5m先にスケルトンを出す

本動作部は、ただコマンドを実行したコマンドブロックもしくはエンティティ(/executeで実行させられたプレイヤー以外のエンティティも含まれます)を基準にスケルトンを出すだけのコマンドなので、今回の技巧とはあまり関係がありません。

問題は条件部のコマンドです。文法的におかしい箇所がコマンド構文の下の説明に見受けられると思いますが、これはいわゆるコマンドの直訳をしたものになっています。
分かりやすく言い換えると、このコマンドは
釣竿を振ったプレイヤーが経験値レベルが0であることを検知する
というものになります。最初に出した例のような言い回しになりましたね。つまりこれで、本動作部のコマンド実行主として釣竿を振った経験値レベルが0のプレイヤーを指定しているというわけです。ここまでは分かっていただけたでしょうか?

しかし、まだ構文の中に/executeコマンドをはさむ意味はこれだけでは分かりませんね。一見すると、「execute @p ~~~」がなくても同じ動作をしそうなものです。
ということで、「execute @p ~~~」をはさんでいるかいないかでどのように挙動が変わってしまうのか、実際にシミュレーションしてみましょう。

execute @p ~~~をはさんだ場合

/execute @e[type=fishing_hook] ~~~ execute @p ~~~ testfor @s[l=0]

今回の例のコマンドを実際に使用している遅延コマンドは、マルチに対応したつくりになっています。そのため、釣竿を振ったプレイヤーを特定するためには出した釣り針(fishing_hook)から1番近いプレイヤーを指定することが前提になります。
よって、execute @p ~~~」で1番近いプレイヤーを指定してからさらにそのプレイヤー(=釣竿を振ったプレイヤー)の経験値レベルが0(以下)かを検知しているのです。

例えばこの下の画像の例でいうと、近くに経験値レベルが0のプレイヤーがいたとしても関係なく、釣竿を振ったプレイヤーが指定の対象となり経験値レベルの検知が行われます。
この場合では釣竿を振ったプレイヤーが経験値レベル2なので、検知自体は失敗のため出力がされずそこで流れが終わりとなります。が、指定の対象は釣竿を振ったプレイヤーしかいないため他のプレイヤーを検知することは絶対にありえません。
(ただしあまりにも釣竿を振ったプレイヤーが他のプレイヤーと近い場合には、そもそもの指定の対象が他のプレイヤーにいってしまい、検知は他のプレイヤーにしか行なわれません。)

execute @p ~~~をはさまなかった場合

/execute @e[type=fishing_hook] ~~~ testfor @p[l=0]

一回/executeをはさむことで対象を絞ってから検知を実行することができるのは分かりましたね。
それでは、「execute @p ~~~」をはさまなかった場合、どういった挙動をするのでしょうか?

/testforコマンドの対象としている「@p[l=0]」という引数指定付きセレクタは、「経験値レベルが0(以下)のプレイヤーのうち1番近いプレイヤー」という意味を表しています。
よって、釣竿を振ったプレイヤー(釣り針から1番近いプレイヤー)かどうか一切関係なく経験値レベルが0で1番近くのプレイヤーが検知されます。「指定してからそのプレイヤーを検知」という流れはここにはありません。
「釣竿を振ったプレイヤーの経験値レベルが0かどうか」ではなく「経験値レベルが0の、釣竿を振ったプレイヤー(というより釣り針から1番近いプレイヤー)がいるかどうか」を検知するというコマンドになってしまうのです。

先ほどのように下の画像の例を使うと、釣竿を振ったプレイヤーとそのプレイヤーが違う存在だったとしても関係なく、経験値レベルが0のプレイヤーがいるかどうかの検知が行われます。
この場合では近くにいたプレイヤーのなかに経験値レベルが0だったプレイヤーがいたため検知が成功し出力がされます。が、釣竿を振ったプレイヤーの経験値レベルが0かどうか」は検知することができません。


どうでしょうか?なるべく噛み砕いて解説をしたつもりですが、「execute @p ~~~」をわざわざコマンド構文内にはさむ理由、理解していただけたでしょうか?
これをはさむかはさまないかで、コマンドの挙動はとても大きく変わってしまうこともあります。重要なコマンドの技巧として、ぜひ覚えてくださいね。

終わりに

実は今回の内容、今までの講座の中でもダントツで難しいコマンド応用法でした。もしかしたら今は理解できなかったという方もいらっしゃるかもしれません。
しかしこの内容は、いずれ皆さんもぶつかるであろうセレクタの複雑な指定の問題を解決できる、非常に便利な応用法です!今は意味が分からなくても、少しずつ理屈を理解していってくださればいいかなと思います。

また、応用のしかたの難易度が高いのもこの技巧の特徴です。今回の例で内容自体は理解していても、実践するのはなかなかに難しいかと思われます。ぜひ応用を自由にできるよう、皆さんご自身の手で自分なりの研究を重ねてみてくださいね。

分からないところやコマンド内容についての疑問点などありましたら、ぜひコメントでお寄せくださいね。

それでは、今回はこれで終わりとなります。お疲れ様でした。


前回↓

次回↓
更新をお待ちください。