feat(skill&shield): 实现护盾持续时间功能,调整魔法盾冷却
1. 为护盾技能添加duration配置,支持永久/限时护盾 2. 新增护盾倒计时逻辑,到期自动清空护盾 3. 调整英雄6301魔法盾的冷却时间为10秒,新增7秒持续时长配置 4. 重构HeroAttrsComp,新增护盾持续时间字段与清空护盾方法
This commit is contained in:
@@ -166,6 +166,7 @@ export interface SkillConfig {
|
||||
bck_chance?: number, // 击退概率(百分点;未配置视为 0 不击退,可由 heroSet overrides 覆写)
|
||||
buff_type?: Attrs, // Buff 类型 (单一职责)
|
||||
timed_buff_id?: number, // 计时性 buff 配置 id(指向 BuffList),存在时走 buffManager 而非永久 add_*
|
||||
shield_duration?: number, // 护盾持续时间(秒),仅 kind=Shield 生效;缺省/<=0 表示永久护盾
|
||||
buff_value?: number, // 覆写计时 buff 的修饰数值(modifiers.value / tick.damage_or_heal),由药水卡自定义档位
|
||||
buff_duration?: number, // 覆写计时 buff 的持续时间(秒),不配置则用 BuffList 默认值
|
||||
buff_chance?: number, // 计时 buff 施加概率(百分点,缺省 100)
|
||||
@@ -205,6 +206,7 @@ export interface SkillOverrides {
|
||||
bck_chance?: number;
|
||||
buff_type?: Attrs;
|
||||
timed_buff_id?: number;
|
||||
shield_duration?: number;
|
||||
buff_value?: number;
|
||||
buff_duration?: number;
|
||||
buff_chance?: number;
|
||||
@@ -384,8 +386,8 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
//============================= ====== 辅助技能 回合技能 ====== ==========================
|
||||
6301: {
|
||||
uuid: 6301, name: "护盾", sp_name: "buff_wind", icon: "28-Electric-Wave", TGroup: TGroup.Self, readyAnm: "up_blue", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, kind: SkillKind.Shield, ap: 30, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "获得施法者最大生命30%的护盾",
|
||||
DTType: DTType.single, kind: SkillKind.Shield, ap: 30, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, shield_duration: 7,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "获得施法者最大生命30%的护盾, 持续7秒",
|
||||
},
|
||||
6302: {
|
||||
uuid: 6302, name: "治疗", sp_name: "buff_wind", icon: "g_priest_zldy_skill", TGroup: TGroup.Team, readyAnm: "up_green", endAnm: "", act: "atk",
|
||||
|
||||
@@ -549,7 +549,7 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"ap":120}, desc: "普通攻击 造成 120% 伤害" },
|
||||
],
|
||||
},
|
||||
6301: { uuid: 6301, name: "魔法盾", lv: 1, cd: 8, ccd: 0, overrides: {"ap":30}, desc: "{target}获得生命最大值{ap}%的护盾",
|
||||
6301: { uuid: 6301, name: "魔法盾", lv: 1, cd: 10, ccd: 0, overrides: {"ap":30}, desc: "{target}获得生命最大值{ap}%的护盾",
|
||||
lv_entries: [
|
||||
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":60}, desc: "{target}获得生命最大值{ap}%的护盾" },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":120}, desc: "{target}获得生命最大值{ap}%的护盾" },
|
||||
|
||||
@@ -28,18 +28,34 @@ const TICK_STEP = 0.1;
|
||||
export class BuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
|
||||
private timer = new Timer(TICK_STEP);
|
||||
|
||||
// HeroAttrsComp 可选,用于 DoT/HoT 的血量结算与护盾倒计时
|
||||
private processShieldTimer(attrsComp: HeroAttrsComp | null): void {
|
||||
if (!attrsComp) return;
|
||||
// 永久护盾(duration<=0)不参与倒计时
|
||||
if (attrsComp.shield_duration <= 0) return;
|
||||
attrsComp.shield_duration -= TICK_STEP;
|
||||
if (attrsComp.shield_duration <= 0) {
|
||||
attrsComp.clear_shield();
|
||||
mLogger.log(DEBUG, "BuffSystem", `护盾到期: ${attrsComp.hero_name}(eid:${attrsComp.ent?.eid ?? "-"}) 护盾已清空`);
|
||||
}
|
||||
}
|
||||
|
||||
// filter 改为 allOf(HeroAttrsComp):护盾倒计时挂在 HeroAttrsComp 上,
|
||||
// 若按 BuffComp 过滤,无 buff 的实体不会被遍历,护盾到期清空会失效
|
||||
filter(): ecs.IMatcher {
|
||||
return ecs.allOf(BuffComp);
|
||||
return ecs.allOf(HeroAttrsComp);
|
||||
}
|
||||
|
||||
update(e: ecs.Entity): void {
|
||||
if (!this.timer.update(this.dt)) return;
|
||||
|
||||
const buffComp = e.get(BuffComp);
|
||||
if (!buffComp) return;
|
||||
// HeroAttrsComp 必有(filter 保证),用于 DoT/HoT 血量结算与护盾倒计时
|
||||
const attrsComp = e.get(HeroAttrsComp);
|
||||
this.processShieldTimer(attrsComp);
|
||||
|
||||
// HeroAttrsComp 可选,用于 DoT/HoT 的血量结算
|
||||
const attrsComp = e.has(HeroAttrsComp) ? e.get(HeroAttrsComp) : null;
|
||||
// BuffComp 可选:无 buff 时仅做护盾倒计时
|
||||
const buffComp = e.has(BuffComp) ? e.get(BuffComp) : null;
|
||||
if (!buffComp) return;
|
||||
|
||||
// ---- 处理所有 buff 层 ----
|
||||
let anyChanged = false;
|
||||
|
||||
@@ -42,6 +42,8 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
shield: number = 0; // 当前护盾
|
||||
/** 护盾获得时的快照值,作为护盾进度条分母(护盾为覆盖语义,分母不能随扣盾变化) */
|
||||
shield_max: number = 0;
|
||||
/** 护盾剩余持续时间(秒),<=0 表示永久护盾;由 BuffSystem 定时递减,归零时清空护盾 */
|
||||
shield_duration: number = 0;
|
||||
defense: number = 0; // 防御(除法递减模型减伤,见 getFinalDefense)
|
||||
|
||||
// ==================== 攻击属性 (补充) ====================
|
||||
@@ -168,13 +170,27 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
*
|
||||
* Why 覆盖而非累加:新护盾直接替换旧护盾,避免多源护盾无限叠加导致数值膨胀。
|
||||
* @param value 新的护盾值(<=0 时视为清空护盾)
|
||||
* @param duration 护盾持续时间(秒),<=0 或不传表示永久护盾;到期由 BuffSystem 清空
|
||||
*/
|
||||
add_shield(value: number) {
|
||||
add_shield(value: number, duration: number = 0) {
|
||||
this.shield = Math.max(0, Math.floor(value));
|
||||
// 覆盖为新护盾时刷新快照分母;清空护盾时分母归零
|
||||
this.shield_max = this.shield;
|
||||
this.shield_duration = Math.max(0, duration);
|
||||
this.dirty_shield = true; // 标记护盾需要更新
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空护盾(护盾到期或外部强制驱散时调用)。
|
||||
* 直接置零并打脏标记,视图层据此隐藏护盾条与特效。
|
||||
*/
|
||||
clear_shield() {
|
||||
if (this.shield <= 0) return;
|
||||
this.shield = 0;
|
||||
this.shield_max = 0;
|
||||
this.shield_duration = 0;
|
||||
this.dirty_shield = true;
|
||||
}
|
||||
add_hp_max(value: number) {
|
||||
this.hp_max += value
|
||||
this.hp += value
|
||||
@@ -701,6 +717,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
this.dis = 100;
|
||||
this.shield = 0;
|
||||
this.shield_max = 0;
|
||||
this.shield_duration = 0;
|
||||
this.defense = 0;
|
||||
|
||||
// 重置新增属性
|
||||
|
||||
@@ -575,7 +575,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
} else if (kind === SkillKind.Shield && sAp !== 0) {
|
||||
// 护盾值 = ap% × 施法者最终最大生命(getFinalHpMax 含驻场光环与计时 buff 加成)
|
||||
const addShield = Math.max(0, Math.floor(_cAttrsComp.getFinalHpMax() * sAp / 100));
|
||||
model.add_shield(addShield);
|
||||
// shield_duration 缺省/<=0 表示永久护盾
|
||||
model.add_shield(addShield, config.shield_duration ?? 0);
|
||||
}
|
||||
|
||||
if (config.buff_type !== undefined) {
|
||||
|
||||
Reference in New Issue
Block a user