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/) 展示了更详细的信息。 -可别怪我没提醒哦! +切记! :::