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.
 
 
 
 

1143 lines
42 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/swallow.ogg"
  209. ],
  210. "preload": [
  211. ],
  212. "refresh": () => {
  213. setBackgroundColor(50 - state.player.stats.health.value / 2, 0, 0);
  214. },
  215. "world": {
  216. "pepper-grinder": {
  217. "id": "pepper-grinder",
  218. "name": "Pepper Grinder",
  219. "desc": "You're hiding behind a pepper grinder",
  220. "move": (room) => {
  221. print(["You dart over to the pepper grinder, which looms over you like a greatwood."]);
  222. },
  223. "enter": (room) => {
  224. },
  225. "exit": (room) => {
  226. },
  227. "actions": [
  228. {
  229. name: "Tap",
  230. desc: "Bang on the pepper shaker",
  231. execute: (room) => {
  232. print(["You thump the pepper shaker, making a dull thud."]);
  233. const safe = checkSuspicion(25);
  234. if (safe && getStat("suspicion") > 50) {
  235. print(["Geta leans in to have a closer look. He's going to catch you if you don't move!"]);
  236. startTimer({
  237. id: "pepper-investigate",
  238. func: () => {
  239. if (state.player.location == "pepper-grinder") {
  240. print(["He catches you.", newline, "You're tossed into the fox's jaws."]);
  241. goToRoom("maw");
  242. } else {
  243. print(["You evaded the fox."]);
  244. }
  245. },
  246. delay: 3000,
  247. loop: false,
  248. classes: [
  249. "free"
  250. ]
  251. });
  252. }
  253. },
  254. show: [
  255. ],
  256. conditions: [
  257. ]
  258. },
  259. {
  260. name: "Wait",
  261. desc: "Wait for the fox to finish his breakfast. Surely you'll be able to escape after that...right?",
  262. execute: (room) => {
  263. state.info.time.value = 60 * 60 * 7 + 60 * 20;
  264. },
  265. show: [
  266. ],
  267. conditions: [
  268. ]
  269. },
  270. ],
  271. "exits": {
  272. "up": {
  273. "target": "bowl",
  274. "desc": "Walk up to the cereal bowl",
  275. "show": [
  276. ],
  277. "conditions": [
  278. ],
  279. "hooks": [
  280. (room, exit) => {
  281. return checkSuspicion(10);
  282. }
  283. ]
  284. },
  285. "left": {
  286. "target": "table",
  287. "desc": "Run out into the open",
  288. "show": [
  289. ],
  290. "conditions": [
  291. ],
  292. "hooks": [
  293. ]
  294. },
  295. },
  296. "hooks": [
  297. ],
  298. "data": {
  299. "stats": {
  300. }
  301. }
  302. },
  303. "bowl": {
  304. "id": "bowl",
  305. "name": "Behind the Bowl",
  306. "desc": "You're crouched behind Geta's bowl of cereal",
  307. "move": (room) => {
  308. print(["You scurry up to the looming bowl, staying low and out of Geta's sight."]);
  309. },
  310. "enter": (room) => {
  311. },
  312. "exit": (room) => {
  313. },
  314. "actions": [
  315. ],
  316. "exits": {
  317. "ascend": {
  318. "target": "in-bowl",
  319. "desc": "Climb into Geta's cereal",
  320. "show": [
  321. ],
  322. "conditions": [
  323. ],
  324. "hooks": [
  325. ]
  326. },
  327. "down": {
  328. "target": "pepper-grinder",
  329. "desc": "Run back behind the pepper grinder",
  330. "show": [
  331. ],
  332. "conditions": [
  333. ],
  334. "hooks": [
  335. (room, exit) => {
  336. return checkSuspicion(15);
  337. }
  338. ]
  339. },
  340. },
  341. "hooks": [
  342. ],
  343. "data": {
  344. "stats": {
  345. }
  346. }
  347. },
  348. "table": {
  349. "id": "table",
  350. "name": "Table",
  351. "desc": "You're out in the open!",
  352. "move": (room) => {
  353. },
  354. "enter": (room) => {
  355. startTimer({
  356. id: "table-suspicion",
  357. func: () => {
  358. checkSuspicion(1.5);
  359. return true;
  360. },
  361. delay: 100,
  362. loop: true,
  363. classes: [
  364. "free"
  365. ]
  366. });
  367. },
  368. "exit": (room) => {
  369. stopTimer("table-suspicion");
  370. },
  371. "actions": [
  372. ],
  373. "exits": {
  374. "right": {
  375. "target": "pepper-grinder",
  376. "desc": "Run back to cover",
  377. "show": [
  378. ],
  379. "conditions": [
  380. ],
  381. "hooks": [
  382. ]
  383. },
  384. },
  385. "hooks": [
  386. ],
  387. "data": {
  388. "stats": {
  389. }
  390. }
  391. },
  392. "in-bowl": {
  393. "id": "in-bowl",
  394. "name": "Bowl",
  395. "desc": "You're in the cereal bowl...",
  396. "move": (room) => {
  397. print(["Why did you do that?"]);
  398. },
  399. "enter": (room) => {
  400. state.player.stats.suspicion.hidden = true;
  401. stopClassTimers("free");
  402. startTimer({
  403. id: "geta-eat",
  404. func: () => {
  405. if (Math.random() < 0.6) {
  406. print(["Geta scoops up a spoonful of cereal; you narrowly avoid being caught."]);
  407. return true;
  408. } else {
  409. print(["Geta scoops you up and slurps you into his maw."]);
  410. goToRoom("maw");
  411. return false;
  412. }
  413. },
  414. delay: 3000,
  415. loop: true,
  416. classes: [
  417. "free"
  418. ]
  419. });
  420. },
  421. "exit": (room) => {
  422. },
  423. "actions": [
  424. ],
  425. "exits": {
  426. "ascend": {
  427. "target": "bowl",
  428. "desc": "Try to climb back out!",
  429. "show": [
  430. ],
  431. "conditions": [
  432. ],
  433. "hooks": [
  434. (room, exit) => {
  435. print([
  436. "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."
  437. ]);
  438. goToRoom("maw");
  439. return false;
  440. }
  441. ]
  442. },
  443. },
  444. "hooks": [
  445. ],
  446. "data": {
  447. "stats": {
  448. }
  449. }
  450. },
  451. "maw": {
  452. "id": "maw",
  453. "name": "Geta's Maw",
  454. "desc": "You've been slurped up into the fox's jaws",
  455. "move": (room) => {
  456. },
  457. "enter": (room) => {
  458. state.player.stats.suspicion.hidden = true;
  459. stopClassTimers("free");
  460. state.player.stats.mawPos.hidden = false;
  461. state.geta.slurps = 0;
  462. state.geta.chews = 0;
  463. state.geta.swallowsLeft = 3 + Math.floor(Math.random() * 3);
  464. state.geta.mawMovement = 1;
  465. startTimer({
  466. id: "maw-random-movement",
  467. func: () => {
  468. const time = new Date().getTime();
  469. const movementFactor = (state.geta.mawMovement + limbsLost());
  470. const fastPart = Math.sin(time / 200) / 1600 / 3;
  471. const slowPart = Math.sin(time / 1000) / 1600;
  472. changeStat("mawPos", movementFactor * (fastPart + slowPart));
  473. if (getStat("mawPos") <= 0.02) {
  474. print(["You slip too far back. Geta doesn't even have to try to swallow you like the food you are."]);
  475. goToRoom("throat");
  476. return false;
  477. } else if (getStat("mawPos") >= 0.98) {
  478. 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."]);
  479. changeStat("health", -90);
  480. goToRoom("stomach");
  481. return false;
  482. }
  483. return true;
  484. },
  485. delay: 1000 / 60,
  486. loop: true,
  487. classes: [
  488. "maw-struggle"
  489. ]
  490. });
  491. startTimer({
  492. id: "maw-struggle",
  493. func: () => {
  494. if (state.geta.swallowsLeft <= 0) {
  495. print(["Geta picks up his bowl of cereal and drinks it down, swallowing you in the process."]);
  496. state.geta.swallowsLeft = -1;
  497. goToRoom("throat");
  498. return false;
  499. }
  500. let choice;
  501. if (Math.random() < 0.2) {
  502. const choices = [
  503. "slosh",
  504. "tilt-back",
  505. "shove",
  506. ];
  507. choice = choices[Math.floor(Math.random() * choices.length)];
  508. } else if (Math.random() > state.geta.slurps / 3) {
  509. choice = "slurp";
  510. } else if (state.geta.chews - Math.floor(Math.random() * 3) < state.geta.slurps) {
  511. choice = "chew";
  512. } else {
  513. choice = "swallow";
  514. }
  515. if (choice == "swallow") {
  516. if (getStat("mawPos") < 0.15) {
  517. print(["You're too far back. The fox swallows a mouthful of cereal, taking you with it."]);
  518. goToRoom("throat");
  519. return false;
  520. } else {
  521. printRandom([
  522. ["A light swallow drags a lump of chewed-up cereal into Geta's depths."],
  523. ["Geta swallows, dragging you closer to your demise."],
  524. ["Your captor's throat ripples as he gulps down his breakfast."]
  525. ]);
  526. statLerp("mawPos", -0.25, 500);
  527. state.geta.slurps = 0;
  528. state.geta.chews = 0;
  529. state.geta.swallowsLeft -= 1;
  530. return Math.random() * 1500 + 1500;
  531. }
  532. } else if (choice == "slurp") {
  533. statLerp("mawPos", -0.1, 250);
  534. printRandom([
  535. ["A spoonful of cereal slips into the fox's " + synonym("slippery") + " maw."],
  536. ["Geta slurps up some more of his breakfast."],
  537. ["You're shoved back a bit as Geta slurps up more cereal."]
  538. ]);
  539. state.geta.slurps += 1;
  540. return Math.random() * 1000 + 2500;
  541. } else if (choice == "chew") {
  542. if (getStat("mawPos") > 0.85) {
  543. const limb = randomBodyPart();
  544. state.player.limbs[limb] = false;
  545. const limbName = limbs[limb];
  546. if (limb == "head") {
  547. print(["Geta's jaws crush down on your head. You die."]);
  548. changeStat("health", -100);
  549. goToRoom("stomach");
  550. } else {
  551. print(["You scream in pain as your " + limbName + " is shattered by the fox's jaws"]);
  552. changeStat("health", -40);
  553. return true;
  554. }
  555. } else {
  556. printRandom([
  557. ["Cruel fangs crush down on the food around you."],
  558. ["Geta chews on his breakfast."],
  559. ["The fox's fangs close with a crackle-crunch of cereal."]
  560. ]);
  561. statLerp("mawPos", Math.random() / 10 - 0.05, 250);
  562. state.geta.chews += 1;
  563. return Math.random() * 500 + 1300;
  564. }
  565. } else if (choice == "slosh") {
  566. print(["Geta's tongue sloshes from side to side, throwing you around his maw like a ship in a storm."]);
  567. state.geta.mawMovement = 3;
  568. startTimer({
  569. id: "maw-slosh-end",
  570. func: () => {
  571. state.geta.mawMovement = 1;
  572. print(["The sloshing ends."]);
  573. return true;
  574. },
  575. delay: 4000,
  576. loop: false,
  577. classes: [
  578. "maw-struggle"
  579. ]
  580. });
  581. return Math.random() * 1500 + 4500;
  582. } else if (choice == "tilt-back") {
  583. print(["Geta tilts his head back, sending rivults of slobber flowing down into that yawning gullet."]);
  584. state.geta.mawMovement = 0.2;
  585. statLerp("mawPos", -1, 4000);
  586. startTimer({
  587. id: "maw-tilt-text",
  588. func: () => {
  589. state.geta.mawMovement = 1;
  590. print(["The fox's muzzle tilts back down as he SWALLOWS hard."]);
  591. statLerp("mawPos", -0.3, 500);
  592. state.geta.swallowsLeft -= 1;
  593. state.geta.slurps = 0;
  594. state.geta.chews = 0;
  595. return true;
  596. },
  597. delay: 4000,
  598. loop: false,
  599. classes: [
  600. ]
  601. });
  602. return 5000 + Math.random() * 1000;
  603. } else if (choice == "shove") {
  604. print(["Geta's tongue lurches forward, shoving you towards the front of his maw!"]);
  605. statLerp("mawPos", 0.2, 500);
  606. return 2000 + Math.random() * 1000;
  607. }
  608. },
  609. delay: 0,
  610. loop: true,
  611. classes: [
  612. "maw-struggle"
  613. ]
  614. });
  615. startTimer({
  616. id: "maw-taunts",
  617. func: () => {
  618. printRandom([
  619. ["\"Did you really think I wouldn't notice you?\""],
  620. ["\"You're going to feel good dying in my guts.\""],
  621. ["\"I could just crush you...but where's the fun in that?\""]
  622. ]);
  623. return Math.random() * 5000 + 5000;
  624. },
  625. delay: 5000,
  626. loop: true,
  627. classes: [
  628. "maw-struggle"
  629. ]
  630. });
  631. },
  632. "exit": (room) => {
  633. },
  634. "actions": [
  635. {
  636. name: "Struggle",
  637. desc: "Pull yourself away from the fox's throat! Just don't go too far forward...",
  638. execute: (room) => {
  639. print(["You drag yourself forward"]);
  640. statLerp("mawPos", 0.15 + Math.random() * 0.05, 250);
  641. },
  642. show: [
  643. ],
  644. conditions: [
  645. ]
  646. },
  647. {
  648. name: "Slip Back",
  649. desc: "Slide back towards Geta's gullet",
  650. execute: (room) => {
  651. if (Math.random() < 0.9) {
  652. print(["You let yourself slip back."]);
  653. statLerp("mawPos", -0.2 - Math.random() * 0.1, 250);
  654. } else {
  655. print(["You lose your grip, sliding back quite far!"]);
  656. statLerp("mawPos", -0.3 - Math.random() * 0.15, 250);
  657. }
  658. },
  659. show: [
  660. ],
  661. conditions: [
  662. ]
  663. },
  664. {
  665. name: "Dive In",
  666. desc: "Throw yourself towards the fox's throat",
  667. execute: (room) => {
  668. 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."]);
  669. goToRoom("throat");
  670. },
  671. show: [
  672. ],
  673. conditions: [
  674. ]
  675. },
  676. ],
  677. "exits": {
  678. },
  679. "hooks": [
  680. ],
  681. "data": {
  682. "stats": {
  683. }
  684. }
  685. },
  686. "throat": {
  687. "id": "throat",
  688. "name": "Geta's Gullet",
  689. "desc": "GULP!",
  690. "move": (room) => {
  691. },
  692. "enter": (room) => {
  693. playSfx("sfx/swallow.ogg");
  694. state.player.stats.mawPos.hidden = true;
  695. stopClassTimers("maw-struggle");
  696. startTimer({
  697. id: "throat-swallow",
  698. func: () => {
  699. print(["You slush down into Geta's stomach"]);
  700. goToRoom("stomach");
  701. return true;
  702. },
  703. delay: 7000,
  704. loop: false,
  705. classes: [
  706. ]
  707. });
  708. },
  709. "exit": (room) => {
  710. },
  711. "actions": [
  712. {
  713. name: "Struggle",
  714. desc: "Try to climb back out!",
  715. execute: (room) => {
  716. print(["Nope"]);
  717. },
  718. show: [
  719. ],
  720. conditions: [
  721. ]
  722. },
  723. {
  724. name: "Give up",
  725. desc: "Dive down into Geta's stomach",
  726. execute: (room) => {
  727. print(["You submit to your predator."]);
  728. goToRoom("stomach");
  729. stopTimer("throat-swallow");
  730. },
  731. show: [
  732. ],
  733. conditions: [
  734. ]
  735. },
  736. ],
  737. "exits": {
  738. },
  739. "hooks": [
  740. ],
  741. "data": {
  742. "stats": {
  743. }
  744. }
  745. },
  746. "stomach": {
  747. "id": "stomach",
  748. "name": "Geta's Stomach",
  749. "desc": "Glorp",
  750. "move": (room) => {
  751. },
  752. "enter": (room) => {
  753. playLoop("loop/stomach.ogg");
  754. stopClassTimers("maw-struggle");
  755. state.geta.acidStrength = 1;
  756. startTimer({
  757. id: "digest-random",
  758. func: () => {
  759. const choices = [
  760. () => {
  761. const crushed = randomBodyPart();
  762. const name = limbs[crushed];
  763. if (name == "head") {
  764. print(["A powerful fold of muscle grips your head, crushing it like a grape and killing you instantly."]);
  765. changeStat("health", -100);
  766. return false;
  767. } else {
  768. print(["Geta's stomach grips your " + name + " and crushes it with a horrific CRACK"]);
  769. changeStat("health", -40);
  770. return true;
  771. }
  772. },
  773. () => {
  774. printRandom([["Geta squeezes in on his gut with both hands, sloshing you around in the sickly stew of cereal, milk, and enzymatic slime."],
  775. ["Your organic prison snarls and churns, soaking you in fresh acids and hastening your wretched demise."]]);
  776. changeStat("health", -10);
  777. return true;
  778. },
  779. () => {
  780. if (state.geta.swallowsLeft == 0) {
  781. print(["A deep series of *glurks* rattles your bones."]);
  782. startTimer({
  783. id: "stomach-milk",
  784. func: () => {
  785. print(["A torrent of cold milk pours into the fox's stomach."]);
  786. return false;
  787. },
  788. delay: 3000,
  789. loop: false,
  790. classes: [
  791. "digestion"
  792. ]
  793. });
  794. } else if (state.geta.swallowsLeft > 0) {
  795. print(["Muffled chewing comes from far above. A moment later, you hear a wet *gluk*"]);
  796. startTimer({
  797. id: "stomach-cereal",
  798. func: () => {
  799. print(["A slimy heap of well-chewed corn flakes splatters down around you."]);
  800. return false;
  801. },
  802. delay: 4000,
  803. loop: false,
  804. classes: [
  805. ]
  806. });
  807. } else if (state.geta.swallowsLeft < 0) {
  808. print(["You hear a few light swallows."]);
  809. startTimer({
  810. id: "stomach-coffee",
  811. func: () => {
  812. print(["Gouts of hot, bitter coffee pour into the fox's guts."]);
  813. return false;
  814. },
  815. delay: 3000,
  816. loop: false,
  817. classes: [
  818. ]
  819. });
  820. }
  821. return true;
  822. },
  823. () => {
  824. print(["\"You were barely worth eating,\" murmurs the fox. \"So small. So weak.\""]);
  825. return true;
  826. }
  827. ];
  828. return choices[Math.floor(Math.random() * choices.length)]();
  829. },
  830. delay: 5000,
  831. loop: true,
  832. classes: [
  833. "digestion"
  834. ]
  835. });
  836. startTimer({
  837. id: "digest",
  838. func: () => {
  839. changeStat("health", -0.3 * state.geta.acidStrength);
  840. if (getStat("health") <= 0) {
  841. print(["You're digested before too long."]);
  842. goToRoom("digested");
  843. return false;
  844. }
  845. return true;
  846. },
  847. delay: 100,
  848. loop: true,
  849. classes: [
  850. "digestion"
  851. ]
  852. });
  853. },
  854. "exit": (room) => {
  855. },
  856. "actions": [
  857. {
  858. name: "Squirm",
  859. desc: "Rub at the walls of the fox's churning stomach",
  860. execute: (room) => {
  861. printRandom([
  862. ["You punch and kick at the walls"],
  863. ["A powerful churn grabs hold of you, stifling any attempts at struggling"],
  864. ["Your little thumps and kicks do little to faze your captor"]
  865. ]);
  866. },
  867. show: [
  868. ],
  869. conditions: [
  870. ]
  871. },
  872. {
  873. name: "Beg",
  874. desc: "Plead for your life",
  875. execute: (room) => {
  876. printRandom([
  877. [
  878. "\"PLEASE!\" you scream, thumping on the walls of the vulpine's gut. \"Let me out!\"",
  879. ]
  880. ])
  881. if (Math.random() < 0.7) {
  882. print(["Your pleas fall on deaf ears."]);
  883. } else {
  884. printRandom([
  885. ["\"Shhhh,\" growls Geta, \"you're going to die in me. Stop whimpering.\""],
  886. ["A long moment passes. \"Poor thing,\" says your captor."]
  887. ])
  888. }
  889. },
  890. show: [
  891. ],
  892. conditions: [
  893. ]
  894. },
  895. {
  896. name: "Scream",
  897. desc: "IT HURTS",
  898. execute: (room) => {
  899. printRandom([
  900. [
  901. "\"Oh god, oh god, oh god,\" you wail...quivering and quaking as you're digested alive. \"GETA!\""
  902. ],
  903. [
  904. "A blood-curdling scream bellows from your burning lungs."
  905. ],
  906. [
  907. "You let out a hideous wail as the fox digests you alive."
  908. ]
  909. ]);
  910. if (Math.random() < 0.5) {
  911. print(["Geta doesn't notice."]);
  912. } else {
  913. print(["A booming chuckle rocks your body."]);
  914. printRandom([
  915. ["\"I hope you're suffering in there.\""],
  916. ["\"Pathetic little snack.\""],
  917. ["\"Ready to die?\""]
  918. ]);
  919. }
  920. },
  921. show: [
  922. ],
  923. conditions: [
  924. ]
  925. },
  926. ],
  927. "exits": {
  928. },
  929. "hooks": [
  930. ],
  931. "data": {
  932. "stats": {
  933. }
  934. }
  935. },
  936. "digested": {
  937. "id": "digested",
  938. "name": "Fat",
  939. "desc": "You're just fat now",
  940. "move": (room) => {
  941. },
  942. "enter": (room) => {
  943. stopClassTimers("digestion");
  944. playSfx("sfx/absorb.ogg");
  945. },
  946. "exit": (room) => {
  947. },
  948. "actions": [
  949. {
  950. name: "Gurgle",
  951. desc: "Glorp",
  952. execute: (room) => {
  953. printRandom([
  954. ["Grrrrgle"],
  955. ["Glorp"],
  956. ["Glrrrrrrnnnnnn..."],
  957. ["Gwoooooorgle"]
  958. ]);
  959. },
  960. show: [
  961. ],
  962. conditions: [
  963. ]
  964. },
  965. ],
  966. "exits": {
  967. },
  968. "hooks": [
  969. ],
  970. "data": {
  971. "stats": {
  972. }
  973. }
  974. },
  975. }
  976. });
  977. })();