npc-mannequin/README.md
2026-08-01 18:32:50 +09:00

278 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MannequinNPC
Minecraft の `minecraft:mannequin` を、ID付きのNPCとして作成・登録・管理する Paper/Folia プラグインです。
見た目や姿勢をコマンドから変更できるほか、プレイヤーを目で追う動作、右クリック時のメッセージ送信・コマンド実行、消滅後の再スポーンを設定できます。NPCの定義は `mannequins.yml` に保存されます。
## 主な機能
- プレイヤーの現在地への Mannequin 作成
- 既存の Mannequin エンティティの登録
- 姿勢、利き手、スキン、服レイヤー、名前、説明文などの変更
- 無敵化、移動固定、体力の設定
- 指定座標や近くのプレイヤーを向く視線制御
- 右クリックしたプレイヤーや会話中のプレイヤーへの追従
- 右クリックごとのメッセージ送信・コンソールコマンド実行
- アクションの順次実行とランダム実行
- エンティティ消滅時の自動再スポーン
- Paper Services Manager を介した `MannequinRegistry` の公開
- Folia のリージョンスケジューラを用いた定期的な視線更新
Mannequin 自体の仕様は [note-mannequin.md](./note-mannequin.md) にまとめています。
## 動作要件
| 項目 | 要件 |
| --- | --- |
| サーバー | Paper/Folia 26.1 系 |
| コンパイル対象API | `paper-api:26.1.2.build.49-beta` |
| Java | 25 |
| Minecraft | `minecraft:mannequin` を利用できるバージョン |
Kotlin標準ライブラリ、`kommand-lib`、`permits-lib` は Shadow JAR に同梱されるため、サーバーへ別途導入する必要はありません。
## ビルドと導入
このリポジトリは `kommand-lib` を Git submodule として参照します。単独で取得した場合は、先にサブモジュールを初期化してください。
```bash
git submodule update --init --recursive
./gradlew shadowJar
```
生成物は次の場所に出力されます。
```text
build/libs/MannequinNPC-1.0-min.jar
```
JARをサーバーの `plugins/` へ配置して起動してください。
crafters-toolbox 管理下のプロジェクトでは、プロジェクトルートから次のコマンドでビルドと配置を行えます。
```bash
crtb components update npc-mannequin
```
## クイックスタート
プレイヤーの現在位置と向きでNPCを作成し、見た目と会話を設定する例です。
```mcfunction
/mannequin create guide
/mannequin set guide profile player Notch
/mannequin set guide description set <gold>案内人
/mannequin set guide immovable on
/mannequin set guide invulnerable on
/mannequin set guide lookat near range 8
/mannequin set guide event add message <yellow>こんにちは<player>さん
```
設定後に `/mannequin` を実行すると、登録済みNPCの状態と保存位置を確認できます。チャット上のIDをクリックすると設定コマンドが、`offline` をクリックすると再スポーンコマンドが入力・実行されます。
## コマンド
メインコマンドは `/mannequin` です。次のエイリアスも利用できます。
- `/mnpc`
- `/mnq`
- `/npcmannequin`
`<id>` はプラグイン内でNPCを識別する任意の文字列です。IDはコマンド補完にも使われます。
### 登録と配置
| コマンド | 説明 |
| --- | --- |
| `/mannequin` | 登録済みNPCの一覧を表示します。 |
| `/mannequin list` | 登録済みNPCの一覧を表示します。 |
| `/mannequin create <id>` | 実行したプレイヤーの現在位置に新しいMannequinを作成します。 |
| `/mannequin register <id> <selector>` | セレクターに含まれる最初のMannequinを、現在の状態ごと登録します。 |
| `/mannequin register <id> <selector> --overwrite` | 同じIDの定義を、対象エンティティの状態で置き換えます。 |
| `/mannequin move <id>` | 保存位置を実行したプレイヤーの現在位置・向きへ変更し、存在するエンティティも移動します。 |
| `/mannequin apply <id>` | 保存済み設定を適用します。エンティティが見つからなければ保存位置に再生成します。 |
| `/mannequin remove <id>` | 登録だけを解除し、ワールド内のエンティティは残します。 |
| `/mannequin remove <id> --delete-entity` | 登録を解除し、関連付けられたエンティティも削除します。 |
既存エンティティを登録する例:
```mcfunction
/summon minecraft:mannequin ~ ~ ~
/mannequin register shopkeeper @e[type=minecraft:mannequin,sort=nearest,limit=1]
```
### 外観と基本状態
| コマンド | 説明 |
| --- | --- |
| `/mannequin set <id> pose <pose>` | 姿勢を変更します。 |
| `/mannequin set <id> mainhand <left\|right>` | 利き手を変更します。 |
| `/mannequin set <id> immovable <state>` | ノックバックなどによる移動を固定・解除します。 |
| `/mannequin set <id> invulnerable <state>` | ダメージ無効を設定します。 |
| `/mannequin set <id> health <value>` | 体力を設定します。入力範囲は `0`〜`1024` で、適用時に最大体力以下へ補正されます。 |
| `/mannequin set <id> name set <MiniMessage>` | カスタム名を設定します。 |
| `/mannequin set <id> name clear` | カスタム名を解除します。 |
| `/mannequin set <id> description set <MiniMessage>` | Mannequinの説明文を設定し、表示状態にします。 |
| `/mannequin set <id> description clear` | カスタム説明文を解除し、標準の説明文に戻します。 |
| `/mannequin set <id> description hide` | 説明文を非表示にします。 |
| `/mannequin set <id> description show` | 説明文を表示します。 |
| `/mannequin set <id> profile player <player>` | オンラインプレイヤー、または指定名からプロフィールを作成して適用します。 |
| `/mannequin set <id> profile clear` | 保存プロフィールを解除し、Mannequinの標準プロフィールに戻します。 |
| `/mannequin set <id> respawn-delay <seconds>` | 消滅後の再スポーン待ち時間を秒で設定します。負数で無効、`0` で即時です。 |
`<state>``true` / `false` / `on` / `off` を受け付けます。内部の真偽値パーサーは `yes` / `no` / `1` / `0` にも対応しています。
利用できる姿勢:
```text
standing
sleeping
sneaking
swimming
spin_attack
long_jumping
fall_flying
```
名前、説明文、メッセージには MiniMessage 形式を使用できます。
```mcfunction
/mannequin set guide name set <gold><bold>Guide</bold></gold>
/mannequin set guide description set <gray>右クリックで話す</gray>
```
### スキンレイヤー
| コマンド | 説明 |
| --- | --- |
| `/mannequin set <id> layers hide <layer>` | 指定レイヤーを非表示にします。 |
| `/mannequin set <id> layers show <layer>` | 指定レイヤーを表示します。 |
| `/mannequin set <id> layers clear` | すべてのレイヤーを表示状態に戻します。 |
利用できるレイヤー:
```text
cape
jacket
left_sleeve
right_sleeve
left_pants_leg
right_pants_leg
hat
```
## 右クリック時のアクション
登録済みMannequinをメインハンドで右クリックすると、設定されたアクションが1件実行されます。
| コマンド | 説明 |
| --- | --- |
| `/mannequin set <id> event add command <command>` | コンソールとして実行するコマンドを末尾に追加します。先頭の `/` は省略できます。 |
| `/mannequin set <id> event add message <MiniMessage>` | クリックしたプレイヤーだけに送るメッセージを末尾に追加します。 |
| `/mannequin set <id> event mode default` | プレイヤーごとに先頭から順次実行し、末尾の次は先頭へ戻ります。 |
| `/mannequin set <id> event mode random` | クリックごとにランダムな1件を実行します。 |
| `/mannequin set <id> event timeout <seconds>` | 順次実行の位置と会話追従を維持する時間を設定します。既定値は5秒です。 |
| `/mannequin set <id> event list` | モードとアクション一覧を表示します。プレイヤーには削除・並べ替え用のクリックUIも表示します。 |
| `/mannequin set <id> event remove <index>` | 指定インデックスのアクションを削除します。 |
| `/mannequin set <id> event swap <index1> <index2>` | 2件の順序を入れ替えます。 |
アクションのインデックスは `0` から始まります。コマンドとメッセージでは `<player>` がクリックしたプレイヤー名に置換されます。
```mcfunction
/mannequin set shop event add message <gold>いらっしゃいませ<player>さん
/mannequin set shop event add command give <player> minecraft:bread 1
/mannequin set shop event mode default
/mannequin set shop event timeout 10
```
`command` アクションは常にコンソールから実行されます。プレイヤー本人の実行コンテキストが必要な場合は、次のように `execute as` を明示してください。
```mcfunction
/mannequin set shop event add command execute as <player> at @s run say hello
```
## 視線制御
| コマンド | 説明 |
| --- | --- |
| `/mannequin set <id> lookat pos <x> <y> <z>` | 固定座標を見るようにします。実行者がプレイヤーならそのワールド、コンソールなら `world` を使用します。 |
| `/mannequin set <id> lookat near range <radius>` | 半径内で最も近い非Spectatorプレイヤーを追います。範囲は `0`〜`64` ブロックです。 |
| `/mannequin set <id> lookat onclick <state>` | 右クリックしたプレイヤーを一時的に見る動作を切り替えます。 |
| `/mannequin set <id> lookat conversation <state>` | 順次アクションで会話中のプレイヤーを見る動作を切り替えます。 |
| `/mannequin set <id> lookat auto-turn on\|off` | 注視対象がいなくなった後、保存済みの向きへ戻る動作を切り替えます。 |
| `/mannequin set <id> lookat auto-turn wait <seconds>` | 元の向きへ戻り始めるまでの待ち時間を設定します。既定値は0.5秒です。 |
| `/mannequin set <id> lookat auto-turn take <seconds>` | 元の向きへ補間して戻る時間を設定します。`0` 以下では即座に戻ります。既定値は0.5秒です。 |
| `/mannequin set <id> lookat clear` | 固定座標、近距離追従、クリック追従を解除し、視線関連設定を既定値へ戻します。 |
複数の対象が有効な場合は、次の順で優先されます。
1. 直近に右クリックしたプレイヤー
2. 会話中のプレイヤー
3. 設定半径内で最も近いプレイヤー
4. 設定した固定座標
視線は2 tickごとに更新されます。クリック追従の継続時間には `auto-turn wait` の値が使われ、正数でない場合は2秒になります。会話追従は順次アクションの対話状態を利用するため、ランダムモードでは発生しません。
## パーミッション
すべてのコマンドは次のルート権限で保護されています。既定値は `false` なので、権限管理プラグインなどから明示的に付与してください。
```text
npc-mannequin.command.mannequin
```
`kommand-lib``permits-lib` によって、`npc-mannequin.command.mannequin.list` や `npc-mannequin.command.mannequin.set.pose` のようなリテラル単位のノードも動的に登録されます。現在のコマンド定義ではルート権限も実行条件になるため、運用時はまず上記のルート権限を付与してください。
## データ保存
NPC定義は次のファイルへYAML形式で保存されます。
```text
plugins/MannequinNPC/mannequins.yml
```
登録、移動、設定変更、削除のたびにファイル全体が更新されます。通常はコマンド経由で編集してください。ワールド上のエンティティが見つからなくなった場合でも、保存位置があれば `/mannequin apply <id>` で再生成できます。
現在、次の設定はコマンド実行中のエンティティには反映されますが、`mannequins.yml` へシリアライズされません。サーバー再起動後は既定値へ戻る点に注意してください。
- カスタム名 (`name`)
- 無敵状態 (`invulnerable`)
- 体力 (`health`)
- 再スポーン待ち時間 (`respawn-delay`)
姿勢、利き手、移動固定、説明文、スキンレイヤー、プロフィール、位置、視線制御、クリックアクションは永続化されます。
また、視線更新はFoliaのリージョンスケジューラに対応していますが、自動再スポーンの遅延処理は現在Bukkit Schedulerを使用しています。Folia環境では `respawn-delay` を利用せず、必要に応じて `/mannequin apply <id>` で再生成してください。
## 他プラグインから利用する
有効化時に `MannequinRegistry` が Paper の Services Manager へ登録されます。MannequinNPCへの依存とクラス参照を設定したプラグインから、登録済みNPCを取得・更新できます。
```kotlin
import net.hareworks.npc_mannequin.service.MannequinRegistry
import org.bukkit.Bukkit
val registry = Bukkit.getServicesManager()
.load(MannequinRegistry::class.java)
?: error("MannequinNPC is not enabled")
val guide = registry.find("guide")
registry.updateSettings("guide") { settings ->
settings.copy(immovable = true)
}
```
主な公開操作は `all`、`find`、`register`、`create`、`updateSettings`、`apply`、`relocate`、`remove`、`locate` です。
## プロジェクト構成
```text
src/main/kotlin/net/hareworks/npc-mannequin/
├── Plugin.kt # ライフサイクルとサービス登録
├── commands/MannequinCommands.kt # コマンドツリー
├── mannequin/MannequinSettings.kt # 永続化モデル
├── service/ # 操作、登録、イベント、視線更新
├── storage/MannequinStorage.kt # mannequins.yml の読み書き
└── text/TextSerializers.kt # MiniMessage変換
```