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