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.
 
 
 
 

655 lines
20 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. ]
  255. },
  256. },
  257. "hooks": [
  258. ],
  259. "data": {
  260. "stats": {
  261. }
  262. }
  263. },
  264. "table": {
  265. "id": "table",
  266. "name": "Table",
  267. "desc": "You're out in the open!",
  268. "move": (room, state) => {
  269. },
  270. "enter": (room, state) => {
  271. startTimer({
  272. id: "table-suspicion",
  273. func: state => {
  274. checkSuspicion(state, 1.5);
  275. return true;
  276. },
  277. delay: 100,
  278. loop: true,
  279. classes: [
  280. "free"
  281. ]
  282. }, state);
  283. },
  284. "exit": (room, state) => {
  285. stopTimer("table-suspicion", state);
  286. },
  287. "actions": [
  288. ],
  289. "exits": {
  290. "right": {
  291. "target": "pepper-grinder",
  292. "desc": "Run back to cover",
  293. "show": [
  294. ],
  295. "conditions": [
  296. ],
  297. "hooks": [
  298. ]
  299. },
  300. },
  301. "hooks": [
  302. ],
  303. "data": {
  304. "stats": {
  305. }
  306. }
  307. },
  308. "in-bowl": {
  309. "id": "in-bowl",
  310. "name": "Bowl",
  311. "desc": "You're in the cereal bowl...",
  312. "move": (room, state) => {
  313. print(["Why did you do that?"]);
  314. },
  315. "enter": (room, state) => {
  316. stopClassTimers("free", state);
  317. startTimer({
  318. id: "geta-eat",
  319. func: state => {
  320. if (Math.random() < 0.6) {
  321. print(["Geta scoops up a spoonful of cereal; you narrowly avoid being caught."]);
  322. return true;
  323. } else {
  324. print(["Geta scoops you up and slurps you into his maw."]);
  325. goToRoom("maw", state);
  326. return false;
  327. }
  328. },
  329. delay: 3000,
  330. loop: true,
  331. classes: [
  332. ]
  333. }, state);
  334. },
  335. "exit": (room, state) => {
  336. },
  337. "actions": [
  338. ],
  339. "exits": {
  340. },
  341. "hooks": [
  342. ],
  343. "data": {
  344. "stats": {
  345. }
  346. }
  347. },
  348. "maw": {
  349. "id": "maw",
  350. "name": "Geta's Maw",
  351. "desc": "You've been slurped up into the fox's jaws",
  352. "move": (room, state) => {
  353. },
  354. "enter": (room, state) => {
  355. stopClassTimers("free", state);
  356. startTimer({
  357. id: "swallow",
  358. func: state => {
  359. print(["It's too late to escape. You're swallowed down."]);
  360. stopTimer("maw-tease", state);
  361. goToRoom("throat", state);
  362. return true;
  363. },
  364. delay: Math.random() * 5000 + 6000,
  365. loop: false,
  366. classes: [
  367. ]
  368. }, state);
  369. startTimer({
  370. id: "maw-tease",
  371. func: state => {
  372. printRandom([
  373. ["Your captor teases you with a sharp, sloppy swallow, barely holding you back from plunging down that slick gullet."],
  374. ["You're sloshed to and fro, battered against the fox's gums by his undulating tongue."],
  375. ["Slobber drenches your body as you're smothered beneath Geta's hot tongue."]
  376. ]);
  377. return Math.random() * 2000 + 3000;
  378. },
  379. delay: 3000,
  380. loop: true,
  381. classes: [
  382. ]
  383. }, state);
  384. },
  385. "exit": (room, state) => {
  386. },
  387. "actions": [
  388. ],
  389. "exits": {
  390. },
  391. "hooks": [
  392. ],
  393. "data": {
  394. "stats": {
  395. }
  396. }
  397. },
  398. "throat": {
  399. "id": "throat",
  400. "name": "Geta's Gullet",
  401. "desc": "GULP!",
  402. "move": (room, state) => {
  403. },
  404. "enter": (room, state) => {
  405. startTimer({
  406. id: "throat-swallow",
  407. func: state => {
  408. print(["You slush down into Geta's stomach"]);
  409. goToRoom("stomach", state);
  410. return true;
  411. },
  412. delay: 7000,
  413. loop: false,
  414. classes: [
  415. ]
  416. }, state);
  417. },
  418. "exit": (room, state) => {
  419. },
  420. "actions": [
  421. {
  422. name: "Struggle",
  423. desc: "Try to climb back out!",
  424. execute: (room, state) => {
  425. print(["Nope"]);
  426. },
  427. show: [
  428. ],
  429. conditions: [
  430. ]
  431. },
  432. {
  433. name: "Give up",
  434. desc: "Dive down into Geta's stomach",
  435. execute: (room, state) => {
  436. print(["You submit to your predator."]);
  437. goToRoom("stomach", state);
  438. stopTimer("throat-swallow", state);
  439. },
  440. show: [
  441. ],
  442. conditions: [
  443. ]
  444. },
  445. ],
  446. "exits": {
  447. },
  448. "hooks": [
  449. ],
  450. "data": {
  451. "stats": {
  452. }
  453. }
  454. },
  455. "stomach": {
  456. "id": "stomach",
  457. "name": "Geta's Stomach",
  458. "desc": "Glorp",
  459. "move": (room, state) => {
  460. },
  461. "enter": (room, state) => {
  462. playLoop("loop/stomach.ogg");
  463. startTimer({
  464. id: "digest",
  465. func: state => {
  466. changeStat("health", -0.3, state);
  467. if (getStat("health", state) <= 0) {
  468. print(["You're digested before too long."]);
  469. goToRoom("digested", state);
  470. return false;
  471. }
  472. return true;
  473. },
  474. delay: 100,
  475. loop: true,
  476. classes: [
  477. ]
  478. }, state);
  479. },
  480. "exit": (room, state) => {
  481. },
  482. "actions": [
  483. {
  484. name: "Squirm",
  485. desc: "Rub at the walls of the fox's churning stomach",
  486. execute: (room, state) => {
  487. printRandom([
  488. ["You punch and kick at the walls"],
  489. ["A powerful churn grabs hold of you, stifling any attempts at struggling"],
  490. ["Your little thumps and kicks do little to faze your captor"]
  491. ]);
  492. },
  493. show: [
  494. ],
  495. conditions: [
  496. ]
  497. },
  498. ],
  499. "exits": {
  500. },
  501. "hooks": [
  502. ],
  503. "data": {
  504. "stats": {
  505. }
  506. }
  507. },
  508. "digested": {
  509. "id": "digested",
  510. "name": "Fat",
  511. "desc": "You're just fat now",
  512. "move": (room, state) => {
  513. },
  514. "enter": (room, state) => {
  515. },
  516. "exit": (room, state) => {
  517. },
  518. "actions": [
  519. {
  520. name: "Gurgle",
  521. desc: "Glorp",
  522. execute: (room, state) => {
  523. printRandom([
  524. ["Grrrrgle"],
  525. ["Glorp"],
  526. ["Glrrrrrrnnnnnn..."],
  527. ["Gwoooooorgle"]
  528. ]);
  529. },
  530. show: [
  531. ],
  532. conditions: [
  533. ]
  534. },
  535. ],
  536. "exits": {
  537. },
  538. "hooks": [
  539. ],
  540. "data": {
  541. "stats": {
  542. }
  543. }
  544. },
  545. }
  546. });
  547. })();