1 | /* program ITVERB.C */
|
---|
2 |
|
---|
3 |
|
---|
4 | #include <stdio.h>
|
---|
5 | #include "advent.h"
|
---|
6 | #include "advdec.h"
|
---|
7 |
|
---|
8 | _PROTOTYPE(void needobj, (void));
|
---|
9 | _PROTOTYPE(void ivtake, (void));
|
---|
10 | _PROTOTYPE(void ivopen, (void));
|
---|
11 | _PROTOTYPE(void ivkill, (void));
|
---|
12 | _PROTOTYPE(void ivdrink, (void));
|
---|
13 | _PROTOTYPE(void ivquit, (void));
|
---|
14 | _PROTOTYPE(void ivfoo, (void));
|
---|
15 | _PROTOTYPE(void inventory, (void));
|
---|
16 | _PROTOTYPE(void addobj, (int obj));
|
---|
17 | _PROTOTYPE(void ivpour, (void));
|
---|
18 | _PROTOTYPE(void ivfill, (void));
|
---|
19 | _PROTOTYPE(void ivbrief, (void));
|
---|
20 | _PROTOTYPE(void ivread, (void));
|
---|
21 | _PROTOTYPE(void ivcombo, (void));
|
---|
22 | _PROTOTYPE(void iveat, (void));
|
---|
23 | /*
|
---|
24 | Routines to process intransitive verbs
|
---|
25 | */
|
---|
26 | void itverb()
|
---|
27 | {
|
---|
28 | int i;
|
---|
29 |
|
---|
30 | newtravel = FALSE;
|
---|
31 | switch (verb) {
|
---|
32 | case DROP:
|
---|
33 | case SAY:
|
---|
34 | case WAVE:
|
---|
35 | case CALM:
|
---|
36 | case RUB:
|
---|
37 | case THROW:
|
---|
38 | case FIND:
|
---|
39 | case FEED:
|
---|
40 | case BREAK:
|
---|
41 | case WAKE:
|
---|
42 | case WEAR:
|
---|
43 | case HIT:
|
---|
44 | case DIAL:
|
---|
45 | case PLAY:
|
---|
46 | case PICK:
|
---|
47 | case PUT:
|
---|
48 | case TURN: needobj(); break;
|
---|
49 | case TAKE:
|
---|
50 | case YANK:
|
---|
51 | case GET:
|
---|
52 | case INSRT:
|
---|
53 | case REMOVE:
|
---|
54 | case BURN: ivtake(); break;
|
---|
55 | case OPEN:
|
---|
56 | case CLOSE:
|
---|
57 | case LOCK:
|
---|
58 | case UNLOCK: ivopen(); break;
|
---|
59 | case NOTHING: rspeak(54); break;
|
---|
60 | case ON:
|
---|
61 | case OFF: trverb(); break;
|
---|
62 | case WALK: actspk(verb); break;
|
---|
63 | case KILL: ivkill(); break;
|
---|
64 | case POUR: ivpour(); break;
|
---|
65 | case EAT: iveat(); break;
|
---|
66 | case DRINK: ivdrink(); break;
|
---|
67 | case QUIT: ivquit(); break;
|
---|
68 | case INVENTORY: inventory(); break;
|
---|
69 | case FILL: ivfill(); break;
|
---|
70 | case BLAST: ivblast(); break;
|
---|
71 | case SCORE: score(TRUE); break;
|
---|
72 | case FOO: ivfoo(); break;
|
---|
73 | case BRIEF: ivbrief(); break;
|
---|
74 | case READ: ivread(); break;
|
---|
75 | case SUSPEND:
|
---|
76 | if (g.closing)
|
---|
77 | rspeak(378);
|
---|
78 | else
|
---|
79 | saveadv("advent.sav");
|
---|
80 | break;
|
---|
81 | case RESTORE: restore("advent.sav"); break;
|
---|
82 | case ANSWER:
|
---|
83 | if ((g.loc != 189) || (g.prop[PHONE] != 0))
|
---|
84 | needobj();
|
---|
85 | else {
|
---|
86 | object = PHONE;
|
---|
87 | itverb();
|
---|
88 | }
|
---|
89 | break;
|
---|
90 | case BLOW: rspeak(268); break;
|
---|
91 | /* Action verb 'LEAVE' has no object */
|
---|
92 | case LEAVE: bug(29); break;
|
---|
93 | /* Call if no phone is handy, yell. */
|
---|
94 | case YELL:
|
---|
95 | if (!here(PHONE))
|
---|
96 | needobj();
|
---|
97 | else if (!g.closed)
|
---|
98 | rspeak(271);
|
---|
99 | else {
|
---|
100 | rspeak(283);
|
---|
101 | normend();
|
---|
102 | }
|
---|
103 | break;
|
---|
104 | /* Health. give him a diagnosis. */
|
---|
105 | case HEALTH:
|
---|
106 | if (g.numdie)
|
---|
107 | fprintf(stdout, "You have been killed %d times otherwise\n",
|
---|
108 | g.numdie);
|
---|
109 | if (g.health >= 95) {
|
---|
110 | if (pct(50))
|
---|
111 | rspeak(348);
|
---|
112 | else
|
---|
113 | rspeak(349);
|
---|
114 | } else {
|
---|
115 | fprintf(stdout,
|
---|
116 | "Your health rating is %2d out of a possible 100.\n",
|
---|
117 | g.health);
|
---|
118 | rspeak(381 + (100 - g.health) / 20);
|
---|
119 | }
|
---|
120 | break;
|
---|
121 | case LOOK: ivlook(); break;
|
---|
122 | case COMBO:
|
---|
123 | if (at(SAFE))
|
---|
124 | ivcombo();
|
---|
125 | break;
|
---|
126 | case SWEEP:
|
---|
127 | /* Dust/sweep */
|
---|
128 | if (!at(CARVNG) || !athand(BRUSH) || (g.prop[CARVNG] == 1))
|
---|
129 | rspeak(342);
|
---|
130 | else {
|
---|
131 | g.prop[CARVNG] = 1;
|
---|
132 | rspeak(363);
|
---|
133 | rspeak(372);
|
---|
134 | }
|
---|
135 | break;
|
---|
136 | case TERSE:
|
---|
137 | /* Terse/unterse. supress all long_form descriptions. */
|
---|
138 | g.terse = !g.terse;
|
---|
139 | g.detail = 3;
|
---|
140 | rspeak(54);
|
---|
141 | break;
|
---|
142 | case WIZ:
|
---|
143 | is_wiz = !is_wiz;
|
---|
144 | case MAP:
|
---|
145 | rspeak(54);
|
---|
146 | break;
|
---|
147 | case GATE:
|
---|
148 | if (is_wiz) {
|
---|
149 | static char buf[INPUTBUFLEN];
|
---|
150 | sscanf(ask("Location ? ", buf, sizeof(buf)), "%d", &g.loc);
|
---|
151 | }
|
---|
152 | rspeak(54);
|
---|
153 | break;
|
---|
154 | case PIRLOC:
|
---|
155 | if (is_wiz) {
|
---|
156 | fprintf(stdout, "The dwarfs are at locations:\n");
|
---|
157 | for (i = 1; i < DWARFMAX; i++)
|
---|
158 | fprintf(stdout, " %4d", g.dloc[i]);
|
---|
159 | fprintf(stdout, "\nThe pirate is at location %4d\n",
|
---|
160 | g.dloc[DWARFMAX]);
|
---|
161 | }
|
---|
162 | rspeak(54);
|
---|
163 | break;
|
---|
164 | default:
|
---|
165 | printf("This intransitive not implemented yet\n");
|
---|
166 | }
|
---|
167 | return;
|
---|
168 | }
|
---|
169 |
|
---|
170 | /*
|
---|
171 | Routine to indicate no reasonable
|
---|
172 | object for verb found. Used mostly by
|
---|
173 | intransitive verbs.
|
---|
174 | */
|
---|
175 | void needobj()
|
---|
176 | {
|
---|
177 | printf("%s what?\n", vtxt[vrbx]);
|
---|
178 | return;
|
---|
179 | }
|
---|
180 |
|
---|
181 | /*
|
---|
182 | CARRY, TAKE etc.
|
---|
183 | */
|
---|
184 | void ivtake()
|
---|
185 | {
|
---|
186 | int anobj, item;
|
---|
187 |
|
---|
188 | anobj = 0;
|
---|
189 | for (item = 1; item < MAXOBJ; ++item)
|
---|
190 | if (g.place[item] == g.loc)
|
---|
191 | if (anobj == 0)
|
---|
192 | anobj = item;
|
---|
193 | else {
|
---|
194 | needobj();
|
---|
195 | return;
|
---|
196 | }
|
---|
197 |
|
---|
198 | if (anobj == 0 || (dcheck() && g.dflag >= 2) || blind())
|
---|
199 | needobj();
|
---|
200 | else {
|
---|
201 | object = anobj;
|
---|
202 | if (verb == YANK)
|
---|
203 | vyank();
|
---|
204 | else if (verb == WEAR)
|
---|
205 | vwear();
|
---|
206 | else
|
---|
207 | vtake();
|
---|
208 | }
|
---|
209 | return;
|
---|
210 | }
|
---|
211 |
|
---|
212 | /*
|
---|
213 | OPEN, LOCK, UNLOCK
|
---|
214 | */
|
---|
215 | void ivopen()
|
---|
216 | {
|
---|
217 | int obj_cnt, item;
|
---|
218 |
|
---|
219 | for (item = 1, obj_cnt = 0; item < MAXOBJ; item++) {
|
---|
220 | if ((g.place[item] == g.loc) && (hinged(item))) {
|
---|
221 | object = item;
|
---|
222 | obj_cnt++;
|
---|
223 | }
|
---|
224 | }
|
---|
225 | if (obj_cnt != 1)
|
---|
226 | needobj();
|
---|
227 | else if (verb == LOCK)
|
---|
228 | vlock();
|
---|
229 | else if (verb == UNLOCK)
|
---|
230 | vunlock();
|
---|
231 | else if (verb == SHUT)
|
---|
232 | vclose();
|
---|
233 | else
|
---|
234 | vopen();
|
---|
235 | }
|
---|
236 |
|
---|
237 | /*
|
---|
238 | ATTACK, KILL etc
|
---|
239 | */
|
---|
240 | boolean previous_obj;
|
---|
241 |
|
---|
242 | void ivkill()
|
---|
243 | {
|
---|
244 | previous_obj = FALSE;
|
---|
245 | if (dcheck() && g.dflag >= 2)
|
---|
246 | object = DWARF;
|
---|
247 | if (here(SNAKE))
|
---|
248 | addobj(SNAKE);
|
---|
249 | if (at(DRAGON) && g.prop[DRAGON] == 0)
|
---|
250 | addobj(DRAGON);
|
---|
251 | if (at(TROLL))
|
---|
252 | addobj(TROLL);
|
---|
253 | if (here(GNOME))
|
---|
254 | addobj(GNOME);
|
---|
255 | if (here(BEAR) && g.prop[BEAR] == 0)
|
---|
256 | addobj(BEAR);
|
---|
257 | if (here(WUMPUS) && g.prop[WUMPUS] == 0)
|
---|
258 | addobj(WUMPUS);
|
---|
259 | /* Can't attack bird by throwing axe */
|
---|
260 | if (here(BIRD) && verb != THROW)
|
---|
261 | addobj(BIRD);
|
---|
262 | /* Clam and oyster both treated as clam for intransitive case; no
|
---|
263 | harm done. */
|
---|
264 | if (here(CLAM) || here(OYSTER))
|
---|
265 | addobj(CLAM);
|
---|
266 |
|
---|
267 | if ((previous_obj) || (object == 0))
|
---|
268 | rspeak(44);
|
---|
269 | else
|
---|
270 | vkill();
|
---|
271 | return;
|
---|
272 | }
|
---|
273 |
|
---|
274 | /*
|
---|
275 | POUR if no object, assume liq in container, if holding one.
|
---|
276 | */
|
---|
277 | void ivpour()
|
---|
278 | {
|
---|
279 | if ((holding(BOTTLE)) && (liq(BOTTLE) != 0) && !holding(CASK))
|
---|
280 | object = BOTTLE;
|
---|
281 | if ((holding(CASK)) && (liq(CASK) != 0) && !holding(BOTTLE))
|
---|
282 | object = CASK;
|
---|
283 |
|
---|
284 | if (object == 0)
|
---|
285 | needobj();
|
---|
286 | else
|
---|
287 | trverb();
|
---|
288 | }
|
---|
289 |
|
---|
290 | /*
|
---|
291 | EAT. intransitive: assume edible if present, else ask what.
|
---|
292 | If he as more than one edible, or none, 'EAT' is ambiguous
|
---|
293 | without an explicit object.
|
---|
294 | */
|
---|
295 | void iveat()
|
---|
296 | {
|
---|
297 | int i;
|
---|
298 |
|
---|
299 | previous_obj = FALSE;
|
---|
300 | for (i = 1; i < MAXOBJ; i++) {
|
---|
301 | if ((here(i)) && (edible(i)))
|
---|
302 | addobj(i);
|
---|
303 | }
|
---|
304 | if ((previous_obj) || (object == 0))
|
---|
305 | needobj();
|
---|
306 | else
|
---|
307 | trverb();
|
---|
308 | }
|
---|
309 |
|
---|
310 | /*
|
---|
311 | DRINK. If no object, assume water or wine and look for them here.
|
---|
312 | If potable is in bottle or cask, drink that. If not, see if there
|
---|
313 | is something drinkable nearby (stream, lake, wine fountain, etc.),
|
---|
314 | and drink that. If he has stuff in both containers, ask which.
|
---|
315 | */
|
---|
316 | void ivdrink()
|
---|
317 | {
|
---|
318 | int ll;
|
---|
319 |
|
---|
320 | previous_obj = FALSE;
|
---|
321 | ll = liqloc(g.loc);
|
---|
322 | if ((ll == WATER) || (ll == WINE)) {
|
---|
323 | object = ll;
|
---|
324 | iobj = -1;
|
---|
325 | }
|
---|
326 | ll = liq(BOTTLE);
|
---|
327 | if ((athand(BOTTLE)) && ((ll == WATER) || (ll == WINE))) {
|
---|
328 | object = ll;
|
---|
329 | iobj = BOTTLE;
|
---|
330 | }
|
---|
331 | ll = liq(CASK);
|
---|
332 | if ((athand(CASK)) && ((ll == WATER) || (ll == WINE))
|
---|
333 | && iobj != BOTTLE) {
|
---|
334 | object = ll;
|
---|
335 | iobj = CASK;
|
---|
336 | } else
|
---|
337 | object = 0;
|
---|
338 |
|
---|
339 | if (object == 0)
|
---|
340 | needobj();
|
---|
341 | else
|
---|
342 | trverb();
|
---|
343 | }
|
---|
344 |
|
---|
345 | /*
|
---|
346 | QUIT intransitive only. Verify intent and exit if that's what he wants
|
---|
347 | */
|
---|
348 | void ivquit()
|
---|
349 | {
|
---|
350 | gaveup = yes(22, 54, 54);
|
---|
351 | if (gaveup)
|
---|
352 | normend();
|
---|
353 | return;
|
---|
354 | }
|
---|
355 |
|
---|
356 | /*
|
---|
357 | INVENTORY
|
---|
358 | */
|
---|
359 | void inventory()
|
---|
360 | {
|
---|
361 | int i, msg;
|
---|
362 | boolean init_msg;
|
---|
363 |
|
---|
364 | init_msg = TRUE;
|
---|
365 | msg = 98;
|
---|
366 | for (i = 1; i < MAXOBJ; i++) {
|
---|
367 | if (!holding(i) || wearng(i) || i == BEAR || i == BOAT)
|
---|
368 | continue;
|
---|
369 | if (init_msg)
|
---|
370 | rspeak(99);
|
---|
371 | pspeak(i, -1);
|
---|
372 | init_msg = FALSE;
|
---|
373 | msg = 0;
|
---|
374 | lookin(i);
|
---|
375 | }
|
---|
376 |
|
---|
377 | /* Tell him what he is wearing */
|
---|
378 | init_msg = TRUE;
|
---|
379 | for (i = 1; i < MAXOBJ; i++) {
|
---|
380 | if (wearng(i)) {
|
---|
381 | if (init_msg)
|
---|
382 | fprintf(stdout, "\nYou are wearing:\n");
|
---|
383 | fprintf(stdout, " ");
|
---|
384 | pspeak(i, -1);
|
---|
385 | msg = 0;
|
---|
386 | init_msg = FALSE;
|
---|
387 | }
|
---|
388 | }
|
---|
389 |
|
---|
390 | if (holding(BOAT)) {
|
---|
391 | rspeak(221);
|
---|
392 | lookin(BOAT);
|
---|
393 | }
|
---|
394 | if (holding(BEAR))
|
---|
395 | msg = 141;
|
---|
396 |
|
---|
397 | if (msg)
|
---|
398 | rspeak(msg);
|
---|
399 | return;
|
---|
400 | }
|
---|
401 |
|
---|
402 | /*
|
---|
403 | FILL bottle or cask must be empty, and some liquid avaible
|
---|
404 | */
|
---|
405 | void ivfill()
|
---|
406 | {
|
---|
407 | if ((g.prop[CASK] == 1) && !here(CASK))
|
---|
408 | object = CASK;
|
---|
409 | if ((g.prop[BOTTLE] == 1) && !here(BOTTLE))
|
---|
410 | object = BOTTLE;
|
---|
411 |
|
---|
412 | if ((here(BOTTLE) && here(CASK)) || (object == 0))
|
---|
413 | needobj();
|
---|
414 | else
|
---|
415 | trverb();
|
---|
416 | }
|
---|
417 |
|
---|
418 | /*
|
---|
419 | BLAST etc.
|
---|
420 | */
|
---|
421 | void ivblast()
|
---|
422 | {
|
---|
423 | if (!g.closed)
|
---|
424 | actspk(verb);
|
---|
425 | else {
|
---|
426 | g.bonus = 135;
|
---|
427 | if (g.place[ROD2] == 212 && g.loc == 116)
|
---|
428 | g.bonus = 133;
|
---|
429 | if (g.place[ROD2] == 116 && g.loc != 116)
|
---|
430 | g.bonus = 134;
|
---|
431 | rspeak(g.bonus);
|
---|
432 | normend();
|
---|
433 | }
|
---|
434 | return;
|
---|
435 | }
|
---|
436 |
|
---|
437 | /*
|
---|
438 | Handle fee fie foe foo...
|
---|
439 | */
|
---|
440 | void ivfoo()
|
---|
441 | {
|
---|
442 | int k;
|
---|
443 | int msg;
|
---|
444 |
|
---|
445 | k = VAL(vocab(vtxt[vrbx], MISC));
|
---|
446 | if (g.foobar != 1 - k) {
|
---|
447 | if (g.foobar == 0)
|
---|
448 | msg = 42;
|
---|
449 | else
|
---|
450 | msg = 151;
|
---|
451 | rspeak(msg);
|
---|
452 | return;
|
---|
453 | }
|
---|
454 | g.foobar = k;
|
---|
455 | if (k != 4)
|
---|
456 | return;
|
---|
457 | g.foobar = 0;
|
---|
458 | if (g.place[EGGS] == plac[EGGS] ||
|
---|
459 | (toting(EGGS) && g.loc == plac[EGGS])) {
|
---|
460 | rspeak(42);
|
---|
461 | return;
|
---|
462 | }
|
---|
463 | /* Bring back troll if we steal the eggs back from him before
|
---|
464 | crossing */
|
---|
465 | if (g.place[EGGS] == 0 && g.place[TROLL] == 0 && g.prop[TROLL] == 0)
|
---|
466 | g.prop[TROLL] = 1;
|
---|
467 |
|
---|
468 | if (here(EGGS))
|
---|
469 | k = 1;
|
---|
470 | else if (g.loc == plac[EGGS])
|
---|
471 | k = 0;
|
---|
472 | else
|
---|
473 | k = 2;
|
---|
474 | move(EGGS, plac[EGGS]);
|
---|
475 | pspeak(EGGS, k);
|
---|
476 | return;
|
---|
477 | }
|
---|
478 |
|
---|
479 | /*
|
---|
480 | brief/unbrief. intransitive only.
|
---|
481 | suppress long descriptions after first time.
|
---|
482 | */
|
---|
483 | void ivbrief()
|
---|
484 | {
|
---|
485 | int msg;
|
---|
486 |
|
---|
487 | g.detail = 3;
|
---|
488 | g.terse = FALSE;
|
---|
489 | if (g.abbnum != 10000) {
|
---|
490 | msg = 156;
|
---|
491 | g.abbnum = 10000;
|
---|
492 | } else {
|
---|
493 | msg = 374;
|
---|
494 | g.abbnum = 5;
|
---|
495 | }
|
---|
496 | rspeak(msg);
|
---|
497 | }
|
---|
498 |
|
---|
499 | /*
|
---|
500 | read etc...
|
---|
501 | */
|
---|
502 | void ivread()
|
---|
503 | {
|
---|
504 | previous_obj = FALSE;
|
---|
505 | if (here(BOOK))
|
---|
506 | object = BOOK;
|
---|
507 | if (here(BOOK2))
|
---|
508 | addobj(BOOK2);
|
---|
509 | if (here(BILLBD))
|
---|
510 | addobj(BILLBD);
|
---|
511 | if (here(CARVNG))
|
---|
512 | addobj(CARVNG);
|
---|
513 | if (here(MAGAZINE))
|
---|
514 | addobj(MAGAZINE);
|
---|
515 | if (here(MESSAGE))
|
---|
516 | addobj(MESSAGE);
|
---|
517 | if (here(OYSTER))
|
---|
518 | addobj(OYSTER);
|
---|
519 | if (here(POSTER))
|
---|
520 | addobj(POSTER);
|
---|
521 | if (here(TABLET))
|
---|
522 | addobj(TABLET);
|
---|
523 |
|
---|
524 | if (previous_obj || object == 0 || dark())
|
---|
525 | needobj();
|
---|
526 | else
|
---|
527 | vread();
|
---|
528 | return;
|
---|
529 | }
|
---|
530 |
|
---|
531 | /*
|
---|
532 | LOOK. can't give more detail. Pretend it wasn't dark (though it may "now"
|
---|
533 | be dark) so he won't fall into a pit staring into the gloom.
|
---|
534 | */
|
---|
535 | void ivlook()
|
---|
536 | {
|
---|
537 | if (g.detail++ < 3)
|
---|
538 | rspeak(15);
|
---|
539 | g.wzdark = FALSE;
|
---|
540 | g.visited[g.loc] = 0;
|
---|
541 | g.newloc = g.loc;
|
---|
542 | newtravel = TRUE;
|
---|
543 | return;
|
---|
544 | }
|
---|
545 |
|
---|
546 | /*
|
---|
547 | COMBO: trying to open safe. (see comments for fee fie foe foo)
|
---|
548 | */
|
---|
549 | void ivcombo()
|
---|
550 | {
|
---|
551 | int k, msg;
|
---|
552 |
|
---|
553 | k = VAL(vocab(vtxt[vrbx], MISC)) - 10;
|
---|
554 | msg = 42;
|
---|
555 | if (g.combo != 1 - k) {
|
---|
556 | if (g.combo != 0)
|
---|
557 | msg = 366;
|
---|
558 | rspeak(msg);
|
---|
559 | return;
|
---|
560 | }
|
---|
561 | g.combo = k;
|
---|
562 | if (k != 3)
|
---|
563 | rspeak(371);
|
---|
564 | else {
|
---|
565 | g.combo = 0;
|
---|
566 | bitoff(SAFE, LOCKBT);
|
---|
567 | biton(SAFE, OPENBT);
|
---|
568 | g.prop[SAFE] = 1;
|
---|
569 | if (g.prop[BOOK] < 0) {
|
---|
570 | g.tally--;
|
---|
571 | g.prop[BOOK] = 0;
|
---|
572 | /* If remaining treasures too elusive, zap his lamp. this
|
---|
573 | duplicates some code, must be done here since book is
|
---|
574 | contained ins safe & tally stuff only works for thing
|
---|
575 | deposited at a location. */
|
---|
576 | if ((g.tally == g.tally2) && (g.tally != 0))
|
---|
577 | g.limit = (g.limit < 35) ? g.limit : 35;
|
---|
578 | }
|
---|
579 | rspeak(365);
|
---|
580 | }
|
---|
581 | }
|
---|
582 |
|
---|
583 | /*
|
---|
584 | ensure uniqueness as objects are searched
|
---|
585 | out for an intransitive verb
|
---|
586 | */
|
---|
587 | void addobj(obj)
|
---|
588 | int obj;
|
---|
589 | {
|
---|
590 | if (!previous_obj) {
|
---|
591 | if (object != 0)
|
---|
592 | previous_obj = TRUE;
|
---|
593 | else
|
---|
594 | object = obj;
|
---|
595 | }
|
---|
596 | return;
|
---|
597 | }
|
---|