diff --git a/README.md b/README.md index e36f950..fa68803 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,234 @@ -# 海豹js扩展模板 +# 最终物语规则插件 +## 介绍 -### 介绍 +本插件工作于 [海豹骰点核心](https://github.com/sealdice/sealdice-core),并基于其 [TS 模板库](https://github.com/sealdice/sealdice-js-ext-template) 实现。 -一个简单易用的项目模板。 +本插件为海豹核心带来了「最终物语(Fabula Ultima)」规则支持。 -使用esbuild编译代码,并将多个源码文件打包成一个。 +> [!NOTE] +> 目前,由于官方中文版规则书尚未发布,部分名词采用的是民间汉化版翻译,会在官方中文规则书发布后进行修正替换。 +## 安装 -### 如何使用 +在本项目 Release 页面中,直接下载最新编译的 JS 文件,或 [点击这里](https://github.com/MintCider/seal-fu/releases/latest/download/seal-fu.js) 下载。随后上传到海豹核心即可。 -clone或下载项目,随后: +## 命令 +### `.st` 操作人物卡 + +`.st` 命令的使用方式请参考 [海豹手册相关内容](https://docs.sealdice.com/use/coc7.html#st-%E6%93%8D%E4%BD%9C%E4%BA%BA%E7%89%A9%E5%8D%A1),这里着重介绍最终物语规则相关的人物卡属性。 + +| 属性名 | 属性别名 | +|---------|-------------------------------------| +| 生命值 | hp、hit point、hit points | +| 生命值上限 | hpmax | +| 精神值 | mp、mental point、mental points | +| 精神值上限 | mpmax | +| 库存点 | ip、inventory point、inventory points | +| 库存点上限 | ipmax | +| 物语点 | fp、fabula point、fabula points | +| 泽尼特 | z、zenit | +| 先攻修正值 | im、initiative modifier | +| 物防 | pd、df、defense、物理防御 | +| 魔防 | md、magical defense、魔法防御 | +| 灵巧骰面初始值 | dex、dexterity、灵巧 | +| 洞察骰面初始值 | ins、insight、洞察 | +| 力量骰面初始值 | mig、might、力量 | +| 意志骰面初始值 | wlp、willpower、意志 | + +在初始化人物卡时,可以使用任意属性别名进行属性设定,插件会自动将其转化为对应的属性。 + +> [!NOTE] +> 设定灵巧、洞察、力量、意志四维属性时,请输入对应属性骰的面数(6、8、10、12 之一)。当属性骰发生变动时(如状态效果、临时 buff 等),请不要使用 `.st` 修改,请参考后面的 `.buff` 和 `.ds` 命令。 + +以下两个例子都是合理的属性设定方式: + +```text +.st 卡珊德拉-灵巧10 洞察6 力量8 意志8 生命值50 生命值上限50 精神值50 精神值上限50 库存点6 库存点上限6 物语点3 泽尼特170 先攻修正值-2 物防11 魔防8 ``` -npm install -npm run build + +```text +.st 卡珊德拉-dex=10 ins=6 mig=8 wlp=8 hp=50 hpmax=50 mp=50 mpmax=50 ip=6 ipmax=6 fp=3 z=170 im=-2 pd=11 md=8 ``` -好的,现在你的项目被编译成功了,就在dist目录。 +### `.sn` 自动群名片 -默认的名字是`sealdce-js-ext.js`,其逻辑写在src/index.ts +`.sn` 命令的使用方式请参考 [海豹手册相关内容](https://docs.sealdice.com/use/log.html#sn-%E8%87%AA%E5%8A%A8%E7%BE%A4%E5%90%8D%E7%89%87),这里着重介绍最终物语规则提供的两个群名片预设模版。 +- `.sn fu`:`角色名 HP50/50 MP50/50 IP6/6 FP3 Z170 PD11 MD8` +- `.sn fuS`:`角色名 HP50/50 MP50/50 PD11 MD8` -### 开发指南 +### `.rc` 检定 -看这里,这边有大量的例子,以及海豹用户写的插件: +`.rc <属性 1>+<属性 2>+<修正值>` -https://github.com/sealdice/javascript +支持的属性为:灵巧、洞察、力量、意志、dex、ins、mig、wlp,不区分大小写。 -由于无法动态调试,建议将纯逻辑部分独立编写,随后你就可以在调试编译后,用nodejs去验证你的想法: +支持的修正值为:整数。 +例子: + +```text +.rc 灵巧+洞察+1 +.rc mig+wlp-2 ``` -npm run build-dev -node ./dev/sealdice-js-ext.js + +```text +<卡珊德拉>的灵巧+洞察+1检定结果为:d8(缓慢)+d6+1=[4+6+1]=11 +HR:6 ``` -当然,不止是node,任何其他js环境都行,浏览器里也行。 +如果由于状态效果或临时 buff 导致属性骰发生变动,检定回复中会进行提示。如果检定出大成功/大失败,检定回复会进行提示。同时,检定回复会自动显示 HR。 + +### `.ri` 先攻 + +`.ri [修正值]` + +自动进行一次「灵巧+洞察+先攻修正值」的检定,可以额外附加一个整数修正值。 + +例子: + +```text +.ri +.ri +3 +``` + +```text +<卡珊德拉>的先攻检定结果为:d8(缓慢)+d6+0(先攻修正)+3=[7+3+0+3]=13 +``` + +### `.buff` 状态效果 + +此命令支持的状态效果为:缓慢、眩晕、虚弱、动摇、愤怒、中毒。 + +#### 切换状态效果 + +`.buff <状态效果>` + +为自己附加或消除某种状态效果。 + +#### 附加状态效果 + +`.buff add <状态效果>` + +#### 消除状态效果 + +`.buff del <状态效果>` + +`.buff clr` + +后者会消除全部状态效果。 + +### `.ds` 临时调整属性骰 + +此命令支持的属性为:灵巧、洞察、力量、意志、dex、ins、mig、wlp,不区分大小写。 + +此命令支持的调整值为:整数。 + +> [!NOTE] +> 每一点调整值会改变属性骰的一个**级别**,即骰面增大或减小 2. + +#### 将对应属性骰增大或减小对应级别 +`.ds <属性>+<调整值>` -### 填写个人信息 +#### 重置属性骰 -当插件开发完成后(或者开始开发时),你需要修改几处地方: +`.ds rst <属性>` -* header.txt 这个文件是你插件的描述信息 +`.ds rst all` -* tools/build-config.js 最开头一行"var filename = 'sealdce-js-ext.js';",改成你中意的名字,注意不要与现有的重名 +后者会重置全部属性骰。 +#### 例子 -### 编译和发布 +> [!NOTE] +> 此命令与状态效果产生的影响叠加计算,并且永远不会超出属性骰的上下限。 +```text +.buff 缓慢 +.ds 力量+1 +.ds dex-1 +.rc dex+mig ``` -npm run build + +```text +<卡珊德拉>的灵巧+力量检定结果为:d6(缓慢、ds-1)+d10(ds+1)=[3+9]=12 +HR:9 +``` + +### `.bond` 牵绊 + +> [!NOTE] +> 目前,牵绊仅作为辅助记录,不会对检定产生影响。 + +此命令支持的情感为:赞赏、自卑、忠诚、怀疑、喜爱、仇恨。 + +#### 建立牵绊 + +`.bond add <名字> <情感>` + +#### 遗忘牵绊 + +`.bond del <编号>/<名字>` + +`.bond clr` + +后者会遗忘全部牵绊。 + +#### 调整牵绊情感 + +`.bond emo add <编号>/<名字> <情感>` + +`.bond emo del <编号>/<名字> <情感>` + +#### 查看所有牵绊 + +`.bond list` + +#### 例子 + +```text +.bond add 布莱尔 赞赏 +``` + +```text +.bond emo add 1 喜爱 +<卡珊德拉>与<布莱尔>的牵绊增加了喜爱情感 +``` + +```text +.bond emo add 1 仇恨 +<卡珊德拉>与<布莱尔>的牵绊已有喜爱情感,不能再增加仇恨情感 +``` + +```text +.bond emo del 布莱尔 喜爱 +<卡珊德拉>与<布莱尔>的牵绊不再有喜爱情感 ``` -从dist目录找出你的编译结果,将其装入海豹测试并分享即可! +### `.clk` 命刻 + +#### 创建命刻 + +`.clk add <名字> <大小> [进度]` + +命刻的进度默认为 0,可以通过提供 `[进度]` 参数调整初始进度。 + +#### 删除命刻 + +`.clk del <名字>` + +`.clk clr` + +后者会删除全部命刻。 + +#### 调整进度 -当然,你也可以把你的劳动成果提交到这里: +`.clk fill <名字> <进度变化>` -https://github.com/sealdice/javascript/tree/main/scripts +使对应命刻的进度发生对应变化,进度变化应为正负整数,超过命刻范围(`[0, 命刻大小]`)的变化会限制在范围之内。 -这样用户就可以直接在海豹的插件面板进行安装了。 +#### 查看群内全部命刻 +`.clk list` diff --git a/docs/release_notes/v0.1.0.md b/docs/release_notes/v0.1.0.md new file mode 100644 index 0000000..1d79074 --- /dev/null +++ b/docs/release_notes/v0.1.0.md @@ -0,0 +1,11 @@ +## 功能 + +- 适配海豹核心 `.st` 命令,可以通过 `.st` 设定人物卡属性。 +- 增加 `.rc` 命令用于检定掷骰。 +- 增加 `.ri` 命令用于先攻掷骰。 +- 增加 `.buff` 命令用于附加状态效果。 +- 增加 `.ds` 命令用于临时修改属性骰大小。 +- 增加 `.bond` 命令用于记录牵绊。 +- 增加 `.clk` 命令用于记录命刻。 + +请参考 README 或帮助文本(`. help`)使用以上命令。 diff --git a/header.txt b/header.txt index 170a6ce..a16c62f 100644 --- a/header.txt +++ b/header.txt @@ -3,9 +3,23 @@ // @author Mint Cider // @version 0.1.0 // @description 为海豹添加最终物语规则。详细使用说明见项目主页 README。 -// @timestamp 1728294492 +// @timestamp 1728452500 // @license MIT // @homepageURL https://github.com/MintCider/seal-fu // @updateUrl https://github.com/MintCider/seal-fu/releases/latest/download/seal-fu.js -// @sealVersion 1.2.0 +// @sealVersion >=1.2.0-0 // ==/UserScript== + +// # v0.1.0 更新日志 +// +// ## 功能 +// +// - 适配海豹核心 `.st` 命令,可以通过 `.st` 设定人物卡属性。 +// - 增加 `.rc` 命令用于检定掷骰。 +// - 增加 `.ri` 命令用于先攻掷骰。 +// - 增加 `.buff` 命令用于附加状态效果。 +// - 增加 `.ds` 命令用于临时修改属性骰大小。 +// - 增加 `.bond` 命令用于记录牵绊。 +// - 增加 `.clk` 命令用于记录命刻。 +// +// 请参考 README 或帮助文本(`. help`)使用以上命令。 diff --git a/src/data.ts b/src/data.ts new file mode 100644 index 0000000..5acedf8 --- /dev/null +++ b/src/data.ts @@ -0,0 +1,239 @@ +export const attributeEffects = { + "灵巧": ["缓慢", "愤怒"], + "洞察": ["眩晕", "愤怒"], + "力量": ["虚弱", "中毒"], + "意志": ["动摇", "中毒"], +} + +export const numToChinese = {1: "一", 2: "二", 3: "三", 4: "四", 5: "五", 6: "六"} + +export const emoToKey = {"赞赏": "赞赏", "自卑": "赞赏", "忠诚": "忠诚", "怀疑": "忠诚", "喜爱": "喜爱", "仇恨": "喜爱"} + +export const emoToValue = {"赞赏": 1, "自卑": -1, "忠诚": 1, "怀疑": -1, "喜爱": 1, "仇恨": -1} + +export const negEmo = {"赞赏": "自卑", "自卑": "赞赏", "忠诚": "怀疑", "怀疑": "忠诚", "喜爱": "仇恨", "仇恨": "喜爱"} + +// function generateBondExpr(index: number): string { +// if (!(index in [1, 2, 3, 4, 5, 6])) { +// return ""; +// } +// const numStr = numToChinese[index]; +// return "{" + +// `$t赞赏文本 = 牵绊${numStr}赞赏 == 1 ? '赞赏', 牵绊${numStr}赞赏 == -1 ? '自卑', 牵绊${numStr}赞赏 == 0 ? ''; ` + +// `$t忠诚文本 = 牵绊${numStr}忠诚 == 1 ? '忠诚', 牵绊${numStr}忠诚 == -1 ? '怀疑', 牵绊${numStr}忠诚 == 0 ? ''; ` + +// `$t喜爱文本 = 牵绊${numStr}喜爱 == 1 ? '喜爱', 牵绊${numStr}喜爱 == -1 ? '仇恨', 牵绊${numStr}喜爱 == 0 ? ''; ` + +// `if 牵绊${numStr}喜爱 && (牵绊${numStr}赞赏 || 牵绊${numStr}忠诚) {$t喜爱文本 = '与' + $t喜爱文本}; ` + +// `if 牵绊${numStr}忠诚 && 牵绊${numStr}赞赏 && 牵绊${numStr}喜爱 {$t忠诚文本 = '、' + $t忠诚文本}; ` + +// `if 牵绊${numStr}忠诚 && 牵绊${numStr}赞赏 && 牵绊${numStr}喜爱 == 0 {$t忠诚文本 = '与' + $t忠诚文本}` + +// `}{牵绊${numStr}}-{$t赞赏文本}{$t忠诚文本}{$t喜爱文本}` +// } + +function generateAttributeExpr(attribute: string): string { + const effect1 = attributeEffects[attribute][0]; + const effect2 = attributeEffects[attribute][1]; + return "{" + + `if ${attribute}骰面 == 0 {${attribute}骰面 = ${attribute}骰面初始值}; ` + + `if ${effect1} {$t${effect1}文本 = '${effect1}'; $t${attribute}变动 = 1} ` + + `else {$t${effect1}文本 = ''}; ` + + `if ${effect2} {$t${effect2}文本 = $t${attribute}变动 ? '、${effect2}' : '${effect2}'; $t${attribute}变动 = 1} ` + + `else {$t${effect2}文本 = ''}; ` + + `if ${attribute}骰面增减值 {$t${attribute}增减文本 = ($t${attribute}变动 ? '、' : '') + (${attribute}骰面增减值 > 0 ? \`ds+{${attribute}骰面增减值}\` : \`ds{${attribute}骰面增减值}\`)} ` + + `else {$t${attribute}增减文本 = ''}; $t${attribute}变动 = 0; $t${attribute}附属文本 = $t${effect1}文本 + $t${effect2}文本 + $t${attribute}增减文本; ` + + `if $t${attribute}附属文本 {$t${attribute}附属文本 = \`({$t${attribute}附属文本})\`}; 'd' + str(${attribute}骰面) + $t${attribute}附属文本` + + "}" +} + +export function generateAttributeStatusExpr(attribute: string): string { + const effect1 = attributeEffects[attribute][0]; + const effect2 = attributeEffects[attribute][1]; + return "{" + + `if ${effect1} {$t${effect1}文本 = '${effect1}'; $t${attribute}变动 = 1} ` + + `else {$t${effect1}文本 = ''}; ` + + `if ${effect2} {$t${effect2}文本 = $t${attribute}变动 ? '、${effect2}' : '${effect2}'; $t${attribute}变动 = 1} ` + + `else {$t${effect2}文本 = ''}; ` + + `if ${attribute}骰面增减值 {$t${attribute}增减文本 = ($t${attribute}变动 ? '、' : '') + (${attribute}骰面增减值 > 0 ? \`ds+{${attribute}骰面增减值}\` : \`ds{${attribute}骰面增减值}\`)} ` + + `else {$t${attribute}增减文本 = ''}; $t${attribute}变动 = 0; $t${attribute}附属文本 = $t${effect1}文本 + $t${effect2}文本 + $t${attribute}增减文本; ` + + `if $t${attribute}附属文本 {$t${attribute}附属文本 = \`({$t${attribute}附属文本})\`}; $t${attribute}附属文本` + + "}" +} + +// const statusExpr = "{" + +// "if 缓慢 {$t缓慢文本 = '缓慢'; $t存在状态效果 = 1} " + +// "else {$t缓慢文本 = ''}; " + +// "if 眩晕 {$t眩晕文本 = $t存在状态效果 ? '+眩晕' : '眩晕'; $t存在状态效果 = 1} " + +// "else {$t眩晕文本 = ''}; " + +// "if 虚弱 {$t虚弱文本 = $t存在状态效果 ? '+虚弱' : '虚弱'; $t存在状态效果 = 1} " + +// "else {$t虚弱文本 = ''}; " + +// "if 动摇 {$t动摇文本 = $t存在状态效果 ? '+动摇' : '动摇'; $t存在状态效果 = 1} " + +// "else {$t动摇文本 = ''}; " + +// "if 愤怒 {$t愤怒文本 = $t存在状态效果 ? '+愤怒' : '愤怒'; $t存在状态效果 = 1} " + +// "else {$t愤怒文本 = ''}; " + +// "if 中毒 {$t中毒文本 = $t存在状态效果 ? '+中毒' : '中毒'; $t存在状态效果 = 1} " + +// "else {$t中毒文本 = ''}; " + +// "$t存在状态效果 = 0; " + +// "$t状态效果 = $t缓慢文本 + $t眩晕文本 + $t虚弱文本 + $t动摇文本 + $t愤怒文本 + $t中毒文本; " + +// "if $t状态效果 == '' {$t状态效果 = '无'}" + +// "}" + +// "{$t状态效果}" + +export const ruleTemplate = { + "name": "fu", + "fullName": "最终物语", + "authors": ["Mint Cider"], + "version": "0.1.0", + "updatedTime": "2024.10.07", + "templateVer": "1.0", + + // .set 相关内容,使用.set fish开启,切6面骰,并提示enableTip中的内容 + "setConfig": { + "diceSides": 6, + "enableTip": "已切换至 6 面骰,并自动开启最终物语(seal-fu)扩展", + "keys": ["fu", "最终物语"], + "relatedExt": ["seal-fu"] + }, + + // sn相关内容,可使用.sn fish自动设置名片 + "nameTemplate": { + "fu": { + "template": "{$t玩家_RAW} HP{生命值}/{生命值上限} MP{精神值}/{精神值上限} IP{库存点}/{库存点上限} FP{物语点} Z{泽尼特} PD{防御} MD{魔防}", + "helpText": "自动设置最终物语名片" + }, + "fuS": { + "template": "{$t玩家_RAW} HP{生命值}/{生命值上限} MP{精神值}/{精神值上限} PD{防御} MD{魔防}", + "helpText": "自动设置最终物语简短版名片" + } + }, + + "attrConfig": { + // st show 置顶内容 + "top": ["灵巧", "洞察", "力量", "意志"], + "sortBy": "name", + // st show 隐藏内容 + "ignores": ["生命值上限", "精神值上限", "库存点上限", + "灵巧骰面", "灵巧骰面初始值", "洞察骰面", "洞察骰面初始值", "力量骰面", "力量骰面初始值", "意志骰面", "意志骰面初始值", + "灵巧骰面增减值", "洞察骰面增减值", "力量骰面增减值", "意志骰面增减值", + "缓慢", "眩晕", "虚弱", "动摇", "愤怒", "中毒", + "牵绊一", "牵绊二", "牵绊三", "牵绊四", "牵绊五", "牵绊六", + "牵绊一赞赏", "牵绊一忠诚", "牵绊一喜爱", + "牵绊二赞赏", "牵绊二忠诚", "牵绊二喜爱", + "牵绊三赞赏", "牵绊三忠诚", "牵绊三喜爱", + "牵绊四赞赏", "牵绊四忠诚", "牵绊四喜爱", + "牵绊五赞赏", "牵绊五忠诚", "牵绊五喜爱", + "牵绊六赞赏", "牵绊六忠诚", "牵绊六喜爱", + "牵绊数" + ], + // st show 展示内容,例如到 st show hp 会展示“生命值: 10/14” + "showAs": { + "生命值": "{生命值}/{生命值上限}", + "精神值": "{精神值}/{精神值上限}", + "库存点": "{库存点}/{库存点上限}", + "灵巧": generateAttributeExpr("灵巧"), + "洞察": generateAttributeExpr("洞察"), + "力量": generateAttributeExpr("力量"), + "意志": generateAttributeExpr("意志"), + }, + }, + + // 默认值 + // "defaults": { + // "上工": 5, + // }, + // 默认值 - 计算属性,如闪避为“敏捷 / 2 ” + // "defaultsComputed": { + // // 注意: 目前(v1.2.4)有一些限制,showAs中的项,千万不能有默认值 + // // 此外defaults中的内容也不能出现在defaultsComputed里 + // "生命值上限": "脸皮 * 2", + // }, + // 同义词,存卡和设置属性时,所有右边的词会被转换为左边的词,不分大小写(sAN视同San/san) + "alias": { + "生命值": ["hp", "hit point", "hit points"], + "生命值上限": ["hpmax"], + "精神值": ["mp", "mental point", "mental points"], + "精神值上限": ["mpmax"], + "库存点": ["ip", "inventory point", "inventory points"], + "库存点上限": ["ipmax"], + "物语点": ["fp", "fabula point", "fabula points"], + "泽尼特": ["z", "zenit"], + "先攻修正值": ["im", "initiative modifier"], + "物防": ["pd", "df", "defense", "物理防御"], + "魔防": ["md", "magical defense", "魔法防御"], + "灵巧骰面初始值": ["dex", "dexterity", "灵巧"], + "洞察骰面初始值": ["ins", "insight", "洞察"], + "力量骰面初始值": ["mig", "might", "力量"], + "意志骰面初始值": ["wlp", "willpower", "意志"], + }, + + // 可自定义词组,未实装 + // "textMap": { + // "fish-test": { + // "设置测试_成功": [ + // ["设置完成", 1] + // ] + // } + // }, + // "textMapHelpInfo": null +} + +export const rcHelp = "最终物语检定指令:\n\n" + + ".rc <属性 1>+<属性 2>+<修正值>\n\n" + + "支持的属性为:灵巧、洞察、力量、意志、dex、ins、mig、wlp,不区分大小写\n" + + "支持的修正值为:整数\n" + + "例子:\n" + + ".rc 灵巧+洞察+1\n" + + ".rc mig+wlp-2" + +export const riHelp = "最终物语先攻检定指令:\n\n" + + ".ri [修正值]\n\n" + + "自动进行一次「灵巧+洞察+先攻修正值」的检定,可以额外附加一个整数修正值\n" + + "例子:\n" + + ".ri\n" + + ".ri +3" + +export const buffHelp = "最终物语状态效果指令:\n\n" + + ".buff <状态效果>:切换状态效果\n" + + ".buff add <状态效果>:附加状态效果\n" + + ".buff del <状态效果>:消除状态效果\n" + + ".buff clr:消除全部状态效果\n\n" + + "支持的状态效果为:缓慢、眩晕、虚弱、动摇、愤怒、中毒" + +export const dsHelp = "最终物语临时调整属性骰指令:\n\n" + + ".ds <属性>+<调整值>:将对应属性骰增大或减小对应级别\n" + + ".ds rst <属性>:重置对应属性骰\n" + + ".ds rst all:重置全部属性骰\n\n" + + "支持的属性为:灵巧、洞察、力量、意志、dex、ins、mig、wlp,不区分大小写\n" + + "支持的调整值为:整数\n" + + "例子:" + + ".ds 力量+1:力量属性骰增大一级(6 ➯ 8 ➯ 10 ➯ 12)\n" + + ".ds dex-1:灵巧属性骰减小一级(12 ➯ 10 ➯ 8 ➯ 6)" + +export const bondHelp = "最终物语牵绊指令:\n\n" + + ".bond add <名字> <情感>:与<名字>建立情感为<情感>的牵绊\n" + + ".bond del <编号>/<名字>:遗忘对应的牵绊\n" + + ".bond clr:遗忘全部牵绊\n" + + ".bond emo add <编号>/<名字> <情感>:为对应牵绊添加对应情感\n" + + ".bond emo del <编号>/<名字> <情感>:遗忘对应牵绊的对应情感\n" + + ".bond list:查看所有牵绊\n\n" + + "支持的情感为:赞赏、自卑、忠诚、怀疑、喜爱、仇恨" + +export const clkHelp = "最终物语命刻指令:\n\n" + + ".clk add <名字> <大小> [进度]:创建大小为<大小>,名字为<名字>的命刻,进度默认为0\n" + + ".clk del <名字>:删除对应的命刻\n" + + ".clk clr:删除全部命刻\n" + + ".clk fill <名字> <进度变化>:使对应命刻的进度发生对应变化\n" + + ".clk list:查看群内全部命刻\n\n" + + "支持的大小为:正整数\n" + + "支持的进度为:非负整数\n" + + "支持的进度变化为:整数" + +export const attributeAlias = { + "dex": "灵巧", + "ins": "洞察", + "mig": "力量", + "wlp": "意志" +} + +export type Clock = { + name: string; + size: number; + current: number; +} diff --git a/src/index.ts b/src/index.ts index 8fdb47b..5718741 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,497 @@ +import { + attributeAlias, + bondHelp, + buffHelp, + clkHelp, + Clock, + dsHelp, emoToKey, emoToValue, + generateAttributeStatusExpr, negEmo, numToChinese, + rcHelp, + riHelp, + ruleTemplate +} from "./data"; +import {reEvaluateAttributes, removeBondByIndex} from "./util"; + +function registerTemplate() { + try { + seal.gameSystem.newTemplate(JSON.stringify(ruleTemplate)); + } catch (e) { + console.log(e); + } +} + +// 检定 +function commandRc(ctx: seal.MsgContext, msg: seal.Message, cmdArgs: seal.CmdArgs): seal.CmdExecuteResult { + const command = cmdArgs.getArgN(1); + if (command === "help") { + seal.replyToSender(ctx, msg, rcHelp); + return seal.ext.newCmdExecuteResult(true); + } + const checkStr = cmdArgs.getRestArgsFrom(1).replace(/\s+/g, ''); + const matches = checkStr.match(/^(灵巧|洞察|力量|意志|dex|ins|mig|wlp)\+(灵巧|洞察|力量|意志|dex|ins|mig|wlp)([+-]\d+)?$/i); + if (!matches) { + seal.replyToSender(ctx, msg, "检定格式有误,可使用 .rc help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + const attribute1: string = matches[1].toLowerCase() in attributeAlias ? + attributeAlias[matches[1].toLowerCase()] : matches[1]; + const attribute2: string = matches[2].toLowerCase() in attributeAlias ? + attributeAlias[matches[2].toLowerCase()] : matches[2]; + const modifier: string = matches[3]; + seal.format(ctx, `{if ${attribute1}骰面 == 0 {${attribute1}骰面 = ${attribute1}骰面初始值}}`); + const attributeNumber1 = seal.vars.intGet(ctx, `${attribute1}骰面`)[0]; + if (!attributeNumber1) { + seal.replyToSender(ctx, msg, seal.format(ctx, `{$t玩家}未设置${attribute1}属性`)); + return seal.ext.newCmdExecuteResult(true); + } + seal.format(ctx, `{if ${attribute2}骰面 == 0 {${attribute2}骰面 = ${attribute2}骰面初始值}}`); + const attributeNumber2 = seal.vars.intGet(ctx, `${attribute2}骰面`)[0]; + if (!attributeNumber2) { + seal.replyToSender(ctx, msg, seal.format(ctx, `{$t玩家}未设置${attribute2}属性`)); + return seal.ext.newCmdExecuteResult(true); + } + const modifierNumber = modifier ? Number(modifier) : 0; + const roll1 = Number(seal.format(ctx, `{d${attributeNumber1}}`)); + const roll2 = Number(seal.format(ctx, `{d${attributeNumber2}}`)); + const result = roll1 + roll2 + modifierNumber; + const hr = roll1 > roll2 ? roll1 : roll2; + const fumble = roll1 === 1 && roll2 === 1; + const criticalSuccess = roll1 === roll2 && roll1 >= 6; + seal.replyToSender(ctx, msg, + seal.vars.strGet(ctx, "$t玩家")[0] + `的${attribute1}+${attribute2}${modifier ? modifier : ""}检定结果为:` + + `d${attributeNumber1}` + seal.format(ctx, generateAttributeStatusExpr(attribute1)) + + `+d${attributeNumber2}` + seal.format(ctx, generateAttributeStatusExpr(attribute2)) + + `${modifier ? modifier : ""}=` + + `[${roll1}+${roll2}${modifier ? modifier : ""}]=${result} ` + + `${fumble ? "大失败!" : ""}${criticalSuccess ? "大成功!" : ""}\n` + + `HR:${hr}` + ); + return seal.ext.newCmdExecuteResult(true); +} + +// 先攻检定 +function commandRi(ctx: seal.MsgContext, msg: seal.Message, cmdArgs: seal.CmdArgs): seal.CmdExecuteResult { + const modifier = cmdArgs.getArgN(1); + if (modifier === "help") { + seal.replyToSender(ctx, msg, riHelp); + return seal.ext.newCmdExecuteResult(true); + } + if (!modifier.match(/^([+-]\d+)?$/)) { + seal.replyToSender(ctx, msg, "先攻检定的额外修正值格式错误,可以使用 .ri help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + seal.format(ctx, `{if 灵巧骰面 == 0 {灵巧骰面 = 灵巧骰面初始值}}`); + const dexNumber = seal.vars.intGet(ctx, `灵巧骰面`)[0]; + if (!dexNumber) { + seal.replyToSender(ctx, msg, seal.format(ctx, `{$t玩家}未设置灵巧属性`)); + return seal.ext.newCmdExecuteResult(true); + } + seal.format(ctx, `{if 洞察骰面 == 0 {洞察骰面 = 洞察骰面初始值}}`); + const insNumber = seal.vars.intGet(ctx, `洞察骰面`)[0]; + if (!insNumber) { + seal.replyToSender(ctx, msg, seal.format(ctx, `{$t玩家}未设置洞察属性`)); + return seal.ext.newCmdExecuteResult(true); + } + const modifierNumber = modifier ? Number(modifier) : 0; + const dexRoll = Number(seal.format(ctx, `{d${dexNumber}}`)); + const insRoll = Number(seal.format(ctx, `{d${insNumber}}`)); + const im = seal.vars.intGet(ctx, "先攻修正值")[0]; + const result = dexRoll + insRoll + modifierNumber + im; + const fumble = dexRoll === 1 && insRoll === 1; + const criticalSuccess = dexRoll === insRoll && dexRoll >= 6; + seal.replyToSender(ctx, msg, + seal.vars.strGet(ctx, "$t玩家")[0] + `的先攻检定结果为:` + + `d${dexNumber}` + seal.format(ctx, generateAttributeStatusExpr("灵巧")) + + `+d${insNumber}` + seal.format(ctx, generateAttributeStatusExpr("洞察")) + + `${im >= 0 ? `+${im}(先攻修正)` : `${im}(先攻修正)`}${modifier ? modifier : ""}=` + + `[${dexRoll}+${insRoll}${im >= 0 ? `+${im}` : `${im}`}${modifier ? modifier : ""}]=${result} ` + + `${fumble ? "大失败!" : ""}${criticalSuccess ? "大成功!" : ""}` + ); + return seal.ext.newCmdExecuteResult(true); +} + +// 状态效果 +function commandBuff(ctx: seal.MsgContext, msg: seal.Message, cmdArgs: seal.CmdArgs): seal.CmdExecuteResult { + const command = cmdArgs.getArgN(1); + switch (command) { + case "help": { + seal.replyToSender(ctx, msg, buffHelp); + return seal.ext.newCmdExecuteResult(true); + } + case "缓慢": + case "眩晕": + case "虚弱": + case "动摇": + case "愤怒": + case "中毒": { + const effect = seal.vars.intGet(ctx, command)[0]; + if (effect) { + seal.vars.intSet(ctx, command, 0); + reEvaluateAttributes(ctx); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `的${command}状态消退了……`); + return seal.ext.newCmdExecuteResult(true); + } else { + seal.vars.intSet(ctx, command, 1); + reEvaluateAttributes(ctx); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `进入${command}状态了……`); + return seal.ext.newCmdExecuteResult(true); + } + } + case "add": { + const effect = cmdArgs.getArgN(2); + if (!["缓慢", "眩晕", "虚弱", "动摇", "愤怒", "中毒"].includes(effect)) { + seal.replyToSender(ctx, msg, "状态效果有误,可使用 .buff help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + seal.vars.intSet(ctx, effect, 1); + reEvaluateAttributes(ctx); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `进入${effect}状态了……`); + return seal.ext.newCmdExecuteResult(true); + } + case "del": { + const effect = cmdArgs.getArgN(2); + if (!["缓慢", "眩晕", "虚弱", "动摇", "愤怒", "中毒"].includes(effect)) { + seal.replyToSender(ctx, msg, "状态效果有误,可使用 .buff help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + seal.vars.intSet(ctx, effect, 0); + reEvaluateAttributes(ctx); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `的${effect}状态消退了……`); + return seal.ext.newCmdExecuteResult(true); + } + case "clr": { + for (const effect of ["缓慢", "眩晕", "虚弱", "动摇", "愤怒", "中毒"]) { + seal.vars.intSet(ctx, effect, 0); + } + reEvaluateAttributes(ctx); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `的全部状态消退了……`); + return seal.ext.newCmdExecuteResult(true); + } + default: { + seal.replyToSender(ctx, msg, "格式有误,可使用 .buff help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + } +} + +// 属性增减 +function commandDs(ctx: seal.MsgContext, msg: seal.Message, cmdArgs: seal.CmdArgs): seal.CmdExecuteResult { + const command = cmdArgs.getArgN(1); + if (command === "help") { + seal.replyToSender(ctx, msg, dsHelp); + return seal.ext.newCmdExecuteResult(true); + } + if (command === "rst") { + let attribute = cmdArgs.getArgN(2); + if (attribute.match(/^all$/i)) { + seal.vars.intSet(ctx, "灵巧骰面增减值", 0); + seal.vars.intSet(ctx, "洞察骰面增减值", 0); + seal.vars.intSet(ctx, "力量骰面增减值", 0); + seal.vars.intSet(ctx, "意志骰面增减值", 0); + reEvaluateAttributes(ctx); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + "全部属性骰的临时变动重置了"); + return seal.ext.newCmdExecuteResult(true); + } + if (!attribute.match(/^(灵巧|洞察|力量|意志|dex|ins|mig|wlp)$/i)) { + seal.replyToSender(ctx, msg, "属性有误,可使用 .ds help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + attribute = attribute.toLowerCase() in attributeAlias ? + attributeAlias[attribute.toLowerCase()] : attribute; + seal.vars.intSet(ctx, `${attribute}骰面增减值`, 0); + reEvaluateAttributes(ctx); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `${attribute}属性骰的临时变动重置了`); + return seal.ext.newCmdExecuteResult(true); + } + const dsStr = cmdArgs.getRestArgsFrom(1).replace(/\s+/g, ''); + const matches = dsStr.match(/^(灵巧|洞察|力量|意志|dex|ins|mig|wlp)([+-]\d+)$/i); + if (!matches) { + seal.replyToSender(ctx, msg, "属性变动格式有误,可使用 .ds help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + const attribute: string = matches[1].toLowerCase() in attributeAlias ? + attributeAlias[matches[1].toLowerCase()] : matches[1]; + const modifier = matches[2]; + let ds = seal.vars.intGet(ctx, `${attribute}骰面增减值`)[0]; + ds += Number(modifier); + seal.vars.intSet(ctx, `${attribute}骰面增减值`, ds); + reEvaluateAttributes(ctx); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `${attribute}属性骰临时${modifier}`); + return seal.ext.newCmdExecuteResult(true); +} + +// 牵绊 +function commandBond(ctx: seal.MsgContext, msg: seal.Message, cmdArgs: seal.CmdArgs): seal.CmdExecuteResult { + const bondNum = seal.vars.intGet(ctx, "牵绊数")[0]; + const command = cmdArgs.getArgN(1); + switch (command) { + case "help": { + seal.replyToSender(ctx, msg, bondHelp); + return seal.ext.newCmdExecuteResult(true); + } + case "add": { + if (bondNum >= 6) { + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `已有${bondNum}条牵绊,不能再添加新牵绊`); + return seal.ext.newCmdExecuteResult(true); + } + const name = cmdArgs.getArgN(2); + const emo = cmdArgs.getArgN(3); + if (!["赞赏", "自卑", "忠诚", "怀疑", "喜爱", "仇恨"].includes(emo)) { + seal.replyToSender(ctx, msg, "情感有误,可使用 .bond help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + seal.vars.strSet(ctx, `牵绊${numToChinese[bondNum + 1]}`, name); + seal.vars.intSet(ctx, `牵绊${numToChinese[bondNum + 1]}${emoToKey[emo]}`, emoToValue[emo]); + seal.vars.intSet(ctx, "牵绊数", bondNum + 1); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `与<${name}>建立了${emo}牵绊`); + return seal.ext.newCmdExecuteResult(true); + } + case "del": { + const target = cmdArgs.getArgN(2); + let index = 0; + if(target.match(/^[1-6]$/)) { + if(Number(target) > bondNum) { + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `没有第${target}条牵绊`); + return seal.ext.newCmdExecuteResult(true); + } + index = Number(target) + } + for (let i = 1; i <= bondNum; i++) { + if(seal.vars.strGet(ctx, `牵绊${numToChinese[i]}`)[0] === target) { + index = i; + break; + } + } + if(index === 0) { + seal.replyToSender(ctx, msg, `找不到要遗忘的目标牵绊:${target}`); + return seal.ext.newCmdExecuteResult(true); + } + removeBondByIndex(ctx, index); + if(target.match(/^[1-6]$/)) { + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `不再有第${target}条牵绊`); + } else { + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `与<${target}>不再有牵绊`); + } + return seal.ext.newCmdExecuteResult(true); + } + case "clr": { + for (let i = 1; i <= 6; i++) { + seal.vars.strSet(ctx, `牵绊${numToChinese[i]}`, ""); + seal.vars.intSet(ctx, `牵绊${numToChinese[i]}赞赏`, 0); + seal.vars.intSet(ctx, `牵绊${numToChinese[i]}忠诚`, 0); + seal.vars.intSet(ctx, `牵绊${numToChinese[i]}喜爱`, 0); + } + seal.vars.intSet(ctx, "牵绊数", 0); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `遗忘了全部牵绊`); + return seal.ext.newCmdExecuteResult(true); + } + case "emo": { + const option = cmdArgs.getArgN(2); + const target = cmdArgs.getArgN(3); + const emo = cmdArgs.getArgN(4); + let index = 0; + if(target.match(/^[1-6]$/)) { + if(Number(target) > bondNum) { + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `没有第${target}条牵绊`); + return seal.ext.newCmdExecuteResult(true); + } + index = Number(target) + } + for (let i = 1; i <= bondNum; i++) { + if(seal.vars.strGet(ctx, `牵绊${numToChinese[i]}`)[0] === target) { + index = i; + break; + } + } + if(index === 0) { + seal.replyToSender(ctx, msg, `找不到目标牵绊:${target}`); + return seal.ext.newCmdExecuteResult(true); + } + if (!["赞赏", "自卑", "忠诚", "怀疑", "喜爱", "仇恨"].includes(emo)) { + seal.replyToSender(ctx, msg, "情感有误,可使用 .bond help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + switch (option) { + case "add": { + if(seal.vars.intGet(ctx, `牵绊${numToChinese[index]}${emoToKey[emo]}`)[0] === 0) { + seal.vars.intSet(ctx, `牵绊${numToChinese[index]}${emoToKey[emo]}`, emoToValue[emo]); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `与<` + seal.vars.strGet(ctx, `牵绊${numToChinese[index]}`)[0] + `>的牵绊增加了${emo}情感`); + return seal.ext.newCmdExecuteResult(true); + } else { + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `与<` + seal.vars.strGet(ctx, `牵绊${numToChinese[index]}`)[0] + `>的牵绊已有` + + `${seal.vars.intGet(ctx, `牵绊${numToChinese[index]}${emoToKey[emo]}`)[0] === emoToValue[emo] ? emo : negEmo[emo]}情感,` + + `不能再增加${emo}情感`); + return seal.ext.newCmdExecuteResult(true); + } + } + case "del": { + if(seal.vars.intGet(ctx, `牵绊${numToChinese[index]}${emoToKey[emo]}`)[0] === emoToValue[emo]) { + seal.vars.intSet(ctx, `牵绊${numToChinese[index]}${emoToKey[emo]}`, 0); + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `与<` + seal.vars.strGet(ctx, `牵绊${numToChinese[index]}`)[0] + `>的牵绊不再有${emo}情感`); + return seal.ext.newCmdExecuteResult(true); + } else { + seal.replyToSender(ctx, msg, seal.vars.strGet(ctx, "$t玩家")[0] + `与<` + seal.vars.strGet(ctx, `牵绊${numToChinese[index]}`)[0] + `>的牵绊不存在${emo}情感`); + return seal.ext.newCmdExecuteResult(true); + } + } + default: { + seal.replyToSender(ctx, msg, "不支持的情感操作,可使用 .bond help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + } + } + case "list": { + let result = ""; + for (let i = 1; i <= bondNum; i++) { + result += `牵绊${numToChinese[i]}:${seal.vars.strGet(ctx, `牵绊${numToChinese[i]}`)[0]}-`; + let admiration = ""; + let loyalty = ""; + let affection = ""; + switch(seal.vars.intGet(ctx, `牵绊${numToChinese[i]}赞赏`)[0]) { + case 1: admiration = "赞赏"; break; + case -1: admiration = "自卑"; break; + default: admiration = ""; + } + switch(seal.vars.intGet(ctx, `牵绊${numToChinese[i]}忠诚`)[0]) { + case 1: loyalty = "忠诚"; break; + case -1: loyalty = "怀疑"; break; + default: loyalty = ""; + } + switch(seal.vars.intGet(ctx, `牵绊${numToChinese[i]}喜爱`)[0]) { + case 1: affection = "喜爱"; break; + case -1: affection = "仇恨"; break; + default: affection = ""; + } + if (affection && (admiration || loyalty)) { + affection = "与" + affection; + } + if (loyalty && admiration && affection) { + loyalty = "、" + loyalty; + } + if (loyalty && admiration && !affection) { + loyalty = "与" + loyalty; + } + result += admiration + loyalty + affection + "\n"; + } + seal.replyToSender(ctx, msg, result ? result : seal.vars.strGet(ctx, "$t玩家")[0] + "无牵绊"); + return seal.ext.newCmdExecuteResult(true); + } + default: { + seal.replyToSender(ctx, msg, "格式有误,可使用 .bond help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + } +} + +// 命刻 +function commandClk(ctx: seal.MsgContext, msg: seal.Message, cmdArgs: seal.CmdArgs): seal.CmdExecuteResult { + const command = cmdArgs.getArgN(1); + const clocks: Clock[] = JSON.parse(seal.vars.strGet(ctx, "$gfu_clocks")[0] ? seal.vars.strGet(ctx, "$gfu_clocks")[0] : "[]"); + switch (command) { + case "help": { + seal.replyToSender(ctx, msg, clkHelp); + return seal.ext.newCmdExecuteResult(true); + } + case "add": { + const name = cmdArgs.getArgN(2); + const size = cmdArgs.getArgN(3); + const current = cmdArgs.getArgN(4); + if (!size.match(/^\d+$/)) { + seal.replyToSender(ctx, msg, "命刻大小有误,可使用 .clk help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + if (current && !current.match(/^\d+$/)) { + seal.replyToSender(ctx, msg, "命刻进度有误,可使用 .clk help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + let currentNum = current ? Number(current) : 0; + if (currentNum > Number(size)) { + currentNum = Number(size); + } + clocks.push({ + name: name, + size: Number(size), + current: current ? Number(current) : 0, + }); + seal.vars.strSet(ctx, "$gfu_clocks", JSON.stringify(clocks)); + seal.replyToSender(ctx, msg, `已创建大小为${size}的命刻:${name}`); + return seal.ext.newCmdExecuteResult(true); + } + case "del": { + const name = cmdArgs.getArgN(2); + const index = clocks.findIndex(clock => clock.name === name); + if (index === -1) { + seal.replyToSender(ctx, msg, `群内不存在命刻:${name}`); + return seal.ext.newCmdExecuteResult(true); + } + clocks.splice(index, 1); + seal.vars.strSet(ctx, "$gfu_clocks", JSON.stringify(clocks)); + seal.replyToSender(ctx, msg, `已删除命刻:${name}`); + return seal.ext.newCmdExecuteResult(true); + } + case "clr": { + seal.vars.strSet(ctx, "$gfu_clocks", JSON.stringify([])); + seal.replyToSender(ctx, msg, "群内全部命刻已删除"); + return seal.ext.newCmdExecuteResult(true); + } + case "fill": { + const name = cmdArgs.getArgN(2); + const numStr = cmdArgs.getArgN(3); + const index = clocks.findIndex(clock => clock.name === name); + if (index === -1) { + seal.replyToSender(ctx, msg, `群内不存在命刻:${name}`); + return seal.ext.newCmdExecuteResult(true); + } + if (!numStr.match(/^[+-]?\d+$/)) { + seal.replyToSender(ctx, msg, "数字有误,可使用 .clk help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + clocks[index].current += Number(numStr); + if (clocks[index].current < 0) { + clocks[index].current = 0; + } + if (clocks[index].current > clocks[index].size) { + clocks[index].current = clocks[index].size; + } + seal.vars.strSet(ctx, "$gfu_clocks", JSON.stringify(clocks)); + seal.replyToSender(ctx, msg, `命刻:${clocks[index].name},大小:${clocks[index].size},当前进度:${clocks[index].current}\n`); + return seal.ext.newCmdExecuteResult(true); + } + case "list": { + let result = ""; + for (const clock of clocks) { + result += `命刻:${clock.name},大小:${clock.size},当前进度:${clock.current}\n`; + } + seal.replyToSender(ctx, msg, result ? result : "群内无命刻"); + return seal.ext.newCmdExecuteResult(true); + } + default: { + seal.replyToSender(ctx, msg, "格式有误,可使用 .clk help 查看使用说明"); + return seal.ext.newCmdExecuteResult(true); + } + } +} + +function registerCommand(ext: seal.ExtInfo, key: string, help: string, func: (ctx: seal.MsgContext, msg: seal.Message, cmdArgs: seal.CmdArgs) => seal.CmdExecuteResult) { + const cmd = seal.ext.newCmdItemInfo(); + cmd.name = key; + cmd.help = help; + cmd.solve = func; + ext.cmdMap[key] = cmd; +} + function main() { + registerTemplate(); // 注册扩展 let ext = seal.ext.find("seal-fu"); if (!ext) { ext = seal.ext.new("seal-fu", "Mint Cider", "0.1.0"); + registerCommand(ext, "rc", rcHelp, commandRc); + registerCommand(ext, "ri", riHelp, commandRi); + registerCommand(ext, "buff", buffHelp, commandBuff); + registerCommand(ext, "ds", dsHelp, commandDs); + registerCommand(ext, "bond", bondHelp, commandBond); + registerCommand(ext, "clk", clkHelp, commandClk); seal.ext.register(ext); } } diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..7a301d7 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,41 @@ +import {attributeEffects, numToChinese} from "./data"; + +export function reEvaluateAttributes(ctx: seal.MsgContext) { + for (const attribute of ["灵巧", "洞察", "力量", "意志"]) { + let dsMod = seal.vars.intGet(ctx, `${attribute}骰面增减值`)[0]; + if (seal.vars.intGet(ctx, attributeEffects[attribute][0])[0]) { + dsMod -= 1; + } + if (seal.vars.intGet(ctx, attributeEffects[attribute][1])[0]) { + dsMod -= 1; + } + let ds = seal.vars.intGet(ctx, `${attribute}骰面初始值`)[0]; + if (ds == 0) { + continue; + } + ds += dsMod * 2; + if (ds < 6) { + ds = 6; + } + if (ds > 12) { + ds = 12; + } + seal.vars.intSet(ctx, `${attribute}骰面`, ds); + } +} + +export function removeBondByIndex(ctx: seal.MsgContext, index: number) { + const bondNum = seal.vars.intGet(ctx, "牵绊数")[0]; + for (let i = index; i <= bondNum - 1; i++) { + seal.vars.strSet(ctx, `牵绊${numToChinese[i]}`, seal.vars.strGet(ctx, `牵绊${numToChinese[i + 1]}`)[0]); + seal.vars.intSet(ctx, `牵绊${numToChinese[i]}赞赏`, seal.vars.intGet(ctx, `牵绊${numToChinese[i + 1]}赞赏`)[0]); + seal.vars.intSet(ctx, `牵绊${numToChinese[i]}忠诚`, seal.vars.intGet(ctx, `牵绊${numToChinese[i + 1]}忠诚`)[0]); + seal.vars.intSet(ctx, `牵绊${numToChinese[i]}喜爱`, seal.vars.intGet(ctx, `牵绊${numToChinese[i + 1]}喜爱`)[0]); + } + seal.vars.strSet(ctx, `牵绊${numToChinese[bondNum]}`, ""); + seal.vars.intSet(ctx, `牵绊${numToChinese[bondNum]}赞赏`, 0); + seal.vars.intSet(ctx, `牵绊${numToChinese[bondNum]}忠诚`, 0); + seal.vars.intSet(ctx, `牵绊${numToChinese[bondNum]}喜爱`, 0); + + seal.vars.intSet(ctx, "牵绊数", bondNum - 1); +} diff --git a/types/seal.d.ts b/types/seal.d.ts index 8b26e19..505b534 100644 --- a/types/seal.d.ts +++ b/types/seal.d.ts @@ -213,7 +213,7 @@ declare namespace seal { /** 吃掉前缀并去除复数空格 `set xxx xxx` => `xxx xxx`,返回修改后的字符串和是否修改成功的布尔值 */ eatPrefixWith(...s: string[]): [string, boolean] /** 将第 n 个参数及之后参数用空格拼接起来; 如指令 `send to qq x1 x2`,n=3返回 `x1 x2` */ - getRestArgsFrom(n: number): number + getRestArgsFrom(n: number): string /** 检查第N项参数是否为某个字符串,n从1开始,若没有第n项参数也视为失败 */ isArgEqual(n: number, ...s: string[]): boolean } @@ -287,7 +287,7 @@ declare namespace seal { type BanRankType = number /* 禁止等级 - BanRankBanned = -30 + BanRankBanned = -30 警告等级 BanRankWarn = -10 常规等级 @@ -340,7 +340,7 @@ declare namespace seal { */ remove(ctx: MsgContext, id: string): void; - /** 获取名单全部用户 */ + /** 获取名单全部用户 */ getList(): BanListInfoItem[]; /** @@ -444,7 +444,7 @@ declare namespace seal { newConfigItem(ext: ExtInfo,key: string,defaultValue: any,desc: string):ConfigItem; /** * 注册配置 - * @param ext 扩展对象 + * @param ext 扩展对象 * @param configs 配置项对象 */ registerConfig(ext: ExtInfo,...configs:ConfigItem[]):unknown; @@ -596,7 +596,7 @@ declare namespace seal { */ export function createTempCtx(ep: EndPointInfo, msg: Message): MsgContext; /** - * + * * @param ctx 上下文 * @param tmpl 模板文本 */ @@ -610,7 +610,7 @@ declare namespace seal { export function getCtxProxyAtPos(ctx: MsgContext, cmdArgs: CmdArgs, pos: number): MsgContext; type VersionDetailsType = { - // + // versionCode: number // 版本号+日期 如 1.4.6+20240810 version: string