freebsd-nq/games/adventure/main.c
Jordan K. Hubbard 554eb505f8 Bring in the 4.4 Lite games directory, modulo man page changes and segregation
of the x11 based games.  I'm not going to tag the originals with bsd_44_lite
and do this in two stages since it's just not worth it for this collection,
and I've got directory renames to deal with that way.  Bleah.
Submitted by:	jkh
1994-09-04 04:03:31 +00:00

581 lines
18 KiB
C

/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* The game adventure was originally written in Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by Jim
* Gillogly. This code is derived from software contributed to Berkeley
* by Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/2/93";
#endif /* not lint */
/* Re-coding of advent in C: main program */
#include <sys/file.h>
#include <stdio.h>
#include "hdr.h"
main(argc,argv)
int argc;
char **argv;
{
extern int errno;
register int i;
int rval,ll;
struct text *kk;
extern trapdel();
init(); /* Initialize everything */
signal(2,trapdel);
if (argc > 1) /* Restore file specified */
{ /* Restart is label 8305 (Fortran) */
i = restore(argv[1]); /* See what we've got */
switch(i)
{
case 0: /* The restore worked fine */
yea=Start(0);
k=null;
unlink(argv[1]);/* Don't re-use the save */
goto l8; /* Get where we're going */
case 1: /* Couldn't open it */
exit(0); /* So give up */
case 2: /* Oops -- file was altered */
rspeak(202); /* You dissolve */
exit(0); /* File could be non-adventure */
} /* So don't unlink it. */
}
startup(); /* prepare for a user */
for (;;) /* main command loop (label 2) */
{ if (newloc<9 && newloc!=0 && closng)
{ rspeak(130); /* if closing leave only by */
newloc=loc; /* main office */
if (!panic) clock2=15;
panic=TRUE;
}
rval=fdwarf(); /* dwarf stuff */
if (rval==99) die(99);
l2000: if (loc==0) die(99); /* label 2000 */
kk = &stext[loc];
if ((abb[loc]%abbnum)==0 || kk->seekadr==0)
kk = &ltext[loc];
if (!forced(loc) && dark(0))
{ if (wzdark && pct(35))
{ die(90);
goto l2000;
}
kk = &rtext[16];
}
l2001: if (toting(bear)) rspeak(141); /* 2001 */
speak(kk);
k=1;
if (forced(loc))
goto l8;
if (loc==33 && pct(25)&&!closng) rspeak(8);
if (!dark(0))
{ abb[loc]++;
for (i=atloc[loc]; i!=0; i=link[i]) /*2004 */
{ obj=i;
if (obj>100) obj -= 100;
if (obj==steps && toting(nugget)) continue;
if (prop[obj]<0)
{ if (closed) continue;
prop[obj]=0;
if (obj==rug||obj==chain)
prop[obj]=1;
tally--;
if (tally==tally2 && tally != 0)
if (limit>35) limit=35;
}
ll = prop[obj]; /* 2006 */
if (obj==steps && loc==fixed[steps])
ll = 1;
pspeak(obj, ll);
} /* 2008 */
goto l2012;
l2009: k=54; /* 2009 */
l2010: spk=k;
l2011: rspeak(spk);
}
l2012: verb=0; /* 2012 */
obj=0;
l2600: checkhints(); /* to 2600-2602 */
if (closed)
{ if (prop[oyster]<0 && toting(oyster))
pspeak(oyster,1);
for (i=1; i<100; i++)
if (toting(i)&&prop[i]<0) /*2604 */
prop[i] = -1-prop[i];
}
wzdark=dark(0); /* 2605 */
if (knfloc>0 && knfloc!=loc) knfloc=1;
getin(&wd1,&wd2);
if (delhit) /* user typed a DEL */
{ delhit=0; /* reset counter */
copystr("quit",wd1); /* pretend he's quitting*/
*wd2=0;
}
l2608: if ((foobar = -foobar)>0) foobar=0; /* 2608 */
/* should check here for "magic mode" */
turns++;
if (demo && turns>=SHORT) done(1); /* to 13000 */
if (verb==say && *wd2!=0) verb=0;
if (verb==say)
goto l4090;
if (tally==0 && loc>=15 && loc!=33) clock1--;
if (clock1==0)
{ closing(); /* to 10000 */
goto l19999;
}
if (clock1<0) clock2--;
if (clock2==0)
{ caveclose(); /* to 11000 */
continue; /* back to 2 */
}
if (prop[lamp]==1) limit--;
if (limit<=30 && here(batter) && prop[batter]==0
&& here(lamp))
{ rspeak(188); /* 12000 */
prop[batter]=1;
if (toting(batter)) drop(batter,loc);
limit=limit+2500;
lmwarn=FALSE;
goto l19999;
}
if (limit==0)
{ limit = -1; /* 12400 */
prop[lamp]=0;
rspeak(184);
goto l19999;
}
if (limit<0&&loc<=8)
{ rspeak(185); /* 12600 */
gaveup=TRUE;
done(2); /* to 20000 */
}
if (limit<=30)
{ if (lmwarn|| !here(lamp)) goto l19999; /*12200*/
lmwarn=TRUE;
spk=187;
if (place[batter]==0) spk=183;
if (prop[batter]==1) spk=189;
rspeak(spk);
}
l19999: k=43;
if (liqloc(loc)==water) k=70;
if (weq(wd1,"enter") &&
(weq(wd2,"strea")||weq(wd2,"water")))
goto l2010;
if (weq(wd1,"enter") && *wd2!=0) goto l2800;
if ((!weq(wd1,"water")&&!weq(wd1,"oil"))
|| (!weq(wd2,"plant")&&!weq(wd2,"door")))
goto l2610;
if (at(vocab(wd2,1))) copystr("pour",wd2);
l2610: if (weq(wd1,"west"))
if (++iwest==10) rspeak(17);
l2630: i=vocab(wd1,-1);
if (i== -1)
{ spk=60; /* 3000 */
if (pct(20)) spk=61;
if (pct(20)) spk=13;
rspeak(spk);
goto l2600;
}
k=i%1000;
kq=i/1000+1;
switch(kq)
{ case 1: goto l8;
case 2: goto l5000;
case 3: goto l4000;
case 4: goto l2010;
default:
printf("Error 22\n");
exit(0);
}
l8:
switch(march())
{ case 2: continue; /* i.e. goto l2 */
case 99:
switch(die(99))
{ case 2000: goto l2000;
default: bug(111);
}
default: bug(110);
}
l2800: copystr(wd2,wd1);
*wd2=0;
goto l2610;
l4000: verb=k;
spk=actspk[verb];
if (*wd2!=0 && verb!=say) goto l2800;
if (verb==say) obj= *wd2;
if (obj!=0) goto l4090;
l4080:
switch(verb)
{ case 1: /* take = 8010 */
if (atloc[loc]==0||link[atloc[loc]]!=0) goto l8000;
for (i=1; i<=5; i++)
if (dloc[i]==loc&&dflag>=2) goto l8000;
obj=atloc[loc];
goto l9010;
case 2: case 3: case 9: /* 8000 : drop,say,wave */
case 10: case 16: case 17: /* calm,rub,toss */
case 19: case 21: case 28: /* find,feed,break */
case 29: /* wake */
l8000: printf("%s what?\n",wd1);
obj=0;
goto l2600;
case 4: case 6: /* 8040 open,lock */
spk=28;
if (here(clam)) obj=clam;
if (here(oyster)) obj=oyster;
if (at(door)) obj=door;
if (at(grate)) obj=grate;
if (obj!=0 && here(chain)) goto l8000;
if (here(chain)) obj=chain;
if (obj==0) goto l2011;
goto l9040;
case 5: goto l2009; /* nothing */
case 7: goto l9070; /* on */
case 8: goto l9080; /* off */
case 11: goto l8000; /* walk */
case 12: goto l9120; /* kill */
case 13: goto l9130; /* pour */
case 14: /* eat: 8140 */
if (!here(food)) goto l8000;
l8142: dstroy(food);
spk=72;
goto l2011;
case 15: goto l9150; /* drink */
case 18: /* quit: 8180 */
gaveup=yes(22,54,54);
if (gaveup) done(2); /* 8185 */
goto l2012;
case 20: /* invent=8200 */
spk=98;
for (i=1; i<=100; i++)
{ if (i!=bear && toting(i))
{ if (spk==98) rspeak(99);
blklin=FALSE;
pspeak(i,-1);
blklin=TRUE;
spk=0;
}
}
if (toting(bear)) spk=141;
goto l2011;
case 22: goto l9220; /* fill */
case 23: goto l9230; /* blast */
case 24: /* score: 8240 */
scorng=TRUE;
printf("If you were to quit now, you would score");
printf(" %d out of a possible ",score());
printf("%d.",mxscor);
scorng=FALSE;
gaveup=yes(143,54,54);
if (gaveup) done(2);
goto l2012;
case 25: /* foo: 8250 */
k=vocab(wd1,3);
spk=42;
if (foobar==1-k) goto l8252;
if (foobar!=0) spk=151;
goto l2011;
l8252: foobar=k;
if (k!=4) goto l2009;
foobar=0;
if (place[eggs]==plac[eggs]
||(toting(eggs)&&loc==plac[eggs])) goto l2011;
if (place[eggs]==0&&place[troll]==0&&prop[troll]==0)
prop[troll]=1;
k=2;
if (here(eggs)) k=1;
if (loc==plac[eggs]) k=0;
move(eggs,plac[eggs]);
pspeak(eggs,k);
goto l2012;
case 26: /* brief=8260 */
spk=156;
abbnum=10000;
detail=3;
goto l2011;
case 27: /* read=8270 */
if (here(magzin)) obj=magzin;
if (here(tablet)) obj=obj*100+tablet;
if (here(messag)) obj=obj*100+messag;
if (closed&&toting(oyster)) obj=oyster;
if (obj>100||obj==0||dark(0)) goto l8000;
goto l9270;
case 30: /* suspend=8300 */
spk=201;
if (demo) goto l2011;
printf("I can suspend your adventure for you so");
printf(" you can resume later, but\n");
printf("you will have to wait at least");
printf(" %d minutes before continuing.",latncy);
if (!yes(200,54,54)) goto l2012;
datime(&saved,&savet);
ciao(argv[0]); /* Do we quit? */
continue; /* Maybe not */
case 31: /* hours=8310 */
printf("Colossal cave is closed 9am-5pm Mon ");
printf("through Fri except holidays.\n");
goto l2012;
default: bug(23);
}
l4090:
switch(verb)
{ case 1: /* take = 9010 */
l9010: switch(trtake())
{ case 2011: goto l2011;
case 9220: goto l9220;
case 2009: goto l2009;
case 2012: goto l2012;
default: bug(102);
}
l9020: case 2: /* drop = 9020 */
switch(trdrop())
{ case 2011: goto l2011;
case 19000: done(3);
case 2012: goto l2012;
default: bug(105);
}
l9030: case 3:
switch(trsay())
{ case 2012: goto l2012;
case 2630: goto l2630;
default: bug(107);
}
l9040: case 4: case 6: /* open, close */
switch(tropen())
{ case 2011: goto l2011;
case 2010: goto l2010;
default: bug(106);
}
case 5: goto l2009; /* nothing */
case 7: /* on 9070 */
l9070: if (!here(lamp)) goto l2011;
spk=184;
if (limit<0) goto l2011;
prop[lamp]=1;
rspeak(39);
if (wzdark) goto l2000;
goto l2012;
case 8: /* off */
l9080: if (!here(lamp)) goto l2011;
prop[lamp]=0;
rspeak(40);
if (dark(0)) rspeak(16);
goto l2012;
case 9: /* wave */
if ((!toting(obj))&&(obj!=rod||!toting(rod2)))
spk=29;
if (obj!=rod||!at(fissur)||!toting(obj)||closng)
goto l2011;
prop[fissur]=1-prop[fissur];
pspeak(fissur,2-prop[fissur]);
goto l2012;
case 10: case 11: case 18: /* calm, walk, quit */
case 24: case 25: case 26: /* score, foo, brief */
case 30: case 31: /* suspend, hours */
goto l2011;
l9120: case 12: /* kill */
switch(trkill())
{ case 8000: goto l8000;
case 8: goto l8;
case 2011: goto l2011;
case 2608: goto l2608;
case 19000: done(3);
default: bug(112);
}
l9130: case 13: /* pour */
if (obj==bottle||obj==0) obj=liq(0);
if (obj==0) goto l8000;
if (!toting(obj)) goto l2011;
spk=78;
if (obj!=oil&&obj!=water) goto l2011;
prop[bottle]=1;
place[obj]=0;
spk=77;
if (!(at(plant)||at(door))) goto l2011;
if (at(door))
{ prop[door]=0; /* 9132 */
if (obj==oil) prop[door]=1;
spk=113+prop[door];
goto l2011;
}
spk=112;
if (obj!=water) goto l2011;
pspeak(plant,prop[plant]+1);
prop[plant]=(prop[plant]+2)% 6;
prop[plant2]=prop[plant]/2;
k=null;
goto l8;
case 14: /* 9140 - eat */
if (obj==food) goto l8142;
if (obj==bird||obj==snake||obj==clam||obj==oyster
||obj==dwarf||obj==dragon||obj==troll
||obj==bear) spk=71;
goto l2011;
l9150: case 15: /* 9150 - drink */
if (obj==0&&liqloc(loc)!=water&&(liq(0)!=water
||!here(bottle))) goto l8000;
if (obj!=0&&obj!=water) spk=110;
if (spk==110||liq(0)!=water||!here(bottle))
goto l2011;
prop[bottle]=1;
place[water]=0;
spk=74;
goto l2011;
case 16: /* 9160: rub */
if (obj!=lamp) spk=76;
goto l2011;
case 17: /* 9170: throw */
switch(trtoss())
{ case 2011: goto l2011;
case 9020: goto l9020;
case 9120: goto l9120;
case 8: goto l8;
case 9210: goto l9210;
default: bug(113);
}
case 19: case 20: /* 9190: find, invent */
if (at(obj)||(liq(0)==obj&&at(bottle))
||k==liqloc(loc)) spk=94;
for (i=1; i<=5; i++)
if (dloc[i]==loc&&dflag>=2&&obj==dwarf)
spk=94;
if (closed) spk=138;
if (toting(obj)) spk=24;
goto l2011;
l9210: case 21: /* feed */
switch(trfeed())
{ case 2011: goto l2011;
default: bug(114);
}
l9220: case 22: /* fill */
switch(trfill())
{ case 2011: goto l2011;
case 8000: goto l8000;
case 9020: goto l9020;
default: bug(115);
}
l9230: case 23: /* blast */
if (prop[rod2]<0||!closed) goto l2011;
bonus=133;
if (loc==115) bonus=134;
if (here(rod2)) bonus=135;
rspeak(bonus);
done(2);
l9270: case 27: /* read */
if (dark(0)) goto l5190;
if (obj==magzin) spk=190;
if (obj==tablet) spk=196;
if (obj==messag) spk=191;
if (obj==oyster&&hinted[2]&&toting(oyster)) spk=194;
if (obj!=oyster||hinted[2]||!toting(oyster)
||!closed) goto l2011;
hinted[2]=yes(192,193,54);
goto l2012;
l9280: case 28: /* break */
if (obj==mirror) spk=148;
if (obj==vase&&prop[vase]==0)
{ spk=198;
if (toting(vase)) drop(vase,loc);
prop[vase]=2;
fixed[vase]= -1;
goto l2011;
}
if (obj!=mirror||!closed) goto l2011;
rspeak(197);
done(3);
l9290: case 29: /* wake */
if (obj!=dwarf||!closed) goto l2011;
rspeak(199);
done(3);
default: bug(24);
}
l5000:
obj=k;
if (fixed[k]!=loc && !here(k)) goto l5100;
l5010: if (*wd2!=0) goto l2800;
if (verb!=0) goto l4090;
printf("What do you want to do with the %s?\n",wd1);
goto l2600;
l5100: if (k!=grate) goto l5110;
if (loc==1||loc==4||loc==7) k=dprssn;
if (loc>9&&loc<15) k=entrnc;
if (k!=grate) goto l8;
l5110: if (k!=dwarf) goto l5120;
for (i=1; i<=5; i++)
if (dloc[i]==loc&&dflag>=2) goto l5010;
l5120: if ((liq(0)==k&&here(bottle))||k==liqloc(loc)) goto l5010;
if (obj!=plant||!at(plant2)||prop[plant2]==0) goto l5130;
obj=plant2;
goto l5010;
l5130: if (obj!=knife||knfloc!=loc) goto l5140;
knfloc = -1;
spk=116;
goto l2011;
l5140: if (obj!=rod||!here(rod2)) goto l5190;
obj=rod2;
goto l5010;
l5190: if ((verb==find||verb==invent)&&*wd2==0) goto l5010;
printf("I see no %s here\n",wd1);
goto l2012;
}
}