refactor(hero): 重构英雄等级升级逻辑,对齐英雄加载行为

1. 将英雄等级升级的属性计算逻辑与Hero.load保持一致,新增base属性快照
2. 新增对加成属性按等级累加的处理
3. 重新解析各触发/光环/复活技能的运行时缓存
4. 调整英雄升级倍率为2,优化英雄养成节奏
5. 调整英雄头像预制体的UI布局尺寸与偏移

fix: 修正战斗属性计算与技能缓存不一致的问题
This commit is contained in:
pan
2026-08-06 15:55:31 +08:00
parent 407973655a
commit 2273aeaf01
3 changed files with 107 additions and 63 deletions

View File

@@ -33,7 +33,7 @@ export enum FightSet {
/** 英雄可升级到的最高等级(通过升级卡提升) */
HERO_MAX_LV = 6,
/** 英雄属性随等级成长的倍率ap/hp = base * MULTIPLIER^(lv-1) */
HERO_LV_MULTIPLIER = 3,
HERO_LV_MULTIPLIER = 2,
// BACK_RANG=30,//后退范围
BACK_RANG = 30,//后退范围
FiIGHT_TIME = 30,//战斗时间

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 } from "../common/config/heroSet";
import { HeroInfo, HType, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv } from "../common/config/heroSet";
import { HeroViewComp } from "../hero/HeroViewComp";
import { FacSet, FightSet } from "../common/config/GameSet";
import { MissionEconomy } from "./MissionEconomy";
@@ -2038,6 +2038,12 @@ export class MissionCardComp extends CCComp {
/**
* 应用英雄等级变化(属性按 HERO_LV_MULTIPLIER 重新计算)。
* 沿用旧版本 SkillLvUp 的技能等级映射规则。
*
* 与 Hero.load 保持一致:
* 1. 同步刷新 base_ap/base_hp 快照,下游 UI/复活读到当前 lv 的基础值
* 2. 走 getRuntimeAp/getRuntimeHp 应用驻场光环乘区
* 3. 重新解析 runtime_* 触发缓存与光环/复活,避免升级后停在旧等级快照
* 4. 按 ≤nextLv 累加 hp_bonus/ap_bonus
*/
public applyHeroLevel(model: HeroAttrsComp, targetLv: number) {
const hero = HeroInfo[model.hero_uuid];
@@ -2045,9 +2051,47 @@ export class MissionCardComp extends CCComp {
const nextLv = Math.max(1, Math.min(FightSet.HERO_MAX_LV, Math.floor(targetLv)));
const hpRate = model.hp_max > 0 ? model.hp / model.hp_max : 1;
model.lv = nextLv;
model.ap = hero.ap * Math.pow(FightSet.HERO_LV_MULTIPLIER, nextLv - 1);
model.hp_max = hero.hp * Math.pow(FightSet.HERO_LV_MULTIPLIER, nextLv - 1);
// 同步 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);
model.base_ap = base_ap;
model.base_hp = base_hp;
// 走驻场光环乘区,与 Hero.load 行为一致;怪物保持基础值
if (model.fac === FacSet.HERO) {
model.ap = model.getRuntimeAp(base_ap);
model.hp_max = model.getRuntimeHp(base_hp);
} else {
model.ap = base_ap;
model.hp_max = base_hp;
}
// 按 ≤nextLv 累加 hp_bonus/ap_bonus沿用 Hero.load 的加法区规则)
if (model.hp_bonus) {
let hpExtra = 0;
for (const e of model.hp_bonus) { if (e.lv <= nextLv) hpExtra += e.value; }
model.hp_max += hpExtra;
}
if (model.ap_bonus) {
let apExtra = 0;
for (const e of model.ap_bonus) { if (e.lv <= nextLv) apExtra += e.value; }
model.ap += apExtra;
}
// 血量按当前血线比例映射到新上限,保留升级前战斗状态
model.hp = Math.max(1, Math.floor(model.hp_max * Math.max(0, Math.min(1, hpRate))));
// 重新解析触发技能/驻场光环/复活到运行时缓存(与 Hero.load 对齐)
model.runtime_call = resolveTriggerByLv(model.call, nextLv);
model.runtime_dead = resolveTriggerByLv(model.dead, nextLv);
model.runtime_fstart = resolveTriggerByLv(model.fstart, nextLv);
model.runtime_fend = resolveTriggerByLv(model.fend, nextLv);
model.runtime_atking = resolveTriggerByLv(model.atking, nextLv);
model.runtime_atked = resolveTriggerByLv(model.atked, nextLv);
model.runtime_field = resolveFieldByLv(model.field, nextLv);
model.runtime_revive = resolveReviveByLv(model.revive, nextLv);
model.skills = {};
for (const key in hero.skills) {
const skill = hero.skills[key];