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.
117 lines
3.1 KiB
117 lines
3.1 KiB
|
3 weeks ago
|
import type { BattleServices } from '../combat/BattleServices';
|
||
|
|
import type { AbilityContext } from '../combat/AbilityContext';
|
||
|
|
import type { EffectSpec } from '../config/BattleConfigTypes';
|
||
|
|
|
||
|
|
/** 效果处理器签名 */
|
||
|
|
export type EffectHandler = (
|
||
|
|
services: BattleServices,
|
||
|
|
ctx: AbilityContext,
|
||
|
|
params: Record<string, unknown>,
|
||
|
|
spec: EffectSpec,
|
||
|
|
) => void;
|
||
|
|
|
||
|
|
/** 条件处理器签名 */
|
||
|
|
export type ConditionHandler = (
|
||
|
|
services: BattleServices,
|
||
|
|
ctx: AbilityContext,
|
||
|
|
params: Record<string, unknown>,
|
||
|
|
) => boolean;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 全局单表:抖音/微信等小游戏分包可能把同一模块加载成两份,
|
||
|
|
* 类静态 Map 会分裂成「注册在 A、执行读 B」→ PlayPresentation 丢失 → 表现锁死、塔不攻击。
|
||
|
|
*/
|
||
|
|
function globalHandlers<T>(key: string): Map<string, T> {
|
||
|
|
const g = globalThis as unknown as Record<string, Map<string, T> | undefined>;
|
||
|
|
let m = g[key];
|
||
|
|
if (!m) {
|
||
|
|
m = new Map();
|
||
|
|
g[key] = m;
|
||
|
|
}
|
||
|
|
return m;
|
||
|
|
}
|
||
|
|
|
||
|
|
const EFFECT_KEY = '__mx_battle_EffectRegistry__';
|
||
|
|
const CONDITION_KEY = '__mx_battle_ConditionRegistry__';
|
||
|
|
|
||
|
|
/** 技能效果注册表 */
|
||
|
|
export class EffectRegistry {
|
||
|
|
private static get _handlers(): Map<string, EffectHandler> {
|
||
|
|
return globalHandlers<EffectHandler>(EFFECT_KEY);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param type 效果类型键
|
||
|
|
* @param handler 处理函数
|
||
|
|
*/
|
||
|
|
static register(type: string, handler: EffectHandler): void {
|
||
|
|
this._handlers.set(type, handler);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param type 效果类型键
|
||
|
|
* @returns 已注册的处理函数
|
||
|
|
*/
|
||
|
|
static get(type: string): EffectHandler | undefined {
|
||
|
|
return this._handlers.get(type);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param type 效果类型键
|
||
|
|
* @returns 是否已注册
|
||
|
|
*/
|
||
|
|
static has(type: string): boolean {
|
||
|
|
return this._handlers.has(type);
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 清空所有注册(测试用) */
|
||
|
|
static clear(): void {
|
||
|
|
this._handlers.clear();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 技能条件注册表 */
|
||
|
|
export class ConditionRegistry {
|
||
|
|
private static get _handlers(): Map<string, ConditionHandler> {
|
||
|
|
return globalHandlers<ConditionHandler>(CONDITION_KEY);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param type 条件类型键
|
||
|
|
* @param handler 处理函数
|
||
|
|
*/
|
||
|
|
static register(type: string, handler: ConditionHandler): void {
|
||
|
|
this._handlers.set(type, handler);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param type 条件类型键
|
||
|
|
* @returns 已注册的处理函数
|
||
|
|
*/
|
||
|
|
static get(type: string): ConditionHandler | undefined {
|
||
|
|
return this._handlers.get(type);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param services 战斗服务聚合
|
||
|
|
* @param ctx 技能上下文
|
||
|
|
* @param type 条件类型键
|
||
|
|
* @param params 条件参数
|
||
|
|
* @returns 条件是否满足(未注册默认 true)
|
||
|
|
*/
|
||
|
|
static evaluate(
|
||
|
|
services: BattleServices,
|
||
|
|
ctx: AbilityContext,
|
||
|
|
type: string,
|
||
|
|
params: Record<string, unknown> = {},
|
||
|
|
): boolean {
|
||
|
|
const h = this._handlers.get(type);
|
||
|
|
return h ? h(services, ctx, params) : true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 清空所有注册(测试用) */
|
||
|
|
static clear(): void {
|
||
|
|
this._handlers.clear();
|
||
|
|
}
|
||
|
|
}
|