feat(hero): 新增完整计时性Buff/Debuff系统

本次提交实现了游戏内完整的计时性增益/减益系统,包含:
1. 新增Buff配置表与运行时数据组件
2. 实现属性修饰器与最终属性计算逻辑
3. 完成Buff管理、计时结算与周期效果处理
4. 兼容旧有控制状态系统,支持平滑过渡
5. 附带完整的系统设计文档

同时关闭了两个闲置的任务界面节点。
This commit is contained in:
pan
2026-07-23 15:48:59 +08:00
parent 708ca0827a
commit c4e7f2584b
11 changed files with 714 additions and 2 deletions

View File

@@ -7,6 +7,8 @@ import { FieldSkillSet, FieldSkillType, SkillOverrides } from "../common/config/
import { smc } from "../common/SingletonModuleComp";
import { Attrs } from "../common/config/HeroAttrs";
import { FieldSkillHelper } from "./FieldSkillHelper";
import { BuffComp } from "./BuffComp";
import { BuffList, ModOp } from "../common/config/BuffSet";
@ecs.register('HeroAttrs')
export class HeroAttrsComp extends ecs.Comp {
public debugMode: boolean = false;
@@ -320,6 +322,76 @@ export class HeroAttrsComp extends ecs.Comp {
return baseHp * (1 + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroHp) / 100);
}
// ==================== 计时性 Buff 最终值 ====================
//
// 以下方法在驻场属性的基础上,叠加 BuffComp 中计时性 buff/debuff 的修饰器,
// 输出"最终生效值"。设计依据ECSComp 持有 ent 字段指向所属 Entity
// 因此可直接通过 this.ent.get(BuffComp) 取到同实体上的 buff 组件。
/**
* 聚合目标身上所有活跃 buff 对指定属性的计时性修饰。
* 每层 buff 独立贡献其配置中的 modifiers。
*
* @param attr 目标属性枚举
* @returns flatSum=Flat 修饰总和pctSum=百分比修饰总和(百分点)
*/
private aggregateTimedMods(attr: Attrs): { flatSum: number; pctSum: number } {
const result = { flatSum: 0, pctSum: 0 };
if (!this.ent) return result;
const buffComp = this.ent.get(BuffComp);
if (!buffComp || buffComp.buffs.size === 0) return result;
buffComp.buffs.forEach((layers, buffId) => {
const cfg = BuffList[buffId];
if (!cfg || !cfg.modifiers) return;
// 每层独立贡献,模拟叠层放大效果
for (let i = 0; i < layers.length; i++) {
for (const mod of cfg.modifiers) {
if (mod.attr !== attr) continue;
if (mod.op === ModOp.Flat) {
result.flatSum += mod.value;
} else {
// PercentAdd 与 PercentMul 暂统一按加法百分比聚合;
// PercentMul 真正的独立乘区尚未启用TODO: 启用时需改造为多乘区连乘
result.pctSum += mod.value;
}
}
}
});
return result;
}
/**
* 最终攻击力 = (基础攻击 + Flat 修饰) × (1 + 百分比修饰 / 100)。
* 融合驻场加成与计时性 buff 修饰。
*/
public getFinalAp(): number {
const runtimeAp = this.getRuntimeAp(this.ap);
const mods = this.aggregateTimedMods(Attrs.ap);
return (runtimeAp + mods.flatSum) * (1 + mods.pctSum / 100);
}
/**
* 最终最大生命 = (基础最大生命 + Flat 修饰) × (1 + 百分比修饰 / 100)。
* 融合驻场加成与计时性 buff 修饰。
*/
public getFinalHpMax(): number {
const runtimeHp = this.getRuntimeHp(this.hp_max);
const mods = this.aggregateTimedMods(Attrs.hp_max);
return (runtimeHp + mods.flatSum) * (1 + mods.pctSum / 100);
}
/**
* 最终暴击率 = 驻场实时暴击率 + Flat/百分比修饰之和。
* 暴击率是加法模型Flat 和 PercentAdd 均直接累加到百分点。
*/
public getFinalCritical(): number {
const base = this.getRuntimeCritical();
const mods = this.aggregateTimedMods(Attrs.critical);
return base + mods.flatSum + mods.pctSum;
}
/** 根据攻速加成换算实际攻击间隔,避免直接改写配置里的基础 CD。 */
public getEffectiveSkillCd(skillId: number): number {
const skill = this.skills[skillId];