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

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

1.1       rubenllo    1: /*
                      2:  * Routines to deal with the pack
                      3:  *
                      4:  * @(#)pack.c  4.40 (Berkeley) 02/05/99
                      5:  *
                      6:  * Rogue: Exploring the Dungeons of Doom
                      7:  * Copyright (C) 1980-1983, 1985, 1999 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 <string.h>
                     14: #include <curses.h>
                     15: #include <ctype.h>
                     16: #include "rogue.h"
                     17:
                     18: /*
                     19:  * update_mdest:
                     20:  *      Called after picking up an object, before discarding it.
                     21:  *      If this was the object of something's desire, that monster will
                     22:  *      get mad and run at the hero
                     23:  */
                     24: void
                     25: update_mdest(THING *obj)
                     26: {
                     27:     register THING *mp;
                     28:
                     29:     for (mp = mlist; mp != NULL; mp = next(mp))
                     30:         if (mp->t_dest == &obj->o_pos)
                     31:      mp->t_dest = &hero;
                     32: }
                     33:
                     34: /*
                     35:  * add_pack:
                     36:  *     Pick up an object and add it to the pack.  If the argument is
                     37:  *     non-null use it as the linked_list pointer instead of gettting
                     38:  *     it off the ground.
                     39:  */
                     40:
                     41: void
                     42: add_pack(THING *obj, int silent)
                     43: {
                     44:     THING *op, *lp;
                     45:     int from_floor;
                     46:     int discarded = 0;
                     47:
                     48:     from_floor = FALSE;
                     49:     if (obj == NULL)
                     50:     {
                     51:        if ((obj = find_obj(hero.y, hero.x)) == NULL)
                     52:            return;
                     53:        from_floor = TRUE;
                     54:     }
                     55:
                     56:     /*
                     57:      * Check for and deal with scare monster scrolls
                     58:      */
                     59:     if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
                     60:        if (obj->o_flags & ISFOUND)
                     61:        {
                     62:            detach(lvl_obj, obj);
                     63:            mvaddch(hero.y, hero.x, floor_ch());
                     64:            chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
                     65:             update_mdest(obj);
                     66:             discarded = 1;
                     67:            discard(obj);
                     68:            msg("the scroll turns to dust as you pick it up");
                     69:            return;
                     70:        }
                     71:
                     72:     if (pack == NULL)
                     73:     {
                     74:        pack = obj;
                     75:        obj->o_packch = pack_char();
                     76:        inpack++;
                     77:     }
                     78:     else
                     79:     {
                     80:        lp = NULL;
                     81:        for (op = pack; op != NULL; op = next(op))
                     82:        {
                     83:            if (op->o_type != obj->o_type)
                     84:                lp = op;
                     85:            else
                     86:            {
                     87:                while (op->o_type == obj->o_type && op->o_which != obj->o_which)
                     88:                {
                     89:                    lp = op;
                     90:                    if (next(op) == NULL)
                     91:                        break;
                     92:                    else
                     93:                        op = next(op);
                     94:                }
                     95:                if (op->o_type == obj->o_type && op->o_which == obj->o_which)
                     96:                {
                     97:                    if (ISMULT(op->o_type))
                     98:                    {
                     99:                        if (!pack_room(from_floor, obj))
                    100:                            return;
                    101:                        op->o_count++;
                    102: dump_it:
                    103:                        update_mdest(obj);
                    104:                        discard(obj);
                    105:                        obj = op;
                    106:                         discarded = 1;
                    107:                        lp = NULL;
                    108:                        goto out;
                    109:                    }
                    110:                    else if (obj->o_group)
                    111:                    {
                    112:                        lp = op;
                    113:                        while (op->o_type == obj->o_type
                    114:                            && op->o_which == obj->o_which
                    115:                            && op->o_group != obj->o_group)
                    116:                        {
                    117:                            lp = op;
                    118:                            if (next(op) == NULL)
                    119:                                break;
                    120:                            else
                    121:                                op = next(op);
                    122:                        }
                    123:                        if (op->o_type == obj->o_type
                    124:                            && op->o_which == obj->o_which
                    125:                            && op->o_group == obj->o_group)
                    126:                        {
                    127:                                op->o_count += obj->o_count;
                    128:                                inpack--;
                    129:                                if (!pack_room(from_floor, obj))
                    130:                                    return;
                    131:                                goto dump_it;
                    132:                        }
                    133:                    }
                    134:                    else
                    135:                        lp = op;
                    136:                }
                    137: out:
                    138:                break;
                    139:            }
                    140:        }
                    141:
                    142:        if (lp != NULL)
                    143:        {
                    144:            if (!pack_room(from_floor, obj))
                    145:                return;
                    146:            else
                    147:            {
                    148:                obj->o_packch = pack_char();
                    149:                next(obj) = next(lp);
                    150:                prev(obj) = lp;
                    151:                if (next(lp) != NULL)
                    152:                    prev(next(lp)) = obj;
                    153:                next(lp) = obj;
                    154:            }
                    155:        }
                    156:     }
                    157:
                    158:     obj->o_flags |= ISFOUND;
                    159:
                    160:     /*
                    161:      * If this was the object of something's desire, that monster will
                    162:      * get mad and run at the hero.
                    163:      */
                    164:     if (!discarded)
                    165:         update_mdest(obj);
                    166:
                    167:     if (obj->o_type == AMULET)
                    168:        amulet = TRUE;
                    169:     /*
                    170:      * Notify the user
                    171:      */
                    172:     if (!silent)
                    173:     {
                    174:        if (!terse)
                    175:            addmsg("you now have ");
                    176:        msg("%s (%c)", inv_name(obj, !terse), obj->o_packch);
                    177:     }
                    178: }
                    179:
                    180: /*
                    181:  * pack_room:
                    182:  *     See if there's room in the pack.  If not, print out an
                    183:  *     appropriate message
                    184:  */
                    185: int
                    186: pack_room(int from_floor, THING *obj)
                    187: {
                    188:     if (++inpack > MAXPACK)
                    189:     {
                    190:        if (!terse)
                    191:            addmsg("there's ");
                    192:        addmsg("no room");
                    193:        if (!terse)
                    194:            addmsg(" in your pack");
                    195:        endmsg();
                    196:        if (from_floor)
                    197:            move_msg(obj);
                    198:        inpack = MAXPACK;
                    199:        return FALSE;
                    200:     }
                    201:
                    202:     if (from_floor)
                    203:     {
                    204:        detach(lvl_obj, obj);
                    205:        mvaddch(hero.y, hero.x, floor_ch());
                    206:        chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
                    207:     }
                    208:
                    209:     return TRUE;
                    210: }
                    211:
                    212: /*
                    213:  * leave_pack:
                    214:  *     take an item out of the pack
                    215:  */
                    216: THING *
                    217: leave_pack(THING *obj, int newobj, int all)
                    218: {
                    219:     THING *nobj;
                    220:
                    221:     inpack--;
                    222:     nobj = obj;
                    223:     if (obj->o_count > 1 && !all)
                    224:     {
                    225:        last_pick = obj;
                    226:        obj->o_count--;
                    227:        if (obj->o_group)
                    228:            inpack++;
                    229:        if (newobj)
                    230:        {
                    231:            nobj = new_item();
                    232:            *nobj = *obj;
                    233:            next(nobj) = NULL;
                    234:            prev(nobj) = NULL;
                    235:            nobj->o_count = 1;
                    236:        }
                    237:     }
                    238:     else
                    239:     {
                    240:        last_pick = NULL;
                    241:        pack_used[obj->o_packch - 'a'] = FALSE;
                    242:        detach(pack, obj);
                    243:     }
                    244:     return nobj;
                    245: }
                    246:
                    247: /*
                    248:  * pack_char:
                    249:  *     Return the next unused pack character.
                    250:  */
                    251: int
                    252: pack_char(void)
                    253: {
                    254:     int *bp;
                    255:
                    256:     for (bp = pack_used; *bp; bp++)
                    257:        continue;
                    258:     *bp = TRUE;
                    259:     return ((int)(bp - pack_used) + 'a');
                    260: }
                    261:
                    262: /*
                    263:  * inventory:
                    264:  *     List what is in the pack.  Return TRUE if there is something of
                    265:  *     the given type.
                    266:  */
                    267: int
                    268: inventory(const THING *list, int type)
                    269: {
                    270:     static char inv_temp[MAXSTR];
                    271:
                    272:     n_objs = 0;
                    273:     for (; list != NULL; list = next(list))
                    274:     {
                    275:        if (type && type != list->o_type && !(type == CALLABLE &&
                    276:            list->o_type != FOOD && list->o_type != AMULET) &&
                    277:            !(type == R_OR_S && (list->o_type == RING || list->o_type == STICK)))
                    278:                continue;
                    279:        n_objs++;
                    280: #ifdef MASTER
                    281:        if (!list->o_packch)
                    282:            strcpy(inv_temp, "%s");
                    283:        else
                    284: #endif
                    285:            sprintf(inv_temp, "%c) %%s", list->o_packch);
                    286:        msg_esc = TRUE;
                    287:        if (add_line(inv_temp, inv_name(list, FALSE)) == ESCAPE)
                    288:        {
                    289:            msg_esc = FALSE;
                    290:            msg("");
                    291:            return TRUE;
                    292:        }
                    293:        msg_esc = FALSE;
                    294:     }
                    295:     if (n_objs == 0)
                    296:     {
                    297:        if (terse)
                    298:            msg(type == 0 ? "empty handed" :
                    299:                            "nothing appropriate");
                    300:        else
                    301:            msg(type == 0 ? "you are empty handed" :
                    302:                            "you don't have anything appropriate");
                    303:        return FALSE;
                    304:     }
                    305:     end_line();
                    306:     return TRUE;
                    307: }
                    308:
                    309: /*
                    310:  * pick_up:
                    311:  *     Add something to characters pack.
                    312:  */
                    313:
                    314: void
                    315: pick_up(int ch)
                    316: {
                    317:     THING *obj;
                    318:
                    319:     if (on(player, ISLEVIT))
                    320:        return;
                    321:
                    322:     obj = find_obj(hero.y, hero.x);
                    323:     if (move_on)
                    324:        move_msg(obj);
                    325:     else
                    326:        switch (ch)
                    327:        {
                    328:            case GOLD:
                    329:                if (obj == NULL)
                    330:                    return;
                    331:                money(obj->o_goldval);
                    332:                detach(lvl_obj, obj);
                    333:                update_mdest(obj);
                    334:                discard(obj);
                    335:                proom->r_goldval = 0;
                    336:                break;
                    337:            default:
                    338: #ifdef MASTER
                    339:                debug("Where did you pick a '%s' up???", unctrl(ch));
                    340: #endif
                    341:            case ARMOR:
                    342:            case POTION:
                    343:            case FOOD:
                    344:            case WEAPON:
                    345:            case SCROLL:
                    346:            case AMULET:
                    347:            case RING:
                    348:            case STICK:
                    349:                add_pack(NULL, FALSE);
                    350:                break;
                    351:        }
                    352: }
                    353:
                    354: /*
                    355:  * move_msg:
                    356:  *     Print out the message if you are just moving onto an object
                    357:  */
                    358:
                    359: void
                    360: move_msg(const THING *obj)
                    361: {
                    362:     if (!terse)
                    363:        addmsg("you ");
                    364:     msg("moved onto %s", inv_name(obj, TRUE));
                    365: }
                    366:
                    367: /*
                    368:  * picky_inven:
                    369:  *     Allow player to inventory a single item
                    370:  */
                    371:
                    372: void
                    373: picky_inven(void)
                    374: {
                    375:     THING *obj;
                    376:     int mch;
                    377:
                    378:     if (pack == NULL)
                    379:        msg("you aren't carrying anything");
                    380:     else if (next(pack) == NULL)
                    381:        msg("a) %s", inv_name(pack, FALSE));
                    382:     else
                    383:     {
                    384:        msg(terse ? "item: " : "which item do you wish to inventory: ");
                    385:        mpos = 0;
                    386:        if ((mch = readchar()) == ESCAPE)
                    387:        {
                    388:            msg("");
                    389:            return;
                    390:        }
                    391:        for (obj = pack; obj != NULL; obj = next(obj))
                    392:            if (mch == obj->o_packch)
                    393:            {
                    394:                msg("%c) %s", mch, inv_name(obj, FALSE));
                    395:                return;
                    396:            }
                    397:        msg("'%s' not in pack", unctrl(mch));
                    398:     }
                    399: }
                    400:
                    401: /*
                    402:  * get_item:
                    403:  *     Pick something out of a pack for a purpose
                    404:  */
                    405: THING *
                    406: get_item(const char *purpose, int type)
                    407: {
                    408:     THING *obj;
                    409:     int ch;
                    410:
                    411:     if (pack == NULL)
                    412:        msg("you aren't carrying anything");
                    413:     else if (again)
                    414:        if (last_pick)
                    415:            return last_pick;
                    416:        else
                    417:            msg("you ran out");
                    418:     else
                    419:     {
                    420:        for (;;)
                    421:        {
                    422:            if (!terse)
                    423:                addmsg("which object do you want to ");
                    424:            addmsg(purpose);
                    425:            if (terse)
                    426:                addmsg(" what");
                    427:            msg("? (* for list): ");
                    428:            ch = readchar();
                    429:            mpos = 0;
                    430:            /*
                    431:             * Give the poor player a chance to abort the command
                    432:             */
                    433:            if (ch == ESCAPE)
                    434:            {
                    435:                reset_last();
                    436:                after = FALSE;
                    437:                msg("");
                    438:                return NULL;
                    439:            }
                    440:            n_objs = 1;         /* normal case: person types one char */
                    441:            if (ch == '*')
                    442:            {
                    443:                mpos = 0;
                    444:                if (inventory(pack, type) == 0)
                    445:                {
                    446:                    after = FALSE;
                    447:                    return NULL;
                    448:                }
                    449:                continue;
                    450:            }
                    451:            for (obj = pack; obj != NULL; obj = next(obj))
                    452:                if (obj->o_packch == ch)
                    453:                    break;
                    454:            if (obj == NULL)
                    455:            {
                    456:                msg("'%s' is not a valid item",unctrl(ch));
                    457:                continue;
                    458:            }
                    459:            else {
                    460:                msg("");
                    461:                return obj;
                    462:            }
                    463:        }
                    464:     }
                    465:     return NULL;
                    466: }
                    467:
                    468: /*
                    469:  * money:
                    470:  *     Add or subtract gold from the pack
                    471:  */
                    472:
                    473: void
                    474: money(int value)
                    475: {
                    476:     purse += value;
                    477:     mvaddch(hero.y, hero.x, floor_ch());
                    478:     chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
                    479:     if (value > 0)
                    480:     {
                    481:        if (!terse)
                    482:            addmsg("you found ");
                    483:        msg("%d gold pieces", value);
                    484:     }
                    485: }
                    486:
                    487: /*
                    488:  * floor_ch:
                    489:  *     Return the appropriate floor character for her room
                    490:  */
                    491: int
                    492: floor_ch(void)
                    493: {
                    494:     if (proom->r_flags & ISGONE)
                    495:        return PASSAGE;
                    496:     return (show_floor() ? FLOOR : ' ');
                    497: }
                    498:
                    499: /*
                    500:  * floor_at:
                    501:  *     Return the character at hero's position, taking see_floor
                    502:  *     into account
                    503:  */
                    504: int
                    505: floor_at(void)
                    506: {
                    507:     int ch;
                    508:
                    509:     ch = chat(hero.y, hero.x);
                    510:     if (ch == FLOOR)
                    511:        ch = floor_ch();
                    512:     return ch;
                    513: }
                    514:
                    515: /*
                    516:  * reset_last:
                    517:  *     Reset the last command when the current one is aborted
                    518:  */
                    519:
                    520: void
                    521: reset_last(void)
                    522: {
                    523:     last_comm = l_last_comm;
                    524:     last_dir = l_last_dir;
                    525:     last_pick = l_last_pick;
                    526: }

CVSweb