1 /* $NetBSD: main.c,v 1.21 2009/08/25 06:56:52 dholland Exp $ */
2
3 /*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * The game adventure was originally written in Fortran by Will Crowther
8 * and Don Woods. It was later translated to C and enhanced by Jim
9 * Gillogly. This code is derived from software contributed to Berkeley
10 * by Jim Gillogly at The Rand Corporation.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #include <sys/cdefs.h>
38 #ifndef lint
39 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\
40 The Regents of the University of California. All rights reserved.");
41 #endif /* not lint */
42
43 #ifndef lint
44 #if 0
45 static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/2/93";
46 #else
47 __RCSID("$NetBSD: main.c,v 1.21 2009/08/25 06:56:52 dholland Exp $");
48 #endif
49 #endif /* not lint */
50
51 /* Re-coding of advent in C: main program */
52
53 #include <sys/file.h>
54 #include <err.h>
55 #include <signal.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <unistd.h>
59 #include "hdr.h"
60 #include "extern.h"
61
62 int
main(int argc,char ** argv)63 main(int argc, char **argv)
64 {
65 int i;
66 int rval, ll;
67 struct text *kk;
68
69 /* revoke setgid privileges from dm */
70 setgid(getgid());
71
72 init(); /* Initialize everything */
73 signal(SIGINT, trapdel);
74
75 if (argc > 1) { /* Restore file specified */
76 /* Restart is label 8305 (Fortran) */
77 i = restore(argv[1]); /* See what we've got */
78 switch (i) {
79 case 0: /* The restore worked fine */
80 yea = Start();
81 k = null;
82 unlink(argv[1]); /* Don't re-use the save */
83 goto l8; /* Get where we're going */
84 case 1: /* Couldn't open it */
85 errx(1,"can't open file"); /* So give up */
86 case 2: /* Oops -- file was altered */
87 rspeak(202); /* You dissolve */
88 exit(1); /* File could be non-adventure */
89 } /* So don't unlink it. */
90 }
91 startup(); /* prepare for a user */
92
93 for (;;) { /* main command loop (label 2) */
94 if (newloc < 9 && newloc != 0 && isclosing) {
95 rspeak(130); /* if closing leave only by */
96 newloc = loc; /* main office */
97 if (!panic)
98 clock2 = 15;
99 panic = TRUE;
100 }
101 rval = fdwarf(); /* dwarf stuff */
102 if (rval == 99)
103 die(99);
104
105 l2000: if (loc == 0)
106 die(99); /* label 2000 */
107 kk = &stext[loc];
108 if ((abb[loc] % abbnum) == 0 || kk->seekadr == 0)
109 kk = <ext[loc];
110 if (!forced(loc) && dark()) {
111 if (wasdark && pct(35)) {
112 die(90);
113 goto l2000;
114 }
115 kk = &rtext[16];
116 }
117 #if 0
118 l2001:
119 #endif
120 if (toting(bear))
121 rspeak(141); /* 2001 */
122 speak(kk);
123 k = 1;
124 if (forced(loc))
125 goto l8;
126 if (loc == 33 && pct(25) && !isclosing)
127 rspeak(8);
128 if (!dark()) {
129 abb[loc]++;
130 for (i = atloc[loc]; i != 0; i = links[i]) { /* 2004 */
131 obj = i;
132 if (obj > 100)
133 obj -= 100;
134 if (obj == steps && toting(nugget))
135 continue;
136 if (prop[obj] < 0) {
137 if (closed)
138 continue;
139 prop[obj] = 0;
140 if (obj == rug || obj == chain)
141 prop[obj] = 1;
142 tally--;
143 if (tally == tally2 && tally != 0)
144 if (limit > 35)
145 limit = 35;
146 }
147 ll = prop[obj]; /* 2006 */
148 if (obj == steps && loc == fixed[steps])
149 ll = 1;
150 pspeak(obj, ll);
151 } /* 2008 */
152 goto l2012;
153 l2009: k = 54; /* 2009 */
154 l2010: spk = k;
155 l2011: rspeak(spk);
156 }
157 l2012: verb = 0; /* 2012 */
158 obj = 0;
159 l2600: checkhints(); /* to 2600-2602 */
160 if (closed) {
161 if (prop[oyster] < 0 && toting(oyster))
162 pspeak(oyster, 1);
163 for (i = 1; i < 100; i++)
164 if (toting(i) && prop[i] < 0) /* 2604 */
165 prop[i] = -1 - prop[i];
166 }
167 wasdark = dark(); /* 2605 */
168 if (knfloc > 0 && knfloc != loc)
169 knfloc = 1;
170 getin(&wd1, &wd2);
171 if (delhit) { /* user typed a DEL */
172 delhit = 0; /* reset counter */
173 copystr("quit", wd1); /* pretend he's quitting */
174 *wd2 = 0;
175 }
176 l2608: if ((foobar = -foobar) > 0)
177 foobar = 0; /* 2608 */
178 /* should check here for "magic mode" */
179 turns++;
180 if (demo && turns >= SHORT)
181 done(1); /* to 13000 */
182
183 if (verb == say && *wd2 != 0)
184 verb = 0;
185 if (verb == say)
186 goto l4090;
187 if (tally == 0 && loc >= 15 && loc != 33)
188 clock1--;
189 if (clock1 == 0) {
190 closing(); /* to 10000 */
191 goto l19999;
192 }
193 if (clock1 < 0)
194 clock2--;
195 if (clock2 == 0) {
196 caveclose(); /* to 11000 */
197 continue; /* back to 2 */
198 }
199 if (prop[lamp] == 1)
200 limit--;
201 if (limit <= 30 && here(batter) && prop[batter] == 0
202 && here(lamp)) {
203 rspeak(188); /* 12000 */
204 prop[batter] = 1;
205 if (toting(batter))
206 drop(batter, loc);
207 limit = limit + 2500;
208 lmwarn = FALSE;
209 goto l19999;
210 }
211 if (limit == 0) {
212 limit = -1; /* 12400 */
213 prop[lamp] = 0;
214 rspeak(184);
215 goto l19999;
216 }
217 if (limit < 0 && loc <= 8) {
218 rspeak(185); /* 12600 */
219 gaveup = TRUE;
220 done(2); /* to 20000 */
221 }
222 if (limit <= 30) {
223 if (lmwarn || !here(lamp))
224 goto l19999; /* 12200 */
225 lmwarn = TRUE;
226 spk = 187;
227 if (place[batter] == 0)
228 spk = 183;
229 if (prop[batter] == 1)
230 spk = 189;
231 rspeak(spk);
232 }
233 l19999: k = 43;
234 if (liqloc(loc) == water)
235 k = 70;
236 if (weq(wd1, "enter") &&
237 (weq(wd2, "strea") || weq(wd2, "water")))
238 goto l2010;
239 if (weq(wd1, "enter") && *wd2 != 0)
240 goto l2800;
241 if ((!weq(wd1, "water") && !weq(wd1, "oil"))
242 || (!weq(wd2, "plant") && !weq(wd2, "door")))
243 goto l2610;
244 if (at(vocab(wd2, 1, 0)))
245 copystr("pour", wd2);
246
247 l2610: if (weq(wd1, "west"))
248 if (++iwest == 10)
249 rspeak(17);
250 l2630: i = vocab(wd1, -1, 0);
251 if (i == -1) {
252 spk = 60; /* 3000 */
253 if (pct(20))
254 spk = 61;
255 if (pct(20))
256 spk = 13;
257 rspeak(spk);
258 goto l2600;
259 }
260 k = i % 1000;
261 kq = i / 1000 + 1;
262 switch (kq) {
263 case 1:
264 goto l8;
265 case 2:
266 goto l5000;
267 case 3:
268 goto l4000;
269 case 4:
270 goto l2010;
271 default:
272 bug(22);
273 }
274
275 l8:
276 switch (march()) {
277 case 2:
278 continue; /* i.e. goto l2 */
279 case 99:
280 die(99);
281 goto l2000;
282 default:
283 bug(110);
284 }
285
286 l2800: copystr(wd2, wd1);
287 *wd2 = 0;
288 goto l2610;
289
290 l4000: verb = k;
291 spk = actspeak[verb];
292 if (*wd2 != 0 && verb != say)
293 goto l2800;
294 if (verb == say)
295 obj = *wd2;
296 if (obj != 0)
297 goto l4090;
298 #if 0
299 l4080:
300 #endif
301 switch (verb) {
302 case 1: /* take = 8010 */
303 if (atloc[loc] == 0 || links[atloc[loc]] != 0)
304 goto l8000;
305 for (i = 1; i <= 5; i++)
306 if (dloc[i] == loc && dflag >= 2)
307 goto l8000;
308 obj = atloc[loc];
309 goto l9010;
310 case 2:
311 case 3:
312 case 9: /* 8000 : drop,say,wave */
313 case 10:
314 case 16:
315 case 17: /* calm,rub,toss */
316 case 19:
317 case 21:
318 case 28: /* find,feed,break */
319 case 29: /* wake */
320 l8000: printf("%s what?\n", wd1);
321 obj = 0;
322 goto l2600;
323 case 4:
324 case 6: /* 8040 open,lock */
325 spk = 28;
326 if (here(clam))
327 obj = clam;
328 if (here(oyster))
329 obj = oyster;
330 if (at(door))
331 obj = door;
332 if (at(grate))
333 obj = grate;
334 if (obj != 0 && here(chain))
335 goto l8000;
336 if (here(chain))
337 obj = chain;
338 if (obj == 0)
339 goto l2011;
340 goto l9040;
341 case 5:
342 goto l2009; /* nothing */
343 case 7:
344 goto l9070; /* on */
345 case 8:
346 goto l9080; /* off */
347 case 11:
348 goto l8000; /* walk */
349 case 12:
350 goto l9120; /* kill */
351 case 13:
352 goto l9130; /* pour */
353 case 14: /* eat: 8140 */
354 if (!here(food))
355 goto l8000;
356 l8142: destroy(food);
357 spk = 72;
358 goto l2011;
359 case 15:
360 goto l9150; /* drink */
361 case 18: /* quit: 8180 */
362 gaveup = yes(22, 54, 54);
363 if (gaveup)
364 done(2); /* 8185 */
365 goto l2012;
366 case 20: /* invent=8200 */
367 spk = 98;
368 for (i = 1; i <= 100; i++) {
369 if (i != bear && toting(i)) {
370 if (spk == 98)
371 rspeak(99);
372 blklin = FALSE;
373 pspeak(i, -1);
374 blklin = TRUE;
375 spk = 0;
376 }
377 }
378 if (toting(bear))
379 spk = 141;
380 goto l2011;
381 case 22:
382 goto l9220; /* fill */
383 case 23:
384 goto l9230; /* blast */
385 case 24: /* score: 8240 */
386 scoring = TRUE;
387 printf("If you were to quit now, you would score");
388 printf(" %d out of a possible ", score());
389 printf("%d.", maxscore);
390 scoring = FALSE;
391 gaveup = yes(143, 54, 54);
392 if (gaveup)
393 done(2);
394 goto l2012;
395 case 25: /* foo: 8250 */
396 k = vocab(wd1, 3, 0);
397 spk = 42;
398 if (foobar == 1 - k)
399 goto l8252;
400 if (foobar != 0)
401 spk = 151;
402 goto l2011;
403 l8252: foobar = k;
404 if (k != 4)
405 goto l2009;
406 foobar = 0;
407 if (place[eggs] == plac[eggs]
408 || (toting(eggs) && loc == plac[eggs]))
409 goto l2011;
410 if (place[eggs] == 0 && place[troll] == 0 &&
411 prop[troll] == 0)
412 prop[troll] = 1;
413 k = 2;
414 if (here(eggs))
415 k = 1;
416 if (loc == plac[eggs])
417 k = 0;
418 move(eggs, plac[eggs]);
419 pspeak(eggs, k);
420 goto l2012;
421 case 26: /* brief=8260 */
422 spk = 156;
423 abbnum = 10000;
424 detail = 3;
425 goto l2011;
426 case 27: /* read=8270 */
427 if (here(magazine))
428 obj = magazine;
429 if (here(tablet))
430 obj = obj * 100 + tablet;
431 if (here(message))
432 obj = obj * 100 + message;
433 if (closed && toting(oyster))
434 obj = oyster;
435 if (obj > 100 || obj == 0 || dark())
436 goto l8000;
437 goto l9270;
438 case 30: /* suspend=8300 */
439 spk = 201;
440 if (demo)
441 goto l2011;
442 printf("I can suspend your adventure for you so");
443 printf(" you can resume later, but\n");
444 printf("you will have to wait at least");
445 printf(" %d minutes before continuing.", latency);
446 if (!yes(200, 54, 54))
447 goto l2012;
448 datime(&saveday, &savet);
449 ciao(); /* Do we quit? */
450 continue; /* Maybe not */
451 case 31: /* hours=8310 */
452 printf("Colossal cave is closed 9am-5pm Mon ");
453 printf("through Fri except holidays.\n");
454 goto l2012;
455 default:
456 bug(23);
457 }
458
459 l4090:
460 switch (verb) {
461 case 1: /* take = 9010 */
462 l9010: switch (trtake()) {
463 case 2011:
464 goto l2011;
465 case 9220:
466 goto l9220;
467 case 2009:
468 goto l2009;
469 case 2012:
470 goto l2012;
471 default:
472 bug(102);
473 }
474 l9020: case 2: /* drop = 9020 */
475 switch (trdrop()) {
476 case 2011:
477 goto l2011;
478 case 19000:
479 done(3);
480 case 2012:
481 goto l2012;
482 default:
483 bug(105);
484 }
485 #if 0
486 l9030:
487 #endif
488 case 3:
489 switch (trsay()) {
490 case 2012:
491 goto l2012;
492 case 2630:
493 goto l2630;
494 default:
495 bug(107);
496 }
497 l9040: case 4:
498 case 6: /* open, close */
499 switch (tropen()) {
500 case 2011:
501 goto l2011;
502 case 2010:
503 goto l2010;
504 default:
505 bug(106);
506 }
507 case 5:
508 goto l2009; /* nothing */
509 case 7: /* on 9070 */
510 l9070: if (!here(lamp))
511 goto l2011;
512 spk = 184;
513 if (limit < 0)
514 goto l2011;
515 prop[lamp] = 1;
516 rspeak(39);
517 if (wasdark)
518 goto l2000;
519 goto l2012;
520
521 case 8: /* off */
522 l9080: if (!here(lamp))
523 goto l2011;
524 prop[lamp] = 0;
525 rspeak(40);
526 if (dark())
527 rspeak(16);
528 goto l2012;
529
530 case 9: /* wave */
531 if ((!toting(obj)) && (obj != rod || !toting(rod2)))
532 spk = 29;
533 if (obj != rod || !at(fissure) || !toting(obj) || isclosing)
534 goto l2011;
535 prop[fissure] = 1 - prop[fissure];
536 pspeak(fissure, 2 - prop[fissure]);
537 goto l2012;
538 case 10:
539 case 11:
540 case 18: /* calm, walk, quit */
541 case 24:
542 case 25:
543 case 26: /* score, foo, brief */
544 case 30:
545 case 31: /* suspend, hours */
546 goto l2011;
547 l9120: case 12:/* kill */
548 switch (trkill()) {
549 case 8000:
550 goto l8000;
551 case 8:
552 goto l8;
553 case 2011:
554 goto l2011;
555 case 2608:
556 goto l2608;
557 case 19000:
558 done(3);
559 default:
560 bug(112);
561 }
562 l9130: case 13:/* pour */
563 if (obj == bottle || obj == 0)
564 obj = liq();
565 if (obj == 0)
566 goto l8000;
567 if (!toting(obj))
568 goto l2011;
569 spk = 78;
570 if (obj != oil && obj != water)
571 goto l2011;
572 prop[bottle] = 1;
573 place[obj] = 0;
574 spk = 77;
575 if (!(at(plant) || at(door)))
576 goto l2011;
577 if (at(door)) {
578 prop[door] = 0; /* 9132 */
579 if (obj == oil)
580 prop[door] = 1;
581 spk = 113 + prop[door];
582 goto l2011;
583 }
584 spk = 112;
585 if (obj != water)
586 goto l2011;
587 pspeak(plant, prop[plant] + 1);
588 prop[plant] = (prop[plant] + 2) % 6;
589 prop[plant2] = prop[plant] / 2;
590 k = null;
591 goto l8;
592 case 14: /* 9140 - eat */
593 if (obj == food)
594 goto l8142;
595 if (obj == bird || obj == snake || obj == clam
596 || obj == oyster || obj == dwarf || obj == dragon
597 || obj == troll || obj == bear)
598 spk = 71;
599 goto l2011;
600 l9150: case 15:/* 9150 - drink */
601 if (obj == 0 && liqloc(loc) != water && (liq() != water
602 || !here(bottle)))
603 goto l8000;
604 if (obj != 0 && obj != water)
605 spk = 110;
606 if (spk == 110 || liq() != water || !here(bottle))
607 goto l2011;
608 prop[bottle] = 1;
609 place[water] = 0;
610 spk = 74;
611 goto l2011;
612 case 16: /* 9160: rub */
613 if (obj != lamp)
614 spk = 76;
615 goto l2011;
616 case 17: /* 9170: throw */
617 switch (trtoss()) {
618 case 2011:
619 goto l2011;
620 case 9020:
621 goto l9020;
622 case 9120:
623 goto l9120;
624 case 8:
625 goto l8;
626 case 9210:
627 goto l9210;
628 default:
629 bug(113);
630 }
631 case 19:
632 case 20: /* 9190: find, invent */
633 if (at(obj) || (liq() == obj && at(bottle))
634 || k == liqloc(loc))
635 spk = 94;
636 for (i = 1; i <= 5; i++)
637 if (dloc[i] == loc && dflag >= 2
638 && obj == dwarf)
639 spk = 94;
640 if (closed)
641 spk = 138;
642 if (toting(obj))
643 spk = 24;
644 goto l2011;
645 l9210: case 21:/* feed */
646 switch (trfeed()) {
647 case 2011:
648 goto l2011;
649 default:
650 bug(114);
651 }
652 l9220: case 22:/* fill */
653 switch (trfill()) {
654 case 2011:
655 goto l2011;
656 case 8000:
657 goto l8000;
658 case 9020:
659 goto l9020;
660 default:
661 bug(115);
662 }
663 l9230: case 23:/* blast */
664 if (prop[rod2] < 0 || !closed)
665 goto l2011;
666 bonus = 133;
667 if (loc == 115)
668 bonus = 134;
669 if (here(rod2))
670 bonus = 135;
671 rspeak(bonus);
672 done(2);
673 l9270: case 27:/* read */
674 if (dark())
675 goto l5190;
676 if (obj == magazine)
677 spk = 190;
678 if (obj == tablet)
679 spk = 196;
680 if (obj == message)
681 spk = 191;
682 if (obj == oyster && hinted[2] && toting(oyster))
683 spk = 194;
684 if (obj != oyster || hinted[2] || !toting(oyster)
685 || !closed)
686 goto l2011;
687 hinted[2] = yes(192, 193, 54);
688 goto l2012;
689 #if 0
690 l9280:
691 #endif
692 case 28: /* break */
693 if (obj == mirror)
694 spk = 148;
695 if (obj == vase && prop[vase] == 0) {
696 spk = 198;
697 if (toting(vase))
698 drop(vase, loc);
699 prop[vase] = 2;
700 fixed[vase] = -1;
701 goto l2011;
702 }
703 if (obj != mirror || !closed)
704 goto l2011;
705 rspeak(197);
706 done(3);
707 #if 0
708 l9290:
709 #endif
710 case 29: /* wake */
711 if (obj != dwarf || !closed)
712 goto l2011;
713 rspeak(199);
714 done(3);
715
716 default:
717 bug(24);
718 }
719
720 l5000:
721 obj = k;
722 if (fixed[k] != loc && !here(k))
723 goto l5100;
724 l5010: if (*wd2 != 0)
725 goto l2800;
726 if (verb != 0)
727 goto l4090;
728 printf("What do you want to do with the %s?\n", wd1);
729 goto l2600;
730 l5100: if (k != grate)
731 goto l5110;
732 if (loc == 1 || loc == 4 || loc == 7)
733 k = depression;
734 if (loc > 9 && loc < 15)
735 k = entrance;
736 if (k != grate)
737 goto l8;
738 l5110: if (k != dwarf)
739 goto l5120;
740 for (i = 1; i <= 5; i++)
741 if (dloc[i] == loc && dflag >= 2)
742 goto l5010;
743 l5120: if ((liq() == k && here(bottle)) || k == liqloc(loc))
744 goto l5010;
745 if (obj != plant || !at(plant2) || prop[plant2] == 0)
746 goto l5130;
747 obj = plant2;
748 goto l5010;
749 l5130: if (obj != knife || knfloc != loc)
750 goto l5140;
751 knfloc = -1;
752 spk = 116;
753 goto l2011;
754 l5140: if (obj != rod || !here(rod2))
755 goto l5190;
756 obj = rod2;
757 goto l5010;
758 l5190: if ((verb == find || verb == invent) && *wd2 == 0)
759 goto l5010;
760 printf("I see no %s here\n", wd1);
761 goto l2012;
762 }
763 }
764