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