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

Annotation of early-roguelike/urogue/monsters.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:     monsters.c - File with various monster functions in it
                      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 <stdlib.h>
                     20: #include <string.h>
                     21: #include <ctype.h>
                     22: #include "rogue.h"
                     23:
                     24: /*
                     25:     summon_monster()
                     26:         Summon a monster.
                     27: */
                     28:
                     29: struct linked_list *
                     30: summon_monster(int type, int familiar, int print_message)
                     31: {
                     32:     struct linked_list  *mp;
                     33:     struct thing    *tp;
                     34:     int   monster;
                     35:
                     36:     if (familiar && !is_wearing(R_WIZARD) && off(player, CANSUMMON))
                     37:     {
                     38:         msg("Only spellcasters can summon familiars!");
                     39:         return(NULL);
                     40:     }
                     41:
                     42:     if (type == 0)    /* Random monster modified by level */
                     43:     {
                     44:         int ndice = min(pstats.s_lvl, (nummonst - NUMSUMMON) / 8);
                     45:
                     46:         monster = min(nummonst, roll(ndice, pstats.s_charisma));
                     47:
                     48:                /*
                     49:          * if a familiar exists, and it is higher in level, make it
                     50:          * again
                     51:          */
                     52:
                     53:         if (fam_ptr != NULL)
                     54:                {
                     55:             struct thing   *fp = THINGPTR(fam_ptr);
                     56:
                     57:             monster = max(fp->t_index, monster);
                     58:         }
                     59:        }
                     60:     else
                     61:         monster = type;
                     62:
                     63:     turn_on(player, SUMMONING);
                     64:
                     65:     mp = creat_mons(&player, monster, NOMESSAGE);
                     66:
                     67:     if (!mp)
                     68:     {
                     69:         msg("Summon failed.");
                     70:         turn_off(player, SUMMONING);
                     71:         return(NULL);
                     72:     }
                     73:
                     74:     if (print_message == MESSAGE)
                     75:     {
                     76:         msg("A %s appears out of nowhere!", monsters[monster].m_name);
                     77:
                     78:         if (familiar)
                     79:             msg("I am here to serve %s.", whoami);
                     80:         else
                     81:         {
                     82:             msg("My goodness, are you Yendor?");
                     83:             ++mons_summoned;
                     84:             debug("%d monsters now summoned.", mons_summoned);
                     85:         }
                     86:     }
                     87:
                     88:     tp = THINGPTR(mp);
                     89:     turn_on(*tp, ISCHARMED);    /* Summoned monsters are always charmed */
                     90:
                     91:     if (familiar)
                     92:     {
                     93:         int i;
                     94:         static const unsigned long fam_on[]= {ISREGEN,CANSHOOT,CANWIELD,HASARMOR,ISFAMILIAR,0};
                     95:         static const unsigned long fam_off[]={ISMEAN, ISHUH, ISINVIS,
                     96:                     CANSURPRISE, NOMOVE,
                     97:                     ISSLOW, ISSHADOW, ISGREED, ISFAST,
                     98:                     CANFLY, ISFLEE, 0};
                     99:
                    100:         for (i = 0; fam_on[i]; i++)
                    101:             turn_on(*tp, fam_on[i]);
                    102:
                    103:         for (i = 0; fam_off[i]; i++)
                    104:             turn_off(*tp, fam_off[i]);
                    105:
                    106:         if (fam_ptr != NULL)    /* Get rid of old familiar */
                    107:         {
                    108:             struct thing    *fp = THINGPTR(fam_ptr);
                    109:             struct linked_list  *fpack = fp->t_pack;
                    110:             struct linked_list  *item;
                    111:
                    112:             if (fpack != NULL)  /* Transfer pack */
                    113:             {
                    114:                 if (tp->t_pack == NULL)
                    115:                     tp->t_pack = fpack;
                    116:                 else
                    117:                 {
                    118:                     for(item=tp->t_pack; item->l_next != NULL; item=next(item))
                    119:                         ;   /* find last item in list */
                    120:
                    121:                     item->l_next = fpack;
                    122:                     fpack->l_prev = item;
                    123:                 }
                    124:             }
                    125:
                    126:             fpack = NULL;
                    127:             killed(NULL, fam_ptr, NOMESSAGE, NOPOINTS);
                    128:         }
                    129:
                    130:         fam_ptr = mp;
                    131:         fam_type = monster;
                    132:
                    133:         /* improve their abilities a bit */
                    134:
                    135:         tp->t_stats.s_hpt += roll(2, pstats.s_lvl);
                    136:         tp->t_stats.s_lvl += roll(2, (pstats.s_lvl / 4) + 1);
                    137:         tp->t_stats.s_arm -= roll(2, (pstats.s_lvl / 4) + 1);
                    138:         tp->t_stats.s_str += roll(2, (pstats.s_lvl / 4) + 1);
                    139:         tp->t_stats.s_intel += roll(2, (pstats.s_lvl / 4) + 1);
                    140:         tp->t_stats.s_wisdom += roll(2, (pstats.s_lvl / 4) + 1);
                    141:         tp->t_stats.s_dext += roll(2, (pstats.s_lvl / 4) + 1);
                    142:         tp->t_stats.s_const += roll(2, (pstats.s_lvl / 4) + 1);
                    143:         tp->t_stats.s_charisma += roll(2, (pstats.s_lvl / 4) + 1);
                    144:
                    145:                /* some monsters do no damage by default */
                    146:
                    147:                if (strcmp(tp->t_stats.s_dmg, "0d0") == 0)
                    148:             tp->t_stats.s_dmg = "1d8";
                    149:
                    150:         tp->maxstats = tp->t_stats; /* structure assignment */
                    151:     }
                    152:
                    153:     turn_off(player, SUMMONING);
                    154:
                    155:     return(mp);
                    156: }
                    157:
                    158: /*
                    159:      randmonster()
                    160:         wander - wandering monster allowed
                    161:         grab - a throne room monster allowed
                    162: */
                    163:
                    164: int
                    165: randmonster(int wander, int grab)
                    166: {
                    167:     int mons_number, cur_level, range, i;
                    168:
                    169:     /* Do we want a merchant? */
                    170:
                    171:     if (wander == WANDER && monsters[nummonst].m_wander && rnd(5000) < 3)
                    172:         return(nummonst);
                    173:
                    174:     cur_level = level;
                    175:     range = 4 * NLEVMONS;
                    176:     i = 0;
                    177:
                    178:     do
                    179:     {
                    180:         if (i++ > range * 10)   /* just in case all have be genocided */
                    181:         {
                    182:             i = 0;
                    183:
                    184:             if (--cur_level <= 0)
                    185:                 fatal("Rogue could not find a monster to make");
                    186:         }
                    187:
                    188:         mons_number = NLEVMONS * (cur_level - 1) +
                    189:             (rnd(range) - (range - 1 - NLEVMONS));
                    190:
                    191:         if (mons_number < 1)
                    192:             mons_number = rnd(NLEVMONS) + 1;
                    193:         else if (mons_number > nummonst - NUMSUMMON - 1)
                    194:         {
                    195:             if (grab == GRAB)
                    196:                 mons_number = rnd(range + NUMSUMMON) +
                    197:                     (nummonst - 1) -
                    198:                     (range + NUMSUMMON - 1);
                    199:             else if (mons_number > nummonst - 1)
                    200:                 mons_number = rnd(range) +
                    201:                 (nummonst - NUMSUMMON - 1) -
                    202:                 (range - 1);
                    203:         }
                    204:     }
                    205:     while (wander == WANDER ? !monsters[mons_number].m_wander ||
                    206:         !monsters[mons_number].m_normal :
                    207:         !monsters[mons_number].m_normal);
                    208:
                    209:     return((short)mons_number);
                    210: }
                    211:
                    212: /*
                    213:     new_monster()
                    214:         Pick a new monster and add it to the list
                    215: */
                    216:
                    217: void
                    218: new_monster(struct linked_list *item, int type, coord *cp, int max_monster)
                    219: {
                    220:     struct thing    *tp;
                    221:     struct monster  *mp;
                    222:     char    *ip, *hitp;
                    223:     int   i, min_intel, max_intel;
                    224:     int   num_dice, num_sides = 8, num_extra = 0;
                    225:     int eff_charisma = pstats.s_charisma;
                    226:     int eff_intel = pstats.s_intel;
                    227:
                    228:     attach(mlist, item);
                    229:     tp = THINGPTR(item);
                    230:     tp->t_index = type;
                    231:     tp->t_wasshot = FALSE;
                    232:     tp->t_type = monsters[type].m_appear;
                    233:     tp->t_ctype = C_MONSTER;
                    234:     tp->t_no_move = 0;
                    235:     tp->t_doorgoal = -1;
                    236:     tp->t_pos = *cp;
                    237:     tp->t_oldpos = *cp;
                    238:     tp->t_oldch = CCHAR( mvwinch(cw, cp->y, cp->x) );
                    239:     mvwaddch(mw, cp->y, cp->x, tp->t_type);
                    240:     mp = &monsters[tp->t_index];
                    241:
                    242:     /* Figure out monster's hit points */
                    243:
                    244:     hitp = mp->m_stats.s_hpt;
                    245:     num_dice = atoi(hitp);
                    246:
                    247:     if ((hitp = strchr(hitp, 'd')) != NULL)
                    248:     {
                    249:         num_sides = atoi(++hitp);
                    250:
                    251:         if ((hitp = strchr(hitp, '+')) != NULL)
                    252:             num_extra = atoi(++hitp);
                    253:     }
                    254:
                    255:     if (max_monster == MAXSTATS)
                    256:         tp->t_stats.s_hpt = num_dice * num_sides + num_extra;
                    257:     else
                    258:         tp->t_stats.s_hpt = roll(num_dice, num_sides) + num_extra;
                    259:
                    260:     tp->t_stats.s_lvl = mp->m_stats.s_lvl;
                    261:     tp->t_stats.s_arm = mp->m_stats.s_arm;
                    262:     tp->t_stats.s_dmg = mp->m_stats.s_dmg;
                    263:     tp->t_stats.s_exp = mp->m_stats.s_exp + mp->m_add_exp * tp->t_stats.s_hpt;
                    264:     tp->t_stats.s_str = mp->m_stats.s_str;
                    265:
                    266:     if (max_level > 30)
                    267:     {
                    268:         tp->t_stats.s_hpt += roll(4, (max_level - 60) * 2);
                    269:         tp->t_stats.s_lvl += roll(4, (max_level - 60) / 8);
                    270:         tp->t_stats.s_arm -= roll(2, (max_level - 60) / 8);
                    271:         tp->t_stats.s_str += roll(2, (max_level - 60) / 12);
                    272:         tp->t_stats.s_exp += roll(4, (max_level - 60) * 2) * mp->m_add_exp;
                    273:     }
                    274:
                    275:     /*
                    276:      * just initailize others values to something reasonable for now
                    277:      * maybe someday will *really* put these in monster table
                    278:      */
                    279:
                    280:     tp->t_stats.s_wisdom = 8 + rnd(4);
                    281:     tp->t_stats.s_dext = 8 + rnd(4);
                    282:     tp->t_stats.s_const = 8 + rnd(4);
                    283:     tp->t_stats.s_charisma = 8 + rnd(4);
                    284:
                    285:     if (max_level > 45)
                    286:         tp->t_stats.s_dext += roll(2, (max_level - 50) / 8);
                    287:
                    288:     /* Set the initial flags */
                    289:
                    290:     for (i = 0; i < 16; i++)
                    291:         tp->t_flags[i] = 0;
                    292:
                    293:     for (i = 0; i < 16; i++)
                    294:         turn_on(*tp, mp->m_flags[i]);
                    295:
                    296:     /* suprising monsters don't always surprise you */
                    297:
                    298:     if (!max_monster && on(*tp, CANSURPRISE) && rnd(100) < 20)
                    299:         turn_off(*tp, CANSURPRISE);
                    300:
                    301:     /* If this monster is unique, genocide it */
                    302:
                    303:     if (on(*tp, ISUNIQUE))
                    304:         mp->m_normal = FALSE;
                    305:
                    306:     /* gods automatically get special abilities */
                    307:
                    308:     if (on(*tp, ISGOD))
                    309:     {
                    310:         turn_on(*tp, CANFRIGHTEN);
                    311:         turn_on(*tp, CANCAST);
                    312:         turn_on(*tp, CANFLY);
                    313:         turn_on(*tp, CANBARGAIN);
                    314:         turn_on(*tp, ISLARGE);
                    315:         turn_on(*tp, CANTELEPORT);
                    316:         turn_on(*tp, CANSPEAK);
                    317:         turn_on(*tp, CANDARKEN);
                    318:         turn_on(*tp, CANSEE);
                    319:         turn_on(*tp, CANLIGHT);
                    320:         turn_on(*tp, BMAGICHIT);
                    321:     }
                    322:
                    323:     tp->t_turn = TRUE;
                    324:     tp->t_pack = NULL;
                    325:
                    326:     /* Figure intelligence */
                    327:
                    328:     min_intel = atoi(mp->m_intel);
                    329:
                    330:     if ((ip = (char *) strchr(mp->m_intel, '-')) == NULL)
                    331:         tp->t_stats.s_intel = min_intel;
                    332:     else
                    333:     {
                    334:         max_intel = atoi(++ip);
                    335:
                    336:         if (max_monster)
                    337:             tp->t_stats.s_intel = max_intel;
                    338:         else
                    339:             tp->t_stats.s_intel = min_intel + rnd(max_intel - min_intel);
                    340:     }
                    341:
                    342:     tp->t_stats.s_power = (rnd(tp->t_stats.s_lvl / 5) + 1) * tp->t_stats.s_intel;
                    343:
                    344:     tp->maxstats = tp->t_stats; /* structure assignment */
                    345:
                    346:     /* If the monster can shoot, it may have a weapon */
                    347:
                    348:     if (on(*tp, CANSHOOT) && (max_monster || rnd(9) < 6))
                    349:     {
                    350:         struct linked_list  *thrower_item, *missile_item;
                    351:         struct object *thrower, *a_missile;
                    352:
                    353:         thrower_item = new_item(sizeof *thrower);
                    354:         thrower = OBJPTR(thrower_item);
                    355:         carried_weapon(tp, thrower);
                    356:
                    357:         missile_item = new_item(sizeof *a_missile);
                    358:         a_missile = OBJPTR(missile_item);
                    359:         carried_weapon(tp, a_missile);
                    360:
                    361:         /* The monster may use a crossbow, sling, footbow, or an arrow */
                    362:         /* Take racial preferences into account */
                    363:
                    364:         if ((strcmp(mp->m_name, "elf") == 0) ||
                    365:             (strcmp(mp->m_name, "noldor elf") == 0))
                    366:         {
                    367:             thrower->o_which = BOW;
                    368:
                    369:             if (rnd(5) == 0)
                    370:                 a_missile->o_which = SILVERARROW;
                    371:             else
                    372:                 a_missile->o_which = ARROW;
                    373:         }
                    374:         else if ((strcmp(mp->m_name, "dwarf") == 0) ||
                    375:                 (strcmp(mp->m_name, "kazad dwarf") == 0))
                    376:         {
                    377:             thrower->o_which = CROSSBOW;
                    378:             a_missile->o_which = BOLT;
                    379:         }
                    380:         else if (on(*tp, ISSMALL))
                    381:         {
                    382:             switch (rnd(3))
                    383:             {
                    384:                 case 0:
                    385:                     thrower->o_which = SLING;
                    386:                     a_missile->o_which = BULLET;
                    387:                     break;
                    388:                 default:
                    389:                     thrower->o_which = SLING;
                    390:                     a_missile->o_which = ROCK;
                    391:             }
                    392:         }
                    393:         else if (on(*tp, ISLARGE))
                    394:         {
                    395:             switch (rnd(4))
                    396:             {
                    397:                 case 0:
                    398:                     thrower->o_which = CROSSBOW;
                    399:                     a_missile->o_which = BOLT;
                    400:                     break;
                    401:
                    402:                 case 1:
                    403:                     thrower->o_which = FOOTBOW;
                    404:                     a_missile->o_which = FBBOLT;
                    405:                     break;
                    406:
                    407:                 default:
                    408:                     thrower->o_which = BOW;
                    409:
                    410:                     if (rnd(5) == 0)
                    411:                         a_missile->o_which = FLAMEARROW;
                    412:                     else
                    413:                         a_missile->o_which = ARROW;
                    414:
                    415:                     break;
                    416:             }
                    417:         }
                    418:         else
                    419:         {
                    420:             switch (rnd(6))
                    421:             {
                    422:                 case 1:
                    423:                     thrower->o_which = SLING;
                    424:                     a_missile->o_which = ROCK;
                    425:                     break;
                    426:
                    427:                 case 2:
                    428:                     thrower->o_which = CROSSBOW;
                    429:                     a_missile->o_which = BOLT;
                    430:                     break;
                    431:
                    432:                 case 3:
                    433:                     thrower->o_which = FOOTBOW;
                    434:                     a_missile->o_which = FBBOLT;
                    435:                     break;
                    436:
                    437:                 case 4:
                    438:                     thrower->o_which = BOW;
                    439:                     a_missile->o_which = ARROW;
                    440:                     break;
                    441:
                    442:                 default:
                    443:                     thrower->o_which = SLING;
                    444:                     a_missile->o_which = BULLET;
                    445:                     break;
                    446:             }
                    447:         }
                    448:
                    449:         init_weapon(thrower, thrower->o_which);
                    450:         init_weapon(a_missile, a_missile->o_which);
                    451:
                    452:         attach(tp->t_pack, thrower_item);
                    453:         attach(tp->t_pack, missile_item);
                    454:     }
                    455:
                    456:     /* monsters that wield weapons */
                    457:
                    458:     if (on(*tp, CANWIELD))
                    459:     {
                    460:         if (max_monster || rnd(3))
                    461:         {
                    462:             struct linked_list  *wield_item;
                    463:             struct object   *wielded;
                    464:
                    465:             wield_item = new_item(sizeof *wielded);
                    466:             wielded = OBJPTR(wield_item);
                    467:             carried_weapon(tp, wielded);
                    468:
                    469:             i = rnd(CLAYMORE - CLUB) + rnd(2 * tp->t_stats.s_lvl);
                    470:             i = min(i, CLAYMORE);
                    471:             wielded->o_which = i;
                    472:             init_weapon(wielded, wielded->o_which);
                    473:
                    474:             /* Is it too heavy? */
                    475:
                    476:             if (itemweight(wielded) > 8 * tp->t_stats.s_str)
                    477:                 discard(wield_item);
                    478:             else
                    479:                 attach(tp->t_pack, wield_item);
                    480:         }
                    481:     }
                    482:
                    483:     if (is_wearing(R_AGGR))
                    484:         chase_it(cp, &player);
                    485:     else
                    486:     {
                    487:         turn_off(*tp, ISRUN);
                    488:
                    489:         if (on(*tp, ISFLEE) && (rnd(4) == 0))
                    490:             turn_off(*tp, ISFLEE);
                    491:
                    492:         if (rnd(luck) == 0)
                    493:             switch (player.t_ctype)
                    494:             {
                    495:                 case C_MAGICIAN:
                    496:                 case C_ILLUSION:
                    497:                     eff_intel = 2 * pstats.s_intel;
                    498:                     break;
                    499:                 case C_DRUID:
                    500:                     eff_intel = 2 * pstats.s_intel;
                    501:                 case C_RANGER:
                    502:                     eff_charisma = 2 * pstats.s_charisma;
                    503:                     break;
                    504:                 case C_ASSASIN:
                    505:                 case C_THIEF:
                    506:                 case C_NINJA:
                    507:                     eff_charisma = pstats.s_charisma / 2;
                    508:                     break;
                    509:             }
                    510:
                    511:         /* LOWFRIENDLY monsters might be friendly */
                    512:
                    513:         i = roll(1,100);
                    514:
                    515:         if (i == 0 || (on(*tp, LOWFRIENDLY) && i < eff_charisma) ||
                    516:             (on(*tp, MEDFRIENDLY) && i < 3 * eff_charisma) ||
                    517:             (on(*tp, HIGHFRIENDLY) && i < 5 * eff_charisma))
                    518:         {
                    519:             turn_on(*tp, ISFRIENDLY);
                    520:             turn_off(*tp, ISMEAN);
                    521:         }
                    522:
                    523:         i = roll(1,100);
                    524:
                    525:         if (i == 0 || (on(*tp, LOWCAST) && i < eff_intel) ||
                    526:             (on(*tp, MEDCAST) && i < 3 * eff_intel) ||
                    527:             (on(*tp, HIGHCAST) && i < 5 * eff_intel))
                    528:         {
                    529:             turn_on(*tp, CANCAST);
                    530:         }
                    531:
                    532:         if (on(*tp, ISDISGUISE))
                    533:         {
                    534:             char    mch = 0;
                    535:
                    536:             if (tp->t_pack != NULL)
                    537:                 mch = (OBJPTR(tp->t_pack))->o_type;
                    538:             else
                    539:                 switch (rnd(level > arts[0].ar_level ? 10 : 9))
                    540:                 {
                    541:                     case 0: mch = GOLD;     break;
                    542:                     case 1: mch = POTION;   break;
                    543:                     case 2: mch = SCROLL;   break;
                    544:                     case 3: mch = FOOD;     break;
                    545:                     case 4: mch = WEAPON;   break;
                    546:                     case 5: mch = ARMOR;    break;
                    547:                     case 6: mch = RING;     break;
                    548:                     case 7: mch = STICK;    break;
                    549:                     case 8: mch = monsters[randmonster(NOWANDER, NOGRAB)].m_appear;
                    550:                                 break;
                    551:                     case 9: mch = ARTIFACT; break;
                    552:                 }
                    553:
                    554:             tp->t_disguise = mch;
                    555:         }
                    556:     }
                    557: }
                    558:
                    559: /*
                    560:     wanderer()
                    561:         A wandering monster has awakened and is headed for the player
                    562: */
                    563:
                    564: void
                    565: wanderer(void)
                    566: {
                    567:     int i, cnt = 0;
                    568:     struct room *hr = roomin(hero);
                    569:     struct linked_list  *item;
                    570:     struct thing    *tp;
                    571:     coord   cp;
                    572:     char    *loc;
                    573:     int which;
                    574:
                    575:     /* Find a place for it -- avoid the player's room */
                    576:
                    577:     do
                    578:     {
                    579:         do
                    580:         {
                    581:             cnt++;
                    582:             i = rnd_room();
                    583:         }
                    584:         while (!(hr != &rooms[i] || levtype == MAZELEV
                    585:                || levtype == THRONE || cnt > 5000));
                    586:
                    587:         rnd_pos(&rooms[i], &cp);
                    588:     }
                    589:     while(!step_ok(cp.y, cp.x, NOMONST, NULL));
                    590:
                    591:     /* Create a new wandering monster */
                    592:
                    593:     item = new_item(sizeof *tp);
                    594:     which = randmonster(TRUE, FALSE);
                    595:     new_monster(item, which, &cp, FALSE);
                    596:
                    597:     tp = THINGPTR(item);
                    598:     tp->t_pos = cp;     /* Assign the position to the monster */
                    599:
                    600:     chase_it(&tp->t_pos, &player);
                    601:
                    602:     i = rnd(7);
                    603:
                    604:     if (on(*tp, ISSWARM) && i < 5)
                    605:         cnt = roll(2, 4);
                    606:     else if (on(*tp, ISFLOCK) && i < 5)
                    607:         cnt = roll(1, 4);
                    608:     else
                    609:         cnt = 0;
                    610:
                    611:     for (i = 1; i <= cnt; i++)
                    612:     {
                    613:         struct linked_list  *ip = creat_mons(tp, which, NOMESSAGE);
                    614:
                    615:         if (ip != NULL)
                    616:         {
                    617:             struct thing    *mp = THINGPTR(ip);
                    618:
                    619:             if (on(*tp, ISFRIENDLY))
                    620:                 turn_on(*mp, ISFRIENDLY);
                    621:             else
                    622:                 turn_off(*mp, ISFRIENDLY);
                    623:         }
                    624:     }
                    625:
                    626:     if (cnt > 0)
                    627:     {
                    628:         if (on(*tp, LOWCAST) || on(*tp, MEDCAST) || on(*tp, HIGHCAST))
                    629:             turn_on(*tp, CANCAST);
                    630:
                    631:         tp->t_stats.s_hpt += roll(2, 8);
                    632:         tp->t_stats.s_lvl += roll(2, 3);
                    633:         tp->t_stats.s_arm -= roll(1, 6);
                    634:         tp->t_stats.s_str += roll(2, 3);
                    635:         tp->t_stats.s_intel += roll(2, 3);
                    636:         tp->t_stats.s_exp += roll(2, 8) * monsters[which].m_add_exp;
                    637:     }
                    638:
                    639:     i = DISTANCE(cp, hero);
                    640:
                    641:     if (i < 20)
                    642:         loc = "very close to you";
                    643:     else if (i < 400)
                    644:         loc = "nearby";
                    645:     else
                    646:         loc = "in the distance";
                    647:
                    648:     if (wizard)
                    649:         msg("Started a wandering %s.", monsters[tp->t_index].m_name);
                    650:     else if (on(*tp, ISUNDEAD) && (player.t_ctype == C_CLERIC ||
                    651:             player.t_ctype == C_PALADIN || is_wearing(R_PIETY)))
                    652:         msg("You sense a new ungodly monster %s.", loc);
                    653:     else if (on(player, CANHEAR) || (player.t_ctype == C_THIEF &&
                    654:             rnd(20) == 0))
                    655:         msg("You hear a new %s moving %s.",
                    656:             monsters[tp->t_index].m_name, loc);
                    657:     else if (on(player, CANSCENT) || (player.t_ctype == C_THIEF &&
                    658:             rnd(20) == 0))
                    659:         msg("You smell a new %s %s.", monsters[tp->t_index].m_name,
                    660:             loc);
                    661: }
                    662:
                    663: /*
                    664:     wake_monster
                    665:
                    666:         what to do when the hero steps next to a monster
                    667: */
                    668:
                    669: struct linked_list *
                    670: wake_monster(int y, int x)
                    671: {
                    672:     struct thing    *tp;
                    673:     struct linked_list  *it;
                    674:     struct room *trp;
                    675:     char    *mname;
                    676:
                    677:     if ((it = find_mons(y, x)) == NULL)
                    678:     {
                    679:         debug("Can't find monster in show.");
                    680:         return(NULL);
                    681:     }
                    682:
                    683:     tp = THINGPTR(it);
                    684:
                    685:     if ((good_monster(*tp)) || on(player, SUMMONING))
                    686:     {
                    687:         chase_it(&tp->t_pos, &player);
                    688:         turn_off(*tp, ISINVIS);
                    689:         turn_off(*tp, CANSURPRISE);
                    690:         return(it);
                    691:     }
                    692:
                    693:     trp = roomin(tp->t_pos);   /* Current room for monster */
                    694:     mname = monsters[tp->t_index].m_name;
                    695:
                    696:     /* Let greedy ones guard gold */
                    697:
                    698:     if (on(*tp, ISGREED) && off(*tp, ISRUN))
                    699:         if ((trp != NULL) && (lvl_obj != NULL))
                    700:         {
                    701:             struct linked_list  *item;
                    702:             struct object   *cur;
                    703:
                    704:             for (item = lvl_obj; item != NULL; item = next(item))
                    705:             {
                    706:                 cur = OBJPTR(item);
                    707:
                    708:                 if ((cur->o_type == GOLD) &&
                    709:                     (roomin(cur->o_pos) == trp))
                    710:                 {
                    711:                     /* Run to the gold */
                    712:                     tp->t_horde = cur;
                    713:                     turn_on(*tp, ISRUN);
                    714:                     turn_off(*tp, ISDISGUISE);
                    715:                     tp->t_ischasing = FALSE;
                    716:                     /* Make it worth protecting */
                    717:                     cur->o_count += roll(2, 3) * GOLDCALC;
                    718:                     break;
                    719:                 }
                    720:             }
                    721:         }
                    722:
                    723:     /*
                    724:      * Every time he sees mean monster, it might start chasing him unique
                    725:      * monsters always do
                    726:      */
                    727:
                    728:     if (  (on(*tp, ISUNIQUE)) ||
                    729:           ( (rnd(100) > 33) &&
                    730:             on(*tp, ISMEAN) &&
                    731:             off(*tp, ISHELD) &&
                    732:             off(*tp, ISRUN) &&
                    733:             !is_stealth(&player) &&
                    734:             (off(player, ISINVIS) || on(*tp, CANSEE))
                    735:           )
                    736:        )
                    737:     {
                    738:         chase_it(&tp->t_pos, &player);
                    739:     }
                    740:
                    741:     /* Handle gaze attacks */
                    742:
                    743:     if (on(*tp, ISRUN) && cansee(tp->t_pos.y, tp->t_pos.x) &&
                    744:             off(player, ISINVIS))
                    745:     {
                    746:         if (on(*tp, CANHUH))    /* Confusion */
                    747:         {
                    748:             if (on(player, CANREFLECT))
                    749:             {
                    750:                 msg("You reflect the bewildering stare of the %s.", mname);
                    751:
                    752:                 if (save_throw(VS_MAGIC, tp))
                    753:                 {
                    754:                     msg("The %s is confused!", mname);
                    755:                     turn_on(*tp, ISHUH);
                    756:                 }
                    757:                 else
                    758:                     msg("The %s staggers for a moment.", mname);
                    759:             }
                    760:             else if (save(VS_MAGIC))
                    761:             {
                    762:                 msg("You feel dizzy for a moment, but it quickly passes.");
                    763:
                    764:                 if (rnd(100) < 67)
                    765:                     turn_off(*tp, CANHUH);
                    766:             }
                    767:             else if (off(player, ISCLEAR))
                    768:             {
                    769:                 if (off(player, ISHUH))
                    770:                 {
                    771:                     light_fuse(FUSE_UNCONFUSE, 0, rnd(20) + HUHDURATION, AFTER);
                    772:                     msg("The %s's gaze has confused you.", mname);
                    773:                     turn_on(player, ISHUH);
                    774:                 }
                    775:                 else
                    776:                     lengthen_fuse(FUSE_UNCONFUSE, rnd(20) + HUHDURATION);
                    777:             }
                    778:         }
                    779:
                    780:         if (on(*tp, CANSNORE))      /* Sleep */
                    781:         {
                    782:             if (on(player, CANREFLECT))
                    783:             {
                    784:                 msg("You reflect the lethargic glance of the %s", mname);
                    785:
                    786:                 if (save_throw(VS_PARALYZATION, tp))
                    787:                 {
                    788:                     msg("The %s falls asleep!", mname);
                    789:                     tp->t_no_move += SLEEPTIME;
                    790:                 }
                    791:             }
                    792:             else if (no_command == 0 && !save(VS_PARALYZATION))
                    793:             {
                    794:                 if (is_wearing(R_ALERT))
                    795:                     msg("You feel slightly drowsy for a moment.");
                    796:                 else
                    797:                 {
                    798:                     msg("The %s's gaze puts you to sleep.", mname);
                    799:                     no_command = SLEEPTIME;
                    800:
                    801:                     if (rnd(100) < 50)
                    802:                         turn_off(*tp, CANSNORE);
                    803:                 }
                    804:             }
                    805:         }
                    806:
                    807:         if (on(*tp, CANFRIGHTEN))   /* Fear */
                    808:         {
                    809:             turn_off(*tp, CANFRIGHTEN);
                    810:
                    811:             if (on(player, CANREFLECT))
                    812:             {
                    813:                 msg("The %s sees its reflection. ", mname);
                    814:
                    815:                 if (save_throw(VS_MAGIC,tp))
                    816:                 {
                    817:                     msg("The %s is terrified by its reflection!", mname);
                    818:                     turn_on(*tp, ISFLEE);
                    819:                 }
                    820:             }
                    821:             else
                    822:             {
                    823:                 if (!save(VS_WAND) && !(on(player, ISFLEE) &&
                    824:                        (player.t_chasee==tp)))
                    825:                 {
                    826:                     if ((player.t_ctype != C_PALADIN) &&
                    827:                         off(player, SUPERHERO))
                    828:                     {
                    829:                         turn_on(player, ISFLEE);
                    830:                         player.t_ischasing = FALSE;
                    831:                         player.t_chasee    = tp;
                    832:                         msg("The sight of the %s terrifies you.", mname);
                    833:                     }
                    834:                     else
                    835:                         msg("My, the %s looks ugly.", mname);
                    836:                 }
                    837:             }
                    838:         }
                    839:
                    840:         if (on(*tp, LOOKSLOW))     /* Slow */
                    841:         {
                    842:             turn_off(*tp, LOOKSLOW);
                    843:
                    844:             if (on(player, CANREFLECT))
                    845:             {
                    846:                 msg("You reflect the mournful glare of the %s.", mname);
                    847:
                    848:                 if (save_throw(VS_MAGIC,tp))
                    849:                 {
                    850:                     msg("The %s is slowing down!", mname);
                    851:                     turn_on(*tp, ISSLOW);
                    852:                 }
                    853:             }
                    854:             else if (is_wearing(R_FREEDOM) || save(VS_MAGIC))
                    855:                 msg("You feel run-down for a moment.");
                    856:             else
                    857:             {
                    858:                 if (on(player, ISHASTE))    /* Already sped up */
                    859:                 {
                    860:                     extinguish_fuse(FUSE_NOHASTE);
                    861:                     nohaste(NULL);
                    862:                 }
                    863:                 else
                    864:                 {
                    865:                     msg("You feel yourself moving %sslower.",
                    866:                      on(player, ISSLOW) ? "even " : "");
                    867:
                    868:                     if (on(player, ISSLOW))
                    869:                         lengthen_fuse(FUSE_NOSLOW, rnd(4) + 4);
                    870:                     else
                    871:                     {
                    872:                         turn_on(player, ISSLOW);
                    873:                         player.t_turn = TRUE;
                    874:                         light_fuse(FUSE_NOSLOW, 0, rnd(4) + 4, AFTER);
                    875:                     }
                    876:                 }
                    877:             }
                    878:         }
                    879:
                    880:         if (on(*tp, CANBLIND))  /* Blinding */
                    881:         {
                    882:             turn_off(*tp, CANBLIND);
                    883:
                    884:             if (on(player, CANREFLECT))
                    885:             {
                    886:                 msg("You reflect the blinding stare of the %s.", mname);
                    887:
                    888:                 if (save_throw(VS_WAND, tp))
                    889:                 {
                    890:                     msg("The %s is blinded!", mname);
                    891:                     turn_on(*tp, ISHUH);
                    892:                 }
                    893:             }
                    894:             else if (off(player, ISBLIND))
                    895:                 if (save(VS_WAND) || is_wearing(R_TRUESEE) || is_wearing(R_SEEINVIS))
                    896:                     msg("Your eyes film over for a moment.");
                    897:                 else
                    898:                 {
                    899:                     msg("The gaze of the %s blinds you.", mname);
                    900:                     turn_on(player, ISBLIND);
                    901:                     light_fuse(FUSE_SIGHT, 0, rnd(30) + 20, AFTER);
                    902:                     look(FALSE);
                    903:                 }
                    904:         }
                    905:
                    906:         if (on(*tp, LOOKSTONE))  /* Stoning */
                    907:         {
                    908:             turn_off(*tp, LOOKSTONE);
                    909:
                    910:             if (on(player, CANREFLECT))
                    911:             {
                    912:                 msg("You reflect the flinty look of the %s.", mname);
                    913:
                    914:                 if (save_throw(VS_PETRIFICATION,tp))
                    915:                 {
                    916:                     msg("The %s suddenly stiffens", mname);
                    917:                     tp->t_no_move += STONETIME;
                    918:                 }
                    919:                 else
                    920:                 {
                    921:                     msg("The %s is turned to stone!", mname);
                    922:                     killed(&player, it, NOMESSAGE, POINTS);
                    923:                 }
                    924:             }
                    925:             else
                    926:             {
                    927:                 if (on(player, CANINWALL))
                    928:                     msg("The %s cannot focus on you.", mname);
                    929:                 else
                    930:                 {
                    931:                     msg("The gaze of the %s stiffens your limbs.", mname);
                    932:
                    933:                     if (save(VS_PETRIFICATION))
                    934:                         no_command = STONETIME;
                    935:                     else if (rnd(100))
                    936:                         no_command = STONETIME * 3;
                    937:                     else
                    938:                     {
                    939:                         msg("The gaze of the %s petrifies you.", mname);
                    940:                         msg("You are turned to stone!!! --More--");
                    941:                         wait_for(' ');
                    942:                         death(D_PETRIFY);
                    943:                         return(it);
                    944:                     }
                    945:                 }
                    946:             }
                    947:         }
                    948:     }
                    949:
                    950:     /*
                    951:      * True Sight sees all Never see ISINWALL or CANSURPRISE See ISSHADOW
                    952:      * 80% See ISINVIS with See Invisibilty
                    953:      */
                    954:
                    955:     if (off(player, CANTRUESEE) &&
                    956:         on(*tp, ISINWALL) || on(*tp, CANSURPRISE) ||
                    957:         (on(*tp, ISSHADOW) && rnd(100) < 80) ||
                    958:         (on(*tp, ISINVIS) && off(player, CANSEE)))
                    959:        {
                    960:            /*
                    961:            TODO: incomplete - need to finish logic
                    962:            int ch = mvwinch(stdscr, y, x);
                    963:            */
                    964:        }
                    965:
                    966:
                    967:     /* hero might be able to hear or smell monster if he can't see it */
                    968:
                    969:     if ((rnd(player.t_ctype == C_THIEF ? 40 : 200) == 0 ||
                    970:             on(player, CANHEAR)) && !cansee(tp->t_pos.y, tp->t_pos.x))
                    971:         msg("You hear a %s nearby.", mname);
                    972:     else if ((rnd(player.t_ctype == C_THIEF ? 40 : 200) == 0 ||
                    973:             on(player, CANSCENT)) && !cansee(tp->t_pos.y, tp->t_pos.x))
                    974:         msg("You smell a %s nearby.", mname);
                    975:
                    976:     return(it);
                    977: }
                    978:
                    979: /*
                    980:     genocide()
                    981:         wipe out hated monsters flags:    ISBLESSED, ISCURSED
                    982: */
                    983:
                    984: void
                    985: genocide(int flags)
                    986: {
                    987:     struct linked_list  *ip;
                    988:     struct thing    *mp;
                    989:     struct linked_list  *nip;
                    990:     int    which_monst;
                    991:     int    blessed = flags & ISBLESSED;
                    992:     int    cursed = flags & ISCURSED;
                    993:
                    994:     while ((which_monst = get_monster_number("genocide")) == 0)
                    995:         ;
                    996:
                    997:     if (cursed)    /* oops... */
                    998:     {
                    999:         new_level(THRONE, which_monst);
                   1000:         msg("What's this I hear about you trying to wipe me out?");
                   1001:         fighting = running = after = FALSE;
                   1002:         return;
                   1003:     }
                   1004:
                   1005:     /* Remove this monster from the present level */
                   1006:
                   1007:     for (ip = mlist; ip; ip = nip)
                   1008:     {
                   1009:         mp = THINGPTR(ip);
                   1010:         nip = next(ip);
                   1011:
                   1012:         if (mp->t_index == which_monst)
                   1013:         {
                   1014:             check_residue(mp);  /* Check for special features before removing */
                   1015:             remove_monster(&mp->t_pos, ip);
                   1016:         }
                   1017:     }
                   1018:
                   1019:     /* Remove from available monsters */
                   1020:
                   1021:     monsters[which_monst].m_normal = FALSE;
                   1022:     monsters[which_monst].m_wander = FALSE;
                   1023:     mpos = 0;
                   1024:     msg("You have wiped out the %s.", monsters[which_monst].m_name);
                   1025:
                   1026:     if (blessed)
                   1027:         genocide(ISNORMAL);
                   1028: }
                   1029:
                   1030:
                   1031: /*
                   1032:     id_monst()
                   1033:         lists the monsters with the displayed by the character unless
                   1034:         there is only one in which case it is returned as the string
                   1035: */
                   1036:
                   1037: void
                   1038: id_monst(int monster)
                   1039: {
                   1040:     int i;
                   1041:
                   1042:     for (i = 1; i <= nummonst + 2; i++)
                   1043:         if (monsters[i].m_appear == monster)
                   1044:             add_line("A %s ", monsters[i].m_name);
                   1045:
                   1046:     end_line();
                   1047: }
                   1048:
                   1049:
                   1050: /*
                   1051:     check_residue()
                   1052:         takes care of any effect of the monster
                   1053: */
                   1054:
                   1055: void
                   1056: check_residue(struct thing *tp)
                   1057: {
                   1058:     /* Take care of special abilities */
                   1059:
                   1060:     if (on(*tp, DIDHOLD) && (--hold_count == 0))
                   1061:         turn_off(player, ISHELD);
                   1062:
                   1063:     /* If it has lowered player, give him back a level, maybe */
                   1064:
                   1065:     if (on(*tp, DIDDRAIN) && rnd(3) == 0)
                   1066:         raise_level();
                   1067:
                   1068:     /* If frightened of this monster, stop */
                   1069:
                   1070:     if (on(player, ISFLEE) && (player.t_chasee==tp))
                   1071:         turn_off(player, ISFLEE);
                   1072:
                   1073:     /* If monster was suffocating player, stop it */
                   1074:     if (on(*tp, DIDSUFFOCATE))
                   1075:         extinguish_fuse(FUSE_SUFFOCATE);
                   1076:
                   1077:     /* If something with fire, may darken */
                   1078:     if (on(*tp, HASFIRE))
                   1079:     {
                   1080:         struct room *rp = roomin(tp->t_pos);
                   1081:
                   1082:         if (rp && (--(rp->r_fires) <= 0))
                   1083:         {
                   1084:             rp->r_flags &= ~HASFIRE;
                   1085:             light(&tp->t_pos);
                   1086:         }
                   1087:     }
                   1088: }
                   1089:
                   1090: /*
                   1091:     sell()
                   1092:         displays a menu of goods from which the player may choose to
                   1093:         purchase something.
                   1094: */
                   1095:
                   1096: #define SELL_ITEMS 10       /* How many things 'q' might carry */
                   1097:
                   1098: void
                   1099: sell(struct thing *tp)
                   1100: {
                   1101:     struct linked_list  *item;
                   1102:     int i, j, min_worth, nitems, chance, which_item, w;
                   1103:     char goods;
                   1104:     struct object   *obj;
                   1105:     char    buffer[2 * LINELEN];
                   1106:     char    dbuf[2 * LINELEN];
                   1107:
                   1108:     struct
                   1109:     {
                   1110:         int which;
                   1111:         int plus1, plus2;
                   1112:         int count;
                   1113:         int worth;
                   1114:         int flags;
                   1115:         char    *name;
                   1116:     }
                   1117:     selection[SELL_ITEMS];
                   1118:
                   1119:     int effective_purse = ((player.t_ctype == C_PALADIN) ?
                   1120:                    (9 * purse / 10) : purse);
                   1121:
                   1122:     min_worth = -1;     /* hope item is never worth less than this */
                   1123:     item = find_mons(tp->t_pos.y, tp->t_pos.x); /* Get pointer to monster */
                   1124:
                   1125:     /* Select the items */
                   1126:
                   1127:     nitems = rnd(6) + 5;
                   1128:
                   1129:     switch (rnd(6))
                   1130:     {
                   1131:         /* Armor */
                   1132:         case 0:
                   1133:         case 1:
                   1134:             goods = ARMOR;
                   1135:             for (i = 0; i < nitems; i++)
                   1136:             {
                   1137:                 chance = rnd(100);
                   1138:
                   1139:                 for (j = 0; j < maxarmors; j++)
                   1140:                     if (chance < armors[j].a_prob)
                   1141:                         break;
                   1142:
                   1143:                 if (j == maxarmors)
                   1144:                 {
                   1145:                     debug("Picked a bad armor %d", chance);
                   1146:                     j = 0;
                   1147:                 }
                   1148:
                   1149:                 selection[i].which = j;
                   1150:                 selection[i].count = 1;
                   1151:
                   1152:                 if (rnd(100) < 40)
                   1153:                     selection[i].plus1 = rnd(5) + 1;
                   1154:                 else
                   1155:                     selection[i].plus1 = 0;
                   1156:
                   1157:                 selection[i].name = armors[j].a_name;
                   1158:
                   1159:                 switch (luck)
                   1160:                 {
                   1161:                     case 0: break;
                   1162:                     case 1:
                   1163:                         if (rnd(3) == 0)
                   1164:                         {
                   1165:                             selection[i].flags |=  ISCURSED;
                   1166:                             selection[i].plus1 =  -1 - rnd(5);
                   1167:                         }
                   1168:                         break;
                   1169:
                   1170:                     default:
                   1171:                         if (rnd(luck))
                   1172:                         {
                   1173:                             selection[i].flags |= ISCURSED;
                   1174:                             selection[i].plus1 =  -1 - rnd(5);
                   1175:                         }
                   1176:                         break;
                   1177:                 }
                   1178:
                   1179:                 /* Calculate price */
                   1180:
                   1181:                 w = armors[j].a_worth;
                   1182:                 w *= (1 + luck + (10 * selection[i].plus1));
                   1183:                 w = (w / 2) + (roll(6, w) / 6);
                   1184:                 selection[i].worth = max(w, 25);
                   1185:
                   1186:                 if (min_worth > selection[i].worth || i == 1)
                   1187:                     min_worth = selection[i].worth;
                   1188:             }
                   1189:             break;
                   1190:
                   1191:             /* Weapon */
                   1192:         case 2:
                   1193:         case 3:
                   1194:             goods = WEAPON;
                   1195:             for (i = 0; i < nitems; i++)
                   1196:             {
                   1197:                 selection[i].which = rnd(maxweapons);
                   1198:                 selection[i].count = 1;
                   1199:
                   1200:                 if (rnd(100) < 35)
                   1201:                 {
                   1202:                     selection[i].plus1 = rnd(3);
                   1203:                     selection[i].plus2 = rnd(3);
                   1204:                 }
                   1205:                 else
                   1206:                 {
                   1207:                     selection[i].plus1 = 0;
                   1208:                     selection[i].plus2 = 0;
                   1209:                 }
                   1210:
                   1211:                 if (weaps[selection[i].which].w_flags & ISMANY)
                   1212:                     selection[i].count = rnd(15) + 8;
                   1213:
                   1214:                 selection[i].name = weaps[selection[i].which].w_name;
                   1215:
                   1216:                 switch (luck)
                   1217:                 {
                   1218:                     case 0: break;
                   1219:                     case 1:
                   1220:                         if (rnd(3) == 0)
                   1221:                         {
                   1222:                             selection[i].flags |= ISCURSED;
                   1223:                             selection[i].plus1 =  -rnd(3);
                   1224:                             selection[i].plus2 =  -rnd(3);
                   1225:                         }
                   1226:                         break;
                   1227:
                   1228:                     default:
                   1229:                         if (rnd(luck))
                   1230:                         {
                   1231:                             selection[i].flags |= ISCURSED;
                   1232:                             selection[i].plus1 =  -rnd(3);
                   1233:                             selection[i].plus2 =  -rnd(3);
                   1234:                         }
                   1235:                         break;
                   1236:                 }
                   1237:
                   1238:                 w = weaps[selection[i].which].w_worth * selection[i].count;
                   1239:                 w *= (1 + luck + (10 * selection[i].plus1 +
                   1240:                           10 * selection[i].plus2));
                   1241:                 w = (w / 2) + (roll(6, w) / 6);
                   1242:                 selection[i].worth = max(w, 25);
                   1243:
                   1244:                 if (min_worth > selection[i].worth || i == 1)
                   1245:                     min_worth = selection[i].worth;
                   1246:             }
                   1247:             break;
                   1248:
                   1249:             /* Staff or wand */
                   1250:         case 4:
                   1251:             goods = STICK;
                   1252:
                   1253:             for (i = 0; i < nitems; i++)
                   1254:             {
                   1255:                 selection[i].which = pick_one(ws_magic, maxsticks);
                   1256:                 selection[i].plus1 = rnd(11) + 5;
                   1257:                 selection[i].count = 1;
                   1258:                 selection[i].name = ws_magic[selection[i].which].mi_name;
                   1259:
                   1260:                 switch (luck)
                   1261:                 {
                   1262:                     case 0: break;
                   1263:                     case 1:
                   1264:                         if (rnd(3) == 0)
                   1265:                         {
                   1266:                             selection[i].flags |= ISCURSED;
                   1267:                             selection[i].plus1 = 1;
                   1268:                         }
                   1269:                         break;
                   1270:
                   1271:                     default:
                   1272:                         if (rnd(luck))
                   1273:                         {
                   1274:                             selection[i].flags |= ISCURSED;
                   1275:                             selection[i].plus1 = 1;
                   1276:                         }
                   1277:                 }
                   1278:
                   1279:                 w = ws_magic[selection[i].which].mi_worth;
                   1280:                 w += (luck + 1) * 20 * selection[i].plus1;
                   1281:                 w = (w / 2) + (roll(6, w) / 6);
                   1282:                 selection[i].worth = max(w, 25);
                   1283:
                   1284:                 if (min_worth > selection[i].worth || i == 1)
                   1285:                     min_worth = selection[i].worth;
                   1286:             }
                   1287:             break;
                   1288:
                   1289:             /* Ring */
                   1290:
                   1291:         case 5:
                   1292:             goods = RING;
                   1293:             for (i = 0; i < nitems; i++)
                   1294:             {
                   1295:                 selection[i].which = pick_one(r_magic, maxrings);
                   1296:                 selection[i].plus1 = rnd(2) + 1;
                   1297:                 selection[i].count = 1;
                   1298:
                   1299:                 if (rnd(100) < r_magic[selection[i].which].mi_bless + 10)
                   1300:                     selection[i].plus1 += rnd(2) + 1;
                   1301:
                   1302:                 selection[i].name = r_magic[selection[i].which].mi_name;
                   1303:
                   1304:                 switch (luck)
                   1305:                 {
                   1306:                     case 0: break;
                   1307:                     case 1:
                   1308:                         if (rnd(3) == 0)
                   1309:                         {
                   1310:                             selection[i].flags |= ISCURSED;
                   1311:                             selection[i].plus1 =  -1 - rnd(2);
                   1312:                         }
                   1313:                         break;
                   1314:
                   1315:                     default:
                   1316:                         if (rnd(luck))
                   1317:                         {
                   1318:                             selection[i].flags |= ISCURSED;
                   1319:                             selection[i].plus1 =  -1 - rnd(2);
                   1320:                         }
                   1321:                 }
                   1322:
                   1323:                 w = r_magic[selection[i].which].mi_worth;
                   1324:
                   1325:                 switch(selection[i].which)
                   1326:                 {
                   1327:                     case R_DIGEST:
                   1328:                         if (selection[i].plus1 > 2)
                   1329:                             selection[i].plus1 = 2;
                   1330:                         else if (selection[i].plus1 < 1)
                   1331:                             selection[i].plus1 = 1;
                   1332:                     /* fall thru here to other cases */
                   1333:                     case R_ADDSTR:
                   1334:                     case R_ADDDAM:
                   1335:                     case R_PROTECT:
                   1336:                     case R_ADDHIT:
                   1337:                     case R_ADDINTEL:
                   1338:                     case R_ADDWISDOM:
                   1339:                         if (selection[i].plus1 > 0)
                   1340:                             w += selection[i].plus1 * 50;
                   1341:                 }
                   1342:
                   1343:                 w *= (1 + luck);
                   1344:                 w = (w / 2) + (roll(6, w) / 6);
                   1345:                 selection[i].worth = max(w, 25);
                   1346:
                   1347:                 if (min_worth > selection[i].worth * selection[i].count)
                   1348:                     min_worth = selection[i].worth;
                   1349:             }
                   1350:     }
                   1351:
                   1352:     /* See if player can afford an item */
                   1353:
                   1354:     if (min_worth > effective_purse)
                   1355:     {
                   1356:         msg("The %s eyes your small purse and departs.",
                   1357:             monsters[nummonst].m_name);
                   1358:
                   1359:         /* Get rid of the monster */
                   1360:
                   1361:         killed(NULL, item, NOMESSAGE, NOPOINTS);
                   1362:
                   1363:         return;
                   1364:     }
                   1365:
                   1366:     /* Display the goods */
                   1367:
                   1368:     msg("The %s shows you his wares.", monsters[nummonst].m_name);
                   1369:     wstandout(cw);
                   1370:     mvwaddstr(cw, 0, mpos, morestr);
                   1371:     wstandend(cw);
                   1372:     wrefresh(cw);
                   1373:     wait_for(' ');
                   1374:     msg("");
                   1375:     clearok(cw, TRUE);
                   1376:     touchwin(cw);
                   1377:
                   1378:     wclear(hw);
                   1379:     touchwin(hw);
                   1380:
                   1381:     for (i = 0; i < nitems; i++)
                   1382:     {
                   1383:         if (selection[i].worth > effective_purse)
                   1384:             continue;
                   1385:
                   1386:         wmove(hw, i + 2, 0);
                   1387:         sprintf(dbuf, "[%c] ", ('a' + i));
                   1388:
                   1389:         switch(goods)
                   1390:         {
                   1391:             case ARMOR:
                   1392:                 strcat(dbuf, "Some ");
                   1393:                 break;
                   1394:             case WEAPON:
                   1395:                 if (selection[i].count == 1)
                   1396:                     strcat(dbuf, "A ");
                   1397:                 else
                   1398:                 {
                   1399:                     sprintf(buffer, "%2d ", selection[i].count);
                   1400:                     strcat(dbuf, buffer);
                   1401:                 }
                   1402:                 break;
                   1403:
                   1404:             case STICK:
                   1405:                 strcat(dbuf, "A ");
                   1406:                 strcat(dbuf, ws_type[selection[i].which]);
                   1407:                 strcat(dbuf, " of ");
                   1408:                 break;
                   1409:
                   1410:             case RING:
                   1411:                 strcat(dbuf, "A ring of ");
                   1412:                 break;
                   1413:         }
                   1414:
                   1415:         strcat(dbuf, selection[i].name);
                   1416:
                   1417:         if (selection[i].count > 1)
                   1418:             strcat(dbuf, "s");
                   1419:
                   1420:         sprintf(buffer, "%-50.80s Price:  %d", dbuf, selection[i].worth);
                   1421:         waddstr(hw, buffer);
                   1422:     }
                   1423:
                   1424:     sprintf(buffer, "Purse:  %ld", purse);
                   1425:     mvwaddstr(hw, nitems + 3, 0, buffer);
                   1426:     mvwaddstr(hw, 0, 0, "How about one of the following goods? ");
                   1427:     wrefresh(hw);
                   1428:
                   1429:     /* Get rid of the monster */
                   1430:
                   1431:     killed(NULL, item, NOMESSAGE, NOPOINTS);
                   1432:
                   1433:     which_item = (short) ((readchar() & 0177) - 'a');
                   1434:
                   1435:     while (which_item < 0 || which_item >= nitems ||
                   1436:         selection[which_item].worth > effective_purse)
                   1437:     {
                   1438:         if (which_item == (short) ESCAPE - (short) 'a')
                   1439:             return;
                   1440:
                   1441:         mvwaddstr(hw, 0, 0, "Please enter one of the listed items: ");
                   1442:         wrefresh(hw);
                   1443:         which_item = (short) ((readchar() & 0177) - 'a');
                   1444:     }
                   1445:
                   1446:     if (purse > selection[which_item].worth)
                   1447:          purse -= selection[which_item].worth;
                   1448:     else
                   1449:          purse = 0L;
                   1450:
                   1451:     item = spec_item(goods, selection[which_item].which,
                   1452:           selection[which_item].plus1, selection[which_item].plus2);
                   1453:
                   1454:     obj = OBJPTR(item);
                   1455:
                   1456:     if (selection[which_item].count > 1)
                   1457:     {
                   1458:         obj->o_count = selection[which_item].count;
                   1459:         obj->o_group = ++group;
                   1460:     }
                   1461:
                   1462:     /* If a stick or ring, let player know the type */
                   1463:
                   1464:     switch (goods)
                   1465:     {
                   1466:         case STICK: know_items[TYP_STICK][selection[which_item].which] = TRUE;
                   1467:                     break;
                   1468:         case RING:  know_items[TYP_RING][selection[which_item].which] = TRUE;
                   1469:                     break;
                   1470:     }
                   1471:
                   1472:     if (add_pack(item, MESSAGE) == FALSE)
                   1473:     {
                   1474:         obj->o_pos = hero;
                   1475:         fall(&player, item, TRUE, FALSE);
                   1476:     }
                   1477: }
                   1478:
                   1479: void
                   1480: carried_weapon(struct thing *owner, struct object *weapon)
                   1481: {
                   1482:     weapon->o_hplus = (rnd(4) < 3) ? 0 : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
                   1483:     weapon->o_dplus = (rnd(4) < 3) ? 0 : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
                   1484:     weapon->o_hplus += rnd(owner->t_stats.s_lvl / 3 + 1);
                   1485:     weapon->o_hplus += rnd(owner->t_stats.s_lvl / 3 + 1);
                   1486:     weapon->o_damage = weapon->o_hurldmg = "0d0";
                   1487:     weapon->o_ac = 11;
                   1488:     weapon->o_count = 1;
                   1489:     weapon->o_group = 0;
                   1490:
                   1491:     if ((weapon->o_hplus <= 0) && (weapon->o_dplus <= 0))
                   1492:         weapon->o_flags = ISCURSED;
                   1493:
                   1494:     weapon->o_flags = 0;
                   1495:     weapon->o_type = WEAPON;
                   1496:     weapon->o_mark[0] = '\0';
                   1497: }

CVSweb