Files
Genarrative/src/services/storyEngine/endingResolver.ts
高物 ddcb5d5c8c
Some checks failed
CI / verify (push) Has been cancelled
Rework story engine flow and reorganize project docs
2026-04-06 23:19:00 +08:00

82 lines
2.7 KiB
TypeScript

import type {
CompanionResolution,
EndingState,
FactionTensionState,
GameState,
} from '../../types';
function resolveEndingType(params: {
activeThreadCount: number;
fracturedCompanions: number;
hottestFactionTemperature: number;
}) {
if (params.hottestFactionTemperature >= 78 && params.fracturedCompanions >= 2) {
return 'tragic' as const;
}
if (params.activeThreadCount >= 3 && params.hottestFactionTemperature >= 70) {
return 'bitter_sweet' as const;
}
if (params.fracturedCompanions >= 1) {
return 'fractured' as const;
}
if (params.activeThreadCount >= 3) {
return 'ascendant' as const;
}
return 'heroic' as const;
}
export function resolveEndingState(params: {
state: GameState;
companionResolutions: CompanionResolution[];
factionTensionStates: FactionTensionState[];
}) {
const activeThreadIds = params.state.storyEngineMemory?.activeThreadIds ?? [];
const fracturedCompanions = params.companionResolutions.filter((resolution) =>
resolution.resolutionType === 'estranged' || resolution.resolutionType === 'departed',
).length;
const hottestFactionTemperature =
params.factionTensionStates.reduce(
(max, item) => Math.max(max, item.temperature),
0,
);
const endingType = resolveEndingType({
activeThreadCount: activeThreadIds.length,
fracturedCompanions,
hottestFactionTemperature,
});
return {
id: `ending:${endingType}:${activeThreadIds.slice(0, 2).join('+') || 'main'}`,
title:
endingType === 'heroic'
? '守住火种'
: endingType === 'tragic'
? '余烬之末'
: endingType === 'bitter_sweet'
? '代价之后'
: endingType === 'fractured'
? '裂开的同路'
: '新秩序的门槛',
endingType,
summary:
endingType === 'heroic'
? '你勉强把局势拖回了可继续前行的方向。'
: endingType === 'tragic'
? '真相被揭开,但代价也一并吞没了许多人。'
: endingType === 'bitter_sweet'
? '你走到了终点,但一路上失去的东西无法被轻易抹平。'
: endingType === 'fractured'
? '你推进了主线,却没能把所有同行者一起带到终点。'
: '你不只是解开旧线,也推开了一个更大的新局面。',
contributingThreadIds: activeThreadIds,
companionResolutions: params.companionResolutions,
worldOutcomeSummary:
params.factionTensionStates.length > 0
? params.factionTensionStates
.slice(0, 2)
.map((item) => item.pressureSummary)
.join(' ')
: '世界在你的选择之后开始改口。',
} satisfies EndingState;
}