diff --git a/art/maps/bellhouse-section.svg b/art/maps/bellhouse-section.svg index 8e8c4e8..bfecdae 100644 --- a/art/maps/bellhouse-section.svg +++ b/art/maps/bellhouse-section.svg @@ -161,7 +161,7 @@ 11 · Pipe room — Centre's in-tray 12 · Plant floor — boilers, coal face, transmitter 13 · Vigil hall * - 14 · Allotments and Buffer Depot * + 14 · Vegetable tunnels and Buffer Depot * 15 · The Sump * * pit galleries, not drawn diff --git a/art/maps/bellhouse-section.webp b/art/maps/bellhouse-section.webp index 76b6be2..91ae977 100644 Binary files a/art/maps/bellhouse-section.webp and b/art/maps/bellhouse-section.webp differ diff --git a/art/maps/bh-control.svg b/art/maps/bh-control.svg index c95ea31..30199cf 100644 --- a/art/maps/bh-control.svg +++ b/art/maps/bh-control.svg @@ -6,6 +6,7 @@ .rm2 { fill:#11417d; stroke:#e8f1fb; stroke-width:5; } .rock { fill:#0e3668; stroke:#9fbde0; stroke-width:4; stroke-dasharray:18 10; } .gap { stroke:#154a8a; stroke-width:12; } + .gap2 { stroke:#11417d; stroke-width:12; } .rgap { stroke:#0e3668; stroke-width:12; } .swing { fill:none; stroke:#e8f1fb; stroke-width:3; } .fur { fill:#1b579c; stroke:#cfe0f3; stroke-width:3; } @@ -19,6 +20,7 @@ .lbl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:30px; fill:#f4f8fd; letter-spacing:2px; } .sub { font-family:'Courier New',Courier,monospace; font-size:21px; fill:#b9d0ea; } + .exit { font-weight:700; fill:#e8f1fb; } .fl { font-family:'Courier New',Courier,monospace; font-size:18px; fill:#e8f1fb; text-anchor:middle; } .ttl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:34px; @@ -33,111 +35,118 @@ - - MAIN CORRIDOR - + + MAIN CORRIDOR + + ← LOBBY · SHEET 1 + + REGISTRY · SHEET 3 → + CONTROL ROOM Controller's floor - 7 - - CONSOLE · DIALS · TANNOY DESK - - - - - - - - - SITUATION MAP · REGION 12 - - - - - - - - SCOPE - SEALED 1974 — by order + 7 + + CONSOLE · DIALS · TANNOY DESK + + + + + + + + + + SITUATION MAP · REGION 12 + + + + + + + + SCOPE + SEALED 1974 — by order CONTROLLER E. Sowerby DESK - - - - letters from Centre + + + + files · Centre STUDIO broadcast · 1962 - - - - TAPE DECK - - - SAFE - - MIXER - - - MIC - new tape rec'd from Centre 2019 - - PIPE ROOM - Centre's in-tray - 11 - - PIPE - - IN-TRAY - every 90 days - - COMMS - teleprinters · switchboard - - TP - - TP - - SWITCHBOARD - - - no line out - - - - - - - - - - - - + + + + TAPE DECK + + + SAFE + + MIXER + + + MIC + new tape rec'd from Centre 2019 + + SECRETARIAT + minutes · rotas + + + + + + + + + + COMMS + teleprinters · switchboard + + TP + + TP + + SWITCHBOARD + + + no line out + + + + + + + + + + + + - - KEY - - - DOOR - - 7 - LOCATION No. - pencil - = AMENDED AT THE SEAT, 1974–2026 - - = UNLINED MINE WORKINGS - 1 SQUARE = 5 FT · N ↑ + + KEY + + + DOOR + + 7 + LOCATION No. + pencil + = AMENDED AT THE SEAT, 1974–2026 + + = UNLINED MINE WORKINGS + 1 SQUARE = 5 FT · NORTH ← REGIONAL SEAT OF GOVERNMENT 12 · BELLHOUSE - SHEET 2 OF 7 · LEVEL 2 · GOVERNMENT + SHEET 2 OF 8 · LEVEL 1 · GOVERNMENT CONTROL ROOM - SCALE: ONE SQUARE = 5 FT + SCALE: ONE SQUARE = 5 FT · SECTION: SO-H04 DRG RSG12/02 · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT diff --git a/art/maps/bh-control.webp b/art/maps/bh-control.webp index 9879017..ff48934 100644 Binary files a/art/maps/bh-control.webp and b/art/maps/bh-control.webp differ diff --git a/art/maps/bh-creche.svg b/art/maps/bh-creche.svg index 26a9a19..9f15549 100644 --- a/art/maps/bh-creche.svg +++ b/art/maps/bh-creche.svg @@ -6,6 +6,7 @@ .rm2 { fill:#11417d; stroke:#e8f1fb; stroke-width:5; } .rock { fill:#0e3668; stroke:#9fbde0; stroke-width:4; stroke-dasharray:18 10; } .gap { stroke:#154a8a; stroke-width:12; } + .gap2 { stroke:#11417d; stroke-width:12; } .rgap { stroke:#0e3668; stroke-width:12; } .swing { fill:none; stroke:#e8f1fb; stroke-width:3; } .fur { fill:#1b579c; stroke:#cfe0f3; stroke-width:3; } @@ -19,6 +20,7 @@ .lbl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:30px; fill:#f4f8fd; letter-spacing:2px; } .sub { font-family:'Courier New',Courier,monospace; font-size:21px; fill:#b9d0ea; } + .exit { font-weight:700; fill:#e8f1fb; } .fl { font-family:'Courier New',Courier,monospace; font-size:18px; fill:#e8f1fb; text-anchor:middle; } .ttl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:34px; @@ -33,8 +35,16 @@ - - WELFARE CORRIDOR + + LOWER CORRIDOR + + + + UP + UP TO LEVEL 1 · SHEET 4 + + + ← PIPE ROOM & PLANT · SHEET 6 CLOAKS @@ -53,7 +63,7 @@ SCHOOLROOM 10 - BLACKBOARD + BLACKBOARD TEACHER @@ -69,103 +79,103 @@ atlas: 1971 edition - + PLAYROOM - - pinned drawings along this wall + + pinned drawings along this wall RUG - - TOYS + + TOYS DORMITORY under-twelves - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - speaker fitted 2019 — 03:00 nightly - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + speaker fitted 2019 — 03:00 nightly + WASHROOM - - - - - - - BATHS - - + + + + + + + BATHS + + - - - - + + + + - - + + KEY @@ -179,14 +189,14 @@ = AMENDED AT THE SEAT, 1974–2026 = UNLINED MINE WORKINGS - 1 SQUARE = 5 FT · N ↑ + 1 SQUARE = 5 FT · NORTH ← REGIONAL SEAT OF GOVERNMENT 12 · BELLHOUSE - SHEET 5 OF 7 · LEVEL 3 · WELFARE + SHEET 5 OF 8 · LEVEL 2 · WELFARE CRECHE & SCHOOL - SCALE: ONE SQUARE = 5 FT + SCALE: ONE SQUARE = 5 FT · SECTION: SO-H04 DRG RSG12/05 · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT diff --git a/art/maps/bh-creche.webp b/art/maps/bh-creche.webp index 5b6ad64..4e511fe 100644 Binary files a/art/maps/bh-creche.webp and b/art/maps/bh-creche.webp differ diff --git a/art/maps/bh-lobby.svg b/art/maps/bh-lobby.svg index c058b7d..b7331bc 100644 --- a/art/maps/bh-lobby.svg +++ b/art/maps/bh-lobby.svg @@ -6,6 +6,7 @@ .rm2 { fill:#11417d; stroke:#e8f1fb; stroke-width:5; } .rock { fill:#0e3668; stroke:#9fbde0; stroke-width:4; stroke-dasharray:18 10; } .gap { stroke:#154a8a; stroke-width:12; } + .gap2 { stroke:#11417d; stroke-width:12; } .rgap { stroke:#0e3668; stroke-width:12; } .swing { fill:none; stroke:#e8f1fb; stroke-width:3; } .fur { fill:#1b579c; stroke:#cfe0f3; stroke-width:3; } @@ -19,6 +20,7 @@ .lbl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:30px; fill:#f4f8fd; letter-spacing:2px; } .sub { font-family:'Courier New',Courier,monospace; font-size:21px; fill:#b9d0ea; } + .exit { font-weight:700; fill:#e8f1fb; } .fl { font-family:'Courier New',Courier,monospace; font-size:18px; fill:#e8f1fb; text-anchor:middle; } .ttl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:34px; @@ -33,105 +35,115 @@ - FROM ADIT (SEALED 1975) BLAST LOCK outer lock - - - air goes wrong here + + + air goes wrong here + ADIT DECONTAM. showers · lockers - - - + + + LOBBY public waiting 6 - - ENQUIRIES COUNTER - - - - - - - - - - - - - - - NOTICEBOARD - housing list — see Mr Ogden - + + ENQUIRIES COUNTER + + + + + + + + + + + + + + + NOTICEBOARD + housing list — see Mr Ogden + ENQUIRIES Mr Ogden - - DESK - - - - - ☎ - - INTERVIEW - the door does not lock - - TABLE - - - - - - WARDENS' POST - - - truncheon rack - - MAIN - CORRIDOR - - - - - - - - - - - - - + + DESK + + + + + ☎ + + INTERVIEW + does not lock + + TABLE + + + + + + ARMOURY + + + arms rack + key: Controller + + WARDENS' + post + + + truncheons + + MAIN CORRIDOR + + CONTROL, REGISTRY, SICK BAY · SHEETS 2–4 → + + + + + + + + + + + + + + + - - KEY - - - DOOR - - 7 - LOCATION No. - pencil - = AMENDED AT THE SEAT, 1974–2026 - - = UNLINED MINE WORKINGS - 1 SQUARE = 5 FT · N ↑ + + KEY + + + DOOR + + 7 + LOCATION No. + pencil + = AMENDED AT THE SEAT, 1974–2026 + + = UNLINED MINE WORKINGS + 1 SQUARE = 5 FT · NORTH ← REGIONAL SEAT OF GOVERNMENT 12 · BELLHOUSE - SHEET 1 OF 7 · LEVEL 1 · ENTRY + SHEET 1 OF 8 · LEVEL 1 · ENTRY LOBBY & ENQUIRIES - SCALE: ONE SQUARE = 5 FT + SCALE: ONE SQUARE = 5 FT · SECTION: SO-H04 DRG RSG12/01 · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT diff --git a/art/maps/bh-lobby.webp b/art/maps/bh-lobby.webp index da5163f..f3af198 100644 Binary files a/art/maps/bh-lobby.webp and b/art/maps/bh-lobby.webp differ diff --git a/art/maps/bh-plant.svg b/art/maps/bh-plant.svg new file mode 100644 index 0000000..89d8dd1 --- /dev/null +++ b/art/maps/bh-plant.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + LOWER CORRIDOR + + CRECHE · SHEET 5 → + + PIPE ROOM + Centre's in-tray + 11 + + PIPE + 4" pneumatic from moor ↑ + + IN-TRAY + + + every 90 days + + STORES + issue counter + + COUNTER + + + + + + PLANT FLOOR + 12 + + COAL BOILER + + GEN 1 + + GEN 2 + + DUCTING + + PUMPS + + FILTERS + coal up from No.2 road + + + + INCLINE + ↓ PIT GALLERIES · SHEET 7 + + COAL HOPPER + + HOPPER + + TRANSMITTER + feed to mast + + + valve racks + + PANEL + + MAST CABLE ↑ MOOR + + + + + + + + + + + + + + + + + KEY + + + DOOR + + 7 + LOCATION No. + pencil + = AMENDED AT THE SEAT, 1974–2026 + + = UNLINED MINE WORKINGS + 1 SQUARE = 5 FT · NORTH ← + + + + + REGIONAL SEAT OF GOVERNMENT 12 · BELLHOUSE + SHEET 6 OF 8 · LEVEL 2 · SERVICES + PIPE ROOM & PLANT + SCALE: ONE SQUARE = 5 FT · SECTION: SO-H04 + DRG RSG12/06 · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT + diff --git a/art/maps/bh-plant.webp b/art/maps/bh-plant.webp new file mode 100644 index 0000000..6425d36 Binary files /dev/null and b/art/maps/bh-plant.webp differ diff --git a/art/maps/bh-registry.svg b/art/maps/bh-registry.svg index 3a714bd..1f41444 100644 --- a/art/maps/bh-registry.svg +++ b/art/maps/bh-registry.svg @@ -6,6 +6,7 @@ .rm2 { fill:#11417d; stroke:#e8f1fb; stroke-width:5; } .rock { fill:#0e3668; stroke:#9fbde0; stroke-width:4; stroke-dasharray:18 10; } .gap { stroke:#154a8a; stroke-width:12; } + .gap2 { stroke:#11417d; stroke-width:12; } .rgap { stroke:#0e3668; stroke-width:12; } .swing { fill:none; stroke:#e8f1fb; stroke-width:3; } .fur { fill:#1b579c; stroke:#cfe0f3; stroke-width:3; } @@ -19,6 +20,7 @@ .lbl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:30px; fill:#f4f8fd; letter-spacing:2px; } .sub { font-family:'Courier New',Courier,monospace; font-size:21px; fill:#b9d0ea; } + .exit { font-weight:700; fill:#e8f1fb; } .fl { font-family:'Courier New',Courier,monospace; font-size:18px; fill:#e8f1fb; text-anchor:middle; } .ttl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:34px; @@ -33,19 +35,23 @@ - - MAIN CORRIDOR + + MAIN CORRIDOR + + ← CONTROL ROOM · SHEET 2 + + SICK BAY · SHEET 4 → PUBLIC COUNTER 8 - - COUNTER - - - - - - TAKE A NUMBER + + COUNTER + flap + + + + + TAKE A NUMBER complaints: allow 11 weeks RECORDS @@ -63,65 +69,64 @@ - BIRTHS · DEATHS · HOUSING · RATIONS · 1974– - + BIRTHS · DEATHS · HOUSING · RATIONS · 1974– + REGISTRAR A. Pennyfeather - - DESK - - + + DESK + + STRONGROOM standing orders - - - SAFE - - - - + + + SAFE + + + + TYPING POOL - - - - + + + + - - - - - - - - - - - - - + + + + + + + + + + + + - - KEY - - - DOOR - - 7 - LOCATION No. - pencil - = AMENDED AT THE SEAT, 1974–2026 - - = UNLINED MINE WORKINGS - 1 SQUARE = 5 FT · N ↑ + + KEY + + + DOOR + + 7 + LOCATION No. + pencil + = AMENDED AT THE SEAT, 1974–2026 + + = UNLINED MINE WORKINGS + 1 SQUARE = 5 FT · NORTH ← REGIONAL SEAT OF GOVERNMENT 12 · BELLHOUSE - SHEET 3 OF 7 · LEVEL 2 · GOVERNMENT + SHEET 3 OF 8 · LEVEL 1 · GOVERNMENT REGISTRY - SCALE: ONE SQUARE = 5 FT + SCALE: ONE SQUARE = 5 FT · SECTION: SO-H04 DRG RSG12/03 · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT diff --git a/art/maps/bh-registry.webp b/art/maps/bh-registry.webp index d6dadb8..584ff3f 100644 Binary files a/art/maps/bh-registry.webp and b/art/maps/bh-registry.webp differ diff --git a/art/maps/bh-sickbay.svg b/art/maps/bh-sickbay.svg index 12b1f65..e44e4c7 100644 --- a/art/maps/bh-sickbay.svg +++ b/art/maps/bh-sickbay.svg @@ -6,6 +6,7 @@ .rm2 { fill:#11417d; stroke:#e8f1fb; stroke-width:5; } .rock { fill:#0e3668; stroke:#9fbde0; stroke-width:4; stroke-dasharray:18 10; } .gap { stroke:#154a8a; stroke-width:12; } + .gap2 { stroke:#11417d; stroke-width:12; } .rgap { stroke:#0e3668; stroke-width:12; } .swing { fill:none; stroke:#e8f1fb; stroke-width:3; } .fur { fill:#1b579c; stroke:#cfe0f3; stroke-width:3; } @@ -19,6 +20,7 @@ .lbl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:30px; fill:#f4f8fd; letter-spacing:2px; } .sub { font-family:'Courier New',Courier,monospace; font-size:21px; fill:#b9d0ea; } + .exit { font-weight:700; fill:#e8f1fb; } .fl { font-family:'Courier New',Courier,monospace; font-size:18px; fill:#e8f1fb; text-anchor:middle; } .ttl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:34px; @@ -33,76 +35,84 @@ - - WELFARE CORRIDOR + + MAIN CORRIDOR + + ← REGISTRY · SHEET 3 + + + + DOWN + DOWN TO LEVEL 2 · SHEET 5 + RECEPTION 9 DESK - - - - + + + + GENERAL WARD eighteen beds - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIDE ROOM Mrs Marlow - - - - - - + + + + + + DISPENSARY - - - + + + MEDICAL OFFICER Dr Larkhall - - DESK - - - + + DESK + + + DELIVERY maternity @@ -115,22 +125,22 @@ THEATRE TABLE - + ISOLATION - - - - - unused since '78 + + + + + unused since '78 - - + + @@ -149,27 +159,29 @@ + + - - KEY - - - DOOR - - 7 - LOCATION No. - pencil - = AMENDED AT THE SEAT, 1974–2026 - - = UNLINED MINE WORKINGS - 1 SQUARE = 5 FT · N ↑ + + KEY + + + DOOR + + 7 + LOCATION No. + pencil + = AMENDED AT THE SEAT, 1974–2026 + + = UNLINED MINE WORKINGS + 1 SQUARE = 5 FT · NORTH ← REGIONAL SEAT OF GOVERNMENT 12 · BELLHOUSE - SHEET 4 OF 7 · LEVEL 3 · WELFARE + SHEET 4 OF 8 · LEVEL 1 · WELFARE SICK BAY - SCALE: ONE SQUARE = 5 FT + SCALE: ONE SQUARE = 5 FT · SECTION: SO-H04 DRG RSG12/04 · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT diff --git a/art/maps/bh-sickbay.webp b/art/maps/bh-sickbay.webp index d7d1385..e2c2b1e 100644 Binary files a/art/maps/bh-sickbay.webp and b/art/maps/bh-sickbay.webp differ diff --git a/art/maps/bh-sump.svg b/art/maps/bh-sump.svg index 6189942..9fb2692 100644 --- a/art/maps/bh-sump.svg +++ b/art/maps/bh-sump.svg @@ -1,11 +1,12 @@ - + - - No.2 COAL ROAD - growing beds under lamps + + + + INCLINE + ↑ PLANT FLOOR · SHEET 6 + + No.2 COAL ROAD + growing beds under lamps 14 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - workings beyond: not surveyed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VIGIL HALL · SHEET 8 → + + BUFFER DEPOT + tins · blankets · oil + + + workings west: not surveyed No.3 COAL ROAD trout tanks @@ -98,47 +109,48 @@ eggs → Welfare, Tues/Fri - SUMP STAIR + + SUMP STAIR THE SUMP 15 - - - - CELL 1 - - + CELL 1 + + - CELL 2 - - + + CELL 2 + + - CELL 3 - - + + CELL 3 + + - CELL 4 - - + + CELL 4 + + - - WARDEN - locks: 1962 pattern — oil them + + WARDEN + locks: 1962 pattern — oil them + + - - ← to Welfare stair KEY @@ -152,14 +164,14 @@ = AMENDED AT THE SEAT, 1974–2026 = UNLINED MINE WORKINGS - 1 SQUARE = 5 FT · N ↑ + 1 SQUARE = 5 FT · NORTH ← REGIONAL SEAT OF GOVERNMENT 12 · BELLHOUSE - SHEET 7 OF 7 · LEVEL 4 · WORKINGS - TUNNELS & SUMP - SCALE: ONE SQUARE = 5 FT + SHEET 7 OF 8 · PIT GALLERIES + COAL ROADS & SUMP + SCALE: ONE SQUARE = 5 FT · SECTION: SO-H04 DRG RSG12/07 · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT diff --git a/art/maps/bh-sump.webp b/art/maps/bh-sump.webp index 1cf649d..b269335 100644 Binary files a/art/maps/bh-sump.webp and b/art/maps/bh-sump.webp differ diff --git a/art/maps/bh-vigil.svg b/art/maps/bh-vigil.svg index 24948b1..5dda950 100644 --- a/art/maps/bh-vigil.svg +++ b/art/maps/bh-vigil.svg @@ -1,11 +1,12 @@ - + - - VIGIL HALL - 13 - - PLATFORM - - lectern - - ROLL OF HONOUR - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 999 seats — add one - - CORR. - - PLANT FLOOR - 12 - - COAL BOILER - - GEN 1 - - GEN 2 - - DUCTING - - PUMPS - - FILTERS - coal from No.2 road - - TRANSMITTER - feed to mast - - - valve racks - - PANEL - - MAST CABLE ↑ MOOR - - - - - - - - - - + + ← SHEET 7 + + VIGIL HALL + 13 + + PLATFORM + + ROLL OF HONOUR + + lectern + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + STACK + + STACK + + STACK + Thursday: chairs out — all 999 stand + standing room + + + + + fire exit → galleries - - KEY - - - DOOR - - 7 - LOCATION No. - pencil - = AMENDED AT THE SEAT, 1974–2026 - - = UNLINED MINE WORKINGS - 1 SQUARE = 5 FT · N ↑ + + KEY + + + DOOR + + 7 + LOCATION No. + pencil + = AMENDED AT THE SEAT, 1974–2026 + + = UNLINED MINE WORKINGS + 1 SQUARE = 5 FT · NORTH ← REGIONAL SEAT OF GOVERNMENT 12 · BELLHOUSE - SHEET 6 OF 7 · LEVEL 3 · ASSEMBLY - VIGIL HALL & PLANT - SCALE: ONE SQUARE = 5 FT - DRG RSG12/06 · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT + SHEET 8 OF 8 · PIT GALLERIES + VIGIL HALL + SCALE: ONE SQUARE = 5 FT · SECTION: SO-H04 + DRG RSG12/08 · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT diff --git a/art/maps/bh-vigil.webp b/art/maps/bh-vigil.webp index 929825f..dda1484 100644 Binary files a/art/maps/bh-vigil.webp and b/art/maps/bh-vigil.webp differ diff --git a/docs/scenarios/STANDING_ORDER.md b/docs/scenarios/STANDING_ORDER.md index 6a58a6c..e22c2df 100644 --- a/docs/scenarios/STANDING_ORDER.md +++ b/docs/scenarios/STANDING_ORDER.md @@ -609,11 +609,14 @@ is much harder at four**, and the table above says how much. ## Locations — quick reference -**The underground is seven blueprint scenes** in the Adventure, one sheet each, drawn as +**The underground is eight blueprint scenes** in the Adventure, one sheet each, drawn as the 1962 drawing office issued them with fifty years of pencil amendments. They are -2800×2000 at five feet to the square, so tokens and the Foundry grid line up. **Nothing on -a sheet gives away a GM secret**; the pencil notes are what the people below wrote. -The section drawing (SO-H04) is the overview. +2800×2000 at five feet to the square, so tokens and the Foundry grid line up. **North is to +the left on every sheet**, matching the section drawing (SO-H04): Level 1 runs from the lobby +at the north end to the sick bay and the stair down at the south; Level 2 runs from the +crèche under the sick bay north to the pipe room and plant; an incline from the plant floor +goes down to the pit galleries. Every corridor end says which sheet it leads to. **Nothing +on a sheet gives away a GM secret**; the pencil notes are what the people below wrote. | # | Location | Act | Blueprint scene | One line | |---|---|---|---|---| @@ -622,37 +625,20 @@ The section drawing (SO-H04) is the overview. | 3 | The vent | 1 | — | Warm, smells of coal; the crossing | | 4 | The postal pipe | 1/2 | — | How Centre's letters arrive | | 5 | The adit | 1 | — | Filled with rubble in 1975 | -| 6 | Lobby and Enquiries | 1 | **Sheet 1** | Mr Ogden; the crossing lands in the blast lock | -| 7 | Control Room and studio | 2/3 | **Sheet 2** | Sowerby, the letters, the safe, the tape | +| 6 | Lobby and Enquiries | 1 | **Sheet 1** | Mr Ogden; the crossing lands in the blast lock; the wardens' post and the armoury | +| 7 | Control Room and studio | 2/3 | **Sheet 2** | Sowerby's office, the studio safe, the tape | | 8 | Registry | 2 | **Sheet 3** | Pennyfeather and the Order, in the strongroom | | 9 | Sick bay | 2/3 | **Sheet 4** | Marlow's side room, Larkhall's office, the delivery room | | 10 | Crèche | 2/3 | **Sheet 5** | Kit, Nell, the drawings, the dormitory speaker | -| 11 | Pipe room | 2 | **Sheet 2** | Centre's in-tray | +| 11 | Pipe room | 2 | **Sheet 6** | Centre's in-tray | | 12 | Plant floor | 3 | **Sheet 6** | The transmitter room — the mast route | -| 13 | Vigil hall | 2/3 | **Sheet 6** | The chant; Thursday's assembly | -| 14 | The vegetable tunnels | 2 | **Sheet 7** | Lamps, beds, trout tanks, hens — the run route | +| 13 | Vigil hall | 2/3 | **Sheet 8** | The chant; Thursday's assembly, all 999 standing | +| 14 | The vegetable tunnels | 2 | **Sheet 7** | Beds, trout tanks, hens, the Buffer Depot — the run route | | 15 | The Sump | 2 | **Sheet 7** | Four cells; the detention ends here | -**Which sheet when:** Sheet 1 for Act One's arrival and interview; Sheets 7 and 1–3 for the -detention, wherever the guards catch them; Sheet 2 for getting the tape; Sheet 5 for the -cure; Sheet 6 for the broadcast. - ----|---|---|---| -| 1 | Wetherlaw farm | 1 | Coal soot, and Joan with a brush | -| 2 | The soot edge | 1 | A straight line of soot across the fields | -| 3 | The vent | 1 | Warm, smells of coal; the crossing | -| 4 | The postal pipe | 1/2 | How Centre's letters arrive | -| 5 | The adit | 1 | Filled with rubble in 1975 | -| 6 | Lobby and Enquiries | 1 | Mr Ogden | -| 7 | Control Room and studio | 2/3 | Sowerby, the letters, the safe, the tape | -| 8 | Registry | 2 | Pennyfeather and the Order | -| 9 | Sick bay | 2/3 | Marlow, Larkhall, Ruth | -| 10 | Crèche | 2/3 | Kit, Nell, the humming, the speaker | -| 11 | Pipe room | 2 | Centre's in-tray | -| 12 | Plant floor | 3 | The transmitter | -| 13 | Vigil hall | 2/3 | The chant; Thursday's assembly | -| 14 | The vegetable tunnels | 2 | Lamps, trout, hens | -| 15 | The Sump | 2 | The cells | +**Which sheet when:** Sheet 1 for Act One's arrival and interview. For the detention, whichever +sheet the guards catch them on, then Sheet 7. Sheet 2 for getting the tape, Sheet 5 for the +cure, and Sheets 8 and 6 for the broadcast: the assembly, and the transmitter. --- diff --git a/docs/scenarios/STANDING_ORDER_ART.md b/docs/scenarios/STANDING_ORDER_ART.md index 60ecc8c..ab83985 100644 --- a/docs/scenarios/STANDING_ORDER_ART.md +++ b/docs/scenarios/STANDING_ORDER_ART.md @@ -14,10 +14,11 @@ and the **quarantine unit** — are bestiary entries and their prompts live in the art; only the uses below changed. **Mr Smith must never be drawn** — a face is the one thing the case says nobody can recall — and no prompt for him belongs in this sheet. -**v1.1 added seven blueprint scenes** of the underground, `art/maps/bh-*.webp`. They are +**v1.1 added eight blueprint scenes** of the underground, `art/maps/bh-*.webp`. They are drawn, not generated, by `tools/bellhouse-plans.mjs` (white line on blueprint blue, Courier -lettering, pencil amendments in yellow); edit the script and run it with `--render`. No -prompt belongs here for them. +lettering, pencil amendments in yellow, north to the left as on the section). Edit the +script, run it with `--check` (doors on shared walls, swings clear, furniture inside its +room, every room reachable), then `--render`. No prompt belongs here for them. --- diff --git a/package.json b/package.json index 8b4a55f..a0217bf 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "play": "node tools/playthrough.mjs", "mj": "node tools/mj-queue.mjs", "simulate": "node tools/simulate.mjs", - "check": "bun tools/check-rules.mjs && bun tools/check-kits.mjs && bun tools/check-lang.mjs && bun tools/check-templates.mjs && bun tools/check-behaviour.mjs && bun tools/check-scenarios.mjs && bun tools/check-rollable.mjs && bun tools/check-outcomes.mjs && bun tools/check-creatures.mjs && bun tools/check-powers.mjs && bun tools/check-anatomy.mjs && bun tools/check-lethality.mjs && bun tools/check-focus.mjs && bun tools/check-firstblood.mjs && bun tools/check-attackers.mjs && bun tools/check-fight-tail.mjs && bun tools/check-packs.mjs && bun tools/detention-tables.mjs --check && bun tools/check-cited.mjs && bun tools/check-figures.mjs && bun tools/check-handouts.mjs && bun tools/check-bestiary.mjs", + "check": "bun tools/check-rules.mjs && bun tools/check-kits.mjs && bun tools/check-lang.mjs && bun tools/check-templates.mjs && bun tools/check-behaviour.mjs && bun tools/check-scenarios.mjs && bun tools/check-rollable.mjs && bun tools/check-outcomes.mjs && bun tools/check-creatures.mjs && bun tools/check-powers.mjs && bun tools/check-anatomy.mjs && bun tools/check-lethality.mjs && bun tools/check-focus.mjs && bun tools/check-firstblood.mjs && bun tools/check-attackers.mjs && bun tools/check-fight-tail.mjs && bun tools/check-packs.mjs && bun tools/detention-tables.mjs --check && bun tools/bellhouse-plans.mjs --check && bun tools/check-cited.mjs && bun tools/check-figures.mjs && bun tools/check-handouts.mjs && bun tools/check-bestiary.mjs", "test": "bun run check", "readme": "bun tools/update-readme.mjs" }, diff --git a/packs/standingorder/000003.log b/packs/standingorder/000003.log index 5bf1397..6e78594 100644 Binary files a/packs/standingorder/000003.log and b/packs/standingorder/000003.log differ diff --git a/tools/bellhouse-plans.mjs b/tools/bellhouse-plans.mjs index b161914..d8e3c5a 100644 --- a/tools/bellhouse-plans.mjs +++ b/tools/bellhouse-plans.mjs @@ -1,5 +1,5 @@ /** - * STANDING ORDER — the Bellhouse blueprints: seven floor plans of the Seat, one per + * STANDING ORDER — the Bellhouse blueprints: eight floor plans of the Seat, one per * Foundry scene. * * Drawn from declared rooms rather than generated, for culland-hall.svg's reason: a room, @@ -8,8 +8,21 @@ * drawn one. Labels are what a 1962 drawing office would have written, plus the pencil * amendments of fifty years below; nothing on a plan tells the players a GM secret. * + * The sheets follow the section drawing (SO-H04, bellhouse-section.svg): locations 6-9 on + * Level 1, 10-12 on Level 2, and 13-15 in the pit galleries the section does not draw. + * North is to the left on every sheet, as on the section (looking west): the lobby is the + * north end, the sick bay and the stair down the south. Every sheet names where its + * corridors lead, so the eight read as one building. + * * node tools/bellhouse-plans.mjs write art/maps/bh-*.svg * node tools/bellhouse-plans.mjs --render and render each to .webp (rsvg-convert, cwebp) + * node tools/bellhouse-plans.mjs --check hold every sheet to the rules below, write nothing + * + * WHAT --check HOLDS. Every door and archway sits on a wall two different spaces share (or + * on an outside wall it is declared to leave by). Every door swings into a space, clear of + * furniture and lettering. Every piece of furniture sits wholly inside one room. No two + * rooms overlap unless one is inside the other. Every room can be walked to from the + * sheet's way in. It does not judge whether a room is sensible; that is a person's job. */ import { writeFileSync } from "node:fs"; import { execFileSync } from "node:child_process"; @@ -17,29 +30,42 @@ import path from "node:path"; const ROOT = path.resolve(path.dirname(new URL(import.meta.url).pathname), ".."); const OUT = path.join(ROOT, "art", "maps"); -const S = 100, W = 28, H = 20; +const S = 100, W = 28, H = 20, SHEETS = 8; const esc = s => String(s).replace(/&/g, "&").replace(//g, ">"); const p = n => +(n * S).toFixed(1); /* ---------------------------------------------------------------- primitives */ +/* Approximate lettering widths, in squares per character, for the checker. */ +const CHAR = { lbl: 0.2, sub: 0.126, pen: 0.13, tb: 0.12 }; + function sheet() { const g = []; + const geo = { rooms: [], doors: [], items: [], labels: [], exits: [] }; + const item = (x, y, w, h, kind) => geo.items.push({ x, y, w, h, kind }); + const label = (x, y, t, cls, size) => { + const cw = CHAR[cls] ?? 0.12; + const k = size ? size / { lbl: 30, sub: 21, pen: 27, tb: 20 }[cls] : 1; + geo.labels.push({ x, y: y - 0.24 * k, w: t.length * cw * k, h: 0.3 * k, text: t, kind: cls }); + }; const api = { - g, - room(x, y, w, h, label, { sub, n, cls = "rm", lx = 0.3, ly = 0.75 } = {}) { + g, geo, + room(x, y, w, h, name, { sub, n, cls = "rm", lx = 0.3, ly = 0.75, entry = false } = {}) { g.push(``); - if (label) g.push(`${esc(label)}`); - if (sub) g.push(`${esc(sub)}`); + geo.rooms.push({ x, y, w, h, name: name ?? `(${x},${y})`, entry }); + if (name) { g.push(`${esc(name)}`); label(x + lx, y + ly, name, "lbl"); } + if (sub) { g.push(`${esc(sub)}`); label(x + lx, y + ly + 0.38, sub, "sub"); } if (n != null) { g.push(`` + `${n}`); + item(x + w - 0.75, y + 0.15, 0.6, 0.6, "number"); } }, /* A door on a wall: `v` for a vertical wall at x, else horizontal at y. A gap in the - wall and a quarter-circle swing, the way a drawing office draws one. */ - door(x, y, v, len = 1, flip = false) { + wall and a quarter-circle swing, the way a drawing office draws one. `flip` swings it + to the left of a vertical wall, or above a horizontal one. */ + door(x, y, v, len = 1, flip = false, { out = false } = {}) { const L = p(len), X = p(x), Y = p(y), d = flip ? -1 : 1; if (v) { g.push(``, @@ -48,73 +74,99 @@ function sheet() { g.push(``, ``); } + geo.doors.push({ x, y, v, len, d, out, swing: true }); }, /* An open archway: just the gap. */ arch(x, y, v, len = 2, cls = "gap") { const X = p(x), Y = p(y), L = p(len); g.push(v ? `` : ``); + geo.doors.push({ x, y, v, len, d: 0, out: false, swing: false }); }, - box(x, y, w, h, label, size = 20) { + box(x, y, w, h, text, size = 20) { g.push(``); - if (label) g.push(`${esc(label)}`); + if (text) g.push(`${esc(text)}`); + item(x, y, w, h, text || "box"); }, - chair(x, y) { g.push(``); }, + chair(x, y) { g.push(``); item(x, y, 0.34, 0.34, "chair"); }, bed(x, y, vert = true, w = 0.9, l = 2) { const [bw, bh] = vert ? [w, l] : [l, w]; g.push(``); g.push(vert ? `` : ``); + item(x, y, bw, bh, "bed"); }, - shelf(x, y, w, h) { + shelf(x, y, w, h, kind = "shelf") { g.push(``); const lines = []; - if (w >= h) for (let i = x + 0.25; i < x + w; i += 0.25) lines.push(`M${p(i)} ${p(y)}V${p(y + h)}`); - else for (let j = y + 0.25; j < y + h; j += 0.25) lines.push(`M${p(x)} ${p(j)}H${p(x + w)}`); + if (w >= h) for (let i = x + 0.25; i < x + w - 0.01; i += 0.25) lines.push(`M${p(i)} ${p(y)}V${p(y + h)}`); + else for (let j = y + 0.25; j < y + h - 0.01; j += 0.25) lines.push(`M${p(x)} ${p(j)}H${p(x + w)}`); g.push(``); + item(x, y, w, h, kind); }, - reels(x, y, label = "TAPE") { + reels(x, y, text = "TAPE") { g.push(``, ``, ``, - `${esc(label)}`); + `${esc(text)}`); + item(x, y, 2, 1.2, "reels"); }, safe(x, y) { g.push(``, ``, - `SAFE`); + `SAFE`); + item(x, y, 0.8, 1.15, "safe"); }, speaker(x, y) { g.push(``, ``); + item(x - 0.16, y - 0.26, 0.9, 0.52, "speaker"); }, - round(x, y, r, label) { + round(x, y, r, text) { g.push(``); - if (label) g.push(`${esc(label)}`); + if (text) g.push(`${esc(text)}`); + item(x - r, y - r, 2 * r, 2 * r, text || "round"); }, - stairs(x, y, w, h, label = "STAIR") { + peg(x, y) { g.push(``); item(x - 0.07, y - 0.07, 0.14, 0.14, "peg"); }, + /* A flight of stairs is a room of its own: you walk through it. */ + stairs(x, y, w, h, text, { vert = false, entry = false } = {}) { g.push(``); const d = []; - for (let j = y + 0.3; j < y + h; j += 0.3) d.push(`M${p(x)} ${p(j)}H${p(x + w)}`); - g.push(``, - `${esc(label)}`); + if (vert) for (let i = x + 0.3; i < x + w - 0.01; i += 0.3) d.push(`M${p(i)} ${p(y)}V${p(y + h)}`); + else for (let j = y + 0.3; j < y + h - 0.01; j += 0.3) d.push(`M${p(x)} ${p(j)}H${p(x + w)}`); + g.push(``); + const tw = text.length * 0.12 + 0.2; + g.push(``, + `${esc(text)}`); + geo.rooms.push({ x, y, w, h, name: text, entry, stairs: true }); }, blast(x, y, h) { g.push(``); const d = []; - for (let j = y; j < y + h; j += 0.2) d.push(`M${p(x) - 22} ${p(j) + 20}l44 -20`); + for (let j = y; j < y + h - 0.01; j += 0.2) d.push(`M${p(x) - 22} ${p(j) + 20}l44 -20`); g.push(``); + geo.doors.push({ x, y, v: true, len: h, d: 0, out: true, swing: false }); }, - /* The drawing office's own lettering, outside a room. */ - text(x, y, t, cls = "sub", extra = "") { - g.push(`${esc(t)}`); + /* The drawing office's own lettering. */ + text(x, y, t, cls = "sub") { + g.push(`${esc(t)}`); + label(x, y, t, cls); }, /* Pencil: fifty years of amendments in a different hand. */ pencil(x, y, t, rot = -2) { g.push(`${esc(t)}`); + label(x, y, t, "pen"); }, - arrow(x1, y1, x2, y2) { - g.push(``); + /* Where a corridor leaves the sheet: an arrow to the edge and the sheet it reaches. */ + exit(x, y, dir, t, { tx, ty } = {}) { + const [dx, dy] = { l: [-1, 0], r: [1, 0], u: [0, -1], d: [0, 1] }[dir]; + const x2 = dx < 0 ? 0.15 : dx > 0 ? W - 0.15 : x, y2 = dy < 0 ? 0.15 : dy > 0 ? H - 0.15 : y; + g.push(``); + const lx = tx ?? (dx > 0 ? x2 - t.length * CHAR.sub - 0.1 : dx < 0 ? 0.2 : x + 0.2); + const ly = ty ?? (dy === 0 ? y - 0.2 : dy < 0 ? 0.45 : H - 0.3); + g.push(`${esc(t)}`); + if (t) label(lx, ly, t, "sub"); + geo.exits.push({ x, y, text: t }); }, raw(s) { g.push(s); } }; @@ -126,6 +178,7 @@ const STYLE = ` .rm2 { fill:#11417d; stroke:#e8f1fb; stroke-width:5; } .rock { fill:#0e3668; stroke:#9fbde0; stroke-width:4; stroke-dasharray:18 10; } .gap { stroke:#154a8a; stroke-width:12; } + .gap2 { stroke:#11417d; stroke-width:12; } .rgap { stroke:#0e3668; stroke-width:12; } .swing { fill:none; stroke:#e8f1fb; stroke-width:3; } .fur { fill:#1b579c; stroke:#cfe0f3; stroke-width:3; } @@ -139,6 +192,7 @@ const STYLE = ` .lbl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:30px; fill:#f4f8fd; letter-spacing:2px; } .sub { font-family:'Courier New',Courier,monospace; font-size:21px; fill:#b9d0ea; } + .exit { font-weight:700; fill:#e8f1fb; } .fl { font-family:'Courier New',Courier,monospace; font-size:18px; fill:#e8f1fb; text-anchor:middle; } .ttl { font-family:'Courier New',Courier,monospace; font-weight:700; font-size:34px; @@ -148,31 +202,40 @@ const STYLE = ` fill:#ffe98a; } `; -function render(no, title, level, draw, { legend = [1, 15.6] } = {}) { +const TITLE_BLOCK = { x: 19, y: 16.5, w: 8.7, h: 3.3 }; +const LEGEND = { w: 6.4, h: 3.8 }; + +function build(plan) { const s = sheet(); - draw(s); + plan.draw(s); + const legend = plan.legend ?? [0.3, 16.1]; + return { s, legend }; +} + +function render(plan) { + const { s, legend } = build(plan); + const { no, title, level } = plan; const grid = []; for (let i = 1; i < W; i++) grid.push(`M${i * S} 0V${H * S}`); for (let j = 1; j < H; j++) grid.push(`M0 ${j * S}H${W * S}`); // Title block, bottom right, as a drawing office would box it. - const tb = [19, 16.5, 8.7, 3.3]; - const [tx, ty, tw, th] = tb.map(p); + const [tx, ty, tw, th] = [TITLE_BLOCK.x, TITLE_BLOCK.y, TITLE_BLOCK.w, TITLE_BLOCK.h].map(p); const block = ` REGIONAL SEAT OF GOVERNMENT 12 · BELLHOUSE - SHEET ${no} OF 7 · ${esc(level)} + SHEET ${no} OF ${SHEETS} · ${esc(level)} ${esc(title)} - SCALE: ONE SQUARE = 5 FT + SCALE: ONE SQUARE = 5 FT · SECTION: SO-H04 DRG RSG12/${String(no).padStart(2, "0")} · ISSUED 1962 · COPY NOT TO LEAVE THE SEAT`; // Legend, bottom left. const [lx, ly] = legend.map(p); const key = ` - + KEY @@ -184,7 +247,7 @@ function render(no, title, level, draw, { legend = [1, 15.6] } = {}) { = AMENDED AT THE SEAT, 1974–2026 = UNLINED MINE WORKINGS - 1 SQUARE = 5 FT · N ↑`; + 1 SQUARE = 5 FT · NORTH ←`; return ` @@ -205,186 +268,222 @@ function render(no, title, level, draw, { legend = [1, 15.6] } = {}) { /* ---------------------------------------------------------------- the sheets */ +const MAIN = "MAIN CORRIDOR", LOWER = "LOWER CORRIDOR"; + export const PLANS = [ +/* Level 1, the adit end. The crossing lands in the blast lock; the adit beyond the blast + door has been rubble since 1975. */ { key: "bh-lobby", no: 1, title: "LOBBY & ENQUIRIES", level: "LEVEL 1 · ENTRY", draw: s => { - s.text(0.3, 0.6, "FROM ADIT (SEALED 1975)"); - s.room(1, 6, 4, 6, "BLAST LOCK", { sub: "outer lock" }); + s.room(1, 6, 4, 6, "BLAST LOCK", { sub: "outer lock", entry: true }); s.blast(1, 8, 2); - s.raw(``); - s.pencil(1.6, 11.6, "air goes wrong here", -3); + s.raw(``); + s.pencil(1.5, 11.5, "air goes wrong here", -3); + s.text(0.2, 7.6, "ADIT"); s.room(5, 6, 4, 6, "DECONTAM.", { sub: "showers · lockers" }); - for (const y of [8, 9.3, 10.6]) s.round(6, y, 0.3); + for (const y of [8.4, 9.6, 10.8]) s.round(6.7, y, 0.3); s.shelf(7.9, 7.4, 0.8, 4.2); s.room(9, 3, 10, 12, "LOBBY", { n: 6, sub: "public waiting" }); - s.box(14.5, 5.2, 3.8, 0.8, "ENQUIRIES COUNTER"); - s.box(17.5, 6, 0.8, 2.4); - for (const x of [10, 11, 12]) for (const y of [9, 11, 13]) { s.chair(x, y); } - s.box(9.8, 8.4, 2.9, 0.4); s.box(9.8, 10.4, 2.9, 0.4); s.box(9.8, 12.4, 2.9, 0.4); - s.box(15, 14.4, 3.6, 0.35, "NOTICEBOARD", 14); - s.pencil(14.6, 13.9, "housing list — see Mr Ogden", -1); - s.room(19, 3, 5, 5, "ENQUIRIES", { sub: "Mr Ogden" }); - s.box(20, 4.6, 2, 1, "DESK"); s.chair(21, 5.8); s.shelf(23.1, 3.6, 0.7, 3.6); - s.round(20.3, 7.2, 0.25, "☎"); - s.room(19, 8, 5, 4, "INTERVIEW", { sub: "the door does not lock" }); - s.box(20.4, 9.8, 2.2, 1.1, "TABLE"); - s.chair(20.6, 9.3); s.chair(21.8, 9.3); s.chair(20.6, 11); s.chair(21.8, 11); - s.room(19, 12, 5, 3, "WARDENS' POST"); - s.shelf(19.4, 13.4, 2.5, 0.5); s.text(19.4, 14.6, "truncheon rack", "sub"); - s.room(12, 0, 3, 3, null, { cls: "rm2" }); s.text(12.2, 1.3, "MAIN", "lbl"); s.text(12.2, 1.9, "CORRIDOR", "sub"); - s.arrow(13.5, 2.6, 13.5, 0.3); - s.door(5, 8.5, true, 1); s.door(9, 8.5, true, 1); - s.door(19, 4.8, true, 1, true); s.door(19, 9.2, true, 1, true); s.door(19, 13, true, 1, true); - s.arch(12.5, 3, false, 2); - s.arrow(0.5, 0.9, 0.5, 5.5); + s.box(14.2, 5, 3.8, 0.8, "ENQUIRIES COUNTER"); + s.box(17.2, 5.8, 0.8, 2.4); + for (const y of [8.4, 10.4, 12.4]) { + s.box(10, y, 2.9, 0.4); + for (const x of [10.2, 11.2, 12.2]) s.chair(x, y + 0.55); + } + s.box(14, 14.4, 3.6, 0.35, "NOTICEBOARD", 14); + s.pencil(13.6, 13.9, "housing list — see Mr Ogden", -1); + s.room(19, 3, 4.5, 4.5, "ENQUIRIES", { sub: "Mr Ogden" }); + s.box(20.2, 4.9, 2, 1, "DESK"); s.chair(21, 6.1); s.shelf(22.7, 3.9, 0.6, 2.4); + s.round(22.9, 7, 0.25, "☎"); + s.room(19, 7.5, 4.5, 4, "INTERVIEW", { sub: "does not lock" }); + s.box(20.2, 9.3, 2.2, 1.1, "TABLE"); + s.chair(20.4, 8.85); s.chair(21.7, 8.85); s.chair(20.4, 10.5); s.chair(21.7, 10.5); + s.room(23.5, 3, 4, 4.5, "ARMOURY"); + s.shelf(23.8, 5, 3.4, 0.6); s.text(23.8, 6.1, "arms rack"); + s.pencil(23.8, 7.1, "key: Controller", -2); + s.room(23.5, 7.5, 4, 4, "WARDENS'", { sub: "post" }); + s.shelf(24, 10.2, 2.4, 0.5); s.text(24, 11.15, "truncheons"); + s.room(19, 11.5, 8.5, 3, MAIN, { cls: "rm2", ly: 1.9, lx: 0.4, entry: true }); + s.exit(27, 12.4, "r", "CONTROL, REGISTRY, SICK BAY · SHEETS 2–4 →", { tx: 19.2, ty: 15.05 }); + s.door(5, 8.6, true, 1); s.door(9, 8.6, true, 1); + s.door(19, 4.3, true, 1, true); s.door(19, 8.9, true, 1, true); + s.door(26.6, 7.5, false, 0.8, true); s.door(23.5, 8.5, true, 0.8, true); s.door(24.4, 11.5, false, 1); + s.arch(19, 12, true, 2, "gap2"); }}, -{ key: "bh-control", no: 2, title: "CONTROL ROOM", level: "LEVEL 2 · GOVERNMENT", draw: s => { - s.room(0.5, 1, 27, 2, "MAIN CORRIDOR", { cls: "rm2", ly: 1.25 }); - s.room(1, 4, 12, 9, "CONTROL ROOM", { n: 7, sub: "Controller's floor" }); - s.box(1.8, 5.5, 10.4, 0.9, "CONSOLE · DIALS · TANNOY DESK"); - for (let x = 2.5; x < 12; x += 1.4) s.chair(x, 6.6); - s.box(3.5, 8, 6, 2.6, "SITUATION MAP · REGION 12", 20); - for (const [x, y] of [[3.8, 7.4], [5.6, 7.4], [7.4, 7.4], [3.8, 10.8], [5.6, 10.8], [7.4, 10.8]]) s.chair(x, y); - s.round(11.4, 11.4, 0.55, "SCOPE"); - s.pencil(9.8, 12.6, "SEALED 1974 — by order", -2); +/* Level 1. Locations 7 and the Controller's floor. */ +{ key: "bh-control", no: 2, title: "CONTROL ROOM", level: "LEVEL 1 · GOVERNMENT", draw: s => { + s.room(0.5, 1, 27, 3, MAIN, { cls: "rm2", ly: 1.3, lx: 11, entry: true }); + s.exit(1, 3.4, "l", "← LOBBY · SHEET 1", { ty: 0.6 }); + s.exit(27, 3.4, "r", "REGISTRY · SHEET 3 →", { ty: 0.6 }); + s.room(1, 4, 13, 9, "CONTROL ROOM", { n: 7, sub: "Controller's floor" }); + s.box(1.6, 5.6, 11.8, 0.9, "CONSOLE · DIALS · TANNOY DESK"); + for (let x = 2.4; x < 13; x += 1.4) s.chair(x, 6.65); + s.box(3.5, 8.1, 6, 2.5, "SITUATION MAP · REGION 12", 20); + for (const x of [3.9, 6.3, 8.7]) { s.chair(x, 7.5); s.chair(x, 10.8); } + s.round(12.3, 11.5, 0.55, "SCOPE"); + s.pencil(9, 12.7, "SEALED 1974 — by order", -2); s.room(14, 4, 6, 5, "CONTROLLER", { sub: "E. Sowerby" }); - s.box(15.2, 5.8, 2.4, 1.1, "DESK"); s.chair(16.1, 7.1); - s.shelf(19.1, 4.6, 0.7, 3.8); s.text(17.4, 8.7, "letters from Centre", "sub"); + s.box(15.2, 5.8, 2.4, 1.1, "DESK"); s.chair(16.2, 7.1); + s.shelf(19.1, 4.3, 0.7, 3.6); s.text(17.3, 8.6, "files · Centre"); s.room(14, 9, 6, 6, "STUDIO", { sub: "broadcast · 1962" }); - s.reels(14.6, 10.6, "TAPE DECK"); - s.safe(18.6, 10.2); - s.box(15, 12.6, 2.6, 0.9, "MIXER"); s.chair(15.9, 13.7); - s.round(18.8, 13.6, 0.3, "MIC"); - s.pencil(14.3, 14.7, "new tape rec'd from Centre 2019", -1); - s.room(21, 4, 6, 5, "PIPE ROOM", { n: 11, sub: "Centre's in-tray" }); - s.round(24, 6.6, 0.55, "PIPE"); - s.box(21.5, 6.1, 1.8, 0.8, "IN-TRAY"); - s.pencil(21.4, 8.7, "every 90 days", -2); - s.room(21, 9, 6, 6, "COMMS", { sub: "teleprinters · switchboard" }); - s.box(21.6, 10.8, 1.3, 1, "TP"); s.box(23.2, 10.8, 1.3, 1, "TP"); - s.box(21.6, 12.6, 4.8, 0.9, "SWITCHBOARD"); s.chair(22.3, 13.8); s.chair(24.3, 13.8); - s.pencil(24.6, 10.6, "no line out", 4); - s.door(3, 4, false, 1, true); s.door(16, 4, false, 1, true); s.door(23, 4, false, 1, true); - s.door(14, 11, true, 1, true); s.door(14.8, 9, false, 1, true); s.door(23.5, 9, false, 1, true); + s.reels(15.6, 10.7, "TAPE DECK"); + s.safe(18.9, 9.25); + s.box(15.2, 12.6, 2.6, 0.9, "MIXER"); s.chair(16.3, 13.7); + s.round(19.2, 13.7, 0.3, "MIC"); + s.pencil(14.3, 14.75, "new tape rec'd from Centre 2019", -1); + s.room(20, 4, 7.5, 5, "SECRETARIAT", { sub: "minutes · rotas" }); + for (const x of [20.6, 22.8, 25]) { s.box(x, 6.1, 1.6, 0.8); s.chair(x + 0.6, 7.1); } + s.shelf(20.4, 8.2, 3, 0.55); + s.room(20, 9, 7.5, 6, "COMMS", { sub: "teleprinters · switchboard" }); + s.box(21, 10.9, 1.3, 1, "TP"); s.box(22.7, 10.9, 1.3, 1, "TP"); + s.box(20.6, 12.7, 5, 0.9, "SWITCHBOARD"); s.chair(21.6, 13.9); s.chair(23.6, 13.9); + s.pencil(24.4, 11.3, "no line out", 4); + s.door(2.2, 4, false, 1, true); s.door(14.8, 4, false, 1, true); s.door(25.8, 4, false, 1, true); + s.door(14, 11.6, true, 1, true); s.door(14.4, 9, false, 0.9, true); s.door(26.1, 9, false, 1, true); }}, -{ key: "bh-registry", no: 3, title: "REGISTRY", level: "LEVEL 2 · GOVERNMENT", draw: s => { - s.room(0.5, 1, 27, 2, "MAIN CORRIDOR", { cls: "rm2", ly: 1.25 }); +/* Level 1. Location 8. The public side of the counter is the corridor side. */ +{ key: "bh-registry", no: 3, title: "REGISTRY", level: "LEVEL 1 · GOVERNMENT", draw: s => { + s.room(0.5, 1, 27, 3, MAIN, { cls: "rm2", ly: 1.3, lx: 11, entry: true }); + s.exit(1, 3.4, "l", "← CONTROL ROOM · SHEET 2", { ty: 0.6 }); + s.exit(27, 3.4, "r", "SICK BAY · SHEET 4 →", { ty: 0.6 }); s.room(1, 4, 9, 7, "PUBLIC COUNTER", { n: 8 }); - s.box(1, 7.4, 6.5, 0.7, "COUNTER"); - for (const x of [2, 3.5, 5, 6.5]) s.chair(x, 5.6); - s.box(5.4, 4.3, 2, 0.45, "TAKE A NUMBER", 13); + s.box(1, 7.4, 7.4, 0.7, "COUNTER"); + s.text(8.5, 7.9, "flap"); + for (const x of [1.6, 3, 4.4]) s.chair(x, 5.9); + s.box(5.6, 5.9, 2, 0.45, "TAKE A NUMBER", 13); s.pencil(1.4, 10.6, "complaints: allow 11 weeks", -2); s.room(10, 4, 12, 11, "RECORDS"); for (let x = 11; x < 21.5; x += 1.5) s.shelf(x, 5.6, 0.6, 7.6); - s.text(10.4, 14.5, "BIRTHS · DEATHS · HOUSING · RATIONS · 1974–", "sub"); - s.room(22, 4, 5, 5, "REGISTRAR", { sub: "A. Pennyfeather" }); - s.box(23, 5.8, 2.2, 1, "DESK"); s.chair(23.8, 7.1); - s.room(22, 9, 5, 6, "STRONGROOM", { sub: "standing orders" }); - s.safe(25.6, 9.9); s.shelf(22.5, 11.2, 3.8, 0.7); s.shelf(22.5, 13.3, 3.8, 0.7); + s.text(10.4, 14.5, "BIRTHS · DEATHS · HOUSING · RATIONS · 1974–"); + s.room(22, 4, 5.5, 5, "REGISTRAR", { sub: "A. Pennyfeather" }); + s.box(23.2, 5.8, 2.2, 1, "DESK"); s.chair(24.1, 7.1); + s.room(22, 9, 5.5, 6, "STRONGROOM", { sub: "standing orders" }); + s.safe(26.3, 10.1); s.shelf(22.5, 11.4, 3.5, 0.7); s.shelf(22.5, 13.4, 3.5, 0.7); s.room(1, 11, 9, 4, "TYPING POOL"); - for (const x of [1.8, 4.3, 6.8]) { s.box(x, 12.3, 1.8, 0.8); s.chair(x + 0.7, 13.4); } - s.door(3.6, 4, false, 1, true); s.door(24, 4, false, 1, true); - s.door(10, 5.2, true, 1, true); s.door(22, 6, true, 1, true); s.door(24.8, 9, false, 0.9, true); - s.arch(8, 7.4, true, 0.7); - s.door(4, 11, false, 1); + for (const x of [1.4, 4.1, 6.8]) { s.box(x, 12.3, 1.8, 0.8); s.chair(x + 0.7, 13.4); } + s.door(3.2, 4, false, 1, true); s.door(24.2, 4, false, 1, true); + s.door(10, 9.3, true, 1, true); s.door(22, 8, true, 0.9, true); s.door(26.3, 9, false, 0.9, true); + s.door(6.2, 11, false, 1, true); }}, -{ key: "bh-sickbay", no: 4, title: "SICK BAY", level: "LEVEL 3 · WELFARE", draw: s => { - s.room(0.5, 1, 27, 2, "WELFARE CORRIDOR", { cls: "rm2", ly: 1.25 }); +/* Level 1, the far end. Location 9, and the stair down to Level 2. */ +{ key: "bh-sickbay", no: 4, title: "SICK BAY", level: "LEVEL 1 · WELFARE", draw: s => { + s.room(0.5, 1, 24, 3, MAIN, { cls: "rm2", ly: 1.3, lx: 11, entry: true }); + s.exit(1, 3.4, "l", "← REGISTRY · SHEET 3", { ty: 0.6 }); + s.stairs(24.5, 1, 3, 3, "DOWN"); + s.text(19.6, 0.6, "DOWN TO LEVEL 2 · SHEET 5"); + s.arch(24.5, 1.5, true, 2, "gap2"); s.room(1, 4, 6, 5, "RECEPTION", { n: 9 }); s.box(1.6, 5.7, 3, 0.7, "DESK"); - for (const x of [1.6, 2.6, 3.6, 4.6]) s.chair(x, 7.1); + for (const x of [1.6, 2.6, 3.6, 4.6]) s.chair(x, 7.2); s.room(7, 4, 12, 6, "GENERAL WARD", { sub: "eighteen beds" }); - for (let x = 7.5; x < 17; x += 1.1) { s.bed(x, 5.2); s.bed(x, 7.9, true, 0.9, 1.9); } + for (let x = 7.6; x < 17; x += 1.1) { s.bed(x, 5.3); s.bed(x, 7.9, true, 0.9, 1.9); } s.room(19, 4, 4, 3, "SIDE ROOM", { sub: "Mrs Marlow" }); - s.bed(21.8, 4.3, true, 0.9, 1.8); s.chair(21, 5.4); s.shelf(19.3, 6.2, 1.6, 0.5); - s.room(23, 4, 4, 3, "DISPENSARY"); - s.shelf(23.3, 5.5, 3.4, 0.6); - s.room(19, 7, 8, 3, "MEDICAL OFFICER", { sub: "Dr Larkhall" }); - s.box(23, 8.2, 2, 1, "DESK"); s.shelf(26.1, 7.3, 0.6, 2.4); s.chair(23.7, 9.3); + s.bed(21.9, 4.2, true, 0.9, 1.8); s.chair(20.9, 5.4); s.shelf(19.3, 6.3, 1.4, 0.5); + s.room(23, 4, 4.5, 3, "DISPENSARY"); + s.shelf(23.3, 5.1, 3.9, 0.55); + s.room(19, 7, 8.5, 3, "MEDICAL OFFICER", { sub: "Dr Larkhall" }); + s.box(23.2, 8.2, 2, 1, "DESK"); s.shelf(26.6, 7.3, 0.6, 2.4); s.chair(23.9, 9.3); s.room(7, 10, 7, 5, "DELIVERY", { sub: "maternity" }); s.bed(10, 11.8, false, 1, 2.2); s.round(12.9, 12.4, 0.35, "COT"); s.pencil(7.4, 14.6, "Cotter — due Thurs", -2); s.room(14, 10, 6, 5, "THEATRE"); - s.box(15.8, 11.6, 2.4, 1, "TABLE"); s.round(18.9, 11, 0.4); s.shelf(14.3, 14, 3, 0.6); + s.box(15.8, 11.6, 2.4, 1, "TABLE"); s.round(18.9, 11.2, 0.4); s.shelf(14.3, 14, 3, 0.6); s.room(1, 9, 6, 6, "ISOLATION"); s.room(1, 11, 3, 4, null); s.room(4, 11, 3, 4, null); - s.bed(1.8, 12.4); s.bed(4.8, 12.4); - s.pencil(1.3, 10.6, "unused since '78", -1); - s.door(3.5, 4, false, 1, true); s.door(24.5, 4, false, 1, true); + s.bed(1.8, 12.6); s.bed(4.8, 12.6); + s.pencil(4.4, 10.6, "unused since '78", -1); + s.door(3.5, 4, false, 1, true); s.door(23.4, 4, false, 0.9, true); s.door(7, 6, true, 1, true); s.door(19, 5, true, 1, true); s.door(19, 8.2, true, 1, true); s.door(10, 10, false, 1); s.door(16.2, 10, false, 1); s.door(3.2, 9, false, 1, true); s.door(2.5, 11, false, 0.8); s.door(5.2, 11, false, 0.8); - s.door(21.2, 7, false, 0.8, true); + s.door(21.2, 7, false, 0.8, true); s.door(25.8, 7, false, 0.8, true); }}, -{ key: "bh-creche", no: 5, title: "CRECHE & SCHOOL", level: "LEVEL 3 · WELFARE", draw: s => { - s.room(0.5, 1, 27, 2, "WELFARE CORRIDOR", { cls: "rm2", ly: 1.25 }); +/* Level 2. Location 10, directly below the sick bay. */ +{ key: "bh-creche", no: 5, title: "CRECHE & SCHOOL", level: "LEVEL 2 · WELFARE", draw: s => { + s.room(0.5, 1, 24, 3, LOWER, { cls: "rm2", ly: 1.3, lx: 9, entry: true }); + s.stairs(24.5, 1, 3, 3, "UP"); + s.text(20.6, 0.6, "UP TO LEVEL 1 · SHEET 4"); + s.arch(24.5, 1.5, true, 2, "gap2"); + s.exit(1, 3.4, "l", "← PIPE ROOM & PLANT · SHEET 6", { ty: 0.6 }); s.room(1, 4, 5, 4, "CLOAKS"); - for (let y = 5.3; y < 7.8; y += 0.5) s.raw(``); + for (let y = 5.3; y < 7.8; y += 0.5) s.peg(1.3, y); s.room(1, 8, 5, 5, "STAFF", { sub: "K. Marlow" }); s.bed(1.5, 10.2); s.box(3.4, 9.6, 1.8, 0.8, "DESK"); s.room(6, 4, 10, 7, "SCHOOLROOM", { n: 10 }); - s.box(7, 5.2, 5, 0.25, "", 12); s.text(7, 5.9, "BLACKBOARD", "sub"); + s.box(7, 5.2, 5, 0.25); s.text(7, 5.9, "BLACKBOARD"); s.box(12.8, 5.6, 2, 0.9, "TEACHER"); - for (let x = 7; x < 15; x += 2) for (let y = 6.9; y < 10; y += 1.2) { s.box(x, y, 1.3, 0.6); } + for (let x = 7; x < 15; x += 2) for (let y = 6.9; y < 10; y += 1.2) s.box(x, y, 1.3, 0.6); s.pencil(12.4, 10.7, "atlas: 1971 edition", -2); - s.room(16, 4, 11, 7, "PLAYROOM"); - s.raw(``); - s.text(16.3, 5.4, "pinned drawings along this wall", "sub"); + s.room(16, 4, 11.5, 7, "PLAYROOM"); + s.raw(``); + s.text(16.3, 5.4, "pinned drawings along this wall"); s.box(18, 6.6, 4, 2.6, "RUG", 20); for (const [x, y] of [[23.5, 7], [25.4, 6.4], [24.6, 8.8], [17.2, 9.9]]) s.round(x, y, 0.35); - s.box(25.3, 9.6, 1.4, 1.1, "TOYS", 16); + s.box(25.6, 9.6, 1.4, 1.1, "TOYS", 16); s.room(6, 11, 14, 5, "DORMITORY", { sub: "under-twelves" }); - for (let x = 6.6; x < 19.5; x += 0.95) { s.bed(x, 12.3, true, 0.7, 1.3); s.bed(x, 14.3, true, 0.7, 1.3); } - s.speaker(13, 11.35); - s.pencil(13.8, 11.95, "speaker fitted 2019 — 03:00 nightly", -1); - s.room(20, 11, 7, 5, "WASHROOM"); - for (let x = 21.8; x < 26.8; x += 1.2) s.round(x, 12.9, 0.3); - s.box(21, 14, 5, 0.8, "BATHS"); - s.door(3, 4, false, 1, true); s.door(6, 5, true, 1); s.door(16, 6.4, true, 1); - s.door(10.4, 11, false, 1); s.door(2.8, 8, false, 1); s.door(6, 11.6, true, 1, true); - s.door(20, 13, true, 1); -}, legend: [0.3, 16.1] }, + for (let x = 6.6; x < 19.5; x += 0.95) { s.bed(x, 12.4, true, 0.7, 1.3); s.bed(x, 14.4, true, 0.7, 1.3); } + s.speaker(13.2, 11.4); + s.pencil(14.2, 12.1, "speaker fitted 2019 — 03:00 nightly", -1); + s.room(20, 11, 7.5, 5, "WASHROOM"); + for (let x = 22; x < 27; x += 1.2) s.round(x, 12.9, 0.3); + s.box(21.4, 14.3, 5, 0.8, "BATHS"); + s.door(3.8, 4, false, 1, true); s.door(6, 5, true, 1); s.door(16, 6.4, true, 1); + s.door(9.6, 11, false, 1); s.door(4, 8, false, 1); s.door(6, 11.6, true, 1, true); + s.door(20, 12.6, true, 1); +}}, -{ key: "bh-vigil", no: 6, title: "VIGIL HALL & PLANT", level: "LEVEL 3 · ASSEMBLY", draw: s => { - s.room(1, 1, 14, 13, "VIGIL HALL", { n: 13, ly: 12.5 }); - s.box(3, 1.5, 10, 1.8, "PLATFORM", 22); - s.box(7.6, 3.4, 0.8, 0.5, "", 12); s.text(8.6, 3.9, "lectern", "sub"); - s.box(3.5, 1.1, 5, 0.3, "", 10); - s.text(9, 1.35, "ROLL OF HONOUR", "sub"); - for (let y = 4.8; y < 11.5; y += 0.8) for (let x = 2; x < 12.8; x += 0.55) { - if (x > 7.4 && x < 8.3) continue; - s.raw(``); - } - s.speaker(1.5, 4.5); s.speaker(1.5, 10); - s.pencil(9.6, 12.4, "999 seats — add one", -2); - s.room(15, 1, 2, 18, null, { cls: "rm2" }); - s.text(15.3, 17.4, "CORR.", "sub"); - s.room(17, 1, 10, 9, "PLANT FLOOR", { n: 12 }); - s.box(17.8, 2.4, 3.4, 2.6, "COAL BOILER"); - s.box(22, 2.4, 2.2, 2, "GEN 1"); s.box(24.6, 2.4, 2.2, 2, "GEN 2"); - s.box(17.8, 6.2, 8.6, 0.6, "DUCTING"); - s.box(17.8, 7.6, 2.4, 1.6, "PUMPS"); s.box(21, 7.6, 2.4, 1.6, "FILTERS"); - s.pencil(23.6, 8.8, "coal from No.2 road", -2); - s.room(17, 10, 10, 5.5, "TRANSMITTER", { sub: "feed to mast" }); - s.shelf(18, 11.8, 5, 0.9); s.text(18, 13.2, "valve racks", "sub"); - s.box(24, 11.6, 2.2, 1.4, "PANEL"); - s.raw(``); - s.text(24.3, 15.1, "MAST CABLE ↑ MOOR", "sub"); - s.door(15, 5.5, true, 1); s.door(15, 11, true, 1); - s.door(17, 4, true, 1, true); s.door(17, 12, true, 1, true); - s.arrow(16, 18.8, 16, 19.9); s.arrow(16, 1.2, 16, 0.1); -}, legend: [1, 15.6] }, +/* Level 2. Locations 11 and 12. The pneumatic pipe comes down from the moor into the pipe + room; the incline goes down to the pit galleries from the plant floor's coal side. */ +{ key: "bh-plant", no: 6, title: "PIPE ROOM & PLANT", level: "LEVEL 2 · SERVICES", draw: s => { + s.room(0.5, 1, 27, 3, LOWER, { cls: "rm2", ly: 1.3, lx: 11, entry: true }); + s.exit(27, 3.4, "r", "CRECHE · SHEET 5 →", { ty: 0.6 }); + s.room(1, 4, 7, 6, "PIPE ROOM", { n: 11, sub: "Centre's in-tray" }); + s.round(4.4, 6.9, 0.55, "PIPE"); + s.text(1.3, 8.2, "4\" pneumatic from moor ↑"); + s.box(5.8, 6.3, 1.6, 1.4, "IN-TRAY", 15); + s.shelf(1.4, 9.1, 4, 0.5); + s.pencil(4.4, 5.9, "every 90 days", -2); + s.room(1, 10, 7, 5, "STORES", { sub: "issue counter" }); + s.box(1.3, 11.9, 4.4, 0.6, "COUNTER"); + s.shelf(1.4, 13.6, 6.2, 0.6); s.shelf(6.8, 10.5, 0.7, 2.6); + s.room(8, 4, 19.5, 7, "PLANT FLOOR", { n: 12 }); + s.box(9, 5.6, 3.4, 2.6, "COAL BOILER"); + s.box(13.4, 5.6, 2.4, 2, "GEN 1"); s.box(16.4, 5.6, 2.4, 2, "GEN 2"); + s.box(19.6, 5.4, 6.8, 0.6, "DUCTING"); + s.box(20, 7.2, 2.4, 1.6, "PUMPS"); s.box(23.2, 7.2, 2.4, 1.6, "FILTERS"); + s.pencil(13.4, 9.3, "coal up from No.2 road", -2); + s.stairs(8, 11, 3, 4, "INCLINE", {}); + s.text(8.2, 15.6, "↓ PIT GALLERIES · SHEET 7"); + s.room(11, 11, 5, 4, "COAL HOPPER"); + s.box(11.8, 12.4, 3.4, 2, "HOPPER"); + s.room(16, 11, 11.5, 4.5, "TRANSMITTER", { sub: "feed to mast" }); + s.shelf(17, 12.9, 5, 0.9); s.text(17, 14.3, "valve racks"); + s.box(23.6, 12.3, 2.2, 1.4, "PANEL"); + s.raw(``); + s.text(22.3, 15.2, "MAST CABLE ↑ MOOR"); + s.door(3.4, 4, false, 1, true); s.door(10, 4, false, 1, true); s.door(21.5, 4, false, 1, true); + s.door(8, 8.6, true, 1, true); s.door(4.2, 10, false, 1); + s.arch(8.5, 11, false, 2); s.arch(11.5, 11, false, 3); + s.door(20.2, 11, false, 1); +}}, -{ key: "bh-sump", no: 7, title: "TUNNELS & SUMP", level: "LEVEL 4 · WORKINGS", draw: s => { - s.room(0.5, 1.5, 27, 3, "No.2 COAL ROAD", { cls: "rock", n: 14, sub: "growing beds under lamps" }); - for (let x = 6; x < 26; x += 2.4) s.shelf(x, 2.2, 2, 0.6); - for (let x = 6; x < 26; x += 2.4) s.shelf(x, 3.7, 2, 0.6); - s.pencil(20, 1.3, "workings beyond: not surveyed", -1); +/* Pit galleries. Location 14 and the Buffer Depot, and location 15. Unlined coal roads; + only the Sump and the depot were ever built out. */ +{ key: "bh-sump", no: 7, title: "COAL ROADS & SUMP", level: "PIT GALLERIES", draw: s => { + s.stairs(0.5, 1.5, 3, 3, "INCLINE", { entry: true }); + s.text(0.3, 1.2, "↑ PLANT FLOOR · SHEET 6"); + s.room(3.5, 1.5, 24, 3, "No.2 COAL ROAD", { cls: "rock", n: 14, sub: "growing beds under lamps", lx: 0.2 }); + s.arch(3.5, 2, true, 2, "rgap"); + for (let x = 8.8; x < 26; x += 2.2) { s.shelf(x, 1.8, 1.9, 0.55, "beds"); s.shelf(x, 3.65, 1.9, 0.55, "beds"); } + s.exit(27, 3, "r", "VIGIL HALL · SHEET 8 →", { ty: 1.2 }); s.room(9, 4.5, 2, 3, null, { cls: "rock" }); s.room(17, 4.5, 2, 3, null, { cls: "rock" }); + s.room(11, 4.5, 6, 3, "BUFFER DEPOT", { sub: "tins · blankets · oil" }); + s.shelf(11.4, 6.4, 5.2, 0.5); + s.pencil(1, 6.3, "workings west: not surveyed", -1); s.room(0.5, 7.5, 18.5, 3, "No.3 COAL ROAD", { cls: "rock", sub: "trout tanks" }); for (let x = 6; x < 16.5; x += 2.8) s.box(x, 8.1, 2.3, 1.8, "TANK", 16); s.room(19, 6.5, 8.5, 5, "HEN RUN", { cls: "rock" }); @@ -392,31 +491,158 @@ export const PLANS = [ s.pencil(20.3, 8.6, "eggs → Welfare, Tues/Fri", -2); s.stairs(13, 10.5, 3, 4, "SUMP STAIR"); s.room(1, 11.5, 12, 2, "THE SUMP", { n: 15, ly: 1.3 }); - for (const x of [1, 4, 7, 10]) s.room(x, 13.5, 3, 4.5, null); for (const [i, x] of [1, 4, 7, 10].entries()) { - s.text(x + 0.3, 14.1, `CELL ${i + 1}`, "sub"); - s.bed(x + 0.5, 15.3); + s.room(x, 13.5, 3, 4.5, `CELL ${i + 1}`, { lx: 0.2, ly: 0.9 }); + s.bed(x + 0.5, 15.4); s.door(x + 1.9, 13.5, false, 0.9); } - s.box(8.8, 11.9, 2, 0.8, "WARDEN"); - s.pencil(1.3, 18.6, "locks: 1962 pattern — oil them", -1); + s.box(8.8, 11.8, 2, 0.8, "WARDEN"); + s.pencil(1.3, 18.7, "locks: 1962 pattern — oil them", -1); s.arch(13.5, 10.5, false, 2, "rgap"); s.arch(13, 12, true, 1); s.arch(9, 4.5, false, 2, "rgap"); s.arch(9, 7.5, false, 2, "rgap"); s.arch(17, 4.5, false, 2, "rgap"); s.arch(17, 7.5, false, 2, "rgap"); - s.door(19, 8.5, true, 1); - s.arrow(1.3, 3, 0.1, 3); - s.text(0.6, 1.2, "← to Welfare stair", "sub"); -}, legend: [17.5, 12.1] } + s.door(11, 5.2, true, 1, true); s.door(19, 8.5, true, 1); +}, legend: [17.5, 12.1] }, + +/* Pit galleries. Location 13: a hall lined out of a worked seam, for the whole Seat. + 999 people standing need about 5,000 sq ft; this is 7,800. */ +{ key: "bh-vigil", no: 8, title: "VIGIL HALL", level: "PIT GALLERIES", draw: s => { + s.room(0.5, 7, 2, 4, null, { cls: "rock", entry: true }); + s.text(0.2, 6.6, "← SHEET 7"); + s.room(2.5, 1, 24.5, 14, "VIGIL HALL", { n: 13, ly: 13.6 }); + s.box(8, 1.4, 12, 1.9, "PLATFORM", 22); + s.box(9, 1.05, 10, 0.22); s.text(20.3, 1.45, "ROLL OF HONOUR"); + s.box(13.6, 3.5, 0.8, 0.5); s.text(14.6, 3.95, "lectern"); + for (let y = 5; y < 10.5; y += 0.8) for (let x = 4.5; x < 23.8; x += 0.55) { + if (x > 13.5 && x < 14.6) continue; + s.chair(x, y); + } + for (const y of [4.6, 11.4]) s.speaker(2.9, y); + for (const x of [18.5, 20.3, 22.1]) s.box(x, 12.2, 1.4, 1.4, "STACK", 14); + s.pencil(6, 12.4, "Thursday: chairs out — all 999 stand", -2); + s.text(15.6, 14.4, "standing room"); + s.door(2.5, 7.6, true, 1.8); + s.door(27, 7.5, true, 1, true, { out: true }); + s.text(23.2, 7.2, "fire exit → galleries"); +}} ]; -/* The legend on sheet 7 sits above the title block; the title block never moves. */ +/* ---------------------------------------------------------------- the check */ + +const EPS = 0.02; +const inside = (a, b, t = EPS) => a.x >= b.x - t && a.y >= b.y - t && a.x + a.w <= b.x + b.w + t && a.y + a.h <= b.y + b.h + t; +const overlap = (a, b, t = EPS) => a.x < b.x + b.w - t && b.x < a.x + a.w - t && a.y < b.y + b.h - t && b.y < a.y + a.h - t; +const holds = (r, x, y) => x > r.x && x < r.x + r.w && y > r.y && y < r.y + r.h; +const area = r => r.w * r.h; +const smallest = (rooms, x, y) => rooms.filter(r => holds(r, x, y)).sort((a, b) => area(a) - area(b))[0] ?? null; +const onEdge = (r, d) => d.v + ? (Math.abs(r.x - d.x) < EPS || Math.abs(r.x + r.w - d.x) < EPS) && d.y >= r.y - EPS && d.y + d.len <= r.y + r.h + EPS + : (Math.abs(r.y - d.y) < EPS || Math.abs(r.y + r.h - d.y) < EPS) && d.x >= r.x - EPS && d.x + d.len <= r.x + r.w + EPS; + +export function checkPlan(plan) { + const { s, legend } = build(plan); + const { rooms, doors, items, labels } = s.geo; + const out = []; + const where = d => `${d.swing ? "door" : "opening"} at (${d.x},${d.y})`; + const furniture = items.filter(i => i.kind !== "number"); + const reserved = [ + { ...TITLE_BLOCK, name: "title block" }, + { x: legend[0], y: legend[1], ...LEGEND, name: "key" } + ]; + + // Rooms: none crosses another; none sits on the key or title block. + for (let i = 0; i < rooms.length; i++) { + for (let j = i + 1; j < rooms.length; j++) { + const a = rooms[i], b = rooms[j]; + if (overlap(a, b) && !inside(a, b) && !inside(b, a)) out.push(`rooms ${a.name} and ${b.name} overlap`); + } + for (const z of reserved) if (overlap(rooms[i], z)) out.push(`room ${rooms[i].name} runs under the ${z.name}`); + } + + // Doors: on a shared wall, between two different spaces, swinging into one of them clear. + const edges = []; + for (const d of doors) { + const m = d.len / 2; + const [ax, ay, bx, by] = d.v ? [d.x - 0.05, d.y + m, d.x + 0.05, d.y + m] : [d.x + m, d.y - 0.05, d.x + m, d.y + 0.05]; + const A = smallest(rooms, ax, ay), B = smallest(rooms, bx, by); + if (d.out) { + if (!A === !B) out.push(`${where(d)} is marked as leaving the building but has space on ${A && B ? "both sides" : "neither side"}`); + if (!(A && onEdge(A, d)) && !(B && onEdge(B, d))) out.push(`${where(d)} is not on a wall`); + continue; + } + if (!A || !B) { out.push(`${where(d)} opens onto solid rock (${A?.name ?? "nothing"} | ${B?.name ?? "nothing"})`); continue; } + if (A === B) { out.push(`${where(d)} is not on a wall — ${A.name} on both sides`); continue; } + if (!onEdge(A, d) && !onEdge(B, d)) out.push(`${where(d)} between ${A.name} and ${B.name} is not on either room's wall`); + edges.push([A, B]); + if (!d.swing) continue; + const into = d.d < 0 ? A : B; + const sw = d.v ? { x: d.d < 0 ? d.x - d.len : d.x, y: d.y, w: d.len, h: d.len } + : { x: d.x, y: d.d < 0 ? d.y - d.len : d.y, w: d.len, h: d.len }; + if (!inside(sw, into)) out.push(`${where(d)} swings out of ${into.name}`); + for (const i of furniture) if (overlap(sw, i)) out.push(`${where(d)} swings into ${i.kind} at (${i.x},${i.y}) in ${into.name}`); + for (const l of labels) if (overlap(sw, l)) out.push(`${where(d)} swings across the lettering "${l.text}"`); + for (const e of doors) if (e !== d && e.swing) { + const sw2 = e.v ? { x: e.d < 0 ? e.x - e.len : e.x, y: e.y, w: e.len, h: e.len } : { x: e.x, y: e.d < 0 ? e.y - e.len : e.y, w: e.len, h: e.len }; + if (overlap(sw, sw2, 0.05) && (d.x < e.x || (d.x === e.x && d.y < e.y))) out.push(`${where(d)} and the door at (${e.x},${e.y}) swing into each other`); + } + } + + // Furniture: wholly in one room, clear of other furniture and of lettering. + for (const i of items) { + const r = smallest(rooms, i.x + i.w / 2, i.y + i.h / 2); + if (!r) { out.push(`${i.kind} at (${i.x},${i.y}) is outside every room`); continue; } + if (!inside(i, r)) out.push(`${i.kind} at (${i.x},${i.y}) crosses the wall of ${r.name}`); + const inner = rooms.find(q => q !== r && inside(q, r) && overlap(i, q)); + if (inner) out.push(`${i.kind} at (${i.x},${i.y}) in ${r.name} overlaps the room ${inner.name}`); + } + for (let a = 0; a < items.length; a++) for (let b = a + 1; b < items.length; b++) { + const i = items[a], j = items[b]; + if (overlap(i, j)) out.push(`${i.kind} at (${i.x},${i.y}) overlaps ${j.kind} at (${j.x},${j.y})`); + } + for (const l of labels) { + for (const i of furniture) if (overlap(l, i, 0.05)) out.push(`the lettering "${l.text}" runs over ${i.kind} at (${i.x},${i.y})`); + for (const z of reserved) if (overlap(l, z)) out.push(`the lettering "${l.text}" runs under the ${z.name}`); + if (l.x + l.w > W || l.x < 0) out.push(`the lettering "${l.text}" runs off the sheet`); + if (!smallest(rooms, l.x + 0.05, l.y + l.h / 2)) { + for (const q of rooms) if (overlap(l, q)) out.push(`the lettering "${l.text}" starts outside and runs into ${q.name}`); + } + const r = smallest(rooms, l.x + 0.05, l.y + l.h / 2); + if (r && l.kind !== "pen" && l.x + l.w > r.x + r.w + EPS) out.push(`the lettering "${l.text}" runs out of ${r.name}`); + } + + // Every room is reachable from the way in. + const start = rooms.filter(r => r.entry); + if (!start.length) out.push("the sheet has no way in"); + const seen = new Set(start); + const parent = r => rooms.filter(q => q !== r && inside(r, q)).sort((a, b) => area(a) - area(b))[0]; + let grew = true; + while (grew) { + grew = false; + for (const [a, b] of edges) { + if (seen.has(a) !== seen.has(b)) { seen.add(a); seen.add(b); grew = true; } + } + } + for (const r of rooms) if (!seen.has(r)) out.push(`${r.name} cannot be reached from the way in`); + return [...new Set(out)]; +} if (import.meta.url === `file://${process.argv[1]}`) { - const doRender = process.argv.includes("--render"); + const argv = process.argv.slice(2); + if (argv.includes("--check")) { + let bad = 0; + for (const pl of PLANS) { + const problems = checkPlan(pl); + bad += problems.length; + console.log(` sheet ${pl.no} ${pl.key}: ${problems.length ? problems.length + " problem(s)" : "OK"}`); + problems.forEach(x => console.log(` - ${x}`)); + } + if (PLANS.length !== SHEETS) { console.log(` ${PLANS.length} sheets drawn, ${SHEETS} numbered`); bad++; } + process.exit(bad ? 1 : 0); + } + const doRender = argv.includes("--render"); for (const pl of PLANS) { - const svg = render(pl.no, pl.title, pl.level, pl.draw, pl.legend ? { legend: pl.legend } : {}); const svgPath = path.join(OUT, `${pl.key}.svg`); - writeFileSync(svgPath, svg); + writeFileSync(svgPath, render(pl)); if (doRender) { const png = path.join(OUT, `${pl.key}.png`); execFileSync("rsvg-convert", ["-w", "2800", "-h", "2000", svgPath, "-o", png]); diff --git a/tools/scenario-standingorder.mjs b/tools/scenario-standingorder.mjs index 71fe86f..ed69bcc 100644 --- a/tools/scenario-standingorder.mjs +++ b/tools/scenario-standingorder.mjs @@ -170,16 +170,17 @@ export const SO_PLATES = [ { name: "9 · Bellhouse — section", src: "art/maps/bellhouse-section.webp" } ]; -/* The underground as seven blueprint scenes, drawn by tools/bellhouse-plans.mjs. Numbers +/* The underground as eight blueprint scenes, drawn by tools/bellhouse-plans.mjs. Numbers are the Locations table's. 2800x2000 at 100px to the square, like Culland Hall. */ export const SO_SCENES = [ - { key: "bh_lobby", name: "Bellhouse 1 · Lobby and Enquiries (6)", nav: "Lobby", src: "art/maps/bh-lobby.webp" }, - { key: "bh_control", name: "Bellhouse 2 · Control Room and Pipe Room (7, 11)", nav: "Control", src: "art/maps/bh-control.webp" }, - { key: "bh_registry", name: "Bellhouse 3 · Registry (8)", nav: "Registry", src: "art/maps/bh-registry.webp" }, - { key: "bh_sickbay", name: "Bellhouse 4 · Sick Bay (9)", nav: "Sick Bay", src: "art/maps/bh-sickbay.webp" }, - { key: "bh_creche", name: "Bellhouse 5 · Creche and School (10)", nav: "Creche", src: "art/maps/bh-creche.webp" }, - { key: "bh_vigil", name: "Bellhouse 6 · Vigil Hall and Plant Floor (12, 13)", nav: "Vigil Hall", src: "art/maps/bh-vigil.webp" }, - { key: "bh_sump", name: "Bellhouse 7 · Coal Roads and the Sump (14, 15)", nav: "Sump", src: "art/maps/bh-sump.webp" } + { key: "bh_lobby", name: "Bellhouse 1 · Lobby and Enquiries (6)", nav: "Lobby", src: "art/maps/bh-lobby.webp" }, + { key: "bh_control", name: "Bellhouse 2 · Control Room and Studio (7)", nav: "Control", src: "art/maps/bh-control.webp" }, + { key: "bh_registry", name: "Bellhouse 3 · Registry (8)", nav: "Registry", src: "art/maps/bh-registry.webp" }, + { key: "bh_sickbay", name: "Bellhouse 4 · Sick Bay (9)", nav: "Sick Bay", src: "art/maps/bh-sickbay.webp" }, + { key: "bh_creche", name: "Bellhouse 5 · Creche and School (10)", nav: "Creche", src: "art/maps/bh-creche.webp" }, + { key: "bh_plant", name: "Bellhouse 6 · Pipe Room and Plant Floor (11, 12)", nav: "Plant", src: "art/maps/bh-plant.webp" }, + { key: "bh_sump", name: "Bellhouse 7 · Coal Roads and the Sump (14, 15)", nav: "Sump", src: "art/maps/bh-sump.webp" }, + { key: "bh_vigil", name: "Bellhouse 8 · Vigil Hall (13)", nav: "Vigil Hall", src: "art/maps/bh-vigil.webp" } ]; /* The detention detail. Truncheons, not firearms: the Seat's armoury is locked and the