1 | /* program ENGLISH.C */
|
---|
2 |
|
---|
3 |
|
---|
4 | #include <stdio.h>
|
---|
5 | #include <string.h>
|
---|
6 | #include <ctype.h>
|
---|
7 | #include <stdlib.h>
|
---|
8 | #include "advent.h"
|
---|
9 | #include "advdec.h"
|
---|
10 |
|
---|
11 | #define ALL 109
|
---|
12 |
|
---|
13 | #define ENTER 3
|
---|
14 | #define CRAWL 17
|
---|
15 | #define JUMP 39
|
---|
16 | #define CLIMB 56
|
---|
17 | #define XYZZY 62
|
---|
18 | #define PLUGH 65
|
---|
19 | #define PLOVER 71
|
---|
20 | #define PHUCE 82
|
---|
21 |
|
---|
22 | _PROTOTYPE(static void getwords, (void));
|
---|
23 | _PROTOTYPE(static void clrlin, (void));
|
---|
24 | _PROTOTYPE(static void doobj, (int *));
|
---|
25 | _PROTOTYPE(static boolean doiobj, (void));
|
---|
26 | _PROTOTYPE(static boolean do_scoop_up, (void));
|
---|
27 | _PROTOTYPE(static boolean check_next, (void));
|
---|
28 |
|
---|
29 | static char buffer[INPUTBUFLEN] = {'\0', '\0', '\0', '\0'};
|
---|
30 | static char *txt[MAXWORDS] = {buffer, buffer, buffer, buffer};
|
---|
31 | static char *cindex = buffer;
|
---|
32 | static boolean pflag;
|
---|
33 | static int vrbkey, words[MAXWORDS] = {0, 0, 0, 0}, word, wdx = 0;
|
---|
34 | static int takdir[20] = {2, 6, 9, 10, 11, 13, 14, 17, 23, 25,
|
---|
35 | 33, 34, 36, 37, 39, 78, 79, 80, 89, -1};
|
---|
36 |
|
---|
37 | static int vkey[60] = {
|
---|
38 | 0, 199, 9, 0, 130, 0, 197, 0, 0, 243,
|
---|
39 | 0, 0, 89, 140, 0, 5, 0, 227, 0, 0,
|
---|
40 | 0, 31, 42, 0, 0, 0, 0, 172, 1, 0,
|
---|
41 | 0, 0, 254, 0, 69, 0, 0, 92, 0, 0,
|
---|
42 | 138, 137, 149, 239, 45, 74, 183, 0, 0, 112,
|
---|
43 | 241, 0, 114, 0, 30, 0, 0, 0, 0, 0
|
---|
44 | };
|
---|
45 |
|
---|
46 | static int ptab[260] = {
|
---|
47 | 0, 3028, 3065, 3009, -3005, 5071, 5070, 5058, -5020, 19055,
|
---|
48 | 19108, 19038, 19020, 19071, 19070, 19058, 19004, 19048, 19091, 19094,
|
---|
49 | 19112, 19002, 19118, 2062, 2066, 2047, 2067, 2053, 2065, -2010,
|
---|
50 | -3114, 4034, 4011, 4101, 4035, 4099, 4098, 4017, 4104, 4014,
|
---|
51 | 4015, -4087, 3083, 3085, -3081, 5055, 5108, 5020, 5071, 5070,
|
---|
52 | 5058, 5004, 5048, 5091, 5112, 5099, 5118, 19055, 19108, 19020,
|
---|
53 | 19071, 19070, 19058, 19004, 19048, 19091, 19112, 19099,-19118, 3028,
|
---|
54 | 3065, 3009, 3005, -3018, 19055, 19108, 19038, 19020, 19071, 19070,
|
---|
55 | 19058, 19004, 19004, 19048, 19091, 19094, 19112, 19002,-19118, 3028,
|
---|
56 | 3065, -3018, 19055, 19108, 19038, 19020, 19071, 19070, 19058, 19004,
|
---|
57 | 19048, 19091, 19094, 19112, 19118, 2062, 2066, 2047, 2067, 2053,
|
---|
58 | 2065, -2010, 3102, -3090, 19055, 19108, 19020, 19071, 19070, 19058,
|
---|
59 | 19004, 19048, 19091, 19014, 19015, 19112, 19118, 19120, 19120, -9999,
|
---|
60 | 3090, 3102, 3028, 3057, 3065, 3009, -3005,-29999, 2052, -2068,
|
---|
61 | 2024, 2065, 2091, 2042, 2073, 5071, 5070, 5058, -5020, 30999,
|
---|
62 | 2062, 2066, 2047, 2067, 2053, 2065, 2010, 2073, 19055, 19108,
|
---|
63 | 19038, 19020, 19071, 19070, 19058, 19004, 19048, 19091, 19094, 19112,
|
---|
64 | 19002,-19118, 2014, 2015, 2013, 2999, 5014, 5015, 5013, 5999,
|
---|
65 | 5110, 5113, -5999, 5055, 5108, 5020, 5071, 5070, 5058, 5004,
|
---|
66 | 5048, 5091, 5014, 5015, 5112, 5099, -5118, 3102, -3090, 6066,
|
---|
67 | 6047, 6067, 6053, 6072, 6073, 5055, 5108, 5020, 5071, 5070,
|
---|
68 | 5004, 5004, 5048, 5091, 5112, 5099, 5118, 19055, 19108, 19020,
|
---|
69 | 19071, 19070, 19058, 19004, 19048, 19091,-19118, 4034, 4011, 4101,
|
---|
70 | 4035, 4099, 4098, 4017, 4104, 4027, 4087, 9999,-30999, 2002,
|
---|
71 | -6002, 3102, -3090, 9999, 4034, 4011, 4101, 4035, 4099, 4087,
|
---|
72 | 4098, 4017, 4104, -4027, -5999, 0, 0, 0, 0, 0,
|
---|
73 | };
|
---|
74 |
|
---|
75 | static int adjkey[40] = {
|
---|
76 | 0, 15, 38, 64, 4, 63, 1, 61, 62, 67,
|
---|
77 | 9, 27, 53, 46, 47, 60, 31, 39, 40, 6,
|
---|
78 | 43, 26, 32, 28, 34, 50, 49, 45, 44, 10,
|
---|
79 | 20, 25, 21, 36, 37, 30, 33, 0, 0, 0
|
---|
80 | };
|
---|
81 |
|
---|
82 | static int adjtab[70] = {
|
---|
83 | 0, 5, 98, -83, 2, -90, 66, 41, -90, -39,
|
---|
84 | 41, 14, 15, 50, -11, 50, 64, 56, 72, -74,
|
---|
85 | -19, 119, 59, 73, -118, -119, -70, -41, 95, -118,
|
---|
86 | -118, -58, -71, -120, 110, -108, -120, -73, -62, -60,
|
---|
87 | 110, 54, -63, -67, -41, -27, -47, 52, -75, -69,
|
---|
88 | 65, 112, -3, 41, 72, 90, 20, 101, 107, -118,
|
---|
89 | -55, -10, -38, -4, 48, 9, -71, -39, 0, 0
|
---|
90 | };
|
---|
91 |
|
---|
92 | /*
|
---|
93 | Analyze a two word sentence
|
---|
94 | */
|
---|
95 | int english()
|
---|
96 | {
|
---|
97 |
|
---|
98 | char *ch_ptr, *word1, *word2;
|
---|
99 | int type, val, type2, val2, adj, k, kk;
|
---|
100 | static int iwest = 0;
|
---|
101 |
|
---|
102 | if (!(words[++wdx])) {
|
---|
103 | getwords();
|
---|
104 | wdx = 0;
|
---|
105 | }
|
---|
106 | pflag = FALSE;
|
---|
107 | word = words[wdx];
|
---|
108 | if (word < 0) { /* check first word */
|
---|
109 | printf("I didn't understand the word \"%s\"\n", txt[wdx]);
|
---|
110 | words[wdx+1] = 0;
|
---|
111 | return (FALSE); /* didn't know it */
|
---|
112 | }
|
---|
113 | type2 = val2 = -1;
|
---|
114 | type = CLASS(word);
|
---|
115 | clrlin();
|
---|
116 | val = VAL(word);
|
---|
117 | if (words[wdx + 1] && CLASS(words[wdx + 1]) != CONJUNCTION) {
|
---|
118 |
|
---|
119 | /* 'SAY' or 'CALL'. If no next word, pass on to higher powers. */
|
---|
120 | if (type == ACTION && (val == SAY || val == YELL)) {
|
---|
121 | word = words[++wdx];
|
---|
122 | if (!(word == XYZZY || word == PLUGH
|
---|
123 | || word == PLOVER || word == PHUCE)) {
|
---|
124 | if (val == SAY)
|
---|
125 | printf("Okay, \"%s\".\n", txt[wdx]);
|
---|
126 | else {
|
---|
127 | for (ch_ptr = txt[wdx]; *ch_ptr; ch_ptr++)
|
---|
128 | if (islower(*ch_ptr))
|
---|
129 | *ch_ptr = toupper(*ch_ptr);
|
---|
130 | printf("Okay, \"%s\"!!!!!\n", txt[wdx]);
|
---|
131 | }
|
---|
132 | return (FALSE);
|
---|
133 | }
|
---|
134 | } else {
|
---|
135 | word1 = txt[wdx];
|
---|
136 | word2 = txt[wdx + 1];
|
---|
137 |
|
---|
138 | /* Special stuff for 'ENTER'. Can't go into water. 'ENTER
|
---|
139 | BOAT' means 'TAKE BOAT' */
|
---|
140 | if (word == ENTER) {
|
---|
141 | if (CLASS(words[wdx + 1]) == NOUN && VAL(words[wdx + 1]) == BOAT)
|
---|
142 | word = TAKE + 2000;
|
---|
143 | else if ((strcmp(word2, "stream") == 0)
|
---|
144 | || (strcmp(word2, "water") == 0)
|
---|
145 | || (strcmp(word2, "reservoir") == 0)
|
---|
146 | || (strcmp(word2, "ocean") == 0)
|
---|
147 | || (strcmp(word2, "sea") == 0)
|
---|
148 | || (strcmp(word2, "pool") == 0)) {
|
---|
149 | rspeak(liqloc(g.loc) == WATER ? 70 : 43);
|
---|
150 | wdx++;
|
---|
151 | return (FALSE);
|
---|
152 | }
|
---|
153 | } else {
|
---|
154 | type2 = CLASS(words[wdx + 1]);
|
---|
155 | val2 = VAL(words[wdx + 1]);
|
---|
156 |
|
---|
157 | /* 'LEAVE' is motion verb, unsless leaving an object.
|
---|
158 | E.G., 'LEAVE BOAT' or 'LEAVE BOTTLE'. BUt make sure
|
---|
159 | to leave ('DROP') only totable objects. */
|
---|
160 | if (strcmp(word1, "leave") == 0 && type2 == NOUN) {
|
---|
161 | if (!hinged(val2) || g.fixed[val2])
|
---|
162 | word = LEAVE + 2000;
|
---|
163 |
|
---|
164 | /* IF 'LIGHT LAMP', Light must be taken as an
|
---|
165 | action verb, not a noun. */
|
---|
166 | } else if (strcmp(word1, "light") == 0
|
---|
167 | && VAL(words[wdx + 1]) == LAMP) {
|
---|
168 | word = ON + 2000;
|
---|
169 |
|
---|
170 | /* 'WATER PLANT' becomes 'POUR WATER', If we are at
|
---|
171 | plant. 'OIL DOOR' becomes 'POUR OIL', etc., etc. */
|
---|
172 | } else if ((strcmp(word1, "water") == 0 || strcmp(word1, "oil") == 0)
|
---|
173 | && (strcmp(word2, "plant") == 0 || strcmp(word2, "door") == 0
|
---|
174 | || strcmp(word2, "sword") == 0 || strcmp(word2, "anvil") == 0)
|
---|
175 | && at(val2)) {
|
---|
176 | words[wdx + 1] = word;
|
---|
177 | txt[wdx + 1] = txt[wdx];
|
---|
178 | word = POUR + 2000;
|
---|
179 | }
|
---|
180 | }
|
---|
181 | }
|
---|
182 |
|
---|
183 | }
|
---|
184 | /* This is the 'inner' loop. Dispatching of all word in a clause
|
---|
185 | after the first comes through here. */
|
---|
186 | do {
|
---|
187 | switch (CLASS(word)) {
|
---|
188 | case MOTION:
|
---|
189 | {
|
---|
190 | boolean do_part2;
|
---|
191 | int i;
|
---|
192 |
|
---|
193 | do_part2 = FALSE;
|
---|
194 | type = CLASS(verbs[vrbx]);
|
---|
195 | val = VAL(verbs[vrbx]);
|
---|
196 | if (!vrbx)
|
---|
197 | do_part2 = TRUE;
|
---|
198 | else {
|
---|
199 | if (type > ACTION) {
|
---|
200 | rspeak(confuz());
|
---|
201 | return (FALSE);
|
---|
202 | }
|
---|
203 | }
|
---|
204 | if (type == ACTION) {
|
---|
205 | if (val == GO)
|
---|
206 | do_part2 = TRUE;
|
---|
207 | else {
|
---|
208 | if (val == TAKE) {
|
---|
209 | for (i = 0; i < 20; i++)
|
---|
210 | if (takdir[i] == val)
|
---|
211 | do_part2 = TRUE;
|
---|
212 | }
|
---|
213 | if (!do_part2) {
|
---|
214 | word = vocab(txt[wdx], 1);
|
---|
215 | if (word)
|
---|
216 | words[wdx--] = word;
|
---|
217 | }
|
---|
218 | }
|
---|
219 | } else if (type != CRAWL && type != JUMP
|
---|
220 | && type != CLIMB)
|
---|
221 | do_part2 = TRUE;
|
---|
222 | if (do_part2) {
|
---|
223 | verbs[1] = word;
|
---|
224 | vrbx = 1;
|
---|
225 | if (strcmp(txt[wdx], "west") == 0) {
|
---|
226 | iwest++;
|
---|
227 | if (iwest == 10)
|
---|
228 | rspeak(17);
|
---|
229 | }
|
---|
230 | }
|
---|
231 | break;
|
---|
232 | }
|
---|
233 | case NOUN:
|
---|
234 | if (pflag) {
|
---|
235 | if (!doiobj())
|
---|
236 | return (FALSE);
|
---|
237 | } else {
|
---|
238 | word = VAL(word);
|
---|
239 | if (word == ALL) {
|
---|
240 | if (!do_scoop_up())
|
---|
241 | return (FALSE);
|
---|
242 | } else {
|
---|
243 | doobj(&word);
|
---|
244 | if (word > 0) {
|
---|
245 | objs[++objx] = word;
|
---|
246 | otxt[objx] = txt[wdx];
|
---|
247 | } else {
|
---|
248 | clrlin();
|
---|
249 | pflag = FALSE;
|
---|
250 | wdx++;
|
---|
251 | while (words[wdx]) {
|
---|
252 | if (CLASS(words[wdx]) == CONJUNCTION)
|
---|
253 | break;
|
---|
254 | wdx++;
|
---|
255 | }
|
---|
256 | if (words[wdx] == 0)
|
---|
257 | return (FALSE);
|
---|
258 | }
|
---|
259 | }
|
---|
260 | }
|
---|
261 | break;
|
---|
262 | case ACTION:
|
---|
263 | if (vrbx == 0)
|
---|
264 | vrbx++;
|
---|
265 | else {
|
---|
266 | if (VAL(verbs[vrbx]) == TAKE) {
|
---|
267 | val = VAL(word);
|
---|
268 | if (val == DRINK || val == INVENTORY
|
---|
269 | || val == SCORE || val == NOTHING
|
---|
270 | || val == LOOK);
|
---|
271 | else if (val == GO && (
|
---|
272 | strcmp(txt[wdx], "walk") == 0
|
---|
273 | || strcmp(txt[wdx], "run") == 0
|
---|
274 | || strcmp(txt[wdx], "hike") == 0));
|
---|
275 | else {
|
---|
276 | rspeak(confuz());
|
---|
277 | return (FALSE);
|
---|
278 | }
|
---|
279 | } else if (objx || CLASS(words[wdx - 1]) == CONJUNCTION) {
|
---|
280 | rspeak(confuz());
|
---|
281 | return (FALSE);
|
---|
282 | }
|
---|
283 | }
|
---|
284 | verbs[vrbx] = word;
|
---|
285 | vtxt[vrbx] = txt[wdx];
|
---|
286 | break;
|
---|
287 | case MISC:
|
---|
288 | if (vrbx) {
|
---|
289 | rspeak(confuz());
|
---|
290 | return (FALSE);
|
---|
291 | }
|
---|
292 | verbs[1] = word;
|
---|
293 | vrbx = 1;
|
---|
294 | break;
|
---|
295 | case PREPOSITION:
|
---|
296 | if (CLASS(verbs[vrbx]) != ACTION || iobx) {
|
---|
297 | rspeak(confuz());
|
---|
298 | return (FALSE);
|
---|
299 | }
|
---|
300 | vrbkey = vkey[VAL(verbs[vrbx])];
|
---|
301 | if (!vrbkey) {
|
---|
302 | rspeak(confuz());
|
---|
303 | return (FALSE);
|
---|
304 | }
|
---|
305 | prep = VAL(word);
|
---|
306 | pflag = TRUE;
|
---|
307 | break;
|
---|
308 | case ADJACTIVE:
|
---|
309 | /* Adjective handler. Scarf the next word, make sure it is
|
---|
310 | a valid object for this object. Then call getobj to see
|
---|
311 | if it is really there, Then link into object code. */
|
---|
312 | adj = VAL(word);
|
---|
313 | if (!check_next())
|
---|
314 | return (FALSE);
|
---|
315 | else if (CLASS(word) == CONJUNCTION) {
|
---|
316 | printf("%s what?\n", txt[wdx - 1]);
|
---|
317 | return (FALSE);
|
---|
318 | } else {
|
---|
319 | if (CLASS(word) != NOUN)
|
---|
320 | word = vocab(txt[wdx], NOUN);
|
---|
321 | if (word == -1 || CLASS(word) != NOUN || VAL(word) == ALL) {
|
---|
322 | rspeak(confuz());
|
---|
323 | return (FALSE);
|
---|
324 | }
|
---|
325 | words[wdx] = word;
|
---|
326 | kk = VAL(word);
|
---|
327 | for (k = adjkey[adj]; adjtab[k] >= 0; k++) {
|
---|
328 | if (kk == abs(adjtab[k]))
|
---|
329 | break;
|
---|
330 | }
|
---|
331 | if (adjtab[k] < 0) {
|
---|
332 | rspeak(confuz());
|
---|
333 | return (FALSE);
|
---|
334 | }
|
---|
335 | }
|
---|
336 | break;
|
---|
337 | case CONJUNCTION:
|
---|
338 | if (!check_next())
|
---|
339 | return (FALSE);
|
---|
340 | switch (CLASS(word)) {
|
---|
341 | case MOTION:
|
---|
342 | case ACTION:
|
---|
343 | case MISC:
|
---|
344 | words[wdx--] = 0;
|
---|
345 | break;
|
---|
346 | case NOUN:
|
---|
347 | case ADJACTIVE:
|
---|
348 | break;
|
---|
349 | case PREPOSITION:
|
---|
350 | case CONJUNCTION:
|
---|
351 | rspeak(confuz());
|
---|
352 | return (FALSE);
|
---|
353 | default:
|
---|
354 | bug(33);
|
---|
355 | }
|
---|
356 | break;
|
---|
357 | default:
|
---|
358 | bug(33);
|
---|
359 | }
|
---|
360 | word = words[++wdx];
|
---|
361 | if (word < 0) {
|
---|
362 | if (pct(50))
|
---|
363 | printf("I don't understand the word %s?\n", txt[wdx]);
|
---|
364 | else
|
---|
365 | printf("Mumble ? %s\n", txt[wdx]);
|
---|
366 |
|
---|
367 | words[wdx+1] = 0;
|
---|
368 | return (FALSE);
|
---|
369 | }
|
---|
370 | type = CLASS(word);
|
---|
371 | if (type == NOUN) {
|
---|
372 | /* It's not the first: Make sure he included a comma or
|
---|
373 | 'and'. Differenctiate between direct & indirect objects.
|
---|
374 | Check for special case of multiple ofjects: 'feed bear
|
---|
375 | honey' or 'throw troll nugget'. */
|
---|
376 | if ((pflag ? iobx : objx)
|
---|
377 | && CLASS(words[wdx - 1]) != CONJUNCTION) {
|
---|
378 | val = VAL(verbs[vrbx]);
|
---|
379 | if (!living(objs[objx]) || (val != THROW && val != FEED)) {
|
---|
380 | rspeak(confuz());
|
---|
381 | return (FALSE);
|
---|
382 | }
|
---|
383 | iobx++;
|
---|
384 | iobjs[iobx] = objs[objx];
|
---|
385 | objs[objx] = 0;
|
---|
386 | objx++;
|
---|
387 | }
|
---|
388 | }
|
---|
389 | } while (word);
|
---|
390 |
|
---|
391 | if (verbs[1] == 0) {
|
---|
392 | if (objs[1] == 0) {
|
---|
393 | rspeak(confuz());
|
---|
394 | clrlin();
|
---|
395 | } else if (objs[2])
|
---|
396 | printf("What do you want to do with them?\n");
|
---|
397 | else
|
---|
398 | printf("What do you want to do with %s?\n", otxt[1]);
|
---|
399 | return (FALSE);
|
---|
400 | } else if (objx > 1 && iobx > 1) {
|
---|
401 | rspeak(confuz());
|
---|
402 | return (FALSE);
|
---|
403 | }
|
---|
404 | return (TRUE);
|
---|
405 |
|
---|
406 | }
|
---|
407 |
|
---|
408 | /*
|
---|
409 | retrieve input line (max INPUTBUFLEN chars), convert to lower case
|
---|
410 | & rescan for first two words (max. WORDSIZE-1 chars).
|
---|
411 | */
|
---|
412 | static void getwords()
|
---|
413 | {
|
---|
414 | static int wdx = 0;
|
---|
415 | int i, term_loc;
|
---|
416 | char terminator;
|
---|
417 |
|
---|
418 | if (*cindex == '\0') {
|
---|
419 | while (!*ask("\n> ", buffer, sizeof(buffer))) ;
|
---|
420 | for (cindex = buffer; *cindex; cindex++)
|
---|
421 | if (isupper(*cindex))
|
---|
422 | *cindex = tolower(*cindex);
|
---|
423 | cindex = buffer;
|
---|
424 | }
|
---|
425 | wdx = 0;
|
---|
426 | buffer[sizeof(buffer)-1] = '\0';
|
---|
427 | for (i = 0; i < MAXWORDS; i++) {
|
---|
428 | txt[i] = &buffer[sizeof(buffer)-1];
|
---|
429 | words[i] = 0;
|
---|
430 | }
|
---|
431 | do {
|
---|
432 | while (*cindex == ' ')
|
---|
433 | cindex++;
|
---|
434 | txt[wdx] = cindex;
|
---|
435 | term_loc = strcspn(cindex, " ,.;\n");
|
---|
436 | cindex += term_loc;
|
---|
437 | terminator = *cindex;
|
---|
438 | *cindex++ = '\0';
|
---|
439 | if ((strcmp(txt[wdx], "a") != 0)
|
---|
440 | && (strcmp(txt[wdx], "the") != 0)
|
---|
441 | && (strcmp(txt[wdx], "an") != 0)) {
|
---|
442 | words[wdx] = vocab(txt[wdx], 0);
|
---|
443 | wdx++;
|
---|
444 | }
|
---|
445 | if (terminator == ',') {
|
---|
446 | txt[wdx] = "and";
|
---|
447 | words[wdx] = vocab(txt[wdx], 0);
|
---|
448 | wdx++;
|
---|
449 | }
|
---|
450 | }
|
---|
451 | while ((terminator != ';') && (terminator != '.')
|
---|
452 | && (terminator != '\0') && (terminator != '\n'));
|
---|
453 | if (terminator == '\0')
|
---|
454 | cindex--;
|
---|
455 | return;
|
---|
456 | }
|
---|
457 |
|
---|
458 | /* CLRIN, clears out all surrent syntax args in preparation for
|
---|
459 | * new input line
|
---|
460 | */
|
---|
461 |
|
---|
462 | static void clrlin()
|
---|
463 | {
|
---|
464 | int i;
|
---|
465 |
|
---|
466 | for (i = 0; i < MAXWORDS; i++) {
|
---|
467 | verbs[i] = 0;
|
---|
468 | vtxt[i] = &buffer[sizeof(buffer)-1];
|
---|
469 | }
|
---|
470 |
|
---|
471 | for (i = 0; i < MAXITEMS; i++) {
|
---|
472 | objs[i] = 0;
|
---|
473 | otxt[i] = &buffer[sizeof(buffer)-1];
|
---|
474 | iobjs[i] = 0;
|
---|
475 | iotxt[i] = &buffer[sizeof(buffer)-1];
|
---|
476 | }
|
---|
477 | vrbx = 0;
|
---|
478 | objx = 0;
|
---|
479 | iobx = 0;
|
---|
480 | prep = 0;
|
---|
481 | }
|
---|
482 |
|
---|
483 | /*
|
---|
484 | Routine to process an object.
|
---|
485 | */
|
---|
486 | static void doobj(object)
|
---|
487 | int *object;
|
---|
488 | {
|
---|
489 | int msg;
|
---|
490 |
|
---|
491 | if (holding(*object))
|
---|
492 | return;
|
---|
493 | if (blind()) {
|
---|
494 | printf("I see no %s here.\n", txt[wdx]);
|
---|
495 | *object = 0;
|
---|
496 | return;
|
---|
497 | }
|
---|
498 | /* Is object here? if so, transitive */
|
---|
499 | if (g.fixed[*object] == g.loc || athand(*object))
|
---|
500 | return;
|
---|
501 | else if (here(*object)) {
|
---|
502 | msg = plural(*object) ? 373 : 335;
|
---|
503 | *object = 0;
|
---|
504 | rspeak(msg);
|
---|
505 | }
|
---|
506 | /* Did he give grate as destination? */
|
---|
507 | else if (*object == GRATE) {
|
---|
508 | if (g.loc == 1 || g.loc == 4 || g.loc == 7) {
|
---|
509 | verbs[1] = DEPRESSION;
|
---|
510 | vrbx = 1;
|
---|
511 | return;
|
---|
512 | } else if (g.loc > 9 && g.loc < 15) {
|
---|
513 | verbs[1] = ENTRANCE;
|
---|
514 | vrbx = 1;
|
---|
515 | return;
|
---|
516 | }
|
---|
517 | }
|
---|
518 | /* Is it a dwarf he is after? */
|
---|
519 | else if (dcheck() && g.dflag >= 2) {
|
---|
520 | *object = DWARF;
|
---|
521 | }
|
---|
522 | /* Is he trying to get/use a liquid? */
|
---|
523 | else if (liqloc(g.loc) == *object
|
---|
524 | || (liq(BOTTLE) == *object && athand(BOTTLE))
|
---|
525 | || (liq(CASK) == *object && athand(CASK)));
|
---|
526 | else if (*object == PLANT && at(PLANT2) &&
|
---|
527 | g.prop[PLANT2] == 0) {
|
---|
528 | *object = PLANT2;
|
---|
529 | } else if (*object == ROCKS && at(CARVNG)) {
|
---|
530 | *object = CARVNG;
|
---|
531 | }
|
---|
532 | /* Is he trying to grab a knife? */
|
---|
533 | else if (*object == KNIFE && g.knfloc == g.loc) {
|
---|
534 | rspeak(116);
|
---|
535 | g.knfloc = -1;
|
---|
536 | }
|
---|
537 | /* Is he trying to get at dynamite? */
|
---|
538 | else if (*object == ROD && athand(ROD2)) {
|
---|
539 | *object = ROD2;
|
---|
540 | } else if (*object == DOOR && (at(SAFE) || at(TDOOR)
|
---|
541 | || at(TDOOR2) || at(PDOOR))) {
|
---|
542 | if (at(TDOOR2))
|
---|
543 | *object = TDOOR2;
|
---|
544 | else if (at(PDOOR))
|
---|
545 | *object = PDOOR;
|
---|
546 | else if (at(SAFE))
|
---|
547 | *object = SAFE;
|
---|
548 | else
|
---|
549 | *object = TDOOR;
|
---|
550 | } else if (*object == BOOK && athand(BOOK2)) {
|
---|
551 | *object = BOOK2;
|
---|
552 | } else if (!(verbs[vrbx] == FIND || verbs[vrbx] == INVENTORY)) {
|
---|
553 | *object = 0;
|
---|
554 | printf("I see no %s here.\n", txt[wdx]);
|
---|
555 | }
|
---|
556 | return;
|
---|
557 | }
|
---|
558 |
|
---|
559 | static boolean doiobj()
|
---|
560 | {
|
---|
561 | char dk[INPUTBUFLEN], dkk[INPUTBUFLEN];
|
---|
562 | int kk;
|
---|
563 | boolean ok;
|
---|
564 |
|
---|
565 | /* checks object is valid for this preposition */
|
---|
566 | ok = TRUE;
|
---|
567 | word = VAL(word);
|
---|
568 | if (word != ALL) {
|
---|
569 | doobj(&word);
|
---|
570 | if (word > 0) {
|
---|
571 | iobjs[++iobx] = word;
|
---|
572 | iotxt[iobx] = txt[wdx];
|
---|
573 | } else
|
---|
574 | ok = FALSE;
|
---|
575 | }
|
---|
576 | kk = abs(ptab[vrbkey]) / 1000;
|
---|
577 | if (kk == prep) {
|
---|
578 | /* preprosition is valid with this verb now check object of
|
---|
579 | preprosition */
|
---|
580 |
|
---|
581 | if (word == 0 || CLASS(word) == CONJUNCTION) {
|
---|
582 | /* no object following prepresition: check special cases */
|
---|
583 |
|
---|
584 | pflag = FALSE;
|
---|
585 | strcpy(dk, txt[--wdx]);
|
---|
586 | strcpy(dkk, vtxt[vrbx]);
|
---|
587 | ok = FALSE;
|
---|
588 | if ((strcmp(dk, "on") == 0
|
---|
589 | || strcmp(dk, "off") == 0)
|
---|
590 | && (strcmp(dkk, "turn") == 0
|
---|
591 | || objs[objx] == LAMP))
|
---|
592 | ok = TRUE;
|
---|
593 | if (strcmp(dkk, "take") == 0
|
---|
594 | || strcmp(dkk, "put") == 0)
|
---|
595 | ok = TRUE;
|
---|
596 | if (strcmp(dk, "up") == 0
|
---|
597 | && strcmp(dkk, "pick") == 0)
|
---|
598 | ok = TRUE;
|
---|
599 | if (strcmp(dk, "down") == 0
|
---|
600 | && (strcmp(dkk, "put") == 0 || verbs[vrbx] == THROW) )
|
---|
601 | ok = TRUE;
|
---|
602 | } else {
|
---|
603 | /* object follows preposition See if it's plausible. */
|
---|
604 |
|
---|
605 | kk = abs(ptab[vrbkey]) % 1000;
|
---|
606 | if (kk == word && kk == ALL) {
|
---|
607 | if (!do_scoop_up())
|
---|
608 | return (FALSE);
|
---|
609 | } else if (!(kk == word || kk == 999)) {
|
---|
610 | vrbkey++;
|
---|
611 | ok = ptab[vrbkey - 1] < 0 ? FALSE : TRUE;
|
---|
612 | }
|
---|
613 | }
|
---|
614 | }
|
---|
615 | return (ok);
|
---|
616 | }
|
---|
617 |
|
---|
618 | static boolean do_scoop_up()
|
---|
619 | {
|
---|
620 | int i, val;
|
---|
621 |
|
---|
622 | val = VAL(verbs[vrbx]);
|
---|
623 | if (val == DROP || val == PUT || val == LEAVE) {
|
---|
624 | for (i = 1; i < MAXOBJ; i++) {
|
---|
625 | if (!athand(i) || g.fixed[i])
|
---|
626 | continue;
|
---|
627 | if (i > WATER && i <= WINE + 1)
|
---|
628 | continue;
|
---|
629 | if (toting(i)) {
|
---|
630 | objs[++objx] = i;
|
---|
631 | otxt[objx] = "BUG???";
|
---|
632 | if (objx >= 44)
|
---|
633 | break;
|
---|
634 | }
|
---|
635 | }
|
---|
636 | }
|
---|
637 | if (val == TAKE || val == PICK || val == GET) {
|
---|
638 | if (blind()) {
|
---|
639 | rspeak(357);
|
---|
640 | return (FALSE);
|
---|
641 | } else {
|
---|
642 | for (i = 1; i < MAXOBJ; i++) {
|
---|
643 | if (!athand(i) || g.fixed[i])
|
---|
644 | continue;
|
---|
645 | if (i > WATER && i <= WINE + 1)
|
---|
646 | continue;
|
---|
647 | if (!toting(i)) {
|
---|
648 | objs[++objx] = i;
|
---|
649 | otxt[objx] = "BUG???";
|
---|
650 | if (objx >= 44)
|
---|
651 | break;
|
---|
652 | }
|
---|
653 | }
|
---|
654 | }
|
---|
655 | }
|
---|
656 | return (TRUE);
|
---|
657 | }
|
---|
658 |
|
---|
659 | static boolean check_next()
|
---|
660 | {
|
---|
661 |
|
---|
662 | word = words[wdx + 1];
|
---|
663 | if (word > 0)
|
---|
664 | return (TRUE);
|
---|
665 | else if (word == 0)
|
---|
666 | rspeak(confuz());
|
---|
667 | else {
|
---|
668 | if (pct(50))
|
---|
669 | printf("I don't understand the word %s?\n", txt[wdx]);
|
---|
670 | else
|
---|
671 | printf("Mumble ? %s\n", txt[wdx]);
|
---|
672 | words[wdx+1] = 0;
|
---|
673 | }
|
---|
674 |
|
---|
675 | return (FALSE);
|
---|
676 | }
|
---|