refactor(hero): 新增英雄技能文案生成模块HeroSkillText

1.  新增HeroSkillText.ts,实现基于内联模板的实时技能文案渲染,解决数值与文案不同步问题
2.  为HSkillInfo、LvSkillEntry、LvTriggerEntry新增desc模板字段,配置技能描述模板
3.  重构HeroSkillDesc.ts,新增buildEffectOnlyRich方法,兼容旧UI引用
4.  为所有英雄配置添加技能描述模板,替换原硬编码文案逻辑
This commit is contained in:
pan
2026-08-27 20:40:53 +08:00
parent 434ab91f81
commit d929a99172
3 changed files with 497 additions and 44 deletions

View File

@@ -0,0 +1,415 @@
/**
* @file HeroSkillText.ts
* @description 英雄技能文案生成器(heroInfo 内联描述模板驱动)
*
* 与 HeroSkillDesc(SkillDescSet 中央模板表)并列的新一代文案层:
* - 描述模板直接配置在 heroInfo(HSkillInfo.desc / LvSkillEntry.desc / LvTriggerEntry.desc),
* "同一底座技能、不同英雄语境"的表述差异在英雄配置处表达;
* - 数值永远从 mergeSkillParams 合并后的实时配置取值(占位符渲染),
* 改 overrides 数值文案自动同步,杜绝"改数值忘改文案"漂移;
* - 英雄当前等级取自 SingletonModuleComp 的局外成长等级(smc.getHeroOuterLv)。
*
* 两个输出(均为富文本 BBCode,RichText 直接可用):
* 1. buildHeroSkillDesc(heroUuid) —— 当前局外等级下各技能最大生效档的完整说明
* 2. buildHeroSkillTierDesc(heroUuid, skillUuid) —— 指定技能各阶段说明:
* slv1 给完整能力 + 激活英雄等级;slv2+ 给相对上一级的提升 + 解锁英雄等级
*
* 占位符规范(模板作者可用,渲染时数值片段自动绿色高亮):
* {target} 目标语义(自身/敌方/全体友方/N名队友…,与 SCastSystem 目标选取一致)
* {dur} 计时 buff 持续秒数(buff_duration 优先,回退 BuffList 默认)
* {buff_value} 计时 buff 修饰数值(tick 类取绝对值展示,modifiers 类保留正负号)
* {字段名} 合并后技能配置数值(ap/para/frz/stun/crt/bck/hit_count/num/summon_count…)
*
* 依赖:heroSet(配置与 resolver)、SkillSet/BuffSet/SkillDescSet(底座)、smc(局外等级)。
* HeroSkillDesc.ts 暂时保留兼容旧 UI 引用,待迁移完成后移除。
*/
import {
HeroInfo, SkillTriggerType, SkillTriggerName, HSkillInfo, LvSkillEntry, LvTriggerEntry,
TriggerGrouped, resolveSkillOverrides, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv,
getGroupedTriggerName, getFieldSkillName, getReviveSkillName,
} from "./config/heroSet";
import { SkillSet, mergeSkillParams, SkillConfig, SkillKind, TGroup, FieldSkillSet } from "./config/SkillSet";
import { BuffList } from "./config/BuffSet";
import { FieldDescSet, FieldValueFmt } from "./config/SkillDescSet";
import { FacSet } from "./config/GameSet";
import { smc } from "./SingletonModuleComp";
/* ==================== 富文本片段(与 HeroSkillDesc 同配色,保证新旧面板视觉一致) ==================== */
/** 富文本数值高亮色(鲜亮绿色) */
const RICH_VALUE_COLOR = "#3CE66E";
/** 数值描边色(深绿,衬托亮绿填充) */
const RICH_VALUE_OUTLINE = "#145A32";
/** 技能名高亮色(蜜桃橙) */
const RICH_NAME_COLOR = "#F8C471";
/** 技能名描边色(深褐) */
const RICH_NAME_OUTLINE = "#6E2C00";
/** 数值富文本片段:亮绿填充 + 深绿描边 */
function valueRich(text: string | number): string {
return `<outline color=${RICH_VALUE_OUTLINE} width=1><color=${RICH_VALUE_COLOR}>${text}</color></outline>`;
}
/** 技能名富文本片段:「技能名」蜜桃橙填充 + 深褐描边 */
function skillNameRich(name: string): string {
return `<outline color=${RICH_NAME_OUTLINE} width=1><color=${RICH_NAME_COLOR}>「${name}」</color></outline>`;
}
/* ==================== 模板渲染基础 ==================== */
/** 需要遍历的触发技能类型(field/revive 结构不同,单独处理) */
const TRIGGER_KEYS: SkillTriggerType[] = [
SkillTriggerType.Call,
SkillTriggerType.Dead,
SkillTriggerType.FStart,
SkillTriggerType.Atking,
SkillTriggerType.Atked,
];
/** 占位符模式:{target}/{dur}/{buff_value}/{技能字段名} */
const PLACEHOLDER_PATTERN = /\{(\w+)\}/g;
/**
* 解析目标描述文本(与战斗 SCastSystem 目标选取语义严格一致)
*/
function buildTargetDesc(skill: SkillConfig): string {
switch (skill.TGroup) {
case TGroup.Self:
return "自身";
case TGroup.Enemy:
return "敌方";
case TGroup.Ally:
case TGroup.All:
return "全体友方";
case TGroup.Team: {
const n = Math.max(1, Math.floor(skill.hit_count ?? 1));
// 治疗类命中低血量队友
if (skill.kind === SkillKind.Heal) {
return n > 1 ? `${n}名低血量队友` : "低血量队友";
}
return `${n}名队友`;
}
default:
return "全体友方";
}
}
/** 计时 buff 生效时长(overrides.buff_duration 优先,回退 BuffList 默认) */
function getBuffDuration(skill: SkillConfig): number {
if (skill.timed_buff_id === undefined) return 0;
return skill.buff_duration ?? BuffList[skill.timed_buff_id]?.duration ?? 0;
}
/** 计时 buff 修饰数值(tick 类伤害取绝对值展示;modifiers 类保留正负号表达增减) */
function getBuffValue(skill: SkillConfig): number {
if (skill.timed_buff_id === undefined) return skill.buff_value ?? 0;
if (skill.buff_value !== undefined) return skill.buff_value;
const buff = BuffList[skill.timed_buff_id];
if (!buff) return 0;
if (buff.modifiers?.length) return buff.modifiers[0].value;
if (buff.tick) return Math.abs(buff.tick.damage_or_heal);
return 0;
}
/**
* 渲染 heroInfo 内联描述模板:数值占位符替换为合并后配置实时值并绿色高亮。
* Why: 数值不写死在模板里,overrides 调整档位数值时文案自动同步。
* @param tmpl 描述模板(含占位符)
* @param skill mergeSkillParams 合并后的技能配置
*/
function renderDesc(tmpl: string, skill: SkillConfig): string {
return tmpl.replace(PLACEHOLDER_PATTERN, (raw, key: string) => {
if (key === "target") return buildTargetDesc(skill);
if (key === "dur") return valueRich(getBuffDuration(skill));
if (key === "buff_value") return valueRich(getBuffValue(skill));
const v = (skill as unknown as Record<string, unknown>)[key];
// 未定义数值字段按 0 渲染,避免面板出现 undefined(模板与配置不匹配的兜底)
return v === undefined ? valueRich(0) : valueRich(String(v));
});
}
/** 无模板时兜底:回退底座技能的 info 备注 */
function fallbackDesc(skill: SkillConfig): string {
return String(skill.info ?? "");
}
/** 取英雄展示等级:英雄用局外成长等级(smc),怪物无成长直接用配置 lv */
function getHeroDisplayLv(heroUuid: number, configLv: number, fac: FacSet): number {
if (fac !== FacSet.HERO) return Math.max(1, configLv);
return Math.max(1, smc.getHeroOuterLv(heroUuid));
}
/* ==================== 输出一:当前等级最大生效档说明 ==================== */
/**
* 输出一:英雄当前局外等级下,全部技能最大生效档的完整说明(富文本)。
*
* 覆盖:普攻/大招(skills,resolve ≤lv 最大档)、5 类触发技能、驻场光环(field)、
* 复活(revive)。每行 = 「技能名」+ 触发语境 + 模板渲染后的效果文本(数值高亮)。
*
* @param heroUuid 英雄 uuid(HeroInfo key)
* @param showName 是否包含「技能名」片段(面板 true,紧凑卡片 false)
* @returns 多行富文本串,\n 分隔;英雄不存在时返回 ""
*/
export function buildHeroSkillDesc(heroUuid: number, showName: boolean = true): string {
const hero = HeroInfo[heroUuid];
if (!hero) return "";
const lv = getHeroDisplayLv(heroUuid, hero.lv, hero.fac);
const lines: string[] = [];
const nameSeg = (n: string) => (showName && n ? `${skillNameRich(n)} ` : "");
// ---- 普攻/大招(skills):resolve 当前等级生效档,渲染该档模板 ----
for (const key in hero.skills) {
const hSkill = hero.skills[key];
if (!hSkill) continue;
const base = SkillSet[hSkill.uuid];
if (!base) continue;
const skill = mergeSkillParams(base, resolveSkillOverrides(hSkill, lv));
// 生效档(≤lv 最大档):取其 s_lv 与 desc;未配置 desc 的档位继承上一档模板
let entry: LvSkillEntry | undefined;
let inheritDesc = hSkill.desc;
for (const e of hSkill.lv_entries ?? []) {
if (e.lv <= lv) {
if (!entry || e.lv > entry.lv) entry = e;
if (e.desc) inheritDesc = e.desc;
}
}
const sLv = entry?.s_lv ?? hSkill.lv;
const text = inheritDesc ? renderDesc(inheritDesc, skill) : fallbackDesc(skill);
lines.push(`${nameSeg(hSkill.name ?? base.name)}Lv.${valueRich(sLv)}: ${text}`);
}
// ---- 5 类标准触发技能:resolve 当前等级生效档 ----
for (const type of TRIGGER_KEYS) {
const grouped = hero[type] as TriggerGrouped | undefined;
if (!grouped) continue;
for (const item of resolveTriggerByLv(grouped, lv)) {
const base = SkillSet[item.s_uuid];
if (!base) continue;
const skill = mergeSkillParams(base, item.overrides);
// 档位模板继承链:组内 ≤lv 档依次覆盖(后配置的生效),缺省回退第 1 档
const entries = grouped[item.s_uuid] ?? [];
let tmpl: string | undefined;
for (const e of entries) {
if (e.lv <= lv && e.desc) tmpl = e.desc;
}
tmpl = tmpl ?? entries[0]?.desc;
const text = tmpl ? renderDesc(tmpl, skill) : fallbackDesc(skill);
// 进击/受击带触发次数,拼为"攻击3次";其余用触发类型简称
const trig = type === SkillTriggerType.Atking || type === SkillTriggerType.Atked
? `${SkillTriggerName[type]}${valueRich(item.t_num)}次`
: SkillTriggerName[type];
lines.push(`${nameSeg(getGroupedTriggerName(grouped, item.s_uuid))}${trig}, ${text}`);
}
}
// ---- 驻场光环(field):查 FieldDescSet 按 type 渲染,数值实时高亮 ----
for (const entry of resolveFieldByLv(hero.field, lv)) {
const fs = FieldSkillSet[entry.uuid];
const desc = fs ? FieldDescSet[fs.type] : undefined;
if (!fs || !desc) continue;
const val = desc.fmt === FieldValueFmt.Percent
? `+${Math.round(entry.value * 100)}%`
: desc.fmt === FieldValueFmt.IntMinus ? `-${entry.value}` : `+${entry.value}`;
lines.push(`${nameSeg(getFieldSkillName(entry.uuid))}${desc.verb}${valueRich(val)}`);
}
// ---- 复活(revive):次数复刻战斗公式 r_num + floor((lv-1)*upr) ----
const revive = resolveReviveByLv(hero.revive, lv);
if (revive) {
const count = revive.r_num + Math.floor((lv - 1) * revive.upr);
const hpPct = SkillSet[revive.s_uuid]?.ap ?? 0;
lines.push(`${nameSeg(getReviveSkillName())}每回合可复活${valueRich(count)}次, 死亡后以${valueRich(`${Math.round(hpPct)}%`)}生命原地重生`);
}
return lines.join("\n");
}
/* ==================== 输出二:指定技能各阶段(分档)说明 ==================== */
/** 一个技能等级档位的统一结构(普攻 lv_entries 与触发技能 LvTriggerEntry 归一) */
interface ISkillTierInfo {
/** 技能等级(展示用,取 s_lv,缺省按档位序号) */
sLv: number;
/** 该档生效的英雄等级(激活/解锁提示) */
heroLv: number;
/** 合并底座后的完整技能配置 */
skill: SkillConfig;
/** 该档描述模板(继承链解析后) */
desc?: string;
/** 触发技能档位的触发次数(普攻无) */
tNum: number;
}
/** 相邻档 diff 参与展示的字段(排除动画/弹道/特效等玩家无感字段),t_num 为触发技能专有 */
const DIFF_KEYS: string[] = [
"ap", "hit_count", "num", "summon_count", "crt", "frz", "stun", "para",
"bck", "bck_chance", "buff_duration", "buff_value", "t_num", "timed_buff_id",
];
/** diff 字段的称谓与单位("新增/漂移"描述共用) */
const DIFF_META: Record<string, { label: string; unit: string }> = {
ap: { label: "伤害", unit: "%" },
hit_count: { label: "命中", unit: "次" },
num: { label: "双发", unit: "次" },
summon_count: { label: "召唤数", unit: "" },
crt: { label: "暴击", unit: "%" },
frz: { label: "冰冻", unit: "%" },
stun: { label: "击晕", unit: "%" },
para: { label: "麻痹", unit: "%" },
bck: { label: "击退", unit: "" },
bck_chance: { label: "击退概率", unit: "%" },
buff_duration: { label: "持续", unit: "秒" },
buff_value: { label: "增益强度", unit: "" },
t_num: { label: "触发次数", unit: "次" },
};
/** 读取档位某展示字段的实时值(t_num/buff_value 走专用取值) */
function getTierValue(tier: ISkillTierInfo, key: string): number {
if (key === "t_num") return tier.tNum;
if (key === "buff_value") return getBuffValue(tier.skill);
const v = (tier.skill as unknown as Record<string, unknown>)[key];
return typeof v === "number" ? v : 0;
}
/**
* 相邻两档 diff:数值漂移(差值)+ 新功能(上级为 0 本级新增)+ 计时 buff 增减。
* Why: slv2+ 只描述"多得到了什么",让玩家一眼看清每级提升。
*/
function buildTierDiff(prev: ISkillTierInfo, cur: ISkillTierInfo): string[] {
const parts: string[] = [];
for (const key of DIFF_KEYS) {
// 计时 buff 增减单独处理:展示 buff 名而非内部 id
if (key === "timed_buff_id") {
const pb = prev.skill.timed_buff_id ?? 0;
const cb = cur.skill.timed_buff_id ?? 0;
if (pb === cb) continue;
if (!pb && cb) parts.push(`新增${valueRich(BuffList[cb]?.name ?? "计时增益")}`);
else if (pb && !cb) parts.push(`移除${valueRich(BuffList[pb]?.name ?? "计时增益")}`);
else parts.push(`${valueRich(BuffList[pb]?.name ?? "计时增益")}→${valueRich(BuffList[cb]?.name ?? "计时增益")}`);
continue;
}
const meta = DIFF_META[key];
if (!meta) continue;
const pv = getTierValue(prev, key);
const cv = getTierValue(cur, key);
if (cv === pv) continue;
if (pv === 0 && cv > 0) {
parts.push(`新增${meta.label}${valueRich(`${cv}${meta.unit}`)}`);
} else {
const d = cv - pv;
parts.push(`${meta.label}${valueRich(`${d > 0 ? "+" : ""}${d}${meta.unit}`)}`);
}
}
return parts;
}
/** 收集普攻/大招(skills)的全部等级档位(slv 升序,模板走继承链) */
function collectSkillTiers(hSkill: HSkillInfo): ISkillTierInfo[] {
const base = SkillSet[hSkill.uuid];
if (!base) return [];
const entries = [...(hSkill.lv_entries ?? [])].sort((a, b) => (a.s_lv ?? 0) - (b.s_lv ?? 0));
const tiers: ISkillTierInfo[] = [];
// slv1 = 基础档(底座 + 基础 overrides),激活等级取 s_lv≤1 档的 lv(缺省 1)
const lv1 = entries.find(e => (e.s_lv ?? 0) <= 1);
tiers.push({
sLv: lv1?.s_lv ?? 1,
heroLv: lv1?.lv ?? 1,
skill: mergeSkillParams(base, hSkill.overrides),
desc: lv1?.desc ?? hSkill.desc,
tNum: 0,
});
// slv2+ = lv_entries 各档(与基础 overrides 浅合并,档位字段优先)
for (const e of entries) {
if ((e.s_lv ?? 0) < 2) continue;
tiers.push({
sLv: e.s_lv ?? 0,
heroLv: e.lv,
skill: mergeSkillParams(mergeSkillParams(base, hSkill.overrides), e.overrides),
desc: e.desc,
tNum: 0,
});
}
// 模板继承链:未配置 desc 的档位沿用上一档模板(机制不变仅数值变化的档位免配)
let inherit: string | undefined;
for (const t of tiers) {
if (t.desc) inherit = t.desc;
else t.desc = inherit;
}
return tiers;
}
/**
* 输出二:指定技能的各阶段说明(富文本)。
*
* 输出结构(按技能等级升序,通用支持任意档数):
* - slv1:完整能力 + 数值 +(英雄X级激活)
* - slv2+:相对上一级的提升(数值漂移/新增效果/计时 buff 增减)+(英雄Y级解锁)
*
* 技能定位顺序:hero.skills[skillUuid](普攻/大招)→ 5 类触发技能组 → 未找到返回 ""。
* Why: 同一底座技能可能被多个英雄以不同 overrides 引用,必须以英雄语境取档。
*
* @param heroUuid 英雄 uuid(HeroInfo key)
* @param skillUuid 技能 uuid(skills key 或触发组 s_uuid)
* @param showName 是否包含「技能名」片段
* @returns 多行富文本串,\n 分隔;技能不属于该英雄时返回 ""
*/
export function buildHeroSkillTierDesc(heroUuid: number, skillUuid: number, showName: boolean = true): string {
const hero = HeroInfo[heroUuid];
if (!hero) return "";
let name = "";
let tiers: ISkillTierInfo[] = [];
let triggerLabel = "";
const hSkill = hero.skills?.[skillUuid];
if (hSkill) {
// 普攻/大招路径
name = hSkill.name ?? SkillSet[skillUuid]?.name ?? "";
tiers = collectSkillTiers(hSkill);
} else {
// 触发技能路径:在 5 类触发组中定位 s_uuid
for (const type of TRIGGER_KEYS) {
const grouped = hero[type] as TriggerGrouped | undefined;
const entries = grouped?.[skillUuid];
if (!grouped || !entries?.length) continue;
const base = SkillSet[skillUuid];
if (!base) return "";
const sorted = [...entries].sort((a, b) => (a.s_lv ?? 0) - (b.s_lv ?? 0));
name = getGroupedTriggerName(grouped, skillUuid);
let inherit: string | undefined;
tiers = sorted.map((e: LvTriggerEntry, i: number) => {
if (e.desc) inherit = e.desc;
return {
sLv: e.s_lv ?? (i + 1),
heroLv: e.lv,
skill: mergeSkillParams(base, e.overrides),
desc: e.desc ?? inherit,
tNum: e.t_num,
};
});
triggerLabel = (type === SkillTriggerType.Atking || type === SkillTriggerType.Atked)
? `${SkillTriggerName[type]}${valueRich(sorted[0].t_num)}次`
: SkillTriggerName[type];
break;
}
}
if (tiers.length === 0) return "";
const nameSeg = showName && name ? `${skillNameRich(name)} ` : "";
const lines: string[] = [];
for (let i = 0; i < tiers.length; i++) {
const t = tiers[i];
const head = `${nameSeg}Lv.${valueRich(t.sLv)}(英雄${valueRich(t.heroLv)}级${i === 0 ? "激活" : "解锁"})`;
if (i === 0) {
// 技能 1 级:完整能力 + 数值(含激活英雄等级)
const text = t.desc ? renderDesc(t.desc, t.skill) : fallbackDesc(t.skill);
lines.push(`${head}: ${triggerLabel ? `${triggerLabel}, ` : ""}${text}`);
} else {
// 技能 2 级起:相对上一级的提升 + 解锁英雄等级
const diff = buildTierDiff(tiers[i - 1], t);
lines.push(`${head}: ${diff.length > 0 ? diff.join(",") : "无变化"}`);
}
}
return lines.join("\n");
}

View File

@@ -2,6 +2,11 @@
* @file HeroSkillDesc.ts
* @description 英雄技能/能力描述的【唯一文字表达标准层】
*
* @deprecated 已被 HeroSkillText.ts(heroInfo 内联 desc 模板驱动)取代。
* 本文件暂时保留兼容旧 UI 引用(HerosListComp/CHeroComp/HeroBoxComp/HeroMoreCom/
* SCardComp/ItemListComp/IBoxComp/EquipListComp/SinfoComp),待各面板迁移至
* buildHeroSkillDesc / buildHeroSkillTierDesc 后移除。新代码请勿再引用本模块。
*
* 设计目标:
* heroSet / SkillSet 中的 info / infos 仅作"基础备注",不再承担面板展示。
* 所有功能性描述(触发技能、驻场光环、复活、等级额外属性加成)统一由本模块
@@ -30,7 +35,7 @@
*/
import { SkillTriggerName, SkillTriggerType, TriggerGrouped, LvTriggerEntry, LvFieldEntry, LvReviveEntry, LvBonusEntry, FieldEntry, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, resolveSkillOverrides, getGroupedTriggerName, getFieldSkillName, getReviveSkillName, HGrowType, calcGrowBonus, HSkillInfo } from "./heroSet";
import { FieldSkillSet, mergeSkillParams, SkillConfig, SkillKind, SkillOverrides, SkillSet, TGroup } from "./SkillSet";
import { FieldDescSet, FieldValueFmt, SkillDescSet } from "./SkillDescSet";
import { FieldDescSet, FieldValueFmt, SkillDescSet, SkillDescConfig } from "./SkillDescSet";
import { BuffList } from "./BuffSet";
import { Attrs } from "./HeroAttrs";
import { CardConfig } from "./CardSet";
@@ -203,8 +208,8 @@ function makeLine(head: string, rendered: string): ISkillLine {
* overrides 仅给 timed_buff_id 而未覆写 buff_value / buff_duration 时,
* 从 BuffList[timed_buff_id] 取默认值,保证 1 级基础档文案完整。
*/
function buildEffectLine(head: string, skill: SkillConfig): ISkillLine {
const desc = SkillDescSet[skill.uuid];
function buildEffectLine(head: string, skill: SkillConfig, descOverride?: SkillDescConfig): ISkillLine {
const desc = descOverride ?? SkillDescSet[skill.uuid];
// 未入表技能回退基础备注 info,无法抽出数值,整行不高亮
if (!desc) return { prefix: `${head}${String(skill.info ?? "")}`, value: "", suffix: "" };
@@ -541,6 +546,24 @@ export function buildSingleSkillRich(skillUuid: number, overrides?: SkillOverrid
return cdTag ? `${nameTag} ${cdTag}\n${effect}` : `${nameTag}\n${effect}`;
}
/**
* 单个技能纯效果富文本(SInfo 提升面板用):不含技能名与 Lv 前缀,仅输出效果描述。
* @param skillUuid SkillSet 技能 UUID
* @param overrides 可选覆写参数
* @param desc 可选 SkillDescConfig(heroSet 技能项自带说明,优先于 SkillDescSet)
* @returns 单行富文本串:如 "造成攻击力<color=#27AE60>250%</color>的伤害"
*/
export function buildEffectOnlyRich(skillUuid: number, overrides?: SkillOverrides, desc?: SkillDescConfig): string {
const base = SkillSet[skillUuid];
if (!base) return "未知技能";
const skill = mergeSkillParams(base, overrides);
const line = buildEffectLine("", skill, desc);
const prefix = line.prefix.replace(SKILL_NAME_PATTERN, (m, g1) => skillNameRich(g1));
return line.value
? `${prefix}${valueRich(line.value)}${line.suffix}`
: `${prefix}${line.suffix}`;
}
/**
* 装备/驻场光环详情富文本:展示全部词条,数值绿色高亮。
* @param entries 驻场光环词条数组(uuid 指向 FieldSkillSet 底座,value 为生效数值)

View File

@@ -328,6 +328,8 @@ export interface HSkillInfo {
cd: number; // 技能cd
ccd: number; // 占位当前cd,用于cd计时
overrides?: SkillOverrides; // 角色专属参数覆盖(全等级生效,作为底)
/** 技能描述模板(基础档):占位符 {target}/{dur}/{技能字段名},由 HeroSkillText 渲染合并后实时数值 */
desc?: string;
lv_entries?: LvSkillEntry[]; // 按英雄等级分档(按 lv 升序,运行时取 ≤英雄等级 的最大档)
}
@@ -339,6 +341,8 @@ export interface LvSkillEntry {
lv: number; // 达到该英雄等级时此档生效
s_lv?: SkillLv; // 此档对应的技能等级(标注用)
overrides: SkillOverrides; // 此档注入的效果
/** 此档描述模板:缺省继承上一档模板;新增机制的档位(如附加中毒)需单独配置 */
desc?: string;
}
/**
@@ -351,6 +355,8 @@ export interface LvTriggerEntry {
name?: string; // 该 s_uuid 触发技能组的对外展示名(写在第 1 档,作为组名)
t_num: number;
overrides?: SkillOverrides;
/** 此档描述模板:缺省回退该组第 1 档 desc;由 HeroSkillText 渲染合并后实时数值 */
desc?: string;
}
/**
@@ -411,21 +417,22 @@ export const HeroInfo: Record<number, heroInfo> = {
uuid: 5001, name: "紫电魔女", path: "hm1", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: HERO_ROLE_BASE[HRole.Mage].hp - 5, ap: HERO_ROLE_BASE[HRole.Mage].ap + 10, def: HERO_ROLE_BASE[HRole.Mage].def,
skills: {
// 普攻:紫魔球底座 + overrides 注入麻痹
6010: { uuid: 6010, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100, para: 30 } },
6010: { uuid: 6010, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100, para: 30 }, desc: "掷出紫魔球,对{target}造成攻击力{ap}%伤害,{para}%概率麻痹目标" },
// 大招:大能量波,独立 cd,按英雄等级分档成长
6203: {
uuid: 6203, name: "能量波", lv: 1, cd: 8, ccd: 0,
overrides: { ap: 250, bck: 30, para: 40, summon_count: 1 },
desc: "释放{summon_count}道能量波,对{target}造成攻击力{ap}%伤害,击退{bck},{para}%概率麻痹",
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 250, bck: 60, para: 40, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 300, bck: 90, timed_buff_id: 7005, para: 50, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 400, timed_buff_id: 7025, para: 70, summon_count: 3 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 300, bck: 90, timed_buff_id: 7005, para: 50, summon_count: 2 }, desc: "释放{summon_count}道能量波,对{target}造成攻击力{ap}%伤害,击退{bck},{para}%概率麻痹,并使目标中毒(每0.5秒受到{buff_value}点毒伤,持续{dur}秒)" },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 400, timed_buff_id: 7025, para: 70, summon_count: 3 }, desc: "释放{summon_count}道能量波,对{target}造成攻击力{ap}%伤害,击退{bck},{para}%概率麻痹,并使目标麻痹{dur}秒(技能CD减速50%)" },
],
},
},
atking: {
6010: [
{ lv: 2, s_lv: SkillLv.Lv1, name: "雷霆万钧", t_num: 3, overrides: { para: 100 } },
{ lv: 2, s_lv: SkillLv.Lv1, name: "雷霆万钧", t_num: 3, overrides: { para: 100 }, desc: "释放紫魔球轰击{target},{para}%概率麻痹目标" },
],
},
field: [
@@ -437,21 +444,22 @@ export const HeroInfo: Record<number, heroInfo> = {
5002: {
uuid: 5002, name: "刀刀暴击", path: "hk2", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, hp: HERO_ROLE_BASE[HRole.Warrior].hp, ap: HERO_ROLE_BASE[HRole.Warrior].ap + 15, def: HERO_ROLE_BASE[HRole.Warrior].def,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, desc: "挥刀对{target}造成攻击力{ap}%伤害" },
// 大招:光闪,独立 cd,按英雄等级分档成长
6100: {
uuid: 6100, name: "光闪", lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150 },
desc: "斩出光闪,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7007 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, hit_count: 8, num: 1 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 360, bck: 50 } },
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7007 }, desc: "斩出光闪,对{target}造成攻击力{ap}%伤害,并使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, hit_count: 8, num: 1 }, desc: "斩出光闪,对{target}连击{hit_count}次,每次造成攻击力{ap}%伤害,并双发{num}次" },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 360, bck: 50 }, desc: "斩出光闪,对{target}造成攻击力{ap}%伤害,并击退{bck}" },
],
},
},
atking: {
6004: [
{ lv: 2, s_lv: SkillLv.Lv1, name: "致命节奏", t_num: 3, overrides: { crt: 30 } },
{ lv: 2, s_lv: SkillLv.Lv1, name: "致命节奏", t_num: 3, overrides: { crt: 30 }, desc: "释放斩击,{crt}%概率造成暴击" },
],
},
field: [
@@ -463,26 +471,27 @@ export const HeroInfo: Record<number, heroInfo> = {
5003: {
uuid: 5003, name: "格挡反杀", path: "hk4", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, hp: HERO_ROLE_BASE[HRole.Warrior].hp + 10, ap: HERO_ROLE_BASE[HRole.Warrior].ap + 5, def: HERO_ROLE_BASE[HRole.Warrior].def + 5,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, desc: "挥刀对{target}造成攻击力{ap}%伤害" },
// 大招:闪电斩,独立 cd,按英雄等级分档成长
6103: {
uuid: 6103, name: "闪电斩", lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150, para: 40, summon_count: 1 },
desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害,{para}%概率麻痹",
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7006, para: 40, summon_count: 1 } },
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7006, para: 40, summon_count: 1 }, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害,{para}%概率麻痹,并使目标攻击力{buff_value}%(持续{dur}秒)" },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, timed_buff_id: 7006, buff_value: -15, para: 50, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 200, hit_count: 6, bck: 40, para: 60, summon_count: 3 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 200, hit_count: 6, bck: 40, para: 60, summon_count: 3 }, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害(命中{hit_count}次),{para}%概率麻痹,击退{bck}" },
],
},
},
atked: {
6301: [
{ lv: 5, s_lv: SkillLv.Lv1, name: "罗生门", t_num: 4, overrides: { TGroup: TGroup.Self, ap: 2 } },
{ lv: 5, s_lv: SkillLv.Lv1, name: "罗生门", t_num: 4, overrides: { TGroup: TGroup.Self, ap: 2 }, desc: "{target}获得{ap}次格挡护盾" },
],
},
fstart: {
6200: [
{ lv: 2, s_lv: SkillLv.Lv1, name: "三十六烦恼凤", t_num: 1, overrides: { ap: 500 } },
{ lv: 2, s_lv: SkillLv.Lv1, name: "三十六烦恼凤", t_num: 1, overrides: { ap: 500 }, desc: "入场释放剑气,对{target}造成攻击力{ap}%伤害" },
],
},
field: [
@@ -494,21 +503,22 @@ export const HeroInfo: Record<number, heroInfo> = {
5004: {
uuid: 5004, name: "冻住不谢", path: "hm2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: HERO_ROLE_BASE[HRole.Mage].hp, ap: HERO_ROLE_BASE[HRole.Mage].ap + 5, def: HERO_ROLE_BASE[HRole.Mage].def + 5,
skills: {
6009: { uuid: 6009, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
6009: { uuid: 6009, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, desc: "射出寒冰珠,对{target}造成攻击力{ap}%伤害" },
// 大招:大能量波,独立 cd,按英雄等级分档成长
6203: {
uuid: 6203, name: "能量波", lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150, summon_count: 1 },
desc: "释放能量波,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, frz: 15, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, frz: 30, hit_count: 8, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 200, timed_buff_id: 7003, summon_count: 3 } },
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, frz: 15, summon_count: 1 }, desc: "释放能量波,对{target}造成攻击力{ap}%伤害,{frz}%概率冰冻" },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, frz: 30, hit_count: 8, summon_count: 2 }, desc: "释放能量波,对{target}造成攻击力{ap}%伤害,{frz}%概率冰冻,命中{hit_count}次" },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 200, timed_buff_id: 7003, summon_count: 3 }, desc: "释放{summon_count}道能量波,对{target}造成攻击力{ap}%伤害,并冰冻目标{dur}秒" },
],
},
},
atking: {
6009: [
{ lv: 2, s_lv: SkillLv.Lv1, name: "霜寒之触", t_num: 3, overrides: { timed_buff_id: 7003 } },
{ lv: 2, s_lv: SkillLv.Lv1, name: "霜寒之触", t_num: 3, overrides: { timed_buff_id: 7003 }, desc: "释放寒气,冰冻{target}{dur}秒" },
],
},
field: [
@@ -520,11 +530,12 @@ export const HeroInfo: Record<number, heroInfo> = {
5005: {
uuid: 5005, name: "叠甲骑士", path: "hk1", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, hp: HERO_ROLE_BASE[HRole.Tank].hp + 20, ap: HERO_ROLE_BASE[HRole.Tank].ap, def: HERO_ROLE_BASE[HRole.Tank].def + 10,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, desc: "挥剑对{target}造成攻击力{ap}%伤害" },
// 大招位辅助技能:护盾,按英雄等级分档成长(护盾层数)
6301: {
uuid: 6301, name: "叠甲", lv: 1, cd: 8, ccd: 0,
overrides: { TGroup: TGroup.Self, ap: 3, summon_count: 1 },
desc: "{target}获得{ap}次格挡护盾",
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { TGroup: TGroup.Self, ap: 5, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { TGroup: TGroup.Self, ap: 6, summon_count: 2 } },
@@ -534,17 +545,17 @@ export const HeroInfo: Record<number, heroInfo> = {
},
atked: {
6004: [
{ lv: 5, s_lv: SkillLv.Lv1, name: "反击减攻", t_num: 4, overrides: { timed_buff_id: 7006 } },
{ lv: 5, s_lv: SkillLv.Lv1, name: "反击减攻", t_num: 4, overrides: { timed_buff_id: 7006 }, desc: "反击使攻击者攻击力{buff_value}%,持续{dur}秒" },
],
},
fstart: {
6412: [
{ lv: 2, s_lv: SkillLv.Lv1, name: "铁壁壁垒", t_num: 1, overrides: { TGroup: TGroup.Team, ap: 50 } },
{ lv: 2, s_lv: SkillLv.Lv1, name: "铁壁壁垒", t_num: 1, overrides: { TGroup: TGroup.Team, ap: 50 }, desc: "{target}防御提升{ap}点" },
],
},
dead: {
6302: [
{ lv: 7, s_lv: SkillLv.Lv1, name: "死亡缠绕", t_num: 1, overrides: { TGroup: TGroup.Ally, ap: 200 } },
{ lv: 7, s_lv: SkillLv.Lv1, name: "死亡缠绕", t_num: 1, overrides: { TGroup: TGroup.Ally, ap: 200 }, desc: "死亡时为{target}回复攻击力{ap}%生命" },
],
},
field: [
@@ -560,26 +571,27 @@ export const HeroInfo: Record<number, heroInfo> = {
5006: {
uuid: 5006, name: "光明奶爸", path: "hh1", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Support, role: HRole.Support, hp: HERO_ROLE_BASE[HRole.Support].hp + 15, ap: HERO_ROLE_BASE[HRole.Support].ap, def: HERO_ROLE_BASE[HRole.Support].def + 10,
skills: {
6012: { uuid: 6012, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0 },
6012: { uuid: 6012, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0, desc: "投掷药瓶,对{target}造成攻击力{ap}%伤害" },
// 大招:治疗,独立 cd,按英雄等级分档成长
6302: {
uuid: 6302, name: "治疗", lv: 1, cd: 8, ccd: 0,
overrides: { TGroup: TGroup.Team, ap: 300, summon_count: 1 },
desc: "为{target}回复攻击力{ap}%生命",
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { TGroup: TGroup.Team, ap: 400, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { TGroup: TGroup.Team, ap: 450, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { TGroup: TGroup.Team, ap: 450, timed_buff_id: 7010, summon_count: 3 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { TGroup: TGroup.Team, ap: 450, timed_buff_id: 7010, summon_count: 3 }, desc: "为{target}回复攻击力{ap}%生命,并附加再生(每0.5秒回复{buff_value}点生命,持续{dur}秒)" },
],
},
},
atking: {
6302: [
{ lv: 5, s_lv: SkillLv.Lv1, name: "圣洁之锤", t_num: 3, overrides: { TGroup: TGroup.Self, ap: 100 } },
{ lv: 5, s_lv: SkillLv.Lv1, name: "圣洁之锤", t_num: 3, overrides: { TGroup: TGroup.Self, ap: 100 }, desc: "释放圣光,为{target}回复攻击力{ap}%生命" },
],
},
fstart: {
6412: [
{ lv: 2, s_lv: SkillLv.Lv1, name: "圣光庇佑", t_num: 1, overrides: { TGroup: TGroup.Team, ap: 30 } },
{ lv: 2, s_lv: SkillLv.Lv1, name: "圣光庇佑", t_num: 1, overrides: { TGroup: TGroup.Team, ap: 30 }, desc: "{target}防御提升{ap}点" },
],
},
field: [
@@ -591,21 +603,22 @@ export const HeroInfo: Record<number, heroInfo> = {
5007: {
uuid: 5007, name: "微醺战神", path: "hk3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, hp: HERO_ROLE_BASE[HRole.Tank].hp + 15, ap: HERO_ROLE_BASE[HRole.Tank].ap + 5, def: HERO_ROLE_BASE[HRole.Tank].def + 10,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, desc: "挥拳对{target}造成攻击力{ap}%伤害" },
// 大招:气斩,独立 cd,按英雄等级分档成长
6101: {
uuid: 6101, name: "气斩", lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150, summon_count: 1 },
desc: "斩出气刃,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7002, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, bck: 60, timed_buff_id: 7002, buff_value: 20, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 220, bck: 80, summon_count: 3 } },
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7002, summon_count: 1 }, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,并使目标易伤(受到伤害加深,持续{dur}秒)" },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, bck: 60, timed_buff_id: 7002, buff_value: 20, summon_count: 2 }, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,击退{bck},并使目标易伤(持续{dur}秒)" },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 220, bck: 80, summon_count: 3 }, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,击退{bck}" },
],
},
},
atking: {
6004: [
{ lv: 2, s_lv: SkillLv.Lv1, name: "雷霆一击", t_num: 3, overrides: { bck: 40 } },
{ lv: 2, s_lv: SkillLv.Lv1, name: "雷霆一击", t_num: 3, overrides: { bck: 40 }, desc: "重击{target},击退{bck}" },
],
},
// card_lv 3:lv9 无光环,改为基础属性+50%
@@ -617,21 +630,22 @@ export const HeroInfo: Record<number, heroInfo> = {
5008: {
uuid: 5008, name: "眩晕暴击哥", path: "hk5", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, hp: HERO_ROLE_BASE[HRole.Warrior].hp + 5, ap: HERO_ROLE_BASE[HRole.Warrior].ap + 20, def: HERO_ROLE_BASE[HRole.Warrior].def,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, desc: "挥斧对{target}造成攻击力{ap}%伤害" },
// 大招:开山斧,独立 cd,按英雄等级分档成长
6104: {
uuid: 6104, name: "开山斧", lv: 1, cd: 8, ccd: 0,
overrides: { ap: 300, summon_count: 1 },
desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 300, stun: 20, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 350, stun: 35, hit_count: 8, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 400, timed_buff_id: 7004, summon_count: 3 } },
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 300, stun: 20, summon_count: 1 }, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,{stun}%概率击晕" },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 350, stun: 35, hit_count: 8, summon_count: 2 }, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,{stun}%概率击晕,命中{hit_count}次" },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 400, timed_buff_id: 7004, summon_count: 3 }, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,并击晕目标{dur}秒" },
],
},
},
atking: {
6004: [
{ lv: 2, s_lv: SkillLv.Lv1, name: "火眼金睛", t_num: 3, overrides: { crt: 25 } },
{ lv: 2, s_lv: SkillLv.Lv1, name: "火眼金睛", t_num: 3, overrides: { crt: 25 }, desc: "释放斩击,{crt}%概率造成暴击" },
],
},
field: [
@@ -643,27 +657,28 @@ export const HeroInfo: Record<number, heroInfo> = {
5009: {
uuid: 5009, name: "铁壳斧弟", path: "hc1", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, hp: HERO_ROLE_BASE[HRole.Tank].hp + 10, ap: HERO_ROLE_BASE[HRole.Tank].ap + 5, def: HERO_ROLE_BASE[HRole.Tank].def + 15,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, desc: "挥斧对{target}造成攻击力{ap}%伤害" },
// 大招:气斩,独立 cd,按英雄等级分档成长
6101: {
uuid: 6101, name: "气斩", lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150, summon_count: 1 },
desc: "斩出气刃,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 180, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 200, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 220, bck: 40, summon_count: 3 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 220, bck: 40, summon_count: 3 }, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,击退{bck}" },
],
},
},
atking: {
6302: [
{ lv: 5, s_lv: SkillLv.Lv1, name: "嗜血战斧", t_num: 4, overrides: { TGroup: TGroup.Self, ap: 120 } },
{ lv: 5, s_lv: SkillLv.Lv1, name: "嗜血战斧", t_num: 4, overrides: { TGroup: TGroup.Self, ap: 120 }, desc: "释放嗜血斩击,为{target}回复攻击力{ap}%生命" },
],
},
atked: {
// 坚硬皮肤:借 6513 防御爆发底座注入 7023 防御强化(+50%,可无限叠层)
6513: [
{ lv: 2, s_lv: SkillLv.Lv1, name: "坚硬皮肤", t_num: 2, overrides: { TGroup: TGroup.Self, timed_buff_id: 7023, buff_duration: 10 } },
{ lv: 2, s_lv: SkillLv.Lv1, name: "坚硬皮肤", t_num: 2, overrides: { TGroup: TGroup.Self, timed_buff_id: 7023, buff_duration: 10 }, desc: "{target}防御提升{buff_value}%,持续{dur}秒" },
],
},
// card_lv 3:lv9 无光环,改为基础属性+50%