Veto: Seitenwahl per Messerrunde, freie Messer-Server in der Lobby, Organisator legt fest, wer beginnt
This commit is contained in:
1 parent
7b6ce01d05
commit
cdf41df01c
9 files changed
+138
-8
No files matched your search
@@ -170,7 +170,21 @@ function Stage(ctx) {
|
||||
{missing.map((t) => <li key={t.key}><strong className={`team-${t.key.toLowerCase()}`}>{t.name}:</strong> {readinessGap(t, state.requireFullTeams)}</li>)}
|
||||
</ul>
|
||||
)}
|
||||
{isOrg ? (
|
||||
{state.vetoStart === 'knife' && <KnifeRound state={state} />}
|
||||
{isOrg && state.vetoStart === 'knife' ? (
|
||||
<div className="knife-decide">
|
||||
<p>Wer hat die Messerrunde gewonnen? Dieses Team beginnt das Veto.</p>
|
||||
<div className="row">
|
||||
{['A', 'B'].map((t) => (
|
||||
<button key={t} className={`btn btn-lg knife-team-${t.toLowerCase()}`} disabled={!state.canStartVeto || !!busy}
|
||||
onClick={() => act('veto/start', { firstTeam: t }, `Veto gestartet – ${state.teams[t].name} beginnt`)}>
|
||||
{state.teams[t].name} beginnt
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
{!state.canStartVeto && <p className="small muted">Die Knöpfe werden aktiv, sobald beide Teams bereit sind.</p>}
|
||||
</div>
|
||||
) : isOrg ? (
|
||||
<>
|
||||
<button className="btn btn-primary btn-lg" disabled={!state.canStartVeto || !!busy}
|
||||
onClick={() => act('veto/start', null, 'Veto gestartet')}>
|
||||
@@ -178,6 +192,8 @@ function Stage(ctx) {
|
||||
</button>
|
||||
{!state.canStartVeto && <p className="small muted">Der Knopf wird aktiv, sobald beide Teams bereit sind.</p>}
|
||||
</>
|
||||
) : state.vetoStart === 'knife' ? (
|
||||
<p className="small muted">Nach der Messerrunde legt der Organisator fest, welches Team das Veto beginnt.</p>
|
||||
) : (
|
||||
<p className="small muted">
|
||||
{missing.length === 0
|
||||
@@ -200,6 +216,56 @@ function Stage(ctx) {
|
||||
}
|
||||
|
||||
/** Sagt konkret, was einem Team noch fehlt, damit es als bereit gilt. */
|
||||
/**
|
||||
* Seitenwahl per Messerrunde: freie Messer-Server vorschlagen, passende Teamgröße zuerst.
|
||||
* Frei = niemand drauf (oder Spielerzahl unbekannt).
|
||||
*/
|
||||
function KnifeRound({ state }) {
|
||||
const [servers, setServers] = useState(null);
|
||||
useEffect(() => {
|
||||
let alive = true;
|
||||
const load = () => api('/knife-servers').then((res) => alive && setServers(res.servers)).catch(() => alive && setServers([]));
|
||||
load();
|
||||
const t = setInterval(load, 10_000);
|
||||
return () => {
|
||||
alive = false;
|
||||
clearInterval(t);
|
||||
};
|
||||
}, []);
|
||||
const free = (servers ?? []).filter((k) => !k.playerCount);
|
||||
const matching = free.filter((k) => k.mode === state.mode);
|
||||
const shown = matching.length ? matching : free;
|
||||
return (
|
||||
<div className="knife-round">
|
||||
<h3>Seitenwahl per Messerrunde</h3>
|
||||
<p className="small">
|
||||
Beide Teams gehen zusammen auf einen freien Messer-Server und spielen eine Runde nur mit Messer. Danach legt der Organisator fest,
|
||||
welches Team das Veto beginnt.
|
||||
</p>
|
||||
{servers === null ? (
|
||||
<p className="small muted">Suche freie Messer-Server …</p>
|
||||
) : shown.length === 0 ? (
|
||||
<p className="small tone-pending">Gerade ist kein Messer-Server frei. Fragt die Turnierleitung, oder wartet, bis einer frei wird.</p>
|
||||
) : (
|
||||
<>
|
||||
{!matching.length && <p className="small muted">Kein freier Server mit eurer Teamgröße, hier die anderen freien:</p>}
|
||||
<ul className="knife-list">
|
||||
{shown.map((k) => (
|
||||
<li key={k.id}>
|
||||
<strong>{k.name}</strong>
|
||||
{k.modeShort && <span className="knife-mode">{k.modeShort}</span>}
|
||||
<span className="muted small">{k.mapName}</span>
|
||||
<code>{k.connect}</code>
|
||||
<a className="btn btn-sm btn-primary" href={k.steamUrl}>Verbinden</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function readinessGap(team, requireFull) {
|
||||
const r = team.readiness;
|
||||
const gaps = [];
|
||||
|
||||
Reference in new issue
Block a user