From a58dc818ee251d39f90738dd8a6ab0252c13b126 Mon Sep 17 00:00:00 2001 From: panw Date: Thu, 19 Mar 2026 17:10:37 +0800 Subject: [PATCH] =?UTF-8?q?refactor(hero):=20=E7=A7=BB=E9=99=A4=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E7=9A=84buff=E7=B3=BB=E7=BB=9F=E5=B9=B6=E7=AE=80?= =?UTF-8?q?=E5=8C=96=E5=B1=9E=E6=80=A7=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除Buff/Debuff状态管理相关的接口和数据结构 - 简化addBuff方法,直接应用属性变化而不处理buff生命周期 - 移除Interval、Timed、Permanent等buff类型的处理逻辑 - 简化属性应用逻辑,仅支持AP、HP_MAX、SHIELD_MAX三种属性 - 删除HeroBuffSystem中的buff更新逻辑,系统现在为空实现 - 移除状态检查的复杂逻辑,isStun和isFrost直接返回false --- assets/script/game/hero/HeroAttrsComp.ts | 329 ++--------------------- 1 file changed, 23 insertions(+), 306 deletions(-) diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index 6fa3b46b..7b7e872c 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -1,41 +1,8 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { Attrs, BType } from "../common/config/HeroAttrs"; -import { BuffConf, BuffRunType } from "../common/config/SkillSet"; -import { HeroDisVal, HeroInfo, HType } from "../common/config/heroSet"; +import { BuffConf } from "../common/config/SkillSet"; +import { HeroDisVal, HType } from "../common/config/heroSet"; import { mLogger } from "../common/Logger"; -import { smc } from "../common/SingletonModuleComp"; -import { HeroViewComp } from "./HeroViewComp"; -import { _decorator } from "cc"; - - -/** - * 可撤销的属性型 Buff/Debuff 实例 - * - 仅用于 Timed 类型 - * - 进入 BUFFS/DEBUFFS 后会在到期时自动反向回滚 - */ -interface ActiveBuffState { - id: number - attr: Attrs - sourceUuid: number - value: number - BType: BType - time: number -} -/** - * 间隔触发型效果实例 - * - 不直接进入 BUFFS/DEBUFFS - * - 由 HeroBuffSystem 每帧推进 tick/remain 并触发执行 - */ -interface IntervalBuffState { - id: number - attr: Attrs - sourceUuid: number - value: number - BType: BType - interval: number - remain: number - tick: number -} @ecs.register('HeroAttrs') export class HeroAttrsComp extends ecs.Comp { public debugMode: boolean = false; @@ -96,13 +63,6 @@ export class HeroAttrsComp extends ecs.Comp { maxSkillDistance: number = 0; // 最远技能攻击距离(缓存,受MP影响) minSkillDistance: number = 0; // 最近技能攻击距离(缓存,不受MP影响,用于停止位置判断) - // ==================== Buff/Debuff 系统 ==================== - /** 持久型buff数组 - 不会自动过期 */ - BUFFS: Record = {}; - DEBUFFS: Record = {}; - INTERVAL_EFFECTS: IntervalBuffState[] = []; - private buffInstanceId = 0; - // ==================== 标记状态 ==================== is_dead: boolean = false; is_count_dead: boolean = false; @@ -132,16 +92,8 @@ export class HeroAttrsComp extends ecs.Comp { * 从 HeroInfo 读取初始配置,建立属性系统 */ initAttrs() { - // 清空现有 buff/debuff - this.BUFFS = {}; - this.DEBUFFS = {}; - this.INTERVAL_EFFECTS = []; - this.buffInstanceId = 0; - // 获取英雄配置 - const heroInfo = HeroInfo[this.hero_uuid]; - if (!heroInfo) return; - - + this.in_stun = false; + this.in_frost = false; } /*******************基础属性管理********************/ @@ -188,95 +140,24 @@ export class HeroAttrsComp extends ecs.Comp { */ addBuff(buffConf: BuffConf) { const normalized = this.normalizeBuffValue(buffConf); - const runType = this.resolveRunType(buffConf); - // Interval:按间隔触发,写入 INTERVAL_EFFECTS,由系统统一执行 - if (runType === BuffRunType.Interval) { - const interval = buffConf.interval && buffConf.interval > 0 ? buffConf.interval : 1; - const remain = buffConf.time > 0 ? buffConf.time : interval; - this.INTERVAL_EFFECTS.push({ - id: ++this.buffInstanceId, - attr: buffConf.buff, - sourceUuid: buffConf.uuid, - value: normalized.value, - BType: normalized.BType, - interval, - remain, - tick: interval - }); - return; - } - // Permanent:一次性生效,不写入 BUFFS/DEBUFFS,不存在自动撤销 - if (runType === BuffRunType.Permanent) { - this.applyAttrChange(buffConf.buff, normalized.value, normalized.BType); - return; - } - // Timed:先应用,再记录,后续 updateList 到期后自动反向移除 - const duration = buffConf.time > 0 ? buffConf.time : 1; - - const targetList = buffConf.isDebuff ? this.DEBUFFS : this.BUFFS; - const attrKey = buffConf.buff as unknown as number; // 强制转换 key 类型以适配 Record - if (!targetList[attrKey]) { - targetList[attrKey] = []; - } - - const currentBuffs = targetList[attrKey]; - currentBuffs.push({ - id: ++this.buffInstanceId, - attr: buffConf.buff, - sourceUuid: buffConf.uuid, - value: normalized.value, - BType: normalized.BType, - time: duration - }); - this.applyAttrChange(buffConf.buff, normalized.value, normalized.BType); - if (this.debugMode) { - mLogger.log(this.debugMode, 'HeroAttrs', `添加Buff: ${buffConf.name}, 属性:${buffConf.buff}, 值:${normalized.value}, 时间:${duration}`); + mLogger.log(this.debugMode, 'HeroAttrs', `添加属性: ${buffConf.name}, 属性:${buffConf.buff}, 值:${normalized.value}`); } } - /** - * runType 解析优先级: - * 1) 显式配置 runType - * 2) 兼容旧配置:存在 interval 视为 Interval - * 3) time>0 视为 Timed,否则 Permanent - */ - private resolveRunType(buffConf: BuffConf): BuffRunType { - if (buffConf.runType !== undefined) return buffConf.runType; - if (buffConf.interval && buffConf.interval > 0) return BuffRunType.Interval; - return buffConf.time > 0 ? BuffRunType.Timed : BuffRunType.Permanent; - } - /** * 把配置值统一转换为“可直接写入容器和结算”的数值 * - RATIO 会在写入前转换为 VALUE * - BOOLEAN 保持原类型 */ private normalizeBuffValue(buffConf: BuffConf): { value: number; BType: BType } { - if (buffConf.BType === BType.BOOLEAN) { - return { value: buffConf.value, BType: BType.BOOLEAN }; - } return { - value: this.resolveBuffValue(buffConf.buff, buffConf.value, buffConf.BType), + value: buffConf.value, BType: BType.VALUE }; } - private resolveBuffValue(attr: Attrs, value: number, type: BType): number { - if (type !== BType.RATIO) return value; - if (attr === Attrs.hp || attr === Attrs.shield) { - return this.hp_max * value / 100; - } - if (attr === Attrs.hp_max || attr === Attrs.shield_max) { - return this[attr] * value / 100; - } - if (typeof this[attr] === "number") { - return (this[attr] as number) * value / 100; - } - return value; - } - /** * 通用属性修改应用 * @param attr 属性名 @@ -285,48 +166,25 @@ export class HeroAttrsComp extends ecs.Comp { * @param reverse 是否反向应用 (用于移除 buff) */ private applyAttrChange(attr: Attrs, value: number, type: BType, reverse: boolean = false) { + const mappedAttr = attr === Attrs.hp ? Attrs.hp_max : (attr === Attrs.shield ? Attrs.shield_max : attr); + if (mappedAttr !== Attrs.ap && mappedAttr !== Attrs.hp_max && mappedAttr !== Attrs.shield_max) return; + void type; let finalValue = value; - - // 如果是移除 buff,取反 - if (reverse) { - finalValue = -value; - } + if (reverse) finalValue = -finalValue; - // 护盾特殊处理:同时修改当前值和最大值 - if (attr === Attrs.shield && type === BType.VALUE) { - this.shield += finalValue; - this.shield_max += finalValue; - this.shield = Math.max(0, this.shield); - this.shield_max = Math.max(0, this.shield_max); - this.dirty_shield = true; + if (mappedAttr === Attrs.ap) { + this.ap = Math.max(0, this.ap + finalValue); return; } - - if (type === BType.RATIO) { - finalValue = this.resolveBuffValue(attr, finalValue, BType.RATIO); - if (typeof this[attr] === 'number') { - this[attr] = (this[attr] as number) + finalValue; - } - } else if (type === BType.BOOLEAN) { - // 布尔型/状态型:value > 0 为 true/计数+1,移除时 -1 - // 这里使用计数器方式来支持多个同类状态叠加 - // 例如 IN_FROST 是一个状态,不是属性。 - // 需要在 HeroAttrsComp 中定义对应的状态计数器,或者利用 DEBUFFS 列表的存在性判断状态 - // 暂时直接修改属性(如果属性是 boolean) - if (typeof this[attr] === 'boolean') { - this[attr] = !reverse; // 添加设为 true, 移除设为 false (不仅确,多个冰冻会出问题) - // 正确做法:updateBuffsDebuffs 中根据列表是否为空来设置状态 - } - } else { - // VALUE 固定值 - if (typeof this[attr] === 'number') { - this[attr] = (this[attr] as number) + finalValue; - } + if (mappedAttr === Attrs.hp_max) { + this.hp_max = Math.max(1, this.hp_max + finalValue); + if (this.hp > this.hp_max) this.hp = this.hp_max; + this.dirty_hp = true; + return; } - - // 标记脏数据(如果有对应的 dirty 标记) - if (attr === Attrs.hp) this.dirty_hp = true; - if (attr === Attrs.shield) this.dirty_shield = true; + this.shield_max = Math.max(0, this.shield_max + finalValue); + this.shield = Math.max(0, Math.min(this.shield + finalValue, this.shield_max)); + this.dirty_shield = true; } //======更新cd========// updateCD(dt: number){ @@ -340,10 +198,10 @@ export class HeroAttrsComp extends ecs.Comp { } } isStun(): boolean { - return this.in_stun; + return false; } isFrost(): boolean { - return this.in_frost; + return false; } triggerAtkCD() { this.a_cd = 0; @@ -353,103 +211,8 @@ export class HeroAttrsComp extends ecs.Comp { this.s_cd = 0; this.can_skill = false; } - // ==================== 临时 BUFF/DEBUFF 更新 ==================== - /** - * 更新临时 buff/debuff 的剩余时间 - * @param dt 时间增量 - */ - updateBuffsDebuffs(dt: number) { - this.updateList(this.BUFFS, dt); - this.updateList(this.DEBUFFS, dt); - - // 更新状态标记 (根据 DEBUFFS 列表是否存在有效项) - this.updateStatusFlags(); - } - /** - * 仅做“采集触发事件”,不做数值执行 - * 实际执行由 HeroBuffSystem.applyIntervalEffect 统一处理 - */ - collectIntervalEffectsBySystem(dt: number): IntervalBuffState[] { - const triggered: IntervalBuffState[] = []; - for (let i = this.INTERVAL_EFFECTS.length - 1; i >= 0; i--) { - const state = this.INTERVAL_EFFECTS[i]; - state.remain -= dt; - state.tick -= dt; - while (state.tick <= 0 && state.remain > 0) { - triggered.push({ - id: state.id, - attr: state.attr, - sourceUuid: state.sourceUuid, - value: state.value, - BType: state.BType, - interval: state.interval, - remain: state.remain, - tick: state.tick - }); - state.tick += state.interval; - } - if (state.remain <= 0) { - this.INTERVAL_EFFECTS.splice(i, 1); - } - } - return triggered; - } - applyStoredEffect(attr: Attrs, value: number, type: BType) { - this.applyAttrChange(attr, value, type); - } - /** - * Timed Buff/Debuff 到期更新 - * - 到期时调用 applyAttrChange(reverse=true) 回滚 - * - 该函数只处理 BUFFS/DEBUFFS,不处理 INTERVAL_EFFECTS - */ - private updateList(list: Record, dt: number) { - for (const attrKey in list) { - const buffs = list[attrKey]; - if (!buffs || buffs.length === 0) continue; - - // 倒序遍历以便移除 - for (let i = buffs.length - 1; i >= 0; i--) { - const buff = buffs[i]; - buff.time -= dt; - - if (buff.time <= 0) { - this.applyAttrChange(buff.attr, buff.value, buff.BType, true); - - buffs.splice(i, 1); - if (this.debugMode) { - mLogger.log(this.debugMode, 'HeroAttrs', `Buff过期: 属性:${buff.attr}, 恢复值:${buff.value}`); - } - } - } - - // 如果该属性的 buff 列表空了,可以清理 key (可选) - if (buffs.length === 0) { - delete list[attrKey]; - } - } - } - - private updateStatusFlags() { - // 检查特定状态的 Debuff 列表是否为空,来更新 boolean 标志 - this.checkStatus(Attrs.IN_FROST, 'in_frost'); - this.checkStatus(Attrs.IN_STUN, 'in_stun'); - } - - private checkStatus(attr: Attrs, flagName: string) { - const key = attr as unknown as number; - const hasBuff = this.DEBUFFS[key] && this.DEBUFFS[key].length > 0; - - // 只有当状态改变时才赋值,避免每帧赋值 - if (this[flagName] !== hasBuff) { - this[flagName] = hasBuff; - // 状态变化日志 - if (this.debugMode) { - mLogger.log(this.debugMode, 'HeroAttrs', `状态变更: ${this.hero_name}, ${flagName} = ${hasBuff}`); - } - } - } // ==================== 技能距离缓存管理 ==================== @@ -525,10 +288,6 @@ export class HeroAttrsComp extends ecs.Comp { this.in_frost = false; this.in_stun = false; - this.BUFFS = {}; - this.DEBUFFS = {}; - this.INTERVAL_EFFECTS = []; - this.buffInstanceId = 0; // 重置技能距离缓存 this.maxSkillDistance = 0; this.minSkillDistance = 0; @@ -568,49 +327,7 @@ export class HeroBuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpd } update(e: ecs.Entity): void { - if (!smc.mission.play || smc.mission.pause) return; - const attrs = e.get(HeroAttrsComp); - if (!attrs || attrs.is_dead) return; - // 1) 推进 Timed Buff/Debuff 生命周期 - attrs.updateBuffsDebuffs(this.dt); - // 2) 收集本帧到点的 Interval 触发 - const triggered = attrs.collectIntervalEffectsBySystem(this.dt); - if (triggered.length === 0) return; - const view = e.get(HeroViewComp); - // 3) 统一执行数值与表现 - for (const effect of triggered) { - this.applyIntervalEffect(attrs, view, effect); - } - } - - /** - * 间隔效果统一执行入口 - * - 先做数值结算 - * - 再按实际变化触发表现,避免无效动画 - */ - private applyIntervalEffect(attrs: HeroAttrsComp, view: HeroViewComp | null, effect: IntervalBuffState) { - if (effect.attr === Attrs.hp) { - const oldHp = attrs.hp; - attrs.add_hp(effect.value, true); - const delta = attrs.hp - oldHp; - if (view && delta !== 0) { - view.playIntervalEffect(effect.attr, delta, effect.sourceUuid); - } - return; - } - if (effect.attr === Attrs.shield) { - const oldShield = attrs.shield; - attrs.add_shield(effect.value, true); - const delta = attrs.shield - oldShield; - if (view && delta !== 0) { - view.playIntervalEffect(effect.attr, delta, effect.sourceUuid); - } - return; - } - attrs.applyStoredEffect(effect.attr, effect.value, effect.BType); - if (view) { - view.playIntervalEffect(effect.attr, effect.value, effect.sourceUuid); - } + void e; } }