diff --git a/src/core/game-host.ts b/src/core/game-host.ts index da2de92..8d1c99f 100644 --- a/src/core/game-host.ts +++ b/src/core/game-host.ts @@ -3,7 +3,6 @@ import { CommandSchema, CommandRegistry, PromptEvent, - parseCommandSchema, } from '@/utils/command'; import {createGameCommandRegistry, createGameContext, IGameContext, PromptDef} from './game'; @@ -14,12 +13,14 @@ export class GameHost, TResult=unknown> { readonly status: ReadonlySignal; readonly activePromptSchema: ReadonlySignal; readonly activePromptPlayer: ReadonlySignal; + readonly activePromptHint: ReadonlySignal; private _context: IGameContext; private _start: (ctx: IGameContext) => Promise; private _status: Signal; private _activePromptSchema: Signal; private _activePromptPlayer: Signal; + private _activePromptHint: Signal; private _createInitialState: () => TState; private _eventListeners: Map<'start' | 'dispose', Set<() => void>>; private _isDisposed = false; @@ -45,6 +46,9 @@ export class GameHost, TResult=unknown> { this._activePromptPlayer = new Signal(null); this.activePromptPlayer = this._activePromptPlayer; + + this._activePromptHint = new Signal(null); + this.activePromptHint = this._activePromptHint; this._setupPromptTracking(); } @@ -56,17 +60,20 @@ export class GameHost, TResult=unknown> { currentPromptEvent = e as PromptEvent; this._activePromptSchema.value = currentPromptEvent.schema; this._activePromptPlayer.value = currentPromptEvent.currentPlayer; + this._activePromptHint.value = currentPromptEvent.hintText || null; }); this._context._commands.on('promptEnd', () => { currentPromptEvent = null; this._activePromptSchema.value = null; this._activePromptPlayer.value = null; + this._activePromptHint.value = null; }); // Initial state this._activePromptSchema.value = null; this._activePromptPlayer.value = null; + this._activePromptHint.value = null; } tryInput(input: string): string | null { @@ -77,7 +84,6 @@ export class GameHost, TResult=unknown> { } tryAnswerPrompt(def: PromptDef, ...args: TArgs){ - if(typeof def.schema === 'string') def.schema = parseCommandSchema(def.schema); return this._context._commands._tryCommit({ name: def.schema.name, params: args, diff --git a/src/core/game.ts b/src/core/game.ts index 1076653..009421b 100644 --- a/src/core/game.ts +++ b/src/core/game.ts @@ -5,7 +5,7 @@ import { CommandRunnerContextExport, CommandSchema, createCommandRegistry, - createCommandRunnerContext, + createCommandRunnerContext, parseCommandSchema, } from "@/utils/command"; import {PromptValidator} from "@/utils/command/command-runner"; @@ -47,7 +47,7 @@ export function createGameContext = {} >( return commands.runParsed(command); }, prompt(def, validator, currentPlayer) { - return commands.prompt(def.schema, validator, currentPlayer); + return commands.prompt(def.schema, validator, def.hintText, currentPlayer); }, _state: state, @@ -60,10 +60,12 @@ export function createGameContext = {} >( } export type PromptDef = { - schema: CommandSchema | string, + schema: CommandSchema, + hintText?: string, } -export function createPromptDef(schema: CommandSchema | string): PromptDef { - return { schema }; +export function createPromptDef(schema: CommandSchema | string, hintText?: string): PromptDef { + schema = typeof schema === 'string' ? parseCommandSchema(schema) : schema; + return { schema, hintText }; } export function createGameCommandRegistry = {} >() { diff --git a/src/utils/command/command-registry.ts b/src/utils/command/command-registry.ts index 50ff49c..23290c7 100644 --- a/src/utils/command/command-registry.ts +++ b/src/utils/command/command-registry.ts @@ -146,8 +146,9 @@ export function createCommandRunnerContext( }; const prompt = ( - schema: CommandSchema | string, + schema: CommandSchema, validator: PromptValidator, + hintText?: string, currentPlayer?: string | null ): Promise => { const resolvedSchema = typeof schema === 'string' ? parseCommandSchema(schema) : schema; @@ -174,7 +175,7 @@ export function createCommandRunnerContext( emitPromptEnd(); reject(new Error(reason ?? 'Cancelled')); }; - activePrompt = { schema: resolvedSchema, currentPlayer: currentPlayer ?? null, tryCommit, cancel }; + activePrompt = { schema: resolvedSchema, hintText, currentPlayer: currentPlayer ?? null, tryCommit, cancel }; const event: PromptEvent = { schema: resolvedSchema, currentPlayer: currentPlayer ?? null, tryCommit, cancel }; for (const listener of promptListeners) { listener(event); diff --git a/src/utils/command/command-runner.ts b/src/utils/command/command-runner.ts index 809e9bb..a5ba237 100644 --- a/src/utils/command/command-runner.ts +++ b/src/utils/command/command-runner.ts @@ -2,6 +2,8 @@ import type { Command, CommandSchema } from './types'; export type PromptEvent = { schema: CommandSchema; + /** 提示文本 */ + hintText?: string; /** 当前等待输入的玩家 */ currentPlayer: string | null; /** @@ -35,7 +37,7 @@ export type CommandRunnerContext = { context: TContext; run: (input: string) => Promise>; runParsed: (command: Command) => Promise>; - prompt: (schema: CommandSchema | string, validator: PromptValidator, currentPlayer?: string | null) => Promise; + prompt: (schema: CommandSchema, validator: PromptValidator, hintText?: string, currentPlayer?: string | null) => Promise; on: (event: T, listener: (e: CommandRunnerEvents[T]) => void) => void; off: (event: T, listener: (e: CommandRunnerEvents[T]) => void) => void; };