1
0
Fork 0
polaris-task-force/src/lib/market/npcDialogue.ts
Z8MB1E 80ec3a0386 refactor(market): pass currency config through market UI
Market listings, offer dialogs, negotiation panels, and history now render prices from the full CurrencyConfig (symbol + singular/plural) instead of a nullable currency label string.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-06 01:23:57 -04:00

67 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export type NpcDialogueKind =
"firm" | "lowball" | "backward" | "stall" | "concede" | "good" | "overpay" | "closed" | "accept";
type DialogueLine = (amount: string, asking: string) => string;
const LINES: Record<NpcDialogueKind, DialogueLine[]> = {
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());
}