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