677 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			677 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*	program ENGLISH.C					*/
 | 
						|
 | 
						|
 | 
						|
#include	<stdio.h>
 | 
						|
#include	<string.h>
 | 
						|
#include	<ctype.h>
 | 
						|
#include	<stdlib.h>
 | 
						|
#include	"advent.h"
 | 
						|
#include	"advdec.h"
 | 
						|
 | 
						|
#define ALL	109
 | 
						|
 | 
						|
#define ENTER	 3
 | 
						|
#define CRAWL	17
 | 
						|
#define JUMP	39
 | 
						|
#define CLIMB	56
 | 
						|
#define XYZZY	62
 | 
						|
#define PLUGH	65
 | 
						|
#define PLOVER	71
 | 
						|
#define PHUCE	82
 | 
						|
 | 
						|
_PROTOTYPE(static void getwords, (void));
 | 
						|
_PROTOTYPE(static void clrlin, (void));
 | 
						|
_PROTOTYPE(static void doobj, (int *));
 | 
						|
_PROTOTYPE(static boolean doiobj, (void));
 | 
						|
_PROTOTYPE(static boolean do_scoop_up, (void));
 | 
						|
_PROTOTYPE(static boolean check_next, (void));
 | 
						|
 | 
						|
static char buffer[INPUTBUFLEN] = {'\0', '\0', '\0', '\0'};
 | 
						|
static char *txt[MAXWORDS] = {buffer, buffer, buffer, buffer};
 | 
						|
static char *cindex = buffer;
 | 
						|
static boolean pflag;
 | 
						|
static int vrbkey, words[MAXWORDS] = {0, 0, 0, 0}, word, wdx = 0;
 | 
						|
static int takdir[20] = {2,  6,  9, 10, 11, 13, 14, 17, 23, 25,
 | 
						|
			33, 34, 36, 37, 39, 78, 79, 80, 89, -1};
 | 
						|
 | 
						|
static int vkey[60] = {
 | 
						|
     0,   199,     9,     0,   130,     0,   197,     0,     0,   243,
 | 
						|
     0,     0,    89,   140,     0,     5,     0,   227,     0,     0,
 | 
						|
     0,    31,    42,     0,     0,     0,     0,   172,     1,     0,
 | 
						|
     0,     0,   254,     0,    69,     0,     0,    92,     0,     0,
 | 
						|
   138,   137,   149,   239,    45,    74,   183,     0,     0,   112,
 | 
						|
   241,     0,   114,     0,    30,     0,     0,     0,     0,     0
 | 
						|
};
 | 
						|
 | 
						|
static int ptab[260] = {
 | 
						|
     0,  3028,  3065,  3009, -3005,  5071,  5070,  5058, -5020, 19055,
 | 
						|
 19108, 19038, 19020, 19071, 19070, 19058, 19004, 19048, 19091, 19094,
 | 
						|
 19112, 19002, 19118,  2062,  2066,  2047,  2067,  2053,  2065, -2010,
 | 
						|
 -3114,  4034,  4011,  4101,  4035,  4099,  4098,  4017,  4104,  4014,
 | 
						|
  4015, -4087,  3083,  3085, -3081,  5055,  5108,  5020,  5071,  5070,
 | 
						|
  5058,  5004,  5048,  5091,  5112,  5099,  5118, 19055, 19108, 19020,
 | 
						|
 19071, 19070, 19058, 19004, 19048, 19091, 19112, 19099,-19118,  3028,
 | 
						|
  3065,  3009,  3005, -3018, 19055, 19108, 19038, 19020, 19071, 19070,
 | 
						|
 19058, 19004, 19004, 19048, 19091, 19094, 19112, 19002,-19118,  3028,
 | 
						|
  3065, -3018, 19055, 19108, 19038, 19020, 19071, 19070, 19058, 19004,
 | 
						|
 19048, 19091, 19094, 19112, 19118,  2062,  2066,  2047,  2067,  2053,
 | 
						|
  2065, -2010,  3102, -3090, 19055, 19108, 19020, 19071, 19070, 19058,
 | 
						|
 19004, 19048, 19091, 19014, 19015, 19112, 19118, 19120, 19120, -9999,
 | 
						|
  3090,  3102,  3028,  3057,  3065,  3009, -3005,-29999,  2052, -2068,
 | 
						|
  2024,  2065,  2091,  2042,  2073,  5071,  5070,  5058, -5020, 30999,
 | 
						|
  2062,  2066,  2047,  2067,  2053,  2065,  2010,  2073, 19055, 19108,
 | 
						|
 19038, 19020, 19071, 19070, 19058, 19004, 19048, 19091, 19094, 19112,
 | 
						|
 19002,-19118,  2014,  2015,  2013,  2999,  5014,  5015,  5013,  5999,
 | 
						|
  5110,  5113, -5999,  5055,  5108,  5020,  5071,  5070,  5058,  5004,
 | 
						|
  5048,  5091,  5014,  5015,  5112,  5099, -5118,  3102, -3090,  6066,
 | 
						|
  6047,  6067,  6053,  6072,  6073,  5055,  5108,  5020,  5071,  5070,
 | 
						|
  5004,  5004,  5048,  5091,  5112,  5099,  5118, 19055, 19108, 19020,
 | 
						|
 19071, 19070, 19058, 19004, 19048, 19091,-19118,  4034,  4011,  4101,
 | 
						|
  4035,  4099,  4098,  4017,  4104,  4027,  4087,  9999,-30999,  2002,
 | 
						|
 -6002,  3102, -3090,  9999,  4034,  4011,  4101,  4035,  4099,  4087,
 | 
						|
  4098,  4017,  4104, -4027, -5999,     0,     0,     0,     0,     0,
 | 
						|
};
 | 
						|
 | 
						|
static int adjkey[40] = {
 | 
						|
     0,    15,    38,    64,     4,    63,     1,    61,    62,    67,
 | 
						|
     9,    27,    53,    46,    47,    60,    31,    39,    40,     6,
 | 
						|
    43,    26,    32,    28,    34,    50,    49,    45,    44,    10,
 | 
						|
    20,    25,    21,    36,    37,    30,    33,     0,     0,     0
 | 
						|
};
 | 
						|
 | 
						|
static int adjtab[70] = {
 | 
						|
     0,     5,    98,   -83,     2,   -90,    66,    41,   -90,   -39,
 | 
						|
    41,    14,    15,    50,   -11,    50,    64,    56,    72,   -74,
 | 
						|
   -19,   119,    59,    73,  -118,  -119,   -70,   -41,    95,  -118,
 | 
						|
  -118,   -58,   -71,  -120,   110,  -108,  -120,   -73,   -62,   -60,
 | 
						|
   110,    54,   -63,   -67,   -41,   -27,   -47,    52,   -75,   -69,
 | 
						|
    65,   112,    -3,    41,    72,    90,    20,   101,   107,  -118,
 | 
						|
   -55,   -10,   -38,    -4,    48,     9,   -71,   -39,     0,     0
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
  Analyze a two word sentence
 | 
						|
*/
 | 
						|
int english()
 | 
						|
{
 | 
						|
 | 
						|
    char *ch_ptr, *word1, *word2;
 | 
						|
    int type, val, type2, val2, adj, k, kk;
 | 
						|
    static int iwest = 0;
 | 
						|
 | 
						|
    if (!(words[++wdx])) {
 | 
						|
	getwords();
 | 
						|
	wdx = 0;
 | 
						|
    }
 | 
						|
    pflag = FALSE;
 | 
						|
    word = words[wdx];
 | 
						|
    if (word < 0) {			/* check first word	 */
 | 
						|
	printf("I didn't understand the word \"%s\"\n", txt[wdx]);
 | 
						|
	words[wdx+1] = 0;
 | 
						|
	return (FALSE);			/* didn't know it	 */
 | 
						|
    }
 | 
						|
    type2 = val2 = -1;
 | 
						|
    type = CLASS(word);
 | 
						|
    clrlin();
 | 
						|
    val = VAL(word);
 | 
						|
    if (words[wdx + 1] && CLASS(words[wdx + 1]) != CONJUNCTION) {
 | 
						|
 | 
						|
	/* 'SAY' or 'CALL'.  If no next word, pass on to higher powers. */
 | 
						|
	if (type == ACTION && (val == SAY || val == YELL)) {
 | 
						|
	    word = words[++wdx];
 | 
						|
	    if (!(word == XYZZY || word == PLUGH
 | 
						|
		  || word == PLOVER || word == PHUCE)) {
 | 
						|
		if (val == SAY)
 | 
						|
		    printf("Okay, \"%s\".\n", txt[wdx]);
 | 
						|
		else {
 | 
						|
		    for (ch_ptr = txt[wdx]; *ch_ptr; ch_ptr++)
 | 
						|
			if (islower(*ch_ptr))
 | 
						|
			    *ch_ptr = toupper(*ch_ptr);
 | 
						|
		    printf("Okay, \"%s\"!!!!!\n", txt[wdx]);
 | 
						|
		}
 | 
						|
		return (FALSE);
 | 
						|
	    }
 | 
						|
	} else {
 | 
						|
	    word1 = txt[wdx];
 | 
						|
	    word2 = txt[wdx + 1];
 | 
						|
 | 
						|
	    /* Special stuff for 'ENTER'.  Can't go into water. 'ENTER
 | 
						|
	       BOAT' means 'TAKE BOAT' */
 | 
						|
	    if (word == ENTER) {
 | 
						|
		if (CLASS(words[wdx + 1]) == NOUN && VAL(words[wdx + 1]) == BOAT)
 | 
						|
		    word = TAKE + 2000;
 | 
						|
		else if ((strcmp(word2, "stream") == 0)
 | 
						|
			 || (strcmp(word2, "water") == 0)
 | 
						|
			 || (strcmp(word2, "reservoir") == 0)
 | 
						|
			 || (strcmp(word2, "ocean") == 0)
 | 
						|
			 || (strcmp(word2, "sea") == 0)
 | 
						|
			 || (strcmp(word2, "pool") == 0)) {
 | 
						|
		    rspeak(liqloc(g.loc) == WATER ? 70 : 43);
 | 
						|
		    wdx++;
 | 
						|
		    return (FALSE);
 | 
						|
		}
 | 
						|
	    } else {
 | 
						|
		type2 = CLASS(words[wdx + 1]);
 | 
						|
		val2 = VAL(words[wdx + 1]);
 | 
						|
 | 
						|
		/* 'LEAVE' is motion verb, unsless leaving an object.
 | 
						|
		   E.G., 'LEAVE BOAT' or 'LEAVE BOTTLE'.  BUt make sure
 | 
						|
		   to leave ('DROP') only totable objects. */
 | 
						|
		if (strcmp(word1, "leave") == 0 && type2 == NOUN) {
 | 
						|
		    if (!hinged(val2) || g.fixed[val2])
 | 
						|
			word = LEAVE + 2000;
 | 
						|
 | 
						|
		    /* IF 'LIGHT LAMP', Light must be taken as an
 | 
						|
		       action verb, not a noun. */
 | 
						|
		} else if (strcmp(word1, "light") == 0
 | 
						|
			   && VAL(words[wdx + 1]) == LAMP) {
 | 
						|
		    word = ON + 2000;
 | 
						|
 | 
						|
		    /* 'WATER PLANT' becomes 'POUR WATER', If we are at
 | 
						|
		       plant. 'OIL DOOR' becomes 'POUR OIL', etc., etc. */
 | 
						|
		} else if ((strcmp(word1, "water") == 0 || strcmp(word1, "oil") == 0)
 | 
						|
			   && (strcmp(word2, "plant") == 0 || strcmp(word2, "door") == 0
 | 
						|
			       || strcmp(word2, "sword") == 0 || strcmp(word2, "anvil") == 0)
 | 
						|
			   && at(val2)) {
 | 
						|
		    words[wdx + 1] = word;
 | 
						|
		    txt[wdx + 1] = txt[wdx];
 | 
						|
		    word = POUR + 2000;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
    }
 | 
						|
    /* This is the 'inner' loop.  Dispatching of all word in a clause
 | 
						|
       after the first comes through here. */
 | 
						|
    do {
 | 
						|
	switch (CLASS(word)) {
 | 
						|
	case MOTION:
 | 
						|
	    {
 | 
						|
		boolean do_part2;
 | 
						|
		int i;
 | 
						|
 | 
						|
		do_part2 = FALSE;
 | 
						|
		type = CLASS(verbs[vrbx]);
 | 
						|
		val = VAL(verbs[vrbx]);
 | 
						|
		if (!vrbx)
 | 
						|
		    do_part2 = TRUE;
 | 
						|
		else {
 | 
						|
		    if (type > ACTION) {
 | 
						|
			rspeak(confuz());
 | 
						|
			return (FALSE);
 | 
						|
		    }
 | 
						|
		}
 | 
						|
		if (type == ACTION) {
 | 
						|
		    if (val == GO)
 | 
						|
			do_part2 = TRUE;
 | 
						|
		    else {
 | 
						|
			if (val == TAKE) {
 | 
						|
			    for (i = 0; i < 20; i++)
 | 
						|
				if (takdir[i] == val)
 | 
						|
				    do_part2 = TRUE;
 | 
						|
			}
 | 
						|
			if (!do_part2) {
 | 
						|
			    word = vocab(txt[wdx], 1);
 | 
						|
			    if (word)
 | 
						|
				words[wdx--] = word;
 | 
						|
			}
 | 
						|
		    }
 | 
						|
		} else if (type != CRAWL && type != JUMP
 | 
						|
			   && type != CLIMB)
 | 
						|
		    do_part2 = TRUE;
 | 
						|
		if (do_part2) {
 | 
						|
		    verbs[1] = word;
 | 
						|
		    vrbx = 1;
 | 
						|
		    if (strcmp(txt[wdx], "west") == 0) {
 | 
						|
			iwest++;
 | 
						|
			if (iwest == 10)
 | 
						|
			    rspeak(17);
 | 
						|
		    }
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	case NOUN:
 | 
						|
	    if (pflag) {
 | 
						|
		if (!doiobj())
 | 
						|
		    return (FALSE);
 | 
						|
	    } else {
 | 
						|
		word = VAL(word);
 | 
						|
		if (word == ALL) {
 | 
						|
		    if (!do_scoop_up())
 | 
						|
			return (FALSE);
 | 
						|
		} else {
 | 
						|
		    doobj(&word);
 | 
						|
		    if (word > 0) {
 | 
						|
			objs[++objx] = word;
 | 
						|
			otxt[objx] = txt[wdx];
 | 
						|
		    } else {
 | 
						|
			clrlin();
 | 
						|
			pflag = FALSE;
 | 
						|
			wdx++;
 | 
						|
			while (words[wdx]) {
 | 
						|
			    if (CLASS(words[wdx]) == CONJUNCTION)
 | 
						|
				break;
 | 
						|
			    wdx++;
 | 
						|
			}
 | 
						|
			if (words[wdx] == 0)
 | 
						|
			    return (FALSE);
 | 
						|
		    }
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    break;
 | 
						|
	case ACTION:
 | 
						|
	    if (vrbx == 0)
 | 
						|
		vrbx++;
 | 
						|
	    else {
 | 
						|
		if (VAL(verbs[vrbx]) == TAKE) {
 | 
						|
		    val = VAL(word);
 | 
						|
		    if (val == DRINK || val == INVENTORY
 | 
						|
			|| val == SCORE || val == NOTHING
 | 
						|
			|| val == LOOK);
 | 
						|
		    else if (val == GO && (
 | 
						|
					 strcmp(txt[wdx], "walk") == 0
 | 
						|
				       || strcmp(txt[wdx], "run") == 0
 | 
						|
				   || strcmp(txt[wdx], "hike") == 0));
 | 
						|
		    else {
 | 
						|
			rspeak(confuz());
 | 
						|
			return (FALSE);
 | 
						|
		    }
 | 
						|
		} else if (objx || CLASS(words[wdx - 1]) == CONJUNCTION) {
 | 
						|
		    rspeak(confuz());
 | 
						|
		    return (FALSE);
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    verbs[vrbx] = word;
 | 
						|
	    vtxt[vrbx] = txt[wdx];
 | 
						|
	    break;
 | 
						|
	case MISC:
 | 
						|
	    if (vrbx) {
 | 
						|
		rspeak(confuz());
 | 
						|
		return (FALSE);
 | 
						|
	    }
 | 
						|
	    verbs[1] = word;
 | 
						|
	    vrbx = 1;
 | 
						|
	    break;
 | 
						|
	case PREPOSITION:
 | 
						|
	    if (CLASS(verbs[vrbx]) != ACTION || iobx) {
 | 
						|
		rspeak(confuz());
 | 
						|
		return (FALSE);
 | 
						|
	    }
 | 
						|
	    vrbkey = vkey[VAL(verbs[vrbx])];
 | 
						|
	    if (!vrbkey) {
 | 
						|
		rspeak(confuz());
 | 
						|
		return (FALSE);
 | 
						|
	    }
 | 
						|
	    prep = VAL(word);
 | 
						|
	    pflag = TRUE;
 | 
						|
	    break;
 | 
						|
	case ADJACTIVE:
 | 
						|
	    /* Adjective handler. Scarf the next word, make sure it is
 | 
						|
	       a valid object for this object.  Then call getobj to see
 | 
						|
	       if it is really there, Then link into object code. */
 | 
						|
	    adj = VAL(word);
 | 
						|
	    if (!check_next())
 | 
						|
		return (FALSE);
 | 
						|
	    else if (CLASS(word) == CONJUNCTION) {
 | 
						|
		printf("%s what?\n", txt[wdx - 1]);
 | 
						|
		return (FALSE);
 | 
						|
	    } else {
 | 
						|
		if (CLASS(word) != NOUN)
 | 
						|
		    word = vocab(txt[wdx], NOUN);
 | 
						|
		if (word == -1 || CLASS(word) != NOUN || VAL(word) == ALL) {
 | 
						|
		    rspeak(confuz());
 | 
						|
		    return (FALSE);
 | 
						|
		}
 | 
						|
		words[wdx] = word;
 | 
						|
		kk = VAL(word);
 | 
						|
		for (k = adjkey[adj]; adjtab[k] >= 0; k++) {
 | 
						|
		    if (kk == abs(adjtab[k]))
 | 
						|
			break;
 | 
						|
		}
 | 
						|
		if (adjtab[k] < 0) {
 | 
						|
		    rspeak(confuz());
 | 
						|
		    return (FALSE);
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    break;
 | 
						|
	case CONJUNCTION:
 | 
						|
	    if (!check_next())
 | 
						|
		return (FALSE);
 | 
						|
	    switch (CLASS(word)) {
 | 
						|
	    case MOTION:
 | 
						|
	    case ACTION:
 | 
						|
	    case MISC:
 | 
						|
		words[wdx--] = 0;
 | 
						|
		break;
 | 
						|
	    case NOUN:
 | 
						|
	    case ADJACTIVE:
 | 
						|
		break;
 | 
						|
	    case PREPOSITION:
 | 
						|
	    case CONJUNCTION:
 | 
						|
		rspeak(confuz());
 | 
						|
		return (FALSE);
 | 
						|
	    default:
 | 
						|
		bug(33);
 | 
						|
	    }
 | 
						|
	    break;
 | 
						|
	default:
 | 
						|
	    bug(33);
 | 
						|
	}
 | 
						|
	word = words[++wdx];
 | 
						|
	if (word < 0) {
 | 
						|
	    if (pct(50))
 | 
						|
		printf("I don't understand the word %s?\n", txt[wdx]);
 | 
						|
	    else
 | 
						|
		printf("Mumble ?  %s\n", txt[wdx]);
 | 
						|
 | 
						|
	    words[wdx+1] = 0;
 | 
						|
	    return (FALSE);
 | 
						|
	}
 | 
						|
	type = CLASS(word);
 | 
						|
	if (type == NOUN) {
 | 
						|
	    /* It's not the first:  Make sure he included a comma or
 | 
						|
	       'and'. Differenctiate between direct & indirect objects.
 | 
						|
	       Check for special case of multiple ofjects: 'feed bear
 | 
						|
	       honey' or 'throw troll nugget'. */
 | 
						|
	    if ((pflag ? iobx : objx)
 | 
						|
		&& CLASS(words[wdx - 1]) != CONJUNCTION) {
 | 
						|
		val = VAL(verbs[vrbx]);
 | 
						|
		if (!living(objs[objx]) || (val != THROW && val != FEED)) {
 | 
						|
		    rspeak(confuz());
 | 
						|
		    return (FALSE);
 | 
						|
		}
 | 
						|
		iobx++;
 | 
						|
		iobjs[iobx] = objs[objx];
 | 
						|
		objs[objx] = 0;
 | 
						|
		objx++;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    } while (word);
 | 
						|
 | 
						|
    if (verbs[1] == 0) {
 | 
						|
	if (objs[1] == 0) {
 | 
						|
	    rspeak(confuz());
 | 
						|
	    clrlin();
 | 
						|
	} else if (objs[2])
 | 
						|
	    printf("What do you want to do with them?\n");
 | 
						|
	else
 | 
						|
	    printf("What do you want to do with %s?\n", otxt[1]);
 | 
						|
	return (FALSE);
 | 
						|
    } else if (objx > 1 && iobx > 1) {
 | 
						|
	rspeak(confuz());
 | 
						|
	return (FALSE);
 | 
						|
    }
 | 
						|
    return (TRUE);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  retrieve input line (max INPUTBUFLEN chars), convert to lower case
 | 
						|
   & rescan for first two words (max. WORDSIZE-1 chars).
 | 
						|
*/
 | 
						|
static void getwords()
 | 
						|
{
 | 
						|
    static int wdx = 0;
 | 
						|
    int i, term_loc;
 | 
						|
    char terminator;
 | 
						|
 | 
						|
    if (*cindex == '\0') {
 | 
						|
	while (!*ask("\n> ", buffer, sizeof(buffer))) ;
 | 
						|
	for (cindex = buffer; *cindex; cindex++)
 | 
						|
	    if (isupper(*cindex))
 | 
						|
		*cindex = tolower(*cindex);
 | 
						|
	cindex = buffer;
 | 
						|
    }
 | 
						|
    wdx = 0;
 | 
						|
    buffer[sizeof(buffer)-1] = '\0';
 | 
						|
    for (i = 0; i < MAXWORDS; i++) {
 | 
						|
	txt[i] = &buffer[sizeof(buffer)-1];
 | 
						|
	words[i] = 0;
 | 
						|
    }
 | 
						|
    do {
 | 
						|
	while (*cindex == ' ')
 | 
						|
	    cindex++;
 | 
						|
	txt[wdx] = cindex;
 | 
						|
	term_loc = strcspn(cindex, " ,.;\n");
 | 
						|
	cindex += term_loc;
 | 
						|
	terminator = *cindex;
 | 
						|
	*cindex++ = '\0';
 | 
						|
	if ((strcmp(txt[wdx], "a") != 0)
 | 
						|
	    && (strcmp(txt[wdx], "the") != 0)
 | 
						|
	    && (strcmp(txt[wdx], "an") != 0)) {
 | 
						|
	    words[wdx] = vocab(txt[wdx], 0);
 | 
						|
	    wdx++;
 | 
						|
	}
 | 
						|
	if (terminator == ',') {
 | 
						|
	    txt[wdx] = "and";
 | 
						|
	    words[wdx] = vocab(txt[wdx], 0);
 | 
						|
	    wdx++;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    while ((terminator != ';') && (terminator != '.')
 | 
						|
	   && (terminator != '\0') && (terminator != '\n'));
 | 
						|
    if (terminator == '\0')
 | 
						|
	cindex--;
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
/* CLRIN, clears out all surrent syntax args in preparation for
 | 
						|
 * new input line
 | 
						|
 */
 | 
						|
 | 
						|
static void clrlin()
 | 
						|
{
 | 
						|
    int i;
 | 
						|
 | 
						|
    for (i = 0; i < MAXWORDS; i++) {
 | 
						|
	verbs[i] = 0;
 | 
						|
	vtxt[i] = &buffer[sizeof(buffer)-1];
 | 
						|
    }
 | 
						|
 | 
						|
    for (i = 0; i < MAXITEMS; i++) {
 | 
						|
	objs[i] = 0;
 | 
						|
	otxt[i] = &buffer[sizeof(buffer)-1];
 | 
						|
	iobjs[i] = 0;
 | 
						|
	iotxt[i] = &buffer[sizeof(buffer)-1];
 | 
						|
    }
 | 
						|
    vrbx = 0;
 | 
						|
    objx = 0;
 | 
						|
    iobx = 0;
 | 
						|
    prep = 0;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Routine to process an object.
 | 
						|
*/
 | 
						|
static void doobj(object)
 | 
						|
int *object;
 | 
						|
{
 | 
						|
    int msg;
 | 
						|
 | 
						|
    if (holding(*object))
 | 
						|
	return;
 | 
						|
    if (blind()) {
 | 
						|
	printf("I see no %s here.\n", txt[wdx]);
 | 
						|
	*object = 0;
 | 
						|
	return;
 | 
						|
    }
 | 
						|
    /* Is object here?  if so, transitive */
 | 
						|
    if (g.fixed[*object] == g.loc || athand(*object))
 | 
						|
	return;
 | 
						|
    else if (here(*object)) {
 | 
						|
	msg = plural(*object) ? 373 : 335;
 | 
						|
	*object = 0;
 | 
						|
	rspeak(msg);
 | 
						|
    }
 | 
						|
    /* Did he give grate as destination? */
 | 
						|
    else if (*object == GRATE) {
 | 
						|
	if (g.loc == 1 || g.loc == 4 || g.loc == 7) {
 | 
						|
	    verbs[1] = DEPRESSION;
 | 
						|
	    vrbx = 1;
 | 
						|
	    return;
 | 
						|
	} else if (g.loc > 9 && g.loc < 15) {
 | 
						|
	    verbs[1] = ENTRANCE;
 | 
						|
	    vrbx = 1;
 | 
						|
	    return;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    /* Is it a dwarf he is after? */
 | 
						|
    else if (dcheck() && g.dflag >= 2) {
 | 
						|
	*object = DWARF;
 | 
						|
    }
 | 
						|
    /* Is he trying to get/use a liquid? */
 | 
						|
    else if (liqloc(g.loc) == *object
 | 
						|
	     || (liq(BOTTLE) == *object && athand(BOTTLE))
 | 
						|
	     || (liq(CASK) == *object && athand(CASK)));
 | 
						|
    else if (*object == PLANT && at(PLANT2) &&
 | 
						|
	     g.prop[PLANT2] == 0) {
 | 
						|
	*object = PLANT2;
 | 
						|
    } else if (*object == ROCKS && at(CARVNG)) {
 | 
						|
	*object = CARVNG;
 | 
						|
    }
 | 
						|
    /* Is he trying to grab a knife? */
 | 
						|
    else if (*object == KNIFE && g.knfloc == g.loc) {
 | 
						|
	rspeak(116);
 | 
						|
	g.knfloc = -1;
 | 
						|
    }
 | 
						|
    /* Is he trying to get at dynamite? */
 | 
						|
    else if (*object == ROD && athand(ROD2)) {
 | 
						|
	*object = ROD2;
 | 
						|
    } else if (*object == DOOR && (at(SAFE) || at(TDOOR)
 | 
						|
				   || at(TDOOR2) || at(PDOOR))) {
 | 
						|
	if (at(TDOOR2))
 | 
						|
	    *object = TDOOR2;
 | 
						|
	else if (at(PDOOR))
 | 
						|
	    *object = PDOOR;
 | 
						|
	else if (at(SAFE))
 | 
						|
	    *object = SAFE;
 | 
						|
	else
 | 
						|
	    *object = TDOOR;
 | 
						|
    } else if (*object == BOOK && athand(BOOK2)) {
 | 
						|
	*object = BOOK2;
 | 
						|
    } else if (!(verbs[vrbx] == FIND || verbs[vrbx] == INVENTORY)) {
 | 
						|
	*object = 0;
 | 
						|
	printf("I see no %s here.\n", txt[wdx]);
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static boolean doiobj()
 | 
						|
{
 | 
						|
    char dk[INPUTBUFLEN], dkk[INPUTBUFLEN];
 | 
						|
    int kk;
 | 
						|
    boolean ok;
 | 
						|
 | 
						|
    /* checks object is valid for this preposition */
 | 
						|
    ok = TRUE;
 | 
						|
    word = VAL(word);
 | 
						|
    if (word != ALL) {
 | 
						|
	doobj(&word);
 | 
						|
	if (word > 0) {
 | 
						|
	    iobjs[++iobx] = word;
 | 
						|
	    iotxt[iobx] = txt[wdx];
 | 
						|
	} else
 | 
						|
	    ok = FALSE;
 | 
						|
    }
 | 
						|
    kk = abs(ptab[vrbkey]) / 1000;
 | 
						|
    if (kk == prep) {
 | 
						|
	/* preprosition is valid with this verb now check object of
 | 
						|
	   preprosition */
 | 
						|
 | 
						|
	if (word == 0 || CLASS(word) == CONJUNCTION) {
 | 
						|
	    /* no object following prepresition: check special cases */
 | 
						|
 | 
						|
	    pflag = FALSE;
 | 
						|
	    strcpy(dk, txt[--wdx]);
 | 
						|
	    strcpy(dkk, vtxt[vrbx]);
 | 
						|
	    ok = FALSE;
 | 
						|
	    if ((strcmp(dk, "on") == 0
 | 
						|
		 || strcmp(dk, "off") == 0)
 | 
						|
		&& (strcmp(dkk, "turn") == 0
 | 
						|
		    || objs[objx] == LAMP))
 | 
						|
		ok = TRUE;
 | 
						|
	    if (strcmp(dkk, "take") == 0
 | 
						|
		|| strcmp(dkk, "put") == 0)
 | 
						|
		ok = TRUE;
 | 
						|
	    if (strcmp(dk, "up") == 0
 | 
						|
		&& strcmp(dkk, "pick") == 0)
 | 
						|
		ok = TRUE;
 | 
						|
	    if (strcmp(dk, "down") == 0
 | 
						|
		 && (strcmp(dkk, "put") == 0 || verbs[vrbx] == THROW) )
 | 
						|
		ok = TRUE;
 | 
						|
	} else {
 | 
						|
	    /* object follows preposition See if it's plausible. */
 | 
						|
 | 
						|
	    kk = abs(ptab[vrbkey]) % 1000;
 | 
						|
	    if (kk == word && kk == ALL) {
 | 
						|
		if (!do_scoop_up())
 | 
						|
		    return (FALSE);
 | 
						|
	    } else if (!(kk == word || kk == 999)) {
 | 
						|
		vrbkey++;
 | 
						|
		ok = ptab[vrbkey - 1] < 0 ? FALSE : TRUE;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return (ok);
 | 
						|
}
 | 
						|
 | 
						|
static boolean do_scoop_up()
 | 
						|
{
 | 
						|
    int i, val;
 | 
						|
 | 
						|
    val = VAL(verbs[vrbx]);
 | 
						|
    if (val == DROP || val == PUT || val == LEAVE) {
 | 
						|
	for (i = 1; i < MAXOBJ; i++) {
 | 
						|
	    if (!athand(i) || g.fixed[i])
 | 
						|
		continue;
 | 
						|
	    if (i > WATER && i <= WINE + 1)
 | 
						|
		continue;
 | 
						|
	    if (toting(i)) {
 | 
						|
		objs[++objx] = i;
 | 
						|
		otxt[objx] = "BUG???";
 | 
						|
		if (objx >= 44)
 | 
						|
		    break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (val == TAKE || val == PICK || val == GET) {
 | 
						|
	if (blind()) {
 | 
						|
	    rspeak(357);
 | 
						|
	    return (FALSE);
 | 
						|
	} else {
 | 
						|
	    for (i = 1; i < MAXOBJ; i++) {
 | 
						|
		if (!athand(i) || g.fixed[i])
 | 
						|
		    continue;
 | 
						|
		if (i > WATER && i <= WINE + 1)
 | 
						|
		    continue;
 | 
						|
		if (!toting(i)) {
 | 
						|
		    objs[++objx] = i;
 | 
						|
		    otxt[objx] = "BUG???";
 | 
						|
		    if (objx >= 44)
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return (TRUE);
 | 
						|
}
 | 
						|
 | 
						|
static boolean check_next()
 | 
						|
{
 | 
						|
 | 
						|
    word = words[wdx + 1];
 | 
						|
    if (word > 0)
 | 
						|
	return (TRUE);
 | 
						|
    else if (word == 0)
 | 
						|
	rspeak(confuz());
 | 
						|
    else {
 | 
						|
	if (pct(50))
 | 
						|
	    printf("I don't understand the word %s?\n", txt[wdx]);
 | 
						|
	else
 | 
						|
	    printf("Mumble ?  %s\n", txt[wdx]);
 | 
						|
	words[wdx+1] = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return (FALSE);
 | 
						|
}
 |