fixed train# specific rules. cleaned up display topline and train display on division map

This commit is contained in:
Jesse
2026-08-09 19:44:18 -04:00
parent 4a800a053a
commit 6ead39c530
14 changed files with 316 additions and 57 deletions
+42
View File
@@ -307,7 +307,49 @@ function mainlinePhase(s: GameState, events: GameEvent[]): AdvanceResult {
for (const [id, tray] of order) {
if (s.movedThisPhase.has(id)) continue;
const where = tray.position;
const moved = moveTrain(s, id, tray, events);
/**
* X18 CIRCUS TRAIN — "one turn stopped on any track (circus set-up) earns 1 point".
*
* The flag was declared on the profile and read NOWHERE, so the one card in the deck that pays
* for standing still paid nothing: reported from a playtest where TX18 sat on a siding for a
* full Stage and no point arrived. Claimed once — an Extra runs once and is gone.
*
* "Stopped" is measured against the Mainline Phase: the train attempted to move and stayed where
* it was. A train that is still in the district when the phase runs has not moved either, which
* is the circus setting up on a siding rather than crossing the Division.
*/
if (!tray.stopPointClaimed && trainProfile(tray.trainNumber ?? 0, tray.trainIsExtra)?.rules.stopEarnsPoint) {
const stillThere =
tray.position.at === where.at &&
(tray.position.at !== 'mainline' || where.at !== 'mainline' || tray.position.index === where.index) &&
(tray.position.at !== 'grid' ||
where.at !== 'grid' ||
(tray.position.coord.row === where.coord.row && tray.position.coord.col === where.coord.col));
if (moved !== 'expedited' && stillThere) {
tray.stopPointClaimed = true;
const owner = tray.position.at === 'grid' ? tray.position.owner : 0;
const label =
tray.position.at === 'grid'
? `(${tray.position.coord.row},${tray.position.coord.col})`
: tray.position.at === 'mainline'
? `Mainline card ${tray.position.index}`
: `the ${tray.position.side} Division Point`;
events.push({ type: 'trainStoodStill', trainNumber: tray.trainNumber ?? 0, where: label });
const p = s.players[owner];
if (p) {
p.revenue += 1;
events.push({
type: 'revenueChanged',
player: owner,
delta: 1,
total: p.revenue,
reason: 'circus set-up — a Stage spent standing still',
});
}
}
}
if (moved === 'needsClearance') return { events, needsInput: true };
// An expedited train may act twice in one Stage: it arrives and departs (Q3).
if (moved === 'expedited') {