プレイヤーのアイテム操作

ページ名:プレイヤーのアイテム操作

プレイヤーのnbtを/dataで操作することは禁止されています。
またバージョン1.14.4まではstore resultで例外的にプレイヤーのアイテムnbtに
数値を保存できていましたが、1.15にてバグとして修正されてしまいました。

ここでは1.15追加コマンドの/data modifyと/lootを用いた
プレイヤーのアイテム操作についてまとめます。


下準備:シュルカーボックスのルートテーブル設定

2020/09/13追記:
サバイバルでシュルカーボックスを壊したとき中身が消滅していたため
ルートテーブルと/lootコマンドの一部を修正しました。
デバッグ棒(サバイバルでは何も壊せない)で/loot ... mineしたときとそれ以外で条件が分かれるようにしています。
追記ここまで


loot ... mine x y z debug_stick
により座標のブロックを破壊したときのドロップをプレイヤーのインベントリに移すことが可能です。
通常のタイルエンティティは/lootしても中のアイテムに関係なくタイルエンティティそのものが入手されますが、
ルートテーブルを書き換えたシュルカーボックスのみ、中のアイテムを受け渡すことが可能になります。

データパックに下記のルートテーブルを追加します。
(色付きのシュルカーボックスはそれぞれ別のルートテーブルになるので注意)
data\minecraft\loot_tables\blocks\shulker_box.json

開く +-

{

  "type": "minecraft:block",

  "pools": [

      {

          "rolls": 1,

          "entries": [

              {

                  "type": "minecraft:alternatives",

                  "children": [

                      {

                          "type": "minecraft:dynamic",

                          "name": "minecraft:contents",

                          "conditions": [

                              {

                                  "condition": "minecraft:match_tool",

                                  "predicate": {

                                      "item": "minecraft:debug_stick"

                                  }

                              }

                          ]

                      },

                      {

                          "type": "minecraft:item",

                          "name": "minecraft:shulker_box",

                          "functions": [

                              {

                                  "function": "minecraft:copy_name",

                                  "source": "block_entity"

                              },

                              {

                                  "function": "minecraft:copy_nbt",

                                  "source": "block_entity",

                                  "ops": [

                                      {

                                          "source": "Lock",

                                          "target": "BlockEntityTag.Lock",

                                          "op": "replace"

                                      },

                                      {

                                          "source": "LootTable",

                                          "target": "BlockEntityTag.LootTable",

                                          "op": "replace"

                                      },

                                      {

                                          "source": "LootTableSeed",

                                          "target": "BlockEntityTag.LootTableSeed",

                                          "op": "replace"

                                      }

                                  ]

                              },

                              {

                                  "function": "minecraft:set_contents",

                                  "entries": [

                                      {

                                          "type": "minecraft:dynamic",

                                          "name": "minecraft:contents"

                                      }

                                  ]

                              }

                          ]

                      }

                  ]

              }

          ]

      }

  ]

}

dynamics functionはシュルカーボックスにのみ利用できる関数であり、
中のアイテムのルートが可能になります。

シュルカーボックスは常に読み込まれるスポーンチャンクかforceloadチャンクに設置します。
状況に応じて2個のシュルカーボックスを設置すると便利です。
以降は下記の座標を用いて説明します。

単体ルート用: 座標 0 1 0  Slot:0bにのみアイテムを入れておく(必須)
複数ルート用: 座標 0 2 0

試しにシュルカーボックスにアイテムを入れて
/loot give @p mine 0 1 0 debug_stick
を実行し、中のアイテムを入手できたら導入成功です。


1. プレイヤーアイテムの取得

/data modifyによりプレイヤーアイテムをnbt操作のできる外部にコピーします。
次の理由から、シュルカーボックスではなく一旦storageにコピーすることが望ましいです。
・エンティティ、タイルエンティティは変更のたびに全nbtが更新されるため負荷が高い
・エンティティ、タイルエンティティは異常のあるアイテムが削除される
 例:プレイヤーの足装備Slot:100bをシュルカーボックスにコピーするとシュルカーボックスのSlot 0~26bの範囲外のため削除される

storageの名前空間とnbt名は任意の値を設定できます。
ここでは単体アイテムはitem Item、複数アイテムはitems Itemsとしています。

2. nbtの変更

storage上でnbtを変更します。
単体アイテムはシュルカーボックスに移すときのためにSlotを削除(=0b)しておきます。

3. プレイヤーにアイテムを移す

/data modifyにより一旦storageからシュルカーボックスにアイテムを移した後、
/loot ... mineによりシュルカーボックスのアイテムをプレイヤーに移動させます。


サンプルコマンド

・手持ちの装備類の耐久値を回復させる

execute as <プレイヤー> でfunction実行:

#手持ちのアイテムをコピー
    data modify storage item Item set from entity @s SelectedItem
#耐久値を削除
    data remove storage item Item.tag.Damage
#Slotを削除
    data remove storage item Item.Slot
#storageからシュルカーボックスに移す
    data modify block 0 1 0 Items[0] set from storage item Item
#手持ちのアイテムを置換
    loot replace entity @s weapon.mainhand 1 mine 0 1 0 debug_stick


・エンダーチェストにあるりんごの個数を64にする

execute as <プレイヤー> でファンクション実行:

#エンダーチェスト全体をコピー
    data modify storage items Items set from entity @s EnderItems
#りんごの個数を64にする
    data modify storage items Items[{id:"minecraft:apple"}].Count set value 64
#storageからシュルカーボックスに移す
    data modify block 0 2 0 Items set from storage items Items
#エンダーチェスト全体を置換
    loot replace entity @s enderchest.0 mine 0 2 0 debug_stick


・インベントリのエメラルドをダイヤモンドに置換する

シュルカーボックスにはインベントリ全体が収まりきらないので1個ずつ処理します。
replace_inventory_by_slotファンクションにて元のスロットにアイテムを戻しています。

execute as <プレイヤー> if data entity @s Inventory[{id:"minecraft:emerald"}] でファンクション実行:

#エメラルド1個をコピー
    data modify storage item Item set from entity @s Inventory[{id:"minecraft:emerald"}]
#ダイヤモンドに置換
    data modify storage item Item.id set value "minecraft:diamond"
#Slotをスコアに保存する(Numberスコアをdummyで作成しておく)
    execute store result score #Slot Number run data get storage item Item.Slot
#Slotを削除する
    data remove storage item Item.Slot
#storageからシュルカーボックスに移す
    data modify block 0 1 0 Items[0] set from storage item Item
#手持ちのアイテムを置換(パスはデータパックに合わせる)
    function replace_inventory_by_slot


replace_inventory_by_slotファンクション:

開く +-

    execute if score #Slot Number matches 0 run loot replace entity @s container.0 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 1 run loot replace entity @s container.1 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 2 run loot replace entity @s container.2 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 3 run loot replace entity @s container.3 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 4 run loot replace entity @s container.4 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 5 run loot replace entity @s container.5 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 6 run loot replace entity @s container.6 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 7 run loot replace entity @s container.7 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 8 run loot replace entity @s container.8 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 9 run loot replace entity @s container.9 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 10 run loot replace entity @s container.10 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 11 run loot replace entity @s container.11 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 12 run loot replace entity @s container.12 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 13 run loot replace entity @s container.13 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 14 run loot replace entity @s container.14 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 15 run loot replace entity @s container.15 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 16 run loot replace entity @s container.16 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 17 run loot replace entity @s container.17 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 18 run loot replace entity @s container.18 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 19 run loot replace entity @s container.19 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 20 run loot replace entity @s container.20 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 21 run loot replace entity @s container.21 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 22 run loot replace entity @s container.22 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 23 run loot replace entity @s container.23 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 24 run loot replace entity @s container.24 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 25 run loot replace entity @s container.25 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 26 run loot replace entity @s container.26 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 27 run loot replace entity @s container.27 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 28 run loot replace entity @s container.28 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 29 run loot replace entity @s container.29 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 30 run loot replace entity @s container.30 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 31 run loot replace entity @s container.31 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 32 run loot replace entity @s container.32 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 33 run loot replace entity @s container.33 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 34 run loot replace entity @s container.34 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 35 run loot replace entity @s container.35 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 100 run loot replace entity @s armor.feet 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 101 run loot replace entity @s armor.legs 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 102 run loot replace entity @s armor.chest 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches 103 run loot replace entity @s armor.head 1 mine 0 1 0 debug_stick
    execute if score #Slot Number matches -106 run loot replace entity @s offhand 1 mine 0 1 0 debug_stick

 

シェアボタン: このページをSNSに投稿するのに便利です。

コメント

返信元返信をやめる

※ 悪質なユーザーの書き込みは制限します。

最新を表示する
teso

シュルカ―のルートテーブルが入ってくれません

返信
2021-05-28 13:33:48

NG表示方式

NGID一覧