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 shouldAutoOpenPanel( 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) => shouldAutoOpenPanel(prefs, id, content)); const eventLogLines = logEntries.map((e) => e.choiceLabel ? `Story: ${e.choiceLabel}` : `Story: ${content.storyNodesById[e.nodeId]?.prose.slice(0, 40)}…`, ); return { enteredNodeIds, logEntries, shouldOpenPanel, eventLogLines }; }