/** @format */ import {ComRole} from '../components/ComRole' import {ECSSystem} from '../lib/ECSSystem' import {GenFilterKey} from '../lib/ECSComponent' import {FightWorld} from '../worlds/FightWorld' import {ComCocosNode} from '../components/ComCocosNode' import {ComSkill} from '../components/ComSkill' import {cCollider} from '../../collision/Collider' import {ComTransform} from '../components/ComTransform' import {Log} from '../../utils/LogUtils' import { BUFF_EFFECT_TYPE, BUFF_TYPE, HIT_ANI_TYPE, NEGATIVE_TYPE, ROLE_TYPE, SKILL_DIR_TYPE, SKILL_EFFECT_TYPE, SKILL_TYPE, } from '../../enums/Enum' import {ComFindEnemy} from '../components/ComFindEnemy' import {Data} from '../../GameControl' import {ComAttackable} from '../components/ComAttackable' import {ComSkillAbel} from '../components/ComSkillAbel' import {SkillConfig} from '../../config/SkillConfig' import {cObject} from '../../collision/Object' import {ComMovable} from '../components/ComMovable' import {FrameAniConfig} from '../../config/FrameAniConfig' import {ComHasSkill} from '../components/ComHasSkill' const FILTER_SKILL = GenFilterKey([ComSkill, ComTransform, ComCocosNode]) export class SysSkill extends ECSSystem { /** 连接 */ public onAdd(world: FightWorld): void {} /** 断开连接 */ public onRemove(world: FightWorld): void {} /** 添加实体 */ public onEntityEnter(world: FightWorld, entity: number): void {} /** */ public onEntityLeave(world: FightWorld, entity: number): void {} /** 更新 */ public onUpdate(world: FightWorld, dt: number): void { let filterSkill = world.getFilter(FILTER_SKILL) //持续技能 filterSkill.walk((entity: number) => { let comCocosNode = world.getComponent(entity, ComCocosNode) if (!comCocosNode.loaded) return let comSkill = world.getComponent(entity, ComSkill) let targetRole = world.getComponent(comSkill.role, ComRole) let comTransform = world.getComponent(entity, ComTransform) // 释放完的技能不再处理 if (!comSkill.dirty) return let isOneRole = world.isOneRoleSkill(comSkill.skillCfg) //当技能是指向技能,目标死亡了,移除这个技能 if (world.isDie(targetRole) && isOneRole) { world.removeSkillEntity(entity) return } comSkill.countDown -= dt if (isOneRole) { let targetComTransform = world.getComponent(comSkill.role, ComTransform) comTransform.x = targetComTransform.x + comSkill.skillCfg.offsetPos[1] comTransform.y = targetComTransform.y + targetComTransform.halfHeight * (comSkill.skillCfg.offsetPos[0] - 1) + comSkill.skillCfg.offsetPos[2] } let changeHpCb = entity => { let comHurtRole = world.getComponent(entity, ComRole) if (world.isDie(comHurtRole)) return let hpRateHurt = 0 let isHurt = true //加BUFF let buffs = [] for (let buffID of comSkill.skillCfg.buffs) { buffs.push(world.createBuff(buffID, comSkill.fightData)) } if (comSkill.skillCfg.type != SKILL_TYPE.holo && buffs.length > 0) { for (let buff of buffs) { world.addBuff(entity, buff, comSkill.fightData) } } for (let i = 0; i < comSkill.skillCfg.effectType.length; i++) { let type = comSkill.skillCfg.effectType[i] if (type == SKILL_EFFECT_TYPE.rateHpHurt) { hpRateHurt = comSkill.skillCfg.effectParm[i][0] } } for (let i = 0; i < comHurtRole.buffs.length; i++) { for (let j = 0; j < comHurtRole.buffs[i].buffCfg.effectType.length; j++) { let type = comHurtRole.buffs[i].buffCfg.effectType[j] if ( type == BUFF_EFFECT_TYPE.immune && comHurtRole.buffs[i].buffCfg.effectParm[j].slice(0).includes(comSkill.skillCfg.ID) ) { if (comHurtRole.buffs[i].immuneTimes < comHurtRole.buffs[i].buffCfg.effectParm[j][0]) { comHurtRole.buffs[i].immuneTimes += 1 } else { isHurt = false } } } } if (isHurt) { //百分比伤害加上固定伤害 if (hpRateHurt > 0) { //受击特效统一处理,这里是0 world.changeHpByHurt(entity, (comHurtRole.HP * hpRateHurt) / Data.game.rateNum, false, 0) } world.changeHpBySkill(comSkill, entity) } if (comSkill.skillCfg.hitID[HIT_ANI_TYPE.role]) { world.createAni(comSkill.skillCfg.hitID[HIT_ANI_TYPE.role], entity) } } if (comSkill.skillCfg.type == SKILL_TYPE.attackBack) { comSkill.cObject.containsBody.forEach((cbody, bodyEntity) => { let comBackRole = world.getComponent(bodyEntity, ComRole) if (world.isDie(comBackRole) || world.isEnter(bodyEntity)) return changeHpCb(bodyEntity) let comBackTransform = world.getComponent(bodyEntity, ComTransform) //免疫击退效果 if ( comBackRole.buffs.some(buff => { let buffCfg = buff.buffCfg return ( buffCfg.buffType == BUFF_TYPE.negativeImmune && buffCfg.effectParm[ buffCfg.effectType.indexOf(BUFF_EFFECT_TYPE.immuneNegative) ]?.includes(NEGATIVE_TYPE.back) ) }) ) { return } let comBackFindEnemy = world.getComponent(bodyEntity, ComFindEnemy) let comBackAttackable = world.getComponent(bodyEntity, ComAttackable) let comBackSkillAbel = world.getComponent(bodyEntity, ComSkillAbel) let comBackCocosNode = world.getComponent(bodyEntity, ComCocosNode) let comBackHasSkill = world.getComponent(bodyEntity, ComHasSkill) // 修改X位置 --->修改成跟随技能一起移动 超过战场不动了 if ( (comTransform.x + comSkill.skillCfg.attackRangeX / 2 >= Data.game.fightSizeMaxX && comBackRole.group != Data.game.gFriend) || (comTransform.x - comSkill.skillCfg.attackRangeX / 2 <= Data.game.fightSizeMinX && comBackRole.group == Data.game.gFriend) ) { return } comBackTransform.x = comTransform.x + ((comBackRole.group == Data.game.gFriend ? -1 : 1) * comSkill.skillCfg.attackRangeX) / 2 let spineComTransform = world.getComponent(comBackRole.spineEntity, ComTransform) spineComTransform.x = comBackTransform.x // 此处必须让所有的cObject位置更新 comBackCocosNode.node?.getComponents(cObject).forEach(cObject => { cObject.setPosition(cc.v3(comBackTransform.x, comTransform.y, 0)) }) // 移除自己的寻敌 comBackFindEnemy.enemy = 0 // 移除自己即将攻击 敌方即将被攻击 let enemyComFindEnemy = world.getComponent(comBackFindEnemy.willAttackMelee, ComFindEnemy) if (enemyComFindEnemy) enemyComFindEnemy.willBeAttackMelee = 0 comBackFindEnemy.willAttackMelee = 0 // 移除自己被即将攻击 敌方即将攻击 enemyComFindEnemy = world.getComponent(comBackFindEnemy.willBeAttackMelee, ComFindEnemy) if (enemyComFindEnemy) enemyComFindEnemy.willAttackMelee = 0 comBackFindEnemy.willBeAttackMelee = 0 //移除自己的攻击 comBackAttackable.curAttack = 0 //移除近战包围圈 comBackAttackable.beAttacks.forEach(entity => { let beAttackComAttackable = world.getComponent(entity, ComAttackable) if (beAttackComAttackable) beAttackComAttackable.curAttack = 0 }) //移除顶盾技能 comBackSkillAbel.isInShield = false let findIndex = comBackRole.buffs.findIndex( value => value.buffCfg.buffType == BUFF_TYPE.shieldReduceHurt, ) if (findIndex != -1) { //将顶盾的buff去掉 comBackRole.buffs.splice(findIndex, 1) //将顶盾的罩子,友军免疫远程攻击buff去掉 world.removeNodeEntity(comBackSkillAbel.ani) let skillIndex = comBackRole.skills.findIndex(v => v.type == SKILL_TYPE.holo) if (skillIndex >= 0) { let allEntity = Array.from(comBackHasSkill.skillCObjects[skillIndex].containsBody.keys()) allEntity = allEntity.filter(entityTmp => !world.isDie(entityTmp)) allEntity.forEach(v => { let tmpComRole = world.getComponent(v, ComRole) let findIndex = tmpComRole.buffs.findIndex( value => value.buffCfg.buffType == BUFF_TYPE.rangedImmune, ) if (findIndex != -1) { console.warn('去掉免疫buff') tmpComRole.buffs.splice(findIndex, 1) } }) } } //将技能弹射子弹去除 if (comBackSkillAbel.bullets) { comBackSkillAbel.bullets.forEach(v => { world.removeBulletEntity(v) }) comBackSkillAbel.bullets.length = 0 } //打断技能 comBackSkillAbel.skillConfig = null comBackSkillAbel.roles.length = 0 comBackSkillAbel.dirty = false }) } else if (!comSkill.hurtFrameCompleted && comSkill.countDown <= comSkill.skillCfg.hurtFrame) { comSkill.hurtFrameCompleted = true if (isOneRole) { changeHpCb(comSkill.role) } else { let allEntity = Array.from(comSkill.cObject.containsBody.keys()) allEntity = allEntity.filter(entityTmp => !world.isDie(entityTmp)) for (let i = 0; i < Math.min(allEntity.length, comSkill.skillCfg.maxRole); i++) { changeHpCb(allEntity[i]) } } } // 时间到的技能移除 if (comSkill.countDown <= 0) { comSkill.dirty = false world.removeSkillEntity(entity) return } //绘制范围 world.drawDebug(entity, comSkill.cObject) return false }) } }