the Roster Pass: every train at the Office visible
Builds "The Roster Pass" / "Two Trains, One Card" (station display for multiple trains at one Office). The Office is the one square where more than one train may legally stand at once (one per A/D track), and CellView.train had room for exactly one — a second train at a busy Station was counted in the old A/D pips and never drawn. CellView.train -> CellView.trains: TrainView[], seat-filtered and collecting every match rather than the first (fixes a latent cross-district leak in the process: trainOnCard never checked seat). The A/D pips are replaced with one roster chip per A/D track, always, free or occupied; clicking a chip sets selectedCrew, wiring the board and the action panel to the same value. standingWest moves from CrewTray to TrackCard: two trays sharing one Office card need one shared split, not one each, and there is no such thing as "west of one particular A/D track". No save migration — Save replays through the engine — and a stale value on an emptied card is inert because nothing reads a split with no train standing there. The Division map's Office cell is now sized by A/D capacity rather than occupancy, so it holds still as trains arrive and leave; chips lay into fixed slots instead of centre-spreading onto the Limits cards either side. 584 tests, 0 failures. Verified end-to-end against the built app and a direct render of a 4-train Terminal (screenshotted). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAt2YCXgd5qCjBcF2x34aK
This commit is contained in:
@@ -36,6 +36,7 @@ const straight = (standing: RollingStock[] = []): TrackCard => ({
|
||||
geometry: { kind: 'track', geometry: 'straight' },
|
||||
baseOperationalRail: true,
|
||||
standing,
|
||||
standingWest: 0,
|
||||
facility: null,
|
||||
modifiers: [],
|
||||
enhancements: [],
|
||||
@@ -149,7 +150,14 @@ describe('a cut parks in the same order however many cars come off at once', ()
|
||||
|
||||
// Facing east: the nose cut (boxcar) is set out east of the engine, the tail cut (tank) west.
|
||||
assert.deepEqual(standingAt(s, at(1, 0)), ['tank', 'boxcar']);
|
||||
assert.equal(s.trays.get(id)!.standingWest, 1, 'the engine should be standing between the two cuts');
|
||||
// `standingWest` lives on the CARD now, not the tray (docs/plans/switching-paths.md — "The
|
||||
// Roster Pass"): the Office is the one square more than one train may share, and a cut lies
|
||||
// west or east of the block of A/D tracks rather than of any one engine.
|
||||
assert.equal(
|
||||
areaOf(s, 0).grid.get(coordKey(at(1, 0)))!.standingWest,
|
||||
1,
|
||||
'the engine should be standing between the two cuts',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user