koishi-plugin-achievement
基于 Koishi 的成就系统。
注意:此插件需要依赖数据库服务运行。
基本用法
这是一个基础插件,它提供了名为 achievements
的服务。其他插件可以使用此服务注册不同的成就,并通过事件系统在期望的时机触发成就。
下面将以猜数字游戏为例,介绍成就系统的注册方法。
注册成就
使用 ctx.achievement.register
方法注册成就。任何成就都至少需要提供以下 3 个属性:
ts
ctx.achievement.register({
// 成就的唯一标识符
id: 'guess-number.quick',
// 用于显示的成就名称
name: '预言家',
// 成就的描述文本
desc: '在一局猜数字游戏中在 3 步之内猜对结果。',
})
除此以外,成就系统还支持一批可选属性,将在下面介绍。
触发成就
我们可以在会话对象上触发成就。
ts
if (steps <= 3) {
// 修改用户的成就记录,并返回一个字符串:
// 恭喜 用户名 取得了成就「预言家」!
session.achieve('guess-number.quick')
}
我们也可以传入第二个参数,表示是否触发。因此上面的写法等价于:
ts
// 修改用户的成就记录,并返回一个字符串:
// 恭喜 用户名 取得了成就「预言家」!
session.achieve('guess-number.quick', steps <= 3)
任何成就只会触发一次。如果该用户已经获得过该成就,则上述调用只会返回一个空串。
查看成就
使用 achv 指令查看成就列表:
它有如下的选项列表:
-a
显示已获得的成就-A
显示未获得的成就-f
显示全部成就,相当于-aA
在 achv 后面加上成就名可以查看具体的成就信息:
管理员操作
高级用法
隐藏成就
默认情况下未取得的成就的名称和描述都是可见的。如果想要设计隐藏成就,我们提供了两种方案。
- 如果想要隐藏整个成就,可以使用
hidden
属性。被隐藏的成就不会显示在成就列表中,也无法用成就名查看。当用户使用-A
选项查看未获得的成就时,成就名将会显示为????
。 - 如果想要隐藏成就的描述,可以使用
hint
属性。当成就未被取得时,成就描述将被替换为hint
中定义的文本。
成就进度
如果想在未取得成就的状态下显示获取进度,可以使用 progress
属性。它应该是一个函数,接收一个用户对象,返回一个 0~1 之间的进度值。这个回调函数所需的用户字段可以使用 userFields
属性指定。
多级成就
一个成就可以被分为多个阶段分别完成。每达成一个阶段都会触发对应的提示。它的实现方法也非常简单:只需将上述 desc
属性替换为对应的数组即可。
此时如果 name
仍为字符串,那么每一级成就的名称相同;如果 name
也为数组,则每一级成就会有不同的名称。玩家默认只能看到第一级的名称,只有解锁后续等级后才能看到对应的名称。
ts
ctx.achievement.register({
id: 'guess-number.many',
name: ['日积月累', '水滴石穿'],
desc: [
'总共完成 100 次猜数字游戏。',
'总共完成 1000 次猜数字游戏。',
],
})
触发成就时,需要向 session.achieve()
传入数组作为第二个参数,表示每一级是否触发。
ts
session.achieve('guess-number.many', [
count >= 100,
count >= 1000,
])
成就分类
如果你的成就数量太多,那么在显示时就很容易刷屏。
多语言支持 [WIP]
成就系统也支持多语言。只需将上述任意字符串替换为键值对即可:
ts
ctx.achievement.register({
id: 'guess-number.quick',
name: {
zh: '预言家',
en: 'Prophet',
},
desc: {
zh: '在一局猜数字游戏中在 3 步之内猜对结果。',
en: 'Answer correctly within 3 moves in a number guessing game.'
},
})
如果你安装了 @koishijs/plugin-locales,这些字符串也可以在网页控制台中修改。