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