feat(state): story trigger orchestration and auto-open rules
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
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 };
|
||||
}
|
||||
Reference in New Issue
Block a user