導入
皆さん初めまして、自称JEコマンダーの大辞林ティーと申します。
コマンダーの皆さんは再帰処理をご存知だと思いますが、その中でNBTの引き渡しをしたことはありますか?
値の受け渡しをするだけでNBT操作の幅がグンと広がるので、この記事を皆さんの頭の片隅に入れてもらえると幸いです。
何がすごいの
まず、再帰処理で値の受け渡しが可能になると何がすごいのでしょう?
それはズバリ、 入れ子構造を扱える ようになる所でしょう。
例えば、シュルカーボックスの中にはシュルカーボックスが入っており、その中にもシュルカーボックスが入っている。その全ての中にあるアイテムをまとめて取り出す。
そういった機能を作れるようになります。
どうやるの
では、NBTの受け渡しの仕方について考えてみましょう。
まずはstorageの直下に input_val や output_val などを作って受け渡しをする、としてみましょう。
しかし、これだと関数内で同じ関数をよんだときにstorageの値が被ってしまいます。
この問題の解決策はシンプルで、乱数を使えばいいのです。
例えばstorage直下に data<乱数> を作り、その中に input_val や output_val を入れる。
最後に使い終わったら data<乱数> を消すだけで証拠隠滅もできます。
ここで1つ注意点があり、scoreboardの被りの対策もすることです。
私は関数が呼ばれるごとに乱数を用いた名前のスコアボードを定義していますが、セレクターのほうに乱数を用いる方がいいのかもしれません。
最小の例
それでは値の受け渡しをする際の例をみてみましょう
TestDatapack/
└ data/
└ namespace/
└ function/
├ main.mcfunction //関数本体
├ read.mcfunction
└ read2.mcfunction //関数読み込み用
$scoreboard objectives add test$(random) dummy
$data modify storage namespace:test data$(random).output_val set value "bar"
$tellraw @a [{text:"input_val"},{nbt:"data$(random).input_val",storage:"namespace:test"}]
$tellraw @a [{text:"output_val"},{nbt:"data$(random).output_val",storage:"namespace:test"}]
$scoreboard objectives remove test$(random)
execute store result storage namespace:test test_random int 1 run random value 0..2147483646
function namespace:read2 with storage namespace:test
data remove storage namespace:test test_random
$data modify storage namespace:test data$(test_random).input_value set value "foo"
$function namespace:main {random:$(test_random)}
$tellraw @a [{text:"returned output_val:"},{nbt:"data$(test_random).output_val",storage:"namespace:test"}]
$data remove storage namespace:test data$(test_random)
こんな感じのにロジックを組み込めば完成です
呼び出しに2つファイルを使わないといけないのが少し面倒ですね…
書き方があまり直感的ではないですが、プログラミングの再帰処理の本来の力を引き出すためだと思って我慢しましょう
最後に
ここまでで皆さんは再帰処理の可能性を感じてくれましたでしょうか。
次回はこの仕組みの魅力を実感してもらうため、具体的な例を挙げてみようかなと思っています。
最後まで読んでくれてありがとうございます。