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