import type { AbilityContext } from './AbilityContext'; import type { EffectSpec } from '../config/BattleConfigTypes'; import { ConditionRegistry, EffectRegistry } from '../registry/EffectRegistry'; import { traceCombatDamage } from 'db://assets/mx/tools/CombatDamageTrace'; /** 效果执行器(零依赖,从 ctx.services 取子系统) */ export class EffectExecutor { /** * @param ctx 技能上下文 * @param spec 效果配置 */ execute(ctx: AbilityContext, spec: EffectSpec): void { if (spec.conditions) { for (const c of spec.conditions) { if (!ConditionRegistry.evaluate(ctx.services, ctx, c.type, c.params ?? {})) { return; } } } const handler = EffectRegistry.get(spec.type); if (!handler) { const isCritical = spec.type === 'DealDamage' || spec.type === 'PlayPresentation'; const msg = `[EffectExecutor] unknown effect: ${spec.type} caster=${ctx.caster} abilityId=${ctx.abilityId}`; if (isCritical) { console.error(msg); } else { console.log(msg); } return; } handler(ctx.services, ctx, spec.params ?? {}, spec); if (spec.type === 'DealDamage') { traceCombatDamage('effectExecuted', { type: spec.type, caster: ctx.caster, abilityId: ctx.abilityId, }); } } /** * @param ctx 技能上下文 * @param specs 效果配置列表 */ executeAll(ctx: AbilityContext, specs: EffectSpec[]): void { for (const s of specs) this.execute(ctx, s); } }