#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1991, 1993\
The Regents of the University of California. All rights reserved.");
#endif
#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/2/93";
#else
__RCSID("$NetBSD: main.c,v 1.22 2021/05/02 12:50:43 rillig Exp $");
#endif
#endif
#include <sys/file.h>
#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "hdr.h"
#include "extern.h"
int
main(int argc, char **argv)
{
int i;
int rval, ll;
struct text *kk;
setgid(getgid());
init();
signal(SIGINT, trapdel);
if (argc > 1) {
i = restore(argv[1]);
switch (i) {
case 0:
yea = Start();
k = null;
unlink(argv[1]);
goto l8;
case 1:
errx(1,"can't open file");
case 2:
rspeak(202);
exit(1);
}
}
startup();
for (;;) {
if (newloc < 9 && newloc != 0 && isclosing) {
rspeak(130);
newloc = loc;
if (!panic)
clock2 = 15;
panic = TRUE;
}
rval = fdwarf();
if (rval == 99)
die(99);
l2000: if (loc == 0)
die(99);
kk = &stext[loc];
if ((abb[loc] % abbnum) == 0 || kk->seekadr == 0)
kk = <ext[loc];
if (!forced(loc) && dark()) {
if (wasdark && pct(35)) {
die(90);
goto l2000;
}
kk = &rtext[16];
}
#if 0
l2001:
#endif
if (toting(bear))
rspeak(141);
speak(kk);
k = 1;
if (forced(loc))
goto l8;
if (loc == 33 && pct(25) && !isclosing)
rspeak(8);
if (!dark()) {
abb[loc]++;
for (i = atloc[loc]; i != 0; i = links[i]) {
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];
if (obj == steps && loc == fixed[steps])
ll = 1;
pspeak(obj, ll);
}
goto l2012;
l2009: k = 54;
l2010: spk = k;
l2011: rspeak(spk);
}
l2012: verb = 0;
obj = 0;
l2600: checkhints();
if (closed) {
if (prop[oyster] < 0 && toting(oyster))
pspeak(oyster, 1);
for (i = 1; i < 100; i++)
if (toting(i) && prop[i] < 0)
prop[i] = -1 - prop[i];
}
wasdark = dark();
if (knfloc > 0 && knfloc != loc)
knfloc = 1;
getin(&wd1, &wd2);
if (delhit) {
delhit = 0;
copystr("quit", wd1);
*wd2 = 0;
}
l2608: if ((foobar = -foobar) > 0)
foobar = 0;
turns++;
if (demo && turns >= SHORT)
done(1);
if (verb == say && *wd2 != 0)
verb = 0;
if (verb == say)
goto l4090;
if (tally == 0 && loc >= 15 && loc != 33)
clock1--;
if (clock1 == 0) {
closing();
goto l19999;
}
if (clock1 < 0)
clock2--;
if (clock2 == 0) {
caveclose();
continue;
}
if (prop[lamp] == 1)
limit--;
if (limit <= 30 && here(batter) && prop[batter] == 0
&& here(lamp)) {
rspeak(188);
prop[batter] = 1;
if (toting(batter))
drop(batter, loc);
limit = limit + 2500;
lmwarn = FALSE;
goto l19999;
}
if (limit == 0) {
limit = -1;
prop[lamp] = 0;
rspeak(184);
goto l19999;
}
if (limit < 0 && loc <= 8) {
rspeak(185);
gaveup = TRUE;
done(2);
}
if (limit <= 30) {
if (lmwarn || !here(lamp))
goto l19999;
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, 0)))
copystr("pour", wd2);
l2610: if (weq(wd1, "west"))
if (++iwest == 10)
rspeak(17);
l2630: i = vocab(wd1, -1, 0);
if (i == -1) {
spk = 60;
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:
bug(22);
}
l8:
switch (march()) {
case 2:
continue;
case 99:
die(99);
goto l2000;
default:
bug(110);
}
l2800: copystr(wd2, wd1);
*wd2 = 0;
goto l2610;
l4000: verb = k;
spk = actspeak[verb];
if (*wd2 != 0 && verb != say)
goto l2800;
if (verb == say)
obj = *wd2;
if (obj != 0)
goto l4090;
#if 0
l4080:
#endif
switch (verb) {
case 1:
if (atloc[loc] == 0 || links[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:
case 10:
case 16:
case 17:
case 19:
case 21:
case 28:
case 29:
l8000: printf("%s what?\n", wd1);
obj = 0;
goto l2600;
case 4:
case 6:
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;
case 7:
goto l9070;
case 8:
goto l9080;
case 11:
goto l8000;
case 12:
goto l9120;
case 13:
goto l9130;
case 14:
if (!here(food))
goto l8000;
l8142: destroy(food);
spk = 72;
goto l2011;
case 15:
goto l9150;
case 18:
gaveup = yes(22, 54, 54);
if (gaveup)
done(2);
goto l2012;
case 20:
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;
case 23:
goto l9230;
case 24:
scoring = TRUE;
printf("If you were to quit now, you would score");
printf(" %d out of a possible ", score());
printf("%d.", maxscore);
scoring = FALSE;
gaveup = yes(143, 54, 54);
if (gaveup)
done(2);
goto l2012;
case 25:
k = vocab(wd1, 3, 0);
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:
spk = 156;
abbnum = 10000;
detail = 3;
goto l2011;
case 27:
if (here(magazine))
obj = magazine;
if (here(tablet))
obj = obj * 100 + tablet;
if (here(message))
obj = obj * 100 + message;
if (closed && toting(oyster))
obj = oyster;
if (obj > 100 || obj == 0 || dark())
goto l8000;
goto l9270;
case 30:
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.", latency);
if (!yes(200, 54, 54))
goto l2012;
datime(&saveday, &savet);
ciao();
continue;
case 31:
printf("Colossal cave is closed 9am-5pm Mon ");
printf("through Fri except holidays.\n");
goto l2012;
default:
bug(23);
}
l4090:
switch (verb) {
case 1:
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:
switch (trdrop()) {
case 2011:
goto l2011;
case 19000:
done(3);
case 2012:
goto l2012;
default:
bug(105);
}
#if 0
l9030:
#endif
case 3:
switch (trsay()) {
case 2012:
goto l2012;
case 2630:
goto l2630;
default:
bug(107);
}
l9040: case 4:
case 6:
switch (tropen()) {
case 2011:
goto l2011;
case 2010:
goto l2010;
default:
bug(106);
}
case 5:
goto l2009;
case 7:
l9070: if (!here(lamp))
goto l2011;
spk = 184;
if (limit < 0)
goto l2011;
prop[lamp] = 1;
rspeak(39);
if (wasdark)
goto l2000;
goto l2012;
case 8:
l9080: if (!here(lamp))
goto l2011;
prop[lamp] = 0;
rspeak(40);
if (dark())
rspeak(16);
goto l2012;
case 9:
if ((!toting(obj)) && (obj != rod || !toting(rod2)))
spk = 29;
if (obj != rod || !at(fissure) || !toting(obj) || isclosing)
goto l2011;
prop[fissure] = 1 - prop[fissure];
pspeak(fissure, 2 - prop[fissure]);
goto l2012;
case 10:
case 11:
case 18:
case 24:
case 25:
case 26:
case 30:
case 31:
goto l2011;
l9120: case 12:
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:
if (obj == bottle || obj == 0)
obj = liq();
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;
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:
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:
if (obj == 0 && liqloc(loc) != water && (liq() != water
|| !here(bottle)))
goto l8000;
if (obj != 0 && obj != water)
spk = 110;
if (spk == 110 || liq() != water || !here(bottle))
goto l2011;
prop[bottle] = 1;
place[water] = 0;
spk = 74;
goto l2011;
case 16:
if (obj != lamp)
spk = 76;
goto l2011;
case 17:
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:
if (at(obj) || (liq() == 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:
switch (trfeed()) {
case 2011:
goto l2011;
default:
bug(114);
}
l9220: case 22:
switch (trfill()) {
case 2011:
goto l2011;
case 8000:
goto l8000;
case 9020:
goto l9020;
default:
bug(115);
}
l9230: case 23:
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:
if (dark())
goto l5190;
if (obj == magazine)
spk = 190;
if (obj == tablet)
spk = 196;
if (obj == message)
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;
#if 0
l9280:
#endif
case 28:
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);
#if 0
l9290:
#endif
case 29:
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 = depression;
if (loc > 9 && loc < 15)
k = entrance;
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() == 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;
}
}