import {CheckData} from "./newmap.ts"; import { bat0, bat1, charm0, charm1, lore0, lore1, party0, party1, stare0, stare1, stealth0, stealth1 } from "./skills.ts"; import { sprThrallBat, sprThrallCharm, sprThrallLore, sprThrallParty, sprThrallStare, sprThrallStealth } from "./sprites.ts"; import {Sprite} from "./engine/internal/sprite.ts"; export type Thrall = { id: number } class ThrallsTable { #thralls: ThrallData[] constructor() { this.#thralls = []; } add(data: ThrallData) { let id = this.#thralls.length; this.#thralls.push(data); return {id}; } get(thrall: Thrall): ThrallData { return this.#thralls[thrall.id] } getAll(): Thrall[] { let thralls = []; for (let id = 0; id < this.#thralls.length; id++) { thralls.push({id}) } return thralls; } } export type ThrallData = { label: string, sprite: Sprite, posterCheck: CheckData, initialCheck: CheckData, lifeStageText: Record } export enum LifeStage { Fresh = "fresh", Average = "average", Poor = "poor", Vampirized = "vampirized", Dead = "dead", } export type LifeStageText = { prebite: string, postbite: string, } let table = new ThrallsTable(); export function getThralls() { return table; } // Thralls are labeled by which zone's item they like // Their initial check is, generally, the initial check of the // thrall n-2 or thrall n+1 (ex: Party's initial check is Stealth // or Lore) export let thrallParty = table.add({ label: "Garrett", sprite: sprThrallParty, posterCheck: { label: "This room would be perfect for someone with an ostensibly managed gambling addiction.", options: [], }, initialCheck: { label: "That's Garrett. He plays poker, but he goes to the zoo to cool down after he's lost a lot of chips. His ice cream cone has melted.", options: [ { skill: () => stealth1, // Disguise locked: "\"What's wrong, Garrett?\"", failure: "\"If you're not a large pile of money, don't talk to me.\"\n\nHe sobs into his ice cream.", unlockable: "*look like a large pile of money*", success: "He scoops you eagerly into his wallet.", }, { skill: () => lore0, // Respect Elders locked: "TODO", failure: "TODO", unlockable: "TODO", success: "TODO", }, ] }, lifeStageText: { fresh: { prebite: "Garrett flips a poker chip and mutters to himself.", postbite: "You plunge your fangs into his feathered neck and feed.", }, average: { prebite: "Garrett looks a little less fresh than last time. He's resigned to the fate of being bitten.", postbite: "You puncture him in almost the same place as before and take a moderate amount of blood from his veins." }, poor: { prebite: "Garrett, limp in bed, doesn't look like he's doing so well. He's pale and he's breathing heavily.", postbite: "\"Please...\" you hear him moan as you force him into the state of ecstasy that brings compliance.", }, vampirized: { prebite: "Garrett looks about as cold and pale as you. Another bite may kill him.", postbite: "The final bite is always the most satisfying. You feel little emotion as you hold the body of a dead crow in your arms.", }, dead: { prebite: "This bird is dead, on account of the fact that you killed him with your teeth.", postbite: "The blood in his veins hasn't coagulated yet. There's still more. Still more...", } }, }) export let thrallLore = table.add({ label: "Lupin", sprite: sprThrallLore, posterCheck: { label: "This room would be perfect for someone with a love of nature and screaming.", options: [], }, initialCheck: { label: "That's Lupin. He's a Wolf Scout, but hardcore about it. I'm not sure he knows he's a raccoon.", options: [ { skill: () => stare1, // Hypnotize locked: "TODO", failure: "TODO", unlockable: "\"I'm a wolf too.\"", success: "He blinks a few times under your gaze -- then touches your muzzle -- then his own -- then arfs submissively.", }, { skill: () => bat0, // Screech locked: "TODO", failure: "TODO", unlockable: "\"Wolf Scouts AWOO!\"", success: "Taken aback at how well you know the cheer, he freezes -- then joins you with a similar howl.", }, ] }, lifeStageText: { fresh: { prebite: "Lupin awoos quietly to himself.", postbite: "You bite the raccoon and drink his blood.", }, average: { prebite: "The color in Lupin's cheeks is beginning to fade. He's becoming accustomed to your bite.", postbite: "He'll let you do anything to him if you make him feel good, so you make him feel good. Fresh blood...", }, poor: { prebite: "Lupin is barely conscious. There's drool at the edges of his mouth and his eyes are glassy.", postbite: "This is no concern to you. You're hungry. You need this.", }, vampirized: { prebite: "Lupin's fangs have erupted partially from his jaw. You've taken enough. More will kill him.", postbite: "His life is less valuable to you than his warm, delicious blood. You need sustenance.", }, dead: { prebite: "This dead raccoon used to be full of blood. Now he's empty. Isn't that a shame?", postbite: "You root around in his neck. His decaying muscle is soft.", } }, }) export let thrallBat = table.add({ label: "Monica", sprite: sprThrallBat, posterCheck: { label: "This room would be perfect for some kind of television chef.", options: [], }, initialCheck: { label: "That's Monica. You've seen her cook on TV! Looks like she's enjoying a kiwi flan.", options: [ { skill: () => party1, // Rave locked: "TODO", failure: "TODO", unlockable: "Slide her a sachet of cocaine.", success: "\"No way. Ketamine if you've got it.\" You do.\n\n(It's not effective on vampires.)", }, { skill: () => charm0, // Flatter locked: "TODO", failure: "TODO", unlockable: "\"You're the best cook ever!\"", success: "\"Settle down!\" she says, lowering your volume with a sweep of her hand. \"It's true though.\"", }, ] }, lifeStageText: { fresh: { prebite: "Monica nibbles a pastry.", postbite: "You dig your teeth into the koala's mortal flesh.", }, average: { prebite: "Monica doesn't look as fresh and vibrant as you recall from her TV show.", postbite: "A little bite seems to improve her mood, even though she twitches involuntarily as if you're hurting her.", }, poor: { prebite: "Monica weakly raises a hand as if to stop you from approaching for a bite.", postbite: "You press yourself to her body and embrace her. Her fingers curl around you and she lets you drink your fill.", }, vampirized: { prebite: "Monica shows no interest in food. She's lethargic, apathetic. A bite would kill her, but you're thirsty.", postbite: "Her last words are too quiet to make out, but you're not interested in them. Nothing matters except blood.", }, dead: { prebite: "This used to be Monica. Now it's just her corpse.", postbite: "She's very delicate, even as a corpse.", } }, }) export let thrallCharm = table.add({ label: "Renfield", sprite: sprThrallCharm, posterCheck: { label: "This room would be perfect for someone who likes vampires even more than you enjoy being a vampire.", options: [], }, initialCheck: { label: "Doesn't this guy seem a little creepy? His nametag says Renfield. Not sure you should trust him...", options: [ { skill: () => lore1, // Brick by Brick locked: "TODO", failure: "TODO", unlockable: "\"Wanna see my crypt?\"", success: "He salivates -- swallowing hard before he manages, in response to the prospect, a firm \"YES!\"", }, { skill: () => stealth0, // Be Quiet locked: "TODO", failure: "TODO", unlockable: "Say absolutely nothing.", success: "His mind overflows with fantasy, and when you let a glint of fang peek through, he claps his arms affectionately around your supercold torso.", }, ] }, lifeStageText: { fresh: { prebite: "Renfield exposes the underside of his jaw.", postbite: "You press your face flat to his armorlike scales and part them with your teeth.", }, average: { prebite: "Renfield seems relieved to be free of all that extra blood.", postbite: "You taste a little bit of fear as you press yourself to him. Is he less devoted than you thought?", }, poor: { prebite: "Renfield presses his face to the window. He won't resist you and won't look at you. He does not want your bite.", postbite: "Does it matter that he doesn't want your bite? You're hungry. He should have known you would do this.", }, vampirized: { prebite: "Renfield is repulsed by the vampiric features that his body has begun to display. Another bite would kill him.", postbite: "Better to free him if he's going to behave like this anyways.", }, dead: { prebite: "Here lies a crocodile who really, really liked vampires.", postbite: "At least in death he can't backslide on his promise to feed you.", } }, }) export let thrallStealth = table.add({ label: "Narthyss", sprite: sprThrallStealth, posterCheck: { label: "This room would be perfect for someone who can breathe fire.", options: [], }, initialCheck: { label: "Narthyss (dragon, heiress) actually owns the club, so she probably wouldn't talk to you... Would she?", options: [ { skill: () => bat1, // Flap locked: "TODO", failure: "TODO", unlockable: "Hang upside-down and offer her a martini.", success: "\"You're ADORABLE!\" She's yours forever.", }, { skill: () => stare0, // Dazzle locked: "TODO", failure: "TODO", unlockable: "TODO", success: "TODO", }, ] }, lifeStageText: { fresh: { prebite: "Narthyss is producing a new track on her gamer PC.", postbite: "You push her mouse and keyboard aside and focus her attention on your eyes.", }, average: { prebite: "Narthyss has no desire to be interrupted, but you're thirsty.", postbite: "You dazzle her with your eyes and nip her neck with erotic enthusiasm.", }, poor: { prebite: "Narthyss knows better than to resist you -- but you sense that you've taken more than she wants.", postbite: "Her response to your approach is automatic. No matter what she tells you, you show fang -- she shows neck.", }, vampirized: { prebite: "Narthyss' fire has gone out. She's a creature of venom and blood now. Another bite would kill her.", postbite: "Now she is a creature of nothing at all.", }, dead: { prebite: "Narthyss used to be a dragon. Now she's dead.", postbite: "Dragons decay slowly. There's still some warmth in there if you bury your fangs deep enough.", } }, }) export let thrallStare = table.add({ label: "Ridley", sprite: sprThrallStare, posterCheck: { label: "This room would be perfect for a soulless robot.", options: [], }, initialCheck: { label: "Ridley is the library's catalogue system. It can give you an incorrect answer to any question. (It has a couple gears loose.)", options: [ { skill: () => charm1, // Befriend locked: "\"How many Rs in 'strawberry'?\"", failure: "It generates an image of a sad fruit shrugging in a muddy plantation.", unlockable: "TODO", success: "TODO", }, { skill: () => party0, // Chug locked: "TODO", failure: "TODO", unlockable: "Drink a whole bottle of ink.", success: "TODO", }, ] }, lifeStageText: { fresh: { prebite: "Ridley is solving math problems.", postbite: "You delicately sip electronic blood from the robot's neck." }, average: { prebite: "Ridley's display brightens at your presence. It looks damaged.", postbite: "Damaged or not -- the robot has blood and you need it badly.", }, poor: { prebite: "The symbols on Ridley's screen have less and less rational connection. It's begging to be fed upon.", postbite: "The quality of the robot's blood decreases with every bite, but the taste is still pleasurable." }, vampirized: { prebite: "With no concern for its survival, the now-fanged robot begs you for one more bite. This would kill it.", postbite: "Nothing is stronger than your need for blood -- and its desperation has put you in quite a state...", }, dead: { prebite: "Ridley was a robot and now Ridley is a dead robot.", postbite: "Tastes zappy.", } }, })