(() => {
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(["\"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) => {
},
"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": {
}
}
},
}
});
})();