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

Annotation of early-roguelike/arogue7/things.c, Revision 1.1

1.1     ! rubenllo    1: /*
        !             2:  * things.c - functions for dealing with things like potions and scrolls
        !             3:  *
        !             4:  * Advanced Rogue
        !             5:  * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Based on "Rogue: Exploring the Dungeons of Doom"
        !             9:  * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
        !            10:  * All rights reserved.
        !            11:  *
        !            12:  * See the file LICENSE.TXT for full copyright and licensing information.
        !            13:  */
        !            14:
        !            15: /*
        !            16:  * Contains functions for dealing with things like
        !            17:  * potions and scrolls
        !            18:  *
        !            19:  */
        !            20:
        !            21: #include "curses.h"
        !            22: #include <ctype.h>
        !            23: #include <string.h>
        !            24: #include "rogue.h"
        !            25:
        !            26: int pick_one(struct magic_item *magic, int nitems);
        !            27: char *blesscurse(int flags);
        !            28: char *p_kind(struct object *obj);
        !            29: int extras(void);
        !            30:
        !            31: /*
        !            32:  * print out the number of charges on a stick
        !            33:  */
        !            34: char *
        !            35: charge_str(struct object *obj)
        !            36: {
        !            37:     static char buf[20];
        !            38:
        !            39:     if (!(obj->o_flags & ISKNOW))
        !            40:        buf[0] = '\0';
        !            41:     else if (terse)
        !            42:        sprintf(buf, " [%d]", obj->o_charges);
        !            43:     else
        !            44:        sprintf(buf, " [%d charges]", obj->o_charges);
        !            45:     return buf;
        !            46: }
        !            47: /*
        !            48:  * inv_name:
        !            49:  *     return the name of something as it would appear in an
        !            50:  *     inventory.
        !            51:  */
        !            52: char *
        !            53: inv_name(struct object *obj, bool drop)
        !            54: {
        !            55:     register char *pb;
        !            56:
        !            57:     pb = prbuf;
        !            58:     pb[0] = '\0';
        !            59:     switch(obj->o_type) {
        !            60:        case SCROLL:
        !            61:            if (obj->o_count == 1)
        !            62:                 sprintf(pb, "A %sscroll ", blesscurse(obj->o_flags));
        !            63:            else
        !            64:                 sprintf(pb, "%d %sscrolls ",
        !            65:                        obj->o_count, blesscurse(obj->o_flags));
        !            66:            pb = &pb[strlen(pb)];
        !            67:            if (s_know[obj->o_which] || (obj->o_flags & ISPOST))
        !            68:                sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
        !            69:            else if (s_guess[obj->o_which])
        !            70:                sprintf(pb, "named %s", s_guess[obj->o_which]);
        !            71:            else
        !            72:                sprintf(pb, "titled '%s'", s_names[obj->o_which]);
        !            73:         when POTION:
        !            74:            if (obj->o_count == 1)
        !            75:                 sprintf(pb, "A %spotion ", blesscurse(obj->o_flags));
        !            76:            else
        !            77:                 sprintf(pb, "%d %spotions ",
        !            78:                        obj->o_count, blesscurse(obj->o_flags));
        !            79:            pb = &pb[strlen(pb)];
        !            80:            if (p_know[obj->o_which])
        !            81:                sprintf(pb, "of %s (%s)", p_magic[obj->o_which].mi_name,
        !            82:                    p_kind(obj));
        !            83:            else if (obj->o_flags & ISPOST)
        !            84:                sprintf(pb, "of %s", p_magic[obj->o_which].mi_name);
        !            85:            else if (p_guess[obj->o_which])
        !            86:                sprintf(pb, "named %s (%s)", p_guess[obj->o_which],
        !            87:                    p_colors[obj->o_which]);
        !            88:            else {
        !            89:                pb = prbuf;
        !            90:                if (obj->o_count == 1)
        !            91:                    sprintf(pb, "A%s %s potion",
        !            92:                            vowelstr(p_colors[obj->o_which]),
        !            93:                            p_colors[obj->o_which]);
        !            94:                else
        !            95:                    sprintf(pb, "%d %s potions",
        !            96:                            obj->o_count, p_colors[obj->o_which]);
        !            97:            }
        !            98:        when FOOD:
        !            99:            if (obj->o_count == 1)
        !           100:                sprintf(pb, "A%s %s", vowelstr(foods[obj->o_which].mi_name),
        !           101:                        foods[obj->o_which].mi_name);
        !           102:            else
        !           103:                sprintf(pb, "%d %ss", obj->o_count,foods[obj->o_which].mi_name);
        !           104:        when WEAPON:
        !           105:            if (obj->o_count > 1)
        !           106:                sprintf(pb, "%d ", obj->o_count);
        !           107:            else
        !           108:                strcpy(pb, "A ");
        !           109:            pb = &pb[strlen(pb)];
        !           110:            if (obj->o_flags & ISKNOW) {
        !           111:                strcat(pb, num(obj->o_hplus, obj->o_dplus));
        !           112:                strcat (pb, " ");
        !           113:            }
        !           114:            strcat(pb, weaps[obj->o_which].w_name);
        !           115:            if (obj->o_count > 1)
        !           116:                strcat(pb, "s");
        !           117:            if (obj == cur_weapon)
        !           118:                strcat(pb, " (weapon in hand)");
        !           119:            if (obj->o_flags & ISPOISON)
        !           120:                strcat(pb, " {Poisoned}");
        !           121:        when ARMOR:
        !           122:            if (obj->o_flags & ISKNOW) {
        !           123:                strcat(pb, num(armors[obj->o_which].a_class - obj->o_ac, 0));
        !           124:                strcat(pb, " ");
        !           125:            }
        !           126:            strcat(pb, armors[obj->o_which].a_name);
        !           127:            if (obj == cur_armor)
        !           128:                strcat(pb, " (being worn)");
        !           129:        when STICK:
        !           130:            sprintf(pb, "A %s%s ",
        !           131:                blesscurse(obj->o_flags), ws_type[obj->o_which]);
        !           132:            pb = &pb[strlen(pb)];
        !           133:            if (ws_know[obj->o_which] || obj->o_flags & ISKNOW)
        !           134:                sprintf(pb, "of %s%s (%s)", ws_magic[obj->o_which].mi_name,
        !           135:                    charge_str(obj), ws_made[obj->o_which]);
        !           136:            else if (obj->o_flags & ISPOST)
        !           137:                sprintf(pb, "of %s", ws_magic[obj->o_which].mi_name);
        !           138:            else if (ws_guess[obj->o_which])
        !           139:                sprintf(pb, "named %s (%s)", ws_guess[obj->o_which],
        !           140:                    ws_made[obj->o_which]);
        !           141:            else {
        !           142:                pb = prbuf;
        !           143:                sprintf(pb, "A %s %s", ws_made[obj->o_which],
        !           144:                    ws_type[obj->o_which]);
        !           145:            }
        !           146:            if (obj == cur_weapon)
        !           147:                strcat(prbuf, " (weapon in hand)");
        !           148:         when RING:
        !           149:            if (r_know[obj->o_which] || obj->o_flags & ISKNOW)
        !           150:                sprintf(pb, "A%s ring of %s (%s)", ring_num(obj),
        !           151:                    r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
        !           152:            else if (obj->o_flags & ISPOST)
        !           153:                sprintf(pb, "A ring of %s", r_magic[obj->o_which].mi_name);
        !           154:            else if (r_guess[obj->o_which])
        !           155:                sprintf(pb, "A ring named %s (%s)",
        !           156:                    r_guess[obj->o_which], r_stones[obj->o_which]);
        !           157:            else
        !           158:                sprintf(pb, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
        !           159:                    r_stones[obj->o_which]);
        !           160:            if     (obj == cur_ring[LEFT_1] || obj == cur_ring[LEFT_2] ||
        !           161:                    obj == cur_ring[LEFT_3] || obj == cur_ring[LEFT_4])
        !           162:                        strcat(pb, " (on left hand)");
        !           163:            if     (obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] ||
        !           164:                    obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4])
        !           165:                        strcat(pb, " (on right hand)");
        !           166:        when RELIC:
        !           167:            if (obj->o_flags & ISKNOW)
        !           168:                switch(obj->o_which) {
        !           169:                case QUILL_NAGROM:
        !           170:                    sprintf(pb, "%s%s", rel_magic[obj->o_which].mi_name,
        !           171:                            charge_str(obj));
        !           172:                otherwise:
        !           173:                    strcpy(pb, rel_magic[obj->o_which].mi_name);
        !           174:            }
        !           175:            else switch(obj->o_which) {
        !           176:                case MUSTY_DAGGER:
        !           177:                    strcpy(pb, "Two very fine daggers marked MDDE");
        !           178:                when EMORI_CLOAK:
        !           179:                    strcpy(pb, "A silk cloak");
        !           180:                when HEIL_ANKH:
        !           181:                    strcpy(pb, "A golden ankh");
        !           182:                when MING_STAFF:
        !           183:                    strcpy(pb, "A finely carved staff");
        !           184:                when ORCUS_WAND:
        !           185:                    strcpy(pb, "A sparkling ivory wand");
        !           186:                when ASMO_ROD:
        !           187:                    strcpy(pb, "A glistening ebony rod");
        !           188:                when YENDOR_AMULET:
        !           189:                    strcpy(pb, "A silver amulet");
        !           190:                when STONEBONES_AMULET:
        !           191:                    strcpy(pb, "A stone amulet");
        !           192:                when BRIAN_MANDOLIN:
        !           193:                    strcpy(pb, "A gleaming mandolin");
        !           194:                when HRUGGEK_MSTAR:
        !           195:                    strcpy(pb, "A huge morning star");
        !           196:                when AXE_AKLAD:
        !           197:                    strcpy(pb, "A jewel encrusted axe");
        !           198:                when QUILL_NAGROM:
        !           199:                    strcpy(pb, "A bright white feather");
        !           200:                when GERYON_HORN:
        !           201:                    strcpy(pb, "A jet black horn");
        !           202:                when YEENOGHU_FLAIL:
        !           203:                    strcpy(pb, "A shimmering flail");
        !           204:                when SURTUR_RING:
        !           205:                    strcpy(pb, "A fiery red ring");
        !           206:                otherwise:
        !           207:                    strcpy(pb, "A magical item");
        !           208:            }
        !           209:
        !           210:            /* Take care of wielding and wearing */
        !           211:            switch (obj->o_which) {
        !           212:                case EMORI_CLOAK:
        !           213:                    if (cur_armor == NULL && cur_misc[WEAR_CLOAK] == NULL)
        !           214:                        strcat(pb, " (being worn)");
        !           215:                    if (obj->o_charges)
        !           216:                        strcat(pb, " [charged]");
        !           217:                    else
        !           218:                        strcat(pb, " [discharged]");
        !           219:                when HEIL_ANKH:
        !           220:                    if (cur_relic[HEIL_ANKH]) strcat(pb, " (in hand)");
        !           221:                when EYE_VECNA:
        !           222:                    if (cur_relic[EYE_VECNA]) strcat(pb, " (in eye socket)");
        !           223:                when STONEBONES_AMULET:
        !           224:                    if (cur_relic[STONEBONES_AMULET])
        !           225:                        strcat(pb, " (in chest)");
        !           226:                when YENDOR_AMULET:
        !           227:                    if (cur_relic[YENDOR_AMULET])
        !           228:                        strcat(pb, " (in chest)");
        !           229:                when MUSTY_DAGGER:
        !           230:                case HRUGGEK_MSTAR:
        !           231:                case AXE_AKLAD:
        !           232:                case YEENOGHU_FLAIL:
        !           233:                case MING_STAFF:
        !           234:                case ASMO_ROD:
        !           235:                case ORCUS_WAND:
        !           236:                    if (cur_weapon == obj) strcat(pb, " (weapon in hand)");
        !           237:                when SURTUR_RING:
        !           238:                    if (cur_relic[SURTUR_RING])
        !           239:                        strcat(pb, " (in nose)");
        !           240:            }
        !           241:        when MM:
        !           242:            if (m_know[obj->o_which])
        !           243:                        strcpy(pb, misc_name(obj));
        !           244:            else {
        !           245:                switch (obj->o_which) {
        !           246:                    case MM_JUG:
        !           247:                    case MM_BEAKER:
        !           248:                        strcpy(pb, "A bottle");
        !           249:                    when MM_KEOGHTOM:
        !           250:                        strcpy(pb, "A jar");
        !           251:                    when MM_JEWEL:
        !           252:                        strcpy(pb, "An amulet");
        !           253:                    when MM_BOOK:
        !           254:                    case MM_SKILLS:
        !           255:                        strcpy(pb, "A book");
        !           256:                    when MM_ELF_BOOTS:
        !           257:                    case MM_DANCE:
        !           258:                        strcpy(pb, "A pair of boots");
        !           259:                    when MM_BRACERS:
        !           260:                        strcpy(pb, "A pair of bracers");
        !           261:                    when MM_OPEN:
        !           262:                    case MM_HUNGER:
        !           263:                        strcpy(pb, "A chime");
        !           264:                    when MM_DISP:
        !           265:                    case MM_R_POWERLESS:
        !           266:                    case MM_PROTECT:
        !           267:                        strcpy(pb, "A cloak");
        !           268:                    when MM_DRUMS:
        !           269:                        strcpy(pb, "A set of drums");
        !           270:                    when MM_DISAPPEAR:
        !           271:                    case MM_CHOKE:
        !           272:                        strcpy(pb, "A pouch of dust");
        !           273:                    when MM_G_DEXTERITY:
        !           274:                    case MM_G_OGRE:
        !           275:                    case MM_FUMBLE:
        !           276:                        strcpy(pb, "A pair of gauntlets");
        !           277:                    when MM_ADAPTION:
        !           278:                    case MM_STRANGLE:
        !           279:                        strcpy(pb, "A necklace");
        !           280:                    otherwise:
        !           281:                        strcpy(pb, "A magical item");
        !           282:                }
        !           283:                if (m_guess[obj->o_which]) {
        !           284:                    strcat(pb, " named: ");
        !           285:                    strcat(pb, m_guess[obj->o_which]);
        !           286:                }
        !           287:            }
        !           288:            if (obj == cur_misc[WEAR_BOOTS]     ||
        !           289:                obj == cur_misc[WEAR_BRACERS]   ||
        !           290:                obj == cur_misc[WEAR_CLOAK]     ||
        !           291:                obj == cur_misc[WEAR_GAUNTLET]  ||
        !           292:                obj == cur_misc[WEAR_NECKLACE]  ||
        !           293:                obj == cur_misc[WEAR_JEWEL])
        !           294:                    strcat(pb, " (being worn)");
        !           295:        when GOLD:
        !           296:                sprintf(pb, "%d Pieces of Gold", obj->o_count);
        !           297:        otherwise:
        !           298:            debug("Picked up something funny");
        !           299:            sprintf(pb, "Something bizarre %s", unctrl(obj->o_type));
        !           300:     }
        !           301:
        !           302:     /* Is it marked? */
        !           303:     if (obj->o_mark[0]) {
        !           304:        pb = &pb[strlen(pb)];
        !           305:        sprintf(pb, " <%s>", obj->o_mark);
        !           306:     }
        !           307:
        !           308:     if (obj->o_flags & ISPROT)
        !           309:        strcat(pb, " [protected]");
        !           310:     if (drop && isupper(prbuf[0]))
        !           311:        prbuf[0] = tolower(prbuf[0]);
        !           312:     else if (!drop && islower(*prbuf))
        !           313:        *prbuf = toupper(*prbuf);
        !           314:     if (!drop)
        !           315:        strcat(pb, ".");
        !           316:     /*
        !           317:      * Truncate if long. Use cols-4 to offset the "pack letter" of a normal
        !           318:      * inventory listing.
        !           319:      */
        !           320:     prbuf[cols-4] = '\0';
        !           321:     return prbuf;
        !           322: }
        !           323:
        !           324: /*
        !           325:  * weap_name:
        !           326:  *     Return the name of a weapon.
        !           327:  */
        !           328: char *
        !           329: weap_name(struct object *obj)
        !           330: {
        !           331:     switch (obj->o_type) {
        !           332:        case WEAPON:
        !           333:            return(weaps[obj->o_which].w_name);
        !           334:        when MISSILE:
        !           335:            return(ws_magic[obj->o_which].mi_name);
        !           336:        when RELIC:
        !           337:            switch (obj->o_which) {
        !           338:                case MUSTY_DAGGER:
        !           339:                    return("daggers");
        !           340:                when YEENOGHU_FLAIL:
        !           341:                    return("flail");
        !           342:                when AXE_AKLAD:
        !           343:                    return("axe");
        !           344:                when HRUGGEK_MSTAR:
        !           345:                    return("morning star");
        !           346:                when MING_STAFF:
        !           347:                    return("staff");
        !           348:                when ORCUS_WAND:
        !           349:                    return("wand");
        !           350:                when ASMO_ROD:
        !           351:                    return("rod");
        !           352:            }
        !           353:     }
        !           354:     return("weapon");
        !           355: }
        !           356:
        !           357: /*
        !           358:  * drop:
        !           359:  *     put something down
        !           360:  */
        !           361: bool
        !           362: drop(struct linked_list *item)
        !           363: {
        !           364:     register char ch;
        !           365:     register struct linked_list *obj, *nobj;
        !           366:     register struct object *op;
        !           367:
        !           368:     if (item == NULL) {
        !           369:        /* We charge 2 movement times to drop something */
        !           370:        if (player.t_action == C_DROP && player.t_using != NULL) {
        !           371:            obj = player.t_using;
        !           372:            player.t_using = NULL;
        !           373:            player.t_action = A_NIL;
        !           374:        }
        !           375:
        !           376:        /* t_action == C_DROP always when called from command() */
        !           377:        else {
        !           378:            if ((obj = get_item(pack, "drop", ALL, FALSE, FALSE)) == NULL) {
        !           379:                player.t_action = A_NIL;
        !           380:                player.t_using = NULL;
        !           381:                return(FALSE);
        !           382:            }
        !           383:            if (player.t_action == C_DROP) {
        !           384:                player.t_using = obj;
        !           385:                player.t_no_move = 2 * movement(&player);
        !           386:                return(FALSE);  /* We'll come back after we've waited */
        !           387:            }
        !           388:        }
        !           389:
        !           390:        switch(ch = CCHAR(mvwinch(stdscr, hero.y, hero.x))) {
        !           391:        case PASSAGE:
        !           392:        case SCROLL:
        !           393:        case POTION:
        !           394:        case WEAPON:
        !           395:        case FLOOR:
        !           396:        case STICK:
        !           397:        case ARMOR:
        !           398:        case POOL:
        !           399:        case RELIC:
        !           400:        case GOLD:
        !           401:        case FOOD:
        !           402:        case RING:
        !           403:        case MM:
        !           404:            break;
        !           405:        default:
        !           406:            msg("Can't leave it here");
        !           407:            return(FALSE);
        !           408:        }
        !           409:     }
        !           410:     else {
        !           411:        obj = item;
        !           412:     }
        !           413:     op = OBJPTR(obj);
        !           414:     if (!dropcheck(op))
        !           415:        return(FALSE);
        !           416:
        !           417:     /*
        !           418:      * If it is a scare monster scroll, curse it
        !           419:      */
        !           420:     if (op->o_type == SCROLL && op->o_which == S_SCARE) {
        !           421:        if (op->o_flags & ISBLESSED)
        !           422:            op->o_flags &= ~ISBLESSED;
        !           423:        else op->o_flags |= ISCURSED;
        !           424:     }
        !           425:
        !           426:     /*
        !           427:      * Take it out of the pack
        !           428:      */
        !           429:     if (op->o_count >= 2 && op->o_group == 0)
        !           430:     {
        !           431:        nobj = new_item(sizeof *op);
        !           432:        op->o_count--;
        !           433:        op = OBJPTR(nobj);
        !           434:        *op = *(OBJPTR(obj));
        !           435:        op->o_count = 1;
        !           436:        obj = nobj;
        !           437:     }
        !           438:     else {
        !           439:        detach(pack, obj);
        !           440:         inpack--;
        !           441:     }
        !           442:     if(ch == POOL) {
        !           443:        msg("Your %s sinks out of sight.",inv_name(op,TRUE));
        !           444:        o_discard(obj);
        !           445:     }
        !           446:     else if (levtype == POSTLEV) {
        !           447:        op->o_pos = hero;       /* same place as hero */
        !           448:        fall(obj,FALSE);
        !           449:        if (item == NULL)       /* if item wasn't sold */
        !           450:            msg("Thanks for your donation to the fiend's flea market.");
        !           451:     }
        !           452:     else {
        !           453:        /*
        !           454:         * Link it into the level object list
        !           455:         */
        !           456:        attach(lvl_obj, obj);
        !           457:        mvaddch(hero.y, hero.x, op->o_type);
        !           458:        op->o_pos = hero;
        !           459:        msg("Dropped %s", inv_name(op, TRUE));
        !           460:     }
        !           461:     updpack(FALSE, &player);
        !           462:     return (TRUE);
        !           463: }
        !           464:
        !           465: /*
        !           466:  * do special checks for dropping or unweilding|unwearing|unringing
        !           467:  */
        !           468: bool
        !           469: dropcheck(struct object *op)
        !           470: {
        !           471:     int save_max;
        !           472:
        !           473:     if (op == NULL)
        !           474:        return TRUE;
        !           475:     if (levtype == POSTLEV) {
        !           476:        if ((op->o_flags & ISCURSED) && (op->o_flags & ISKNOW)) {
        !           477:            msg("The trader does not accept your shoddy merchandise");
        !           478:            return(FALSE);
        !           479:        }
        !           480:     }
        !           481:
        !           482:     /* Player will not drop a relic */
        !           483:     if (op->o_type == RELIC) {
        !           484:        /*
        !           485:         * There is a 1% cumulative chance per relic that trying to get
        !           486:         * rid of it will cause the relic to turn on the player.
        !           487:         */
        !           488:        if (rnd(100) < cur_relic[op->o_which]++) {
        !           489:            msg("The artifact turns on you.");
        !           490:            msg("It crushes your mind!!! -- More --");
        !           491:            pstats.s_hpt = -1;
        !           492:            wait_for (' ');
        !           493:            death(D_RELIC);
        !           494:        }
        !           495:        else {
        !           496:            if (terse) msg("Can't release it.");
        !           497:            else msg("You cannot bring yourself to release it.");
        !           498:            return FALSE;
        !           499:        }
        !           500:     }
        !           501:
        !           502:     /* If we aren't wearing it, we can drop it */
        !           503:     if (!is_current(op)) return TRUE;
        !           504:
        !           505:     /* At this point, we know we are wearing the item */
        !           506:     if (op->o_flags & ISCURSED) {
        !           507:        msg("You can't.  It appears to be cursed.");
        !           508:        return FALSE;
        !           509:     }
        !           510:     if (op->o_type == RING && cur_misc[WEAR_GAUNTLET] != NULL) {
        !           511:        msg ("You have to remove your gauntlets first!");
        !           512:        return FALSE;
        !           513:     }
        !           514:     cur_null(op);      /* set current to NULL */
        !           515:     if (op->o_type == RING) {
        !           516:        switch (op->o_which) {
        !           517:        case R_ADDSTR:    save_max = max_stats.s_str;
        !           518:                          chg_str(-op->o_ac);
        !           519:                          max_stats.s_str = save_max;
        !           520:        when R_ADDHIT:    pstats.s_dext -= op->o_ac;
        !           521:        when R_ADDINTEL:  pstats.s_intel -= op->o_ac;
        !           522:        when R_ADDWISDOM: pstats.s_wisdom -= op->o_ac;
        !           523:        when R_SEEINVIS:  if (!ISWEARING(R_SEEINVIS) &&
        !           524:                              find_slot(unsee) == 0) {
        !           525:                                turn_off(player, CANSEE);
        !           526:                                msg("The tingling feeling leaves your eyes");
        !           527:                          }
        !           528:                          light(&hero);
        !           529:                          mvwaddch(cw, hero.y, hero.x, PLAYER);
        !           530:        when R_WARMTH:    if (!ISWEARING(R_WARMTH) && !find_slot(nocold))
        !           531:                                turn_off(player, NOCOLD);
        !           532:        when R_FIRE:      if (!ISWEARING(R_FIRE)        &&
        !           533:                              !cur_relic[SURTUR_RING]   &&
        !           534:                              !find_slot(nofire))
        !           535:                                turn_off(player, NOFIRE);
        !           536:        when R_LIGHT: {
        !           537:                          if(roomin(&hero) != NULL) {
        !           538:                                light(&hero);
        !           539:                                mvwaddch(cw, hero.y, hero.x, PLAYER);
        !           540:                          }
        !           541:                      }
        !           542:        when R_SEARCH:    kill_daemon(ring_search);
        !           543:        when R_TELEPORT:  kill_daemon(ring_teleport);
        !           544:        }
        !           545:     }
        !           546:     else if (op->o_type == MM) {
        !           547:        switch (op->o_which) {
        !           548:            case MM_ADAPTION:
        !           549:                turn_off(player, NOGAS);
        !           550:
        !           551:            when MM_STRANGLE:
        !           552:                msg("You can breathe again.....whew!");
        !           553:                kill_daemon(strangle);
        !           554:
        !           555:            when MM_DANCE:
        !           556:                turn_off(player, ISDANCE);
        !           557:                msg ("Your feet take a break.....whew!");
        !           558:
        !           559:            when MM_FUMBLE:
        !           560:                kill_daemon(fumble);
        !           561:        }
        !           562:     }
        !           563:     return TRUE;
        !           564: }
        !           565:
        !           566: /*
        !           567:  * return a new thing
        !           568:  */
        !           569: struct linked_list *
        !           570: new_thing(int thing_type, bool allow_curse)
        !           571: {
        !           572:     register struct linked_list *item;
        !           573:     register struct object *cur;
        !           574:     register int j;
        !           575:     register int blesschance, cursechance;
        !           576:
        !           577:     item = new_item(sizeof *cur);
        !           578:     cur = OBJPTR(item);
        !           579:     cur->o_hplus = cur->o_dplus = 0;
        !           580:     strncpy(cur->o_damage, "0d0", sizeof(cur->o_damage));
        !           581:     strncpy(cur->o_hurldmg, "0d0", sizeof(cur->o_hurldmg));
        !           582:     cur->o_ac = 0;
        !           583:     cur->o_count = 1;
        !           584:     cur->o_group = 0;
        !           585:     cur->contents = NULL;
        !           586:     cur->o_flags = 0;
        !           587:     cur->o_weight = 0;
        !           588:     cur->o_mark[0] = '\0';
        !           589:     /*
        !           590:      * Decide what kind of object it will be
        !           591:      * If we haven't had food for a while, let it be food.
        !           592:      */
        !           593:     blesschance = rnd(100);
        !           594:     if (allow_curse) cursechance = rnd(100);
        !           595:     else cursechance = 100;    /* No chance of curse */
        !           596:
        !           597:     /* Get the type of item (pick one if 'any' is specified) */
        !           598:     if (thing_type == ALL) j = pick_one(things, NUMTHINGS);
        !           599:     else j = thing_type;
        !           600:
        !           601:     /*
        !           602:      * make sure he gets his vitamins
        !           603:      */
        !           604:     if (thing_type == ALL && no_food > 3)
        !           605:        j = 2;
        !           606:     /*
        !           607:      * limit the number of foods on a level because it sometimes
        !           608:      * gets out of hand in the "deep" levels where there is a
        !           609:      * treasure room on most every level with lots of food in it
        !           610:      */
        !           611:     while (thing_type == ALL && levtype != POSTLEV && foods_this_level > 2 &&
        !           612:           j == 2)
        !           613:        j = pick_one(things, NUMTHINGS);        /* not too many.... */
        !           614:     switch (j)
        !           615:     {
        !           616:        case TYP_POTION:
        !           617:            cur->o_type = POTION;
        !           618:            do {
        !           619:                cur->o_which = pick_one(p_magic, MAXPOTIONS);
        !           620:            } while (!allow_curse && p_magic[cur->o_which].mi_curse == 100);
        !           621:            cur->o_weight = things[TYP_POTION].mi_wght;
        !           622:            if (cursechance < p_magic[cur->o_which].mi_curse)
        !           623:                cur->o_flags |= ISCURSED;
        !           624:            else if (blesschance < p_magic[cur->o_which].mi_bless)
        !           625:                cur->o_flags |= ISBLESSED;
        !           626:
        !           627:            /* If we made a gain ability potion, see what kind it is */
        !           628:            if (cur->o_which == P_ABIL) cur->o_kind = rnd(NUMABILITIES);
        !           629:
        !           630:        when TYP_SCROLL:
        !           631:            cur->o_type = SCROLL;
        !           632:            do {
        !           633:                cur->o_which = pick_one(s_magic, MAXSCROLLS);
        !           634:            } while (!allow_curse && s_magic[cur->o_which].mi_curse == 100);
        !           635:            cur->o_weight = things[TYP_SCROLL].mi_wght;
        !           636:            if (cursechance < s_magic[cur->o_which].mi_curse)
        !           637:                cur->o_flags |= ISCURSED;
        !           638:            else if (blesschance < s_magic[cur->o_which].mi_bless)
        !           639:                cur->o_flags |= ISBLESSED;
        !           640:        when TYP_FOOD:
        !           641:            no_food = 0;
        !           642:            cur->o_type = FOOD;
        !           643:            cur->o_weight = things[TYP_FOOD].mi_wght;
        !           644:            cur->o_count += extras();
        !           645:            foods_this_level += cur->o_count;
        !           646:            cur->o_which = pick_one(foods, MAXFOODS);
        !           647:        when TYP_WEAPON:
        !           648:            cur->o_type = WEAPON;
        !           649:            cur->o_which = rnd(MAXWEAPONS);
        !           650:            init_weapon(cur, cur->o_which);
        !           651:            if (cursechance < 20)
        !           652:            {
        !           653:
        !           654:                cur->o_flags |= ISCURSED;
        !           655:                cur->o_hplus -= rnd(2) + 1;
        !           656:                cur->o_dplus -= rnd(2) + 1;
        !           657:            }
        !           658:            else if (blesschance < 50) {
        !           659:
        !           660:                cur->o_hplus += rnd(5) + 1;
        !           661:                cur->o_dplus += rnd(5) + 1;
        !           662:            }
        !           663:        when TYP_ARMOR:
        !           664:            cur->o_type = ARMOR;
        !           665:            for (j = 0; j < MAXARMORS; j++)
        !           666:                if (blesschance < armors[j].a_prob)
        !           667:                    break;
        !           668:            if (j == MAXARMORS)
        !           669:            {
        !           670:                debug("Picked a bad armor %d", blesschance);
        !           671:                j = 0;
        !           672:            }
        !           673:            cur->o_which = j;
        !           674:            cur->o_ac = armors[j].a_class;
        !           675:            cur->o_weight = armors[j].a_wght;
        !           676:            if (cursechance < 20)
        !           677:            {
        !           678:                cur->o_flags |= ISCURSED;
        !           679:                cur->o_ac += rnd(3)+1;
        !           680:            }
        !           681:            else if (blesschance < 35)
        !           682:                cur->o_ac -= rnd(3)+1;
        !           683:        when TYP_RING:
        !           684:            cur->o_type = RING;
        !           685:            do {
        !           686:                cur->o_which = pick_one(r_magic, MAXRINGS);
        !           687:            } while (!allow_curse && r_magic[cur->o_which].mi_curse == 100);
        !           688:            cur->o_weight = things[TYP_RING].mi_wght;
        !           689:            if (cursechance < r_magic[cur->o_which].mi_curse)
        !           690:                cur->o_flags |= ISCURSED;
        !           691:            else if (blesschance < r_magic[cur->o_which].mi_bless)
        !           692:                cur->o_flags |= ISBLESSED;
        !           693:            switch (cur->o_which)
        !           694:            {
        !           695:                case R_ADDSTR:
        !           696:                case R_ADDWISDOM:
        !           697:                case R_ADDINTEL:
        !           698:                case R_PROTECT:
        !           699:                case R_ADDHIT:
        !           700:                case R_ADDDAM:
        !           701:                    cur->o_ac = rnd(2) + 1;     /* From 1 to 3 */
        !           702:                    if (cur->o_flags & ISCURSED)
        !           703:                        cur->o_ac = -cur->o_ac;
        !           704:                    if (cur->o_flags & ISBLESSED) cur->o_ac++;
        !           705:                when R_DIGEST:
        !           706:                    if (cur->o_flags & ISCURSED) cur->o_ac = -1;
        !           707:                    else if (cur->o_flags & ISBLESSED) cur->o_ac = 2;
        !           708:                    else cur->o_ac = 1;
        !           709:            }
        !           710:        when TYP_STICK:
        !           711:            cur->o_type = STICK;
        !           712:            do {
        !           713:                cur->o_which = pick_one(ws_magic, MAXSTICKS);
        !           714:            } while (!allow_curse && ws_magic[cur->o_which].mi_curse == 100);
        !           715:            fix_stick(cur);
        !           716:            if (cursechance < ws_magic[cur->o_which].mi_curse)
        !           717:                cur->o_flags |= ISCURSED;
        !           718:            else if (blesschance < ws_magic[cur->o_which].mi_bless)
        !           719:                cur->o_flags |= ISBLESSED;
        !           720:        when TYP_MM:
        !           721:            cur->o_type = MM;
        !           722:            do {
        !           723:                cur->o_which = pick_one(m_magic, MAXMM);
        !           724:            } while (!allow_curse && m_magic[cur->o_which].mi_curse == 100);
        !           725:            cur->o_weight = things[TYP_MM].mi_wght;
        !           726:            if (cursechance < m_magic[cur->o_which].mi_curse)
        !           727:                cur->o_flags |= ISCURSED;
        !           728:            else if (blesschance < m_magic[cur->o_which].mi_bless)
        !           729:                cur->o_flags |= ISBLESSED;
        !           730:            switch (cur->o_which) {
        !           731:                case MM_JUG:
        !           732:                    switch(rnd(11)) {
        !           733:                        case 0: cur->o_ac = P_PHASE;
        !           734:                        when 1: cur->o_ac = P_CLEAR;
        !           735:                        when 2: cur->o_ac = P_SEEINVIS;
        !           736:                        when 3: cur->o_ac = P_HEALING;
        !           737:                        when 4: cur->o_ac = P_MFIND;
        !           738:                        when 5: cur->o_ac = P_TFIND;
        !           739:                        when 6: cur->o_ac = P_HASTE;
        !           740:                        when 7: cur->o_ac = P_RESTORE;
        !           741:                        when 8: cur->o_ac = P_FLY;
        !           742:                        when 9: cur->o_ac = P_SKILL;
        !           743:                        when 10:cur->o_ac = P_FFIND;
        !           744:                    }
        !           745:                when MM_OPEN:
        !           746:                    cur->o_ac = (4 + rnd(5)) * 5;
        !           747:                when MM_HUNGER:
        !           748:                case MM_DRUMS:
        !           749:                case MM_DISAPPEAR:
        !           750:                case MM_CHOKE:
        !           751:                case MM_KEOGHTOM:
        !           752:                    cur->o_ac = 3 + (rnd(3)+1) * 3;
        !           753:                when MM_BRACERS:
        !           754:                    if (cur->o_flags & ISCURSED)
        !           755:                        cur->o_ac = -(rnd(3)+1);
        !           756:                    else
        !           757:                        cur->o_ac = rnd(8)+1;
        !           758:                when MM_PROTECT:
        !           759:                    if (cur->o_flags & ISCURSED)
        !           760:                        cur->o_ac = -(rnd(3)+1);
        !           761:                    else
        !           762:                        cur->o_ac = rnd(5)+1;
        !           763:                when MM_DISP:
        !           764:                    cur->o_ac = 2;
        !           765:                when MM_SKILLS: /*  set it to a character class */
        !           766:                    cur->o_ac = rnd(NUM_CHARTYPES-1);
        !           767:                otherwise:
        !           768:                    cur->o_ac = 0;
        !           769:            }
        !           770:        otherwise:
        !           771:            debug("Picked a bad kind of object");
        !           772:            wait_for(' ');
        !           773:     }
        !           774:     return item;
        !           775: }
        !           776:
        !           777: /*
        !           778:  * provide a new item tailored to specification
        !           779:  */
        !           780: struct linked_list *
        !           781: spec_item(int type, int which, int hit, int damage)
        !           782: {
        !           783:     register struct linked_list *item;
        !           784:     register struct object *obj;
        !           785:
        !           786:     item = new_item(sizeof *obj);
        !           787:     obj = OBJPTR(item);
        !           788:     obj->o_count = 1;
        !           789:     obj->o_group = 0;
        !           790:     obj->contents = NULL;
        !           791:     obj->o_type = type;
        !           792:     obj->o_which = which;
        !           793:     strncpy(obj->o_damage, "0d0", sizeof(obj->o_damage));
        !           794:     strncpy(obj->o_hurldmg, "0d0", sizeof(obj->o_hurldmg));
        !           795:     obj->o_hplus = 0;
        !           796:     obj->o_dplus = 0;
        !           797:     obj->o_flags = 0;
        !           798:     obj->o_mark[0] = '\0';
        !           799:     obj->o_text = NULL;
        !           800:     obj->o_launch = 0;
        !           801:     obj->o_weight = 0;
        !           802:
        !           803:     /* Handle special characteristics */
        !           804:     switch (type) {
        !           805:        case WEAPON:
        !           806:            init_weapon(obj, which);
        !           807:            obj->o_hplus = hit;
        !           808:            obj->o_dplus = damage;
        !           809:            obj->o_ac = 10;
        !           810:
        !           811:            if (hit > 0 || damage > 0) obj->o_flags |= ISBLESSED;
        !           812:            else if (hit < 0 || damage < 0) obj->o_flags |= ISCURSED;
        !           813:
        !           814:        when ARMOR:
        !           815:            obj->o_ac = armors[which].a_class - hit;
        !           816:            if (hit > 0) obj->o_flags |= ISBLESSED;
        !           817:            else if (hit < 0) obj->o_flags |= ISCURSED;
        !           818:
        !           819:        when RING:
        !           820:            obj->o_ac = hit;
        !           821:            switch (obj->o_which) {
        !           822:                case R_ADDSTR:
        !           823:                case R_ADDWISDOM:
        !           824:                case R_ADDINTEL:
        !           825:                case R_PROTECT:
        !           826:                case R_ADDHIT:
        !           827:                case R_ADDDAM:
        !           828:                case R_DIGEST:
        !           829:                    if (hit > 1) obj->o_flags |= ISBLESSED;
        !           830:                    else if (hit < 0) obj->o_flags |= ISCURSED;
        !           831:            }
        !           832:
        !           833:        when STICK:
        !           834:            fix_stick(obj);
        !           835:            obj->o_charges = hit;
        !           836:
        !           837:        when GOLD:
        !           838:            obj->o_type = GOLD;
        !           839:            obj->o_count = GOLDCALC;
        !           840:            obj->o_ac = 11;
        !           841:
        !           842:        when MM:
        !           843:            obj->o_type = MM;
        !           844:            obj->o_ac = hit;
        !           845:
        !           846:        when RELIC:
        !           847:            /* Handle weight here since these are all created uniquely */
        !           848:            obj->o_weight = things[TYP_RELIC].mi_wght;
        !           849:            if (obj->o_which == EMORI_CLOAK)
        !           850:                obj->o_charges = 1;
        !           851:
        !           852:     }
        !           853:     return(item);
        !           854: }
        !           855:
        !           856: /*
        !           857:  * pick an item out of a list of nitems possible magic items
        !           858:  */
        !           859: int
        !           860: pick_one(struct magic_item *magic, int nitems)
        !           861: {
        !           862:     register struct magic_item *end;
        !           863:     register int i;
        !           864:     register struct magic_item *start;
        !           865:
        !           866:     start = magic;
        !           867:     for (end = &magic[nitems], i = rnd(1000); magic < end; magic++)
        !           868:        if (i < magic->mi_prob)
        !           869:            break;
        !           870:     if (magic == end)
        !           871:     {
        !           872:        if (wizard)
        !           873:        {
        !           874:            msg("bad pick_one: %d from %d items", i, nitems);
        !           875:            for (magic = start; magic < end; magic++)
        !           876:                msg("%s: %d%%", magic->mi_name, magic->mi_prob);
        !           877:        }
        !           878:        magic = start;
        !           879:     }
        !           880:     return (int) (magic - start);
        !           881: }
        !           882:
        !           883:
        !           884: /* blesscurse returns whether, according to the flag, the object is
        !           885:  * blessed, cursed, or neither
        !           886:  */
        !           887:
        !           888: char *
        !           889: blesscurse(int flags)
        !           890: {
        !           891:     if (flags & ISKNOW)  {
        !           892:        if (flags & ISCURSED) return("cursed ");
        !           893:        if (flags & ISBLESSED) return("blessed ");
        !           894:        return("normal ");
        !           895:     }
        !           896:     return("");
        !           897: }
        !           898:
        !           899: /*
        !           900:  * p_kind returns the type of potion for some types of identified potions;
        !           901:  * otherwise, it returns the color.
        !           902:  * We assume that obj points to a potion
        !           903:  */
        !           904:
        !           905: char *
        !           906: p_kind(struct object *obj)
        !           907: {
        !           908:     if (obj->o_which == P_ABIL) return(abilities[obj->o_kind]);
        !           909:     else return(p_colors[obj->o_which]);
        !           910: }
        !           911:
        !           912: /*
        !           913:  * extras:
        !           914:  *     Return the number of extra items to be created
        !           915:  */
        !           916: int
        !           917: extras(void)
        !           918: {
        !           919:        reg int i;
        !           920:
        !           921:        i = rnd(100);
        !           922:        if (i < 4)              /* 4% for 2 more */
        !           923:            return (2);
        !           924:        else if (i < 11)        /* 7% for 1 more */
        !           925:            return (1);
        !           926:        else                    /* otherwise no more */
        !           927:            return (0);
        !           928: }

CVSweb