fix tracks to all be EW. no more NS tracks

This commit is contained in:
Jesse
2026-08-05 01:00:11 -04:00
parent 821d3cdffa
commit 2d348e1ecf
16 changed files with 1157 additions and 355 deletions
+21 -19
View File
@@ -1345,44 +1345,44 @@ export function reduce(s: GameState, e: GameEvent): void {
}
/**
* Builds the card a play would place, at the chosen orientation (Gap 11). Returns null when the
* variant index is out of range, which `check` reports rather than silently defaulting — a wrong
* Builds the card a play would place, at the chosen orientation. Returns null when the variant
* index is out of range, which `check` reports rather than silently defaulting — a wrong
* orientation is a different card, not a detail.
*/
function protoCard(
kind: { kind: string; geometry?: string; facility?: string },
kind: { kind: string; geometry?: string; facility?: string; hand?: string },
variant: number | undefined,
): TrackCard | null {
const base = { standing: [], facility: null, modifiers: [], enhancements: [] };
if (kind.kind === 'track') {
const geometry = kind.geometry as TrackGeometry;
const options = variantsFor(geometry);
// Track is a per-player supply rather than a deck card, so nothing reaches this branch today.
// It still needs a hand: handedness IS the slope, and defaulting silently would lay a card on
// the wrong diagonal.
const hand = (kind.hand as Hand | undefined) ?? 'left';
const options = variantsFor(geometry, hand);
const v = options[variant ?? 0];
if (!v) return null;
return {
geometry: {
kind: 'track',
geometry,
...(v.axis ? { axis: v.axis } : {}),
...(v.arc ? { arc: v.arc } : {}),
...(v.turnout ? { turnout: v.turnout } : {}),
...(v.bypass ? { bypass: v.bypass } : {}),
...(hand !== 'none' ? { hand } : {}),
},
baseOperationalRail: geometry !== 'turnout',
...base,
};
}
const options = facilityVariants();
const v = options[variant ?? 0];
if (!v) return null;
// A Facility is plain east-west track, as every industry card on the printed sheet is, so there
// is exactly one orientation and any index past it is out of range.
if (!facilityVariants()[variant ?? 0]) return null;
return {
geometry: {
kind: 'facility',
facility: kind.facility as never,
...(v.axis ? { axis: v.axis } : {}),
},
geometry: { kind: 'facility', facility: kind.facility as never },
baseOperationalRail: true,
...base,
};
@@ -1440,14 +1440,14 @@ function adjacentFacilityCoord(
coord: GridCoord,
modifier?: ModifierKind,
): GridCoord | null {
// Q7 — nothing exists above the Running Track, so §9's "nine nearby spots" is really six.
if (coord.row > area.runningRow) return null;
// A turnout's 45° leg reaches north as readily as south (turn the card 180°), so a district grows
// on both sides of the Running Track and §9's "nine nearby spots" really is nine. The old Q7
// guard here rejected the three above outright.
const hosts = modifier ? modifierProfile(modifier).hosts : null;
for (let dr = -1; dr <= 1; dr++) {
for (let dc = -1; dc <= 1; dc++) {
if (dr === 0 && dc === 0) continue;
const c = { row: coord.row + dr, col: coord.col + dc };
if (c.row > area.runningRow) continue;
const f = area.grid.get(coordKey(c))?.facility;
if (!f) continue;
if (hosts && !hosts.includes(f.subtype)) continue;
@@ -1560,20 +1560,22 @@ function spendCard(s: GameState, player: PlayerIndex, cardId: CardId): void {
s.decks.salvageYard.push(cardId);
}
/** A track piece from the player's own supply, at the chosen rotation. */
/**
* A track piece from the player's own supply, at the chosen rotation — which for a printed card is
* 0° or 180°, and never a flip, so `hand` decides which diagonal the 45° leg can lie on.
*/
function protoTrackCard(
geometry: TrackGeometry,
hand: Hand,
variant: number | undefined,
): TrackCard | null {
const options = variantsFor(geometry);
const options = variantsFor(geometry, hand);
const v = options[variant ?? 0];
if (!v) return null;
return {
geometry: {
kind: 'track',
geometry,
...(v.axis ? { axis: v.axis } : {}),
...(v.arc ? { arc: v.arc } : {}),
...(v.turnout ? { turnout: v.turnout } : {}),
...(hand !== 'none' ? { hand } : {}),