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