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.
 
 
 
 

677 lines
21 KiB

  1. (() => {
  2. function checkSuspicion(state, add = 0) {
  3. const old = getStat("suspicion", state);
  4. if (add >= 0) {
  5. add *= state.geta.awareness;
  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. stories.push({
  18. "id": "geta-unaware",
  19. "name": "Geta's Breakfast",
  20. "tags": [
  21. "Player Prey",
  22. "Digestion",
  23. "Macro/Micro"
  24. ],
  25. "intro": {
  26. "start": "pepper-grinder",
  27. "setup": state => {
  28. state.geta = {};
  29. state.geta.awareness = 1;
  30. state.player.stats.health = { name: "Health", type: "meter", value: 100, min: 0, max: 100, color: "rgb(255,55,55)" };
  31. state.player.stats.suspicion = { name: "Suspicion", type: "meter", value: 0, min: 0, max: 100, color: "rgb(100,100,100)" };
  32. state.info.time.value = 60 * 60 * 7 + 60 * 17;
  33. state.player.flags.caught = false;
  34. startTimer({
  35. id: "clock",
  36. func: state => {
  37. state.info.time.value += 1;
  38. state.info.time.value %= 86000;
  39. return true;
  40. },
  41. delay: 1000,
  42. loop: true,
  43. classes: [
  44. ]
  45. }, state);
  46. startTimer({
  47. id: "suspicion-decay",
  48. func: state => {
  49. checkSuspicion(state, -0.1);
  50. return true;
  51. },
  52. delay: 100,
  53. loop: true,
  54. classes: [
  55. "free"
  56. ]
  57. }, state);
  58. startTimer({
  59. id: "timeout",
  60. func: state => {
  61. if (state.info.time.value == 60 * 60 * 7 + 60 * 19) {
  62. print(["The fox is almost done with his breakfast..."]);
  63. }
  64. if (state.info.time.value >= 60 * 60 * 7 + 60 * 20) {
  65. print(["Time's up! In you go."]);
  66. goToRoom("maw", state);
  67. return false;
  68. }
  69. return true;
  70. },
  71. delay: 1000,
  72. loop: true,
  73. classes: [
  74. "free"
  75. ]
  76. }, state);
  77. startTimer({
  78. id: "geta-action",
  79. func: state => {
  80. const random = Math.random();
  81. if (random < 0.7) {
  82. print(["Geta slurps up a spoonful of cereal."]);
  83. } else if (random < 0.9) {
  84. state.geta.awareness = 0.1;
  85. print(["The fox yawns and stretches."]);
  86. startTimer({
  87. id: "yawn-end",
  88. func: state => {
  89. print(["Geta finishes his stretch"]);
  90. state.geta.awareness = 1;
  91. return true;
  92. },
  93. delay: 2000,
  94. loop: false,
  95. classes: [
  96. "free"
  97. ]
  98. }, state);
  99. } else {
  100. state.geta.awareness = 2;
  101. print(["Geta narrows his eyes and looks around the table. Something seems off to him..."]);
  102. startTimer({
  103. id: "squint-end",
  104. func: state => {
  105. print(["He goes back to his breakfast."]);
  106. state.geta.awareness = 1;
  107. return true;
  108. },
  109. delay: 4000,
  110. loop: false,
  111. classes: [
  112. "free"
  113. ]
  114. }, state);
  115. }
  116. return 5000
  117. },
  118. delay: 5000,
  119. loop: true,
  120. classes: [
  121. "free"
  122. ]
  123. }, state);
  124. },
  125. "intro": state => {
  126. print(["Game started", newline, "Exposition goes here later."]);
  127. }
  128. },
  129. "sounds": [
  130. "loop/stomach.ogg"
  131. ],
  132. "preload": [
  133. ],
  134. "world": {
  135. "pepper-grinder": {
  136. "id": "pepper-grinder",
  137. "name": "Pepper Grinder",
  138. "desc": "You're hiding behind a pepper grinder",
  139. "move": (room, state) => {
  140. print(["You dart over to the pepper grinder, which looms over you like a greatwood."]);
  141. },
  142. "enter": (room, state) => {
  143. },
  144. "exit": (room, state) => {
  145. },
  146. "actions": [
  147. {
  148. name: "Tap",
  149. desc: "Bang on the pepper shaker",
  150. execute: (room, state) => {
  151. print(["You thump the pepper shaker, making a dull thud."]);
  152. const safe = checkSuspicion(state, 25);
  153. if (safe && getStat("suspicion", state) > 50) {
  154. print(["Geta leans in to have a closer look. He's going to catch you if you don't move!"]);
  155. startTimer({
  156. id: "pepper-investigate",
  157. func: state => {
  158. if (state.player.location == "pepper-grinder") {
  159. print(["He catches you.", newline, "You're tossed into the fox's jaws."]);
  160. goToRoom("maw", state);
  161. } else {
  162. print(["You evaded the fox."]);
  163. }
  164. },
  165. delay: 3000,
  166. loop: false,
  167. classes: [
  168. "free"
  169. ]
  170. }, state);
  171. }
  172. },
  173. show: [
  174. ],
  175. conditions: [
  176. ]
  177. },
  178. {
  179. name: "Wait",
  180. desc: "Wait for the fox to finish his breakfast. Surely you'll be able to escape after that...right?",
  181. execute: (room, state) => {
  182. state.info.time.value = 60 * 60 * 7 + 60 * 20;
  183. },
  184. show: [
  185. ],
  186. conditions: [
  187. ]
  188. },
  189. ],
  190. "exits": {
  191. "up": {
  192. "target": "bowl",
  193. "desc": "Walk up to the cereal bowl",
  194. "show": [
  195. ],
  196. "conditions": [
  197. ],
  198. "hooks": [
  199. (room, exit, state) => {
  200. return checkSuspicion(state, 10);
  201. }
  202. ]
  203. },
  204. "left": {
  205. "target": "table",
  206. "desc": "Run out into the open",
  207. "show": [
  208. ],
  209. "conditions": [
  210. ],
  211. "hooks": [
  212. ]
  213. },
  214. },
  215. "hooks": [
  216. ],
  217. "data": {
  218. "stats": {
  219. }
  220. }
  221. },
  222. "bowl": {
  223. "id": "bowl",
  224. "name": "Behind the Bowl",
  225. "desc": "You're crouched behind Geta's bowl of cereal",
  226. "move": (room, state) => {
  227. print(["You scurry up to the looming bowl, staying low and out of Geta's sight."]);
  228. },
  229. "enter": (room, state) => {
  230. },
  231. "exit": (room, state) => {
  232. },
  233. "actions": [
  234. ],
  235. "exits": {
  236. "ascend": {
  237. "target": "in-bowl",
  238. "desc": "Climb into Geta's cereal",
  239. "show": [
  240. ],
  241. "conditions": [
  242. ],
  243. "hooks": [
  244. ]
  245. },
  246. "down": {
  247. "target": "pepper-grinder",
  248. "desc": "Run back behind the pepper grinder",
  249. "show": [
  250. ],
  251. "conditions": [
  252. ],
  253. "hooks": [
  254. (room, exit, state) => {
  255. return checkSuspicion(state, 15);
  256. }
  257. ]
  258. },
  259. },
  260. "hooks": [
  261. ],
  262. "data": {
  263. "stats": {
  264. }
  265. }
  266. },
  267. "table": {
  268. "id": "table",
  269. "name": "Table",
  270. "desc": "You're out in the open!",
  271. "move": (room, state) => {
  272. },
  273. "enter": (room, state) => {
  274. startTimer({
  275. id: "table-suspicion",
  276. func: state => {
  277. checkSuspicion(state, 1.5);
  278. return true;
  279. },
  280. delay: 100,
  281. loop: true,
  282. classes: [
  283. "free"
  284. ]
  285. }, state);
  286. },
  287. "exit": (room, state) => {
  288. stopTimer("table-suspicion", state);
  289. },
  290. "actions": [
  291. ],
  292. "exits": {
  293. "right": {
  294. "target": "pepper-grinder",
  295. "desc": "Run back to cover",
  296. "show": [
  297. ],
  298. "conditions": [
  299. ],
  300. "hooks": [
  301. ]
  302. },
  303. },
  304. "hooks": [
  305. ],
  306. "data": {
  307. "stats": {
  308. }
  309. }
  310. },
  311. "in-bowl": {
  312. "id": "in-bowl",
  313. "name": "Bowl",
  314. "desc": "You're in the cereal bowl...",
  315. "move": (room, state) => {
  316. print(["Why did you do that?"]);
  317. },
  318. "enter": (room, state) => {
  319. stopClassTimers("free", state);
  320. startTimer({
  321. id: "geta-eat",
  322. func: state => {
  323. if (Math.random() < 0.6) {
  324. print(["Geta scoops up a spoonful of cereal; you narrowly avoid being caught."]);
  325. return true;
  326. } else {
  327. print(["Geta scoops you up and slurps you into his maw."]);
  328. goToRoom("maw", state);
  329. return false;
  330. }
  331. },
  332. delay: 3000,
  333. loop: true,
  334. classes: [
  335. "free"
  336. ]
  337. }, state);
  338. },
  339. "exit": (room, state) => {
  340. },
  341. "actions": [
  342. ],
  343. "exits": {
  344. "ascend": {
  345. "target": "bowl",
  346. "desc": "Try to climb back out!",
  347. "show": [
  348. ],
  349. "conditions": [
  350. ],
  351. "hooks": [
  352. (room, exit, state) => {
  353. print([
  354. "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."
  355. ]);
  356. goToRoom("maw", state);
  357. return false;
  358. }
  359. ]
  360. },
  361. },
  362. "hooks": [
  363. ],
  364. "data": {
  365. "stats": {
  366. }
  367. }
  368. },
  369. "maw": {
  370. "id": "maw",
  371. "name": "Geta's Maw",
  372. "desc": "You've been slurped up into the fox's jaws",
  373. "move": (room, state) => {
  374. },
  375. "enter": (room, state) => {
  376. stopClassTimers("free", state);
  377. startTimer({
  378. id: "swallow",
  379. func: state => {
  380. print(["It's too late to escape. You're swallowed down."]);
  381. stopTimer("maw-tease", state);
  382. goToRoom("throat", state);
  383. return true;
  384. },
  385. delay: Math.random() * 5000 + 6000,
  386. loop: false,
  387. classes: [
  388. ]
  389. }, state);
  390. startTimer({
  391. id: "maw-tease",
  392. func: state => {
  393. printRandom([
  394. ["Your captor teases you with a sharp, sloppy swallow, barely holding you back from plunging down that slick gullet."],
  395. ["You're sloshed to and fro, battered against the fox's gums by his undulating tongue."],
  396. ["Slobber drenches your body as you're smothered beneath Geta's hot tongue."]
  397. ]);
  398. return Math.random() * 2000 + 3000;
  399. },
  400. delay: 3000,
  401. loop: true,
  402. classes: [
  403. ]
  404. }, state);
  405. },
  406. "exit": (room, state) => {
  407. },
  408. "actions": [
  409. ],
  410. "exits": {
  411. },
  412. "hooks": [
  413. ],
  414. "data": {
  415. "stats": {
  416. }
  417. }
  418. },
  419. "throat": {
  420. "id": "throat",
  421. "name": "Geta's Gullet",
  422. "desc": "GULP!",
  423. "move": (room, state) => {
  424. },
  425. "enter": (room, state) => {
  426. startTimer({
  427. id: "throat-swallow",
  428. func: state => {
  429. print(["You slush down into Geta's stomach"]);
  430. goToRoom("stomach", state);
  431. return true;
  432. },
  433. delay: 7000,
  434. loop: false,
  435. classes: [
  436. ]
  437. }, state);
  438. },
  439. "exit": (room, state) => {
  440. },
  441. "actions": [
  442. {
  443. name: "Struggle",
  444. desc: "Try to climb back out!",
  445. execute: (room, state) => {
  446. print(["Nope"]);
  447. },
  448. show: [
  449. ],
  450. conditions: [
  451. ]
  452. },
  453. {
  454. name: "Give up",
  455. desc: "Dive down into Geta's stomach",
  456. execute: (room, state) => {
  457. print(["You submit to your predator."]);
  458. goToRoom("stomach", state);
  459. stopTimer("throat-swallow", state);
  460. },
  461. show: [
  462. ],
  463. conditions: [
  464. ]
  465. },
  466. ],
  467. "exits": {
  468. },
  469. "hooks": [
  470. ],
  471. "data": {
  472. "stats": {
  473. }
  474. }
  475. },
  476. "stomach": {
  477. "id": "stomach",
  478. "name": "Geta's Stomach",
  479. "desc": "Glorp",
  480. "move": (room, state) => {
  481. },
  482. "enter": (room, state) => {
  483. playLoop("loop/stomach.ogg");
  484. startTimer({
  485. id: "digest",
  486. func: state => {
  487. changeStat("health", -0.3, state);
  488. if (getStat("health", state) <= 0) {
  489. print(["You're digested before too long."]);
  490. goToRoom("digested", state);
  491. return false;
  492. }
  493. return true;
  494. },
  495. delay: 100,
  496. loop: true,
  497. classes: [
  498. ]
  499. }, state);
  500. },
  501. "exit": (room, state) => {
  502. },
  503. "actions": [
  504. {
  505. name: "Squirm",
  506. desc: "Rub at the walls of the fox's churning stomach",
  507. execute: (room, state) => {
  508. printRandom([
  509. ["You punch and kick at the walls"],
  510. ["A powerful churn grabs hold of you, stifling any attempts at struggling"],
  511. ["Your little thumps and kicks do little to faze your captor"]
  512. ]);
  513. },
  514. show: [
  515. ],
  516. conditions: [
  517. ]
  518. },
  519. ],
  520. "exits": {
  521. },
  522. "hooks": [
  523. ],
  524. "data": {
  525. "stats": {
  526. }
  527. }
  528. },
  529. "digested": {
  530. "id": "digested",
  531. "name": "Fat",
  532. "desc": "You're just fat now",
  533. "move": (room, state) => {
  534. },
  535. "enter": (room, state) => {
  536. },
  537. "exit": (room, state) => {
  538. },
  539. "actions": [
  540. {
  541. name: "Gurgle",
  542. desc: "Glorp",
  543. execute: (room, state) => {
  544. printRandom([
  545. ["Grrrrgle"],
  546. ["Glorp"],
  547. ["Glrrrrrrnnnnnn..."],
  548. ["Gwoooooorgle"]
  549. ]);
  550. },
  551. show: [
  552. ],
  553. conditions: [
  554. ]
  555. },
  556. ],
  557. "exits": {
  558. },
  559. "hooks": [
  560. ],
  561. "data": {
  562. "stats": {
  563. }
  564. }
  565. },
  566. }
  567. });
  568. })();