Advancementを使ったイベント検知のサンプル集

Advancement とは

イクラの進捗のことですね。

何らかのプレイヤーが行った動き(トリガー)によって、進捗が開放されるアレです。

今回はそれを使って、イベント検知しちゃおうってブログです。

基本的な処理の流れ

こんな感じでやっていきます。

  1. Advancementでトリガーを設定!
  2. 勝手にトリガーが検知!
  3. functionを呼び出す!
  4. /advancement コマンドで取得した進捗をなかったことにする!
  5. やりたいことをやる!

では、まずはAdvancementファイルを作っていきましょう。

root.jsonを追加する

まずは準備として、以下にファイルを作りましょう。

datapacks/<データパック>/data/<パック>/advancements/<名前>/root.json

そして、root.jsonはこんな感じで書いちゃいましょう。ちなみにroot.jsonは必須ファイルです。

※ プレイヤーが見ない部分なので極限まで削ってます。こだわりたい方はこだわってください。

{
    "display": {
        "title": "",
        "description": "",
        "icon": {
            "item": "air"
        }
    },
    "criteria": {
        "": {
            "trigger": "impossible"
        }
    }
}

進捗を追加する

では、イベント取得用の進捗を追加しちゃいましょう。

datapacks/<データパック>/data/<パック>/advancements/<名前>/<イベント>.json

そして中身はこちら。

※ 極限まで削ってます。以下略。

{
    "parent": "<パック>:<名前>/root",
    "display": {
        "title": "",
        "description": "",
        "icon": {
            "item": "air"
        },
        "show_toast": false,
        "announce_to_chat": false,
    },
    "criteria": {
        ★ ここは後で説明します。
    },
    "rewards": {
        "function": "★ 呼び出したいfunctionファイル(x:exec みたいな)"
    }
}

何を追加したのかをざっと説明。

  • parent: この進捗の一つ前の進捗を指定。今回は全部rootにつなげます。
  • display.show_toast: 右上に表示するかどうか。もちろん表示しないので、false。
  • display.announce_to_chat: チャットに表示するかどうか。もちろん表示しないので、false。
  • rewards.function: 進捗が達成されたときに呼び出すfunctionファイル。

トリガーを書く

はい。今回のメインです。前のcriteriaに指定するのですが、詳しく説明を始めると膨大なので、私が使いそうなやつだけピックアップ!

他のトリガーや詳しい条件など見たい方はこちらを見てね。

https://minecraft-ja.gamepedia.com/%E9%80%B2%E6%8D%97/JSON%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88

https://minecraft.gamepedia.com/Advancement/JSON_format

特定の村人に話しかけた

「村人A」という名前がついた村人に話しかけたときにイベント発生させる例。

1.16で追加されたトリガー。

{
    "criteria": {
        "": {
            "trigger": "player_interacted_with_entity",
            "conditions": {
                "entity": {
                    "type": "villager",
                    "nbt": "{CustomName:'{\"text\":\"村人A\"}'}"
                }
            }
        }
    }
}

ちなみに村人は下のコマンドで召喚すると、取引画面が出ません。

summon villager ~ ~ ~ {NoAI:true,Offers:[],CustomName:'"村人A"'}

特定のアイテムを使った

event:special というタグがついたリンゴを食べたときにイベント発生させる例。

{
    "criteria": {
        "": {
            "trigger": "consume_item",
            "conditions": {
                "item": {
                    "item": "apple",
                    "nbt": "{event:special}"
                }
            }
        }
    }
}

ちなみに上のアイテムは下のコマンドで手に入ります。(アイテムなら任意のタグがつけられます)

give @p apple{event:special}

特定のモブにダメージを受けた

ケルトンが打った矢でダメージ受けたときにイベント発生させる例。

{
    "criteria": {
        "": {
            "trigger": "entity_hurt_player",
            "conditions": {
                "damage": {
                    "source_entity": {
                        "type": "skeleton",
                        "direct_entity": {
                            "type": "arrow"
                        }
                    }
                }
            }
        }
    }
}

特定のモブに倒された

クリーパーの爆発で倒されたときにイベント発生させる例。

{
    "criteria": {
        "": {
            "trigger": "entity_killed_player",
            "conditions": {
                "entity": {
                    "type": "creeper"
                },
                "killing_blow": {
                    "is_explosion": true
                }
            }
        }
    }
}

特定のモブにダメージを与えた

プレイヤーにダメージを与えたときにイベント発生させる例。

{
    "criteria": {
        "": {
            "trigger": "player_hurt_entity",
            "conditions": {
                "entity": {
                    "type": "player"
                }
            }
        }
    }
}

特定のモブを倒した

ダイヤ剣でモブを倒したときにイベント発生させる例。

{
    "criteria": {
        "": {
            "trigger": "player_killed_entity",
            "conditions": {
                "killing_blow": {
                    "source_entity": {
                        "nbt": "{SelectedItem:{id:\"minecraft:diamond_sword\"}}"
                    }
                }
            }
        }
    }
}

特定のブロックを置いた

石をxが-100、yが1~10の間、zが100~110の間に置いたときにイベント発生させる例。

{
    "criteria": {
        "": {
            "trigger": "placed_block",
            "conditions": {
                "item": {
                    "item": "stone"
                },
                "location": {
                    "position": {
                        "x": -100,
                        "y": {
                            "max": 10,
                            "min": 1
                        },
                        "z": {
                            "max": 110,
                            "min": 100
                        }
                    }
                }
            }
        }
    }
}

functionファイルで進捗を消す

イベントが一回しか取得できないのは困りますよね。

ということで、呼び出された瞬間に進捗をなかったことにしちゃいましょう。

# 呼び出されたので進捗を消す
advancement revoke @s only <パック>:<名前>/<イベント>

# 消したらなにかする
tellraw @s "Hello World!"

@sを使っていますね。そうです。進捗を達成したプレイヤーがfunctionファイルを呼び出したことになるので、@sが使えちゃいます!

トリガーの種類も条件もいっぱいある

ということで、進捗でイベントを取得してコマンドを実行する方法でした。

トリガーは数十種類ありますし、条件もかなり大量にあります。あなたがやりたいことが見つかるかも?