The climb: the arcade runs the whole earned ladder, the tempo follows the territory, the court is yours
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
041827c4dc
commit
689550d2d5
7 files changed
+104
-52
No files matched your search
+40
-26
@@ -303,9 +303,24 @@ swatches('kitRow', 'kitName', KITS, 'kit', () => pickedKit, id => pickedKit = id
|
||||
swatches('skinRow', 'skinName', SKINS, 'skin', () => pickedSkin, id => pickedSkin = id);
|
||||
refreshLook();
|
||||
|
||||
// THE LEAGUE PANEL (the leagues): the setup's league-mode face — your league writ large and the
|
||||
// band's roster with your all-time felled counts (stats' per-foe tallies, key 'L'+index). The
|
||||
// identity block this replaces still shows for every non-league mode; the card owns it anyway.
|
||||
// THE CLIMB PANEL: the arcade's setup face — the marathon's length (grown by every promotion)
|
||||
// and your best run. Reuses the league panel's furniture; the foes row stays empty (up to 18
|
||||
// tiles is a wall, and the training picker already shows the roster face-up).
|
||||
function buildClimbPanel() {
|
||||
const lg = leagueOf(profile.prof.lg);
|
||||
document.getElementById('lgBadge').src = `assets/badge_l${lg.id}.png?v=${SPRV}`;
|
||||
const name = document.getElementById('lgName');
|
||||
name.textContent = 'THE CLIMB';
|
||||
name.style.color = '';
|
||||
const best = stats.read('all', undefined, stats.MODE_MATCH).longest;
|
||||
document.getElementById('lgSub').textContent =
|
||||
`THE CLUB FROM THE BOTTOM — ${lg.band[1]} STAND` + (best ? ` · BEST RUN: ${best} FELLED` : '');
|
||||
document.getElementById('lgFoes').innerHTML = '';
|
||||
}
|
||||
|
||||
// THE LEAGUE PANEL (the leagues): the cup's setup face — your league writ large and the band's
|
||||
// roster with your all-time felled counts (stats' per-foe tallies, key 'L'+index). The identity
|
||||
// block these panels replace still shows for every other mode; the card owns it anyway.
|
||||
function buildLeaguePanel() {
|
||||
const lg = leagueOf(profile.prof.lg);
|
||||
const badge = document.getElementById('lgBadge');
|
||||
@@ -336,27 +351,26 @@ function buildLeaguePanel() {
|
||||
// On the LEAGUE MODES the player block steps aside for the league panel (Oliver: the identity is
|
||||
// on the card now — the setup should show the league and who of it you have already beaten).
|
||||
function syncSetup() {
|
||||
const leagueMode = pickedMode === 'zombie' || pickedMode === 'cup';
|
||||
document.getElementById('who').style.display = leagueMode ? 'none' : 'flex';
|
||||
document.getElementById('lgPanel').style.display = leagueMode ? 'block' : 'none';
|
||||
document.getElementById('s01').textContent = leagueMode ? '01 · YOUR LEAGUE' : '01 · PLAYER';
|
||||
if (leagueMode) buildLeaguePanel();
|
||||
const cupMode = pickedMode === 'cup', climbMode = pickedMode === 'zombie';
|
||||
document.getElementById('who').style.display = cupMode || climbMode ? 'none' : 'flex';
|
||||
document.getElementById('lgPanel').style.display = cupMode || climbMode ? 'block' : 'none';
|
||||
document.getElementById('s01').textContent =
|
||||
cupMode ? '01 · YOUR LEAGUE' : climbMode ? '01 · THE CLIMB' : '01 · PLAYER';
|
||||
if (cupMode) buildLeaguePanel(); else if (climbMode) buildClimbPanel();
|
||||
if (!courtUnlocked(picked)) picked = leagueOf(profile.prof.lg).court;
|
||||
// ...and the COURT section stops pretending to be a choice on the league modes (Oliver: a
|
||||
// league HAS its court — start() has forced it all along): only the league's own row shows,
|
||||
// ringed, as the venue. Every other mode gets the full pickable list. This runs AFTER the
|
||||
// generic repaint below would, so it has the last word on .on/.lock.
|
||||
// the COURT section: the CUP is the league fixture — one ringed row, the home venue, no choice
|
||||
// (Oliver: a league HAS its court). The climb and every other mode keep the full pickable list.
|
||||
const homeCourt = leagueOf(profile.prof.lg).court;
|
||||
document.getElementById('s02').innerHTML = leagueMode
|
||||
document.getElementById('s02').innerHTML = cupMode
|
||||
? '02 · HOME COURT<span>SET BY YOUR LEAGUE</span>' : '02 · COURT';
|
||||
courtList.classList.toggle('fixed', leagueMode);
|
||||
courtList.classList.toggle('fixed', cupMode);
|
||||
for (const el of courtList.children) {
|
||||
const c = COURTS.find(x => x.id === el.dataset.id), l = courtLeague(el.dataset.id);
|
||||
const open = courtUnlocked(el.dataset.id);
|
||||
el.classList.toggle('lock', !open && !leagueMode);
|
||||
el.classList.toggle('on', leagueMode ? el.dataset.id === homeCourt
|
||||
: open && el.dataset.id === picked);
|
||||
el.style.display = leagueMode && el.dataset.id !== homeCourt ? 'none' : '';
|
||||
el.classList.toggle('lock', !open && !cupMode);
|
||||
el.classList.toggle('on', cupMode ? el.dataset.id === homeCourt
|
||||
: open && el.dataset.id === picked);
|
||||
el.style.display = cupMode && el.dataset.id !== homeCourt ? 'none' : '';
|
||||
// the sub line carries the lock and names the price — the tile stays visible, as a goal should
|
||||
el.querySelector('i').textContent = open ? c.sub : 'LOCKED — REACH ' + l.name;
|
||||
}
|
||||
@@ -440,7 +454,7 @@ for (const c of COURTS) {
|
||||
// Tapping a tile SELECTS it and nothing more. It used to start the match on the spot, which gave
|
||||
// you no way to look at the three of them and no way back out of the screen.
|
||||
b.addEventListener('click', () => {
|
||||
if (pickedMode === 'zombie' || pickedMode === 'cup') return; // the league picks the venue
|
||||
if (pickedMode === 'cup') return; // the cup is the league fixture — the league picks
|
||||
if (!courtUnlocked(c.id)) return; // locked: the row itself says which league opens it
|
||||
picked = c.id;
|
||||
for (const el of courtList.children) el.classList.toggle('on', el === b);
|
||||
@@ -541,7 +555,7 @@ function buildTrain() {
|
||||
const top = Math.min(LADDER, leagueOf(profile.prof.lg).band[1]);
|
||||
for (let n = 1; n <= top; n++) {
|
||||
const f = matchFoe(n), b = document.createElement('button');
|
||||
b.innerHTML = `<img src="${foeArt(f)}" alt=""><b>${f.name}</b><i>RUNG ${n}</i>`;
|
||||
b.innerHTML = `<img src="${foeArt(f)}" alt=""><b>${f.name}</b><i>No. ${n}</i>`;
|
||||
b.addEventListener('click', () => { trainRung = n; start('train'); });
|
||||
trainList.appendChild(b);
|
||||
}
|
||||
@@ -669,8 +683,8 @@ const boardFor = m => m === 'zombie' || m === 'cup' || m === 'train' ? stats.MOD
|
||||
function summary() {
|
||||
const t = TOURS.find(x => x.id === pickedTour) || TOURS[0];
|
||||
const lg = leagueOf(profile.prof.lg);
|
||||
const leagueMode = pickedMode === 'zombie' || pickedMode === 'cup';
|
||||
const c = COURTS.find(x => x.id === (leagueMode ? lg.court : picked)) || COURTS[0];
|
||||
const cupMode = pickedMode === 'cup';
|
||||
const c = COURTS.find(x => x.id === (cupMode ? lg.court : picked)) || COURTS[0];
|
||||
const m = MODES.find(x => x.id === pickedMode) || MODES[0];
|
||||
// the mark to beat is the PICKED MODE's own, because the three of them do not measure the same
|
||||
// thing — see the record-shape note in stats.endRun. The cup banks through endRun as MODE_MATCH
|
||||
@@ -681,7 +695,7 @@ function summary() {
|
||||
const name = m.id === 'classic'
|
||||
? m.name + ' · ' + (DIFFS.find(d => d.id === pickedDiff) || DIFFS[1]).name : m.name;
|
||||
document.getElementById('sSum').innerHTML =
|
||||
`<span>${name} · ${t.name.replace(' SINGLES', '')} · ${c.name}${leagueMode
|
||||
`<span>${name} · ${t.name.replace(' SINGLES', '')} · ${c.name}${cupMode
|
||||
? ' · LEAGUE ' + lg.id : ''}</span>`
|
||||
// training banks nothing, so there is no mark to beat and the footer must not invent one
|
||||
+ `<span>${m.id === 'train' ? 'NOTHING AT STAKE — JUST REPS'
|
||||
@@ -718,9 +732,9 @@ function start(modeId = pickedMode) {
|
||||
if (!menuUp()) return;
|
||||
selectTour(pickedTour);
|
||||
selectKit(pickedKit); selectSkin(pickedSkin);
|
||||
// THE LEAGUES: a league match is played on the league's own court — the pick stays yours in
|
||||
// classic, gore, netplay and training (among the unlocked courts).
|
||||
selectCourt(modeId === 'zombie' || modeId === 'cup' ? leagueOf(profile.prof.lg).court : picked);
|
||||
// THE LEAGUES: the CUP is the league fixture and plays the league's own court; every other
|
||||
// mode — the climb included, it is an exhibition — plays your pick (among the unlocked).
|
||||
selectCourt(modeId === 'cup' ? leagueOf(profile.prof.lg).court : picked);
|
||||
menuDuck(true); // the theme belongs to the menus — hand the court over to the ambience
|
||||
intro.hidden = true; ambient(); voice('quiet_please'); // low atmosphere bed starts with the first gesture
|
||||
// ...and the mode the setup screen picked. THREE LINES, because that is genuinely all the modes
|
||||
|
||||
Reference in new issue
Block a user