SysRoleState.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /** @format */
  2. import {EventDie, EventHPChange} from '../core/NodeEvent'
  3. import {ComAttackable} from '../components/ComAttackable'
  4. import {ComBehaviorTree} from '../components/ComBehaviorTree'
  5. import {ComCocosNode} from '../components/ComCocosNode'
  6. import {ComMovable} from '../components/ComMovable'
  7. import {ComRole} from '../components/ComRole'
  8. import {ECSSystem} from '../lib/ECSSystem'
  9. import {GenFilterKey} from '../lib/ECSComponent'
  10. import {FightWorld} from '../worlds/FightWorld'
  11. import {ComFindEnemy} from '../components/ComFindEnemy'
  12. import {ComDie} from '../components/ComDie'
  13. import {cCollider} from '../../collision/Collider'
  14. import {ccUtils} from '../../utils/ccUtils'
  15. import {ComTransform} from '../components/ComTransform'
  16. import {ComHasSkill} from '../components/ComHasSkill'
  17. import {ComSkillAbel} from '../components/ComSkillAbel'
  18. import {Data} from '../../GameControl'
  19. import {ComLifeTime} from '../components/ComLifeTime'
  20. import {ComFriend} from '../components/ComFriend'
  21. import {ComEnemy} from '../components/ComEnemy'
  22. import {ComDizzy} from '../components/ComDizzy'
  23. import {ATTR_NAME, ENTRY, MONSTER_TYPE, ROLE_TYPE, SKILL_TYPE} from '../../enums/Enum'
  24. import {EntryObj} from '../core/GameInterface'
  25. import {ComFrameAni} from '../components/ComFrameAni'
  26. export const FILTER_ROLE_NODE = GenFilterKey(
  27. [ComCocosNode, ComRole, ComMovable, ComAttackable, ComFindEnemy, ComTransform, ComBehaviorTree],
  28. [ComDie],
  29. )
  30. export class SysRoleState extends ECSSystem {
  31. /** 连接 */
  32. public onAdd(world: FightWorld): void {}
  33. /** 断开连接 */
  34. public onRemove(world: FightWorld): void {}
  35. /** 添加实体 */
  36. public onEntityEnter(world: FightWorld, entity: number): void {}
  37. /** */
  38. public onEntityLeave(world: FightWorld, entity: number): void {}
  39. /** 更新 */
  40. public onUpdate(world: FightWorld, dt: number): void {
  41. world.getFilter(FILTER_ROLE_NODE).walk((entity: number) => {
  42. let comCocosNode = world.getComponent(entity, ComCocosNode)
  43. if (!comCocosNode.loaded) return
  44. let comRole = world.getComponent(entity, ComRole)
  45. let comAttackable = world.getComponent(entity, ComAttackable)
  46. let comFindEnemy = world.getComponent(entity, ComFindEnemy)
  47. let comHasSkill = world.getComponent(entity, ComHasSkill)
  48. let comSkillAbel = world.getComponent(entity, ComSkillAbel)
  49. ccUtils.setLabel(
  50. CC_DEV && cc.debug.isDisplayStats()
  51. ? `ID:${entity}${comFindEnemy.enemy ? '寻敌:' + comFindEnemy.enemy : ''}${
  52. comFindEnemy.willAttackMelee ? '将攻:' + comFindEnemy.willAttackMelee : ''
  53. }${comFindEnemy.willBeAttackMelee ? '将被攻:' + comFindEnemy.willBeAttackMelee : ''}${
  54. comAttackable.curAttack ? '攻击:' + comAttackable.curAttack : ''
  55. }${comAttackable.beAttacks.length > 0 ? '被包围:' + comAttackable.beAttacks : ''}`
  56. : '',
  57. comCocosNode.node,
  58. 'entity',
  59. )
  60. if (comRole && comRole.HPDirty) {
  61. let hpRate = Math.floor((comRole.nowHP / comRole.HP) * 100)
  62. if (world.isBase(comRole)) {
  63. } else if (world.isBoss(comRole)) {
  64. world.fightCore.showBossHP(comRole)
  65. }
  66. let keys = Object.keys(ATTR_NAME)
  67. let attrAddByHpChangeCb = (entryObj: EntryObj, isMore: boolean) => {
  68. if (entryObj) {
  69. for (let i = 0; i < entryObj.numArr.length; i++) {
  70. let params = entryObj.numArr[i]
  71. let canAdd = (isMore && hpRate > params[0]) || (!isMore && hpRate < params[0])
  72. if (canAdd) {
  73. if (!entryObj.num) {
  74. entryObj.num =
  75. (comRole.roleCfg[keys[params[1] - 1]] * params[2]) / Data.game.rateNum
  76. comRole[keys[params[1] - 1]] += entryObj.num
  77. }
  78. } else if (entryObj.num) {
  79. //扣除加的值
  80. comRole[keys[params[1] - 1]] -= entryObj.num
  81. entryObj.num = 0
  82. }
  83. }
  84. }
  85. }
  86. attrAddByHpChangeCb(comRole.entryMap.get(ENTRY.moreThanHPAttr), true)
  87. attrAddByHpChangeCb(comRole.entryMap.get(ENTRY.belowHPAttr), false)
  88. comCocosNode.events.push(
  89. new EventHPChange(
  90. comRole.HP,
  91. comRole.lastHP,
  92. comRole.nowHP,
  93. comRole.lastShieldHP,
  94. comRole.shieldHP,
  95. ),
  96. )
  97. if (!world.fightCore.gameOver && world.fightCore.teamEntity.includes(entity)) {
  98. world.fightCore.changeTeamHp()
  99. }
  100. if (world.isDie(comRole)) {
  101. if (!world.fightCore.gameOver) {
  102. if (world.isBase(comRole)) {
  103. let isWin = comRole.group == Data.game.gEnemy
  104. } else if (
  105. (comRole.roleCfg.type == MONSTER_TYPE.boss ||
  106. comRole.roleCfg.type == MONSTER_TYPE.elite ||
  107. comRole.roleCfg.type == MONSTER_TYPE.normal) &&
  108. !comRole.isExtraEnemy &&
  109. !world.fightCore.gameOver
  110. ) {
  111. if (comRole.roleCfg.type == MONSTER_TYPE.elite) {
  112. world.fightCore.eliteNum += 1
  113. } else if (comRole.roleCfg.type == MONSTER_TYPE.boss) {
  114. world.fightCore.bossNum += 1
  115. world.fightCore.hideBossHP()
  116. } else if (comRole.roleCfg.type == MONSTER_TYPE.normal) {
  117. world.fightCore.monsterNum += 1
  118. }
  119. let comTrans = world.getComponent(entity, ComTransform)
  120. world.fightCore.changeKillNum()
  121. }
  122. }
  123. //从敌方近战敌人攻击数组中移除
  124. if (comAttackable.isMelee && comAttackable.curAttack) {
  125. let enemyComMovable = world.getComponent(comAttackable.curAttack, ComMovable)
  126. if (enemyComMovable) {
  127. let isLeftIndex = enemyComMovable.leftMeleeEnemiesPosDirty.indexOf(entity)
  128. if (isLeftIndex >= 0) {
  129. enemyComMovable.leftMeleeEnemiesPosDirty.splice(isLeftIndex, 1)
  130. } else {
  131. let isRightIndex = enemyComMovable.rightMeleeEnemiesPosDirty.indexOf(entity)
  132. if (isRightIndex >= 0) enemyComMovable.leftMeleeEnemiesPosDirty.splice(isRightIndex, 1)
  133. }
  134. }
  135. }
  136. //从召唤者数组中移除
  137. if (comRole.parent > 0) {
  138. let createRole = world.getComponent(comRole.parent, ComRole)
  139. if (!world.isDie(createRole)) {
  140. createRole.babys.splice(createRole.babys.indexOf(entity), 1)
  141. //宝宝达到召唤上限 将CD设为最大值,等有宝宝死亡,再重置CD
  142. createRole.skillCountDowns.forEach((value, skillIndex) => {
  143. let skillCfg = createRole.skills[skillIndex]
  144. if (
  145. skillCfg.type == SKILL_TYPE.createRole &&
  146. skillCfg.createRole[0] == comRole.roleCfg.ID &&
  147. skillCfg.createMax > 0 &&
  148. createRole.babys.filter(
  149. baby => world.getComponent(baby, ComRole)?.roleCfg.ID == skillCfg.createRole[0],
  150. ).length < skillCfg.createMax &&
  151. value == Infinity
  152. ) {
  153. createRole.skillCountDowns[skillIndex] = createRole.skillCDs[skillIndex]
  154. }
  155. })
  156. }
  157. }
  158. let comSpineNode = world.getComponent(comRole.spineEntity, ComCocosNode)
  159. if (!comRole.transDirty) {
  160. comCocosNode.events.push(new EventDie())
  161. //同步spine死亡
  162. comSpineNode?.events.push(new EventDie())
  163. }
  164. world.fightCore.handleDie(entity)
  165. //移除buff特效
  166. for (let buff of comRole.buffs) {
  167. for (let aniEntity of buff.aniEntityArr) {
  168. let comFrameAni = world.getComponent(aniEntity, ComFrameAni)
  169. if (comFrameAni) comFrameAni.countDown = 0
  170. }
  171. }
  172. //移除有碰撞体的组件
  173. world.removeComponent(entity, ComRole)
  174. cCollider.inst.remove(comRole.cObject.body)
  175. comCocosNode.node.removeComponent(comRole.cObject)
  176. comRole.cObject = null
  177. world.removeComponent(entity, ComFindEnemy)
  178. cCollider.inst.remove(comFindEnemy.cObject.body)
  179. cCollider.inst.remove(comFindEnemy.attackCObject.body)
  180. comCocosNode.node.removeComponent(comFindEnemy.cObject)
  181. comCocosNode.node.removeComponent(comFindEnemy.attackCObject)
  182. comFindEnemy.cObject = null
  183. comFindEnemy.attackCObject = null
  184. if (comFindEnemy.cObjectMeleeX) {
  185. cCollider.inst.remove(comFindEnemy.cObjectMeleeX.body)
  186. comCocosNode.node.removeComponent(comFindEnemy.cObjectMeleeX)
  187. comFindEnemy.cObjectMeleeX = null
  188. }
  189. world.removeComponent(entity, ComHasSkill)
  190. comHasSkill.skillCObjects.forEach(skillCObject => {
  191. if (skillCObject) {
  192. cCollider.inst.remove(skillCObject.body)
  193. comCocosNode.node.removeComponent(skillCObject)
  194. }
  195. })
  196. //移除其他可能有的组件
  197. world.removeComponent(entity, ComBehaviorTree)
  198. world.removeComponent(entity, ComAttackable)
  199. world.removeComponent(entity, ComMovable)
  200. if (comSkillAbel.bullets) {
  201. comSkillAbel.bullets.forEach(v => {
  202. world.removeBulletEntity(v)
  203. })
  204. comSkillAbel.bullets.length = 0
  205. }
  206. world.removeComponent(entity, ComSkillAbel)
  207. world.removeComponent(entity, ComFriend)
  208. world.removeComponent(entity, ComEnemy)
  209. world.removeComponent(entity, ComDizzy)
  210. world.removeComponent(entity, ComLifeTime)
  211. if (comRole.transDirty) {
  212. comRole.transDirty = false
  213. world.removeNodeEntity(entity)
  214. if (comSpineNode) {
  215. world.removeNodeEntity(comRole.spineEntity)
  216. }
  217. } else {
  218. let comDie = world.addComponent(entity, ComDie)
  219. comDie.countDown = comRole.dieTime > 0 ? 1 : 0
  220. comDie.spineEntity = comRole.spineEntity
  221. }
  222. }
  223. comRole.HPDirty = false
  224. }
  225. return false
  226. })
  227. }
  228. }