explodorama / files / src / ui / tapChoice.ts
tapChoice.ts
bb3823d2 2026-10-31 Pavel Safronov | 1 | import type { ActionId } from '../sim/types' |
| 2 | import { 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 | */ | |
| 11 | const 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 | ||
| 17 | export 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 | } |