|  | (() => {
    function checkSuspicion(state, add = 0) {
        const old = getStat("suspicion", state);
        if (add >= 0) {
            add *= state.info.awareness.value;
        }
        changeStat("suspicion", add, state);
        if (getStat("suspicion", state) >= 100) {
            print(["Geta spots you!", "You're snatched up and tossed into the fox's bowl of cereal."]);
            goToRoom("in-bowl", state);
            return false;
        } else if (getStat("suspicion", state) >= 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) {
        const choices = Object.entries(state.player.limbs).filter(([name, status]) => {
            return status;
        }).map(([name, status]) => name);
        return choices[Math.floor(Math.random() * choices.length)];
    }
    const limbs = {
        head: "head",
        leftArm: "left arm",
        rightArm: "right arm",
        leftLeg: "left leg",
        rightLeg: "right leg"
    };
    stories.push({
        "id": "geta-unaware",
        "name": "Geta's Breakfast",
        "tags": [
            "Player Prey",
            "Digestion",
            "Macro/Micro",
            "Hard Vore"
        ],
        "intro": {
            "start": "pepper-grinder",
            "setup": state => {
                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, color: "rgb(255,55,55)" };
                state.player.stats.suspicion = { name: "Suspicion", type: "meter", value: 0, min: 0, max: 100, color: "rgb(100,100,100)" };
                state.player.stats.mawPos = { "name": "Struggle", "type": "meter", "value": 0.5, "min": 0, "max": 1, "color": "rgb(0,255,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.rightLef = true;
                startTimer({
                    id: "clock",
                    func: state => {
                        state.info.time.value += 1;
                        state.info.time.value %= 86000;
                        return true;
                    },
                    delay: 1000,
                    loop: true,
                    classes: [
                    ]
                }, state);
                startTimer({
                    id: "suspicion-decay",
                    func: state => {
                        checkSuspicion(state, -0.1);
                        return true;
                    },
                    delay: 100,
                    loop: true,
                    classes: [
                        "free"
                    ]
                }, state);
                startTimer({
                    id: "timeout",
                    func: state => {
                        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);
                            return false;
                        }
                        return true;
                    },
                    delay: 1000,
                    loop: true,
                    classes: [
                        "free"
                    ]
                }, state);
                startTimer({
                    id: "geta-action",
                    func: state => {
                        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: state => {
                                    print(["Geta finishes his stretch"]);
                                    state.info.awareness.value = 1;
                                    return true;
                                },
                                delay: 5000,
                                loop: false,
                                classes: [
                                    "free"
                                ]
                            }, state);
                            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: state => {
                                    print(["He goes back to his breakfast."]);
                                    state.info.awareness.value = 1;
                                    return true;
                                },
                                delay: 5000,
                                loop: false,
                                classes: [
                                    "free"
                                ]
                            }, state);
                            return Math.random() * 1000 + 6000
                        }
                    },
                    delay: 5000,
                    loop: true,
                    classes: [
                        "free"
                    ]
                }, state);
            },
            "intro": state => {
                print(["Game started", newline, "Exposition goes here later."]);
            }
        },
        "sounds": [
            "loop/stomach.ogg"
        ],
        "preload": [
        ],
        "world": {
            "pepper-grinder": {
                "id": "pepper-grinder",
                "name": "Pepper Grinder",
                "desc": "You're hiding behind a pepper grinder",
                "move": (room, state) => {
                    print(["You dart over to the pepper grinder, which looms over you like a greatwood."]);
                },
                "enter": (room, state) => {
                },
                "exit": (room, state) => {
                },
                "actions": [
                    {
                        name: "Tap",
                        desc: "Bang on the pepper shaker",
                        execute: (room, state) => {
                            print(["You thump the pepper shaker, making a dull thud."]);
                            const safe = checkSuspicion(state, 25);
                            if (safe && getStat("suspicion", state) > 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 => {
                                        if (state.player.location == "pepper-grinder") {
                                            print(["He catches you.", newline, "You're tossed into the fox's jaws."]);
                                            goToRoom("maw", state);
                                        } else {
                                            print(["You evaded the fox."]);
                                        }
                                    },
                                    delay: 3000,
                                    loop: false,
                                    classes: [
                                        "free"
                                    ]
                                }, state);
                            }
                        },
                        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) => {
                            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, state) => {
                                return checkSuspicion(state, 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, state) => {
                    print(["You scurry up to the looming bowl, staying low and out of Geta's sight."]);
                },
                "enter": (room, state) => {
                },
                "exit": (room, state) => {
                },
                "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, state) => {
                                return checkSuspicion(state, 15);
                            }
                        ]
                    },
                },
                "hooks": [
                ],
                "data": {
                    "stats": {
                    }
                }
            },
            "table": {
                "id": "table",
                "name": "Table",
                "desc": "You're out in the open!",
                "move": (room, state) => {
                },
                "enter": (room, state) => {
                    startTimer({
                        id: "table-suspicion",
                        func: state => {
                            checkSuspicion(state, 1.5);
                            return true;
                        },
                        delay: 100,
                        loop: true,
                        classes: [
                            "free"
                        ]
                    }, state);
                },
                "exit": (room, state) => {
                    stopTimer("table-suspicion", state);
                },
                "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, state) => {
                    print(["Why did you do that?"]);
                },
                "enter": (room, state) => {
                    stopClassTimers("free", state);
                    startTimer({
                        id: "geta-eat",
                        func: state => {
                            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);
                                return false;
                            }
                        },
                        delay: 3000,
                        loop: true,
                        classes: [
                            "free"
                        ]
                    }, state);
                },
                "exit": (room, state) => {
                },
                "actions": [
                ],
                "exits": {
                    "ascend": {
                        "target": "bowl",
                        "desc": "Try to climb back out!",
                        "show": [
                        ],
                        "conditions": [
                        ],
                        "hooks": [
                            (room, exit, state) => {
                                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);
                                return false;
                            }
                        ]
                    },
                },
                "hooks": [
                ],
                "data": {
                    "stats": {
                    }
                }
            },
            "maw": {
                "id": "maw",
                "name": "Geta's Maw",
                "desc": "You've been slurped up into the fox's jaws",
                "move": (room, state) => {
                },
                "enter": (room, state) => {
                    stopClassTimers("free", state);
                    state.player.stats.mawPos.hidden = false;
                    state.geta.slurps = 0;
                    state.geta.chews = 0;
                    state.geta.swallowsLeft = 3 + Math.floor(Math.random() * 3);
                    startTimer({
                        id: "maw-random-movement",
                        func: state => {
                            changeStat("mawPos", Math.random() / 50 - 0.01, state);
                            return true;
                        },
                        delay: 100,
                        loop: true,
                        classes: [
                            "maw-struggle"
                        ]
                    }, state);
                    startTimer({
                        id: "maw-struggle",
                        func: state => {
                            if (getStat("mawPos", state) <= 0.05) {
                                print(["Swallowed!"]);
                                goToRoom("throat", state);
                                return false;
                            } else if (getStat("mawPos", state) >= 0.95) {
                                print(["Chewed!"]);
                                changeStat("health", -90, state);
                                goToRoom("stomach", state);
                                return false;
                            }
                            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);
                                return false;
                            }
                            let choice;
                            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", state) < 0.15) {
                                    print(["Swallowed!"]);
                                    goToRoom("throat", state);
                                    return false;
                                } else {
                                    print(["Swallows"]);
                                    changeStat("mawPos", -0.25, state);
                                    state.geta.slurps = 0;
                                    state.geta.chews = 0;
                                    state.geta.swallowsLeft -= 1;
                                    return Math.random() * 1500 + 2500;
                                }
                            } else if (choice == "slurp") {
                                changeStat("mawPos", -0.1, state);
                                print(["Slurps"]);
                                state.geta.slurps += 1;
                                return Math.random() * 1000 + 1500;
                            } else if (choice == "chew") {
                                if (getStat("mawPos", state) > 0.85) {
                                    print(["Chewed!"]);
                                    changeStat("health", -90, state);
                                    goToRoom("stomach", state);
                                    return false;
                                } else {
                                    print(["Chews"]);
                                    state.geta.chews += 1;
                                    return Math.random() * 500 + 1000;
                                }
                            }
                        },
                        delay: 0,
                        loop: true,
                        classes: [
                            "maw-struggle"
                        ]
                    }, state);
                },
                "exit": (room, state) => {
                },
                "actions": [
                    {
                        name: "Struggle",
                        desc: "Pull yourself away from the fox's throat! Just don't go too far forward...",
                        execute: (room, state) => {
                            print(["You drag yourself forward"]);
                            changeStat("mawPos", Math.random() * 0.1 + 0.15, state);
                        },
                        show: [
                        ],
                        conditions: [
                        ]
                    },
                    {
                        name: "Slip Back",
                        desc: "Slide back towards Geta's gullet",
                        execute: (room, state) => {
                            print(["You let yourself slip back"]);
                            changeStat("mawPos", -Math.random() / 5 - 0.2, state);
                        },
                        show: [
                        ],
                        conditions: [
                        ]
                    },
                ],
                "exits": {
                },
                "hooks": [
                ],
                "data": {
                    "stats": {
                    }
                }
            },
            "throat": {
                "id": "throat",
                "name": "Geta's Gullet",
                "desc": "GULP!",
                "move": (room, state) => {
                },
                "enter": (room, state) => {
                    state.player.stats.mawPos.hidden = true;
                    stopClassTimers("maw-struggle", state);
                    startTimer({
                        id: "throat-swallow",
                        func: state => {
                            print(["You slush down into Geta's stomach"]);
                            goToRoom("stomach", state);
                            return true;
                        },
                        delay: 7000,
                        loop: false,
                        classes: [
                        ]
                    }, state);
                },
                "exit": (room, state) => {
                },
                "actions": [
                    {
                        name: "Struggle",
                        desc: "Try to climb back out!",
                        execute: (room, state) => {
                            print(["Nope"]);
                        },
                        show: [
                        ],
                        conditions: [
                        ]
                    },
                    {
                        name: "Give up",
                        desc: "Dive down into Geta's stomach",
                        execute: (room, state) => {
                            print(["You submit to your predator."]);
                            goToRoom("stomach", state);
                            stopTimer("throat-swallow", state);
                        },
                        show: [
                        ],
                        conditions: [
                        ]
                    },
                ],
                "exits": {
                },
                "hooks": [
                ],
                "data": {
                    "stats": {
                    }
                }
            },
            "stomach": {
                "id": "stomach",
                "name": "Geta's Stomach",
                "desc": "Glorp",
                "move": (room, state) => {
                },
                "enter": (room, state) => {
                    playLoop("loop/stomach.ogg");
                    stopClassTimers("maw-struggle", state);
                    state.geta.acidStrength = 1;
                    startTimer({
                        id: "digest-random",
                        func: state => {
                            const choices = [
                                () => {
                                    const crushed = randomBodyPart(state);
                                    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);
                                        return false;
                                    } else {
                                        print(["Geta's stomach grips your " + name + " and crushes it with a horrific CRACK"]);
                                        changeStat("health", -40, state);
                                        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);
                                    return true;
                                },
                                () => {
                                    print(["Your organic prison snarls and churns, soaking you in fresh acids and hastening your wretched demise."]);
                                    state.geta.acidStretngth += 1;
                                    return true;
                                },
                                () => {
                                    print(["\"You were barely worth eating,\" murmurs the fox. \"So small. So weak.\""]);
                                    return true;
                                }
                            ];
                            return choices[Math.floor(Math.random() * choices.length)]();
                        },
                        delay: 5000,
                        loop: true,
                        classes: [
                            "digestion"
                        ]
                    }, state);
                    startTimer({
                        id: "digest",
                        func: state => {
                            changeStat("health", -0.3 * state.geta.acidStrength, state);
                            if (getStat("health", state) <= 0) {
                                print(["You're digested before too long."]);
                                goToRoom("digested", state);
                                return false;
                            }
                            return true;
                        },
                        delay: 100,
                        loop: true,
                        classes: [
                            "digestion"
                        ]
                    }, state);
                },
                "exit": (room, state) => {
                },
                "actions": [
                    {
                        name: "Squirm",
                        desc: "Rub at the walls of the fox's churning stomach",
                        execute: (room, state) => {
                            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: [
                        ]
                    },
                ],
                "exits": {
                },
                "hooks": [
                ],
                "data": {
                    "stats": {
                    }
                }
            },
            "digested": {
                "id": "digested",
                "name": "Fat",
                "desc": "You're just fat now",
                "move": (room, state) => {
                },
                "enter": (room, state) => {
                    stopClassTimers("digestion", state);
                },
                "exit": (room, state) => {
                },
                "actions": [
                    {
                        name: "Gurgle",
                        desc: "Glorp",
                        execute: (room, state) => {
                            printRandom([
                                ["Grrrrgle"],
                                ["Glorp"],
                                ["Glrrrrrrnnnnnn..."],
                                ["Gwoooooorgle"]
                            ]);
                        },
                        show: [
                        ],
                        conditions: [
                        ]
                    },
                ],
                "exits": {
                },
                "hooks": [
                ],
                "data": {
                    "stats": {
                    }
                }
            },
        }
    });
})();
 |