ルッキーのコマンドメモ

主にマイクラのコマンドやデータパックに関することを書いていきます。

(マイクラ コマンド・データパック) プレイヤが食べ物を食べたことをしらべる方法

食べ物を食べたことを検知する

今回は特定の食べ物を食べたことを検知してコマンドを実行する方法を紹介します。
これを利用すると、食べるとエフェクトのかかる食料を作ることができます。

目次

特定の食べ物を食べたことを検知する

スコアボードを使う方法

食べ物を食べたことはスコアボードを使うことで調べることができます。 あらかじめ、以下のコマンドを実行してスコアを作成します。

# eatという特定の食べ物を食べたことを検知するスコアを作成
scoreboard objectives add eat minecraft.used:minecraft.<検知したい食べ物>

そして、スコアが1以上になったプレイヤに対してコマンドを実行することで、その食べ物を食べたプレイヤに対してコマンドを動かせます。

# eatのスコアが1以上の時にそのプレイヤに耐性のエフェクトをかける
execute as @a if score @s eat matches 1.. run effect give @s minecraft:resistance 3 0
# スコアをリセットする
scoreboard players reset @a eat

advancementを利用する方法

advancementのconsume_itemを利用する方法でも食料を食べたことを検知することができます。
データパック内でdata/<名前空間>/advancements/<好きな名前>.jsonというようにファイルをつくり、以下のように記述します。

{
  "criteria": {
    "requirement": {
      "trigger": "minecraft:consume_item",
      "conditions": {
        "item": {
          "items": [
            "minecraft:<検知したい食べ物>"
          ]
        }
      }
    }
  }
}

そしてコマンドでこの進捗を達成しているプレイヤに対してコマンドを実行することで、食料を食べたプレイヤにコマンドを実行できます。

execute as @a[advancements={<名前空間>:<設定した名前>=true}] run effect give @s minecraft:resistance 3 0
advancement revoke @a only <名前空間>:<設定した名前>

あるいは、以下のようにadvancementの達成報酬としてfunctionを実行する方法もあります。

<名前空間>:<設定した名前>.json

{
  "criteria": {
    "requirement": {
      "trigger": "minecraft:consume_item",
      "conditions": {
        "item": {
          "items": [
            "minecraft:<検知したい食べ物>"
          ]
        }
      }
    }
  },
  "rewards": {"<名前空間>:<function名>"}
}

<名前空間>:<function名>.mcfunction

effect give @s minecraft:resistance 3 0
advancement revoke @s only <名前空間>:<設定した名前>

少し面倒に感じますが、function内で@s以外のセレクタを使う必要がなく、進捗が達成された時にしかfunctionを実行しなくていいので、処理が軽くなるという利点があります。

ケーキを食べたことを検知する場合

ケーキを食べたことを検知する場合、上記の方法では検知することができません。 以下のようなスコアボードを設定して、検知します。

# eat_cakeというケーキを食べたことを検知するスコアを作成
scoreboard objectives add eat_cake minecraft.custom:minecraft.eat_cake_slice

eat_cake.mcfunction

# eat_cakeのスコアが1以上の時にそのプレイヤに耐性のエフェクトをかける
execute as @a if score @s eat_cake matches 1.. run effect give @s minecraft:resistance 3 0
# スコアをリセットする
scoreboard players reset @a eat_cake

複数の食べ物のうちのどれかを食べたことを検知する場合

複数の食べ物うちのどれかを食べたことを検知したい場合には、単純にスコアの数を増やせば良いです。 しかし、スコアによって検知する方法では食べ物の数が増えると大変になる上、個別にexecute if コマンドを実行することになるので処理も重くなってしまいます。
以下に魚を食べたことを検知する例のスコアボードによる実装とadvancementによる実装をそれぞれ示します。

スコアボードによる実装

あらかじめ使用しておく

# スコアボードの作成
scoreboard objectives add eat_cod minecraft.used:minecraft.cod
scoreboard objectives add eat_cooked_cod minecraft.used:minecraft.cooked_cod
scoreboard objectives add eat_salmon minecraft.used:minecraft.salmon
scoreboard objectives add eat_cooked_salmon minecraft.used:minecraft.cooked_salmon
scoreboard objectives add eat_pufferfish minecraft.used:minecraft.pufferfish
scoreboard objectives add eat_tropical_fish minecraft.used:minecraft.tropical_fish

検知用function

# 魚を食べたプレイヤにエフェクトをかける
execute as @a if score @s eat_cod matches 1.. run effect give @s minecraft:resistance 3 0
execute as @a if score @s eat_cooked_cod matches 1.. run effect give @s minecraft:resistance 3 0
execute as @a if score @s eat_salmon matches 1.. run effect give @s minecraft:resistance 3 0
execute as @a if score @s eat_cooked_salmon matches 1.. run effect give @s minecraft:resistance 3 0
execute as @a if score @s eat_pufferfish matches 1.. run effect give @s minecraft:resistance 3 0
execute as @a if score @s eat_tropical_fish matches 1.. run effect give @s minecraft:resistance 3 0
# スコアをリセットする
scoreboard players reset @a eat_cod
scoreboard players reset @a eat_cooked_cod
scoreboard players reset @a eat_salmon
scoreboard players reset @a eat_cooked_salmon
scoreboard players reset @a eat_pufferfish
scoreboard players reset @a eat_tropical_fish

advancementによる実装

eat_fish.json

{
  "criteria": {
    "requirement": {
      "trigger": "minecraft:consume_item",
      "conditions": {
        "item": {
          "items": [
            "minecraft:tropical_fish",
            "minecraft:pufferfish",
            "minecraft:cooked_salmon",
            "minecraft:salmon",
            "minecraft:cooked_cod",
            "minecraft:cod"
          ]
        }
      }
    }
  },
  "rewards": {"<名前空間>:eat_fish"}
}

eat_fish.mcfunction

effect give @s minecraft:resistance 3 0
advancement revoke @s only <名前空間>:eat_fish

このように、検知したい食べ物の種類が複数ある場合には、advancementを使った方が簡単で、処理も軽くなります。

全ての食べ物のうちのどれかを食べたことを検知したい

おまけとして、全ての食べ物のうちのどれかを食べたことを検知するadvancementを載せておきます

eat_food.json

{
  "criteria": {
    "requirement": {
      "trigger": "minecraft:consume_item",
      "conditions": {
        "item": {
          "items": [
            "minecraft:suspicious_stew",
            "minecraft:rabbit_stew",
            "minecraft:beetroot_soup",
            "minecraft:mushroom_stew",
            "minecraft:spider_eye",
            "minecraft:rotten_flesh",
            "minecraft:pumpkin_pie",
            "minecraft:cookie",
            "minecraft:bread",
            "minecraft:pufferfish",
            "minecraft:tropical_fish",
            "minecraft:cooked_salmon",
            "minecraft:salmon",
            "minecraft:cooked_cod",
            "minecraft:cod",
            "minecraft:cooked_rabbit",
            "minecraft:rabbit",
            "minecraft:cooked_chicken",
            "minecraft:chicken",
            "minecraft:cooked_mutton",
            "minecraft:mutton",
            "minecraft:cooked_porkchop",
            "minecraft:porkchop",
            "minecraft:cooked_beef",
            "minecraft:beef",
            "minecraft:dried_kelp",
            "minecraft:beetroot",
            "minecraft:poisonous_potato",
            "minecraft:baked_potato",
            "minecraft:potato",
            "minecraft:golden_carrot",
            "minecraft:carrot",
            "minecraft:chorus_fruit",
            "minecraft:glow_berries",
            "minecraft:sweet_berries",
            "minecraft:melon_slice",
            "minecraft:enchanted_golden_apple",
            "minecraft:golden_apple",
            "minecraft:apple"
          ]
        }
      }
    }
  }
}

これと、ケーキを食べたことを検知する方法を利用することで、プレイヤが何かアイテムを食べたことを検知できます。

まとめ

特定の食べ物を食べたことを検知する場合にはスコアボードかadvancementを使うことができます。
検知したい食べ物が1,2個程度で比較的少ない場合にはスコアボードによる実装が簡単ですが、検知したい食べ物がたくさんある場合にはadvancementを使って実装する方が簡単で処理も軽くなります。