feat(trigger-editor): 添加触发组概率与保底配置功能

1. 新增触发组条目字段t_chance(触发概率)和pity_add(保底叠加),仅攻击/受击组生效
2. 为TriggerGroupEditor传入分组标识,动态显示概率配置表单项
3. 新增条目创建时继承同组末档概率参数的逻辑
4. 更新常量定义与文档说明,补充概率参数使用规则
5. 在前端展示和服务端导出中添加概率相关信息展示
This commit is contained in:
pan
2026-09-21 16:01:41 +08:00
parent be6d941b90
commit cd9e7296a1
9 changed files with 93 additions and 28 deletions

View File

@@ -68,18 +68,18 @@
],
"atking": {},
"atked": {
"6301": [
"6302": [
{
"lv": 4,
"s_lv": 1,
"name": "全体圣盾",
"name": "",
"t_num": 3,
"overrides": {
"TGroup": null,
"ap": 10,
"icon": "Stat_UnitSummonIncrease_01"
"ap": 10
},
"desc": "全队获得本英雄生命最大值{ap}%的护盾"
"desc": "有 {t_chance}% 的概率,治疗自己 {ap}%生命最大值",
"t_chance": 50,
"pity_add": 20
}
]
},

View File

@@ -70,9 +70,11 @@
## 4. 触发组规范(atking / atked / fstart / fend / dead)
- 结构:`{ "<技能uuid字符串>": [条目, ...] }`,一个组可挂多个技能 uuid;
- 条目:`{lv, s_lv, name, t_num, overrides, desc}`;
- 条目:`{lv, s_lv, name, t_num, t_chance?, pity_add?, overrides, desc}`;
- 解锁等级惯例 **lv4**(`lv:4, s_lv:1`;heroSet.ts 头部注释写的 lv6 已过时,现有英雄与编辑器默认值均为 lv4);
- `t_num`:每 n 次普攻(atking)/受击(atked)触发一次;fstart/fend 为每回合开始/结束固定触发 1 次,`t_num` 恒填 1;
- `t_chance`:触发概率(百分点 0~100,**仅 atking/atked 生效**,其余组忽略);缺省/100 = 必触发。示例 30 表示次数条件达成后掷骰 30%;
- `pity_add`:保底叠加(百分点,仅 atking/atked 生效);未触发时为该技能累积下次概率增量,触发成功后清零、封顶 100。示例 `t_chance:30, pity_add:20` → 30/50/70/90/100 递进;
- `name` 为组对外展示名(写在该组首档),留空回退底座名;
- 复活:在 `dead` 某条目 `overrides` 配 `revive_hp`(回血%)+ `revive_count`(次数上限);
- 无触发组时写空对象 `{}`,**不要省略字段**。

View File

@@ -215,6 +215,9 @@ function renderSingleHero(h) {
if (e.s_lv) eparts.push(`s_lv: SkillLv.Lv${e.s_lv}`)
if (e.name) eparts.push(`name: ${JSON.stringify(e.name)}`)
eparts.push(`t_num: ${e.t_num}`)
// 概率参数:仅攻/受击触发消费;缺省(100/0)不输出,保持生成 TS 干净
if (e.t_chance != null && e.t_chance < 100) eparts.push(`t_chance: ${e.t_chance}`)
if (e.pity_add != null && e.pity_add > 0) eparts.push(`pity_add: ${e.pity_add}`)
if (e.overrides && Object.keys(e.overrides).length) eparts.push(`overrides: ${serializeOverrides(e.overrides)}`)
if (e.desc) eparts.push(`desc: ${JSON.stringify(e.desc)}`)
push(` { ${eparts.join(', ')} },`)
@@ -351,6 +354,8 @@ function csvTrigger(grp) {
const name = e.name || base?.name || ''
const ov = e.overrides || {}
const parts = [`t_num${e.t_num}`]
// 攻/受击组附带概率信息(缺省 100 不展示)
if (e.t_chance != null && e.t_chance < 100) parts.push(`概率${e.t_chance}%`)
if (ov.ap != null) parts.push(`ap${ov.ap}`)
const desc = e.desc || ''
return `${sid} ${name}(${parts.join(';')}):${desc}`