source: trunk/minix/commands/advent/verb.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 38.5 KB
Line 
1/* program VERB.C */
2
3#include "stdio.h"
4#include "advent.h"
5#include "advdec.h"
6
7 /* Initialize default verb messages */
8static _CONST int actmsg[56] = {
9 0, 24, 29, 0, 33, 0, 33, 38, 38, 42,
10 14, 43, 110, 29, 110, 73, 75, 29, 13, 59,
11 59, 174, 313, 67, 13, 147, 155, 369, 146, 110,
12 13, 13, 24, 25, 110, 262, 14, 29, 271, 14,
13 14, 24, 29, 38, 24, 331, 24, 109, 332, 0,
14 0, 348, 358, 0, 364, 0};
15
16_PROTOTYPE(static int ck_obj, (void));
17_PROTOTYPE(void von, (void));
18_PROTOTYPE(void voff, (void));
19_PROTOTYPE(void vwave, (void));
20_PROTOTYPE(void veat, (void));
21_PROTOTYPE(void vthrow, (void));
22_PROTOTYPE(void vfind, (void));
23_PROTOTYPE(void vfill, (void));
24_PROTOTYPE(void vfeed, (void));
25_PROTOTYPE(void vbreak, (void));
26_PROTOTYPE(void vwake, (void));
27_PROTOTYPE(void vdrop, (void));
28_PROTOTYPE(void vpour, (void));
29_PROTOTYPE(void vput, (void));
30_PROTOTYPE(void vread, (void));
31_PROTOTYPE(void vinsert, (void));
32_PROTOTYPE(void vextract, (void));
33_PROTOTYPE(static boolean do_battle, (int *));
34_PROTOTYPE(void vhit, (void));
35_PROTOTYPE(void vanswer, (void));
36_PROTOTYPE(void vblow, (void));
37_PROTOTYPE(void vdial, (void));
38_PROTOTYPE(void vplay, (void));
39_PROTOTYPE(void vpick, (void));
40_PROTOTYPE(void vput, (void));
41_PROTOTYPE(void vturn, (void));
42_PROTOTYPE(void vget, (void));
43_PROTOTYPE(void vlook, (void));
44
45
46/*
47 Routine to process a transitive verb
48*/
49void trverb()
50{
51 newtravel = FALSE;
52 switch (verb) {
53 case NOTHING:
54 case CALM:
55 case WALK:
56 case QUIT:
57 case SCORE:
58 case FOO:
59 case SUSPEND: break;
60 case TAKE: vtake(); break;
61 case DROP: vdrop(); break;
62 case SAY: bug(34); break;
63 case OPEN: vopen(); break;
64 case CLOSE: vclose(); break;
65 case LOCK: vlock(); break;
66 case UNLOCK: vunlock(); break;
67 case ON: von(); break;
68 case OFF: voff(); break;
69 case WAVE: vwave(); break;
70 case KILL: vkill(); break;
71 case POUR: vpour(); break;
72 case EAT: veat(); break;
73 case DRINK: vdrink(); break;
74 case RUB:
75 if (object != LAMP)
76 rspeak(76);
77 else
78 actspk(RUB);
79 break;
80 case THROW:
81 if (prep == PREPDN)
82 vput();
83 else
84 vthrow();
85 break;
86 case FEED: vfeed(); break;
87 case FIND:
88 case INVENTORY: vfind(); break;
89 case FILL: vfill(); break;
90 case BLAST: ivblast(); break;
91 case READ: vread(); break;
92 case BREAK: vbreak(); break;
93 case WAKE: vwake(); break;
94 case REMOVE: vextract(); break;
95 case YANK: vyank(); break;
96 case WEAR: vwear(); break;
97 case HIT: vhit(); break;
98 case ANSWER: vanswer(); break;
99 case BLOW: vblow(); break;
100 case DIAL: vdial(); break;
101 case PLAY: vplay(); break;
102 case PICK: vpick(); break;
103 case PUT: vput(); break;
104 case TURN: vturn(); break;
105 case GET: vget(); break;
106 case INSRT: vinsert(); break;
107 case LOOK: vlook(); break;
108 default:
109 printf("This verb is not implemented yet.\n");
110 }
111 return;
112}
113
114/*
115 Routine to speak default verb message
116*/
117void actspk(verb)
118int verb;
119{
120 int i;
121
122 if (verb < 1 || verb > 55)
123 bug(39);
124 i = actmsg[verb];
125 if (i)
126 rspeak(i);
127 return;
128}
129
130/*
131 CARRY TAKE etc.
132*/
133void vtake()
134{
135 int msg;
136
137 msg = 0;
138 if (object == BIRD && !g.closed && athand(BIRD)
139 && g.place[BIRD] != g.loc) {
140 rspeak(407);
141 return;
142 }
143 if (prep == PREPOF) {
144 if (object && iobj) {
145 rspeak(confuz());
146 return;
147 } else if (!object) {
148 object = iobj;
149 iobj = 0;
150 vdrop();
151 return;
152 }
153 }
154 msg = 24;
155 if (object == BOAT)
156 msg = 281;
157 if (plural(object))
158 msg = 297;
159 if (holding(object)) {
160 rspeak(msg);
161 return;
162 }
163 /* Special case objects and fixed objects */
164 msg = ck_obj();
165 if (g.fixed[object]) {
166 rspeak(msg);
167 return;
168 }
169 if (prep == PREPIN) {
170 vinsert();
171 return;
172 }
173 /* Special case for liquids */
174 if (object == WATER || object == OIL || object == WINE) {
175 if (here(BOTTLE) && here(CASK)) {
176 rspeak(315);
177 return;
178 }
179 iobj = object;
180 if (here(BOTTLE)) {
181 object = BOTTLE;
182 if (holding(BOTTLE))
183 vfill();
184 else
185 rspeak(312);
186 return;
187 } else if (here(CASK)) {
188 object = CASK;
189 if (holding(CASK))
190 vfill();
191 else
192 rspeak(312);
193 return;
194 } else {
195 rspeak(312);
196 return;
197 }
198 }
199 if (object != BEAR && ((burden(0) + burden(object)) > 15)) {
200 if (wearng(object)) {
201 g.prop[object] = 0;
202 bitoff(object, WEARBT);
203 }
204 rspeak(92);
205 return;
206 }
207 if (prep == PREPFR || enclosed(object)) {
208 vextract();
209 return;
210 }
211 msg = 343;
212 /* Poster: hides wall safe */
213 if (object == POSTER && g.place[SAFE] == 0) {
214 g.prop[POSTER] = 1;
215 msg = 362;
216 /* Move safe and wall containing safe into view */
217 drop(SAFE, g.loc);
218 drop(WALL2, g.loc);
219 }
220 /* Boat: need the pole to push it */
221 if (object == BOAT) {
222 if (!toting(POLE) && g.place[POLE] != -BOAT) {
223 rspeak(218);
224 return;
225 } else {
226 g.prop[BOAT] = 1;
227 msg = 221;
228 }
229 }
230 /* Special case for bird. */
231 if (object == BIRD && g.prop[BIRD] <= 0) {
232 if (athand(ROD)) {
233 rspeak(26);
234 return;
235 }
236 if (!holding(CAGE)) {
237 rspeak(27);
238 return;
239 }
240 if (!ajar(CAGE)) {
241 rspeak(358);
242 return;
243 }
244 insert(BIRD, CAGE);
245 bitoff(CAGE, OPENBT);
246 pspeak(object, -1);
247 rspeak(54);
248 return;
249 }
250 /* SWORD If in anvil, need crown & must yank */
251 if (object == SWORD && g.prop[SWORD] != 0) {
252 if (iobj && iobj != ANVIL) {
253 rspeak(noway());
254 return;
255 }
256 if (verb != YANK)
257 if (!yes(215, 0, 54))
258 return;
259
260 if (!wearng(CROWN)) {
261 g.fixed[SWORD] = -1;
262 g.prop[SWORD] = 3;
263 pspeak(SWORD, 2);
264 return;
265 }
266 }
267 carry(object, g.loc);
268 if (object == POLE || object == SKEY || object == SWORD
269 || ((object == CLOAK || object == RING) && !wearng(object)) )
270 g.prop[object] = 0;
271
272 if (verb == YANK || object == SWORD)
273 msg = 204;
274 rspeak(msg);
275 return;
276}
277
278static int ck_obj()
279{
280 int msg;
281
282 msg = noway();
283 if (object == PLANT && g.prop[PLANT] <= 0)
284 msg = 115;
285 if (object == BEAR && g.prop[BEAR] == 1)
286 msg = 169;
287 if (object == CHAIN && g.prop[BEAR] != 0)
288 msg = 170;
289 if (object == SWORD && g.prop[SWORD] == 5)
290 msg = 208;
291 if (object == CLOAK && g.prop[CLOAK] == 2)
292 msg = 242;
293 if (object == AXE && g.prop[AXE] == 2)
294 msg = 246;
295 if (object == PHONE)
296 msg = 251;
297 if (object == BEES || object == HIVE)
298 msg = 295;
299 if (object == STICKS)
300 msg = 296;
301 return (msg);
302}
303
304/*
305 DROP etc.
306*/
307void vdrop()
308{
309 int msg;
310
311 /* Check for dynamite */
312 if (holding(ROD2) && object == ROD && !holding(ROD))
313 object = ROD2;
314 if (plural(object))
315 msg = 105;
316 else
317 msg = 29;
318
319 if (object == liq(BOTTLE))
320 object = BOTTLE;
321 else if (object == liq(CASK))
322 object = CASK;
323
324 if (!toting(object)) {
325 rspeak(msg);
326 return;
327 }
328 if (prep == PREPIN) {
329 vinsert();
330 return;
331 }
332 /* Snake and bird */
333 if (object == BIRD && here(SNAKE)) {
334 rspeak(30);
335 if (g.closed) {
336 dwarfend();
337 return;
338 }
339 extract(BIRD);
340 destroy(SNAKE);
341 /* Set snake prop for use by travel options */
342 g.prop[SNAKE] = 1;
343 drop(BIRD, g.loc);
344 return;
345 }
346 msg = 344;
347 if (verb == LEAVE)
348 msg = 353;
349 if (verb == THROW)
350 msg = 352;
351 if (verb == TAKE)
352 msg = 54;
353 if (object == POLE && holding(BOAT)) {
354 rspeak(280);
355 return;
356 }
357 /* Coins and vending machine */
358 if (object == COINS && here(VEND)) {
359 destroy(COINS);
360 drop(BATTERIES, g.loc);
361 pspeak(BATTERIES, 0);
362 return;
363 }
364 /* Bird and dragon (ouch!!) */
365 if (object == BIRD && at(DRAGON) && g.prop[DRAGON] == 0) {
366 rspeak(154);
367 extract(BIRD);
368 destroy(BIRD);
369 if (g.place[SNAKE] == plac[SNAKE])
370 g.tally2++;
371 return;
372 }
373 /* Bear and troll */
374 if (object == BEAR && at(TROLL)) {
375 msg = 163;
376 destroy(TROLL);
377 destroy(TROLL + MAXOBJ);
378 move(TROLL2, plac[TROLL]);
379 move((TROLL2 + MAXOBJ), fixd[TROLL]);
380 juggle(CHASM);
381 g.prop[TROLL] = 2;
382 }
383 /* Vase */
384 else if (object == VASE) {
385 if (g.loc == plac[PILLOW])
386 msg = 54;
387 else {
388 g.prop[VASE] = at(PILLOW) ? 0 : 2;
389 pspeak(VASE, g.prop[VASE] + 1);
390 if (g.prop[VASE] != 0)
391 g.fixed[VASE] = -1;
392 }
393 } else {
394 if (worn(object) || object == POLE || object == BOAT)
395 g.prop[object] = 0;
396 if (worn(object))
397 bitoff(object, WEARBT);
398 if (object == POLE)
399 g.prop[BOAT] = 0;
400 }
401
402 if (enclosed(object))
403 extract(object);
404 drop(object, g.loc);
405 rspeak(msg);
406 return;
407}
408
409/*
410 OPEN. special stuff for opening clam/oyster.
411 The following can be opened without a key:
412 clam/oyster, door, pdoor, bottle, cask, cage
413*/
414void vopen()
415{
416 int msg, oyclam;
417
418 if (!hinged(object))
419 msg = noway();
420 else if (object == PDOOR && g.prop[PDOOR] == 1)
421 msg = 253;
422 else if (ajar(object))
423 msg = 336;
424 else if (locks(object) || iobj == KEYS || iobj == SKEY) {
425 vunlock();
426 return;
427 } else if (locked(object))
428 if (object == DOOR)
429 msg = 111;
430 else
431 msg = 337;
432 else if (object == CLAM || object == OYSTER) {
433 oyclam = (object == OYSTER ? 1 : 0);
434 msg = oyclam + holding(object) ? 120 : 124;
435 if (!athand(TRIDENT))
436 msg = 122 + oyclam;
437 if (iobj != 0 && iobj != TRIDENT)
438 msg = 376 + oyclam;
439
440 if (msg == 124) {
441 destroy(CLAM);
442 drop(OYSTER, g.loc);
443 drop(PEARL, 105);
444 }
445 } else {
446 msg = 54;
447 biton(object, OPENBT);
448 }
449 rspeak(msg);
450 return;
451}
452
453/*
454 close, shut
455 the following can be closed without keys:
456 door, pdoor, bottle, cask, cage
457*/
458void vclose()
459{
460 if (!hinged(object))
461 rspeak(noway());
462 else if (!ajar(object))
463 rspeak(338);
464 else if (locks(object))
465 vlock();
466 else {
467 rspeak(54);
468 bitoff(object, OPENBT);
469 }
470}
471
472/*
473 Lamp ON.
474*/
475void von()
476{
477 if (!athand(LAMP))
478 actspk(verb);
479 else if (g.limit < 0)
480 rspeak(184);
481 else if (g.prop[LAMP] == 1)
482 rspeak(321);
483 else {
484 g.prop[LAMP] = 1;
485 if (g.loc == 200)
486 rspeak(108);
487 else
488 rspeak(39);
489 if (g.wzdark) {
490 g.wzdark = 0;
491 describe();
492 descitem();
493 }
494 }
495 return;
496}
497
498/*
499 Lamp OFF.
500*/
501void voff()
502{
503 if (!athand(LAMP))
504 actspk(verb);
505 else if (g.prop[LAMP] == 0)
506 rspeak(322);
507 else {
508 g.prop[LAMP] = 0;
509 rspeak(40);
510 if (dark())
511 rspeak(16);
512 }
513 return;
514}
515
516/*
517 WAVE. no effect unless waving rod at fissure.
518*/
519void vwave()
520{
521 if (!holding(object) &&
522 (object != ROD || !holding(ROD2)))
523 rspeak(29);
524 else if (object != ROD || !at(FISSURE) ||
525 !holding(object) || g.closing)
526 actspk(verb);
527 else if (iobj != 0 && iobj != FISSURE)
528 actspk(verb);
529 else {
530 g.prop[FISSURE] = 1 - g.prop[FISSURE];
531 pspeak(FISSURE, 2 - g.prop[FISSURE]);
532 if (g.chase == 0 || g.prop[FISSURE] != 0)
533 return;
534 if ((g.loc == 17 && g.oldloc != 27)
535 || (g.loc == 27 && g.oldloc != 17))
536 return;
537 /* Demise of the Wumpus. Champ must have just crossed bridge */
538 rspeak(244);
539 g.chase = 0;
540 drop(RING, 209);
541 g.prop[WUMPUS] = 6;
542 move(WUMPUS, 209);
543 biton(WUMPUS, DEADBT);
544 if (g.place[AXE] != plac[WUMPUS])
545 return;
546 g.fixed[AXE] = 0;
547 g.prop[AXE] = 0;
548
549 }
550 return;
551}
552
553/*
554 ATTACK, KILL etc.
555*/
556void vkill()
557{
558 int msg, i, k;
559 boolean survival;
560
561 survival = TRUE;
562 switch (object) {
563 case BIRD:
564 if (g.closed)
565 msg = 137;
566 else {
567 destroy(BIRD);
568 g.prop[BIRD] = 0;
569 if (g.place[SNAKE] == plac[SNAKE])
570 g.tally2++;
571 msg = 45;
572 }
573 break;
574 case DWARF:
575 if (g.closed) {
576 dwarfend();
577 return;
578 }
579 survival = do_battle(&msg);
580 break;
581 case 0:
582 msg = 44;
583 break;
584 case CLAM:
585 case OYSTER:
586 msg = 150;
587 break;
588 case DOG:
589 if (g.prop[DOG] == 1)
590 msg = 291;
591 else if (iobj == AXE) {
592 object = AXE;
593 iobj = DOG;
594 vthrow();
595 return;
596 } else
597 msg = 110;
598 break;
599 case SNAKE:
600 msg = 46;
601 break;
602 case TROLL:
603 if (iobj == AXE)
604 msg = 158;
605 else
606 msg = 110;
607 break;
608 case BEAR:
609 msg = 165 + (g.prop[BEAR] + 1) / 2;
610 break;
611 case WUMPUS:
612 if (g.prop[WUMPUS] == 6)
613 msg = 167;
614 else if (iobj == AXE) {
615 object = AXE;
616 iobj = WUMPUS;
617 vthrow();
618 return;
619 } else
620 msg = 110;
621 break;
622 case GNOME:
623 msg = 320;
624 break;
625 case DRAGON:
626 if (g.prop[DRAGON] != 0) {
627 msg = 167;
628 break;
629 }
630 if (!yes(49, 0, 0))
631 break;
632 pspeak(DRAGON, 1);
633 biton(DRAGON, DEADBT);
634 g.prop[DRAGON] = 2;
635 g.prop[RUG] = 0;
636 k = (plac[DRAGON] + fixd[DRAGON]) / 2;
637 move((DRAGON + MAXOBJ), -1);
638 move((RUG + MAXOBJ), 0);
639 move(DRAGON, k);
640 move(RUG, k);
641 for (i = 1; i < MAXOBJ; i++)
642 if (g.place[i] == plac[DRAGON]
643 || g.place[i] == fixd[DRAGON]
644 || holding(i))
645 move(i, k);
646 g.loc = k;
647 g.newloc = k;
648 return;
649 default:
650 actspk(verb);
651 return;
652 }
653 rspeak(msg);
654 if (!survival) {
655 g.oldloc2 = g.loc;
656 death();
657 }
658 return;
659}
660
661static boolean do_battle(msg_ptr)
662int *msg_ptr;
663{
664 boolean survival;
665 int temp;
666
667 survival = TRUE;
668 if (iobj == 0)
669 *msg_ptr = 49;
670 else if (iobj != AXE && iobj != SWORD) {
671 *msg_ptr = 355;
672 survival = FALSE;
673 } else if (pct(25)) {
674 temp = iobj;
675 iobj = object;
676 object = temp;
677 vthrow();
678 return (TRUE);
679 } else if (pct(25)) {
680 *msg_ptr = 355;
681 survival = FALSE;
682 } else if (pct(36))
683 *msg_ptr = 354;
684 else {
685 rspeak(356);
686 if (pct(61))
687 *msg_ptr = 52;
688 else {
689 *msg_ptr = 53;
690 survival = FALSE;
691 }
692 }
693 return (survival);
694}
695
696/*
697 POUR
698*/
699void vpour()
700{
701 int msg;
702
703 if (object == BOTTLE || object == CASK) {
704 iobj = object;
705 object = liq(iobj);
706 if (object == 0) {
707 rspeak(316);
708 return;
709 }
710 } else {
711 if (object < WATER || object > (WINE + 1)) {
712 rspeak(78);
713 return;
714 }
715 }
716 if (!holding(BOTTLE) && !holding(CASK)) {
717 rspeak(29);
718 return;
719 }
720 if (holding(BOTTLE) && liq(BOTTLE) == object)
721 iobj = BOTTLE;
722 if (holding(CASK) && liq(CASK) == object)
723 iobj = CASK;
724 if (iobj == 0) {
725 rspeak(29);
726 return;
727 }
728 if (!ajar(iobj)) {
729 rspeak(335);
730 return;
731 }
732 if (iobj == CASK)
733 object++;
734 g.prop[iobj] = 1;
735 extract(object);
736 g.place[object] = 0;
737 msg = 77;
738 if (iobj == CASK) {
739 object--;
740 msg = 104;
741 }
742 if (at(PLANT) || at(DOOR) || (at(SWORD) && g.prop[SWORD] != 0)) {
743 if (at(DOOR)) {
744 g.prop[DOOR] = 0;
745 if (object == OIL) {
746 g.prop[DOOR] = 1;
747 bitoff(DOOR, LOCKBT);
748 biton(DOOR, OPENBT);
749 }
750 msg = 113 + g.prop[DOOR];
751 } else if (at(SWORD)) {
752 /* If sword is alread oily, don't let him clean it. No
753 soap. */
754 if (g.prop[SWORD] != 5) {
755 g.prop[SWORD] = 4;
756 if (object == OIL) {
757 g.prop[SWORD] = 5;
758 g.fixed[SWORD] = -1;
759 }
760 msg = 206 + g.prop[SWORD] - 4;
761 }
762 } else {
763 msg = 112;
764 if (object == WATER) {
765 if (g.prop[PLANT] < 0)
766 g.prop[PLANT] = -g.prop[PLANT] - 1;
767 pspeak(PLANT, g.prop[PLANT] + 1);
768 g.prop[PLANT] = (g.prop[PLANT] + 2) % 6;
769 g.prop[PLANT2] = g.prop[PLANT] / 2;
770 newtravel = TRUE;
771 return;
772 }
773 }
774 }
775 rspeak(msg);
776 return;
777}
778
779/*
780 EAT
781 If he ate the right thing and is in the right place, move him to
782 the other place with all his junk. Otherwise, narky message.
783*/
784void veat()
785{
786 int msg, i, k, ll, kk;
787
788 switch (object) {
789 case HONEY:
790 g.tally2++;
791 case FOOD:
792 destroy(object);
793 msg = 72;
794 break;
795 case BIRD:
796 case SNAKE:
797 case CLAM:
798 case OYSTER:
799 case FLOWER:
800 msg = 301;
801 break;
802 case DWARF:
803 case DRAGON:
804 case TROLL:
805 case DOG:
806 case WUMPUS:
807 case BEAR:
808 case GNOME:
809 msg = 250;
810 break;
811 case MUSHRM:
812 case CAKES:
813 k = object - MUSHRM;
814 ll = 229 + k;
815 k = 159 - k;
816 kk = SKEY;
817 if (object == MUSHRM) {
818 kk = TDOOR;
819 if (g.loc != 158)
820 g.tally2++;
821 }
822 destroy(object);
823 msg = 228;
824 if (!(here(kk) || g.fixed[kk] == g.loc))
825 break;
826 msg = ll;
827 /* If he hasn't taken tiny key off shelf, don't let him get it
828 for free! */
829 for (i = 1; i < MAXOBJ; i++) {
830 if (i == SKEY && g.prop[SKEY] == 1)
831 continue;
832 if (g.place[i] == plac[kk] && g.fixed[i] == 0)
833 move(i, k);
834 }
835 if (g.loc == plac[SKEY] && g.place[SKEY] == plac[SKEY])
836 g.tally2++;
837 g.loc = k;
838 g.newloc = k;
839 newtravel = TRUE;
840 break;
841 default:
842 actspk(verb);
843 return;
844 }
845 rspeak(msg);
846 return;
847}
848
849/*
850 DRINK
851*/
852void vdrink()
853{
854 int msg, k, j;
855
856 if (object == 0 && (iobj == BOTTLE || iobj == CASK))
857 object = liq(iobj);
858 msg = 110;
859 if (object == OIL)
860 msg = 301;
861 if (object != WATER && object != WINE) {
862 rspeak(msg);
863 return;
864 }
865 if (iobj == 0) {
866 if (object == liqloc(g.loc))
867 iobj = -1;
868 if (athand(CASK) && object == liq(CASK))
869 iobj = CASK;
870 if (athand(BOTTLE) && object == liq(BOTTLE))
871 iobj = BOTTLE;
872 }
873 msg = 73;
874 if (iobj != -1) {
875 if (iobj == CASK)
876 object++;
877 extract(object);
878 g.place[object] = 0;
879 g.prop[iobj] = 1;
880 msg = (iobj == CASK) ? 299 : 74;
881 }
882 if (object == WATER || object == (WATER + 1)) {
883 rspeak(msg);
884 return;
885 }
886 /* UH-OH. He's a wino. Let him reap the rewards of incontinence.
887 He'll wander around for awhile, then wake up somewhere or other,
888 having dropped most of his stuff. */
889 rspeak(300);
890 if (g.prop[LAMP] == 1)
891 g.limit -= ranz(g.limit) / 2;
892 if (g.limit < 10)
893 g.limit = 25;
894 k = 0;
895 if (pct(15))
896 k = 49;
897 if (k == 0 && pct(15))
898 k = 53;
899 if (k == 0 && pct(25))
900 k = 132;
901 if (k == 0)
902 k = 175;
903 if (outside(g.loc))
904 k = 5;
905 if (k == g.loc) {
906 rspeak(msg);
907 return;
908 }
909 if (holding(AXE))
910 move(AXE, k);
911 if (holding(LAMP))
912 move(LAMP, k);
913 for (j = 1; j < MAXOBJ; j++) {
914 if (wearng(j))
915 bitoff(j, WEARBT);
916 if (holding(j))
917 drop(j, g.loc);
918 }
919 g.loc = k;
920 g.newloc = k;
921}
922
923/*
924 THROW etc.
925*/
926void vthrow()
927{
928 int msg, i, k, dwarfn;
929
930 if (holding(ROD2) && object == ROD && !holding(ROD))
931 object = ROD2;
932 if (!holding(object)) {
933 actspk(verb);
934 return;
935 }
936 if (object == BOAT || object == BEAR) {
937 rspeak(noway());
938 return;
939 }
940 dwarfn = dcheck();
941 if (iobj == 0) {
942 /* No indirect object was specified. If a dwarf is present,
943 assume it is the object. If not, look for other living
944 thing. If no living things present, treat 'THROW' as 'DROP'. */
945
946 if (dwarfn)
947 iobj = DWARF;
948 else {
949 /* No dwarves present; figure out pausible object. */
950 k = 0;
951 for (i = 1; i < MAXOBJ; i++) {
952 if (at(i) && living(i)) {
953 iobj = i;
954 k++;
955 }
956 }
957 if (k == 0) {
958 vdrop();
959 return;
960 }
961 /* It is a beastie of some sort. Is there more than one?
962 Don't kill the bird by default. */
963 if (k > 1) {
964 rspeak(43);
965 return;
966 } else {
967 if (iobj == BIRD) {
968 vdrop();
969 return;
970 }
971 if (treasr(object) && at(TROLL))
972 iobj = TROLL;
973 }
974 }
975 }
976 if (object == SWORD || object == BOTTLE) {
977 vbreak();
978 return;
979 }
980 if (object == FLOWER && iobj == HIVE)
981 iobj = BEES;
982 if (edible(object) && living(iobj)) {
983 vfeed();
984 return;
985 }
986 /* If not axe, same as drop... */
987 if (object != AXE && iobj != TROLL) {
988 vdrop();
989 return;
990 }
991 /* AXE is THROWN */
992 msg = 48;
993 switch (iobj) {
994 case DRAGON:
995 if (g.prop[DRAGON] == 0)
996 msg = 152;
997 break;
998 case DWARF:
999 /* At a dwarf... */
1000 if (pct(75)) {
1001 g.dseen[dwarfn] = g.dloc[dwarfn] = 0;
1002 msg = 47;
1003 ++g.dkill;
1004 if (g.dkill == 1)
1005 msg = 149;
1006 }
1007 break;
1008 case BEAR:
1009 /* This'll teach him to throw axe at the bear */
1010 if (g.prop[BEAR] == 0) {
1011 msg = 164;
1012 drop(AXE, g.loc);
1013 g.fixed[AXE] = -1;
1014 g.prop[AXE] = 1;
1015 juggle(BEAR);
1016 }
1017 rspeak(msg);
1018 return;
1019 case WUMPUS:
1020 /* Or the WUMPUS! */
1021 if (g.prop[WUMPUS] == 6) {
1022 vdrop();
1023 return;
1024 } else {
1025 msg = 245;
1026 g.prop[AXE] = 2;
1027 if (g.prop[WUMPUS] == 0) {
1028 drop(AXE, g.loc);
1029 g.fixed[AXE] = -1;
1030 juggle(iobj);
1031 } else {
1032 msg = 243;
1033 destroy(AXE);
1034 }
1035 }
1036 rspeak(msg);
1037 return;
1038 case DOG:
1039 /* Or the nice doggie! */
1040 if (g.prop[DOG] != 1) {
1041 msg = 248;
1042 g.prop[AXE] = 3;
1043 drop(AXE, g.loc);
1044 g.fixed[AXE] = -1;
1045 juggle(iobj);
1046 }
1047 rspeak(msg);
1048 return;
1049 case TROLL:
1050 /* Snarf a treasure for the troll */
1051 if (object == AXE) {
1052 msg = 158;
1053 } else if (!treasr(object) ||
1054 (object == CASK && (liq(CASK) != WINE))) {
1055 vdrop();
1056 return;
1057 } else {
1058 msg = 159;
1059 drop(object, 0);
1060 if (object == CASK)
1061 g.place[WINE + 1] = 0;
1062 move(TROLL, 0);
1063 move((TROLL + MAXOBJ), 0);
1064 drop(TROLL2, plac[TROLL]);
1065 drop((TROLL2 + MAXOBJ), fixd[TROLL]);
1066 juggle(CHASM);
1067 rspeak(msg);
1068 return;
1069 }
1070 break;
1071
1072 default:
1073 /* Otherwise it is an attack */
1074 verb = KILL;
1075 object = iobj;
1076 iobj = objs[objx];
1077 vkill();
1078 return;
1079 }
1080
1081 rspeak(msg);
1082 drop(AXE, g.loc);
1083 g.newloc = g.loc;
1084 describe();
1085}
1086
1087/*
1088 FIND might be carrying it, or it might be here. else give caveat.
1089*/
1090void vfind()
1091{
1092 int msg;
1093
1094 if (at(object) ||
1095 (liq(BOTTLE) == object && at(BOTTLE)) ||
1096 object == liqloc(g.loc))
1097 msg = 94;
1098 else if (dcheck() && g.dflag >= 2 && object == DWARF)
1099 msg = 94;
1100 else if (g.closed)
1101 msg = 138;
1102 else if (at(object))
1103 msg = 24;
1104 else {
1105 actspk(verb);
1106 return;
1107 }
1108 rspeak(msg);
1109 return;
1110}
1111
1112/*
1113 FEED
1114*/
1115void vfeed()
1116{
1117 int msg;
1118
1119 if (iobj == 0 || !living(iobj)) {
1120 int i, k, kk;
1121
1122 if (object == BIRD) {
1123 rspeak(100);
1124 return;
1125 }
1126 if (!living(object)) {
1127 rspeak(noway());
1128 return;
1129 }
1130 /* See if there is anything edible around here. */
1131
1132 kk = 0;
1133 k = 0;
1134 for (i = 1; i < MAXOBJ; i++)
1135 if (here(i) && edible(i)) {
1136 k++;
1137 kk = i;
1138 }
1139 iobj = object;
1140 object = kk;
1141 if (k != 1 && !dead(iobj)) {
1142 printf("What do you want to feed the %s\n", otxt[objx]);
1143 objs[1] = 0;
1144 objx = 0;
1145 return;
1146 }
1147 }
1148 /* Feed object ot indirect object */
1149 msg = 102;
1150 switch (iobj) {
1151 case DRAGON:
1152 if (g.prop[DRAGON] != 0)
1153 msg = noway();
1154 break;
1155 case TROLL:
1156 msg = 182;
1157 break;
1158 case SNAKE:
1159 if (object == BIRD && !g.closed) {
1160 msg = 101;
1161 destroy(BIRD);
1162 g.prop[BIRD] = 0;
1163 g.tally2++;
1164 }
1165 break;
1166 case DWARF:
1167 msg = 103;
1168 g.dflag++;
1169 break;
1170 case BEAR:
1171 if (g.prop[BEAR] == 3)
1172 msg = noway();
1173 if (g.prop[BEAR] == 1 || g.prop[BEAR] == 2)
1174 msg = 264;
1175 if (object == FOOD)
1176 msg = 278;
1177 if (object == HONEY) {
1178 g.prop[BEAR] = 1;
1179 g.fixed[AXE] = 0;
1180 destroy(HONEY);
1181 msg = 168;
1182 }
1183 break;
1184 case DOG:
1185 msg = 291;
1186 if (object == FOOD && g.prop[DOG] != 1) {
1187 msg = 249;
1188 destroy(FOOD);
1189 }
1190 break;
1191 case WUMPUS:
1192 if (g.prop[WUMPUS] == 6)
1193 msg = 326;
1194 if (g.prop[WUMPUS] == 0)
1195 msg = 327;
1196 if (object == FOOD)
1197 msg = 240;
1198 break;
1199 case BEES:
1200 if (object == FLOWER) {
1201 if (enclosed(FLOWER))
1202 extract(FLOWER);
1203 drop(FLOWER, g.loc);
1204 g.fixed[FLOWER] = -1;
1205 g.prop[FLOWER] = 1;
1206 drop(HONEY, g.loc);
1207 juggle(HONEY);
1208 msg = 267;
1209 g.prop[HIVE] = 1;
1210 }
1211 }
1212 rspeak(msg);
1213 return;
1214}
1215
1216/*
1217 FILL. object with iobj
1218*/
1219void vfill()
1220{
1221 int msg, k;
1222
1223 if (!vessel(object))
1224 msg = 313;
1225 else {
1226 if (iobj == 0)
1227 iobj = liqloc(g.loc);
1228 if (object == BOTTLE || object == CASK) {
1229 k = (object == CASK) ? 1 : 0;
1230 msg = 0;
1231 if (iobj == 0)
1232 msg = 304 + k;
1233 if (liq(object) != 0)
1234 msg = 302 + k;
1235 if (msg != 0) {
1236 rspeak(msg);
1237 return;
1238 }
1239 msg = 306 + k;
1240 if (iobj == OIL)
1241 msg = 308 + k;
1242 if (iobj == WINE)
1243 msg = 310 + k;
1244 g.prop[object] = (int) g.loc_attrib[g.loc] & 14;
1245 g.place[iobj + k] = -1;
1246 insert(iobj + k, object);
1247 } else if (object == VASE) {
1248 if (iobj == 0 || !holding(VASE)) {
1249 rspeak(144);
1250 return;
1251 }
1252 msg = 145;
1253 g.prop[VASE] = 2;
1254 g.fixed[VASE] = -1;
1255 if (enclosed(object))
1256 extract(object);
1257 drop(object, g.loc);
1258 } else if (object == GRAIL)
1259 msg = 298;
1260 else
1261 msg = 339;
1262 }
1263 rspeak(msg);
1264}
1265
1266/*
1267 READ. Magazine in dwarvish, message we've seen, and ... oyster?
1268*/
1269void vread()
1270{
1271 int msg;
1272
1273 if (blind()) {
1274 actspk(verb);
1275 return;
1276 }
1277 if (object && iobj) {
1278 rspeak(confuz());
1279 return;
1280 }
1281 msg = confuz();
1282 if (!object)
1283 object = iobj;
1284 switch (object) {
1285 case BOOK:
1286 case BOOK2:
1287 msg = 142;
1288 break;
1289 case BILLBD:
1290 msg = 361;
1291 break;
1292 case CARVNG:
1293 msg = 372;
1294 break;
1295 case MAGAZINE:
1296 msg = 190;
1297 break;
1298 case MESSAGE:
1299 msg = 191;
1300 break;
1301 case POSTER:
1302 msg = 370;
1303 break;
1304 case TABLET:
1305 msg = 196;
1306 break;
1307 case OYSTER:
1308 if (g.hinted[2] && holding(OYSTER))
1309 msg = 194;
1310 if (!g.hinted[2] && holding(OYSTER) && g.closed) {
1311 g.hinted[2] = yes(192, 193, 54);
1312 return;
1313 }
1314 break;
1315 }
1316 rspeak(msg);
1317 return;
1318}
1319
1320/*
1321 BREAK. works for mirror in repository and, of course the
1322 vase and bottle. Also the sword is more brittle than it appears.
1323*/
1324void vbreak()
1325{
1326 int msg, k;
1327 boolean it_broke;
1328
1329 it_broke = FALSE;
1330 msg = 146;
1331 switch (object) {
1332 case MIRROR:
1333 msg = 148;
1334 if (g.closed) {
1335 rspeak(197);
1336 dwarfend();
1337 return;
1338 }
1339 break;
1340 case VASE:
1341 if (g.prop[VASE] == 0) {
1342 it_broke = TRUE;
1343 msg = 198;
1344 g.prop[VASE] = 2;
1345 }
1346 break;
1347 case BOTTLE:
1348 if (g.prop[BOTTLE] != 3) {
1349 it_broke = TRUE;
1350 k = liq(BOTTLE);
1351 msg = 231;
1352 g.prop[BOTTLE] = 3;
1353 if (k) {
1354 extract(k);
1355 g.place[k] = 0;
1356 }
1357 }
1358 break;
1359 case SWORD:
1360 msg = 29;
1361 if (holding(SWORD)) {
1362 msg = 279;
1363 g.prop[SWORD] = 4;
1364 it_broke = TRUE;
1365 }
1366 break;
1367 }
1368 if (it_broke) {
1369 if (enclosed(object))
1370 extract(object);
1371 if (holding(object))
1372 drop(object, g.loc);
1373 g.fixed[object] = -1;
1374 }
1375 rspeak(msg);
1376 return;
1377}
1378
1379/*
1380 WAKE. only use is to disturb the dwarves or the Wumpus.
1381 Other wumpus-wakers link here.
1382*/
1383void vwake()
1384{
1385 int msg;
1386
1387 msg = actmsg[verb];
1388 if (at(WUMPUS)) {
1389 g.chase = TRUE;
1390 g.prop[WUMPUS] = 1;
1391 msg = 276;
1392 }
1393 if (at(DOG) && g.prop[DOG] == 1)
1394 msg = 291;
1395 if (object == DWARF && g.closed) {
1396 rspeak(199);
1397 dwarfend();
1398 return;
1399 }
1400 rspeak(msg);
1401 return;
1402}
1403
1404/*
1405 YANK. A variant of 'CARRY'. In general, not a good idea.
1406 At most, it gets the cloak or a couple of snide comments.
1407 */
1408void vyank()
1409{
1410 if (toting(object))
1411 vdrop();
1412 else if (object == BEAR && g.prop[CHAIN])
1413 rspeak(205);
1414 else if (object == CLOAK && g.prop[CLOAK] == 2) {
1415 /* Cloak. big trouble ahead. */
1416 g.prop[ROCKS] = 1;
1417 g.prop[CLOAK] = 0;
1418 g.fixed[CLOAK] = 0;
1419 carry(CLOAK, g.loc);
1420 rspeak(241);
1421 if (at(WUMPUS) && g.prop[WUMPUS] == 0) {
1422 g.chase = 1;
1423 g.prop[WUMPUS] = 1;
1424 rspeak(276);
1425 }
1426 } else
1427 vtake();
1428 return;
1429}
1430
1431/*
1432 WEAR. Only good for jewels, ruby slippers, cloak & crown.
1433 But he might try the sword. Anything else is ridiculous.
1434 Another variant of 'CARRY'.
1435 */
1436void vwear()
1437{
1438 int msg;
1439
1440 if (object == SWORD && g.prop[SWORD] != 3)
1441 msg = 209;
1442 else if (worn(object)) {
1443 if (object == CLOAK && g.prop[CLOAK] == 2)
1444 msg = 242;
1445 else if (wearng(object))
1446 msg = (object == SHOES) ? 227 : 210;
1447 else {
1448 g.prop[object] = 1;
1449 biton(object, WEARBT);
1450 if (enclosed(object))
1451 extract(object);
1452 if (holding(object))
1453 msg = 54;
1454 else {
1455 vtake();
1456 return;
1457 }
1458 }
1459 } else {
1460 printf("Just exactly how does one wear a %s\n", otxt[objx]);
1461 return;
1462 }
1463 rspeak(msg);
1464 return;
1465}
1466
1467/*
1468 HIT. If not punching out telephone, assume attack.
1469 */
1470void vhit()
1471{
1472 if (at(WUMPUS) && g.prop[WUMPUS] == 0) {
1473 vwake();
1474 return;
1475 }
1476 if (object != PHONE) {
1477 vkill();
1478 return;
1479 } else {
1480 if (g.closed) {
1481 rspeak(282);
1482 dwarfend();
1483 return;
1484 }
1485 if (g.prop[PHONE] == 2)
1486 rspeak(256);
1487 else {
1488 drop(SLUGS, g.loc);
1489 g.prop[PHONE] = 2;
1490 g.prop[BOOTH] = 2;
1491 rspeak(257);
1492 }
1493 }
1494 return;
1495}
1496
1497/*
1498 ANSWER (telephone). Smartass for anything else.
1499 */
1500void vanswer()
1501{
1502 int msg;
1503
1504 switch (object) {
1505 case DWARF:
1506 case WUMPUS:
1507 case SNAKE:
1508 case BEAR:
1509 case DRAGON:
1510 msg = 259;
1511 break;
1512 case TROLL:
1513 msg = 258;
1514 break;
1515 case BIRD:
1516 msg = 260;
1517 break;
1518 case PHONE:
1519 if (g.prop[PHONE] != 0)
1520 msg = 269;
1521 else if (g.closed) {
1522 rspeak(283);
1523 normend();
1524 return;
1525 } else {
1526 msg = 261;
1527 g.prop[PHONE] = 1;
1528 g.prop[BOOTH] = 2;
1529 }
1530 break;
1531 default:
1532 msg = actmsg[verb];
1533 break;
1534 }
1535 rspeak(msg);
1536 return;
1537}
1538
1539/*
1540 BLOW. Joshua fit de battle of Jericho, and de walls ...
1541 */
1542void vblow()
1543{
1544 int msg, i, k;
1545
1546 msg = actmsg[verb];
1547 if (object != 0 && iobj != 0) {
1548 rspeak(msg);
1549 return;
1550 }
1551 if (object == 0)
1552 object = iobj;
1553 iobj = 0;
1554 if (object == 0)
1555 msg = 268;
1556 if (object == HORN) {
1557 msg = outside(g.loc) ? 277 : 266;
1558 if (at(WUMPUS)) {
1559 rspeak(msg);
1560 if (g.prop[WUMPUS] == 0)
1561 vwake();
1562 return;
1563 } else if (g.prop[WALL] != 1 && (g.loc == 102 || g.loc == 194)) {
1564 k = g.loc == 194 ? 195 : 196;
1565 msg = 265;
1566 g.prop[WALL] = 1;
1567 for (i = 1; i < MAXOBJ; i++)
1568 if (g.place[i] == g.loc || g.fixed[i] == g.loc)
1569 move(i, k);
1570 g.newloc = k;
1571 }
1572 }
1573 rspeak(msg);
1574 return;
1575}
1576
1577/*
1578 DIAL. No effect unless at phone.
1579 */
1580void vdial()
1581{
1582 if (object != PHONE)
1583 actspk(verb);
1584 else if (g.closed) {
1585 rspeak(283);
1586 normend();
1587 } else
1588 rspeak(271);
1589 return;
1590}
1591
1592/*
1593 PLAY. Only for horn or lyre.
1594 */
1595void vplay()
1596{
1597 int msg;
1598
1599 msg = actmsg[verb];
1600 if (object != 0 && iobj != 0) {
1601 rspeak(confuz());
1602 return;
1603 }
1604 if (object == 0)
1605 object = iobj;
1606 if (object == HORN) {
1607 vblow();
1608 return;
1609 }
1610 if (object == LYRE) {
1611 msg = 287;
1612 if (here(DOG) && !dead(DOG)) {
1613 g.prop[DOG] = 1;
1614 biton(DOG, DEADBT);
1615 g.fixed[AXE] = 0;
1616 g.prop[AXE] = 0;
1617 msg = 288;
1618 }
1619 }
1620 rspeak(msg);
1621 return;
1622}
1623
1624/*
1625 PICK/ PICK UP. Can pick flower & mushrooms,
1626 But must 'PICK UP' everything else.
1627 */
1628void vpick()
1629{
1630 if (object == 0)
1631 object = iobj;
1632 iobj = 0;
1633 if (object == FLOWER || object == MUSHRM || prep != 0)
1634 vtake();
1635 else
1636 rspeak(confuz());
1637 return;
1638}
1639
1640/*
1641 PUT DOWN: equivalent to drop
1642 PUT IN: if liquid, means fill
1643 PUT ON: wear of drop
1644 */
1645void vput()
1646{
1647 if (prep == 0) {
1648 printf("Where do you want to put the %s\n", otxt[objx]);
1649 return;
1650 }
1651 if (prep == PREPIN)
1652 vinsert();
1653 else {
1654 /* PUT ON: wear or put object on iobj */
1655 if (prep == PREPON) {
1656 if (object == 0) {
1657 object = iobj;
1658 otxt[objx] = iotxt[iobx];
1659 iobj = 0;
1660 }
1661 if (worn(object) || object == 0)
1662 vwear();
1663 else
1664 vdrop();
1665 } else {
1666 /* PUT DOWN: "drop" */
1667 if (object == 0 && iobj == 0) {
1668 if (object == 0)
1669 object = iobj;
1670 iobj = 0;
1671 vdrop();
1672 } else
1673 rspeak(noway());
1674 }
1675 }
1676 return;
1677}
1678
1679/* turn on/off */
1680void vturn()
1681{
1682 if (!prep)
1683 rspeak(confuz());
1684 else {
1685 if (!object && iobj == LAMP)
1686 object = LAMP;
1687 if (object != LAMP)
1688 rspeak(noway());
1689 else if (prep == PREPON)
1690 von();
1691 else
1692 voff();
1693 }
1694 return;
1695}
1696
1697/*
1698 GET (no prep): "take"
1699 GET IN: "enter"
1700 GET OUT: "leave"
1701 */
1702void vget()
1703{
1704 if (prep == 0 || prep == PREPFR)
1705 vtake();
1706 else if (object == 0) {
1707 object = iobj;
1708 iobj = 0;
1709 prep = 0;
1710 vtake();
1711 }
1712 return;
1713}
1714
1715/*
1716 INSERT/PUT IN
1717 */
1718void vinsert()
1719{
1720 int msg;
1721
1722 if (iobj == 0) {
1723 printf("Where do you want to %s it?\n", vtxt[vrbx]);
1724 return;
1725 }
1726 msg = noway();
1727 if (object == SWORD && iobj == ANVIL && g.prop[SWORD] == 0)
1728 msg = 350;
1729 if (!vessel(iobj)) {
1730 rspeak(msg);
1731 return;
1732 }
1733 msg = ck_obj();
1734 if (g.fixed[object]) {
1735 rspeak(msg);
1736 return;
1737 }
1738 if (object == iobj) {
1739 rspeak(252);
1740 return;
1741 }
1742 if (iobj == BOTTLE || iobj == CASK || iobj == VASE
1743 || iobj == GRAIL || (object >= WATER && object <= WINE + 1)) {
1744 object = iobj;
1745 iobj = objs[objx];
1746 vfill();
1747 return;
1748 }
1749 if (!ajar(iobj)) {
1750 rspeak(358);
1751 return;
1752 }
1753 if (iobj == CHEST) {
1754 if (object == BOAT)
1755 msg = noway();
1756 else {
1757 if (wearng(object))
1758 bitoff(object, WEARBT);
1759 if (worn(object))
1760 g.prop[object] = 0;
1761 if (enclosed(object))
1762 extract(object);
1763 insert(object, iobj);
1764 msg = 54;
1765 }
1766 rspeak(msg);
1767 return;
1768 }
1769 /* Bird goes into cage and only cage */
1770 if (object == BIRD && iobj != CAGE) {
1771 rspeak(351);
1772 return;
1773 }
1774 if (object != BIRD && iobj == CAGE) {
1775 rspeak(329);
1776 return;
1777 }
1778 if (object == BIRD) {
1779 prep = 0;
1780 vtake();
1781 return;
1782 }
1783 /* Bar vase & pillow from safe, to force putting down on florr */
1784 if ((object == VASE || object == PILLOW) && iobj == SAFE) {
1785 rspeak(329);
1786 return;
1787 }
1788 if (object != RADIUM && iobj == SHIELD) {
1789 rspeak(329);
1790 return;
1791 }
1792 if (iobj == PHONE) {
1793 if (object == COINS || object == SLUGS) {
1794 destroy(object);
1795 msg = 330;
1796 } else
1797 msg = 329;
1798 rspeak(msg);
1799 return;
1800 }
1801 if (iobj == VEND) {
1802 if (object == COINS || object == SLUGS) {
1803 destroy(object);
1804 move(BATTERIES, g.loc);
1805 if (g.prop[BATTERIES] == 1) {
1806 rspeak(317);
1807 g.prop[VEND] = 1;
1808 }
1809 g.prop[BATTERIES] = 0;
1810 pspeak(BATTERIES, 0);
1811 } else
1812 rspeak(noway());
1813 return;
1814 }
1815 /* Put batteries in lamp. There is a glitch here, in that if he
1816 tries to get a third set of batteries before the second set has
1817 been inserted, the second set disappears!
1818 ***fix this some time ***
1819 */
1820 if (iobj == LAMP) {
1821 if (object != BATTERIES || g.prop[BATTERIES] != 0)
1822 msg = noway();
1823 else {
1824 g.prop[BATTERIES] = 1;
1825 if (enclosed(BATTERIES))
1826 extract(BATTERIES);
1827 if (holding(BATTERIES))
1828 drop(BATTERIES, g.loc);
1829 g.limit = 400;
1830 g.prop[LAMP] = 1;
1831 g.lmwarn = FALSE;
1832 msg = 188;
1833 }
1834 rspeak(msg);
1835 return;
1836 }
1837 if (!small(object))
1838 msg = 329;
1839 else {
1840 if (wearng(object))
1841 bitoff(object, WEARBT);
1842 if (worn(object))
1843 g.prop[object] = 0;
1844 if (enclosed(object))
1845 extract(object);
1846 insert(object, iobj);
1847 msg = 54;
1848 }
1849 rspeak(msg);
1850 return;
1851
1852}
1853
1854/* Remove or take from */
1855void vextract()
1856{
1857 int msg;
1858
1859 if (object == RING && g.prop[RING] == 2) {
1860 prep = 0;
1861 iobj = 0;
1862 vtake();
1863 return;
1864 }
1865 msg = 343;
1866 if (iobj == 0) {
1867 if (!enclosed(object))
1868 msg = 340;
1869 iobj = -g.place[object];
1870 }
1871 if (g.place[object] != -iobj)
1872 msg = 341;
1873 if (!ajar(iobj))
1874 msg = 335;
1875 if (object == WATER || object == OIL || object == WINE)
1876 msg = 342;
1877 if (!toting(object) && ((burden(0) + burden(object)) > 15))
1878 msg = 92;
1879 if (msg == 343) {
1880 if (object == BIRD) {
1881 vdrop();
1882 return;
1883 }
1884 extract(object);
1885 }
1886 rspeak(msg);
1887 return;
1888}
1889
1890/*
1891 lock. chain, grate, chest, elfin door
1892 Here are the current lock/unlock messages & numbers:
1893 31 you have no keys.
1894 32 it has no lock.
1895 34 it's already locked.
1896 35 the grate is now locked.
1897 36 the grate is now unlocked.
1898 37 it was allready unlocked.
1899 55 you can't unlock the keys.
1900 171 The chain is now unlocked.
1901 172 The chain is now locked.
1902 173 There is nothing here to which the chain can be locked.
1903 224 Your keys are all too large.
1904 234 The wrought-iron door is now locked.
1905 235 The tiny door is now locked.
1906 236 The wrought-iron door is now unlocked.
1907 237 The tiny door is now unlocked.
1908 375 You don't have the right key.
1909 333 the chest is now locked.
1910 334 the chest is now unlocked.
1911 367 The safe's door swings shut.
1912*/
1913void vlock()
1914{
1915 int msg, k;
1916
1917 if (!hinged(object))
1918 {
1919 printf("I don't know how to lock or unlock the %s\n",
1920 otxt[objx]);
1921 return;
1922 }
1923 else if (!locks(object))
1924 msg = 32;
1925 else if (locked(object))
1926 msg = 34;
1927 else if (!athand(KEYS) && !athand(SKEY) && object != SAFE)
1928 msg = 31;
1929 else {
1930 msg = 375;
1931 switch (object) {
1932 case CHAIN:
1933 if (!athand(KEYS))
1934 break;
1935 msg = 173;
1936 if (g.loc != plac[CHAIN])
1937 break;
1938 msg = 172;
1939 g.prop[CHAIN] = 2;
1940 if (enclosed(CHAIN))
1941 extract(CHAIN);
1942 if (holding(CHAIN))
1943 drop(CHAIN, g.loc);
1944 g.fixed[CHAIN] = -1;
1945 biton(CHAIN, LOCKBT);
1946 bitoff(CHAIN, OPENBT);
1947 break;
1948
1949 case CHEST:
1950 if (!athand(KEYS))
1951 break;
1952 msg = 334;
1953 biton(CHEST, LOCKBT);
1954 bitoff(CHEST, OPENBT);
1955 break;
1956
1957 case TDOOR:
1958 case TDOOR2:
1959 msg = 224;
1960 if (!toting(SKEY))
1961 break;
1962 g.prop[TDOOR] = 0;
1963 g.prop[TDOOR2] = 0;
1964 msg = 234 + (TDOOR2 - object);
1965 k = TDOOR + TDOOR2 - object;
1966 biton(k, LOCKBT);
1967 bitoff(k, OPENBT);
1968 biton(object, LOCKBT);
1969 bitoff(object, OPENBT);
1970 break;
1971
1972 case GRATE:
1973 if (!athand(KEYS))
1974 break;
1975 g.prop[GRATE] = 0;
1976 msg = 35;
1977 biton(GRATE, LOCKBT);
1978 bitoff(GRATE, OPENBT);
1979 break;
1980
1981 case SAFE:
1982 g.prop[SAFE] = 0;
1983 msg = 367;
1984 biton(SAFE, LOCKBT);
1985 bitoff(SAFE, OPENBT);
1986 break;
1987
1988 }
1989 }
1990 rspeak(msg);
1991}
1992
1993/*
1994 UNLOCK. chain, grate, chest, elfin door.
1995*/
1996void vunlock()
1997{
1998 int msg, k;
1999
2000 if (object == KEYS || object == SKEY)
2001 msg = 55;
2002 else if (!hinged(object))
2003 {
2004 printf("I don't know how to lock or unlock the %s\n",
2005 otxt[objx]);
2006 return;
2007 }
2008 else if (!locked(object))
2009 msg = 37;
2010 else if (!locks(object))
2011 msg = 32;
2012 else if (object == SAFE) {
2013 if (iobj == KEYS || iobj == SKEY)
2014 msg = 368;
2015 else
2016 msg = 342;
2017 } else if (!athand(KEYS) && !athand(SKEY))
2018 msg = 31;
2019 else {
2020 msg = 375;
2021 switch (object) {
2022 case CHAIN:
2023 if (!athand(KEYS))
2024 break;
2025 if (g.prop[BEAR] == 0)
2026 msg = 41;
2027 else {
2028 msg = 171;
2029 g.prop[CHAIN] = 0;
2030 g.fixed[CHAIN] = 0;
2031 if (g.prop[BEAR] != 3)
2032 g.prop[BEAR] = 2;
2033 g.fixed[BEAR] = 2 - g.prop[BEAR];
2034 bitoff(CHAIN, LOCKBT);
2035 biton(CHAIN, OPENBT);
2036 }
2037 break;
2038 case CHEST:
2039 if (athand(KEYS)) {
2040 msg = 333;
2041 bitoff(CHEST, LOCKBT);
2042 biton(CHEST, OPENBT);
2043 }
2044 break;
2045 case TDOOR:
2046 case TDOOR2:
2047 /* Elvin door stuff to lock/unlock tiny door w/special key.
2048 the damn thing is really at four places, and we want the
2049 right messages if he only has 'BIG'keys (or no keys).
2050 Also, he can unlock it either while he is big or small. */
2051 msg = 224;
2052 if (!athand(SKEY))
2053 break;
2054 if (g.closing) {
2055 msg = 130;
2056 if (!g.panic)
2057 g.clock2 = 15;
2058 g.panic = TRUE;
2059 } else {
2060 g.prop[TDOOR] = 1;
2061 g.prop[TDOOR2] = 1;
2062 msg = 234 + 2 + (TDOOR2 - object);
2063 k = TDOOR + (TDOOR2 - object);
2064 bitoff(k, LOCKBT);
2065 biton(k, OPENBT);
2066 bitoff(object, LOCKBT);
2067 biton(object, OPENBT);
2068 }
2069 break;
2070 case GRATE:
2071 if (!athand(KEYS))
2072 break;
2073 if (g.closing) {
2074 msg = 130;
2075 if (!g.panic)
2076 g.clock2 = 15;
2077 g.panic = TRUE;
2078 } else {
2079 g.prop[GRATE] = 1;
2080 msg = 36;
2081 bitoff(GRATE, LOCKBT);
2082 biton(GRATE, OPENBT);
2083 }
2084 break;
2085 default:
2086 msg = 33;
2087 }
2088 }
2089 rspeak(msg);
2090}
2091
2092/*
2093 LOOK.
2094*/
2095void vlook()
2096{
2097 int sloc;
2098
2099 if (object != 0) {
2100 rspeak(confuz());
2101 return;
2102 }
2103 /* Look into something (a container). */
2104 if (vessel(iobj)) {
2105 if (!ajar(iobj) && opaque(iobj))
2106 rspeak(actmsg[verb]);
2107 else if (g.holder[iobj] == 0)
2108 rspeak(359);
2109 else {
2110 putchar(' ');
2111 lookin(iobj);
2112 }
2113
2114 /* Look at something. If written, read it. */
2115 } else if (printed(iobj)) {
2116 object = iobj;
2117 iobj = 0;
2118 vread();
2119 } else if (iobj == SPHERE) {
2120 if (!inside(g.loc) || athand(SAPPHIRE))
2121 rspeak(42);
2122 else {
2123 rspeak(400);
2124 printf(" ");
2125 sloc = g.place[SAPPHIRE];
2126 if ((g.loc_attrib[sloc] % 2 == 0 || enclosed(SAPPHIRE))
2127 && sloc != 200
2128 && !g.place[LAMP] == sloc && g.prop[LAMP] != 0)
2129 rspeak(401);
2130 else
2131 desclg(sloc);
2132 if (sloc == 239 && !g.flg239) {
2133 rspeak(403);
2134 g.flg239 = TRUE;
2135 }
2136 printf(" ");
2137 rspeak(402);
2138 }
2139 } else
2140 printf("I see nothing special about the %s?\n", iotxt[iobx]);
2141 return;
2142}
Note: See TracBrowser for help on using the repository browser.