Compare commits
2 Commits
9798930879
...
9f809b1ffa
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f809b1ffa | |||
| e42bdbb671 |
@@ -38,6 +38,7 @@ export class HeroSkillsComp extends ecs.Comp {
|
|||||||
// ==================== 技能槽位列表 ====================
|
// ==================== 技能槽位列表 ====================
|
||||||
/** 技能槽位数组(最多4个技能) */
|
/** 技能槽位数组(最多4个技能) */
|
||||||
skills: Record<number, SkillSlot> = {};
|
skills: Record<number, SkillSlot> = {};
|
||||||
|
max_auto: boolean = true;
|
||||||
|
|
||||||
// ==================== 辅助方法 ====================
|
// ==================== 辅助方法 ====================
|
||||||
|
|
||||||
@@ -270,4 +271,7 @@ export class HeroSkillsComp extends ecs.Comp {
|
|||||||
reset() {
|
reset() {
|
||||||
this.skills = {};
|
this.skills = {};
|
||||||
}
|
}
|
||||||
|
setMaxAuto(on: boolean) {
|
||||||
|
this.max_auto = on;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -52,6 +52,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
|||||||
for (const s_uuid of readySkills) {
|
for (const s_uuid of readySkills) {
|
||||||
const skill = skills.getSkill(s_uuid);
|
const skill = skills.getSkill(s_uuid);
|
||||||
if (!skill) continue;
|
if (!skill) continue;
|
||||||
|
if (skill.hset === HSSet.max && !skills.max_auto) continue;
|
||||||
|
|
||||||
const config = SkillSet[skill.s_uuid];
|
const config = SkillSet[skill.s_uuid];
|
||||||
if (!config || config.SType !== SType.damage) continue;
|
if (!config || config.SType !== SType.damage) continue;
|
||||||
@@ -66,20 +67,44 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private startCast(e: ecs.Entity,skill:SkillSlot,hset:HSSet): void {
|
private startCast(e: ecs.Entity,skill:SkillSlot,hset:HSSet): boolean {
|
||||||
if (!skill||!e) return
|
if (!skill||!e) return false
|
||||||
const skills = e.get(HeroSkillsComp);
|
const skills = e.get(HeroSkillsComp);
|
||||||
const heroAttrs = e.get(HeroAttrsComp);
|
const heroAttrs = e.get(HeroAttrsComp);
|
||||||
const heroView = e.get(HeroViewComp);
|
const heroView = e.get(HeroViewComp);
|
||||||
// 3. 检查施法条件
|
// 3. 检查施法条件
|
||||||
if (!this.checkCastConditions(skills, heroAttrs, skill.s_uuid)) return
|
if (!this.checkCastConditions(skills, heroAttrs, skill.s_uuid)) return false
|
||||||
|
|
||||||
// 4. 执行施法
|
// 4. 执行施法
|
||||||
this.executeCast(e, skill.s_uuid, heroView,hset);
|
const ok = this.executeCast(e, skill.s_uuid, heroView,hset);
|
||||||
// 5. 扣除资源和重置CD
|
// 5. 扣除资源和重置CD
|
||||||
heroAttrs.mp -= skill.cost;
|
if (ok) {
|
||||||
skills.resetCD(skill.s_uuid);
|
heroAttrs.mp -= skill.cost;
|
||||||
|
skills.resetCD(skill.s_uuid);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
public manualCast(e: ecs.Entity, s_uuid: number): boolean {
|
||||||
|
if (!e) return false
|
||||||
|
const skills = e.get(HeroSkillsComp)
|
||||||
|
const heroAttrs = e.get(HeroAttrsComp)
|
||||||
|
const heroView = e.get(HeroViewComp)
|
||||||
|
if (!skills || !heroAttrs || !heroView) return false
|
||||||
|
const slot = skills.getSkill(s_uuid)
|
||||||
|
if (!slot) return false
|
||||||
|
return this.startCast(e, slot, slot.hset)
|
||||||
|
}
|
||||||
|
public manualCastMax(e: ecs.Entity): boolean {
|
||||||
|
const skills = e.get(HeroSkillsComp)
|
||||||
|
if (!skills) return false
|
||||||
|
for (const key in skills.skills) {
|
||||||
|
const s_uuid = Number(key)
|
||||||
|
const slot = skills.getSkill(s_uuid)
|
||||||
|
if (slot && slot.hset === HSSet.max) {
|
||||||
|
return this.manualCast(e, s_uuid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 检查施法条件
|
* 检查施法条件
|
||||||
@@ -106,11 +131,11 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
|||||||
/**
|
/**
|
||||||
* 执行施法
|
* 执行施法
|
||||||
*/
|
*/
|
||||||
private executeCast(casterEntity: ecs.Entity, s_uuid: number, heroView: HeroViewComp,hset:HSSet) {
|
private executeCast(casterEntity: ecs.Entity, s_uuid: number, heroView: HeroViewComp,hset:HSSet): boolean {
|
||||||
const config = SkillSet[s_uuid];
|
const config = SkillSet[s_uuid];
|
||||||
if (!config) {
|
if (!config) {
|
||||||
console.error("[SACastSystem] 技能配置不存在:", s_uuid);
|
console.error("[SACastSystem] 技能配置不存在:", s_uuid);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
// 1. 播放施法动画
|
// 1. 播放施法动画
|
||||||
heroView.playSkillEffect(s_uuid);
|
heroView.playSkillEffect(s_uuid);
|
||||||
@@ -119,14 +144,11 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
|||||||
// 2. 更新攻击类型的天赋触发值
|
// 2. 更新攻击类型的天赋触发值
|
||||||
if(casterEntity.has(TalComp)){
|
if(casterEntity.has(TalComp)){
|
||||||
const talComp = casterEntity.get(TalComp);
|
const talComp = casterEntity.get(TalComp);
|
||||||
if (hset === HSSet.atk) {
|
if (hset === HSSet.atk) talComp.updateCur(TriType.ATK);
|
||||||
talComp.updateCur(TriType.ATK);
|
if (hset != HSSet.atk) talComp.updateCur(TriType.SKILL);
|
||||||
isWFuny= talComp.checkIsTrigger(TalEffet.WFUNY);
|
isDSill=talComp.checkIsTrigger().isDSill
|
||||||
}
|
isWFuny=talComp.checkIsTrigger().isWFuny
|
||||||
if (hset != HSSet.atk) {
|
|
||||||
talComp.updateCur(TriType.SKILL);
|
|
||||||
isDSill= talComp.checkIsTrigger(TalEffet.D_SKILL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -147,8 +169,10 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
|
|||||||
|
|
||||||
const heroAttrs = casterEntity.get(HeroAttrsComp);
|
const heroAttrs = casterEntity.get(HeroAttrsComp);
|
||||||
// console.log(`[SACastSystem] ${heroAttrs?.hero_name ?? '未知'} 施放技能: ${config.name}`);
|
// console.log(`[SACastSystem] ${heroAttrs?.hero_name ?? '未知'} 施放技能: ${config.name}`);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建技能实体
|
* 创建技能实体
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,145 +0,0 @@
|
|||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
|
||||||
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 { Skill } from "../skill/Skill";
|
|
||||||
import { CSRequestComp } from "../skill/STagComps";
|
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ==================== 技能施法系统 手动施法====================
|
|
||||||
*
|
|
||||||
* 职责:
|
|
||||||
* 1. 监听 CSRequestComp 标记组件
|
|
||||||
* 2. 检查施法条件(CD、MP、状态)
|
|
||||||
* 3. 扣除资源(MP)
|
|
||||||
* 4. 创建技能实体
|
|
||||||
* 5. 触发施法动画
|
|
||||||
* 6. 移除请求标记
|
|
||||||
*
|
|
||||||
* 设计理念:
|
|
||||||
* - 使用标记组件驱动,符合 ECS 理念
|
|
||||||
* - 施法检查与执行分离
|
|
||||||
* - 自动处理资源消耗和CD重置
|
|
||||||
*/
|
|
||||||
// @ecs.register('SCastSystem')
|
|
||||||
export class SCastSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 过滤器:拥有技能数据 + 施法请求的实体
|
|
||||||
*/
|
|
||||||
filter(): ecs.IMatcher {
|
|
||||||
return ecs.allOf(HeroSkillsComp, HeroAttrsComp, CSRequestComp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实体进入时触发(即请求施法时)
|
|
||||||
*/
|
|
||||||
entityEnter(e: ecs.Entity): void {
|
|
||||||
if(!smc.mission.play || smc.mission.pause) return;
|
|
||||||
const skillsComp = e.get(HeroSkillsComp);
|
|
||||||
const heroAttrs = e.get(HeroAttrsComp);
|
|
||||||
const request = e.get(CSRequestComp);
|
|
||||||
const heroView = e.get(HeroViewComp);
|
|
||||||
|
|
||||||
// 1. 验证数据完整性
|
|
||||||
if (!skillsComp || !heroAttrs || !request || !heroView) {
|
|
||||||
console.warn("[SCastSystem] 数据不完整,取消施法");
|
|
||||||
e.remove(CSRequestComp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 获取技能数据
|
|
||||||
const skill = skillsComp.getSkill(request.s_uuid);
|
|
||||||
if (!skill) {
|
|
||||||
console.warn(`[SCastSystem] 技能索引无效: ${request.s_uuid }`);
|
|
||||||
e.remove(CSRequestComp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 检查施法条件
|
|
||||||
if (!this.checkCastConditions(skillsComp, heroAttrs, request.s_uuid)) {
|
|
||||||
e.remove(CSRequestComp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 执行施法
|
|
||||||
this.executeCast(e, skill, request.targets, heroView);
|
|
||||||
|
|
||||||
// 5. 扣除资源和重置CD
|
|
||||||
heroAttrs.mp -= skill.cost;
|
|
||||||
skillsComp.resetCD(request.s_uuid);
|
|
||||||
|
|
||||||
// 6. 移除请求标记
|
|
||||||
e.remove(CSRequestComp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查施法条件
|
|
||||||
*/
|
|
||||||
private checkCastConditions(skillsComp: HeroSkillsComp, heroAttrs: HeroAttrsComp, skillIndex: number): boolean {
|
|
||||||
// 检查角色状态
|
|
||||||
if (heroAttrs.is_dead) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查控制状态(眩晕、冰冻)
|
|
||||||
if (heroAttrs.isStun() || heroAttrs.isFrost()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查CD和MP
|
|
||||||
if (!skillsComp.canCast(skillIndex, heroAttrs.mp)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行施法
|
|
||||||
*/
|
|
||||||
private executeCast(casterEntity: ecs.Entity, skill: any, targets: Vec3[], heroView: HeroViewComp) {
|
|
||||||
const config = SkillSet[skill.uuid];
|
|
||||||
if (!config) {
|
|
||||||
console.error("[SCastSystem] 技能配置不存在:", skill.uuid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 播放施法动画
|
|
||||||
heroView.playSkillEffect(skill.uuid);
|
|
||||||
|
|
||||||
// 2. 延迟创建技能实体(等待动画)
|
|
||||||
const delay = config.with ?? 0.3; // 施法前摇时间
|
|
||||||
heroView.scheduleOnce(() => {
|
|
||||||
this.createSkill(skill.uuid, heroView, targets);
|
|
||||||
}, delay);
|
|
||||||
|
|
||||||
const heroAttrs = casterEntity.get(HeroAttrsComp);
|
|
||||||
console.log(`[SCastSystem] ${heroAttrs?.hero_name ?? '未知'} 施放技能: ${config.name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建技能实体
|
|
||||||
*/
|
|
||||||
private createSkill(skillId: number, caster: HeroViewComp, targets: Vec3[]) {
|
|
||||||
// 检查节点有效性
|
|
||||||
if (!caster.node || !caster.node.isValid) {
|
|
||||||
console.warn("[SCastSystem] 施法者节点无效");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取场景节点
|
|
||||||
const parent = caster.node.parent;
|
|
||||||
if (!parent) {
|
|
||||||
console.warn("[SCastSystem] 场景节点无效");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ 使用现有的 SkillEnt 创建技能
|
|
||||||
// const skill = ecs.getEntity<Skill>(Skill);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -129,22 +129,35 @@ export class TalComp extends ecs.Comp {
|
|||||||
// 判断是否有天赋被触发
|
// 判断是否有天赋被触发
|
||||||
return Triggers;
|
return Triggers;
|
||||||
}
|
}
|
||||||
checkIsTrigger(effet: TalEffet) {
|
getTriggers() {
|
||||||
|
// 存储所有触发的天赋
|
||||||
|
let Triggers: Record<string, TalSlot> = {};
|
||||||
|
// 遍历所有天赋
|
||||||
for (let uuid in this.Tals) {
|
for (let uuid in this.Tals) {
|
||||||
const talent = this.Tals[uuid];
|
const talent = this.Tals[uuid];
|
||||||
// 匹配天赋类型
|
if (talent.cur >= (talent.Trigger - talent.Trigger_add)) { // 修复触发条件,累积值达到或超过触发阈值时触发
|
||||||
if (talent.effet == effet) {
|
console.log(`[TalComp]天赋触发,天赋ID:${uuid}`);
|
||||||
// 修复触发条件逻辑:累积值达到或超过触发阈值时触发
|
// 重置累积值
|
||||||
// 原逻辑中 `talent.Trigger-talent.Trigger` 总是为0,导致任何累积值都能触发
|
talent.cur = 0;
|
||||||
if (talent.cur >= (talent.Trigger - talent.Trigger_add)) { // 修复触发条件,累积值达到或超过触发阈值时触发
|
// 添加到触发列表
|
||||||
console.log(`[TalComp]天赋触发,天赋ID:${uuid}`);
|
Triggers[uuid] = talent;
|
||||||
// 重置累积值
|
}
|
||||||
talent.cur = 0;
|
|
||||||
// 添加到触发列表
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 判断是否有天赋被触发
|
||||||
|
return Triggers;
|
||||||
|
}
|
||||||
|
checkIsTrigger() {
|
||||||
|
let res = {
|
||||||
|
isDSill:false,
|
||||||
|
isWFuny:false,
|
||||||
|
}
|
||||||
|
for(let uuid in this.Tals){
|
||||||
|
let trigger=this.Tals[uuid]
|
||||||
|
if(trigger.effet==TalEffet.WFUNY) res.isWFuny=true
|
||||||
|
if(trigger.effet==TalEffet.D_SKILL) res.isDSill=true
|
||||||
|
|
||||||
|
}
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 更新天赋的效果数值
|
* 更新天赋的效果数值
|
||||||
|
|||||||
Reference in New Issue
Block a user