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