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