import type { EntityId } from 'db://assets/mx/module/ecs'; import { createAbilityContext } from 'db://assets/mx/module/battle/combat/AbilityContext'; import { SkillPresentationEnv } from '../skill/SkillPresentationEnv'; import type { SkillPresentationContext } from '../skill/SkillPresentationTypes'; /** 影子伤害参数 */ export interface ShadowDealParams { /** 伤害系数(倍数) */ scale?: number; /** 直伤类型 */ damageType?: string; /** 命中效果串(同 atk_buff1 语法);不传用构建时的默认 */ skillAtkBuff1?: string; /** 命中效果串 2;不传用构建时的默认 */ skillAtkBuff2?: string; } /** * 影子上下文:普攻 cast 间隔短于表现时长时会被下一次施法 cancel('superseded'), * 与 cast 生命周期解耦的延迟效果(环形龙影/追加伤害等)用—— * isAlive 只看施法者存活;伤害走独立通道 * (与 SkillPresentationBridge.dealDamage 相同:before→calc→after、atk_buff 命中效果、可暴击)。 * @param ctx 表现上下文 * @param buff1 默认命中效果串(不传时 dealDamage 的兜底) * @param buff2 默认命中效果串 2 */ export function buildShadowDealContext( ctx: SkillPresentationContext, buff1: string, buff2: string, ): SkillPresentationContext { const session = SkillPresentationEnv.getBattleSession(); const caster = ctx.caster; const abilityId = ctx.abilityId; const level = ctx.level; const dealDamage = (target: EntityId, p?: ShadowDealParams): boolean => { if (!session || !session.world.isAlive(caster) || !session.world.isAlive(target)) return false; const abilityCtx = createAbilityContext(session, caster, abilityId, [target]); abilityCtx.level = level; abilityCtx.targets = [target]; const amount = session.damage.dealToTarget(caster, target, { scale: p?.scale ?? 1, damageType: p?.damageType, skillAtkBuff1: p?.skillAtkBuff1 ?? buff1, skillAtkBuff2: p?.skillAtkBuff2 ?? buff2, }, abilityCtx); return amount > 0; }; return { ...ctx, get isAlive() { return !!session && session.world.isAlive(caster); }, dealDamage, finish: (): void => {}, cancel: (): void => {}, } as SkillPresentationContext; }