1. 将各业务模块中的硬编码console日志替换为自定义Logger模块,新增DEBUG开关控制日志输出 2. 为MissSkillsComp新增道具卡牌使用处理逻辑,支持药水类技能直接给全队施加buff 3. 修复了道具卡牌事件监听绑定错误的问题 4. 新增了hero预制体的meta配置文件 5. 调整了装备预制体的UI布局参数
137 lines
5.0 KiB
TypeScript
137 lines
5.0 KiB
TypeScript
/**
|
||
* BuffManager — buff/debuff 的应用、驱散、查询管理器。
|
||
*
|
||
* 设计说明:
|
||
* - 非 ECS 组件,是普通 class 单例(参考 smc 的单例暴露模式)。
|
||
* - 对外提供 applyBuff / dispel / getStack / hasControl 四组核心能力。
|
||
* - 控制类 buff(冰冻/眩晕)统一写入 BuffComp,由 BuffSystem 计时到期;
|
||
* 旧字段 frost_end_time/stun_end_time 已随 HeroBuffSystem 一并下线。
|
||
*/
|
||
|
||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||
import { BuffCategory, BuffList } from "../common/config/BuffSet";
|
||
import { BuffComp, ActiveBuff } from "./BuffComp";
|
||
import { mLogger } from "../common/Logger";
|
||
|
||
/** Buff 模块调试日志开关 */
|
||
const DEBUG = false;
|
||
|
||
/** applyBuff 的覆盖参数(预留按需覆写持续时间 / 修饰数值) */
|
||
export interface BuffApplyOverrides {
|
||
duration?: number;
|
||
/** 覆写计时 buff 的修饰数值(modifiers.value / tick.damage_or_heal),由药水卡 buff_value 自定义档位 */
|
||
value?: number;
|
||
}
|
||
|
||
class BuffManagerImpl {
|
||
/**
|
||
* 对目标施加一个 buff 实例。
|
||
*
|
||
* 叠层规则:
|
||
* - max_stack === 0:无限叠加,始终 push 新层
|
||
* - existing.length < max_stack:push 新层
|
||
* - 已满:移除最老层(数组首部)后追加新层,保持 FIFO 刷新语义
|
||
*
|
||
* @param target 目标实体
|
||
* @param buffId BuffList 配置 id
|
||
* @param sourceUuid 施法者 uuid(0=系统/无主)
|
||
* @param sourceAp 施法者攻击力快照(用于 DoT 缩放)
|
||
* @param overrides 可选覆写参数
|
||
*/
|
||
applyBuff(target: ecs.Entity, buffId: number, sourceUuid: number = 0, sourceAp: number = 0, overrides?: BuffApplyOverrides): void {
|
||
const cfg = BuffList[buffId];
|
||
if (!cfg) {
|
||
mLogger.warn(true, "BuffManager", `applyBuff: buffId=${buffId} 配置不存在,跳过`);
|
||
return;
|
||
}
|
||
mLogger.log(DEBUG, "BuffManager", `applyBuff: buff=${cfg.name}(${buffId}) target_eid=${target.eid} duration=${overrides?.duration ?? cfg.duration} value_override=${overrides?.value} source_ap=${sourceAp}`);
|
||
|
||
const buffComp = this.ensureBuffComp(target);
|
||
const duration = overrides?.duration ?? cfg.duration;
|
||
|
||
let layers = buffComp.buffs.get(buffId);
|
||
if (!layers) {
|
||
layers = [];
|
||
buffComp.buffs.set(buffId, layers);
|
||
}
|
||
|
||
const newLayer = new ActiveBuff(buffId, duration, sourceUuid, sourceAp, overrides?.value);
|
||
|
||
if (cfg.max_stack === 0 || layers.length < cfg.max_stack) {
|
||
layers.push(newLayer);
|
||
} else {
|
||
layers.shift();
|
||
layers.push(newLayer);
|
||
}
|
||
|
||
buffComp.dirty_buffs = true;
|
||
}
|
||
|
||
/**
|
||
* 驱散目标身上匹配的 buff。
|
||
*
|
||
* @param target 目标实体
|
||
* @param category 仅驱散该类别(不传=所有类别)
|
||
* @param excludeIds 排除的 buff id 列表
|
||
* @returns 移除的 buff 种类数
|
||
*/
|
||
dispel(target: ecs.Entity, category?: BuffCategory, excludeIds?: number[]): number {
|
||
if (!target.has(BuffComp)) return 0;
|
||
const buffComp = target.get(BuffComp);
|
||
|
||
let removedKinds = 0;
|
||
buffComp.buffs.forEach((layers, buffId) => {
|
||
const cfg = BuffList[buffId];
|
||
if (!cfg) return;
|
||
if (excludeIds && excludeIds.includes(buffId)) return;
|
||
if (category !== undefined && cfg.category !== category) return;
|
||
|
||
if (layers.length > 0) removedKinds++;
|
||
buffComp.buffs.delete(buffId);
|
||
});
|
||
|
||
buffComp.dirty_buffs = true;
|
||
return removedKinds;
|
||
}
|
||
|
||
/**
|
||
* 获取目标身上指定 buff 的当前叠层数。
|
||
* @returns 层数(未命中返回 0)
|
||
*/
|
||
getStack(target: ecs.Entity, buffId: number): number {
|
||
if (!target.has(BuffComp)) return 0;
|
||
const buffComp = target.get(BuffComp);
|
||
return buffComp.buffs.get(buffId)?.length ?? 0;
|
||
}
|
||
|
||
/**
|
||
* 判断目标是否处于指定类型的控制状态下。
|
||
* 唯一判定来源:BuffComp 中是否存在对应 control_kind 的活跃控制 buff。
|
||
*/
|
||
hasControl(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;
|
||
}
|
||
|
||
// ==================== 私有方法 ====================
|
||
|
||
/**
|
||
* 确保目标实体拥有 BuffComp,没有则添加。
|
||
*/
|
||
private ensureBuffComp(target: ecs.Entity): BuffComp {
|
||
if (!target.has(BuffComp)) {
|
||
target.add(BuffComp);
|
||
}
|
||
return target.get(BuffComp);
|
||
}
|
||
}
|
||
|
||
/** Buff 管理器单例(全局唯一实例) */
|
||
export const buffManager = new BuffManagerImpl();
|