Annotation of researchv10no/games/rogue/pack.c, revision 1.1.1.1

1.1       root        1: #include <curses.h>
                      2: #include <ctype.h>
                      3: #include "rogue.h"
                      4: 
                      5: /*
                      6:  * Routines to deal with the pack
                      7:  *
                      8:  * @(#)pack.c  3.6 (Berkeley) 6/15/81
                      9:  */
                     10: 
                     11: /*
                     12:  * add_pack:
                     13:  *     Pick up an object and add it to the pack.  If the argument is non-null
                     14:  * use it as the linked_list pointer instead of gettting it off the ground.
                     15:  */
                     16: add_pack(item, silent)
                     17: register struct linked_list *item;
                     18: bool silent;
                     19: {
                     20:     register struct linked_list *ip, *lp;
                     21:     register struct object *obj, *op;
                     22:     register char ch;
                     23:     register bool exact, from_floor;
                     24: 
                     25:     if (item == NULL)
                     26:     {
                     27:        from_floor = TRUE;
                     28:        if ((item = find_obj(hero.y, hero.x)) == NULL)
                     29:            return;
                     30:     }
                     31:     else
                     32:        from_floor = FALSE;
                     33:     obj = (struct object *) ldata(item);
                     34:     /*
                     35:      * Link it into the pack.  Search the pack for a object of similar type
                     36:      * if there isn't one, stuff it at the beginning, if there is, look for one
                     37:      * that is exactly the same and just increment the count if there is.
                     38:      * it  that.  Food is always put at the beginning for ease of access, but
                     39:      * is not ordered so that you can't tell good food from bad.  First check
                     40:      * to see if there is something in thr same group and if there is then
                     41:      * increment the count.
                     42:      */
                     43:     if (obj->o_group)
                     44:     {
                     45:        for (ip = pack; ip != NULL; ip = next(ip))
                     46:        {
                     47:            op = (struct object *) ldata(ip);
                     48:            if (op->o_group == obj->o_group)
                     49:            {
                     50:                /*
                     51:                 * Put it in the pack and notify the user
                     52:                 */
                     53:                op->o_count++;
                     54:                if (from_floor)
                     55:                {
                     56:                    detach(lvl_obj, item);
                     57:                    mvaddch(hero.y, hero.x,
                     58:                        (roomin(&hero) == NULL ? PASSAGE : FLOOR));
                     59:                }
                     60:                discard(item);
                     61:                item = ip;
                     62:                goto picked_up;
                     63:            }
                     64:        }
                     65:     }
                     66:     /*
                     67:      * Check if there is room
                     68:      */
                     69:     if (inpack == MAXPACK-1)
                     70:     {
                     71:        msg("You can't carry anything else.");
                     72:        return;
                     73:     }
                     74:     /*
                     75:      * Check for and deal with scare monster scrolls
                     76:      */
                     77:     if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
                     78:        if (obj->o_flags & ISFOUND)
                     79:        {
                     80:            msg("The scroll turns to dust as you pick it up.");
                     81:            detach(lvl_obj, item);
                     82:            mvaddch(hero.y, hero.x, FLOOR);
                     83:            return;
                     84:        }
                     85:        else
                     86:            obj->o_flags |= ISFOUND;
                     87: 
                     88:     inpack++;
                     89:     if (from_floor)
                     90:     {
                     91:        detach(lvl_obj, item);
                     92:        mvaddch(hero.y, hero.x, (roomin(&hero) == NULL ? PASSAGE : FLOOR));
                     93:     }
                     94:     /*
                     95:      * Search for an object of the same type
                     96:      */
                     97:     exact = FALSE;
                     98:     for (ip = pack; ip != NULL; ip = next(ip))
                     99:     {
                    100:        op = (struct object *) ldata(ip);
                    101:        if (obj->o_type == op->o_type)
                    102:            break;
                    103:     }
                    104:     if (ip == NULL)
                    105:     {
                    106:        /*
                    107:         * Put it at the end of the pack since it is a new type
                    108:         */
                    109:        for (ip = pack; ip != NULL; ip = next(ip))
                    110:        {
                    111:            op = (struct object *) ldata(ip);
                    112:            if (op->o_type != FOOD)
                    113:                break;
                    114:            lp = ip;
                    115:        }
                    116:     }
                    117:     else
                    118:     {
                    119:        /*
                    120:         * Search for an object which is exactly the same
                    121:         */
                    122:        while (ip != NULL && op->o_type == obj->o_type)
                    123:        {
                    124:            if (op->o_which == obj->o_which)
                    125:            {
                    126:                exact = TRUE;
                    127:                break;
                    128:            }
                    129:            lp = ip;
                    130:            if ((ip = next(ip)) == NULL)
                    131:                break;
                    132:            op = (struct object *) ldata(ip);
                    133:        }
                    134:     }
                    135:     if (ip == NULL)
                    136:     {
                    137:        /*
                    138:         * Didn't find an exact match, just stick it here
                    139:         */
                    140:        if (pack == NULL)
                    141:            pack = item;
                    142:        else
                    143:        {
                    144:            lp->l_next = item;
                    145:            item->l_prev = lp;
                    146:            item->l_next = NULL;
                    147:        }
                    148:     }
                    149:     else
                    150:     {
                    151:        /*
                    152:         * If we found an exact match.  If it is a potion, food, or a 
                    153:         * scroll, increase the count, otherwise put it with its clones.
                    154:         */
                    155:        if (exact && ISMULT(obj->o_type))
                    156:        {
                    157:            op->o_count++;
                    158:            discard(item);
                    159:            item = ip;
                    160:            goto picked_up;
                    161:        }
                    162:        if ((item->l_prev = prev(ip)) != NULL)
                    163:            item->l_prev->l_next = item;
                    164:        else
                    165:            pack = item;
                    166:        item->l_next = ip;
                    167:        ip->l_prev = item;
                    168:     }
                    169: picked_up:
                    170:     /*
                    171:      * Notify the user
                    172:      */
                    173:     obj = (struct object *) ldata(item);
                    174:     if (notify && !silent)
                    175:     {
                    176:        if (!terse)
                    177:            addmsg("You now have ");
                    178:        msg("%s (%c)", inv_name(obj, !terse), pack_char(obj));
                    179:     }
                    180:     if (obj->o_type == AMULET)
                    181:        amulet = TRUE;
                    182: }
                    183: 
                    184: /*
                    185:  * inventory:
                    186:  *     list what is in the pack
                    187:  */
                    188: inventory(list, type)
                    189: struct linked_list *list;
                    190: int type;
                    191: {
                    192:     register struct object *obj;
                    193:     register char ch;
                    194:     register int n_objs;
                    195:     char inv_temp[80];
                    196: 
                    197:     n_objs = 0;
                    198:     for (ch = 'a'; list != NULL; ch++, list = next(list))
                    199:     {
                    200:        obj = (struct object *) ldata(list);
                    201:        if (type && type != obj->o_type && !(type == CALLABLE &&
                    202:            (obj->o_type == SCROLL || obj->o_type == POTION ||
                    203:             obj->o_type == RING || obj->o_type == STICK)))
                    204:                continue;
                    205:        switch (n_objs++)
                    206:        {
                    207:            /*
                    208:             * For the first thing in the inventory, just save the string
                    209:             * in case there is only one.
                    210:             */
                    211:            case 0:
                    212:                sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE));
                    213:                break;
                    214:            /*
                    215:             * If there is more than one, clear the screen, print the
                    216:             * saved message and fall through to ...
                    217:             */
                    218:            case 1:
                    219:                if (slow_invent)
                    220:                    msg(inv_temp);
                    221:                else
                    222:                {
                    223:                    wclear(hw);
                    224:                    waddstr(hw, inv_temp);
                    225:                    waddch(hw, '\n');
                    226:                }
                    227:            /*
                    228:             * Print the line for this object
                    229:             */
                    230:            default:
                    231:                if (slow_invent)
                    232:                    msg("%c) %s", ch, inv_name(obj, FALSE));
                    233:                else
                    234:                    wprintw(hw, "%c) %s\n", ch, inv_name(obj, FALSE));
                    235:        }
                    236:     }
                    237:     if (n_objs == 0)
                    238:     {
                    239:        if (terse)
                    240:            msg(type == 0 ? "Empty handed." :
                    241:                            "Nothing appropriate");
                    242:        else
                    243:            msg(type == 0 ? "You are empty handed." :
                    244:                            "You don't have anything appropriate");
                    245:        return FALSE;
                    246:     }
                    247:     if (n_objs == 1)
                    248:     {
                    249:        msg(inv_temp);
                    250:        return TRUE;
                    251:     }
                    252:     if (!slow_invent)
                    253:     {
                    254:        mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
                    255:        draw(hw);
                    256:        wait_for(' ');
                    257:        clearok(cw, TRUE);
                    258:        touchwin(cw);
                    259:     }
                    260:     return TRUE;
                    261: }
                    262: 
                    263: /*
                    264:  * pick_up:
                    265:  *     Add something to characters pack.
                    266:  */
                    267: pick_up(ch)
                    268: char ch;
                    269: {
                    270:     switch(ch)
                    271:     {
                    272:        case GOLD:
                    273:            money();
                    274:            break;
                    275:        default:
                    276:            debug("Where did you pick that up???");
                    277:        case ARMOR:
                    278:        case POTION:
                    279:        case FOOD:
                    280:        case WEAPON:
                    281:        case SCROLL:    
                    282:        case AMULET:
                    283:        case RING:
                    284:        case STICK:
                    285:            add_pack(NULL, FALSE);
                    286:            break;
                    287:     }
                    288: }
                    289: 
                    290: /*
                    291:  * picky_inven:
                    292:  *     Allow player to inventory a single item
                    293:  */
                    294: picky_inven()
                    295: {
                    296:     register struct linked_list *item;
                    297:     register char ch, mch;
                    298: 
                    299:     if (pack == NULL)
                    300:        msg("You aren't carrying anything");
                    301:     else if (next(pack) == NULL)
                    302:        msg("a) %s", inv_name((struct object *) ldata(pack), FALSE));
                    303:     else
                    304:     {
                    305:        msg(terse ? "Item: " : "Which item do you wish to inventory: ");
                    306:        mpos = 0;
                    307:        if ((mch = readchar()) == ESCAPE)
                    308:        {
                    309:            msg("");
                    310:            return;
                    311:        }
                    312:        for (ch = 'a', item = pack; item != NULL; item = next(item), ch++)
                    313:            if (ch == mch)
                    314:            {
                    315:                msg("%c) %s",ch,inv_name((struct object *) ldata(item), FALSE));
                    316:                return;
                    317:            }
                    318:        if (!terse)
                    319:            msg("'%s' not in pack", unctrl(mch));
                    320:        msg("Range is 'a' to '%c'", --ch);
                    321:     }
                    322: }
                    323: 
                    324: /*
                    325:  * get_item:
                    326:  *     pick something out of a pack for a purpose
                    327:  */
                    328: struct linked_list *
                    329: get_item(purpose, type)
                    330: char *purpose;
                    331: int type;
                    332: {
                    333:     register struct linked_list *obj;
                    334:     register char ch, och;
                    335: 
                    336:     if (pack == NULL)
                    337:        msg("You aren't carrying anything.");
                    338:     else
                    339:     {
                    340:        for (;;)
                    341:        {
                    342:            if (!terse)
                    343:                addmsg("Which object do you want to ");
                    344:            addmsg(purpose);
                    345:            if (terse)
                    346:                addmsg(" what");
                    347:            msg("? (* for list): ");
                    348:            ch = readchar();
                    349:            mpos = 0;
                    350:            /*
                    351:             * Give the poor player a chance to abort the command
                    352:             */
                    353:            if (ch == ESCAPE || ch == CTRL(G))
                    354:            {
                    355:                after = FALSE;
                    356:                msg("");
                    357:                return NULL;
                    358:            }
                    359:            if (ch == '*')
                    360:            {
                    361:                mpos = 0;
                    362:                if (inventory(pack, type) == 0)
                    363:                {
                    364:                    after = FALSE;
                    365:                    return NULL;
                    366:                }
                    367:                continue;
                    368:            }
                    369:            for (obj = pack, och = 'a'; obj != NULL; obj = next(obj), och++)
                    370:                if (ch == och)
                    371:                    break;
                    372:            if (obj == NULL)
                    373:            {
                    374:                msg("Please specify a letter between 'a' and '%c'", och-1);
                    375:                continue;
                    376:            }
                    377:            else 
                    378:                return obj;
                    379:        }
                    380:     }
                    381:     return NULL;
                    382: }
                    383: 
                    384: pack_char(obj)
                    385: register struct object *obj;
                    386: {
                    387:     register struct linked_list *item;
                    388:     register char c;
                    389: 
                    390:     c = 'a';
                    391:     for (item = pack; item != NULL; item = next(item))
                    392:        if ((struct object *) ldata(item) == obj)
                    393:            return c;
                    394:        else
                    395:            c++;
                    396:     return 'z';
                    397: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.