feat(skill-system): 新增计时debuff机制,支持技能命中敌方附加减益效果

本次提交完整实现了技能对敌附加debuff的完整流程:
1.  新增TimedDebuffSnapshot数据结构,用于透传debuff配置
2.  在SkillConfig和SkillOverrides中新增debuff相关配置项
3.  实现HeroAtkSystem中debuff的判定与施加逻辑
4.  完善后台配置、前端编辑器的debuff配置支持
5.  调整了buff目标判定逻辑,修复了原有默认目标的语义混淆问题
6.  优化了BuffSystem的调试日志,新增了debuff分类标识
7.  批量更新了现有英雄技能的debuff配置示例
This commit is contained in:
pan
2026-09-08 16:37:13 +08:00
parent f5908a9adf
commit be17d18ff3
16 changed files with 214 additions and 124 deletions

View File

@@ -2,6 +2,14 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
import { HeroViewComp } from "./HeroViewComp";
import { SkillOverrides } from "../common/config/SkillSet";
/** 命中后对敌 debuff 快照(由施法技能实体自合并后配置提取并透传,HeroAtkSystem 据此结算) */
export interface TimedDebuffSnapshot {
id: number;
value?: number;
duration?: number;
chance?: number;
}
/**
* ==================== 伤害事件数据 ====================
*
@@ -10,29 +18,31 @@ import { SkillOverrides } from "../common/config/SkillSet";
export interface DamageEvent {
/** 伤害属性数据 */
Attrs: any;
/** 施法者ID */
casterEid: number;
/** 技能UUID */
s_uuid: number;
/** 伤害创建时间戳(用于排序和调试) */
timestamp: number;
/** 伤害事件ID(用于去重和调试) */
eventId: string;
ext_dmg:number //额外伤害
dmg_ratio:number//伤害比例
ext_dmg: number //额外伤害
dmg_ratio: number//伤害比例
/**
* DoT 固定伤害值(>0 时本事件为 DoT tick 结算):
* 跳过 dmgCount 公式直接用该值,且不走击退/受击动画,其余(暴击/冰冻/击晕/护盾/死亡链)与普攻一致
*/
dot_dmg?:number
dot_dmg?: number
/** 命中后概率触发额外技能(由施法技能实体快照自合并后配置,HeroAtkSystem 据此判定;
* overrides 字段透传给被触发技能,用于自定义伤害/数值) */
proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }
/** 命中后对敌 debuff(由施法技能实体自合并后配置快照透传;缺省时 HeroAtkSystem 回退读 SkillSet 底座) */
timed_debuff?: TimedDebuffSnapshot
}
/**
@@ -48,16 +58,16 @@ export class DamageQueueComp extends ecs.Comp {
/** 伤害事件队列 */
damageEvents: DamageEvent[] = [];
private readIndex: number = 0;
/** 队列创建时间 */
createTime: number = 0;
/** 是否正在处理中 */
isProcessing: boolean = false;
/** 已处理的伤害数量 */
processedCount: number = 0;
reset() {
this.damageEvents.length = 0;
this.readIndex = 0;
@@ -65,33 +75,34 @@ export class DamageQueueComp extends ecs.Comp {
this.isProcessing = false;
this.processedCount = 0;
}
/**
* 添加伤害事件到队列
*/
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 {
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 }, timed_debuff?: TimedDebuffSnapshot): void {
const timestamp = Date.now();
const damageEvent: DamageEvent = {
Attrs: attrs || null,
casterEid: casterEid,
s_uuid: s_uuid,
timestamp: timestamp,
eventId: "",
ext_dmg:ext_dmg,
dmg_ratio:dmg_ratio,
dot_dmg:dot_dmg,
proc_skill:proc_skill,
ext_dmg: ext_dmg,
dmg_ratio: dmg_ratio,
dot_dmg: dot_dmg,
proc_skill: proc_skill,
timed_debuff: timed_debuff,
};
this.damageEvents.push(damageEvent);
// 如果是第一个伤害事件,记录创建时间
if (this.getRemainingCount() === 1) {
this.createTime = timestamp;
}
}
/**
* 获取下一个待处理的伤害事件
*/
@@ -105,21 +116,21 @@ export class DamageQueueComp extends ecs.Comp {
}
return event || null;
}
/**
* 获取队列中剩余的伤害事件数量
*/
getRemainingCount(): number {
return this.damageEvents.length - this.readIndex;
}
/**
* 检查队列是否为空
*/
isEmpty(): boolean {
return this.readIndex >= this.damageEvents.length;
}
/**
* 清空队列
*/
@@ -129,7 +140,7 @@ export class DamageQueueComp extends ecs.Comp {
this.processedCount = 0;
this.isProcessing = false;
}
/**
* 按时间戳排序伤害事件(可选功能)
*/
@@ -140,7 +151,7 @@ export class DamageQueueComp extends ecs.Comp {
}
this.damageEvents.sort((a, b) => a.timestamp - b.timestamp);
}
/**
* 去除重复的伤害事件(基于eventId)
*/
@@ -158,7 +169,7 @@ export class DamageQueueComp extends ecs.Comp {
return true;
});
}
/**
* 获取队列统计信息(用于调试)
*/
@@ -187,18 +198,18 @@ 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,proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }): 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 }, timed_debuff?: TimedDebuffSnapshot): void {
let damageQueue = entity.get(DamageQueueComp);
// 如果实体没有伤害队列组件,创建一个
if (!damageQueue) {
damageQueue = entity.add(DamageQueueComp);
}
// 添加伤害事件到队列
damageQueue.addDamageEvent(attrs, casterEid, s_uuid,ext_dmg,dmg_ratio,dot_dmg,proc_skill);
damageQueue.addDamageEvent(attrs, casterEid, s_uuid, ext_dmg, dmg_ratio, dot_dmg, proc_skill, timed_debuff);
}
/**
* 检查实体是否有待处理的伤害
*/
@@ -206,7 +217,7 @@ export class DamageQueueHelper {
const damageQueue = entity.get(DamageQueueComp);
return damageQueue ? !damageQueue.isEmpty() : false;
}
/**
* 获取实体的伤害队列统计信息
*/