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