From e0585b5ddf787441e6978d7a1317b176943d3c78 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Mon, 25 May 2020 17:29:28 -0400 Subject: [PATCH] Switch to 3-space indentation --- .vscode/settings.json | 4 + stories/geta-unaware.js | 2796 +++++++++++++++++++-------------------- 2 files changed, 1402 insertions(+), 1398 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8280043 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.tabSize": 3, + "editor.detectIndentation": false +} \ No newline at end of file diff --git a/stories/geta-unaware.js b/stories/geta-unaware.js index e645b25..909d2d9 100644 --- a/stories/geta-unaware.js +++ b/stories/geta-unaware.js @@ -1,1495 +1,1495 @@ (() => { - 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"); + 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; - } 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" - ] - }); - + }, + 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 = {}; - }, - "intro": () => { - print(["\"Urgh...\", you moan. \"My head...\"", - newline, - "You blink and rub your eyes. You're propped up on something hard and smooth; the ground beneath you is just as uncomfortable. The faint aroma of fried food drifts on the wind. A long moment passes before your eyes clear enough to see — and when they do clear, you see something most distressing!", - newline, - "You're slumped on a kitchen table with your back to a towering pepper mill. You can't be more than an inch tall; a stray peppercorn is as large as a volleyball.", - ]); + 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 } - }, - "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" - ] - }); - - } + 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; }, - show: [ - - ], - conditions: [ - + delay: 5000, + loop: false, + classes: [ + "free" ] - }, - { - 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: [ + }); + return Math.random() * 3000 + 5000 - ], - conditions: [ + } 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" ] - }, - ], - "exits": { - "up": { - "target": "bowl", - "desc": "Walk up to the cereal bowl", - "show": [ - - ], - "conditions": [ - - ], - "hooks": [ - (room, exit) => { - return checkSuspicion(10); - } + }); + + return Math.random() * 1000 + 6000 + + } + }, + delay: 5000, + loop: true, + classes: [ + "free" + ] + }); + + + + }, + "intro": () => { + print(["\"Urgh...\", you moan. \"My head...\"", + newline, + "You blink and rub your eyes. You're propped up on something hard and smooth; the ground beneath you is just as uncomfortable. The faint aroma of fried food drifts on the wind. A long moment passes before your eyes clear enough to see — and when they do clear, you see something most distressing!", + newline, + "You're slumped on a kitchen table with your back to a towering pepper mill. You can't be more than an inch tall; a stray peppercorn is as large as a volleyball.", + ]); + } + }, + "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) => { - ] - }, - "left": { - "target": "table", - "desc": "Run out into the open", - "show": [ + }, + "exit": (room) => { - ], - "conditions": [ + }, + "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": [ - ], - "hooks": [ + ], + "data": { + "stats": { - ] - }, - }, - "hooks": [ + } + } + }, + "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) => { - ], - "data": { - "stats": { + }, + "exit": (room) => { - } - } }, - "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": [ + "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": [ - ], - "conditions": [ + ], + "data": { + "stats": { - ], - "hooks": [ + } + } + }, + "table": { + "id": "table", + "name": "Table", + "desc": "You're out in the open!", + "move": (room) => { - ] - }, - "down": { - "target": "pepper-grinder", - "desc": "Run back behind the pepper grinder", - "show": [ + }, + "enter": (room) => { + startTimer({ + id: "table-suspicion", + func: () => { + checkSuspicion(1.5); + return true; + }, + delay: 100, + loop: true, + classes: [ + "free" + ] + }); - ], - "conditions": [ + }, + "exit": (room) => { + stopTimer("table-suspicion"); + }, + "actions": [ - ], - "hooks": [ - (room, exit) => { - return checkSuspicion(15); - } - ] - }, - }, - "hooks": [ + ], + "exits": { + "right": { + "target": "pepper-grinder", + "desc": "Run back to cover", + "show": [ + + ], + "conditions": [ - ], - "data": { - "stats": { + ], + "hooks": [ - } - } + ] + }, }, - "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" - ] - }); + "hooks": [ - }, - "exit": (room) => { - stopTimer("table-suspicion"); - }, - "actions": [ + ], + "data": { + "stats": { - ], - "exits": { - "right": { - "target": "pepper-grinder", - "desc": "Run back to cover", - "show": [ + } + } + }, + "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" + ] + }); - ], - "conditions": [ + }, + "exit": (room) => { - ], - "hooks": [ + }, + "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": [ - ] - }, - }, - "hooks": [ + ], + "data": { + "stats": { - ], - "data": { - "stats": { + } + } + }, + "hand": { + "id": "hand", + "name": "Geta's Hand", + "desc": "You've been grabbed!", + "move": (room) => { - } - } }, - "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" - ] - }); + "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": [ + }, + "exit": (room) => { - ], - "exits": { - "ascend": { - "target": "bowl", - "desc": "Try to climb back out!", - "show": [ + }, + "actions": [ - ], - "conditions": [ + ], + "exits": { - ], - "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": [ - ] - }, - }, - "hooks": [ + ], + "data": { + "stats": { - ], - "data": { - "stats": { + } + } + }, + "maw": { + "id": "maw", + "name": "Geta's Maw", + "desc": "You've been slurped up into the fox's " + word.foul + " jaws", + "move": (room) => { - } - } }, - "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; + "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 { - print(["Geta teases you"]); - state.geta.handTicksLeft -= 1; - return Math.random() * 2000 + 4000; + 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; } - }, - delay: 5000, - loop: true, - classes: [ - - ] - }); - - }, - "exit": (room) => { - - }, - "actions": [ + } 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; + } - ], - "exits": { - - }, - "hooks": [ + } 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" + ] + }); - ], - "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: [ + "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": { - ] - }, - { - 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); - } + }, + "hooks": [ - }, - show: [ + ], + "data": { + "stats": { - ], - conditions: [ + } + } + }, + "throat": { + "id": "throat", + "name": "Geta's Gullet", + "desc": "GULP!", + "move": (room) => { - ] - }, - { - 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: [ + }, + "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; + } - ], - conditions: [ + } 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; + } - ] - }, - ], - "exits": { + }, + delay: 2000, + loop: true, + classes: [ + "throat-struggle" + ] + }); - }, - "hooks": [ - ], - "data": { - "stats": { + }, + "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": { - } - } }, - "throat": { - "id": "throat", - "name": "Geta's Gullet", - "desc": "GULP!", - "move": (room) => { + "hooks": [ - }, - "enter": (room) => { + ], + "data": { + "stats": { - playSfx("sfx/swallow.ogg"); - playLoop("loop/stomach.ogg", 0.3); + } + } + }, + "stomach": { + "id": "stomach", + "name": "Geta's Stomach", + "desc": "Glorp", + "move": (room) => { - state.player.stats.stamina.hidden = false; - state.player.stats.throatPos.hidden = false; + }, + "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; + } - startTimer({ - id: "throat-stamina", - func: () => { - changeStat("stamina", 0.03); - return true; }, - delay: 1000 / 60, - loop: true, - classes: [ - "throat-struggle" - ] - }); + () => { + 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: [ - 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; + return true; }, - delay: 1000 / 60, - loop: true, - classes: [ - "throat-struggle" - ] - }); - - startTimer({ - id: "throat-swallows", - func: () => { + () => { + 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" + ] + }); - 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; - } + }, + "exit": (room) => { - }, - delay: 2000, - loop: true, - classes: [ - "throat-struggle" + }, + "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!\"", ] - }); - - - }, - "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; - } + ]) + + 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!\"" ], - 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; - } + [ + "A blood-curdling scream bellows from your burning lungs." ], - conditions: [ - + [ + "You let out a hideous wail as the fox digests you alive." ] - }, - ], - "exits": { - - }, - "hooks": [ - - ], - "data": { - "stats": { + ]); + + 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": { - } - } }, - "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); + "hooks": [ - 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; - } + ], + "data": { + "stats": { - 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: [ + } + } + }, + "digested": { + "id": "digested", + "name": "Geta's Stomach", + "desc": "You're just mush now", + "move": (room) => { - ] - }, - { - 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."] - ]) - } + }, + "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); }, - 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?\""] - ]); - } + () => { + print(["A crass belch pours from Geta's maw"]); + statLerp("absorption", 0.05, 1000); }, - show: [ + () => { + print(["Geta's guts writhe and squeeze, soaking up your digested body and crushing your acid-pitted bones"]); + statLerp("absorption", 0.2, 1000); + } + ])(); - ], - conditions: [ + return result ? result : Math.random() * 3000 + 4000; + }, + delay: 2000, + loop: true, + classes: [ + "absorption" + ] + }); - ] - }, - ], - "exits": { - }, - "hooks": [ - ], - "data": { - "stats": { + playSfx("sfx/digest.ogg"); + }, + "exit": (room) => { - } - } }, - "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: [ + "actions": [ + { + name: "Gurgle", + desc: "Glorp", + execute: (room) => { + printRandom([ + ["Grrrrgle"], + ["Glorp"], + ["Glrrrrrrnnnnnn..."], + ["Gwoooooorgle"] + ]); + }, + show: [ + + ], + conditions: [ + + ] + }, + ], + "exits": { - ] - }); + }, + "hooks": [ - startTimer({ - id: "passive-absorb", - func: () => { - changeStat("absorption", 0.0004); + ], + "data": { + "stats": { - if (getStat("absorption") >= 1) { - goToRoom("absorbed"); - return false; - } - return true; - }, - delay: 1000 / 60, - loop: true, - classes: [ - "absorption" - ] - }); + } + } + }, + "absorbed": { + "id": "absorbed", + "name": "Geta's Fat", + "desc": "You're gone.", + "move": (room) => { - 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: [ + }, + "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) => { - ], - conditions: [ + }, + "actions": [ - ] - }, - ], - "exits": { + ], + "exits": { - }, - "hooks": [ + }, + "hooks": [ - ], - "data": { - "stats": { + ], + "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": { - - } - } - }, - } - }); + } + } + }, + } + }); })(); \ No newline at end of file