/*-
 * 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
#if 0
static char sccsid[] = "@(#)subr.c	8.1 (Berkeley) 5/31/93";
#endif
static const char rcsid[] __attribute__((unused)) =
    "$FreeBSD: src/games/adventure/subr.c,v 1.7.2.1 2001/03/05 11:43:11 kris Exp $";
#endif /* not lint */

/*      Re-coding of advent in C: subroutines from main                 */

#include <stdio.h>
#include <string.h>
#include "hdr.h"

static void badmove(void);
static int bitset(int, int);
static int dropper(void);
static int liq2(int);
static int mback(void);
static int specials(void);
static int trbridge(void);

/*              Statement functions     */
int
toting(objj)
int objj;
{
    if(place[objj] == -1) return(TRUE);
    else return(FALSE);
}

int
here(objj)
int objj;
{
    if(place[objj] == loc || toting(objj)) return(TRUE);
    else return(FALSE);
}

int
at(objj)
int objj;
{
    if(place[objj] == loc || fixed[objj] == loc) return(TRUE);
    else return (FALSE);
}

static int
liq2(pbotl)
int pbotl;
{
    return((1 - pbotl) * water + (pbotl / 2) * (water + oil));
}

int
liq() {
    int i;
    i = prop[bottle];

    if(i > -1 - i) return(liq2(i));
    else return(liq2(-1 - i));
}

int
liqloc(locc)     /* may want to clean this one up a bit */
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));
}

static int
bitset(l, n)
int l, n;
{
    if(cond[l] & setbit[n]) return(TRUE);

    return(FALSE);
}

int
forced(locc)
int locc;
{
    if(cond[locc] == 2) return(TRUE);

    return(FALSE);
}

int
dark() {
    if((cond[loc] % 2) == 0 && (prop[lamp] == 0 || !here(lamp)))
        return(TRUE);

    return(FALSE);
}

int
pct(n)
int n;
{
    if(ran(100) < n) return(TRUE);

    return(FALSE);
}


int
fdwarf() {      /* 71 */
    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;       /* 74 */

    if(loc == 0 || forced(loc) || bitset(newloc, 3)) return(2000);

    if(dflag == 0) {
        if(loc >= 15) dflag = 1;

        return(2000);
    }

    if(dflag == 1) {    /* 6000 */
        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; /* 6001 */
        }

        for(i = 1; i <= 5; i++) {
            if(dloc[i] == loc) dloc[i] = daltlc;

            odloc[i] = dloc[i];     /* 6002 */
        }

        rspeak(3);
        drop(axe, loc);
        return(2000);
    }

    dtotal = attack = stick = 0;    /* 6010 */

    for(i = 1; i <= 6; i++) {               /* loop to 6030 */
        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];               /* 6016 */

        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;         /* i.e. goto 6030 */

        dloc[i] = loc;

        if(i == 6) {                    /* pirate's spotted him */
            if(loc == chloc || prop[chest] >= 0) continue;

            k = 0;

            for(j = 50; j <= maxtrs; j++) { /* loop to 6020 */
                if(j == pyram && (loc == plac[pyram]
                                  || loc == plac[emrald])) goto l6020;

                if(toting(j)) goto l6022;

            l6020:

                if(here(j)) k = 1;
            }                               /* 6020 */

            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;       /* to 6030 */
        l6022:
            rspeak(128);

            if(place[messag] == 0) move(chest, chloc);

            move(messag, chloc2);

            for(j = 50; j <= maxtrs; j++) { /* loop to 6023 */
                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++;                       /* 6027 */

        if(odloc[i] != dloc[i]) continue;

        attack++;

        if(knfloc >= 0) knfloc = loc;

        if(ran(1000) < 95 * (dflag - 2)) stick++;
    }                                       /* 6030 */

    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) {                /* 82 */
            rspeak(k + stick);

            if(stick == 0) return(2000);
        }
        else
            printf("%d of them get you!\n", stick); /* 83 */

        oldlc2 = loc;
        return(99);
    }

    rspeak(5);
    k = 52;
    goto l82;
}


int
march() {                                      /* label 8              */
    int ll1, ll2;

    if((tkk = travel[newloc = loc]) == 0) bug(26);

    if(k == null) return(2);

    if(k == cave) {                         /* 40                   */
        if(loc < 8) rspeak(57);

        if(loc >= 8) rspeak(58);

        return(2);
    }

    if(k == look) {                         /* 30                   */
        if(detail++ < 3) rspeak(15);

        wzdark = FALSE;
        abb[loc] = 0;
        return(2);
    }

    if(k == back) {                         /* 20                   */
        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;                  /* 11                   */
    ll2 = tkk->tloc;
    newloc = ll1;                           /* newloc=conditions    */
    k = newloc % 100;                       /* k used for prob      */

    if(newloc <= 300) {
        if(newloc <= 100) {             /* 13                   */
            if(newloc != 0 && !pct(newloc)) goto l12; /* 14   */

        l16:
            newloc = ll2;           /* newloc=location      */

            if(newloc <= 300) return(2);

            if(newloc <= 500)
                switch(specials()) { /* to 30000           */
                    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; /* newloc still conditions*/

l12:    /* alternative to probability move      */

    for(; tkk != 0; tkk = tkk->next)
        if(tkk->tloc != ll2 || tkk->conditions != ll1) break;

    if(tkk == 0) bug(25);

    goto l11;
}



static int
mback() {                                       /* 20                   */
    struct travlist *tk2, *j;
    int ll;

    if(forced(k = oldloc)) k = oldlc2;      /* k=location           */

    oldlc2 = oldloc;
    oldloc = loc;
    tk2 = 0;

    if(k == loc) {
        rspeak(91);
        return(2);
    }

    for(; tkk != 0; tkk = tkk->next) {      /* 21                   */
        ll = tkk->tloc;

        if(ll == k) {
            k = tkk->tverb;         /* k back to verb       */
            tkk = travel[loc];
            return(9);
        }

        if(ll <= 300) {
            j = travel[loc];

            if(forced(ll) && k == j->tloc) tk2 = tkk;
        }
    }

    tkk = tk2;                              /* 23                   */

    if(tkk != 0) {
        k = tkk->tverb;
        tkk = travel[loc];
        return(9);
    }

    rspeak(140);
    return(2);
}


static int
specials() {                                    /* 30000                */
    switch(newloc -= 300) {
        case 1:                             /* 30100                */
            newloc = 99 + 100 - loc;

            if(holdng == 0 || (holdng == 1 && toting(emrald))) return(2);

            newloc = loc;
            rspeak(117);
            return(2);
        case 2:                             /* 30200                */
            drop(emrald, loc);
            return(12);
        case 3:                             /* to 30300             */
            return(trbridge());
        default:
            bug(29);
    }

    /* NOTREACHED */
    return(-1);
}


static int
trbridge() {                                    /* 30300                */
    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; /* 30310                */

    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);
}


static void
badmove() {                                     /* 20                   */
    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);
}

int
bug(n)
int n;
{
    printf("Please tell jim@rand.org that fatal bug %d happened.\n", n);
    exit(1);
}


void
checkhints() {                                  /* 2600 &c              */
    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:     /* 40400 */

                if(prop[grate] == 0 && !here(keys)) goto l40010;

                goto l40020;
            case 5:     /* 40500 */

                if(here(bird) && toting(rod) && obj == bird) goto l40010;

                continue;      /* i.e. goto l40030 */
            case 6:     /* 40600 */

                if(here(snake) && !here(bird)) goto l40010;

                goto l40020;
            case 7:     /* 40700 */

                if(atloc[loc] == 0 && atloc[oldloc] == 0
                        && atloc[oldlc2] == 0 && holdng > 1) goto l40010;

                goto l40020;
            case 8:     /* 40800 */

                if(prop[emrald] != -1 && prop[pyram] == -1) goto l40010;

                goto l40020;
            case 9:
                goto l40010;    /* 40900 */
            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() {                                       /* 9030                 */
    int i;

    if(*wd2 != 0) strcpy(wd1, wd2);

    i = vocab(wd1, -1, 0);

    if(i == 62 || i == 65 || i == 71 || i == 2025) {
        *wd2 = 0;
        obj = 0;
        return(2630);
    }

    printf("\nOkay, \"%s\".\n", wd2);
    return(2012);
}


int
trtake() {                                      /* 9010                 */
    if(toting(obj)) return(2011);   /* 9010 */

    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)) {     /* 9013 */
            rspeak(27);
            return(2012);
        }

        prop[bird] = 1;         /* 9015 */
    }

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);
}


static int
dropper() {                                     /* 9021                 */
    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() {                                      /* 9020                 */
    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)) {        /* 9024                 */
        dstroy(coins);
        drop(batter, loc);
        pspeak(batter, 0);
        return(2012);
    }

    if(obj == bird && at(dragon) && prop[dragon] == 0) { /* 9025         */
        rspeak(154);
        dstroy(bird);
        prop[bird] = 0;

        if(place[snake] == plac[snake]) tally2--;

        return(2012);
    }

    if(obj == bear && at(troll)) {          /* 9026                 */
        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]) { /* 9027                 */
        rspeak(54);
        return(dropper());
    }

    prop[vase] = 2;                         /* 9028                 */

    if(at(pillow)) prop[vase] = 0;

    pspeak(vase, prop[vase] + 1);

    if(prop[vase] != 0) fixed[vase] = -1;

    return(dropper());
}


int
tropen() {                                      /* 9040                 */
    if(obj == clam || obj == oyster) {
        k = 0;                          /* 9046                 */

        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;              /* 9049: lock           */

            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(!apanic) clock2 = 15;

        apanic = TRUE;
        return(2010);
    }

    k = 34 + prop[grate];                   /* 9043                 */
    prop[grate] = 1;

    if(verb == lock) prop[grate] = 0;

    k = k + 2 * prop[grate];
    return(2010);
}


int
trkill() {                              /* 9120                         */
    int i;

    for(i = 1; i <= 5; i++)
        if(dloc[i] == loc && dflag >= 2) break;

    if(i == 6) i = 0;

    if(obj == 0) {                  /* 9122                         */
        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) {               /* 9124                         */
        spk = 137;

        if(closed) return(2011);

        dstroy(bird);
        prop[bird] = 0;

        if(place[snake] == plac[snake]) tally2++;

        spk = 45;
    }

    if(obj == 0) spk = 44;          /* 9125                         */

    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, &wd2);

    if(strncmp(wd1, "y", 1) && strncmp(wd1, "yes", 3)) 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() {                              /* 9170: throw                  */
    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;                      /* 9178                 */
        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;                     /* 9177                 */
        return(9210);
    }

    if(obj != axe) return(9020);

    for(i = 1; i <= 5; i++) {
        if(dloc[i] == loc) {
            spk = 48;               /* 9172                 */

            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() {                                      /* 9210                 */
    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() {                                      /* 9220 */
    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);           /* advent/10 goes to 9024 */
    }

    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() {                             /* 10000 */
    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() {                           /* 11000 */
    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;
}
