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