// The career retrospective. // // Structurally identical however the run went — this is a summary, not a // scoreboard, and there is no win state to congratulate anyone on. It is also // not an ending: the player can close it and carry on from the same turn. import { h } from '../dom.js'; import { statPanel, characterCard } from '../components.js'; import { formatMoney, labelFor } from '../format.js'; import { summarize } from '../summary.js'; export function retrospectiveScreen(pack, state, schema, actions) { const summary = summarize(pack, state); const unit = pack.turnUnit ?? 'turn'; return h('div', { class: 'screen screen--retrospective' }, h('header', { class: 'retro__head' }, h('p', { class: 'retro__eyebrow' }, pack.name), h('h1', { class: 'retro__title' }, 'Career retrospective'), h('p', { class: 'retro__subtitle' }, `${summary.turns} ${unit}${summary.turns === 1 ? '' : 's'} in the ` + `${(pack.stages?.[summary.stage]?.label ?? summary.stage).toLowerCase()}.`), ), h('section', { class: 'retro__section' }, h('h2', { class: 'retro__heading' }, 'Where you ended up'), statPanel(pack, state, schema), ), h('section', { class: 'retro__section' }, h('h2', { class: 'retro__heading' }, 'How it went'), h('dl', { class: 'facts' }, fact(`Highest your ${primaryLabel(pack, summary)} got`, summary.peak === null ? '—' : formatMoney(summary.peak)), fact('Lowest it got', summary.trough === null ? '—' : formatMoney(summary.trough)), summary.daysInTheRed > 0 && fact(`${capitalize(unit)}s in the red`, String(summary.daysInTheRed)), summary.bestDay && fact(`Best ${unit}`, `${formatMoney(summary.bestDay.net)} — ${summary.bestDay.label}`), summary.worstDay && fact(`Worst ${unit}`, `${formatMoney(summary.worstDay.net)} — ${summary.worstDay.label}`), summary.favouriteAction && fact('What you did most', `${summary.favouriteAction.label} (${summary.favouriteAction.count}×)`), fact('Situations you saw', `${summary.eventsSeen} of ${summary.eventsTotal}`), summary.lockedEncounters > 0 && fact('Doors you could not open yet', String(summary.lockedEncounters)), ), ), h('section', { class: 'retro__section' }, h('h2', { class: 'retro__heading' }, 'Where you stand with people'), h('div', { class: 'retro__people' }, (pack.characters ?? []).map((character) => characterCard(pack, state, schema, character)), ), ), h('section', { class: 'retro__section' }, h('h2', { class: 'retro__heading' }, 'Notable moments'), summary.notable.length ? h('ol', { class: 'moments' }, summary.notable.map((moment) => h('li', { class: 'moment' }, moment))) : h('p', { class: 'moments moments--none' }, 'Nothing that anybody would write down. That happens.'), ), h('footer', { class: 'controls' }, h('button', { class: 'button button--primary', onClick: actions.onResume }, 'Keep going'), h('button', { class: 'button button--quiet', onClick: actions.onExportSave }, 'Export save'), h('button', { class: 'button button--quiet', onClick: actions.onExportFeedback }, 'Export feedback log'), h('button', { class: 'button button--quiet', onClick: actions.onNewGame }, 'Start again'), ), ); } /** The pack's own word for its main resource, lowercased for mid-sentence use. */ function primaryLabel(pack, summary) { return summary.primaryPath ? labelFor(pack, summary.primaryPath).toLowerCase() : 'balance'; } function fact(label, value) { return h('div', { class: 'facts__item' }, h('dt', { class: 'facts__label' }, label), h('dd', { class: 'facts__value' }, value), ); } const capitalize = (text) => text.charAt(0).toUpperCase() + text.slice(1);