[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     ! 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