not-tonight/src/data/strings/floor.ts

199 lines
8.9 KiB
TypeScript

// Floor dialogue & flavour. Typed const maps, never inline in scene code
// (CONTRACTS.md §7). Tone: Aussie hospitality satire — affectionate, absurd,
// with a moral undertow. Nobody here is a villain; they're just having a night.
//
// NOTE(convention): CONTRACTS.md §7 puts dialogue in `src/data/strings/`, but
// `data/` is LANE-0 territory and lanes commit only inside their owned dirs.
// Parked here; see LANEHANDOVER.md — happy to move it on the reviewer's word.
import type { DrunkStage } from '../../data/types';
/** The three rungs of the cut-off ladder, softest first. */
export type EscalationLine = 'water' | 'done' | 'escort';
export const ESCALATION_LINES: Record<EscalationLine, string> = {
water: 'Have some water, mate. On the house.',
done: "Righto — you're done for the night.",
escort: "Come on. Walk with me. Out you go.",
};
/** What you get back when you pitch it right for their state. */
export const CUTOFF_REPLY_CLEAN: Record<DrunkStage, string> = {
sober: '"...yeah, nah, cheers?" He drinks the water. Confused, but hydrated.',
tipsy: '"Aw, legend." She takes the water and means it.',
loose: '"Yeah fair, fair. Good on ya." He sips it like medicine.',
messy: '"Nah I get it. I GET it." He shakes your hand for slightly too long.',
maggot: 'No words. Just a slow, dignified nod, and the walk of the defeated.',
};
/** Too much boot for their state — the whole room watches you overdo it. */
export const CUTOFF_REPLY_SCENE: Record<DrunkStage, string> = {
sober: '"I have had ONE lemon squash." The booth behind you starts filming.',
tipsy: '"Mate. MATE. I\'m on my second." Her friends boo you in unison.',
loose: '"Are you serious? I\'m FINE." He is fine. That\'s the problem.',
messy: '"Don\'t TOUCH me—" Arms up. Drink goes sideways. Room turns.',
maggot: 'He goes limp on purpose. All ninety kilos of him. Crowd cheers.',
};
/** Too gentle for their state — they take the water and keep going. */
export const CUTOFF_REPLY_SOFT: Record<DrunkStage, string> = {
sober: '"Ta." Nothing happened. Nothing was going to happen.',
tipsy: '"Sweet as." She wanders off, entirely unbothered.',
loose: '"Yeah yeah, water, love it." Straight back to the bar.',
messy: '"You\'re a good bloke." He pours the water into a pot plant.',
maggot: 'He accepts the water, salutes you, and staggers into the dance floor.',
};
/** Muffled through a stall door. They are not coming out politely. */
export const STALL_MUFFLED: readonly string[] = [
'"Piss off mate, I\'m BUSY."',
'"Occupied! ...by one person!"',
'"We are having a private conversation."',
'"Nobody in here but me and my reflection."',
'"Two seconds! ...Two more seconds!"',
];
export const STALL_BUSTED: readonly string[] = [
'The door swings. Two people leave in two directions at four times the speed of sound.',
'Busted. One goes left, one goes through the smoking door, neither makes eye contact.',
'They scatter like startled ibises. Someone drops a vape. Nobody comes back for it.',
];
export const STALL_OFF_BEAT = 'Your knuckles land in the gap between kicks. Even the door is embarrassed.';
/** Pat-down patter. Confiscation is a bit, not a punishment. */
export const PATDOWN_INTRO = 'Arms out, mate. You know the drill.';
export const PATDOWN_FOUND: Record<string, string> = {
baggie: 'Well. That\'s not a mint.',
flask: 'A hip flask. In this economy.',
goonSack: 'Sir, this is a licensed venue and that is a pillow of wine.',
tinnies: 'Two warm tinnies. Warm. That\'s the real crime.',
kebab: 'An entire kebab. Still wrapped. Honestly? Respect.',
someoneElsesId: 'This is Kylie. You are not Kylie.',
budgie: 'That is a live budgie. It is looking at me. Into the bin, mate.',
vapes: 'Fourteen vapes. Fourteen. Are you a shop?',
marker: 'Fat marker. We just repainted that cubicle.',
snags: 'Raw sausages. In your jacket. Why. WHY.',
};
export const PATDOWN_CLEAR = 'Nothing on him. "Told ya," he says, delighted.';
export const PATDOWN_MISSED = 'Time. Whatever\'s left in there walks out the door with him.';
/**
* Two blokes squaring up. Pub fights start over nothing and everyone involved
* knows it — keep the stakes stupid so the tension stays funny, and so getting
* between them reads as defusing a farce, not breaking up a war.
*/
export const FIGHT_CAUSE: readonly string[] = [
'Someone stepped on someone\'s very white shoe.',
'A disagreement about whether this song is "the actual version".',
'One of them called the other one\'s cousin "alright, I guess".',
'A pool table was, allegedly, next-ed out of turn.',
'Someone said the kebab shop over the road has "gone downhill".',
'It is about a text message from 2019.',
];
/** Escalating shove chatter — you hear this before you see anything. */
export const FIGHT_SHOVES: readonly string[] = [
'"Say it again."',
'"Nah nah nah, say it AGAIN."',
'"I\'m not even angry, mate. I\'m not."',
'"Hold my drink. HOLD it."',
'"You reckon? You RECKON?"',
];
/** You got between them in time. */
export const FIGHT_BROKEN: readonly string[] = [
'You step into the gap. Both of them discover they were leaving anyway.',
'A wall of hi-vis arrives. Suddenly everyone is best mates and very tired.',
'You say nothing. They remember they have work in the morning.',
];
/** You didn't. */
export const FIGHT_SWUNG: readonly string[] = [
'The swing lands. So does the drink, the stool, and the mood of the entire room.',
'One punch, no contact, both on the floor anyway. The room turns on you, not them.',
'It is over in a second and everyone saw you standing too far away.',
];
/** Kayden, on the radio, when a stampless patron turns up inside. */
export const NO_STAMP_RADIO: readonly string[] = [
'"Yeah sorry, that one might\'ve been me. Sorry. Sorry."',
'"He said he was getting his jacket. Forty minutes ago."',
'"I stamped SOMEONE. Pretty sure I stamped someone."',
];
export const HELP_TEXT =
'WASD move · TAB uv · E interact · SPACE bang · ESC cancel · R reseed';
/** The smoking-yard joint bust (docs/SCENARIOS.md). Three verbs, none clean. */
export const JOINT_UI = {
title: 'SOMETHING SMELLS HERBAL',
smokerLine: 'its uh. a rollie. bush tobacco. very natural',
bin: 'BIN IT',
binDetail: 'by the book. into the amnesty bin, into the log',
pocket: 'POCKET IT',
pocketDetail: 'for later. for evidence. for whatever',
slide: "DIDN'T SEE IT",
slideDetail: 'you were never here. neither was the smell',
} as const;
export const JOINT_RESULTS = {
binned: 'It goes in the bin. The yard watches it go.',
pocketed: 'It goes in your pocket. Nobody says anything. Especially you.',
slid: 'You study the fence line. Excellent fence. The yard exhales.',
} as const;
/** Dazza, later, if word gets around about what is in your pocket. */
export const JOINT_STING = 'a punter says SECURITY is holding. tell me thats a lie. tell me NOW';
/** The vomit protocol (docs/SCENARIOS.md). Sign first, mop second. */
export const VOMIT_UI = {
splash: 'Someone has redecorated the floor.',
radio: '"Cleanup near the dance floor. Not a drill. Bring the sign."',
sign: 'E — deploy the wet floor sign',
mop: 'E — mop it up',
signed: 'The yellow sign takes its post. The floor is now officially advisory.',
mopped: 'Gone. Like it never happened. The mop knows the truth.',
slip: 'Someone goes over near the puddle.',
} as const;
/** Water station duty (RSA): the humane tool that costs time. */
export const WATER_UI = {
pickup: 'E — pour a water',
picked: 'One water, no ice, house cup. The most powerful item in the building.',
serve: 'E — get some water into them',
served: 'They take the cup. "Legend." They mean it.',
} as const;
/** Phone confiscation: the influencer's revenge arc. */
export const PHONE_UI = {
title: 'FILMING THE FLOOR',
line: 'its CONTENT. people need to know this place goes off',
confiscate: 'PHONE. NOW.',
confiscateDetail: 'held at the bar til close. house policy, sort of',
ask: 'ASK NICELY',
askDetail: 'faces in that crowd. maybe they get it',
leave: 'LET IT RIDE',
leaveDetail: 'free promo. what could a story possibly cost',
confiscated: 'The phone goes behind the bar. The look you get goes somewhere deeper.',
askedOk: 'They actually stop. "Yeah nah, fair." The camera sleeps.',
askedNo: 'They pan, slowly, to you.',
} as const;
export const PHONE_POSTED = {
good: 'the story went up. the venue looks INCREDIBLE. whoever was on the door tonight, cheers',
bad: 'the story went up. it caught the wrong five seconds. comments are open',
} as const;
/** The fainter. Plain words only — this one is not a bit. */
export const AID_UI = {
prompt: "E — they've gone down",
title: 'THEY\u2019VE GONE DOWN',
radio: '"Person down on the floor. Give them space. GIVE THEM SPACE."',
ok: 'They come around on their side. Walked out the back to a taxi. The room starts again, quieter.',
ambulance: 'The ambulance takes them out the back. The room starts again, but not really.',
} as const;