Annotation of 43BSDReno/games/rogue/pack.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Timothy C. Stoehr.
                      7:  *
                      8:  * Redistribution and use in source and binary forms are permitted
                      9:  * provided that: (1) source distributions retain this entire copyright
                     10:  * notice and comment, and (2) distributions including binaries display
                     11:  * the following acknowledgement:  ``This product includes software
                     12:  * developed by the University of California, Berkeley and its contributors''
                     13:  * in the documentation or other materials provided with the distribution
                     14:  * and in all advertising materials mentioning features or use of this
                     15:  * software. Neither the name of the University nor the names of its
                     16:  * contributors may be used to endorse or promote products derived
                     17:  * from this software without specific prior written permission.
                     18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     20:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     21:  */
                     22: 
                     23: #ifndef lint
                     24: static char sccsid[] = "@(#)pack.c     5.3 (Berkeley) 6/1/90";
                     25: #endif /* not lint */
                     26: 
                     27: /*
                     28:  * pack.c
                     29:  *
                     30:  * This source herein may be modified and/or distributed by anybody who
                     31:  * so desires, with the following restrictions:
                     32:  *    1.)  No portion of this notice shall be removed.
                     33:  *    2.)  Credit shall not be taken for the creation of this source.
                     34:  *    3.)  This code is not to be traded, sold, or used for personal
                     35:  *         gain or profit.
                     36:  *
                     37:  */
                     38: 
                     39: #include "rogue.h"
                     40: 
                     41: char *curse_message = "you can't, it appears to be cursed";
                     42: 
                     43: extern short levitate;
                     44: 
                     45: object *
                     46: add_to_pack(obj, pack, condense)
                     47: object *obj, *pack;
                     48: {
                     49:        object *op;
                     50: 
                     51:        if (condense) {
                     52:                if (op = check_duplicate(obj, pack)) {
                     53:                        free_object(obj);
                     54:                        return(op);
                     55:                } else {
                     56:                        obj->ichar = next_avail_ichar();
                     57:                }
                     58:        }
                     59:        if (pack->next_object == 0) {
                     60:                pack->next_object = obj;
                     61:        } else {
                     62:                op = pack->next_object;
                     63: 
                     64:                while (op->next_object) {
                     65:                        op = op->next_object;
                     66:                }
                     67:                op->next_object = obj;
                     68:        }
                     69:        obj->next_object = 0;
                     70:        return(obj);
                     71: }
                     72: 
                     73: take_from_pack(obj, pack)
                     74: object *obj, *pack;
                     75: {
                     76:        while (pack->next_object != obj) {
                     77:                pack = pack->next_object;
                     78:        }
                     79:        pack->next_object = pack->next_object->next_object;
                     80: }
                     81: 
                     82: /* Note: *status is set to 0 if the rogue attempts to pick up a scroll
                     83:  * of scare-monster and it turns to dust.  *status is otherwise set to 1.
                     84:  */
                     85: 
                     86: object *
                     87: pick_up(row, col, status)
                     88: short *status;
                     89: {
                     90:        object *obj;
                     91: 
                     92:        *status = 1;
                     93: 
                     94:        if (levitate) {
                     95:                message("you're floating in the air!", 0);
                     96:                return((object *) 0);
                     97:        }
                     98:        obj = object_at(&level_objects, row, col);
                     99:        if (!obj) {
                    100:                message("pick_up(): inconsistent", 1);
                    101:                return(obj);
                    102:        }
                    103:        if (    (obj->what_is == SCROL) &&
                    104:                        (obj->which_kind == SCARE_MONSTER) &&
                    105:                        obj->picked_up) {
                    106:                message("the scroll turns to dust as you pick it up", 0);
                    107:                dungeon[row][col] &= (~OBJECT);
                    108:                vanish(obj, 0, &level_objects);
                    109:                *status = 0;
                    110:                if (id_scrolls[SCARE_MONSTER].id_status == UNIDENTIFIED) {
                    111:                        id_scrolls[SCARE_MONSTER].id_status = IDENTIFIED;
                    112:                }
                    113:                return((object *) 0);
                    114:        }
                    115:        if (obj->what_is == GOLD) {
                    116:                rogue.gold += obj->quantity;
                    117:                dungeon[row][col] &= ~(OBJECT);
                    118:                take_from_pack(obj, &level_objects);
                    119:                print_stats(STAT_GOLD);
                    120:                return(obj);    /* obj will be free_object()ed in caller */
                    121:        }
                    122:        if (pack_count(obj) >= MAX_PACK_COUNT) {
                    123:                message("pack too full", 1);
                    124:                return((object *) 0);
                    125:        }
                    126:        dungeon[row][col] &= ~(OBJECT);
                    127:        take_from_pack(obj, &level_objects);
                    128:        obj = add_to_pack(obj, &rogue.pack, 1);
                    129:        obj->picked_up = 1;
                    130:        return(obj);
                    131: }
                    132: 
                    133: drop()
                    134: {
                    135:        object *obj, *new;
                    136:        short ch;
                    137:        char desc[DCOLS];
                    138: 
                    139:        if (dungeon[rogue.row][rogue.col] & (OBJECT | STAIRS | TRAP)) {
                    140:                message("there's already something there", 0);
                    141:                return;
                    142:        }
                    143:        if (!rogue.pack.next_object) {
                    144:                message("you have nothing to drop", 0);
                    145:                return;
                    146:        }
                    147:        if ((ch = pack_letter("drop what?", ALL_OBJECTS)) == CANCEL) {
                    148:                return;
                    149:        }
                    150:        if (!(obj = get_letter_object(ch))) {
                    151:                message("no such item.", 0);
                    152:                return;
                    153:        }
                    154:        if (obj->in_use_flags & BEING_WIELDED) {
                    155:                if (obj->is_cursed) {
                    156:                        message(curse_message, 0);
                    157:                        return;
                    158:                }
                    159:                unwield(rogue.weapon);
                    160:        } else if (obj->in_use_flags & BEING_WORN) {
                    161:                if (obj->is_cursed) {
                    162:                        message(curse_message, 0);
                    163:                        return;
                    164:                }
                    165:                mv_aquatars();
                    166:                unwear(rogue.armor);
                    167:                print_stats(STAT_ARMOR);
                    168:        } else if (obj->in_use_flags & ON_EITHER_HAND) {
                    169:                if (obj->is_cursed) {
                    170:                        message(curse_message, 0);
                    171:                        return;
                    172:                }
                    173:                un_put_on(obj);
                    174:        }
                    175:        obj->row = rogue.row;
                    176:        obj->col = rogue.col;
                    177: 
                    178:        if ((obj->quantity > 1) && (obj->what_is != WEAPON)) {
                    179:                obj->quantity--;
                    180:                new = alloc_object();
                    181:                *new = *obj;
                    182:                new->quantity = 1;
                    183:                obj = new;
                    184:        } else {
                    185:                obj->ichar = 'L';
                    186:                take_from_pack(obj, &rogue.pack);
                    187:        }
                    188:        place_at(obj, rogue.row, rogue.col);
                    189:        (void) strcpy(desc, "dropped ");
                    190:        get_desc(obj, desc+8);
                    191:        message(desc, 0);
                    192:        (void) reg_move();
                    193: }
                    194: 
                    195: object *
                    196: check_duplicate(obj, pack)
                    197: object *obj, *pack;
                    198: {
                    199:        object *op;
                    200: 
                    201:        if (!(obj->what_is & (WEAPON | FOOD | SCROL | POTION))) {
                    202:                return(0);
                    203:        }
                    204:        if ((obj->what_is == FOOD) && (obj->which_kind == FRUIT)) {
                    205:                return(0);
                    206:        }
                    207:        op = pack->next_object;
                    208: 
                    209:        while (op) {
                    210:                if ((op->what_is == obj->what_is) && 
                    211:                        (op->which_kind == obj->which_kind)) {
                    212: 
                    213:                        if ((obj->what_is != WEAPON) ||
                    214:                        ((obj->what_is == WEAPON) &&
                    215:                        ((obj->which_kind == ARROW) ||
                    216:                        (obj->which_kind == DAGGER) ||
                    217:                        (obj->which_kind == DART) ||
                    218:                        (obj->which_kind == SHURIKEN)) &&
                    219:                        (obj->quiver == op->quiver))) {
                    220:                                op->quantity += obj->quantity;
                    221:                                return(op);
                    222:                        }
                    223:                }
                    224:                op = op->next_object;
                    225:        }
                    226:        return(0);
                    227: }
                    228: 
                    229: next_avail_ichar()
                    230: {
                    231:        register object *obj;
                    232:        register i;
                    233:        boolean ichars[26];
                    234: 
                    235:        for (i = 0; i < 26; i++) {
                    236:                ichars[i] = 0;
                    237:        }
                    238:        obj = rogue.pack.next_object;
                    239:        while (obj) {
                    240:                ichars[(obj->ichar - 'a')] = 1;
                    241:                obj = obj->next_object;
                    242:        }
                    243:        for (i = 0; i < 26; i++) {
                    244:                if (!ichars[i]) {
                    245:                        return(i + 'a');
                    246:                }
                    247:        }
                    248:        return('?');
                    249: }
                    250: 
                    251: wait_for_ack()
                    252: {
                    253:        while (rgetchar() != ' ') ;
                    254: }
                    255: 
                    256: pack_letter(prompt, mask)
                    257: char *prompt;
                    258: unsigned short mask;
                    259: {
                    260:        short ch;
                    261:        unsigned short tmask = mask;
                    262: 
                    263:        if (!mask_pack(&rogue.pack, mask)) {
                    264:                message("nothing appropriate", 0);
                    265:                return(CANCEL);
                    266:        }
                    267:        for (;;) {
                    268: 
                    269:                message(prompt, 0);
                    270: 
                    271:                for (;;) {
                    272:                        ch = rgetchar();
                    273:                        if (!is_pack_letter(&ch, &mask)) {
                    274:                                sound_bell();
                    275:                        } else {
                    276:                                break;
                    277:                        }
                    278:                }
                    279: 
                    280:                if (ch == LIST) {
                    281:                        check_message();
                    282:                        inventory(&rogue.pack, mask);
                    283:                } else {
                    284:                        break;
                    285:                }
                    286:                mask = tmask;
                    287:        }
                    288:        check_message();
                    289:        return(ch);
                    290: }
                    291: 
                    292: take_off()
                    293: {
                    294:        char desc[DCOLS];
                    295:        object *obj;
                    296: 
                    297:        if (rogue.armor) {
                    298:                if (rogue.armor->is_cursed) {
                    299:                        message(curse_message, 0);
                    300:                } else {
                    301:                        mv_aquatars();
                    302:                        obj = rogue.armor;
                    303:                        unwear(rogue.armor);
                    304:                        (void) strcpy(desc, "was wearing ");
                    305:                        get_desc(obj, desc+12);
                    306:                        message(desc, 0);
                    307:                        print_stats(STAT_ARMOR);
                    308:                        (void) reg_move();
                    309:                }
                    310:        } else {
                    311:                message("not wearing any", 0);
                    312:        }
                    313: }
                    314: 
                    315: wear()
                    316: {
                    317:        short ch;
                    318:        register object *obj;
                    319:        char desc[DCOLS];
                    320: 
                    321:        if (rogue.armor) {
                    322:                message("your already wearing some", 0);
                    323:                return;
                    324:        }
                    325:        ch = pack_letter("wear what?", ARMOR);
                    326: 
                    327:        if (ch == CANCEL) {
                    328:                return;
                    329:        }
                    330:        if (!(obj = get_letter_object(ch))) {
                    331:                message("no such item.", 0);
                    332:                return;
                    333:        }
                    334:        if (obj->what_is != ARMOR) {
                    335:                message("you can't wear that", 0);
                    336:                return;
                    337:        }
                    338:        obj->identified = 1;
                    339:        (void) strcpy(desc, "wearing ");
                    340:        get_desc(obj, desc + 8);
                    341:        message(desc, 0);
                    342:        do_wear(obj);
                    343:        print_stats(STAT_ARMOR);
                    344:        (void) reg_move();
                    345: }
                    346: 
                    347: unwear(obj)
                    348: object *obj;
                    349: {
                    350:        if (obj) {
                    351:                obj->in_use_flags &= (~BEING_WORN);
                    352:        }
                    353:        rogue.armor = (object *) 0;
                    354: }
                    355: 
                    356: do_wear(obj)
                    357: object *obj;
                    358: {
                    359:        rogue.armor = obj;
                    360:        obj->in_use_flags |= BEING_WORN;
                    361:        obj->identified = 1;
                    362: }
                    363: 
                    364: wield()
                    365: {
                    366:        short ch;
                    367:        register object *obj;
                    368:        char desc[DCOLS];
                    369: 
                    370:        if (rogue.weapon && rogue.weapon->is_cursed) {
                    371:                message(curse_message, 0);
                    372:                return;
                    373:        }
                    374:        ch = pack_letter("wield what?", WEAPON);
                    375: 
                    376:        if (ch == CANCEL) {
                    377:                return;
                    378:        }
                    379:        if (!(obj = get_letter_object(ch))) {
                    380:                message("No such item.", 0);
                    381:                return;
                    382:        }
                    383:        if (obj->what_is & (ARMOR | RING)) {
                    384:                sprintf(desc, "you can't wield %s",
                    385:                        ((obj->what_is == ARMOR) ? "armor" : "rings"));
                    386:                message(desc, 0);
                    387:                return;
                    388:        }
                    389:        if (obj->in_use_flags & BEING_WIELDED) {
                    390:                message("in use", 0);
                    391:        } else {
                    392:                unwield(rogue.weapon);
                    393:                (void) strcpy(desc, "wielding ");
                    394:                get_desc(obj, desc + 9);
                    395:                message(desc, 0);
                    396:                do_wield(obj);
                    397:                (void) reg_move();
                    398:        }
                    399: }
                    400: 
                    401: do_wield(obj)
                    402: object *obj;
                    403: {
                    404:        rogue.weapon = obj;
                    405:        obj->in_use_flags |= BEING_WIELDED;
                    406: }
                    407: 
                    408: unwield(obj)
                    409: object *obj;
                    410: {
                    411:        if (obj) {
                    412:                obj->in_use_flags &= (~BEING_WIELDED);
                    413:        }
                    414:        rogue.weapon = (object *) 0;
                    415: }
                    416: 
                    417: call_it()
                    418: {
                    419:        short ch;
                    420:        register object *obj;
                    421:        struct id *id_table;
                    422:        char buf[MAX_TITLE_LENGTH+2];
                    423: 
                    424:        ch = pack_letter("call what?", (SCROL | POTION | WAND | RING));
                    425: 
                    426:        if (ch == CANCEL) {
                    427:                return;
                    428:        }
                    429:        if (!(obj = get_letter_object(ch))) {
                    430:                message("no such item.", 0);
                    431:                return;
                    432:        }
                    433:        if (!(obj->what_is & (SCROL | POTION | WAND | RING))) {
                    434:                message("surely you already know what that's called", 0);
                    435:                return;
                    436:        }
                    437:        id_table = get_id_table(obj);
                    438: 
                    439:        if (get_input_line("call it:","",buf,id_table[obj->which_kind].title,1,1)) {
                    440:                id_table[obj->which_kind].id_status = CALLED;
                    441:                (void) strcpy(id_table[obj->which_kind].title, buf);
                    442:        }
                    443: }
                    444: 
                    445: pack_count(new_obj)
                    446: object *new_obj;
                    447: {
                    448:        object *obj;
                    449:        short count = 0;
                    450: 
                    451:        obj = rogue.pack.next_object;
                    452: 
                    453:        while (obj) {
                    454:                if (obj->what_is != WEAPON) {
                    455:                        count += obj->quantity;
                    456:                } else if (!new_obj) {
                    457:                        count++;
                    458:                } else if ((new_obj->what_is != WEAPON) ||
                    459:                        ((obj->which_kind != ARROW) &&
                    460:                        (obj->which_kind != DAGGER) &&
                    461:                        (obj->which_kind != DART) &&
                    462:                        (obj->which_kind != SHURIKEN)) ||
                    463:                        (new_obj->which_kind != obj->which_kind) ||
                    464:                        (obj->quiver != new_obj->quiver)) {
                    465:                        count++;
                    466:                }
                    467:                obj = obj->next_object;
                    468:        }
                    469:        return(count);
                    470: }
                    471: 
                    472: boolean
                    473: mask_pack(pack, mask)
                    474: object *pack;
                    475: unsigned short mask;
                    476: {
                    477:        while (pack->next_object) {
                    478:                pack = pack->next_object;
                    479:                if (pack->what_is & mask) {
                    480:                        return(1);
                    481:                }
                    482:        }
                    483:        return(0);
                    484: }
                    485: 
                    486: is_pack_letter(c, mask)
                    487: short *c;
                    488: unsigned short *mask;
                    489: {
                    490:        if (((*c == '?') || (*c == '!') || (*c == ':') || (*c == '=') ||
                    491:                (*c == ')') || (*c == ']') || (*c == '/') || (*c == ','))) {
                    492:                switch(*c) {
                    493:                case '?':
                    494:                        *mask = SCROL;
                    495:                        break;
                    496:                case '!':
                    497:                        *mask = POTION;
                    498:                        break;
                    499:                case ':':
                    500:                        *mask = FOOD;
                    501:                        break;
                    502:                case ')':
                    503:                        *mask = WEAPON;
                    504:                        break;
                    505:                case ']':
                    506:                        *mask = ARMOR;
                    507:                        break;
                    508:                case '/':
                    509:                        *mask = WAND;
                    510:                        break;
                    511:                case '=':
                    512:                        *mask = RING;
                    513:                        break;
                    514:                case ',':
                    515:                        *mask = AMULET;
                    516:                        break;
                    517:                }
                    518:                *c = LIST;
                    519:                return(1);
                    520:        }
                    521:        return(((*c >= 'a') && (*c <= 'z')) || (*c == CANCEL) || (*c == LIST));
                    522: }
                    523: 
                    524: has_amulet()
                    525: {
                    526:        return(mask_pack(&rogue.pack, AMULET));
                    527: }
                    528: 
                    529: kick_into_pack()
                    530: {
                    531:        object *obj;
                    532:        char desc[DCOLS];
                    533:        short n, stat;
                    534: 
                    535:        if (!(dungeon[rogue.row][rogue.col] & OBJECT)) {
                    536:                message("nothing here", 0);
                    537:        } else {
                    538:                if (obj = pick_up(rogue.row, rogue.col, &stat)) {
                    539:                        get_desc(obj, desc);
                    540:                        if (obj->what_is == GOLD) {
                    541:                                message(desc, 0);
                    542:                                free_object(obj);
                    543:                        } else {
                    544:                                n = strlen(desc);
                    545:                                desc[n] = '(';
                    546:                                desc[n+1] = obj->ichar;
                    547:                                desc[n+2] = ')';
                    548:                                desc[n+3] = 0;
                    549:                                message(desc, 0);
                    550:                        }
                    551:                }
                    552:                if (obj || (!stat)) {
                    553:                        (void) reg_move();
                    554:                }
                    555:        }
                    556: }

unix.superglobalmegacorp.com

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