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

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

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

CVSweb