feat(skill): add proc skill trigger system

实现技能命中后概率触发额外技能的完整流程

1.  新增proc_skill技能配置字段与数据组件
2.  新增公共技能派发工具方法
3.  在HeroAtkSystem中添加触发逻辑
4.  完善伤害事件与技能视图传递proc_skill参数
This commit is contained in:
panFD
2026-09-05 13:26:34 +08:00
parent 30748536d0
commit 63423c5378
7 changed files with 61 additions and 3 deletions

View File

@@ -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);
}
/**

View File

@@ -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) {

View File

@@ -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);
}
}