123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- /** @format */
- import {ECSSystem} from '../lib/ECSSystem'
- import {GenFilterKey} from '../lib/ECSComponent'
- import {FightWorld} from '../worlds/FightWorld'
- import {ComMovable} from '../components/ComMovable'
- import {ComTransform} from '../components/ComTransform'
- import {ComBullet} from '../components/ComBullet'
- import {ComCocosNode} from '../components/ComCocosNode'
- import {ComRole} from '../components/ComRole'
- import {ComAttackable} from '../components/ComAttackable'
- import {ComDie} from '../components/ComDie'
- import {ComEnemy} from '../components/ComEnemy'
- import {ComFriend} from '../components/ComFriend'
- import {Data, Mgr} from '../../GameControl'
- import {EntityIndex} from '../lib/Const'
- import {SkillConfig} from '../../config/SkillConfig'
- import {EventBulletEjection, EventRoleTip} from '../core/NodeEvent'
- import {
- BUFF_EFFECT_TYPE,
- BUFF_TYPE,
- BULLET_EFFECT_TYPE,
- BULLET_TYPE,
- ENTRY,
- FRAME_ANI_NAME,
- GAME_ROLE_TIP,
- ROLE_TYPE,
- SKILL_EFFECT_TYPE,
- } from '../../enums/Enum'
- import {IAttackEffect} from '../core/GameInterface'
- import {IBulletConfig} from '../../config/BulletConfig'
- import {ComFrameAni} from '../components/ComFrameAni'
- const FILTER_BULLET = GenFilterKey([ComBullet, ComMovable, ComCocosNode, ComTransform])
- const FILTER_FRIEND_ROLE = GenFilterKey([ComRole, ComCocosNode, ComTransform, ComFriend], [ComDie])
- const FILTER_ENEMY_ROLE = GenFilterKey([ComRole, ComCocosNode, ComTransform, ComEnemy], [ComDie])
- export class SysBullet 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_BULLET)
- let friendsFilter = world.getFilter(FILTER_FRIEND_ROLE)
- let enemiesFilter = world.getFilter(FILTER_ENEMY_ROLE)
- let changeHpByAttack = (comBullet: ComBullet, roleEntity) => {
- let bulletCfg = comBullet.bulletCfg
- Mgr.audio.playSFX(bulletCfg.sound)
- if (comBullet.bulletCfg.type == BULLET_TYPE.normal) {
- //目标敌人掉血
- let comRoleEnemy = world.getComponent(roleEntity, ComRole)
- let comEnemyCocosNode = world.getComponent(roleEntity, ComCocosNode)
- //基地免疫
- if (comRoleEnemy.roleCfg.type == ROLE_TYPE.base) {
- let effectParmIndex = bulletCfg.effectType.findIndex(
- value => value == BULLET_EFFECT_TYPE.castleVoid,
- )
- if (effectParmIndex >= 0) return
- }
- //是否闪避
- let isDodge =
- comRoleEnemy &&
- Math.getProb(
- comBullet.fightData.hit - comRoleEnemy.dodge > 0
- ? 0
- : (comRoleEnemy.dodge - comBullet.fightData.hit) / Data.game.rateNum,
- )
- if (!isDodge) {
- let attackEffect: IAttackEffect = {isBack: false, isCrit: comBullet.isCrit}
- let hurt = world.getHurtByAttackRole(comBullet.fightData, roleEntity, attackEffect)
- let decrease = 0
- let effectParmIndex = bulletCfg.effectType.findIndex(value => value == BULLET_EFFECT_TYPE.ejection)
- if (effectParmIndex >= 0) decrease = bulletCfg.effectParm[effectParmIndex][0]
- hurt *= Math.pow(1 - decrease / Data.game.rateNum, comBullet.ejectionEnemies.length)
- if (hurt < 0) hurt = 0
- //远程伤害免疫为1点
- if (hurt > 1 && comRoleEnemy.buffs.some(buff => buff.buffCfg.buffType == BUFF_TYPE.rangedImmune)) {
- hurt = 1
- }
- world.changeHpByHurt(roleEntity, hurt, comBullet.isCrit, comBullet.bulletCfg.hitID)
- //暂时屏蔽子弹特效
- //world.changeHpByHurt(roleEntity, hurt, comBullet.isCrit, 0)
- if (!world.isDie(comBullet.fightData.roleEntity)) {
- let createComRole = world.getComponent(comBullet.fightData.roleEntity, ComRole)
- for (let buff of createComRole.buffs) {
- if (buff.buffCfg.buffType == BUFF_TYPE.attackAddBabyHP) {
- //攻击让宝宝加血
- let addHPNum = (hurt * buff.buffCfg.attrRate[0]) / Data.game.rateNum
- createComRole.babys.forEach(baby => {
- world.addHP(addHPNum, baby)
- })
- }
- }
- }
- //吸血
- if (comBullet.fightData.entryMap.get(ENTRY.hurt2HP)?.num > 0) {
- let addHPNum = (comBullet.fightData.entryMap.get(ENTRY.hurt2HP).num * hurt) / Data.game.rateNum
- world.addHP(addHPNum, comBullet.fightData.roleEntity)
- }
- } else {
- comEnemyCocosNode.events.push(new EventRoleTip(GAME_ROLE_TIP.missTip, 0, 'miss'))
- }
- } else if (comBullet.bulletCfg.type == BULLET_TYPE.skill) {
- world.createCardBulletSkill(comBullet, roleEntity)
- }
- }
- filter.walk((bulletEntity: number) => {
- let comCocosNode = world.getComponent(bulletEntity, ComCocosNode)
- if (!comCocosNode.loaded) return
- let comBullet = world.getComponent(bulletEntity, ComBullet)
- let comMovable = world.getComponent(bulletEntity, ComMovable)
- let bulletTrans = world.getComponent(bulletEntity, ComTransform)
- let bulletCfg = comBullet.bulletCfg
- //产生碰撞
- if (comBullet.cObject.containsBody.size > 0) {
- let containsArr = comBullet.cObject.containsBody.keysArr()
- for (let i = 0; i < containsArr.length; i++) {
- let roleEntity = containsArr[i]
- if (
- bulletCfg.isEjection &&
- roleEntity == comBullet.ejectionEnemy &&
- comMovable.pointIdx >= comMovable.points.length
- ) {
- changeHpByAttack(comBullet, roleEntity)
- //推入弹中数组
- comBullet.ejectionEnemies.push(roleEntity)
- //连线的终点改为角色
- if (bulletCfg.effectType.includes(BULLET_EFFECT_TYPE.line)) {
- let lastEjectionAni = comBullet.ejectionAnis[comBullet.ejectionAnis.length - 1]
- let lastComFrameAni = world.getComponent(lastEjectionAni, ComFrameAni)
- if (lastComFrameAni) {
- lastComFrameAni.lineEndEntity = roleEntity
- }
- }
- //子弹移除
- if (comBullet.ejectionEnemies.length >= bulletCfg.maxHitNum) {
- world.removeBulletEntity(bulletEntity)
- } else {
- //子弹弹射
- let targetFilter =
- comBullet.group == Data.game.gFriendBullet ? enemiesFilter : friendsFilter
- let minDistance = Infinity
- let nearestTrans: ComTransform = null
- let nearestEntity: EntityIndex = null
- let ejectionParam: number[] = null
- for (let i = 0; i < bulletCfg.effectType.length; i++) {
- let type = bulletCfg.effectType[i]
- if (type == BULLET_EFFECT_TYPE.ejection) {
- ejectionParam = bulletCfg.effectParm[i]
- }
- }
- let maxAttackRange = ejectionParam
- ? ejectionParam[1]
- : Data.game.fightSizeMaxX - Data.game.fightSizeMinX
- let decrease = ejectionParam ? ejectionParam[0] : 0
- let moreTimesHurt = ejectionParam ? ejectionParam[2] : true
- targetFilter.walk((enemyEntity: number) => {
- let otherTrans = world.getComponent(enemyEntity, ComTransform)
- let dx = otherTrans.x - bulletTrans.x
- let dy = otherTrans.y - bulletTrans.y
- let distance = Math.sqrt(dx * dx + dy * dy)
- //不等于弹射目标不能弹基地
- if (
- distance < minDistance &&
- enemyEntity != comBullet.ejectionEnemy &&
- !world.isBase(enemyEntity) &&
- (moreTimesHurt ||
- (!moreTimesHurt && !comBullet.ejectionEnemies.includes(enemyEntity)))
- ) {
- minDistance = distance
- nearestTrans = otherTrans
- nearestEntity = enemyEntity
- }
- return false
- })
- if (nearestTrans && minDistance < maxAttackRange) {
- comBullet.ejectionEnemy = nearestEntity
- world.initBulletDir(bulletTrans, nearestTrans, comMovable, comBullet, comCocosNode)
- comMovable.speed = bulletCfg.moveSpeed
- //comCocosNode.events.push(new EventBulletEjection(bulletTrans.x, bulletTrans.y))
- //创建连线特效
- if (bulletCfg.effectType.includes(BULLET_EFFECT_TYPE.line)) {
- let aniEntity = world.createAni(FRAME_ANI_NAME.lightLine, 0)
- let comFrameAni = world.getComponent(aniEntity, ComFrameAni)
- let startComTrans = world.getComponent(roleEntity, ComTransform)
- comFrameAni.lineStartPos = cc.v2(startComTrans.x, startComTrans.y)
- if (!world.isDie(roleEntity)) comFrameAni.lineStartEntity = roleEntity
- comFrameAni.lineEndEntity = bulletEntity
- comBullet.ejectionAnis.push(aniEntity)
- }
- return true
- } else {
- world.removeBulletEntity(bulletEntity)
- }
- }
- } else if (!bulletCfg.isEjection && !comBullet.hitEnemies.includes(roleEntity)) {
- if (comBullet.bulletCfg.type == BULLET_TYPE.normal) {
- comBullet.hitEnemies.push(roleEntity)
- if (comBullet.hitEnemies.length <= bulletCfg.maxHitNum) {
- changeHpByAttack(comBullet, roleEntity)
- }
- //子弹移除
- if (comBullet.hitEnemies.length >= bulletCfg.maxHitNum) {
- world.removeBulletEntity(bulletEntity)
- }
- }
- }
- }
- }
- return false
- })
- }
- }
|