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

@@ -18,7 +18,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { oops } from "db://oops-framework/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
import { HeroInfo } from "../common/config/heroSet";
import { HeroInfo, calcGrowBonus } from "../common/config/heroSet";
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
import { Hero } from "../hero/Hero";
import { FacSet, FightSet, getLvColor, NumberFormatter } from "../common/config/GameSet";
@@ -165,11 +165,7 @@ export class HeroBoxComp extends CCComp {
private onUpgradeHeroClick() {
if (!this.eid || !this.model) return;
const heroLv = Math.max(1, Math.floor(this.model.lv ?? 1));
// 已满级:气泡提示,复用英雄栏 smalltip 挂载点
if (heroLv >= FightSet.HERO_MAX_LV) {
oops.message.dispatchEvent(GameEvent.ShowSmallTip, { type: "hero_full", text: "已达最高等级" });
return;
}
// 无限升级:不再拦截满级
oops.audio.playEffect("music/button");
const nextLv = heroLv + 1;
@@ -226,13 +222,16 @@ export class HeroBoxComp extends CCComp {
atked: hero.atked,
field: hero.field,
revive: hero.revive,
grow_type: hero.grow_type,
ap: hero.ap,
hp: hero.hp,
});
// ---- 属性成长(按 HERO_LV_MULTIPLIER 幂成长 + 等级额外加成) ----
// ---- 属性成长(固定基础值 + 成长类型指数递增 + 一次性加成) ----
const attrLine = (lv: number): string => {
const mult = Math.pow(FightSet.HERO_LV_MULTIPLIER, lv - 1);
const ap = Math.floor(hero.ap * mult + HeroBoxComp.sumBonus(hero.ap_bonus, lv));
const hp = Math.floor(hero.hp * mult + HeroBoxComp.sumBonus(hero.hp_bonus, lv));
const grow = calcGrowBonus(hero, lv);
const ap = Math.floor(hero.ap + grow.ap + HeroBoxComp.sumBonus(hero.ap_bonus, lv));
const hp = Math.floor(hero.hp + grow.hp + HeroBoxComp.sumBonus(hero.hp_bonus, lv));
return `攻击 <color=#27AE60>${ap}</color> 生命 <color=#27AE60>${hp}</color>`;
};
@@ -548,17 +547,13 @@ export class HeroBoxComp extends CCComp {
this.sell_price_label.string = `${MissionEconomy.getSellGold(lv)}`;
}
// ---- 升级费用(满级隐藏;金币不足时标红提示) ----
// ---- 升级费用(无限升级:始终显示;金币不足时标红提示) ----
if (this.upgrade_price_label && this.upgrade_price_label.isValid) {
const lv = Math.max(1, Math.floor(this.model.lv ?? 1));
if (lv >= FightSet.HERO_MAX_LV) {
this.upgrade_price_label.string = "";
} else {
const cost = MissionEconomy.getUpgradeCost(lv);
this.upgrade_price_label.string = `${cost}`;
// 金币不足标红,足够恢复默认色,给玩家直观的可升级反馈
this.upgrade_price_label.color = MissionEconomy.getCoin() >= cost ? Color.WHITE : HeroBoxComp.INSUFFICIENT_COLOR;
}
const cost = MissionEconomy.getUpgradeCost(lv);
this.upgrade_price_label.string = `${cost}`;
// 金币不足标红,足够恢复默认色,给玩家直观的可升级反馈
this.upgrade_price_label.color = MissionEconomy.getCoin() >= cost ? Color.WHITE : HeroBoxComp.INSUFFICIENT_COLOR;
}
// ---- AP / HP ----