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

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

1.1       rubenllo    1: /*
                      2:  * monsters.c  -  File with various monster functions in it
                      3:  *
                      4:  * Advanced Rogue
                      5:  * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
                      6:  * All rights reserved.
                      7:  *
                      8:  * Based on "Rogue: Exploring the Dungeons of Doom"
                      9:  * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     10:  * All rights reserved.
                     11:  *
                     12:  * See the file LICENSE.TXT for full copyright and licensing information.
                     13:  */
                     14:
                     15: /*
                     16:  * File with various monster functions in it
                     17:  *
                     18:  */
                     19:
                     20: #include "curses.h"
                     21: #include "rogue.h"
                     22: #include <ctype.h>
                     23: #include <string.h>
                     24: #include <stdlib.h>
                     25:
                     26: 
                     27: /*
                     28:  * Check_residue takes care of any effect of the monster
                     29:  */
                     30: void
                     31: check_residue(struct thing *tp)
                     32: {
                     33:     /*
                     34:      * Take care of special abilities
                     35:      */
                     36:     if (on(*tp, DIDHOLD) && (--hold_count == 0)) {
                     37:        turn_off(player, ISHELD);
                     38:         turn_off(*tp, DIDHOLD);
                     39:     }
                     40:
                     41:     /* If frightened of this monster, stop */
                     42:     if (on(player, ISFLEE) &&
                     43:        player.t_dest == &tp->t_pos) turn_off(player, ISFLEE);
                     44:
                     45:     /* If monster was suffocating player, stop it */
                     46:     if (on(*tp, DIDSUFFOCATE)) {
                     47:        extinguish(suffocate);
                     48:        turn_off(*tp, DIDSUFFOCATE);
                     49:     }
                     50:
                     51:     /* If something with fire, may darken */
                     52:     if (on(*tp, HASFIRE)) {
                     53:        register struct room *rp=roomin(&tp->t_pos);
                     54:        register struct linked_list *fire_item;
                     55:
                     56:        if (rp) {
                     57:            for (fire_item = rp->r_fires; fire_item != NULL;
                     58:                 fire_item = next(fire_item)) {
                     59:                if (THINGPTR(fire_item) == tp) {
                     60:                    detach(rp->r_fires, fire_item);
                     61:                    destroy_item(fire_item);
                     62:                    if (rp->r_fires == NULL) {
                     63:                        rp->r_flags &= ~HASFIRE;
                     64:                        if (cansee(tp->t_pos.y, tp->t_pos.x)) light(&hero);
                     65:                    }
                     66:                    break;
                     67:                }
                     68:            }
                     69:        }
                     70:     }
                     71: }
                     72: 
                     73: /*
                     74:  * Creat_mons creates the specified monster -- any if 0
                     75:  * person: Where to create next to
                     76:  */
                     77:
                     78: bool
                     79: creat_mons(struct thing *person, short monster, bool report)
                     80: {
                     81:     struct linked_list *nitem;
                     82:     register struct thing *tp;
                     83:     struct room *rp;
                     84:     coord *mp;
                     85:
                     86:     if (levtype == POSTLEV)
                     87:        return(FALSE);
                     88:     if ((mp = fallpos(&(person->t_pos), FALSE, 2)) != NULL) {
                     89:        nitem = new_item(sizeof (struct thing));
                     90:        new_monster(nitem,
                     91:                    monster == 0 ? randmonster(FALSE, FALSE)
                     92:                                 : monster,
                     93:                    mp,
                     94:                    TRUE);
                     95:        tp = THINGPTR(nitem);
                     96:        runto(tp, &hero);
                     97:        carry_obj(tp, monsters[tp->t_index].m_carry/2); /* only half chance */
                     98:
                     99:        /* since it just got here, it is disoriented */
                    100:        tp->t_no_move = 2 * movement(tp);
                    101:
                    102:        if (on(*tp, HASFIRE)) {
                    103:            rp = roomin(&tp->t_pos);
                    104:            if (rp) {
                    105:                register struct linked_list *fire_item;
                    106:
                    107:                /* Put the new fellow in the room list */
                    108:                fire_item = creat_item();
                    109:                ldata(fire_item) = (char *) tp;
                    110:                attach(rp->r_fires, fire_item);
                    111:
                    112:                rp->r_flags |= HASFIRE;
                    113:            }
                    114:        }
                    115:
                    116:        /*
                    117:         * If we can see this monster, set oldch to ' ' to make light()
                    118:         * think the creature used to be invisible (ie. not seen here)
                    119:         */
                    120:        if (cansee(tp->t_pos.y, tp->t_pos.x)) tp->t_oldch = ' ';
                    121:        return(TRUE);
                    122:     }
                    123:     if (report) msg("You hear a faint cry of anguish in the distance.");
                    124:     return(FALSE);
                    125: }
                    126: 
                    127: /*
                    128:  * Genmonsters:
                    129:  *     Generate at least 'least' monsters for this single room level.
                    130:  *     'Treas' indicates whether this is a "treasure" level.
                    131:  */
                    132:
                    133: void
                    134: genmonsters(int least, bool treas)
                    135: {
                    136:     reg int i;
                    137:     reg struct room *rp = &rooms[0];
                    138:     reg struct linked_list *item;
                    139:     reg struct thing *mp;
                    140:     coord tp;
                    141:
                    142:     for (i = 0; i < level + least; i++) {
                    143:            if (!treas && rnd(100) < 50)        /* put in some little buggers */
                    144:                    continue;
                    145:            /*
                    146:             * Put the monster in
                    147:             */
                    148:            item = new_item(sizeof *mp);
                    149:            mp = THINGPTR(item);
                    150:            do {
                    151:                    rnd_pos(rp, &tp);
                    152:            } until(mvwinch(stdscr, tp.y, tp.x) == FLOOR);
                    153:
                    154:            new_monster(item, randmonster(FALSE, FALSE), &tp, FALSE);
                    155:            /*
                    156:             * See if we want to give it a treasure to carry around.
                    157:             */
                    158:            carry_obj(mp, monsters[mp->t_index].m_carry);
                    159:
                    160:            /* Calculate a movement rate */
                    161:            mp->t_no_move = movement(mp);
                    162:
                    163:            /* Is it going to give us some light? */
                    164:            if (on(*mp, HASFIRE)) {
                    165:                register struct linked_list *fire_item;
                    166:
                    167:                fire_item = creat_item();
                    168:                ldata(fire_item) = (char *) mp;
                    169:                attach(rp->r_fires, fire_item);
                    170:                rp->r_flags |= HASFIRE;
                    171:            }
                    172:     }
                    173: }
                    174: 
                    175: /*
                    176:  * id_monst returns the index of the monster given its letter
                    177:  */
                    178:
                    179: short
                    180: id_monst(char monster)
                    181: {
                    182:     register short result;
                    183:
                    184:     result = NLEVMONS*vlevel;
                    185:     if (result > NUMMONST) result = NUMMONST;
                    186:
                    187:     for(; result>0; result--)
                    188:        if (monsters[result].m_appear == monster) return(result);
                    189:     for (result=(NLEVMONS*vlevel)+1; result <= NUMMONST; result++)
                    190:        if (monsters[result].m_appear == monster) return(result);
                    191:     return(0);
                    192: }
                    193:
                    194: 
                    195: /*
                    196:  * new_monster:
                    197:  *     Pick a new monster and add it to the list
                    198:  */
                    199:
                    200: void
                    201: new_monster(struct linked_list *item, short type, coord *cp, bool max_monster)
                    202: {
                    203:     register struct thing *tp;
                    204:     register struct monster *mp;
                    205:     register char *ip, *hitp;
                    206:     register int i, min_intel, max_intel;
                    207:     register int num_dice, num_sides=8, num_extra=0;
                    208:
                    209:     attach(mlist, item);
                    210:     tp = THINGPTR(item);
                    211:     tp->t_pack = NULL;
                    212:     tp->t_index = type;
                    213:     tp->t_wasshot = FALSE;
                    214:     tp->t_type = monsters[type].m_appear;
                    215:     tp->t_ctype = C_MONSTER;
                    216:     tp->t_action = A_NIL;
                    217:     tp->t_doorgoal = 0;
                    218:     tp->t_quiet = 0;
                    219:     tp->t_dest = NULL;
                    220:     tp->t_name = NULL;
                    221:     tp->t_pos = tp->t_oldpos = *cp;
                    222:     tp->t_oldch = CCHAR( mvwinch(cw, cp->y, cp->x) );
                    223:     mvwaddch(mw, cp->y, cp->x, tp->t_type);
                    224:     mp = &monsters[tp->t_index];
                    225:
                    226:     /* Figure out monster's hit points */
                    227:     hitp = mp->m_stats.s_hpt;
                    228:     num_dice = atoi(hitp);
                    229:     if ((hitp = strchr(hitp, 'd')) != NULL) {
                    230:        num_sides = atoi(++hitp);
                    231:        if ((hitp = strchr(hitp, '+')) != NULL)
                    232:            num_extra = atoi(++hitp);
                    233:     }
                    234:
                    235:     tp->t_stats.s_lvladj = 0;
                    236:     tp->t_stats.s_lvl = mp->m_stats.s_lvl;
                    237:     tp->t_stats.s_arm = mp->m_stats.s_arm;
                    238:     strncpy(tp->t_stats.s_dmg, mp->m_stats.s_dmg, sizeof(tp->t_stats.s_dmg));
                    239:     tp->t_stats.s_str = mp->m_stats.s_str;
                    240:     tp->t_stats.s_dext = mp->m_stats.s_dex;
                    241:     tp->t_movement = mp->m_stats.s_move;
                    242:     if (vlevel > HARDER) { /* the deeper, the meaner we get */
                    243:         tp->t_stats.s_lvl += (vlevel - HARDER);
                    244:         num_dice += (vlevel - HARDER)/2;
                    245:         tp->t_stats.s_arm -= (vlevel - HARDER) / 4;
                    246:     }
                    247:     if (max_monster)
                    248:        tp->t_stats.s_hpt = num_dice * num_sides + num_extra;
                    249:     else
                    250:        tp->t_stats.s_hpt = roll(num_dice, num_sides) + num_extra;
                    251:     tp->t_stats.s_exp = mp->m_stats.s_exp + mp->m_add_exp*tp->t_stats.s_hpt;
                    252:
                    253:     /*
                    254:      * just initailize others values to something reasonable for now
                    255:      * maybe someday will *really* put these in monster table
                    256:      */
                    257:     tp->t_stats.s_wisdom = 8 + rnd(4);
                    258:     tp->t_stats.s_const = 8 + rnd(4);
                    259:     tp->t_stats.s_charisma = 8 + rnd(4);
                    260:
                    261:     /* Set the initial flags */
                    262:     for (i=0; i<16; i++) tp->t_flags[i] = 0;
                    263:     for (i=0; i<MAXFLAGS; i++)
                    264:        turn_on(*tp, mp->m_flags[i]);
                    265:
                    266:     /*
                    267:      * these are the base chances that a creatures will do something
                    268:      * assuming it can. These are(or can be) modified at runtime
                    269:      * based on what the creature experiences
                    270:      */
                    271:     tp->t_breathe = 75;                /* base chance of breathing */
                    272:     tp->t_artifact = 90;       /* base chance of using artifact */
                    273:     tp->t_summon = 40;         /* base chance of summoning */
                    274:     tp->t_cast = 75;           /* base chance of casting a spell */
                    275:     tp->t_wand = on(*tp, ISUNIQUE) ? 35 : 50;  /* base chance of using wands */
                    276:
                    277:     /* suprising monsters don't always surprise you */
                    278:     if (!max_monster           && on(*tp, CANSURPRISE) &&
                    279:        off(*tp, ISUNIQUE)      && rnd(100) < 20)
                    280:            turn_off(*tp, CANSURPRISE);
                    281:
                    282:     /* If this monster is unique, gen it */
                    283:     if (on(*tp, ISUNIQUE)) mp->m_normal = FALSE;
                    284:
                    285:     /*
                    286:      * If it is the quartermaster, then compute his level and exp pts
                    287:      * based on the level. This will make it fair when thieves try to
                    288:      * steal and give them reasonable experience if they succeed.
                    289:      * Then fill his pack with his wares.
                    290:      */
                    291:     if (on(*tp, CANSELL)) {
                    292:        tp->t_stats.s_exp = vlevel * 100;
                    293:        tp->t_stats.s_lvl = vlevel/2 + 1;
                    294:        make_sell_pack(tp);
                    295:     }
                    296:
                    297:     /* Normally scared monsters have a chance to not be scared */
                    298:     if (on(*tp, ISFLEE) && (rnd(4) == 0)) turn_off(*tp, ISFLEE);
                    299:
                    300:     /* Figure intelligence */
                    301:     min_intel = atoi(mp->m_intel);
                    302:     if ((ip = (char *) strchr(mp->m_intel, '-')) == NULL)
                    303:        tp->t_stats.s_intel = min_intel;
                    304:     else {
                    305:        max_intel = atoi(++ip);
                    306:        if (max_monster)
                    307:            tp->t_stats.s_intel = max_intel;
                    308:        else
                    309:            tp->t_stats.s_intel = min_intel + rnd(max_intel - min_intel);
                    310:     }
                    311:     if (vlevel > HARDER)
                    312:         tp->t_stats.s_intel += ((vlevel - HARDER)/2);
                    313:     tp->maxstats = tp->t_stats;
                    314:
                    315:     /* If the monster can shoot, it may have a weapon */
                    316:     if (on(*tp, CANSHOOT) && ((rnd(100) < (22 + vlevel)) || max_monster)) {
                    317:        struct linked_list *item1;
                    318:        register struct object *cur, *cur1;
                    319:
                    320:        item = new_item(sizeof *cur);
                    321:        item1 = new_item(sizeof *cur1);
                    322:        cur = OBJPTR(item);
                    323:        cur1 = OBJPTR(item1);
                    324:        cur->o_hplus = (rnd(4) < 3) ? 0
                    325:                                    : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
                    326:        cur->o_dplus = (rnd(4) < 3) ? 0
                    327:                                    : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
                    328:        cur1->o_hplus = (rnd(4) < 3) ? 0
                    329:                                    : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
                    330:        cur1->o_dplus = (rnd(4) < 3) ? 0
                    331:                                    : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
                    332:
                    333:         strncpy(cur->o_damage, "0d0", sizeof(cur->o_damage));
                    334:        strncpy(cur->o_hurldmg, "0d0", sizeof(cur->o_hurldmg));
                    335:        strncpy(cur1->o_damage, "0d0", sizeof(cur1->o_damage));
                    336:        strncpy(cur1->o_hurldmg, "0d0", sizeof(cur1->o_hurldmg));
                    337:
                    338:        cur->o_ac = cur1->o_ac = 11;
                    339:        cur->o_count = cur1->o_count = 1;
                    340:        cur->o_group = cur1->o_group = 0;
                    341:        cur->contents = cur1->contents = NULL;
                    342:        if ((cur->o_hplus <= 0) && (cur->o_dplus <= 0)) cur->o_flags = ISCURSED;
                    343:        if ((cur1->o_hplus <= 0) && (cur1->o_dplus <= 0))
                    344:            cur1->o_flags = ISCURSED;
                    345:        cur->o_flags = cur1->o_flags = 0;
                    346:        cur->o_type = cur1->o_type = WEAPON;
                    347:        cur->o_mark[0] = cur1->o_mark[0] = '\0';
                    348:
                    349:        /* The monster may use a crossbow, sling, or an arrow */
                    350:        i = rnd(100);
                    351:        if (i < 10) {
                    352:            cur->o_which = CROSSBOW;
                    353:            cur1->o_which = BOLT;
                    354:            init_weapon(cur, CROSSBOW);
                    355:            init_weapon(cur1, BOLT);
                    356:        }
                    357:        else if (i < 70) {
                    358:            cur->o_which = BOW;
                    359:            cur1->o_which = ARROW;
                    360:            init_weapon(cur, BOW);
                    361:            init_weapon(cur1, ARROW);
                    362:        }
                    363:        else {
                    364:            cur->o_which = SLING;
                    365:            cur1->o_which = ROCK;
                    366:            init_weapon(cur, SLING);
                    367:            init_weapon(cur1, ROCK);
                    368:        }
                    369:
                    370:        attach(tp->t_pack, item);
                    371:        attach(tp->t_pack, item1);
                    372:     }
                    373:
                    374:
                    375:     /* Calculate the initial movement rate */
                    376:     updpack(TRUE, tp);
                    377:     tp->t_no_move = movement(tp);
                    378:
                    379:     if (ISWEARING(R_AGGR))
                    380:        runto(tp, &hero);
                    381:     if (on(*tp, ISDISGUISE))
                    382:     {
                    383:        char mch;
                    384:
                    385:        if (tp->t_pack != NULL)
                    386:            mch = (OBJPTR(tp->t_pack))->o_type;
                    387:        else
                    388:            switch (rnd(10)) {
                    389:                case 0: mch = GOLD;
                    390:                when 1: mch = POTION;
                    391:                when 2: mch = SCROLL;
                    392:                when 3: mch = FOOD;
                    393:                when 4: mch = WEAPON;
                    394:                when 5: mch = ARMOR;
                    395:                when 6: mch = RING;
                    396:                when 7: mch = STICK;
                    397:                when 8: mch = monsters[randmonster(FALSE, FALSE)].m_appear;
                    398:                when 9: mch = MM;
                    399:            }
                    400:        tp->t_disguise = mch;
                    401:     }
                    402: }
                    403: 
                    404: /*
                    405:  * randmonster:
                    406:  *     Pick a monster to show up.  The lower the level,
                    407:  *     the meaner the monster.
                    408:  */
                    409:
                    410: short
                    411: randmonster(bool wander, bool no_unique)
                    412: {
                    413:     register int d, cur_level, range, i;
                    414:
                    415:     /*
                    416:      * Do we want a merchant? Merchant is always in place 'NUMMONST'
                    417:      */
                    418:     if (wander && monsters[NUMMONST].m_wander && rnd(100) < pstats.s_charisma/4)
                    419:        return NUMMONST;
                    420:
                    421:     cur_level = vlevel;
                    422:     range = 4*NLEVMONS;
                    423:     i = 0;
                    424:     do
                    425:     {
                    426:        if (i++ > range*10) { /* just in case all have be genocided */
                    427:            i = 0;
                    428:            if (--cur_level <= 0)
                    429:                fatal("Rogue could not find a monster to make");
                    430:        }
                    431:        d = NLEVMONS*(cur_level - 1) + (rnd(range) - (range - 1 - NLEVMONS));
                    432:        if (d < 1)
                    433:            d = rnd(NLEVMONS) + 1;
                    434:        if (d > NUMMONST - NUMUNIQUE - 1) {
                    435:            if (no_unique)
                    436:                d = rnd(range) + (NUMMONST - NUMUNIQUE - 1) - (range - 1);
                    437:            else if (d > NUMMONST - 1)
                    438:                d = rnd(range+NUMUNIQUE) + (NUMMONST-1) - (range+NUMUNIQUE-1);
                    439:        }
                    440:     }
                    441:     while  (wander ? !monsters[d].m_wander || !monsters[d].m_normal
                    442:                   : !monsters[d].m_normal);
                    443:     return d;
                    444: }
                    445: 
                    446: /* Sell displays a menu of goods from which the player may choose
                    447:  * to purchase something.
                    448:  */
                    449:
                    450: void
                    451: sell(struct thing *tp)
                    452: {
                    453:     register struct linked_list *item, *seller;
                    454:     register struct linked_list *sellpack;
                    455:     register struct object *obj;
                    456:     register int worth, min_worth;
                    457:     char buffer[LINELEN];
                    458:
                    459:
                    460:     /*
                    461:      * Get a linked_list pointer to the seller.  We need this in case
                    462:      * he disappears so we can set monst_dead.
                    463:      */
                    464:     seller = find_mons(tp->t_pos.y, tp->t_pos.x);
                    465:
                    466:     sellpack = tp->t_pack;
                    467:     if (sellpack == NULL) {
                    468:        msg("%s looks puzzled and departs.", prname(monster_name(tp), TRUE));
                    469:
                    470:        /* Get rid of the monster */
                    471:        killed(seller, FALSE, FALSE, FALSE);
                    472:        return;
                    473:     }
                    474:
                    475:     /* See how much the minimum pack item is worth */
                    476:     min_worth = 100000;
                    477:     for (item = sellpack; item != NULL; item = next(item)) {
                    478:        obj = OBJPTR(item);
                    479:        obj->o_flags |= ISPOST; /* Force a long description of the item */
                    480:        worth = get_worth(obj);
                    481:        if (worth < min_worth) min_worth = worth;
                    482:     }
                    483:
                    484:     /* See if player can afford an item */
                    485:     if (min_worth > purse) {
                    486:        msg("%s eyes your small purse and departs.",
                    487:            prname(monster_name(tp), TRUE));
                    488:
                    489:        /* Get rid of the monster */
                    490:        killed(seller, FALSE, FALSE, FALSE);
                    491:        return;
                    492:     }
                    493:
                    494:     /* Announce our intentions */
                    495:     msg("%s opens his pack.--More--", prname(monster_name(tp), TRUE));
                    496:     wait_for(' ');
                    497:
                    498:     /* Try to sell something */
                    499:     sprintf(buffer, "You got %d gold pieces.  Buy", purse);
                    500:     item = get_item(sellpack, buffer, ALL, TRUE, TRUE);
                    501:
                    502:     /* Get rid of the monster */
                    503:     if (item != NULL) detach(tp->t_pack, item);        /* Take it out of the pack */
                    504:     killed(seller, FALSE, FALSE, FALSE);
                    505:
                    506:     if (item == NULL) return;
                    507:
                    508:     /* Can he afford the selected item? */
                    509:     obj = OBJPTR(item);
                    510:
                    511:     worth = get_worth(obj);
                    512:     if (worth > purse) {
                    513:        msg("You cannot afford it.");
                    514:        o_discard(item);
                    515:        return;
                    516:     }
                    517:
                    518:     /* Charge him through the nose */
                    519:     purse -= worth;
                    520:
                    521:     /* If a stick or ring, let player know the type */
                    522:     switch (obj->o_type) {
                    523:        case RING:  r_know[obj->o_which] = TRUE;
                    524:        when POTION:p_know[obj->o_which] = TRUE;
                    525:        when SCROLL:s_know[obj->o_which] = TRUE;
                    526:        when STICK: ws_know[obj->o_which] = TRUE;
                    527:        when MM:    m_know[obj->o_which] = TRUE;
                    528:
                    529:     }
                    530:
                    531:     /* Remove the POST flag that we used for get_item() */
                    532:     obj->o_flags &= ~ISPOST;
                    533:
                    534:     if (add_pack(item, FALSE, NULL) == FALSE) {
                    535:        obj->o_pos = hero;
                    536:        fall(item, TRUE);
                    537:     }
                    538: }
                    539:
                    540:
                    541: 
                    542: /*
                    543:  * what to do when the hero steps next to a monster
                    544:  */
                    545: struct linked_list *
                    546: wake_monster(int y, int x)
                    547: {
                    548:     register struct thing *tp;
                    549:     register struct linked_list *it;
                    550:     register struct room *trp;
                    551:     register char *mname;
                    552:     bool nasty;        /* Will the monster "attack"? */
                    553:
                    554:     if ((it = find_mons(y, x)) == NULL) {
                    555:        msg("Wake:  can't find monster in show (%d, %d)", y, x);
                    556:        return (NULL);
                    557:     }
                    558:     tp = THINGPTR(it);
                    559:     if (on(*tp, ISSTONE)) /* if stoned, don't do anything */
                    560:        return it;
                    561:
                    562:     /*
                    563:      * For now, if we are a friendly monster, we won't do any of
                    564:      * our special effects.
                    565:      */
                    566:     if (on(*tp, ISFRIENDLY)) return it;
                    567:
                    568:     trp = roomin(&tp->t_pos); /* Current room for monster */
                    569:
                    570:     /*
                    571:      * Let greedy ones in a room guard gold
                    572:      * (except in a maze where lots of creatures would all go for the
                    573:      * same piece of gold)
                    574:      */
                    575:     if (on(*tp, ISGREED)       && off(*tp, ISRUN)      &&
                    576:        levtype != MAZELEV      && trp != NULL          &&
                    577:        lvl_obj != NULL) {
                    578:            register struct linked_list *item;
                    579:            register struct object *cur;
                    580:
                    581:            for (item = lvl_obj; item != NULL; item = next(item)) {
                    582:                cur = OBJPTR(item);
                    583:                if ((cur->o_type == GOLD) && (roomin(&cur->o_pos) == trp)) {
                    584:                    /* Run to the gold */
                    585:                    runto(tp, &cur->o_pos);
                    586:
                    587:                    /* Make it worth protecting */
                    588:                    cur->o_count += GOLDCALC + GOLDCALC;
                    589:                    break;
                    590:                }
                    591:            }
                    592:     }
                    593:
                    594:     /*
                    595:      * Every time he sees mean monster, it might start chasing him
                    596:      */
                    597:     if (on(*tp, ISMEAN)                                                        &&
                    598:        off(*tp, ISHELD)                                                &&
                    599:        off(*tp, ISRUN)                                                 &&
                    600:        rnd(100) > 33                                                   &&
                    601:        (!is_stealth(&player) || (on(*tp, ISUNIQUE) && rnd(100) > 50))  &&
                    602:        (off(player, ISINVIS) || on(*tp, CANSEE))                       ||
                    603:        (trp != NULL && (trp->r_flags & ISTREAS))) {
                    604:        runto(tp, &hero);
                    605:     }
                    606:
                    607:     /*
                    608:      * Get the name; we don't want to do it until here because we need to
                    609:      * know whether the monster is still sleeping or not.
                    610:      */
                    611:     mname = monster_name(tp);
                    612:
                    613:     /* See if the monster will bother the player */
                    614:     nasty = (on(*tp, ISRUN) && cansee(tp->t_pos.y, tp->t_pos.x));
                    615:
                    616:     /*
                    617:      * if the creature is awake and can see the player and the
                    618:      * player has the dreaded "eye of vecna" then see if the
                    619:      * creature is turned to stone
                    620:      */
                    621:     if (cur_relic[EYE_VECNA] && nasty && off(*tp, NOSTONE) &&
                    622:        (off(player, ISINVIS) || on(*tp, CANSEE))) {
                    623:        turn_on(*tp, NOSTONE);  /* only have to save once */
                    624:        if (!save(VS_PETRIFICATION, tp, -2)) {
                    625:                turn_on(*tp, ISSTONE);
                    626:                turn_off(*tp, ISRUN);
                    627:                turn_off(*tp, ISINVIS);
                    628:                turn_off(*tp, CANSURPRISE);
                    629:                turn_off(*tp, ISDISGUISE);
                    630:                msg("%s is turned to stone!", prname(mname, TRUE));
                    631:                return it;
                    632:        }
                    633:     }
                    634:
                    635:     /*
                    636:      * Handle monsters that can gaze and do things while running
                    637:      * Player must be able to see the monster and the monster must
                    638:      * not be asleep
                    639:      */
                    640:     if (nasty && !invisible(tp)) {
                    641:        /*
                    642:         * Confusion
                    643:         */
                    644:        if (on(*tp, CANHUH)                              &&
                    645:           (off(*tp, ISINVIS)     || on(player, CANSEE)) &&
                    646:           (off(*tp, CANSURPRISE) || ISWEARING(R_ALERT))) {
                    647:            if (!save(VS_MAGIC, &player, 0)) {
                    648:                if (off(player, ISCLEAR)) {
                    649:                    if (find_slot(unconfuse))
                    650:                        lengthen(unconfuse, HUHDURATION);
                    651:                    else {
                    652:                        fuse(unconfuse, NULL, HUHDURATION, AFTER);
                    653:                        msg("%s's gaze has confused you.",prname(mname, TRUE));
                    654:                        turn_on(player, ISHUH);
                    655:                    }
                    656:                }
                    657:                else msg("You feel dizzy for a moment, but it quickly passes.");
                    658:            }
                    659:            else if (rnd(100) < 67)
                    660:                turn_off(*tp, CANHUH); /* Once you save, maybe that's it */
                    661:        }
                    662:
                    663:        /* Sleep */
                    664:        if(on(*tp, CANSNORE) &&
                    665:           player.t_action != A_FREEZE &&
                    666:           !save(VS_PARALYZATION, &player, 0)) {
                    667:            if (ISWEARING(R_ALERT))
                    668:                msg("You feel slightly drowsy for a moment.");
                    669:            else {
                    670:                msg("%s's gaze puts you to sleep.", prname(mname, TRUE));
                    671:                player.t_no_move += movement(&player) * SLEEPTIME;
                    672:                player.t_action = A_FREEZE;
                    673:                if (rnd(100) < 50) turn_off(*tp, CANSNORE);
                    674:            }
                    675:        }
                    676:
                    677:        /* Fear */
                    678:        if (on(*tp, CANFRIGHTEN) && !on(player, ISFLEE)) {
                    679:            turn_off(*tp, CANFRIGHTEN);
                    680:            if (!ISWEARING(R_HEROISM) &&
                    681:                !save(VS_WAND, &player, -(tp->t_stats.s_lvl/10))) {
                    682:                    turn_on(player, ISFLEE);
                    683:                    player.t_dest = &tp->t_pos;
                    684:                    msg("The sight of %s terrifies you.", prname(mname, FALSE));
                    685:            }
                    686:        }
                    687:
                    688:        /* blinding creatures */
                    689:        if(on(*tp, CANBLIND) && !find_slot(sight)) {
                    690:            turn_off(*tp, CANBLIND);
                    691:            if (!save(VS_WAND, &player, 0)) {
                    692:                msg("The gaze of %s blinds you", prname(mname, FALSE));
                    693:                turn_on(player, ISBLIND);
                    694:                fuse(sight, NULL, rnd(30)+20, AFTER);
                    695:                light(&hero);
                    696:            }
                    697:        }
                    698:
                    699:        /* the sight of the ghost can age you! */
                    700:        if (on(*tp, CANAGE)) {
                    701:            turn_off (*tp, CANAGE);
                    702:            if (!save(VS_MAGIC, &player, 0)) {
                    703:                msg ("The sight of %s ages you!", prname(mname, FALSE));
                    704:                pstats.s_const--;
                    705:                max_stats.s_const--;
                    706:                if (pstats.s_const < 0)
                    707:                    death (D_CONSTITUTION);
                    708:            }
                    709:        }
                    710:
                    711:
                    712:        /* Turning to stone */
                    713:        if (on(*tp, LOOKSTONE)) {
                    714:            turn_off(*tp, LOOKSTONE);
                    715:
                    716:            if (on(player, CANINWALL))
                    717:                msg("The gaze of %s has no effect.", prname(mname, FALSE));
                    718:            else {
                    719:                if (!save(VS_PETRIFICATION, &player, 0) && rnd(100) < 5) {
                    720:                    pstats.s_hpt = -1;
                    721:                    msg("The gaze of %s petrifies you.", prname(mname, FALSE));
                    722:                    msg("You are turned to stone !!! --More--");
                    723:                    wait_for(' ');
                    724:                    death(D_PETRIFY);
                    725:                }
                    726:                else {
                    727:                    msg("The gaze of %s stiffens your limbs.",
                    728:                        prname(mname, FALSE));
                    729:                    player.t_no_move += movement(&player) * STONETIME;
                    730:                    player.t_action = A_FREEZE;
                    731:                }
                    732:            }
                    733:        }
                    734:     }
                    735:
                    736:     return it;
                    737: }
                    738: /*
                    739:  * wanderer:
                    740:  *     A wandering monster has awakened and is headed for the player
                    741:  */
                    742:
                    743: void
                    744: wanderer(void)
                    745: {
                    746:     register int i;
                    747:     register struct room *hr = roomin(&hero);
                    748:     register struct linked_list *item;
                    749:     register struct thing *tp;
                    750:     register long *attr;       /* Points to monsters' attributes */
                    751:     int carry; /* Chance of wanderer carrying anything */
                    752:     short rmonst;      /* Our random wanderer */
                    753:     bool canteleport = FALSE,  /* Can the monster teleport? */
                    754:         seehim;        /* Is monster within sight? */
                    755:     coord cp;
                    756:
                    757:     rmonst = randmonster(TRUE, FALSE); /* Choose a random wanderer */
                    758:     attr = &monsters[rmonst].m_flags[0]; /* Start of attributes */
                    759:     for (i=0; i<MAXFLAGS; i++)
                    760:        if (*attr++ == CANTELEPORT) {
                    761:            canteleport = TRUE;
                    762:            break;
                    763:        }
                    764:
                    765:     /* Find a place for it -- avoid the player's room if can't teleport */
                    766:     do {
                    767:        do {
                    768:            i = rnd_room();
                    769:        } until (canteleport || hr != &rooms[i] || levtype == MAZELEV ||
                    770:                 levtype == OUTSIDE || levtype == POSTLEV);
                    771:
                    772:        /* Make sure the monster does not teleport on top of the player */
                    773:        do {
                    774:            rnd_pos(&rooms[i], &cp);
                    775:        } while (hr == &rooms[i] && ce(cp, hero));
                    776:     } until (step_ok(cp.y, cp.x, NOMONST, NULL));
                    777:
                    778:     /* Create a new wandering monster */
                    779:     item = new_item(sizeof *tp);
                    780:     new_monster(item, rmonst, &cp, FALSE);
                    781:     tp = THINGPTR(item);
                    782:     runto(tp, &hero);
                    783:     tp->t_pos = cp;    /* Assign the position to the monster */
                    784:     seehim = cansee(tp->t_pos.y, tp->t_pos.x);
                    785:     if (on(*tp, HASFIRE)) {
                    786:        register struct room *rp;
                    787:
                    788:        rp = roomin(&tp->t_pos);
                    789:        if (rp) {
                    790:            register struct linked_list *fire_item;
                    791:
                    792:            fire_item = creat_item();
                    793:            ldata(fire_item) = (char *) tp;
                    794:            attach(rp->r_fires, fire_item);
                    795:
                    796:            rp->r_flags |= HASFIRE;
                    797:            if (seehim && next(rp->r_fires) == NULL)
                    798:                light(&hero);
                    799:        }
                    800:     }
                    801:
                    802:     /* See if we give the monster anything */
                    803:     carry = monsters[tp->t_index].m_carry;
                    804:     if (off(*tp, ISUNIQUE)) carry /= 2;        /* Non-unique has only a half chance */
                    805:     carry_obj(tp, carry);
                    806:
                    807:     /* Calculate its movement rate */
                    808:     tp->t_no_move = movement(tp);
                    809:
                    810:     /* Alert the player if a monster just teleported in */
                    811:     if (hr == &rooms[i] && canteleport && seehim && !invisible(tp)) {
                    812:        msg("A %s just teleported in", monster_name(tp));
                    813:        light(&hero);
                    814:        running = FALSE;
                    815:     }
                    816:
                    817:     if (wizard)
                    818:        msg("Started a wandering %s", monster_name(tp));
                    819: }

CVSweb