import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { FacSet } from "../common/config/BoxSet"; import { Attrs } from "../common/config/HeroAttrs"; import { FightSet } from "../common/config/Mission"; import { SkillSet } from "../common/config/SkillSet"; import { DmgDataCom } from "../skill/SDataCom"; import { HeroAttrsComp } from "./HeroAttrsComp"; import { HeroViewComp } from "./HeroViewComp"; /** 业务层对象 */ @ecs.register('HeroAtk') export class HeroAtkComp extends ecs.Comp { /** 业务层组件移除时,重置所有数据为默认值 */ reset() { } } interface FDData{ damage:number, isCrit:boolean, isDodge:boolean, } /** 业务层业务逻辑处理对象 伤害处理系统 */ @ecs.register('HeroAtkSystem') export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate, ecs.IEntityEnterSystem { private debugMode: boolean = false; // 是否启用调试模式 /** * 过滤器:只处理拥有伤害数据的实体 */ filter(): ecs.IMatcher { return ecs.allOf(HeroAttrsComp, DmgDataCom); } /** * 实体首次进入系统时调用(每个实体只调用一次) */ entityEnter(e: ecs.Entity): void { const model = e.get(HeroAttrsComp); const dmgData = e.get(DmgDataCom); if (!model || !dmgData) return; const caster = dmgData.caster; // 深度拷贝伤害数据,避免组件移除后数据丢失 const dmgDataCopy = this.deepCopyDmgData(dmgData); // 立即移除组件,避免重复处理 e.remove(DmgDataCom); // 使用拷贝的数据进行伤害计算 let FDData = this.doAttack(e, dmgDataCopy); console.log(`[HeroAtkSystem] 英雄${model.hero_name} (uuid: ${model.hero_uuid}) 受到 ${caster.ent.get(HeroAttrsComp).hero_name}(uuid: ${caster.ent.get(HeroAttrsComp).hero_uuid})的 伤害 ${FDData.damage},${FDData.isCrit?"暴击":"普通"}攻击,技能ID ${dmgDataCopy.s_uuid}`); } /** * 深度拷贝伤害数据 */ private deepCopyDmgData(dmgData: DmgDataCom): any { return { Attrs: dmgData.Attrs ? { ...dmgData.Attrs } : null, s_uuid: dmgData.s_uuid }; } /** * 处理角色被攻击 * @param target 被攻击的目标实体 * @param dmgData 伤害数据(可以是组件或拷贝的对象) * @returns 实际造成的伤害 */ public doAttack(target: ecs.Entity, dmgDataCopy: any): FDData { const targetModel = target.get(HeroAttrsComp); const targetView = target.get(HeroViewComp); let reDate:FDData={ damage:0, isCrit:false, isDodge:false, } if (!targetModel || targetModel.is_dead) return reDate; // 获取技能配置 const skillConf = SkillSet[dmgDataCopy.s_uuid]; if (!skillConf) return reDate; // 触发被攻击事件 this.onAttacked(target); // 闪避判定 if (this.checkDodge(targetModel)) { // TODO: 触发闪避视图表现 reDate.isDodge=true; return reDate; } // 暴击判定 const isCrit = this.checkCrit(targetModel.Attrs[Attrs.CRITICAL]); let damage = this.dmgCount(dmgDataCopy.Attrs,dmgDataCopy.s_uuid); if (isCrit) { damage = Math.floor(damage * (1 + (FightSet.CRIT_DAMAGE + targetModel.Attrs[Attrs.CRITICAL_DMG]) / 100)); reDate.isCrit=true; } // 伤害计算(考虑易伤等debuff) damage = this.calculateDamage(targetModel, damage); // 护盾吸收 damage =Math.floor(this.absorbShield(targetModel, damage)) if (damage <= 0) return reDate; // 应用伤害到数据层 targetModel.hp -= damage; targetModel.atked_count++; // ✅ 触发视图层表现(伤害数字、受击动画、后退) if (targetView) { targetView.do_atked(damage, isCrit, dmgDataCopy.s_uuid); } // 检查死亡 if (targetModel.hp <= 0) { this.doDead(target); // ✅ 触发死亡视图表现 if (targetView) { targetView.do_dead(); } } if (this.debugMode) { console.log(`[HeroAtkSystem] ${targetModel.hero_name} 受到 ${damage} 点伤害 (暴击: ${isCrit})`); } reDate.damage=damage; return reDate; } //伤害计算,暂时简单计算 private dmgCount(CAttrs:any,s_uuid:number){ let sConf = SkillSet[s_uuid]; if (!sConf) return 0; let AP = sConf.ap*CAttrs[Attrs.AP]/100; return AP; } /** * 处理角色死亡 */ private doDead(entity: ecs.Entity): void { const model = entity.get(HeroAttrsComp); if (!model || model.is_dead) return; model.is_dead = true; // 触发死亡事件 this.onDeath(entity); if (this.debugMode) { console.log(`[HeroBattleSystem] ${model.hero_name} 死亡`); } } /** * 闪避判定 */ private checkDodge(model: HeroAttrsComp): boolean { if (model.Attrs[Attrs.DODGE] > 0) { const random = Math.random() * 100; if (random < model.Attrs[Attrs.DODGE]) { if (this.debugMode) { console.log(`[HeroBattleSystem] ${model.hero_name} 闪避了攻击`); } return true; } } return false; } /** * 暴击判定 */ private checkCrit(critRate: number): boolean { if (critRate > 0) { const random = Math.random() * 100; return random < critRate; } return false; } /** * 伤害计算(考虑易伤等debuff) */ private calculateDamage(model: HeroAttrsComp, baseDamage: number): number { // 这里可以添加易伤等debuff的计算逻辑 // 例如:如果目标有易伤buff,增加受到的伤害 return baseDamage; } /** * 护盾吸收伤害 */ private absorbShield(model: HeroAttrsComp, damage: number): number { if (model.shield <= 0) return damage; if (model.shield >= damage) { model.shield -= damage; if (model.shield <= 0) { model.shield = 0; model.Attrs[Attrs.SHIELD_MAX] = 0; } return 0; } else { const remainingDamage = damage - model.shield; model.shield = 0; model.Attrs[Attrs.SHIELD_MAX] = 0; return remainingDamage; } } /** * 被攻击时触发的事件 */ private onAttacked(entity: ecs.Entity): void { const model = entity.get(HeroAttrsComp); if (!model || model.is_dead) return; // 这里可以添加被攻击时的特殊处理逻辑 if (model.fac === FacSet.MON) return; // 例如:触发某些天赋效果、反击逻辑等 } /** * 死亡时触发的事件 */ private onDeath(entity: ecs.Entity): void { const model = entity.get(HeroAttrsComp); if (!model) return; if (model.fac === FacSet.MON) { // 怪物死亡处理 this.scheduleDrop(entity); } else if (model.fac === FacSet.HERO) { // 英雄死亡处理 this.scheduleHeroDeath(entity); } } /** * 延迟执行掉落逻辑 */ private scheduleDrop(entity: ecs.Entity): void { // 这里可以添加掉落逻辑 // 例如:延迟一段时间后生成掉落物品 } /** * 延迟执行英雄死亡逻辑 */ private scheduleHeroDeath(entity: ecs.Entity): void { // 这里可以添加英雄死亡的特殊处理 // 例如:触发游戏结束、复活机制等 } /** * 启用调试模式 */ enableDebug() { this.debugMode = true; } /** * 禁用调试模式 */ disableDebug() { this.debugMode = false; } /** * 系统更新(每帧调用) * 可以在这里添加需要每帧处理的战斗逻辑 */ update(e: ecs.Entity): void { // 这里可以添加需要每帧处理的战斗逻辑 // 例如:持续伤害、战斗状态检查等 } }