feat: 重构英雄成长系统,支持差异化成长曲线与无限升级

1. 新增英雄成长类型枚举与系数表,实现坦克/战士/刺客等差异化成长
2. 替换旧的固定指数成长逻辑,改用线性累计成长公式
3. 移除英雄等级上限,改为技能等级封顶,调整升级/出售金币计算逻辑
4. 重构属性计算与UI展示逻辑,统一成长计算入口
5. 优化技能文案展示与英雄配置格式
This commit is contained in:
panFD
2026-08-10 23:33:06 +08:00
parent d3ee664b00
commit 4eba1c8ad8
14 changed files with 3085 additions and 2624 deletions

View File

@@ -1,4 +1,4 @@
/**
/**
* @file HeroSkillDesc.ts
* @description 英雄技能/能力描述的【唯一文字表达标准层】
*
@@ -28,7 +28,7 @@
* - SkillDescSet:结构化描述模板
* - FieldSkillSet驻场技能、BuffList计时 buff 默认值兜底、Attrs属性枚举
*/
import { SkillTriggerName, SkillTriggerType, TriggerGrouped, LvTriggerEntry, LvFieldEntry, LvReviveEntry, LvBonusEntry, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, getTriggerSkillName } from "./heroSet";
import { SkillTriggerName, SkillTriggerType, TriggerGrouped, LvTriggerEntry, LvFieldEntry, LvReviveEntry, LvBonusEntry, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, getTriggerSkillName, HGrowType, calcGrowBonus } from "./heroSet";
import { FieldSkillSet, mergeSkillParams, SkillConfig, SkillKind, SkillOverrides, SkillSet, TGroup } from "./SkillSet";
import { FieldDescSet, FieldValueFmt, SkillDescSet } from "./SkillDescSet";
import { BuffList } from "./BuffSet";
@@ -53,6 +53,14 @@ export interface ISkillDescSource {
/** 额外攻击/生命加成(按 lv 累加,用于成长文案) */
ap_bonus?: LvBonusEntry[];
hp_bonus?: LvBonusEntry[];
/** 成长类型(决定每级 hp/ap 标准递增增量) */
grow_type?: HGrowType;
/** 基础攻击/生命(成长基数,线性公式 = 基础 × 系数 × (lv-1) */
ap?: number;
hp?: number;
/** 原始基础攻击/生命HeroAttrsComp 场景优先用作成长基数,避免运行时 hp/ap 重复计成长) */
base_ap?: number;
base_hp?: number;
}
/**
@@ -315,11 +323,16 @@ function buildReviveLines(source: ISkillDescSource, showName: boolean = true, sh
return lines;
}
/** 额外属性加成ap/hp累计结构化行高亮累计数值 */
/** 额外属性加成ap/hp累计结构化行成长递增 + 一次性奖励,高亮累计数值 */
function buildEvolveBonusLines(source: ISkillDescSource): ISkillLine[] {
const lv = Math.max(1, source.lv ?? 1);
let apTotal = 0;
let hpTotal = 0;
// 成长线性增量优先用原始基础值base_*HeroAttrsComp 场景),否则用配置 hp/ap
// 缺基础值时按 0 处理(如纯触发技能描述场景),避免运行时 hp/ap 重复计成长
const baseHp = source.base_hp ?? source.hp ?? 0;
const baseAp = source.base_ap ?? source.ap ?? 0;
const grow = calcGrowBonus({ hp: baseHp, ap: baseAp, grow_type: source.grow_type }, lv);
let apTotal = grow.ap;
let hpTotal = grow.hp;
if (source.ap_bonus) {
for (const e of source.ap_bonus) { if (e.lv <= lv) apTotal += e.value; }
}
@@ -327,8 +340,8 @@ function buildEvolveBonusLines(source: ISkillDescSource): ISkillLine[] {
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] ?? "攻击力" });
if (hpTotal !== 0) lines.push({ prefix: "成长:额外", value: `+${hpTotal}`, suffix: ATTR_NAME[Attrs.hp_max] ?? "最大生命" });
if (apTotal !== 0) lines.push({ prefix: "成长:", value: `+${apTotal}`, suffix: ATTR_NAME[Attrs.ap] ?? "攻击力" });
if (hpTotal !== 0) lines.push({ prefix: "成长:", value: `+${hpTotal}`, suffix: ATTR_NAME[Attrs.hp_max] ?? "最大生命" });
return lines;
}