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