# 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 案内人 /mannequin set guide immovable on /mannequin set guide invulnerable on /mannequin set guide lookat near range 8 /mannequin set guide event add message こんにちは、さん! ``` 設定後に `/mannequin` を実行すると、登録済みNPCの状態と保存位置を確認できます。チャット上のIDをクリックすると設定コマンドが、`offline` をクリックすると再スポーンコマンドが入力・実行されます。 ## コマンド メインコマンドは `/mannequin` です。次のエイリアスも利用できます。 - `/mnpc` - `/mnq` - `/npcmannequin` `` はプラグイン内でNPCを識別する任意の文字列です。IDはコマンド補完にも使われます。 ### 登録と配置 | コマンド | 説明 | | --- | --- | | `/mannequin` | 登録済みNPCの一覧を表示します。 | | `/mannequin list` | 登録済みNPCの一覧を表示します。 | | `/mannequin create ` | 実行したプレイヤーの現在位置に新しいMannequinを作成します。 | | `/mannequin register ` | セレクターに含まれる最初のMannequinを、現在の状態ごと登録します。 | | `/mannequin register --overwrite` | 同じIDの定義を、対象エンティティの状態で置き換えます。 | | `/mannequin move ` | 保存位置を実行したプレイヤーの現在位置・向きへ変更し、存在するエンティティも移動します。 | | `/mannequin apply ` | 保存済み設定を適用します。エンティティが見つからなければ保存位置に再生成します。 | | `/mannequin remove ` | 登録だけを解除し、ワールド内のエンティティは残します。 | | `/mannequin remove --delete-entity` | 登録を解除し、関連付けられたエンティティも削除します。 | 既存エンティティを登録する例: ```mcfunction /summon minecraft:mannequin ~ ~ ~ /mannequin register shopkeeper @e[type=minecraft:mannequin,sort=nearest,limit=1] ``` ### 外観と基本状態 | コマンド | 説明 | | --- | --- | | `/mannequin set pose ` | 姿勢を変更します。 | | `/mannequin set mainhand ` | 利き手を変更します。 | | `/mannequin set immovable ` | ノックバックなどによる移動を固定・解除します。 | | `/mannequin set invulnerable ` | ダメージ無効を設定します。 | | `/mannequin set health ` | 体力を設定します。入力範囲は `0`〜`1024` で、適用時に最大体力以下へ補正されます。 | | `/mannequin set name set ` | カスタム名を設定します。 | | `/mannequin set name clear` | カスタム名を解除します。 | | `/mannequin set description set ` | Mannequinの説明文を設定し、表示状態にします。 | | `/mannequin set description clear` | カスタム説明文を解除し、標準の説明文に戻します。 | | `/mannequin set description hide` | 説明文を非表示にします。 | | `/mannequin set description show` | 説明文を表示します。 | | `/mannequin set profile player ` | オンラインプレイヤー、または指定名からプロフィールを作成して適用します。 | | `/mannequin set profile clear` | 保存プロフィールを解除し、Mannequinの標準プロフィールに戻します。 | | `/mannequin set respawn-delay ` | 消滅後の再スポーン待ち時間を秒で設定します。負数で無効、`0` で即時です。 | `` は `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 Guide /mannequin set guide description set 右クリックで話す ``` ### スキンレイヤー | コマンド | 説明 | | --- | --- | | `/mannequin set layers hide ` | 指定レイヤーを非表示にします。 | | `/mannequin set layers show ` | 指定レイヤーを表示します。 | | `/mannequin set layers clear` | すべてのレイヤーを表示状態に戻します。 | 利用できるレイヤー: ```text cape jacket left_sleeve right_sleeve left_pants_leg right_pants_leg hat ``` ## 右クリック時のアクション 登録済みMannequinをメインハンドで右クリックすると、設定されたアクションが1件実行されます。 | コマンド | 説明 | | --- | --- | | `/mannequin set event add command ` | コンソールとして実行するコマンドを末尾に追加します。先頭の `/` は省略できます。 | | `/mannequin set event add message ` | クリックしたプレイヤーだけに送るメッセージを末尾に追加します。 | | `/mannequin set event mode default` | プレイヤーごとに先頭から順次実行し、末尾の次は先頭へ戻ります。 | | `/mannequin set event mode random` | クリックごとにランダムな1件を実行します。 | | `/mannequin set event timeout ` | 順次実行の位置と会話追従を維持する時間を設定します。既定値は5秒です。 | | `/mannequin set event list` | モードとアクション一覧を表示します。プレイヤーには削除・並べ替え用のクリックUIも表示します。 | | `/mannequin set event remove ` | 指定インデックスのアクションを削除します。 | | `/mannequin set event swap ` | 2件の順序を入れ替えます。 | アクションのインデックスは `0` から始まります。コマンドとメッセージでは `` がクリックしたプレイヤー名に置換されます。 ```mcfunction /mannequin set shop event add message いらっしゃいませ、さん /mannequin set shop event add command give 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 at @s run say hello ``` ## 視線制御 | コマンド | 説明 | | --- | --- | | `/mannequin set lookat pos ` | 固定座標を見るようにします。実行者がプレイヤーならそのワールド、コンソールなら `world` を使用します。 | | `/mannequin set lookat near range ` | 半径内で最も近い非Spectatorプレイヤーを追います。範囲は `0`〜`64` ブロックです。 | | `/mannequin set lookat onclick ` | 右クリックしたプレイヤーを一時的に見る動作を切り替えます。 | | `/mannequin set lookat conversation ` | 順次アクションで会話中のプレイヤーを見る動作を切り替えます。 | | `/mannequin set lookat auto-turn on\|off` | 注視対象がいなくなった後、保存済みの向きへ戻る動作を切り替えます。 | | `/mannequin set lookat auto-turn wait ` | 元の向きへ戻り始めるまでの待ち時間を設定します。既定値は0.5秒です。 | | `/mannequin set lookat auto-turn take ` | 元の向きへ補間して戻る時間を設定します。`0` 以下では即座に戻ります。既定値は0.5秒です。 | | `/mannequin set 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 ` で再生成できます。 現在、次の設定はコマンド実行中のエンティティには反映されますが、`mannequins.yml` へシリアライズされません。サーバー再起動後は既定値へ戻る点に注意してください。 - カスタム名 (`name`) - 無敵状態 (`invulnerable`) - 体力 (`health`) - 再スポーン待ち時間 (`respawn-delay`) 姿勢、利き手、移動固定、説明文、スキンレイヤー、プロフィール、位置、視線制御、クリックアクションは永続化されます。 また、視線更新はFoliaのリージョンスケジューラに対応していますが、自動再スポーンの遅延処理は現在Bukkit Schedulerを使用しています。Folia環境では `respawn-delay` を利用せず、必要に応じて `/mannequin apply ` で再生成してください。 ## 他プラグインから利用する 有効化時に `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変換 ```