1 /* $NetBSD: main.c,v 1.20 2008/07/20 01:03:20 lukem 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.20 2008/07/20 01:03:20 lukem 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 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 && closng) { 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 (wzdark && 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) && !closng) 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 wzdark = 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 = actspk[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: dstroy(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 scorng = TRUE; 387 printf("If you were to quit now, you would score"); 388 printf(" %d out of a possible ", score()); 389 printf("%d.", mxscor); 390 scorng = 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(magzin)) 428 obj = magzin; 429 if (here(tablet)) 430 obj = obj * 100 + tablet; 431 if (here(messag)) 432 obj = obj * 100 + messag; 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.", latncy); 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 (wzdark) 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(fissur) || !toting(obj) || closng) 534 goto l2011; 535 prop[fissur] = 1 - prop[fissur]; 536 pspeak(fissur, 2 - prop[fissur]); 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 == magzin) 677 spk = 190; 678 if (obj == tablet) 679 spk = 196; 680 if (obj == messag) 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 = dprssn; 734 if (loc > 9 && loc < 15) 735 k = entrnc; 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