diff --git a/assets/script/game/common/config/HeroSkillDesc.ts b/assets/script/game/common/config/HeroSkillDesc.ts index 514bdfff..ec12fc8e 100644 --- a/assets/script/game/common/config/HeroSkillDesc.ts +++ b/assets/script/game/common/config/HeroSkillDesc.ts @@ -23,12 +23,12 @@ * 字段结构一致,天然都满足。HeroBoxComp 传 model 显示当前等级;卡池/商店传 heroInfo 显示 1 级。 * * 依赖: - * - heroSet :SkillTriggerName、SkillTriggerType、HeroEvolve + * - heroSet :SkillTriggerName、SkillTriggerType、TriggerGrouped/LvFieldEntry/LvReviveEntry/LvBonusEntry 及 resolver * - SkillSet :SkillSet、mergeSkillParams、SkillOverrides、SkillKind、TGroup * - SkillDescSet:结构化描述模板 * - FieldSkillSet(驻场技能)、BuffList(计时 buff 默认值兜底)、Attrs(属性枚举) */ -import { HeroEvolve, SkillTriggerName, SkillTriggerType } from "./heroSet"; +import { SkillTriggerName, SkillTriggerType, TriggerGrouped, LvFieldEntry, LvReviveEntry, LvBonusEntry, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv } from "./heroSet"; import { FieldSkillSet, mergeSkillParams, SkillConfig, SkillKind, SkillOverrides, SkillSet, TGroup } from "./SkillSet"; import { FieldDescSet, FieldValueFmt, SkillDescSet } from "./SkillDescSet"; import { BuffList } from "./BuffSet"; @@ -37,21 +37,22 @@ import { CardConfig } from "./CardSet"; /** * 生成器入参窄接口:只约束实际读取的字段。 - * heroInfo 与 HeroAttrsComp 的对应字段结构完全一致,天然都满足此接口。 + * heroInfo 与 HeroAttrsComp 的对应字段结构完全一致(均为分组 + lv 数组),天然都满足此接口。 */ export interface ISkillDescSource { - /** 当前等级(用于计算 revive 实际复活次数、evolve 累计加成;静态 heroInfo 恒为 1) */ + /** 当前等级(用于 resolve 触发技能/光环/复活取档;静态 heroInfo 恒为 1) */ lv?: number; - call?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - fend?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - atking?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - atked?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - field?: number[]; - revive?: { s_uuid: number; r_num: number; upr: number }; - /** 等级进化配置(heroInfo 自带;HeroAttrsComp 记录快照),用于累计 ap/hp 额外加成文案 */ - evolve?: Record; + call?: TriggerGrouped; + dead?: TriggerGrouped; + fstart?: TriggerGrouped; + fend?: TriggerGrouped; + atking?: TriggerGrouped; + atked?: TriggerGrouped; + field?: LvFieldEntry[]; + revive?: LvReviveEntry[]; + /** 额外攻击/生命加成(按 lv 累加,用于成长文案) */ + ap_bonus?: LvBonusEntry[]; + hp_bonus?: LvBonusEntry[]; } /** @@ -230,11 +231,11 @@ function buildFieldLine(head: string, uuid: number, showName: boolean = true): I * 复活次数 = r_num + floor((lv - 1) * upr);回血百分比 = SkillSet[s_uuid].ap */ function buildReviveLine(source: ISkillDescSource, showName: boolean = true): ISkillLine | null { - const revive = source.revive; + const lv = Math.max(1, source.lv ?? 1); + const revive = resolveReviveByLv(source.revive, lv); if (!revive) return null; const base = SkillSet[revive.s_uuid]; if (!base) return null; - const lv = Math.max(1, source.lv ?? 1); const maxCount = revive.r_num + Math.floor((lv - 1) * revive.upr); const hpPct = base.ap ?? 0; const tpl = SkillTriggerName[SkillTriggerType.Revive] ?? "复活"; @@ -247,18 +248,16 @@ function buildReviveLine(source: ISkillDescSource, showName: boolean = true): IS }; } -/** evolve 额外属性加成(ap/hp)累计结构化行:高亮累计数值 */ +/** 额外属性加成(ap/hp)累计结构化行:高亮累计数值 */ function buildEvolveBonusLines(source: ISkillDescSource): ISkillLine[] { - const evolve = source.evolve; - if (!evolve) return []; const lv = Math.max(1, source.lv ?? 1); let apTotal = 0; let hpTotal = 0; - for (let elv = 2; elv <= lv; elv++) { - const evo = evolve[elv]; - if (!evo) continue; - apTotal += evo.ap_bonus ?? 0; - hpTotal += evo.hp_bonus ?? 0; + if (source.ap_bonus) { + for (const e of source.ap_bonus) { if (e.lv <= lv) apTotal += e.value; } + } + if (source.hp_bonus) { + for (const e of source.hp_bonus) { if (e.lv <= lv) hpTotal += e.value; } } const lines: ISkillLine[] = []; if (apTotal !== 0) lines.push({ prefix: "成长:额外", value: `+${apTotal}`, suffix: ATTR_NAME[Attrs.ap] ?? "攻击力" }); @@ -267,17 +266,19 @@ function buildEvolveBonusLines(source: ISkillDescSource): ISkillLine[] { } /** - * 构建全部能力结构化行(触发技能 + 驻场光环 + 复活 + evolve 加成)。 + * 构建全部能力结构化行(触发技能 + 驻场光环 + 复活 + 额外加成)。 * 纯文本与富文本两个公开接口共用此结果,仅渲染阶段不同。 * @param showName 是否在行中包含「技能名」片段(英雄盒面板传 false 隐藏技能名) */ function buildSkillLines(source: ISkillDescSource, showName: boolean = true): ISkillLine[] { const lines: ISkillLine[] = []; + const lv = Math.max(1, source.lv ?? 1); - // ---- 6 种标准触发技能 ---- + // ---- 6 种标准触发技能(按当前等级 resolve 后遍历) ---- for (const key of TRIGGER_KEYS) { - const arr = source[key] as { s_uuid: number; t_num: number; overrides?: SkillOverrides }[] | undefined; - if (!arr?.length) continue; + const grouped = source[key] as TriggerGrouped | undefined; + const arr = resolveTriggerByLv(grouped, lv); + if (!arr.length) continue; // 触发类型简称(召唤/亡语/起手/生息/进击/受击) const name = SkillTriggerName[key] ?? key; // 仅进击/受击带触发次数,拼为"×n";其余简称直接用 @@ -293,7 +294,7 @@ function buildSkillLines(source: ISkillDescSource, showName: boolean = true): IS } // ---- 驻场光环(field):查 FieldDescSet 结构化渲染,value 数值高亮 ---- - const fieldUuids = source[SkillTriggerType.Field] as number[] | undefined; + const fieldUuids = resolveFieldByLv(source[SkillTriggerType.Field] as LvFieldEntry[] | undefined, lv); if (fieldUuids?.length) { const tpl = SkillTriggerName[SkillTriggerType.Field] ?? "光环"; for (const uuid of fieldUuids) { diff --git a/assets/script/game/common/config/heroSet.ts b/assets/script/game/common/config/heroSet.ts index 339c220f..95528ec1 100644 --- a/assets/script/game/common/config/heroSet.ts +++ b/assets/script/game/common/config/heroSet.ts @@ -161,18 +161,19 @@ export interface heroInfo { monType?: MonType; // 怪物专属类型 hp: number; // 生命值上限 ap: number; // 攻击力 - [SkillTriggerType.Call]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 召唤后触发的技能配置 - [SkillTriggerType.Dead]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 死亡后触发的技能配置 - [SkillTriggerType.FStart]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 战斗开始时释放的技能配置 - [SkillTriggerType.FEnd]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 战斗结束时释放的技能配置 - [SkillTriggerType.Field]?: number[]; // 驻场技能uuid列表,英雄在场时对全局生效 - [SkillTriggerType.Atking]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 普通攻击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的普攻次数 - [SkillTriggerType.Atked]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数 - [SkillTriggerType.Revive]?: { s_uuid: number, r_num: number, upr: number }; // 复活技能配置,s_uuid: 技能id, r_num: 触发所需的复活次数, upr 等级对复活次数的影响 + [SkillTriggerType.Call]?: TriggerGrouped; // 召唤后触发的技能配置(按 s_uuid 分组,每组按 lv 升序) + [SkillTriggerType.Dead]?: TriggerGrouped; // 死亡后触发的技能配置 + [SkillTriggerType.FStart]?: TriggerGrouped; // 战斗开始时释放的技能配置 + [SkillTriggerType.FEnd]?: TriggerGrouped; // 战斗结束时释放的技能配置 + [SkillTriggerType.Field]?: LvFieldEntry[]; // 驻场光环(按 lv 升序,运行时取 ≤英雄等级 的最大档) + [SkillTriggerType.Atking]?: TriggerGrouped; // 普通攻击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的普攻次数 + [SkillTriggerType.Atked]?: TriggerGrouped; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数 + [SkillTriggerType.Revive]?: LvReviveEntry[]; // 复活技能配置(按 lv 升序,运行时取 ≤英雄等级 的最大档) dis?: number; // 攻击距离(像素) speed?: number; // 移动速度(像素/秒) skills: Record; // 携带技能ID列表 - evolve?: Record; // 等级进化配置,key=等级(2,3,...) + ap_bonus?: LvBonusEntry[]; // 额外攻击加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档) + hp_bonus?: LvBonusEntry[]; // 额外生命加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档) info: string; // 描述文案 /** 分级能力说明,索引0=1级,依次递增;信息面板逐条展示各等级技能与能力 */ infos?: string[]; @@ -187,25 +188,46 @@ export interface HSkillInfo { ccd: number; // 占位当前cd,用于cd计时 overrides?: SkillOverrides; // 角色专属参数覆盖 } + /** - * 英雄等级进化配置 - * 定义英雄在某等级时技能/属性的变化 + * 触发技能单档配置:达到 lv 级时此档参数生效(t_num/overrides 可随等级变化)。 */ -export interface HeroEvolve { - /** 替换普攻技能(清除旧技能,添加新技能) */ - skill?: { s_uuid: number; cd?: number; overrides?: SkillOverrides }; - /** 覆盖触发技能(完全替换该类型的触发配置) */ - atking?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - atked?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - fend?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - /** 覆盖驻场光环(FieldSkillSet uuid 列表,存活期间全局生效) */ - field?: number[]; - revive?: { s_uuid: number; r_num: number; upr: number }; - /** 额外属性加成(在等级倍率基础上叠加) */ - ap_bonus?: number; - hp_bonus?: number; +export interface LvTriggerEntry { + lv: number; // 达到该英雄等级时解锁此档 + t_num: number; + overrides?: SkillOverrides; +} + +/** + * 触发技能按 s_uuid 分组的配置:每个 s_uuid 下按 lv 升序排列。 + * 运行时取每个 s_uuid 中 ≤英雄等级 的最大 lv 档。 + */ +export type TriggerGrouped = Record; + +/** + * 驻场光环按等级解锁:运行时取 ≤英雄等级 的最大 lv 档的 uuids。 + */ +export interface LvFieldEntry { + lv: number; + uuids: number[]; +} + +/** + * 复活技能按等级解锁:运行时取 ≤英雄等级 的最大 lv 档。 + */ +export interface LvReviveEntry { + lv: number; + s_uuid: number; + r_num: number; + upr: number; +} + +/** + * 额外属性加成按等级叠加:运行时累加所有 ≤英雄等级 的档位。 + */ +export interface LvBonusEntry { + lv: number; + value: number; } /* *=============英雄配置列表================ @@ -228,133 +250,124 @@ export const HeroInfo: Record = { 5011: { uuid: 5011, name: "小铁卫", path: "hk1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, - atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }], // 成长主线:护盾层数 4→5→6(等效减伤 57%→67%),6 级追加治疗形成“盾挡+回血”双循环 - // 注意:evolve.atked 为整体替换且逐级顺序应用,高级别需写完整数组 - evolve: { - 2: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } }] }, - 3: { hp_bonus: 150 }, - 4: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 6 } }] }, - 5: { hp_bonus: 150, ap_bonus: 10 }, - 6: { - atked: [ - { s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 6 } }, - { s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.All, ap: 250 } }, - ] - }, + atked: { + 6301: [ + { lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }, + { lv: 2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } }, + { lv: 4, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 6 } }, + ], + 6302: [ + { lv: 6, t_num: 5, overrides: { TGroup: TGroup.All, ap: 250 } }, + ], }, + hp_bonus: [{ lv: 3, value: 150 }, { lv: 5, value: 150 }], + ap_bonus: [{ lv: 5, value: 10 }], info: "✧受伤获得护盾\n✦受伤全队恢复生命", }, 5012: { uuid: 5012, name: "不死小强", path: "hk2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, - atked: [ - { s_uuid: 6302, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 250 } }, - { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }, - ], - evolve: { - 2: { atked: [{ s_uuid: 6302, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 300 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] }, - 3: { hp_bonus: 150 }, - 4: { atked: [{ s_uuid: 6302, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 350 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] }, - 5: { atked: [{ s_uuid: 6302, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 350 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] }, - 6: { - atked: [ - { s_uuid: 6302, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 350 } }, - { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }, - { s_uuid: 6301, t_num: 5, overrides: { TGroup: TGroup.All, ap: 4 } }, - ] - }, + atked: { + 6302: [ + { lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 250 } }, + { lv: 2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 300 } }, + { lv: 4, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 350 } }, + { lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 350 } }, + ], + 6402: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }, + ], + 6301: [ + { lv: 6, t_num: 5, overrides: { TGroup: TGroup.All, ap: 4 } }, + ], }, + hp_bonus: [{ lv: 3, value: 150 }], info: "✧受伤恢复生命\n✦受伤全体获得护盾", }, 5013: { uuid: 5013, name: "铁骨头", path: "hk4", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, - atked: [ - { s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } }, - { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }, - ], - evolve: { - 2: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] }, - 3: { hp_bonus: 150 }, - 4: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] }, - 5: { atked: [{ s_uuid: 6301, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] }, - 6: { - atked: [ - { s_uuid: 6301, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } }, - { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }, - { s_uuid: 6301, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 2 } }, - ] - }, + atked: { + 6301: [ + { lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } }, + { lv: 2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }, + { lv: 4, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } }, + { lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } }, + { lv: 6, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 2 } }, + ], + 6402: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }, + ], }, + hp_bonus: [{ lv: 3, value: 150 }], info: "✧受伤获得护盾与生命\n✦受伤全队获得护盾", }, 5014: { uuid: 5014, name: "怒火武者", path: "hk5", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } }, - atked: [ - { s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, - { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - ], - evolve: { - 2: { atked: [{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }] }, - 3: { hp_bonus: 150 }, - 4: { atked: [{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] }, - 5: { atked: [{ s_uuid: 6401, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] }, - 6: { - atked: [ - { s_uuid: 6401, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } }, - { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, - ] - }, + atked: { + 6401: [ + { lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, + { lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } }, + ], + 6403: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + { lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, + { lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, + ], + 6404: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, + ], }, + hp_bonus: [{ lv: 3, value: 150 }], info: "✧受伤提升攻击与暴击\n✦受伤限时提升暴伤", }, 5015: { uuid: 5015, name: "血刃武者", path: "hc3", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, - atked: [ - { s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } }, - { s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, - ], - evolve: { - 2: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }, { s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } }] }, - 3: { hp_bonus: 200 }, - 4: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } }, { s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] }, - 5: { atked: [{ s_uuid: 6301, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } }, { s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] }, - 6: { - atked: [ - { s_uuid: 6301, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } }, - { s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - { s_uuid: 6301, t_num: 7, overrides: { TGroup: TGroup.Team, ap: 2 } }, - ] - }, + atked: { + 6301: [ + { lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } }, + { lv: 2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }, + { lv: 4, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } }, + { lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } }, + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, ap: 2 } }, + ], + 6404: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, + { lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } }, + { lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }, + ], + 6403: [ + { lv: 6, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + ], }, + hp_bonus: [{ lv: 3, value: 200 }], info: "✧受伤获得护盾与暴伤\n✦受伤追加暴击并给全队护盾", }, 5016: { uuid: 5016, name: "狂血战士", path: "hc4", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 142, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, - atked: [ - { s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, - { s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } }, - ], - evolve: { - 2: { atked: [{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } }] }, - 3: { ap_bonus: 20, hp_bonus: 150 }, - 4: { atked: [{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }] }, - 5: { atked: [{ s_uuid: 6401, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }] }, - 6: { - atked: [ - { s_uuid: 6401, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } }, - { s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6403, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, - ] - }, + atked: { + 6401: [ + { lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, + { lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } }, + ], + 6405: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } }, + { lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } }, + { lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }, + ], + 6403: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + ], + 6404: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, + ], }, + ap_bonus: [{ lv: 3, value: 20 }], + hp_bonus: [{ lv: 3, value: 150 }], info: "✧受伤提升攻击与击晕\n✦受伤追加暴击与暴伤", }, // 以下英雄暂时注释,保留待后续扩展 @@ -389,81 +402,62 @@ export const HeroInfo: Record = { 5021: { uuid: 5021, name: "小刺客", path: "hc1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } }, - atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }], // 成长主线:滚雪球(AP增量固定1,5级阈值5→4刀);6级追加暴伤强化(永久叠加无100%上限,与高AP叠乘) - // 注意:evolve.atking 为整体替换且逐级顺序应用,高级别需写完整数组 - evolve: { - 2: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }] }, - 3: { ap_bonus: 20, hp_bonus: 80 }, - 4: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }] }, - 5: { atking: [{ s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } }] }, - 6: { - atking: [ - { s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } }, - { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 20, buff_duration: 5 } }, - ] - }, + atking: { + 6401: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }, + { lv: 5, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } }, + ], + 6404: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 20, buff_duration: 5 } }, + ], }, + ap_bonus: [{ lv: 3, value: 20 }], + hp_bonus: [{ lv: 3, value: 80 }], info: "✧攻击永久提升攻击\n✦攻击限时提升暴伤", }, 5022: { uuid: 5022, name: "嗜血剑客", path: "hc2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } }, - atking: [ - { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } } - ], - evolve: { - 2: { - atking: [ - { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, - { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } } - ] - }, - 3: { ap_bonus: 20, hp_bonus: 80 }, - 4: { - atking: [ - { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } } - ] - }, - 5: { - atking: [ - { s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } } - ] - }, - 6: { - atking: [ - { s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } }, - { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, - ] - }, + atking: { + 6403: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + { lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, + { lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, + { lv: 5, t_num: 4, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, + ], + 6401: [ + { lv: 1, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } }, + ], + 6404: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, + ], }, + ap_bonus: [{ lv: 3, value: 20 }], + hp_bonus: [{ lv: 3, value: 80 }], info: "✧攻击限时提升暴击\n✦攻击限时提升暴伤", }, 5023: { uuid: 5023, name: "暗影杀手", path: "hc5", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast1].cd, ccd: 0 } }, - atking: [ - { s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }, - { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - ], - evolve: { - 2: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }] }, - 3: { hp_bonus: 100 }, - 4: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] }, - 5: { atking: [{ s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] }, - 6: { - atking: [ - { s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } }, - { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, - { s_uuid: 6409, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7016, buff_value: 5, buff_duration: 5 } }, - ] - }, + atking: { + 6401: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }, + { lv: 5, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } }, + ], + 6403: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + { lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, + { lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, + ], + 6404: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, + ], + 6409: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7016, buff_value: 5, buff_duration: 5 } }, + ], }, + hp_bonus: [{ lv: 3, value: 100 }], info: "✧攻击提升攻击与暴击\n✦攻击追加暴伤与风怒", }, // 5022: { @@ -489,38 +483,36 @@ export const HeroInfo: Record = { 5031: { uuid: 5031, name: "援护弓手", path: "ha1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal2].cd, ccd: 0 } }, - atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } }], // 成长主线:AP增益固定1,5级 hit_count 1→2(2英雄环境=全队);6级追加全队攻速光环 - // 注意:evolve.atking 为整体替换且逐级顺序应用,高级别需写完整数组;field 为驻场光环覆盖 - evolve: { - 2: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } }] }, - 3: { hp_bonus: 60 }, - 4: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } }] }, - 5: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 1 } }] }, - 6: { field: [7006] }, + atking: { + 6401: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } }, + { lv: 5, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 1 } }, + ], }, + hp_bonus: [{ lv: 3, value: 60 }], + field: [{ lv: 6, uuids: [7006] }], info: "✧攻击提升队友攻击\n✦光环全队提升攻速", }, 5032: { uuid: 5032, name: "战术弓手", path: "ha2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120, skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } }, - atking: [ - { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } }, - ], - evolve: { - 2: { atking: [{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } }] }, - 3: { hp_bonus: 80 }, - 4: { atking: [{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }] }, - 5: { atking: [{ s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }] }, - 6: { - atking: [ - { s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }, - { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, - ] - }, + atking: { + 6403: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + { lv: 2, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, + { lv: 4, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, + { lv: 5, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, + ], + 6401: [ + { lv: 1, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } }, + { lv: 4, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }, + ], + 6404: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, + ], }, + hp_bonus: [{ lv: 3, value: 80 }], info: "✧攻击限时提升队友暴击\n✦攻击限时提升队友暴伤", }, // 5032: { @@ -532,24 +524,25 @@ export const HeroInfo: Record = { 5033: { uuid: 5033, name: "鹰眼弓将", path: "ha3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200, skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast3].cd, ccd: 0 } }, - atking: [ - { s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } }, - { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, - ], - evolve: { - 2: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } }, { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } }] }, - 3: { hp_bonus: 100 }, - 4: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }, { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] }, - 5: { atking: [{ s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }, { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] }, - 6: { - atking: [ - { s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }, - { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6403, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - { s_uuid: 6405, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } }, - ] - }, + atking: { + 6401: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } }, + { lv: 4, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }, + { lv: 5, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }, + ], + 6404: [ + { lv: 1, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, + { lv: 2, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } }, + { lv: 4, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }, + ], + 6403: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + ], + 6405: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } }, + ], }, + hp_bonus: [{ lv: 3, value: 100 }], info: "✧攻击提升队友攻击与暴伤\n✦攻击追加队友暴击与击晕", }, // 5033: { @@ -608,83 +601,87 @@ export const HeroInfo: Record = { 5041: { uuid: 5041, name: "殉道卫士", path: "hk1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, - dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }], - evolve: { - 2: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } }] }, - 3: { hp_bonus: 100 }, - 4: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }] }, - 5: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }] }, - 6: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }, { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }] }, + dead: { + 6301: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }, + { lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } }, + { lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, + { lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }, + ], + 6401: [ + { lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, + ], }, + hp_bonus: [{ lv: 3, value: 100 }], info: "✧死亡全队获得护盾\n✦死亡全队提升攻击", }, 5042: { uuid: 5042, name: "遗志将军", path: "hk2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, - dead: [ - { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, - { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } }, - ], - revive: { s_uuid: 6501, r_num: 1, upr: 0.5 }, - evolve: { - 2: { dead: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } }] }, - 3: { revive: { s_uuid: 6501, r_num: 1, upr: 0.6 } }, - 4: { dead: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }] }, - 5: { revive: { s_uuid: 6501, r_num: 1, upr: 0.7 } }, - 6: { - dead: [ - { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, - { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }, - { s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }, - ], - revive: { s_uuid: 6501, r_num: 1, upr: 0.8 }, - }, + dead: { + 6401: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, + ], + 6402: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } }, + { lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } }, + { lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }, + ], + 6301: [ + { lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }, + ], }, + revive: [ + { lv: 1, s_uuid: 6501, r_num: 1, upr: 0.5 }, + { lv: 3, s_uuid: 6501, r_num: 1, upr: 0.6 }, + { lv: 5, s_uuid: 6501, r_num: 1, upr: 0.7 }, + { lv: 6, s_uuid: 6501, r_num: 1, upr: 0.8 }, + ], info: "✧死亡全队攻血提升\n✦死亡全队护盾并复活", }, 5043: { uuid: 5043, name: "亡魂刺客", path: "hc1", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } }, - dead: [ - { s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } }, - { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - ], - evolve: { - 2: { dead: [{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } }, { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }] }, - 3: { hp_bonus: 100 }, - 4: { dead: [{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 6 } }] }, - 5: { dead: [{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] }, - 6: { - dead: [ - { s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, - ] - }, + dead: { + 6405: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } }, + { lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } }, + { lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }, + ], + 6403: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + { lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 6 } }, + { lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, + ], + 6401: [ + { lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, + ], }, + hp_bonus: [{ lv: 3, value: 100 }], info: "✧死亡全队击晕与暴击\n✦死亡全队提升攻击", }, 5044: { uuid: 5044, name: "血誓剑客", path: "hc2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast3].cd, ccd: 0 } }, - dead: [ - { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, - ], - evolve: { - 2: { dead: [{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }] }, - 3: { hp_bonus: 150 }, - 4: { dead: [{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 7, buff_duration: 6 } }] }, - 5: { dead: [{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] }, - 6: { - dead: [ - { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }, - { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, - { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } }, - ] - }, + dead: { + 6403: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + { lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, + { lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, + ], + 6404: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }, + { lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 7, buff_duration: 6 } }, + { lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }, + ], + 6401: [ + { lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, + ], + 6402: [ + { lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } }, + ], }, + hp_bonus: [{ lv: 3, value: 150 }], info: "✧死亡全队暴击与暴伤\n✦死亡全队攻击与生命", }, @@ -694,25 +691,31 @@ export const HeroInfo: Record = { 5045: { uuid: 5045, name: "不灭战魂", path: "hk3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 60, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, - // 死亡释放:5 层护盾 + 全队 +10 HP;复活 1 次血量 50% - dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } }], - revive: { s_uuid: 6501, r_num: 1, upr: 0.5 }, - evolve: { - 2: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } }] }, - 3: { revive: { s_uuid: 6501, r_num: 1, upr: 0.6 } }, - 4: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 7 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }] }, - 5: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }] }, - // 6级终极遗志:追加 AP+5 + 暴击计时 5%;终极涅槃:复活 2 次血量 70% - 6: { - dead: [ - { s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } }, - { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }, - { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, - { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, - ], - revive: { s_uuid: 6501, r_num: 2, upr: 0.7 }, - }, + // 死亡释放:5 层护盾 + 全队 +10 HP;复活 1 次血量 50%。6级终极遗志追加 AP+5 / 暴击 5%,复活 2 次 70% + dead: { + 6301: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, + { lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }, + { lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 7 } }, + { lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } }, + ], + 6402: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } }, + { lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } }, + { lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }, + ], + 6401: [ + { lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, + ], + 6403: [ + { lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }, + ], }, + revive: [ + { lv: 1, s_uuid: 6501, r_num: 1, upr: 0.5 }, + { lv: 3, s_uuid: 6501, r_num: 1, upr: 0.6 }, + { lv: 6, s_uuid: 6501, r_num: 2, upr: 0.7 }, + ], info: "✧死亡全队加护盾\n✧复活1:50%血量\n✦死亡加攻击\n✦复活2:70%血量", }, @@ -722,30 +725,33 @@ export const HeroInfo: Record = { skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } }, // 战前计时 buff:每波开始全队 AP 限时提升(+30/5s → +60/7s → +90/10s),6级追加暴击驻场光环 // 统一复用 7111 基础配置,通过 buff_value/buff_duration 覆写实现三档成长 - fstart: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111 } }], - evolve: { - 2: { hp_bonus: 80 }, - 3: { fstart: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 60, buff_duration: 7 } }] }, - 4: { hp_bonus: 80 }, - 5: { fstart: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 90, buff_duration: 10 } }] }, - 6: { field: [7204] }, + fstart: { + 6401: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111 } }, + { lv: 3, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 60, buff_duration: 7 } }, + { lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 90, buff_duration: 10 } }, + ], }, + hp_bonus: [{ lv: 2, value: 80 }, { lv: 4, value: 80 }], + field: [{ lv: 6, uuids: [7204] }], info: "✧开局全队提升攻击\n✦光环全队提升暴击", }, 5052: { uuid: 5052, name: "护盾牧师", path: "hm2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } }, - fstart: [ - { s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }, - { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }, - ], - evolve: { - 2: { fstart: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }] }, - 3: { hp_bonus: 80 }, - 4: { fstart: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }] }, - 5: { fstart: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }] }, - 6: { field: [7007] }, + fstart: { + 6301: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }, + { lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } }, + { lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, + { lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }, + ], + 6402: [ + { lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }, + ], }, + hp_bonus: [{ lv: 3, value: 80 }], + field: [{ lv: 6, uuids: [7007] }], info: "✧开局全队获得护盾\n✦光环全队提升生命", }, // 5052: { @@ -796,14 +802,13 @@ export const HeroInfo: Record = { 5061: { uuid: 5061, name: "战歌法师", path: "hm3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } }, - field: [7002, 7006], - evolve: { - 2: { field: [7202, 7006] }, - 3: { hp_bonus: 80 }, - 4: { field: [7202, 7206] }, - 5: { field: [7202, 7206] }, - 6: { field: [7202, 7206, 7007] }, - }, + field: [ + { lv: 1, uuids: [7002, 7006] }, + { lv: 2, uuids: [7202, 7006] }, + { lv: 4, uuids: [7202, 7206] }, + { lv: 6, uuids: [7202, 7206, 7007] }, + ], + hp_bonus: [{ lv: 3, value: 80 }], info: "✧光环全队提升攻击\n✦追加提升攻速生命", }, @@ -811,21 +816,19 @@ export const HeroInfo: Record = { 5071: { uuid: 5071, name: "治愈牧师", path: "hh1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40, skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } }, - atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 200 } }], // 成长主线:治疗量 200→250→300%,5级 hit_count 1→2(全队);6级追加护盾 atking,攻防一体 - // 注意:evolve.atking 为整体替换且逐级顺序应用,高级别需写完整数组 - evolve: { - 2: { atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 250 } }] }, - 3: { hp_bonus: 80 }, - 4: { atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 300 } }] }, - 5: { atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 300 } }] }, - 6: { - atking: [ - { s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 300 } }, - { s_uuid: 6301, t_num: 7, overrides: { TGroup: TGroup.Team, ap: 3 } }, - ] - }, + atking: { + 6302: [ + { lv: 1, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 200 } }, + { lv: 2, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 250 } }, + { lv: 4, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 300 } }, + { lv: 5, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 300 } }, + ], + 6301: [ + { lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, ap: 3 } }, + ], }, + hp_bonus: [{ lv: 3, value: 80 }], info: "✧攻击治疗低血队友\n✦攻击全队获得护盾", }, // 5072: { @@ -995,23 +998,64 @@ export const HERO_POWER_WEIGHTS = { DEFAULT_EVAL_SECONDS: 60, }; -/** 计算目标等级下 evolve 提供的累计属性加成 */ +/** + * 解析触发技能在目标等级下的有效条目列表。 + * 每个 s_uuid 取 ≤lv 的最大档;返回扁平数组供评分/触发器消费。 + */ +export function resolveTriggerByLv(grouped: TriggerGrouped | undefined, lv: number): { s_uuid: number; t_num: number; overrides?: SkillOverrides }[] { + if (!grouped) return []; + const result: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[] = []; + for (const key in grouped) { + const entries = grouped[key]; + if (!entries || entries.length === 0) continue; + let pick: LvTriggerEntry | undefined; + for (const e of entries) { + if (e.lv <= lv && (!pick || e.lv > pick.lv)) pick = e; + } + if (pick) result.push({ s_uuid: Number(key), t_num: pick.t_num, overrides: pick.overrides }); + } + return result; +} + +/** 解析驻场光环在目标等级下的有效 uuid 列表(取 ≤lv 的最大档) */ +export function resolveFieldByLv(field: LvFieldEntry[] | undefined, lv: number): number[] { + if (!field || field.length === 0) return []; + let pick: LvFieldEntry | undefined; + for (const e of field) { + if (e.lv <= lv && (!pick || e.lv > pick.lv)) pick = e; + } + return pick ? pick.uuids : []; +} + +/** 解析复活技能在目标等级下的有效配置(取 ≤lv 的最大档) */ +export function resolveReviveByLv(revive: LvReviveEntry[] | undefined, lv: number): { s_uuid: number; r_num: number; upr: number } | undefined { + if (!revive || revive.length === 0) return undefined; + let pick: LvReviveEntry | undefined; + for (const e of revive) { + if (e.lv <= lv && (!pick || e.lv > pick.lv)) pick = e; + } + return pick ? { s_uuid: pick.s_uuid, r_num: pick.r_num, upr: pick.upr } : undefined; +} + +/** 计算目标等级下额外属性加成(hp_bonus/ap_bonus 按 lv 累加) */ function getEvolveBonuses(hero: heroInfo, targetLv: number): { hp: number, ap: number } { let hp = 0; let ap = 0; - if (!hero.evolve) return { hp, ap }; - const maxLv = Math.max(1, Math.min(targetLv, FightSet.HERO_MAX_LV)); - for (let lv = 2; lv <= maxLv; lv++) { - const ev = hero.evolve[lv]; - if (ev) { - hp += ev.hp_bonus || 0; - ap += ev.ap_bonus || 0; + const lv = Math.max(1, targetLv); + if (hero.hp_bonus) { + for (const e of hero.hp_bonus) { + if (e.lv <= lv) hp += e.value; + } + } + if (hero.ap_bonus) { + for (const e of hero.ap_bonus) { + if (e.lv <= lv) ap += e.value; } } return { hp, ap }; } -/** 计算目标等级下的有效 HP/AP(含等级倍率与 evolve 加成) */ +/** 计算目标等级下的有效 HP/AP(含等级倍率与额外加成) */ function getEffectiveStats(hero: heroInfo, targetLv: number): { hp: number, ap: number } { const bonuses = getEvolveBonuses(hero, targetLv); const lv = Math.max(1, targetLv); @@ -1068,7 +1112,7 @@ function getTriggerCount( case SkillTriggerType.FEnd: return getWaveCount(seconds); case SkillTriggerType.Dead: - return getWaveCount(seconds) * (1 + (hero.revive?.r_num || 0)); + return getWaveCount(seconds) * (1 + (resolveReviveByLv(hero.revive, FightSet.HERO_MAX_LV)?.r_num || 0)); } return 1; } @@ -1338,16 +1382,18 @@ export function calcHeroPowerDetailed(hero: heroInfo, targetLv: number = 1, seco const dpsValue = (apEff / cd) * weights.W_DPS_PER_SEC * seconds; const normalAttack = getNormalAttackInfo(hero, targetLv, seconds); - const atking = hero.atking ? calcTriggerPowerDetailed(hero.atking, hero, targetLv, SkillTriggerType.Atking, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; - const atked = hero.atked ? calcTriggerPowerDetailed(hero.atked, hero, targetLv, SkillTriggerType.Atked, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; - const fstart = hero.fstart ? calcTriggerPowerDetailed(hero.fstart, hero, targetLv, SkillTriggerType.FStart, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; - const fend = hero.fend ? calcTriggerPowerDetailed(hero.fend, hero, targetLv, SkillTriggerType.FEnd, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; - const dead = hero.dead ? calcTriggerPowerDetailed(hero.dead, hero, targetLv, SkillTriggerType.Dead, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; - const field = hero.field ? calcFieldPowerDetailed(hero.field, hero, targetLv, seconds) : { total: 0, items: [] as FieldSkillEval[] }; + const atking = hero.atking ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.atking, targetLv), hero, targetLv, SkillTriggerType.Atking, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; + const atked = hero.atked ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.atked, targetLv), hero, targetLv, SkillTriggerType.Atked, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; + const fstart = hero.fstart ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.fstart, targetLv), hero, targetLv, SkillTriggerType.FStart, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; + const fend = hero.fend ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.fend, targetLv), hero, targetLv, SkillTriggerType.FEnd, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; + const dead = hero.dead ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.dead, targetLv), hero, targetLv, SkillTriggerType.Dead, seconds) : { total: 0, items: [] as TriggerSkillEval[] }; + const fieldUuids = resolveFieldByLv(hero.field, targetLv); + const field = fieldUuids.length > 0 ? calcFieldPowerDetailed(fieldUuids, hero, targetLv, seconds) : { total: 0, items: [] as FieldSkillEval[] }; let reviveValue = 0; - if (hero.revive) { - reviveValue = hpEff * hero.revive.upr * hero.revive.r_num * weights.W_revive * getWaveCount(seconds); + const revive = resolveReviveByLv(hero.revive, targetLv); + if (revive) { + reviveValue = hpEff * revive.upr * revive.r_num * weights.W_revive * getWaveCount(seconds); } const total = hpValue + dpsValue + atking.total + atked.total + fstart.total + fend.total + dead.total + field.total + reviveValue; diff --git a/assets/script/game/hero/FieldSkillHelper.ts b/assets/script/game/hero/FieldSkillHelper.ts index 2c646e7b..766074c6 100644 --- a/assets/script/game/hero/FieldSkillHelper.ts +++ b/assets/script/game/hero/FieldSkillHelper.ts @@ -1,6 +1,5 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { FacSet } from "../common/config/GameSet"; -import { HeroInfo } from "../common/config/heroSet"; import { FieldSkillSet, FieldSkillType } from "../common/config/SkillSet"; import { HeroAttrsComp } from "./HeroAttrsComp"; import { SkillBoxComp } from "../map/SkillBoxComp"; @@ -19,12 +18,11 @@ export class FieldSkillHelper { let total = 0; // 1. 统计英雄带来的驻场技能加成 - // 读 model.field(运行时):优先使用 evolve 覆盖后的驻场配置,未升级时回退到 heroInfo 基础配置 + // 读 model.runtime_field(已按当前等级 resolve 的 uuid 列表) ecs.query(ecs.allOf(HeroAttrsComp)).forEach((entity: ecs.Entity) => { const model = entity.get(HeroAttrsComp); if (!model || model.is_dead || model.fac !== FacSet.HERO) return; - const heroConfig = HeroInfo[model.hero_uuid]; - const fields = model.field ?? heroConfig?.field; + const fields = model.runtime_field; if (fields) { for (const skillUuid of fields) { const skillConfig = FieldSkillSet[skillUuid]; diff --git a/assets/script/game/hero/Hero.ts b/assets/script/game/hero/Hero.ts index c11edb97..14106cf4 100644 --- a/assets/script/game/hero/Hero.ts +++ b/assets/script/game/hero/Hero.ts @@ -5,7 +5,7 @@ import { smc } from "../common/SingletonModuleComp"; import { HeroAttrsComp } from "./HeroAttrsComp"; import { HeroViewComp } from "./HeroViewComp"; import { BoxSet, FacSet, FightSet, IndexSet } from "../common/config/GameSet"; -import { HeroInfo, HeroPos, resolveFormationTargetX } from "../common/config/heroSet"; +import { HeroInfo, HeroPos, resolveFormationTargetX, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv } from "../common/config/heroSet"; import { GameEvent } from "../common/config/GameEvent"; import { SkillTriggerType } from "../common/config/heroSet"; import { SkillTriggerHelper } from "./SkillTriggerHelper"; @@ -126,7 +126,7 @@ export class Hero extends ecs.Entity { smc.mission.heroGrid[posIndex] = this.eid; } - // 复制触发技能配置 + // 复制触发技能配置(新结构:按 s_uuid 分组 + lv 数组) model.call = hero.call; model.dead = hero.dead; model.fstart = hero.fstart; @@ -135,6 +135,8 @@ export class Hero extends ecs.Entity { model.atked = hero.atked; model.field = hero.field; model.revive = hero.revive; + model.ap_bonus = hero.ap_bonus; + model.hp_bonus = hero.hp_bonus; // 基础属性按等级倍率初始化 // 使用指数增长公式:等级 2 时为原来的 HERO_LV_MULTIPLIER 倍,等级 3 时为 HERO_LV_MULTIPLIER^2 倍 @@ -164,38 +166,26 @@ export class Hero extends ecs.Entity { model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + hero_lv - 2), ccd: 0 }; } - // 应用等级进化配置(从 lv2 开始逐级覆盖) - if (hero.evolve) { - // 记录 evolve 配置快照(只读引用),供 UI 计算 ap/hp 额外加成文案 - model.evolve = hero.evolve; - for (let elv = 2; elv <= hero_lv; elv++) { - const evo = hero.evolve[elv]; - if (!evo) continue; - // 替换普攻技能 - if (evo.skill) { - const oldSkill = Object.values(model.skills)[0]; - model.skills = {}; - model.skills[evo.skill.s_uuid] = { - uuid: evo.skill.s_uuid, - lv: Math.max(0, 1 + hero_lv - 2), - cd: evo.skill.cd ?? oldSkill?.cd ?? 1, - ccd: 0, - overrides: evo.skill.overrides, - }; - } - // 覆盖触发技能 - if (evo.atking) model.atking = evo.atking; - if (evo.atked) model.atked = evo.atked; - if (evo.dead) model.dead = evo.dead; - if (evo.fstart) model.fstart = evo.fstart; - if (evo.fend) model.fend = evo.fend; - // 覆盖驻场光环(存活期间全局生效) - if (evo.field) model.field = evo.field; - if (evo.revive) model.revive = evo.revive; - // 额外属性加成 - if (evo.ap_bonus) model.ap += evo.ap_bonus; - if (evo.hp_bonus) { model.hp += evo.hp_bonus; model.hp_max += evo.hp_bonus; } - } + // 按当前英雄等级 resolve 触发技能/光环/复活到运行时缓存,供 SkillTriggerHelper 消费 + model.runtime_call = resolveTriggerByLv(model.call, hero_lv); + model.runtime_dead = resolveTriggerByLv(model.dead, hero_lv); + model.runtime_fstart = resolveTriggerByLv(model.fstart, hero_lv); + model.runtime_fend = resolveTriggerByLv(model.fend, hero_lv); + model.runtime_atking = resolveTriggerByLv(model.atking, hero_lv); + model.runtime_atked = resolveTriggerByLv(model.atked, hero_lv); + model.runtime_field = resolveFieldByLv(model.field, hero_lv); + model.runtime_revive = resolveReviveByLv(model.revive, hero_lv); + + // 应用额外属性加成(hp_bonus/ap_bonus 按 ≤英雄等级 累加) + if (model.hp_bonus) { + let hpExtra = 0; + for (const e of model.hp_bonus) { if (e.lv <= hero_lv) hpExtra += e.value; } + model.hp += hpExtra; model.hp_max += hpExtra; + } + if (model.ap_bonus) { + let apExtra = 0; + for (const e of model.ap_bonus) { if (e.lv <= hero_lv) apExtra += e.value; } + model.ap += apExtra; } // 缓存技能射程等派生数据,减少战斗帧内重复计算 diff --git a/assets/script/game/hero/HeroAtkSystem.ts b/assets/script/game/hero/HeroAtkSystem.ts index 7217b520..8fc5e7e8 100644 --- a/assets/script/game/hero/HeroAtkSystem.ts +++ b/assets/script/game/hero/HeroAtkSystem.ts @@ -228,8 +228,8 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda let maxReviveCount = 0; let reviveHpPercent = 50; // 默认恢复50% let reviveSkillConf: any = null; // 提取出来的复活技能配置 - if (TAttrsComp.revive) { - const reviveConf = TAttrsComp.revive; + if (TAttrsComp.runtime_revive) { + const reviveConf = TAttrsComp.runtime_revive; maxReviveCount = reviveConf.r_num + Math.floor((TAttrsComp.lv - 1) * reviveConf.upr); if (TAttrsComp.revived_count < maxReviveCount) { canRevive = true; diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index b93a9e22..280973f6 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -1,5 +1,5 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; -import { HeroDisVal, HeroInfo, HSkillInfo, HType, SkillTriggerType, HeroEvolve } from "../common/config/heroSet"; +import { HeroDisVal, HeroInfo, HSkillInfo, HType, SkillTriggerType, TriggerGrouped, LvFieldEntry, LvReviveEntry, LvBonusEntry } from "../common/config/heroSet"; import { mLogger } from "../common/Logger"; import { FacSet, FightSet } from "../common/config/GameSet"; import { FieldSkillSet, FieldSkillType, SkillOverrides } from "../common/config/SkillSet"; @@ -41,19 +41,37 @@ export class HeroAttrsComp extends ecs.Comp { // ==================== 攻击属性 (补充) ==================== skills: Record = {}; - // ==================== 触发类技能 ==================== - [SkillTriggerType.Call]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - [SkillTriggerType.Dead]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - [SkillTriggerType.FStart]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - [SkillTriggerType.FEnd]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - [SkillTriggerType.Atking]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - [SkillTriggerType.Atked]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; - /** 驻场光环(FieldSkillSet uuid 列表,随 evolve 覆盖,存活期间全局生效) */ - [SkillTriggerType.Field]?: number[]; - [SkillTriggerType.Revive]?: { s_uuid: number, r_num: number, upr: number }; + // ==================== 触发类技能(静态配置,按 s_uuid 分组 + lv 数组) ==================== + [SkillTriggerType.Call]?: TriggerGrouped; + [SkillTriggerType.Dead]?: TriggerGrouped; + [SkillTriggerType.FStart]?: TriggerGrouped; + [SkillTriggerType.FEnd]?: TriggerGrouped; + [SkillTriggerType.Atking]?: TriggerGrouped; + [SkillTriggerType.Atked]?: TriggerGrouped; + /** 驻场光环(按 lv 解锁,存活期间全局生效) */ + [SkillTriggerType.Field]?: LvFieldEntry[]; + [SkillTriggerType.Revive]?: LvReviveEntry[]; + /** 额外攻击/生命加成(按 lv 累加) */ + ap_bonus?: LvBonusEntry[]; + hp_bonus?: LvBonusEntry[]; - /** 等级进化配置快照(引用 heroInfo.evolve,只读;供 UI 计算 ap/hp 额外加成文案) */ - evolve?: Record; + // ==================== 运行时解析缓存(按当前等级 resolve 后的有效列表) ==================== + /** 当前等级下生效的攻击触发条目(供 SkillTriggerHelper 消费) */ + runtime_atking?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; + /** 当前等级下生效的受击触发条目 */ + runtime_atked?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; + /** 当前等级下生效的召唤触发条目 */ + runtime_call?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; + /** 当前等级下生效的死亡触发条目 */ + runtime_dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; + /** 当前等级下生效的战前触发条目 */ + runtime_fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; + /** 当前等级下生效的战后触发条目 */ + runtime_fend?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[]; + /** 当前等级下生效的驻场光环 uuid 列表 */ + runtime_field?: number[]; + /** 当前等级下生效的复活配置 */ + runtime_revive?: { s_uuid: number; r_num: number; upr: number }; // ==================== 特殊属性 ==================== critical: number = 0; // 暴击率 @@ -547,8 +565,18 @@ export class HeroAttrsComp extends ecs.Comp { this.fend = undefined; this.atking = undefined; this.atked = undefined; + this.field = undefined; this.revive = undefined; - this.evolve = undefined; + this.ap_bonus = undefined; + this.hp_bonus = undefined; + this.runtime_atking = undefined; + this.runtime_atked = undefined; + this.runtime_call = undefined; + this.runtime_dead = undefined; + this.runtime_fstart = undefined; + this.runtime_fend = undefined; + this.runtime_field = undefined; + this.runtime_revive = undefined; this.critical = 0; this.critical_res = 0; this.freeze_chance = 0; diff --git a/assets/script/game/hero/HeroViewComp.ts b/assets/script/game/hero/HeroViewComp.ts index ea418283..1abfb249 100644 --- a/assets/script/game/hero/HeroViewComp.ts +++ b/assets/script/game/hero/HeroViewComp.ts @@ -489,7 +489,7 @@ export class HeroViewComp extends CCComp { } // 如果角色带有死亡触发技能,则由 SCastSystem 播放 playReady("dead") - if (this.model && this.model.dead && this.model.dead.length > 0) { + if (this.model && this.model.runtime_dead && this.model.runtime_dead.length > 0) { // SCastSystem will handle the "dead" ready animation } else { // 播放默认死亡特效 diff --git a/assets/script/game/hero/Mon.ts b/assets/script/game/hero/Mon.ts index b55ca471..1db2d030 100644 --- a/assets/script/game/hero/Mon.ts +++ b/assets/script/game/hero/Mon.ts @@ -1,9 +1,9 @@ -import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D, NodePool, tween, Tween} from "cc"; +import { instantiate, Node, Prefab, Vec3, v3, resources, SpriteFrame, Sprite, SpriteAtlas, BoxCollider2D, NodePool, tween, Tween } from "cc"; import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { smc } from "../common/SingletonModuleComp"; import { BoxSet, FacSet, FightSet, IndexSet } from "../common/config/GameSet"; -import { HeroInfo } from "../common/config/heroSet"; +import { HeroInfo, resolveTriggerByLv, resolveReviveByLv } from "../common/config/heroSet"; import { HeroAttrsComp } from "./HeroAttrsComp"; import { HeroViewComp } from "./HeroViewComp"; import { MoveComp } from "./MoveComp"; @@ -109,10 +109,10 @@ export class Monster extends ecs.Entity { const model = this.get(HeroAttrsComp); const view = this.get(HeroViewComp); if (model && view && view.node && view.node.isValid) { - const path = "game/heros/" + HeroInfo[model.hero_uuid].path; - Monster.putToPool(path, view.node); + const path = "game/heros/" + HeroInfo[model.hero_uuid].path; + Monster.putToPool(path, view.node); } - + if (model && model.posIndex >= 0) { if (smc.mission.monGrid[model.posIndex] === this.eid) { smc.mission.monGrid[model.posIndex] = -1; @@ -131,15 +131,15 @@ export class Monster extends ecs.Entity { * 2) 初始化表现、属性、技能与阵营 * 3) 播放下落入场并在落地后启用碰撞与移动 */ - load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, is_boss:boolean=false, dropToY:number = pos.y,mon_lv:number=1, laneIndex:number = 0) { + load(pos: Vec3 = Vec3.ZERO, scale: number = 1, uuid: number = 1001, is_boss: boolean = false, dropToY: number = pos.y, mon_lv: number = 1, laneIndex: number = 0) { // 怪物默认朝左,表现缩放固定为负向 - scale=-1 + scale = -1 // 当前怪物尺寸固定,保留变量便于后续扩展 - let size=1.15 + let size = 1.15 var scene = smc.map.MapView.scene; // 根据配置读取怪物预制体路径 - var path = "game/heros/"+HeroInfo[uuid].path; - + var path = "game/heros/" + HeroInfo[uuid].path; + // 优先从对象池取节点,未命中时再实例化 let node = Monster.getFromPool(path); if (!node) { @@ -157,7 +157,7 @@ export class Monster extends ecs.Entity { if (collider) { collider.enabled = false; } - + let baseScale = (node as any)._baseScale || v3(1, 1, 1); node.setScale(size * baseScale.x, size * baseScale.y); node.setPosition(pos) @@ -191,8 +191,8 @@ export class Monster extends ecs.Entity { model.revive = hero.revive; // 标记是否 Boss,非 Boss 默认记作杂兵 - model.is_boss =is_boss - if(!model.is_boss){ + model.is_boss = is_boss + if (!model.is_boss) { model.is_kalami = true; } @@ -202,7 +202,7 @@ export class Monster extends ecs.Entity { const skill = hero.skills[key]; if (!skill) continue; // 最终技能等级 = 初始技能等级 + 怪物等级增量,且下限为 0 - model.skills[skill.uuid] = { ...skill, lv: Math.max(0,skill.lv + mon_lv - 2), ccd: 0 }; + model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + mon_lv - 2), ccd: 0 }; } // 【测试模式专属】如果有覆盖技能配置则应用 const testSkills = (this as any)._testSkills; @@ -227,15 +227,24 @@ export class Monster extends ecs.Entity { if (testSkills.fend !== undefined) model.fend = testSkills.fend; } + // 按怪物等级 resolve 触发技能/复活到运行时缓存(怪物无 lv 成长,恒用 mon_lv) + model.runtime_call = resolveTriggerByLv(model.call, mon_lv); + model.runtime_dead = resolveTriggerByLv(model.dead, mon_lv); + model.runtime_fstart = resolveTriggerByLv(model.fstart, mon_lv); + model.runtime_fend = resolveTriggerByLv(model.fend, mon_lv); + model.runtime_atking = resolveTriggerByLv(model.atking, mon_lv); + model.runtime_atked = resolveTriggerByLv(model.atked, mon_lv); + model.runtime_revive = resolveReviveByLv(model.revive, mon_lv); + // 缓存技能射程等派生数据,减少战斗帧内重复计算 model.updateSkillDistanceCache(); - + // 注册视图组件并重置对象池复用状态 this.add(view); view.init(); view.as.idle(); // 广播怪物加载事件,供刷怪与战斗系统联动 - oops.message.dispatchEvent("monster_load",this) + oops.message.dispatchEvent("monster_load", this) // 初始化移动参数:方向、目标 X、站位基准 Y const move = this.get(MonMoveComp); move.reset(); @@ -246,7 +255,7 @@ export class Monster extends ecs.Entity { // 依据下落距离自适应入场时长,确保观感一致 const dropDistance = Math.abs(pos.y - dropToY); - + const onDropComplete = () => { if (!node || !node.isValid) return; // 落地后锁定最终位置,切换到落地完成状态 @@ -271,7 +280,7 @@ export class Monster extends ecs.Entity { // 停止旧动画后执行下落 tween,避免复用节点时动画叠加 Tween.stopAllByTarget(node); - + if (dropDistance > 0) { const dropDuration = Math.max(0.18, Math.min(0.38, dropDistance / 1200)); tween(node) @@ -287,10 +296,10 @@ export class Monster extends ecs.Entity { smc.vmdata.mission_data.mon_num++ } - + /** 重置入口:复用 destroy 的释放流程 */ reset() { super.destroy(); } - + } diff --git a/assets/script/game/hero/SkillTriggerHelper.ts b/assets/script/game/hero/SkillTriggerHelper.ts index 4ef0367b..77a0c165 100644 --- a/assets/script/game/hero/SkillTriggerHelper.ts +++ b/assets/script/game/hero/SkillTriggerHelper.ts @@ -42,10 +42,10 @@ export class SkillTriggerHelper { this.handleDead(model, view); break; case SkillTriggerType.FStart: - this.handleArrayTrigger(model.fstart, model, view, type); + this.handleArrayTrigger(model.runtime_fstart, model, view, type); break; case SkillTriggerType.FEnd: - this.handleArrayTrigger(model.fend, model, view, type); + this.handleArrayTrigger(model.runtime_fend, model, view, type); break; case SkillTriggerType.Atking: this.handleAtking(model, view); @@ -61,17 +61,17 @@ export class SkillTriggerHelper { * 支持受【召唤强化羁绊 (SummonCount)】的多次触发加成。 */ private static handleCall(model: HeroAttrsComp, view: HeroViewComp) { - if (!model.call || model.call.length === 0) return; - + if (!model.runtime_call || model.runtime_call.length === 0) return; + let triggerCount = 1; // 仅英雄享受加成,怪物始终只触发 1 次 if (model.fac === FacSet.HERO) { triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.SummonCount); } triggerCount = Math.max(1, Math.floor(triggerCount)); // 确保最少触发 1 次 - + for (let i = 0; i < triggerCount; i++) { - this.dispatchArray(model.call, model, view, SkillTriggerType.Call); + this.dispatchArray(model.runtime_call, model, view, SkillTriggerType.Call); } } @@ -80,18 +80,18 @@ export class SkillTriggerHelper { * 支持受【亡语强化羁绊 (DeadCount)】的多次触发加成。 */ private static handleDead(model: HeroAttrsComp, view: HeroViewComp) { - if (!model.dead || model.dead.length === 0) return; - + if (!model.runtime_dead || model.runtime_dead.length === 0) return; + let triggerCount = 1; if (model.fac === FacSet.HERO) { triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.DeadCount); // 【局内战绩评分系统】统计死亡触发技能生效次数(用于局后防守评分结算) - smc.vmdata.scores.dead_trigger_count += model.dead.length; + smc.vmdata.scores.dead_trigger_count += model.runtime_dead.length; } triggerCount = Math.max(1, Math.floor(triggerCount)); - + for (let i = 0; i < triggerCount; i++) { - this.dispatchArray(model.dead, model, view, SkillTriggerType.Dead); + this.dispatchArray(model.runtime_dead, model, view, SkillTriggerType.Dead); } } @@ -100,15 +100,15 @@ export class SkillTriggerHelper { * 判定逻辑:依据配置中的 t_num(触发所需普攻次数),对比当前的普攻累计次数取模判定。 */ private static handleAtking(model: HeroAttrsComp, view: HeroViewComp) { - if (!model.atking || model.atking.length === 0) return; - + if (!model.runtime_atking || model.runtime_atking.length === 0) return; + let triggerCount = 1; if (model.fac === FacSet.HERO) { triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.AtkCount); } triggerCount = Math.max(1, Math.floor(triggerCount)); - model.atking.forEach(atkConfig => { + model.runtime_atking.forEach(atkConfig => { // atk_count 代表已进行的普攻次数。当其余数刚好整除配置阈值时触发。 if (model.atk_count > 0 && model.atk_count % atkConfig.t_num === 0) { for (let i = 0; i < triggerCount; i++) { @@ -123,15 +123,15 @@ export class SkillTriggerHelper { * 判定逻辑:依据配置中的 t_num(触发所需受击次数),对比当前的受击累计次数取模判定。 */ private static handleAtked(model: HeroAttrsComp, view: HeroViewComp) { - if (!model.atked || model.atked.length === 0) return; - + if (!model.runtime_atked || model.runtime_atked.length === 0) return; + let triggerCount = 1; if (model.fac === FacSet.HERO) { triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.BeAtkCount); } triggerCount = Math.max(1, Math.floor(triggerCount)); - model.atked.forEach(atkConfig => { + model.runtime_atked.forEach(atkConfig => { // atked_count 代表已承受的受击次数。当其余数刚好整除配置阈值时触发。 if (model.atked_count > 0 && model.atked_count % atkConfig.t_num === 0) { for (let i = 0; i < triggerCount; i++) { @@ -144,7 +144,7 @@ export class SkillTriggerHelper { /** * 通用的数组型触发器处理(适用于 FStart / FEnd 等无需额外判定的简单列表触发) */ - private static handleArrayTrigger(configs: {s_uuid: number, t_num: number, overrides?: SkillOverrides}[] | undefined, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) { + private static handleArrayTrigger(configs: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[] | undefined, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) { if (!configs || configs.length === 0) return; this.dispatchArray(configs, model, view, type); } @@ -152,7 +152,7 @@ export class SkillTriggerHelper { /** * 批量派发技能事件 */ - private static dispatchArray(configs: {s_uuid: number, t_num?: number, overrides?: SkillOverrides}[], model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) { + private static dispatchArray(configs: { s_uuid: number, t_num?: number, overrides?: SkillOverrides }[], model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) { configs.forEach(config => this.dispatchSingle(config.s_uuid, model, view, type, config.overrides)); } diff --git a/assets/script/game/map/RogueConfig.ts b/assets/script/game/map/RogueConfig.ts index 0e4cbd2c..905fac97 100644 --- a/assets/script/game/map/RogueConfig.ts +++ b/assets/script/game/map/RogueConfig.ts @@ -304,14 +304,14 @@ export interface GeneratedMonster { /** 该波触发的波次强化 id 列表 */ wave_enchants: string[]; - /** 测试模式专用技能覆盖 */ + /** 测试模式专用技能覆盖(按 s_uuid 分组 + lv 数组,与 heroInfo 结构一致) */ testSkills?: { skill?: { s_uuid: number; cd?: number; overrides?: any }; - atking?: { s_uuid: number; t_num: number; overrides?: any }[]; - atked?: { s_uuid: number; t_num: number; overrides?: any }[]; - dead?: { s_uuid: number; t_num: number; overrides?: any }[]; - fstart?: { s_uuid: number; t_num: number; overrides?: any }[]; - fend?: { s_uuid: number; t_num: number; overrides?: any }[]; + atking?: Record; + atked?: Record; + dead?: Record; + fstart?: Record; + fend?: Record; }; } @@ -334,11 +334,11 @@ export const TestModeConfig = { testWaveEnchant: undefined as string | undefined, skill: undefined as { s_uuid: number; cd?: number; overrides?: any } | undefined, - atking: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined, - atked: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined, - dead: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined, - fstart: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined, - fend: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined, + atking: undefined as Record | undefined, + atked: undefined as Record | undefined, + dead: undefined as Record | undefined, + fstart: undefined as Record | undefined, + fend: undefined as Record | undefined, }; // ======================== 10. 生成引擎 ========================