import type { General, GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js'; import type { RandomGenerator } from '@sammo-ts/common'; import type { WorldStateRepository } from '@sammo-ts/logic/ports/world.js'; import { TriggerCaller, type Trigger } from './core.js'; export interface GeneralWorldView { listGenerals(): General[]; listGeneralsByCity?(cityId: number): General[]; } export interface GeneralActionLogSink { push(message: string): void; } export interface GeneralSkillActivation { has(key: string): boolean; activate(...keys: string[]): void; } export const createGeneralSkillActivation = ( general: General ): GeneralSkillActivation => ({ has: (key: string) => Boolean(general.triggerState.flags[key]), activate: (...keys: string[]) => { for (const key of keys) { general.triggerState.flags[key] = true; } }, }); export interface GeneralActionContext { general: General; world?: WorldStateRepository; worldView?: GeneralWorldView; log?: GeneralActionLogSink; rng?: RandomGenerator; } export interface GeneralTriggerContext< TriggerState extends GeneralTriggerState = GeneralTriggerState, > extends GeneralActionContext { rng: RandomGenerator; skill: GeneralSkillActivation; } export const createGeneralTriggerContext = ( context: GeneralActionContext & { rng: RandomGenerator } ): GeneralTriggerContext => ({ ...context, skill: createGeneralSkillActivation(context.general), }); export type GeneralTrigger< TriggerState extends GeneralTriggerState = GeneralTriggerState, Env extends Record = Record, Arg = unknown, > = Trigger, Env, Arg>; export class GeneralTriggerCaller< TriggerState extends GeneralTriggerState = GeneralTriggerState, Env extends Record = Record, Arg = unknown, > extends TriggerCaller, Env, Arg> {} export abstract class BaseGeneralTrigger< TriggerState extends GeneralTriggerState = GeneralTriggerState, Env extends Record = Record, Arg = unknown, > implements GeneralTrigger { public abstract readonly priority: number; protected constructor(protected readonly general: General) {} get uniqueId(): string { return `${this.priority}_${this.constructor.name}_${this.general.id}`; } abstract action(context: GeneralTriggerContext, env: Env, arg?: Arg): Env; }