[ScriptAPI参考書] イベントの操作 アフターイベント編 #5

# 目次

<ul>
    <li><a href="#はじめに">はじめに</a></li>
    <li><a href="#アフターイベントとは">アフターイベントとは</a></li>
    <li><a href="#注意点">注意点</a></li>
    <li>
        <a href="#worldafterevents">WorldAfterEvents</a>
        <ul>
            <li>
                <details>
                    <summary><a href="#ワールド関連">ワールド関連</a></summary>
                    <ul>
                        <li><a href="#gamerulechange">GameRuleChange</a></li>
                        <li><a href="#messagereceive">MessageReceive</a></li>
                        <li><a href="#weatherchange">WeatherChange</a></li>
                        <li><a href="#worldload">WorldLoad</a></li>
                    </ul>
                </details>
            </li>
            <li>
                <details>
                    <summary><a href="#ブロック関連">ブロック関連</a></summary>
                    <ul>
                        <li><a href="#blockexplode">BlockExplode</a></li>
                        <li><a href="#buttonpush">ButtonPush</a></li>
                        <li><a href="#leveraction">LeverAction</a></li>
                        <li><a href="#pistonactivate">PistonActivate</a></li>
                        <li><a href="#pressureplatepop">PressurePlatePop</a></li>
                        <li><a href="#pressureplatepush">PressurePlatePush</a></li>
                        <li><a href="#targetblockhit">TargetBlockHit</a></li>
                        <li><a href="#tripwiretrip">TripWireTrip</a></li>
                    </ul>
                </details>
            </li>
            <li>
                <details>
                    <summary><a href="#エンティティ関連">エンティティ関連</a></summary>
                    <ul>
                        <li><a href="#datadrivenentitytrigger">DataDrivenEntityTrigger</a></li>
                        <li><a href="#effectadd">EffectAdd</a></li>
                        <li><a href="#entitydie">EntityDie</a></li>
                        <li><a href="#entityhealthchanged">EntityHealthChanged</a></li>
                        <li><a href="#entityhitblock">EntityHitBlock</a></li>
                        <li><a href="#entityhitentity">EntityHitEntity</a></li>
                        <li><a href="#entityhurt">EntityHurt</a></li>
                        <li><a href="#entityload">EntityLoad</a></li>
                        <li><a href="#entityremove">EntityRemove</a></li>
                        <li><a href="#entityspawn">EntitySpawn</a></li>
                        <li><a href="#explosion">Explosion</a></li>
                        <li><a href="#projectilehitblock">ProjectileHitBlock</a></li>
                        <li><a href="#projectilehitentity">ProjectileHitEntity</a></li>
                    </ul>
                </details>
            </li>
            <li>
                <details>
                    <summary><a href="#プレイヤー関連">プレイヤー関連</a></summary>
                    <ul>
                        <li><a href="#chatsend">ChatSend</a></li>
                        <li><a href="#itemcompleteuse">ItemCompleteUse</a></li>
                        <li><a href="#itemreleaseuse">ItemReleaseUse</a></li>
                        <li><a href="#itemstartuse">ItemStartUse</a></li>
                        <li><a href="#itemstopuse">ItemStopUse</a></li>
                        <li><a href="#itemuse">ItemUse</a></li>
                        <li><a href="#itemstartuseon">ItemStartUseOn</a></li>
                        <li><a href="#itemstopuseon">ItemStopUseOn</a></li>
                        <li><a href="#playerbreakblock">PlayerBreakBlock</a></li>
                        <li><a href="#playerplaceblock">PlayerPlaceBlock</a></li>
                        <li><a href="#playerdimensionchange">PlayerDimensionChange</a></li>
                        <li><a href="#playeremote">PlayerEmote</a></li>
                        <li><a href="#playergamemodechange">PlayerGameModeChange</a></li>
                        <li><a href="#playerinputpermissioncategorychange">PlayerInputPermissionCategoryChange</a></li>
                        <li><a href="#playerinteractwithblock">PlayerInteractWithBlock</a></li>
                        <li><a href="#playerinteractwithentity">PlayerInteractWithEntity</a></li>
                        <li><a href="#playerjoin">PlayerJoin</a></li>
                        <li><a href="#playerleave">PlayerLeave</a></li>
                        <li><a href="#playerspawn">PlayerSpawn</a></li>
                    </ul>
                </details>
            </li>
        </ul>
    </li>
    <li>
        <a href="#systemafterevents">SystemAfterEvents</a>
        <ul>
            <li>
                <details>
                    <summary><a href="#システム関連">システム関連</a></summary>
                    <ul>
                        <li><a href="#scripteventreceive">ScriptEventReceive</a></li>
                    </ul>
                </details>
            </li>
        </ul>
    </li>
    <li><a href="#最後に">最後に</a></li>
</ul>

# はじめに
前回に引き続き、ScriptAPIの基本、イベントの操作を扱っていきます。
前回の予告通りどのようなイベントがあるのかを紹介します。
前編で紹介しましたが、ScriptAPIのイベントにはアフターイベントとビフォーイベントの二種類存在し、本編はその内のアフターイベントの内容となっています。

ScriptAPIではバージョンによってイベント名の変更やイベントの追加、削除が行われている為、情報が一致しない可能性のあることに留意した後、本記事を御一読頂けると幸いです。
本編は2025/03/26時点で最新のベータ版`2.0.0-beta`の内容になります。([ここ](https://www.npmjs.com/package/@minecraft/server?activeTab=versions)で最新の公開されているバージョンを確認することが出来ます。)

以下の前編の構造編を理解することによって、よりスムーズに本記事を読む事が出来ます。文章量も抑えていますので、時間に余裕がある方は是非御一読下さい。

https://qiita.com/yuki2825624/items/ee561a01ffd3c9fcdf24

この「ScriptAPI参考書」シリーズではマインクラフト統合版のScriptAPIについて基礎から応用、例文まで詳細に解説し、ScriptAPI開発者や、ScriptAPIの開発を始めようと思っている人の助けになることを目的としています。

また、このシリーズを読むにあたって、ある程度のマインクラフトとJavaScriptの事前知識が必要になってくることがあります。

*注意: このシリーズではMinecraft Bedrock Editionを省略してマインクラフトと表記しています。*

前回: [イベントの操作 構造編](https://qiita.com/yuki2825624/items/ee561a01ffd3c9fcdf24)
次回: 準備中...

# 注意点
本記事を読んで頂くにあたって注意点が幾つかあります。
本シリーズでは初心者向けの記事である側面があるため、コードに非効率な部分などが存在する場合があります。主な要素として、型の使用が厳密ではない、コードが冗長、等が挙げられます。
その為、あまりコードの内容については重箱の隅をつつかないようにお願い致します。ただ、根本的に誤っている部分があれば是非コメント欄でお伝え下さい。

# アフターイベントとは
前編でも解説しましたが、前編から抜粋して解説いたします。

ScriptAPIにおけるアフターイベントとは、任意のイベントが発生した後に実行されるイベントです。
この仕様から、イベントが発生した前と後で変化があるようなイベント(例えば、ブロックが破壊された時に実行されるようなイベント)の場合、発生する前の情報を取得するのには適していません。
但し、イベントが発生する前の情報をイベントのデータとして持つイベントも存在しています。
基本的に、ビフォーイベントと比べてアフターイベントを使用する頻度が高く、イベントの量も多くなっています。

# WorldAfterEvents

## ワールド関連

### GameRuleChange
#### 説明
ゲームルールが変更された時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/gamerulechangeafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly rule: GameRule**
変更されたゲームルール

- **readonly value: boolean | number**
変更された後の値
:::

#### 例文
ランダムティックスピードが100を超えたときに警告メッセージを送信する
```js:GameRuleChange
import { world, GameRule } from "@minecraft/server";

world.afterEvents.gameRuleChange.subscribe((ev) => {
    const { rule, value } = ev;
    if (rule === GameRule.RandomTickSpeed && value > 100) {
        world.sendMessage(`${GameRule.RandomTickSpeed}が100を超えています。`);
    }
});
```

### MessageReceive
#### 説明
クライアントからサーバーにメッセージを渡すために使用される、現在内部にある特定のイベント

様々な記事等から情報を収集、また、実験等を行いましたが、有益な情報を得ることが出来ませんでした。ご存じの方は、コメント等にてお教え頂けると幸いです。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/messagereceiveafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly id: string**
受け取ったメッセージの識別子

- **readonly message: string**
受け取ったメッセージ

- **readonly player: Player**
送信したプレイヤー
:::

#### 例文
```js:MessageRecive
import { world } from "@minecraft/server";

world.afterEvents.messageReceive.subscribe((ev) => {
    // 詳細不明
});
```

### WeatherChange
#### 説明
天候が変化した時に実行されるイベント
`/toggledownfall`を使用して天候を切り替えた場合、このイベントは実行されません。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/weatherchangeafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ
- **readonly dimension: Dimension**
天候が変化したディメンション

- **readonly previousWeather: WeatherType**
変化する前の天候

- **readonly newWeather: WeatherType**
変化した後の天候
:::

#### 例文
天候が変化した時、現在の天候を送信する
```js:WeatherChange
import { world } from "@minecraft/server";

world.afterEvents.weatherChange.subscribe((ev) => {
    const { newWeather } = ev;
    // 例) 現在の天候は Thunder です。
    world.sendMessage(`現在の天候は ${newWeather} です。`);
});
```

### WorldLoad
#### 説明
ワールドのスクリプト環境が初期化(起動)した時に実行するイベント

#### 例文
スクリプト環境が初期化された時にメッセージを送信する
```js:WorldInitialize
import { world } from "@minecraft/server";

world.afterEvents.worldLoad.subscribe(() => {
    world.sendMessage("スクリプトが読み込まれました。");
});
```

## ブロック関連

### BlockExplode
#### 説明
爆発によりブロックが破壊された時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/blockexplodeafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly dimension: Dimension**
爆発が発生したディメンション

- **readonly block: Block**
爆発により破壊されたブロック
`Block`クラスの為、爆発前の情報は扱えません。

- **readonly source?: Entity**
爆発したエンティティ

- **readonly explodedBlockPermutation: BlockPermutation**
爆発により破壊されたブロックの破壊される前の`BlockPermutation`
爆発前のブロックの情報を扱いたいのであれば、`block`ではなくこちらを使用してください。
:::

#### 例文
TNTの爆発により破壊されたブロックをコンテンツログに出力する
```js:BlockExplode
import { world } from "@minecraft/server";

world.afterEvents.blockExplode.subscribe((ev) => {
    const { source, explodedBlockPermutation } = ev;
    if (source?.typeId === "minecraft:tnt") {
        // 例) minecraft:dirt
        console.log(explodedBlockPermutation.type.id);
    }
});
```

### ButtonPush
#### 説明
ボタンが押された時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/buttonpushafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly dimension: Dimension**
ボタンが押されたディメンション

- **readonly block: Block**
押されたボタン

- **readonly source: Entity**
ボタンを押したエンティティ
:::

#### 例文
`(0, 0, 0)`に設置されたボタンを押したエンティティをkillする
```js:ButtonPush
import { world } from "@minecraft/server";

world.afterEvents.buttonPush.subscribe((ev) => {
    const { source, block } = ev;
    if (block.x === 0 && block.y === 0 && block.z === 0) {
        source.kill();
    }
});
```

### LeverAction
#### 説明
レバーが引かれた時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/leveractionafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly dimension: Dimension**
レバーが引かれたディメンション

- **readonly block: Block**
引かれたレバー

- **readonly isPowered: boolean**
レバーがオンになっているか

- **readonly player: Player**
レバーを引いたプレイヤー
:::

#### 例文
任意のレバーがオンになった時に、レバーの座標を送信する
```js:LeverAction
import { world } from "@minecraft/server";

world.afterEvents.leverAction.subscribe((ev) => {
    const { block, isPowered } = ev;
    if (isPowered) {
        world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) のレバーがオンになりました。`);
    }
});
```

### PressurePlatePop
#### 説明
感圧版が上がった時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/pressureplatepopafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly dimension: Dimension**
感圧版が上がったディメンション

- **readonly block: Block**
上がった感圧版

- **readonly previousRedstonePower: number**
上がる前の感圧版のレッドストーン信号の強度

- **readonly redstonePower: number**
上がった後の感圧版のレッドストーン信号の強度
:::

#### 例文
感圧版が上がった時にメッセージを送信する
```js:PressurePlatePop
import { world } from "@minecraft/server";

world.afterEvents.pressurePlatePop.subscribe((ev) => {
    const { block } = ev;
    world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) の感圧版が上がりました。`);
});
```

### PressurePlatePush
#### 説明
感圧版が下がった時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/pressureplatepushafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly dimension: Dimension**
感圧版が下がったディメンション

- **readonly block: Block**
下がった感圧版

- **readonly previousRedstonePower: number**
下がる前の感圧版のレッドストーン信号の強度

- **readonly redstonePower: number**
下がった後の感圧版のレッドストーン信号の強度
:::

#### 例文
感圧版が下がった時にメッセージを送信する
```js:PressurePlatePop
import { world } from "@minecraft/server";

world.afterEvents.pressurePlatePush.subscribe((ev) => {
    const { block } = ev;
    world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) の感圧版が下がりました。`);
});
```

### PistonActivate
#### 説明
ピストンの状態が変化した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/pistonactivateafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly dimension: Dimension**
ピストンの状態が変化したディメンション

- **readonly block: Block**
状態が変化したピストン

- **readonly piston: BlockPistonComponent**
状態が変化したピストンのコンポーネント

- **readonly isExpanding: boolean**
状態が変化したピストンが押されている最中か否か
:::

#### 例文
ピストンが押された時にメッセージを送信する

```js:PistonActivate
import { world } from "@minecraft/server";

world.afterEvents.pistonActivate.subscribe((ev) => {
    const { block, isExpanding } = ev;

    if (isExpanding) {
        world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) のピストンが押されました。`);
    }
});
```

### TargetBlockHit
#### 説明
ターゲットブロックに投擲物がヒットした時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/targetblockhitafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly dimension: Dimension**
ターゲットブロックにヒットしたディメンション

- **readonly block: Block**
ヒットしたターゲットブロック

- **readonly hitVector: Vector3**
ターゲットブロックにヒットしたエンティティの座標

- **readonly source: Entity**
ターゲットブロックにヒットしたエンティティ

- **readonly previousRedstonePower: number**
ヒットする前のターゲットブロックのレッドストーン信号の強度

- **readonly redstonePower: number**
ヒットした後のターゲットブロックのレッドストーン信号の強度
:::

#### 例文
ターゲットブロックにエンティティがヒットした時、そのエンティティのtypeIdを送信する
```js:TargetBlockHit
import { world } from "@minecraft/server";

world.afterEvents.targetBlockHit.subscribe((ev) => {
    const { block, source } = ev;
    // 例) (11, 65, 24) のターゲットブロックに minecraft:arrow がヒットしました。
    world.sendMessage(`(${block.x}, ${block.y}, ${block.z}) のターゲットブロックに ${source.typeId} がヒットしました。`);
});
```

### TripWireTrip
#### 説明
エンティティが糸に引っかかった、若しくは離れた時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/tripwiretripafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly dimension: Dimension**
エンティティが糸に引っかかった、若しくは離れたディメンション

- **readonly block: Block**
エンティティが引っかかった、若しくは離れた糸

- **readonly isPowered: boolean**
エンティティが引っかかった、若しくは離れた糸にレッドストーン信号があるか否か
糸がトリップワイヤーフック等に接続されていなくとも、引っかかった時に`true`、離れた時に`false`となります。

- **readonly sources: Entity[]**
糸に引っかかったエンティティの配列
同時に複数のエンティティが糸に引っかかると配列の要素が複数になります。
但し、エンティティが糸から離れた時は空の配列になります。
:::

#### 例文
トリップワイヤーフックに引っかかったエンティティに対して暗闇を10秒間付与する
```js:TripWireTrip
import { world, TicksPerSecound } from "@minecraft/server";

world.afterEvents.tripWireTrip.subscribe((ev) => {
    const { sources, isPowered } = ev;

    if (isPowered) for (const source of Array.from(sources)) {
        source.addEffect("minecraft:darkness", TicksPerSecond * 10);
    }
});
```

## エンティティ関連

### DataDrivenEntityTrigger
#### 説明
エンティティのイベントがトリガーされた時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/datadrivenentitytriggerafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ
- **getModifiers(): DefinitionModifier[]**
トリガーされたイベントのコンポーネントの状態の変更の更新可能な配列を取得する関数

- **readonly entity: Entity**
イベントをトリガーしたエンティティ

- **readonly eventId: string**
トリガーしたイベント名
:::

:::note info
###### 登録オプション
- **entities?: Entity[]**
イベントをトリガーしたエンティティ

- **entityTypes?: string[]**
イベントをトリガーしたエンティティのtypeId

- **eventTypes?: string[]**
トリガーしたイベントタイプ
:::

#### 例文
クリーパーが爆発し始めた際にメッセージを送信する
```js:DataDrivenEntityTrigger
import { world } from "@minecraft/server";

world.afterEvents.dataDrivenEntityTrigger.subscribe((ev) => {
    const { entity, eventId } = ev;
    const { x, y, z } = entity.location;
    if (entity.typeId === "minecraft:creeper" && eventId === "minecraft:start_exploding_forced") {
        world.sendMessage(`(${x}, ${y}, ${z}) でクリーパーが爆発します。`);
    }
});
```

上記に登録オプションを使用した例
```js:DataDrivenEntityTrigger
import { world } from "@minecraft/server";

world.afterEvents.dataDrivenEntityTrigger.subscribe((ev) => {
    const { entity } = ev;
    const { x, y, z } = entity.location;
    world.sendMessage(`(${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}) でクリーパーが爆発します。`);
}, {
    entityTypes: ["minecraft:creeper"],
    eventTypes: ["minecraft:start_exploding_forced"]
});
```

### EffectAdd
#### 説明
エンティティにエフェクトが付与された時に実行されるイベント
既にエンティティに同一のエフェクトが付与されている場合、このイベントは実行されません。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/effectaddafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ
- **readonly entity: Entity**
エフェクトを付与されたエンティティ

- **readonly effect: Effect**
付与されたエフェクト
:::

:::note info
###### 登録オプション
- **entities?: Entity[]**
エフェクトを付与されたエンティティ

- **entityTypes?: string[]**
エフェクトを付与されたエンティティのtypeId
:::

#### 例文
プレイヤーにエフェクトが付与された時、付与されたエフェクトの内容を送信する
```js:EffectAdd
import { world, Player, TicksPerSecound } from "@minecraft/server";

world.afterEvents.effectAdd.subscribe((ev) => {
    const { entity, effect } = ev;
    if (!(entity instanceof Player)) return;
    // 例) Steve に 10秒間 再生能力 III が付与されました。 
    world.sendMessage(`${entity.name} に ${effect.duration / TicksPerSecond}秒間 ${effect.displayName} が付与されました。`);
});
```

上記に登録オプションを使用した例
```js:EffectAdd
import { world, TicksPerSecound } from "@minecraft/server";

world.afterEvents.effectAdd.subscribe((ev) => {
    const { entity, effect } = ev;
    world.sendMessage(`${entity.name} に ${effect.duration / TicksPerSecond}秒間 ${effect.displayName} が付与されました。`);
}, {
    entityTypes: ["minecraft:player"]
});
```

### EntityDie
#### 説明
エンティティが死亡した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/entitydieafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ
- **readonly deadEntity: Entity**
死亡したエンティティ

- **readonly damageSource: EntityDamageSource**
死亡した原因の情報
:::

:::note info
###### 登録オプション
- **entities?: Entity[]**
死亡したエンティティ

- **entityTypes?: string[]**
死亡したエンティティのtypeId
:::

#### 例文
プレイヤーが死亡した時、殺害したエンティティのtypeIdを送信する
```js:EntityDie
import { world, Player } from "@minecraft/server";

world.afterEvents.entityDie.subscribe((ev) => {
    const { deadEntity, damageSource } = ev;
    const { damagingEntity } = damageSource;
    if (!(deadEntity instanceof Player)) return;
    if (damagingEntity) {
        // 例) Steve は minecraft:wither に殺害されました。
        world.sendMessage(`${deadEntity.name} は ${damagingEntity.typeId} に殺害されました。`);
    } 
});
```

上記に登録オプションを使用した例
```js:EntityDie
import { world } from "@minecraft/server";

world.afterEvents.entityDie.subscribe((ev) => {
    const { deadEntity, damageSource } = ev;
    const { damagingEntity } = damageSource;
    if (damagingEntity) {
        // 例) Steve は minecraft:wither に殺害されました。
        world.sendMessage(`${deadEntity.name} は ${damagingEntity.typeId} に殺害されました。`);
    } 
}, {
    entityTypes: ["minecraft:player"]
});
```

### EntityHealthChanged
#### 説明
エンティティの体力が変化した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/entityhealthchangedafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ
- **readonly entity: Entity**
体力が変化したエンティティ

- **readonly oldValue: number**
変化する前の体力

- **readonly newValue: number**
変化した後の体力
:::

:::note info
###### 登録オプション
- **entities?: Entity[]**
体力が変化したエンティティ

- **entityTypes?: string[]**
体力が変化したエンティティのtypeId
:::

#### 例文
プレイヤーにプレイヤーの体力の増減を送信する
```js:EntityHealthChanged
import { world, Player } from "@minecraft/server";

world.afterEvents.entityHealthChanged.subscribe((ev) => {
    const { entity, newValue, oldValue } = ev;

    if (!(entity instanceof Player)) return;
    const delta = newValue - oldValue;
    if (delta > 0) {
        entity.sendMessage(`体力が ${delta} 増加しました。`);
    }
    if (delta < 0) {
        entity.sendMessage(`体力が ${Math.abs(delta)} 減少しました。`);
    }
});
```

上記に登録オプションを使用した例
```js:EntityHealthChanged
import { world } from "@minecraft/server";

world.afterEvents.entityHealthChanged.subscribe((ev) => {
    const { entity, newValue, oldValue } = ev;

    const delta = newValue - oldValue;
    if (delta > 0) {
        entity.sendMessage(`体力が ${delta} 増加しました。`);
    }
    if (delta < 0) {
        entity.sendMessage(`体力が ${Math.abs(delta)} 減少しました。`);
    }
}, {
    entityTypes: ["minecraft:player"]
});
```

### EntityHitBlock
#### 説明
エンティティがブロックに対して攻撃を行った時に実行されるイベント
矢やトライデント等の投擲による攻撃は[`ProjectileHitBlock`](#projectilehitblock)なので注意して下さい。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/entityhitblockafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly damagingEntity: Entity**
攻撃を行ったエンティティ

- **readonly hitBlock: Block**
攻撃されたブロック

- **readonly hitBlockPermutation: BlockPermutation**
攻撃されたブロックの`BlockPermutation`
ブロックの情報を扱いたいのであれば`hitBlock`ではなくこちらを使用してください。

- **readonly blockFace: Direction**
攻撃されたブロックの面の方角
:::

:::note info
###### 登録オプション
- **entities?: Entity[]**
攻撃を行ったエンティティ

- **entityTypes?: string[]**
攻撃を行ったエンティティのtypeId
:::

#### 例文
プレイヤーがブロックを攻撃した時、攻撃されたブロックのtypeIdを送信する
```js:EntityHitBlock
import { world, Player } from "@minecraft/server";

world.afterEvents.entityHitBlock.subscribe((ev) => {
    const { damagingEntity, hitBlock } = ev;
    if (!(damagingEntity instanceof Player)) return;
    // 例) Steve が minecraft:diamond_block を攻撃しました。
    world.sendMessage(`${damagingEntity.name} が ${hitBlock.typeId} を攻撃しました。`);
});
```

上記に登録オプションを使用した例
```js:EntityHitBlock
import { world } from "@minecraft/server";

world.afterEvents.entityHitBlock.subscribe((ev) => {
    const { damagingEntity, hitBlock } = ev;
    // 例) Steve が minecraft:diamond_block を攻撃しました。
    world.sendMessage(`${damagingEntity.name} が ${hitBlock.typeId} を攻撃しました。`);
}, {
    entityTypes: ["minecraft:player"]
});
```

### EntityHitEntity
#### 説明
エンティティがエンティティに対して攻撃を行って時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/entityhitentityafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly damagingEntity: Entity**
攻撃を行ったエンティティ

- **readonly hitEntity: Entity**
攻撃されたエンティティ
:::

:::note info
###### 登録オプション
- **entities?: Entity[]**
攻撃を行ったエンティティ

- **entityTypes?: string[]**
攻撃を行ったエンティティのtypeId
:::


#### 例文
プレイヤーがエンティティを攻撃した時、攻撃されたエンティティのtypeIdを送信する
```js:EntityHitEntity
import { world, Player } from "@minecraft/server";

world.afterEvents.entityHitBlock.subscribe((ev) => {
    const { damagingEntity, hitEntity } = ev;
    if (!(damagingEntity instanceof Player)) return;
    // 例) Steve が minecraft:cow を攻撃しました。
    world.sendMessage(`${damagingEntity.name} が ${hitEntity.typeId} を攻撃しました。`);
});
```

上記に登録オプションを使用した例
```js:EntityHitEntity
import { world } from "@minecraft/server";

world.afterEvents.entityHitEntity.subscribe((ev) => {
    const { damagingEntity, hitEntity } = ev;
    // 例) Steve が minecraft:cow を攻撃しました。
    world.sendMessage(`${damagingEntity.name} が ${hitEntity.typeId} を攻撃しました。`);
}, {
    entityTypes: ["minecraft:player"]
});
```

### EntityHurt
#### 説明
エンティティがダメージを受けた時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/entityhurtafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly hurtEntity: Entity**
ダメージを受けたエンティティ

- **readonly damage: number**
受けたダメージ量

- **readonly damageSource: EntityDamageSource**
ダメージを受けた原因の情報
:::

:::note info
###### 登録オプション
- **entities?: Entity[]**
ダメージを受けたエンティティ

- **entityTypes?: string[]**
ダメージを受けたエンティティのtypeId
:::

#### 例文
エンティティが落下ダメージを受けた時にメッセージを送信する
```js:EntityHurt
import { world, EntityDamageCause, Player } from "@minecraft/server";

world.afterEvents.entityHurt.subscribe((ev) => {
    const { hurtEntity, damageSource } = ev;
    if (!(hurtEntity instanceof Player)) return;
    if (damageSource.cause === EntityDamageCause.fall) {
        // 例) Steve が落下ダメージを受けました。
        world.sendMessage(`${hurtEntity.name} が落下ダメージを受けました。`);
    }
});
```

上記に登録オプションを使用した例
```js:EntityHurt
import { world, EntityDamageCause } from "@minecraft/server";

world.afterEvents.entityHurt.subscribe((ev) => {
    const { hurtEntity, damageSource } = ev;
    if (damageSource.cause === EntityDamageCause.fall) {
        // 例) Steve が落下ダメージを受けました。
        world.sendMessage(`${hurtEntity.name} が落下ダメージを受けました。`);
    }
}, {
    entityTypes: ["minecraft:player"]
});
```

### EntityLoad
#### 説明
エンティティがロードされた時に実行されるイベント
ここで言うロードとは、「任意のエンティティが読み込まれていないチャンクにいる時、そのチャンクが読み込まれると同時にエンティティがロードされること」を指す。
その為、例えばプレイヤー参加した直後にプレイヤー周辺のチャンクが読み込まれていないと、そのプレイヤー周辺のチャンクにいるエンティティに対してイベントが発生します。
また、上記より`/summon`などで召喚したエンティティはこのイベントに当てはまりません。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/entityloadafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly entity: Entity**
:::

#### 例文
エンティティがロードされた時、最も近いプレイヤーにエンティティの距離とtypeIdを送信する
```js:EntityLoad
import { world } from "@minecraft/server";

world.afterEvents.entityLoad.subscribe((ev) => {
    const { entity } = ev;
    const dimension = entity.dimension;
    const location = entity.location;

    const [player] = dimension.getPlayers({ closest: 1, location });
    if (player?.isValid) {
        const distance = Math.hypot(...Object.keys(location).map((axis) => player.location[axis] - location[axis]));
        // 例) 12.34m 先で minecraft:cow が読み込まれました。
        player.sendMessage(`${distance.toFixed(2)}m 先で ${entity.typeId} が読み込まれました。`);
    }
});
```

### EntityRemove
#### 説明
エンティティが消滅した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/entityremoveafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly removedEntityId: string**
消滅したエンティティのid

- **readonly typeId: string**
消滅したエンティティのtypeId
:::

:::note info
###### 登録オプション
- **entities?: Entity[]**
消滅したエンティティ

- **entityTypes?: string[]**
消滅したエンティティのtypeId
:::


#### 例文
絵画が破壊された時メッセージを送信する
```js:EntityRemove
import { world } from "@minecraft/server";

world.afterEvents.entityRemove.subscribe((ev) => {
    const { typeId } = ev;
    if (typeId === "minecraft:painting") {
        world.sendMessage("絵画が破壊されました。");
    }
});
```

上記に登録オプションを使用した例
```js:EntityRemove
import { world } from "@minecraft/server";

world.afterEvents.entityRemove.subscribe((ev) => {
    world.sendMessage("絵画が破壊されました。");
}, {
    entityTypes: ["minecraft:painting"]
});
```

### EntitySpawn
#### 説明
エンティティがスポーンした時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/entityspawnafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly entity: Entity**
スポーンしたエンティティ

- **readonly cause: EntityInitializationCause**
エンティティがスポーンした原因
:::

#### 例文
牛が繁殖した時にメッセージを送信する
```js:EntitySpawn
import { world, EntityInitializationCause } from "@minecraft/server";

world.afterEvents.entitySpawn.subscribe((ev) => {
    const { entity, cause } = ev;
    if (cause === EntityInitializationCause.Born && entity.typeId === "minecraft:cow") {
        const { x, y, z } = entity.location;
        world.sendMessage(`(${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}) で牛の子が誕生しました！`);
    }
});
```

### Explosion
#### 説明
爆発が発生した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/explosionafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **getImpactedBlocks(): Block[]**
爆発により破壊されたブロックの配列を取得する関数
但し、`Block`クラスの配列である為、爆発前のブロック情報を取得することは出来ません。
爆発前のブロックの情報を扱いたい場合は[`BlockExplode`](#blockexplode)を使用するか、ビフォーイベントを使用してください。

- **readonly dimension: Dimension**
爆発が発生したディメンション

- **readonly source?: Entity**
爆発したエンティティ
:::

#### 例文
tntが爆発した時に爆発した座標と破壊されたブロックの数を送信する
```js:Explosion
import { world } from "@minecraft/server";

world.afterEvents.explosion.subscribe((ev) => {
    const { source } = ev;
    if (source?.typeId === "minecraft:tnt") {
        const { x, y, z } = source.location;
        const blocks = ev.getImpactedBlocks();
        world.sendMessage(`TNTが (${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}) で ${blocks.length}個 のブロックを破壊しました。`);
    }
});
```

### ProjectileHitBlock
#### 説明
投擲物がブロックにヒットした時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/projectilehitblockafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **getBlockHit(): BlockHitInformation**
投擲物がブロックにヒットした時の情報を取得する関数

- **readonly dimension: Dimension**
投擲物がブロックにヒットしたディメンション

- **readonly location: Vector3**
投擲物がブロックにヒットした座標

- **readonly hitVector: Vector3**
投擲物がブロックにヒットした向き

- **readonly source?: Entity**
ブロックにヒットした投擲物を投擲したエンティティ

- **readonly projectile: Entity**
ブロックにヒットした投擲物
:::

#### 例文
プレイヤーが投擲した矢が`(0, 0, 0)`のブロックにヒットした時、プレイヤーにメッセージを送信する
```js:ProjectileHitBlock
import { world } from "@minecraft/server";

world.afterEvents.projectileHitBlock.subscribe((ev) => {
    const { source, projectile, location } = ev;
    if (!(source instanceof Player)) return;
    if (projectile.typeId !== "minecraft:arrow") return;
    if (location.x === 0 && location.y === 0 && location.z === 0) {
        source.sendMessage("矢がヒットしました！");
    }
});
```

### ProjectileHitEntity
#### 説明
投擲物がエンティティにヒットした時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/projectilehitentityafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **getBlockHit(): BlockHitInformation**
投擲物がエンティティにヒットした時の情報を取得する関数

- **readonly dimension: Dimension**
投擲物がエンティティにヒットしたディメンション

- **location: Vector3**
投擲物がエンティティにヒットした座標

- **readonly hitVector: Vector3**
投擲物がエンティティにヒットした向き

- **readonly source?: Entity**
エンティティにヒットした投擲物を投擲したエンティティ

- **readonly projectile: Entity**
エンティティにヒットした投擲物
:::

#### 例文
矢がエンティティにヒットした時、ヒットしたエンティティのtypeIdを送信する
```js:ProjectileHitEntity
import { world } from "@minecraft/server";

world.afterEvents.projectileHitEntity.subscribe((ev) => {
    const { projectile } = ev;
    const entity = ev.getEntityHit().entity;
    if (!entity?.isValid) return;
    if (projectile.typeId === "minecraft:arrow") {
        // 例) minecraft:cow に矢がヒットしました。
        world.sendMessage(`${entity.typeId} に矢がヒットしました。`)
    }
});
```

## プレイヤー関連

### ChatSend
#### 説明
プレイヤーがチャットを送信した時に実行されるイベント
`/say`や`/tell`等でのメッセージ送信では実行されません。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/chatsendafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly message: string**
送信したメッセージ内容

- **readonly sender: Player**
送信したプレイヤー

- **readonly targets?: Player[]**
チャットで@を使用して言及（メンション）されたプレイヤーの配列
現在何らかの影響で、常に`undefined`になります。
:::

#### 例文
チャット内容をコンソールに出力する
```js:ChatSend
import { world } from "@minecraft/server";

world.afterEvents.chatSend.subscribe((ev) => {
    const { sender, message } = ev;
    console.log(`<${sender.name}> ${message}`);
});
```

### ItemCompleteUse
#### 説明
プレイヤーが溜めが可能なアイテム(弓、トライデント、食料等)を溜め切った時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/itemcompleteuseafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly itemStack: ItemStack**
溜め切ったアイテム

- **readonly source: Player**
アイテムを溜め切ったプレイヤー

- **readonly useDuration: number**
アイテムを溜めることが出来る最大tick数と、アイテムを溜めたtick数の差
アイテムを溜め切ったとは、溜めることができる最大tick数に達した事である為、この値は基本的に0になります。
:::

#### 例文
プレイヤーが食べ物を食べた時に、そのアイテムのtypeIdを送信する
```js:ItemCompleteUse
import { world } from "@minecraft/server";

world.afterEvents.itemCompleteUse.subscribe((ev) => {
    const { itemStack, source } = ev;
    if (itemStack.hasComponent("food")) {
        // 例) Steve が minecraft:apple を食べました。
        world.sendMessage(`${source.name} が ${itemStack.typeId} を食べました。`);
    }
});
```

### ItemReleaseUse
#### 説明
溜めが可能なアイテム(弓、トライデント、食料等)を、溜めた後に離した時に実行されるイベント
現在何らかの影響で、弓やトライデント、クロスボウ等の投擲物を溜めた後に離しても、このイベントは実行されません。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/itemreleaseuseafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly itemStack?: ItemStack**
使用したアイテム

- **readonly source: Player**
アイテムを使用したプレイヤー

- **readonly useDuration: number**
アイテムを溜めることが出来る最大tick数と、アイテムを溜めたtick数の差
例えば、リンゴなら、最大32tick溜めることが出来るので、食べ切らずに10tick経過後に離すと、この値は22になります。
:::

#### 例文
プレイヤーが食べ物を食べ切らなかった時に、そのアイテムのtypeIdを送信する
```js:ItemReleaseUse
import { world } from "@minecraft/server";

world.afterEvents.itemReleaseUse.subscribe((ev) => {
    const { itemStack, source, useDuration } = ev;
    if (!itemStack.hasComponent("food")) return;
    if (useDuration > 0) {
        // 例) Steve が minecraft:apple を食べ切りませんでした。
        world.sendMessage(`${source.name} が ${itemStack.typeId} を食べ切りませんでした。`);
    }
});
```

### ItemStartUse
#### 説明
溜めが可能なアイテム(弓、トライデント、食料等)を、溜め始めた時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/itemstartuseafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly itemStack: ItemStack**
使用したアイテム

- **readonly source: Player**
アイテムを使用したプレイヤー

- **readonly useDuration: number**
アイテムを溜めることが出来る最大tick数と、アイテムを溜めたtick数の差
アイテムを使用し始める時は、アイテムを溜めたtick数が0である為、この値は基本的にアイテムを溜めることが出来る最大tickになります。
:::

#### 例文
プレイヤーが弓を溜め始めた時にメッセージを送信する
```js:ItemStartUse
import { world } from "@minecraft/server";

world.afterEvents.itemStartUse.subscribe((ev) => {
    const { itemStack, source } = ev;
    if (itemStack.typeId === "minecraft:bow") {
        // 例) Steve が矢を溜め始めました。
        world.sendMessage(`${source.name} が弓を溜め始めました。`);
    }
});
```

### ItemStopUse
#### 説明
溜めが可能なアイテム(弓、トライデント、食料等)を、溜め中に離した、若しくは溜め終えた時に実行されるイベント
現在何らかの影響で、プレイヤーがディメンションを移動した時にも実行されます。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/itemstopuseafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly itemStack?: ItemStack**
使用したアイテム
使用した後、アイテムが壊れた場合`undefined`になります

- **readonly source: Player**
アイテムを使用したプレイヤー

- **readonly useDuration: number**
アイテムを溜めることが出来る最大tick数と、アイテムを溜めたtick数の差
例えば、リンゴなら、最大32tick溜めることが出来るので、食べ切らずに10tick経過後に離すと、この値は22になります。
:::

#### 例文
プレイヤーが弓で矢を発射した時にメッセージを送信する
```js:ItemStopUse
import { world } from "@minecraft/server";

world.afterEvents.itemStopUse.subscribe((ev) => {
    const { itemStack, source, useDuration } = ev;
    if (itemStack?.typeId === "minecraft:bow" && useDuration <= (72000 - 3)) { // 弓は3tick以上溜めると矢を発射する
        // 例) Steve が矢を発射しました。
        world.sendMessage(`${source.name} が矢を発射しました。`);
    }
});
```

### ItemUse
#### 説明
アイテムを使用した時に実行されるイベント
アイテムが溜められるか否かに関わらず実行されます。
アイテムを持った状態で右クリックをすると、基本的にこのイベントが実行されます。
但し、アイテムをブロックに対して使用した時、このイベントは実行されません。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/itemuseafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly itemStack: ItemStack**
使用したアイテム

- **readonly source: Player**
アイテムを使用したプレイヤー
:::

#### 例文
プレイヤーがホットバーからダイヤモンドのヘルメットを着用した時にメッセージを送信する
(インベントリ欄から着用した時は検知されない)
```js:ItemUse
import { world } from "@minecraft/server";

world.afterEvents.itemUse.subscribe((ev) => {
    const { itemStack, source } = ev;
    if (itemStack.typeId === "minecraft:diamond_helmet") {
        // 例) Steve がダイヤモンドのヘルメットを着用しました。
        world.sendMessage(`${source.name} がダイヤモンドのヘルメットを着用しました。`);
    }
});
```

### ItemStartUseOn
#### 説明
ブロックに対してアイテムを使用し始めた時に実行されるイベント
プレイヤーが素手の場合でも実行されます。
但し、ブロックに対して影響がある場合に限ります。
これには、ブロックを設置した場合も含みます。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/itemstartuseonafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly itemStack?: ItemStack**
使用したアイテム
素手の場合`undefined`になります。

- **readonly source: Player**
アイテムを使用したエンティティ

- **readonly blockFace: Direction**
アイテムを使用したブロックの面の方角

- **readonly block: Block**
アイテムを使用したブロック
:::

#### 例文
オークのボタンを押し始めた時、プレイヤーにメッセージを送信する
```js:ItemStartUseOn
import { world } from "@minecraft/server";

world.afterEvents.itemStartUseOn.subscribe((ev) => {
    const { source, block } = ev;
    if (block.typeId === "minecraft:wooden_button") {
        source.sendMessage("オークのボタンを押し始めました。");
    }
});
```

### ItemStopUseOn
#### 説明
プレイヤーがブロックに対してアイテムを使用し終えた時に実行されるイベント
プレイヤーが素手の場合でも実行されます。
但し、ブロックに対して影響がある場合に限ります。
また、これにはブロックを設置した場合も含みます。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/itemstopuseonafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly itemStack?: ItemStack**
使用したアイテム
素手の場合`undefined`になります。

- **readonly source: Player**
アイテムを使用したプレイヤー

- **readonly block: Block**
アイテムを使用したブロック
現在何らかの影響で、設置可能なアイテムを使用した場合、アイテムを使用したブロックの面の座標の方向に1マス進んだ位置のブロックになります。
:::

#### 例文
オークのボタンを押し終えた時、プレイヤーにメッセージを送信する
```js:ItemStopUseOn
import { world } from "@minecraft/server";

world.afterEvents.itemStopUseOn.subscribe((ev) => {
    const { source, block } = ev;

    if (block.typeId === "minecraft:wooden_button") {
        source.sendMessage("オークのボタンを押し終わりました。");
    }
});
```

### PlayerBreakBlock
#### 説明
プレイヤーがブロックを破壊した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerbreakblockafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
ブロックを破壊したプレイヤー

- **readonly block: Block**
破壊されたブロックのブロック

- **readonly brokenBlockPermutation: BlockPermutation**
破壊されたブロックの`BlockPermutation`
破壊前のブロックの情報を扱いたいのであれば、`block`ではなくこちらを使用してください。

- **readonly itemStackAfterBreak?: ItemStack**
破壊するために使用した後アイテム
素手で破壊した、若しくはアイテムが壊れた場合`undefined`になります

- **readonly itemStackBeforeBreak?: ItemStack**
破壊するために使用したアイテム
素手で破壊した場合は`undefined`になります
:::

:::note info
###### 登録オプション

- **blockTypes?: string[]**
破壊されたブロックのtypeId

- **permutations?: BlockPermutation[]**
破壊されたブロックの`BlockPermutation`の配列
:::

#### 例文
プレイヤーが原木を鉄の斧で破壊した時に、周辺3x3の範囲の同じ原木も破壊する
```js:PlayerBreakBlock
import { world } from "@minecraft/server";

const blockTypes = [
    "minecraft:dark_oak_log",
    "minecraft:mangrove_log",
    "minecraft:jungle_log",
    "minecraft:birch_log",
    "minecraft:oak_log",
    "minecraft:spruce_log",
    "minecraft:acacia_log",
    "minecraft:cherry_log",
    "minecraft:pale_oak_log"
];

world.afterEvents.playerBreakBlock.subscribe((ev) => {
    const { player, block, brokenBlockPermutation, itemStackBeforeBreak } = ev;
    if (itemStackBeforeBreak?.typeId === "minecraft:iron_axe" && blockTypes.includes(brokenBlockPermutation.type.id)) {
        for (let x = -1; x <= 1; x++) for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) {
            const offsetBlock = block.offset({ x, y, z });
            if (!offsetBlock?.isValid || !offsetBlock.matches(brokenBlockPermutation.type.id)) continue;
            const itemStackEntity = offsetBlock.getItemStack();
            offsetBlock.setType("minecraft:air");
            player.dimension.spawnItem(itemStackEntity, offsetBlock);
        }
    }
});
```

上記に登録オプションを使用した例
```js:PlayerBreakBlock
import { world } from "@minecraft/server";

world.afterEvents.playerBreakBlock.subscribe((ev) => {
    const { player, block, brokenBlockPermutation, itemStackBeforeBreak } = ev;
    if (itemStackBeforeBreak?.typeId === "minecraft:iron_axe") {
        for (let x = -1; x <= 1; x++) for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) {
            const offsetBlock = block.offset({ x, y, z });
            if (!offsetBlock?.isValid || !offsetBlock.matches(brokenBlockPermutation.type.id)) continue;
            const itemStackEntity = offsetBlock.getItemStack();
            offsetBlock.setType("minecraft:air");
            player.dimension.spawnItem(itemStackEntity, offsetBlock);
        }
    }
}, {
    blockTypes: [
        "minecraft:dark_oak_log",
        "minecraft:mangrove_log",
        "minecraft:jungle_log",
        "minecraft:birch_log",
        "minecraft:oak_log",
        "minecraft:spruce_log",
        "minecraft:acacia_log",
        "minecraft:cherry_log",
        "minecraft:pale_oak_log"
    ]
});
```

### PlayerPlaceBlock
#### 説明
プレイヤーがブロックを設置した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerplaceblockafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly dimension: Dimension**
プレイヤーがブロックを設置したディメンション

- **readonly block: Block**
プレイヤーが設置したブロック

- **readonly player: Player**
ブロックを設置したプレイヤー
:::

#### 例文
作業台を設置した時、その上に9個作業台を設置する
```js:PlayerPlaceBlock
import { world, BlockVolume } from "@minecraft/server";

world.afterEvents.playerPlaceBlock.subscribe((ev) => {
    const { block, dimension } = ev;
    if (block.typeId === "minecraft:crafting_table") {
        const { x, y, z } = block.location;
        dimension.fillBlocks(new BlockVolume({ x, y: y + 1, z }, { x, y: y + 9, z }), block.permutation);
    }
});
```

上記に登録オプションを使用した例
```js:PlayerPlaceBlock
import { world, BlockVolume } from "@minecraft/server";

world.afterEvents.playerPlaceBlock.subscribe((ev) => {
    const { block, dimension } = ev;
    const { x, y, z } = block.location;
    dimension.fillBlocks(new BlockVolume({ x, y: y + 1, z }, { x, y: y + 9, z }), block.permutation);
}, {
    blockTypes: ["minecraft:crafting_table"]
});
```

### PlayerButtonInput
#### 説明
特定ボタン(キーボードのキー)を押した時、又は離した時に実行されるイベント
現時点では、ジャンプボタンとスニークボタンの入力の取得をすることが出来ます。
但し、たとえジャンプやスニークが出来ない状態であっても、ボタンの入力があれば実行される点に注意してください。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerbuttoninputafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
ボタンを押した、又は離したプレイヤー

- **readonly button: InputButton**
押された、又は離されたボタン

- **readonly newButtonState: ButtonState**
ボタンのステータス
押された場合は`Pressed`、離された場合は`Released`になります
:::

:::note info
###### 登録オプション

- **buttons?: InputButton[]**
押された、又は離されたボタン

- **state?: ButtonState**
ボタンのステータス
:::

#### 例文
プレイヤーがスニークし始めた時、又はスニークし終えた時にメッセージを送信する
```js:PlayerButtonInput
import { world, InputButton, ButtonState } from "@minecraft/server";

world.afterEvents.playerButtonInput.subscribe((ev) => {
    const { player, button, newButtonState } = ev;
    if (button !== InputButton.Sneak) return;
    if (newButtonState === ButtonState.Pressed) {
        // 例) Steve がスニークし始めました。
        world.sendMessage(`${player.name} がスニークし始めました。`);
    }
    if (newButtonState === ButtonState.Released) {
        // 例) Steve がスニークし終えました。
        world.sendMessage(`${player.name} がスニークし終えました。`);
    }
});
```

上記に登録オプションを使用した例
```js:PlayerButtonInput
import { world, InputButton, ButtonState } from "@minecraft/server";

world.afterEvents.playerButtonInput.subscribe((ev) => {
    const { player, newButtonState } = ev;
    if (newButtonState === ButtonState.Pressed) {
        // 例) Steve がスニークし始めました。
        world.sendMessage(`${player.name} がスニークし始めました。`);
    }
    if (newButtonState === ButtonState.Released) {
        // 例) Steve がスニークし終えました。
        world.sendMessage(`${player.name} がスニークし終えました。`);
    }
}, {
    buttons: [InputButton.Sneak]
});
```

### PlayerDimensionChange
#### 説明
プレイヤーがディメンション間を移動した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerdimensionchangeafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
ディメンションを移動したプレイヤー

- **readonly fromDimension: Dimension**
プレイヤーがディメンションを移動する前のディメンション

- **readonly fromLocation: Vector3**
プレイヤーがディメンションを移動する前の座標

- **readonly toDimension: Dimension**
プレイヤーがディメンションを移動した後のディメンション

- **readonly toLocation: Vector3**
プレイヤーがディメンションを移動した後の座標
:::

#### 例文
現在のディメンションをプレイヤーに送信する
```js:PlayerDimensionChange
import { world } from "@minecraft/server";

world.afterEvents.playerDimensionChange.subscribe((ev) => {
    const { player, toDimension } = ev;
    // 例) 現在のディメンションは minecraft:nether です。
    player.sendMessage(`現在のディメンションは ${toDimension.id} です。`);
});
```

### PlayerEmote
#### 説明
プレイヤーがエモートした時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playeremoteafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
エモートしたプレイヤー

- **readonly personaPieceId: string**
プレイヤーがエモートしたエモーションの`persona_piece`のuuid
:::

#### 例文
プレイヤーがエモートした時にメッセージを送信する
```js:PlayerEmote
import { world } from "@minecraft/server";

world.afterEvents.playerEmote.subscribe((ev) => {
    const { player } = ev;
    const { x, y, z } = player.location;
    // Steve が (32.05, 62.00, 51.94)
    world.sendMessage(`${player.name} が (${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}) でエモートしています！`);
});
```

### PlayerGameModeChange
#### 説明
プレイヤーのゲームモードが変化した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playergamemodechangeafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
ゲームモードが変化したプレイヤー

- **readonly toGameMode: GameMode**
変化した後のプレイヤーのゲームモード

- **readonly fromGameMode: GameMode**
変化する前のプレイヤーのゲームモード
:::

#### 例文
プレイヤーのゲームモードがクリエイティブになった時、OP権限が無ければ元のゲームモードに戻し、プレイヤーにメッセージを送信する
```js:PlayerGameModeChange
import { world, GameMode } from "@minecraft/server";

world.afterEvents.playerGameModeChange.subscribe((ev) => {
    const { player, toGameMode, fromGameMode } = ev;
    if (toGameMode === GameMode.creative && !player.isOp()) {
        player.setGameMode(fromGameMode);
        player.sendMessage("権限が不足している為、クリエイティブになることが出来ませんでした。");
    }
});
```

### PlayerInputModeChange
#### 説明
プレイヤーが操作方法を変更した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerinputmodechangeafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
操作方法を実行したプレイヤー

- **readonly newInputModeUsed: InputMode**
変更した後のプレイヤーの操作方法

- **readonly previousInputModeUsed: InputMode**
変更する前のプレイヤー操作方法
:::

#### 例文
```js:PlayerInputModeChange
import { world } from "@minecraft/server";

world.afterEvents.playerInputModeChange.subscribe((ev) => {
    const { player, newInputModeUsed, previousInputModeUsed } = ev;
    // 例) Steve が操作方法を KeyboardAndMouse から Gamepad に変更しました。
    world.sendMessage(`${player.name} が操作方法を ${previousInputModeUsed} から ${newInputModeUsed} に変更しました。`); 
});
```

### PlayerInputPermissionCategoryChange
#### 説明
プレイヤーの入力権限が変化した時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerinputpermissioncategorychangeafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
入力権限が変化したプレイヤー

- **readonly category: InputPermissionCategory**
入力権限のカテゴリ

- **readonly enabled: boolean**
入力権限が有効か否か
:::

#### 例文
入力権限が変更された時、プレイヤーにメッセージを送信する
```js:PlayerInputPermissionCategoryChange
import { world, InputPermissionCategory } from "@minecraft/server";

world.afterEvents.playerInputPermissionCategoryChange.subscribe((ev) => {
    const { player, category, enabled } = ev;
    const key = Object.keys(InputPermissionCategory).find((key) => InputPermissionCategory[key] === category);
    if (enabled) {
        // 例) Sneak の操作が解放されました。
        player.sendMessage(`${key} の操作が解放されました。`);
    }
    else {
        // 例) Sneak の操作が制限されました。
        player.sendMessage(`${key} の操作が制限されました。`);
    }
});
```

### PlayerInteractWithBlock
#### 説明
ブロックに対してインタラクトした時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerinteractwithblockafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
ブロックにインタラクトしたプレイヤー

- **readonly itemStack?: ItemStack**
プレイヤーがブロックにインタラクトする為に使用したアイテム
素手でインタラクトした場合は`undefined`になります

- **readonly beforeItemStack?: ItemStack**
プレイヤーがブロックにインタラクトする為に使用した後のアイテム
素手でインタラクトした、若しくはアイテムが壊れた場合`undefined`になります

- **readonly block: Block**
プレイヤーがインタラクトしたブロック

- **readonly blockFace: Direction**
プレイヤーがインタラクトしたブロックの面の方角

- **readonly faceLocation: Vector3**
プレイヤーがインタラクトしたブロックの面の座標

- **readonly isFirstEvent: boolean**
このインタラクトが長押しの中で最も始めか否か
:::

#### 例文
プレイヤーがスニークしながら看板にインタラクトした時、看板にコマンドが記述されているなら実行し、メッセージを送信する
また、コマンド実行時にエラーが発生した時、プレイヤーにエラーメッセージを送信する
```js:PlayerInteractWithBlock
import { world } from "@minecraft/server";

world.afterEvents.playerInteractWithBlock.subscribe((ev) => {
    const { player, block } = ev;
    if (!player.isSneaking) return;
    const sign = block.getComponent("sign");
    const command = sign?.getText();
    if (command?.startsWith("/")) {
        try {
            player.runCommand(command.slice(1));
            player.sendMessage(`§a正常に実行されました。: ${command}`);
        }
        catch (error) {
            player.sendMessage(`§c${error.message}`);
        }
    }
});
```

### PlayerInteractWithEntity
#### 説明
エンティティに対してインタラクトした時に実行されるイベント

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerinteractwithentityafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
エンティティにインタラクトしたプレイヤー

- **readonly itemStack?: ItemStack**
プレイヤーがエンティティにインタラクトする為に使用したアイテム

- **readonly beforeItemStack: ItemStack**
プレイヤーがエンティティにインタラクトする為に使用した後のアイテム

- **readonly target: Entity**
プレイヤーがインタラクトしたエンティティ
:::

#### 例文
プレイヤーがウシに小麦を上げた時、プレイヤーにリアクションメッセージを送信する
```js:PlayerInteractWithEntity
import { world } from "@minecraft/server";

world.afterEvents.playerInteractWithEntity.subscribe((ev) => {
    const { player, target, beforeItemStack } = ev;
    if (target.typeId === "minecraft:cow" && beforeItemStack?.typeId === "minecraft:wheat") {
        player.sendMessage("<ウシ> ﾑｼｬﾑｼｬ.."); 
    }
});
```

### PlayerJoin
#### 説明
プレイヤーがワールドに参加した時に実行されるイベント
扱えるプレイヤーのデータが名前とidと限られている為、プレイヤーの情報を扱いたい場合、[`PlayerSpawn`](#playerspawn)と、イベントデータの`initialSpawn`を併用して下さい。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerjoinafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly playerName: string**
参加したプレイヤーの名前

- **readonly playerId: id**
参加したプレイヤーのid
:::

#### 例文
プレイヤーの参加を通知する
```js:PlayerJoin
import { world } from "@minecraft/server";

world.afterEvents.playerJoin.subscribe((ev) => {
    const { playerName } = ev;
    // 例) Steve が間もなく参加します。
    world.sendMessage(`${playerName} が間もなく参加します。`);
});
```

### PlayerLeave
#### 説明
プレイヤーがワールドを抜けた時に実行されるイベント
扱えるプレイヤーのデータが名前とidと限られている為、プレイヤーの情報を扱いたい場合、ビフォーイベントを使用して下さい。

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerleaveafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly playerName: string**
プレイヤーの名前

- **readonly playerId: string**
プレイヤーのid
:::

#### 例文
プレイヤーの退出を通知する
```js:PlayerLeave
import { world } from "@minecraft/server";

world.afterEvents.playerLeave.subscribe((ev) => {
    const { playerName } = ev;
    // 例) Steve が退出しました。
    world.sendMessage(`${playerName} が退出しました。`)
});
```

### PlayerSpawn
#### 説明
プレイヤーがリスポーンした時に実行されるイベント
これには、プレイヤーが参加した時も含みます

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerspawnafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly player: Player**
リスポーンしたプレイヤー

- **readonly initialSpawn: boolean**
このリスポーンが最も始めか否か
最も始めのリスポーンで真になる為、プレイヤーが参加した時`true`になります。
:::

#### 例文
プレイヤーの参加を通知する
```js:PlayerSpawn
import { world } from "@minecraft/server";

world.afterEvents.playerSpawn.subscribe((ev) => {
    const { player, initialSpawn } = ev;
    if (initialSpawn) {
        // 例) Steve が参加しました。
        world.sendMessage(`${player.name} が参加しました。`);
    }
});
```

プレイヤーがリスポーンした時、5秒間プレイヤーに耐性を付与する
```js:PlayerSpawn
import { world, TicksPerSecond } from "@minecraft/server";

world.afterEvents.playerSpawn.subscribe((ev) => {
    const { player, initialSpawn } = ev;
    if (!initialSpawn) {
        player.addEffect("minecraft:resistance", TicksPerSecond * 5, { showParticles: false, amplifier: 255 });
    }
});
```

# SystemAfterEvents

## システム関連

### ScriptEventReceive
#### 説明
`/scriptevent`を実行した時に実行されるイベント
コマンドの説明になりますが、構文は

- `/scriptevent <messageId: string> <message: string>`

となっています。
`messageId`は`minecraft`以外の名前空間識別子を付ける必要があります。(例えば、`id:test`や`cmd:test`等としなければいけません。)

[Document](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/scripteventcommandmessageafterevent?view=minecraft-bedrock-stable)

:::note info
###### イベントデータ

- **readonly id: string**
`/scriptevent <messageId> message`
の部分の文字列

- **readonly message: string**
`/scriptevent messageId <message>`
の部分の文字列

- **readonly sourceType: ScriptEventSource**
`/scriptevent`を実行した媒体

- **readonly sourceEntity?: Entity**
`/scriptevent`を実行したエンティティ

- **readonly initiator?: Player**
`/scriptevent`をNPCを介して実行したプレイヤー

- **readonly sourceBlock?: Block**
`/scriptevent`を実行したブロック（主にコマンドブロック）
:::

#### 例文
`/scriptevent cmd:give <itemType> <amount>`の構文でプレイヤーが実行した時、実行したプレイヤーにアイテムを渡す
```js:ScriptEventReceive
import { system, Player, ItemTypes, ItemStack } from "@minecraft/server";

system.afterEvents.scriptEventReceive.subscribe((ev) => {
    const { id, message, sourceEntity } = ev;
    if (!(sourceEntity instanceof Player)) return;
    
    const args = message.split(/ +/);
    if (id === "cmd:give") {
        const itemType = ItemTypes.get(args[0]);
        if (!itemType) {
            sourceEntity.sendMessage("§cアイテム名が無効です。");
            return;
        }
        
        const amount = Number(args[1]);
        if (Number.isNaN(amount) || amount < 1 || amount > 64) {
            sourceEntity.sendMessage("§cアイテムの個数が無効です。");
            return;
        }

        const itemStack = new ItemStack(itemType, amount);
        const container = sourceEntity.getComponent("inventory")?.container;
        container.addItem(itemStack);

        sourceEntity.sendMessage(`${itemType.id}を${amount}個受け取りました。`);
    }
});
```

# 最後に
ここまで読んで頂き有難うございました。
ScriptAPIにおいて、イベントはとても重要な役割を担っており、同時に初心者が躓きやすい部分でもあります。
この記事を通してイベントとは何かを理解出来、また、どのような使い方なのかということが分かって頂ければとても幸いです。

また、誤字脱字、その他誤っている箇所があれば、コメント等にて教えて頂けると幸いです。

次回は引き続きビフォーイベントについて解説していくつもりですので、今後ともよろしくお願い致します。