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

@@ -306,7 +306,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 90,
"width": 100,
"height": 115
}
},
@@ -326,7 +326,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 164,
"width": 184,
"height": 214
}
},
@@ -346,7 +346,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 222
}
},
@@ -366,7 +366,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 180,
"width": 200,
"height": 230
}
},
@@ -386,7 +386,7 @@
],
"value": {
"__type__": "cc.Vec3",
"x": -36.75,
"x": -41.75,
"y": 51.25,
"z": 0
}
@@ -407,7 +407,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 44
}
},
@@ -721,7 +721,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 90,
"width": 100,
"height": 115
}
},
@@ -741,7 +741,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 164,
"width": 184,
"height": 214
}
},
@@ -761,7 +761,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 222
}
},
@@ -781,7 +781,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 180,
"width": 200,
"height": 230
}
},
@@ -801,7 +801,7 @@
],
"value": {
"__type__": "cc.Vec3",
"x": -36.75,
"x": -41.75,
"y": 51.25,
"z": 0
}
@@ -816,7 +816,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 44
}
},
@@ -1130,7 +1130,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 90,
"width": 100,
"height": 115
}
},
@@ -1150,7 +1150,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 164,
"width": 184,
"height": 214
}
},
@@ -1170,7 +1170,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 222
}
},
@@ -1190,7 +1190,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 180,
"width": 200,
"height": 230
}
},
@@ -1210,7 +1210,7 @@
],
"value": {
"__type__": "cc.Vec3",
"x": -36.75,
"x": -41.75,
"y": 51.25,
"z": 0
}
@@ -1225,7 +1225,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 44
}
},
@@ -1539,7 +1539,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 90,
"width": 100,
"height": 115
}
},
@@ -1559,7 +1559,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 164,
"width": 184,
"height": 214
}
},
@@ -1579,7 +1579,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 222
}
},
@@ -1599,7 +1599,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 180,
"width": 200,
"height": 230
}
},
@@ -1619,7 +1619,7 @@
],
"value": {
"__type__": "cc.Vec3",
"x": -36.75,
"x": -41.75,
"y": 51.25,
"z": 0
}
@@ -1634,7 +1634,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 44
}
},
@@ -1948,7 +1948,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 90,
"width": 100,
"height": 115
}
},
@@ -1968,7 +1968,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 164,
"width": 184,
"height": 214
}
},
@@ -1988,7 +1988,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 222
}
},
@@ -2008,7 +2008,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 180,
"width": 200,
"height": 230
}
},
@@ -2028,7 +2028,7 @@
],
"value": {
"__type__": "cc.Vec3",
"x": -36.75,
"x": -41.75,
"y": 51.25,
"z": 0
}
@@ -2043,7 +2043,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 44
}
},
@@ -2357,7 +2357,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 90,
"width": 100,
"height": 115
}
},
@@ -2377,7 +2377,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 164,
"width": 184,
"height": 214
}
},
@@ -2397,7 +2397,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 222
}
},
@@ -2417,7 +2417,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 180,
"width": 200,
"height": 230
}
},
@@ -2437,7 +2437,7 @@
],
"value": {
"__type__": "cc.Vec3",
"x": -36.75,
"x": -41.75,
"y": 51.25,
"z": 0
}
@@ -2452,7 +2452,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 172,
"width": 192,
"height": 44
}
},
@@ -2476,7 +2476,7 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 90,
"width": 100,
"height": 115
},
"_anchorPoint": {
@@ -2612,7 +2612,7 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 160,
"width": 180,
"height": 117.72999999999998
},
"_anchorPoint": {
@@ -4416,7 +4416,7 @@
},
"_lpos": {
"__type__": "cc.Vec3",
"x": -15,
"x": -22.182,
"y": 0,
"z": 0
},
@@ -5793,13 +5793,13 @@
"__prefab": {
"__id__": 334
},
"_alignFlags": 13,
"_alignFlags": 21,
"_target": null,
"_left": 0,
"_right": 437.303,
"_top": -2.5,
"_bottom": -2.5,
"_horizontalCenter": 0,
"_horizontalCenter": -22.182,
"_verticalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
@@ -5882,7 +5882,7 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 230,
"width": 190,
"height": 40
},
"_anchorPoint": {
@@ -6212,7 +6212,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 175,
"width": 190,
"height": 60
}
},
@@ -6232,7 +6232,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 175,
"width": 190,
"height": 60
}
},
@@ -6252,7 +6252,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 167,
"width": 182,
"height": 48
}
},
@@ -6272,7 +6272,7 @@
],
"value": {
"__type__": "cc.Vec3",
"x": -77.5,
"x": -85,
"y": 20.5,
"z": 0
}
@@ -6486,7 +6486,7 @@
"propertyPath": [
"_left"
],
"value": 39.4384765625
"value": 46.9384765625
},
{
"__type__": "CCPropertyOverrideInfo",
@@ -6496,7 +6496,7 @@
"propertyPath": [
"_right"
],
"value": 39.4384765625
"value": 46.9384765625
},
{
"__type__": "CCPropertyOverrideInfo",
@@ -6751,7 +6751,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 175,
"width": 190,
"height": 60
}
},
@@ -6771,7 +6771,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 175,
"width": 190,
"height": 60
}
},
@@ -6791,7 +6791,7 @@
],
"value": {
"__type__": "cc.Size",
"width": 167,
"width": 182,
"height": 48
}
},
@@ -6811,7 +6811,7 @@
],
"value": {
"__type__": "cc.Vec3",
"x": -77.5,
"x": -85,
"y": 20.5,
"z": 0
}
@@ -7025,7 +7025,7 @@
"propertyPath": [
"_left"
],
"value": 39.4384765625
"value": 46.9384765625
},
{
"__type__": "CCPropertyOverrideInfo",
@@ -7035,7 +7035,7 @@
"propertyPath": [
"_right"
],
"value": 39.4384765625
"value": 46.9384765625
},
{
"__type__": "CCPropertyOverrideInfo",
@@ -7684,7 +7684,7 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 180,
"width": 200,
"height": 230
},
"_anchorPoint": {
@@ -8930,8 +8930,8 @@
},
"_alignFlags": 45,
"_target": null,
"_left": 39.4384765625,
"_right": 39.4384765625,
"_left": 46.9384765625,
"_right": 46.9384765625,
"_top": -0.7424999999999962,
"_bottom": 0.2824999999999953,
"_horizontalCenter": 0,
@@ -9878,8 +9878,8 @@
},
"_alignFlags": 45,
"_target": null,
"_left": 39.4384765625,
"_right": 39.4384765625,
"_left": 46.9384765625,
"_right": 46.9384765625,
"_top": -0.7424999999999962,
"_bottom": 0.2824999999999953,
"_horizontalCenter": 0,

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];