SOURCE / PINNED RELEASE
Made of little things.
City Breaker
- Release
- 94d2b8664b10…
- Author-recorded commit
- df23103cbcc1…
- License
- LICENSE
- Author’s source reference
- nostr://npub1sj2vketepqw9v6fmge5fdzuj7atj9sv6qv2jss05n2z6rl64lcfqumdsnt/wss%3A%2F%2Fgit.napplet.soy%2F/n-cf8b858653e
Archive hash verified: eeeed725668c1ece…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
// End of campaign: the numbers, then the honest after-action summary.
import { afterAction } from '../game/campaign';
import { fmtTime, type GameState } from '../game/state';
import { bind, esc } from './dom';
export class EndView {
constructor(private root: HTMLElement, s: GameState, onNew: () => void) {
this.root.replaceChildren();
this.root.className = 'screen end';
const e = s.ended!;
const aa = afterAction(s);
const title = e.outcome === 'win' ? 'The city is broken' : e.outcome === 'partial' ? 'The offensive goes in anyway' : 'Hafenstadt endures';
this.root.innerHTML = `<div class="end-in">
<div class="end-k">${esc(fmtTime(e.hour))} · ${e.outcome.toUpperCase()}</div>
<div class="end-t">${esc(title)}</div>
<p class="end-reason">${esc(e.reason)}</p>
<div class="end-cols">
<table class="stats">${aa.stats.map(([k, v]) => `<tr><th>${esc(k)}</th><td>${esc(v)}</td></tr>`).join('')}</table>
<div class="ussbs">
<div class="ussbs-k">Strategic bombing survey — summary report</div>
${aa.paragraphs.map((p) => `<p>${esc(p)}</p>`).join('')}
</div>
</div>
<button type="button" class="primary big" data-act="new" data-tip="Start over with a new 60-day campaign. The city will be different this time.">New campaign</button>
</div>`;
bind(this.root, { new: () => onNew() });
}
destroy(): void {
/* static */
}
}
