You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
49 lines
1.7 KiB
49 lines
1.7 KiB
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);
|
|
}
|
|
}
|
|
|