(() => { function checkSuspicion(add = 0) { const old = getStat("suspicion"); if (add >= 0) { add *= state.info.awareness.value; } changeStat("suspicion", add); if (getStat("suspicion") >= 100) { print(["Geta spots you!", "You're snatched up and tossed into the fox's bowl of cereal."]); goToRoom("in-bowl"); return false; } else if (getStat("suspicion") >= 75 && old < 75) { print(["The fox is very suspicious. You're going to get caught if you keep this up..."]); } return true; } function randomBodyPart() { const choices = Object.entries(state.player.limbs).filter(([name, status]) => { return status; }).map(([name, status]) => name); return choices[Math.floor(Math.random() * choices.length)]; } function limbsLost() { return Object.entries(state.player.limbs).filter(([name, status]) => { return !status; }).length; } function pickRandom(list) { return list[Math.floor(Math.random() * list.length)]; } const word = { get swallow() { return pickRandom(["swallow", "gulp"]); }, get slimy() { return pickRandom(["slimy", "sloppy", "slick", "glistening"]) }, get disgusting() { return pickRandom(["disgusting", "abhorrent", "rank", "horrific", "nauseating", "sickening", "wretched"]) }, get foul() { return pickRandom(["foul", "rank", "gross"]) }, get fatal() { return pickRandom(["fatal", "deadly"]) }, get painful() { return pickRandom(["painful", "agonizing", "unbearable"]) } } function statLerp(stat, change, duration) { // pretty sure this'll be a random id... const id = new Date().getTime() + Math.random(); const iterations = duration / 1000 * 60; startTimer({ id: id, func: () => { changeStat(stat, change / iterations); return true; }, delay: 1000 / 60, loop: true, classes: [ ] }); startTimer({ id: id + "-stopper", func: () => { stopTimer(id); return false; }, delay: duration, loop: false, classes: [ ] }); } const limbs = { head: "head", leftArm: "left arm", rightArm: "right arm", leftLeg: "left leg", rightLeg: "right leg" }; stories.push({ "id": "geta-unaware", "info": { "name": "Geta's Breakfast", "desc": "Try to sneak past a fox after a catastrophic shrinking incident.", "tags": [ "prey", "fatal", "oral-vore", "hard-vore", "hard-digestion", "macro-micro" ] }, "intro": { "start": "pepper-grinder", "setup": () => { state.info.awareness = { id: "awareness", name: "Geta's Awareness", type: "counter", value: 1, get render() { if (this.value < 1) { return "Distracted"; } else if (this.value == 1) { return "Normal" } else { return "Alert" } } } state.geta = {}; state.player.stats.health = { name: "Health", type: "meter", value: 100, min: 0, max: 100, get color() { return "rgb(" + (155 + this.value) + "," + (this.value / 2) + "," + (this.value / 2) + ")" } }; state.player.stats.stamina = { name: "Stamina", type: "meter", value: 100, min: 0, max: 100, get color() { return "rgb(55," + (155 + this.value) + ",55)" }, hidden: true }; state.player.stats.suspicion = { name: "Suspicion", type: "meter", value: 0, min: 0, max: 100, get color() { return "rgb(" + (155 + this.value) + ",100,100)" } }; state.player.stats.mawPos = { "name": "Struggle", "type": "meter", "value": 0.5, "min": 0, "max": 1, get color() { return (this.value <= 0.15 || this.value >= 0.85) ? "rgb(255,100,0)" : "rgb(0,255,0)" }, hidden: true } state.player.stats.throatPos = { "name": "Descent", "type": "meter", "value": 0.25, "min": 0, "max": 1, get color() { return "rgb(" + (100 + 155 * this.value) + ",0,0)" }, hidden: true } state.player.stats.absorption = { "name": "Absorption", "type": "meter", "value": 0, "min": 0, "max": 1, get color() { return "rgb(" + (100 + 155 * this.value) + ",0,0)" }, hidden: true } state.info.time.value = 60 * 60 * 7 + 60 * 17; state.player.limbs = {}; state.player.limbs.head = true; state.player.limbs.leftArm = true; state.player.limbs.rightArm = true; state.player.limbs.leftLeg = true; state.player.limbs.rightLeg = true; startTimer({ id: "clock", func: () => { state.info.time.value += 1; state.info.time.value %= 86000; return true; }, delay: 1000, loop: true, classes: [ ] }); startTimer({ id: "suspicion-decay", func: () => { checkSuspicion(-0.1); return true; }, delay: 100, loop: true, classes: [ "free" ] }); startTimer({ id: "timeout", func: () => { if (state.info.time.value == 60 * 60 * 7 + 60 * 19) { print(["The fox is almost done with his breakfast..."]); } if (state.info.time.value >= 60 * 60 * 7 + 60 * 20) { print(["Time's up! In you go."]); goToRoom("maw"); return false; } return true; }, delay: 1000, loop: true, classes: [ "free" ] }); startTimer({ id: "geta-action", func: () => { const random = Math.random(); if (random < 0.7) { print(["Geta slurps up a spoonful of cereal."]); return Math.random() * 3000 + 3000 } else if (random < 0.9) { state.info.awareness.value = 0.1; print(["The fox yawns and stretches."]); startTimer({ id: "yawn-end", func: () => { print(["Geta finishes his stretch"]); state.info.awareness.value = 1; return true; }, delay: 5000, loop: false, classes: [ "free" ] }); return Math.random() * 3000 + 5000 } else { state.info.awareness.value = 2; print(["Geta narrows his eyes and looks around the table. Something seems off to him..."]); startTimer({ id: "squint-end", func: () => { print(["He goes back to his breakfast."]); state.info.awareness.value = 1; return true; }, delay: 5000, loop: false, classes: [ "free" ] }); return Math.random() * 1000 + 6000 } }, delay: 5000, loop: true, classes: [ "free" ] }); }, "intro": () => { print(["Game started", newline, "Exposition goes here later."]); } }, "sounds": [ "loop/heartbeat.ogg", "loop/stomach.ogg", "sfx/absorb.ogg", "sfx/big-gulp.ogg", "sfx/digest.ogg", "sfx/gulp-1.ogg", "sfx/gulp-2.ogg", "sfx/gulp-3.ogg", "sfx/swallow.ogg" ], "preload": [ ], "refresh": () => { setBackgroundColor(50 - state.player.stats.health.value / 2, 0, 0); }, "world": { "pepper-grinder": { "id": "pepper-grinder", "name": "Pepper Grinder", "desc": "You're hiding behind a pepper grinder", "move": (room) => { print(["You dart over to the pepper grinder, which looms over you like a greatwood."]); }, "enter": (room) => { }, "exit": (room) => { }, "actions": [ { name: "Tap", desc: "Bang on the pepper shaker", execute: (room) => { print(["You thump the pepper shaker, making a dull thud."]); const safe = checkSuspicion(25); if (safe && getStat("suspicion") > 50) { print(["Geta leans in to have a closer look. He's going to catch you if you don't move!"]); startTimer({ id: "pepper-investigate", func: () => { if (state.player.location == "pepper-grinder") { print([ "A massive hand grasps the grinder and shoves it aside; you fall back and land hard, knocking the wind from your lungs. Stars dance in your corners of your vision as Geta's muzzle looms above, his dull-green eyes fixated on your bite-sized body.", newline, "He frowns and scoops you up, squeezing you between tree-trunk fingers as he raises you up to his slavering maw." ]); goToRoom("hand"); } else { print(["You evaded the fox."]); } }, delay: 3000, loop: false, classes: [ "free" ] }); } }, show: [ ], conditions: [ ] }, { name: "Wait", desc: "Wait for the fox to finish his breakfast. Surely you'll be able to escape after that...right?", execute: (room) => { state.info.time.value = 60 * 60 * 7 + 60 * 20; }, show: [ ], conditions: [ ] }, ], "exits": { "up": { "target": "bowl", "desc": "Walk up to the cereal bowl", "show": [ ], "conditions": [ ], "hooks": [ (room, exit) => { return checkSuspicion(10); } ] }, "left": { "target": "table", "desc": "Run out into the open", "show": [ ], "conditions": [ ], "hooks": [ ] }, }, "hooks": [ ], "data": { "stats": { } } }, "bowl": { "id": "bowl", "name": "Behind the Bowl", "desc": "You're crouched behind Geta's bowl of cereal", "move": (room) => { print(["You scurry up to the looming bowl, staying low and out of Geta's sight."]); }, "enter": (room) => { }, "exit": (room) => { }, "actions": [ ], "exits": { "ascend": { "target": "in-bowl", "desc": "Climb into Geta's cereal", "show": [ ], "conditions": [ ], "hooks": [ ] }, "down": { "target": "pepper-grinder", "desc": "Run back behind the pepper grinder", "show": [ ], "conditions": [ ], "hooks": [ (room, exit) => { return checkSuspicion(15); } ] }, }, "hooks": [ ], "data": { "stats": { } } }, "table": { "id": "table", "name": "Table", "desc": "You're out in the open!", "move": (room) => { }, "enter": (room) => { startTimer({ id: "table-suspicion", func: () => { checkSuspicion(1.5); return true; }, delay: 100, loop: true, classes: [ "free" ] }); }, "exit": (room) => { stopTimer("table-suspicion"); }, "actions": [ ], "exits": { "right": { "target": "pepper-grinder", "desc": "Run back to cover", "show": [ ], "conditions": [ ], "hooks": [ ] }, }, "hooks": [ ], "data": { "stats": { } } }, "in-bowl": { "id": "in-bowl", "name": "Bowl", "desc": "You're in the cereal bowl...", "move": (room) => { print(["Why did you do that?"]); }, "enter": (room) => { state.player.stats.suspicion.hidden = true; stopClassTimers("free"); startTimer({ id: "geta-eat", func: () => { if (Math.random() < 0.6) { print(["Geta scoops up a spoonful of cereal; you narrowly avoid being caught."]); return true; } else { print(["Geta scoops you up and slurps you into his maw."]); goToRoom("maw"); return false; } }, delay: 3000, loop: true, classes: [ "free" ] }); }, "exit": (room) => { }, "actions": [ ], "exits": { "ascend": { "target": "bowl", "desc": "Try to climb back out!", "show": [ ], "conditions": [ ], "hooks": [ (room, exit) => { print([ "You grab at the rim of the bowl and try to pull yourself out. Alas, your struggles are for naught; Geta easily scoops you up in his spoon and, a heartbeat later, slurps you into his sloppy jaws. You didn't stand a chance." ]); goToRoom("maw"); return false; } ] }, }, "hooks": [ ], "data": { "stats": { } } }, "hand": { "id": "hand", "name": "Geta's Hand", "desc": "You've been grabbed!", "move": (room) => { }, "enter": (room) => { stopClassTimers("free"); state.player.stats.suspicion.hidden = true; state.geta.handTicksLeft = 2 + Math.floor(Math.random() * 2); startTimer({ id: "geta-hand-actions", func: () => { if (state.geta.handTicksLeft == 0) { print(["In you go!"]); goToRoom("maw"); return false; } else { print(["Geta teases you"]); state.geta.handTicksLeft -= 1; return Math.random() * 2000 + 4000; } }, delay: 5000, loop: true, classes: [ ] }); }, "exit": (room) => { }, "actions": [ ], "exits": { }, "hooks": [ ], "data": { "stats": { } } }, "maw": { "id": "maw", "name": "Geta's Maw", "desc": "You've been slurped up into the fox's " + word.foul + " jaws", "move": (room) => { }, "enter": (room) => { state.player.stats.suspicion.hidden = true; stopClassTimers("free"); state.player.stats.stamina.hidden = false; state.player.stats.mawPos.hidden = false; state.geta.slurps = 0; state.geta.chews = 0; state.geta.swallowsLeft = 3 + Math.floor(Math.random() * 3); state.geta.mawMovement = 1; print(["You slip into Geta's maw; the atmosphere is " + word.disgusting + ". He'll swallow you alive if you slip too far back, but crawl too far forward, and you'll meet his fangs..."]) startTimer({ id: "maw-stamina", func: () => { changeStat("stamina", 0.1); return true; }, delay: 1000 / 60, loop: true, classes: [ "maw-struggle" ] }); startTimer({ id: "maw-random-movement", func: () => { const time = new Date().getTime(); const movementFactor = (state.geta.mawMovement + limbsLost()); const fastPart = Math.sin(time / 200) / 1600 / 3; const slowPart = Math.sin(time / 1000) / 1600; changeStat("mawPos", movementFactor * (fastPart + slowPart)); if (getStat("mawPos") <= 0.02) { print(["You slip too far back. Geta doesn't even have to try to swallow you like the food you are; you're lost from the world, buried in his hot, tight throat."]); goToRoom("throat"); return false; } else if (getStat("mawPos") >= 0.98) { print(["Geta's jaws close like a falling guillotine's blade. You're crushed like an insect. A sharp gulp drags you down to the fox's guts."]); playSfx("sfx/swallow.ogg"); changeStat("health", -90); goToRoom("throat"); state.player.flags.throatSurrender = true; return false; } return true; }, delay: 1000 / 60, loop: true, classes: [ "maw-struggle" ] }); startTimer({ id: "maw-struggle", func: () => { if (state.geta.swallowsLeft <= 0) { print(["Geta picks up his bowl of cereal and drinks it down, swallowing you in the process."]); state.geta.swallowsLeft = -1; goToRoom("throat"); return false; } let choice; if (Math.random() < 0.2) { const choices = [ "slosh", "tilt-back", "shove", ]; choice = choices[Math.floor(Math.random() * choices.length)]; } else if (Math.random() > state.geta.slurps / 3) { choice = "slurp"; } else if (state.geta.chews - Math.floor(Math.random() * 3) < state.geta.slurps) { choice = "chew"; } else { choice = "swallow"; } if (choice == "swallow") { if (getStat("mawPos") <= 0.15) { print(["You're too far back. The fox swallows a mouthful of cereal, taking you with it."]); goToRoom("throat"); return false; } else { printRandom([ ["A light swallow drags a lump of chewed-up cereal into Geta's " + word.fatal + " depths."], ["Geta swallows, dragging you closer to your demise."], ["Your captor's throat ripples as he gulps down his breakfast."] ]); statLerp("mawPos", -0.25, 500); state.geta.slurps = 0; state.geta.chews = 0; state.geta.swallowsLeft -= 1; return Math.random() * 1500 + 1500; } } else if (choice == "slurp") { statLerp("mawPos", -0.1, 250); printRandom([ ["A spoonful of cereal slips into the fox's sloppy maw."], ["Geta slurps up some more of his breakfast."], ["You're shoved back a bit as Geta slurps up more cereal."] ]); state.geta.slurps += 1; return Math.random() * 1000 + 2500; } else if (choice == "chew") { if (getStat("mawPos") >= 0.85) { const limb = randomBodyPart(); state.player.limbs[limb] = false; const limbName = limbs[limb]; if (limb == "head") { print(["Geta's jaws crush down on your head. You die."]); changeStat("health", -100); goToRoom("stomach"); } else { print(["You scream in pain as your " + limbName + " is shattered by the fox's jaws"]); changeStat("health", -40); return true; } } else { printRandom([ ["Cruel fangs crush down on the food around you."], ["Geta chews on his breakfast."], ["The fox's fangs close with a crackle-crunch of cereal."] ]); statLerp("mawPos", Math.random() / 10 - 0.05, 250); state.geta.chews += 1; return Math.random() * 500 + 1300; } } else if (choice == "slosh") { print(["Geta's tongue sloshes from side to side, throwing you around his maw like a ship in a storm."]); state.geta.mawMovement = 3; startTimer({ id: "maw-slosh-end", func: () => { state.geta.mawMovement = 1; print(["The sloshing ends."]); return true; }, delay: 4000, loop: false, classes: [ "maw-struggle" ] }); return Math.random() * 1500 + 4500; } else if (choice == "tilt-back") { print(["Geta tilts his head back, sending rivults of slobber flowing down into that yawning gullet."]); state.geta.mawMovement = 0.2; statLerp("mawPos", -1, 4000); startTimer({ id: "maw-tilt-text", func: () => { state.geta.mawMovement = 1; print(["The fox's muzzle tilts back down as he SWALLOWS hard."]); statLerp("mawPos", -0.3, 500); state.geta.swallowsLeft -= 1; state.geta.slurps = 0; state.geta.chews = 0; return true; }, delay: 4000, loop: false, classes: [ "maw-struggle" ] }); return 5000 + Math.random() * 1000; } else if (choice == "shove") { print(["Geta's tongue lurches forward, shoving you towards the front of his maw!"]); statLerp("mawPos", 0.2, 500); return 2000 + Math.random() * 1000; } }, delay: 0, loop: true, classes: [ "maw-struggle" ] }); startTimer({ id: "maw-taunts", func: () => { printRandom([ ["\"Did you really think I wouldn't notice you?\""], ["\"You're going to feel good dying in my guts.\""], ["\"I could just crush you...but where's the fun in that?\""] ]); return Math.random() * 5000 + 5000; }, delay: 5000, loop: true, classes: [ "maw-struggle" ] }); }, "exit": (room) => { state.player.stats.stamina.hidden = true; state.player.stats.mawPos.hidden = true; stopClassTimers("maw-struggle"); }, "actions": [ { name: "Struggle", desc: "Pull yourself away from the fox's throat! Just don't go too far forward...", execute: (room) => { if (getStat("stamina") < 25) { print(["You're too tired..."]); } else { print(["You drag yourself forward"]); changeStat("stamina", -25); statLerp("mawPos", 0.15 + Math.random() * 0.05, 250); } }, show: [ ], conditions: [ ] }, { name: "Slip Back", desc: "Slide back towards Geta's gullet", execute: (room) => { if (Math.random() * 25 > getStat("stamina")) { print(["You try to shimmy back an inch or two, but your sore muscles give way; you slide back perilously far!"]); statLerp("mawPos", -0.3 - Math.random() * 0.25, 250); } else if (Math.random() < 0.9) { print(["You let yourself slip back."]); statLerp("mawPos", -0.2 - Math.random() * 0.1, 250); } else { print(["You lose your grip, sliding back quite far!"]); statLerp("mawPos", -0.3 - Math.random() * 0.15, 250); } }, show: [ ], conditions: [ ] }, { name: "Dive In", desc: "Throw yourself towards the fox's throat", execute: (room) => { print(["Resigned to your fate, you toss yourself into Geta's throat. He seems surprised by your eagerness to submit, but swallows you all the same."]); goToRoom("throat"); }, show: [ ], conditions: [ ] }, ], "exits": { }, "hooks": [ ], "data": { "stats": { } } }, "throat": { "id": "throat", "name": "Geta's Gullet", "desc": "GULP!", "move": (room) => { }, "enter": (room) => { playSfx("sfx/swallow.ogg"); playLoop("loop/stomach.ogg", 0.3); state.player.stats.stamina.hidden = false; state.player.stats.throatPos.hidden = false; startTimer({ id: "throat-stamina", func: () => { changeStat("stamina", 0.03); return true; }, delay: 1000 / 60, loop: true, classes: [ "throat-struggle" ] }); state.geta.throatStage = 1; startTimer({ id: "throat-stages", func: () => { if (state.geta.throatStage / 5 < getStat("throatPos")) { state.geta.throatStage = Math.ceil(getStat("throatPos") * 5); switch (state.geta.throatStage) { case 3: print(["You're sinking into the fox's chest..."]); break; case 4: print(["Deeper, deeper still..."]); break; case 5: print(["Your grave is just a swallow or two away."]); break; default: break; } } return true; }, delay: 1000, loop: true, classes: [ "throat-struggle" ] }); startTimer({ id: "throat-descent", func: () => { if (getStat("throatPos") <= 0.01) { print(["Geta swallows HARD, cramming you back down like the food you are."]); changeStat("throatPos", 0.1); statLerp("throatPos", 0.5, 1000); } if (getStat("throatPos") >= 0.99) { goToRoom("stomach"); return false; } changeStat("throatPos", state.player.flags.throatSurrender ? 0.0005 : 0.0001); playLoop("loop/heartbeat.ogg", 0.3 + getStat("throatPos") * 0.7); return true; }, delay: 1000 / 60, loop: true, classes: [ "throat-struggle" ] }); startTimer({ id: "throat-swallows", func: () => { const choice = Math.random(); if (choice < 0.7) { print(["Geta's throat pumps you deeper"]); playSfx(pickRandom([ "sfx/gulp-1.ogg", "sfx/gulp-2.ogg", "sfx/gulp-3.ogg" ])); statLerp("throatPos", 0.1, 1250); return Math.random() * 2000 + 2000; } else if (choice < 0.85) { if (getStat("throatPos") < 0.4) { print(["A finger presses in on you from the outside. Your captor is enjoying himself...but at least it slows your descent a little."]); statLerp("throatPos", 0.05, 2000); return Math.random() * 4000 + 2000; } else { return Math.random() * 200 + 200; } } else { print(["A crushing swallow grips your body and crams you down deep."]); playSfx("sfx/big-gulp.ogg"); statLerp("throatPos", 0.3, 1500); return Math.random() * 2000 + 2000; } }, delay: 2000, loop: true, classes: [ "throat-struggle" ] }); }, "exit": (room) => { state.player.stats.stamina.hidden = true; state.player.stats.throatPos.hidden = true; print(["You slush down into Geta's stomach"]); stopClassTimers("throat-struggle"); }, "actions": [ { name: "Struggle", desc: "Try to climb back out!", execute: (room) => { if (Math.random() * 50 > getStat("stamina")) { print(["You try your best, but your sore muscles are no match."]); } else { print(["Your valiant struggles drag you a little closer to freedom."]); statLerp("throatPos", -0.15, 1000); changeStat("stamina", -20); } }, show: [ (room) => { return !state.player.flags.throatSurrender; } ], conditions: [ ] }, { name: "Give up", desc: "Dive down into Geta's stomach", execute: (room) => { print(["You submit to your predator."]); state.player.flags.throatSurrender = true; }, show: [ (room) => { return !state.player.flags.throatSurrender; } ], conditions: [ ] }, ], "exits": { }, "hooks": [ ], "data": { "stats": { } } }, "stomach": { "id": "stomach", "name": "Geta's Stomach", "desc": "Glorp", "move": (room) => { }, "enter": (room) => { playLoop("loop/stomach.ogg"); stopLoop("loop/heartbeat.ogg"); state.geta.digestionStage = 0; state.geta.acidStrength = 1; startTimer({ id: "digest-stages", func: () => { if (100 - state.geta.digestionStage * 25 - 25 > getStat("health")) { state.geta.digestionStage = Math.floor((100 - getStat("health")) / 25); console.log(state.geta.digestionStage); switch (state.geta.digestionStage) { case 1: print(["Your skin begins to tingle."]); break; case 2: print(["The stinging acids work their way into your tender body."]); break; case 3: print(["You're starting to fall apart..."]); break; default: break; } } return true; }, delay: 1000, loop: true, classes: [ "digestion" ] }); startTimer({ id: "digest-random", func: () => { const choices = [ () => { const crushed = randomBodyPart(); const name = limbs[crushed]; if (name == "head") { print(["A powerful fold of muscle grips your head, crushing it like a grape and killing you instantly."]); changeStat("health", -100); return false; } else { print(["Geta's stomach grips your " + name + " and crushes it with a horrific CRACK"]); changeStat("health", -40); return true; } }, () => { printRandom([["Geta squeezes in on his gut with both hands, sloshing you around in the sickly stew of cereal, milk, and enzymatic slime."], ["Your organic prison snarls and churns, soaking you in fresh acids and hastening your wretched demise."]]); statLerp("health", -10, 2000); return true; }, () => { if (state.geta.swallowsLeft == 0) { print(["A deep series of *glurks* rattles your bones."]); startTimer({ id: "stomach-milk", func: () => { print(["A torrent of cold milk pours into the fox's stomach."]); return false; }, delay: 3000, loop: false, classes: [ "digestion" ] }); } else if (state.geta.swallowsLeft > 0) { print(["Muffled chewing comes from far above. A moment later, you hear a wet *gluk*"]); startTimer({ id: "stomach-cereal", func: () => { print(["A slimy heap of well-chewed corn flakes splatters down around you."]); return false; }, delay: 4000, loop: false, classes: [ ] }); } else if (state.geta.swallowsLeft < 0) { print(["You hear a few light swallows."]); startTimer({ id: "stomach-coffee", func: () => { print(["Gouts of hot, bitter coffee pour into the fox's guts."]); return false; }, delay: 3000, loop: false, classes: [ ] }); } return true; }, () => { print(["\"You were barely worth eating,\" murmurs the fox. \"So small. So weak.\""]); return true; } ]; if (choices[Math.floor(Math.random() * choices.length)]()) { return Math.random() * 3000 + 3500; } else { return false; } }, delay: 5000, loop: true, classes: [ "digestion" ] }); startTimer({ id: "digest", func: () => { changeStat("health", -0.3 * state.geta.acidStrength); if (getStat("health") <= 0) { print(["You're gradually digested, merciful oblivion ending your torment in the " + word.disgusting + " depths of your captor..."]); goToRoom("digested"); return false; } return true; }, delay: 100, loop: true, classes: [ "digestion" ] }); }, "exit": (room) => { }, "actions": [ { name: "Squirm", desc: "Rub at the walls of the fox's churning stomach", execute: (room) => { printRandom([ ["You punch and kick at the walls"], ["A powerful churn grabs hold of you, stifling any attempts at struggling"], ["Your little thumps and kicks do little to faze your captor"] ]); }, show: [ ], conditions: [ ] }, { name: "Beg", desc: "Plead for your life", execute: (room) => { printRandom([ [ "\"PLEASE!\" you scream, thumping on the walls of the vulpine's gut. \"Let me out!\"", ] ]) if (Math.random() < 0.7) { print(["Your pleas fall on deaf ears."]); } else { printRandom([ ["\"Shhhh,\" growls Geta, \"you're going to die in me. Stop whimpering.\""], ["A long moment passes. \"Poor thing,\" says your captor."] ]) } }, show: [ ], conditions: [ ] }, { name: "Scream", desc: "IT HURTS", execute: (room) => { printRandom([ [ "\"Oh god, oh god, oh god,\" you wail...quivering and quaking as you're digested alive. \"GETA!\"" ], [ "A blood-curdling scream bellows from your burning lungs." ], [ "You let out a hideous wail as the fox digests you alive." ] ]); if (Math.random() < 0.5) { print(["Geta doesn't notice."]); } else { print(["A booming chuckle rocks your body."]); printRandom([ ["\"I hope you're suffering in there.\""], ["\"Pathetic little snack.\""], ["\"Ready to die?\""] ]); } }, show: [ ], conditions: [ ] }, ], "exits": { }, "hooks": [ ], "data": { "stats": { } } }, "digested": { "id": "digested", "name": "Geta's Stomach", "desc": "You're just mush now", "move": (room) => { }, "enter": (room) => { stopClassTimers("digestion"); stopTimer("clock"); state.player.stats.health.hidden = true; state.player.stats.absorption.hidden = false; startTimer({ id: "clock", func: () => { state.info.time.value += 2; state.info.time.value %= 86000; return true; }, delay: 1000 / 60, loop: true, classes: [ ] }); startTimer({ id: "passive-absorb", func: () => { changeStat("absorption", 0.0004); if (getStat("absorption") >= 1) { goToRoom("absorbed"); return false; } return true; }, delay: 1000 / 60, loop: true, classes: [ "absorption" ] }); startTimer({ id: "absorbption-random", func: () => { const result = pickRandom([ () => { print(["The fox kneads on his flattening belly"]); statLerp("absorption", 0.1, 1000); }, () => { print(["A crass belch pours from Geta's maw"]); statLerp("absorption", 0.05, 1000); }, () => { print(["Geta's guts writhe and squeeze, soaking up your digested body and crushing your acid-pitted bones"]); statLerp("absorption", 0.2, 1000); } ])(); return result ? result : Math.random() * 3000 + 4000; }, delay: 2000, loop: true, classes: [ "absorption" ] }); playSfx("sfx/digest.ogg"); }, "exit": (room) => { }, "actions": [ { name: "Gurgle", desc: "Glorp", execute: (room) => { printRandom([ ["Grrrrgle"], ["Glorp"], ["Glrrrrrrnnnnnn..."], ["Gwoooooorgle"] ]); }, show: [ ], conditions: [ ] }, ], "exits": { }, "hooks": [ ], "data": { "stats": { } } }, "absorbed": { "id": "absorbed", "name": "Geta's Fat", "desc": "You're gone.", "move": (room) => { }, "enter": (room) => { playSfx("sfx/absorb.ogg"); stopTimer("clock"); stopClassTimers("absorption"); state.player.stats.absorption.hidden = true; print(["Your erasure is completed with a dull, slimy gurgle. Geta has destroyed you."]); }, "exit": (room) => { }, "actions": [ ], "exits": { }, "hooks": [ ], "data": { "stats": { } } }, } }); })();