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

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

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

CVSweb