v0.4.4 — New Game dialog for the opening hand and the three revenue rates, Yard renamed Interchange, and two movement bugs behind a mirrored consist
This commit is contained in:
+22
-10
@@ -38,11 +38,12 @@ import {
|
||||
lengthProfile,
|
||||
officeProfile,
|
||||
trainProfile,
|
||||
houseRules,
|
||||
} from '../engine/content.ts';
|
||||
import type { Intent } from '../engine/intents.ts';
|
||||
import type { Facility, GameState, PlayerIndex, TrackCard, TurnoutOrientation } from '../engine/state.ts';
|
||||
import { playerAtSeat, seatOf, turnOf } from '../engine/state.ts';
|
||||
import type { Hand, TrackGeometry } from '../engine/content.ts';
|
||||
import { playerAtSeat, railFacingOf, seatOf, turnOf } from '../engine/state.ts';
|
||||
import type { Hand, HouseRules, TrackGeometry } from '../engine/content.ts';
|
||||
import type { Port } from '../engine/track.ts';
|
||||
import { connectionsFor, slopeOfPair, variantsFor } from '../engine/track.ts';
|
||||
import type { Impediment } from './narrate.ts';
|
||||
@@ -76,13 +77,14 @@ export type CellView = {
|
||||
* not plan a move at all: "drop 1 car" tells you nothing when you cannot see what is on the back.
|
||||
*
|
||||
* `cars` runs nose first, matching the tray; `engineAt` is where the locomotive sits in it, and
|
||||
* `facing` is the port it points at on this card.
|
||||
* `facing` is which way the engine points — EAST OR WEST, never north or south, whatever the
|
||||
* track under it runs. See `railFacingOf` in state.ts for why, and why the type says so.
|
||||
*/
|
||||
train: {
|
||||
label: string;
|
||||
cars: string[];
|
||||
engineAt: number;
|
||||
facing: string;
|
||||
facing: 'e' | 'w';
|
||||
/**
|
||||
* WHAT THIS PARTICULAR TRAIN'S CARD SAYS.
|
||||
*
|
||||
@@ -188,13 +190,14 @@ export type TrainChip = {
|
||||
* THE SAME TRAIN THE OFFICE CARD DRAWS, so the Division map can draw it the same way.
|
||||
*
|
||||
* `cars` is nose first and carries no engine; `engineAt` is where the engine sits among them and
|
||||
* `facing` is the port it points at. The Division chip used to be a name and a number — and the
|
||||
* number was Stages left to cross, which reads as redundant beside the position already drawn on
|
||||
* the card. A train is worth drawing: what it is carrying, loaded or empty, and which end leads.
|
||||
* `facing` is which way the engine points, east or west. The Division chip used to be a name and a
|
||||
* number — and the number was Stages left to cross, which reads as redundant beside the position
|
||||
* already drawn on the card. A train is worth drawing: what it is carrying, loaded or empty, and
|
||||
* which end leads.
|
||||
*/
|
||||
cars: string[];
|
||||
engineAt: number;
|
||||
facing: string;
|
||||
facing: 'e' | 'w';
|
||||
/**
|
||||
* Which region of a Mainline card the train is standing in, and which way it is going. Absent
|
||||
* everywhere else: a Division Point is a single queue, and inside a district a train moves by
|
||||
@@ -287,6 +290,14 @@ export type Frame = {
|
||||
*/
|
||||
/** Which of §6's three exclusive options the VIEWER has taken this Stage, if any. */
|
||||
option: 'switch' | 'draw' | 'freightAgent' | null;
|
||||
/**
|
||||
* The settings this game was dealt under — the opening hand, and what the three economies pay.
|
||||
*
|
||||
* On the Frame rather than read off the config, for the same reason as everything else here: a
|
||||
* remote client holds no `GameState`, and "what does a load pay in this game?" is a question it
|
||||
* must be able to answer. Resolved, never partial, so nobody downstream re-applies defaults.
|
||||
*/
|
||||
houseRules: HouseRules;
|
||||
status: GameState['status'];
|
||||
outcome: GameState['outcome'];
|
||||
/**
|
||||
@@ -513,7 +524,7 @@ function trainOnCard(s: GameState, key: string): CellView['train'] {
|
||||
label: t.trainNumber === null ? 'crew' : `T${t.trainIsExtra ? 'X' : ''}${t.trainNumber}`,
|
||||
cars: t.consist.map(carLabel),
|
||||
engineAt: Math.max(0, Math.min(t.consist.length, t.engineAt)),
|
||||
facing: t.facing ?? (t.direction === 'west' ? 'w' : 'e'),
|
||||
facing: railFacingOf(t),
|
||||
what: t.trainNumber === null ? 'A local crew — no timetable, no card, no special rules.' : trainRules(t),
|
||||
};
|
||||
void id;
|
||||
@@ -1044,6 +1055,7 @@ export function snapshot(
|
||||
decision,
|
||||
wasted,
|
||||
option: turnOf(s, viewer).option,
|
||||
houseRules: houseRules(s.config),
|
||||
status: s.status,
|
||||
outcome: s.outcome,
|
||||
players: s.players.map((p) => ({
|
||||
@@ -1579,7 +1591,7 @@ function trainChip(s: GameState, id: string): TrainChip {
|
||||
consist: seated,
|
||||
cars,
|
||||
engineAt: at,
|
||||
facing: t.facing ?? (t.direction === 'west' ? 'w' : 'e'),
|
||||
facing: railFacingOf(t),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user