a munch adventure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1234 line
45 KiB

  1. (() => {
  2. function checkSuspicion(add = 0) {
  3. const old = getStat("suspicion");
  4. if (add >= 0) {
  5. add *= state.info.awareness.value;
  6. }
  7. changeStat("suspicion", add);
  8. if (getStat("suspicion") >= 100) {
  9. print(["Geta spots you!", "You're snatched up and tossed into the fox's bowl of cereal."]);
  10. goToRoom("in-bowl");
  11. return false;
  12. } else if (getStat("suspicion") >= 75 && old < 75) {
  13. print(["The fox is very suspicious. You're going to get caught if you keep this up..."]);
  14. }
  15. return true;
  16. }
  17. function randomBodyPart() {
  18. const choices = Object.entries(state.player.limbs).filter(([name, status]) => {
  19. return status;
  20. }).map(([name, status]) => name);
  21. return choices[Math.floor(Math.random() * choices.length)];
  22. }
  23. function limbsLost() {
  24. return Object.entries(state.player.limbs).filter(([name, status]) => {
  25. return !status;
  26. }).length;
  27. }
  28. function synonym(word) {
  29. const choices = {
  30. "slippery": ["slippery", "slimy", "slick", "glistening"],
  31. "chews": ["chews", "crunches"],
  32. "crushes": ["crushes", "pulverizes", "shatters", "smashes"]
  33. }
  34. return choices[word][Math.floor(Math.random() * choices[word].length)];
  35. }
  36. function statLerp(stat, change, duration) {
  37. // pretty sure this'll be a random id...
  38. const id = new Date().getTime() + Math.random();
  39. const iterations = duration / 1000 * 60;
  40. startTimer({
  41. id: id,
  42. func: () => {
  43. changeStat(stat, change / iterations);
  44. return true;
  45. },
  46. delay: 1000 / 60,
  47. loop: true,
  48. classes: [
  49. ]
  50. });
  51. startTimer({
  52. id: id + "-stopper",
  53. func: () => {
  54. stopTimer(id);
  55. return false;
  56. },
  57. delay: duration,
  58. loop: false,
  59. classes: [
  60. ]
  61. });
  62. }
  63. const limbs = {
  64. head: "head",
  65. leftArm: "left arm",
  66. rightArm: "right arm",
  67. leftLeg: "left leg",
  68. rightLeg: "right leg"
  69. };
  70. stories.push({
  71. "id": "geta-unaware",
  72. "name": "Geta's Breakfast",
  73. "tags": [
  74. "Player Prey",
  75. "Digestion",
  76. "Macro/Micro",
  77. "Hard Vore"
  78. ],
  79. "intro": {
  80. "start": "pepper-grinder",
  81. "setup": () => {
  82. state.info.awareness = {
  83. id: "awareness",
  84. name: "Geta's Awareness",
  85. type: "counter",
  86. value: 1,
  87. get render() {
  88. if (this.value < 1) {
  89. return "Distracted";
  90. } else if (this.value == 1) {
  91. return "Normal"
  92. } else {
  93. return "Alert"
  94. }
  95. }
  96. }
  97. state.geta = {};
  98. state.player.stats.health = { name: "Health", type: "meter", value: 100, min: 0, max: 100, color: "rgb(255,55,55)" };
  99. state.player.stats.suspicion = { name: "Suspicion", type: "meter", value: 0, min: 0, max: 100, color: "rgb(100,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 }
  101. state.info.time.value = 60 * 60 * 7 + 60 * 17;
  102. state.player.limbs = {};
  103. state.player.limbs.head = true;
  104. state.player.limbs.leftArm = true;
  105. state.player.limbs.rightArm = true;
  106. state.player.limbs.leftLeg = true;
  107. state.player.limbs.rightLeg = true;
  108. startTimer({
  109. id: "clock",
  110. func: () => {
  111. state.info.time.value += 1;
  112. state.info.time.value %= 86000;
  113. return true;
  114. },
  115. delay: 1000,
  116. loop: true,
  117. classes: [
  118. ]
  119. });
  120. startTimer({
  121. id: "suspicion-decay",
  122. func: () => {
  123. checkSuspicion(-0.1);
  124. return true;
  125. },
  126. delay: 100,
  127. loop: true,
  128. classes: [
  129. "free"
  130. ]
  131. });
  132. startTimer({
  133. id: "timeout",
  134. func: () => {
  135. if (state.info.time.value == 60 * 60 * 7 + 60 * 19) {
  136. print(["The fox is almost done with his breakfast..."]);
  137. }
  138. if (state.info.time.value >= 60 * 60 * 7 + 60 * 20) {
  139. print(["Time's up! In you go."]);
  140. goToRoom("maw");
  141. return false;
  142. }
  143. return true;
  144. },
  145. delay: 1000,
  146. loop: true,
  147. classes: [
  148. "free"
  149. ]
  150. });
  151. startTimer({
  152. id: "geta-action",
  153. func: () => {
  154. const random = Math.random();
  155. if (random < 0.7) {
  156. print(["Geta slurps up a spoonful of cereal."]);
  157. return Math.random() * 3000 + 3000
  158. } else if (random < 0.9) {
  159. state.info.awareness.value = 0.1;
  160. print(["The fox yawns and stretches."]);
  161. startTimer({
  162. id: "yawn-end",
  163. func: () => {
  164. print(["Geta finishes his stretch"]);
  165. state.info.awareness.value = 1;
  166. return true;
  167. },
  168. delay: 5000,
  169. loop: false,
  170. classes: [
  171. "free"
  172. ]
  173. });
  174. return Math.random() * 3000 + 5000
  175. } else {
  176. state.info.awareness.value = 2;
  177. print(["Geta narrows his eyes and looks around the table. Something seems off to him..."]);
  178. startTimer({
  179. id: "squint-end",
  180. func: () => {
  181. print(["He goes back to his breakfast."]);
  182. state.info.awareness.value = 1;
  183. return true;
  184. },
  185. delay: 5000,
  186. loop: false,
  187. classes: [
  188. "free"
  189. ]
  190. });
  191. return Math.random() * 1000 + 6000
  192. }
  193. },
  194. delay: 5000,
  195. loop: true,
  196. classes: [
  197. "free"
  198. ]
  199. });
  200. },
  201. "intro": () => {
  202. print(["Game started", newline, "Exposition goes here later."]);
  203. }
  204. },
  205. "sounds": [
  206. "loop/stomach.ogg",
  207. "sfx/absorb.ogg",
  208. "sfx/digest.ogg",
  209. "sfx/swallow.ogg"
  210. ],
  211. "preload": [
  212. ],
  213. "refresh": () => {
  214. setBackgroundColor(50 - state.player.stats.health.value / 2, 0, 0);
  215. },
  216. "world": {
  217. "pepper-grinder": {
  218. "id": "pepper-grinder",
  219. "name": "Pepper Grinder",
  220. "desc": "You're hiding behind a pepper grinder",
  221. "move": (room) => {
  222. print(["You dart over to the pepper grinder, which looms over you like a greatwood."]);
  223. },
  224. "enter": (room) => {
  225. },
  226. "exit": (room) => {
  227. },
  228. "actions": [
  229. {
  230. name: "Tap",
  231. desc: "Bang on the pepper shaker",
  232. execute: (room) => {
  233. print(["You thump the pepper shaker, making a dull thud."]);
  234. const safe = checkSuspicion(25);
  235. if (safe && getStat("suspicion") > 50) {
  236. print(["Geta leans in to have a closer look. He's going to catch you if you don't move!"]);
  237. startTimer({
  238. id: "pepper-investigate",
  239. func: () => {
  240. if (state.player.location == "pepper-grinder") {
  241. print(["He catches you.", newline, "You're tossed into the fox's jaws."]);
  242. goToRoom("maw");
  243. } else {
  244. print(["You evaded the fox."]);
  245. }
  246. },
  247. delay: 3000,
  248. loop: false,
  249. classes: [
  250. "free"
  251. ]
  252. });
  253. }
  254. },
  255. show: [
  256. ],
  257. conditions: [
  258. ]
  259. },
  260. {
  261. name: "Wait",
  262. desc: "Wait for the fox to finish his breakfast. Surely you'll be able to escape after that...right?",
  263. execute: (room) => {
  264. state.info.time.value = 60 * 60 * 7 + 60 * 20;
  265. },
  266. show: [
  267. ],
  268. conditions: [
  269. ]
  270. },
  271. ],
  272. "exits": {
  273. "up": {
  274. "target": "bowl",
  275. "desc": "Walk up to the cereal bowl",
  276. "show": [
  277. ],
  278. "conditions": [
  279. ],
  280. "hooks": [
  281. (room, exit) => {
  282. return checkSuspicion(10);
  283. }
  284. ]
  285. },
  286. "left": {
  287. "target": "table",
  288. "desc": "Run out into the open",
  289. "show": [
  290. ],
  291. "conditions": [
  292. ],
  293. "hooks": [
  294. ]
  295. },
  296. },
  297. "hooks": [
  298. ],
  299. "data": {
  300. "stats": {
  301. }
  302. }
  303. },
  304. "bowl": {
  305. "id": "bowl",
  306. "name": "Behind the Bowl",
  307. "desc": "You're crouched behind Geta's bowl of cereal",
  308. "move": (room) => {
  309. print(["You scurry up to the looming bowl, staying low and out of Geta's sight."]);
  310. },
  311. "enter": (room) => {
  312. },
  313. "exit": (room) => {
  314. },
  315. "actions": [
  316. ],
  317. "exits": {
  318. "ascend": {
  319. "target": "in-bowl",
  320. "desc": "Climb into Geta's cereal",
  321. "show": [
  322. ],
  323. "conditions": [
  324. ],
  325. "hooks": [
  326. ]
  327. },
  328. "down": {
  329. "target": "pepper-grinder",
  330. "desc": "Run back behind the pepper grinder",
  331. "show": [
  332. ],
  333. "conditions": [
  334. ],
  335. "hooks": [
  336. (room, exit) => {
  337. return checkSuspicion(15);
  338. }
  339. ]
  340. },
  341. },
  342. "hooks": [
  343. ],
  344. "data": {
  345. "stats": {
  346. }
  347. }
  348. },
  349. "table": {
  350. "id": "table",
  351. "name": "Table",
  352. "desc": "You're out in the open!",
  353. "move": (room) => {
  354. },
  355. "enter": (room) => {
  356. startTimer({
  357. id: "table-suspicion",
  358. func: () => {
  359. checkSuspicion(1.5);
  360. return true;
  361. },
  362. delay: 100,
  363. loop: true,
  364. classes: [
  365. "free"
  366. ]
  367. });
  368. },
  369. "exit": (room) => {
  370. stopTimer("table-suspicion");
  371. },
  372. "actions": [
  373. ],
  374. "exits": {
  375. "right": {
  376. "target": "pepper-grinder",
  377. "desc": "Run back to cover",
  378. "show": [
  379. ],
  380. "conditions": [
  381. ],
  382. "hooks": [
  383. ]
  384. },
  385. },
  386. "hooks": [
  387. ],
  388. "data": {
  389. "stats": {
  390. }
  391. }
  392. },
  393. "in-bowl": {
  394. "id": "in-bowl",
  395. "name": "Bowl",
  396. "desc": "You're in the cereal bowl...",
  397. "move": (room) => {
  398. print(["Why did you do that?"]);
  399. },
  400. "enter": (room) => {
  401. state.player.stats.suspicion.hidden = true;
  402. stopClassTimers("free");
  403. startTimer({
  404. id: "geta-eat",
  405. func: () => {
  406. if (Math.random() < 0.6) {
  407. print(["Geta scoops up a spoonful of cereal; you narrowly avoid being caught."]);
  408. return true;
  409. } else {
  410. print(["Geta scoops you up and slurps you into his maw."]);
  411. goToRoom("maw");
  412. return false;
  413. }
  414. },
  415. delay: 3000,
  416. loop: true,
  417. classes: [
  418. "free"
  419. ]
  420. });
  421. },
  422. "exit": (room) => {
  423. },
  424. "actions": [
  425. ],
  426. "exits": {
  427. "ascend": {
  428. "target": "bowl",
  429. "desc": "Try to climb back out!",
  430. "show": [
  431. ],
  432. "conditions": [
  433. ],
  434. "hooks": [
  435. (room, exit) => {
  436. print([
  437. "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."
  438. ]);
  439. goToRoom("maw");
  440. return false;
  441. }
  442. ]
  443. },
  444. },
  445. "hooks": [
  446. ],
  447. "data": {
  448. "stats": {
  449. }
  450. }
  451. },
  452. "maw": {
  453. "id": "maw",
  454. "name": "Geta's Maw",
  455. "desc": "You've been slurped up into the fox's jaws",
  456. "move": (room) => {
  457. },
  458. "enter": (room) => {
  459. state.player.stats.suspicion.hidden = true;
  460. stopClassTimers("free");
  461. state.player.stats.mawPos.hidden = false;
  462. state.geta.slurps = 0;
  463. state.geta.chews = 0;
  464. state.geta.swallowsLeft = 3 + Math.floor(Math.random() * 3);
  465. state.geta.mawMovement = 1;
  466. print(["You slip into Geta's maw. He'll swallow you like the snack you are if you slip too far back, but crawl too far forward, and you'll meet his fangs..."])
  467. startTimer({
  468. id: "maw-random-movement",
  469. func: () => {
  470. const time = new Date().getTime();
  471. const movementFactor = (state.geta.mawMovement + limbsLost());
  472. const fastPart = Math.sin(time / 200) / 1600 / 3;
  473. const slowPart = Math.sin(time / 1000) / 1600;
  474. changeStat("mawPos", movementFactor * (fastPart + slowPart));
  475. if (getStat("mawPos") <= 0.02) {
  476. 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."]);
  477. goToRoom("throat");
  478. return false;
  479. } else if (getStat("mawPos") >= 0.98) {
  480. 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."]);
  481. playSfx("sfx/swallow.ogg");
  482. changeStat("health", -90);
  483. goToRoom("stomach");
  484. return false;
  485. }
  486. return true;
  487. },
  488. delay: 1000 / 60,
  489. loop: true,
  490. classes: [
  491. "maw-struggle"
  492. ]
  493. });
  494. startTimer({
  495. id: "maw-struggle",
  496. func: () => {
  497. if (state.geta.swallowsLeft <= 0) {
  498. print(["Geta picks up his bowl of cereal and drinks it down, swallowing you in the process."]);
  499. state.geta.swallowsLeft = -1;
  500. goToRoom("throat");
  501. return false;
  502. }
  503. let choice;
  504. if (Math.random() < 0.2) {
  505. const choices = [
  506. "slosh",
  507. "tilt-back",
  508. "shove",
  509. ];
  510. choice = choices[Math.floor(Math.random() * choices.length)];
  511. } else if (Math.random() > state.geta.slurps / 3) {
  512. choice = "slurp";
  513. } else if (state.geta.chews - Math.floor(Math.random() * 3) < state.geta.slurps) {
  514. choice = "chew";
  515. } else {
  516. choice = "swallow";
  517. }
  518. if (choice == "swallow") {
  519. if (getStat("mawPos") < 0.15) {
  520. print(["You're too far back. The fox swallows a mouthful of cereal, taking you with it."]);
  521. goToRoom("throat");
  522. return false;
  523. } else {
  524. printRandom([
  525. ["A light swallow drags a lump of chewed-up cereal into Geta's depths."],
  526. ["Geta swallows, dragging you closer to your demise."],
  527. ["Your captor's throat ripples as he gulps down his breakfast."]
  528. ]);
  529. statLerp("mawPos", -0.25, 500);
  530. state.geta.slurps = 0;
  531. state.geta.chews = 0;
  532. state.geta.swallowsLeft -= 1;
  533. return Math.random() * 1500 + 1500;
  534. }
  535. } else if (choice == "slurp") {
  536. statLerp("mawPos", -0.1, 250);
  537. printRandom([
  538. ["A spoonful of cereal slips into the fox's " + synonym("slippery") + " maw."],
  539. ["Geta slurps up some more of his breakfast."],
  540. ["You're shoved back a bit as Geta slurps up more cereal."]
  541. ]);
  542. state.geta.slurps += 1;
  543. return Math.random() * 1000 + 2500;
  544. } else if (choice == "chew") {
  545. if (getStat("mawPos") > 0.85) {
  546. const limb = randomBodyPart();
  547. state.player.limbs[limb] = false;
  548. const limbName = limbs[limb];
  549. if (limb == "head") {
  550. print(["Geta's jaws crush down on your head. You die."]);
  551. changeStat("health", -100);
  552. goToRoom("stomach");
  553. } else {
  554. print(["You scream in pain as your " + limbName + " is shattered by the fox's jaws"]);
  555. changeStat("health", -40);
  556. return true;
  557. }
  558. } else {
  559. printRandom([
  560. ["Cruel fangs crush down on the food around you."],
  561. ["Geta chews on his breakfast."],
  562. ["The fox's fangs close with a crackle-crunch of cereal."]
  563. ]);
  564. statLerp("mawPos", Math.random() / 10 - 0.05, 250);
  565. state.geta.chews += 1;
  566. return Math.random() * 500 + 1300;
  567. }
  568. } else if (choice == "slosh") {
  569. print(["Geta's tongue sloshes from side to side, throwing you around his maw like a ship in a storm."]);
  570. state.geta.mawMovement = 3;
  571. startTimer({
  572. id: "maw-slosh-end",
  573. func: () => {
  574. state.geta.mawMovement = 1;
  575. print(["The sloshing ends."]);
  576. return true;
  577. },
  578. delay: 4000,
  579. loop: false,
  580. classes: [
  581. "maw-struggle"
  582. ]
  583. });
  584. return Math.random() * 1500 + 4500;
  585. } else if (choice == "tilt-back") {
  586. print(["Geta tilts his head back, sending rivults of slobber flowing down into that yawning gullet."]);
  587. state.geta.mawMovement = 0.2;
  588. statLerp("mawPos", -1, 4000);
  589. startTimer({
  590. id: "maw-tilt-text",
  591. func: () => {
  592. state.geta.mawMovement = 1;
  593. print(["The fox's muzzle tilts back down as he SWALLOWS hard."]);
  594. statLerp("mawPos", -0.3, 500);
  595. state.geta.swallowsLeft -= 1;
  596. state.geta.slurps = 0;
  597. state.geta.chews = 0;
  598. return true;
  599. },
  600. delay: 4000,
  601. loop: false,
  602. classes: [
  603. ]
  604. });
  605. return 5000 + Math.random() * 1000;
  606. } else if (choice == "shove") {
  607. print(["Geta's tongue lurches forward, shoving you towards the front of his maw!"]);
  608. statLerp("mawPos", 0.2, 500);
  609. return 2000 + Math.random() * 1000;
  610. }
  611. },
  612. delay: 0,
  613. loop: true,
  614. classes: [
  615. "maw-struggle"
  616. ]
  617. });
  618. startTimer({
  619. id: "maw-taunts",
  620. func: () => {
  621. printRandom([
  622. ["\"Did you really think I wouldn't notice you?\""],
  623. ["\"You're going to feel good dying in my guts.\""],
  624. ["\"I could just crush you...but where's the fun in that?\""]
  625. ]);
  626. return Math.random() * 5000 + 5000;
  627. },
  628. delay: 5000,
  629. loop: true,
  630. classes: [
  631. "maw-struggle"
  632. ]
  633. });
  634. },
  635. "exit": (room) => {
  636. },
  637. "actions": [
  638. {
  639. name: "Struggle",
  640. desc: "Pull yourself away from the fox's throat! Just don't go too far forward...",
  641. execute: (room) => {
  642. print(["You drag yourself forward"]);
  643. statLerp("mawPos", 0.15 + Math.random() * 0.05, 250);
  644. },
  645. show: [
  646. ],
  647. conditions: [
  648. ]
  649. },
  650. {
  651. name: "Slip Back",
  652. desc: "Slide back towards Geta's gullet",
  653. execute: (room) => {
  654. if (Math.random() < 0.9) {
  655. print(["You let yourself slip back."]);
  656. statLerp("mawPos", -0.2 - Math.random() * 0.1, 250);
  657. } else {
  658. print(["You lose your grip, sliding back quite far!"]);
  659. statLerp("mawPos", -0.3 - Math.random() * 0.15, 250);
  660. }
  661. },
  662. show: [
  663. ],
  664. conditions: [
  665. ]
  666. },
  667. {
  668. name: "Dive In",
  669. desc: "Throw yourself towards the fox's throat",
  670. execute: (room) => {
  671. 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."]);
  672. goToRoom("throat");
  673. },
  674. show: [
  675. ],
  676. conditions: [
  677. ]
  678. },
  679. ],
  680. "exits": {
  681. },
  682. "hooks": [
  683. ],
  684. "data": {
  685. "stats": {
  686. }
  687. }
  688. },
  689. "throat": {
  690. "id": "throat",
  691. "name": "Geta's Gullet",
  692. "desc": "GULP!",
  693. "move": (room) => {
  694. },
  695. "enter": (room) => {
  696. playSfx("sfx/swallow.ogg");
  697. state.player.stats.mawPos.hidden = true;
  698. stopClassTimers("maw-struggle");
  699. startTimer({
  700. id: "throat-swallow",
  701. func: () => {
  702. print(["You slush down into Geta's stomach"]);
  703. goToRoom("stomach");
  704. return true;
  705. },
  706. delay: 7000,
  707. loop: false,
  708. classes: [
  709. ]
  710. });
  711. },
  712. "exit": (room) => {
  713. },
  714. "actions": [
  715. {
  716. name: "Struggle",
  717. desc: "Try to climb back out!",
  718. execute: (room) => {
  719. print(["Nope"]);
  720. },
  721. show: [
  722. ],
  723. conditions: [
  724. ]
  725. },
  726. {
  727. name: "Give up",
  728. desc: "Dive down into Geta's stomach",
  729. execute: (room) => {
  730. print(["You submit to your predator."]);
  731. goToRoom("stomach");
  732. stopTimer("throat-swallow");
  733. },
  734. show: [
  735. ],
  736. conditions: [
  737. ]
  738. },
  739. ],
  740. "exits": {
  741. },
  742. "hooks": [
  743. ],
  744. "data": {
  745. "stats": {
  746. }
  747. }
  748. },
  749. "stomach": {
  750. "id": "stomach",
  751. "name": "Geta's Stomach",
  752. "desc": "Glorp",
  753. "move": (room) => {
  754. },
  755. "enter": (room) => {
  756. playLoop("loop/stomach.ogg");
  757. stopClassTimers("maw-struggle");
  758. state.geta.digestionStage = 0;
  759. state.geta.acidStrength = 1;
  760. startTimer({
  761. id: "digest-stages",
  762. func: () => {
  763. if (100 - state.geta.digestionStage * 25 - 25> getStat("health")) {
  764. state.geta.digestionStage = Math.floor((100 - getStat("health")) / 25);
  765. console.log(state.geta.digestionStage);
  766. switch (state.geta.digestionStage) {
  767. case 1:
  768. print(["Your skin begins to tingle."]);
  769. break;
  770. case 2:
  771. print(["The stinging acids work their way into your tender body."]);
  772. break;
  773. case 3:
  774. print(["You're starting to fall apart..."]);
  775. break;
  776. default:
  777. break;
  778. }
  779. }
  780. return true;
  781. },
  782. delay: 1000,
  783. loop: true,
  784. classes: [
  785. "digestion"
  786. ]
  787. });
  788. startTimer({
  789. id: "digest-random",
  790. func: () => {
  791. const choices = [
  792. () => {
  793. const crushed = randomBodyPart();
  794. const name = limbs[crushed];
  795. if (name == "head") {
  796. print(["A powerful fold of muscle grips your head, crushing it like a grape and killing you instantly."]);
  797. changeStat("health", -100);
  798. return false;
  799. } else {
  800. print(["Geta's stomach grips your " + name + " and crushes it with a horrific CRACK"]);
  801. changeStat("health", -40);
  802. return true;
  803. }
  804. },
  805. () => {
  806. printRandom([["Geta squeezes in on his gut with both hands, sloshing you around in the sickly stew of cereal, milk, and enzymatic slime."],
  807. ["Your organic prison snarls and churns, soaking you in fresh acids and hastening your wretched demise."]]);
  808. statLerp("health", -10, 2000);
  809. return true;
  810. },
  811. () => {
  812. if (state.geta.swallowsLeft == 0) {
  813. print(["A deep series of *glurks* rattles your bones."]);
  814. startTimer({
  815. id: "stomach-milk",
  816. func: () => {
  817. print(["A torrent of cold milk pours into the fox's stomach."]);
  818. return false;
  819. },
  820. delay: 3000,
  821. loop: false,
  822. classes: [
  823. "digestion"
  824. ]
  825. });
  826. } else if (state.geta.swallowsLeft > 0) {
  827. print(["Muffled chewing comes from far above. A moment later, you hear a wet *gluk*"]);
  828. startTimer({
  829. id: "stomach-cereal",
  830. func: () => {
  831. print(["A slimy heap of well-chewed corn flakes splatters down around you."]);
  832. return false;
  833. },
  834. delay: 4000,
  835. loop: false,
  836. classes: [
  837. ]
  838. });
  839. } else if (state.geta.swallowsLeft < 0) {
  840. print(["You hear a few light swallows."]);
  841. startTimer({
  842. id: "stomach-coffee",
  843. func: () => {
  844. print(["Gouts of hot, bitter coffee pour into the fox's guts."]);
  845. return false;
  846. },
  847. delay: 3000,
  848. loop: false,
  849. classes: [
  850. ]
  851. });
  852. }
  853. return true;
  854. },
  855. () => {
  856. print(["\"You were barely worth eating,\" murmurs the fox. \"So small. So weak.\""]);
  857. return true;
  858. }
  859. ];
  860. if (choices[Math.floor(Math.random() * choices.length)]()) {
  861. return Math.random() * 3000 + 3500;
  862. } else {
  863. return false;
  864. }
  865. },
  866. delay: 5000,
  867. loop: true,
  868. classes: [
  869. "digestion"
  870. ]
  871. });
  872. startTimer({
  873. id: "digest",
  874. func: () => {
  875. changeStat("health", -0.3 * state.geta.acidStrength);
  876. if (getStat("health") <= 0) {
  877. print(["You're digested before too long."]);
  878. goToRoom("digested");
  879. return false;
  880. }
  881. return true;
  882. },
  883. delay: 100,
  884. loop: true,
  885. classes: [
  886. "digestion"
  887. ]
  888. });
  889. },
  890. "exit": (room) => {
  891. },
  892. "actions": [
  893. {
  894. name: "Squirm",
  895. desc: "Rub at the walls of the fox's churning stomach",
  896. execute: (room) => {
  897. printRandom([
  898. ["You punch and kick at the walls"],
  899. ["A powerful churn grabs hold of you, stifling any attempts at struggling"],
  900. ["Your little thumps and kicks do little to faze your captor"]
  901. ]);
  902. },
  903. show: [
  904. ],
  905. conditions: [
  906. ]
  907. },
  908. {
  909. name: "Beg",
  910. desc: "Plead for your life",
  911. execute: (room) => {
  912. printRandom([
  913. [
  914. "\"PLEASE!\" you scream, thumping on the walls of the vulpine's gut. \"Let me out!\"",
  915. ]
  916. ])
  917. if (Math.random() < 0.7) {
  918. print(["Your pleas fall on deaf ears."]);
  919. } else {
  920. printRandom([
  921. ["\"Shhhh,\" growls Geta, \"you're going to die in me. Stop whimpering.\""],
  922. ["A long moment passes. \"Poor thing,\" says your captor."]
  923. ])
  924. }
  925. },
  926. show: [
  927. ],
  928. conditions: [
  929. ]
  930. },
  931. {
  932. name: "Scream",
  933. desc: "IT HURTS",
  934. execute: (room) => {
  935. printRandom([
  936. [
  937. "\"Oh god, oh god, oh god,\" you wail...quivering and quaking as you're digested alive. \"GETA!\""
  938. ],
  939. [
  940. "A blood-curdling scream bellows from your burning lungs."
  941. ],
  942. [
  943. "You let out a hideous wail as the fox digests you alive."
  944. ]
  945. ]);
  946. if (Math.random() < 0.5) {
  947. print(["Geta doesn't notice."]);
  948. } else {
  949. print(["A booming chuckle rocks your body."]);
  950. printRandom([
  951. ["\"I hope you're suffering in there.\""],
  952. ["\"Pathetic little snack.\""],
  953. ["\"Ready to die?\""]
  954. ]);
  955. }
  956. },
  957. show: [
  958. ],
  959. conditions: [
  960. ]
  961. },
  962. ],
  963. "exits": {
  964. },
  965. "hooks": [
  966. ],
  967. "data": {
  968. "stats": {
  969. }
  970. }
  971. },
  972. "digested": {
  973. "id": "digested",
  974. "name": "Geta's Stomach",
  975. "desc": "You're just mush now",
  976. "move": (room) => {
  977. },
  978. "enter": (room) => {
  979. stopClassTimers("digestion");
  980. stopTimer("clock");
  981. state.player.flags.digestTime = state.info.time.value;
  982. startTimer({
  983. id: "absorb-clock",
  984. func: () => {
  985. state.info.time.value += 1;
  986. state.info.time.value %= 86000;
  987. if (state.info.time.value - state.player.flags.digestTime > 5 * 60) {
  988. print(["Your molten remains drain into the fox's depths..."]);
  989. goToRoom("absorbed");
  990. return false;
  991. }
  992. return true;
  993. },
  994. delay: 1000 / 15,
  995. loop: true,
  996. classes: [
  997. ]
  998. });
  999. playSfx("sfx/digest.ogg");
  1000. },
  1001. "exit": (room) => {
  1002. },
  1003. "actions": [
  1004. {
  1005. name: "Gurgle",
  1006. desc: "Glorp",
  1007. execute: (room) => {
  1008. printRandom([
  1009. ["Grrrrgle"],
  1010. ["Glorp"],
  1011. ["Glrrrrrrnnnnnn..."],
  1012. ["Gwoooooorgle"]
  1013. ]);
  1014. },
  1015. show: [
  1016. ],
  1017. conditions: [
  1018. ]
  1019. },
  1020. ],
  1021. "exits": {
  1022. },
  1023. "hooks": [
  1024. ],
  1025. "data": {
  1026. "stats": {
  1027. }
  1028. }
  1029. },
  1030. "absorbed": {
  1031. "id": "absorbed",
  1032. "name": "Geta's Fat",
  1033. "desc": "You're gone.",
  1034. "move": (room) => {
  1035. },
  1036. "enter": (room) => {
  1037. playSfx("sfx/absorb.ogg");
  1038. },
  1039. "exit": (room) => {
  1040. },
  1041. "actions": [
  1042. ],
  1043. "exits": {
  1044. },
  1045. "hooks": [
  1046. ],
  1047. "data": {
  1048. "stats": {
  1049. }
  1050. }
  1051. },
  1052. }
  1053. });
  1054. })();