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.
56 lines
2.3 KiB
56 lines
2.3 KiB
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;
|
|
}
|
|
|