a munch adventure
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

860 líneas
29 KiB

  1. (() => {
  2. function checkSuspicion(state, add = 0) {
  3. const old = getStat("suspicion", state);
  4. if (add >= 0) {
  5. add *= state.info.awareness.value;
  6. }
  7. changeStat("suspicion", add, state);
  8. if (getStat("suspicion", state) >= 100) {
  9. print(["Geta spots you!", "You're snatched up and tossed into the fox's bowl of cereal."]);
  10. goToRoom("in-bowl", state);
  11. return false;
  12. } else if (getStat("suspicion", state) >= 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(state) {
  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. const limbs = {
  24. head: "head",
  25. leftArm: "left arm",
  26. rightArm: "right arm",
  27. leftLeg: "left leg",
  28. rightLeg: "right leg"
  29. };
  30. stories.push({
  31. "id": "geta-unaware",
  32. "name": "Geta's Breakfast",
  33. "tags": [
  34. "Player Prey",
  35. "Digestion",
  36. "Macro/Micro",
  37. "Hard Vore"
  38. ],
  39. "intro": {
  40. "start": "pepper-grinder",
  41. "setup": state => {
  42. state.info.awareness = {
  43. id: "awareness",
  44. name: "Geta's Awareness",
  45. type: "counter",
  46. value: 1,
  47. get render() {
  48. if (this.value < 1) {
  49. return "Distracted";
  50. } else if (this.value == 1) {
  51. return "Normal"
  52. } else {
  53. return "Alert"
  54. }
  55. }
  56. }
  57. state.geta = {};
  58. state.player.stats.health = { name: "Health", type: "meter", value: 100, min: 0, max: 100, color: "rgb(255,55,55)" };
  59. state.player.stats.suspicion = { name: "Suspicion", type: "meter", value: 0, min: 0, max: 100, color: "rgb(100,100,100)" };
  60. state.player.stats.mawPos = { "name": "Struggle", "type": "meter", "value": 0.5, "min": 0, "max": 1, "color": "rgb(0,255,0)", hidden: true }
  61. state.info.time.value = 60 * 60 * 7 + 60 * 17;
  62. state.player.limbs = {};
  63. state.player.limbs.head = true;
  64. state.player.limbs.leftArm = true;
  65. state.player.limbs.rightArm = true;
  66. state.player.limbs.leftLeg = true;
  67. state.player.limbs.rightLef = true;
  68. startTimer({
  69. id: "clock",
  70. func: state => {
  71. state.info.time.value += 1;
  72. state.info.time.value %= 86000;
  73. return true;
  74. },
  75. delay: 1000,
  76. loop: true,
  77. classes: [
  78. ]
  79. }, state);
  80. startTimer({
  81. id: "suspicion-decay",
  82. func: state => {
  83. checkSuspicion(state, -0.1);
  84. return true;
  85. },
  86. delay: 100,
  87. loop: true,
  88. classes: [
  89. "free"
  90. ]
  91. }, state);
  92. startTimer({
  93. id: "timeout",
  94. func: state => {
  95. if (state.info.time.value == 60 * 60 * 7 + 60 * 19) {
  96. print(["The fox is almost done with his breakfast..."]);
  97. }
  98. if (state.info.time.value >= 60 * 60 * 7 + 60 * 20) {
  99. print(["Time's up! In you go."]);
  100. goToRoom("maw", state);
  101. return false;
  102. }
  103. return true;
  104. },
  105. delay: 1000,
  106. loop: true,
  107. classes: [
  108. "free"
  109. ]
  110. }, state);
  111. startTimer({
  112. id: "geta-action",
  113. func: state => {
  114. const random = Math.random();
  115. if (random < 0.7) {
  116. print(["Geta slurps up a spoonful of cereal."]);
  117. return Math.random() * 3000 + 3000
  118. } else if (random < 0.9) {
  119. state.info.awareness.value = 0.1;
  120. print(["The fox yawns and stretches."]);
  121. startTimer({
  122. id: "yawn-end",
  123. func: state => {
  124. print(["Geta finishes his stretch"]);
  125. state.info.awareness.value = 1;
  126. return true;
  127. },
  128. delay: 5000,
  129. loop: false,
  130. classes: [
  131. "free"
  132. ]
  133. }, state);
  134. return Math.random() * 3000 + 5000
  135. } else {
  136. state.info.awareness.value = 2;
  137. print(["Geta narrows his eyes and looks around the table. Something seems off to him..."]);
  138. startTimer({
  139. id: "squint-end",
  140. func: state => {
  141. print(["He goes back to his breakfast."]);
  142. state.info.awareness.value = 1;
  143. return true;
  144. },
  145. delay: 5000,
  146. loop: false,
  147. classes: [
  148. "free"
  149. ]
  150. }, state);
  151. return Math.random() * 1000 + 6000
  152. }
  153. },
  154. delay: 5000,
  155. loop: true,
  156. classes: [
  157. "free"
  158. ]
  159. }, state);
  160. },
  161. "intro": state => {
  162. print(["Game started", newline, "Exposition goes here later."]);
  163. }
  164. },
  165. "sounds": [
  166. "loop/stomach.ogg"
  167. ],
  168. "preload": [
  169. ],
  170. "world": {
  171. "pepper-grinder": {
  172. "id": "pepper-grinder",
  173. "name": "Pepper Grinder",
  174. "desc": "You're hiding behind a pepper grinder",
  175. "move": (room, state) => {
  176. print(["You dart over to the pepper grinder, which looms over you like a greatwood."]);
  177. },
  178. "enter": (room, state) => {
  179. },
  180. "exit": (room, state) => {
  181. },
  182. "actions": [
  183. {
  184. name: "Tap",
  185. desc: "Bang on the pepper shaker",
  186. execute: (room, state) => {
  187. print(["You thump the pepper shaker, making a dull thud."]);
  188. const safe = checkSuspicion(state, 25);
  189. if (safe && getStat("suspicion", state) > 50) {
  190. print(["Geta leans in to have a closer look. He's going to catch you if you don't move!"]);
  191. startTimer({
  192. id: "pepper-investigate",
  193. func: state => {
  194. if (state.player.location == "pepper-grinder") {
  195. print(["He catches you.", newline, "You're tossed into the fox's jaws."]);
  196. goToRoom("maw", state);
  197. } else {
  198. print(["You evaded the fox."]);
  199. }
  200. },
  201. delay: 3000,
  202. loop: false,
  203. classes: [
  204. "free"
  205. ]
  206. }, state);
  207. }
  208. },
  209. show: [
  210. ],
  211. conditions: [
  212. ]
  213. },
  214. {
  215. name: "Wait",
  216. desc: "Wait for the fox to finish his breakfast. Surely you'll be able to escape after that...right?",
  217. execute: (room, state) => {
  218. state.info.time.value = 60 * 60 * 7 + 60 * 20;
  219. },
  220. show: [
  221. ],
  222. conditions: [
  223. ]
  224. },
  225. ],
  226. "exits": {
  227. "up": {
  228. "target": "bowl",
  229. "desc": "Walk up to the cereal bowl",
  230. "show": [
  231. ],
  232. "conditions": [
  233. ],
  234. "hooks": [
  235. (room, exit, state) => {
  236. return checkSuspicion(state, 10);
  237. }
  238. ]
  239. },
  240. "left": {
  241. "target": "table",
  242. "desc": "Run out into the open",
  243. "show": [
  244. ],
  245. "conditions": [
  246. ],
  247. "hooks": [
  248. ]
  249. },
  250. },
  251. "hooks": [
  252. ],
  253. "data": {
  254. "stats": {
  255. }
  256. }
  257. },
  258. "bowl": {
  259. "id": "bowl",
  260. "name": "Behind the Bowl",
  261. "desc": "You're crouched behind Geta's bowl of cereal",
  262. "move": (room, state) => {
  263. print(["You scurry up to the looming bowl, staying low and out of Geta's sight."]);
  264. },
  265. "enter": (room, state) => {
  266. },
  267. "exit": (room, state) => {
  268. },
  269. "actions": [
  270. ],
  271. "exits": {
  272. "ascend": {
  273. "target": "in-bowl",
  274. "desc": "Climb into Geta's cereal",
  275. "show": [
  276. ],
  277. "conditions": [
  278. ],
  279. "hooks": [
  280. ]
  281. },
  282. "down": {
  283. "target": "pepper-grinder",
  284. "desc": "Run back behind the pepper grinder",
  285. "show": [
  286. ],
  287. "conditions": [
  288. ],
  289. "hooks": [
  290. (room, exit, state) => {
  291. return checkSuspicion(state, 15);
  292. }
  293. ]
  294. },
  295. },
  296. "hooks": [
  297. ],
  298. "data": {
  299. "stats": {
  300. }
  301. }
  302. },
  303. "table": {
  304. "id": "table",
  305. "name": "Table",
  306. "desc": "You're out in the open!",
  307. "move": (room, state) => {
  308. },
  309. "enter": (room, state) => {
  310. startTimer({
  311. id: "table-suspicion",
  312. func: state => {
  313. checkSuspicion(state, 1.5);
  314. return true;
  315. },
  316. delay: 100,
  317. loop: true,
  318. classes: [
  319. "free"
  320. ]
  321. }, state);
  322. },
  323. "exit": (room, state) => {
  324. stopTimer("table-suspicion", state);
  325. },
  326. "actions": [
  327. ],
  328. "exits": {
  329. "right": {
  330. "target": "pepper-grinder",
  331. "desc": "Run back to cover",
  332. "show": [
  333. ],
  334. "conditions": [
  335. ],
  336. "hooks": [
  337. ]
  338. },
  339. },
  340. "hooks": [
  341. ],
  342. "data": {
  343. "stats": {
  344. }
  345. }
  346. },
  347. "in-bowl": {
  348. "id": "in-bowl",
  349. "name": "Bowl",
  350. "desc": "You're in the cereal bowl...",
  351. "move": (room, state) => {
  352. print(["Why did you do that?"]);
  353. },
  354. "enter": (room, state) => {
  355. stopClassTimers("free", state);
  356. startTimer({
  357. id: "geta-eat",
  358. func: state => {
  359. if (Math.random() < 0.6) {
  360. print(["Geta scoops up a spoonful of cereal; you narrowly avoid being caught."]);
  361. return true;
  362. } else {
  363. print(["Geta scoops you up and slurps you into his maw."]);
  364. goToRoom("maw", state);
  365. return false;
  366. }
  367. },
  368. delay: 3000,
  369. loop: true,
  370. classes: [
  371. "free"
  372. ]
  373. }, state);
  374. },
  375. "exit": (room, state) => {
  376. },
  377. "actions": [
  378. ],
  379. "exits": {
  380. "ascend": {
  381. "target": "bowl",
  382. "desc": "Try to climb back out!",
  383. "show": [
  384. ],
  385. "conditions": [
  386. ],
  387. "hooks": [
  388. (room, exit, state) => {
  389. print([
  390. "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."
  391. ]);
  392. goToRoom("maw", state);
  393. return false;
  394. }
  395. ]
  396. },
  397. },
  398. "hooks": [
  399. ],
  400. "data": {
  401. "stats": {
  402. }
  403. }
  404. },
  405. "maw": {
  406. "id": "maw",
  407. "name": "Geta's Maw",
  408. "desc": "You've been slurped up into the fox's jaws",
  409. "move": (room, state) => {
  410. },
  411. "enter": (room, state) => {
  412. stopClassTimers("free", state);
  413. state.player.stats.mawPos.hidden = false;
  414. state.geta.slurps = 0;
  415. state.geta.chews = 0;
  416. state.geta.swallowsLeft = 3 + Math.floor(Math.random() * 3);
  417. startTimer({
  418. id: "maw-random-movement",
  419. func: state => {
  420. changeStat("mawPos", Math.random() / 50 - 0.01, state);
  421. return true;
  422. },
  423. delay: 100,
  424. loop: true,
  425. classes: [
  426. "maw-struggle"
  427. ]
  428. }, state);
  429. startTimer({
  430. id: "maw-struggle",
  431. func: state => {
  432. if (getStat("mawPos", state) <= 0.05) {
  433. print(["Swallowed!"]);
  434. goToRoom("throat", state);
  435. return false;
  436. } else if (getStat("mawPos", state) >= 0.95) {
  437. print(["Chewed!"]);
  438. changeStat("health", -90, state);
  439. goToRoom("stomach", state);
  440. return false;
  441. }
  442. if (state.geta.swallowsLeft <= 0) {
  443. print(["Geta picks up his bowl of cereal and drinks it down, swallowing you in the process."]);
  444. goToRoom("throat", state);
  445. return false;
  446. }
  447. let choice;
  448. if (Math.random() > state.geta.slurps / 3) {
  449. choice = "slurp";
  450. } else if (state.geta.chews - Math.floor(Math.random() * 3) < state.geta.slurps) {
  451. choice = "chew";
  452. } else {
  453. choice = "swallow";
  454. }
  455. if (choice == "swallow") {
  456. if (getStat("mawPos", state) < 0.15) {
  457. print(["Swallowed!"]);
  458. goToRoom("throat", state);
  459. return false;
  460. } else {
  461. print(["Swallows"]);
  462. changeStat("mawPos", -0.25, state);
  463. state.geta.slurps = 0;
  464. state.geta.chews = 0;
  465. state.geta.swallowsLeft -= 1;
  466. return Math.random() * 1500 + 2500;
  467. }
  468. } else if (choice == "slurp") {
  469. changeStat("mawPos", -0.1, state);
  470. print(["Slurps"]);
  471. state.geta.slurps += 1;
  472. return Math.random() * 1000 + 1500;
  473. } else if (choice == "chew") {
  474. if (getStat("mawPos", state) > 0.85) {
  475. print(["Chewed!"]);
  476. changeStat("health", -90, state);
  477. goToRoom("stomach", state);
  478. return false;
  479. } else {
  480. print(["Chews"]);
  481. state.geta.chews += 1;
  482. return Math.random() * 500 + 1000;
  483. }
  484. }
  485. },
  486. delay: 0,
  487. loop: true,
  488. classes: [
  489. "maw-struggle"
  490. ]
  491. }, state);
  492. },
  493. "exit": (room, state) => {
  494. },
  495. "actions": [
  496. {
  497. name: "Struggle",
  498. desc: "Pull yourself away from the fox's throat! Just don't go too far forward...",
  499. execute: (room, state) => {
  500. print(["You drag yourself forward"]);
  501. changeStat("mawPos", Math.random() * 0.1 + 0.15, state);
  502. },
  503. show: [
  504. ],
  505. conditions: [
  506. ]
  507. },
  508. {
  509. name: "Slip Back",
  510. desc: "Slide back towards Geta's gullet",
  511. execute: (room, state) => {
  512. print(["You let yourself slip back"]);
  513. changeStat("mawPos", -Math.random() / 5 - 0.2, state);
  514. },
  515. show: [
  516. ],
  517. conditions: [
  518. ]
  519. },
  520. ],
  521. "exits": {
  522. },
  523. "hooks": [
  524. ],
  525. "data": {
  526. "stats": {
  527. }
  528. }
  529. },
  530. "throat": {
  531. "id": "throat",
  532. "name": "Geta's Gullet",
  533. "desc": "GULP!",
  534. "move": (room, state) => {
  535. },
  536. "enter": (room, state) => {
  537. state.player.stats.mawPos.hidden = true;
  538. stopClassTimers("maw-struggle", state);
  539. startTimer({
  540. id: "throat-swallow",
  541. func: state => {
  542. print(["You slush down into Geta's stomach"]);
  543. goToRoom("stomach", state);
  544. return true;
  545. },
  546. delay: 7000,
  547. loop: false,
  548. classes: [
  549. ]
  550. }, state);
  551. },
  552. "exit": (room, state) => {
  553. },
  554. "actions": [
  555. {
  556. name: "Struggle",
  557. desc: "Try to climb back out!",
  558. execute: (room, state) => {
  559. print(["Nope"]);
  560. },
  561. show: [
  562. ],
  563. conditions: [
  564. ]
  565. },
  566. {
  567. name: "Give up",
  568. desc: "Dive down into Geta's stomach",
  569. execute: (room, state) => {
  570. print(["You submit to your predator."]);
  571. goToRoom("stomach", state);
  572. stopTimer("throat-swallow", state);
  573. },
  574. show: [
  575. ],
  576. conditions: [
  577. ]
  578. },
  579. ],
  580. "exits": {
  581. },
  582. "hooks": [
  583. ],
  584. "data": {
  585. "stats": {
  586. }
  587. }
  588. },
  589. "stomach": {
  590. "id": "stomach",
  591. "name": "Geta's Stomach",
  592. "desc": "Glorp",
  593. "move": (room, state) => {
  594. },
  595. "enter": (room, state) => {
  596. playLoop("loop/stomach.ogg");
  597. stopClassTimers("maw-struggle", state);
  598. state.geta.acidStrength = 1;
  599. startTimer({
  600. id: "digest-random",
  601. func: state => {
  602. const choices = [
  603. () => {
  604. const crushed = randomBodyPart(state);
  605. const name = limbs[crushed];
  606. if (name == "head") {
  607. print(["A powerful fold of muscle grips your head, crushing it like a grape and killing you instantly."]);
  608. changeStat("health", -100, state);
  609. return false;
  610. } else {
  611. print(["Geta's stomach grips your " + name + " and crushes it with a horrific CRACK"]);
  612. changeStat("health", -40, state);
  613. return true;
  614. }
  615. },
  616. () => {
  617. print(["Geta squeezes in on his gut with both hands, sloshing you around in the sickly stew of cereal, milk, and enzymatic slime."]);
  618. changeStat("health", -10, state);
  619. return true;
  620. },
  621. () => {
  622. print(["Your organic prison snarls and churns, soaking you in fresh acids and hastening your wretched demise."]);
  623. state.geta.acidStretngth += 1;
  624. return true;
  625. },
  626. () => {
  627. print(["\"You were barely worth eating,\" murmurs the fox. \"So small. So weak.\""]);
  628. return true;
  629. }
  630. ];
  631. return choices[Math.floor(Math.random() * choices.length)]();
  632. },
  633. delay: 5000,
  634. loop: true,
  635. classes: [
  636. "digestion"
  637. ]
  638. }, state);
  639. startTimer({
  640. id: "digest",
  641. func: state => {
  642. changeStat("health", -0.3 * state.geta.acidStrength, state);
  643. if (getStat("health", state) <= 0) {
  644. print(["You're digested before too long."]);
  645. goToRoom("digested", state);
  646. return false;
  647. }
  648. return true;
  649. },
  650. delay: 100,
  651. loop: true,
  652. classes: [
  653. "digestion"
  654. ]
  655. }, state);
  656. },
  657. "exit": (room, state) => {
  658. },
  659. "actions": [
  660. {
  661. name: "Squirm",
  662. desc: "Rub at the walls of the fox's churning stomach",
  663. execute: (room, state) => {
  664. printRandom([
  665. ["You punch and kick at the walls"],
  666. ["A powerful churn grabs hold of you, stifling any attempts at struggling"],
  667. ["Your little thumps and kicks do little to faze your captor"]
  668. ]);
  669. },
  670. show: [
  671. ],
  672. conditions: [
  673. ]
  674. },
  675. ],
  676. "exits": {
  677. },
  678. "hooks": [
  679. ],
  680. "data": {
  681. "stats": {
  682. }
  683. }
  684. },
  685. "digested": {
  686. "id": "digested",
  687. "name": "Fat",
  688. "desc": "You're just fat now",
  689. "move": (room, state) => {
  690. },
  691. "enter": (room, state) => {
  692. stopClassTimers("digestion", state);
  693. },
  694. "exit": (room, state) => {
  695. },
  696. "actions": [
  697. {
  698. name: "Gurgle",
  699. desc: "Glorp",
  700. execute: (room, state) => {
  701. printRandom([
  702. ["Grrrrgle"],
  703. ["Glorp"],
  704. ["Glrrrrrrnnnnnn..."],
  705. ["Gwoooooorgle"]
  706. ]);
  707. },
  708. show: [
  709. ],
  710. conditions: [
  711. ]
  712. },
  713. ],
  714. "exits": {
  715. },
  716. "hooks": [
  717. ],
  718. "data": {
  719. "stats": {
  720. }
  721. }
  722. },
  723. }
  724. });
  725. })();