Merge pull request #98 from Lafcadia/main

Rewrote the Chinese Skript Document.
This commit is contained in:
lilingfengdev 2024-06-22 12:20:36 +08:00 committed by GitHub
commit dd2d9ec5de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -54,7 +54,7 @@ on join:
效果可以是修改游戏模式、发送消息、移动玩家等任何能够改变游戏世界的动作。
在 SK 中效果是脚本中实际执行的操作或令,用于**改变游戏结果或执行动作**
在 SK 中效果是脚本中实际执行的操作或令,用于**改变游戏结果或执行动作**
举例:
@ -236,11 +236,11 @@ on join:
可以看到 Skript 提供给我们一共 120 个监听。这么多的监听,我们究竟该怎么选择呢?选择完又该如何使用呢?
这里我们拿 "on command" 监听器为例(令执行监听器)。
这里我们拿 "on command" 监听器为例(令执行监听器)。
我们把我们对于事件的定义拿过来:谁在某地做了某事。
现在我们已知要完成的事是“执行令”,现在我们需要知道什么?
现在我们已知要完成的事是“执行令”,现在我们需要知道什么?
我们需要知道的是——“谁”和“某地”。
@ -267,9 +267,9 @@ on command "/op":
监听被触发后,将自动将三个元素 "event-world" "event-commandsender" "event-player" 输出到后台。
如果是一位玩家执行了 "/op" 命令,"event-world" 将会输出玩家在哪个世界执行了命令,"event-commandsender" 将会输出为 "player" 因为监听器由玩家触发 而 "event-player" 则会输出为 "玩家的名字"
如果是一位玩家执行了 "/op" 指令,"event-world" 将会输出玩家在哪个世界执行了指令,"event-commandsender" 将会输出为 "player" 因为监听器由玩家触发 而 "event-player" 则会输出为 "玩家的名字"
那么如果是后台执行了 "/op" 令呢?
那么如果是后台执行了 "/op" 令呢?
因为后台并不存于任何一个世界,也没有名字。上述三个元素只会有 "event-commandsender" 存在并正常输出为 "console" 而其余不存在元素将全部输出为 `"<none>"`
@ -304,29 +304,35 @@ on command "/op":
---
### Conditions(条件)
条件用于判断句 有没有 是不是 都是条件的一种 基本格式为 "if" + 条件
这里我们和学习 Events 一样 我们先通过官方 Doc 找到所有的条件
这里我们拿最常用的一个条件作示例 判断玩家是否有权限
权限的英文是什么? "permission" 我们通过翻阅侧边栏可以得知
与 "permission" 相关的只有 "Has Permission" 一条 官方对这个条件的解释为
"Test whether a player has a certain permission." 翻译过来就是 "检测一个玩家是否拥有某一权限"
即我们所需要的 判断玩家是否有权限 那么我们又该如何使用呢 "Has Permssion" 条件呢?
在 "Has Permission" 下 "Patterns" 给了我们两种标准格式用法
`%players/console% (has|have) [the] permission[s] %texts%`
`%players/console% (doesn't|does not|do not|don't) have [the] permission[s] %texts%`
复制代码
针对这样的格式 我相信很多人可能一头雾水 了解如下几点 或许能帮助你更好的了解用法
"[]"内可以省略
"(...|...)"内必须选择一项填写
"%%"内必须根据其所对应的类型进行填写
player has permission "player.op"
player have the permissions "player.op"
player have permissions "player.op"
...
正如之前所说的 可以省略的地方 无论如何搭配 表达的意思都是一样的
这也是 Skript 一大特点 并不需要非常严谨的语法 只要意思对 语法可以根据个人喜好进行选择
同样我们还是举一个以 "on command" 监听器为核心的例子加深一下大家的理解
条件用于判断句:有没有,是不是。它的基本格式为 "if" + 条件。
这里我们和学习 Events 一样,我们先通过官方 Doc 找到所有的条件。
这里我们拿最常用的一个条件作示例,判断玩家是否有权限。
权限的英文是什么? "permission" 我们通过翻阅侧边栏可以得知与 "permission" 相关的只有 "Has Permission" 一条,官方对这个条件的解释为:"Test whether a player has a certain permission.",翻译过来就是 "检测一个玩家是否拥有某一权限"。即我们所需要的:判断玩家是否有权限,那么我们又该如何使用呢 "Has Permssion" 条件呢?
在 "Has Permission" 下 "Patterns" 给了我们两种标准格式用法:
- `%players/console% (has|have) [the] permission[s] %texts%`
- `%players/console% (doesn't|does not|do not|don't) have [the] permission[s] %texts%`
针对这样的格式,我相信很多人可能一头雾水。了解如下几点,或许能帮助你更好的了解用法:
- "[]" 内可以省略
- "(...|...)" 内必须选择一项填写
- "%%" 内必须根据其所对应的类型进行填写
- `player has permission "player.op"`
- `player have the permissions "player.op"`
- `player have permissions "player.op"`
正如之前所说的:可以省略的地方,无论如何搭配,表达的意思都是一样的。
这也是 Skript 一大特点,并不需要非常严谨的语法。只要意思对,语法可以根据个人喜好进行选择。
同样我们还是举一个以 "on command" 监听器为核心的例子加深一下大家的理解:
```skript
on command "/op":
event-commandsender is player
if event-player has permission "player.op":
@ -334,16 +340,23 @@ on command "/op":
else:
cancel event
send "false" to event-player
复制代码
那么在玩家触发此监听器后 系统将会判断玩家是否有 "player.op" 权限
如果有 指令将会正常进行 并发送 "true" 给玩家
如果没有 指令执行事件将被强制取消 并发送 "false" 给玩家
```
那么在玩家触发此监听器后,系统将会判断玩家是否有 "player.op" 权限。
如果有,指令将会正常进行,并发送 "true" 给玩家。
如果没有,指令执行事件将被强制取消,并发送 "false" 给玩家。
---
### Effects(效果)
与其说它是效果 不如称作行动
我们把条件类的示例拿下来接着分析
与其说它是效果,不如称作行动。
我们把条件类的示例拿下来接着分析:
```skript
on command "/op":
event-commandsender is "player"
if event-player has permission "player.op":
@ -351,8 +364,10 @@ on command "/op":
else:
cancel event
send "false" to event-player
复制代码
我们把两个条件判断句 分别用条件1和条件2替换 那么这段代码就可以写成
```
我们把两个条件判断句替换为条件1和条件2那么这段代码就可以理解为
```
指令监听 "/op":
事件-发送者类别 是 玩家
条件1:
@ -360,33 +375,38 @@ on command "/op":
条件2:
cancel event # 取消事件
send "false" to event-player # 发送消息给玩家
复制代码
我们可以看到 条件判断结束后 代码并没有直接结束 而是分别执行行动
如果我希望执行其他行动呢? 比如我想给一个玩家发送一个 Title 消息
通过在官方 Doc 搜索 关于 Title 相关的 Effects 一共有两个
https://skriptlang.github.io/Skript/effects.html#EffResetTitle
https://skriptlang.github.io/Skript/effects.html#EffSendTitle
通过查看官方的注释
#EffResetTitle
"Resets the title of the player to the default values."
"重置玩家的 Title 至默认值"
#EffSendTitle
"Sends a title/subtitle to the given player(s) with optional fadein/stay/fadeout times."
"发送 Title/Subtitle 至指定玩家 可自定义渐入和淡出的时间"
一目了然 我们需要的是 #EffSendTitle 关于怎么用
本质上和学习Conditions(条件)一样 我们将注意点放在 "Patterns" 上
```
我们可以看到,条件判断结束后,代码并没有直接结束,而是分别执行行动。
如果我希望执行其他行动呢? 比如我想给一个玩家发送一个 Title 消息:
通过在官方 Doc 搜索,我们得知关于 Title 相关的 Effects 一共有两个:
- (EffResetTitle)[https://docs.skriptlang.org/docs.html?search=#EffResetTitle]
"Resets the title of the player to the default values."
"重置玩家的 Title 至默认值"
- (EffSendTitle)[https://docs.skriptlang.org/docs.html?search=#EffSendTitle]
"Sends a title/subtitle to the given player(s) with optional fadein/stay/fadeout times."
"发送 Title/Subtitle 至指定玩家 可自定义渐入和淡出的时间"
我们需要知道的是 #EffSendTitle 的用法。关于怎么用这里本质上和学习Conditions(条件)一样,我们将注意点放在 "Patterns" 上。
``` skript
send title %text% [with subtitle %text%] [to %players%] [for %time span%] [with fade[(-| )]in %time span%] [(and|with) fade[(-| )]out %time span%]
send subtitle %text% [to %players%] [for %time span%] [with fade[(-| )]in %time span%] [(and|with) fade[(-| )]out %time span%]
复制代码
按照我们提到的规则
"[]"内可以省略
"(...|...)"内必须选择一项填写
"%%"内必须根据其所对应的类型进行填写
```
我们大致上认识到行动的基本用法 即
send title "..." with subtitle "..." to player for ... seconds with fade-in ... seconds and fade-out ... seconds
复制代码
将其带入进我们的主代码
按照我们提到的原则:
- "[]" 内可以省略
- "(...|...)" 内必须选择一项填写
- "%%" 内必须根据其所对应的类型进行填写
我们大致上认识到行动的基本用法,即:
`send title "..." with subtitle "..." to player for ... seconds with fade-in ... seconds and fade-out ... seconds`
将其带入进我们的伪代码:
```skript
指令监听 "/op":
事件-发送者类别 是 玩家
条件1:
@ -399,112 +419,161 @@ send title "..." with subtitle "..." to player for ... seconds with fade-in ...
条件2:
cancel event
send "false" to event-player
复制代码
三种方式我们都成功的发送了 Title 信息 只要记住我们的规则
"[]"内可以省略
"(...|...)"内必须选择一项填写
"%%"内必须根据其所对应的类型进行填写
```
所有的用法问题迎刃而解 学会读 "Patterns" 是初学者必备的技能
下文我将不会再提及如何使用 "Patterns" 查阅用法
通过以上三种方式,我们都能成功的发送了 Title 信息。
只要记住以上基本原则,所有的用法问题迎刃而解。
而学会读 "Patterns" 是初学者必备的技能,下文我将不会再提及如何使用 "Patterns" 查阅用法。
---
### Expressions(表达) & Types(类型)
假设你想要调整玩家的最大血量
调整血量 之前我们提过 动词 + 名词形式 这是属于 Effects(效果) 类
有一天你心血来潮,想要调整玩家的最大血量。
调整血量,之前我们提过这属于动词 + 名词形式,这是属于 Effects(效果) 类。
但是实际上是这样么?
实际上并不是 所谓的 Effect(效果) 虽然都是 动词 + 名词形式 但是对于 Effect(效果) 而言
注重的是 动词 而非后面跟着的 名词 例如 在玩家所在位置生成僵尸
实际上并不是,所谓的 Effect(效果) 虽然都是 `动词 + 名词` 形式,但是对于 Effect(效果) 而言。
注重的是 `动词` 而非后面跟着的 `名词` 例如 `在玩家所在位置生成僵尸`
Effect(效果) 所能提供的 只有 "生成"
通过查阅 Doc https://skriptlang.github.io/Skript/effects.html#EffSpawn 我们知道生成的用法基本为
通过查阅[官方文档](https://docs.skriptlang.org/docs.html?search=#EffSecSpawn),我们知道生成的用法基本为:
```skript
(spawn|summon) %entity types% [%directions% %locations%]
(spawn|summon) %number% of %entity types% [%directions% %locations%]
复制代码
但是除去这个词语 我们还剩 "在玩家所在位置" 和 "僵尸"
这两个词我们又该怎么处理呢? 这时候我们就需要用到 Expressions(表达)
位置的英文单词是 "Location" 我们在官方 Doc 查到了 3 种有关 "Location" 的表达
https://skriptlang.github.io/Skript/expressions.html#ExprLocation
https://skriptlang.github.io/Skript/expressions.html#ExprLocationOf
https://skriptlang.github.io/Skript/expressions.html#ExprLocationAt
我们需要什么呢? 我们需要 "玩家所在的位置" 相同地 通过查看官方的注释
我们知道我们需要的是 #ExprLocationOf (The location of a block or entity.)
但是这只解决了我们 "所在位置" 的问题 并没有解决 "玩家" 和 "僵尸" 的问题
我们可以看到 "所在位置" Expressions(表达) 是没有主语的 但是对于 Skript 而言
Skipt 不同于其他语言 正如我在开头所展示的 相比较 Java 而言 Skript 更注重的是语言而非编程
```
我们需要把这些零碎的东西组成句子 必不可少的是主语 次要的是宾语
这时候我们就需要引入 Types(类型) 但凡你发现你的表达里缺少主语/宾语(对象) 来这里准没错
https://skriptlang.github.io/Skript/classes.html
通过翻译我们可以轻松知道 玩家的英文 以及 僵尸的英文 分别为 "player" "zombie"
与之相对应的 我们分别在 Types(类别) 中找到
https://skriptlang.github.io/Skript/classes.html#player
https://skriptlang.github.io/Skript/classes.html#entity
综合上面我们所获得的信息 我们获得了完整一行代码
spawn zombie at location of player
复制代码
---
Wow 恭喜你 看到这 你就可以开始尝试着写一些插件了
这里刚好有一个例子 不妨动动手 试一试
在玩家破坏方块时 检查玩家是否有 "fundamental.break" 这个权限
如果有那就在让后台发送一条命令 "/broadcast %player% 破坏了方块"
如果没有那就取消这个事件 并 向这个玩家发送 "你不能破坏这个方块"
答案不唯一 仅供参考
但是除去这个词语,我们还剩 "在玩家所在位置" 和 "僵尸"。
这两个词我们又该怎么处理呢? 这时候我们就需要用到 Expressions(表达)。
位置的英文单词是 "Location" 我们在官方 Doc 查到了多种有关 "Location" 的表达
- https://docs.skriptlang.org/docs.html?search=#ExprLocation
- https://docs.skriptlang.org/docs.html?search=#ExprLocationOf
- https://docs.skriptlang.org/docs.html?search=#ExprLocationAt
我们需要什么呢? 我们需要 "玩家所在的位置"。相同地,通过查看官方的注释,我们知道我们需要的是 #ExprLocationOf (The location of a block or entity.)。
但是这只解决了我们 "所在位置" 的问题 并没有解决 "玩家" 和 "僵尸" 的问题。
我们可以看到 "所在位置"Expressions(表达) 是没有主语的。
Skript 不同于其他语言,正如我在开头所展示的,相比较 Java 而言 Skript 更**注重的是语言而非编程**。
我们需要把这些零碎的东西组成句子,必不可少的是主语,次要的是宾语。
这时候我们就需要引入 Types(类型),但凡你发现你的表达里缺少主语/宾语(对象),来这里准没错:
https://docs.skriptlang.org/classes.html
通过翻译我们可以轻松知道玩家的英文以及僵尸的英文,分别为 "player"和"zombie"。
与之相对应的,我们分别在 Types(类别) 中找到:
- https://docs.skriptlang.org/docs.html?search=#player
- https://docs.skriptlang.org/docs.html?search=#entity
综合上面我们所获得的信息 我们获得了完整一行代码:
```spawn zombie at location of player```
当然仅仅学这些并不够 为了做到能更快更灵活的使用各类语法
在闲暇的时候 把官方 Doc 提供的所有语法的注释都认真的看一遍是快速上手 Skript 的一种好办法
---
"loop"用法
你开始尝试着写一些有一些小功能的脚本了 但是难免的你会出现这样的问题
你为玩家创建了很多变量 很多都是属于一个类型的
比如你把所有人的游戏币数量都存在了 `{(玩家的名称)的游戏币数}` 这些变量内
你把所有人的点券数量都存在了 `{(玩家的名称)的点券数}` 这些变量内
平时你单独去操作这些变量的时候 觉得也很容易
但是假设突然有一次 由于回档需要补偿玩家损失
你需要将所有玩家的 `{(玩家的名称)的游戏币数}` 这个变量都 +1000
还好只有10个玩家数据 你可以一个一个调 就是浪费一点时间 倒还不成问题
但是如果你有10000个玩家数据 如果你一个一个调 可能玩家都走完了 你也调不完
你遇到了新的问题 如何存储并快速操作一类变量?
这时候你需要两样东西 "数组" "loop"
WOW恭喜你看到这你就可以开始尝试着写一些插件了。
这里刚好有一个例子,不妨动动手,试一试。
- 在玩家破坏方块时 检查玩家是否有 "fundamental.break" 这个权限
- 如果有那就在让后台发送一条指令 "/broadcast %player% 破坏了方块"
- 如果没有那就取消这个事件 并 向这个玩家发送 "你不能破坏这个方块"
答案不唯一,仅供参考。
当然仅仅学这些并不够,为了做到能更快更灵活的使用各类语法,在闲暇的时候,把官方 Doc 提供的所有语法的注释都认真的看一遍是快速上手 Skript 的一种好办法。
---
你开始尝试着写一些有一些小功能的脚本了,但是难免的你会出现这样的问题:
你为玩家创建了很多变量,很多都是属于一个类型的。
比如你把所有人的游戏币数量都存在了 `{(玩家的名称)的游戏币数}` 这些变量内,你把所有人的点券数量都存在了 `{(玩家的名称)的点券数}` 这些变量内……
平时你单独去操作这些变量的时候,觉得也很容易。
但是假设突然有一次,由于回档需要补偿玩家损失。
你需要将所有玩家的 `{(玩家的名称)的游戏币数}` 变量都 +1000。
还好只有10个玩家数据你可以一个一个调就是浪费一点时间倒还不成问题。
但是如果你有10000个玩家数据如果你一个一个调可能玩家都走完了你也调不完。
你遇到了新的问题,如何存储并快速操作一类变量?
这时候你需要两样东西:"数组"和"loop"。
### 数组
数组的基本格式为 `{变量名::变量名::变量名......}`
我们带入实景 将用 `{(玩家的名称)的游戏币数}` 存储转为用 `{金币::(玩家的名称)}` 存储玩家的游戏币数量
我现在服务器有 10000 个玩家
玩家名称为 1,2,3,......,10000
玩家游戏币数量为 100,200,300,......,1000000
那么对应的 `{金币::1}` 就是 名为 "1" 玩家的游戏币数量 100
如果我用输出语句输出 `{金币::1}` 至后台 那么很显然我会得到 100 这个数值
同样的我用输出语句输出 `{金币::10000}` 至后台 我会得到 1000000 这个数值
你可能会说 这不是和用 `{(玩家的名称)的游戏币数}` 一样么?
是的 确实 如果仅仅需要获得某一个玩家的游戏币数量 两者并没有什么区别
但是 数组好用之处在于 如果我将 `{金币::(玩家的名称)}` 中玩家的名称改为 "*" 即 ``{金币::*}``
这时候会产生什么样的效果呢?
``{金币::*}`` 将包含 所有 ``{金币::(玩家的名称)}`` 变量
而这个 却是 ``{(玩家的名称)的游戏币数量}`` 怎么改也做不到的
数组的基本格式为 `{变量名::变量名::变量名......}`
我们带入实景,将用 `{(玩家的名称)的游戏币数}` 存储转为用 `{金币::(玩家的名称)}` 存储玩家的游戏币数量。
例如,服务器有 10000 个玩家,玩家名称为 1,2,3,......,10000玩家游戏币数量为 100,200,300,......,1000000。
那么对应的 `{金币::1}` 就是:名为 "1" 玩家的游戏币数量 100。
如果我用输出语句输出 `{金币::1}` 至后台,那么很显然我会得到 100 这个数值。
同样的我用输出语句输出 `{金币::10000}` 至后台,我会得到 1000000 这个数值。
你可能会说,这不是和用 `{(玩家的名称)的游戏币数}` 一样么?
是的,确实。如果仅仅需要获得某一个玩家的游戏币数量,两者并没有什么区别。
但是,如果我将 `{金币::(玩家的名称)}` 中玩家的名称改为 "*" 即 ``{金币::*}``,这时候会产生什么样的效果呢?
``{金币::*}`` 将包含,所有 ``{金币::(玩家的名称)}`` 变量。
而这个,却是 `{(玩家的名称)的游戏币数量}` 怎么改也做不到的。
### Loop
利用数组我们知道了如何快速获取一类数据
但是我们又该如何快速操作这一类数据呢? 这时候就需要引入我们的 Loop 结构
Loop 即 循环结构 是 Skript 里非常常用的结构语句 主要用于操作数据量较大的一类变量
Loop 共有几大标准配合
Loop + 数组 / Loop + 次数 / Loop + Types(类型)
利用数组我们知道了如何快速获取一类数据。
但是我们又该如何快速操作这一类数据呢? 这时候就需要引入我们的 Loop 结构。
Loop 即 循环结构,是 Skript 里非常常用的结构语句,主要用于操作数据量较大的一类变量。
以下是 Loop 的几大标准配合:
### Loop + 数组 结构
(To Be Added.)
### Loop + 次数 结构
(To Be Added.)
### Loop + Types(类型) 结构
(To Be Added.)
---
### 注册指令
说到现在 我们所有的代码 似乎都是基于监听器进行编写的
我们都需要去触发监听器 才能执行我们的代码 那有没有什么办法可以主动触发我们的代码?
这时候我们就需要引入 MineCraft 插件最核心的功能 指令功能而在 Java 里你可能需要这样注册一个指令
说到现在,我们所有的代码,似乎都是基于监听器进行编写的。
我们都需要去触发监听器,才能执行我们的代码,那有没有什么办法可以主动触发我们的代码?
这时候我们就需要引入 Minecraft 插件最核心的功能,指令功能。
在 Java 里你可能需要这样注册一个指令。
```Java
@Override
@ -517,56 +586,75 @@ public boolean onCommand(final CommandSender sender, Command cmd, String label,
```
但是在 Skript 里你只需这样即可
```skript
command /自定义指令:
trigger:
代码段
复制代码
你并不需要理解其他是什么意思 仅仅需要记住这个格式即可
如果我想注册一个 "/我学你马Java" 的命令 你只需这样
```
你并不需要理解前者是什么意思,仅仅需要记住后者的格式即可。
如果我想注册一个 "/我学你马Java" 的指令,你只需这样:(编者注:不建议注册中文指令。)
```skript
command /我学你马Java:
trigger:
kill player
send "不许说Java坏话" to player
复制代码
通过测试 指令正常触发
通过套公式 你可以创造成千上万的指令不成问题 但是实际上我们在使用一个插件的时候
并不是只有 "/..." 结构的指令存在 更多的是 "/... ... ..." 来构成一类指令
那我们又该如何注册这样结构的指令呢? 非常简单 基本格式与上面几乎无异
```
通过测试,指令正常触发。
通过套公式,你可以创造成千上万的指令不成问题,但是实际上我们在使用一个插件的时候,并不是只有 `/...` 结构的指令存在,更多的是 `/... ... ...` 来构成一类指令。
那我们又该如何注册这样结构的指令呢? 非常简单,基本格式与上面几乎无异。
```skript
command /自定义指令 [<类型>] [<类型>] ...:
trigger:
代码段
```
本人写代码时常用的结构就是这样
有人问 "类型" 有哪些 其实我也说不全 我常用的有这几种
"text" - 字符类型 什么是字符? 就是字面意思 字词符号
"player" - 在线玩家
"offline player" - 离线玩家
"number" - 数字类型
"integer" - 整数类型
那这些类型又有什么用处呢? 它实际上是限制了你可以输入的参数
比如我创建如下指令
本人写代码时常用的结构就是这样。
```
有人问 "类型" 有哪些,其实我也说不全,我常用的有这几种。(编者注,见本页 `了解八大类`。)
- "text" - 字符类型。什么是字符? 可以按照字面意思来理解,字词符号。
- "player" - 在线玩家。
- "offline player" - 离线玩家。
- "number" - 数字类型。
- "integer" - 整数类型。
那这些类型又有什么用处呢? 它实际上是对指令的参数的一种限制。
比如我创建如下指令:
```skript
command /hello [<player>]:
trigger:
代码段
```
可以看到 第一个空格的位置 我需要的参数类型为在线玩家
那么我在执行这个指令的时候必须在这个位置上填上一个在线玩家的名称
同样的如果我把 `"[<player>]"` 换成 `"[<integer>]"` 我就需要在这个位置上填写一个整数
如果我填了 "1.2"(小数/浮点数) Skript 就会提示我 填写的参数类型错误
为什么填写参数 那肯定是在代码段内需要使用这些输进来的参数
那么我们在代码段里有该如何调用这些被我们输入进来的参数呢?
比如像是上面这个指令 它只有一个可以填参数的位置 那么在代码段内 它就是 arg-1 即 第一个参数的意思
我们只需要记住核心规则 它排在第几位 在代码段内 它就是 "arg-几"
当然我在这块的了解并不是很深入 为了不把大家带上歪路 这里引用国外 Skript 作者更为详细的指令注册的教程
---
可以看到,第一个空格的位置,我需要的参数类型为在线玩家。
```
那么我在执行这个指令的时候,必须在这个位置上填上一个在线玩家的名称。
同样的如果我把 `"[<player>]"` 换成 `"[<integer>]"`,我就需要在这个位置上填写一个整数。
如果我填了 "1.2"(小数/浮点数)Skript 就会提示我,填写的参数类型错误。
为什么填写参数?那肯定是在代码段内需要使用这些输进来的参数。
那么我们在代码段里有该如何调用这些被我们输入进来的参数呢?
比如像是上面这个指令,它只有一个可以填参数的位置。那么在代码段内,它就是 `arg-1`,即`第一个参数`的意思。
我们只需要记住核心规则,它排在第几位,在代码段内,它就是 "arg-几"。
当然我在这块的了解并不是很深入,为了不把大家带上歪路,这里引用国外 Skript 原作者更为详细的指令注册的教程。
```skript
command /<指令名称> <参数>:
  aliases:
  executable by:
@ -582,44 +670,48 @@ command /<指令名称> <参数>:
    代码段
```
命令名称(必填)
命令名称基本上是命令 您可以在命令名称中使用任何字符(空格字符除外)
当然如果在命令名称中使用空格字符 那么空格字符后的文本将成为参数
命令名称前的斜杠字符(/)是可选的(但这并不意味着您可以在执行命令时不带斜杠)
参数(可选)
可以通过将参数放在 "[]" 中来使其成为可选参数
类型参数
可以通过使用规定的格式来限制参数的类型 例如: `<type = default value>`
- 类型为 "text/string" 的参数可以接受任何字符 但 "object" 类型不能用作于参数
- 类型可以是多个 (例如 number -> numbers entity -> entities) 通过这样的方法 可以使参数接受多个值
- "= default value" 这一部分是可选的 如果命令执行者未输入参数 系统将自动使用默认值
- 同样你也可以使用这样的方式设置参数默认值 例如: `<item = %player's tool%>`
命令示例:
- 指令名称(必填)
指令名称基本上是指令,您可以在指令名称中使用任何字符(空格字符除外)。
当然如果在指令名称中使用空格字符,那么空格字符后的文本将成为参数。
指令名称前的斜杠字符(/)是可选的(但这并不意味着您可以在执行指令时不带斜杠)。
- 参数(可选)
可以通过将参数放在 "[]" 中来使其成为可选参数。
- 类型参数
可以通过使用规定的格式来限制参数的类型,例如: `<type = default value>`
- 类型为 "text/string" 的参数可以接受任何字符,但 "object" 类型不能用作于参数(编者注:原因大抵是无法输入 `object`)。
- 类型可以是多个 (例如 number -> numbers entity -> entities)。通过这样的方法,可以使参数接受多个值。
- "= default value" 这一部分是可选的,如果指令执行者未输入参数,系统将自动使用默认值。
- 同样你也可以使用这样的方式设置参数默认值,例如: `<item = %player's tool%>`
以下是一份指令示例:
`command /kill <entity types> [in [the] radius <number = 20>]:`
使用 /kill zombies /kill creepers and animals in radius 100 或 /kill monsters in the radius 6 都是可以的
但是如果没有输入数值 系统将自动使用默认值 半径 20
Aliases
子命令 命令的别名 如果需要创建多个子命令 请使用用逗号分隔
示例:(/alias1,alias2,/alias3
Executable By
指定可以使用该命令的执行者
例如console(后台) players(玩家) the console and players(后台和玩家)
Usage
使用不正确时 将发送的消息
Description
命令描述 其他插件可以获取/显示此信息
Permission
执行命令所需要的权限
Permission Message
执行者没有权限 提示信息
Cooldown
多长冷却时间后可以再次使用该命令 需要注意的是 关服时所有命令冷却时间将被重置
Cooldown Message
冷却期间 提示信息
Cooldown Bypass
无视冷却时间所需要的权限
Cooldown Storage
存储冷却时间全局变量名称
使用 `/kill zombies /kill creepers and animals in radius 100``/kill monsters in the radius 6` 都是可以的。
但是如果没有输入数值,系统将自动使用默认值,半径 20。
- Aliases
子指令,指令的别名。如果需要创建多个子指令,请使用用逗号分隔。
示例:(/alias1,alias2,/alias3
- Executable By
指定可以使用该指令的执行者。
例如console(后台), players(玩家), the console and players(后台和玩家)
- Usage
执行者用法不正确时,将发送的消息。
- Description
指令描述,其他插件可以获取/显示此信息。
- Permission
执行指令所需要的权限。
- Permission Message
执行者没有权限时的提示信息。
- Cooldown
多长冷却时间后可以再次使用该指令,需要注意的是,关服时所有指令冷却时间将被重置。
- Cooldown Message
冷却期间,提示信息。
- Cooldown Bypass
无视冷却时间所需要的权限。
- Cooldown Storage
存储冷却时间全局变量名称。
---
@ -631,7 +723,7 @@ Cooldown Storage
这里取 SUPERGUILDS 的一段代码做讲解。
```
```skript
file "plugins/SUPERGUILDS/%{_fileDir}%.yml" does not exists:
create file "plugins/SUPERGUILDS/%{_fileDir}%.yml"
yaml "plugins/SUPERGUILDS/%{_fileDir}%.yml" is not loaded:
@ -660,7 +752,7 @@ function 方法名(参数名:参数类型, 参数名:参数类型, ...):
(关于参数名以及参数类型的定义 可以在 "Command" 栏目下找到 此处不再赘述)
套用公式 我们可以把上面的代码段转换成方法段
```
```skript
function SG_writeFile(variableName: text, value: text, fileDir: text):
file "plugins/SUPERGUILDS/%{_fileDir}%.yml" does not exists:
create file "plugins/SUPERGUILDS/%{_fileDir}%.yml"
@ -672,7 +764,7 @@ function SG_writeFile(variableName: text, value: text, fileDir: text):
若想将 "plugins/SUPERGUILDS/playerdata/玩家UUID.yml" 的 "Datas.Username" 设置为 "**EVER"
```
```skript
file "plugins/SUPERGUILDS/playerdata/%uuid of player%.yml" does not exists:
create file "plugins/SUPERGUILDS/playerdata/%uuid of player%.yml"
yaml "plugins/SUPERGUILDS/playerdata/%uuid of player%.yml" is not loaded:
@ -683,7 +775,7 @@ file "plugins/SUPERGUILDS/playerdata/%uuid of player%.yml" does not exists:
代码即可转换为
```
```skript
SG_writeFile("Datas.Username", "**EVER", "playerdata/%uuid of player%")
```
@ -719,7 +811,7 @@ function 方法名(参数名:参数类型, 参数名:参数类型, ...) :: 输
计算机更是这样。所以这时候就需要参数类型来规范我们运算中的这些值,以下是一份示例。
```
```skript
function SI_isSlotAvaliable(s: integer, z: integer) :: boolean:
set {_m} to {_z} * 9 - 1
{_s} is not between 0 and {_m}:
@ -737,3 +829,10 @@ function SI_isSlotAvaliable(s: integer, z: integer) :: boolean:
到此,所有基础教程已结束,谢谢大家赏脸看完。全文 11111 字,都是自己的一些干货,点个收藏,给点人气便是对我最大的支持。
(请支持原作者 TUCAOEVER。
### 编者 (氿月) 的主要改动
1. 在部分地方加上了注释。
2. 改动了已经失效的原文档链接。
3. 对整篇文章进行了重格式化,使之更符合现代汉语语法和 Markdown 语法,一定程度上增强了可读性。
4. 统一了文章中出现的部分译名,如 `command`,统一使用 `指令` 来指代。