refactor(技能系统): 重构技能系统以使用s_uuid作为主键并优化技能施放逻辑
- 将HeroSkillsComp中的技能数组改为以s_uuid为键的对象存储 - 修改CSRequestComp使用s_uuid替代skillIndex - 优化SkillCastSystem和SACastSystem的施放逻辑 - 为SMoveDataComp添加rePos方法处理技能位置计算 - 移除未使用的SDataComSystem代码
This commit is contained in:
@@ -3,8 +3,8 @@ import { Vec3, v3 } from "cc";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { SkillSet, SType } from "../common/config/SkillSet";
|
||||
import { HeroSkillsComp } from "./HeroSkills";
|
||||
import { CSRequestComp } from "../skill/STagComps";
|
||||
import { HeroSkillsComp, SkillSlot } from "./HeroSkills";
|
||||
import { Skill } from "../skill/Skill";
|
||||
|
||||
/**
|
||||
* ==================== 自动施法系统 ====================
|
||||
@@ -30,38 +30,116 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
||||
|
||||
update(e: ecs.Entity): void {
|
||||
const skills = e.get(HeroSkillsComp);
|
||||
const heroModel = e.get(HeroAttrsComp);
|
||||
const heroAttrs = e.get(HeroAttrsComp);
|
||||
const heroView = e.get(HeroViewComp);
|
||||
if (!skills || !heroModel || !heroView) return;
|
||||
if (!skills || !heroAttrs || !heroView) return;
|
||||
|
||||
// 检查基本条件
|
||||
if (heroModel.is_dead || heroModel.isStun() || heroModel.isFrost()) return;
|
||||
if (heroAttrs.is_dead || heroAttrs.isStun() || heroAttrs.isFrost()) return;
|
||||
|
||||
// 检查是否正在攻击(只有攻击时才释放技能)
|
||||
if (!heroModel.is_atking) return;
|
||||
if (!heroAttrs.is_atking) return;
|
||||
|
||||
// 获取所有可施放的技能
|
||||
const readySkills = skills.getReadySkills(heroModel.mp);
|
||||
const readySkills = skills.getReadySkills(heroAttrs.mp);
|
||||
if (readySkills.length === 0) return;
|
||||
|
||||
// 选择第一个可施放的伤害技能
|
||||
for (const skillIndex of readySkills) {
|
||||
const skill = skills.getSkill(skillIndex);
|
||||
for (const s_uuid of readySkills) {
|
||||
const skill = skills.getSkill(s_uuid);
|
||||
if (!skill) continue;
|
||||
|
||||
const config = SkillSet[skill.uuid];
|
||||
const config = SkillSet[skill.s_uuid];
|
||||
if (!config || config.SType !== SType.damage) continue;
|
||||
|
||||
// ✅ 添加施法请求标记组件
|
||||
const request = e.add(CSRequestComp) as CSRequestComp;
|
||||
request.skillIndex = skillIndex;
|
||||
request.targets = this.sTargets(heroView);
|
||||
// ✅ 开始执行施法
|
||||
this.startCast(e,skill);
|
||||
|
||||
// 一次只施放一个技能
|
||||
break;
|
||||
}
|
||||
}
|
||||
private startCast(e: ecs.Entity,skill:SkillSlot): void {
|
||||
if (!skill||!e) return
|
||||
const skills = e.get(HeroSkillsComp);
|
||||
const heroAttrs = e.get(HeroAttrsComp);
|
||||
const heroView = e.get(HeroViewComp);
|
||||
// 3. 检查施法条件
|
||||
if (!this.checkCastConditions(skills, heroAttrs, skill.s_uuid)) return
|
||||
|
||||
// 4. 执行施法
|
||||
this.executeCast(e, skill.s_uuid, heroView);
|
||||
// 5. 扣除资源和重置CD
|
||||
heroAttrs.mp -= skill.cost;
|
||||
skills.resetCD(skill.s_uuid);
|
||||
|
||||
}
|
||||
/**
|
||||
* 检查施法条件
|
||||
*/
|
||||
private checkCastConditions(skills: HeroSkillsComp, heroAttrs: HeroAttrsComp, s_uuid: number): boolean {
|
||||
// 检查角色状态
|
||||
if (heroAttrs.is_dead) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查控制状态(眩晕、冰冻)
|
||||
if (heroAttrs.isStun() || heroAttrs.isFrost()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查CD和MP
|
||||
if (!skills.canCast(s_uuid, heroAttrs.mp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行施法
|
||||
*/
|
||||
private executeCast(casterEntity: ecs.Entity, s_uuid: number, heroView: HeroViewComp) {
|
||||
const config = SkillSet[s_uuid];
|
||||
if (!config) {
|
||||
console.error("[SkillCastSystem] 技能配置不存在:", s_uuid);
|
||||
return;
|
||||
}
|
||||
// 1. 播放施法动画
|
||||
heroView.playSkillEffect(s_uuid);
|
||||
|
||||
// 2. 延迟创建技能实体(等待动画)
|
||||
const delay = config.with ?? 0.3; // 施法前摇时间
|
||||
heroView.scheduleOnce(() => {
|
||||
this.createSkill(s_uuid, heroView);
|
||||
}, delay);
|
||||
|
||||
const heroAttrs = casterEntity.get(HeroAttrsComp);
|
||||
console.log(`[SkillCastSystem] ${heroAttrs?.hero_name ?? '未知'} 施放技能: ${config.name}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建技能实体
|
||||
*/
|
||||
private createSkill(s_uuid: number, caster: HeroViewComp) {
|
||||
// 检查节点有效性
|
||||
if (!caster.node || !caster.node.isValid) {
|
||||
console.warn("[SkillCastSystem] 施法者节点无效");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取场景节点
|
||||
const parent = caster.node.parent;
|
||||
if (!parent) {
|
||||
console.warn("[SkillCastSystem] 场景节点无效");
|
||||
return;
|
||||
}
|
||||
const targets=this.sTargets(caster);
|
||||
// ✅ 使用Skill 创建技能
|
||||
const skill = ecs.getEntity<Skill>(Skill);
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* 选择目标位置
|
||||
*/
|
||||
@@ -71,8 +149,8 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
||||
|
||||
// 这里可以调用 SkillConComp 的目标选择逻辑
|
||||
// 暂时返回默认位置
|
||||
const heroModel = caster.ent.get(HeroAttrsComp);
|
||||
const fac = heroModel?.fac ?? 0;
|
||||
const heroAttrs = caster.ent.get(HeroAttrsComp);
|
||||
const fac = heroAttrs?.fac ?? 0;
|
||||
const defaultX = fac === 0 ? 400 : -400;
|
||||
targets.push(v3(defaultX, 0, 0));
|
||||
|
||||
@@ -84,11 +162,11 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
||||
*/
|
||||
private sDamageTargets(caster: HeroViewComp, config: any, maxTargets: number): Vec3[] {
|
||||
const targets: Vec3[] = [];
|
||||
const heroModel = caster.ent.get(HeroAttrsComp);
|
||||
if (!heroModel) return targets;
|
||||
const heroAttrs = caster.ent.get(HeroAttrsComp);
|
||||
if (!heroAttrs) return targets;
|
||||
|
||||
// 寻找最近的敌人
|
||||
const enemyPositions = this.findNearbyEnemies(caster, heroModel.fac, config.range || 300);
|
||||
const enemyPositions = this.findNearbyEnemies(caster, heroAttrs.fac, config.range || 300);
|
||||
|
||||
// 选择最多maxTargets个目标
|
||||
for (let i = 0; i < Math.min(maxTargets, enemyPositions.length); i++) {
|
||||
@@ -97,7 +175,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
||||
|
||||
// 如果没有找到敌人,使用默认位置
|
||||
if (targets.length === 0) {
|
||||
targets.push(...this.sDefaultTargets(caster, heroModel.fac));
|
||||
targets.push(...this.sDefaultTargets(caster, heroAttrs.fac));
|
||||
}
|
||||
|
||||
return targets;
|
||||
@@ -108,11 +186,11 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
||||
*/
|
||||
private sHealTargets(caster: HeroViewComp, config: any, maxTargets: number): Vec3[] {
|
||||
const targets: Vec3[] = [];
|
||||
const heroModel = caster.ent.get(HeroAttrsComp);
|
||||
if (!heroModel) return targets;
|
||||
const heroAttrs = caster.ent.get(HeroAttrsComp);
|
||||
if (!heroAttrs) return targets;
|
||||
|
||||
// 寻找血量最低的友军
|
||||
const allyPositions = this.findLowHealthAllies(caster, heroModel.fac, config.range || 200);
|
||||
const allyPositions = this.findLowHealthAllies(caster, heroAttrs.fac, config.range || 200);
|
||||
|
||||
for (let i = 0; i < Math.min(maxTargets, allyPositions.length); i++) {
|
||||
targets.push(allyPositions[i]);
|
||||
@@ -179,5 +257,6 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
||||
|
||||
return allies;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user