'use client'; import { useState } from 'react'; import { FACTIONS } from '@/game/catalog'; import { DIFFICULTIES, type Difficulty } from '@/game/bot-profiles'; import type { GameView } from '@/game/engine'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; export function TwoPlayerControls({ game, disabled, draftLocked = false, pendingEntry, entryRoom, entryProblem, retryDisabled, onModeChange, onSwitch, onAdd, onRetry, onAddBot, onAddControlledBot, }: { game: GameView; disabled: boolean; draftLocked?: boolean; pendingEntry: boolean; entryRoom?: string; entryProblem: string; retryDisabled: boolean; onModeChange: (enabled: boolean) => void; onSwitch: (seat: string) => void; onAdd: (name: string, faction: string) => void; onRetry: () => void; onAddBot: (faction: string, difficulty: Difficulty) => void; onAddControlledBot: (controllerId: string, faction: string, difficulty: Difficulty) => void; }) { const [name, setName] = useState(() => game.players.find((player) => player.id === game.me)?.name ?? ''); const [choice, setChoice] = useState(''); const [botChoice, setBotChoice] = useState(''); const [botDifficulty, setBotDifficulty] = useState('Medium'); const mode = game.twoPlayerControllers; const lobbyLocked = disabled || draftLocked; const controlled = game.controlledFactionSeats ?? []; const modeLocked = !!mode?.controllers.some((controller) => controller.seats.length > 1); const botController = mode?.controllers.find((controller) => controller.seats.length === 1 && game.players.some((player) => player.id === controller.id && !!player.bot)); const canAddBotController = !!mode && mode.controllers.length < 2; const showBotForm = game.status === 'lobby' && game.host === game.me && !!mode && (canAddBotController || !!botController); const available = FACTIONS.filter((item) => (item.expansion === 'base' || game.expansions.includes(item.expansion)) && !game.players.some((player) => player.faction === item.id), ); if (game.status !== 'lobby' && !mode && !pendingEntry && !entryProblem) return null; return (
{game.status === 'lobby' && game.host === game.me && ( )} {game.status === 'lobby' && game.host === game.me && modeLocked &&

This mode cannot be turned off while a player controls two factions.

} {mode && <>

Two-player factions

Each player controls two separate factions. They act independently and are not automatically allied; this interpretation is provisional. Switch between your faction seats to make their decisions and mark each one ready.

{game.status === 'lobby' && } {controlled.length > 1 && } {game.status === 'lobby' && controlled.length === 1 &&
{ event.preventDefault(); if (!lobbyLocked && choice && name.trim() && available.some((item) => item.id === choice)) onAdd(name.trim(), choice); }}>

Add your second faction

setName(event.target.value)} />
} {showBotForm &&
{ event.preventDefault(); if (lobbyLocked || !available.some((item) => item.id === botChoice)) return; if (botController) onAddControlledBot(botController.id, botChoice, botDifficulty); else if (canAddBotController) onAddBot(botChoice, botDifficulty); }}>

{botController ? 'Add the AI player’s second faction' : 'Add an AI player'}

The AI plays each faction independently. Choose a difficulty for this faction; its settings can be changed in the lobby.

} } {pendingEntry &&
A second-faction request for room {entryRoom} is saved in this tab. Retry the same request to confirm its result; it is never retried automatically. {entryRoom !== game.code &&

Open that room to retry this request.

}
} {entryProblem &&

{entryProblem}

}
); }