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

Annotation of early-roguelike/arogue5/pack.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * Routines to deal with the pack
                      3:  *
                      4:  * Advanced Rogue
                      5:  * Copyright (C) 1984, 1985 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 "rogue.h"
                     18:
                     19: char outstring[512];   /* ridiculously long string for use with msg */
                     20:
                     21: bool is_type (struct object *obj, int type);
                     22:
                     23: /*
                     24:  * add_pack:
                     25:  *     Pick up an object and add it to the pack.  If the argument is non-null
                     26:  * use it as the linked_list pointer instead of gettting it off the ground.
                     27:  */
                     28: bool
                     29: add_pack(struct linked_list *item, bool silent, struct linked_list **packret)
                     30: {
                     31:     register struct linked_list *ip, *lp = NULL, *ap;
                     32:     register struct object *obj, *op = NULL;
                     33:     register bool exact, from_floor;
                     34:
                     35:     if (packret != NULL)
                     36:        *packret = NULL;
                     37:
                     38:     if (item == NULL)
                     39:     {
                     40:        from_floor = TRUE;
                     41:        if ((item = find_obj(hero.y, hero.x)) == NULL)
                     42:            return(FALSE);
                     43:     }
                     44:     else
                     45:        from_floor = FALSE;
                     46:     obj = OBJPTR(item);
                     47:     /*
                     48:      * If it is gold, just add its value to rogue's purse and get rid
                     49:      * of it.
                     50:      */
                     51:     if (obj->o_type == GOLD) {
                     52:        register struct linked_list *mitem;
                     53:        register struct thing *tp;
                     54:
                     55:        if (!silent) {
                     56:            if (!terse) addmsg("You found ");
                     57:            msg("%d gold pieces.", obj->o_count);
                     58:        }
                     59:
                     60:        /* First make sure no greedy monster is after this gold.
                     61:         * If so, make the monster run after the rogue instead.
                     62:         */
                     63:         for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
                     64:            tp = THINGPTR(mitem);
                     65:            if (tp->t_dest == &obj->o_pos) tp->t_dest = &hero;
                     66:        }
                     67:
                     68:        purse += obj->o_count;
                     69:        if (from_floor) {
                     70:            detach(lvl_obj, item);
                     71:            if ((ap = find_obj(hero.y, hero.x)) == NULL)
                     72:                mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
                     73:            else
                     74:                mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
                     75:        }
                     76:        o_discard(item);
                     77:        return(TRUE);
                     78:     }
                     79:
                     80:     /*
                     81:      * see if he can carry any more weight
                     82:      */
                     83:     if (itemweight(obj) + pstats.s_pack > pstats.s_carry) {
                     84:        msg("Too much for you to carry.");
                     85:        return FALSE;
                     86:     }
                     87:     /*
                     88:      * Link it into the pack.  Search the pack for a object of similar type
                     89:      * if there isn't one, stuff it at the beginning, if there is, look for one
                     90:      * that is exactly the same and just increment the count if there is.
                     91:      * it  that.  Food is always put at the beginning for ease of access, but
                     92:      * is not ordered so that you can't tell good food from bad.  First check
                     93:      * to see if there is something in thr same group and if there is then
                     94:      * increment the count.
                     95:      */
                     96:     if (obj->o_group)
                     97:     {
                     98:        for (ip = pack; ip != NULL; ip = next(ip))
                     99:        {
                    100:            op = OBJPTR(ip);
                    101:            if (op->o_group == obj->o_group)
                    102:            {
                    103:                /*
                    104:                 * Put it in the pack and notify the user
                    105:                 */
                    106:                op->o_count += obj->o_count;
                    107:                if (from_floor)
                    108:                {
                    109:                    detach(lvl_obj, item);
                    110:                    if ((ap = find_obj(hero.y, hero.x)) == NULL)
                    111:                        mvaddch(hero.y,hero.x,
                    112:                                (roomin(&hero)==NULL ? PASSAGE : FLOOR));
                    113:                    else
                    114:                        mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
                    115:                }
                    116:                o_discard(item);
                    117:                item = ip;
                    118:                goto picked_up;
                    119:            }
                    120:        }
                    121:     }
                    122:
                    123:     /*
                    124:      * Check for and deal with scare monster scrolls
                    125:      */
                    126:     if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
                    127:        if (obj->o_flags & ISCURSED)
                    128:        {
                    129:            msg("The scroll turns to dust as you pick it up.");
                    130:            detach(lvl_obj, item);
                    131:            if ((ap = find_obj(hero.y, hero.x)) == NULL)
                    132:                mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
                    133:            else
                    134:                mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
                    135:            return(TRUE);
                    136:        }
                    137:
                    138:     /*
                    139:      * Search for an object of the same type
                    140:      */
                    141:     exact = FALSE;
                    142:     for (ip = pack; ip != NULL; ip = next(ip))
                    143:     {
                    144:        op = OBJPTR(ip);
                    145:        if (obj->o_type == op->o_type)
                    146:            break;
                    147:     }
                    148:     if (ip == NULL)
                    149:     {
                    150:        /*
                    151:         * Put it at the end of the pack since it is a new type
                    152:         */
                    153:        for (ip = pack; ip != NULL; ip = next(ip))
                    154:        {
                    155:            op = OBJPTR(ip);
                    156:            if (op->o_type != FOOD)
                    157:                break;
                    158:            lp = ip;
                    159:        }
                    160:     }
                    161:     else
                    162:     {
                    163:        /*
                    164:         * Search for an object which is exactly the same
                    165:         */
                    166:        while (ip != NULL && op->o_type == obj->o_type)
                    167:        {
                    168:            if (op->o_which == obj->o_which)
                    169:            {
                    170:                exact = TRUE;
                    171:                break;
                    172:            }
                    173:            lp = ip;
                    174:            if ((ip = next(ip)) == NULL)
                    175:                break;
                    176:            op = OBJPTR(ip);
                    177:        }
                    178:     }
                    179:     /*
                    180:      * Check if there is room
                    181:      */
                    182:     if (ip == NULL || !exact || !ISMULT(obj->o_type)) {
                    183:        if (inpack == MAXPACK-1) {
                    184:            msg(terse ? "No room." : "You can't carry anything else.");
                    185:            return(FALSE);
                    186:        }
                    187:     }
                    188:     inpack++;
                    189:     if (from_floor)
                    190:     {
                    191:        detach(lvl_obj, item);
                    192:        if ((ap = find_obj(hero.y, hero.x)) == NULL)
                    193:            mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
                    194:        else
                    195:            mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
                    196:     }
                    197:     if (ip == NULL)
                    198:     {
                    199:        /*
                    200:         * Didn't find an exact match, just stick it here
                    201:         */
                    202:        if (pack == NULL)
                    203:            pack = item;
                    204:        else
                    205:        {
                    206:            lp->l_next = item;
                    207:            item->l_prev = lp;
                    208:            item->l_next = NULL;
                    209:        }
                    210:     }
                    211:     else
                    212:     {
                    213:        /*
                    214:         * If we found an exact match.  If it is food,
                    215:         * increase the count, otherwise put it with its clones.
                    216:         */
                    217:        if (exact && ISMULT(obj->o_type))
                    218:        {
                    219:            op->o_count += obj->o_count;
                    220:            inpack--;                   /* adjust for previous addition */
                    221:            o_discard(item);
                    222:            item = ip;
                    223:            goto picked_up;
                    224:        }
                    225:        if ((item->l_prev = prev(ip)) != NULL)
                    226:            item->l_prev->l_next = item;
                    227:        else
                    228:            pack = item;
                    229:        item->l_next = ip;
                    230:        ip->l_prev = item;
                    231:     }
                    232: picked_up:
                    233:     /*
                    234:      * Notify the user
                    235:      */
                    236:     obj = OBJPTR(item);
                    237:     if (!silent)
                    238:     {
                    239:        if (!terse)
                    240:            addmsg("You now have ");
                    241:        sprintf(outstring,"%s (%c)", inv_name(obj, !terse), pack_char(pack, obj));
                    242:        msg(outstring);
                    243:     }
                    244:
                    245:     /* Relics can do strange things when you pick them up */
                    246:     if (obj->o_type == RELIC) {
                    247:        cur_relic[obj->o_which]++;      /* Note that we have it */
                    248:        switch (obj->o_which) {
                    249:            case HEIL_ANKH:
                    250:                msg("The ankh welds itself into your hand.");
                    251:
                    252:            /* A cloak must be worn. */
                    253:            when EMORI_CLOAK:
                    254:                if (cur_armor != NULL || cur_misc[WEAR_CLOAK]) {
                    255:                    msg("The cloak insists you remove your current garments.");
                    256:                    if (!dropcheck(cur_armor != NULL ? cur_armor
                    257:                                                     : cur_misc[WEAR_CLOAK])) {
                    258:                        pstats.s_hpt = -1;
                    259:                        msg("The cloak constricts around you.");
                    260:                        msg("It draws your life force from you!!! -- More --");
                    261:                        wait_for(cw,' ');
                    262:                        death(D_RELIC);
                    263:                    }
                    264:                }
                    265:
                    266:            /* The amulet must be worn. */
                    267:            when YENDOR_AMULET:
                    268:                if (cur_misc[WEAR_JEWEL]) {
                    269:                    msg("You have an urge to remove your current amulet.");
                    270:                    if (!dropcheck(cur_misc[WEAR_JEWEL])) {
                    271:                        pstats.s_hpt = -1;
                    272:                        msg("The Amulet of Yendor begins pulsing.");
                    273:                        msg("It fades away.... -- More --");
                    274:                        wait_for(cw,' ');
                    275:                        death(D_RELIC);
                    276:                    }
                    277:                }
                    278:                msg("The amulet welds itself into your chest.");
                    279:
                    280:            /* Weapons will insist on being wielded. */
                    281:            when MUSTY_DAGGER:
                    282:            case HRUGGEK_MSTAR:
                    283:            case YEENOGHU_FLAIL:
                    284:                if (cur_weapon != NULL) {
                    285:                    msg("The artifact insists you release your current weapon.");
                    286:                    if (!dropcheck(cur_weapon)) {
                    287:                        pstats.s_hpt = -1;
                    288:                        msg("The artifact forces your weapon into your heart.");
                    289:                        msg("It hums with satisfaction. -- More --");
                    290:                        wait_for(cw,' ');
                    291:                        death(D_RELIC);
                    292:                    }
                    293:                }
                    294:                cur_weapon = obj;
                    295:        }
                    296:     }
                    297:
                    298:     updpack(FALSE);
                    299:     if (packret != NULL)
                    300:        *packret = item;
                    301:     return(TRUE);
                    302: }
                    303:
                    304: /*
                    305:  * inventory:
                    306:  *     list what is in the pack
                    307:  */
                    308: bool
                    309: inventory(struct linked_list *list, int type)
                    310: {
                    311:     register struct object *obj;
                    312:     register char ch;
                    313:     register int n_objs;
                    314:     register int cnt;
                    315:     char inv_temp[LINELEN];
                    316:
                    317:     cnt = 0;
                    318:     n_objs = 0;
                    319:     for (ch = 'a'; list != NULL; ch++, list = next(list)) {
                    320:        obj = OBJPTR(list);
                    321:        if (!is_type(obj, type))
                    322:            continue;
                    323:        switch (n_objs++) {
                    324:            /*
                    325:             * For the first thing in the inventory, just save the string
                    326:             * in case there is only one.
                    327:             */
                    328:            case 0:
                    329:                sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE));
                    330:                break;
                    331:            /*
                    332:             * If there is more than one, clear the screen, print the
                    333:             * saved message and fall through to ...
                    334:             */
                    335:            case 1:
                    336:                if (slow_invent)
                    337:                    msg(inv_temp);
                    338:                else
                    339:                {
                    340:                    wclear(hw);
                    341:                    waddstr(hw, inv_temp);
                    342:                    waddch(hw, '\n');
                    343:                }
                    344:            /*
                    345:             * Print the line for this object
                    346:             */
                    347:            default:
                    348:                if (ch > 'z')
                    349:                    ch = 'A';
                    350:                if (slow_invent){
                    351:                    sprintf(outstring,"%c) %s", ch, inv_name(obj, FALSE));
                    352:                    msg(outstring);
                    353:                }
                    354:                else {
                    355:                    if (++cnt >= LINES - 2) { /* if bottom of screen */
                    356:                        dbotline(hw, morestr);
                    357:                        cnt = 0;
                    358:                        wclear(hw);
                    359:                    }
                    360:                    wprintw(hw, "%c) %s\n", ch, inv_name(obj, FALSE));
                    361:                }
                    362:        }
                    363:     }
                    364:     if (n_objs == 0) {
                    365:        if (terse)
                    366:            msg(type == 0 ? "Empty handed." :
                    367:                            "Nothing appropriate");
                    368:        else
                    369:            msg(type == 0 ? "You are empty handed." :
                    370:                            "You don't have anything appropriate");
                    371:        return FALSE;
                    372:     }
                    373:     if (n_objs == 1) {
                    374:        msg(inv_temp);
                    375:        return TRUE;
                    376:     }
                    377:     if (!slow_invent)
                    378:     {
                    379:        mvwaddstr(hw, LINES-1, 0, spacemsg);
                    380:        draw(hw);
                    381:        wait_for(hw,' ');
                    382:        clearok(cw, TRUE);
                    383:        touchwin(cw);
                    384:     }
                    385:     return TRUE;
                    386: }
                    387:
                    388: /*
                    389:  * pick_up:
                    390:  *     Add something to characters pack.
                    391:  */
                    392: void
                    393: pick_up(char ch)
                    394: {
                    395:     switch (ch) {
                    396:        default:
                    397:            debug("Where did you pick that up???");
                    398:        case GOLD:
                    399:        case ARMOR:
                    400:        case POTION:
                    401:        case FOOD:
                    402:        case WEAPON:
                    403:        case SCROLL:
                    404:        case MM:
                    405:        case RING:
                    406:        case STICK:
                    407:        case RELIC:
                    408:            while (add_pack(NULL, FALSE, NULL));        /* pick up everything there */
                    409:            break;
                    410:     }
                    411: }
                    412:
                    413: /*
                    414:  * picky_inven:
                    415:  *     Allow player to inventory a single item
                    416:  */
                    417: void
                    418: picky_inven(void)
                    419: {
                    420:     register struct linked_list *item;
                    421:     register char ch, mch;
                    422:
                    423:     if (pack == NULL)
                    424:        msg("You aren't carrying anything");
                    425:     else if (next(pack) == NULL)
                    426:        msg("a) %s", inv_name(OBJPTR(pack), FALSE));
                    427:     else
                    428:     {
                    429:        msg(terse ? "Item: " : "Which item do you wish to inventory: ");
                    430:        mpos = 0;
                    431:        if ((mch = readchar()) == ESCAPE)
                    432:        {
                    433:            msg("");
                    434:            return;
                    435:        }
                    436:
                    437:        /* Check for a special character */
                    438:        switch (mch) {
                    439:            case FOOD:
                    440:            case SCROLL:
                    441:            case POTION:
                    442:            case RING:
                    443:            case STICK:
                    444:            case RELIC:
                    445:            case ARMOR:
                    446:            case WEAPON:
                    447:            case MM:
                    448:                msg("");
                    449:                if (get_item(pack, NULL, mch) == NULL) {
                    450:                    if (terse) msg("None in pack.");
                    451:                    else msg("You have no %c in your pack.", mch);
                    452:                }
                    453:                return;
                    454:        }
                    455:
                    456:        for (ch = 'a', item = pack; item != NULL; item = next(item), ch++)
                    457:            if (ch == mch)
                    458:            {
                    459:                sprintf(outstring, "%c) %s",ch ,inv_name(OBJPTR(item), FALSE));
                    460:                msg(outstring);
                    461:                return;
                    462:            }
                    463:        if (!terse)
                    464:            msg("'%s' not in pack.", unctrl(mch));
                    465:        msg("Range is 'a' to '%c'", --ch);
                    466:     }
                    467: }
                    468:
                    469:
                    470: /*
                    471:  * get_item:
                    472:  *     pick something out of a pack for a purpose
                    473:  *     purpose: NULL if we should be silent (no prompts) *
                    474:  */
                    475: struct linked_list *
                    476: get_item(struct linked_list *list, char *purpose, int type)
                    477: {
                    478:     reg struct linked_list *item;
                    479:     reg struct object *obj;
                    480:     reg int cnt, ch, och;
                    481:     struct linked_list *saveitem = NULL;
                    482:
                    483:     cnt = 0;
                    484:     if (list == NULL) {
                    485:        msg("You aren't carrying anything.");
                    486:        return NULL;
                    487:     }
                    488:     /* see if we have any of the type requested */
                    489:     for(ch = 'a',item = list ; item != NULL ; item = next(item), ch++) {
                    490:        obj = OBJPTR(item);
                    491:        if (is_type(obj, type)) {
                    492:            cnt++;
                    493:            saveitem = item;
                    494:        }
                    495:     }
                    496:     if (cnt == 0) {
                    497:        if (purpose) msg("Nothing to %s",purpose);
                    498:        after = FALSE;
                    499:        return NULL;
                    500:     }
                    501:     else if (cnt == 1) {       /* only found one of 'em */
                    502:        obj = OBJPTR(saveitem);
                    503:        for(;;)  {
                    504:            if (purpose) {      /* Should we prompt the player? */
                    505:                msg("%s what (* for the item)? ",purpose);
                    506:                ch = tolower(readchar());
                    507:            }
                    508:            else {
                    509:                sprintf(outstring, "%c) %s", pack_char(list, obj), inv_name(obj,FALSE));
                    510:                msg(outstring);
                    511:            }
                    512:
                    513:            if (ch == '*') {
                    514:                mpos = 0;
                    515:                sprintf(outstring, "%c) %s", pack_char(list, obj), inv_name(obj,FALSE));
                    516:                msg(outstring);
                    517:                continue;
                    518:            }
                    519:            if (ch == ESCAPE) {
                    520:                msg("");
                    521:                after = FALSE;
                    522:                return NULL;
                    523:            }
                    524:            for(item = list,och = 'a'; item != NULL; item = next(item),och++) {
                    525:                if (ch == och) break;
                    526:                if (och == 'z') och = 'A' - 1;
                    527:            }
                    528:            if (item == NULL) {
                    529:                msg("Please specify a letter between 'a' and '%c'",
                    530:                    och == 'A' ? 'z' : och-1);
                    531:                continue;
                    532:            }
                    533:            if (is_type (OBJPTR(item), type)) {
                    534:                if (purpose) mpos = 0;
                    535:                return item;
                    536:            }
                    537:            else
                    538:                msg ("You can't %s that!", purpose);
                    539:
                    540:        }
                    541:     }
                    542:     for(;;) {
                    543:        if (purpose) {
                    544:            msg("%s what? (* for list): ",purpose);
                    545:            ch = readchar();
                    546:        }
                    547:        else ch = '*';
                    548:
                    549:        mpos = 0;
                    550:        if (ch == ESCAPE) {             /* abort if escape hit */
                    551:            after = FALSE;
                    552:            msg("");            /* clear display */
                    553:            return NULL;
                    554:        }
                    555:        if (ch == '*') {
                    556:            wclear(hw);
                    557:            cnt = 0;
                    558:            for(item = list,ch = 'a'; item != NULL ; item = next(item), ch++) {
                    559:                obj = OBJPTR(item);
                    560:                if (!is_type(OBJPTR(item), type))
                    561:                    continue;
                    562:                wprintw(hw,"%c) %s\n\r",ch,inv_name(obj,FALSE));
                    563:                if (++cnt >= LINES - 2 && next(item) != NULL) {
                    564:                    cnt = 0;
                    565:                    dbotline(hw, spacemsg);
                    566:                    wclear(hw);
                    567:                }
                    568:                if (ch == 'z') ch = 'A' - 1;
                    569:            }
                    570:            wmove(hw, LINES - 1,0);
                    571:            if (purpose) wprintw(hw,"%s what? ",purpose);
                    572:            else waddstr(hw, spacemsg);
                    573:
                    574:            draw(hw);           /* write screen */
                    575:
                    576:            if (purpose) {
                    577:                do {
                    578:                    ch = tolower(wgetch(hw));
                    579:                } until (isalpha(ch) || ch == ESCAPE);
                    580:            }
                    581:            else {
                    582:                ch = pack_char(list, OBJPTR(saveitem)); /* Pick a valid item */
                    583:                wait_for(hw,' ');
                    584:            }
                    585:
                    586:            restscr(cw);                /* redraw orig screen */
                    587:            if(ch == ESCAPE) {
                    588:                after = FALSE;
                    589:                msg("");                /* clear top line */
                    590:                return NULL;    /* all done if abort */
                    591:            }
                    592:            /* ch has item to get from list */
                    593:        }
                    594:        for(item = list,och = 'a'; item != NULL; item = next(item),och++) {
                    595:            if (ch == och) break;
                    596:            if (och == 'z') och = 'A' - 1;
                    597:        }
                    598:        if (item == NULL) {
                    599:            msg("Please specify a letter between 'a' and '%c'",
                    600:                och == 'A' ? 'z' : och-1);
                    601:            continue;
                    602:        }
                    603:        if (is_type(OBJPTR(item), type))
                    604:            return (item);
                    605:        else
                    606:            msg ("You can't %s that!", purpose);
                    607:     }
                    608: }
                    609:
                    610: char
                    611: pack_char(struct linked_list *list, struct object *obj)
                    612: {
                    613:     register struct linked_list *item;
                    614:     register char c;
                    615:
                    616:     c = 'a';
                    617:     for (item = list; item != NULL; item = next(item)) {
                    618:        if (OBJPTR(item) == obj)
                    619:            return c;
                    620:        else {
                    621:            if (c == 'z') c = 'A';
                    622:            else c++;
                    623:        }
                    624:     }
                    625:     return 'z';
                    626: }
                    627:
                    628:
                    629: /*
                    630:  * cur_null:
                    631:  *     This updates cur_weapon etc for dropping things
                    632:  */
                    633: void
                    634: cur_null(struct object *op)
                    635: {
                    636:        if (op == cur_weapon)                   cur_weapon = NULL;
                    637:        else if (op == cur_armor)               cur_armor = NULL;
                    638:        else if (op == cur_ring[LEFT_1])        cur_ring[LEFT_1] = NULL;
                    639:        else if (op == cur_ring[LEFT_2])        cur_ring[LEFT_2] = NULL;
                    640:        else if (op == cur_ring[LEFT_3])        cur_ring[LEFT_3] = NULL;
                    641:        else if (op == cur_ring[LEFT_4])        cur_ring[LEFT_4] = NULL;
                    642:        else if (op == cur_ring[RIGHT_1])       cur_ring[RIGHT_1] = NULL;
                    643:        else if (op == cur_ring[RIGHT_2])       cur_ring[RIGHT_2] = NULL;
                    644:        else if (op == cur_ring[RIGHT_3])       cur_ring[RIGHT_3] = NULL;
                    645:        else if (op == cur_ring[RIGHT_4])       cur_ring[RIGHT_4] = NULL;
                    646:        else if (op == cur_misc[WEAR_BOOTS])    cur_misc[WEAR_BOOTS] = NULL;
                    647:        else if (op == cur_misc[WEAR_JEWEL])    cur_misc[WEAR_JEWEL] = NULL;
                    648:        else if (op == cur_misc[WEAR_GAUNTLET]) cur_misc[WEAR_GAUNTLET] = NULL;
                    649:        else if (op == cur_misc[WEAR_CLOAK])    cur_misc[WEAR_CLOAK] = NULL;
                    650:        else if (op == cur_misc[WEAR_BRACERS])  cur_misc[WEAR_BRACERS] = NULL;
                    651:        else if (op == cur_misc[WEAR_NECKLACE]) cur_misc[WEAR_NECKLACE] = NULL;
                    652: }
                    653:
                    654: /*
                    655:  * idenpack:
                    656:  *     Identify all the items in the pack
                    657:  */
                    658: void
                    659: idenpack(void)
                    660: {
                    661:        reg struct linked_list *pc;
                    662:
                    663:        for (pc = pack ; pc != NULL ; pc = next(pc))
                    664:                whatis(pc);
                    665: }
                    666:
                    667: bool
                    668: is_type (struct object *obj, int type)
                    669: {
                    670:     register bool current;
                    671:
                    672:     if (type == obj->o_type)
                    673:        return (TRUE);
                    674:
                    675:     switch (type) {
                    676:        case ALL:
                    677:            return (TRUE);
                    678:        when ZAPPABLE:
                    679:            if (obj->o_type == STICK) return (TRUE);
                    680:            if (obj->o_type == RELIC)
                    681:                switch (obj->o_which) {
                    682:                    case MING_STAFF:
                    683:                    case ASMO_ROD:
                    684:                    case ORCUS_WAND:
                    685:                        return (TRUE);
                    686:                }
                    687:        when WEARABLE:
                    688:        case REMOVABLE:
                    689:            current = is_current(obj);
                    690:
                    691:            /*
                    692:             * Don't wear thing we are already wearing or remove things
                    693:             * we aren't wearing.
                    694:             */
                    695:            if (type == WEARABLE && current) return (FALSE);
                    696:            else if (type == REMOVABLE && !current) return (FALSE);
                    697:
                    698:            switch (obj->o_type) {
                    699:                case RELIC:
                    700:                    switch (obj->o_which) {
                    701:                        case HEIL_ANKH:
                    702:                        case EMORI_CLOAK:
                    703:                            return (TRUE);
                    704:                    }
                    705:                when MM:
                    706:                    switch (obj->o_which) {
                    707:                        case MM_ELF_BOOTS:
                    708:                        case MM_DANCE:
                    709:                        case MM_BRACERS:
                    710:                        case MM_DISP:
                    711:                        case MM_PROTECT:
                    712:                        case MM_G_DEXTERITY:
                    713:                        case MM_G_OGRE:
                    714:                        case MM_JEWEL:
                    715:                        case MM_R_POWERLESS:
                    716:                        case MM_FUMBLE:
                    717:                        case MM_STRANGLE:
                    718:                        case MM_ADAPTION:
                    719:                            return (TRUE);
                    720:                    }
                    721:                when ARMOR:
                    722:                case RING:
                    723:                    return (TRUE);
                    724:            }
                    725:        when CALLABLE:
                    726:            switch (obj->o_type) {
                    727:            case RING:
                    728:            case POTION:
                    729:            case STICK:
                    730:            case SCROLL:
                    731:            case MM:
                    732:                return(TRUE);
                    733:            }
                    734:        when WIELDABLE:
                    735:            switch (obj->o_type) {
                    736:                case STICK:
                    737:                case WEAPON:
                    738:                    return(TRUE);
                    739:                when RELIC:
                    740:                    switch (obj->o_which) {
                    741:                        case MUSTY_DAGGER:
                    742:                        case HRUGGEK_MSTAR:
                    743:                        case YEENOGHU_FLAIL:
                    744:                        case MING_STAFF:
                    745:                        case ORCUS_WAND:
                    746:                        case ASMO_ROD:
                    747:                            return(TRUE);
                    748:                    }
                    749:            }
                    750:        when IDENTABLE:
                    751:            if (!(obj->o_flags & ISKNOW) && obj->o_type != FOOD)
                    752:                return (TRUE);
                    753:            if (obj->o_type == MM) {
                    754:              switch (obj->o_which) {
                    755:                case MM_JUG:
                    756:                    /* Can still identify a jug if we don't know the potion */
                    757:                    if (obj->o_ac != JUG_EMPTY && !p_know[obj->o_ac])
                    758:                        return (TRUE);
                    759:              }
                    760:            }
                    761:        when USEABLE:
                    762:            if (obj->o_type == MM) {
                    763:                switch(obj->o_which) {
                    764:                case MM_JUG:
                    765:                case MM_BEAKER:
                    766:                case MM_BOOK:
                    767:                case MM_SKILLS:
                    768:                case MM_OPEN:
                    769:                case MM_HUNGER:
                    770:                case MM_DRUMS:
                    771:                case MM_DISAPPEAR:
                    772:                case MM_CHOKE:
                    773:                case MM_KEOGHTOM:
                    774:                    return (TRUE);
                    775:                }
                    776:            }
                    777:            else if (obj->o_type == RELIC) {
                    778:                switch (obj->o_which) {
                    779:                    case EMORI_CLOAK:
                    780:                    case BRIAN_MANDOLIN:
                    781:                    case HEIL_ANKH:
                    782:                    case YENDOR_AMULET:
                    783:                    case GERYON_HORN:
                    784:                        return (TRUE);
                    785:                }
                    786:            }
                    787:        when PROTECTABLE:
                    788:            switch (obj->o_type) {
                    789:                case WEAPON:
                    790:                    if ((obj->o_flags & ISMETAL) == 0) return (FALSE);
                    791:
                    792:                    /* Fall through */
                    793:                case ARMOR:
                    794:                    return (TRUE);
                    795:
                    796:                when MM:
                    797:                    if (obj->o_which == MM_BRACERS) return (TRUE);
                    798:            }
                    799:     }
                    800:     return(FALSE);
                    801: }
                    802:
                    803: void
                    804: del_pack(struct linked_list *item)
                    805: {
                    806:     register struct object *obj;
                    807:
                    808:     obj = OBJPTR(item);
                    809:     if (obj->o_count > 1) {
                    810:        obj->o_count--;
                    811:     }
                    812:     else {
                    813:        cur_null(obj);
                    814:        detach(pack, item);
                    815:        o_discard(item);
                    816:        inpack--;
                    817:     }
                    818: }
                    819:
                    820: /*
                    821:  * carry_obj:
                    822:  *     Check to see if a monster is carrying something and, if so, give
                    823:  * it to him.
                    824:  */
                    825:
                    826: void
                    827: carry_obj(struct thing *mp, int chance)
                    828: {
                    829:     reg struct linked_list *item;
                    830:     reg struct object *obj;
                    831:
                    832:     /*
                    833:      * If there is no chance, just return.
                    834:      * Note that this means there must be a "chance" in order for
                    835:      * the creature to carry a relic.
                    836:      */
                    837:     if (chance <= 0) return;
                    838:
                    839:     /*
                    840:      * check for the relic/artifacts
                    841:      * Do the relics first so they end up last in the pack. Attach()
                    842:      * always adds things to the beginning. This way they will be the
                    843:      * last things dropped when the creature is killed. This will ensure
                    844:      * the relic will be on top if there is a stack of item lying on the
                    845:      * floor and so the hero will know where it is if he's trying to
                    846:      * avoid it
                    847:      */
                    848:     if (on(*mp, CARRYDAGGER)) {
                    849:        item = spec_item(RELIC, MUSTY_DAGGER, 0, 0);
                    850:        obj = OBJPTR(item);
                    851:        obj->o_pos = mp->t_pos;
                    852:        attach(mp->t_pack, item);
                    853:     }
                    854:
                    855:     if (on(*mp, CARRYCLOAK)) {
                    856:        item = spec_item(RELIC, EMORI_CLOAK, 0, 0);
                    857:        obj = OBJPTR(item);
                    858:        obj->o_pos = mp->t_pos;
                    859:        attach(mp->t_pack, item);
                    860:     }
                    861:
                    862:     if (on(*mp, CARRYANKH)) {
                    863:        item = spec_item(RELIC, HEIL_ANKH, 0, 0);
                    864:        obj = OBJPTR(item);
                    865:        obj->o_pos = mp->t_pos;
                    866:        attach(mp->t_pack, item);
                    867:     }
                    868:
                    869:     if (on(*mp, CARRYSTAFF)) {
                    870:        item = spec_item(RELIC, MING_STAFF, 0, 0);
                    871:        obj = OBJPTR(item);
                    872:        obj->o_pos = mp->t_pos;
                    873:        attach(mp->t_pack, item);
                    874:     }
                    875:
                    876:     if (on(*mp, CARRYWAND)) {
                    877:        item = spec_item(RELIC, ORCUS_WAND, 0, 0);
                    878:        obj = OBJPTR(item);
                    879:        obj->o_pos = mp->t_pos;
                    880:        attach(mp->t_pack, item);
                    881:     }
                    882:
                    883:     if (on(*mp, CARRYROD)) {
                    884:        item = spec_item(RELIC, ASMO_ROD, 0, 0);
                    885:        obj = OBJPTR(item);
                    886:        obj->o_pos = mp->t_pos;
                    887:        attach(mp->t_pack, item);
                    888:     }
                    889:
                    890:     if (on(*mp, CARRYAMULET)) {
                    891:        item = spec_item(RELIC, YENDOR_AMULET, 0, 0);
                    892:        obj = OBJPTR(item);
                    893:        obj->o_pos = mp->t_pos;
                    894:        attach(mp->t_pack, item);
                    895:     }
                    896:
                    897:     if (on(*mp, CARRYMANDOLIN)) {
                    898:        item = spec_item(RELIC, BRIAN_MANDOLIN, 0, 0);
                    899:        obj = OBJPTR(item);
                    900:        obj->o_pos = mp->t_pos;
                    901:        attach(mp->t_pack, item);
                    902:     }
                    903:     if (on(*mp, CARRYMSTAR)) {
                    904:        item = spec_item(RELIC, HRUGGEK_MSTAR, 0, 0);
                    905:        obj = OBJPTR(item);
                    906:        obj->o_pos = mp->t_pos;
                    907:        attach(mp->t_pack, item);
                    908:     }
                    909:     if (on(*mp, CARRYFLAIL)) {
                    910:        item = spec_item(RELIC, YEENOGHU_FLAIL, 0, 0);
                    911:        obj = OBJPTR(item);
                    912:        obj->o_pos = mp->t_pos;
                    913:        attach(mp->t_pack, item);
                    914:     }
                    915:     if (on(*mp, CARRYHORN)) {
                    916:        item = spec_item(RELIC, GERYON_HORN, 0, 0);
                    917:        obj = OBJPTR(item);
                    918:        obj->o_pos = mp->t_pos;
                    919:        attach(mp->t_pack, item);
                    920:     }
                    921:     /*
                    922:      * If it carries gold, give it some
                    923:      */
                    924:     if (on(*mp, CARRYGOLD) && rnd(100) < chance) {
                    925:            item = spec_item(GOLD, 0, 0, 0);
                    926:            obj = OBJPTR(item);
                    927:            obj->o_count = GOLDCALC + GOLDCALC;
                    928:            obj->o_pos = mp->t_pos;
                    929:            attach(mp->t_pack, item);
                    930:     }
                    931:
                    932:     /*
                    933:      * If it carries food, give it some
                    934:      */
                    935:     if (on(*mp, CARRYFOOD) && rnd(100) < chance) {
                    936:        item = spec_item(FOOD, 0, 0, 0);
                    937:        obj = OBJPTR(item);
                    938:        obj->o_weight = things[TYP_FOOD].mi_wght;
                    939:        obj->o_pos = mp->t_pos;
                    940:        attach(mp->t_pack, item);
                    941:     }
                    942:
                    943:     /*
                    944:      * If it carries a weapon, give it one
                    945:      */
                    946:     if (on(*mp, CARRYWEAPON) && rnd(100) < chance) {
                    947:        int type, hit, dam;
                    948:
                    949:        /* Get the "bonuses" */
                    950:        hit = rnd(5) - 2;
                    951:        dam = rnd(5) - 2;
                    952:
                    953:        /* Only choose an appropriate type of weapon */
                    954:        switch (rnd(11)) {
                    955:            case 0: type = DAGGER;
                    956:            when 1: type = BATTLEAXE;
                    957:            when 2: type = MACE;
                    958:            when 3: type = SWORD;
                    959:            when 4: type = PIKE;
                    960:            when 5: type = HALBERD;
                    961:            when 6: type = SPETUM;
                    962:            when 7: type = BARDICHE;
                    963:            when 8: type = TRIDENT;
                    964:            when 9: type = BASWORD;
                    965:            otherwise: type = TWOSWORD;
                    966:        }
                    967:
                    968:        /* Create the item */
                    969:        item = spec_item(WEAPON, type, hit, dam);
                    970:        obj = OBJPTR(item);
                    971:        obj->o_pos = mp->t_pos;
                    972:        attach(mp->t_pack, item);
                    973:     }
                    974:
                    975:     /*
                    976:      * If it carries a scroll, give it one
                    977:      */
                    978:     if (on(*mp, CARRYSCROLL) && rnd(100) < chance) {
                    979:        item = new_thing(TYP_SCROLL);
                    980:        obj = OBJPTR(item);
                    981:        obj->o_pos = mp->t_pos;
                    982:
                    983:        /* Can the monster carry this scroll? */
                    984:        if (obj->o_which == S_SCARE && mp->t_stats.s_intel < 16)
                    985:            fall(item, FALSE);  /* This would scare us! */
                    986:        else attach(mp->t_pack, item);
                    987:     }
                    988:
                    989:     /*
                    990:      * If it carries a potion, give it one
                    991:      */
                    992:     if (on(*mp, CARRYPOTION) && rnd(100) < chance) {
                    993:        item = new_thing(TYP_POTION);
                    994:        obj = OBJPTR(item);
                    995:        obj->o_pos = mp->t_pos;
                    996:        attach(mp->t_pack, item);
                    997:     }
                    998:
                    999:     /*
                   1000:      * If it carries a ring, give it one
                   1001:      */
                   1002:     if (on(*mp, CARRYRING) && rnd(100) < chance) {
                   1003:        item = new_thing(TYP_RING);
                   1004:        obj = OBJPTR(item);
                   1005:        obj->o_pos = mp->t_pos;
                   1006:        attach(mp->t_pack, item);
                   1007:     }
                   1008:
                   1009:     /*
                   1010:      * If it carries a wand or staff, give it one
                   1011:      */
                   1012:     if (on(*mp, CARRYSTICK) && rnd(100) < chance) {
                   1013:        item = new_thing(TYP_STICK);
                   1014:        obj = OBJPTR(item);
                   1015:        obj->o_pos = mp->t_pos;
                   1016:        attach(mp->t_pack, item);
                   1017:     }
                   1018:
                   1019:     /*
                   1020:      * If it carries any miscellaneous magic, give it one
                   1021:      */
                   1022:     if (on(*mp, CARRYMISC) && rnd(100) < chance) {
                   1023:        item = new_thing(TYP_MM);
                   1024:        obj = OBJPTR(item);
                   1025:        obj->o_pos = mp->t_pos;
                   1026:        attach(mp->t_pack, item);
                   1027:     }
                   1028: }
                   1029:
                   1030:
                   1031: /*
                   1032:  * grab():
                   1033:  *     See what is on the spot where the player is standing.  If
                   1034:  *     nothing is there, do nothing.  If there is one thing, pick it
                   1035:  *     up.  If there are multiple things, prompt the player for what
                   1036:  *     he wants (* means everything).
                   1037:  */
                   1038:
                   1039: int
                   1040: grab(int y, int x)
                   1041: {
                   1042:     register struct linked_list *next_item, *item;
                   1043:     register struct object *obj;
                   1044:     register int cnt;
                   1045:     int num_there = 0, ch, och;
                   1046:
                   1047:     /*
                   1048:      * Count how many objects there are and move them to the front
                   1049:      * of the level list.
                   1050:      */
                   1051:     for (item = lvl_obj; item != NULL; item = next_item) {
                   1052:        obj = OBJPTR(item);
                   1053:        next_item = next(item);
                   1054:        if (obj->o_pos.y == y && obj->o_pos.x == x) {
                   1055:            num_there++;
                   1056:            detach(lvl_obj, item);      /* Remove it from the list */
                   1057:            attach(lvl_obj, item);      /* Place it at the front of the list */
                   1058:        }
                   1059:     }
                   1060:
                   1061:     /* Nothing there. */
                   1062:     if (num_there < 1) msg("Nothing %s", terse ? "there." : "to pick up.");
                   1063:
                   1064:     /* One thing there */
                   1065:     else if (num_there == 1) {
                   1066:        add_pack(FALSE, FALSE, NULL);
                   1067:        return(1);
                   1068:     }
                   1069:
                   1070:     /* Multiple things there */
                   1071:     else {
                   1072:        wclear(hw);
                   1073:        cnt = 0;
                   1074:        for (item = lvl_obj, ch = 'a'; item != NULL && cnt < num_there;
                   1075:             item = next(item), ch++) {
                   1076:            obj = OBJPTR(item);
                   1077:            wprintw(hw,"%c) %s\n\r", ch, inv_name(obj,FALSE));
                   1078:            if (++cnt >= LINES - 2 && next(item) != NULL) {
                   1079:                cnt = 0;
                   1080:                dbotline(hw, spacemsg);
                   1081:                wclear(hw);
                   1082:            }
                   1083:            if (ch == 'z') ch = 'A' - 1;
                   1084:        }
                   1085:        wmove(hw, LINES - 1,0);
                   1086:        wprintw(hw, "Pick up what? (* for all): ");
                   1087:        draw(hw);               /* write screen */
                   1088:
                   1089:        for (;;) {
                   1090:            do {
                   1091:                ch = tolower(wgetch(hw));
                   1092:            } until (isalpha(ch) || ch == '*' || ch == ESCAPE);
                   1093:            restscr(cw);                /* redraw orig screen */
                   1094:            if (ch == ESCAPE) {
                   1095:                after = FALSE;
                   1096:                msg("");                /* clear top line */
                   1097:                break;
                   1098:            }
                   1099:            if (ch == '*') {
                   1100:                while (add_pack(NULL, TRUE, NULL));     /* pick up everything there */
                   1101:                return(num_there);
                   1102:            }
                   1103:            /* ch has item to get from list */
                   1104:
                   1105:            cnt = 0;
                   1106:            for (item = lvl_obj, och = 'a'; item != NULL && cnt < num_there;
                   1107:                 item = next(item), och++, cnt++) {
                   1108:                if (ch == och)
                   1109:                    break;
                   1110:                if (och == 'z') och = 'A' - 1;
                   1111:            }
                   1112:            if (item == NULL || cnt >= num_there) {
                   1113:                wmove(hw, LINES - 1, 25);
                   1114:                wprintw(hw, " [between 'a' and '%c']:%c ",
                   1115:                    och == 'A' ? 'z' : och-1, '\007');
                   1116:                draw(hw);               /* write screen */
                   1117:                continue;
                   1118:            }
                   1119:            else {
                   1120:                detach(lvl_obj, item);
                   1121:                if (add_pack(item, FALSE, NULL)) {
                   1122:                    /*
                   1123:                     * There should always be at least one item left since we
                   1124:                     * handle the one item case up above.  But it never hurts
                   1125:                     * to make sure we don't have a NULL pointer.
                   1126:                     */
                   1127:                    if ((item = find_obj(hero.y, hero.x)) == NULL)
                   1128:                        mvaddch(y, x, (OBJPTR(item))->o_type);
                   1129:                    return(1);
                   1130:                }
                   1131:                else attach(lvl_obj, item);     /* Couldn't pick it up! */
                   1132:                break;
                   1133:            }
                   1134:        }
                   1135:     }
                   1136:
                   1137:     return(0);
                   1138: }

CVSweb