Files
heros/assets/script/game/skill/AtkConCom.ts
2025-10-15 17:28:16 +08:00

212 lines
8.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { _decorator, Animation, Collider2D, Contact2DType, Tween, v3, Vec3 } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { BezierMove } from "../BezierMove/BezierMove";
import { AType, BuffAttr, DTType, EType, SkillSet, SType, TGroup } from "../common/config/SkillSet";
import { BoxSet, FacSet } from "../common/config/BoxSet";
import { HeroViewComp } from "../hero/HeroViewComp";
import { GameEvent } from "../common/config/GameEvent";
import { smc } from "../common/SingletonModuleComp";
const { ccclass, property } = _decorator;
/** 视图层对象 */
@ccclass('AtkConCom')
@ecs.register('AtkCon', false)
export class AtkConCom extends CCComp {
@property({ type:Boolean })
public anmEnd: boolean = false;
@property({ type:Boolean })
public cbox: boolean = false;
// 核心标识和配置
s_uuid:number = 0;
// 运行时状态(必须缓存的)
is_destroy:boolean = false;
startPos: Vec3 = v3(); // 起始位置
targetPos: Vec3 = v3(); // 目标位置
group:number = 0; //阵营
fac:number=0; //阵营
// 战斗相关运行时数据
ap:number=0;
burn_count:number=0;
burn_value:number=0;
stun_time:number=0;
stun_ratio:number=0;
frost_ratio:number=0;
frost_time:number=0;
run_time:number=0;
hited_time:number=0;
hit_count:number=0;
caster_crit:number=0;
caster_crit_d:number=0;
puncture:number=0;
puncture_damage:number=0;
debuff_up:number=0;
debuff_value:number=0;
debuff_count:number=0;
// 组件引用
anim:Animation=null;
tweenInstance:Tween<any> = null;
private moveDirection: Vec3 | null = null; // 添加一个属性来存储移动方向
// 缓存的配置对象(避免重复查找)
public skillConfig: any = null;
private isInitialized: boolean = false;
private initializeSkillConfig() {
if (this.isInitialized) return;
// 缓存技能配置,避免重复查找
this.skillConfig = SkillSet[this.s_uuid];
if (!this.skillConfig) {
// console.error("[SkillCom] 技能配置不存在:", this.s_uuid);
return;
}
this.isInitialized = true;
// console.log("[SkillCom] 技能配置初始化完成:", this.s_uuid, this.skillConfig.name);
}
start() {
this.initializeSkillConfig();
// var entity = this.ent as ecs.Entity; // ecs.Entity 可转为当前模块的具体实体对象
// this.on(ModuleEvent.Cmd, this.onHandler, this);
this.anim=this.node.getComponent(Animation)
this.on(GameEvent.MissionEnd, this.doDestroy, this);
this.node.active = true;
let collider = this.getComponent(Collider2D);
if(collider) {
collider.group = this.group;
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
}
do_anim(){
if(this.node.getComponent(Animation)){
let anim = this.node.getComponent(Animation);
//console.log("[SkillCom]:has anim",anim)
anim.on(Animation.EventType.FINISHED, this.onAnimationFinished, this);
}
}
do_parabolic(){
let bm=this.node.getComponent(BezierMove)
this.node.angle +=10
// bm.speed=700
if(this.group==BoxSet.MONSTER) {bm.controlPointSide=-1 }
bm.rotationSmoothness=0.6
bm.moveTo(this.targetPos)
}
do_line(){
let bm=this.node.getComponent(BezierMove)
let s_x=this.startPos.x
let s_y=this.startPos.y
let t_x=this.targetPos.x
let t_y=this.targetPos.y
// 设定目标x
this.targetPos.x = 400;
if(this.group == BoxSet.MONSTER) {
bm.controlPointSide = -1;
this.targetPos.x = -400;
}
// 计算斜率
const k = (t_y - s_y) / (t_x - s_x);
// 按直线公式计算新的y
this.targetPos.y = k * (this.targetPos.x - s_x) + s_y;
bm.controlPointOffset=0
bm.rotationSmoothness=0.6
bm.moveTo(this.targetPos);
}
onAnimationFinished(){
// console.log("[SkillCom]:onAnimationFinished",this.s_uuid)
if (!this.skillConfig) return;
if(this.skillConfig.EType==EType.timeEnd) return
if(this.skillConfig.SType!=SType.damage){
}
this.is_destroy=true
}
onBeginContact (seCol: Collider2D, oCol: Collider2D) {
// console.log(this.scale+"碰撞开始 ",seCol,oCol);
if(seCol.node.position.x-oCol.node.position.x > 100 ) return
let target = oCol.getComponent(HeroViewComp)
if(oCol.group!=this.group){
if(target == null) return;
if (!this.skillConfig) return;
// console.log("[SkillCom]:onBeginContact oCol||seCol",oCol.node.position,seCol.node.position)
this.single_damage(target,this.skillConfig.DTType==DTType.range?true:false)
// this.ent.destroy()
}
}
//单体伤害
single_damage(target:HeroViewComp,is_range:boolean=false){
// //console.log("[SkillCom]:onBeginContact hit_count:",this.hit_count,SkillSet[this.s_uuid].hit)
// if(this.hit_count > 0&&!is_range) this.ap=this.ap*(50+this.puncture_damage)/100 // 穿刺后 伤害减半,过滤范围伤害
if(target == null) return;
if (!this.skillConfig) return;
let ap=this.ap
if(this.hit_count > 0 &&!is_range ){
ap=ap*(50+this.puncture_damage)/100
}
target.do_atked(ap,this.caster_crit,this.caster_crit_d,
this.burn_count,this.burn_value,
this.stun_time,this.stun_ratio,
this.frost_time,this.frost_ratio,
this.skillConfig.AtkedType
) // ap 及暴击 属性已经在skill.ts 处理
// console.log("[SkillCom]:single_damage t:tp:rtp",this.node.position,this.targetPos,target.node.position)
if(this.skillConfig.debuff>0){
let debuff=this.skillConfig
let dev=debuff.deV*(100+this.debuff_value)/100
let deR=debuff.deR+this.debuff_up
dev=Math.round(dev*100)/100
let deC=debuff.deC+this.debuff_count //dec只作为次数叠加
// //console.log("[SkillCom]:debuff",this.skillConfig.name,debuff.debuff,deUP.deV,deUP.deC)
target.add_debuff(debuff.debuff,dev,deC,deR)
}
this.hit_count++
// console.log("[SkillCom]:碰撞次数:技能次数:穿刺次数",this.hit_count,this.skillConfig.hit,this.puncture)
if(this.hit_count>=(this.skillConfig.hit+this.puncture)&&(this.skillConfig.DTType!=DTType.range)&&(this.skillConfig.EType!=EType.animationEnd)&&(this.skillConfig.EType!=EType.timeEnd)) this.is_destroy=true // 技能命中次数
}
update(deltaTime: number) {
// 确保配置已初始化(处理 update 可能先于 start 执行的情况)
if (!this.isInitialized) {
this.initializeSkillConfig();
if (!this.skillConfig) return;
}
if(smc.mission.pause) {
if(this.anim) this.anim.pause()
return;
}
if(this.anim) this.anim.resume()
if (!this.node || !this.node.isValid) return;
if(this.skillConfig.EType==EType.timeEnd){
this.run_time+=deltaTime
if(this.run_time>this.skillConfig.in){
// //console.log("[SkillCom]: timeEnd destroy",this.s_uuid,this.run_time)
this.is_destroy=true
}
}
//直线移动
// if(this.skillConfig.AType == AType.linear) this.startLinearMove(deltaTime);
this.toDestroy();
}
toDestroy() {
if(this.is_destroy){
if (this.ent) {
this.ent.destroy();
} else {
// 如果ent不存在直接销毁节点
if (this.node && this.node.isValid) {
this.node.destroy();
}
}
}
}
doDestroy(){
// //console.log("[SkillCom]:doDestroy")
this.is_destroy=true
}
reset() {
this.node.destroy();
}
}