跳转到内容

宿主 API

通过 Register(INpEditorHost host) 获得的 host 是所有功能的起点。本文档介绍信息 · 通知 · 世界 · 事件 · 设置 · 3D 绘制。Add… 注册点见注册点,Scene · View 见场景读取与运行相机。

所有类型都位于 NP.Editor.Sdk 命名空间中。

成员类型SDK说明
SdkVersionstring1.0编辑器的 SDK 版本(例 "1.3.0")
EditorVersionstring1.0编辑器版本(例 "0.9.11")
PluginIdstring1.0自己 plugin.json 中的 id
PluginDirstring1.0自己的 plugin.json 所在文件夹(完整路径)
WorldINpWorld1.0当前世界。即使打开新世界,也始终指向当前世界。
WorldChangedevent Action<NpWorldChange>?1.0世界发生更换时
Committedevent Action<NpCommit>?1.0每完成一步撤销单位时
Message(string text)void1.0简短通知(状态栏 · 视口通知 · 输出日志)
Log(string text)void1.0输出日志中的一行 [<id>] <text>
SettingsINpSettings1.1此插件的设置存储
DrawINpDraw1.1视口 3D 叠加绘制
SceneINpScene1.3读取场景 Actor — 场景读取与运行相机
ViewINpView1.3运行状态 · 相机 — 场景读取与运行相机
Add…void1.0~1.2注册点 — 注册点
成员类型说明
FilePathstring?当前文件路径。尚未保存的新世界为 null
SelectionNpBox?当前选择框。没有时为 null
BoundsNpBox?存在方块的范围。空世界为 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更改方块。一次 = 一步撤销。返回值 = 实际更改的格数
成员说明
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() 取出后再更改。
类型声明说明
NpCellreadonly record struct NpCell(int X, int Y, int Z)一个格(方块坐标)
NpBlockreadonly record struct NpBlock(int X, int Y, int Z, string State)格 + 方块状态字符串
NpBoxreadonly record struct NpBox(NpCell Min, NpCell Max)框(包含两端)。SizeX · SizeY · SizeZ · Contains(x, y, z)
NpVec3readonly record struct NpVec3(float X, float Y, float Z)3D 点(一个方块格 = 1)。NpVec3.Center(NpCell) = 格的中心
NpWorldChangesealed record NpWorldChange(NpWorldChangeReason Reason, string? Path)世界更换的原因和文件路径
NpWorldChangeReasonenum { New, Open, Replaced, ShotScenario }新建 · 打开 · 替换世界 · 开始画面验证
NpCommitsealed record NpCommit(string Label, IReadOnlyList<NpBlockChange> Changes)一步撤销单位
NpBlockChangereadonly 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>] …)调试记录 · 详细结果

每个插件有一个键 · 值(字符串)存储。每次 Set 都会立即写入文件。重启编辑器或重新加载插件后依然保留。

成员类型说明
KeysIReadOnlyCollection<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 · SetBoolvoid按类型保存
Changedevent 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 下的自有文件中。

在视口上叠加绘制线 · 框 · 文字。对方块 · 选择 · 点击没有影响。坐标为世界坐标(一个方块格 = 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 字
size0.1 ~ 20
alpha0 ~ 1
Box 的 min · max顺序颠倒也会自动调整绘制。
禁用插件时自动清除。