/** @format */ import {EventDie, EventHPChange} from '../core/NodeEvent' import {ComAttackable} from '../components/ComAttackable' import {ComBehaviorTree} from '../components/ComBehaviorTree' import {ComCocosNode} from '../components/ComCocosNode' import {ComMovable} from '../components/ComMovable' import {ComRole} from '../components/ComRole' import {ECSSystem} from '../lib/ECSSystem' import {GenFilterKey} from '../lib/ECSComponent' import {FightWorld} from '../worlds/FightWorld' import {ComFindEnemy} from '../components/ComFindEnemy' import {ComDie} from '../components/ComDie' import {cCollider} from '../../collision/Collider' import {ccUtils} from '../../utils/ccUtils' import {ComTransform} from '../components/ComTransform' import {ComHasSkill} from '../components/ComHasSkill' import {ComSkillAbel} from '../components/ComSkillAbel' import {Data} from '../../GameControl' import {ComLifeTime} from '../components/ComLifeTime' import {ComFriend} from '../components/ComFriend' import {ComEnemy} from '../components/ComEnemy' import {ComDizzy} from '../components/ComDizzy' import {ATTR_NAME, ENTRY, MONSTER_TYPE, ROLE_TYPE, SKILL_TYPE} from '../../enums/Enum' import {EntryObj} from '../core/GameInterface' import {ComFrameAni} from '../components/ComFrameAni' export const FILTER_ROLE_NODE = GenFilterKey( [ComCocosNode, ComRole, ComMovable, ComAttackable, ComFindEnemy, ComTransform, ComBehaviorTree], [ComDie], ) export class SysRoleState 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 { world.getFilter(FILTER_ROLE_NODE).walk((entity: number) => { let comCocosNode = world.getComponent(entity, ComCocosNode) if (!comCocosNode.loaded) return let comRole = world.getComponent(entity, ComRole) let comAttackable = world.getComponent(entity, ComAttackable) let comFindEnemy = world.getComponent(entity, ComFindEnemy) let comHasSkill = world.getComponent(entity, ComHasSkill) let comSkillAbel = world.getComponent(entity, ComSkillAbel) ccUtils.setLabel( CC_DEV && cc.debug.isDisplayStats() ? `ID:${entity}${comFindEnemy.enemy ? '寻敌:' + comFindEnemy.enemy : ''}${ comFindEnemy.willAttackMelee ? '将攻:' + comFindEnemy.willAttackMelee : '' }${comFindEnemy.willBeAttackMelee ? '将被攻:' + comFindEnemy.willBeAttackMelee : ''}${ comAttackable.curAttack ? '攻击:' + comAttackable.curAttack : '' }${comAttackable.beAttacks.length > 0 ? '被包围:' + comAttackable.beAttacks : ''}` : '', comCocosNode.node, 'entity', ) if (comRole && comRole.HPDirty) { let hpRate = Math.floor((comRole.nowHP / comRole.HP) * 100) if (world.isBase(comRole)) { } else if (world.isBoss(comRole)) { world.fightCore.showBossHP(comRole) } let keys = Object.keys(ATTR_NAME) let attrAddByHpChangeCb = (entryObj: EntryObj, isMore: boolean) => { if (entryObj) { for (let i = 0; i < entryObj.numArr.length; i++) { let params = entryObj.numArr[i] let canAdd = (isMore && hpRate > params[0]) || (!isMore && hpRate < params[0]) if (canAdd) { if (!entryObj.num) { entryObj.num = (comRole.roleCfg[keys[params[1] - 1]] * params[2]) / Data.game.rateNum comRole[keys[params[1] - 1]] += entryObj.num } } else if (entryObj.num) { //扣除加的值 comRole[keys[params[1] - 1]] -= entryObj.num entryObj.num = 0 } } } } attrAddByHpChangeCb(comRole.entryMap.get(ENTRY.moreThanHPAttr), true) attrAddByHpChangeCb(comRole.entryMap.get(ENTRY.belowHPAttr), false) comCocosNode.events.push( new EventHPChange( comRole.HP, comRole.lastHP, comRole.nowHP, comRole.lastShieldHP, comRole.shieldHP, ), ) if (!world.fightCore.gameOver && world.fightCore.teamEntity.includes(entity)) { world.fightCore.changeTeamHp() } if (world.isDie(comRole)) { if (!world.fightCore.gameOver) { if (world.isBase(comRole)) { let isWin = comRole.group == Data.game.gEnemy } else if ( (comRole.roleCfg.type == MONSTER_TYPE.boss || comRole.roleCfg.type == MONSTER_TYPE.elite || comRole.roleCfg.type == MONSTER_TYPE.normal) && !comRole.isExtraEnemy && !world.fightCore.gameOver ) { if (comRole.roleCfg.type == MONSTER_TYPE.elite) { world.fightCore.eliteNum += 1 } else if (comRole.roleCfg.type == MONSTER_TYPE.boss) { world.fightCore.bossNum += 1 world.fightCore.hideBossHP() } else if (comRole.roleCfg.type == MONSTER_TYPE.normal) { world.fightCore.monsterNum += 1 } let comTrans = world.getComponent(entity, ComTransform) world.fightCore.changeKillNum() } } //从敌方近战敌人攻击数组中移除 if (comAttackable.isMelee && comAttackable.curAttack) { let enemyComMovable = world.getComponent(comAttackable.curAttack, ComMovable) if (enemyComMovable) { let isLeftIndex = enemyComMovable.leftMeleeEnemiesPosDirty.indexOf(entity) if (isLeftIndex >= 0) { enemyComMovable.leftMeleeEnemiesPosDirty.splice(isLeftIndex, 1) } else { let isRightIndex = enemyComMovable.rightMeleeEnemiesPosDirty.indexOf(entity) if (isRightIndex >= 0) enemyComMovable.leftMeleeEnemiesPosDirty.splice(isRightIndex, 1) } } } //从召唤者数组中移除 if (comRole.parent > 0) { let createRole = world.getComponent(comRole.parent, ComRole) if (!world.isDie(createRole)) { createRole.babys.splice(createRole.babys.indexOf(entity), 1) //宝宝达到召唤上限 将CD设为最大值,等有宝宝死亡,再重置CD createRole.skillCountDowns.forEach((value, skillIndex) => { let skillCfg = createRole.skills[skillIndex] if ( skillCfg.type == SKILL_TYPE.createRole && skillCfg.createRole[0] == comRole.roleCfg.ID && skillCfg.createMax > 0 && createRole.babys.filter( baby => world.getComponent(baby, ComRole)?.roleCfg.ID == skillCfg.createRole[0], ).length < skillCfg.createMax && value == Infinity ) { createRole.skillCountDowns[skillIndex] = createRole.skillCDs[skillIndex] } }) } } let comSpineNode = world.getComponent(comRole.spineEntity, ComCocosNode) if (!comRole.transDirty) { comCocosNode.events.push(new EventDie()) //同步spine死亡 comSpineNode?.events.push(new EventDie()) } world.fightCore.handleDie(entity) //移除buff特效 for (let buff of comRole.buffs) { for (let aniEntity of buff.aniEntityArr) { let comFrameAni = world.getComponent(aniEntity, ComFrameAni) if (comFrameAni) comFrameAni.countDown = 0 } } //移除有碰撞体的组件 world.removeComponent(entity, ComRole) cCollider.inst.remove(comRole.cObject.body) comCocosNode.node.removeComponent(comRole.cObject) comRole.cObject = null world.removeComponent(entity, ComFindEnemy) cCollider.inst.remove(comFindEnemy.cObject.body) cCollider.inst.remove(comFindEnemy.attackCObject.body) comCocosNode.node.removeComponent(comFindEnemy.cObject) comCocosNode.node.removeComponent(comFindEnemy.attackCObject) comFindEnemy.cObject = null comFindEnemy.attackCObject = null if (comFindEnemy.cObjectMeleeX) { cCollider.inst.remove(comFindEnemy.cObjectMeleeX.body) comCocosNode.node.removeComponent(comFindEnemy.cObjectMeleeX) comFindEnemy.cObjectMeleeX = null } world.removeComponent(entity, ComHasSkill) comHasSkill.skillCObjects.forEach(skillCObject => { if (skillCObject) { cCollider.inst.remove(skillCObject.body) comCocosNode.node.removeComponent(skillCObject) } }) //移除其他可能有的组件 world.removeComponent(entity, ComBehaviorTree) world.removeComponent(entity, ComAttackable) world.removeComponent(entity, ComMovable) if (comSkillAbel.bullets) { comSkillAbel.bullets.forEach(v => { world.removeBulletEntity(v) }) comSkillAbel.bullets.length = 0 } world.removeComponent(entity, ComSkillAbel) world.removeComponent(entity, ComFriend) world.removeComponent(entity, ComEnemy) world.removeComponent(entity, ComDizzy) world.removeComponent(entity, ComLifeTime) if (comRole.transDirty) { comRole.transDirty = false world.removeNodeEntity(entity) if (comSpineNode) { world.removeNodeEntity(comRole.spineEntity) } } else { let comDie = world.addComponent(entity, ComDie) comDie.countDown = comRole.dieTime > 0 ? 1 : 0 comDie.spineEntity = comRole.spineEntity } } comRole.HPDirty = false } return false }) } }