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; }