explodorama / files / src / ui / tapChoice.ts
tapChoice.ts
| 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 | } |