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

Annotation of early-roguelike/urogue/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:     UltraRogue: The Ultimate Adventure in the Dungeons of Doom
                      5:     Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
                      6:     All rights reserved.
                      7:
                      8:     Based on "Advanced Rogue"
                      9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
                     10:     All rights reserved.
                     11:
                     12:     Based on "Rogue: Exploring the Dungeons of Doom"
                     13:     Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     14:     All rights reserved.
                     15:
                     16:     See the file LICENSE.TXT for full copyright and licensing information.
                     17: */
                     18:
                     19: #include <string.h>
                     20: #include <ctype.h>
                     21: #include "rogue.h"
                     22:
                     23: /*
                     24:     inv_name()
                     25:         return the name of something as it would appear in an inventory.
                     26: */
                     27:
                     28: char *
                     29: inv_name(struct object *obj, int lowercase)
                     30: {
                     31:     char *pb;
                     32:     char buf[1024];
                     33:
                     34:     switch(obj->o_type)
                     35:     {
                     36:         case SCROLL:
                     37:             if (obj->o_count == 1)
                     38:                 sprintf(prbuf, "A %s%sscroll ",
                     39:                     obj->o_flags & CANRETURN ? "claimed " : "",
                     40:                     blesscurse(obj->o_flags));
                     41:             else
                     42:                 sprintf(prbuf, "%d %s%sscrolls ",
                     43:                     obj->o_count,
                     44:                     obj->o_flags & CANRETURN ? "claimed " : "",
                     45:                     blesscurse(obj->o_flags));
                     46:
                     47:             pb = &prbuf[strlen(prbuf)];
                     48:
                     49:             if (know_items[TYP_SCROLL][obj->o_which])
                     50:                 sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
                     51:             else if (guess_items[TYP_SCROLL][obj->o_which])
                     52:                 sprintf(pb, "called %s", guess_items[TYP_SCROLL][obj->o_which]);
                     53:             else
                     54:                 sprintf(pb, "titled '%s'", s_names[obj->o_which]);
                     55:             break;
                     56:
                     57:         case POTION:
                     58:             if (obj->o_count == 1)
                     59:                 sprintf(prbuf, "A %s%spotion ",
                     60:                     obj->o_flags & CANRETURN ? "claimed " : "",
                     61:                     blesscurse(obj->o_flags));
                     62:             else
                     63:                 sprintf(prbuf, "%d %s%spotions ",
                     64:                     obj->o_count,
                     65:                     obj->o_flags & CANRETURN ? "claimed " : "",
                     66:                     blesscurse(obj->o_flags));
                     67:
                     68:             pb = &prbuf[strlen(prbuf)];
                     69:
                     70:             if (know_items[TYP_POTION][obj->o_which])
                     71:                 sprintf(pb, "of %s(%s)", p_magic[obj->o_which].mi_name,
                     72:                     p_colors[obj->o_which]);
                     73:             else if (guess_items[TYP_POTION][obj->o_which])
                     74:                 sprintf(pb, "called %s(%s)", guess_items[TYP_POTION][obj->o_which],
                     75:                     p_colors[obj->o_which]);
                     76:             else
                     77:             {
                     78:                 if (obj->o_count == 1)
                     79:                     sprintf(prbuf, "A%s %s potion",
                     80:                          obj->o_flags & CANRETURN ? " claimed" :
                     81:                         (char *) vowelstr(p_colors[obj->o_which]),
                     82:                         p_colors[obj->o_which]);
                     83:                 else
                     84:                     sprintf(prbuf, "%d %s%s potions",
                     85:                         obj->o_count,
                     86:                      obj->o_flags & CANRETURN ? "claimed " : "",
                     87:                         (char *) p_colors[obj->o_which]);
                     88:             }
                     89:             break;
                     90:
                     91:         case FOOD:
                     92:             if (obj->o_count == 1)
                     93:                 sprintf(prbuf, "A%s %s",
                     94:                     obj->o_flags & CANRETURN ? " claimed" :
                     95:                     (char *) vowelstr(fd_data[obj->o_which].mi_name),
                     96:                     fd_data[obj->o_which].mi_name);
                     97:             else
                     98:                 sprintf(prbuf, "%d %s%ss", obj->o_count,
                     99:                     obj->o_flags & CANRETURN ? "claimed " : "",
                    100:                     fd_data[obj->o_which].mi_name);
                    101:             break;
                    102:
                    103:         case WEAPON:
                    104:             if (obj->o_count > 1)
                    105:                 sprintf(prbuf, "%d ", obj->o_count);
                    106:             else if ((obj->o_flags & (ISZAPPED | CANRETURN | ISPOISON | ISSILVER | ISTWOH)) ||
                    107:                  ((obj->o_flags & (ISKNOW | ISZAPPED)) == (ISKNOW | ISZAPPED)))
                    108:                 strcpy(prbuf, "A ");
                    109:             else
                    110:                 sprintf(prbuf, "A%s ", vowelstr(weaps[obj->o_which].w_name));
                    111:
                    112:             pb = &prbuf[strlen(prbuf)];
                    113:
                    114:             if ((obj->o_flags & ISKNOW) && (obj->o_flags & ISZAPPED))
                    115:                 sprintf(pb, "charged%s ", charge_str(obj,buf));
                    116:
                    117:             pb = &prbuf[strlen(prbuf)];
                    118:
                    119:             if (obj->o_flags & CANRETURN)
                    120:                 sprintf(pb, "claimed ");
                    121:
                    122:             pb = &prbuf[strlen(prbuf)];
                    123:
                    124:             if (obj->o_flags & ISPOISON)
                    125:                 sprintf(pb, "poisoned ");
                    126:
                    127:             pb = &prbuf[strlen(prbuf)];
                    128:
                    129:             if (obj->o_flags & ISSILVER)
                    130:                 sprintf(pb, "silver ");
                    131:
                    132:             if (obj->o_flags & ISTWOH)
                    133:                 sprintf(pb, "two-handed ");
                    134:
                    135:             pb = &prbuf[strlen(prbuf)];
                    136:
                    137:             if (obj->o_flags & ISKNOW)
                    138:                 sprintf(pb, "%s %s", num(obj->o_hplus, obj->o_dplus, buf),
                    139:                 weaps[obj->o_which].w_name);
                    140:             else
                    141:                 sprintf(pb, "%s", weaps[obj->o_which].w_name);
                    142:
                    143:             if (obj->o_count > 1)
                    144:                 strcat(prbuf, "s");
                    145:
                    146:             break;
                    147:
                    148:         case ARMOR:
                    149:             if (obj->o_flags & ISKNOW)
                    150:                 sprintf(prbuf, "%s%s %s",
                    151:                     obj->o_flags & CANRETURN ? "claimed " : "",
                    152:                    num(armors[obj->o_which].a_class - obj->o_ac, 0, buf),
                    153:                     armors[obj->o_which].a_name);
                    154:             else
                    155:                 sprintf(prbuf, "%s%s",
                    156:                     obj->o_flags & CANRETURN ? "claimed " : "",
                    157:                     armors[obj->o_which].a_name);
                    158:
                    159:             break;
                    160:
                    161:         case ARTIFACT:
                    162:             sprintf(prbuf, "the %s", arts[obj->o_which].ar_name);
                    163:
                    164:             if (obj->o_flags & CANRETURN)
                    165:                 strcat(prbuf, " (claimed)");
                    166:
                    167:             break;
                    168:
                    169:         case STICK:
                    170:             sprintf(prbuf, "A %s%s%s ",
                    171:                 obj->o_flags & CANRETURN ? "claimed " : "",
                    172:                 blesscurse(obj->o_flags), ws_type[obj->o_which]);
                    173:
                    174:             pb = &prbuf[strlen(prbuf)];
                    175:
                    176:             if (know_items[TYP_STICK][obj->o_which])
                    177:                 sprintf(pb, "of %s%s(%s)", ws_magic[obj->o_which].mi_name,
                    178:                     charge_str(obj,buf), ws_made[obj->o_which]);
                    179:             else if (guess_items[TYP_STICK][obj->o_which])
                    180:                 sprintf(pb, "called %s(%s)", guess_items[TYP_STICK][obj->o_which],
                    181:                     ws_made[obj->o_which]);
                    182:             else
                    183:                 sprintf(&prbuf[2], "%s%s %s",
                    184:                     obj->o_flags & CANRETURN ? "claimed " : "",
                    185:                     ws_made[obj->o_which],
                    186:                     ws_type[obj->o_which]);
                    187:
                    188:             break;
                    189:
                    190:         case RING:
                    191:             if (know_items[TYP_RING][obj->o_which])
                    192:                 sprintf(prbuf, "A%s%s ring of %s(%s)",
                    193:                     obj->o_flags & CANRETURN ? " claimed" : "", ring_num(obj,buf),
                    194:                     r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
                    195:             else if (guess_items[TYP_RING][obj->o_which])
                    196:                 sprintf(prbuf, "A %sring called %s(%s)",
                    197:                     obj->o_flags & CANRETURN ? "claimed " : "",
                    198:                     guess_items[TYP_RING][obj->o_which], r_stones[obj->o_which]);
                    199:             else
                    200:                 sprintf(prbuf, "A%s %s ring",
                    201:                     obj->o_flags & CANRETURN ? "claimed " :
                    202:                     (char *)vowelstr(r_stones[obj->o_which]),
                    203:                     r_stones[obj->o_which]);
                    204:             break;
                    205:
                    206:         case GOLD:
                    207:             sprintf(prbuf, "%d gold pieces", obj->o_count);
                    208:             break;
                    209:
                    210:         default:
                    211:             debug("Picked up something funny.");
                    212:             sprintf(prbuf, "Something bizarre %s", unctrl(obj->o_type));
                    213:             break;
                    214:     }
                    215:
                    216:     /* Is it marked? */
                    217:
                    218:     if (obj->o_mark[0])
                    219:     {
                    220:         pb = &prbuf[strlen(prbuf)];
                    221:         sprintf(pb, " <%s>", obj->o_mark);
                    222:     }
                    223:
                    224:     if (obj == cur_armor)
                    225:         strcat(prbuf, " (being worn)");
                    226:
                    227:     if (obj == cur_weapon)
                    228:         strcat(prbuf, " (weapon in hand)");
                    229:
                    230:     if (obj == cur_ring[LEFT_1])
                    231:         strcat(prbuf, " (on left hand)");
                    232:     else if (obj == cur_ring[LEFT_2])
                    233:         strcat(prbuf, " (on left hand)");
                    234:     else if (obj == cur_ring[LEFT_3])
                    235:         strcat(prbuf, " (on left hand)");
                    236:     else if (obj == cur_ring[LEFT_4])
                    237:         strcat(prbuf, " (on left hand)");
                    238:     else if (obj == cur_ring[LEFT_5])
                    239:         strcat(prbuf, " (on left hand)");
                    240:     else if (obj == cur_ring[RIGHT_1])
                    241:         strcat(prbuf, " (on right hand)");
                    242:     else if (obj == cur_ring[RIGHT_2])
                    243:         strcat(prbuf, " (on right hand)");
                    244:     else if (obj == cur_ring[RIGHT_3])
                    245:         strcat(prbuf, " (on right hand)");
                    246:     else if (obj == cur_ring[RIGHT_4])
                    247:         strcat(prbuf, " (on right hand)");
                    248:     else if (obj == cur_ring[RIGHT_5])
                    249:         strcat(prbuf, " (on right hand)");
                    250:
                    251:     if (obj->o_flags & ISPROT)
                    252:         strcat(prbuf, " [protected]");
                    253:
                    254:     if (lowercase && isupper(prbuf[0]))
                    255:         prbuf[0] = (char) tolower(prbuf[0]);
                    256:     else if (!lowercase && islower(*prbuf))
                    257:         *prbuf = (char) toupper(*prbuf);
                    258:
                    259:     if (!lowercase)
                    260:         strcat(prbuf, ".");
                    261:
                    262:     return(prbuf);
                    263: }
                    264:
                    265: /*
                    266:     rem_obj()
                    267:         Remove an object from the level.
                    268: */
                    269:
                    270: void
                    271: rem_obj(struct linked_list *item, int dis)
                    272: {
                    273:     struct linked_list  *llptr;
                    274:     struct object *objptr, *op;
                    275:     int x, y;
                    276:
                    277:     if (item == NULL)
                    278:         return;
                    279:
                    280:     detach(lvl_obj, item);
                    281:     objptr = OBJPTR(item);
                    282:
                    283:     if ( (llptr = objptr->next_obj) != NULL )
                    284:     {
                    285:         detach((objptr->next_obj), llptr);
                    286:         attach(lvl_obj, llptr);
                    287:
                    288:         op = OBJPTR(llptr);
                    289:
                    290:        op->next_obj = objptr->next_obj;
                    291:
                    292:        if (op->next_obj)
                    293:             objptr->next_obj->l_prev = NULL;
                    294:
                    295:         objptr->next_obj = NULL;
                    296:
                    297:         y = op->o_pos.y;
                    298:         x = op->o_pos.x;
                    299:
                    300:         if (cansee(y, x))
                    301:             mvwaddch(cw, y, x, op->o_type);
                    302:
                    303:         mvaddch(y, x, op->o_type);
                    304:     }
                    305:     else
                    306:     {
                    307:         y = objptr->o_pos.y;
                    308:         x = objptr->o_pos.x;
                    309:
                    310:         /* problems if dropped in rock */
                    311:
                    312:         mvaddch(y,x,(roomin((objptr->o_pos)) == NULL ? PASSAGE : FLOOR));
                    313:     }
                    314:
                    315:     if (dis)
                    316:         discard(item);
                    317: }
                    318:
                    319: /*
                    320:     add_obj()
                    321:         adds an object to the level
                    322: */
                    323:
                    324: void
                    325: add_obj(struct linked_list *item, int y, int x)
                    326: {
                    327:     struct linked_list  *llptr;
                    328:     struct object*objptr;
                    329:
                    330:     llptr = find_obj(y, x);
                    331:
                    332:     if (llptr)
                    333:     {
                    334:         objptr = OBJPTR(llptr);
                    335:         attach((objptr->next_obj), item);
                    336:     }
                    337:     else
                    338:     {
                    339:         attach(lvl_obj, item);
                    340:         objptr = OBJPTR(item);
                    341:         objptr->next_obj = NULL;
                    342:         objptr->o_pos.y = y;
                    343:         objptr->o_pos.x = x;
                    344:         mvaddch(y, x, objptr->o_type);
                    345:     }
                    346: }
                    347:
                    348: /*
                    349:     drop()
                    350:         put something down
                    351: */
                    352:
                    353: int
                    354: drop(struct linked_list *item)
                    355: {
                    356:     char    ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
                    357:     struct object   *obj;
                    358:
                    359:     switch (ch)
                    360:     {
                    361:         case GOLD:
                    362:         case POTION:
                    363:         case SCROLL:
                    364:         case FOOD:
                    365:         case WEAPON:
                    366:         case ARMOR:
                    367:         case RING:
                    368:         case STICK:
                    369:         case FLOOR:
                    370:         case PASSAGE:
                    371:         case POOL:
                    372:         case ARTIFACT:
                    373:             if (item == NULL && (item = get_item("drop", 0)) == NULL)
                    374:                 return(FALSE);
                    375:             break;
                    376:
                    377:         default:
                    378:             msg("You can't drop something here.");
                    379:             return(FALSE);
                    380:     }
                    381:
                    382:     obj = OBJPTR(item);
                    383:
                    384:     if (!dropcheck(obj))
                    385:         return(FALSE);
                    386:
                    387:     /* Curse a dropped scare monster scroll */
                    388:
                    389:     if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
                    390:     {
                    391:         if (obj->o_flags & ISBLESSED)
                    392:             obj->o_flags &= ~ISBLESSED;
                    393:         else
                    394:             obj->o_flags |= ISCURSED;
                    395:     }
                    396:
                    397:     /* Take it out of the pack */
                    398:
                    399:     if (obj->o_count >= 2 && obj->o_group == 0)
                    400:     {
                    401:         struct linked_list  *nitem = new_item(sizeof *obj);
                    402:
                    403:         obj->o_count--;
                    404:         obj = OBJPTR(nitem);
                    405:         *obj = *(OBJPTR(item));
                    406:         obj->o_count = 1;
                    407:         item = nitem;
                    408:     }
                    409:     else
                    410:         rem_pack(obj);
                    411:
                    412:     if (ch == POOL)
                    413:     {
                    414:         msg("The pool bubbles briefly as your %s sinks out of sight.",
                    415:             inv_name(obj, TRUE));
                    416:         discard(item);
                    417:         item = NULL;
                    418:     }
                    419:     else            /* Link it into the level object list */
                    420:     {
                    421:         add_obj(item, hero.y, hero.x);
                    422:         mvaddch(hero.y, hero.x, obj->o_type);
                    423:     }
                    424:
                    425:     if (obj->o_type == ARTIFACT)
                    426:         has_artifact &= ~(1 << obj->o_which);
                    427:
                    428:     updpack();
                    429:     return(TRUE);
                    430: }
                    431:
                    432: /*
                    433:     dropcheck()
                    434:         do special checks for dropping or unweilding|unwearing|unringing
                    435: */
                    436:
                    437: int
                    438: dropcheck(struct object *op)
                    439: {
                    440:     if (op == NULL)
                    441:         return(TRUE);
                    442:
                    443:     if (op != cur_armor && op != cur_weapon &&
                    444:         op != cur_ring[LEFT_1] && op != cur_ring[LEFT_2] &&
                    445:         op != cur_ring[LEFT_3] && op != cur_ring[LEFT_4] &&
                    446:         op != cur_ring[LEFT_5] &&
                    447:         op != cur_ring[RIGHT_1] && op != cur_ring[RIGHT_2] &&
                    448:         op != cur_ring[RIGHT_3] && op != cur_ring[RIGHT_4] &&
                    449:         op != cur_ring[RIGHT_5])
                    450:         return(TRUE);
                    451:
                    452:     if (op->o_flags & ISCURSED)
                    453:     {
                    454:         msg("You can't.  It appears to be cursed.");
                    455:         return(FALSE);
                    456:     }
                    457:
                    458:     if (op == cur_weapon)
                    459:         cur_weapon = NULL;
                    460:     else if (op == cur_armor)
                    461:     {
                    462:         waste_time();
                    463:         cur_armor = NULL;
                    464:     }
                    465:     else if (op == cur_ring[LEFT_1] || op == cur_ring[LEFT_2] ||
                    466:          op == cur_ring[LEFT_3] || op == cur_ring[LEFT_4] ||
                    467:          op == cur_ring[LEFT_5] ||
                    468:          op == cur_ring[RIGHT_1] || op == cur_ring[RIGHT_2] ||
                    469:          op == cur_ring[RIGHT_3] || op == cur_ring[RIGHT_4] ||
                    470:          op == cur_ring[RIGHT_5])
                    471:     {
                    472:         if (op == cur_ring[LEFT_1])
                    473:             cur_ring[LEFT_1] = NULL;
                    474:         else if (op == cur_ring[LEFT_2])
                    475:             cur_ring[LEFT_2] = NULL;
                    476:         else if (op == cur_ring[LEFT_3])
                    477:             cur_ring[LEFT_3] = NULL;
                    478:         else if (op == cur_ring[LEFT_4])
                    479:             cur_ring[LEFT_4] = NULL;
                    480:         else if (op == cur_ring[LEFT_5])
                    481:             cur_ring[LEFT_5] = NULL;
                    482:         else if (op == cur_ring[RIGHT_1])
                    483:             cur_ring[RIGHT_1] = NULL;
                    484:         else if (op == cur_ring[RIGHT_2])
                    485:             cur_ring[RIGHT_2] = NULL;
                    486:         else if (op == cur_ring[RIGHT_3])
                    487:             cur_ring[RIGHT_3] = NULL;
                    488:         else if (op == cur_ring[RIGHT_4])
                    489:             cur_ring[RIGHT_4] = NULL;
                    490:         else if (op == cur_ring[RIGHT_5])
                    491:             cur_ring[RIGHT_5] = NULL;
                    492:
                    493:         switch (op->o_which)
                    494:         {
                    495:             case R_ADDSTR:
                    496:                 chg_str(-op->o_ac, FALSE, FALSE);
                    497:                 break;
                    498:             case R_ADDHIT:
                    499:                 chg_dext(-op->o_ac, FALSE, FALSE);
                    500:                 break;
                    501:             case R_ADDINTEL:
                    502:                 pstats.s_intel -= op->o_ac;
                    503:                 break;
                    504:             case R_ADDWISDOM:
                    505:                 pstats.s_wisdom -= op->o_ac;
                    506:                 break;
                    507:
                    508:             case R_SEEINVIS:
                    509:                 if (find_slot(FUSE_UNSEE,FUSE) == NULL)
                    510:                 {
                    511:                     turn_off(player, CANSEE);
                    512:                     msg("The tingling feeling leaves your eyes.");
                    513:                 }
                    514:
                    515:                 light(&hero);
                    516:                 mvwaddch(cw, hero.y, hero.x, PLAYER);
                    517:                 break;
                    518:
                    519:             case R_LIGHT:
                    520:                 if (roomin(hero) != NULL)
                    521:                 {
                    522:                     light(&hero);
                    523:                     mvwaddch(cw, hero.y, hero.x, PLAYER);
                    524:                 }
                    525:                 break;
                    526:         }
                    527:     }
                    528:     return(TRUE);
                    529: }
                    530:
                    531: /*
                    532:     new_thing()
                    533:         return a new thing
                    534: */
                    535:
                    536: struct linked_list *
                    537: new_thing(void)
                    538: {
                    539:     int j, k;
                    540:     struct linked_list  *item;
                    541:     struct object   *cur;
                    542:     short   blesschance = srnd(100);
                    543:     short   cursechance = srnd(100);
                    544:
                    545:     item = new_item(sizeof *cur);
                    546:     cur = OBJPTR(item);
                    547:     cur->o_hplus = cur->o_dplus = 0;
                    548:     cur->o_damage = cur->o_hurldmg = "0d0";
                    549:     cur->o_ac = 11;
                    550:     cur->o_count = 1;
                    551:     cur->o_group = 0;
                    552:     cur->o_flags = 0;
                    553:     cur->o_weight = 0;
                    554:     cur->o_mark[0] = '\0';
                    555:
                    556:     /*
                    557:      * Decide what kind of object it will be If we haven't had food for a
                    558:      * while, let it be food.
                    559:      */
                    560:
                    561:     switch (no_food > 3 ? TYP_FOOD : pick_one(things, numthings))
                    562:     {
                    563:         case TYP_POTION:
                    564:             cur->o_type = POTION;
                    565:             cur->o_which = pick_one(p_magic, maxpotions);
                    566:             cur->o_weight = things[TYP_POTION].mi_wght;
                    567:
                    568:             if (cursechance < p_magic[cur->o_which].mi_curse)
                    569:                 cur->o_flags |= ISCURSED;
                    570:             else if (blesschance < p_magic[cur->o_which].mi_bless)
                    571:                 cur->o_flags |= ISBLESSED;
                    572:             break;
                    573:
                    574:         case TYP_SCROLL:
                    575:             cur->o_type = SCROLL;
                    576:             cur->o_which = pick_one(s_magic, maxscrolls);
                    577:             cur->o_weight = things[TYP_SCROLL].mi_wght;
                    578:
                    579:             if (cursechance < s_magic[cur->o_which].mi_curse)
                    580:                 cur->o_flags |= ISCURSED;
                    581:             else if (blesschance < s_magic[cur->o_which].mi_bless)
                    582:                 cur->o_flags |= ISBLESSED;
                    583:             break;
                    584:
                    585:         case TYP_FOOD:
                    586:             no_food = 0;
                    587:             cur->o_type = FOOD;
                    588:             cur->o_which = pick_one(fd_data, maxfoods);
                    589:             cur->o_weight = 2;
                    590:             cur->o_count += extras();
                    591:             break;
                    592:
                    593:         case TYP_WEAPON:
                    594:             cur->o_type = WEAPON;
                    595:             cur->o_which = rnd(maxweapons);
                    596:             init_weapon(cur, cur->o_which);
                    597:
                    598:             if (cursechance < 10)
                    599:             {
                    600:                 short   bad = (rnd(10) < 1) ? 2 : 1;
                    601:
                    602:                 cur->o_flags |= ISCURSED;
                    603:                 cur->o_hplus -= bad;
                    604:                 cur->o_dplus -= bad;
                    605:             }
                    606:             else if (blesschance < 15)
                    607:             {
                    608:                 short   good = (rnd(10) < 1) ? 2 : 1;
                    609:
                    610:                 cur->o_hplus += good;
                    611:                 cur->o_dplus += good;
                    612:             }
                    613:             break;
                    614:
                    615:         case TYP_ARMOR:
                    616:             cur->o_type = ARMOR;
                    617:
                    618:             for (j = 0; j < maxarmors; j++)
                    619:                 if (blesschance < armors[j].a_prob)
                    620:                     break;
                    621:
                    622:             if (j == maxarmors)
                    623:             {
                    624:                 debug("Picked a bad armor %d", blesschance);
                    625:                 j = 0;
                    626:             }
                    627:
                    628:             cur->o_which = j;
                    629:             cur->o_ac = armors[j].a_class;
                    630:
                    631:             if (((k = rnd(100)) < 20) && j != MITHRIL)
                    632:             {
                    633:                 cur->o_flags |= ISCURSED;
                    634:                 cur->o_ac += rnd(3) + 1;
                    635:             }
                    636:             else if (k < 28 || j == MITHRIL)
                    637:                 cur->o_ac -= rnd(3) + 1;
                    638:
                    639:             if (j == MITHRIL)
                    640:                 cur->o_flags |= ISPROT;
                    641:
                    642:             cur->o_weight = armors[j].a_wght;
                    643:
                    644:             break;
                    645:
                    646:         case TYP_RING:
                    647:             cur->o_type = RING;
                    648:             cur->o_which = pick_one(r_magic, maxrings);
                    649:             cur->o_weight = things[TYP_RING].mi_wght;
                    650:
                    651:             if (cursechance < r_magic[cur->o_which].mi_curse)
                    652:                 cur->o_flags |= ISCURSED;
                    653:             else if (blesschance < r_magic[cur->o_which].mi_bless)
                    654:                 cur->o_flags |= ISBLESSED;
                    655:
                    656:             switch (cur->o_which)
                    657:             {
                    658:                 case R_ADDSTR:
                    659:                 case R_ADDWISDOM:
                    660:                 case R_ADDINTEL:
                    661:                 case R_PROTECT:
                    662:                 case R_ADDHIT:
                    663:                 case R_ADDDAM:
                    664:                 case R_CARRYING:
                    665:                     cur->o_ac = rnd(2) + 1; /* From 1 to 3 */
                    666:
                    667:                     if (cur->o_flags & ISCURSED)
                    668:                         cur->o_ac = -cur->o_ac;
                    669:
                    670:                     if (cur->o_flags & ISBLESSED)
                    671:                         cur->o_ac++;
                    672:
                    673:                     break;
                    674:
                    675:                 case R_RESURRECT:
                    676:                 case R_TELCONTROL:
                    677:                 case R_VREGEN:
                    678:                 case R_REGEN:
                    679:                 case R_PIETY:
                    680:                 case R_WIZARD:
                    681:                     cur->o_ac = 0;
                    682:
                    683:                     if (cur->o_flags & ISCURSED)
                    684:                         cur->o_ac = -1;
                    685:
                    686:                     if (cur->o_flags & ISBLESSED)
                    687:                         cur->o_ac = 1;
                    688:
                    689:                     break;
                    690:
                    691:                 case R_DIGEST:
                    692:
                    693:                     if (cur->o_flags & ISCURSED)
                    694:                         cur->o_ac = -1;
                    695:                     else if (cur->o_flags & ISBLESSED)
                    696:                         cur->o_ac = 2;
                    697:                     else
                    698:                         cur->o_ac = 1;
                    699:                     break;
                    700:
                    701:                 default:
                    702:                     cur->o_ac = 0;
                    703:                     break;
                    704:             }
                    705:             break;
                    706:
                    707:         case TYP_STICK:
                    708:             cur->o_type = STICK;
                    709:             cur->o_which = pick_one(ws_magic, maxsticks);
                    710:             fix_stick(cur);
                    711:
                    712:             if (cursechance < ws_magic[cur->o_which].mi_curse)
                    713:                 cur->o_flags |= ISCURSED;
                    714:             else if (blesschance < ws_magic[cur->o_which].mi_bless)
                    715:                 cur->o_flags |= ISBLESSED;
                    716:
                    717:             break;
                    718:
                    719:         default:
                    720:             debug("Picked a bad kind of object");
                    721:             wait_for(' ');
                    722:     }
                    723:
                    724:     return(item);
                    725: }
                    726:
                    727: /*
                    728:     spec_item()
                    729:         provide a new item tailored to specification
                    730: */
                    731:
                    732: struct linked_list  *
                    733: spec_item(char type, int which, int hitp, int damage)
                    734: {
                    735:     struct linked_list  *item;
                    736:     struct object   *obj;
                    737:
                    738:     item = new_item(sizeof *obj);
                    739:     obj = OBJPTR(item);
                    740:
                    741:     obj->o_count = 1;
                    742:     obj->o_group = 0;
                    743:     obj->o_type = type;
                    744:     obj->o_which = which;
                    745:     obj->o_damage = obj->o_hurldmg = "0d0";
                    746:     obj->o_hplus = 0;
                    747:     obj->o_dplus = 0;
                    748:     obj->o_flags = 0;
                    749:     obj->o_mark[0] = '\0';
                    750:     obj->o_text = NULL;
                    751:     obj->o_launch = 0;
                    752:     obj->o_weight = 0;
                    753:
                    754:     switch(type)       /* Handle special characteristics */
                    755:     {
                    756:         case WEAPON:
                    757:             init_weapon(obj, which);
                    758:             obj->o_hplus = hitp;
                    759:             obj->o_dplus = damage;
                    760:             obj->o_ac = 10;
                    761:             break;
                    762:
                    763:         case ARMOR:
                    764:             obj->o_ac = armors[which].a_class - hitp;
                    765:             break;
                    766:
                    767:         case RING:
                    768:             obj->o_ac = hitp;
                    769:             break;
                    770:
                    771:         case STICK:
                    772:             fix_stick(obj);
                    773:             obj->o_charges = hitp;
                    774:             break;
                    775:
                    776:         case GOLD:
                    777:             obj->o_type = GOLD;
                    778:             obj->o_count = GOLDCALC;
                    779:             obj->o_ac = 11;
                    780:             break;
                    781:     }
                    782:
                    783:     if (hitp > 0 || damage > 0)
                    784:         obj->o_flags |= ISBLESSED;
                    785:     else if (hitp < 0 || damage < 0)
                    786:         obj->o_flags |= ISCURSED;
                    787:
                    788:     return(item);
                    789: }
                    790:
                    791: /*
                    792:     pick_one()
                    793:         pick an item out of a list of nitems possible magic items
                    794: */
                    795:
                    796: int
                    797: pick_one(struct magic_item *magic, int nitems)
                    798: {
                    799:     int i;
                    800:     struct magic_item   *end;
                    801:     struct magic_item   *start = magic;
                    802:
                    803:     for (end = &magic[nitems], i = rnd(1000); magic < end; magic++)
                    804:         if (i <= magic->mi_prob)
                    805:             break;
                    806:
                    807:     if (magic == end)
                    808:     {
                    809:         if (wizard)
                    810:         {
                    811:             add_line("Bad pick_one: %d from %d items", i, nitems);
                    812:
                    813:             for (magic = start; magic < end; magic++)
                    814:                 add_line("%s: %d%%", magic->mi_name, magic->mi_prob);
                    815:
                    816:             end_line();
                    817:         }
                    818:         magic = start;
                    819:     }
                    820:
                    821:     return((int)(magic - start));
                    822: }
                    823:
                    824:
                    825: /*
                    826:     blesscurse()
                    827:         returns whether the object is  blessed or cursed
                    828: */
                    829:
                    830: char *
                    831: blesscurse(long flags)
                    832: {
                    833:     if (flags & ISKNOW)
                    834:     {
                    835:         if (flags & ISCURSED)
                    836:             return("cursed ");
                    837:
                    838:         if (flags & ISBLESSED)
                    839:             return("blessed ");
                    840:
                    841:         return("normal ");
                    842:     }
                    843:
                    844:     return("");
                    845: }
                    846:
                    847: /*
                    848:     extras()
                    849:         Return the number of extra food items to be created
                    850: */
                    851:
                    852: int
                    853: extras(void)
                    854: {
                    855:     int i = rnd(100);
                    856:
                    857:     if (i < 10)
                    858:         return(2);
                    859:     else if (i < 20)
                    860:         return(1);
                    861:     else
                    862:         return(0);
                    863: }
                    864:
                    865: /*
                    866:     name_type()
                    867:         Returns a string identifying a pack item's type
                    868: */
                    869:
                    870: char *
                    871: name_type(int type)
                    872: {
                    873:     switch(type)
                    874:     {
                    875:         case ARMOR:
                    876:             return ("armor");
                    877:
                    878:         case WEAPON:
                    879:             return ("weapons");
                    880:
                    881:         case SCROLL:
                    882:             return ("scrolls");
                    883:
                    884:         case RING:
                    885:             return ("rings");
                    886:
                    887:         case STICK:
                    888:             return ("staffs");
                    889:
                    890:         case POTION:
                    891:             return ("potions");
                    892:
                    893:         case FOOD:
                    894:             return ("food");
                    895:
                    896:         case GOLD:
                    897:             return ("gold");
                    898:
                    899:         default:
                    900:             return ("items");
                    901:     }
                    902: }
                    903:
                    904: /*
                    905:     make_item()
                    906:         adds a linked_list structure to the top of an object for interfacing
                    907:         with other routines
                    908: */
                    909:
                    910: linked_list *
                    911: make_item(object *obj_p)
                    912: {
                    913:     linked_list *item_p = new_list();
                    914:
                    915:     item_p->l_next = item_p->l_prev = NULL;
                    916:
                    917:     item_p->data.obj = obj_p;
                    918:
                    919:     return(item_p);
                    920: }
                    921:
                    922: /*
                    923:     is_member()
                    924:         Checks to see if a character is a member of an array
                    925: */
                    926:
                    927: int
                    928: is_member(char *list_p, int member)
                    929: {
                    930:     while (*list_p != 0)
                    931:     {
                    932:         if (*list_p++ == member)
                    933:             return(TRUE);
                    934:     }
                    935:
                    936:     return(FALSE);
                    937: }

CVSweb