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