fix tracks to all be EW. no more NS tracks
This commit is contained in:
+36
-17
@@ -294,18 +294,24 @@ export function divisionSvg(nodes: DivisionView[]): string {
|
||||
/**
|
||||
* The Office Area as a map: one card per grid square, rails drawn edge to edge.
|
||||
*
|
||||
* The through rail sits at a constant height on every card — the alignment the printed cards use —
|
||||
* so abutting cards produce one unbroken line and a gap is visibly a gap.
|
||||
* THE PRINTED CARD, and nothing else (docs/tracks.png). The through rail runs east-west across the
|
||||
* DEAD CENTRE of every card, so abutting cards produce one unbroken line and a gap is visibly a
|
||||
* gap. Everything that leaves through the north or south edge does so at 45°, through the middle of
|
||||
* that edge — which is what lets two stacked cards read as one continuous diagonal.
|
||||
*
|
||||
* The card is 166 x 96, the printed sheet's 259:150 proportions. The aspect is not decoration: the
|
||||
* frog where a 45° leg meets the through track sits H/2 from the centre, so a squarer card pushes
|
||||
* it almost to the edge and a turnout's two routes stop being tellable apart.
|
||||
*/
|
||||
export function officeSvg(
|
||||
cells: CellView[],
|
||||
runningRow: number,
|
||||
ghosts: { row: number; col: number }[] = [],
|
||||
): string {
|
||||
const W = 132;
|
||||
const W = 166;
|
||||
const H = 96;
|
||||
const PAD = 3;
|
||||
const RAIL = 30;
|
||||
const RAIL = H / 2;
|
||||
|
||||
const esc = (t: string): string =>
|
||||
String(t).replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' })[c] ?? c);
|
||||
@@ -356,8 +362,8 @@ export function officeSvg(
|
||||
return out;
|
||||
};
|
||||
|
||||
// Where each port meets the card edge. East and west sit at the rail height so a straight run
|
||||
// stays straight across the whole row; north and south are centred.
|
||||
// Where each port meets the card edge. East and west sit at the rail height — the card's middle —
|
||||
// so a straight run stays straight across the whole row; north and south are centred on the edge.
|
||||
const port = (p: string): { x: number; y: number } => {
|
||||
if (p === 'e') return { x: W, y: RAIL };
|
||||
if (p === 'w') return { x: 0, y: RAIL };
|
||||
@@ -389,15 +395,27 @@ export function officeSvg(
|
||||
// The rails. A Modifier is not track and deliberately gets none — that is why nothing can be
|
||||
// routed through it, and the picture should say so.
|
||||
for (const link of cell.links) {
|
||||
const a = port(link[0] ?? 'e');
|
||||
const b = port(link[1] ?? 'w');
|
||||
const straight = (link === 'ew' || link === 'we') || (link === 'ns' || link === 'sn');
|
||||
if (straight) {
|
||||
out += rail(a.x, a.y, b.x, b.y);
|
||||
const from = link[0] ?? 'e';
|
||||
const to = link[1] ?? 'w';
|
||||
const vertical = from === 'n' || from === 's' ? from : to === 'n' || to === 's' ? to : '';
|
||||
if (vertical === '') {
|
||||
// The through track: edge to edge along the middle of the card.
|
||||
out += rail(port(from).x, port(from).y, port(to).x, port(to).y);
|
||||
} else {
|
||||
// A diverging leg: run out from each edge and meet, which reads as a curve at this size.
|
||||
const mid = { x: W / 2, y: RAIL + (H - RAIL) / 2 };
|
||||
out += rail(a.x, a.y, mid.x, mid.y) + rail(mid.x, mid.y, b.x, b.y);
|
||||
/**
|
||||
* A 45° LEG, drawn as the card prints it: along the centre line from the east or west edge
|
||||
* to the FROG, then out at exactly 45° through the middle of the north or south edge.
|
||||
*
|
||||
* The frog is `H/2` from the centre because a 45° run climbing half the card's height
|
||||
* travels half its height sideways. This used to be a fixed elbow at (W/2, RAIL+(H-RAIL)/2)
|
||||
* — below the rail on the assumption everything diverged downward — which drew a leg
|
||||
* reaching north as a hook that dropped past the rail and came back up, and drew nothing at
|
||||
* any angle the matching rule cares about.
|
||||
*/
|
||||
const side = vertical === from ? to : from;
|
||||
const frog = { x: W / 2 + (side === 'e' ? H / 2 : -H / 2), y: RAIL };
|
||||
const edge = port(vertical);
|
||||
out += rail(port(side).x, port(side).y, frog.x, frog.y) + rail(frog.x, frog.y, edge.x, edge.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,9 +471,10 @@ export function officeSvg(
|
||||
}
|
||||
|
||||
if (cell.enhancements.length > 0) {
|
||||
// Above the load pipeline, not on it: an `onCard` enhancement can land on a facility, and at
|
||||
// the old baseline the label printed straight through the green/MEN|AT|WORK/red squares.
|
||||
out += `<text class="bs-enh" x="6" y="${H - 46}">${esc(cell.enhancements.join(' · '))}</text>`;
|
||||
// ABOVE the rail. An `onCard` enhancement can land on a facility, so it has to clear both the
|
||||
// load pipeline below and the through track — and with the rail now down the middle of the
|
||||
// card, the old y = H-46 baseline printed the label straight along the rail itself.
|
||||
out += `<text class="bs-enh" x="6" y="26">${esc(cell.enhancements.join(' · '))}</text>`;
|
||||
}
|
||||
if (cell.tray) {
|
||||
out += `<g class="bs-crew"><rect x="${W / 2 - 26}" y="${RAIL - 10}" width="52" height="20" rx="3"/>` +
|
||||
|
||||
Reference in New Issue
Block a user