import type { GameContent } from '../content/index'; import type { GameState } from '../engine/game'; import { evaluateTriggers, type StoryEvent, type TriggerContext } from '../engine/story'; import type { GamePrefs } from './prefs'; import type { StoryLogEntry } from './store'; export interface StoryUiEffect { enteredNodeIds: string[]; logEntries: StoryLogEntry[]; shouldOpenPanel: boolean; eventLogLines: string[]; } export function storyEventsToLogEntries(events: StoryEvent[]): StoryLogEntry[] { return events .filter((e) => e.kind === 'enter') .map((e) => ({ nodeId: e.nodeId, prose: e.prose, choiceLabel: e.choiceLabel })); } export function shouldAutoNavigateToStory( prefs: GamePrefs, nodeId: string, content: GameContent, ): boolean { const node = content.storyNodesById[nodeId]; if (!node) return false; if (prefs.storyOpenMode === 'manual') return false; if (prefs.storyOpenMode === 'auto') return true; return (node.choices?.length ?? 0) > 0; } export function processStoryTriggers( state: GameState, content: GameContent, ctx: TriggerContext, prefs: GamePrefs, ): StoryUiEffect { const { enteredNodeIds, events } = evaluateTriggers(state, content, ctx); const logEntries = storyEventsToLogEntries(events); const shouldOpenPanel = enteredNodeIds.length > 0 && enteredNodeIds.some((id) => shouldAutoNavigateToStory(prefs, id, content)); const customLogs = events.filter((e) => e.kind === 'log').map((e) => e.prose); const eventLogLines = [ ...customLogs, ...logEntries.map((e) => e.choiceLabel ? `Story: ${e.choiceLabel}` : `Story: ${(content.storyNodesById[e.nodeId]?.prose ?? '').slice(0, 40)}…`, ), ]; return { enteredNodeIds, logEntries, shouldOpenPanel, eventLogLines }; }