diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index 3e582793..ba8ae751 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -1,5 +1,12 @@ // ========== 从 HeroAttrs.ts 导入属性相关定义 ========== import { Attrs, NeAttrs,BType, getAttrs, AttrsType, isRatioAttr } from "./HeroAttrs"; + +export enum HSSet { + atk = 0, // 普通攻击 + skill = 1, // 一般技能 + max = 2, // 必杀技 +} + export enum TGroup { Self = 0, // 自身 Ally = 1, // 所有敌人 diff --git a/assets/script/game/common/config/TalSet.ts b/assets/script/game/common/config/TalSet.ts index 58afa4ea..25a78153 100644 --- a/assets/script/game/common/config/TalSet.ts +++ b/assets/script/game/common/config/TalSet.ts @@ -23,13 +23,11 @@ export enum TalEffet { MP=3, //回蓝 百分比 BUFF = 4, // 暴击率,闪避率等,可叠加的触发后清零 STATS=5, // 状态 - N_ATK = 6, // 下n次普通攻击暴击 - N_SKILL=7, // 下n次技能攻击暴击 - WFUNY=8, // 风怒 - SPLASH=9, // 溅射 - D_SKILL=10, //两次技能 - SHIELD=11, // 护盾 - LDMG=12, // 减伤 + WFUNY=6, // 风怒 + SPLASH=7, // 溅射 + D_SKILL=8, //两次技能 + SHIELD=9, // 护盾 + LDMG=10, // 减伤 } export enum TalTarget { @@ -44,6 +42,8 @@ export enum TalAttrs { BACK_CHANCE=Attrs.BACK_CHANCE, // 击退概率 SILENCE_CHANCE=Attrs.SILENCE_CHANCE, // 沉默概率 CRITICAL=Attrs.CRITICAL, // 暴击率 + AP=Attrs.AP, // 攻击力 + MP=Attrs.MAP, // 魔法 } /** * 天赋配置接口 @@ -110,12 +110,12 @@ export const talConf: Record = { desc:"被攻击3次后, 下1次伤害减50%"}, - /*** 失去血量触发 ***/ - 7201:{uuid:7201,name:"背水",triType:TriType.HPL,Trigger:50,target:TalTarget.SELF,effet:TalEffet.N_ATK,value:10,attrs:TalAttrs.NON, + /*** 失去血量触发 ***/ //需要重新设计,触发类型 + 7201:{uuid:7201,name:"背水",triType:TriType.HPL,Trigger:50,target:TalTarget.SELF,effet:TalEffet.BUFF,value:10,attrs:TalAttrs.AP, desc:"每失去50%生命值,获得下10次普通攻击暴击"}, - /*** 升级触发 ***/ - 7301:{uuid:7301,name:"勤勉",triType:TriType.LUP,Trigger:1,target:TalTarget.SELF,effet:TalEffet.N_ATK,value:10,attrs:TalAttrs.NON, + /*** 升级触发 ***/ //需要重新设计,触发类型 + 7301:{uuid:7301,name:"勤勉",triType:TriType.LUP,Trigger:1,target:TalTarget.SELF,effet:TalEffet.BUFF,value:5,attrs:TalAttrs.AP, desc:"每升1级,获得下5次技能暴击"}, }; diff --git a/assets/script/game/hero/HeroSkills.ts b/assets/script/game/hero/HeroSkills.ts index ead4cfa5..48e39dfc 100644 --- a/assets/script/game/hero/HeroSkills.ts +++ b/assets/script/game/hero/HeroSkills.ts @@ -1,7 +1,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { Attrs } from "../common/config/HeroAttrs"; import { HeroInfo } from "../common/config/heroSet"; -import { SkillSet } from "../common/config/SkillSet"; +import { HSSet, SkillSet } from "../common/config/SkillSet"; import { HeroAttrsComp } from "./HeroAttrsComp"; /** @@ -15,8 +15,10 @@ export interface SkillSlot { cost: number; // MP消耗 level: number; // 技能等级(预留) dis: number; // 攻击距离 + hset: HSSet; // 技能设定, 0:普通攻击, 1:一般技能, 2:必杀技 } + /** * ==================== 英雄技能数据组件 ==================== * @@ -56,6 +58,9 @@ export class HeroSkillsComp extends ecs.Comp { } // 第0个技能的 cd_max 取 herosinfo[uuid].as const cdMax = i === 0 ? HeroInfo[uuid].as : config.cd; + let hset = HSSet.atk; + if(i ===1) hset = HSSet.skill; + if(i ===2) hset = HSSet.max; this.skills[s_uuid] = { s_uuid: config.uuid, cd: 0, @@ -63,6 +68,7 @@ export class HeroSkillsComp extends ecs.Comp { cost: config.cost, level: 1, dis: Number(config.dis), + hset: hset, }; } @@ -80,7 +86,7 @@ export class HeroSkillsComp extends ecs.Comp { * @param s_uuid 技能配置ID * @param entity 实体对象(用于更新技能距离缓存) */ - addSkill(s_uuid: number, entity?: ecs.Entity) { + addSkill(s_uuid: number, entity?: ecs.Entity, hset: HSSet=HSSet.skill) { const config = SkillSet[s_uuid]; if (!config) { console.warn(`[HeroSkills] 技能配置不存在: ${s_uuid}`); @@ -93,6 +99,7 @@ export class HeroSkillsComp extends ecs.Comp { cost: config.cost, level: 1, dis: Number(config.dis), + hset: hset, }; // 更新技能距离缓存 diff --git a/assets/script/game/hero/SACastSystem.ts b/assets/script/game/hero/SACastSystem.ts index 08227330..501ca7d0 100644 --- a/assets/script/game/hero/SACastSystem.ts +++ b/assets/script/game/hero/SACastSystem.ts @@ -2,10 +2,12 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec import { Vec3, v3 } from "cc"; import { HeroAttrsComp } from "./HeroAttrsComp"; import { HeroViewComp } from "./HeroViewComp"; -import { SkillSet, SType } from "../common/config/SkillSet"; +import { HSSet, SkillSet, SType } from "../common/config/SkillSet"; import { HeroSkillsComp, SkillSlot } from "./HeroSkills"; import { Skill } from "../skill/Skill"; import { smc } from "../common/SingletonModuleComp"; +import { TalComp } from "./TalComp"; +import { TalEffet, TriType } from "../common/config/TalSet"; /** * ==================== 自动施法系统 ==================== @@ -58,13 +60,13 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat if (!this.hasEnemyInSkillRange(heroView, heroAttrs, skill.dis)) continue; // ✅ 开始执行施法 - this.startCast(e,skill); + this.startCast(e,skill,skill.hset); // 一次只施放一个技能 break; } } - private startCast(e: ecs.Entity,skill:SkillSlot): void { + private startCast(e: ecs.Entity,skill:SkillSlot,hset:HSSet): void { if (!skill||!e) return const skills = e.get(HeroSkillsComp); const heroAttrs = e.get(HeroAttrsComp); @@ -73,7 +75,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat if (!this.checkCastConditions(skills, heroAttrs, skill.s_uuid)) return // 4. 执行施法 - this.executeCast(e, skill.s_uuid, heroView); + this.executeCast(e, skill.s_uuid, heroView,hset); // 5. 扣除资源和重置CD heroAttrs.mp -= skill.cost; skills.resetCD(skill.s_uuid); @@ -104,7 +106,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat /** * 执行施法 */ - private executeCast(casterEntity: ecs.Entity, s_uuid: number, heroView: HeroViewComp) { + private executeCast(casterEntity: ecs.Entity, s_uuid: number, heroView: HeroViewComp,hset:HSSet) { const config = SkillSet[s_uuid]; if (!config) { console.error("[SACastSystem] 技能配置不存在:", s_uuid); @@ -112,12 +114,36 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat } // 1. 播放施法动画 heroView.playSkillEffect(s_uuid); + let isDSill=false + let isWFuny=false + // 2. 更新攻击类型的天赋触发值 + if(casterEntity.has(TalComp)){ + const talComp = casterEntity.get(TalComp); + if (hset === HSSet.atk) { + talComp.updateCur(TriType.ATK); + isWFuny= talComp.checkIsTrigger(TalEffet.WFUNY); + } + if (hset != HSSet.atk) { + talComp.updateCur(TriType.SKILL); + isDSill= talComp.checkIsTrigger(TalEffet.D_SKILL); + } + } + // 2. 延迟创建技能实体(等待动画) const delay = 0.3 heroView.scheduleOnce(() => { - this.createSkill(s_uuid, heroView); + this.createSkill(s_uuid, heroView,isWFuny); + isWFuny=false }, delay); + + if(isDSill){ + heroView.playSkillEffect(s_uuid); + heroView.scheduleOnce(() => { + this.createSkill(s_uuid, heroView,isWFuny); + isWFuny=false + }, delay); + } const heroAttrs = casterEntity.get(HeroAttrsComp); // console.log(`[SACastSystem] ${heroAttrs?.hero_name ?? '未知'} 施放技能: ${config.name}`); @@ -126,7 +152,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat /** * 创建技能实体 */ - private createSkill(s_uuid: number, caster: HeroViewComp) { + private createSkill(s_uuid: number, caster: HeroViewComp,isWFuny:boolean) { // 检查节点有效性 if (!caster.node || !caster.node.isValid) { console.warn("[SACastSystem] 施法者节点无效"); diff --git a/assets/script/game/hero/TalComp.ts b/assets/script/game/hero/TalComp.ts index 2002c746..aeef4e3e 100644 --- a/assets/script/game/hero/TalComp.ts +++ b/assets/script/game/hero/TalComp.ts @@ -1,39 +1,221 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; -import { BuffConf, SkillSet } from "../common/config/SkillSet"; -import { TalAttrs, TalEffet, TalTarget, TriType } from "../common/config/TalSet"; -import { HeroInfo } from "../common/config/heroSet"; +import { TalAttrs, talConf, TalEffet, TalTarget, TriType} from "../common/config/TalSet"; import { HeroViewComp } from "./HeroViewComp"; - - +/** + * 天赋槽位接口定义 + * 描述单个天赋的数据结构 + */ export interface TalSlot { - uuid: number; // 天赋ID + uuid: number; // 天赋唯一标识符 name: string; // 天赋名称 - value: number; // 触发的效果价值 - Trigger:boolean //触发值减值 - C_Trigger:number //当前值 + triType: TriType; // 天赋触发类型 + target: TalTarget; + effet: TalEffet; + attrs?:TalAttrs //触发的attrs效果的对应attrs value: number; // 触发的效果数值 + value: number; // 触发的效果数值 + value_add: number; // 触发的效果数值增量 + Trigger: number; // 天赋触发阈值 + Trigger_add: number; // 天赋触发阈值减值 + desc: string; // 天赋描述(说明触发条件和效果) + cur: number; // 当前累积值 } /** * 天赋系统组件类 - * 继承自 CCComp,作为 ECS 架构中的组件存在 - * 负责管理英雄的天赋系统,包括天赋获取、触发、效果应用等 + * 作为ECS架构中的组件,负责管理英雄的天赋系统 + * + * 核心功能: + * - 初始化英雄天赋系统 + * - 添加新天赋到英雄 + * - 累积天赋触发进度 + * - 检查并触发满足条件的天赋 + * - 管理天赋效果数值 */ @ecs.register('TalComp', false) export class TalComp extends ecs.Comp { - /** 英雄视图组件引用,运行时获取避免循环引用 */ + /** 英雄视图组件引用,运行时获取以避免循环引用 */ private heroView: any = null; - private skillCon:any=null; - /** 英雄唯一标识符,用于从配置中获取英雄信息 */ + + /** 英雄唯一标识符,用于从配置中获取英雄相关信息 */ private heroUuid: number = 0; - /** 天赋数组 */ + + /** 天赋集合,以天赋ID为键,存储所有已获得的天赋 */ Tals: Record = {}; - /** 天赋槽位数组,默认开启2个,最多4个 */ - TalSlots:number[]=[1,1,0,0] - - reset() { - + + /** + * 组件初始化方法 + * @param heroUuid 英雄唯一标识符 + */ + init(heroUuid: number) { + this.heroUuid = heroUuid; + // 从实体中获取英雄视图组件引用 + this.heroView = this.ent.get(HeroViewComp); + // 初始化天赋集合 + this.Tals = {}; } + /** + * 为英雄添加一个新天赋 + * @param talUuid 要添加的天赋ID + * + * 添加流程: + * 1. 检查天赋是否已存在 + * 2. 检查天赋配置是否存在 + * 3. 创建并初始化天赋数据 + */ + addTal(talUuid: number) { + // 检查天赋是否已存在 + if (this.Tals[talUuid]) { + console.error(`[TalComp]天赋已存在,天赋ID:${talUuid}`); + return; + } + + // 获取天赋配置 + const tConf = talConf[talUuid]; + if (!tConf) { + console.error(`[TalComp]天赋配置不存在,天赋ID:${talUuid}`); + return; + } + + // 创建并初始化天赋数据 + this.Tals[talUuid] = { + uuid: talUuid, + name: tConf.name, + triType: tConf.triType, + target: tConf.target, + effet: tConf.effet, + attrs: tConf.attrs, + value: tConf.value, // 效果数值初始为配置值 + value_add: 0, // 效果数值增量初始为0 + Trigger: tConf.Trigger, // 触发阈值(后续可从配置中读取) + Trigger_add: 0, // 触发阈值增量初始为0 + desc: tConf.desc, + cur: 0, // 当前累积值初始为0 + }; + } + checkTal() { + return Object.keys(this.Tals).length > 0; + } + /** + * 检查并触发指定类型的天赋 + * @param triType 要检查的天赋触发类型 + * @returns 触发的天赋对象集合,若没有触发则返回false + * + * 检查逻辑: + * 1. 遍历所有同类型天赋 + * 2. 检查累积值是否达到触发条件 + * 3. 触发后重置累积值 + * 4. 收集并返回所有触发的天赋 + */ + checkTriggers(effet: TalEffet) { + // 存储所有触发的天赋 + let Triggers: Record = {}; + // 遍历所有天赋 + for (let uuid in this.Tals) { + const talent = this.Tals[uuid]; + // 匹配天赋类型 + if (talent.effet == effet) { + // 修复触发条件逻辑:累积值达到或超过触发阈值时触发 + // 原逻辑中 `talent.Trigger-talent.Trigger` 总是为0,导致任何累积值都能触发 + if (talent.cur >= (talent.Trigger - talent.Trigger_add)) { // 修复触发条件,累积值达到或超过触发阈值时触发 + console.log(`[TalComp]天赋触发,天赋ID:${uuid}`); + // 重置累积值 + talent.cur = 0; + // 添加到触发列表 + Triggers[uuid] = talent; + } + } + } + // 判断是否有天赋被触发 + return Triggers; + } + checkIsTrigger(effet: TalEffet) { + for (let uuid in this.Tals) { + const talent = this.Tals[uuid]; + // 匹配天赋类型 + if (talent.effet == effet) { + // 修复触发条件逻辑:累积值达到或超过触发阈值时触发 + // 原逻辑中 `talent.Trigger-talent.Trigger` 总是为0,导致任何累积值都能触发 + if (talent.cur >= (talent.Trigger - talent.Trigger_add)) { // 修复触发条件,累积值达到或超过触发阈值时触发 + console.log(`[TalComp]天赋触发,天赋ID:${uuid}`); + // 重置累积值 + talent.cur = 0; + // 添加到触发列表 + return true; + } + } + } + } + /** + * 更新天赋的效果数值 + * @param talUuid 天赋ID + * @param val 要增减的数值 + * + * 功能: + * - 用于调整天赋的实际效果数值 + * - 可通过正负数来增加或减少效果 + */ + updateVal(talUuid: number, val: number) { + // 检查天赋是否存在 + if (!this.Tals[talUuid]) { + console.error(`[TalComp]天赋不存在,天赋ID:${talUuid}`); + return; + } + + // 更新天赋效果数值 + this.Tals[talUuid].value_add += val; + } + + updateTrigger(talUuid: number, val: number) { + // 检查天赋是否存在 + if (!this.Tals[talUuid]) { + console.error(`[TalComp]天赋不存在,天赋ID:${talUuid}`); + return; + } + + // 更新天赋触发阈值 + this.Tals[talUuid].Trigger_add += val; + if (this.Tals[talUuid].Trigger-this.Tals[talUuid].Trigger_add <= 1) { + this.Tals[talUuid].Trigger_add = this.Tals[talUuid].Trigger-1; + } + } + /** + * 更新指定类型天赋的累积值 + * @param triType 天赋触发类型 + * @param val 要增加的累积值,默认值为1 + * + * 设计注意: + * - 当前实现只会更新第一个匹配类型的天赋 + * - 累积值用于后续判断是否触发天赋效果 + */ + updateCur(triType: TriType, val: number = 1) { + // 遍历所有天赋 + for (let uuid in this.Tals) { + const talent = this.Tals[uuid]; + + // 找到第一个匹配类型的天赋并更新 + if (talent.triType == triType) { + talent.cur += val; + break; // 只更新第一个匹配的天赋 + } + } + } + + /** + * 重置组件状态 + * + * 功能: + * - 清空所有天赋数据 + * - 重置英雄ID + * - 清除英雄视图引用 + * - 为组件的复用做准备 + */ + reset() { + this.Tals = {}; + this.heroUuid = 0; + this.heroView = null; + } + } \ No newline at end of file