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