[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

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