fuzzyworld

explodorama / files / src / ui / tapChoice.ts

tapChoice.ts

Blame: the commit that last changed each line · file · history

bb3823d2 2026-10-31 Pavel Safronov1import type { ActionId } from '../sim/types'
2import { openDialog } from './dialog'
3
4/**
5 * A tap or key that two of the player's actions could answer (picks.ts `tapChoices`; user
6 * request, 2026-10-31: a bomb next to a player with Kick and Bomb Pass): asks which, and takes
7 * no turn until one is chosen. Dismissed, it does nothing. An option that would cost a life is
8 * marked and red (it is offered only after a button was picked, as a picked button's tile is
9 * never refused; a plain tap leaves such an option out, and takes the other one at once).
10 */
11const LABELS: Partial<Record<ActionId, { label: string; text: string }>> = {
12 kick: { label: 'Kick it', text: 'The bomb slides away from you, and you stay where you are.' },
13 move: { label: 'Walk onto it', text: 'You step onto the bomb’s tile (Bomb Pass).' },
14 detonate: { label: 'Set it off', text: 'The bomb explodes this turn (Detonator).' },
15}
16
17export function openTapChoice(ids: readonly ActionId[], choose: (id: ActionId) => void, deadly: (id: ActionId) => boolean = () => false): void {
18 openDialog({
19 title: 'Which one?',
20 body: ids.map((id) => `<p><strong>${LABELS[id]?.label ?? id}.</strong> ${LABELS[id]?.text ?? ''}${deadly(id) ? ' <b>It costs you a life this turn.</b>' : ''}</p>`).join(''),
21 buttons: [
22 ...ids.map((id) => ({ label: LABELS[id]?.label ?? id, kind: deadly(id) ? ('danger' as const) : ('primary' as const), onClick: () => choose(id) })),
23 { label: 'Cancel', kind: 'plain' as const },
24 ],
25 })
26}