refactor(hero): 重构额外属性加成系统,统一为bonus字段

1.  将原ap_bonus/hp_bonus/def_bonus三个字段合并为通用的bonus数组结构
2.  新增多属性同时配置能力,支持hp/ap/def百分比加成与crt/frz/stun/para固定百分点加成
3.  更新所有前端编辑器、服务端渲染与游戏运行时逻辑适配新配置格式
4.  添加数据兼容迁移逻辑,自动处理旧版英雄配置数据
This commit is contained in:
panFD
2026-09-07 23:05:30 +08:00
parent a1c8f46c50
commit ed738d2e30
10 changed files with 180 additions and 94 deletions

View File

@@ -137,9 +137,7 @@ export class Hero extends ecs.Entity {
model.atking = hero.atking;
model.atked = hero.atked;
model.field = hero.field;
model.ap_bonus = hero.ap_bonus;
model.hp_bonus = hero.hp_bonus;
model.def_bonus = hero.def_bonus;
model.bonus = hero.bonus;
// 基础属性:固定基础值 × 品质系数(相邻品质差 5%),成长由 grow_type 线性递增提供
// TODO: 局外升级机制落地后,此处基础值将与存档强化累加重算
@@ -184,26 +182,30 @@ export class Hero extends ecs.Entity {
model.runtime_field = resolveFieldByLv(model.field, hero_lv);
// 复活已纳入 dead 触发组,无需单独解析 revive
// 应用额外属性加成(成长类型每级递增 + hp/ap/def_bonus 一次性奖励累加)
// 应用额外属性加成(成长类型每级递增 + bonus 档位累加)
// 成长增量:仅英雄生效(model.fac 已为 HERO),按 grow_type 递增曲线累计
const grow = calcGrowBonus(hero, hero_lv);
model.hp += grow.hp; model.hp_max += grow.hp;
model.ap += grow.ap;
model.defense += grow.def;
if (model.hp_bonus) {
let hpExtra = 0;
for (const e of model.hp_bonus) { if (e.lv <= hero_lv) hpExtra += e.value; }
model.hp += hpExtra; model.hp_max += hpExtra;
}
if (model.ap_bonus) {
let apExtra = 0;
for (const e of model.ap_bonus) { if (e.lv <= hero_lv) apExtra += e.value; }
model.ap += apExtra;
}
if (model.def_bonus) {
let defExtra = 0;
for (const e of model.def_bonus) { if (e.lv <= hero_lv) defExtra += e.value; }
model.defense += defExtra;
if (model.bonus) {
// 百分比基数:基础×品质 + 成长快照(不含 bonus 自身,多档加法叠加不滚雪球)
const snapHp = model.hp_max, snapAp = model.ap, snapDef = model.defense;
let hpP = 0, apP = 0, defP = 0;
for (const e of model.bonus) {
if (e.lv > hero_lv) continue;
const a = e.attrs;
hpP += a.hp ?? 0; apP += a.ap ?? 0; defP += a.def ?? 0;
// 概率类:固定百分点直接累加
model.critical += a.crt ?? 0;
model.freeze_chance += a.frz ?? 0;
model.stun_chance += a.stun ?? 0;
model.paralyze_chance += a.para ?? 0;
}
const hpAdd = Math.round(snapHp * hpP / 100);
model.hp += hpAdd; model.hp_max += hpAdd;
model.ap += Math.round(snapAp * apP / 100);
model.defense += Math.round(snapDef * defP / 100);
}
// lv12 职业属性专项:达到 12 级时按职业对单项基础属性 +50%

View File

@@ -1,5 +1,5 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { HeroDisVal, HeroInfo, HSkillInfo, HType, SkillTriggerType, TriggerGrouped, LvFieldEntry, LvBonusEntry, FieldEntry, HRole } from "../common/config/heroSet";
import { HeroDisVal, HeroInfo, HSkillInfo, HType, SkillTriggerType, TriggerGrouped, LvFieldEntry, LvBonusAttrsEntry, FieldEntry, HRole } from "../common/config/heroSet";
import { mLogger } from "../common/Logger";
import { FacSet, FightSet } from "../common/config/GameSet";
import { FieldSkillSet, FieldSkillType, SkillOverrides } from "../common/config/SkillSet";
@@ -53,10 +53,8 @@ export class HeroAttrsComp extends ecs.Comp {
[SkillTriggerType.Atked]?: TriggerGrouped;
/** 驻场光环(按 lv 解锁,存活期间全局生效) */
[SkillTriggerType.Field]?: LvFieldEntry[];
/** 额外攻击/生命/防御加成(按 lv 累加) */
ap_bonus?: LvBonusEntry[];
hp_bonus?: LvBonusEntry[];
def_bonus?: LvBonusEntry[];
/** 额外属性加成(按 lv 累加:hp/ap/def 百分比、 crt/frz/stun/para 固定百分点) */
bonus?: LvBonusAttrsEntry[];
// ==================== 运行时解析缓存(按当前等级 resolve 后的有效列表) ====================
/** 当前等级下生效的攻击触发条目(供 SkillTriggerHelper 消费) */
@@ -704,9 +702,7 @@ export class HeroAttrsComp extends ecs.Comp {
this.atking = undefined;
this.atked = undefined;
this.field = undefined;
this.ap_bonus = undefined;
this.hp_bonus = undefined;
this.def_bonus = undefined;
this.bonus = undefined;
this.runtime_atking = undefined;
this.runtime_atked = undefined;
this.runtime_call = undefined;