Add optional short alliance victory
Verify and publish checkpoint container / container (push) Successful in 11m2s
Verify and publish checkpoint container / container (push) Successful in 11m2s
This commit is contained in:
1 parent
8fb9f59106
commit
e896570f07
25 files changed
+632
-27
No files matched your search
@@ -77,19 +77,21 @@ export function AdminLobbyControls({ accountId, code, canManage, onClose, onUpda
|
||||
}
|
||||
function selectKind(next: AdminLobbyAction['type']) {
|
||||
setKind(next); setConfirmed(false); setTarget('');
|
||||
setEnabled(next === 'rules' ? lobby?.advanced ?? false : next === 'techTokens' ? lobby?.techTokens ?? false : lobby?.strongholdCards ?? false);
|
||||
setEnabled(next === 'rules' ? lobby?.advanced ?? false : next === 'techTokens' ? lobby?.techTokens ?? false :
|
||||
next === 'shortAllianceVictory' ? lobby?.shortAllianceVictory ?? false : lobby?.strongholdCards ?? false);
|
||||
if (next === 'addBot') setFaction(baseFactions.find(item => !lobby?.players.some(player => player.faction === item.id))?.id ?? 'atreides');
|
||||
if (next === 'removeBot' || next === 'configureBot') selectTarget(lobby?.players.find(player => player.bot)?.id ?? '');
|
||||
if (next === 'assignHost') setTarget(lobby?.players.find(player => player.hostEligible && player.id !== lobby.host)?.id ?? '');
|
||||
}
|
||||
const action: AdminLobbyAction = kind === 'rules' ? { type: kind, advanced: enabled } :
|
||||
kind === 'techTokens' || kind === 'strongholdCards' ? { type: kind, enabled } :
|
||||
kind === 'techTokens' || kind === 'strongholdCards' || kind === 'shortAllianceVictory' ? { type: kind, enabled } :
|
||||
kind === 'addBot' ? { type: kind, faction, difficulty } :
|
||||
kind === 'configureBot' ? { type: kind, target, faction, difficulty, position } : { type: kind, target };
|
||||
const selectedPlayer = lobby?.players.find(player => player.id === target);
|
||||
const availableFactions = baseFactions.filter(item => !lobby?.players.some(player => player.faction === item.id && (kind !== 'configureBot' || player.id !== target)));
|
||||
const actionable = lobby?.editable && (kind === 'rules' ? enabled !== lobby.advanced :
|
||||
kind === 'techTokens' ? enabled !== lobby.techTokens : kind === 'strongholdCards' ? enabled !== lobby.strongholdCards && (!enabled || lobby.advanced) :
|
||||
kind === 'shortAllianceVictory' ? enabled !== lobby.shortAllianceVictory :
|
||||
kind === 'addBot' ? lobby.players.length < 6 && availableFactions.some(item => item.id === faction) :
|
||||
kind === 'assignHost' ? selectedPlayer?.hostEligible && target !== lobby.host :
|
||||
kind === 'removeBot' ? !!selectedPlayer?.bot : !!selectedPlayer?.bot && availableFactions.some(item => item.id === faction) &&
|
||||
@@ -142,7 +144,7 @@ export function AdminLobbyControls({ accountId, code, canManage, onClose, onUpda
|
||||
<div className="admin-section-heading"><h2 id="admin-lobby-title" ref={title} tabIndex={-1}>Lobby configuration · {code}</h2><Button variant="outline" disabled={busy} onClick={onClose}>Close lobby configuration</Button></div>
|
||||
{notice && <output className="admin-notice">{notice}</output>}
|
||||
{loading ? <output>Loading lobby configuration…</output> : !lobby ? <Button disabled={busy} onClick={() => void refresh()}>Retry loading lobby</Button> : <>
|
||||
<p>Current rules: <strong>{lobby.advanced ? 'Advanced preview' : 'Basic'}</strong> · Tech Tokens {lobby.techTokens ? 'on' : 'off'} · Stronghold Cards {lobby.strongholdCards ? 'on' : 'off'}.</p>
|
||||
<p>Current rules: <strong>{lobby.advanced ? 'Advanced preview' : 'Basic'}</strong> · Tech Tokens {lobby.techTokens ? 'on' : 'off'} · Stronghold Cards {lobby.strongholdCards ? 'on' : 'off'} · Three-stronghold alliance victory {lobby.shortAllianceVictory ? 'on' : 'off'}.</p>
|
||||
<p>Advanced preview is unfinished. Players must review the warning and the host must explicitly start the preview.</p>
|
||||
<ul className="admin-lobby-roster">{lobby.players.map(player => <li key={player.id}>
|
||||
<strong>{player.name}</strong>{player.id === lobby.host ? ' · Host' : ''} · {FACTIONS.find(item => item.id === player.faction)?.name ?? player.faction} · {player.bot ? `AI: ${player.bot}` : 'Human'} · Circle {player.position} · {player.ready ? 'Ready' : 'Not ready'}
|
||||
@@ -159,14 +161,15 @@ export function AdminLobbyControls({ accountId, code, canManage, onClose, onUpda
|
||||
<Button disabled={busy} onClick={() => void submit(pending)}>Retry saved lobby request</Button>
|
||||
</div> : lobby.editable && <form onSubmit={event => { event.preventDefault(); void submit(); }}>
|
||||
<label>Change<select value={kind} disabled={busy} onChange={e => selectKind(e.target.value as AdminLobbyAction['type'])}>
|
||||
<option value="rules">Rules mode</option><option value="techTokens">Tech Tokens</option><option value="strongholdCards">Stronghold Cards</option>
|
||||
<option value="rules">Rules mode</option><option value="techTokens">Tech Tokens</option><option value="strongholdCards">Stronghold Cards</option><option value="shortAllianceVictory">Three-stronghold alliance victory</option>
|
||||
<option value="addBot">Add AI player</option><option value="configureBot">Configure AI player</option><option value="removeBot">Remove AI player</option><option value="assignHost">Assign host</option>
|
||||
</select></label>
|
||||
{(kind === 'rules' || kind === 'techTokens' || kind === 'strongholdCards') && <label>{kind === 'rules' ? 'Rules mode' : kind === 'techTokens' ? 'Tech Tokens' : 'Stronghold Cards'}<select value={String(enabled)} disabled={busy} onChange={e => { setEnabled(e.target.value === 'true'); setConfirmed(false); }}>
|
||||
{(kind === 'rules' || kind === 'techTokens' || kind === 'strongholdCards' || kind === 'shortAllianceVictory') && <label>{kind === 'rules' ? 'Rules mode' : kind === 'techTokens' ? 'Tech Tokens' : kind === 'strongholdCards' ? 'Stronghold Cards' : 'Three-stronghold alliance victory'}<select value={String(enabled)} disabled={busy} onChange={e => { setEnabled(e.target.value === 'true'); setConfirmed(false); }}>
|
||||
<option value="false">{kind === 'rules' ? 'Basic' : 'Off'}</option><option value="true" disabled={kind === 'strongholdCards' && !lobby.advanced}>{kind === 'rules' ? 'Advanced preview' : 'On'}</option>
|
||||
</select></label>}
|
||||
{kind === 'rules' && !enabled && lobby.strongholdCards && <p>Switching to Basic also turns off Stronghold Cards.</p>}
|
||||
{kind === 'techTokens' && <p>Tech Tokens require at least three players before the game can start.</p>}
|
||||
{kind === 'shortAllianceVictory' && <p>Two-member alliances need three strongholds with at least three controllers; two-controller games retain four.</p>}
|
||||
{(kind === 'configureBot' || kind === 'removeBot' || kind === 'assignHost') && <label>{kind === 'assignHost' ? 'New host' : 'AI player'}<select value={target} disabled={busy} onChange={e => selectTarget(e.target.value)}>
|
||||
<option value="">Choose a player</option>{lobby.players.filter(player => kind === 'assignHost' ? player.hostEligible && player.id !== lobby.host : player.bot).map(player => <option key={player.id} value={player.id}>{player.name}</option>)}
|
||||
</select></label>}
|
||||
|
||||
@@ -2104,6 +2104,9 @@ export function GameTable({
|
||||
{g.status === 'playing' && <MixedBidPromises game={g} send={act} busy={busy} />}
|
||||
{g.status === 'playing' && <MixedBattlePromises game={g} />}
|
||||
{g.status === 'playing' && <FutureBattleLeaderPromises game={g} />}
|
||||
{g.status === 'playing' && g.shortAllianceVictory && <p className="notice">
|
||||
Optional alliance rule: a two-member alliance wins with three strongholds when at least three people or AI controllers are playing. Two-controller games retain their four-stronghold target.
|
||||
</p>}
|
||||
{g.status === 'playing' && <MixedTraitorPromises game={g} />}
|
||||
{g.status === 'playing' && <TravelPromises game={g} busy={busy} act={act} />}
|
||||
{g.status === 'playing' && <TurnActionPromises game={g} busy={g.semutaReaction &&
|
||||
@@ -2244,6 +2247,11 @@ export function GameTable({
|
||||
g.players.some(player => player.faction === 'choam') && <p className="notice">
|
||||
Printed Kull is inactive in this lobby. Its preview requires a supported {g.advanced ? 'Advanced' : 'Basic'} configuration and may need different module selections.
|
||||
</p>}
|
||||
<label className="checkbox-row">
|
||||
<input type="checkbox" checked={g.shortAllianceVictory} disabled={busy || g.host !== me.id}
|
||||
onChange={(e) => act({type: 'shortAllianceVictory', enabled: e.target.checked})} />
|
||||
Optional: two-member alliances win with three strongholds (three or more controllers)
|
||||
</label>
|
||||
<label className="checkbox-row">
|
||||
<input
|
||||
type="checkbox"
|
||||
|
||||
Reference in new issue
Block a user