import { Node, Vec3 } from "cc"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { HeroViewComp } from "../hero/HeroViewComp"; import { HeroSkillsComp } from "./heroSkillsComp"; import { endType, SkillSet, TargetGroup, TargetType } from "../common/config/SkillSet"; import { CdType } from "../common/config/SkillSet"; import { oops } from "db://oops-framework/core/Oops"; import { GameEvent } from "../common/config/GameEvent"; import { Skill } from "../skills/Skill"; import { SkillCom } from "../skills/SkillCom"; import { AnimType } from "../common/config/SkillSet"; /** 技能系统 */ @ecs.register('SkillSystem') export class SkillSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { private _timers: { [key: string]: number } = {}; private _damageQueue: Array<{ timer: number; callback: () => void }> = []; private readonly SKILL_RANGE_X = 10; // x轴判定范围 private readonly SKILL_RANGE_Y = 10; // y轴判定范围 init(): void { oops.message.on(GameEvent.MissionEnd, this.clear_timer, this); } filter(): ecs.IMatcher { return ecs.allOf(SkillCom); } update(e: ecs.Entity) { const skill = e.get(SkillCom); if(this.checkSkill(skill)){ if(skill.atk_count < 1){ skill.atk_count++; // console.log("技能命中目标",skill.caster,skill.target,SkillSet[skill.s_uuid]); this.applySkillEffect(skill.caster,skill.target,SkillSet[skill.s_uuid],e); } } this.processDamageQueue(); } private processDamageQueue() { const delta = this.dt; for (let i = this._damageQueue.length - 1; i >= 0; i--) { this._damageQueue[i].timer -= delta; if (this._damageQueue[i].timer <= 0) { this._damageQueue[i].callback(); this._damageQueue.splice(i, 1); } } } checkSkill(skill: SkillCom) { const targetPos = skill.target.node.position; const target = skill.target; const skillPos = skill.node.position; // 根据技能配置获取判定范围 const config = SkillSet[skill.s_uuid]; const rangeX = config?.rangeX || 30; // 默认值为10 const rangeY = config?.rangeY || 40; const distanceX = Math.abs(targetPos.x - skillPos.x); const distanceY = Math.abs(targetPos.y+40 - skillPos.y); const isInRange = distanceX < rangeX && distanceY < rangeY; return isInRange; } /** 应用技能效果 */ private applySkillEffect(casterView:HeroViewComp, targetView: HeroViewComp, config: typeof SkillSet[keyof typeof SkillSet],e:ecs.Entity) { // 直接计算伤害(包含防御减免) const damageResult = this.calculateDamage(casterView, targetView, config); // 将施法者传入applyDamage方法 this.applyDamage(targetView,damageResult); // 播放技能特效 casterView.playSkillEffect(config.uuid); console.log(`${casterView.hero_name} 对 ${targetView.hero_name} 造成 ${damageResult.value}伤害`); if(config.endType === endType.collision){ e.destroy(); } } private calculateDamage(caster: HeroViewComp, target: HeroViewComp, config: typeof SkillSet[keyof typeof SkillSet]) { const result = { value: 0, isCrit: false, isDodged: false, delay: 0.3, // 默认延迟 ignoreDefense: false, canCrit: true, } let final = caster.ap * config.ap / 100; // 伤害浮动(±10%) const damageFloat = 0.9 + Math.random() * 0.2; // 0.9~1.1 final *= damageFloat; final = Math.round(final); result.value = Math.max(1, final); // 确保最小伤害为1 result.isCrit = false; return result; } private applyDamage(targetView: HeroViewComp, result: any,) {; this._damageQueue.push({ timer: 0, callback: () => { if (!targetView?.ent.has(HeroViewComp)) return; let remainingDamage = result.value; if (targetView.shield > 0) { const shieldAbsorb = Math.min(targetView.shield, remainingDamage); targetView.shield -= shieldAbsorb; remainingDamage -= shieldAbsorb; if (targetView.shield <= 0) { targetView.BUFFCOMP.show_shield(false); } } if (remainingDamage > 0) { targetView.hp -= remainingDamage; if(targetView.hp <= 0) { targetView.BUFFCOMP.dead() targetView.to_grave(); } targetView.showDamage(result.value, true); } else { targetView.BUFFCOMP.tooltip(5,"*吸收*"); } } }); } public clear_timer() { console.log("clear_timer"); Object.values(this._timers).forEach(clearTimeout); } onDestroy() { Object.values(this._timers).forEach(clearTimeout); } /** 应用负面状态 */ private applyDebuff(target: ecs.Entity, config: typeof SkillSet[keyof typeof SkillSet]) { // 实现debuff逻辑... } }