Home | History | Annotate | Line # | Download | only in rogue
object.c revision 1.10.10.2
      1 /*	object.c,v 1.10.10.1 2008/01/09 01:30:57 matt 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[] = "@(#)object.c	8.1 (Berkeley) 5/31/93";
     39 #else
     40 __RCSID("object.c,v 1.10.10.1 2008/01/09 01:30:57 matt Exp");
     41 #endif
     42 #endif /* not lint */
     43 
     44 /*
     45  * object.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 "rogue.h"
     57 
     58 object level_objects;
     59 unsigned short dungeon[DROWS][DCOLS];
     60 short foods = 0;
     61 char *fruit = NULL;
     62 
     63 static object *free_list = NULL;
     64 
     65 fighter rogue = {
     66 	INIT_AW,	/* armor */
     67 	INIT_AW,	/* weapon */
     68 	INIT_RINGS,	/* left ring */
     69 	INIT_RINGS,	/* right ring */
     70 	INIT_HP,	/* Hp current */
     71 	INIT_HP,	/* Hp max */
     72 	INIT_STR,	/* Str current */
     73 	INIT_STR,	/* Str max */
     74 	INIT_PACK,	/* pack */
     75 	INIT_GOLD,	/* gold */
     76 	INIT_EXPLEVEL,	/* exp level */
     77 	INIT_EXP,	/* exp points */
     78 	0, 0,		/* row, col */
     79 	INIT_CHAR,	/* char */
     80 	INIT_MOVES	/* moves */
     81 };
     82 
     83 struct id id_potions[POTIONS] = {
     84 {100, "blue ",     "of increase strength ", 0},
     85 {250, "red ",      "of restore strength ", 0},
     86 {100, "green ",    "of healing ", 0},
     87 {200, "grey ",     "of extra healing ", 0},
     88  {10, "brown ",    "of poison ", 0},
     89 {300, "clear ",    "of raise level ", 0},
     90  {10, "pink ",     "of blindness ", 0},
     91  {25, "white ",    "of hallucination ", 0},
     92 {100, "purple ",   "of detect monster ", 0},
     93 {100, "black ",    "of detect things ", 0},
     94  {10, "yellow ",   "of confusion ", 0},
     95  {80, "plaid ",    "of levitation ", 0},
     96 {150, "burgundy ", "of haste self ", 0},
     97 {145, "beige ",    "of see invisible ", 0}
     98 };
     99 
    100 struct id id_scrolls[SCROLS] = {
    101 {505, "", "of protect armor ", 0},
    102 {200, "", "of hold monster ", 0},
    103 {235, "", "of enchant weapon ", 0},
    104 {235, "", "of enchant armor ", 0},
    105 {175, "", "of identify ", 0},
    106 {190, "", "of teleportation ", 0},
    107  {25, "", "of sleep ", 0},
    108 {610, "", "of scare monster ", 0},
    109 {210, "", "of remove curse ", 0},
    110  {80, "", "of create monster ",0},
    111  {25, "", "of aggravate monster ",0},
    112 {180, "", "of magic mapping ", 0},
    113  {90, "", "of confuse monster ", 0}
    114 };
    115 
    116 struct id id_weapons[WEAPONS] = {
    117 	{150, "short bow ", "", 0},
    118 	  {8, "darts ", "", 0},
    119 	 {15, "arrows ", "", 0},
    120 	 {27, "daggers ", "", 0},
    121 	 {35, "shurikens ", "", 0},
    122 	{360, "mace ", "", 0},
    123 	{470, "long sword ", "", 0},
    124 	{580, "two-handed sword ", "", 0}
    125 };
    126 
    127 struct id id_armors[ARMORS] = {
    128 	{300, "leather armor ", "", (UNIDENTIFIED)},
    129 	{300, "ring mail ", "", (UNIDENTIFIED)},
    130 	{400, "scale mail ", "", (UNIDENTIFIED)},
    131 	{500, "chain mail ", "", (UNIDENTIFIED)},
    132 	{600, "banded mail ", "", (UNIDENTIFIED)},
    133 	{600, "splint mail ", "", (UNIDENTIFIED)},
    134 	{700, "plate mail ", "", (UNIDENTIFIED)}
    135 };
    136 
    137 struct id id_wands[WANDS] = {
    138 	 {25, "", "of teleport away ",0},
    139 	 {50, "", "of slow monster ", 0},
    140 	  {8, "", "of invisibility ",0},
    141 	 {55, "", "of polymorph ",0},
    142 	  {2, "", "of haste monster ",0},
    143 	 {20, "", "of magic missile ",0},
    144 	 {20, "", "of cancellation ",0},
    145 	  {0, "", "of do nothing ",0},
    146 	 {35, "", "of drain life ",0},
    147 	 {20, "", "of cold ",0},
    148 	 {20, "", "of fire ",0}
    149 };
    150 
    151 struct id id_rings[RINGS] = {
    152 	 {250, "", "of stealth ",0},
    153 	 {100, "", "of teleportation ", 0},
    154 	 {255, "", "of regeneration ",0},
    155 	 {295, "", "of slow digestion ",0},
    156 	 {200, "", "of add strength ",0},
    157 	 {250, "", "of sustain strength ",0},
    158 	 {250, "", "of dexterity ",0},
    159 	  {25, "", "of adornment ",0},
    160 	 {300, "", "of see invisible ",0},
    161 	 {290, "", "of maintain armor ",0},
    162 	 {270, "", "of searching ",0},
    163 };
    164 
    165 void
    166 put_objects(void)
    167 {
    168 	short i, n;
    169 	object *obj;
    170 
    171 	if (cur_level < max_level) {
    172 		return;
    173 	}
    174 	n = coin_toss() ? get_rand(2, 4) : get_rand(3, 5);
    175 	while (rand_percent(33)) {
    176 		n++;
    177 	}
    178 	if (party_room != NO_ROOM) {
    179 		make_party();
    180 	}
    181 	for (i = 0; i < n; i++) {
    182 		obj = gr_object();
    183 		rand_place(obj);
    184 	}
    185 	put_gold();
    186 }
    187 
    188 void
    189 put_gold(void)
    190 {
    191 	short i, j;
    192 	short row,col;
    193 	boolean is_maze, is_room;
    194 
    195 	for (i = 0; i < MAXROOMS; i++) {
    196 		is_maze = (rooms[i].is_room & R_MAZE) ? 1 : 0;
    197 		is_room = (rooms[i].is_room & R_ROOM) ? 1 : 0;
    198 
    199 		if (!(is_room || is_maze)) {
    200 			continue;
    201 		}
    202 		if (is_maze || rand_percent(GOLD_PERCENT)) {
    203 			for (j = 0; j < 50; j++) {
    204 				row = get_rand(rooms[i].top_row+1,
    205 				rooms[i].bottom_row-1);
    206 				col = get_rand(rooms[i].left_col+1,
    207 				rooms[i].right_col-1);
    208 				if ((dungeon[row][col] == FLOOR) ||
    209 					(dungeon[row][col] == TUNNEL)) {
    210 					plant_gold(row, col, is_maze);
    211 					break;
    212 				}
    213 			}
    214 		}
    215 	}
    216 }
    217 
    218 void
    219 plant_gold(short row, short col, boolean is_maze)
    220 {
    221 	object *obj;
    222 
    223 	obj = alloc_object();
    224 	obj->row = row; obj->col = col;
    225 	obj->what_is = GOLD;
    226 	obj->quantity = get_rand((2 * cur_level), (16 * cur_level));
    227 	if (is_maze) {
    228 		obj->quantity += obj->quantity / 2;
    229 	}
    230 	dungeon[row][col] |= OBJECT;
    231 	(void)add_to_pack(obj, &level_objects, 0);
    232 }
    233 
    234 void
    235 place_at(object *obj, int row, int col)
    236 {
    237 	obj->row = row;
    238 	obj->col = col;
    239 	dungeon[row][col] |= OBJECT;
    240 	(void)add_to_pack(obj, &level_objects, 0);
    241 }
    242 
    243 object *
    244 object_at(object *pack, short row, short col)
    245 {
    246 	object *obj = NULL;
    247 
    248 	if (dungeon[row][col] & (MONSTER | OBJECT)) {
    249 		obj = pack->next_object;
    250 
    251 		while (obj && ((obj->row != row) || (obj->col != col))) {
    252 			obj = obj->next_object;
    253 		}
    254 		if (!obj) {
    255 			messagef(1, "object_at(): inconsistent");
    256 		}
    257 	}
    258 	return(obj);
    259 }
    260 
    261 object *
    262 get_letter_object(int ch)
    263 {
    264 	object *obj;
    265 
    266 	obj = rogue.pack.next_object;
    267 
    268 	while (obj && (obj->ichar != ch)) {
    269 		obj = obj->next_object;
    270 	}
    271 	return(obj);
    272 }
    273 
    274 void
    275 free_stuff(object *objlist)
    276 {
    277 	object *obj;
    278 
    279 	while (objlist->next_object) {
    280 		obj = objlist->next_object;
    281 		objlist->next_object =
    282 			objlist->next_object->next_object;
    283 		free_object(obj);
    284 	}
    285 }
    286 
    287 const char *
    288 name_of(const object *obj)
    289 {
    290 	const char *retstring;
    291 
    292 	switch(obj->what_is) {
    293 	case SCROL:
    294 		retstring = obj->quantity > 1 ? "scrolls " : "scroll ";
    295 		break;
    296 	case POTION:
    297 		retstring = obj->quantity > 1 ? "potions " : "potion ";
    298 		break;
    299 	case FOOD:
    300 		if (obj->which_kind == RATION) {
    301 			retstring = "food ";
    302 		} else {
    303 			retstring = fruit;
    304 		}
    305 		break;
    306 	case WAND:
    307 		retstring = is_wood[obj->which_kind] ? "staff " : "wand ";
    308 		break;
    309 	case WEAPON:
    310 		switch(obj->which_kind) {
    311 		case DART:
    312 			retstring=obj->quantity > 1 ? "darts " : "dart ";
    313 			break;
    314 		case ARROW:
    315 			retstring=obj->quantity > 1 ? "arrows " : "arrow ";
    316 			break;
    317 		case DAGGER:
    318 			retstring=obj->quantity > 1 ? "daggers " : "dagger ";
    319 			break;
    320 		case SHURIKEN:
    321 			retstring=obj->quantity > 1?"shurikens ":"shuriken ";
    322 			break;
    323 		default:
    324 			retstring = id_weapons[obj->which_kind].title;
    325 		}
    326 		break;
    327 	case ARMOR:
    328 		retstring = "armor ";
    329 		break;
    330 	case RING:
    331 			retstring = "ring ";
    332 		break;
    333 	case AMULET:
    334 		retstring = "amulet ";
    335 		break;
    336 	default:
    337 		retstring = "unknown ";
    338 		break;
    339 	}
    340 	return(retstring);
    341 }
    342 
    343 object *
    344 gr_object(void)
    345 {
    346 	object *obj;
    347 
    348 	obj = alloc_object();
    349 
    350 	if (foods < (cur_level / 3)) {
    351 		obj->what_is = FOOD;
    352 		foods++;
    353 	} else {
    354 		obj->what_is = gr_what_is();
    355 	}
    356 	switch(obj->what_is) {
    357 	case SCROL:
    358 		gr_scroll(obj);
    359 		break;
    360 	case POTION:
    361 		gr_potion(obj);
    362 		break;
    363 	case WEAPON:
    364 		gr_weapon(obj, 1);
    365 		break;
    366 	case ARMOR:
    367 		gr_armor(obj);
    368 		break;
    369 	case WAND:
    370 		gr_wand(obj);
    371 		break;
    372 	case FOOD:
    373 		get_food(obj, 0);
    374 		break;
    375 	case RING:
    376 		gr_ring(obj, 1);
    377 		break;
    378 	}
    379 	return(obj);
    380 }
    381 
    382 unsigned short
    383 gr_what_is(void)
    384 {
    385 	short percent;
    386 	unsigned short what_is;
    387 
    388 	percent = get_rand(1, 91);
    389 
    390 	if (percent <= 30) {
    391 		what_is = SCROL;
    392 	} else if (percent <= 60) {
    393 		what_is = POTION;
    394 	} else if (percent <= 64) {
    395 		what_is = WAND;
    396 	} else if (percent <= 74) {
    397 		what_is = WEAPON;
    398 	} else if (percent <= 83) {
    399 		what_is = ARMOR;
    400 	} else if (percent <= 88) {
    401 		what_is = FOOD;
    402 	} else {
    403 		what_is = RING;
    404 	}
    405 	return(what_is);
    406 }
    407 
    408 void
    409 gr_scroll(object *obj)
    410 {
    411 	short percent;
    412 
    413 	percent = get_rand(0, 91);
    414 
    415 	obj->what_is = SCROL;
    416 
    417 	if (percent <= 5) {
    418 		obj->which_kind = PROTECT_ARMOR;
    419 	} else if (percent <= 10) {
    420 		obj->which_kind = HOLD_MONSTER;
    421 	} else if (percent <= 20) {
    422 		obj->which_kind = CREATE_MONSTER;
    423 	} else if (percent <= 35) {
    424 		obj->which_kind = IDENTIFY;
    425 	} else if (percent <= 43) {
    426 		obj->which_kind = TELEPORT;
    427 	} else if (percent <= 50) {
    428 		obj->which_kind = SLEEP;
    429 	} else if (percent <= 55) {
    430 		obj->which_kind = SCARE_MONSTER;
    431 	} else if (percent <= 64) {
    432 		obj->which_kind = REMOVE_CURSE;
    433 	} else if (percent <= 69) {
    434 		obj->which_kind = ENCH_ARMOR;
    435 	} else if (percent <= 74) {
    436 		obj->which_kind = ENCH_WEAPON;
    437 	} else if (percent <= 80) {
    438 		obj->which_kind = AGGRAVATE_MONSTER;
    439 	} else if (percent <= 86) {
    440 		obj->which_kind = CON_MON;
    441 	} else {
    442 		obj->which_kind = MAGIC_MAPPING;
    443 	}
    444 }
    445 
    446 void
    447 gr_potion(object *obj)
    448 {
    449 	short percent;
    450 
    451 	percent = get_rand(1, 118);
    452 
    453 	obj->what_is = POTION;
    454 
    455 	if (percent <= 5) {
    456 		obj->which_kind = RAISE_LEVEL;
    457 	} else if (percent <= 15) {
    458 		obj->which_kind = DETECT_OBJECTS;
    459 	} else if (percent <= 25) {
    460 		obj->which_kind = DETECT_MONSTER;
    461 	} else if (percent <= 35) {
    462 		obj->which_kind = INCREASE_STRENGTH;
    463 	} else if (percent <= 45) {
    464 		obj->which_kind = RESTORE_STRENGTH;
    465 	} else if (percent <= 55) {
    466 		obj->which_kind = HEALING;
    467 	} else if (percent <= 65) {
    468 		obj->which_kind = EXTRA_HEALING;
    469 	} else if (percent <= 75) {
    470 		obj->which_kind = BLINDNESS;
    471 	} else if (percent <= 85) {
    472 		obj->which_kind = HALLUCINATION;
    473 	} else if (percent <= 95) {
    474 		obj->which_kind = CONFUSION;
    475 	} else if (percent <= 105) {
    476 		obj->which_kind = POISON;
    477 	} else if (percent <= 110) {
    478 		obj->which_kind = LEVITATION;
    479 	} else if (percent <= 114) {
    480 		obj->which_kind = HASTE_SELF;
    481 	} else {
    482 		obj->which_kind = SEE_INVISIBLE;
    483 	}
    484 }
    485 
    486 void
    487 gr_weapon(object *obj, int assign_wk)
    488 {
    489 	short percent;
    490 	short i;
    491 	short blessing, increment;
    492 
    493 	obj->what_is = WEAPON;
    494 	if (assign_wk) {
    495 		obj->which_kind = get_rand(0, (WEAPONS - 1));
    496 	}
    497 	if ((obj->which_kind == ARROW) || (obj->which_kind == DAGGER) ||
    498 		(obj->which_kind == SHURIKEN) || (obj->which_kind == DART)) {
    499 		obj->quantity = get_rand(3, 15);
    500 		obj->quiver = get_rand(0, 126);
    501 	} else {
    502 		obj->quantity = 1;
    503 	}
    504 	obj->hit_enchant = obj->d_enchant = 0;
    505 
    506 	percent = get_rand(1, 96);
    507 	blessing = get_rand(1, 3);
    508 
    509 	if (percent <= 32) {
    510 		if (percent <= 16) {
    511 			increment = 1;
    512 		} else {
    513 			increment = -1;
    514 			obj->is_cursed = 1;
    515 		}
    516 		for (i = 0; i < blessing; i++) {
    517 			if (coin_toss()) {
    518 				obj->hit_enchant += increment;
    519 			} else {
    520 				obj->d_enchant += increment;
    521 			}
    522 		}
    523 	}
    524 	switch(obj->which_kind) {
    525 	case BOW:
    526 	case DART:
    527 		obj->damage = "1d1";
    528 		break;
    529 	case ARROW:
    530 		obj->damage = "1d2";
    531 		break;
    532 	case DAGGER:
    533 		obj->damage = "1d3";
    534 		break;
    535 	case SHURIKEN:
    536 		obj->damage = "1d4";
    537 		break;
    538 	case MACE:
    539 		obj->damage = "2d3";
    540 		break;
    541 	case LONG_SWORD:
    542 		obj->damage = "3d4";
    543 		break;
    544 	case TWO_HANDED_SWORD:
    545 		obj->damage = "4d5";
    546 		break;
    547 	}
    548 }
    549 
    550 void
    551 gr_armor(object *obj)
    552 {
    553 	short percent;
    554 	short blessing;
    555 
    556 	obj->what_is = ARMOR;
    557 	obj->which_kind = get_rand(0, (ARMORS - 1));
    558 	obj->class = obj->which_kind + 2;
    559 	if ((obj->which_kind == PLATE) || (obj->which_kind == SPLINT)) {
    560 		obj->class--;
    561 	}
    562 	obj->is_protected = 0;
    563 	obj->d_enchant = 0;
    564 
    565 	percent = get_rand(1, 100);
    566 	blessing = get_rand(1, 3);
    567 
    568 	if (percent <= 16) {
    569 		obj->is_cursed = 1;
    570 		obj->d_enchant -= blessing;
    571 	} else if (percent <= 33) {
    572 		obj->d_enchant += blessing;
    573 	}
    574 }
    575 
    576 void
    577 gr_wand(object *obj)
    578 {
    579 	obj->what_is = WAND;
    580 	obj->which_kind = get_rand(0, (WANDS - 1));
    581 	obj->class = get_rand(3, 7);
    582 }
    583 
    584 void
    585 get_food(object *obj, boolean force_ration)
    586 {
    587 	obj->what_is = FOOD;
    588 
    589 	if (force_ration || rand_percent(80)) {
    590 		obj->which_kind = RATION;
    591 	} else {
    592 		obj->which_kind = FRUIT;
    593 	}
    594 }
    595 
    596 void
    597 put_stairs(void)
    598 {
    599 	short row, col;
    600 
    601 	gr_row_col(&row, &col, (FLOOR | TUNNEL));
    602 	dungeon[row][col] |= STAIRS;
    603 }
    604 
    605 int
    606 get_armor_class(const object *obj)
    607 {
    608 	if (obj) {
    609 		return(obj->class + obj->d_enchant);
    610 	}
    611 	return(0);
    612 }
    613 
    614 object *
    615 alloc_object(void)
    616 {
    617 	object *obj;
    618 
    619 	if (free_list) {
    620 		obj = free_list;
    621 		free_list = free_list->next_object;
    622 	} else if (!(obj = md_malloc(sizeof(object)))) {
    623 			messagef(0, "cannot allocate object, saving game");
    624 			save_into_file(error_file);
    625 			clean_up("alloc_object:  save failed");
    626 	}
    627 	obj->quantity = 1;
    628 	obj->ichar = 'L';
    629 	obj->picked_up = obj->is_cursed = 0;
    630 	obj->in_use_flags = NOT_USED;
    631 	obj->identified = UNIDENTIFIED;
    632 	obj->damage = "1d1";
    633 	return(obj);
    634 }
    635 
    636 void
    637 free_object(object *obj)
    638 {
    639 	obj->next_object = free_list;
    640 	free_list = obj;
    641 }
    642 
    643 void
    644 make_party(void)
    645 {
    646 	short n;
    647 
    648 	party_room = gr_room();
    649 
    650 	n = rand_percent(99) ? party_objects(party_room) : 11;
    651 	if (rand_percent(99)) {
    652 		party_monsters(party_room, n);
    653 	}
    654 }
    655 
    656 void
    657 show_objects(void)
    658 {
    659 	object *obj;
    660 	short mc, rc, row, col;
    661 	object *monster;
    662 
    663 	obj = level_objects.next_object;
    664 
    665 	while (obj) {
    666 		row = obj->row;
    667 		col = obj->col;
    668 
    669 		rc = get_mask_char(obj->what_is);
    670 
    671 		if (dungeon[row][col] & MONSTER) {
    672 			if ((monster =
    673 			    object_at(&level_monsters, row, col)) != NULL) {
    674 				monster->trail_char = rc;
    675 			}
    676 		}
    677 		mc = mvinch(row, col);
    678 		if (((mc < 'A') || (mc > 'Z')) &&
    679 			((row != rogue.row) || (col != rogue.col))) {
    680 			mvaddch(row, col, rc);
    681 		}
    682 		obj = obj->next_object;
    683 	}
    684 
    685 	monster = level_monsters.next_object;
    686 
    687 	while (monster) {
    688 		if (monster->m_flags & IMITATES) {
    689 			mvaddch(monster->row, monster->col, (int)monster->disguise);
    690 		}
    691 		monster = monster->next_monster;
    692 	}
    693 }
    694 
    695 void
    696 put_amulet(void)
    697 {
    698 	object *obj;
    699 
    700 	obj = alloc_object();
    701 	obj->what_is = AMULET;
    702 	rand_place(obj);
    703 }
    704 
    705 void
    706 rand_place(object *obj)
    707 {
    708 	short row, col;
    709 
    710 	gr_row_col(&row, &col, (FLOOR | TUNNEL));
    711 	place_at(obj, row, col);
    712 }
    713 
    714 void
    715 c_object_for_wizard(void)
    716 {
    717 	short ch, max, wk;
    718 	object *obj;
    719 	char buf[80];
    720 
    721 	max = 0;
    722 	if (pack_count(NULL) >= MAX_PACK_COUNT) {
    723 		messagef(0, "pack full");
    724 		return;
    725 	}
    726 	messagef(0, "type of object?");
    727 
    728 	while (r_index("!?:)]=/,\033", (ch = rgetchar()), 0) == -1) {
    729 		sound_bell();
    730 	}
    731 	check_message();
    732 
    733 	if (ch == '\033') {
    734 		return;
    735 	}
    736 	obj = alloc_object();
    737 
    738 	switch(ch) {
    739 	case '!':
    740 		obj->what_is = POTION;
    741 		max = POTIONS - 1;
    742 		break;
    743 	case '?':
    744 		obj->what_is = SCROL;
    745 		max = SCROLS - 1;
    746 		break;
    747 	case ',':
    748 		obj->what_is = AMULET;
    749 		break;
    750 	case ':':
    751 		get_food(obj, 0);
    752 		break;
    753 	case ')':
    754 		gr_weapon(obj, 0);
    755 		max = WEAPONS - 1;
    756 		break;
    757 	case ']':
    758 		gr_armor(obj);
    759 		max = ARMORS - 1;
    760 		break;
    761 	case '/':
    762 		gr_wand(obj);
    763 		max = WANDS - 1;
    764 		break;
    765 	case '=':
    766 		max = RINGS - 1;
    767 		obj->what_is = RING;
    768 		break;
    769 	}
    770 	if ((ch != ',') && (ch != ':')) {
    771 GIL:
    772 		if (get_input_line("which kind?", "", buf, sizeof(buf), "", 0, 1)) {
    773 			wk = get_number(buf);
    774 			if ((wk >= 0) && (wk <= max)) {
    775 				obj->which_kind = wk;
    776 				if (obj->what_is == RING) {
    777 					gr_ring(obj, 0);
    778 				}
    779 			} else {
    780 				sound_bell();
    781 				goto GIL;
    782 			}
    783 		} else {
    784 			free_object(obj);
    785 			return;
    786 		}
    787 	}
    788 	get_desc(obj, buf, sizeof(buf));
    789 	messagef(0, "%s", buf);
    790 	(void)add_to_pack(obj, &rogue.pack, 1);
    791 }
    792