宿主 API
通过 Register(INpEditorHost host) 获得的 host 是所有功能的起点。本文档介绍信息 · 通知 · 世界 · 事件 · 设置 · 3D 绘制。Add… 注册点见注册点,Scene · View 见场景读取与运行相机。
所有类型都位于 NP.Editor.Sdk 命名空间中。
INpEditorHost
Section titled “INpEditorHost”| 成员 | 类型 | SDK | 说明 |
|---|---|---|---|
SdkVersion | string | 1.0 | 编辑器的 SDK 版本(例 "1.3.0") |
EditorVersion | string | 1.0 | 编辑器版本(例 "0.9.11") |
PluginId | string | 1.0 | 自己 plugin.json 中的 id |
PluginDir | string | 1.0 | 自己的 plugin.json 所在文件夹(完整路径) |
World | INpWorld | 1.0 | 当前世界。即使打开新世界,也始终指向当前世界。 |
WorldChanged | event Action<NpWorldChange>? | 1.0 | 世界发生更换时 |
Committed | event Action<NpCommit>? | 1.0 | 每完成一步撤销单位时 |
Message(string text) | void | 1.0 | 简短通知(状态栏 · 视口通知 · 输出日志) |
Log(string text) | void | 1.0 | 输出日志中的一行 [<id>] <text> |
Settings | INpSettings | 1.1 | 此插件的设置存储 |
Draw | INpDraw | 1.1 | 视口 3D 叠加绘制 |
Scene | INpScene | 1.3 | 读取场景 Actor — 场景读取与运行相机 |
View | INpView | 1.3 | 运行状态 · 相机 — 场景读取与运行相机 |
Add… | void | 1.0~1.2 | 注册点 — 注册点 |
世界:INpWorld
Section titled “世界:INpWorld”| 成员 | 类型 | 说明 |
|---|---|---|
FilePath | string? | 当前文件路径。尚未保存的新世界为 null |
Selection | NpBox? | 当前选择框。没有时为 null |
Bounds | NpBox? | 存在方块的范围。空世界为 null。会扫描整个世界,因此不要频繁调用。 |
GetBlock(int x, int y, int z) | string | 方块状态字符串。空气为 "minecraft:air" |
IsAir(int x, int y, int z) | bool | 是否为空气 |
Blocks(NpBox? box = null) | IEnumerable<NpBlock> | 所有非空气格。传入 box 时只返回其内部。框外的区块会被跳过。 |
CountBlocks() | long | 非空气方块的数量 |
Edit(string label, Action<INpEdit> build) | int | 更改方块。一次 = 一步撤销。返回值 = 实际更改的格数 |
INpEdit(仅在 Edit 内)
Section titled “INpEdit(仅在 Edit 内)”| 成员 | 说明 |
|---|---|
Set(int x, int y, int z, string state) | 用方块状态字符串更改该格。空字符串 · "air" · "minecraft:air" 表示空气。 |
Clear(int x, int y, int z) | 将该格改为空气。 |
int n = host.World.Edit("돌 바닥", e =>{ for (int x = 0; x < 8; x++) for (int z = 0; z < 8; z++) e.Set(x, 0, z, "minecraft:stone");});host.Message($"{n}칸 바꿈 (Ctrl+Z 로 되돌리기)");label是撤销记录中显示的名称。- 锁定的格会被跳过。锁定的格 = 协作建造锁定 · 已锁定的 Actor · 被格守卫(
AddCellGuard)阻止的格。因此返回值可能小于写入的格数。 - 若有其他大型编辑任务(填充 · 地形等)正在运行,会抛出
InvalidOperationException。若不处理,插件将被隔离。 - 方块状态字符串不经检查,按原样写入。请准确使用 Minecraft 格式(
命名空间:id[属性=值,…])。不要省略命名空间(minecraft:)。自定义方块为np:<id>。 - 不要在遍历
Blocks()的同时执行Edit。先用.ToList()取出后再更改。
| 类型 | 声明 | 说明 |
|---|---|---|
NpCell | readonly record struct NpCell(int X, int Y, int Z) | 一个格(方块坐标) |
NpBlock | readonly record struct NpBlock(int X, int Y, int Z, string State) | 格 + 方块状态字符串 |
NpBox | readonly record struct NpBox(NpCell Min, NpCell Max) | 框(包含两端)。SizeX · SizeY · SizeZ · Contains(x, y, z) |
NpVec3 | readonly record struct NpVec3(float X, float Y, float Z) | 3D 点(一个方块格 = 1)。NpVec3.Center(NpCell) = 格的中心 |
NpWorldChange | sealed record NpWorldChange(NpWorldChangeReason Reason, string? Path) | 世界更换的原因和文件路径 |
NpWorldChangeReason | enum { New, Open, Replaced, ShotScenario } | 新建 · 打开 · 替换世界 · 开始画面验证 |
NpCommit | sealed record NpCommit(string Label, IReadOnlyList<NpBlockChange> Changes) | 一步撤销单位 |
NpBlockChange | readonly record struct NpBlockChange(int X, int Y, int Z, string Old, string New) | 一个格的变更前 · 变更后状态 |
| 事件 | 时机 | 传递的值 | 应做的事 |
|---|---|---|---|
WorldChanged | 新建 · 打开 · 替换世界 · 开始画面验证 | NpWorldChange | 清空自己的状态(预览 · 选择 · 绘制 · 检查结果)。 |
Committed | 每完成一步撤销单位时(包括用户编辑) | NpCommit | 仅用于记录 · 统计,保持轻量。 |
host.WorldChanged += c =>{ _towers.Clear(); host.Draw.Clear();};host.Committed += c => _edits += c.Changes.Count; // 保持轻量Committed的Changes在读取时才生成方块名称。格数较多时只看Count,不要逐个读取。- 处理器中发生异常时,该插件会被隔离。
- 宿主事件在插件卸载时自动解除。
-=不起任何作用。若要停止处理,请在处理器内用标志过滤。
| 成员 | 显示位置 | 使用场合 |
|---|---|---|
Message(text) | 状态栏 · 视口通知 · 输出日志 | 向用户告知结果时 |
Log(text) | 输出日志([<id>] …) | 调试记录 · 详细结果 |
设置:INpSettings(SDK 1.1)
Section titled “设置:INpSettings(SDK 1.1)”每个插件有一个键 · 值(字符串)存储。每次 Set 都会立即写入文件。重启编辑器或重新加载插件后依然保留。
| 成员 | 类型 | 说明 |
|---|---|---|
Keys | IReadOnlyCollection<string> | 已保存的键列表 |
Get(string key) | string? | 值。没有时为 null |
Get(string key, string fallback) | string | 值。没有时为 fallback |
GetInt(string key, int fallback = 0) | int | 按整数读取。无法读取时为 fallback |
GetDouble(string key, double fallback = 0) | double | 按实数读取 |
GetBool(string key, bool fallback = false) | bool | 按 "true" / "false" 读取 |
Set(string key, string? value) | void | 保存。为 null 时删除。空键会抛出异常。 |
SetInt · SetDouble · SetBool | void | 按类型保存 |
Changed | event Action<string>? | 值被更改或删除时(键名) |
_height = host.Settings.GetInt("height", 12);// 面板的数字字段更改时立即保存.Number("높이", _height, 4, 64, 1, v => { _height = (int)v; host.Settings.SetInt("height", _height); })| 项目 | 值 |
|---|---|
| 文件 | %APPDATA%\NPEditor\plugin_settings\<id>.json |
| 格式 | {"format":"np-plugin-settings","version":1,"values":{…}} |
| 相同的值 | 再次 Set 也不会写入。 |
| 损坏的文件 | 以空设置启动,旧文件保留为 <id>.json.bad。 |
| 较大的数据 | 不要放入。每次 Set 都会重写整个文件。数 MB 的数据放在 PluginDir 下的自有文件中。 |
3D 绘制:INpDraw(SDK 1.1)
Section titled “3D 绘制:INpDraw(SDK 1.1)”在视口上叠加绘制线 · 框 · 文字。对方块 · 选择 · 点击没有影响。坐标为世界坐标(一个方块格 = 1)。颜色为 "#rrggbb"。
| 成员 | 说明 |
|---|---|
Count | 当前绘制的数量 |
Line(NpVec3 a, NpVec3 b, string color = "#ffcc33") | 线 |
Box(NpVec3 min, NpVec3 max, string color = "#ffcc33", bool filled = false, float alpha = 0.25f) | 框的棱线。filled 时还绘制半透明面。 |
Cell(NpCell c, string color = "#ffcc33", bool filled = false) | 一个方块格的框(略微放大) |
Text(NpVec3 at, string text, string color = "#ffffff", float size = 1f) | 始终朝向相机的文字。size = 以方块高度为基准的倍率 |
Clear() | 全部清除 |
void Redraw(){ host.Draw.Clear(); // 重绘时先清除再全部绘制 if (host.World.Selection is not { } b) return; host.Draw.Box(new NpVec3(b.Min.X, b.Min.Y, b.Min.Z), new NpVec3(b.Max.X + 1, b.Max.Y + 1, b.Max.Z + 1), "#ffcc33", filled: true, alpha: 0.1f); host.Draw.Text(new NpVec3(b.Min.X, b.Max.Y + 2, b.Min.Z), $"{b.SizeX}×{b.SizeY}×{b.SizeZ}");}| 限制 | 值 |
|---|---|
| 最大数量 | 每个插件 20,000 个。超出部分被忽略。 |
| 文字长度 | 最多 200 字 |
size | 0.1 ~ 20 |
alpha | 0 ~ 1 |
Box 的 min · max | 顺序颠倒也会自动调整绘制。 |
| 禁用插件时 | 自动清除。 |