feat(hero&buff): 新增限时最大生命Buff与配套技能

新增7029生命爆发Buff和对应6517技能,实现限时提升最大生命功能:
1.  Buff生效时按增量等量回血,到期自动钳回血量防止溢血
2.  血条显示逻辑适配动态最大生命值变化
3.  新增血量与最终最大生命同步方法统一处理边界情况
This commit is contained in:
pan
2026-09-07 11:16:02 +08:00
parent 852976d54b
commit 922ca7318d
5 changed files with 58 additions and 3 deletions

View File

@@ -106,6 +106,12 @@ export class HeroAttrsComp extends ecs.Comp {
dirty_shield: boolean = false; // 护盾变更标记
dirty_lv: boolean = false; // 等级变更标记
/**
* 最终最大生命(getFinalHpMax)的最近快照,用于计时 hp_max buff 生效/到期时的血量同步。
* null 表示尚未建立快照(初始化/对象池复用后首次 syncHpWithFinalMax 仅记录不结算)。
*/
private _lastFinalHpMax: number | null = null;
// ==================== 技能距离缓存 ====================
maxSkillDistance: number = 0; // 最远技能攻击距离(缓存,受MP影响)
minSkillDistance: number = 0; // 最近技能攻击距离(缓存,不受MP影响,用于停止位置判断)
@@ -168,6 +174,35 @@ export class HeroAttrsComp extends ecs.Comp {
return value
}
/**
* 同步当前血量与最终最大生命的偏差(计时 hp_max buff 的生效/到期结算钩子)。
*
* Why: 计时 buff 的上限增减不回写 hp_max 字段,若不做同步:
* - 生效时血条比例骤降(分母变大、分子不变),满血单位表现为"掉血",体验极差;
* - 到期时 hp 可能超过回落后的新上限,出现"溢血"。
* 策略:上限增量按等量回血(与永久路径 add_hp_max 口径一致,满血也有收益);
* 上限回落时钳回新上限,借出的生命随到期自然收回。
* 单点快照 diff 覆盖生效/到期/驱散/叠层全部路径,BuffManager/BuffSystem 无需感知。
*/
syncHpWithFinalMax() {
const finalMax = this.getFinalHpMax();
// 首次调用仅建立快照,避免初始化/对象池复用时误回血
if (this._lastFinalHpMax === null) {
this._lastFinalHpMax = finalMax;
return;
}
const delta = finalMax - this._lastFinalHpMax;
if (delta === 0) return;
if (delta > 0) {
// 等量回血。直接写 this.hp 而非走 add_hp,避免 add_hp 内 clamp → getFinalHpMax 的递归
this.hp += delta;
} else if (this.hp > finalMax) {
this.hp = finalMax; // 上限回落,钳回防溢血
}
this._lastFinalHpMax = finalMax;
this.dirty_hp = true; // 驱动血条刷新
}
add_ap(value: number) {
this.ap += value
return value
@@ -700,6 +735,8 @@ export class HeroAttrsComp extends ecs.Comp {
this.dirty_hp = false;
this.dirty_shield = false;
this.dirty_lv = false;
// 重置计时 hp_max buff 的血量同步快照(下次 syncHpWithFinalMax 重新建立基准)
this._lastFinalHpMax = null;
}
}

View File

@@ -119,8 +119,11 @@ export class HeroTopBarComp extends CCComp {
/** 更新血量进度条 */
public hpShow(): void {
if (!this._model || !this.hpProgressBar) return;
// 计时 hp_max buff 的增删不走 dirty_hp,显示前先做上限-血量同步(等量回血/到期钳回)
this._model.syncHpWithFinalMax();
const hp = this._model.hp;
const hpMax = this._model.hp_max;
// 分母用 getFinalHpMax:计时 hp_max buff 的上限加成需实时反映到血条
const hpMax = this._model.getFinalHpMax();
let targetProgress = hpMax > 0 ? hp / hpMax : 0;
targetProgress = clamp(targetProgress, 0, 1);

View File

@@ -155,6 +155,8 @@ export class HeroViewComp extends CCComp {
const buffComp = this.ent.has(BuffComp) ? this.ent.get(BuffComp) : null;
if (buffComp && buffComp.dirty_buffs) {
this.topBar.debuffShow(buffComp);
// hp_max 计时 buff 的生效/到期会改变血条上限,同步刷新血条(内部走 syncHpWithFinalMax)
this.topBar.hpShow();
buffComp.dirty_buffs = false;
}
}