2022-03-30 10:57:19 +08:00

121 lines
5.6 KiB
TypeScript

import { ComAttackable } from "../components/ComAttackable";
import { ComBeAttacked } from "../components/ComBeAttacked";
import { ComMonitor } from "../components/ComMonitor";
import { ComRoleConfig } from "../components/ComRoleConfig";
import { ComTransform } from "../components/ComTransform";
import { ECSSystem } from "../lib/ECSSystem";
import { ECSWorld, GenFillterKey } from "../lib/ECSWorld";
const FILTER_ATTACKABLE = GenFillterKey([ComAttackable]);
const FILTER_BEATTACKED = GenFillterKey([ComBeAttacked]);
export class SysAttack extends ECSSystem {
/** 连接 */
public onAdd(world: ECSWorld): void {
}
/** 断开连接 */
public onRemove(world: ECSWorld): void {
}
/** 添加实体 */
public onEntityEnter(world: ECSWorld, entity: number): void {
}
/** */
public onEntityLeave(world: ECSWorld, entity: number): void {
let filter = world.getFilter(FILTER_ATTACKABLE);
// 判断当前monitor是否
filter.entities.forEach((value: boolean, otherEntity: number) => {
let comBeAttacked = world.getComponent(otherEntity, ComBeAttacked);
if(!comBeAttacked) return ;
if(comBeAttacked.attacker == entity) comBeAttacked.attacker = -1;
});
}
/** 更新 */
public onUpdate(world: ECSWorld, dt: number): void {
let filter = world.getFilter(FILTER_ATTACKABLE);
filter.walk((entity: number) => {
let comTransSelf = world.getComponent(entity, ComTransform);
let comAttackable = world.getComponent(entity, ComAttackable);
let comRoleConfigSelf = world.getComponent(entity, ComRoleConfig);
if(!comAttackable.dirty) return ;
comAttackable.countDown -= dt;
if(comAttackable.countDown <= 0) {
comAttackable.dirty = false;
for(const entityOther of comAttackable.willHurts) {
let comBeAttacked = world.getComponent(entityOther, ComBeAttacked);
if(comBeAttacked && comBeAttacked.attacker == entity) comBeAttacked.attacker = -1;
}
comAttackable.willHurts.length = 0;
}
let limitX = comTransSelf.x + Math.sign(comTransSelf.dir.x) * comAttackable.hurtArea.x;
let minX = Math.min(comTransSelf.x, limitX);
let maxX = Math.max(comTransSelf.x, limitX);
let minY = comTransSelf.y - comAttackable.hurtArea.y;
let maxY = comTransSelf.y + comAttackable.hurtArea.y;
let _checkBeAttack = (entityOther: number) => {
if(entity == entityOther) return false;
let comRoleConfigOther = world.getComponent(entityOther, ComRoleConfig);
if(!comRoleConfigOther || comRoleConfigOther.team == comRoleConfigSelf.team) return false;
let comTransOther = world.getComponent(entityOther, ComTransform);
if(comTransOther.x < minX || comTransOther.x > maxX || Math.abs(comTransOther.y - comTransSelf.y) >= comAttackable.hurtArea.y) {
return false;
}
return true
}
comAttackable.debugInfo = {
points: [cc.v2(minX, minY), cc.v2(maxX, minY), cc.v2(maxX, maxY), cc.v2(minX, maxY)],
color: cc.Color.RED,
};
// 即将攻击未完成, 并且处于即将攻击时间段
if(!comAttackable.willHurtFrameCompleted && comAttackable.countDown <= comAttackable.willHurtFrame) {
comAttackable.willHurtFrameCompleted = true;
world.getFilter(FILTER_BEATTACKED).walk((entityOther: number) => {
if(!_checkBeAttack(entityOther)) return ;
let comBeAttackedOther = world.getComponent(entityOther, ComBeAttacked);
comBeAttackedOther.attacker = entity;
comAttackable.willHurts.push(entityOther)
return false;
})
}
if(!comAttackable.hurtFrameCompleted && comAttackable.countDown <= comAttackable.hurtFrame) {
comAttackable.hurtFrameCompleted = true;
world.getFilter(FILTER_BEATTACKED).walk((entityOther: number) => {
let comBeAttacked = world.getComponent(entityOther, ComBeAttacked);
if(comBeAttacked && comBeAttacked.attacker == entity) comBeAttacked.attacker = -1;
if(!_checkBeAttack(entityOther)) return ;
let comRoleConfigOther = world.getComponent(entityOther, ComRoleConfig);
// 扣血
if(!comRoleConfigOther || comRoleConfigOther.nowHP <= 0) return ;
comRoleConfigOther.lastHP = comRoleConfigOther.nowHP;
comRoleConfigOther.nowHP -= comAttackable.attack;
comRoleConfigOther.HPDirty = true;
// 打断对方的攻击动作
let comAttackableOther = world.getComponent(entityOther, ComAttackable);
if(!comAttackableOther || comAttackableOther.countDown <= 0) return ;
comAttackableOther.hurtFrameCompleted = true;
comAttackableOther.countDown = 0.25;
let comMonitorOther = world.getComponent(entityOther, ComMonitor);
if(comMonitorOther.others.indexOf(entity) == -1) {
comMonitorOther.others[0] = entity;
}
return false;
});
}
return false;
});
}
}