import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { HeroViewComp } from "./HeroViewComp"; /** * ==================== 伤害事件数据 ==================== * * 单个伤害事件的数据结构 */ export interface DamageEvent { /** 伤害属性数据 */ Attrs: any; /** 施法者 */ caster: HeroViewComp; /** 技能UUID */ s_uuid: number; /** 伤害创建时间戳(用于排序和调试) */ timestamp: number; /** 伤害事件ID(用于去重和调试) */ eventId: string; ext_dmg:number //额外伤害 dmg_ratio:number//伤害比例 } /** * ==================== 伤害队列组件 ==================== * * 用途: * - 存储一个实体在当前帧收到的所有伤害事件 * - 支持批量处理,避免同帧多伤害冲突 * - 提供伤害事件的排序和去重功能 */ @ecs.register('DamageQueue') export class DamageQueueComp extends ecs.Comp { /** 伤害事件队列 */ damageEvents: DamageEvent[] = []; /** 队列创建时间 */ createTime: number = 0; /** 是否正在处理中 */ isProcessing: boolean = false; /** 已处理的伤害数量 */ processedCount: number = 0; reset() { this.damageEvents = []; this.createTime = 0; this.isProcessing = false; this.processedCount = 0; } /** * 添加伤害事件到队列 */ addDamageEvent(attrs: any, caster: HeroViewComp, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1): void { const timestamp = Date.now(); const eventId = `${caster.ent.eid}_${s_uuid}_${timestamp}_${Math.random()}`; const damageEvent: DamageEvent = { Attrs: attrs ? { ...attrs } : null, // 深拷贝属性数据 caster: caster, s_uuid: s_uuid, timestamp: timestamp, eventId: eventId, ext_dmg:ext_dmg, dmg_ratio:dmg_ratio, }; this.damageEvents.push(damageEvent); // 如果是第一个伤害事件,记录创建时间 if (this.damageEvents.length === 1) { this.createTime = timestamp; } } /** * 获取下一个待处理的伤害事件 */ getNextDamageEvent(): DamageEvent | null { if (this.damageEvents.length === 0) return null; return this.damageEvents.shift() || null; } /** * 获取队列中剩余的伤害事件数量 */ getRemainingCount(): number { return this.damageEvents.length; } /** * 检查队列是否为空 */ isEmpty(): boolean { return this.damageEvents.length === 0; } /** * 清空队列 */ clear(): void { this.damageEvents = []; this.processedCount = 0; this.isProcessing = false; } /** * 按时间戳排序伤害事件(可选功能) */ sortByTimestamp(): void { this.damageEvents.sort((a, b) => a.timestamp - b.timestamp); } /** * 去除重复的伤害事件(基于eventId) */ removeDuplicates(): void { const seen = new Set(); this.damageEvents = this.damageEvents.filter(event => { if (seen.has(event.eventId)) { return false; } seen.add(event.eventId); return true; }); } /** * 获取队列统计信息(用于调试) */ getQueueStats(): { totalEvents: number; processedEvents: number; remainingEvents: number; isProcessing: boolean; createTime: number; } { return { totalEvents: this.processedCount + this.damageEvents.length, processedEvents: this.processedCount, remainingEvents: this.damageEvents.length, isProcessing: this.isProcessing, createTime: this.createTime }; } } /** * ==================== 伤害队列辅助工具 ==================== */ export class DamageQueueHelper { /** * 为实体添加伤害事件 * 如果实体没有伤害队列组件,会自动创建 */ static addDamageToEntity(entity: ecs.Entity, attrs: any, caster: HeroViewComp, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1): void { let damageQueue = entity.get(DamageQueueComp); // 如果实体没有伤害队列组件,创建一个 if (!damageQueue) { damageQueue = entity.add(DamageQueueComp); } // 添加伤害事件到队列 damageQueue.addDamageEvent(attrs, caster, s_uuid,ext_dmg,dmg_ratio); } /** * 检查实体是否有待处理的伤害 */ static hasPendingDamage(entity: ecs.Entity): boolean { const damageQueue = entity.get(DamageQueueComp); return damageQueue ? !damageQueue.isEmpty() : false; } /** * 获取实体的伤害队列统计信息 */ static getEntityDamageStats(entity: ecs.Entity): any { const damageQueue = entity.get(DamageQueueComp); return damageQueue ? damageQueue.getQueueStats() : null; } }