#include <stdio.h>
#include <stdlib.h>
#include "extern.h"
#include "hdr.h"
int
toting(int objj)
{
if (place[objj] == -1)
return (TRUE);
return (FALSE);
}
int
here(int objj)
{
if (place[objj] == loc || toting(objj))
return (TRUE);
return (FALSE);
}
int
at(int objj)
{
if (place[objj] == loc || fixed[objj] == loc)
return (TRUE);
else
return (FALSE);
}
int
liq2(int pbotl)
{
return ((1 - pbotl) * water + (pbotl / 2) * (water + oil));
}
int
liq(void)
{
int i;
i = prop[bottle];
if (i > -1 - i)
return (liq2(i));
return (liq2(-1 - i));
}
int
liqloc(int locc)
{
int i, j, l;
i = cond[locc] / 2;
j = ((i * 2) % 8) - 5;
l = cond[locc] / 4;
l = l % 2;
return (liq2(j * l + 1));
}
int
bitset(int l, int n)
{
if (cond[l] & setbit[n])
return (TRUE);
return (FALSE);
}
int
forced(int locc)
{
if (cond[locc] == 2)
return (TRUE);
return (FALSE);
}
int
dark(void)
{
if ((cond[loc] % 2) == 0 && (prop[lamp] == 0 || !here(lamp)))
return (TRUE);
return (FALSE);
}
int
pct(int n)
{
if (ran(100) < n)
return (TRUE);
return (FALSE);
}
int
fdwarf(void)
{
int i, j;
struct travlist *kk;
if (newloc != loc && !forced(loc) && !bitset(loc, 3)) {
for (i = 1; i <= 5; i++) {
if (odloc[i] != newloc || !dseen[i])
continue;
newloc = loc;
rspeak(2);
break;
}
}
loc = newloc;
if (loc == 0 || forced(loc) || bitset(newloc, 3))
return (2000);
if (dflag == 0) {
if (loc >= 15)
dflag = 1;
return (2000);
}
if (dflag == 1) {
if (loc < 15 || pct(95))
return (2000);
dflag = 2;
for (i = 1; i <= 2; i++) {
j = 1 + ran(5);
if (pct(50) && saved == -1)
dloc[j] = 0;
}
for (i = 1; i <= 5; i++) {
if (dloc[i] == loc)
dloc[i] = daltlc;
odloc[i] = dloc[i];
}
rspeak(3);
drop(axe, loc);
return (2000);
}
dtotal = attack = stick = 0;
for (i = 1; i <= 6; i++) {
if (dloc[i] == 0)
continue;
j = 1;
for (kk = travel[dloc[i]]; kk != 0; kk = kk->next) {
newloc = kk->tloc;
if (newloc > 300 || newloc < 15 || newloc == odloc[i]
|| (j > 1 && newloc == tk[j-1]) || j >= 20
|| newloc == dloc[i] || forced(newloc)
|| (i == 6 && bitset(newloc, 3))
|| kk->conditions == 100)
continue;
tk[j++] = newloc;
}
tk[j] = odloc[i];
if (j >= 2)
j--;
j = 1 + ran(j);
odloc[i] = dloc[i];
dloc[i] = tk[j];
dseen[i] = (dseen[i] && loc >= 15) || (dloc[i] == loc || odloc[i] == loc);
if (!dseen[i])
continue;
dloc[i] = loc;
if (i == 6) {
if (loc == chloc || prop[chest] >= 0)
continue;
k = 0;
for (j = 50; j <= maxtrs; j++) {
if (j == pyram && (loc == plac[pyram]
|| loc == plac[emrald]))
goto l6020;
if (toting(j))
goto l6022;
l6020: if (here(j))
k = 1;
}
if (tally == tally2 + 1 && k == 0 && place[chest] == 0
&& here(lamp) && prop[lamp] == 1)
goto l6025;
if (odloc[6] != dloc[6] && pct(20))
rspeak(127);
continue;
l6022: rspeak(128);
if (place[messag] == 0)
move(chest, chloc);
move(messag, chloc2);
for (j = 50; j <= maxtrs; j++) {
if (j == pyram && (loc == plac[pyram]
|| loc == plac[emrald]))
continue;
if (at(j) && fixed[j] == 0)
carry(j, loc);
if (toting(j))
drop(j, chloc);
}
l6024: dloc[6] = odloc[6] = chloc;
dseen[6] = FALSE;
continue;
l6025: rspeak(186);
move(chest, chloc);
move(messag, chloc2);
goto l6024;
}
dtotal++;
if (odloc[i] != dloc[i])
continue;
attack++;
if (knfloc >= 0)
knfloc = loc;
if (ran(1000) < 95 * (dflag - 2))
stick++;
}
if (dtotal == 0)
return (2000);
if (dtotal != 1) {
printf("There are %d threatening little dwarves ", dtotal);
printf("in the room with you.\n");
}
else
rspeak(4);
if (attack == 0)
return (2000);
if (dflag == 2)
dflag = 3;
if (saved != -1)
dflag = 20;
if (attack != 1) {
printf("%d of them throw knives at you!\n", attack);
k = 6;
l82: if (stick <= 1) {
rspeak(k + stick);
if (stick == 0)
return (2000);
} else
printf("%d of them get you!\n", stick);
oldlc2 = loc;
return (99);
}
rspeak(5);
k = 52;
goto l82;
}
int
march(void)
{
int ll1, ll2;
if ((tkk = travel[newloc = loc]) == 0)
bug(26);
if (k == null)
return (2);
if (k == cave) {
if (loc < 8)
rspeak(57);
if (loc >= 8)
rspeak(58);
return (2);
}
if (k == look) {
if (detail++ < 3)
rspeak(15);
wzdark = FALSE;
abb[loc] = 0;
return (2);
}
if (k == back) {
switch(mback()) {
case 2: return (2);
case 9: goto l9;
default: bug(100);
}
}
oldlc2 = oldloc;
oldloc = loc;
l9:
for (; tkk != 0; tkk = tkk->next)
if (tkk->tverb == 1 || tkk->tverb == k)
break;
if (tkk == 0) {
badmove();
return (2);
}
l11: ll1 = tkk->conditions;
ll2 = tkk->tloc;
newloc = ll1;
k = newloc % 100;
if (newloc <= 300) {
if (newloc <= 100) {
if (newloc != 0 && !pct(newloc))
goto l12;
l16: newloc = ll2;
if (newloc <= 300)
return (2);
if (newloc <= 500)
switch (specials()) {
case 2: return (2);
case 12: goto l12;
case 99: return (99);
default: bug(101);
}
rspeak(newloc - 500);
newloc = loc;
return (2);
}
if (toting(k) || (newloc > 200 && at(k)))
goto l16;
goto l12;
}
if (prop[k] != (newloc / 100) - 3)
goto l16;
l12:
for (; tkk != 0; tkk = tkk->next)
if (tkk->tloc != ll2 || tkk->conditions != ll1)
break;
if (tkk == 0)
bug(25);
goto l11;
}
int
mback(void)
{
struct travlist *tk2,*j;
int ll;
if (forced(k = oldloc))
k = oldlc2;
oldlc2 = oldloc;
oldloc = loc;
tk2 = 0;
if (k == loc) {
rspeak(91);
return (2);
}
for (; tkk != 0; tkk = tkk->next) {
ll = tkk->tloc;
if (ll == k) {
k = tkk->tverb;
tkk = travel[loc];
return (9);
}
if (ll <= 300) {
j = travel[loc];
if (forced(ll) && k == j->tloc)
tk2 = tkk;
}
}
tkk = tk2;
if (tkk != 0) {
k = tkk->tverb;
tkk = travel[loc];
return (9);
}
rspeak(140);
return (2);
}
int
specials(void)
{
switch(newloc -= 300) {
case 1:
newloc = 99 + 100 - loc;
if (holdng == 0 || (holdng == 1 && toting(emrald)))
return (2);
newloc = loc;
rspeak(117);
return (2);
case 2:
drop(emrald, loc);
return (12);
case 3:
return (trbridge());
default:
bug(29);
}
}
int
trbridge(void)
{
if (prop[troll] == 1) {
pspeak(troll, 1);
prop[troll] = 0;
move(troll2, 0);
move(troll2 + 100, 0);
move(troll, plac[troll]);
move(troll + 100, fixd[troll]);
juggle(chasm);
newloc = loc;
return (2);
}
newloc = plac[troll] + fixd[troll] - loc;
if (prop[troll] == 0)
prop[troll] = 1;
if (!toting(bear))
return (2);
rspeak(162);
prop[chasm] = 1;
prop[troll] = 2;
drop(bear, newloc);
fixed[bear] = -1;
prop[bear] = 3;
if (prop[spices] < 0)
tally2++;
oldlc2 = newloc;
return (99);
}
void
badmove(void)
{
spk = 12;
if (k >= 43 && k <= 50)
spk = 9;
if (k == 29 || k == 30)
spk = 9;
if (k == 7 || k == 36 || k == 37)
spk = 10;
if (k == 11 || k == 19)
spk = 11;
if (verb == find || verb == invent)
spk = 59;
if (k == 62 || k == 65)
spk = 42;
if (k == 17)
spk = 80;
rspeak(spk);
}
void
bug(int n)
{
fprintf(stderr,
"Please use sendbug to report that bug %d happened in adventure.\n", n);
exit(n);
}
void
checkhints(void)
{
int hint;
for (hint = 4; hint <= hntmax; hint++) {
if (hinted[hint])
continue;
if (!bitset(loc, hint))
hintlc[hint] = -1;
hintlc[hint]++;
if (hintlc[hint] < hints[hint][1])
continue;
switch (hint) {
case 4:
if (prop[grate] == 0 && !here(keys))
goto l40010;
goto l40020;
case 5:
if (here(bird) && toting(rod) && obj == bird)
goto l40010;
continue;
case 6:
if (here(snake) && !here(bird))
goto l40010;
goto l40020;
case 7:
if (atloc[loc] == 0 && atloc[oldloc] == 0
&& atloc[oldlc2] == 0 && holdng > 1)
goto l40010;
goto l40020;
case 8:
if (prop[emrald] != -1 && prop[pyram] == -1)
goto l40010;
goto l40020;
case 9:
goto l40010;
default:
bug(27);
}
l40010: hintlc[hint] = 0;
if (!yes(hints[hint][3], 0, 54))
continue;
printf("I am prepared to give you a hint, but it will ");
printf("cost you %d points.\n", hints[hint][2]);
hinted[hint] = yes(175, hints[hint][4], 54);
l40020: hintlc[hint] = 0;
}
}
int
trsay(void)
{
int i;
if (wd2[0] != 0)
strlcpy(wd1, wd2, sizeof(wd1));
i = vocab(wd1, -1, 0);
if (i == 62 || i == 65 || i == 71 || i == 2025) {
wd2[0] = 0;
obj = 0;
return (2630);
}
printf("\nOkay, \"%s\".\n", wd2);
return (2012);
}
int
trtake(void)
{
if (toting(obj))
return (2011);
spk = 25;
if (obj == plant && prop[plant] <= 0)
spk = 115;
if (obj == bear && prop[bear] == 1)
spk = 169;
if (obj == chain && prop[bear] != 0)
spk = 170;
if (fixed[obj] != 0)
return (2011);
if (obj == water || obj == oil) {
if (here(bottle) && liq() == obj) {
obj = bottle;
goto l9017;
}
obj = bottle;
if (toting(bottle) && prop[bottle] == 1)
return (9220);
if (prop[bottle] != 1)
spk = 105;
if (!toting(bottle))
spk = 104;
return (2011);
}
l9017: if (holdng >= 7) {
rspeak(92);
return (2012);
}
if (obj == bird) {
if (prop[bird] != 0)
goto l9014;
if (toting(rod)) {
rspeak(26);
return (2012);
}
if (!toting(cage)) {
rspeak(27);
return (2012);
}
prop[bird] = 1;
}
l9014: if ((obj == bird || obj == cage) && prop[bird] != 0)
carry(bird + cage - obj, loc);
carry(obj, loc);
k = liq();
if (obj == bottle && k != 0)
place[k] = -1;
return (2009);
}
int
dropper(void)
{
k = liq();
if (k == obj)
obj = bottle;
if (obj == bottle && k != 0)
place[k] = 0;
if (obj == cage && prop[bird] != 0)
drop(bird, loc);
if (obj == bird)
prop[bird] = 0;
drop(obj, loc);
return (2012);
}
int
trdrop(void)
{
if (toting(rod2) && obj == rod && !toting(rod))
obj = rod2;
if (!toting(obj))
return (2011);
if (obj == bird && here(snake)) {
rspeak(30);
if (closed)
return (19000);
dstroy(snake);
prop[snake] = 1;
return (dropper());
}
if (obj == coins && here(vend)) {
dstroy(coins);
drop(batter, loc);
pspeak(batter, 0);
return (2012);
}
if (obj == bird && at(dragon) && prop[dragon] == 0) {
rspeak(154);
dstroy(bird);
prop[bird] = 0;
if (place[snake] == plac[snake])
tally2--;
return (2012);
}
if (obj == bear && at(troll)) {
rspeak(163);
move(troll, 0);
move(troll + 100, 0);
move(troll2, plac[troll]);
move(troll2 + 100, fixd[troll]);
juggle(chasm);
prop[troll] = 2;
return (dropper());
}
if (obj != vase || loc == plac[pillow]) {
rspeak(54);
return (dropper());
}
prop[vase] = 2;
if (at(pillow))
prop[vase] = 0;
pspeak(vase, prop[vase] + 1);
if (prop[vase] != 0)
fixed[vase] = -1;
return (dropper());
}
int
tropen(void)
{
if (obj == clam || obj == oyster) {
k = 0;
if (obj == oyster)
k = 1;
spk = 124 + k;
if (toting(obj))
spk = 120 + k;
if (!toting(tridnt))
spk = 122 + k;
if (verb == lock)
spk = 61;
if (spk != 124)
return (2011);
dstroy(clam);
drop(oyster, loc);
drop(pearl, 105);
return (2011);
}
if (obj == door)
spk = 111;
if (obj == door && prop[door] == 1)
spk = 54;
if (obj == cage)
spk = 32;
if (obj == keys)
spk = 55;
if (obj == grate || obj == chain)
spk = 31;
if (spk != 31||!here(keys))
return (2011);
if (obj == chain) {
if (verb == lock) {
spk = 172;
if (prop[chain] != 0)
spk = 34;
if (loc != plac[chain])
spk = 173;
if (spk != 172)
return (2011);
prop[chain] = 2;
if (toting(chain))
drop(chain, loc);
fixed[chain] = -1;
return (2011);
}
spk = 171;
if (prop[bear] == 0)
spk = 41;
if (prop[chain] == 0)
spk = 37;
if (spk != 171)
return (2011);
prop[chain] = 0;
fixed[chain] = 0;
if (prop[bear] != 3)
prop[bear] = 2;
fixed[bear] = 2 - prop[bear];
return (2011);
}
if (closng) {
k = 130;
if (!panic)
clock2 = 15;
panic = TRUE;
return (2010);
}
k = 34 + prop[grate];
prop[grate] = 1;
if (verb == lock)
prop[grate] = 0;
k = k + 2 * prop[grate];
return (2010);
}
int
trkill(void)
{
int i;
for (i = 1; i <= 5; i++)
if (dloc[i] == loc && dflag >= 2)
break;
if (i == 6)
i = 0;
if (obj == 0) {
if (i != 0)
obj = dwarf;
if (here(snake))
obj = obj * 100 + snake;
if (at(dragon) && prop[dragon] == 0)
obj = obj * 100 + dragon;
if (at(troll))
obj = obj * 100 + troll;
if (here(bear) && prop[bear] == 0)
obj = obj * 100 + bear;
if (obj > 100)
return (8000);
if (obj == 0) {
if (here(bird) && verb != throw)
obj = bird;
if (here(clam) || here(oyster))
obj = 100 * obj + clam;
if (obj > 100)
return (8000);
}
}
if (obj == bird) {
spk = 137;
if (closed)
return (2011);
dstroy(bird);
prop[bird] = 0;
if (place[snake] == plac[snake])
tally2++;
spk = 45;
}
if (obj == 0)
spk = 44;
if (obj == clam || obj == oyster)
spk = 150;
if (obj == snake)
spk = 46;
if (obj == dwarf)
spk = 49;
if (obj == dwarf && closed)
return (19000);
if (obj == dragon)
spk = 147;
if (obj == troll)
spk = 157;
if (obj == bear)
spk = 165 + (prop[bear] + 1) / 2;
if (obj != dragon || prop[dragon] != 0)
return (2011);
rspeak(49);
verb = 0;
obj = 0;
getin(wd1, sizeof(wd1), wd2, sizeof(wd2));
if (!weq(wd1, "y") && !weq(wd1, "yes"))
return (2608);
pspeak(dragon, 1);
prop[dragon] = 2;
prop[rug] = 0;
k = (plac[dragon] + fixd[dragon]) / 2;
move(dragon + 100, -1);
move(rug + 100, 0);
move(dragon, k);
move(rug, k);
for (obj = 1; obj <= 100; obj++)
if (place[obj] == plac[dragon] || place[obj] == fixd[dragon])
move(obj, k);
loc = k;
k = null;
return (8);
}
int
trtoss(void)
{
int i;
if (toting(rod2) && obj == rod && !toting(rod))
obj = rod2;
if (!toting(obj))
return (2011);
if (obj >= 50 && obj <= maxtrs && at(troll)) {
spk = 159;
drop(obj, 0);
move(troll, 0);
move(troll + 100, 0);
drop(troll2, plac[troll]);
drop(troll2 + 100, fixd[troll]);
juggle(chasm);
return (2011);
}
if (obj == food && here(bear)) {
obj = bear;
return (9210);
}
if (obj != axe)
return (9020);
for (i = 1; i <= 5; i++) {
if (dloc[i] == loc) {
spk = 48;
if (ran(3) == 0 || saved != -1) {
l9175:
rspeak(spk);
drop(axe, loc);
k = null;
return (8);
}
dseen[i] = FALSE;
dloc[i] = 0;
spk = 47;
dkill++;
if (dkill == 1)
spk = 149;
goto l9175;
}
}
spk = 152;
if (at(dragon) && prop[dragon] == 0)
goto l9175;
spk = 158;
if (at(troll))
goto l9175;
if (here(bear) && prop[bear] == 0) {
spk = 164;
drop(axe, loc);
fixed[axe] = -1;
prop[axe] = 1;
juggle(bear);
return (2011);
}
obj = 0;
return (9120);
}
int
trfeed(void)
{
if (obj == bird) {
spk = 100;
return (2011);
}
if (obj == snake || obj == dragon || obj == troll) {
spk = 102;
if (obj == dragon && prop[dragon] != 0)
spk = 110;
if (obj == troll)
spk = 182;
if (obj != snake || closed || !here(bird))
return (2011);
spk = 101;
dstroy(bird);
prop[bird] = 0;
tally2++;
return (2011);
}
if (obj == dwarf) {
if (!here(food))
return (2011);
spk = 103;
dflag++;
return (2011);
}
if (obj == bear) {
if (prop[bear] == 0)
spk = 102;
if (prop[bear] == 3)
spk = 110;
if (!here(food))
return (2011);
dstroy(food);
prop[bear] = 1;
fixed[axe] = 0;
prop[axe] = 0;
spk = 168;
return (2011);
}
spk = 14;
return (2011);
}
int
trfill(void)
{
if (obj == vase) {
spk = 29;
if (liqloc(loc) == 0)
spk = 144;
if (liqloc(loc) == 0 || !toting(vase))
return (2011);
rspeak(145);
prop[vase] = 2;
fixed[vase] = -1;
return (9020);
}
if (obj != 0 && obj != bottle)
return (2011);
if (obj == 0 && !here(bottle))
return (8000);
spk = 107;
if (liqloc(loc) == 0)
spk = 106;
if (liq() != 0)
spk = 105;
if (spk != 107)
return (2011);
prop[bottle] = ((cond[loc] % 4) / 2) * 2;
k = liq();
if (toting(bottle))
place[k] = -1;
if (k == oil)
spk = 108;
return (2011);
}
void
closing(void)
{
int i;
prop[grate] = prop[fissur] = 0;
for (i = 1; i <= 6; i++) {
dseen[i] = FALSE;
dloc[i] = 0;
}
move(troll, 0);
move(troll + 100, 0);
move(troll2, plac[troll]);
move(troll2 + 100, fixd[troll]);
juggle(chasm);
if (prop[bear] != 3)
dstroy(bear);
prop[chain] = 0;
fixed[chain] = 0;
prop[axe] = 0;
fixed[axe] = 0;
rspeak(129);
clock1 = -1;
closng = TRUE;
}
void
caveclose(void)
{
int i;
prop[bottle] = put(bottle, 115, 1);
prop[plant] = put(plant, 115, 0);
prop[oyster] = put(oyster, 115, 0);
prop[lamp] = put(lamp, 115, 0);
prop[rod] = put(rod, 115, 0);
prop[dwarf] = put(dwarf, 115, 0);
loc = 115;
oldloc = 115;
newloc = 115;
put(grate, 116, 0);
prop[snake] = put(snake, 116, 1);
prop[bird] = put(bird, 116, 1);
prop[cage] = put(cage, 116, 0);
prop[rod2] = put(rod2, 116, 0);
prop[pillow] = put(pillow, 116, 0);
prop[mirror] = put(mirror, 115, 0);
fixed[mirror] = 116;
for (i = 1; i <= 100; i++)
if (toting(i))
dstroy(i);
rspeak(132);
closed = TRUE;
}