not-tonight/src/data/strings/door.ts
2026-07-20 05:35:47 +10:00

208 lines
7.2 KiB
TypeScript

// Door-phase flavour text. Aussie register per docs/GAME_DESIGN.md §5 — affectionate,
// absurd, never sneering at the punter. Added by LANE-DOOR; nothing here is imported
// by another lane, so it can move to a shared strings module at integration.
export const DOOR_UI = {
rope: 'UNHOOK ROPE',
ropeWaiting: 'NEXT!',
ropeEmpty: 'NOBODY THERE',
admit: 'ADMIT',
deny: 'NOT TONIGHT',
test: 'SOBRIETY TEST',
patDown: 'PAT-DOWN',
clicker: 'CLICKER',
phone: 'PHONE',
idTray: 'ID TRAY',
idTrayEmpty: 'no ID handed over',
dressCode: "DAZZA'S RULES",
dressCodeEmpty: 'no rules yet.\nuse ur judgement\n(dont)',
} as const;
/** Shown once, first thirty seconds, then never again. A stranger must be able to play. */
export const DOOR_TUTORIAL = [
'click the rope to call someone up',
'hover their clothes to look closer',
'click the ID in the tray to read it',
'ADMIT or NOT TONIGHT',
] as const;
export const PATRON_GREETINGS: readonly string[] = [
'evening mate',
'howsit goin',
'big night?',
'me and the girls just wanna dance',
'is it busy in there',
'my mates already inside',
"we've been in the queue for ages",
'do youse do stamps',
'yeah nah yeah',
"how ya goin' champ",
'is there a cover charge or',
'straight up i just need a sit down',
];
export const DRUNK_GREETINGS: readonly string[] = [
"i'm not even that drunk",
"i've had like. two",
'love this place. love it',
'yourrrre a legend by the way',
'wheres the kebab shop',
'i know the DJ. sort of',
"i'm fine i'm fine i'm fine",
];
/**
* The owner's mate (design §3.1 — "the trap"). Usually a lie, occasionally
* true, and denying a true one is the worst call at the rope. The tell has to
* be a NAME rather than confidence, because confidence is free — and 'terry'
* is the name Dazza begs you about in his `owner-scare` text.
*/
export const OWNER_HINTS: readonly string[] = [
'terry said swing by tonight',
"i drink with the owner. terry. we're mates",
"ring terry if you like. he'll vouch",
'ive known terry since the old venue',
"terry's expecting me, don't make it weird",
'me and terry go back. ask him',
];
export const CLAIM_LINES: readonly string[] = [
"i'm on the list",
'i know the owner',
"we're on the list under Bec",
'yeah nah my names definitely down',
'i was here last weekend',
];
/** What the room mutters when you send someone away. Never cruel about the patron. */
export const DENY_REACTIONS: readonly string[] = [
'the queue goes quiet',
'someone films it',
'a bloke in the queue claps. once.',
'muffled outrage',
'nobody argues',
'the queue shuffles forward',
];
export const ADMIT_REACTIONS: readonly string[] = [
'in they go',
'the queue breathes out',
'a small cheer',
'door thuds shut',
];
/**
* "Dazza does a lap" — the deferred sting for waving a violator through. There
* are several because one phrasing repeated six times in a night reads as a
* broken game rather than a man losing his patience. `{rule}` is the card label.
*/
export const DAZZA_LAP_LINES: readonly string[] = [
'did a lap mate and the sign says "{rule}" so explain that one to me',
'im looking at someone by the bar rn. "{rule}". we discussed this',
'mate. "{rule}". i typed it out and everything',
'not being funny but whats the point of me sending u the rules. "{rule}"',
'one on the dancefloor right now. "{rule}". i felt that in my chest',
'ur letting them in with "{rule}" still on the card. bold',
'the owner walked past that one. "{rule}". i aged a year',
];
export const lapLine = (short: string, roll: number): string => {
const i = Math.min(DAZZA_LAP_LINES.length - 1, Math.floor(roll * DAZZA_LAP_LINES.length));
return (DAZZA_LAP_LINES[i] ?? DAZZA_LAP_LINES[0]!).replace('{rule}', short);
};
/**
* Dazza noticing, later, that someone you waved through has ripened. Keyed by
* how far gone they already were at the rope — he is describing the room, never
* grading the player.
*/
export const DAZZA_RIPEN_LINES: Record<string, readonly string[]> = {
loose: [
'someone in here has found their second wind and it is not a good one',
'theres a bloke doing the shuffle by the speaker. u know the shuffle',
'one of urs has started telling people about his ute',
],
messy: [
'mate whoever u let in with the eyes is now sitting on the floor. SITTING',
'we have a leaner. by the bar. leaning on people not walls',
'someone just tried to order from the DJ',
],
maggot: [
'the bloke u waved through is in the garden bed. the GARDEN BED',
'im watching security carry someone out and i am asking myself questions',
'whoever that was they are now horizontal and thats on the door',
],
};
export const ripenLine = (stage: string, roll: number): string => {
const pool = DAZZA_RIPEN_LINES[stage] ?? DAZZA_RIPEN_LINES.loose!;
const i = Math.min(pool.length - 1, Math.floor(roll * pool.length));
return pool[i] ?? pool[0]!;
};
/**
* Dazza rescinding a rule when a newer one pushes it off the card
* (rules cap at ACTIVE_RULE_CAP — his attention span, not a settings screen).
*/
export const RULE_RETRACTIONS: readonly string[] = [
'dazza: forget the "{rule}" thing. new priorities',
'dazza: "{rule}" is over. keep up',
'dazza: im rescinding "{rule}". it wasnt working. dont ask',
];
export const SOBRIETY_UI = {
title: 'SOBRIETY TEST',
pickPrompt: 'pick your test',
waiting: 'they think about it...',
passBtn: 'PASSED',
failBtn: 'FAILED',
hint: 'you can rule however you like. thats the job',
} as const;
export const PATDOWN_LINES = {
clean: 'pockets are empty. just lint and a servo receipt',
found: (item: string): string => `AMNESTY BIN: ${item}`,
} as const;
export const REPORT_UI = {
title: 'INCIDENT REPORT',
subtitle: 'management requires an account of the night. be accurate. or dont',
nothingToReport: 'nothing happened worth writing down.\n\nthat is, itself, a kind of night.',
filed: 'REPORT FILED',
done: 'click to knock off',
/** Same weight either way — the game does not grade the paperwork. */
filedFlavour: (embellished: boolean): string =>
embellished
? 'dazza signs it without reading it. the filing cabinet closes.'
: 'dazza signs it without reading it. the filing cabinet closes.',
} as const;
export const SUMMARY_UI = {
title: 'LAST DRINKS',
subtitle: '3:00 AM · the lights come up',
replay: 'click anywhere for another night',
} as const;
export const FAIL_TEXT = {
vibe: {
title: 'THE VIBE DIED',
dazza: 'the room is a MORGUE mate. dont come in tomorrow. or do. i dont know. no. dont',
},
aggro: {
title: 'THE QUEUE WENT UP',
dazza: 'someone glassed the door. THE DOOR. u had one job and the job was the door',
},
licence: {
title: 'LICENCE PULLED',
dazza: 'the inspector just walked out with the licence in a SLEEVE. do not text me. do not call me. terry is going to hear about this',
},
} as const;
/** Dazza's night-end verdicts, worst to best. Index chosen by final vibe. */
export const DAZZA_SIGNOFF: readonly string[] = [
'ok that was rough. we go again thursday. bring a jacket',
'not ur best night but the room stayed open so. thats something',
'solid. the owner didnt call me once. thats the highest praise i have',
'mate. MATE. that room was electric. im telling terry u did that',
];