diff --git a/docs/.vitepress/zh_cn.ts b/docs/.vitepress/zh_cn.ts
index e05c1af..233f916 100644
--- a/docs/.vitepress/zh_cn.ts
+++ b/docs/.vitepress/zh_cn.ts
@@ -9,10 +9,28 @@ export const zh_cn = defineConfig({
sidebar: [
{
items: [
- { text: '欢迎', link: '/zh-cn/' },
+ { text: '欢迎!', link: '/zh-cn/' }
+ ]
+ },
+ {
+ text: '使用',
+ items: [
{ text: '事件', link: '/zh-cn/Events' },
{ text: '命令', link: '/zh-cn/Commands' },
- { text: '算术', link: '/zh-cn/Arithmetica' }
+ { text: '表达式', link: '/zh-cn/Expressions' },
+ ]
+ },
+ {
+ text: '开发',
+ items: [
+ { text: '事件', link: '/zh-cn/develop/Events'},
+ { text: '命令', link: '/zh-cn/develop/Commands'}
+ ]
+ },
+ {
+ text: 'Meta',
+ items: [
+ { text: '设计', link: 'https://github.com/constellation-mc/commander/discussions/3' }
]
}
],
diff --git a/docs/zh-cn/Arithmetica.md b/docs/zh-cn/Arithmetica.md
deleted file mode 100644
index 2b6a820..0000000
--- a/docs/zh-cn/Arithmetica.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# 算术
-
-命令官模组凭借动态实体数据,实现了运算表达式的功能。
-
-算术使用 [exp4j](https://www.objecthunter.net/exp4j/index.html) 来实现运算功能。掌握它并非必要,但多有好处。
-
-## 额外功能
-
-本模组在 exp4j 的基础上,添加了一些额外功能。
-
-- `round` 能够四舍五入一个值。接受 1 个值。
-- `random` 能在指定范围内生成随机数。接受 2 个值(最小,最大)。
-- `clamp` 将其他两个值约束在范围内。接受 3 个值(值,最小,最大)。
-- `min` 返回两数中的最小数。接受 2 个值(a,b)。
-- `max` 返回两数中的最大数。接受 2 个值(a,b)。
-- `lerp` 平滑地将初值过渡到末值。`初值 + 平滑系数 * (末值 - 初值)`。接受 3 个值(平滑系数,初值,末值)。
-
-## 读取源数据
-
-因为算术以游戏的战利品功能为情境,你可以通过一种叫"提取"的特殊句法来读取源数据。
-```
-标识符[字段]
-标识符[字段$动态数据]
-```
-字段对准确度要求极高,在错误的情境下使用会直接使游戏崩溃。
-
-示例:
-```
-minecraft:this_entity[x]
-minecraft:this_entity[living/attribute$generic.max_health]
-minecraft:this_entity[rot/x]
-minecraft:origin[world/day_time]
-```
-
-前景:说明所有可用字段。
-
-## 使用算术
-
-通过使用 `cmd:arithmetica` 命令,你可以快速上手。记得用 `"` 括住表达式来满足格式要求。
-
-其他使用情境见 [命令宏](Commands#command-macros) 和 `commander:arithmetica` 的战利品数字提供器。
-
-提供 condition(条件)的例子如下,非常简单:
-
-```json
-{
- "condition": "minecraft:value_check",
- "value": {
- "type": "commander:arithmetica",
- "arithmetica": "round(random(5, 15))"
- },
- "range": {
- "min": 12.3,
- "max": 32
- }
-}
-```
diff --git a/docs/zh-cn/Commands.md b/docs/zh-cn/Commands.md
index ee3e51d..a2e8b4b 100644
--- a/docs/zh-cn/Commands.md
+++ b/docs/zh-cn/Commands.md
@@ -12,6 +12,10 @@
[[toc]]
+## 选择器
+
+一些命令需要你指定“选择器”。选择器用于选择执行者,它可以是一个位置,也可以(可选)是一个实体。一些例外除外,选择器模仿了原版的战利品情境。你可以在[内置选择器](https://github.com/constellation-mc/commander/blob/main/src/main/java/me/melontini/commander/impl/builtin/BuiltInSelectors.java)页面,了解所有的内置选择器:。
+
## 内置命令
本模组内置了少量命令,因为游戏内交互应该交给 `/` 样式的命令,或者函数。
@@ -36,19 +40,20 @@
对于想要在命令中插入一些东西的人,命令宏是不二之选。
-命令宏就是 `${{}}`,一个能让你从选择器中,动态插入内容的代码块。目前有两种命令宏:字符串宏和算术宏。
-
-正如其名,字符串宏能够在命令中插入字符串,比如:
+命令宏就是 `${{}}`,一个能让你通过表达式,动态插入内容的代码块。示例如下:
```
-"/say 我的名字是${{origin[world/key]}}!"
+"/say 我的名字是${{level.dimension.location}}!"
```
这段命令在主世界中执行,将输出 `我的名字是minecraft:overworld`。
-相比之下,算术宏要有趣得多。算术宏由 [算术](Arithmetica) 支持,你可以在那个页面了解更多关于数学表达式的信息。
+你可以在[表达式](Expressions)页面中,了解更多关于它的信息。
+
+命令宏默认返回字符串,但你可以像这样将它转化为其它类型:
-算术宏永远会返回一个浮点数(比如 `1.7480`),但你可以通过在表达式前加上 `(long)` 来给它截断,比如:
```
-$(long){{random(0, 34)}}
+$(long){{random(0, 34)}} 34.52946 -> 34
+$(double){{true}} true -> 1.0
+$(bool){{0}} 0 -> false
```
### `commander:cancel`
@@ -97,7 +102,7 @@ $(long){{random(0, 34)}}
"type": "commander:commands",
"selector": "this_entity",
"commands": [
- "/say mmm... diamond..."
+ "/say 是钻石..."
]
},
{
@@ -112,8 +117,7 @@ $(long){{random(0, 34)}}
:::
### `commander:random`
-这一类型将按权重随机执行其中的命令。默认执行一轮。你可以在非必要的 `rolls` 字段中指定轮次(支持 [算术](Arithmetica))。
-
+这一类型将按权重随机执行其中的命令。默认执行一轮。你可以在非必要的 `rolls` 字段中指定轮次(支持[表达式](Expressions))。
::: details 示例
```json
{
diff --git a/docs/zh-cn/Events.md b/docs/zh-cn/Events.md
index 75c9d09..3b96ed8 100644
--- a/docs/zh-cn/Events.md
+++ b/docs/zh-cn/Events.md
@@ -1,15 +1,30 @@
# 事件
-事件是游戏内,触发 [命令](Commands) 的节点。
+事件是游戏内,触发[命令](Commands)的节点。
## 订阅文件的引入
-当你订阅文件中声明一个事件时,实际上是在标识你想要订阅的事件。事件可以在 `parameters` 代码块中接受额外的参数,但(目前)内置事件并不要求具备它们。
+当你订阅文件中声明一个事件时,实际上是在标识你想要订阅的事件。事件可以在 `parameters` 代码块中接受额外的参数,但(目前)内置事件并不要求具备它们。订阅文件将在 `commander/events` 下被读取。
+
+```
+|- recipes
+|- commander
+ |- events
+ |- test_event.json
+ |- folder
+ |- nested.json
+|- tags
+```
+
+声明事件的典型例子如下:
::: details 示例
```json
{
"event": "commander:after_killed_by_other"
+ "commands": [
+
+ ]
}
```
@@ -18,7 +33,10 @@
{
"event": "modid:custom_event",
"parameters": {
- }
+ },
+ "commands": [
+
+ ]
}
```
:::
@@ -45,8 +63,6 @@
## 内置事件
-在 `commander` 命名空间下,本模组涵盖了绝大部分兼容的 fabric 事件。这里的返回指 [取消类命令](Commands#commandercancel)。
+在 `commander` 命名空间下,本模组涵盖了绝大部分兼容的 fabric 事件。这里的返回指[取消类命令](Commands#commandercancel)。
当前可用的事件请见:[实体事件](https://github.com/constellation-mc/commander/blob/main/src/main/java/me/melontini/commander/impl/builtin/events/EntityEvents.java),[玩家事件](https://github.com/constellation-mc/commander/blob/main/src/main/java/me/melontini/commander/impl/builtin/events/PlayerEvents.java),[服务器生命周期](https://github.com/constellation-mc/commander/blob/main/src/main/java/me/melontini/commander/impl/builtin/events/ServerLifecycle.java),[服务器刻](https://github.com/constellation-mc/commander/blob/main/src/main/java/me/melontini/commander/impl/builtin/events/ServerTick.java)。
-
-前景:自动生成事件列表。
diff --git a/docs/zh-cn/Expressions.md b/docs/zh-cn/Expressions.md
new file mode 100644
index 0000000..e375e2c
--- /dev/null
+++ b/docs/zh-cn/Expressions.md
@@ -0,0 +1,67 @@
+# 表达式
+
+命令官模组凭借动态实体数据,实现了运算表达式的功能。
+
+算术使用 [EvalEx](https://ezylang.github.io/EvalEx/) 来实现运算功能。掌握它并非必要,但多有好处。
+
+## 额外功能
+
+本模组在 EvalEx 的基础上,添加了一些额外功能。
+
+- `random` 能在指定范围内生成随机数。接受 2 个值(最小,最大)。
+- `clamp` 将其他两个值约束在范围内。接受 3 个值(值,最小,最大)。
+- `lerp` 平滑地将初值过渡到末值。`初值 + 平滑系数 * (末值 - 初值)`。接受 3 个值(平滑系数,初值,末值)。
+
+## 读取情境数据
+
+因为算术以游戏的战利品功能为情境,你可以通过一种叫"提取"的特殊句法来读取源数据。
+```
+标识符.字段
+标识符.方法
+标识符.方法.字段.方法
+```
+注意,你的用到的字段与情境**必须**存在,不然表达式是无效的。
+
+示例:
+```
+minecraft:this_entity.getX
+this_entity.getHealth
+minecraft:this_entity.isInWaterOrRain
+this_entity.blockPosition.getX
+origin.x
+origin.reverse.y
+minecraft:level.getDayTime
+```
+
+表达式使用的是 Mojang 的映射(首次载入时下载),这意味着几乎所有公共的字段和 get 类型的方法都可以在表达式里使用。如果本模组无法设置映射,你可能需要依赖于平台的名称(比如 Fabric 的中间映射)。
+
+## 使用表达式
+
+通过使用 `cmd:arithmetica` 命令,你可以快速上手。记得用 `"` 括住表达式来满足格式要求。
+
+其他使用情境见[命令宏](Commands#command-macros),`commander:arithmetica` 的数字提供器以及 `commander:expression` 接口。
+
+使用接口的例子:
+
+```json
+{
+ "condition": "commander:expression",
+ "value": "level.isDay"
+}
+```
+
+在条件下使用接口的例子:
+
+```json
+{
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "commander:arithmetica",
+ "value": "round(random(5, 15))"
+ },
+ "range": {
+ "min": 12.3,
+ "max": 32
+ }
+}
+```
diff --git a/docs/zh-cn/develop/Commands.md b/docs/zh-cn/develop/Commands.md
new file mode 100644
index 0000000..9fed5ee
--- /dev/null
+++ b/docs/zh-cn/develop/Commands.md
@@ -0,0 +1,58 @@
+# 命令
+
+大多情况下,你应该使用 `/` 类型的命令,但有时,我们会需要一些额外的发挥空间。
+
+## 创建命令
+
+创建新的命令很简单,你要做的是:实现 `Command` 接口,通过创建一个[编码器](https://forge.gemwire.uk/wiki/Codecs)来序列化或反序列化命令,然后用 `CommandTypes.register()` 来注册编码器。
+
+让我们创建一个能够将字符串转化为标准输出的命令。
+
+```java
+public record DummyCommand(String text) implements Command {
+
+ @Override
+ public boolean execute(EventContext context) {
+ System.out.println(text());
+ return true; //执行成功则返回
+ }
+
+ @Override
+ public CommandType type() {
+ return null;
+ }
+}
+```
+
+接下来,我们再为这个命令[编码器](https://forge.gemwire.uk/wiki/Codecs)创建一个编码器。
+
+```java
+public static final Codec CODEC = Codec.STRING.fieldOf("text").xmap(DummyCommand::new, DummyCommand::text).codec();
+```
+
+再然后,我们需要注册这一命令来获取 `CommandType`。
+
+```java
+public static final CommandType DUMMY = CommandType.register(new Identifier("modid", "print"), DummyCommand.CODEC);
+```
+
+最后,在 `type()` 返回这个类型。
+
+```java
+@Override
+public CommandType type() {
+ return MyModInit.DUMMY;
+}
+```
+
+## 事件情境
+
+你可以通过事件情境,检索与事件类型一起传递的 `LootContext`。
+
+```java
+context.lootContext().getWorld(); //返回服务端世界
+
+context.lootContext().get(LootContextParameters.TOOL); //如果不存在,返回参数或空值。
+
+context.lootContext().requireParameter(LootContextParameters.TOOL); //如果不存在,返回参数或抛出异常。
+```
diff --git a/docs/zh-cn/develop/Events.md b/docs/zh-cn/develop/Events.md
new file mode 100644
index 0000000..979b49c
--- /dev/null
+++ b/docs/zh-cn/develop/Events.md
@@ -0,0 +1,69 @@
+# 事件
+
+本模组引入了全新的数据包事件系统,使数据包能够像模组一样监听事件。
+
+最好的实践办法就是找到一个 Fabric 的事件,让本模组对它进行监听。
+
+## 创建事件类型
+
+为了实现模组的事件支持,你需要先注册一个事件类型,以便本模组进行分发。你可以通过 `EventType.Builder` 类来构建并注册事件。
+
+```java
+public static final EventType CUSTOM_EVENT = EventType.builder().build(new Identifier("modid", "custom_event"));
+```
+
+如果你的事件需要返回类型,你可以通过 `cancelTerm()` 来指定取消条件编解码器。
+
+```java
+EventType.builder()
+ .cancelTerm(Codec.INT)
+ .build(new Identifier("modid", "custom_event"));
+```
+
+通过使用 `extension()`,事件可以接受额外的参数。在指定扩展后,你可以返回自定义类型。
+
+```java
+EventType.builder()
+ .extension(Codec.STRING, subscriptions -> {
+ //处理数据
+ return /*返回监听者*/;
+ })
+ .build(new Identifier("modid", "custom_event"));
+```
+
+默认的返回类型是 `List`。
+
+## 调用事件
+
+如果你没有指定扩展,或选择返回 `List`,你可以使用附带的 `EventExecutors` 辅助单元。
+
+为了使用这一辅助单元,你需要传递:事件类型、执行的世界,以及战利品情境提供者。
+
+```java
+CustomEvent.EVENT.register((world, entity) -> runVoid(CUSTOM_EVENT, world, () -> makeContext(world, entity, entity.getPos())));
+```
+
+```java
+private static LootContext makeContext(ServerWorld world, Entity entity, Vec3d origin) {
+ LootContextParameterSet.Builder builder = new LootContextParameterSet.Builder(world);
+ builder.add(THIS_ENTITY, entity).add(ORIGIN, origin);
+ return new LootContext.Builder(builder.build(LootContextTypes.COMMAND)).build(null /*在 1.20.4,.empty()可选*/);
+}
+```
+
+如果你指定了扩展,或者使用了不受支持的返回类型,就需要编写自定义的解析逻辑。
+
+为了编写这一逻辑,你需要创建 `EventContext`。`EventContext` 用于把执行参数传递给命令。
+
+```java
+EventContext context = EventContext.builder(type)
+ .addParameter(EventKey.LOOT_CONTEXT, /*战利品情境的实例*/)
+ .build();
+for (Command.Conditioned subscriber : subscribers) subscriber.execute(context);
+```
+你可以通过调用 `getReturnValue(def)` 来获取返回的值,默认值可以为空值。返回的类型是 generic。
+
+```java
+boolean val = context.getReturnValue(def);
+if (val != def) return val;
+```
diff --git a/docs/zh-cn/index.md b/docs/zh-cn/index.md
index 7d0d10d..0e252a3 100644
--- a/docs/zh-cn/index.md
+++ b/docs/zh-cn/index.md
@@ -1,19 +1,18 @@
---
comment: false
---
-
# 命令官
命令官模组是对原版数据包系统的补充。
-它引入了全新的事件系统,灵活的 json 命令,新的 `/` 类命令,进阶的数学表达式支持,还有更多!
+它引入了全新的事件系统,灵活的 json 命令,新的 `/` 类命令,可读取数据的进阶数学表达式支持,还有更多!
本模组不会有客户端特性,一切都会在服务端执行。
::: danger 注意
-这个模组只能在 Modrinth,CurseForge 和 GitHub 的 Actions 上被下载到。如果你从*其他*任何地方下载这个模组,你的电脑很可能感染类似 [fractureiser](https://github.com/fractureiser-investigation/fractureiser) 的病毒。
+这个模组只能在 Modrinth,CurseForge 和 GitHub 的 Actions 上被下载到。如果你从*其他*任何地方下载到了这个模组,你的电脑很可能面临感染像 [fractureiser](https://github.com/fractureiser-investigation/fractureiser) 病毒的风险。
-这个页面 [拒绝模组再分发](https://stopmodreposts.org/)展示了更详细的信息。
+这个页面 [拒绝模组再分发](https://stopmodreposts.org/) 展示了更详细的信息。
-可别怪我没提醒哦!
+切记!
:::