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

Annotation of early-roguelike/urogue/bag.c, Revision 1.1

1.1     ! rubenllo    1: /*
        !             2:     bag.c  -  functions for dealing with bags
        !             3:
        !             4:     UltraRogue: The Ultimate Adventure in the Dungeons of Doom
        !             5:     Copyright (C) 1986, 1992, 1993, 1995 Herb Chong
        !             6:     All rights reserved.
        !             7:
        !             8:     See the file LICENSE.TXT for full copyright and licensing information.
        !             9: */
        !            10:
        !            11: /*
        !            12:  * new bag functions
        !            13:  *
        !            14:  * This is a simple version of bag.c that uses linked lists to perform the bag
        !            15:  * functions. The bag is just a linked list of objects (struct object) to be
        !            16:  * specific, but most of that is supposed to be hidden from the user, who
        !            17:  * should access the bag only through the functions presented here.
        !            18:  */
        !            19:
        !            20: #include <stdlib.h>
        !            21: #include "rogue.h"
        !            22:
        !            23: /*
        !            24:  * apply_to_bag
        !            25:  *
        !            26:  * This is the general bag manipulation routine. The bag is subjected to
        !            27:  * selection criteria and those objects which pass are processed by an action
        !            28:  * routine. The two criteria are type and filter function. The filter
        !            29:  * function returns TRUE if the object passes and FALSE otherwise. The filter
        !            30:  * function is passed the object and the user-supplied argument. This gives
        !            31:  * the user plenty of flexibility in determining which items will be
        !            32:  * processed. The action routine is passed the object, the id, and the
        !            33:  * user-supplied argument given to apply_to_bag. Specifying NULL for either
        !            34:  * the type or filter function means that criterion always selects. A NULL
        !            35:  * action routine means no processing is done and the first object which
        !            36:  * passes the filter is returned to the user. The action routine returns TRUE
        !            37:  * if processing should continue or FALSE if the current item should be
        !            38:  * returned to the caller.
        !            39:  *
        !            40:  * Returns NULL if the bag is empty or if nothing qualified.
        !            41:  *
        !            42:  * linked_list *bag_p;       // linked list of objects
        !            43:  * int          type;        // what is its type (ARMOR, ...)
        !            44:  * int        (*bff_p)();    // bag filter function
        !            45:  * int        (*baf_p)();    // bag action routine
        !            46:  * long         user_arg;    // user argument for filter, action
        !            47:  *
        !            48:  */
        !            49:
        !            50: struct object *
        !            51: apply_to_bag(struct linked_list *bag_p,
        !            52:              int type,
        !            53:              int (*bff_p)(struct object *obj, bag_arg *user_arg),
        !            54:              int (*baf_p)(struct object *obj, bag_arg *user_arg, int id),
        !            55:              void *user_arg)
        !            56: {
        !            57:     struct object *bag_obj_p = NULL;  /* qualifying object */
        !            58:     struct object *cur_obj_p;         /* current object */
        !            59:     bag_arg arg;
        !            60:
        !            61:     arg.varg = user_arg;
        !            62:
        !            63:     if (bag_p == NULL)
        !            64:         return (NULL);
        !            65:
        !            66:     for (; bag_p != NULL; bag_p = next(bag_p))
        !            67:     {
        !            68:         cur_obj_p = OBJPTR(bag_p);
        !            69:
        !            70:         if (type != 0 && type != cur_obj_p->o_type)
        !            71:             continue;
        !            72:
        !            73:         if (bff_p != NULL && !(*bff_p)(cur_obj_p, &arg))
        !            74:             continue;
        !            75:
        !            76:         /*
        !            77:          * At this point, we have an object which qualifies for
        !            78:          * processing
        !            79:          */
        !            80:
        !            81:         bag_obj_p = cur_obj_p;  /* in case the user wants it */
        !            82:
        !            83:         if (baf_p != NULL && (*baf_p)(cur_obj_p, &arg, identifier(bag_obj_p)))
        !            84:             continue;
        !            85:
        !            86:         /*
        !            87:          * We have an object which qualifies, quit now!
        !            88:          */
        !            89:
        !            90:         break;
        !            91:     }
        !            92:
        !            93:     if (bag_p == NULL)
        !            94:         return (NULL);
        !            95:
        !            96:     return (bag_obj_p);
        !            97: }
        !            98:
        !            99: /*
        !           100:     count_bag()
        !           101:
        !           102:         Counts up all bag items which meet the selection criteria
        !           103: */
        !           104:
        !           105: int
        !           106: count_bag(linked_list *bag_p,
        !           107:           int type,
        !           108:           int (*bff_p)(struct object *obj, bag_arg *junk))
        !           109: {
        !           110:     int cnt = 0;
        !           111:     apply_to_bag(bag_p, type, bff_p, baf_increment, &cnt);
        !           112:
        !           113:     return(cnt);
        !           114: }
        !           115:
        !           116: /*
        !           117:     del_bag()
        !           118:
        !           119:         Removes an object from a bag and throws it away.
        !           120: */
        !           121:
        !           122: void
        !           123: del_bag(linked_list *bag_p, object *obj_p)
        !           124: {
        !           125:     pop_bag(&bag_p, obj_p);  /* get the thing from the bag */
        !           126:     ur_free(obj_p);         /* release the memory */
        !           127: }
        !           128:
        !           129: /*
        !           130:     pop_bag()
        !           131:
        !           132:         Removes an item from a bag and returns it to the user. If the item is
        !           133:         not in the bag, return NULL.
        !           134: */
        !           135:
        !           136: struct object *
        !           137: pop_bag(linked_list **bag_pp, object *obj_p)
        !           138: {
        !           139:     linked_list *item_p;
        !           140:
        !           141:     for (item_p = *bag_pp; item_p != NULL && OBJPTR(item_p) != obj_p;
        !           142:          item_p = next(item_p));
        !           143:
        !           144:     if (item_p == NULL)
        !           145:         return (NULL);
        !           146:
        !           147:     _detach(bag_pp, item_p);
        !           148:
        !           149:     return (obj_p);
        !           150: }
        !           151:
        !           152: /*
        !           153:     push_bag()
        !           154:
        !           155:         stuff another item into the bag
        !           156: */
        !           157:
        !           158: void
        !           159: push_bag(linked_list **bag_pp, object *obj_p)
        !           160: {
        !           161:     struct linked_list *item_p = NULL;
        !           162:     struct linked_list *new_p  = NULL;
        !           163:     struct linked_list *best_p = NULL;
        !           164:
        !           165:     new_p             = new_list();
        !           166:     new_p->data.obj   = obj_p;              /* attach our object   */
        !           167:     identifier(obj_p) = get_ident(obj_p);   /* tag this object for */
        !           168:                                             /*     inventory       */
        !           169:     /*
        !           170:      * Find a place in the bag - try to match the type, then sort by
        !           171:      * identifier
        !           172:      */
        !           173:
        !           174:     for (item_p = *bag_pp; item_p != NULL; item_p = next(item_p))
        !           175:     {
        !           176:         if ((OBJPTR(item_p))->o_type == obj_p->o_type)
        !           177:         {
        !           178:             if (best_p == NULL)
        !           179:                 best_p = item_p;
        !           180:             else if (identifier((OBJPTR(item_p))) >
        !           181:                      identifier((OBJPTR(best_p))) &&
        !           182:                      identifier((OBJPTR(item_p))) <
        !           183:                      identifier(obj_p))
        !           184:                 best_p = item_p;
        !           185:         }
        !           186:     }
        !           187:
        !           188:     _attach_after(bag_pp, best_p, new_p);   /* stuff it in the list */
        !           189:
        !           190:     return;
        !           191: }
        !           192:
        !           193: /*
        !           194:     scan_bag()
        !           195:
        !           196:         Gets the object from the bag that matches the type and id. The object
        !           197:         is not removed from the bag.
        !           198: */
        !           199:
        !           200: struct object *
        !           201: scan_bag(linked_list *bag_p, int type, int id)
        !           202: {
        !           203:     object  *obj_p = NULL;
        !           204:
        !           205:     for (; bag_p != NULL; bag_p = next(bag_p))
        !           206:     {
        !           207:         obj_p = OBJPTR(bag_p);
        !           208:
        !           209:         if (obj_p->o_type == type && identifier(obj_p) == id)
        !           210:             break;
        !           211:     }
        !           212:
        !           213:     if (bag_p == NULL)
        !           214:         return(NULL);
        !           215:
        !           216:     return(obj_p);
        !           217: }
        !           218:
        !           219: /*
        !           220:     baf_decrement_test()
        !           221:
        !           222:         Assumes the argument is a pointer to int and it just decrements it.
        !           223:         Returns TRUE, except when the count goes to zero.
        !           224: */
        !           225:
        !           226: int
        !           227: baf_decrement_test(struct object *obj_p, bag_arg *count_p, int id)
        !           228: {
        !           229:     NOOP(obj_p);
        !           230:     NOOP(id);
        !           231:
        !           232:     if (*count_p->iarg > 0)
        !           233:         return(TRUE);
        !           234:
        !           235:     return(FALSE);
        !           236: }
        !           237:
        !           238: /*
        !           239:     baf_identify()
        !           240:
        !           241:         Bag action function to identify an object. This is needed to conform
        !           242:         to bag action routine calling conventions and to put the linked list
        !           243:         structure on top of the object before calling whatis()
        !           244: */
        !           245:
        !           246: int
        !           247: baf_identify(struct object *obj_p, bag_arg *junk, int id)
        !           248: {
        !           249:     linked_list l;
        !           250:     linked_list *lp = &l;
        !           251:
        !           252:     NOOP(junk);
        !           253:     NOOP(id);
        !           254:
        !           255:     lp->data.obj = obj_p;    /* stuff object in the right place */
        !           256:     whatis(lp);
        !           257:
        !           258:     return(TRUE);
        !           259: }
        !           260:
        !           261: /*
        !           262:     baf_increment()
        !           263:
        !           264:         Assumes the argument is a pointer to int and it just increments it and
        !           265:         returns TRUE
        !           266: */
        !           267:
        !           268: int
        !           269: baf_increment(object *obj_p, bag_arg *count_p, int id)
        !           270: {
        !           271:     NOOP(obj_p);
        !           272:     NOOP(id);
        !           273:
        !           274:     (*count_p->iarg)++;
        !           275:
        !           276:     return(TRUE);
        !           277: }
        !           278:
        !           279: /*
        !           280:     baf_print_item()
        !           281:         Bag action function to print a single item, inventory style.
        !           282: */
        !           283:
        !           284: int
        !           285: baf_print_item(struct object *obj_p, bag_arg *type, int id)
        !           286: {
        !           287:     char inv_temp[3 * LINELEN];  /* plenty of space for paranoid programmers */
        !           288:
        !           289:     if (*type->iarg == 0)
        !           290:         sprintf(inv_temp, "%c%c) %s", obj_p->o_type,
        !           291:               print_letters[id], inv_name(obj_p, LOWERCASE));
        !           292:     else
        !           293:         sprintf(inv_temp, "%c) %s", print_letters[id],
        !           294:             inv_name(obj_p, LOWERCASE));
        !           295:
        !           296:     add_line(inv_temp);
        !           297:     return(TRUE);
        !           298: }
        !           299:
        !           300: /*
        !           301:     bff_group()
        !           302:         This bag filter function checks to see if two items can be combined by
        !           303:         adjusting the count. Grouped items can be combined if the group numbers
        !           304:         match. The only other item that is allowed to have a count is food, and
        !           305:         there an exact match is required.
        !           306: */
        !           307:
        !           308: int
        !           309: bff_group(struct object *obj_p, bag_arg *arg)
        !           310: {
        !           311:     struct object *new_obj_p = arg->obj;
        !           312:
        !           313:     if (new_obj_p->o_group > 0 && new_obj_p->o_group == obj_p->o_group)
        !           314:         return(TRUE);
        !           315:
        !           316:     if (new_obj_p->o_type == FOOD &&
        !           317:         obj_p->o_type == new_obj_p->o_type &&
        !           318:         obj_p->o_which == new_obj_p->o_which)
        !           319:         return(TRUE);
        !           320:
        !           321:     return(FALSE);
        !           322: }
        !           323:
        !           324: /*
        !           325:     bff_callable
        !           326:         Figures out which items can be callable: current rules are:
        !           327:             potions, scrolls, staffs, and rings.
        !           328: */
        !           329:
        !           330: int
        !           331: bff_callable(struct object *obj_p, bag_arg *junk)
        !           332: {
        !           333:     NOOP(junk);
        !           334:
        !           335:     if (obj_p->o_type == POTION || obj_p->o_type == RING ||
        !           336:         obj_p->o_type == STICK || obj_p->o_type == SCROLL)
        !           337:         return(TRUE);
        !           338:
        !           339:     return(FALSE);
        !           340: }
        !           341:
        !           342: /*
        !           343:     bff_markable()
        !           344:         Selects which items can be marked. Current rules exclude only gold.
        !           345: */
        !           346:
        !           347: int
        !           348: bff_markable(struct object *obj_p, bag_arg *junk)
        !           349: {
        !           350:     NOOP(junk);
        !           351:
        !           352:     if (obj_p->o_type == GOLD)
        !           353:         return(FALSE);
        !           354:
        !           355:     return(TRUE);
        !           356: }
        !           357:
        !           358: /*
        !           359:     bffron()
        !           360:         returns TRUE if hero is wearing this ring
        !           361: */
        !           362:
        !           363: int
        !           364: bffron(object *obj_p, bag_arg *junk)
        !           365: {
        !           366:     NOOP(junk);
        !           367:
        !           368:     return(cur_ring[LEFT_1] == obj_p || cur_ring[LEFT_2] == obj_p ||
        !           369:         cur_ring[LEFT_3] == obj_p || cur_ring[LEFT_4] == obj_p ||
        !           370:         cur_ring[LEFT_5] ||
        !           371:         cur_ring[RIGHT_1] == obj_p || cur_ring[RIGHT_2] == obj_p ||
        !           372:         cur_ring[RIGHT_3] == obj_p || cur_ring[RIGHT_4] == obj_p ||
        !           373:         cur_ring[RIGHT_5]);
        !           374: }
        !           375:
        !           376: /*
        !           377:     bff_zappable()
        !           378:         Selects which items can be zapped. This includes both sticks and
        !           379:         magically enhanced weapons with lightning ability.
        !           380: */
        !           381:
        !           382: int
        !           383: bff_zappable(struct object *obj_p, bag_arg *junk)
        !           384: {
        !           385:     NOOP(junk);
        !           386:
        !           387:     if (obj_p->o_type == STICK)
        !           388:         return(TRUE);
        !           389:
        !           390:     if (obj_p->o_type == WEAPON && obj_p->o_flags & ISZAPPED)
        !           391:         return(TRUE);
        !           392:
        !           393:     return (FALSE);
        !           394: }
        !           395:
        !           396: /*
        !           397:     baf_curse()
        !           398:         Curse all non-artifact items in the player's pack
        !           399: */
        !           400:
        !           401: int
        !           402: baf_curse(struct object *obj_p, bag_arg *junk, int id)
        !           403: {
        !           404:     NOOP(junk);
        !           405:     NOOP(id);
        !           406:
        !           407:     if (obj_p->o_type != ARTIFACT && rnd(8) == 0)
        !           408:     {
        !           409:         obj_p->o_flags |= ISCURSED;
        !           410:         obj_p->o_flags &= ~ISBLESSED;
        !           411:     }
        !           412:
        !           413:     return(TRUE);
        !           414: }
        !           415:
        !           416: /*
        !           417:     bafcweapon()
        !           418:         bag action routine to fetch the current weapon
        !           419: */
        !           420:
        !           421: int
        !           422: bafcweapon(struct object *obj_p, bag_arg *junk, int id)
        !           423: {
        !           424:     NOOP(junk);
        !           425:     NOOP(id);
        !           426:
        !           427:     if (obj_p == cur_weapon)
        !           428:         return(FALSE); /* found what we wanted - stop and return it */
        !           429:
        !           430:     return(TRUE);
        !           431: }
        !           432:
        !           433: /*
        !           434:     bafcarmor()
        !           435:         bag action routine to fetch the current armor
        !           436: */
        !           437:
        !           438: int
        !           439: bafcarmor(struct object *obj_p, bag_arg *junk, int id)
        !           440: {
        !           441:     NOOP(junk);
        !           442:     NOOP(id);
        !           443:
        !           444:     if (obj_p == cur_armor)
        !           445:         return(FALSE); /* found what we wanted - stop and return it */
        !           446:
        !           447:     return(TRUE);
        !           448: }

CVSweb