- 规范化DBuff的枚举命名,修正属性对应关系 - 统一DBuff与Attrs的双向映射,通过TransformBuffs函数处理转换 - 移除旧的getAttrFieldFromDebuff方法,改用更灵活的映射数组 - 更新Attrs枚举,增加被易伤、防护盾等新属性 - 重新调整AttrsType映射,保证属性类型一致性 refactor(hero): 重构Hero和Monster初始化属性及buff系统 - Hero初始化时完善基础属性赋值,新增基础移动速度与攻击距离 - Hero使用initAttrs替代initBuffsDebuffs,重构buff/debuff初始化流程 - Monster初始化简化,统一按Hero写法初始化基础属性和Attrs - 实现buff/debuff属性智能覆盖与叠加时长的改进逻辑 - 属性计算改用统一逻辑,支持数值型和百分比型准确计算 - 增加属性值范围限制,确保部分属性在合理区间内 refactor(heroViewComp): 优化buff/debuff管理及状态判断 - 统一buff和debuff的持久与临时管理字典及更新方法 - 优化临时buff/debuff的更新时间处理,自动触发属性重新计算 - 提供isStun和isFrost接口简化眩晕、冰冻状态判断 - 规范注释及代码格式,提升可读性和维护性 refactor(skillConComp): 优化眩晕与冰冻状态判断逻辑 - 移除遍历判断,改用HeroViewComp的isStun和isFrost方法 - 简化技能冷却更新逻辑,提升性能 chore(heroSet): 添加AttrSet枚举定义属性最大值限制 docs(rogueConfig): 更新说明文档中的属性枚举定义说明 - 将属性增强枚举由BuffAttr修改为Attrs,以保持一致性
177 lines
6.1 KiB
TypeScript
177 lines
6.1 KiB
TypeScript
import { _decorator, Component, Node, ProgressBar, v3, Vec3 } from 'cc';
|
|
import { HeroViewComp } from './HeroViewComp';
|
|
import { Attrs, DBuff, 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';
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass('SkillCon')
|
|
@ecs.register('SkillCon')
|
|
export class SkillConComp extends CCComp {
|
|
HeroView:any=null;
|
|
HeroEntity: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)
|
|
// //console.log(this.HeroView.uid+"=>"+this.HeroView.hero_name+"=> SkillConComp onLoad")
|
|
}
|
|
start() {
|
|
// //console.log(this.HeroView.uuid+"=>"+this.HeroView.hero_name+"=> SkillConComp 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.length;i++){
|
|
skills[i].cd += dt;
|
|
if(skills[i].cd > 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]) {
|
|
// //console.log(view.uuid+"=>"+view.hero_name+"施放技能:"+config.uuid);
|
|
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>(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.HeroView.ex_show("blue")
|
|
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);
|
|
}
|
|
}
|
|
|
|
|