import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { HeroViewComp } from "./HeroViewComp"; /** * ==================== 伤害事件数据 ==================== * * 单个伤害事件的数据结构 */ export interface DamageEvent { /** 伤害属性数据 */ Attrs: any; /** 施法者ID */ casterEid: number; /** 技能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[] = []; private readIndex: number = 0; /** 队列创建时间 */ createTime: number = 0; /** 是否正在处理中 */ isProcessing: boolean = false; /** 已处理的伤害数量 */ processedCount: number = 0; reset() { this.damageEvents.length = 0; this.readIndex = 0; this.createTime = 0; this.isProcessing = false; this.processedCount = 0; } /** * 添加伤害事件到队列 */ addDamageEvent(attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1): void { const timestamp = Date.now(); const damageEvent: DamageEvent = { Attrs: attrs || null, casterEid: casterEid, s_uuid: s_uuid, timestamp: timestamp, eventId: "", ext_dmg:ext_dmg, dmg_ratio:dmg_ratio, }; this.damageEvents.push(damageEvent); // 如果是第一个伤害事件,记录创建时间 if (this.getRemainingCount() === 1) { this.createTime = timestamp; } } /** * 获取下一个待处理的伤害事件 */ getNextDamageEvent(): DamageEvent | null { if (this.readIndex >= this.damageEvents.length) return null; const event = this.damageEvents[this.readIndex]; this.readIndex += 1; if (this.readIndex >= 32 && this.readIndex * 2 >= this.damageEvents.length) { this.damageEvents = this.damageEvents.slice(this.readIndex); this.readIndex = 0; } return event || null; } /** * 获取队列中剩余的伤害事件数量 */ getRemainingCount(): number { return this.damageEvents.length - this.readIndex; } /** * 检查队列是否为空 */ isEmpty(): boolean { return this.readIndex >= this.damageEvents.length; } /** * 清空队列 */ clear(): void { this.damageEvents.length = 0; this.readIndex = 0; this.processedCount = 0; this.isProcessing = false; } /** * 按时间戳排序伤害事件(可选功能) */ sortByTimestamp(): void { if (this.readIndex > 0) { this.damageEvents = this.damageEvents.slice(this.readIndex); this.readIndex = 0; } this.damageEvents.sort((a, b) => a.timestamp - b.timestamp); } /** * 去除重复的伤害事件(基于eventId) */ removeDuplicates(): void { const seen = new Set(); if (this.readIndex > 0) { this.damageEvents = this.damageEvents.slice(this.readIndex); this.readIndex = 0; } 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.getRemainingCount(), isProcessing: this.isProcessing, createTime: this.createTime }; } } /** * ==================== 伤害队列辅助工具 ==================== */ export class DamageQueueHelper { /** * 为实体添加伤害事件 * 如果实体没有伤害队列组件,会自动创建 */ static addDamageToEntity(entity: ecs.Entity, attrs: any, casterEid: number, 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, casterEid, 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; } }