From 63423c5378d6d430adbde0b840ace1eb1d2f1f7f Mon Sep 17 00:00:00 2001 From: panFD Date: Sat, 5 Sep 2026 13:26:34 +0800 Subject: [PATCH] feat(skill): add proc skill trigger system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现技能命中后概率触发额外技能的完整流程 1. 新增proc_skill技能配置字段与数据组件 2. 新增公共技能派发工具方法 3. 在HeroAtkSystem中添加触发逻辑 4. 完善伤害事件与技能视图传递proc_skill参数 --- assets/script/game/common/config/SkillSet.ts | 12 ++++++++++++ assets/script/game/hero/DamageQueueComp.ts | 11 ++++++++--- assets/script/game/hero/HeroAtkSystem.ts | 19 +++++++++++++++++++ assets/script/game/hero/SkillTriggerHelper.ts | 13 +++++++++++++ assets/script/game/skill/SDataCom.ts | 5 +++++ assets/script/game/skill/Skill.ts | 2 ++ assets/script/game/skill/SkillView.ts | 2 ++ 7 files changed, 61 insertions(+), 3 deletions(-) diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index ae0e0757..cbfe71a1 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -171,6 +171,15 @@ export interface SkillConfig { call_hero?: number, // 召唤技能召唤英雄id(可选) summon_count?: number, // 单次施法召唤的技能实体个数(未配置时回退 prefab 上 SkillView.summon_count) is_accel?: boolean, // 是否逐渐加速飞行 + /** + * 命中后概率触发额外技能(技能级触发器)。 + * s_uuid: 被触发的技能 uuid;chance: 触发概率(百分点,缺省 100)。 + * overrides: 透传给被触发技能的覆写参数(如 ap/hit_count 等),用于自定义被触发技能的伤害/数值; + * 与被触发技能自身在 heroSet 中的 overrides 叠加(本次传入优先)。 + * 触发走 SkillTriggerHelper/forceCastTriggerSkill 通道(无视 CD、无施法前摇),与 atking 同一通道。 + * 支持在 lv_entries 的 overrides 里按等级覆写(利用 overrides 浅合并机制)。 + */ + proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }, info: string, // 技能描述 } @@ -202,6 +211,9 @@ export interface SkillOverrides { revive_hp?: number; /** 复活次数上限,配合 revive_hp 使用(仅 dead 触发有效) */ revive_count?: number; + /** 命中后概率触发额外技能(技能级触发器,覆写 SkillConfig.proc_skill),支持 lv_entries 按等级覆写; + * overrides 字段可自定义被触发技能的伤害/数值(如 ap),透传给 forceCastTriggerSkill */ + proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }; /** 英雄语境专属图标(图鉴面板/技能弹窗展示用):配置后覆盖 SkillSet.icon, * 实现"同一底座、不同英雄/档位不同外观"(如 5002 普攻与冲刺斩同 6004 但图标不同) */ icon?: string; diff --git a/assets/script/game/hero/DamageQueueComp.ts b/assets/script/game/hero/DamageQueueComp.ts index fd18cf3b..53506c60 100644 --- a/assets/script/game/hero/DamageQueueComp.ts +++ b/assets/script/game/hero/DamageQueueComp.ts @@ -1,5 +1,6 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { HeroViewComp } from "./HeroViewComp"; +import { SkillOverrides } from "../common/config/SkillSet"; /** * ==================== 伤害事件数据 ==================== @@ -29,6 +30,9 @@ export interface DamageEvent { * 跳过 dmgCount 公式直接用该值,且不走击退/受击动画,其余(暴击/冰冻/击晕/护盾/死亡链)与普攻一致 */ dot_dmg?:number + /** 命中后概率触发额外技能(由施法技能实体快照自合并后配置,HeroAtkSystem 据此判定; + * overrides 字段透传给被触发技能,用于自定义伤害/数值) */ + proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides } } /** @@ -65,7 +69,7 @@ export class DamageQueueComp extends ecs.Comp { /** * 添加伤害事件到队列 */ - addDamageEvent(attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1,dot_dmg:number=0): void { + addDamageEvent(attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1,dot_dmg:number=0,proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }): void { const timestamp = Date.now(); const damageEvent: DamageEvent = { @@ -77,6 +81,7 @@ export class DamageQueueComp extends ecs.Comp { ext_dmg:ext_dmg, dmg_ratio:dmg_ratio, dot_dmg:dot_dmg, + proc_skill:proc_skill, }; this.damageEvents.push(damageEvent); @@ -182,7 +187,7 @@ export class DamageQueueHelper { * 为实体添加伤害事件 * 如果实体没有伤害队列组件,会自动创建 */ - static addDamageToEntity(entity: ecs.Entity, attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1,dot_dmg:number=0): void { + static addDamageToEntity(entity: ecs.Entity, attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1,dot_dmg:number=0,proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }): void { let damageQueue = entity.get(DamageQueueComp); // 如果实体没有伤害队列组件,创建一个 @@ -191,7 +196,7 @@ export class DamageQueueHelper { } // 添加伤害事件到队列 - damageQueue.addDamageEvent(attrs, casterEid, s_uuid,ext_dmg,dmg_ratio,dot_dmg); + damageQueue.addDamageEvent(attrs, casterEid, s_uuid,ext_dmg,dmg_ratio,dot_dmg,proc_skill); } /** diff --git a/assets/script/game/hero/HeroAtkSystem.ts b/assets/script/game/hero/HeroAtkSystem.ts index 684d44d1..04367d38 100644 --- a/assets/script/game/hero/HeroAtkSystem.ts +++ b/assets/script/game/hero/HeroAtkSystem.ts @@ -271,6 +271,25 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda } } + // 命中概率触发额外技能(proc_skill):配置由施法技能实体快照自合并后配置(含 heroSet overrides/lv_entries), + // 触发走 SkillTriggerHelper/forceCastTriggerSkill 通道(无视 CD、无施法前摇),与 atking 同一通道。 + // 防递归:被触发的技能经 forceCastTriggerSkill 不再产生 proc_skill 伤害事件之外的新事件,且不会累加 atk_count。 + if (!isDot && damageEvent.proc_skill) { + const proc = damageEvent.proc_skill; + const procChance = proc.chance ?? 100; + if (procChance >= 100 || Math.random() * 100 < procChance) { + const caster = ecs.getEntityByEid(casterEid); + if (caster) { + const casterAttrs = caster.get(HeroAttrsComp); + const casterView = caster.get(HeroViewComp); + if (casterAttrs && casterView && !casterAttrs.is_dead && !casterAttrs.is_reviving) { + // proc_skill.overrides 透传给被触发技能(如自定义 ap 伤害),与被触发技能自身 overrides 叠加(本次传入优先) + SkillTriggerHelper.dispatchSinglePublic(proc.s_uuid, casterAttrs, casterView, SkillTriggerType.Atking, proc.overrides); + } + } + } + } + // 检查死亡 if (TAttrsComp.hp <= 0) { diff --git a/assets/script/game/hero/SkillTriggerHelper.ts b/assets/script/game/hero/SkillTriggerHelper.ts index c252735c..4aaf02c1 100644 --- a/assets/script/game/hero/SkillTriggerHelper.ts +++ b/assets/script/game/hero/SkillTriggerHelper.ts @@ -166,4 +166,17 @@ export class SkillTriggerHelper { overrides: overrides }); } + + /** + * 公共单技能派发(供 HeroAtkSystem 等命中后触发场景调用)。 + * 直接复用 TriggerSkill 通道(forceCastTriggerSkill),无视 CD、无施法前摇。 + * @param s_uuid 被触发的技能 uuid + * @param model 施法者属性组件 + * @param view 施法者视图组件 + * @param type 触发类型(语义来源,如 SkillTriggerType.Atking) + * @param overrides 透传给被触发技能的覆写参数 + */ + public static dispatchSinglePublic(s_uuid: number, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType, overrides?: SkillOverrides) { + this.dispatchSingle(s_uuid, model, view, type, overrides); + } } diff --git a/assets/script/game/skill/SDataCom.ts b/assets/script/game/skill/SDataCom.ts index a2de7063..6c35e4a5 100644 --- a/assets/script/game/skill/SDataCom.ts +++ b/assets/script/game/skill/SDataCom.ts @@ -1,5 +1,6 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { BoxSet } from "../common/config/GameSet"; +import { SkillOverrides } from "../common/config/SkillSet"; /** 业务层对象 */ //技能数据 @@ -16,6 +17,9 @@ export class SDataCom extends ecs.Comp { dmg_ratio:number=1 //伤害比例 hit_count:number=0 //击中数量 max_hit_count:number=0 //最大可命中次数 + /** 命中后概率触发额外技能(由 Skill.load 从合并后配置快照;DamageEvent 透传给 HeroAtkSystem 判定; + * overrides 字段透传给被触发技能,用于自定义伤害/数值) */ + proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }; reset() { this.Attrs=null this.group=BoxSet.HERO @@ -27,6 +31,7 @@ export class SDataCom extends ecs.Comp { this.max_hit_count=0 this.ext_dmg=0 this.dmg_ratio=1 + this.proc_skill=undefined } } diff --git a/assets/script/game/skill/Skill.ts b/assets/script/game/skill/Skill.ts index 4366bf86..3a9a6922 100644 --- a/assets/script/game/skill/Skill.ts +++ b/assets/script/game/skill/Skill.ts @@ -242,6 +242,8 @@ export class Skill extends ecs.Entity { sDataCom.ext_dmg = ext_dmg sDataCom.hit_count = 0 sDataCom.max_hit_count = Math.max(1, sHit) + // 快照合并后(基础配置+heroSet overrides/lv_entries)的 proc_skill,命中时由 HeroAtkSystem 判定触发 + sDataCom.proc_skill = config.proc_skill; SView.init(); }; diff --git a/assets/script/game/skill/SkillView.ts b/assets/script/game/skill/SkillView.ts index ae43898d..f59c05d9 100644 --- a/assets/script/game/skill/SkillView.ts +++ b/assets/script/game/skill/SkillView.ts @@ -219,6 +219,8 @@ export class SkillView extends CCComp { this.sData.s_uuid, this.sData.ext_dmg, finalRatio, + 0, + this.sData.proc_skill, ); } close_collider() {