export type NpcDialogueKind = "firm" | "lowball" | "backward" | "stall" | "concede" | "good" | "overpay" | "closed" | "accept"; type DialogueLine = (amount: string, asking: string) => string; const LINES: Record = { firm: [ (amount) => `I'm not going any lower than ${amount}. Take it or leave it.`, (amount) => `That's my final price — ${amount}. I've got other buyers knocking.`, (amount) => `I'm holding at ${amount}. My prices are already fair.`, ], lowball: [ (amount) => `That's an insult! I'll come down to ${amount} — not a fraction less.`, (amount) => `You're joking, right? ${amount} and not a fraction less.`, (amount) => `I paid more than that for lunch! ${amount} — final offer.`, ], backward: [ (amount) => `Now you're offering less than before? I'm holding firm at ${amount}.`, (amount) => `We were making progress and now this? I'm staying at ${amount}.`, ], stall: [ () => "Really? That's hardly different. Negotiate like you mean it.", () => "That tiny increase isn't negotiating. Come back with a real number.", () => "You're just inching up now. Bring something meaningful.", ], concede: [ (amount) => `Hmm, not sure about that... how about ${amount}?`, (amount) => `I could stretch to ${amount}... if we're serious about this.`, (amount) => `Let's not waste each other's time — ${amount}.`, (amount) => `Alright, I'll bend a little. ${amount}?`, ], good: [ () => "Now we're talking. That's a fair price — you've got a deal.", () => "You drive a hard bargain, but that's a price I can live with.", () => "That works for me. A man's gotta make a living, after all.", ], overpay: [ () => "Wait — more than I asked? Sold! You won't regret it.", () => "Generous! I'd have taken less, but I won't argue. It's yours.", () => "Whoa, okay! Not going to talk you out of that one. Done deal.", ], closed: [ (_amount, asking) => `Alright, that's enough haggling. Buy it at ${asking} or not at all.`, (_amount, asking) => `I'm done negotiating. The price is ${asking} — take it or leave it.`, ], accept: [ () => "I think that price is acceptable. Let's shake on it.", () => "Done. Pleasure doing business with you.", () => "Deal! Good doing business with you.", ], }; /** * Vendor flavour lines for the in-dialog chat. Amounts are formatted plain. * Pass a custom `rng` (0–1) for deterministic output; otherwise a line is * picked at random each call. */ export function npcDialogue( kind: NpcDialogueKind, amount?: number, asking?: number, rng: () => number = Math.random, ): string { const lines = LINES[kind]; const index = Math.min(lines.length - 1, Math.max(0, Math.floor(rng() * lines.length))); return lines[index]((amount ?? 0).toLocaleString(), (asking ?? 0).toLocaleString()); }