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