123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- /** @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 {ComSkillAbel} from '../components/ComSkillAbel'
- import {ComHasSkill} from '../components/ComHasSkill'
- import {ComFindEnemy} from '../components/ComFindEnemy'
- import {Data} from '../../GameControl'
- import {EventBuffChange} from '../core/NodeEvent'
- import {ComDizzy} from '../components/ComDizzy'
- import {BT} from '../../behaviorTree/BehaviorTree'
- import {ComDie} from '../components/ComDie'
- import {ComAttackable} from '../components/ComAttackable'
- import {Log} from '../../utils/LogUtils'
- import {ROLE_TYPE, SKILL_DIR_TYPE, SKILL_EFFECT_TYPE, SKILL_TYPE} from '../../enums/Enum'
- import {ComBehaviorTree} from '../components/ComBehaviorTree'
- import {ComTransform} from '../components/ComTransform'
- export class SysHasSkill extends ECSSystem {
- FILTER_HAS_SKILL = GenFilterKey([ComHasSkill, ComSkillAbel, ComCocosNode, ComRole, ComBehaviorTree], [ComDie])
- /** 连接 */
- 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 filter = world.getFilter(this.FILTER_HAS_SKILL)
- filter.walk((entity: number) => {
- let comRole = world.getComponent(entity, ComRole)
- let comHasSkill = world.getComponent(entity, ComHasSkill)
- let comSkillAbel = world.getComponent(entity, ComSkillAbel)
- let comDizzy = world.getComponent(entity, ComDizzy)
- let comTransform = world.getComponent(entity, ComTransform)
- //晕眩的时候不判断是否有技能
- if (comDizzy && comDizzy.dirty) return
- // 先判断技能CD
- for (let i = 0; i < comRole.skillCountDowns.length; i++) {
- let skillCfg = comRole.skills[i]
- let skillCObject = comHasSkill.skillCObjects[i]
- //处理光环要处理是否是伤害光环和是否是自己
- if (skillCfg.type == SKILL_TYPE.holo && skillCObject) {
- let canAddBuff = true
- let leftTime = 0
- //绿巨人顶盾才能加光环
- if (skillCfg.effectType.includes(SKILL_EFFECT_TYPE.shieldHolo) && !comSkillAbel.isInShield) {
- canAddBuff = false
- }
- if (comSkillAbel.isInShield) {
- leftTime = comSkillAbel.countDown
- }
- if (canAddBuff) {
- //绘制范围
- world.drawDebug(entity, skillCObject)
- skillCObject.curInBody.forEach(inBody => {
- let inBodyComRole = world.getComponent(inBody, ComRole)
- if (!world.isDie(inBodyComRole)) {
- for (let buffID of skillCfg.buffs) {
- let index = inBodyComRole.buffs.findIndex(v =>
- skillCfg.buffs.includes(v.buffCfg.ID),
- )
- if (
- index < 0 &&
- inBodyComRole.roleCfg.type != ROLE_TYPE.totem &&
- inBodyComRole.roleCfg.type != ROLE_TYPE.base
- ) {
- let buff = world.createBuff(buffID, comRole)
- if (leftTime > 0) {
- buff.countDown = leftTime
- }
- world.addBuff(inBody, buff, comRole)
- }
- }
- }
- })
- }
- skillCObject.curOutBody.forEach(body => {
- let outBodyComRole = world.getComponent(body, ComRole)
- if (!world.isDie(outBodyComRole)) {
- for (let buffID of skillCfg.buffs) {
- let index = outBodyComRole.buffs.findIndex(v => v.buffCfg.ID == buffID)
- if (index >= 0) {
- let removeBuffs = outBodyComRole.buffs.splice(index, 1)
- world.removeBuffAttr(body, removeBuffs[0])
- // world
- // .getComponent(body, ComCocosNode)
- // .events.push(new EventBuffChange(outBodyComRole.buffs, [], removeBuffs))
- }
- }
- }
- })
- continue
- }
- //处理非光环可以施放的技能
- comRole.skillCountDowns[i] -= dt
- //先判断角色不是在放技能,技能CD好了,特定技能达成条件可以施放
- if (comRole.skillCountDowns[i] <= 0 && !comSkillAbel.dirty) {
- if (
- skillCfg.minRole <= 0 &&
- skillCfg.type != SKILL_TYPE.createRole &&
- skillCfg.type != SKILL_TYPE.transRole
- ) {
- Log.error('非召唤技能,变身技能配置错误,没有角色最小数量', JSON.stringify(skillCfg))
- continue
- }
- if (skillCfg.dirType == SKILL_DIR_TYPE.baby && comRole.babys.length == 0) {
- //没有宝宝可以释放技能
- continue
- }
- if (skillCfg.type == SKILL_TYPE.createRole) {
- if (
- skillCfg.createMax > 0 &&
- comRole.babys.filter(
- baby => world.getComponent(baby, ComRole)?.roleCfg.ID == skillCfg.createRole[0],
- ).length >= skillCfg.createMax
- ) {
- //宝宝达到召唤上限 将CD设为最大值,等有宝宝死亡,再重置CD
- comRole.skillCountDowns[i] = Infinity
- continue
- }
- //召唤一次后不能再召唤
- if (skillCfg.createMax <= 0) {
- comRole.skillCountDowns[i] = Infinity
- }
- }
- skillCObject.containsBody.forEach((value, key) => {
- if (world.isDie(key) || world.isEnter(key)) {
- skillCObject.containsBody.delete(key)
- }
- })
- if (skillCObject.containsBody.size >= skillCfg.minRole) {
- let containsArr = skillCObject.containsBody.keysArr()
- for (let i = containsArr.length - 1; i >= 0; i--) {
- let targetComRole = world.getComponent(containsArr[i], ComRole)
- if (world.isBase(targetComRole)) {
- containsArr.splice(i, 1)
- }
- }
- containsArr.outOrder()
- if (skillCfg.type == SKILL_TYPE.moveBack) {
- // 检测背刺的时候自己没有打人,没有将要打人,没有将要被打,没有被近战打, 敌人正在攻击
- let comFindEnemy = world.getComponent(entity, ComFindEnemy)
- let comAttackable = world.getComponent(entity, ComAttackable)
- // 检测背刺的时候自己没有打人,没有将要打人,没有将要被打,没有被近战打
- if (
- comAttackable.curAttack ||
- comFindEnemy.willAttackMelee ||
- comFindEnemy.willBeAttackMelee ||
- comAttackable.beAttacks.length > 0
- ) {
- continue
- }
- //敌军:敌军不是正在攻击目标或者是有背刺技能的敌人不触发背刺,敌军死亡不触发背刺
- for (let i = containsArr.length - 1; i >= 0; i--) {
- let targetComAttackable = world.getComponent(containsArr[i], ComAttackable)
- let targetComRole = world.getComponent(containsArr[i], ComRole)
- if (
- targetComAttackable.beAttacks.length == 0 ||
- targetComRole.skills.find(v => v.type == SKILL_TYPE.moveBack)
- ) {
- containsArr.splice(i, 1)
- }
- }
- }
- if (skillCfg.dirType == SKILL_DIR_TYPE.minHpRole) {
- containsArr.sort((a, b) => {
- let aComAttackable = world.getComponent(a, ComAttackable)
- let bComAttackable = world.getComponent(b, ComAttackable)
- if (aComAttackable.isMelee != bComAttackable.isMelee) {
- return Number(bComAttackable.isMelee) - Number(aComAttackable.isMelee)
- } else {
- let aComRole = world.getComponent(a, ComRole)
- let bComRole = world.getComponent(b, ComRole)
- return aComRole.nowHP / aComRole.HP - bComRole.nowHP / bComRole.HP
- }
- })
- if (containsArr.length > 1) containsArr.length = 1
- } else if (
- skillCfg.dirType == SKILL_DIR_TYPE.selfRole ||
- skillCfg.dirType == SKILL_DIR_TYPE.selfNormal
- ) {
- containsArr.length = 0
- containsArr.push(entity)
- //顶盾不能在前往攻击点施放
- if (skillCfg.type == SKILL_TYPE.shield) {
- let comFindEnemy = world.getComponent(entity, ComFindEnemy)
- if (comFindEnemy?.willAttackMelee) {
- containsArr.length = 0
- }
- }
- } else if (skillCfg.dirType == SKILL_DIR_TYPE.maxDistance) {
- let selfPos = cc.v2(comTransform.x, comTransform.y)
- containsArr.sort((a, b) => {
- //按照距离排序
- let aComTrans = world.getComponent(a, ComTransform)
- let bComTrans = world.getComponent(b, ComTransform)
- if (aComTrans && bComTrans) {
- let aPos = cc.v2(aComTrans.x, aComTrans.y)
- let bPos = cc.v2(bComTrans.x, bComTrans.y)
- return bPos.sub(selfPos).mag() - aPos.subtract(selfPos).mag()
- } else {
- return 0
- }
- })
- }
- // 没有施放目标,判断下一个技能
- if (containsArr.length <= 0 && skillCfg.minRole > 0) continue
- comSkillAbel.skillConfig = skillCfg
- comSkillAbel.roles.length = 0
- if (
- skillCfg.dirType == SKILL_DIR_TYPE.normal ||
- skillCfg.dirType == SKILL_DIR_TYPE.selfNormal ||
- skillCfg.dirType == SKILL_DIR_TYPE.selfRole ||
- skillCfg.dirType == SKILL_DIR_TYPE.anyRole ||
- skillCfg.dirType == SKILL_DIR_TYPE.minHpRole ||
- skillCfg.dirType == SKILL_DIR_TYPE.maxDistance
- ) {
- if (containsArr[0]) comSkillAbel.roles.push(containsArr[0])
- } else if (skillCfg.dirType == SKILL_DIR_TYPE.baby) {
- comRole.babys.forEach(baby => comSkillAbel.roles.push(baby))
- }
- break
- }
- }
- }
- return false
- })
- }
- }
|