refactor(hero): 新增英雄技能文案生成模块HeroSkillText
1. 新增HeroSkillText.ts,实现基于内联模板的实时技能文案渲染,解决数值与文案不同步问题 2. 为HSkillInfo、LvSkillEntry、LvTriggerEntry新增desc模板字段,配置技能描述模板 3. 重构HeroSkillDesc.ts,新增buildEffectOnlyRich方法,兼容旧UI引用 4. 为所有英雄配置添加技能描述模板,替换原硬编码文案逻辑
This commit is contained in:
415
assets/script/game/common/HeroSkillText.ts
Normal file
415
assets/script/game/common/HeroSkillText.ts
Normal 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");
|
||||
}
|
||||
@@ -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 为生效数值)
|
||||
|
||||
@@ -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%
|
||||
|
||||
Reference in New Issue
Block a user