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

@@ -52,7 +52,7 @@ import { MissSkillsComp } from "./MissSkillsComp";
import { oops } from "db://oops-framework/core/Oops";
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
import { smc } from "../common/SingletonModuleComp";
import { HeroInfo, HType, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv } from "../common/config/heroSet";
import { HeroInfo, HType, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, calcGrowBonus } from "../common/config/heroSet";
import { HeroViewComp } from "../hero/HeroViewComp";
import { FacSet, FightSet } from "../common/config/GameSet";
import { MissionEconomy } from "./MissionEconomy";
@@ -771,10 +771,7 @@ export class MissionCardComp extends CCComp {
if (!eid) return;
const actor = this.queryAliveHeroActors().find(item => item.eid === eid);
if (!actor) return;
if (actor.model.lv >= FightSet.HERO_MAX_LV) {
oops.gui.toast(`已达最高等级`);
return;
}
// 无限升级:不再拦截满级,仅校验金币
// 统一经济管理入口:按当前等级扣费
if (!MissionEconomy.executeUpgradeCost(actor.model.lv)) {
oops.gui.toast(`金币不足`);
@@ -2192,8 +2189,7 @@ export class MissionCardComp extends CCComp {
if (!heroEid) return false;
const actor = this.queryAliveHeroActors().find(item => item.eid === heroEid);
if (!actor) return false;
if (actor.model.lv >= FightSet.HERO_MAX_LV) return false;
const nextLv = Math.min(FightSet.HERO_MAX_LV, actor.model.lv + 1);
const nextLv = actor.model.lv + 1;
this.applyHeroLevel(actor.model, nextLv);
if (actor.view) {
actor.view.playBuff("buff_lvup");
@@ -2202,8 +2198,8 @@ export class MissionCardComp extends CCComp {
}
/**
* 应用英雄等级变化(属性按 HERO_LV_MULTIPLIER 重新计算)。
* 沿用旧版本 SkillLvUp 的技能等级映射规则。
* 应用英雄等级变化(属性 = 固定基础值 + grow_type 指数递增重新计算)。
* 沿用旧版本 SkillLvUp 的技能等级映射规则(技能按 HERO_SKILL_MAX_LV 封顶)
*
* 与 Hero.load 保持一致:
* 1. 同步刷新 base_ap/base_hp 快照,下游 UI/复活读到当前 lv 的基础值
@@ -2214,13 +2210,13 @@ export class MissionCardComp extends CCComp {
public applyHeroLevel(model: HeroAttrsComp, targetLv: number) {
const hero = HeroInfo[model.hero_uuid];
if (!hero) return;
const nextLv = Math.max(1, Math.min(FightSet.HERO_MAX_LV, Math.floor(targetLv)));
const nextLv = Math.max(1, Math.floor(targetLv));
const hpRate = model.hp_max > 0 ? model.hp / model.hp_max : 1;
model.lv = nextLv;
// 同步 base 快照(与 Hero.load 同公式),保证 UI/复活等下游读到当前 lv 的基础值
const base_ap = hero.ap * Math.pow(FightSet.HERO_LV_MULTIPLIER, nextLv - 1);
const base_hp = hero.hp * Math.pow(FightSet.HERO_LV_MULTIPLIER, nextLv - 1);
// 同步 base 快照(与 Hero.load 同公式:固定基础值,成长由 grow_type 指数递增提供)
const base_ap = hero.ap;
const base_hp = hero.hp;
model.base_ap = base_ap;
model.base_hp = base_hp;
@@ -2233,7 +2229,10 @@ export class MissionCardComp extends CCComp {
model.hp_max = base_hp;
}
// 按 ≤nextLv 累加 hp_bonus/ap_bonus沿用 Hero.load 的加法区规则)
// 按 ≤nextLv 累加:成长类型每级递增 + hp_bonus/ap_bonus 一次性奖励(沿用 Hero.load 的加法区规则)
const grow = calcGrowBonus(hero, nextLv);
model.hp_max += grow.hp;
model.ap += grow.ap;
if (model.hp_bonus) {
let hpExtra = 0;
for (const e of model.hp_bonus) { if (e.lv <= nextLv) hpExtra += e.value; }
@@ -2262,7 +2261,7 @@ export class MissionCardComp extends CCComp {
for (const key in hero.skills) {
const skill = hero.skills[key];
if (!skill) continue;
model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + nextLv - 2), ccd: 0 };
model.skills[skill.uuid] = { ...skill, lv: Math.min(FightSet.HERO_SKILL_MAX_LV, Math.max(0, skill.lv + nextLv - 2)), ccd: 0 };
}
model.updateSkillDistanceCache();
model.dirty_hp = true;