[BACK]Return to pack.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / arogue7

Annotation of early-roguelike/arogue7/pack.c, Revision 1.1.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