From 287610897074068075b1841cded6e1ad41746a43 Mon Sep 17 00:00:00 2001 From: panFD Date: Thu, 23 Jul 2026 21:07:38 +0800 Subject: [PATCH] =?UTF-8?q?refactor(hero):=20=E7=A7=BB=E9=99=A4=E6=97=A7?= =?UTF-8?q?=E7=89=88=E6=8E=A7=E5=88=B6buff=E8=AE=A1=E6=97=B6=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=EF=BC=8C=E7=BB=9F=E4=B8=80=E7=94=A8buff=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完成全量buff系统迁移,删除HeroBuffSystem和旧的计时字段, 所有冰冻/眩晕控制效果改为通过BuffManager管理, 简化了控制状态判定逻辑,移除了新旧系统兼容代码 --- assets/script/game/hero/BuffManager.ts | 105 +++-------------------- assets/script/game/hero/BuffSystem.ts | 5 +- assets/script/game/hero/HeroAtkSystem.ts | 4 +- assets/script/game/hero/HeroAttrsComp.ts | 57 ++++-------- 4 files changed, 30 insertions(+), 141 deletions(-) diff --git a/assets/script/game/hero/BuffManager.ts b/assets/script/game/hero/BuffManager.ts index 469ce0b2..61c007d3 100644 --- a/assets/script/game/hero/BuffManager.ts +++ b/assets/script/game/hero/BuffManager.ts @@ -4,14 +4,12 @@ * 设计说明: * - 非 ECS 组件,是普通 class 单例(参考 smc 的单例暴露模式)。 * - 对外提供 applyBuff / dispel / getStack / hasControl 四组核心能力。 - * - 控制类 buff 采用"双写"策略:既写入 BuffComp(新框架),也同步调用 - * HeroAttrsComp.toFrost/toStun(旧框架),保证过渡期表现一致。 + * - 控制类 buff(冰冻/眩晕)统一写入 BuffComp,由 BuffSystem 计时到期; + * 旧字段 frost_end_time/stun_end_time 已随 HeroBuffSystem 一并下线。 */ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; -import { BuffCategory, BuffConfig, BuffList } from "../common/config/BuffSet"; -import { FightSet } from "../common/config/GameSet"; -import { HeroAttrsComp } from "./HeroAttrsComp"; +import { BuffCategory, BuffList } from "../common/config/BuffSet"; import { BuffComp, ActiveBuff } from "./BuffComp"; /** applyBuff 的覆盖参数(预留按需覆写持续时间) */ @@ -26,9 +24,7 @@ class BuffManagerImpl { * 叠层规则: * - max_stack === 0:无限叠加,始终 push 新层 * - existing.length < max_stack:push 新层 - * - 已满:替换最老层(数组末尾) - * - * 控制类(is_control)额外双写旧字段(frost/stun)。 + * - 已满:移除最老层(数组首部)后追加新层,保持 FIFO 刷新语义 * * @param target 目标实体 * @param buffId BuffList 配置 id @@ -54,16 +50,10 @@ class BuffManagerImpl { if (cfg.max_stack === 0 || layers.length < cfg.max_stack) { layers.push(newLayer); } else { - // 已满,移除最老层(数组首部)后追加新层,保持 FIFO 刷新语义 layers.shift(); layers.push(newLayer); } - // 控制类双写旧字段 - if (cfg.is_control) { - this.applyControlEffect(target, cfg, duration); - } - buffComp.dirty_buffs = true; } @@ -80,8 +70,6 @@ class BuffManagerImpl { const buffComp = target.get(BuffComp); let removedKinds = 0; - const controlKindsCleared: ('frost' | 'stun')[] = []; - buffComp.buffs.forEach((layers, buffId) => { const cfg = BuffList[buffId]; if (!cfg) return; @@ -90,18 +78,8 @@ class BuffManagerImpl { if (layers.length > 0) removedKinds++; buffComp.buffs.delete(buffId); - - // 记录被驱散的控制类型,用于后续重算 - if (cfg.is_control && cfg.control_kind && cfg.control_kind !== 'none') { - controlKindsCleared.push(cfg.control_kind); - } }); - // 控制类驱散后重算旧字段 - if (controlKindsCleared.length > 0) { - this.recomputeControlState(target, controlKindsCleared); - } - buffComp.dirty_buffs = true; return removedKinds; } @@ -118,23 +96,15 @@ class BuffManagerImpl { /** * 判断目标是否处于指定类型的控制状态下。 - * 同时检查新框架 BuffComp 和旧字段,兼容过渡期。 + * 唯一判定来源:BuffComp 中是否存在对应 control_kind 的活跃控制 buff。 */ hasControl(target: ecs.Entity, kind: 'frost' | 'stun'): boolean { - // 新框架:检查 BuffComp 中是否有对应控制类 buff - if (target.has(BuffComp)) { - const buffComp = target.get(BuffComp); - for (const [buffId, layers] of buffComp.buffs) { - if (layers.length === 0) continue; - const cfg = BuffList[buffId]; - if (cfg?.is_control && cfg.control_kind === kind) return true; - } - } - // 旧字段兜底 - if (target.has(HeroAttrsComp)) { - const attrs = target.get(HeroAttrsComp); - if (kind === 'frost') return attrs.isFrost(); - if (kind === 'stun') return attrs.isStun(); + if (!target.has(BuffComp)) return false; + const buffComp = target.get(BuffComp); + for (const [buffId, layers] of buffComp.buffs) { + if (layers.length === 0) continue; + const cfg = BuffList[buffId]; + if (cfg?.is_control && cfg.control_kind === kind) return true; } return false; } @@ -150,59 +120,6 @@ class BuffManagerImpl { } return target.get(BuffComp); } - - /** - * 控制效果双写:将控制类 buff 同步写入旧字段。 - * duration 会被换算成 toFrost/toStun 所需的倍数参数。 - */ - private applyControlEffect(target: ecs.Entity, cfg: BuffConfig, duration: number): void { - if (!target.has(HeroAttrsComp)) return; - const attrs = target.get(HeroAttrsComp); - - if (cfg.control_kind === 'frost') { - // toFrost(time) 内部会乘以 FROST_TIME,这里反除得到倍数 - attrs.toFrost(duration / FightSet.FROST_TIME); - } else if (cfg.control_kind === 'stun') { - attrs.toStun(duration / FightSet.STUN_TIME); - } - } - - /** - * 驱散控制 buff 后重算旧字段。 - * 如果对应类型的控制 buff 已全部清除,则立即将旧字段归零。 - * - * @param target 目标实体 - * @param clearedKinds 本次被驱散的控制类型列表 - */ - private recomputeControlState(target: ecs.Entity, clearedKinds: ('frost' | 'stun')[]): void { - if (!target.has(HeroAttrsComp)) return; - const attrs = target.get(HeroAttrsComp); - - // 检查是否还有同类型控制 buff 残留 - const hasFrostInBuff = this.hasControlInBuff(target, 'frost'); - const hasStunInBuff = this.hasControlInBuff(target, 'stun'); - - if (clearedKinds.includes('frost') && !hasFrostInBuff) { - attrs.frost_end_time = 0; - } - if (clearedKinds.includes('stun') && !hasStunInBuff) { - attrs.stun_end_time = 0; - } - } - - /** - * 仅检查 BuffComp 中是否存在指定控制类型(不查旧字段)。 - */ - private hasControlInBuff(target: ecs.Entity, kind: 'frost' | 'stun'): boolean { - if (!target.has(BuffComp)) return false; - const buffComp = target.get(BuffComp); - for (const [buffId, layers] of buffComp.buffs) { - if (layers.length === 0) continue; - const cfg = BuffList[buffId]; - if (cfg?.is_control && cfg.control_kind === kind) return true; - } - return false; - } } /** Buff 管理器单例(全局唯一实例) */ diff --git a/assets/script/game/hero/BuffSystem.ts b/assets/script/game/hero/BuffSystem.ts index 8cad3e10..522d01a7 100644 --- a/assets/script/game/hero/BuffSystem.ts +++ b/assets/script/game/hero/BuffSystem.ts @@ -5,10 +5,9 @@ * - 遍历 BuffComp.buffs,每层 remaining -= 步长 * - 若配置了 tick 效果(DoT/HoT),累计 tick_acc 并按 interval 结算伤害/治疗 * - 到期的层从数组中移除;数组空则清理 key - * - 兼容期:同时递减旧字段 frost_end_time / stun_end_time * - * 注意:当前 HeroBuffSystem 仍在运行相同的 frost/stun 递减逻辑, - * 待旧系统完全下线后可移除此处兼容代码。 + * 控制类 buff(冰冻/眩晕)不在此处做特殊处理:层存活期间 hasControl 判定 + * 即生效,到期移除后控制自然解除。旧 HeroBuffSystem 已下线。 */ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; diff --git a/assets/script/game/hero/HeroAtkSystem.ts b/assets/script/game/hero/HeroAtkSystem.ts index f5db2f8b..5abe6199 100644 --- a/assets/script/game/hero/HeroAtkSystem.ts +++ b/assets/script/game/hero/HeroAtkSystem.ts @@ -200,14 +200,14 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda targetView.playEnd(skillConf.endAnm); if (isFrost) { TAttrsComp.toFrost(); - targetView.in_iced(TAttrsComp.frost_end_time); + targetView.in_iced(FightSet.FROST_TIME); if (damageEvent.Attrs.fac === FacSet.HERO) { smc.vmdata.scores.freeze_count++; } } if (isStun) { TAttrsComp.toStun(); - targetView.in_stun(TAttrsComp.stun_end_time); + targetView.in_stun(FightSet.STUN_TIME); if (damageEvent.Attrs.fac === FacSet.HERO) { smc.vmdata.scores.stun_count++; } diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index 52ff2f6e..459ccc9e 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -1,7 +1,6 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { HeroDisVal, HeroInfo, HSkillInfo, HType, SkillTriggerType } from "../common/config/heroSet"; import { mLogger } from "../common/Logger"; -import { Timer } from "db://oops-framework/core/common/timer/Timer"; import { FacSet, FightSet } from "../common/config/GameSet"; import { FieldSkillSet, FieldSkillType, SkillOverrides } from "../common/config/SkillSet"; import { smc } from "../common/SingletonModuleComp"; @@ -9,6 +8,11 @@ import { Attrs } from "../common/config/HeroAttrs"; import { FieldSkillHelper } from "./FieldSkillHelper"; import { BuffComp } from "./BuffComp"; import { BuffList, ModOp } from "../common/config/BuffSet"; +import { buffManager } from "./BuffManager"; + +/** 控制类 buff 配置 id(对应 BuffList) */ +const BUFF_ID_FROST = 7003; +const BUFF_ID_STUN = 7004; @ecs.register('HeroAttrs') export class HeroAttrsComp extends ecs.Comp { public debugMode: boolean = false; @@ -64,9 +68,6 @@ export class HeroAttrsComp extends ecs.Comp { invincible_time: number = 0;// 无敌时间 - frost_end_time: number = 0; - stun_end_time: number = 0; - boom: boolean = false; // 自爆怪 // ==================== 脏标签标记 ==================== @@ -106,8 +107,6 @@ export class HeroAttrsComp extends ecs.Comp { * 从 HeroInfo 读取初始配置,建立属性系统 */ initAttrs() { - this.frost_end_time = 0; - this.stun_end_time = 0; } /*******************基础属性管理********************/ @@ -167,14 +166,16 @@ export class HeroAttrsComp extends ecs.Comp { } + /** 施加冰冻:委托 buffManager 写入 BuffComp,duration = FROST_TIME * time */ toFrost(time: number = 1) { - const frostTime = FightSet.FROST_TIME * time; - this.frost_end_time = Math.max(this.frost_end_time, frostTime); + if (!this.ent) return; + buffManager.applyBuff(this.ent, BUFF_ID_FROST, 0, 0, { duration: FightSet.FROST_TIME * time }); } + /** 施加击晕:委托 buffManager 写入 BuffComp,并清零技能 CD */ toStun(time: number = 1) { - const stunTime = FightSet.STUN_TIME * time; - this.stun_end_time = Math.max(this.stun_end_time, stunTime); + if (!this.ent) return; + buffManager.applyBuff(this.ent, BUFF_ID_STUN, 0, 0, { duration: FightSet.STUN_TIME * time }); // 击晕时 CD 清零 for (const key in this.skills) { @@ -215,11 +216,13 @@ export class HeroAttrsComp extends ecs.Comp { skill.ccd = Math.min(actualCd, skill.ccd + dt); } } + /** 是否处于冰冻状态(统一走 BuffComp 判定) */ isFrost(): boolean { - return this.frost_end_time > 0 + return !!this.ent && buffManager.hasControl(this.ent, 'frost'); } + /** 是否处于击晕状态(统一走 BuffComp 判定) */ isStun(): boolean { - return this.stun_end_time > 0 + return !!this.ent && buffManager.hasControl(this.ent, 'stun'); } getSkillLevel(skillId: number): number { if (!skillId) return 0; @@ -547,9 +550,6 @@ export class HeroAttrsComp extends ecs.Comp { this.wfuny = 0; this.boom = false; - this.frost_end_time = 0; - this.stun_end_time = 0; - // 重置技能距离缓存 this.maxSkillDistance = 0; this.minSkillDistance = 0; @@ -578,32 +578,5 @@ export class HeroAttrsComp extends ecs.Comp { } } -@ecs.register('HeroBuffSystem') -export class HeroBuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { - private timer = new Timer(0.1) - filter(): ecs.IMatcher { - return ecs.allOf(HeroAttrsComp); - } - - update(e: ecs.Entity): void { - if (this.timer.update(this.dt)) { - const attrsComp = e.get(HeroAttrsComp); - if (attrsComp.frost_end_time > 0) { - attrsComp.frost_end_time -= 0.1; - if (attrsComp.frost_end_time <= 0) { - attrsComp.frost_end_time = 0; - } - } - if (attrsComp.stun_end_time > 0) { - attrsComp.stun_end_time -= 0.1; - if (attrsComp.stun_end_time <= 0) { - attrsComp.stun_end_time = 0; - } - } - } - void e; - } -} -