sharo-jefの雑記帳

インフラエンジニアの雑記帳

【Minecraft】プレイヤーが所持しているアイテムの情報を更新する方法

Minecraftdata コマンドではプレイヤーの情報を更新できないので、他の手段でプレイヤーが所持しているアイテムの情報を更新してみる。

大まかな流れは以下の通り。

  1. アイテムの NBT タグ情報を storage にコピー
  2. シュルカーボックス内に何かしらのアイテムを入れる
  3. シュルカーボックス内のアイテムの情報を書き換える
  4. 書き換えたアイテムを元のスロット(プレイヤーのインベントリ)に戻す

シュルカーボックスからアイテムを戻すために loot_table を上書きする必要があるので注意。

アイテムの NBT タグ情報を storage にコピー

# メインハンドのアイテムの場合
data modify storage foo:bar Item set from entity @s SelectedItem
# それ以外のアイテムの場合 (Slot にはスロット ID を入れる)
data modify storage foo:bar Item set from entity @s Inventory[{Slot:-106b}]

# Slot 情報を消す
data remove storage foo:bar Item.Slot

この例では foo:bar の Item にアイテム情報を保存している。

主要なスロット ID は以下のとおり。

スロット スロット ID
オフハンド -106b
ヘルメット 103b
チェストプレート 102b
レギンス 101b
ブーツ 100b

シュルカーボックスにアイテムを格納

アイテム情報を編集するためにシュルカーボックスにアイテムを入れる。 配布マップであれば遠くに置けば良いが、その他の用途ではどこにブロックを置くか考える必要があるかも。 今回の解説では 0 0 0 に配置する。

インベントリを持つブロックであれば、シュルカーボックス以外でもできるかもしれない。

# 既に置いてあるシュルカーボックスを使う場合は setblock で置く必要は無い
setblock 0 0 0 minecraft:shulker_box

# container.0 に何かしらのアイテムを入れる
loot replace block 0 0 0 container.0 loot blocks/stone
# container.0 に入っているアイテムの情報を書き換える(id ごと書き換えるので元のアイテムは何でも良いと思われる)
data modify block 0 0 0 Items[0] merge from storage foo:bar Item

# シュルカーボックスを消す場合は以下を実行
setblock 0 0 0 minecraft:air

シュルカーボックス内のアイテムをプレイヤーのインベントリに戻す

loot replace entity @s weapon.mainhand 1 mine 0 0 0 minecraft:debug_stick

戻すスロットを変更したい場合は weapon.mainhand の部分を変更する。 主要なスロットは以下のとおり。

スロット スロット名
オフハンド weapon.offhand
ヘルメット armor.head
チェストプレート armor.chest
レギンス armor.legs
ブーツ armor.feet

上記のコマンドでアイテムを戻すためには、下記のようにシュルカーボックスの loot_table を変更しておく必要がある。 これを設定していない場合はアイテムが入ったシュルカーボックスが戻ってくる。 以下の設定の場合は 0 0 0 に配置されたもの以外には影響しない。

{
    "type": "minecraft:block",
    "pools": [
        {
            "rolls": 1,
            "entries": [
                {
                    "type": "minecraft:dynamic",
                    "name": "minecraft:contents",
                    "conditions": [
                        {
                            "condition": "minecraft:location_check",
                            "predicate": {
                                "block": {
                                    "nbt": "{\"x\":0,\"y\":0,\"z\":0}"
                                }
                            }
                        }
                    ]
                }
            ]
        },
        {
            "bonus_rolls": 0.0,
            "entries": [
                {
                    "type": "minecraft:item",
                    "functions": [
                        {
                            "function": "minecraft:copy_name",
                            "source": "block_entity"
                        },
                        {
                            "function": "minecraft:copy_nbt",
                            "ops": [
                                {
                                    "op": "replace",
                                    "source": "Lock",
                                    "target": "BlockEntityTag.Lock"
                                },
                                {
                                    "op": "replace",
                                    "source": "LootTable",
                                    "target": "BlockEntityTag.LootTable"
                                },
                                {
                                    "op": "replace",
                                    "source": "LootTableSeed",
                                    "target": "BlockEntityTag.LootTableSeed"
                                }
                            ],
                            "source": "block_entity"
                        },
                        {
                            "type": "minecraft:shulker_box",
                            "entries": [
                                {
                                    "type": "minecraft:dynamic",
                                    "name": "minecraft:contents"
                                }
                            ],
                            "function": "minecraft:set_contents"
                        }
                    ],
                    "name": "minecraft:shulker_box"
                }
            ],
            "rolls": 1.0
        }
    ]
}

0 0 0 以外に shulker_box を置く場合等、条件を変える場合は以下の部分を書き換える必要がある。

                    "conditions": [
                        {
                            "condition": "minecraft:location_check",
                            "predicate": {
                                "block": {
                                    "nbt": "{\"x\":0,\"y\":0,\"z\":0}"
                                }
                            }
                        }
                    ]