123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- /** @format */
- import {ComAttackable} from '../components/ComAttackable'
- import {ComRole} from '../components/ComRole'
- import {ComTransform} from '../components/ComTransform'
- import {ECSSystem} from '../lib/ECSSystem'
- import {FightWorld} from '../worlds/FightWorld'
- import {ComFindEnemy} from '../components/ComFindEnemy'
- import {ComCocosNode} from '../components/ComCocosNode'
- import {Data, Mgr} from '../../GameControl'
- import {cBody} from '../../collision/Body'
- import {ComDie} from '../components/ComDie'
- import {GenFilterKey} from '../lib/ECSComponent'
- import {EventRoleTip} from '../core/NodeEvent'
- import {BUFF_TYPE, ENTRY, FRAME_ANI_NAME, GAME_ROLE_TIP} from '../../enums/Enum'
- import {IAttackEffect} from '../core/GameInterface'
- import {ComBullet} from '../components/ComBullet'
- import {ComBehaviorTree} from '../components/ComBehaviorTree'
- const FILTER_ATTACKABLE = GenFilterKey([ComTransform, ComAttackable, ComRole, ComCocosNode, ComBehaviorTree], [ComDie])
- export class SysAttack 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 filter = world.getFilter(FILTER_ATTACKABLE)
- let rate = Data.game.rateNum
- filter.walk((entity: number) => {
- let comRole = world.getComponent(entity, ComRole)
- let comAttackable = world.getComponent(entity, ComAttackable)
- let comTransform = world.getComponent(entity, ComTransform)
- let comCocosNode = world.getComponent(entity, ComCocosNode)
- if (!comAttackable.dirty) return
- comAttackable.countDown -= dt
- if (comAttackable.countDown <= 0) {
- comAttackable.dirty = false
- }
- if (!comAttackable.hurtFrameCompleted && comAttackable.countDown <= comAttackable.hurtFrame) {
- let comFindEnemy = world.getComponent(entity, ComFindEnemy)
- let comRoleEnemy = world.getComponent(comAttackable.curAttack, ComRole)
- let comTransformEnemy = world.getComponent(comAttackable.curAttack, ComTransform)
- if (world.isDie(comAttackable.curAttack)) return
- comAttackable.hurtFrameCompleted = true
- comRole.attackNum += 1
- let iAttack: IAttackEffect = {
- isCrit: Math.getProb(comRole.attackCrit / rate),
- isBack: Math.sign(comTransform.dir.x) == Math.sign(comTransformEnemy.dir.x),
- }
- //闪避率=1-(1+命中/10000)*(1-闪避/10000) 闪避率0%-90%
- let dodgeRate = 1 - (1 + comRole.hit / Data.game.rateNum) * (1 - comRoleEnemy.dodge / Data.game.rateNum)
- dodgeRate = Math.max(dodgeRate, 0)
- dodgeRate = Math.min(dodgeRate, 0.9)
- let isDodge = comRoleEnemy && Math.getProb(dodgeRate)
- let hurt = 0
- let isKill = false
- if (comAttackable.isMelee) {
- hurt = world.getHurtByAttackRole(comRole, comAttackable.curAttack, iAttack)
- Mgr.audio.playSFX(comRole.roleCfg.sound)
- if (!isDodge) {
- if (hurt > 0) {
- //被反弹伤害
- world.changeHpByRebound(entity, comAttackable.curAttack)
- //普攻吸血
- if (comRole.entryMap.get(ENTRY.hurt2HP)?.num > 0) {
- let addHPNum = (comRole.entryMap.get(ENTRY.hurt2HP).num * hurt) / Data.game.rateNum
- world.addHP(addHPNum, entity)
- }
- }
- // world.changeHpByHurt(
- // comAttackable.curAttack,
- // hurt,
- // iAttack.isCrit,
- // comRole.roleCfg.hitID ? comRole.roleCfg.hitID : FRAME_ANI_NAME.normalHurt,
- // )
- //临时屏蔽近战攻击特效
- world.changeHpByHurt(comAttackable.curAttack, hurt, iAttack.isCrit, comRole.roleCfg.hitID)
- //杀人+1
- if (world.isDie(comRoleEnemy)) {
- comRole.killNum += 1
- isKill = true
- }
- } else {
- let curAttackCocosNode = world.getComponent(comAttackable.curAttack, ComCocosNode)
- curAttackCocosNode.events.push(new EventRoleTip(GAME_ROLE_TIP.missTip, 0, 'miss'))
- }
- //处理近战buff
- comRole.buffs.forEach(buff => {
- let buffConfig = buff.buffCfg
- if (
- (buffConfig.buffType == BUFF_TYPE.attackGetHp ||
- (buffConfig.buffType == BUFF_TYPE.attackCritGetHp && iAttack.isCrit)) &&
- hurt > 0 &&
- !isDodge
- ) {
- //攻击吸血
- let addHPNum = (hurt * buffConfig.attrRate[0]) / rate
- world.addHP(addHPNum, entity)
- } else if (buffConfig.buffType == BUFF_TYPE.killNum && isKill) {
- //根据杀敌加攻击
- comRole.attack += (comRole.roleCfg.attack * buffConfig.attrRate[0]) / rate
- }
- })
- } else {
- let bullets = world.createBulletEntity(entity, iAttack.isCrit)
- bullets.forEach(bullet => {
- let comBullet = world.getComponent(bullet, ComBullet)
- comBullet.fightData.attackNum = comRole.attackNum
- })
- }
- let sputterRate: number = 0
- comRole.buffs.forEach(buff => {
- // 溅射比例
- if (buff.buffCfg.buffType == BUFF_TYPE.sputter && buff.buffCfg.attrRate[0] > sputterRate) {
- sputterRate = buff.buffCfg.attrRate[0]
- }
- })
- if (sputterRate > 0 && !isDodge) {
- iAttack.sputter = sputterRate
- comFindEnemy.attackCObject.containsBody.forEach((cBody: cBody, entityOther: number) => {
- // 溅射
- if (entityOther != comAttackable.curAttack && !world.isDie(entityOther)) {
- let otherComTransform = world.getComponent(entityOther, ComTransform)
- if (
- (comTransform.dir.x > 0 &&
- otherComTransform.x - comTransform.x >= Data.game.meleeRange / 2) ||
- (!(comTransform.dir.x > 0) &&
- otherComTransform.x - comTransform.x <= Data.game.meleeRange / 2)
- ) {
- world.changeHpByHurt(
- entityOther,
- world.getHurtByAttackRole(comRole, entityOther, iAttack),
- false,
- 0,
- )
- }
- }
- })
- }
- }
- return false
- })
- }
- }
|