diff options
Diffstat (limited to 'src/town/words.rs')
| -rw-r--r-- | src/town/words.rs | 633 |
1 files changed, 633 insertions, 0 deletions
diff --git a/src/town/words.rs b/src/town/words.rs new file mode 100644 index 0000000..251f2b2 --- /dev/null +++ b/src/town/words.rs @@ -0,0 +1,633 @@ +//! What things in a city are called, and what people there say. +//! +//! Names use the same templates as `names`: `{w}` is a new word in the +//! culture's tongue, `{n}` a number, `{r}` a Roman numeral. + +use super::{Kind, Land, Pond, Purpose, QuarterKind, Role, ShopKind, Thing, Tile}; +use crate::names::{Culture, pick}; +use crate::seed::Rng; +use crate::space::system::Terrain; + +fn fill(culture: Culture, templates: &'static [&'static str], rng: &mut Rng) -> String { + culture.expand(pick(templates, rng), rng) +} + +pub fn quarter_name(culture: Culture, kind: QuarterKind, rng: &mut Rng) -> String { + use QuarterKind::*; + let templates: &'static [&'static str] = match (culture, kind) { + (Culture::Qaari, Market) => &["the {w} Souk", "the Great Souk", "the Spice Souk"], + (Culture::Qaari, Gate) => &["the Caravan Yards", "the {w} Caravanserai", "the Gate of {w}"], + (Culture::Qaari, Homes) => &["the {w} Quarter", "the Lanes of {w}", "the Old Wells"], + (Culture::Qaari, Poor) => &["the Lower Wells", "the Dust Quarter", "the {w} Warren"], + (Culture::Qaari, Grand) => &["the Rise of {w}", "the Shaded Heights", "the Palace Rise"], + (Culture::Qaari, Holy) => { + &["the Shrine Steps", "the Deep Well Quarter", "the {w} Sanctuary"] + } + (Culture::Qaari, Works) => { + &["the Dyers' Lanes", "the Glassblowers' Quarter", "the Tanneries"] + } + (Culture::Qaari, Gardens) => &["the Palm Gardens", "the {w} Oasis", "the Date Groves"], + (Culture::Cant, Market) => &["the Exchange Floor", "Barter Deck {n}", "the {w} Market"], + (Culture::Cant, Gate) => &["the Intake", "Gate Sector {n}", "the Receiving Yards"], + (Culture::Cant, Homes) => &["Hab Sector {n}", "the {w} Habs", "Dormitory Row {r}"], + (Culture::Cant, Poor) => &["the Undercroft", "the Sump", "Sector {n}-Low"], + (Culture::Cant, Grand) => &["the Primarch's Tier", "the Upper Spire", "the {w} Tier"], + (Culture::Cant, Holy) => &["the Litany Steps", "the Engine Precinct", "the Fane Sector"], + (Culture::Cant, Works) => &["the Foundry Ward", "Pipe Row", "the {w} Works"], + (Culture::Cant, Gardens) => { + &["the Coolant Pools", "the Fungus Vaults", "the Moss Terraces"] + } + (Culture::Houses, Market) => &["the {w} Market", "the Marble Exchange", "the Silk Arcade"], + (Culture::Houses, Gate) => { + &["the Gate of {w}", "the Customs Quarter", "the Carriage Yards"] + } + (Culture::Houses, Homes) => &["the {w} Quarter", "Lantern Row", "the {w} Walk"], + (Culture::Houses, Poor) => &["the Stews", "Tallow Lane", "the {w} Rookery"], + (Culture::Houses, Grand) => &["the Archon's Hill", "the {w} Heights", "the Court Quarter"], + (Culture::Houses, Holy) => { + &["the Cathedral Close", "the {w} Cloisters", "the Choir Quarter"] + } + (Culture::Houses, Works) => &["the Perfumers' Quarter", "the Ateliers", "Glass Street"], + (Culture::Houses, Gardens) => &["the {w} Gardens", "the Pleasure Gardens", "the Orangery"], + (Culture::Drift, Market) => &["the Swap", "the {w} Bazaar", "the Hanging Market"], + (Culture::Drift, Gate) => &["the Moorings", "the {w} Berths", "the Dockside"], + (Culture::Drift, Homes) => &["the Bunks", "{w} Row", "the Hull Quarter"], + (Culture::Drift, Poor) => &["the Scrap", "the Leaky End", "the {w} Tangle"], + (Culture::Drift, Grand) => &["Captains' Row", "the High Masts", "the {w} Deck"], + (Culture::Drift, Holy) => &["the Lantern Quarter", "the Rememberings", "the {w} Vigil"], + (Culture::Drift, Works) => &["the Splice", "the Sail Lofts", "the {w} Yards"], + (Culture::Drift, Gardens) => { + &["the Green Tanks", "the {w} Hydroponics", "the Garden Hulls"] + } + }; + fill(culture, templates, rng) +} + +/// Who works in a workshop. +fn trades(culture: Culture) -> &'static [&'static str] { + match culture { + Culture::Qaari => &["weaver", "potter", "glassblower", "dyer", "coppersmith", "rugmaker"], + Culture::Cant => &["welder", "wire-drawer", "gear-cutter", "plater", "cogwright"], + Culture::Houses => &["perfumer", "jeweller", "tailor", "luthier", "mask-maker", "glazier"], + Culture::Drift => &["sailmaker", "splicer", "tinker", "chartmaker", "ropemaker"], + } +} + +/// What a building is called: "a house", "House Vastre", "the Qasr Khaseem". +pub fn building_name(kind: Kind, culture: Culture, rng: &mut Rng) -> String { + use Culture::*; + let templates: &'static [&'static str] = match (kind, culture) { + (Kind::Shop(shop), _) => return shop_name(shop, culture, rng), + (Kind::House, _) => &["a house"], + (Kind::Tenement, Qaari) => &["a courtyard tenement"], + (Kind::Tenement, Cant) => &["a hab-block"], + (Kind::Tenement, Houses) => &["a lodging house"], + (Kind::Tenement, Drift) => &["a bunkhouse"], + (Kind::Manor, Qaari) => &["the House of {w}", "the {w} Mansion"], + (Kind::Manor, Cant) => &["the {w} Habitation", "Residence {w}-{n}"], + (Kind::Manor, Houses) => &["House {w}", "the {w} Townhouse"], + (Kind::Manor, Drift) => &["the {w} Berth", "Captain {w}'s"], + (Kind::Palace, Qaari) => &["the Qasr {w}"], + (Kind::Palace, Cant) => &["the Primarch's Spire"], + (Kind::Palace, Houses) => &["the Archon's Palace"], + (Kind::Palace, Drift) => &["the Speaker's Hulk"], + (Kind::Temple, Qaari) => &["the Deep Well of {w}"], + (Kind::Temple, Cant) => &["the Fane of the Engine"], + (Kind::Temple, Houses) => &["the Basilica of {w}"], + (Kind::Temple, Drift) => &["the Lantern of the Lost"], + (Kind::Shrine, Qaari) => &["a well-shrine"], + (Kind::Shrine, Cant) => &["a litany-chapel"], + (Kind::Shrine, Houses) => &["a chapel"], + (Kind::Shrine, Drift) => &["a waystone shrine"], + (Kind::Workshop, _) => { + let trade = pick(trades(culture), rng); + return format!("a {trade}'s workshop"); + } + (Kind::Warehouse, Qaari) => &["a caravan store"], + (Kind::Warehouse, Cant) => &["a depot"], + (Kind::Warehouse, Houses) => &["a warehouse"], + (Kind::Warehouse, Drift) => &["a cargo shed"], + (Kind::Bathhouse, Qaari) => &["the {w} Baths", "a bathhouse"], + (Kind::Bathhouse, _) => &["the {w} Baths", "a bathhouse"], + (Kind::Guardhouse, Qaari) => &["a gatehouse"], + (Kind::Guardhouse, Cant) => &["an enforcer post"], + (Kind::Guardhouse, Houses) => &["a guardhouse"], + (Kind::Guardhouse, Drift) => &["the watch-house"], + }; + fill(culture, templates, rng) +} + +pub fn shop_name(kind: ShopKind, culture: Culture, rng: &mut Rng) -> String { + use Culture::*; + use ShopKind::*; + let templates: &'static [&'static str] = match (kind, culture) { + (Broker, Qaari) => &["the {w} Assay", "the Ore Souk of {w}"], + (Broker, Cant) => &["the Ore-Tithe of {w}", "Assay Station {n}"], + (Broker, Houses) => &["the {w} Exchange", "the Royal Assayer"], + (Broker, Drift) => &["{w}'s Scales", "the Weigh-In"], + (Doctor, Qaari) => &["the House of Salves", "the {w} Infirmary"], + (Doctor, Cant) => &["the Mending Shrine", "Repair Bay {n}"], + (Doctor, Houses) => &["Physician {w}'s", "the {w} Hospice"], + (Doctor, Drift) => &["the Patchwright", "the Sick Bay"], + (Scholar, Qaari) => &["the Sand Archive", "the House of {w}'s Scrolls"], + (Scholar, Cant) => &["the Index of Relics", "Archive {r}"], + (Scholar, Houses) => &["the {w} Athenaeum", "the {w} Collection"], + (Scholar, Drift) => &["the Rememberer", "the Log-Keeper"], + (Tavern, Qaari) => &["the {w} Cistern", "the Thirsty Dune", "the {w} Tea House"], + (Tavern, Cant) => &["the Oil Hall", "the Burnt Gasket", "Refreshment Unit {n}"], + (Tavern, Houses) => &["the {w} Salon", "the Gilded {w}", "the Masquerade"], + (Tavern, Drift) => &["the Slack Line", "the {w} Mooring", "the Last Burn"], + (Shipyard, Qaari) => &["the Caravan-Wrights", "the {w} Yards"], + (Shipyard, Cant) => &["Hull Foundry {w}", "Drydock {n}"], + (Shipyard, Houses) => &["the Royal Yards", "the {w} Shipwrights"], + (Shipyard, Drift) => &["the Splicers", "{w}'s Slip"], + (Armoury, Qaari) => &["the {w} Blade-Souk", "the House of Edges"], + (Armoury, Cant) => &["Armoury {r}", "the Arc-Smithy of {w}"], + (Armoury, Houses) => &["the {w} Armourers", "the Duellists' Gallery"], + (Armoury, Drift) => &["{w}'s Iron", "the Gun Locker"], + }; + fill(culture, templates, rng) +} + +/// What a ruler is called. +pub fn ruler_title(culture: Culture) -> &'static str { + match culture { + Culture::Qaari => "the Well-Warden", + Culture::Cant => "the Primarch", + Culture::Houses => "the Archon", + Culture::Drift => "the Speaker", + } +} + +/// "A guard", for people without a name. +pub fn role_name(role: Role, culture: Culture) -> &'static str { + match role { + Role::Passerby => "A passer-by", + Role::Child => "A child", + Role::Porter => "A porter", + Role::Pilgrim => "A pilgrim", + Role::Stallholder => "A stallholder", + Role::Guard => match culture { + Culture::Cant => "An enforcer", + _ => "A guard", + }, + Role::Keeper(_) => "The keeper", + Role::Resident => "Someone who lives here", + Role::Servant => "A servant", + Role::Ruler => ruler_title(culture), + Role::Courtier => "A courtier", + Role::Priest => match culture { + Culture::Qaari => "A well-priest", + Culture::Cant => "A tech-cantor", + Culture::Houses => "A priest", + Culture::Drift => "A lamplighter", + }, + Role::Worshipper => "A worshipper", + Role::Worker => "A worker", + Role::Patron => "A drinker", + Role::Patient => "A patient", + Role::Bather => "A bather", + Role::Watchman => "A watchman", + Role::Reader => "A reader", + } +} + +/// What someone says when you bump into them. +pub fn lines(role: Role, culture: Culture) -> &'static [&'static str] { + use Culture::*; + match (role, culture) { + (Role::Passerby, _) => chatter(culture), + (Role::Stallholder, _) => cries(culture), + (Role::Child, Qaari) => &[ + "Is that your ship? Is it faster than a sandstorm?", + "I can hold my breath through a whole dust-wind.", + "My brother says wrecks have ghosts in them.", + ], + (Role::Child, Cant) => &[ + "I am in my apprentice cycle. I'm not supposed to talk to you.", + "Do your engines pray? Ours do.", + "I counted all the bolts on the wall. There are four thousand and six.", + ], + (Role::Child, Houses) => &[ + "Mother says spacers are common. Are you common?", + "I'm going to be an Archon when I grow up. Or a pirate.", + "Bet you can't catch me!", + ], + (Role::Child, Drift) => &[ + "Have you been to the stars? Which one's the best?", + "I was born on a ship, you know. I'm only visiting.", + "Tag! You're it!", + ], + (Role::Porter, _) => &[ + "Mind your back! Heavy load!", + "Two more crates and I can eat.", + "Out of the way, it's on my head, not yours.", + "They pay by the load, not by the step. Shift.", + ], + (Role::Pilgrim, _) => &[ + "I've walked forty days to get here.", + "They say a prayer here is heard twice.", + "Have you come to pray too? You don't look it.", + "I promised my mother I'd come. She's been dead nine years.", + ], + (Role::Guard, Qaari) => &[ + "Keep your hands where the sun can see them.", + "No blades drawn in the souk, offworlder.", + "The gate shuts when the third wind blows. Be in, or be out.", + ], + (Role::Guard, Cant) => &[ + "Halt. Proceed. You were not stopped.", + "Unit. Your papers are in order. Probably.", + "Patrol cycle four hundred and twelve. All nominal.", + ], + (Role::Guard, Houses) => &[ + "Move along, spacer. Nothing to see but your betters.", + "The Archon's peace is kept here.", + "Draw steel in this city and you'll leave it lighter.", + ], + (Role::Guard, Drift) => &[ + "Easy, spacer. Nobody's looking for trouble.", + "Watch shift. Twelve hours of nothing, mostly.", + "If anyone asks, I was awake.", + ], + (Role::Keeper(_), _) => &["What can I do for you?"], + (Role::Resident, Qaari) => &[ + "You'll take water? Everyone who comes in takes water.", + "My grandmother built this house with her own hands.", + "Shut the door behind you, the sand gets in.", + "A guest! Sit, sit. Not there. There.", + ], + (Role::Resident, Cant) => &[ + "Unauthorised presence in a hab-unit. I'll allow it.", + "The walls hum at night. It's comforting.", + "Visitors are logged. You have been logged.", + "My shift starts in an hour. Be brief.", + ], + (Role::Resident, Houses) => &[ + "We weren't expecting callers. Do forgive the state of things.", + "Mind the portraits. Every one of them is watching you.", + "If you're selling something, we already have two.", + "Oh! A spacer. How thrilling. Please don't touch anything.", + ], + (Role::Resident, Drift) => &[ + "Come in, come in. Nobody locks a door in the Drift.", + "It's small, but it doesn't move. I'm still getting used to that.", + "Got any news from out there?", + "Sit anywhere. Everything's somebody's, nothing's anyone's.", + ], + (Role::Servant, _) => &[ + "The household is not receiving.", + "I'm to polish the silver before the bell.", + "You didn't see me sitting down.", + "Wipe your feet. Please. I just did that floor.", + ], + (Role::Ruler, Qaari) => &[ + "Every drop in this city is counted, offworlder, and I count them.", + "Sit in my shade. Few strangers are offered it.", + "The deep erg gives and the deep erg takes. I only keep the ledger.", + ], + (Role::Ruler, Cant) => &[ + "The Engine wills, and I implement. State your function.", + "You are a variable. I dislike variables.", + "Efficiency is devotion. You are wasting both.", + ], + (Role::Ruler, Houses) => &[ + "We so rarely receive spacers. How novel.", + "Kneel, if you know how. No? Then bow. No? Then stand there.", + "My ancestors held this city for eleven hundred years. I intend to beat that.", + ], + (Role::Ruler, Drift) => &[ + "I don't rule. Someone has to hold the tiller, that's all.", + "The council meets when it meets. Sit, if you like.", + "Every ship that docks here is family until it isn't.", + ], + (Role::Courtier, _) => &[ + "Petitions are heard at noon. It is never noon.", + "I've been waiting for an audience since the last eclipse.", + "Don't stand there. That's where the last ambassador stood.", + "Have you heard who dined with whom? No? Then what use are you?", + ], + (Role::Priest, Qaari) => &[ + "The deep well answers every question with silence. Silence is an answer.", + "Drink, and remember who dug the well before you.", + "Water remembers. That is why we pray over it.", + ], + (Role::Priest, Cant) => &[ + "Blessed be the torque. Blessed be the tolerance.", + "Every machine is a prayer that works.", + "The Engine turns. Will you turn with it?", + ], + (Role::Priest, Houses) => &[ + "The saints loved this city once. We are trying to remind them.", + "Light a candle, if you have a coin. Light two, if you have a sin.", + "Even the Archon kneels here. Briefly.", + ], + (Role::Priest, Drift) => &[ + "Every lantern here is someone who didn't come home.", + "We remember the lost so the void doesn't have to.", + "If you board wrecks, light one for whoever you find.", + ], + (Role::Worshipper, _) => &[ + "Shh.", + "...and keep the void from the hull, and the hull from the void...", + "I'm praying. Go away. Kindly.", + "Pray with us, or step softly.", + ], + (Role::Worker, _) => &[ + "Mind the edge, it's sharp.", + "Commissions take a month. Two if you're rude.", + "Every piece made by hand. My hands. Look at them.", + "Pass me that. No, the other one.", + ], + (Role::Patron, _) => &[ + "Buy a round and I'll tell you a story. Two rounds, a true one.", + "This is my stool. It knows me.", + "The wrecks out past the belt? Cursed, the lot of them.", + "One more and I'll go home. I said that last night too.", + "You've got the look of someone who boards wrecks.", + ], + (Role::Patient, _) => &[ + "Don't mind me. I'm dying, slightly.", + "The doctor says I'll mend. The doctor says that to everyone.", + "Got bitten by something aboard a wreck. Don't ask what.", + ], + (Role::Bather, _) => &[ + "Ah. Heaven is hot water.", + "Close the door, you're letting the steam out.", + "Best thing about a planet: baths.", + ], + (Role::Watchman, _) => &[ + "Nothing in here but crates. And me.", + "If you're thinking of stealing, think harder.", + "I count the crates every hour. Still forty-one.", + ], + (Role::Reader, _) => &[ + "Shh. Some of us are reading.", + "Did you know the old empire had nine words for vacuum?", + "I've been on this page for three days.", + ], + } +} + +/// What passers-by say when you bump into them. +pub fn chatter(culture: Culture) -> &'static [&'static str] { + match culture { + Culture::Qaari => &[ + "Water and shade to you, offworlder.", + "The caravan from the deep erg is three days late. Three!", + "Don't drink from the public cistern after dusk. Old law.", + "My cousin crews an ore hauler. He says the belt sings at night.", + "You smell of ship. Go to the tavern; everyone does.", + "The glass storms took the east road again.", + ], + Culture::Cant => &[ + "Unit. Your hull is unblessed. Have it seen to.", + "The litany runs at the third bell. Attendance is noted.", + "Every bolt remembers the hand that turned it.", + "Salvage is sacrament. Do not waste it.", + "I was a pump-servitor before my promotion. I miss the pumps.", + "Do not touch the pipes. The pipes are listening.", + ], + Culture::Houses => &[ + "Mind your boots on the marble, spacer.", + "A House is hosting again. Nobody was invited, so everybody will go.", + "They say the Archon's heir has taken up mining. Imagine.", + "The fountain was a gift. Everything here was a gift. Everything has a price.", + "Do you dance? No? Pity.", + "Never bow lower than the person you're bowing to.", + ], + Culture::Drift => &[ + "Hey, spacer. Long burn?", + "Planets make me dizzy. Too much down.", + "Trade you a song for a ration bar.", + "My mother was born between stars. So was I. It's strange, being here.", + "Somebody's always leaving. That's the Drift.", + "If you see a blue hull with a broken mast, that's my aunt. Wave.", + ], + } +} + +/// What stallholders call out. +pub fn cries(culture: Culture) -> &'static [&'static str] { + match culture { + Culture::Qaari => &[ + "Dates! Sun-dates, sweet as a promise!", + "Spiced locust, two for a ¤!", + "Rugs! Woven by hand, by grandmother's hand!", + "Water-skins, never leaked, never once!", + ], + Culture::Cant => &[ + "Bearings, blessed and greased!", + "Lubricant, consecrated this very morning!", + "Prayer-wire by the metre!", + "Spare parts for spare souls!", + ], + Culture::Houses => &[ + "Candied petals, fit for a court!", + "Silks from the Gardens!", + "Scent of the old capital, one drop a ¤!", + "Masks for the season's balls!", + ], + Culture::Drift => &[ + "Patches, hull or heart!", + "Songs, fresh from the void!", + "Ration bars, hardly expired!", + "Charts of places that might still be there!", + ], + } +} + +pub fn room_name(purpose: Purpose, culture: Culture) -> &'static str { + use Purpose::*; + match purpose { + Living => "the front room", + Bedroom => "a bedroom", + Kitchen => "the kitchen", + Store => "a storeroom", + Lodging => "someone's room", + Taproom => "the taproom", + Parlour => "the back room", + Cellar => "the cellar", + Counter => "the shop", + Ward => "the ward", + Stacks => "the stacks", + Assay => "the assay room", + Yard => "the yard", + Smithy => "the smithy", + Hall => "the hall", + Dining => "the dining room", + Library => "the library", + Bedchamber => "a bedchamber", + Gallery => "the gallery", + Throne => "the throne room", + Council => "the council chamber", + Treasury => "the treasury", + Nave => match culture { + Culture::Qaari => "the well-court", + Culture::Cant => "the engine hall", + Culture::Houses => "the nave", + Culture::Drift => "the lantern hall", + }, + Vestry => "the vestry", + Cell => "a cell", + Shrine => "the shrine", + Workroom => "the workshop", + Storehouse => "the store", + Office => "the office", + Changing => "the changing room", + Baths => "the baths", + Steam => "the steam room", + Guardroom => "the guardroom", + Bunks => "the bunk room", + } +} + +/// What bumping into a piece of furniture tells you. +pub fn thing_about(thing: Thing, culture: Culture) -> &'static str { + use Culture::*; + use Thing::*; + match (thing, culture) { + (Table, _) => "A table, ringed with old cups.", + (Chair | Pew | Bench | Throne, _) => "A seat.", + (Bed, Qaari) => "A sleeping mat on a low frame, piled with rugs.", + (Bed, Cant) => "A cot of welded mesh. Exactly as comfortable as required.", + (Bed, Houses) => "A canopied bed, its curtains heavy with dust.", + (Bed, Drift) => "A hammock-bed, rigged as if the floor might go away.", + (Hearth, Cant) => "A heating coil glows behind a grille.", + (Hearth, _) => "A fire crackles in the hearth.", + (Stove, _) => "A stove, still warm, smelling of whatever was cooked last.", + (Shelf, _) => "Shelves crammed with books, jars and keepsakes.", + (Chest, _) => "A chest. Locked, and none of your business.", + (Crate, _) => "Crates, stencilled with marks you can't read.", + (Barrel, _) => "A barrel. It sloshes.", + (Altar, Qaari) => "The sacred well. The water is so deep it's black.", + (Altar, Cant) => "The Engine: a vast machine that only turns. It hums in your teeth.", + (Altar, Houses) => "An altar of white stone, gold-leafed, crowded with candles.", + (Altar, Drift) => "A lantern-mast, a lantern hung on it for everyone lost in the void.", + (Pillar, _) => "A pillar, carved all the way up.", + (Statue, Qaari) => "A statue of a caravan-master, worn smooth by sandstorms.", + (Statue, Cant) => "A statue of a Fabricant, its face a smooth steel plate.", + (Statue, Houses) => "A marble statue of someone important, looking down on you.", + (Statue, Drift) => "A figurehead, salvaged from some old ship.", + (Plant, Qaari) => "A potted palm, carefully watered.", + (Plant, _) => "A potted plant, carefully watered.", + (Bath, _) => "Steaming water. It smells of minerals.", + (Anvil, _) => "An anvil, bright where the hammer falls.", + (Forge, _) => "A forge, roaring. The heat pushes you back.", + (Loom, _) => "A loom, strung with half a rug.", + (Workbench, _) => "A workbench, scattered with tools and offcuts.", + (Rack, _) => "A rack of pikes and stun-staves.", + (Lamp, Cant) => "A glow-tube on a stand, flickering.", + (Lamp, _) => "A lamp on a tall stand.", + (Engine, _) => "Half a ship's engine, opened up like a patient.", + } +} + +/// What bumping into something in the street tells you, if anything, in +/// a city of `culture` on `land`. For `Tile::Wild`, see `wild_about`. +pub fn tile_about(tile: Tile, culture: Culture, land: Land) -> Option<&'static str> { + use Culture::*; + Some(match (tile, culture) { + (Tile::Centrepiece, Qaari) => "The cistern's water is cool, dark and very still.", + (Tile::Centrepiece, Cant) => "The furnace roars. Prayers are welded to its flue.", + (Tile::Centrepiece, Houses) => { + "Coins glint at the bottom of the fountain. Wishes, or bribes." + } + (Tile::Centrepiece, Drift) => { + "A mast of welded hull-plate, hung with a hundred little bells." + } + (Tile::Statue, _) => thing_about(Thing::Statue, culture), + (Tile::Well, Qaari) => "A covered well, padlocked. Water isn't free here.", + (Tile::Well, Cant) => "A coolant tap, sealed with a litany-tag.", + (Tile::Well, Houses) => "A little fountain, a stone fish spitting into a basin.", + (Tile::Well, Drift) => "A water tank on legs, with a cup on a chain.", + (Tile::Water, _) => pond_about(land), + (Tile::Sea, _) => "The sea, grey-green and restless, all the way to the sky.", + (Tile::Tree, _) => tree_about(culture, land.terrain), + (Tile::Lamp, Cant) => "A glow-tube on a post, buzzing.", + (Tile::Lamp, _) => "A lamp post.", + (Tile::Decor, Drift) => "A heap of salvage, sorted by someone, for some reason.", + (Tile::Decor, _) => "A tangle of pipes, warm to the touch.", + (Tile::Roof, _) => return None, + _ => return None, + }) +} + +fn pond_about(land: Land) -> &'static str { + match (land.pond(), land.terrain) { + (Pond::Water, Terrain::Desert) => "A cistern pool, shaded and very still.", + (Pond::Water, _) => "A pond. Fish, or something like them, move under the surface.", + (Pond::Ice, Terrain::Ice) => "A pond frozen to the bottom, clear as glass.", + (Pond::Ice, _) => "A frozen pond. Something dark moves slowly under the ice.", + (Pond::Dry, _) => "A pond, dried to cracked mud. Someone's raked the cracks.", + (Pond::Lava, _) => "A pool of molten rock behind an iron rail. The heat is ferocious.", + } +} + +fn tree_about(culture: Culture, terrain: Terrain) -> &'static str { + match (terrain, culture) { + (Terrain::Desert, Culture::Qaari) => "A date palm, rattling in the hot wind.", + (Terrain::Desert, _) => "A date palm, its fronds grey with dust.", + (Terrain::Ice, _) => "A glass-pine. Its needles chime when the wind moves them.", + (Terrain::Ocean | Terrain::Jungle, Culture::Houses) => { + "A clipped yew, shaped like a bird. Something keeps trying to unclip it." + } + (Terrain::Ocean, _) => "A salt-pine, leaning away from the sea wind.", + (Terrain::Jungle, _) => "A strangler fig, wound round what used to be another tree.", + (Terrain::Barren | Terrain::Clouds, _) => { + "A spire of violet crystal, taller than you. It's growing, very slowly." + } + (Terrain::Forge, _) => "A fungus stalk as tall as a lamp post, warm and faintly pulsing.", + } +} + +/// What bumping into the `sort`th sort of thing outside the walls tells +/// you (see `Town::wild_sort`). +pub fn wild_about(terrain: Terrain, sort: usize) -> &'static str { + let [first, second] = match terrain { + Terrain::Desert => [ + "A cactus, fat with stored water and bristling with spines.", + "A boulder, scoured smooth by the sand.", + ], + Terrain::Ice => [ + "A spire of blue ice, taller than you and slowly leaning.", + "A boulder, glazed with ice.", + ], + Terrain::Ocean => { + ["Black rock, slick with spray.", "A heap of kelp, washed up and drying. It smells."] + } + Terrain::Jungle => [ + "Trees, crowded so close you can't push between them.", + "A wall of ferns and creepers, alive with clicking.", + ], + Terrain::Barren | Terrain::Clouds => [ + "A crag of grey rock, crusted with rust-red lichen.", + "A cluster of violet crystals, knee-high.", + ], + Terrain::Forge => { + ["A heap of black basalt, still warm.", "A vent, breathing hot, sulphurous air."] + } + }; + if sort == 0 { first } else { second } +} + +/// What the road out of a gate leads to. +pub fn beyond(terrain: Terrain) -> &'static str { + match terrain { + Terrain::Desert => "The road runs on into the dunes. There's nothing out there for you.", + Terrain::Ice => { + "The road runs on across the snowfields. There's nothing out there for you." + } + Terrain::Ocean => { + "The causeway runs on out to sea, to the fishing piers. There's nothing out there \ + for you." + } + Terrain::Jungle => "The road runs on under the canopy. There's nothing out there for you.", + Terrain::Barren | Terrain::Clouds => { + "The road runs on across the grey dust. There's nothing out there for you." + } + Terrain::Forge => { + "The road runs on between smoking lava fields. There's nothing out there for you." + } + } +} |