]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - rogue/inventory.c
sprinkle static
[bsdgames-darwin.git] / rogue / inventory.c
1 /* $NetBSD: inventory.c,v 1.13 2008/01/14 03:50:01 dholland Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Timothy C. Stoehr.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/cdefs.h>
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)inventory.c 8.1 (Berkeley) 5/31/93";
39 #else
40 __RCSID("$NetBSD: inventory.c,v 1.13 2008/01/14 03:50:01 dholland Exp $");
41 #endif
42 #endif /* not lint */
43
44 /*
45 * inventory.c
46 *
47 * This source herein may be modified and/or distributed by anybody who
48 * so desires, with the following restrictions:
49 * 1.) No portion of this notice shall be removed.
50 * 2.) Credit shall not be taken for the creation of this source.
51 * 3.) This code is not to be traded, sold, or used for personal
52 * gain or profit.
53 *
54 */
55
56 #include <stdarg.h>
57 #include "rogue.h"
58
59 boolean is_wood[WANDS];
60 const char *press_space = " --press space to continue--";
61
62 static const char *const wand_materials[WAND_MATERIALS] = {
63 "steel ",
64 "bronze ",
65 "gold ",
66 "silver ",
67 "copper ",
68 "nickel ",
69 "cobalt ",
70 "tin ",
71 "iron ",
72 "magnesium ",
73 "chrome ",
74 "carbon ",
75 "platinum ",
76 "silicon ",
77 "titanium ",
78
79 "teak ",
80 "oak ",
81 "cherry ",
82 "birch ",
83 "pine ",
84 "cedar ",
85 "redwood ",
86 "balsa ",
87 "ivory ",
88 "walnut ",
89 "maple ",
90 "mahogany ",
91 "elm ",
92 "palm ",
93 "wooden "
94 };
95
96 static const char *const gems[GEMS] = {
97 "diamond ",
98 "stibotantalite ",
99 "lapi-lazuli ",
100 "ruby ",
101 "emerald ",
102 "sapphire ",
103 "amethyst ",
104 "quartz ",
105 "tiger-eye ",
106 "opal ",
107 "agate ",
108 "turquoise ",
109 "pearl ",
110 "garnet "
111 };
112
113 static const char *const syllables[MAXSYLLABLES] = {
114 "blech ",
115 "foo ",
116 "barf ",
117 "rech ",
118 "bar ",
119 "blech ",
120 "quo ",
121 "bloto ",
122 "oh ",
123 "caca ",
124 "blorp ",
125 "erp ",
126 "festr ",
127 "rot ",
128 "slie ",
129 "snorf ",
130 "iky ",
131 "yuky ",
132 "ooze ",
133 "ah ",
134 "bahl ",
135 "zep ",
136 "druhl ",
137 "flem ",
138 "behil ",
139 "arek ",
140 "mep ",
141 "zihr ",
142 "grit ",
143 "kona ",
144 "kini ",
145 "ichi ",
146 "tims ",
147 "ogr ",
148 "oo ",
149 "ighr ",
150 "coph ",
151 "swerr ",
152 "mihln ",
153 "poxi "
154 };
155
156 #define COMS 48
157
158 struct id_com_s {
159 short com_char;
160 const char *com_desc;
161 };
162
163 static const struct id_com_s com_id_tab[COMS] = {
164 {'?', "? prints help"},
165 {'r', "r read scroll"},
166 {'/', "/ identify object"},
167 {'e', "e eat food"},
168 {'h', "h left "},
169 {'w', "w wield a weapon"},
170 {'j', "j down"},
171 {'W', "W wear armor"},
172 {'k', "k up"},
173 {'T', "T take armor off"},
174 {'l', "l right"},
175 {'P', "P put on ring"},
176 {'y', "y up & left"},
177 {'R', "R remove ring"},
178 {'u', "u up & right"},
179 {'d', "d drop object"},
180 {'b', "b down & left"},
181 {'c', "c call object"},
182 {'n', "n down & right"},
183 {'\0', "<SHIFT><dir>: run that way"},
184 {')', ") print current weapon"},
185 {'\0', "<CTRL><dir>: run till adjacent"},
186 {']', "] print current armor"},
187 {'f', "f<dir> fight till death or near death"},
188 {'=', "= print current rings"},
189 {'t', "t<dir> throw something"},
190 {'\001', "^A print Hp-raise average"},
191 {'m', "m<dir> move onto without picking up"},
192 {'z', "z<dir> zap a wand in a direction"},
193 {'o', "o examine/set options"},
194 {'^', "^<dir> identify trap type"},
195 {'\022', "^R redraw screen"},
196 {'&', "& save screen into 'rogue.screen'"},
197 {'s', "s search for trap/secret door"},
198 {'\020', "^P repeat last message"},
199 {'>', "> go down a staircase"},
200 {'\033', "^[ cancel command"},
201 {'<', "< go up a staircase"},
202 {'S', "S save game"},
203 {'.', ". rest for a turn"},
204 {'Q', "Q quit"},
205 {',', ", pick something up"},
206 {'!', "! shell escape"},
207 {'i', "i inventory"},
208 {'F', "F<dir> fight till either of you dies"},
209 {'I', "I inventory single item"},
210 {'v', "v print version number"},
211 {'q', "q quaff potion" }
212 };
213
214 void
215 inventory(const object *pack, unsigned short mask)
216 {
217 object *obj;
218 short i = 0, j;
219 size_t maxlen = 0, n;
220 short row, col;
221
222 struct {
223 short letter;
224 short sepchar;
225 char desc[DCOLS];
226 char savebuf[DCOLS+8];
227 } descs[MAX_PACK_COUNT+1];
228
229
230 obj = pack->next_object;
231
232 if (!obj) {
233 messagef(0, "your pack is empty");
234 return;
235 }
236 while (obj) {
237 if (obj->what_is & mask) {
238 descs[i].letter = obj->ichar;
239 descs[i].sepchar = ((obj->what_is & ARMOR) && obj->is_protected)
240 ? '}' : ')';
241 get_desc(obj, descs[i].desc, sizeof(descs[i].desc));
242 n = strlen(descs[i].desc) + 4;
243 if (n > maxlen) {
244 maxlen = n;
245 }
246 i++;
247 /*assert(i<=MAX_PACK_COUNT);*/
248 }
249 obj = obj->next_object;
250 }
251 if (maxlen < 27) maxlen = 27;
252 if (maxlen > DCOLS-2) maxlen = DCOLS-2;
253 col = DCOLS - (maxlen + 2);
254
255 for (row = 0; ((row <= i) && (row < DROWS)); row++) {
256 for (j = col; j < DCOLS; j++) {
257 descs[row].savebuf[j-col] = mvinch(row, j);
258 }
259 descs[row].savebuf[j-col] = 0;
260 if (row < i) {
261 mvprintw(row, col, " %c%c %s",
262 descs[row].letter, descs[row].sepchar,
263 descs[row].desc);
264 }
265 else {
266 mvaddstr(row, col, press_space);
267 }
268 clrtoeol();
269 }
270 refresh();
271 wait_for_ack();
272
273 move(0, 0);
274 clrtoeol();
275
276 for (j = 1; ((j <= i) && (j < DROWS)); j++) {
277 mvaddstr(j, col, descs[j].savebuf);
278 }
279 }
280
281 void
282 id_com(void)
283 {
284 int ch = 0;
285 short i, j, k;
286
287 while (ch != CANCEL) {
288 check_message();
289 messagef(0, "Character you want help for (* for all):");
290
291 refresh();
292 ch = getchar();
293
294 switch(ch) {
295 case LIST:
296 {
297 char save[(((COMS / 2) + (COMS % 2)) + 1)][DCOLS];
298 short rows = (((COMS / 2) + (COMS % 2)) + 1);
299 boolean need_two_screens = FALSE;
300
301 if (rows > LINES) {
302 need_two_screens = 1;
303 rows = LINES;
304 }
305 k = 0;
306
307 for (i = 0; i < rows; i++) {
308 for (j = 0; j < DCOLS; j++) {
309 save[i][j] = mvinch(i, j);
310 }
311 }
312 MORE:
313 for (i = 0; i < rows; i++) {
314 move(i, 0);
315 clrtoeol();
316 }
317 for (i = 0; i < (rows-1); i++) {
318 if (i < (LINES-1)) {
319 if (((i + i) < COMS) && ((i+i+k) < COMS)) {
320 mvaddstr(i, 0, com_id_tab[i+i+k].com_desc);
321 }
322 if (((i + i + 1) < COMS) && ((i+i+k+1) < COMS)) {
323 mvaddstr(i, (DCOLS/2),
324 com_id_tab[i+i+k+1].com_desc);
325 }
326 }
327 }
328 mvaddstr(rows - 1, 0, need_two_screens ? more : press_space);
329 refresh();
330 wait_for_ack();
331
332 if (need_two_screens) {
333 k += ((rows-1) * 2);
334 need_two_screens = 0;
335 goto MORE;
336 }
337 for (i = 0; i < rows; i++) {
338 move(i, 0);
339 for (j = 0; j < DCOLS; j++) {
340 addch(save[i][j]);
341 }
342 }
343 }
344 break;
345 default:
346 if (!pr_com_id(ch)) {
347 if (!pr_motion_char(ch)) {
348 check_message();
349 messagef(0, "unknown character");
350 }
351 }
352 ch = CANCEL;
353 break;
354 }
355 }
356 }
357
358 int
359 pr_com_id(int ch)
360 {
361 int i;
362
363 if (!get_com_id(&i, ch)) {
364 return(0);
365 }
366 check_message();
367 messagef(0, "%s", com_id_tab[i].com_desc);
368 return(1);
369 }
370
371 int
372 get_com_id(int *indexp, short ch)
373 {
374 short i;
375
376 for (i = 0; i < COMS; i++) {
377 if (com_id_tab[i].com_char == ch) {
378 *indexp = i;
379 return(1);
380 }
381 }
382 return(0);
383 }
384
385 int
386 pr_motion_char(int ch)
387 {
388 if ( (ch == 'J') ||
389 (ch == 'K') ||
390 (ch == 'L') ||
391 (ch == 'H') ||
392 (ch == 'Y') ||
393 (ch == 'U') ||
394 (ch == 'N') ||
395 (ch == 'B') ||
396 (ch == '\012') ||
397 (ch == '\013') ||
398 (ch == '\010') ||
399 (ch == '\014') ||
400 (ch == '\025') ||
401 (ch == '\031') ||
402 (ch == '\016') ||
403 (ch == '\002')) {
404 const char *until;
405 int n = 0; /* XXX: GCC */
406 if (ch <= '\031') {
407 ch += 96;
408 until = " until adjacent";
409 } else {
410 ch += 32;
411 until = "";
412 }
413 (void)get_com_id(&n, ch);
414 check_message();
415 messagef(0, "run %s%s", com_id_tab[n].com_desc + 8, until);
416 return(1);
417 } else {
418 return(0);
419 }
420 }
421
422 void
423 mix_colors(void)
424 {
425 short i, j, k;
426 char t[MAX_ID_TITLE_LEN];
427
428 for (i = 0; i <= 32; i++) {
429 j = get_rand(0, (POTIONS - 1));
430 k = get_rand(0, (POTIONS - 1));
431 strlcpy(t, id_potions[j].title, sizeof(t));
432 strlcpy(id_potions[j].title, id_potions[k].title,
433 sizeof(id_potions[j].title));
434 strlcpy(id_potions[k].title, t, sizeof(id_potions[k].title));
435 }
436 }
437
438 void
439 make_scroll_titles(void)
440 {
441 short i, j, n;
442 short sylls, s;
443 size_t maxlen = sizeof(id_scrolls[0].title);
444
445 for (i = 0; i < SCROLS; i++) {
446 sylls = get_rand(2, 5);
447 (void)strlcpy(id_scrolls[i].title, "'", maxlen);
448
449 for (j = 0; j < sylls; j++) {
450 s = get_rand(1, (MAXSYLLABLES-1));
451 (void)strlcat(id_scrolls[i].title, syllables[s],
452 maxlen);
453 }
454 /* trim trailing space */
455 n = strlen(id_scrolls[i].title);
456 id_scrolls[i].title[n-1] = 0;
457
458 (void)strlcat(id_scrolls[i].title, "' ", maxlen);
459 }
460 }
461
462 struct sbuf {
463 char *buf;
464 size_t maxlen;
465 };
466
467 static void sbuf_init(struct sbuf *s, char *buf, size_t maxlen);
468 static void sbuf_addstr(struct sbuf *s, const char *str);
469 static void sbuf_addf(struct sbuf *s, const char *fmt, ...)
470 __attribute__((__format__(__printf__, 2, 3)));
471 static void desc_count(struct sbuf *s, int n);
472 static void desc_called(struct sbuf *s, const object *);
473
474 static
475 void
476 sbuf_init(struct sbuf *s, char *buf, size_t maxlen)
477 {
478 s->buf = buf;
479 s->maxlen = maxlen;
480 /*assert(maxlen>0);*/
481 s->buf[0] = 0;
482 }
483
484 static
485 void
486 sbuf_addstr(struct sbuf *s, const char *str)
487 {
488 strlcat(s->buf, str, s->maxlen);
489 }
490
491 static
492 void
493 sbuf_addf(struct sbuf *s, const char *fmt, ...)
494 {
495 va_list ap;
496 size_t initlen;
497
498 initlen = strlen(s->buf);
499 va_start(ap, fmt);
500 vsnprintf(s->buf+initlen, s->maxlen-initlen, fmt, ap);
501 va_end(ap);
502 }
503
504 static
505 void
506 desc_count(struct sbuf *s, int n)
507 {
508 if (n == 1) {
509 sbuf_addstr(s, "an ");
510 } else {
511 sbuf_addf(s, "%d ", n);
512 }
513 }
514
515 static
516 void
517 desc_called(struct sbuf *s, const object *obj)
518 {
519 struct id *id_table;
520
521 id_table = get_id_table(obj);
522 sbuf_addstr(s, name_of(obj));
523 sbuf_addstr(s, "called ");
524 sbuf_addstr(s, id_table[obj->which_kind].title);
525 }
526
527 void
528 get_desc(const object *obj, char *desc, size_t desclen)
529 {
530 const char *item_name;
531 struct id *id_table;
532 struct sbuf db;
533 unsigned short objtype_id_status;
534
535 if (obj->what_is == AMULET) {
536 (void)strlcpy(desc, "the amulet of Yendor ", desclen);
537 return;
538 }
539
540 if (obj->what_is == GOLD) {
541 snprintf(desc, desclen, "%d pieces of gold", obj->quantity);
542 return;
543 }
544
545 item_name = name_of(obj);
546 id_table = get_id_table(obj);
547 if (wizard || id_table == NULL) {
548 objtype_id_status = IDENTIFIED;
549 }
550 else {
551 objtype_id_status = id_table[obj->which_kind].id_status;
552 }
553 if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) {
554 if (obj->identified) {
555 objtype_id_status = IDENTIFIED;
556 }
557 }
558
559 sbuf_init(&db, desc, desclen);
560
561 switch (obj->what_is) {
562 case FOOD:
563 if (obj->which_kind == RATION) {
564 if (obj->quantity > 1) {
565 sbuf_addf(&db,
566 "%d rations of %s", obj->quantity,
567 item_name);
568 } else {
569 sbuf_addf(&db, "some %s", item_name);
570 }
571 } else {
572 sbuf_addf(&db, "an %s", item_name);
573 }
574 break;
575 case SCROL:
576 desc_count(&db, obj->quantity);
577 if (objtype_id_status==UNIDENTIFIED) {
578 sbuf_addstr(&db, item_name);
579 sbuf_addstr(&db, "entitled: ");
580 sbuf_addstr(&db, id_table[obj->which_kind].title);
581 } else if (objtype_id_status==CALLED) {
582 desc_called(&db, obj);
583 } else {
584 sbuf_addstr(&db, item_name);
585 sbuf_addstr(&db, id_table[obj->which_kind].real);
586 }
587 break;
588 case POTION:
589 desc_count(&db, obj->quantity);
590 if (objtype_id_status==UNIDENTIFIED) {
591 sbuf_addstr(&db, id_table[obj->which_kind].title);
592 sbuf_addstr(&db, item_name);
593 } else if (objtype_id_status==CALLED) {
594 desc_called(&db, obj);
595 } else {
596 sbuf_addstr(&db, item_name);
597 sbuf_addstr(&db, id_table[obj->which_kind].real);
598 }
599 break;
600 case WAND:
601 desc_count(&db, obj->quantity);
602 if (objtype_id_status==UNIDENTIFIED) {
603 sbuf_addstr(&db, id_table[obj->which_kind].title);
604 sbuf_addstr(&db, item_name);
605 } else if (objtype_id_status==CALLED) {
606 desc_called(&db, obj);
607 } else {
608 sbuf_addstr(&db, item_name);
609 sbuf_addstr(&db, id_table[obj->which_kind].real);
610 if (wizard || obj->identified) {
611 sbuf_addf(&db, "[%d]", obj->class);
612 }
613 }
614 break;
615 case RING:
616 desc_count(&db, obj->quantity);
617 if (objtype_id_status==UNIDENTIFIED) {
618 sbuf_addstr(&db, id_table[obj->which_kind].title);
619 sbuf_addstr(&db, item_name);
620 } else if (objtype_id_status==CALLED) {
621 desc_called(&db, obj);
622 } else {
623 if ((wizard || obj->identified) &&
624 (obj->which_kind == DEXTERITY ||
625 obj->which_kind == ADD_STRENGTH)) {
626 sbuf_addf(&db, "%+d ", obj->class);
627 }
628 sbuf_addstr(&db, item_name);
629 sbuf_addstr(&db, id_table[obj->which_kind].real);
630 }
631 break;
632 case ARMOR:
633 /* no desc_count() */
634 if (objtype_id_status==UNIDENTIFIED) {
635 sbuf_addstr(&db, id_table[obj->which_kind].title);
636 } else {
637 sbuf_addf(&db, "%+d %s[%d] ", obj->d_enchant,
638 id_table[obj->which_kind].title,
639 get_armor_class(obj));
640 }
641 break;
642 case WEAPON:
643 desc_count(&db, obj->quantity);
644 if (objtype_id_status==UNIDENTIFIED) {
645 sbuf_addstr(&db, name_of(obj));
646 } else {
647 sbuf_addf(&db, "%+d,%+d %s",
648 obj->hit_enchant, obj->d_enchant,
649 name_of(obj));
650 }
651 break;
652 }
653
654 if (obj->in_use_flags & BEING_WIELDED) {
655 sbuf_addstr(&db, "in hand");
656 } else if (obj->in_use_flags & BEING_WORN) {
657 sbuf_addstr(&db, "being worn");
658 } else if (obj->in_use_flags & ON_LEFT_HAND) {
659 sbuf_addstr(&db, "on left hand");
660 } else if (obj->in_use_flags & ON_RIGHT_HAND) {
661 sbuf_addstr(&db, "on right hand");
662 }
663
664 if (!strncmp(db.buf, "an ", 3)) {
665 if (!is_vowel(db.buf[3])) {
666 memmove(db.buf+2, db.buf+3, strlen(db.buf+3)+1);
667 db.buf[1] = ' ';
668 }
669 }
670 }
671
672 void
673 get_wand_and_ring_materials(void)
674 {
675 short i, j;
676 boolean used[WAND_MATERIALS];
677
678 for (i = 0; i < WAND_MATERIALS; i++) {
679 used[i] = 0;
680 }
681 for (i = 0; i < WANDS; i++) {
682 do {
683 j = get_rand(0, WAND_MATERIALS-1);
684 } while (used[j]);
685 used[j] = 1;
686 (void)strlcpy(id_wands[i].title, wand_materials[j],
687 sizeof(id_wands[i].title));
688 is_wood[i] = (j > MAX_METAL);
689 }
690 for (i = 0; i < GEMS; i++) {
691 used[i] = 0;
692 }
693 for (i = 0; i < RINGS; i++) {
694 do {
695 j = get_rand(0, GEMS-1);
696 } while (used[j]);
697 used[j] = 1;
698 (void)strlcpy(id_rings[i].title, gems[j],
699 sizeof(id_rings[i].title));
700 }
701 }
702
703 void
704 single_inv(short ichar)
705 {
706 short ch, ch2;
707 char desc[DCOLS];
708 object *obj;
709
710 ch = ichar ? ichar : pack_letter("inventory what?", ALL_OBJECTS);
711
712 if (ch == CANCEL) {
713 return;
714 }
715 if (!(obj = get_letter_object(ch))) {
716 messagef(0, "no such item.");
717 return;
718 }
719 ch2 = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')';
720 get_desc(obj, desc, sizeof(desc));
721 messagef(0, "%c%c %s", ch, ch2, desc);
722 }
723
724 struct id *
725 get_id_table(const object *obj)
726 {
727 switch(obj->what_is) {
728 case SCROL:
729 return(id_scrolls);
730 case POTION:
731 return(id_potions);
732 case WAND:
733 return(id_wands);
734 case RING:
735 return(id_rings);
736 case WEAPON:
737 return(id_weapons);
738 case ARMOR:
739 return(id_armors);
740 }
741 return((struct id *)0);
742 }
743
744 void
745 inv_armor_weapon(boolean is_weapon)
746 {
747 if (is_weapon) {
748 if (rogue.weapon) {
749 single_inv(rogue.weapon->ichar);
750 } else {
751 messagef(0, "not wielding anything");
752 }
753 } else {
754 if (rogue.armor) {
755 single_inv(rogue.armor->ichar);
756 } else {
757 messagef(0, "not wearing anything");
758 }
759 }
760 }
761
762 void
763 id_type(void)
764 {
765 const char *id;
766 int ch;
767
768 messagef(0, "what do you want identified?");
769
770 ch = rgetchar();
771
772 if ((ch >= 'A') && (ch <= 'Z')) {
773 id = m_names[ch-'A'];
774 } else if (ch < 32) {
775 check_message();
776 return;
777 } else {
778 switch(ch) {
779 case '@':
780 id = "you";
781 break;
782 case '%':
783 id = "staircase";
784 break;
785 case '^':
786 id = "trap";
787 break;
788 case '+':
789 id = "door";
790 break;
791 case '-':
792 case '|':
793 id = "wall of a room";
794 break;
795 case '.':
796 id = "floor";
797 break;
798 case '#':
799 id = "passage";
800 break;
801 case ' ':
802 id = "solid rock";
803 break;
804 case '=':
805 id = "ring";
806 break;
807 case '?':
808 id = "scroll";
809 break;
810 case '!':
811 id = "potion";
812 break;
813 case '/':
814 id = "wand or staff";
815 break;
816 case ')':
817 id = "weapon";
818 break;
819 case ']':
820 id = "armor";
821 break;
822 case '*':
823 id = "gold";
824 break;
825 case ':':
826 id = "food";
827 break;
828 case ',':
829 id = "the Amulet of Yendor";
830 break;
831 default:
832 id = "unknown character";
833 break;
834 }
835 }
836 check_message();
837 messagef(0, "'%c': %s", ch, id);
838 }