import { _decorator, Component, Node, ProgressBar, v3, Vec3 } from 'cc'; import { HeroViewComp } from './HeroViewComp'; import { SkillSet, SType, TGroup, } from '../common/config/SkillSet'; import { ecs } from 'db://oops-framework/libs/ecs/ECS'; import { GameEvent } from '../common/config/GameEvent'; import { FacSet } from '../common/config/BoxSet'; import { smc } from '../common/SingletonModuleComp'; import { CCComp } from 'db://oops-framework/module/common/CCComp'; import { MonModelComp } from './MonModelComp'; import { HeroModelComp } from './HeroModelComp'; import { SkillEnt } from '../skill/SkillEnt'; import { Attrs } from '../common/config/HeroAttrs'; import { TalComp } from './TalComp'; const { ccclass, property } = _decorator; @ccclass('SkillCon') @ecs.register('SkillCon') export class SkillConComp extends CCComp { HeroView:any=null; HeroEntity:any=null; TALCOMP:any=null; skill_cd=0 private _timers: { [key: string]: any } = {}; init(): void { this.on(GameEvent.FightEnd, this.clear_timer, this); } onLoad(){ this.HeroView=this.node.getComponent(HeroViewComp) this.TALCOMP=this.node.getComponent(TalComp) } start() { this.HeroEntity=this.HeroView.ent } update(dt: number) { if(!smc.mission.play||smc.mission.pause) return if(!this.HeroView.isStun() && !this.HeroView.isFrost()) { let skills=this.HeroView.skills for(let i=0;i skills[i].cd_max&&this.HeroView.mp >= skills[i].cost){ if(SkillSet[skills[i].uuid].SType==SType.damage&&this.HeroView.is_atking){ this.castSkill(SkillSet[skills[i].uuid]) this.HeroView.skills[i].cd = 0 this.HeroView.mp -= skills[i].cost } } } } } /** 施放技能 */ castSkill(config: typeof SkillSet[keyof typeof SkillSet]) { let wfuny=this.check_wfuny() let dmg=0 this.doSkill(config,wfuny,dmg); } private doSkill(config: typeof SkillSet[keyof typeof SkillSet],is_wfuny:boolean=false,dmg:number=0) { // 添加节点有效性检查 if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) { return; } let targets:any=null if(config.TGroup==TGroup.Self){ targets = [this.node.position] } if(config.TGroup==TGroup.Enemy){ targets = this.selectTargets(config.t_num) } this.HeroView.playSkillEffect(config.uuid) const sEnt = ecs.getEntity(SkillEnt); const timerId = setTimeout(() => { // 再次检查节点有效性 if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) { return; } console.log("技能开始",sEnt) sEnt.load( this.node.position, this.node.parent, config.uuid, targets, this.HeroView, dmg ); }, 300); if(is_wfuny){ this.scheduleOnce(()=>{ this.doSkill(config,false,dmg) },0.1) } // 保存定时器ID this._timers[`skill_${config.uuid}`] = timerId; } check_wfuny(){ let random = Math.random()*100 if(random < this.HeroView.Attrs[Attrs.WFUNY]){ return true } return false } check_target(){ if(this.HeroView.fac==FacSet.HERO){ return ecs.query(ecs.allOf(MonModelComp)) }else{ return ecs.query(ecs.allOf(HeroModelComp)) } } get_front(entities:any){ let keyPos = this.HeroView.fac==FacSet.HERO ? Math.min(...entities.map(e => e.get(HeroViewComp).node.position.x)) : Math.max(...entities.map(e => e.get(HeroViewComp).node.position.x)); let keyEntity = entities.find(e => e.get(HeroViewComp).node.position.x === keyPos); return keyEntity.get(HeroViewComp).node.position; } /** * 选择目标(整合版) * @param t_num 目标数量,第一个是最近的前排,后续随机(可重复) * @returns 目标坐标数组 */ private selectTargets(t_num: number): Vec3[] { const targets: Vec3[] = []; const entities = this.check_target(); // 如果没有目标实体 if (entities.length === 0) { const defaultPos = this.HeroView.fac === FacSet.HERO ? v3(400, 0, 0) : v3(-400, 0, 0); // 返回t_num个相同的默认位置 for (let i = 0; i < t_num; i++) { targets.push(defaultPos.clone()); } return targets; } // 第一个目标:最前排(离施法者最近的) const frontPos = this.get_front(entities); targets.push(v3(frontPos.x, frontPos.y, 0)); // 后续目标:随机选择(可以重复) for (let i = 1; i < t_num; i++) { const randomEntity = entities[Math.floor(Math.random() * entities.length)]; const randomPos = randomEntity.get(HeroViewComp).node.position; targets.push(v3(randomPos.x, randomPos.y, 0)); } return targets; } public clear_timer() { // console.log("[SkillConComp]:clear_timer",this.HeroView); Object.values(this._timers).forEach(clearTimeout); } reset() { this.clear_timer(); } onDestroy() { // 清理所有定时器 // console.log("[SkillConComp]:onDestroy:",this.node.name) Object.values(this._timers).forEach(clearTimeout); this._timers = {}; // 移除事件监听 this.off(GameEvent.CastHeroSkill); } }