【JE】意外と知らない!?知っておくべきNBTの指定方法

スポンサーリンク

※この記事に書かれているのはJE1.21.1の情報です。

はじめに

こんにちは、はちみつと申します。

皆さんはコマンドについてどれくらい知ってますか?

コマンドを使う上で、実は知らなかった記述ってありませんか?

僕も未だに「こう書けばこれできたんだ!!!」みたいな発見がよくあるので、これからいくつか共有したいと思います。

アイテムコンポーネントの指定方法

〇〇を含む

例えば魔法の杖を作った時に「杖を持った事を検知したい」となった時。

ABの魔法の杖があったとします。

それぞれの杖には、

# Aの杖
{
components:{
"minecraft:custom_data":{
wand:1b
}
}
}
# Bの杖
{
    components:{
        "minecraft:custom_data":{
            wand:1b,
            magic_id:0
        }
    }
}

といったカスタムデータが設定されているとします。

wand:1b

▲これは「このアイテムが杖である」ことを表しています。

magic_id:0

▲これが杖を使う事で発動する魔法のIDです。

魔法のIDは杖によって変わります(という設定)
※Aの杖にIDが設定されてないのはツッコまないで

これでプレイヤーが杖を持っていることを検知するなら、execute if itemsを使うのが一番簡単です。

/execute if items entity @s weapon.mainhand アイテム名[custom_data={wand:1b}]

しかし、このような記述で実行してしまうと、Aの杖しか検知してくれません。

逆に、

/execute if items entity @s weapon.mainhand アイテム名[custom_data={wand:1b, magic_id:0}]

と書いて実行すると、Bの杖しか検知してくれません。

もちろん、杖ごとに全て書くなんてあまりにも面倒すぎますよね。

そこで、wand:1bが含まれているという条件で検知する方法が実は用意されているのです。

/execute if items entity @s weapon.mainhand アイテム名[custom_data~{wand:1b}]

どこが変わったか分かりますか?

custom_data~{wand:1b}の所ですね。

=」だと完全一致じゃないと検知してくれませんが、「~」だとその記述が入っていれば検知してくれるのです。

・・・まぁ、predicateでやるのが一番良いんですが、/clearコマンドとかで大事になるので覚えておくと便利です。

〇〇もしくは〇〇

今度は脱出マップでプレイヤーに金床で、紙にキーワードを書いて貰うとしましょう。

例えば正解が「ダイヤモンド」だった場合、「ダイヤ」「ダイアモンド」「diamond」・・・等々、色んな書き方があると思います。

これらを検知するために

clear @s paper[custom_name="ダイヤモンド"] 0
clear @s paper[custom_name="ダイアモンド"] 0
clear @s paper[custom_name="ダイヤ"] 0
clear @s paper[custom_name="diamond"] 0
・・・

って書いてたら処理が多くなって面倒じゃないですか?面倒ですよね?functionだったらこっちの方が見やすいとか言わないで

そこで、ひとまとめにしてこう書いちゃいましょう。

paper[custom_name="ダイヤモンド" | custom_name="ダイアモンド" | custom_name="ダイヤ" | custom_name="diamond"]

コンポーネントの間に「|」を書くと、「〇〇もしくは〇〇」といった条件になるので、1コマンドで正解のワードを書いたか確認できるのです。
※「|」は、バックスペース(文字を消すやつ)の左にある「¥」をSHIFTキーを押したまま入力すると打てます。

ちなみに、「,」カンマにすると、「〇〇かつ〇〇」といった条件になります。

上の例の「|」を「,」に置き換えちゃうと、名前が「ダイヤモンド」かつ「ダイアモンド」かつ「ダイヤ」かつ「diamond」である必要があるという意味になるのですが、絶対その状況はあり得ないので一生検知されません。シュレディンガーの猫みたい

NBTの細かい指定方法

NBTを取得したい

これは正直基本的な事なんですが、僕がコマンドに興味を持った時に知らなくて不便だったヤツなので、一応共有しておきたいと思います。

一番よく使うのは「自分の持っているアイテムのNBTデータを取得したい時」

/data get entity @s SelectedItem

で取得できます。

例えばこれで「ダメージ増加Vのエンチャ本」のデータを取得したとき中身は、

{
    id: "minecraft:enchanted_book",
    count: 1,
    components: {
        "minecraft:stored_enchantments": {
            levels: { "minecraft:sharpness": 5 }
        }
    }
}

このようになっていると思います。

ここでこのエンチャ本に「どのエンチャント効果が付いてるのか知りたい」時などは、さっきのコマンドだと余計な情報が沢山出てきて解読するのが面倒ですよね。

そこで、

/data get entity @s SelectedItem.components."minecraft:stored_enchantments".levels

このように指定して実行すると、

{ "minecraft:sharpness": 5 }

を結果として取得することが出来ます。

これだとスッキリしてて分かりやすいですよね。

このNBTの指定方法はめちゃめちゃよく使うので是非覚えておいてください。

リストのn番目を指定したい

こう書くとちょっとややこしく感じるかもしれませんが・・・

例えば、チェストの中身とかってリスト形式というもので保存されていて、

0.webp

▲のチェストの中身をNBTで取り出すと、

Items:[
    {count: 1, Slot: 0b, id: "minecraft:iron_sword"},
    {count: 1, Slot: 1b, id: "minecraft:iron_axe"},
    {count: 1, Slot: 2b, id: "minecraft:iron_shovel"},
    {count: 1, Slot: 3b, id: "minecraft:iron_pickaxe"},
    {count: 1, Slot: 4b, id: "minecraft:iron_hoe"}
]

といった感じになると思います。

ここで3番目のアイテム、すなわち「鉄のシャベル」のNBTを取り出したい場合。

Items[2]

と指定することで取り出すことが出来ます。

ここで一つ疑問が出てくる人もいるはずです。

何故3番目」を指定するために2と書くのか。

プログラミング言語等のコンピューターの世界では、基本的に数字は「0」から始めるというお決まりがあります。

Minecraftもそれに則り01番目」として数えるのでこのような書き方になる訳です。

ちなみに・・・

これはチェスト上の「左から3番目のアイテム」を指定しているわけではありません。

どういう事かというと、

Items:[
    1番目 → {count: 1, Slot: 0b, id: "minecraft:iron_sword"},
    2番目 → {count: 1, Slot: 1b, id: "minecraft:iron_axe"},
    3番目 → {count: 1, Slot: 2b, id: "minecraft:iron_shovel"},
    4番目 → {count: 1, Slot: 3b, id: "minecraft:iron_pickaxe"},
    5番目 → {count: 1, Slot: 4b, id: "minecraft:iron_hoe"}
]

このリストの上から3番目」を指定しています。

例えば、

1.webp

こんな感じでアイテムをバラバラに配置してしまっても、NBTのデータ上では、

Items:[
    1番目 → {count: 1, Slot: 0b, id: "minecraft:iron_sword"},
    2番目 → {count: 1, Slot: 6b, id: "minecraft:iron_axe"},
    3番目 → {count: 1, Slot: 10b, id: "minecraft:iron_shovel"},
    4番目 → {count: 1, Slot: 16b, id: "minecraft:iron_pickaxe"},
    5番目 → {count: 1, Slot: 22b, id: "minecraft:iron_hoe"}
]

同じ数、そして同じ順番で表されています。

違うのはチェストのどこに配置されているかを表すSlotだけですね。

この状況で、

Items[2]

を指定した場合も、同じく「鉄のシャベル」が取り出されるはずです。

また、リストの一番最後の要素を取り出したい場合。

Items[-1]

と書くことで一番後ろの要素を取り出すことが出来ます。

Items:[
    1番目 → {count: 1, Slot: 0b, id: "minecraft:iron_sword"},
    2番目 → {count: 1, Slot: 1b, id: "minecraft:iron_axe"},
    3番目 → {count: 1, Slot: 2b, id: "minecraft:iron_shovel"},
    4番目 → {count: 1, Slot: 3b, id: "minecraft:iron_pickaxe"},
    5番目 → {count: 1, Slot: 4b, id: "minecraft:iron_hoe"}
]

この場合は5番目の「鉄のクワ」が取り出されることになりますね。

最後を指定するなら一見「Items[4]」でも行けるじゃんと思いますが、これだとリスト内の要素が増えた場合に対処できません。

Items:[
    1番目 → {count: 1, Slot: 0b, id: "minecraft:iron_sword"},
    2番目 → {count: 1, Slot: 1b, id: "minecraft:iron_axe"},
    3番目 → {count: 1, Slot: 2b, id: "minecraft:iron_shovel"},
    4番目 → {count: 1, Slot: 3b, id: "minecraft:iron_pickaxe"},
    5番目 → {count: 1, Slot: 4b, id: "minecraft:iron_hoe"},
    6番目 → {count: 1, Slot: 5b, id: "minecraft:diamond_sword"},
    7番目 → {count: 1, Slot: 6b, id: "minecraft:diamond_axe"}
]

チェストの中身がこうなった時に、

Items[4]

を指定していると、当然上から5番目にある「鉄のクワ」が取得されます。

Items[-1]

にしておくことで、リストの中身がどれだけ増えても一番最後の「ダイヤの斧」を取得することが出来ます。

リストの中に「〇〇」があるやつを指定したい

今度はチェストの特定の位置にあるアイテムのNBTを取り出したい場合。

1-1.webp

同じようにこんな配置のチェストがあったとします。

Items:[
    {count: 1, Slot: 0b, id: "minecraft:iron_sword"},
    {count: 1, Slot: 6b, id: "minecraft:iron_axe"},
    {count: 1, Slot: 10b, id: "minecraft:iron_shovel"},
    {count: 1, Slot: 16b, id: "minecraft:iron_pickaxe"},
    {count: 1, Slot: 22b, id: "minecraft:iron_hoe"}
]

「鉄の斧」位置にあるアイテムを取り出したい場合。

「鉄の斧」の位置は「Slot: 6b」なので、

Items[{Slot: 6b}]

と指定することで「Slot: 6b」にあるアイテムを取り出すことが出来ます。

逆に、

Items[{id: "minecraft:iron_axe"}]

と指定すると「鉄の斧」がどの場所に配置されていても取り出すことが出来ます。

データが存在するかしないかを知りたい

例えば「/execute if data」で「チェストの中身が5個以上埋まっているとき」を検知したい時。

/execute if data block ~ ~ ~ Items[4]

と書くことでItems[4]データが存在するか否かを検知することが出来ます。

ちなみに、

/execute if data block ~ ~ ~ {Items:[{},{},{},{},{}]}

これでも同じように検知できました。
わざわざこう書くメリットは無いと思うけど・・・

また、アイテムにコンポーネント等があるかどうかを指定することも出来ます。

/execute if data entity @s SelectedItem.components

カスタムデータが設定されてるかどうかとかも・・・

/execute if data entity @s SelectedItem.components."minecraft:custom_data"

こう書くことで検知することが出来ます。

/execute if data entity @s {SelectedItem:{components:{"minecraft:custom_data":{}}}}

一応これでも出来ますが、データのあるなしを検知したいならさっきの書き方のほうが見やすい上ラクなので良いですよね。

さいごに

今回紹介したのは少しマイナーで難しい要素かもしれませんが、使いこなせればかなり自由度が広がって複雑なことも出来るようになるので、この機会に是非覚えて帰ってください!

最後まで読んでくださってありがとうございました!

おわり

※投稿記事に含まれるファイルやリンクにより発生した被害についてクラフターズコロニーは責任を取りません
投稿通報

コメント

  1. そうだ~で検知出来るんだった、忘れてた!
    Thank you!

    • お役に立てて良かったです~!

コメント通報