user card Hand becomes the action surface, the board shows the train, and a reverse stops turning it around, other bug fixes too.
This commit is contained in:
+33
-3
@@ -12,6 +12,8 @@
|
||||
*/
|
||||
|
||||
import { BOARD_CSS, divisionSvg, officeSvg } from '../sim/board-svg.ts';
|
||||
import { TURNCHART_CSS, turnChartHtml } from '../sim/turnchart.ts';
|
||||
import { PANEL_CSS, blockedHtml, facilitiesHtml, handHtml, pilesHtml, yardHtml } from './panels.ts';
|
||||
import { cuesFor } from '../sim/narrate.ts';
|
||||
import { playCue } from './sound.ts';
|
||||
import { TOOLTIP_CSS, installTooltips } from './tooltip.ts';
|
||||
@@ -109,8 +111,13 @@ function show(i: number): void {
|
||||
// whistles, and stepping back would sound a Stage ending that is being un-done.
|
||||
if (soundOn && at === from + 1) for (const c of step.cues) playCue(c);
|
||||
|
||||
$('vclock').textContent = `Day ${f.day} · Stage ${f.stage} — ${f.clock}`;
|
||||
$('vphase').textContent = f.phase;
|
||||
// The live game's turn chart, from the shared renderer: same five phases, same violet "you are
|
||||
// here". A replay used to report the Day and phase as two plain strings, so the one thing a player
|
||||
// glances at most often looked nothing like it does in play.
|
||||
// A replay carries the seat names in the frame's own lines rather than a player table, so the
|
||||
// solitaire seat is named directly; a multi-player replay reports the index it has.
|
||||
const actorName = f.actor === null ? null : `Player ${f.actor + 1}`;
|
||||
$('turnchart').innerHTML = turnChartHtml(f, actorName);
|
||||
$('vrev').textContent = String(f.revenue);
|
||||
$('vpos').textContent = `${at} / ${steps.length - 1}`;
|
||||
($('vscrub') as HTMLInputElement).value = String(at);
|
||||
@@ -139,6 +146,17 @@ function show(i: number): void {
|
||||
log += `<div class="line t-${l.tone}${k === at ? ' now' : ''}">${esc(l.text)}</div>`;
|
||||
}
|
||||
}
|
||||
// The same side panels the playable page shows, from the same renderers. A replay is the game
|
||||
// being watched, so it drops only what asks you to act.
|
||||
$('vhand').innerHTML = handHtml(f);
|
||||
$('vdepts').innerHTML = pilesHtml(f);
|
||||
$('vdivyard').innerHTML = yardHtml(f.yards.division);
|
||||
$('vclsyard').innerHTML = yardHtml(f.yards.classification);
|
||||
$('vdivtot').textContent = `${f.yards.divisionTotal} cars`;
|
||||
$('vclstot').textContent = `${f.yards.classificationTotal} cars`;
|
||||
$('vblocked').innerHTML = blockedHtml(f);
|
||||
$('vfacs').innerHTML = facilitiesHtml(f);
|
||||
|
||||
$('vlog').innerHTML = log;
|
||||
const logEl = $('vlog');
|
||||
logEl.scrollTop = logEl.scrollHeight;
|
||||
@@ -252,6 +270,18 @@ function wire(): void {
|
||||
show(at + 1);
|
||||
}, Number(($('vspeed') as HTMLSelectElement).value));
|
||||
};
|
||||
/**
|
||||
* A SPEED CHANGE HAS TO TAKE EFFECT WHILE IT IS PLAYING.
|
||||
*
|
||||
* The interval is created with whatever the select held at the moment play started, and nothing
|
||||
* re-read it — so choosing "extra slow" mid-replay did nothing at all and the pace looked stuck.
|
||||
* The standalone replay has always restarted its timer on change; this viewer was missed.
|
||||
*/
|
||||
($('vspeed') as HTMLSelectElement).onchange = () => {
|
||||
if (!timer) return;
|
||||
$('vplay').click();
|
||||
$('vplay').click();
|
||||
};
|
||||
$('vdistricttoggle').onclick = () => {
|
||||
const f = steps[at]?.frame;
|
||||
const open = districtMode === 'auto' ? (f ? FOCUS_PHASES.has(f.phaseKey) : true) : districtMode === 'open';
|
||||
@@ -283,7 +313,7 @@ function wire(): void {
|
||||
}
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = BOARD_CSS + TOOLTIP_CSS;
|
||||
style.textContent = BOARD_CSS + TOOLTIP_CSS + TURNCHART_CSS + PANEL_CSS;
|
||||
document.head.appendChild(style);
|
||||
installTooltips();
|
||||
wire();
|
||||
|
||||
Reference in New Issue
Block a user