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