| @@ -1,24 +1,24 @@ | |||
| (() => { | |||
| function checkSuspicion(state, add = 0) { | |||
| const old = getStat("suspicion", state); | |||
| function checkSuspicion(add = 0) { | |||
| const old = getStat("suspicion"); | |||
| if (add >= 0) { | |||
| add *= state.info.awareness.value; | |||
| } | |||
| changeStat("suspicion", add, state); | |||
| if (getStat("suspicion", state) >= 100) { | |||
| 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", state); | |||
| goToRoom("in-bowl"); | |||
| return false; | |||
| } else if (getStat("suspicion", state) >= 75 && old < 75) { | |||
| } 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(state) { | |||
| function randomBodyPart() { | |||
| const choices = Object.entries(state.player.limbs).filter(([name, status]) => { | |||
| return status; | |||
| }).map(([name, status]) => name); | |||
| @@ -26,7 +26,7 @@ | |||
| return choices[Math.floor(Math.random() * choices.length)]; | |||
| } | |||
| function limbsLost(state) { | |||
| function limbsLost() { | |||
| return Object.entries(state.player.limbs).filter(([name, status]) => { | |||
| return !status; | |||
| }).length; | |||
| @@ -36,8 +36,8 @@ | |||
| const iterations = duration / 1000 * 60; | |||
| startTimer({ | |||
| id: id, | |||
| func: state => { | |||
| changeStat(stat, change / iterations, state); | |||
| func: () =>{ | |||
| changeStat(stat, change / iterations); | |||
| return true; | |||
| }, | |||
| delay: 1000 / 60, | |||
| @@ -45,12 +45,12 @@ | |||
| classes: [ | |||
| ] | |||
| }, state); | |||
| }); | |||
| startTimer({ | |||
| id: id + "-stopper", | |||
| func: state => { | |||
| stopTimer(id, state); | |||
| func: () =>{ | |||
| stopTimer(id); | |||
| return false; | |||
| }, | |||
| delay: duration, | |||
| @@ -58,7 +58,7 @@ | |||
| classes: [ | |||
| ] | |||
| }, state); | |||
| }); | |||
| } | |||
| @@ -81,7 +81,7 @@ | |||
| ], | |||
| "intro": { | |||
| "start": "pepper-grinder", | |||
| "setup": state => { | |||
| "setup": () =>{ | |||
| state.info.awareness = { | |||
| id: "awareness", | |||
| @@ -115,7 +115,7 @@ | |||
| startTimer({ | |||
| id: "clock", | |||
| func: state => { | |||
| func: () =>{ | |||
| state.info.time.value += 1; | |||
| state.info.time.value %= 86000; | |||
| return true; | |||
| @@ -125,12 +125,12 @@ | |||
| classes: [ | |||
| ] | |||
| }, state); | |||
| }); | |||
| startTimer({ | |||
| id: "suspicion-decay", | |||
| func: state => { | |||
| checkSuspicion(state, -0.1); | |||
| func: () =>{ | |||
| checkSuspicion(-0.1); | |||
| return true; | |||
| }, | |||
| delay: 100, | |||
| @@ -138,18 +138,18 @@ | |||
| classes: [ | |||
| "free" | |||
| ] | |||
| }, state); | |||
| }); | |||
| startTimer({ | |||
| id: "timeout", | |||
| func: state => { | |||
| 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", state); | |||
| goToRoom("maw"); | |||
| return false; | |||
| } | |||
| return true; | |||
| @@ -159,11 +159,11 @@ | |||
| classes: [ | |||
| "free" | |||
| ] | |||
| }, state); | |||
| }); | |||
| startTimer({ | |||
| id: "geta-action", | |||
| func: state => { | |||
| func: () =>{ | |||
| const random = Math.random(); | |||
| if (random < 0.7) { | |||
| @@ -175,7 +175,7 @@ | |||
| startTimer({ | |||
| id: "yawn-end", | |||
| func: state => { | |||
| func: () =>{ | |||
| print(["Geta finishes his stretch"]); | |||
| state.info.awareness.value = 1; | |||
| return true; | |||
| @@ -185,7 +185,7 @@ | |||
| classes: [ | |||
| "free" | |||
| ] | |||
| }, state); | |||
| }); | |||
| return Math.random() * 3000 + 5000 | |||
| } else { | |||
| @@ -194,7 +194,7 @@ | |||
| startTimer({ | |||
| id: "squint-end", | |||
| func: state => { | |||
| func: () =>{ | |||
| print(["He goes back to his breakfast."]); | |||
| state.info.awareness.value = 1; | |||
| return true; | |||
| @@ -204,7 +204,7 @@ | |||
| classes: [ | |||
| "free" | |||
| ] | |||
| }, state); | |||
| }); | |||
| return Math.random() * 1000 + 6000 | |||
| @@ -215,12 +215,12 @@ | |||
| classes: [ | |||
| "free" | |||
| ] | |||
| }, state); | |||
| }); | |||
| }, | |||
| "intro": state => { | |||
| "intro": () =>{ | |||
| print(["Game started", newline, "Exposition goes here later."]); | |||
| } | |||
| }, | |||
| @@ -235,33 +235,33 @@ | |||
| "id": "pepper-grinder", | |||
| "name": "Pepper Grinder", | |||
| "desc": "You're hiding behind a pepper grinder", | |||
| "move": (room, state) => { | |||
| "move": (room) => { | |||
| print(["You dart over to the pepper grinder, which looms over you like a greatwood."]); | |||
| }, | |||
| "enter": (room, state) => { | |||
| "enter": (room) => { | |||
| }, | |||
| "exit": (room, state) => { | |||
| "exit": (room) => { | |||
| }, | |||
| "actions": [ | |||
| { | |||
| name: "Tap", | |||
| desc: "Bang on the pepper shaker", | |||
| execute: (room, state) => { | |||
| execute: (room) => { | |||
| print(["You thump the pepper shaker, making a dull thud."]); | |||
| const safe = checkSuspicion(state, 25); | |||
| const safe = checkSuspicion(25); | |||
| if (safe && getStat("suspicion", state) > 50) { | |||
| 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: state => { | |||
| func: () =>{ | |||
| if (state.player.location == "pepper-grinder") { | |||
| print(["He catches you.", newline, "You're tossed into the fox's jaws."]); | |||
| goToRoom("maw", state); | |||
| goToRoom("maw"); | |||
| } else { | |||
| print(["You evaded the fox."]); | |||
| } | |||
| @@ -271,7 +271,7 @@ | |||
| classes: [ | |||
| "free" | |||
| ] | |||
| }, state); | |||
| }); | |||
| } | |||
| }, | |||
| @@ -285,7 +285,7 @@ | |||
| { | |||
| name: "Wait", | |||
| desc: "Wait for the fox to finish his breakfast. Surely you'll be able to escape after that...right?", | |||
| execute: (room, state) => { | |||
| execute: (room) => { | |||
| state.info.time.value = 60 * 60 * 7 + 60 * 20; | |||
| }, | |||
| show: [ | |||
| @@ -307,8 +307,8 @@ | |||
| ], | |||
| "hooks": [ | |||
| (room, exit, state) => { | |||
| return checkSuspicion(state, 10); | |||
| (room, exit) => { | |||
| return checkSuspicion(10); | |||
| } | |||
| ] | |||
| @@ -340,13 +340,13 @@ | |||
| "id": "bowl", | |||
| "name": "Behind the Bowl", | |||
| "desc": "You're crouched behind Geta's bowl of cereal", | |||
| "move": (room, state) => { | |||
| "move": (room) => { | |||
| print(["You scurry up to the looming bowl, staying low and out of Geta's sight."]); | |||
| }, | |||
| "enter": (room, state) => { | |||
| "enter": (room) => { | |||
| }, | |||
| "exit": (room, state) => { | |||
| "exit": (room) => { | |||
| }, | |||
| "actions": [ | |||
| @@ -376,8 +376,8 @@ | |||
| ], | |||
| "hooks": [ | |||
| (room, exit, state) => { | |||
| return checkSuspicion(state, 15); | |||
| (room, exit) => { | |||
| return checkSuspicion(15); | |||
| } | |||
| ] | |||
| }, | |||
| @@ -395,14 +395,14 @@ | |||
| "id": "table", | |||
| "name": "Table", | |||
| "desc": "You're out in the open!", | |||
| "move": (room, state) => { | |||
| "move": (room) => { | |||
| }, | |||
| "enter": (room, state) => { | |||
| "enter": (room) => { | |||
| startTimer({ | |||
| id: "table-suspicion", | |||
| func: state => { | |||
| checkSuspicion(state, 1.5); | |||
| func: () =>{ | |||
| checkSuspicion(1.5); | |||
| return true; | |||
| }, | |||
| delay: 100, | |||
| @@ -410,11 +410,11 @@ | |||
| classes: [ | |||
| "free" | |||
| ] | |||
| }, state); | |||
| }); | |||
| }, | |||
| "exit": (room, state) => { | |||
| stopTimer("table-suspicion", state); | |||
| "exit": (room) => { | |||
| stopTimer("table-suspicion"); | |||
| }, | |||
| "actions": [ | |||
| @@ -447,21 +447,21 @@ | |||
| "id": "in-bowl", | |||
| "name": "Bowl", | |||
| "desc": "You're in the cereal bowl...", | |||
| "move": (room, state) => { | |||
| "move": (room) => { | |||
| print(["Why did you do that?"]); | |||
| }, | |||
| "enter": (room, state) => { | |||
| stopClassTimers("free", state); | |||
| "enter": (room) => { | |||
| stopClassTimers("free"); | |||
| startTimer({ | |||
| id: "geta-eat", | |||
| func: state => { | |||
| 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", state); | |||
| goToRoom("maw"); | |||
| return false; | |||
| } | |||
| @@ -471,10 +471,10 @@ | |||
| classes: [ | |||
| "free" | |||
| ] | |||
| }, state); | |||
| }); | |||
| }, | |||
| "exit": (room, state) => { | |||
| "exit": (room) => { | |||
| }, | |||
| "actions": [ | |||
| @@ -491,11 +491,11 @@ | |||
| ], | |||
| "hooks": [ | |||
| (room, exit, state) => { | |||
| (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", state); | |||
| goToRoom("maw"); | |||
| return false; | |||
| } | |||
| @@ -515,11 +515,11 @@ | |||
| "id": "maw", | |||
| "name": "Geta's Maw", | |||
| "desc": "You've been slurped up into the fox's jaws", | |||
| "move": (room, state) => { | |||
| "move": (room) => { | |||
| }, | |||
| "enter": (room, state) => { | |||
| stopClassTimers("free", state); | |||
| "enter": (room) => { | |||
| stopClassTimers("free"); | |||
| state.player.stats.mawPos.hidden = false; | |||
| @@ -530,21 +530,21 @@ | |||
| startTimer({ | |||
| id: "maw-random-movement", | |||
| func: state => { | |||
| func: () =>{ | |||
| const time = new Date().getTime(); | |||
| const movementFactor = (state.geta.mawMovement + limbsLost(state)); | |||
| 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), state); | |||
| changeStat("mawPos", movementFactor * (fastPart + slowPart)); | |||
| if (getStat("mawPos", state) <= 0.02) { | |||
| 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."]); | |||
| goToRoom("throat", state); | |||
| goToRoom("throat"); | |||
| return false; | |||
| } else if (getStat("mawPos", state) >= 0.98) { | |||
| } 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."]); | |||
| changeStat("health", -90, state); | |||
| goToRoom("stomach", state); | |||
| changeStat("health", -90); | |||
| goToRoom("stomach"); | |||
| return false; | |||
| } | |||
| @@ -555,15 +555,15 @@ | |||
| classes: [ | |||
| "maw-struggle" | |||
| ] | |||
| }, state); | |||
| }); | |||
| startTimer({ | |||
| id: "maw-struggle", | |||
| func: state => { | |||
| func: () =>{ | |||
| if (state.geta.swallowsLeft <= 0) { | |||
| print(["Geta picks up his bowl of cereal and drinks it down, swallowing you in the process."]); | |||
| goToRoom("throat", state); | |||
| goToRoom("throat"); | |||
| return false; | |||
| } | |||
| @@ -580,9 +580,9 @@ | |||
| } | |||
| if (choice == "swallow") { | |||
| if (getStat("mawPos", state) < 0.15) { | |||
| if (getStat("mawPos") < 0.15) { | |||
| print(["Swallowed!"]); | |||
| goToRoom("throat", state); | |||
| goToRoom("throat"); | |||
| return false; | |||
| } else { | |||
| print(["Swallows"]); | |||
| @@ -599,18 +599,18 @@ | |||
| state.geta.slurps += 1; | |||
| return Math.random() * 1000 + 1500; | |||
| } else if (choice == "chew") { | |||
| if (getStat("mawPos", state) > 0.85) { | |||
| const limb = randomBodyPart(state); | |||
| if (getStat("mawPos") > 0.85) { | |||
| const limb = randomBodyPart(); | |||
| state.player.limbs[limb] = false; | |||
| const limbName = limbs[limb]; | |||
| if (limb == "head") { | |||
| print(["He chewed your head :((("]); | |||
| changeStat("health", -100, state); | |||
| goToRoom("stomach", state); | |||
| changeStat("health", -100); | |||
| goToRoom("stomach"); | |||
| } else { | |||
| print(["He chewed your " + limbName + " :("]); | |||
| changeStat("health", -40, state); | |||
| changeStat("health", -40); | |||
| return true; | |||
| } | |||
| @@ -624,7 +624,7 @@ | |||
| state.geta.mawMovement = 3; | |||
| startTimer({ | |||
| id: "maw-slosh-end", | |||
| func: state => { | |||
| func: () =>{ | |||
| state.geta.mawMovement = 1; | |||
| print(["The sloshing ends."]); | |||
| return true; | |||
| @@ -634,7 +634,7 @@ | |||
| classes: [ | |||
| "maw-struggle" | |||
| ] | |||
| }, state); | |||
| }); | |||
| return Math.random() * 1500 + 4500; | |||
| } | |||
| @@ -644,11 +644,11 @@ | |||
| classes: [ | |||
| "maw-struggle" | |||
| ] | |||
| }, state); | |||
| }); | |||
| startTimer({ | |||
| id: "maw-taunts", | |||
| func: state => { | |||
| func: () =>{ | |||
| printRandom([ | |||
| ["\"Did you really think I wouldn't notice you?\""], | |||
| ["\"You're going to feel good dying in my guts.\""], | |||
| @@ -662,18 +662,18 @@ | |||
| classes: [ | |||
| "maw-struggle" | |||
| ] | |||
| }, state); | |||
| }); | |||
| }, | |||
| "exit": (room, state) => { | |||
| "exit": (room) => { | |||
| }, | |||
| "actions": [ | |||
| { | |||
| name: "Struggle", | |||
| desc: "Pull yourself away from the fox's throat! Just don't go too far forward...", | |||
| execute: (room, state) => { | |||
| execute: (room) => { | |||
| print(["You drag yourself forward"]); | |||
| statLerp("maw-swallow", "mawPos", 0.15 + Math.random() * 0.05, 250); | |||
| }, | |||
| @@ -687,7 +687,7 @@ | |||
| { | |||
| name: "Slip Back", | |||
| desc: "Slide back towards Geta's gullet", | |||
| execute: (room, state) => { | |||
| execute: (room) => { | |||
| if (Math.random() < 0.9){ | |||
| print(["You let yourself slip back."]); | |||
| statLerp("maw-swallow", "mawPos", -0.2 - Math.random() * 0.1, 250); | |||
| @@ -721,20 +721,20 @@ | |||
| "id": "throat", | |||
| "name": "Geta's Gullet", | |||
| "desc": "GULP!", | |||
| "move": (room, state) => { | |||
| "move": (room) => { | |||
| }, | |||
| "enter": (room, state) => { | |||
| "enter": (room) => { | |||
| state.player.stats.mawPos.hidden = true; | |||
| stopClassTimers("maw-struggle", state); | |||
| stopClassTimers("maw-struggle"); | |||
| startTimer({ | |||
| id: "throat-swallow", | |||
| func: state => { | |||
| func: () =>{ | |||
| print(["You slush down into Geta's stomach"]); | |||
| goToRoom("stomach", state); | |||
| goToRoom("stomach"); | |||
| return true; | |||
| }, | |||
| delay: 7000, | |||
| @@ -742,17 +742,17 @@ | |||
| classes: [ | |||
| ] | |||
| }, state); | |||
| }); | |||
| }, | |||
| "exit": (room, state) => { | |||
| "exit": (room) => { | |||
| }, | |||
| "actions": [ | |||
| { | |||
| name: "Struggle", | |||
| desc: "Try to climb back out!", | |||
| execute: (room, state) => { | |||
| execute: (room) => { | |||
| print(["Nope"]); | |||
| }, | |||
| show: [ | |||
| @@ -765,10 +765,10 @@ | |||
| { | |||
| name: "Give up", | |||
| desc: "Dive down into Geta's stomach", | |||
| execute: (room, state) => { | |||
| execute: (room) => { | |||
| print(["You submit to your predator."]); | |||
| goToRoom("stomach", state); | |||
| stopTimer("throat-swallow", state); | |||
| goToRoom("stomach"); | |||
| stopTimer("throat-swallow"); | |||
| }, | |||
| show: [ | |||
| @@ -794,37 +794,37 @@ | |||
| "id": "stomach", | |||
| "name": "Geta's Stomach", | |||
| "desc": "Glorp", | |||
| "move": (room, state) => { | |||
| "move": (room) => { | |||
| }, | |||
| "enter": (room, state) => { | |||
| "enter": (room) => { | |||
| playLoop("loop/stomach.ogg"); | |||
| stopClassTimers("maw-struggle", state); | |||
| stopClassTimers("maw-struggle"); | |||
| state.geta.acidStrength = 1; | |||
| startTimer({ | |||
| id: "digest-random", | |||
| func: state => { | |||
| func: () =>{ | |||
| const choices = [ | |||
| () => { | |||
| const crushed = randomBodyPart(state); | |||
| 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, state); | |||
| changeStat("health", -100); | |||
| return false; | |||
| } else { | |||
| print(["Geta's stomach grips your " + name + " and crushes it with a horrific CRACK"]); | |||
| changeStat("health", -40, state); | |||
| changeStat("health", -40); | |||
| return true; | |||
| } | |||
| }, | |||
| () => { | |||
| print(["Geta squeezes in on his gut with both hands, sloshing you around in the sickly stew of cereal, milk, and enzymatic slime."]); | |||
| changeStat("health", -10, state); | |||
| changeStat("health", -10); | |||
| return true; | |||
| }, | |||
| () => { | |||
| @@ -846,16 +846,16 @@ | |||
| classes: [ | |||
| "digestion" | |||
| ] | |||
| }, state); | |||
| }); | |||
| startTimer({ | |||
| id: "digest", | |||
| func: state => { | |||
| changeStat("health", -0.3 * state.geta.acidStrength, state); | |||
| func: () =>{ | |||
| changeStat("health", -0.3 * state.geta.acidStrength); | |||
| if (getStat("health", state) <= 0) { | |||
| if (getStat("health") <= 0) { | |||
| print(["You're digested before too long."]); | |||
| goToRoom("digested", state); | |||
| goToRoom("digested"); | |||
| return false; | |||
| } | |||
| @@ -867,17 +867,17 @@ | |||
| classes: [ | |||
| "digestion" | |||
| ] | |||
| }, state); | |||
| }); | |||
| }, | |||
| "exit": (room, state) => { | |||
| "exit": (room) => { | |||
| }, | |||
| "actions": [ | |||
| { | |||
| name: "Squirm", | |||
| desc: "Rub at the walls of the fox's churning stomach", | |||
| execute: (room, state) => { | |||
| execute: (room) => { | |||
| printRandom([ | |||
| ["You punch and kick at the walls"], | |||
| ["A powerful churn grabs hold of you, stifling any attempts at struggling"], | |||
| @@ -908,20 +908,20 @@ | |||
| "id": "digested", | |||
| "name": "Fat", | |||
| "desc": "You're just fat now", | |||
| "move": (room, state) => { | |||
| "move": (room) => { | |||
| }, | |||
| "enter": (room, state) => { | |||
| stopClassTimers("digestion", state); | |||
| "enter": (room) => { | |||
| stopClassTimers("digestion"); | |||
| }, | |||
| "exit": (room, state) => { | |||
| "exit": (room) => { | |||
| }, | |||
| "actions": [ | |||
| { | |||
| name: "Gurgle", | |||
| desc: "Glorp", | |||
| execute: (room, state) => { | |||
| execute: (room) => { | |||
| printRandom([ | |||
| ["Grrrrgle"], | |||
| ["Glorp"], | |||