Annotation of early-roguelike/arogue7/pack.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * pack.c - Routines to deal with the pack.
! 3: *
! 4: * Advanced Rogue
! 5: * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
! 6: * All rights reserved.
! 7: *
! 8: * Based on "Rogue: Exploring the Dungeons of Doom"
! 9: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 10: * All rights reserved.
! 11: *
! 12: * See the file LICENSE.TXT for full copyright and licensing information.
! 13: */
! 14:
! 15: #include "curses.h"
! 16: #include <ctype.h>
! 17: #include <string.h>
! 18: #include "rogue.h"
! 19: #ifdef PC7300
! 20: #include "menu.h"
! 21: #endif
! 22:
! 23: bool is_type (struct object *obj, int type);
! 24:
! 25: /*
! 26: * Routines to deal with the pack
! 27: */
! 28:
! 29: /*
! 30: * add_pack:
! 31: * Pick up an object and add it to the pack. If the argument is non-null
! 32: * use it as the linked_list pointer instead of gettting it off the ground.
! 33: */
! 34: bool
! 35: add_pack(struct linked_list *item, bool silent, struct linked_list **packret)
! 36: {
! 37: register struct linked_list *ip, *lp = NULL, *ap;
! 38: register struct object *obj, *op = NULL;
! 39: register bool exact, from_floor;
! 40:
! 41: if (packret != NULL)
! 42: *packret = NULL;
! 43:
! 44: if (item == NULL)
! 45: {
! 46: from_floor = TRUE;
! 47: if ((item = find_obj(hero.y, hero.x)) == NULL)
! 48: return(FALSE);
! 49: }
! 50: else
! 51: from_floor = FALSE;
! 52: obj = OBJPTR(item);
! 53: /*
! 54: * If it is gold, just add its value to rogue's purse and get rid
! 55: * of it.
! 56: */
! 57: if (obj->o_type == GOLD) {
! 58: register struct linked_list *mitem;
! 59: register struct thing *tp;
! 60:
! 61: if (!silent) {
! 62: if (!terse) addmsg("You found ");
! 63: msg("%d gold pieces.", obj->o_count);
! 64: }
! 65:
! 66: /* First make sure no greedy monster is after this gold.
! 67: * If so, make the monster run after the rogue instead.
! 68: */
! 69: for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
! 70: tp = THINGPTR(mitem);
! 71: if (tp->t_dest == &obj->o_pos) tp->t_dest = &hero;
! 72: }
! 73:
! 74: purse += obj->o_count;
! 75: if (from_floor) {
! 76: detach(lvl_obj, item);
! 77: if ((ap = find_obj(hero.y, hero.x)) == NULL)
! 78: mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
! 79: else
! 80: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
! 81: }
! 82: o_discard(item);
! 83: return(TRUE);
! 84: }
! 85:
! 86: /*
! 87: * see if he can carry any more weight
! 88: */
! 89: if (itemweight(obj) + pstats.s_pack > pstats.s_carry) {
! 90: msg("Too much for you to carry.");
! 91: return FALSE;
! 92: }
! 93: /*
! 94: * Link it into the pack. Search the pack for a object of similar type
! 95: * if there isn't one, stuff it at the beginning, if there is, look for one
! 96: * that is exactly the same and just increment the count if there is.
! 97: * it that. Food is always put at the beginning for ease of access, but
! 98: * is not ordered so that you can't tell good food from bad. First check
! 99: * to see if there is something in thr same group and if there is then
! 100: * increment the count.
! 101: */
! 102: if (obj->o_group)
! 103: {
! 104: for (ip = pack; ip != NULL; ip = next(ip))
! 105: {
! 106: op = OBJPTR(ip);
! 107: if (op->o_group == obj->o_group)
! 108: {
! 109: /*
! 110: * Put it in the pack and notify the user
! 111: */
! 112: op->o_count += obj->o_count;
! 113: if (from_floor)
! 114: {
! 115: detach(lvl_obj, item);
! 116: if ((ap = find_obj(hero.y, hero.x)) == NULL)
! 117: mvaddch(hero.y,hero.x,
! 118: (roomin(&hero)==NULL ? PASSAGE : FLOOR));
! 119: else
! 120: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
! 121: }
! 122: o_discard(item);
! 123: item = ip;
! 124: goto picked_up;
! 125: }
! 126: }
! 127: }
! 128:
! 129: /*
! 130: * Check for and deal with scare monster scrolls
! 131: */
! 132: if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
! 133: if (obj->o_flags & ISCURSED)
! 134: {
! 135: msg("The scroll turns to dust as you pick it up.");
! 136: detach(lvl_obj, item);
! 137: if ((ap = find_obj(hero.y, hero.x)) == NULL)
! 138: mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
! 139: else
! 140: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
! 141: return(TRUE);
! 142: }
! 143:
! 144: /*
! 145: * Search for an object of the same type
! 146: */
! 147: exact = FALSE;
! 148: for (ip = pack; ip != NULL; ip = next(ip))
! 149: {
! 150: op = OBJPTR(ip);
! 151: if (obj->o_type == op->o_type)
! 152: break;
! 153: }
! 154: if (ip == NULL)
! 155: {
! 156: /*
! 157: * Put it at the end of the pack since it is a new type
! 158: */
! 159: for (ip = pack; ip != NULL; ip = next(ip))
! 160: {
! 161: op = OBJPTR(ip);
! 162: if (op->o_type != FOOD)
! 163: break;
! 164: lp = ip;
! 165: }
! 166: }
! 167: else
! 168: {
! 169: /*
! 170: * Search for an object which is exactly the same
! 171: */
! 172: while (ip != NULL && op->o_type == obj->o_type)
! 173: {
! 174: if (op->o_which == obj->o_which)
! 175: {
! 176: exact = TRUE;
! 177: break;
! 178: }
! 179: lp = ip;
! 180: if ((ip = next(ip)) == NULL)
! 181: break;
! 182: op = OBJPTR(ip);
! 183: }
! 184: }
! 185: /*
! 186: * Check if there is room
! 187: */
! 188: if (ip == NULL || !exact || !ISMULT(obj->o_type)) {
! 189: if (inpack == MAXPACK-1) {
! 190: msg(terse ? "No room." : "You can't carry anything else.");
! 191: return(FALSE);
! 192: }
! 193: }
! 194: inpack++;
! 195: if (from_floor)
! 196: {
! 197: detach(lvl_obj, item);
! 198: if ((ap = find_obj(hero.y, hero.x)) == NULL)
! 199: mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
! 200: else
! 201: mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
! 202: }
! 203: if (ip == NULL)
! 204: {
! 205: /*
! 206: * Didn't find an exact match, just stick it here
! 207: */
! 208: if (pack == NULL)
! 209: pack = item;
! 210: else
! 211: {
! 212: lp->l_next = item;
! 213: item->l_prev = lp;
! 214: item->l_next = NULL;
! 215: }
! 216: }
! 217: else
! 218: {
! 219: /*
! 220: * If we found an exact match. If it is food,
! 221: * increase the count, otherwise put it with its clones.
! 222: */
! 223: if (exact && ISMULT(obj->o_type))
! 224: {
! 225: op->o_count += obj->o_count;
! 226: inpack--; /* adjust for previous addition */
! 227: o_discard(item);
! 228: item = ip;
! 229: goto picked_up;
! 230: }
! 231: if ((item->l_prev = prev(ip)) != NULL)
! 232: item->l_prev->l_next = item;
! 233: else
! 234: pack = item;
! 235: item->l_next = ip;
! 236: ip->l_prev = item;
! 237: }
! 238: picked_up:
! 239: /*
! 240: * Notify the user
! 241: */
! 242: obj = OBJPTR(item);
! 243: if (!silent)
! 244: {
! 245: if (!terse)
! 246: addmsg("You now have ");
! 247: msg("%s (%c)", inv_name(obj, !terse), pack_char(pack, obj));
! 248: }
! 249:
! 250: /* Relics can do strange things when you pick them up */
! 251: if (obj->o_type == RELIC) {
! 252: int newclass;
! 253: switch (obj->o_which) {
! 254: /* the ankh of Heil gives you prayers */
! 255: case HEIL_ANKH:
! 256: msg("The ankh welds itself into your hand.");
! 257: if (player.t_ctype != C_CLERIC && player.t_ctype != C_PALADIN)
! 258: fuse(prayer_recovery, NULL, SPELLTIME, AFTER);
! 259:
! 260: /* A cloak must be worn. */
! 261: when EMORI_CLOAK:
! 262: if (cur_armor != NULL || cur_misc[WEAR_CLOAK]) {
! 263: msg("The cloak insists you remove your current garments.");
! 264: if (!dropcheck(cur_armor != NULL ? cur_armor
! 265: : cur_misc[WEAR_CLOAK])) {
! 266: pstats.s_hpt = -1;
! 267: msg("The cloak constricts around you.");
! 268: msg("It draws your life force from you!!! -- More --");
! 269: wait_for(' ');
! 270: death(D_RELIC);
! 271: }
! 272: }
! 273: if (obj->o_charges < 0) /* should never happen, but.... */
! 274: obj->o_charges = 0;
! 275: if (obj->o_charges == 0)
! 276: fuse(cloak_charge, obj, CLOAK_TIME, AFTER);
! 277:
! 278: /* The amulet must be worn. */
! 279: when STONEBONES_AMULET:
! 280: case YENDOR_AMULET:
! 281: if (cur_misc[WEAR_JEWEL] ||
! 282: cur_relic[STONEBONES_AMULET] ||
! 283: cur_relic[YENDOR_AMULET]) {
! 284: msg("You have an urge to remove your current amulet.");
! 285: }
! 286: if((cur_misc[WEAR_JEWEL] && !dropcheck(cur_misc[WEAR_JEWEL])) ||
! 287: cur_relic[STONEBONES_AMULET] ||
! 288: cur_relic[YENDOR_AMULET]) {
! 289: pstats.s_hpt = -1;
! 290: msg("The %s begins pulsing.", inv_name(obj, TRUE));
! 291: msg("It fades away.... -- More --");
! 292: wait_for(' ');
! 293: death(D_RELIC);
! 294: }
! 295: msg("The %s welds itself into your chest.",inv_name(obj,TRUE));
! 296:
! 297: /* The eye must be inserted in eye socket */
! 298: when EYE_VECNA:
! 299: msg("The eye forces you to jam it into your eye socket!");
! 300: pstats.s_hpt -= 75;
! 301: if (pstats.s_hpt < 0) {
! 302: msg ("The pain is too much for you! -- More --");
! 303: wait_for(' ');
! 304: death(D_RELIC);
! 305: }
! 306: waste_time();
! 307: msg("The excrutiating pain slowly turns into a dull throb.");
! 308:
! 309: when QUILL_NAGROM:
! 310: fuse(quill_charge,NULL,player.t_ctype==C_MAGICIAN ? 4 : 8,AFTER);
! 311:
! 312: /* Weapons will insist on being wielded. */
! 313: when MUSTY_DAGGER:
! 314: case HRUGGEK_MSTAR:
! 315: case YEENOGHU_FLAIL:
! 316: case AXE_AKLAD:
! 317: /* For the daggers start a fuse to change player to a thief. */
! 318: /* and set a daemon to eat gold. */
! 319: if (obj->o_which == MUSTY_DAGGER) {
! 320: newclass = C_THIEF;
! 321: fuse(changeclass, &newclass, roll(20, 20), AFTER);
! 322: if (purse > 0)
! 323: msg("Your purse feels lighter");
! 324: else
! 325: purse = 1; /* fudge to get right msg from eat_gold() */
! 326: eat_gold(obj);
! 327: start_daemon(eat_gold, obj, AFTER);
! 328: }
! 329: /* For the axe start a fuse to change player to a fighter. */
! 330: if (obj->o_which == AXE_AKLAD) {
! 331: newclass = C_FIGHTER;
! 332: fuse(changeclass, &newclass, roll(20, 20), AFTER);
! 333: }
! 334: if (cur_weapon != NULL) {
! 335: msg("The artifact insists you release your current weapon.");
! 336: if (!dropcheck(cur_weapon)) {
! 337: pstats.s_hpt = -1;
! 338: msg("The artifact forces your weapon into your heart.");
! 339: msg("It hums with satisfaction. -- More --");
! 340: wait_for(' ');
! 341: death(D_RELIC);
! 342: }
! 343: }
! 344: cur_weapon = obj;
! 345:
! 346: when SURTUR_RING:
! 347: msg("The ring forces itself through your nose!");
! 348: pstats.s_hpt -= 22;
! 349: if (pstats.s_hpt < 0) {
! 350: msg ("The pain is too much for you! -- More --");
! 351: wait_for(' ');
! 352: death(D_RELIC);
! 353: }
! 354: waste_time();
! 355: turn_on(player, NOFIRE);
! 356: msg("The pain slowly subsides.");
! 357: otherwise:
! 358: break;
! 359: }
! 360: cur_relic[obj->o_which]++; /* Note that we have it */
! 361: }
! 362:
! 363: updpack(FALSE, &player);
! 364: if (packret != NULL)
! 365: *packret = item;
! 366: return(TRUE);
! 367: }
! 368:
! 369: #ifdef PC7300
! 370: static menu_t Display; /* The menu structure */
! 371: static mitem_t Dispitems[MAXPACK+1]; /* Info for each line */
! 372: static char Displines[MAXPACK+1][LINELEN+1]; /* The lines themselves */
! 373: #endif
! 374:
! 375: /*
! 376: * inventory:
! 377: * list what is in the pack
! 378: */
! 379: bool
! 380: inventory(struct linked_list *list, int type)
! 381: {
! 382: register struct object *obj;
! 383: register char ch;
! 384: register int n_objs, cnt, maxx, curx;
! 385: char inv_temp[2*LINELEN+1];
! 386:
! 387: cnt = 0;
! 388: n_objs = 0;
! 389: for (ch = 'a'; list != NULL; ch++, list = next(list)) {
! 390: obj = OBJPTR(list);
! 391: if (!is_type(obj, type))
! 392: continue;
! 393: switch (n_objs++) {
! 394: /*
! 395: * For the first thing in the inventory, just save the string
! 396: * in case there is only one.
! 397: */
! 398: case 0:
! 399: sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE));
! 400: break;
! 401: /*
! 402: * If there is more than one, clear the screen, print the
! 403: * saved message and fall through to ...
! 404: */
! 405: case 1:
! 406: if (slow_invent)
! 407: msg(inv_temp);
! 408: else
! 409: {
! 410: wclear(hw);
! 411: waddstr(hw, inv_temp);
! 412: waddch(hw, '\n');
! 413:
! 414: maxx = strlen(inv_temp); /* Length of the listing */
! 415:
! 416: #ifdef PC7300
! 417: /* Put it into the PC menu display */
! 418: strcpy(Displines[0], inv_temp);
! 419: Dispitems[0].mi_name = Displines[0];
! 420: Dispitems[0].mi_flags = 0;
! 421: Dispitems[0].mi_val = 0;
! 422: #endif
! 423: }
! 424: /*
! 425: * Print the line for this object
! 426: */
! 427: default:
! 428: if (ch > 'z')
! 429: ch = 'A';
! 430: if (slow_invent)
! 431: msg("%c) %s", ch, inv_name(obj, FALSE));
! 432: else {
! 433: if (++cnt >= lines - 2) { /* if bottom of screen */
! 434: dbotline(hw, morestr);
! 435: cnt = 0;
! 436: wclear(hw);
! 437: }
! 438: sprintf(inv_temp, "%c) %s\n", ch, inv_name(obj, FALSE));
! 439: curx = strlen(inv_temp) - 1; /* Don't count new-line */
! 440: if (curx > maxx) maxx = curx;
! 441: waddstr(hw, inv_temp);
! 442: #ifdef PC7300
! 443: /* Put it into the PC menu display */
! 444: strcpy(Displines[n_objs-1], inv_temp);
! 445: Displines[n_objs-1][curx] = '\0'; /* Strip newline */
! 446: Dispitems[n_objs-1].mi_name = Displines[n_objs-1];
! 447: Dispitems[n_objs-1].mi_flags = 0;
! 448: Dispitems[n_objs-1].mi_val = 0;
! 449: #endif
! 450: }
! 451: }
! 452: }
! 453: if (n_objs == 0) {
! 454: if (terse)
! 455: msg(type == ALL ? "Empty handed." :
! 456: "Nothing appropriate");
! 457: else
! 458: msg(type == ALL ? "You are empty handed." :
! 459: "You don't have anything appropriate");
! 460: return FALSE;
! 461: }
! 462: if (n_objs == 1) {
! 463: msg(inv_temp);
! 464: return TRUE;
! 465: }
! 466: if (!slow_invent)
! 467: {
! 468: #ifdef PC7300
! 469: /* Place an end marker for the items */
! 470: Dispitems[n_objs].mi_name = 0;
! 471:
! 472: /* Set up the main menu structure */
! 473: Display.m_label = "Inventory";
! 474: Display.m_title = "Pack Contents";
! 475: Display.m_prompt = "Press Cancl to continue.";
! 476: Display.m_curptr = '\0';
! 477: Display.m_markptr = '\0';
! 478: Display.m_flags = 0;
! 479: Display.m_selcnt = 0;
! 480: Display.m_items = Dispitems;
! 481: Display.m_curi = 0;
! 482:
! 483: /*
! 484: * Try to display the menu. If we don't have a local terminal,
! 485: * the call will fail and we will just continue with the
! 486: * normal mode.
! 487: */
! 488: if (menu(&Display) >= 0) return TRUE;
! 489: #endif
! 490: waddstr(hw, spacemsg);
! 491: curx = strlen(spacemsg);
! 492: if (curx > maxx) maxx = curx;
! 493:
! 494: /*
! 495: * If we have fewer than half a screenful, don't clear the screen.
! 496: * Leave an extra blank line at the bottom and 3 blank columns
! 497: * to he right.
! 498: */
! 499: if (menu_overlay && n_objs < lines / 2 + 2) {
! 500: over_win(cw, hw, n_objs + 2, maxx + 3, n_objs, curx, ' ');
! 501: return TRUE;
! 502: }
! 503:
! 504: draw(hw);
! 505: wait_for(' ');
! 506: clearok(cw, TRUE);
! 507: touchwin(cw);
! 508: }
! 509: return TRUE;
! 510: }
! 511:
! 512: /*
! 513: * picky_inven:
! 514: * Allow player to inventory a single item
! 515: */
! 516: void
! 517: picky_inven(void)
! 518: {
! 519: register struct linked_list *item;
! 520: register char ch, mch;
! 521:
! 522: if (pack == NULL)
! 523: msg("You aren't carrying anything");
! 524: else if (next(pack) == NULL)
! 525: msg("a) %s", inv_name(OBJPTR(pack), FALSE));
! 526: else
! 527: {
! 528: msg(terse ? "Item: " : "Which item do you wish to inventory: ");
! 529: mpos = 0;
! 530: if ((mch = readchar()) == ESCAPE)
! 531: {
! 532: msg("");
! 533: return;
! 534: }
! 535:
! 536: /* Check for a special character */
! 537: switch (mch) {
! 538: case FOOD:
! 539: case SCROLL:
! 540: case POTION:
! 541: case RING:
! 542: case STICK:
! 543: case RELIC:
! 544: case ARMOR:
! 545: case WEAPON:
! 546: case MM:
! 547: msg("");
! 548: if (get_item(pack, NULL, mch, FALSE, FALSE) == NULL) {
! 549: if (terse) msg("None in pack.");
! 550: else msg("You have no %c in your pack.", mch);
! 551: }
! 552: return;
! 553: }
! 554:
! 555: for (ch = 'a', item = pack; item != NULL; item = next(item), ch++)
! 556: if (ch == mch)
! 557: {
! 558: msg("%c) %s",ch,inv_name(OBJPTR(item), FALSE));
! 559: return;
! 560: }
! 561: if (!terse)
! 562: msg("'%s' not in pack.", unctrl(mch));
! 563: msg("Range is 'a' to '%c'", --ch);
! 564: }
! 565: }
! 566:
! 567:
! 568: /*
! 569: * get_item:
! 570: * pick something out of a pack for a purpose
! 571: * purpose: NULL if we should be silent (no prompts)
! 572: */
! 573: struct linked_list *
! 574: get_item(struct linked_list *list, char *purpose, int type, bool askfirst,
! 575: bool showcost)
! 576: {
! 577: reg struct linked_list *item;
! 578: reg struct object *obj;
! 579: reg int cnt, pagecnt, ch, och, maxx, curx, confused;
! 580: struct linked_list *saveitem = NULL;
! 581: char description[2*LINELEN+1];
! 582: char cost[LINELEN/2];
! 583: #ifdef PC7300
! 584: int menucount = 0;
! 585: int usemenu = 1;
! 586: #endif
! 587:
! 588: /*
! 589: * If this is the player's pack and the player is confused, we
! 590: * might just take anything.
! 591: */
! 592: if (list == player.t_pack && on(player, ISHUH) && rnd(100) < 75)
! 593: confused = 1;
! 594: else confused = 0;
! 595:
! 596: cnt = 0;
! 597: if (list == NULL) {
! 598: msg("You aren't carrying anything.");
! 599: return NULL;
! 600: }
! 601: /* see if we have any of the type requested */
! 602: for(ch = 'a',item = list ; item != NULL ; item = next(item), ch++) {
! 603: obj = OBJPTR(item);
! 604: if (is_type(obj, type)) {
! 605: cnt++;
! 606: saveitem = item;
! 607: }
! 608: }
! 609: if (cnt == 0) {
! 610: if (purpose) msg("Nothing to %s", purpose);
! 611: after = FALSE;
! 612: return NULL;
! 613: }
! 614: else if (cnt == 1) { /* only found one of 'em */
! 615: obj = OBJPTR(saveitem);
! 616: while(TRUE) {
! 617: if (purpose) { /* Should we prompt the player? */
! 618: msg("%s what (* for the item)?",purpose);
! 619: ch = tolower(readchar());
! 620: }
! 621: else {
! 622: ch = pack_char(list, obj);
! 623: msg("%c) %s", ch, inv_name(obj,FALSE));
! 624: }
! 625:
! 626: if (ch == '*') {
! 627: mpos = 0;
! 628: msg("%c) %s",pack_char(list, obj),inv_name(obj,FALSE));
! 629: continue;
! 630: }
! 631: if (ch == ESCAPE) {
! 632: msg("");
! 633: after = FALSE;
! 634: return NULL;
! 635: }
! 636: for(item = list,och = 'a'; item != NULL; item = next(item),och++) {
! 637: if (ch == och) break;
! 638: if (och == 'z') och = 'A' - 1;
! 639: }
! 640: if (item == NULL) {
! 641: msg("Please specify a letter between 'a' and '%c'",
! 642: och == 'A' ? 'z' : och-1);
! 643: continue;
! 644: }
! 645: if (is_type (OBJPTR(item), type)) {
! 646: if (purpose) mpos = 0;
! 647: return item;
! 648: }
! 649: else
! 650: msg ("You can't %s that!", purpose);
! 651:
! 652: }
! 653: }
! 654: while (TRUE) {
! 655: if (!askfirst && purpose) {
! 656: msg("%s what? (* for list): ",purpose);
! 657: ch = readchar();
! 658: }
! 659: else ch = '*';
! 660:
! 661: mpos = 0;
! 662: if (ch == ESCAPE) { /* abort if escape hit */
! 663: after = FALSE;
! 664: msg(""); /* clear display */
! 665: return NULL;
! 666: }
! 667:
! 668: if (ch == '*') {
! 669: wclear(hw);
! 670: pagecnt = 0;
! 671: maxx = 0;
! 672: for(item = list,ch = 'a'; item != NULL ; item = next(item), ch++) {
! 673: obj = OBJPTR(item);
! 674: if (!is_type(OBJPTR(item), type))
! 675: continue;
! 676: cost[0] = '\0';
! 677: if (showcost) {
! 678: sprintf(description, "[%d] ", get_worth(obj));
! 679: sprintf(cost, "%8.8s", description);
! 680: }
! 681: sprintf(description,"%c) %s%s\n\r",ch,cost,inv_name(obj,FALSE));
! 682: waddstr(hw, description);
! 683: curx = strlen(description) - 2; /* Don't count \n or \r */
! 684: if (maxx < curx) maxx = curx;
! 685: #ifdef PC7300
! 686: if (usemenu) {
! 687: /* Put it into the PC menu display */
! 688: strcpy(Displines[menucount], description);
! 689: Displines[menucount][curx] = '\0'; /* Strip newline */
! 690: Dispitems[menucount].mi_name = Displines[menucount];
! 691: Dispitems[menucount].mi_flags = 0;
! 692: Dispitems[menucount++].mi_val = (int) item;
! 693: }
! 694: #endif
! 695: if (++pagecnt >= lines - 2 && next(item) != NULL) {
! 696: pagecnt = 0;
! 697: dbotline(hw, spacemsg);
! 698: wclear(hw);
! 699: }
! 700: if (ch == 'z') ch = 'A' - 1;
! 701: }
! 702:
! 703: /* Put in the prompt */
! 704: if (purpose) sprintf(description, "%s what? ", purpose);
! 705: else strcpy(description, spacemsg);
! 706: waddstr(hw, description);
! 707: curx = strlen(description);
! 708: if (maxx < curx) maxx = curx;
! 709:
! 710: #ifdef PC7300
! 711: if (usemenu) {
! 712: /* Place an end marker for the items */
! 713: Dispitems[menucount].mi_name = 0;
! 714:
! 715: /* Set up the main menu structure */
! 716: Display.m_label = "Sub-Inventory";
! 717: if (purpose) {
! 718: Display.m_title = description;
! 719: Display.m_prompt =
! 720: "Select an item or press Cancl for no selection.";
! 721: Display.m_selcnt = 1;
! 722: }
! 723: else {
! 724: Display.m_title = 0;
! 725: Display.m_prompt = "Press Cancl to continue.";
! 726: Display.m_selcnt = 0;
! 727: }
! 728: Display.m_curptr = '\0';
! 729: Display.m_markptr = '\0';
! 730: Display.m_flags = 0;
! 731: Display.m_items = Dispitems;
! 732: Display.m_curi = 0;
! 733:
! 734: /*
! 735: * Try to display the menu. If we don't have a local terminal,
! 736: * the call will fail and we will just continue with the
! 737: * normal mode.
! 738: */
! 739: if (menu(&Display) >= 0) {
! 740: msg("");
! 741: if (Display.m_selcnt == 0) {
! 742: /* Menu was cancelled */
! 743: if (purpose) {
! 744: after = FALSE;
! 745: return NULL; /* all done if abort */
! 746: }
! 747: else return saveitem;
! 748: }
! 749: else return (struct linked_list *) Display.m_curi->mi_val;
! 750: }
! 751: else {
! 752: usemenu = 0; /* Can't use the menu facilities */
! 753: }
! 754: }
! 755: #endif
! 756: /* Write the screen */
! 757: if ((menu_overlay && cnt < lines / 2 + 2) || cnt == 1) {
! 758: over_win(cw, hw, cnt + 2, maxx + 3, cnt, curx, '\0');
! 759: cnt = -1; /* Indicate we used over_win */
! 760: }
! 761: else draw(hw);
! 762:
! 763: if (purpose) {
! 764: do {
! 765: ch = tolower(readchar());
! 766: } until (isalpha(ch) || ch == ESCAPE);
! 767: }
! 768: else {
! 769: ch = pack_char(list, OBJPTR(saveitem)); /* Pick a valid item */
! 770: wait_for(' ');
! 771: }
! 772:
! 773: /* Redraw original screen */
! 774: if (cnt < 0) {
! 775: clearok(cw, FALSE); /* Setup to redraw current screen */
! 776: touchwin(cw); /* clearing first */
! 777: }
! 778: else restscr(cw);
! 779:
! 780: if(ch == ESCAPE) {
! 781: after = FALSE;
! 782: msg(""); /* clear top line */
! 783: return NULL; /* all done if abort */
! 784: }
! 785: /* ch has item to get from list */
! 786: }
! 787:
! 788: for (item = list,och = 'a'; item != NULL; item = next(item),och++) {
! 789: if (confused) {
! 790: /*
! 791: * Confused is incremented each time so that if the rnd(cnt)
! 792: * clause keeps failing, confused will equal cnt for the
! 793: * last item of the correct type and rnd(cnt) < cnt will
! 794: * have to be true.
! 795: */
! 796: if (is_type(OBJPTR(item), type) && rnd(cnt) < confused++)
! 797: break;
! 798: }
! 799: else if (ch == och) break;
! 800: if (och == 'z') och = 'A' - 1;
! 801: }
! 802:
! 803: if (item == NULL) {
! 804: msg("Please specify a letter between 'a' and '%c'",
! 805: och == 'A' ? 'z' : och-1);
! 806: continue;
! 807: }
! 808:
! 809: if (is_type(OBJPTR(item), type))
! 810: return (item);
! 811: else
! 812: msg ("You can't %s that!", purpose);
! 813: }
! 814: }
! 815:
! 816: char
! 817: pack_char(struct linked_list *list, struct object *obj)
! 818: {
! 819: register struct linked_list *item;
! 820: register char c;
! 821:
! 822: c = 'a';
! 823: for (item = list; item != NULL; item = next(item)) {
! 824: if (OBJPTR(item) == obj)
! 825: return c;
! 826: else {
! 827: if (c == 'z') c = 'A';
! 828: else c++;
! 829: }
! 830: }
! 831: return 'z';
! 832: }
! 833:
! 834:
! 835: /*
! 836: * cur_null:
! 837: * This updates cur_weapon etc for dropping things
! 838: */
! 839: void
! 840: cur_null(struct object *op)
! 841: {
! 842: if (op == cur_weapon) cur_weapon = NULL;
! 843: else if (op == cur_armor) cur_armor = NULL;
! 844: else if (op == cur_ring[LEFT_1]) cur_ring[LEFT_1] = NULL;
! 845: else if (op == cur_ring[LEFT_2]) cur_ring[LEFT_2] = NULL;
! 846: else if (op == cur_ring[LEFT_3]) cur_ring[LEFT_3] = NULL;
! 847: else if (op == cur_ring[LEFT_4]) cur_ring[LEFT_4] = NULL;
! 848: else if (op == cur_ring[RIGHT_1]) cur_ring[RIGHT_1] = NULL;
! 849: else if (op == cur_ring[RIGHT_2]) cur_ring[RIGHT_2] = NULL;
! 850: else if (op == cur_ring[RIGHT_3]) cur_ring[RIGHT_3] = NULL;
! 851: else if (op == cur_ring[RIGHT_4]) cur_ring[RIGHT_4] = NULL;
! 852: else if (op == cur_misc[WEAR_BOOTS]) cur_misc[WEAR_BOOTS] = NULL;
! 853: else if (op == cur_misc[WEAR_JEWEL]) cur_misc[WEAR_JEWEL] = NULL;
! 854: else if (op == cur_misc[WEAR_GAUNTLET]) cur_misc[WEAR_GAUNTLET] = NULL;
! 855: else if (op == cur_misc[WEAR_CLOAK]) cur_misc[WEAR_CLOAK] = NULL;
! 856: else if (op == cur_misc[WEAR_BRACERS]) cur_misc[WEAR_BRACERS] = NULL;
! 857: else if (op == cur_misc[WEAR_NECKLACE]) cur_misc[WEAR_NECKLACE] = NULL;
! 858: }
! 859:
! 860: /*
! 861: * idenpack:
! 862: * Identify all the items in the pack
! 863: */
! 864: void
! 865: idenpack(void)
! 866: {
! 867: reg struct linked_list *pc;
! 868:
! 869: for (pc = pack ; pc != NULL ; pc = next(pc))
! 870: whatis(pc);
! 871: }
! 872:
! 873: bool
! 874: is_type (struct object *obj, int type)
! 875: {
! 876: register bool current;
! 877:
! 878: if (type == obj->o_type)
! 879: return (TRUE);
! 880:
! 881: switch (type) {
! 882: case ALL:
! 883: return (TRUE);
! 884: when READABLE:
! 885: if (obj->o_type == SCROLL ||
! 886: (obj->o_type == MM && obj->o_which == MM_SKILLS))
! 887: return (TRUE);
! 888: when QUAFFABLE:
! 889: if (obj->o_type == POTION ||
! 890: (obj->o_type == MM && obj->o_which == MM_JUG))
! 891: return (TRUE);
! 892: when ZAPPABLE:
! 893: if (obj->o_type == STICK) return (TRUE);
! 894: if (obj->o_type == RELIC)
! 895: switch (obj->o_which) {
! 896: case MING_STAFF:
! 897: case ASMO_ROD:
! 898: case ORCUS_WAND:
! 899: case EMORI_CLOAK:
! 900: return (TRUE);
! 901: }
! 902: when WEARABLE:
! 903: case REMOVABLE:
! 904: current = is_current(obj);
! 905:
! 906: /*
! 907: * Don't wear thing we are already wearing or remove things
! 908: * we aren't wearing.
! 909: */
! 910: if (type == WEARABLE && current) return (FALSE);
! 911: else if (type == REMOVABLE && !current) return (FALSE);
! 912:
! 913: switch (obj->o_type) {
! 914: case RELIC:
! 915: switch (obj->o_which) {
! 916: case HEIL_ANKH:
! 917: case EMORI_CLOAK:
! 918: return (TRUE);
! 919: }
! 920: when MM:
! 921: switch (obj->o_which) {
! 922: case MM_ELF_BOOTS:
! 923: case MM_DANCE:
! 924: case MM_BRACERS:
! 925: case MM_DISP:
! 926: case MM_PROTECT:
! 927: case MM_G_DEXTERITY:
! 928: case MM_G_OGRE:
! 929: case MM_JEWEL:
! 930: case MM_R_POWERLESS:
! 931: case MM_FUMBLE:
! 932: case MM_STRANGLE:
! 933: case MM_ADAPTION:
! 934: return (TRUE);
! 935: }
! 936: when ARMOR:
! 937: case RING:
! 938: return (TRUE);
! 939: }
! 940: when CALLABLE:
! 941: switch (obj->o_type) {
! 942: case RING: if (!r_know[obj->o_which]) return(TRUE);
! 943: when POTION: if (!p_know[obj->o_which]) return(TRUE);
! 944: when STICK: if (!ws_know[obj->o_which]) return(TRUE);
! 945: when SCROLL: if (!s_know[obj->o_which]) return(TRUE);
! 946: when MM: if (!m_know[obj->o_which]) return(TRUE);
! 947: }
! 948: when WIELDABLE:
! 949: switch (obj->o_type) {
! 950: case STICK:
! 951: case WEAPON:
! 952: return(TRUE);
! 953: when RELIC:
! 954: switch (obj->o_which) {
! 955: case MUSTY_DAGGER:
! 956: case HRUGGEK_MSTAR:
! 957: case YEENOGHU_FLAIL:
! 958: case AXE_AKLAD:
! 959: case MING_STAFF:
! 960: case ORCUS_WAND:
! 961: case ASMO_ROD:
! 962: return(TRUE);
! 963: }
! 964: }
! 965: when IDENTABLE:
! 966: if (!(obj->o_flags & ISKNOW) && obj->o_type != FOOD)
! 967: return (TRUE);
! 968: if (obj->o_type == MM) {
! 969: switch (obj->o_which) {
! 970: case MM_JUG:
! 971: /* Can still identify a jug if we don't know the potion */
! 972: if (obj->o_ac != JUG_EMPTY && !p_know[obj->o_ac])
! 973: return (TRUE);
! 974: }
! 975: }
! 976: when USEABLE:
! 977: if (obj->o_type == MM) {
! 978: switch(obj->o_which) {
! 979: case MM_BEAKER:
! 980: case MM_BOOK:
! 981: case MM_OPEN:
! 982: case MM_HUNGER:
! 983: case MM_DRUMS:
! 984: case MM_DISAPPEAR:
! 985: case MM_CHOKE:
! 986: case MM_KEOGHTOM:
! 987: return (TRUE);
! 988: }
! 989: }
! 990: else if (obj->o_type == RELIC) {
! 991: switch (obj->o_which) {
! 992: case EMORI_CLOAK:
! 993: case BRIAN_MANDOLIN:
! 994: case HEIL_ANKH:
! 995: case YENDOR_AMULET:
! 996: case STONEBONES_AMULET:
! 997: case GERYON_HORN:
! 998: case EYE_VECNA:
! 999: case QUILL_NAGROM:
! 1000: case SURTUR_RING:
! 1001: return (TRUE);
! 1002: }
! 1003: }
! 1004: else if (obj->o_type == POTION) {
! 1005: /*
! 1006: * only assassins can use poison
! 1007: */
! 1008: if (player.t_ctype == C_ASSASIN && obj->o_which == P_POISON)
! 1009: return(TRUE);
! 1010: }
! 1011: when PROTECTABLE:
! 1012: switch (obj->o_type) {
! 1013: case WEAPON:
! 1014: if ((obj->o_flags & ISMETAL) == 0) return (FALSE);
! 1015:
! 1016: /* Fall through */
! 1017: case ARMOR:
! 1018: return (TRUE);
! 1019:
! 1020: when MM:
! 1021: if (obj->o_which == MM_BRACERS) return (TRUE);
! 1022: }
! 1023: }
! 1024: return(FALSE);
! 1025: }
! 1026:
! 1027: void
! 1028: del_pack(struct linked_list *item)
! 1029: {
! 1030: register struct object *obj;
! 1031:
! 1032: obj = OBJPTR(item);
! 1033: if (obj->o_count > 1) {
! 1034: obj->o_count--;
! 1035: }
! 1036: else {
! 1037: cur_null(obj);
! 1038: detach(pack, item);
! 1039: o_discard(item);
! 1040: inpack--;
! 1041: }
! 1042: }
! 1043:
! 1044: /*
! 1045: * carry_obj:
! 1046: * Check to see if a monster is carrying something and, if so, give
! 1047: * it to him.
! 1048: */
! 1049:
! 1050: void
! 1051: carry_obj(struct thing *mp, int chance)
! 1052: {
! 1053: reg struct linked_list *item;
! 1054: reg struct object *obj;
! 1055:
! 1056: /*
! 1057: * If there is no chance, just return.
! 1058: * Note that this means there must be a "chance" in order for
! 1059: * the creature to carry a relic.
! 1060: */
! 1061: if (chance <= 0) return;
! 1062:
! 1063: /*
! 1064: * check for the relic/artifacts
! 1065: * Do the relics first so they end up last in the pack. Attach()
! 1066: * always adds things to the beginning. This way they will be the
! 1067: * last things dropped when the creature is killed. This will ensure
! 1068: * the relic will be on top if there is a stack of item lying on the
! 1069: * floor and so the hero will know where it is if he's trying to
! 1070: * avoid it. Note that only UNIQUEs carry relics.
! 1071: */
! 1072: if (on(*mp, ISUNIQUE)) {
! 1073: if (on(*mp, CARRYMDAGGER)) {
! 1074: item = spec_item(RELIC, MUSTY_DAGGER, 0, 0);
! 1075: obj = OBJPTR(item);
! 1076: obj->o_pos = mp->t_pos;
! 1077: attach(mp->t_pack, item);
! 1078: }
! 1079:
! 1080: if (on(*mp, CARRYCLOAK)) {
! 1081: item = spec_item(RELIC, EMORI_CLOAK, 0, 0);
! 1082: obj = OBJPTR(item);
! 1083: obj->o_pos = mp->t_pos;
! 1084: attach(mp->t_pack, item);
! 1085: }
! 1086:
! 1087: if (on(*mp, CARRYANKH)) {
! 1088: item = spec_item(RELIC, HEIL_ANKH, 0, 0);
! 1089: obj = OBJPTR(item);
! 1090: obj->o_pos = mp->t_pos;
! 1091: attach(mp->t_pack, item);
! 1092: }
! 1093:
! 1094: if (on(*mp, CARRYSTAFF)) {
! 1095: item = spec_item(RELIC, MING_STAFF, 0, 0);
! 1096: obj = OBJPTR(item);
! 1097: obj->o_pos = mp->t_pos;
! 1098: attach(mp->t_pack, item);
! 1099: }
! 1100:
! 1101: if (on(*mp, CARRYWAND)) {
! 1102: item = spec_item(RELIC, ORCUS_WAND, 0, 0);
! 1103: obj = OBJPTR(item);
! 1104: obj->o_pos = mp->t_pos;
! 1105: attach(mp->t_pack, item);
! 1106: }
! 1107:
! 1108: if (on(*mp, CARRYROD)) {
! 1109: item = spec_item(RELIC, ASMO_ROD, 0, 0);
! 1110: obj = OBJPTR(item);
! 1111: obj->o_pos = mp->t_pos;
! 1112: attach(mp->t_pack, item);
! 1113: }
! 1114:
! 1115: if (on(*mp, CARRYYAMULET)) {
! 1116: item = spec_item(RELIC, YENDOR_AMULET, 0, 0);
! 1117: obj = OBJPTR(item);
! 1118: obj->o_pos = mp->t_pos;
! 1119: attach(mp->t_pack, item);
! 1120: }
! 1121:
! 1122: if (on(*mp, CARRYBAMULET)) {
! 1123: item = spec_item(RELIC, STONEBONES_AMULET, 0, 0);
! 1124: obj = OBJPTR(item);
! 1125: obj->o_pos = mp->t_pos;
! 1126: attach(mp->t_pack, item);
! 1127: }
! 1128:
! 1129: if (on(*mp, CARRYMANDOLIN)) {
! 1130: item = spec_item(RELIC, BRIAN_MANDOLIN, 0, 0);
! 1131: obj = OBJPTR(item);
! 1132: obj->o_pos = mp->t_pos;
! 1133: attach(mp->t_pack, item);
! 1134: }
! 1135: if (on(*mp, CARRYEYE)) {
! 1136: item = spec_item(RELIC, EYE_VECNA, 0, 0);
! 1137: obj = OBJPTR(item);
! 1138: obj->o_pos = mp->t_pos;
! 1139: attach(mp->t_pack, item);
! 1140: }
! 1141: if (on(*mp, CARRYAXE)) {
! 1142: item = spec_item(RELIC, AXE_AKLAD, 0, 0);
! 1143: obj = OBJPTR(item);
! 1144: obj->o_pos = mp->t_pos;
! 1145: attach(mp->t_pack, item);
! 1146: }
! 1147: if (on(*mp, CARRYQUILL)) {
! 1148: register int i, howmany;
! 1149:
! 1150: item = spec_item(RELIC, QUILL_NAGROM, 0, 0);
! 1151: obj = OBJPTR(item);
! 1152: obj->o_pos = mp->t_pos;
! 1153: obj->o_charges = rnd(QUILLCHARGES);
! 1154: attach(mp->t_pack, item);
! 1155: howmany = roll(4,3);
! 1156: for (i=0; i<howmany; i++) {
! 1157: /*
! 1158: * the quill writes scrolls so give him a bunch
! 1159: */
! 1160: item = new_thing(TYP_SCROLL, FALSE);
! 1161: obj = OBJPTR(item);
! 1162: obj->o_pos = mp->t_pos;
! 1163: attach(mp->t_pack, item);
! 1164: }
! 1165: }
! 1166: if (on(*mp, CARRYMSTAR)) {
! 1167: item = spec_item(RELIC, HRUGGEK_MSTAR, 0, 0);
! 1168: obj = OBJPTR(item);
! 1169: obj->o_pos = mp->t_pos;
! 1170: attach(mp->t_pack, item);
! 1171: }
! 1172: if (on(*mp, CARRYFLAIL)) {
! 1173: item = spec_item(RELIC, YEENOGHU_FLAIL, 0, 0);
! 1174: obj = OBJPTR(item);
! 1175: obj->o_pos = mp->t_pos;
! 1176: attach(mp->t_pack, item);
! 1177: }
! 1178: if (on(*mp, CARRYHORN)) {
! 1179: item = spec_item(RELIC, GERYON_HORN, 0, 0);
! 1180: obj = OBJPTR(item);
! 1181: obj->o_pos = mp->t_pos;
! 1182: attach(mp->t_pack, item);
! 1183: }
! 1184: if (on(*mp, CARRYSURTURRING)) {
! 1185: item = spec_item(RELIC, SURTUR_RING, 0, 0);
! 1186: obj = OBJPTR(item);
! 1187: obj->o_pos = mp->t_pos;
! 1188: attach(mp->t_pack, item);
! 1189: }
! 1190: }
! 1191: /*
! 1192: * If it carries gold, give it some
! 1193: */
! 1194: if (on(*mp, CARRYGOLD) && rnd(100) < chance) {
! 1195: item = spec_item(GOLD, 0, 0, 0);
! 1196: obj = OBJPTR(item);
! 1197: obj->o_count = GOLDCALC + GOLDCALC;
! 1198: obj->o_pos = mp->t_pos;
! 1199: attach(mp->t_pack, item);
! 1200: }
! 1201:
! 1202: /*
! 1203: * If it carries food, give it some
! 1204: */
! 1205: if (on(*mp, CARRYFOOD) && rnd(100) < chance) {
! 1206: item = spec_item(FOOD, 0, 0, 0);
! 1207: obj = OBJPTR(item);
! 1208: obj->o_weight = things[TYP_FOOD].mi_wght;
! 1209: obj->o_pos = mp->t_pos;
! 1210: attach(mp->t_pack, item);
! 1211: }
! 1212:
! 1213: /*
! 1214: * If it carries a weapon, give it one
! 1215: */
! 1216: if (on(*mp, CARRYWEAPON) && rnd(100) < chance) {
! 1217: int type, hit, dam;
! 1218:
! 1219: /* Get the "bonuses" */
! 1220: hit = rnd(5 + (vlevel / 5)) - 2;
! 1221: dam = rnd(5 + (vlevel / 5)) - 2;
! 1222:
! 1223: /* Only choose an appropriate type of weapon */
! 1224: switch (rnd(12)) {
! 1225: case 0: type = DAGGER;
! 1226: when 1: type = BATTLEAXE;
! 1227: when 2: type = MACE;
! 1228: when 3: type = SWORD;
! 1229: when 4: type = PIKE;
! 1230: when 5: type = HALBERD;
! 1231: when 6: type = SPETUM;
! 1232: when 7: type = BARDICHE;
! 1233: when 8: type = TRIDENT;
! 1234: when 9: type = BASWORD;
! 1235: when 10:type = DART;
! 1236: otherwise: type = TWOSWORD;
! 1237: }
! 1238:
! 1239: /* Create the item */
! 1240: item = spec_item(WEAPON, type, hit, dam);
! 1241: obj = OBJPTR(item);
! 1242: obj->o_pos = mp->t_pos;
! 1243: attach(mp->t_pack, item);
! 1244: }
! 1245:
! 1246: /*
! 1247: * If it carries a dagger, give it one
! 1248: */
! 1249: if (on(*mp, CARRYDAGGER) && rnd(100) < chance) {
! 1250: int hit, dam;
! 1251:
! 1252: /* Get the "bonuses" */
! 1253: hit = rnd(3 + (vlevel / 5)) - 1;
! 1254: dam = rnd(3 + (vlevel / 5)) - 1;
! 1255:
! 1256: /* Create the item */
! 1257: item = spec_item(WEAPON, DAGGER, hit, dam);
! 1258: obj = OBJPTR(item);
! 1259: obj->o_pos = mp->t_pos;
! 1260: attach(mp->t_pack, item);
! 1261: }
! 1262:
! 1263: /*
! 1264: * If it carries a scroll, give it one
! 1265: */
! 1266: if (on(*mp, CARRYSCROLL) && rnd(100) < chance) {
! 1267: item = new_thing(TYP_SCROLL, TRUE);
! 1268: obj = OBJPTR(item);
! 1269: obj->o_pos = mp->t_pos;
! 1270:
! 1271: /* Can the monster carry this scroll? */
! 1272: if (obj->o_which == S_SCARE && mp->t_stats.s_intel < 16)
! 1273: fall(item, FALSE); /* This would scare us! */
! 1274: else attach(mp->t_pack, item);
! 1275: }
! 1276:
! 1277: /*
! 1278: * If it carries a potion, give it one
! 1279: */
! 1280: if (on(*mp, CARRYPOTION) && rnd(100) < chance) {
! 1281: item = new_thing(TYP_POTION, TRUE);
! 1282: obj = OBJPTR(item);
! 1283: obj->o_pos = mp->t_pos;
! 1284: attach(mp->t_pack, item);
! 1285: }
! 1286:
! 1287: /*
! 1288: * If it carries a ring, give it one
! 1289: */
! 1290: if (on(*mp, CARRYRING) && rnd(100) < chance) {
! 1291: item = new_thing(TYP_RING, TRUE);
! 1292: obj = OBJPTR(item);
! 1293: obj->o_pos = mp->t_pos;
! 1294: attach(mp->t_pack, item);
! 1295: }
! 1296:
! 1297: /*
! 1298: * If it carries a wand or staff, give it one
! 1299: */
! 1300: if (on(*mp, CARRYSTICK) && rnd(100) < chance) {
! 1301: item = new_thing(TYP_STICK, TRUE);
! 1302: obj = OBJPTR(item);
! 1303: obj->o_pos = mp->t_pos;
! 1304: attach(mp->t_pack, item);
! 1305: }
! 1306:
! 1307: /*
! 1308: * If it carries any miscellaneous magic, give it one
! 1309: */
! 1310: if (on(*mp, CARRYMISC) && rnd(100) < chance) {
! 1311: item = new_thing(TYP_MM, TRUE);
! 1312: obj = OBJPTR(item);
! 1313: obj->o_pos = mp->t_pos;
! 1314: attach(mp->t_pack, item);
! 1315: }
! 1316:
! 1317: /* Update the monster's encumberance */
! 1318: updpack(TRUE, mp);
! 1319: }
! 1320:
! 1321:
! 1322: /*
! 1323: * grab():
! 1324: * See what is on the spot where the player is standing. If
! 1325: * nothing is there, do nothing. If there is one thing, pick it
! 1326: * up. If there are multiple things, prompt the player for what
! 1327: * he wants (* means everything).
! 1328: */
! 1329:
! 1330: int
! 1331: grab(int y, int x)
! 1332: {
! 1333: register struct linked_list *next_item, *item;
! 1334: register struct object *obj;
! 1335: register int cnt, pagecnt;
! 1336: int num_there = 0, ch, och;
! 1337:
! 1338: /*
! 1339: * Count how many objects there are and move them to the front
! 1340: * of the level list.
! 1341: */
! 1342: for (item = lvl_obj; item != NULL; item = next_item) {
! 1343: obj = OBJPTR(item);
! 1344: next_item = next(item);
! 1345: if (obj->o_pos.y == y && obj->o_pos.x == x) {
! 1346: num_there++;
! 1347: detach(lvl_obj, item); /* Remove it from the list */
! 1348: attach(lvl_obj, item); /* Place it at the front of the list */
! 1349: }
! 1350: }
! 1351:
! 1352: /* Nothing there. */
! 1353: if (num_there < 1) msg("Nothing %s", terse ? "there." : "to pick up.");
! 1354:
! 1355: /* Something or things there */
! 1356: else {
! 1357: char linebuf[2*LINELEN+1];
! 1358: int curlen, maxlen = 0;
! 1359:
! 1360: wclear(hw);
! 1361: cnt = 0;
! 1362: pagecnt = 0;
! 1363: for (item = lvl_obj, ch = 'a'; item != NULL && cnt < num_there;
! 1364: item = next(item), ch++, cnt++) {
! 1365: obj = OBJPTR(item);
! 1366: /* Construct how the line will look */
! 1367: sprintf(linebuf, "%c) %s\n\r", ch, inv_name(obj,FALSE));
! 1368:
! 1369: /* See how long it is */
! 1370: curlen = strlen(linebuf) - 2; /* Don't count \n or \r */
! 1371: if (maxlen < curlen) maxlen = curlen;
! 1372:
! 1373: /* Draw it in the window */
! 1374: waddstr(hw, linebuf);
! 1375:
! 1376: if (++pagecnt >= lines - 2 && next(item) != NULL) {
! 1377: pagecnt = 0;
! 1378: maxlen = 0;
! 1379: dbotline(hw, spacemsg);
! 1380: wclear(hw);
! 1381: }
! 1382: if (ch == 'z') ch = 'A' - 1;
! 1383: }
! 1384:
! 1385: strcpy(linebuf, "Pick up what? (* for all): ");
! 1386:
! 1387: /* See how long it is */
! 1388: curlen = strlen(linebuf); /* Don't count \n or \r */
! 1389: if (maxlen < curlen) maxlen = curlen;
! 1390:
! 1391: /* Draw it in the window */
! 1392: waddstr(hw, linebuf);
! 1393:
! 1394: /*
! 1395: * If we have fewer than half a screenful, don't clear the screen.
! 1396: * Leave an extra blank line at the bottom and 3 blank columns
! 1397: * to he right.
! 1398: */
! 1399: if (menu_overlay && num_there < lines / 2 + 2) {
! 1400: over_win(cw, hw, num_there + 2, maxlen + 3, num_there, curlen, '\0');
! 1401: pagecnt = -1; /* Indicate we used over_win */
! 1402: }
! 1403: else draw(hw); /* write screen */
! 1404:
! 1405: for (;;) {
! 1406: do {
! 1407: ch = tolower(readchar());
! 1408: } until (isalpha(ch) || ch == '*' || ch == ESCAPE);
! 1409:
! 1410: /* Redraw original screen */
! 1411: if (pagecnt < 0) {
! 1412: clearok(cw, FALSE); /* Setup to redraw current screen */
! 1413: touchwin(cw); /* clearing first */
! 1414: }
! 1415: else restscr(cw);
! 1416:
! 1417: if (ch == ESCAPE) {
! 1418: after = FALSE;
! 1419: msg(""); /* clear top line */
! 1420: break;
! 1421: }
! 1422: if (ch == '*') {
! 1423: player.t_action = A_PICKUP;
! 1424: return(1); /* set action to PICKUP and delay for first one */
! 1425: }
! 1426: /* ch has item to get from list */
! 1427:
! 1428: cnt = 0;
! 1429: for (item = lvl_obj, och = 'a'; item != NULL && cnt < num_there;
! 1430: item = next(item), och++, cnt++) {
! 1431: if (ch == och)
! 1432: break;
! 1433: if (och == 'z') och = 'A' - 1;
! 1434: }
! 1435: if (item == NULL || cnt >= num_there) {
! 1436: wmove(hw, pagecnt < 0 ? num_there : pagecnt, 25);
! 1437: wprintw(hw, " [between 'a' and '%c']: ",
! 1438: och == 'A' ? 'z' : och-1);
! 1439: if (maxlen < 49) maxlen = 49;
! 1440:
! 1441: /*
! 1442: * If we have fewer than half a screenful, don't clear the
! 1443: * screen. Leave an extra blank line at the bottom and
! 1444: * 3 blank columns to he right.
! 1445: */
! 1446: if (menu_overlay && num_there < lines / 2 + 2) {
! 1447: over_win(cw, hw, num_there + 2, maxlen + 3,
! 1448: num_there, 49, '\0');
! 1449: cnt = -1; /* Indicate we used over_win */
! 1450: }
! 1451: else draw(hw); /* write screen */
! 1452: continue;
! 1453: }
! 1454: else {
! 1455: detach(lvl_obj, item);
! 1456: if (add_pack(item, FALSE, NULL)) {
! 1457: /*
! 1458: * We make sure here that the dungeon floor gets
! 1459: * updated with what's left on the vacated spot.
! 1460: */
! 1461: if ((item = find_obj(y, x)) == NULL) {
! 1462: coord roomcoord; /* Needed to pass to roomin() */
! 1463:
! 1464: roomcoord.y = y;
! 1465: roomcoord.x = x;
! 1466: mvaddch(y, x,
! 1467: (roomin(&roomcoord) == NULL ? PASSAGE : FLOOR));
! 1468: }
! 1469: else mvaddch(y, x, (OBJPTR(item))->o_type);
! 1470: return(1);
! 1471: }
! 1472: else attach(lvl_obj, item); /* Couldn't pick it up! */
! 1473: break;
! 1474: }
! 1475: }
! 1476: }
! 1477:
! 1478: return(0);
! 1479: }
! 1480:
! 1481: /*
! 1482: * make_sell_pack:
! 1483: *
! 1484: * Create a pack for sellers (a la quartermaster)
! 1485: */
! 1486:
! 1487: void
! 1488: make_sell_pack(struct thing *tp)
! 1489: {
! 1490: reg struct linked_list *item;
! 1491: reg struct object *obj;
! 1492: reg int sell_type, nitems, i;
! 1493:
! 1494: /* Select the items */
! 1495: nitems = rnd(6) + 5;
! 1496:
! 1497: switch (rnd(9)) {
! 1498: /* Armor */
! 1499: case 0:
! 1500: case 1:
! 1501: turn_on(*tp, CARRYARMOR);
! 1502: sell_type = TYP_ARMOR;
! 1503: break;
! 1504:
! 1505: /* Weapon */
! 1506: case 2:
! 1507: case 3:
! 1508: turn_on(*tp, CARRYWEAPON);
! 1509: sell_type = TYP_WEAPON;
! 1510: break;
! 1511:
! 1512: /* Staff or wand */
! 1513: case 4:
! 1514: turn_on(*tp, CARRYSTICK);
! 1515: sell_type = TYP_STICK;
! 1516: break;
! 1517:
! 1518: /* Ring */
! 1519: case 5:
! 1520: turn_on(*tp, CARRYRING);
! 1521: sell_type = TYP_RING;
! 1522: break;
! 1523:
! 1524: /* scroll */
! 1525: case 6:
! 1526: turn_on(*tp, CARRYSCROLL);
! 1527: sell_type = TYP_SCROLL;
! 1528: break;
! 1529:
! 1530: /* potions */
! 1531: case 7:
! 1532: turn_on(*tp, CARRYPOTION);
! 1533: sell_type = TYP_POTION;
! 1534: break;
! 1535:
! 1536: /* Miscellaneous magic */
! 1537: case 8:
! 1538: turn_on(*tp, CARRYMISC);
! 1539: sell_type = TYP_MM;
! 1540: break;
! 1541: }
! 1542: for (i=0; i<nitems; i++) {
! 1543: item = new_thing(sell_type, FALSE);
! 1544: obj = OBJPTR(item);
! 1545: obj->o_pos = tp->t_pos;
! 1546: attach(tp->t_pack, item);
! 1547: }
! 1548: }
CVSweb