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

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

1.1       rubenllo    1: /*
                      2:     chase.c  -  Code for one creature to chase another
                      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 <ctype.h>
                     21: #include <limits.h>
                     22: #include "rogue.h"
                     23:
                     24: /*
                     25:     do_chase()
                     26:         Make one thing chase another.
                     27: */
                     28:
                     29: void
                     30: do_chase(struct thing *th, int flee)
                     31: {
                     32:     struct room    *rer;        /* room of chaser */
                     33:     struct room    *ree;        /* room of chasee */
                     34:     struct room    *old_room;   /* old room of monster */
                     35:     struct room    *new_room;   /* new room of monster */
                     36:
                     37:     int i, mindist = INT_MAX, maxdist = INT_MIN, dist = INT_MIN;
                     38:
                     39:     int last_door = -1;     /* Door we just came from */
                     40:     int stoprun = FALSE;    /* TRUE means we are there */
                     41:     int rundoor;            /* TRUE means run to a door */
                     42:     int hit_bad = FALSE;    /* TRUE means hit bad monster */
                     43:     int mon_attack;         /* TRUE means find a monster to hit */
                     44:
                     45:     char    sch;
                     46:     struct linked_list *item;
                     47:     coord   this;           /* Temporary destination for chaser */
                     48:
                     49:     if (!th->t_ischasing)
                     50:         return;
                     51:
                     52:     /* Make sure the monster can move */
                     53:
                     54:     if (th->t_no_move != 0)
                     55:     {
                     56:         th->t_no_move--;
                     57:         return;
                     58:     }
                     59:
                     60:     /*
                     61:      * Bad monsters check for a good monster to hit, friendly monsters
                     62:      * check for a bad monster to hit.
                     63:      */
                     64:
                     65:     mon_attack = FALSE;
                     66:
                     67:     if (good_monster(*th))
                     68:     {
                     69:         hit_bad = TRUE;
                     70:         mon_attack = TRUE;
                     71:     }
                     72:     else if (on(*th, ISMEAN))
                     73:     {
                     74:         hit_bad = FALSE;
                     75:         mon_attack = TRUE;
                     76:     }
                     77:
                     78:     if (mon_attack)
                     79:     {
                     80:         struct linked_list  *mon_to_hit;
                     81:
                     82:        mon_to_hit = f_mons_a(th->t_pos.y, th->t_pos.x, hit_bad);
                     83:
                     84:         if (mon_to_hit)
                     85:         {
                     86:             mon_mon_attack(th, mon_to_hit, pick_weap(th), NOTHROWN);
                     87:             return;
                     88:         }
                     89:     }
                     90:
                     91:     /* no nearby monster to hit */
                     92:
                     93:     rer = roomin(th->t_pos);            /* Find room of chaser */
                     94:     ree = roomin(th->t_chasee->t_pos);  /* Find room of chasee */
                     95:
                     96:     /*
                     97:      * We don't count doors as inside rooms for this routine
                     98:      */
                     99:
                    100:     if (mvwinch(stdscr, th->t_pos.y, th->t_pos.x) == DOOR)
                    101:         rer = NULL;
                    102:
                    103:     this = th->t_chasee->t_pos;
                    104:
                    105:     /*
                    106:      * If we are not in a corridor and not a phasing monster, then if we
                    107:      * are running after the player, we run to a door if he is not in the
                    108:      * same room. If we are fleeing, we run to a door if he IS in the
                    109:      * same room.  Note:  We don't bother with doors in mazes. Phasing
                    110:      * monsters don't need to look for doors. There are no doors in mazes
                    111:      * and throne rooms.
                    112:      */
                    113:
                    114:     if (levtype != MAZELEV && levtype != THRONE && rer != NULL && off(*th, CANINWALL))
                    115:     {
                    116:         if (flee)
                    117:             rundoor = (rer == ree);
                    118:         else
                    119:             rundoor = (rer != ree);
                    120:     }
                    121:     else
                    122:         rundoor = FALSE;
                    123:
                    124:     if (rundoor)
                    125:     {
                    126:         coord   d_exit;   /* A particular door */
                    127:         int exity, exitx;   /* Door's coordinates */
                    128:
                    129:         if (th->t_doorgoal != -1)
                    130:         { /* Do we already have the goal? */
                    131:             this = rer->r_exit[th->t_doorgoal];
                    132:             dist = 0;   /* Indicate that we have our door */
                    133:         }
                    134:         else
                    135:             for (i = 0; i < rer->r_nexits; i++)
                    136:             {   /* Loop through doors */
                    137:                 d_exit = rer->r_exit[i];
                    138:                 exity = d_exit.y;
                    139:                 exitx = d_exit.x;
                    140:
                    141:                 /* Avoid secret doors */
                    142:                 if (mvwinch(stdscr, exity, exitx) == DOOR)
                    143:                 {
                    144:                     /* Were we just on this door? */
                    145:                     if (ce(d_exit, th->t_oldpos))
                    146:                         last_door = i;
                    147:                     else
                    148:                     {
                    149:                         dist = DISTANCE(th->t_chasee->t_pos, d_exit);
                    150:
                    151:                         /*
                    152:                          * If fleeing, we want to
                    153:                          * maximize distance from
                    154:                          * door to what we flee, and
                    155:                          * minimize distance from
                    156:                          * door to us.
                    157:                          */
                    158:
                    159:                         if (flee)
                    160:                             dist-=DISTANCE(th->t_pos,d_exit);
                    161:
                    162:                         /*
                    163:                          * Maximize distance if
                    164:                          * fleeing, otherwise
                    165:                          * minimize it
                    166:                          */
                    167:
                    168:                         if ((flee && (dist > maxdist)) ||
                    169:                             (!flee && (dist < mindist)))
                    170:                         {
                    171:                             th->t_doorgoal = i; /* Use this door */
                    172:                             this = d_exit;
                    173:                             mindist = maxdist = dist;
                    174:                         }
                    175:                     }
                    176:                 }
                    177:             }
                    178:
                    179:         /* Could we not find a door? */
                    180:         if (dist == INT_MIN)
                    181:         {
                    182:             /* If we were on a door, go ahead and use it */
                    183:             if (last_door != -1)
                    184:             {
                    185:                 th->t_doorgoal = last_door;
                    186:                 this = th->t_oldpos;
                    187:                 dist = 0;   /* Indicate that we found a door */
                    188:             }
                    189:         }
                    190:
                    191:         /* Indicate that we do not want to flee from the door */
                    192:         if (dist != INT_MIN)
                    193:             flee = FALSE;
                    194:     }
                    195:     else
                    196:         th->t_doorgoal = -1;    /* Not going to any door */
                    197:
                    198:     /*
                    199:      * this now contains what we want to run to this time so we run to
                    200:      * it.  If we hit it we either want to fight it or stop running
                    201:      */
                    202:
                    203:     if (!chase(th, &this, flee))
                    204:     {
                    205:         if (ce(th->t_nxtpos, hero))
                    206:         {
                    207:             /* merchants try to sell something */
                    208:
                    209:             if (on(*th, CANSELL))
                    210:             {
                    211:                 sell(th);
                    212:                 return;
                    213:             }
                    214:             else if (off(*th, ISFRIENDLY) && off(*th, ISCHARMED)
                    215:                     && (off(*th, CANFLY) || (on(*th, CANFLY) && rnd(2))))
                    216:                     attack(th, pick_weap(th), FALSE);
                    217:                 return;
                    218:         }
                    219:         else if (on(*th, NOMOVE))
                    220:             stoprun = TRUE;
                    221:     }
                    222:
                    223:     if (!curr_mons)
                    224:         return;     /* Did monster get itself killed? */
                    225:
                    226:     if (on(*th, NOMOVE))
                    227:         return;
                    228:
                    229:     /* If we have a scavenger, it can pick something up */
                    230:
                    231:     if ((item = find_obj(th->t_nxtpos.y, th->t_nxtpos.x)) != NULL)
                    232:     {
                    233:                struct linked_list *node, *top = item;
                    234:         struct object *obt;
                    235:
                    236:                while(top)
                    237:                {
                    238:                        /* grab all objects that qualify */
                    239:
                    240:                        struct object *obj = OBJPTR(item);
                    241:
                    242:                        obt = OBJPTR(top);
                    243:                        node = obt->next_obj;
                    244:
                    245:                        if (on(*th, ISSCAVENGE) ||
                    246:                 ((on(*th, CANWIELD) || on(*th, CANSHOOT)) &&
                    247:                 (obj->o_type == WEAPON || obj->o_type == ARMOR)) ||
                    248:                 (on(*th, CANCAST) && is_magic(obj)))
                    249:                        {
                    250:                 rem_obj(top, FALSE);
                    251:                 attach(th->t_pack, top);
                    252:             }
                    253:
                    254:                        top = node;
                    255:                }
                    256:
                    257:                light(&hero);
                    258:     }
                    259:
                    260:     mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
                    261:     sch = CCHAR( mvwinch(cw, th->t_nxtpos.y, th->t_nxtpos.x) );
                    262:
                    263:     /* Get old and new room of monster */
                    264:     old_room = roomin(th->t_pos);
                    265:     new_room = roomin(th->t_nxtpos);
                    266:
                    267:     /* If the monster can illuminate rooms, check for a change */
                    268:     if (on(*th, HASFIRE))
                    269:     {
                    270:         /* Is monster entering a room? */
                    271:         if (old_room != new_room && new_room != NULL)
                    272:         {
                    273:             new_room->r_flags |= HASFIRE;
                    274:             new_room->r_fires++;
                    275:             if (cansee(th->t_nxtpos.y, th->t_nxtpos.x) && new_room->r_fires==1)
                    276:                 light(&hero);
                    277:         }
                    278:
                    279:         /* Is monster leaving a room? */
                    280:         if (old_room != new_room && old_room != NULL)
                    281:         {
                    282:             if (--(old_room->r_fires) <= 0)
                    283:             {
                    284:                 old_room->r_flags &= ~HASFIRE;
                    285:                 if (cansee(th->t_pos.y, th->t_pos.x))
                    286:                     light(&th->t_pos);
                    287:             }
                    288:         }
                    289:     }
                    290:
                    291:     /*
                    292:      * If monster is entering player's room and player can see it, stop
                    293:      * the player's running.
                    294:      */
                    295:
                    296:     if (new_room != old_room && new_room != NULL &&
                    297:         new_room == ree && cansee(th->t_nxtpos.y, th->t_nxtpos.x) &&
                    298:         (off(*th, ISINVIS) || (off(*th, ISSHADOW) || rnd(10) == 0) ||
                    299:          on(player, CANSEE)) && off(*th, CANSURPRISE))
                    300:         running = FALSE;
                    301:
                    302:     if (rer != NULL && (rer->r_flags & ISDARK) &&
                    303:         !(rer->r_flags & HASFIRE) && sch == FLOOR &&
                    304:          DISTANCE(th->t_nxtpos, th->t_pos) < see_dist &&
                    305:         off(player, ISBLIND))
                    306:         th->t_oldch = ' ';
                    307:     else
                    308:         th->t_oldch = sch;
                    309:
                    310:     if (cansee(th->t_nxtpos.y, th->t_nxtpos.x) &&
                    311:       off(*th, ISINWALL) &&
                    312:       ((off(*th, ISINVIS) && (off(*th, ISSHADOW) || rnd(100) < 10)) ||
                    313:       on(player, CANSEE)) &&
                    314:       off(*th, CANSURPRISE))
                    315:         mvwaddch(cw, th->t_nxtpos.y, th->t_nxtpos.x, th->t_type);
                    316:
                    317:     mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
                    318:     mvwaddch(mw, th->t_nxtpos.y, th->t_nxtpos.x, th->t_type);
                    319:
                    320:     /* Record monster's last position (if new one is different) */
                    321:
                    322:     if (!ce(th->t_nxtpos, th->t_pos))
                    323:         th->t_oldpos = th->t_pos;
                    324:
                    325:     th->t_pos = th->t_nxtpos; /* Mark the monster's new position */
                    326:
                    327:     /* If the monster is on a trap, trap it */
                    328:
                    329:     sch = CCHAR(mvinch(th->t_nxtpos.y, th->t_nxtpos.x));
                    330:
                    331:     if (isatrap(sch))
                    332:     {
                    333:         debug("Monster trapped by %c.", sch);
                    334:
                    335:         if (cansee(th->t_nxtpos.y, th->t_nxtpos.x))
                    336:             th->t_oldch = sch;
                    337:
                    338:         be_trapped(th, th->t_nxtpos);
                    339:     }
                    340:
                    341:     /* And stop running if need be */
                    342:
                    343:     if (stoprun && ce(th->t_pos, th->t_chasee->t_pos))
                    344:     {
                    345:         th->t_ischasing = FALSE;
                    346:         turn_off(*th, ISRUN);
                    347:     }
                    348: }
                    349:
                    350: /*
                    351:     chase_it()
                    352:         Set a monster running after something or stop it from running (for
                    353:         when it dies)
                    354: */
                    355:
                    356: void
                    357: chase_it(coord *runner, struct thing *th)
                    358: {
                    359:     struct linked_list  *item;
                    360:     struct thing    *tp;
                    361:
                    362:     /* If we couldn't find him, something is funny */
                    363:
                    364:     if ((item = find_mons(runner->y, runner->x)) == NULL)
                    365:     {
                    366:         debug("CHASER '%s'", unctrl(winat(runner->y, runner->x)));
                    367:         return;
                    368:     }
                    369:
                    370:     tp = THINGPTR(item);
                    371:
                    372:     /* Start the beastie running */
                    373:
                    374:     tp->t_ischasing = TRUE;
                    375:     tp->t_chasee    = th;
                    376:
                    377:     turn_on(*tp, ISRUN);
                    378:     turn_off(*tp, ISDISGUISE);
                    379:
                    380:     return;
                    381: }
                    382:
                    383: /*
                    384:     chase()
                    385:         Find the spot for the chaser(er) to move closer to the chasee(ee).
                    386:         Returns TRUE if we want to keep on chasing later, FALSE if we reach the
                    387:         goal.
                    388: */
                    389:
                    390: int
                    391: chase(struct thing *tp, coord *ee, int flee)
                    392: {
                    393:     int x, y;
                    394:     int dist, thisdist, monst_dist = INT_MAX;
                    395:     struct linked_list  *weapon;
                    396:     coord   *er = &tp->t_pos;
                    397:     coord shoot;
                    398:     coord *shootit_dir = NULL;
                    399:     int ch;
                    400:     char   mch;
                    401:     int    next_player = FALSE;
                    402:
                    403:     /* Take care of shooting directions */
                    404:
                    405:     if (on(*tp, CANBREATHE) || on(*tp, CANSHOOT) || on(*tp, CANCAST))
                    406:     {
                    407:         if (good_monster(*tp))
                    408:         {
                    409:             shootit_dir = find_shoot(tp, &shoot); /* find a mean monster */
                    410:
                    411:             if (wizard && shootit_dir)
                    412:                 msg("Found monster to attack towards (%d,%d).",
                    413:                     shootit_dir->x, shootit_dir->y);
                    414:         }
                    415:         else
                    416:             shootit_dir = can_shoot(er, ee, &shoot);  /* shoot hero */
                    417:     }
                    418:
                    419:     /*
                    420:      * If the thing is confused, let it move randomly. Some monsters are
                    421:      * slightly confused all of the time.
                    422:      */
                    423:
                    424:     if ((on(*tp, ISHUH) && rnd(10) < 8) ||
                    425:         ((on(*tp, ISINVIS) || on(*tp, ISSHADOW)) && rnd(100) < 20) ||
                    426:         (on(player, ISINVIS) && off(*tp, CANSEE)))
                    427:     {   /* Player is invisible */
                    428:
                    429:         /* get a valid random move */
                    430:
                    431:         tp->t_nxtpos = rndmove(tp);
                    432:
                    433:         dist = DISTANCE(tp->t_nxtpos, *ee);
                    434:
                    435:         if (on(*tp, ISHUH) && rnd(20) == 0) /* monster might lose confusion */
                    436:             turn_off(*tp, ISHUH);
                    437:
                    438:         /*
                    439:          * check to see if random move takes creature away from
                    440:          * player if it does then turn off ISHELD
                    441:          */
                    442:
                    443:         if (dist > 1 && on(*tp, DIDHOLD))
                    444:         {
                    445:             turn_off(*tp, DIDHOLD);
                    446:             turn_on(*tp, CANHOLD);
                    447:
                    448:             if (--hold_count == 0)
                    449:                 turn_off(player, ISHELD);
                    450:         }
                    451:     } /* If we can breathe, we may do so */
                    452:     else if (on(*tp, CANBREATHE) && (shootit_dir) && (rnd(100) < 67) &&
                    453:          (off(player, ISDISGUISE) || (rnd(tp->t_stats.s_lvl) > 6)) &&
                    454:          (DISTANCE(*er, *ee) < BOLT_LENGTH * BOLT_LENGTH))
                    455:     {
                    456:         int   chance;
                    457:         char    *breath;
                    458:
                    459:         /* Will it breathe at random */
                    460:
                    461:         if (on(*tp, CANBRANDOM))
                    462:         {
                    463:             if (rnd(level / 20) == 0 && tp->t_index != nummonst + 1
                    464:                 && !(good_monster(*tp)))
                    465:                 turn_off(*tp, CANBRANDOM);
                    466:
                    467:             /* Select type of breath */
                    468:
                    469:             chance = rnd(100);
                    470:
                    471:             if (chance < 11)
                    472:                 breath = "acid";
                    473:             else if (chance < 22)
                    474:                 breath = "flame";
                    475:             else if (chance < 33)
                    476:                 breath = "lightning bolt";
                    477:             else if (chance < 44)
                    478:                 breath = "chlorine gas";
                    479:             else if (chance < 55)
                    480:                 breath = "ice";
                    481:             else if (chance < 66)
                    482:                 breath = "nerve gas";
                    483:             else if (chance < 77)
                    484:                 breath = "sleeping gas";
                    485:             else if (chance < 88)
                    486:                 breath = "slow gas";
                    487:             else
                    488:                 breath = "fear gas";
                    489:         } /* Or can it breathe acid? */
                    490:         else if (on(*tp, CANBACID))
                    491:         {
                    492:             if (!good_monster(*tp) && rnd(level / 15) == 0)
                    493:                 turn_off(*tp, CANBACID);
                    494:
                    495:             breath = "acid";
                    496:         } /* Or can it breathe fire */
                    497:         else if (on(*tp, CANBFIRE))
                    498:         {
                    499:             if (!good_monster(*tp) && rnd(level / 15) == 0)
                    500:                 turn_off(*tp, CANBFIRE);
                    501:
                    502:             breath = "flame";
                    503:         } /* Or can it breathe electricity? */
                    504:         else if (on(*tp, CANBBOLT))
                    505:         {
                    506:             if (!good_monster(*tp) && rnd(level / 15) == 0)
                    507:                 turn_off(*tp, CANBBOLT);
                    508:
                    509:             breath = "lightning bolt";
                    510:         } /* Or can it breathe gas? */
                    511:         else if (on(*tp, CANBGAS))
                    512:         {
                    513:             if (!good_monster(*tp) && rnd(level / 15) == 0)
                    514:                 turn_off(*tp, CANBGAS);
                    515:
                    516:             breath = "chlorine gas";
                    517:         } /* Or can it breathe ice? */
                    518:         else if (on(*tp, CANBICE))
                    519:         {
                    520:             if (!good_monster(*tp) && rnd(level / 15) == 0)
                    521:                 turn_off(*tp, CANBICE);
                    522:
                    523:             breath = "ice";
                    524:         }
                    525:         else if (on(*tp, CANBPGAS))
                    526:         {
                    527:             if (!good_monster(*tp) && rnd(level / 15) == 0)
                    528:                 turn_off(*tp, CANBPGAS);
                    529:
                    530:             breath = "nerve gas";
                    531:         }
                    532:         else if (on(*tp, CANBSGAS))
                    533:         {
                    534:             if (!good_monster(*tp) && rnd(level / 15) == 0)
                    535:                 turn_off(*tp, CANBSGAS);
                    536:
                    537:             breath = "sleeping gas";
                    538:         }
                    539:         else if (on(*tp, CANBSLGAS))
                    540:         {
                    541:             if (!good_monster(*tp) && rnd(level / 15) == 0)
                    542:                 turn_off(*tp, CANBSLGAS);
                    543:
                    544:             breath = "slow gas";
                    545:         }
                    546:         else
                    547:         {
                    548:             if (!good_monster(*tp) && rnd(level / 15) == 0)
                    549:                 turn_off(*tp, CANBFGAS);
                    550:
                    551:             breath = "fear gas";
                    552:         }
                    553:
                    554:         shoot_bolt(tp, *er, *shootit_dir, (tp == THINGPTR(fam_ptr)),
                    555:                tp->t_index, breath, roll(tp->t_stats.s_lvl, 6));
                    556:
                    557:         tp->t_nxtpos = *er;
                    558:
                    559:         dist = DISTANCE(tp->t_nxtpos, *ee);
                    560:
                    561:         if (!curr_mons)
                    562:             return (TRUE);
                    563:     }
                    564:     else if (shootit_dir && on(*tp, CANCAST) &&
                    565:          (off(player, ISDISGUISE) || (rnd(tp->t_stats.s_lvl) > 6)))
                    566:     {
                    567:         /*
                    568:             If we can cast spells we might do so - even if adjacent fleeing
                    569:             monsters are restricted to certain spells
                    570:         */
                    571:
                    572:         incant(tp, *shootit_dir);
                    573:         tp->t_nxtpos = *er;
                    574:         dist = DISTANCE(tp->t_nxtpos, *ee);
                    575:     }
                    576:     else if (shootit_dir && on(*tp, CANSHOOT))
                    577:     {
                    578:        weapon = get_hurl(tp);
                    579:
                    580:        if (weapon &&
                    581:          (off(*tp, ISFLEE) || rnd(DISTANCE(*er, *ee)) > 2) &&
                    582:          (off(player, ISDISGUISE) || (rnd(tp->t_stats.s_lvl) > 6)))
                    583:        {
                    584:            /*
                    585:                Should we shoot or throw something? fleeing monsters
                    586:                may to shoot anyway if far enough away
                    587:            */
                    588:
                    589:            missile(shootit_dir->y, shootit_dir->x, weapon, tp);
                    590:            tp->t_nxtpos = *er;
                    591:            dist = DISTANCE(tp->t_nxtpos, *ee);
                    592:        }
                    593:     }
                    594:     else
                    595:     {
                    596:         /*
                    597:             Otherwise, find the empty spot next to the chaser that is closest
                    598:             to the chasee.
                    599:         */
                    600:         int ey, ex;
                    601:         struct room *rer, *ree;
                    602:         int dist_to_old = INT_MIN;   /* Dist from goal to old position */
                    603:
                    604:         /* Get rooms */
                    605:         rer = roomin(*er);
                    606:         ree = roomin(*ee);
                    607:
                    608:         /*
                    609:          * This will eventually hold where we move to get closer. If
                    610:          * we can't find an empty spot, we stay where we are.
                    611:          */
                    612:
                    613:         dist = flee ? 0 : INT_MAX;
                    614:         tp->t_nxtpos = *er;
                    615:
                    616:         /* Are we at our goal already? */
                    617:
                    618:         if (!flee && ce(tp->t_nxtpos, *ee))
                    619:             return (FALSE);
                    620:
                    621:         ey = er->y + 1;
                    622:         ex = er->x + 1;
                    623:
                    624:         for (x = er->x - 1; x <= ex; x++)
                    625:             for (y = er->y - 1; y <= ey; y++)
                    626:             {
                    627:                 coord   tryp; /* test position */
                    628:
                    629:                 /* Don't try off the screen */
                    630:
                    631:                 if ((x < 0) || (x >= COLS) || (y < 1) || (y >= LINES - 2))
                    632:                     continue;
                    633:
                    634:                 /*
                    635:                  * Don't try the player if not going after
                    636:                  * the player or he's disguised and monster is dumb
                    637:                  */
                    638:
                    639:                 if (((off(*tp, ISFLEE) && !ce(hero, *ee)) ||
                    640:                      (on(player, ISDISGUISE) && (rnd(tp->t_stats.s_lvl) < 6))
                    641:                      || good_monster(*tp))
                    642:                     && x == hero.x && y == hero.y)
                    643:                     continue;
                    644:
                    645:                 tryp.x = x;
                    646:                 tryp.y = y;
                    647:
                    648:                 /*
                    649:                  * Is there a monster on this spot closer to
                    650:                  * our goal? Don't look in our spot or where
                    651:                  * we were.
                    652:                  */
                    653:
                    654:                 if (!ce(tryp, *er) && !ce(tryp, tp->t_oldpos) &&
                    655:                     isalpha( (mch = CCHAR(mvwinch(mw, y, x))) ) )
                    656:                 {
                    657:                     int test_dist;
                    658:
                    659:                     test_dist = DISTANCE(tryp,*ee);
                    660:                     if (test_dist <= 25 &&  /* Let's be fairly close */
                    661:                         test_dist < monst_dist)
                    662:                     {
                    663:
                    664:                         /* Could we really move there? */
                    665:
                    666:                         mvwaddch(mw, y, x, ' '); /* Temp blank monst */
                    667:
                    668:                         if (diag_ok(er, &tryp, tp))
                    669:                             monst_dist = test_dist;
                    670:
                    671:                         mvwaddch(mw, y, x, mch);    /* Restore monster */
                    672:                     }
                    673:                 }
                    674:
                    675:                 if (!diag_ok(er, &tryp, tp))
                    676:                     continue;
                    677:
                    678:                 ch = mvwinch(cw, y, x); /* Screen character */
                    679:
                    680:                 /*
                    681:                  * Stepping on player is NOT okay if we are
                    682:                  * fleeing
                    683:                  */
                    684:
                    685:                 if (on(*tp, ISFLEE) && (ch == PLAYER))
                    686:                                    next_player = TRUE;
                    687:
                    688:                 if (step_ok(y, x, NOMONST, tp) &&
                    689:                     (off(*tp, ISFLEE) || ch != PLAYER))
                    690:                 {
                    691:
                    692:                     /*
                    693:                      * If it is a trap, an intelligent
                    694:                      * monster may not step on it (unless
                    695:                      * our hero is on top!)
                    696:                      */
                    697:
                    698:                     if (isatrap(ch))
                    699:                     {
                    700:                         if (!(ch == RUSTTRAP) &&
                    701:                             !(ch == FIRETRAP && on(*tp, NOFIRE)) &&
                    702:                             rnd(10) < tp->t_stats.s_intel &&
                    703:                         (y != hero.y || x != hero.x))
                    704:                             continue;
                    705:                     }
                    706:
                    707:                     /*
                    708:                      * OK -- this place counts
                    709:                      */
                    710:
                    711:                     thisdist = DISTANCE(tryp, *ee);
                    712:
                    713:                     /*
                    714:                      * Adjust distance if we are being
                    715:                      * shot at to moving out of line of sight.
                    716:                      */
                    717:
                    718:                     if (tp->t_wasshot && tp->t_stats.s_intel > 5 &&
                    719:                         ce(hero, *ee))
                    720:                     {
                    721:                         /* Move out of line of sight */
                    722:                         if (straight_shot(tryp.y, tryp.x, ee->y, ee->x, NULL))
                    723:                         {
                    724:                             if (flee)
                    725:                                 thisdist -= SHOTPENALTY;
                    726:                             else
                    727:                                 thisdist += SHOTPENALTY;
                    728:                         }
                    729:
                    730:                         /*
                    731:                          * But do we want to leave
                    732:                          * the room?
                    733:                          */
                    734:                         else if (rer && rer == ree && ch == DOOR)
                    735:                             thisdist += DOORPENALTY;
                    736:                     }
                    737:
                    738:                     /*
                    739:                      * Don't move to the last position if
                    740:                      * we can help it
                    741:                      */
                    742:
                    743:                     if (ce(tryp, tp->t_oldpos))
                    744:                         dist_to_old = thisdist;
                    745:                     else if ((flee && (thisdist > dist)) ||
                    746:                          (!flee && (thisdist < dist)))
                    747:                     {
                    748:                         tp->t_nxtpos = tryp;
                    749:                         dist = thisdist;
                    750:                     }
                    751:                 }
                    752:             }
                    753:
                    754:         /*
                    755:          * If we are running from the player and he is in our way, go
                    756:          * ahead and slug him.
                    757:          */
                    758:
                    759:         if (next_player && DISTANCE(*er,*ee) < dist &&
                    760:             step_ok(tp->t_chasee->t_pos.y, tp->t_chasee->t_pos.x, NOMONST, tp))
                    761:         {
                    762:             tp->t_nxtpos = tp->t_chasee->t_pos;    /* Okay to hit player */
                    763:             return(FALSE);
                    764:         }
                    765:
                    766:
                    767:         /*
                    768:          * If we can't get closer to the player (if that's our goal)
                    769:          * because other monsters are in the way, just stay put
                    770:          */
                    771:
                    772:         if (!flee && ce(hero, *ee) && monst_dist < INT_MAX &&
                    773:             DISTANCE(*er, hero) < dist)
                    774:             tp->t_nxtpos = *er;
                    775:
                    776:         /* Do we want to go back to the last position? */
                    777:         else if (dist_to_old != INT_MIN &&   /* It is possible to move back */
                    778:              ((flee && dist == 0) ||        /* No other possible moves */
                    779:               (!flee && dist == INT_MAX)))
                    780:         {
                    781:             /* Do we move back or just stay put (default)? */
                    782:
                    783:             dist = DISTANCE(*er,*ee); /* Current distance */
                    784:
                    785:             if (!flee || (flee && (dist_to_old > dist)))
                    786:                 tp->t_nxtpos = tp->t_oldpos;
                    787:         }
                    788:     }
                    789:
                    790:     /* Make sure we have the real distance now */
                    791:     dist = DISTANCE(tp->t_nxtpos, *ee);
                    792:
                    793:     /* Mark monsters in a wall */
                    794:
                    795:     switch(mvinch(tp->t_nxtpos.y, tp->t_nxtpos.x))
                    796:     {
                    797:         case WALL:
                    798:         case '-':
                    799:         case '|':
                    800:             turn_on(*tp, ISINWALL);
                    801:             break;
                    802:         default:
                    803:             turn_off(*tp, ISINWALL);
                    804:     }
                    805:
                    806:     if (off(*tp, ISFLEE) &&
                    807:         !(!SAME_POS((tp->t_chasee->t_pos),hero) || off(player, ISINWALL) || on(*tp, CANINWALL)))
                    808:         return(dist != 0);
                    809:     else /* May actually hit here from a confused move */
                    810:         return(!ce(tp->t_nxtpos, hero));
                    811: }
                    812:
                    813: /*
                    814:     roomin(coord *cp)
                    815:
                    816:         Find what room some coordinates are in.
                    817:         NULL means they aren't in any room.
                    818: */
                    819:
                    820: struct room *
                    821: roomin(coord cp)
                    822: {
                    823:     struct room *rp;
                    824:     int i;
                    825:
                    826:     for (i = 0; i < MAXROOMS; i++)
                    827:     {
                    828:         rp = &rooms[i];
                    829:
                    830:         if ((cp.x <= (rp->r_pos.x + (rp->r_max.x - 1))) &&
                    831:             (cp.y <= (rp->r_pos.y + (rp->r_max.y - 1))) &&
                    832:             (cp.x >= rp->r_pos.x)                       &&
                    833:             (cp.y >= rp->r_pos.y))
                    834:         {
                    835:             return(rp);
                    836:         }
                    837:     }
                    838:
                    839:     return(NULL);
                    840: }
                    841:
                    842: /*
                    843:  * find_mons: Find the monster from his corrdinates
                    844:  */
                    845:
                    846: struct linked_list  *
                    847: find_mons(int y, int x)
                    848: {
                    849:     struct linked_list  *item;
                    850:
                    851:     for (item = mlist; item != NULL; item = next(item))
                    852:     {
                    853:         struct thing *th = THINGPTR(item);
                    854:
                    855:         if (th->t_pos.y == y && th->t_pos.x == x)
                    856:             return item;
                    857:     }
                    858:     return NULL;
                    859: }
                    860:
                    861: /*
                    862:  * Find an unfriendly monster around us to hit
                    863:  */
                    864:
                    865: struct linked_list  *
                    866: f_mons_a(int y, int x, int hit_bad)
                    867: {
                    868:     int row, col;
                    869:     struct linked_list  *item;
                    870:     struct thing    *tp;
                    871:
                    872:     for (row = x - 1; row <= x + 1; row++)
                    873:         for (col = y - 1; col <= y + 1; col++)
                    874:             if (row == x && col == y)
                    875:                 continue;
                    876:             else if (col > 0 && row > 0 &&
                    877:                 isalpha(mvwinch(mw, col, row)) &&
                    878:                  ((item = find_mons(col, row)) != NULL))
                    879:             {
                    880:                 tp = THINGPTR(item);
                    881:                 if ((good_monster(*tp) && !hit_bad) ||
                    882:                     (!good_monster(*tp) && hit_bad))
                    883:                     return (item);
                    884:             }
                    885:
                    886:     return (NULL);
                    887: }
                    888:
                    889:
                    890: /*
                    891:     diag_ok()
                    892:         Check to see if the move is legal if it is diagonal
                    893: */
                    894:
                    895: int
                    896: diag_ok(coord *sp, coord *ep, struct thing *flgptr)
                    897: {
                    898:     if (ep->x == sp->x || ep->y == sp->y)
                    899:         return TRUE;
                    900:
                    901:     return (step_ok(ep->y, sp->x, MONSTOK, flgptr) &&
                    902:         step_ok(sp->y, ep->x, MONSTOK, flgptr));
                    903: }
                    904:
                    905: /*
                    906:     cansee()
                    907:         returns true if the hero can see a certain coordinate.
                    908: */
                    909:
                    910: int
                    911: cansee(int y, int x)
                    912: {
                    913:     struct room *rer;
                    914:     coord   tp;
                    915:
                    916:     if (on(player, ISBLIND))
                    917:         return FALSE;
                    918:
                    919:     tp.y = y;
                    920:     tp.x = x;
                    921:     rer = roomin(tp);
                    922:
                    923:     /*
                    924:      * We can only see if the hero in the same room as the coordinate and
                    925:      * the room is lit or if it is close.
                    926:      */
                    927:
                    928:     return ((rer != NULL &&
                    929:          rer == roomin(hero) &&
                    930:          (!(rer->r_flags & ISDARK) || (rer->r_flags & HASFIRE)) &&
                    931:          (levtype != MAZELEV || /* Maze level needs direct line */
                    932:           maze_view(tp.y, tp.x))) ||
                    933:         DISTANCE(tp,hero) < see_dist);
                    934: }
                    935:
                    936: coord   *
                    937: find_shoot(struct thing *tp, coord *dir)
                    938: {
                    939:     struct room *rtp;
                    940:     int ulx, uly, xmx, ymx, xmon, ymon, tpx, tpy, row, col;
                    941:     struct linked_list  *mon;
                    942:     struct thing    *ick;
                    943:
                    944:     rtp = roomin(tp->t_pos);   /* Find room of chaser */
                    945:
                    946:     if (rtp == NULL)
                    947:         return NULL;
                    948:
                    949:     ulx = rtp->r_pos.x;
                    950:     uly = rtp->r_pos.y;
                    951:     xmx = rtp->r_max.x;
                    952:     ymx = rtp->r_max.y;
                    953:
                    954:     tpx = tp->t_pos.x;
                    955:     tpy = tp->t_pos.y;
                    956:
                    957:     for (col = ulx; col < (ulx + xmx); col++)
                    958:         for (row = uly; row < (uly + ymx); row++)
                    959:         {
                    960:             if (row > 0 && col > 0 && isalpha(mvwinch(mw, row, col)))
                    961:             {
                    962:                mon = find_mons(row, col);
                    963:
                    964:                 if (mon)
                    965:                 {
                    966:                     ick = THINGPTR(mon);
                    967:                     xmon = ick->t_pos.x;
                    968:                     ymon = ick->t_pos.y;
                    969:
                    970:                     if (!(good_monster(*ick)))
                    971:                     {
                    972:                         if (straight_shot(tpy, tpx, ymon, xmon, dir))
                    973:                             return(dir);
                    974:                     }
                    975:                 }
                    976:             }
                    977:         }
                    978:
                    979:     return(NULL);
                    980: }
                    981:
                    982: /*
                    983:     can_shoot()
                    984:         determines if the monster (er) has a direct line of shot at the
                    985:         player (ee).  If so, it returns the direction in which to shoot.
                    986: */
                    987:
                    988: coord *
                    989: can_shoot(coord *er, coord *ee, coord *dir)
                    990: {
                    991:     int ery, erx, eey, eex;
                    992:
                    993:     /* Make sure we are chasing the player */
                    994:
                    995:     if (!ce((*ee), hero))
                    996:         return(NULL);
                    997:
                    998:     /* They must be in the same room */
                    999:
                   1000:     if (roomin(*er) != roomin(hero))
                   1001:         return(NULL);
                   1002:
                   1003:     ery = er->y;
                   1004:     erx = er->x;
                   1005:     eey = ee->y;
                   1006:     eex = ee->x;
                   1007:
                   1008:     /* Will shoot unless next to player, then 80% prob will fight */
                   1009:
                   1010:     if ((DISTANCE(*er,*ee) < 4) && (rnd(100) < 80))
                   1011:         return(NULL);
                   1012:
                   1013:     /* Do we have a straight shot? */
                   1014:
                   1015:     if (!straight_shot(ery, erx, eey, eex, dir))
                   1016:         return(NULL);
                   1017:     else
                   1018:         return(dir);
                   1019: }
                   1020:
                   1021: /*
                   1022:     straight_shot()
                   1023:         See if there is a straight line of sight between the two
                   1024:         given coordinates.  If shooting is not NULL, it is a pointer to a
                   1025:         structure which should be filled with the direction to shoot (if
                   1026:         there is a line of sight).  If shooting, monsters get in the way.
                   1027:         Otherwise, they do not.
                   1028: */
                   1029:
                   1030: int
                   1031: straight_shot(int ery, int erx, int eey, int eex, coord *dir)
                   1032: {
                   1033:     int dy, dx; /* Deltas */
                   1034:     int ch;
                   1035:
                   1036:     /* Does the monster have a straight shot at player */
                   1037:
                   1038:     if ((ery != eey) && (erx != eex) &&
                   1039:         (abs(ery - eey) != abs(erx - eex)))
                   1040:         return (FALSE);
                   1041:
                   1042:     /* Get the direction to shoot */
                   1043:
                   1044:     if (eey > ery)
                   1045:         dy = 1;
                   1046:     else if (eey == ery)
                   1047:         dy = 0;
                   1048:     else
                   1049:         dy = -1;
                   1050:
                   1051:     if (eex > erx)
                   1052:         dx = 1;
                   1053:     else if (eex == erx)
                   1054:         dx = 0;
                   1055:     else
                   1056:         dx = -1;
                   1057:
                   1058:     /* Make sure we have free area all the way to the player */
                   1059:
                   1060:     ery += dy;
                   1061:     erx += dx;
                   1062:
                   1063:     while ((ery != eey) || (erx != eex))
                   1064:     {
                   1065:         switch(ch = winat(ery, erx))
                   1066:         {
                   1067:             case '|':
                   1068:             case '-':
                   1069:             case WALL:
                   1070:             case DOOR:
                   1071:             case SECRETDOOR:
                   1072:                 return(FALSE);
                   1073:             default:
                   1074:                 if (dir && isalpha(ch))
                   1075:                     return(FALSE);
                   1076:         }
                   1077:
                   1078:         ery += dy;
                   1079:         erx += dx;
                   1080:     }
                   1081:
                   1082:     if (dir)
                   1083:     {     /* If we are shooting -- put in the directions */
                   1084:         dir->y = dy;
                   1085:         dir->x = dx;
                   1086:     }
                   1087:
                   1088:     return(TRUE);
                   1089: }
                   1090:
                   1091: /*
                   1092:     get_hurl
                   1093:         returns the weapon that the monster will "throw" if it has one
                   1094: */
                   1095:
                   1096: struct linked_list  *
                   1097: get_hurl(struct thing *tp)
                   1098: {
                   1099:     struct linked_list  *arrow,  *bolt,      *rock, *silverarrow, *fbbolt;
                   1100:     struct linked_list  *bullet, *firearrow, *dart, *dagger,      *shuriken;
                   1101:     struct linked_list  *oil,    *grenade;
                   1102:
                   1103:     struct linked_list  *pitem;
                   1104:     int bow = FALSE, crossbow = FALSE, sling = FALSE, footbow = FALSE;
                   1105:
                   1106:     /* Don't point to anything to begin with */
                   1107:
                   1108:     arrow = bolt = rock = silverarrow = fbbolt = NULL;
                   1109:     bullet = firearrow = dart = dagger = shuriken = NULL;
                   1110:     oil = grenade = NULL;
                   1111:
                   1112:     for (pitem = tp->t_pack; pitem != NULL; pitem = next(pitem))
                   1113:         if ((OBJPTR(pitem))->o_type == WEAPON)
                   1114:             switch ((OBJPTR(pitem))->o_which)
                   1115:             {
                   1116:                 case    BOW:bow = TRUE; break;
                   1117:                 case    CROSSBOW:crossbow = TRUE; break;
                   1118:                 case    SLING:sling = TRUE; break;
                   1119:                 case    FOOTBOW:footbow = TRUE; break;
                   1120:                 case    ROCK:rock = pitem; break;
                   1121:                 case    ARROW:arrow = pitem; break;
                   1122:                 case    SILVERARROW:silverarrow = pitem; break;
                   1123:                 case    BOLT:bolt = pitem; break;
                   1124:                 case    FBBOLT:fbbolt = pitem; break;
                   1125:                 case    BULLET:bullet = pitem; break;
                   1126:                 case    FLAMEARROW:firearrow = pitem; break;
                   1127:                 case    DART:dart = pitem; break;
                   1128:                 case    DAGGER:dagger = pitem; break;
                   1129:                 case    SHURIKEN:shuriken = pitem; break;
                   1130:                 case    MOLOTOV:oil = pitem; break;
                   1131:                 case    GRENADE:shuriken = pitem; break;
                   1132:             }
                   1133:
                   1134:     if (bow && silverarrow)
                   1135:         return(silverarrow);
                   1136:
                   1137:     if (crossbow && bolt)
                   1138:         return(bolt);
                   1139:
                   1140:     if (bow && firearrow)
                   1141:         return(firearrow);
                   1142:
                   1143:     if (off(*tp, ISCHARMED) && oil)
                   1144:         return(oil);
                   1145:
                   1146:     if (off(*tp, ISCHARMED) && grenade)
                   1147:         return(grenade);
                   1148:
                   1149:     if (footbow && fbbolt)
                   1150:         return(fbbolt);
                   1151:
                   1152:     if (bow && arrow)
                   1153:         return(arrow);
                   1154:
                   1155:     if (sling && bullet)
                   1156:         return(bullet);
                   1157:
                   1158:     if (sling && rock)
                   1159:         return(rock);
                   1160:
                   1161:     if (shuriken)
                   1162:         return(shuriken);
                   1163:
                   1164:     if (dagger)
                   1165:         return(dagger);
                   1166:
                   1167:     if (silverarrow)
                   1168:         return(silverarrow);
                   1169:
                   1170:     if (firearrow)
                   1171:         return(firearrow);
                   1172:
                   1173:     if (fbbolt)
                   1174:         return(fbbolt);
                   1175:
                   1176:     if (bolt)
                   1177:         return(bolt);
                   1178:
                   1179:     if (bullet)
                   1180:         return(bullet);
                   1181:
                   1182:     if (dart)
                   1183:         return(dart);
                   1184:
                   1185:     if (rock)
                   1186:         return(rock);
                   1187:
                   1188:     return(NULL);
                   1189: }
                   1190:
                   1191: /*
                   1192:     pick_weap()
                   1193:         returns the biggest weapon that the monster will wield if it
                   1194:         has a non-launching or non-missile weapon returns NULL if no weapon, or
                   1195:         bare hands is better
                   1196: */
                   1197:
                   1198: struct object *
                   1199: pick_weap(struct thing *tp)
                   1200: {
                   1201:     int weap_dam = maxdamage(tp->t_stats.s_dmg);
                   1202:     struct object   *ret_obj = NULL;
                   1203:     struct linked_list  *pitem;
                   1204:
                   1205:     if (on(*tp, CANWIELD))
                   1206:     {
                   1207:         for (pitem = tp->t_pack; pitem != NULL; pitem = next(pitem))
                   1208:         {
                   1209:             struct object   *obj = OBJPTR(pitem);
                   1210:
                   1211:             if (obj->o_type != WEAPON && !(obj->o_flags&(ISLAUNCHER|ISMISL)) &&
                   1212:                 maxdamage(obj->o_damage) > weap_dam)
                   1213:             {
                   1214:                 weap_dam = maxdamage(obj->o_damage);
                   1215:                 ret_obj = obj;
                   1216:             }
                   1217:         }
                   1218:     }
                   1219:
                   1220:     return (ret_obj);
                   1221: }
                   1222:
                   1223: /*
                   1224:     canblink()
                   1225:         checks if the monster can teleport (blink).  If so, it will try
                   1226:         to blink the monster next to the player.
                   1227: */
                   1228:
                   1229: int
                   1230: can_blink(struct thing *tp)
                   1231: {
                   1232:     int   y, x, index = 9;
                   1233:     coord   tryp;       /* To hold the coordinates for use in diag_ok */
                   1234:     int    spots[9], found_one = FALSE;
                   1235:
                   1236:     /*
                   1237:      * First, can the monster even blink?  And if so, there is only a 30%
                   1238:      * chance that it will do so.  And it won't blink if it is running.
                   1239:      */
                   1240:
                   1241:     if (off(*tp, CANBLINK) || (on(*tp, ISHELD)) ||
                   1242:         on(*tp, ISFLEE) ||
                   1243:         (on(*tp, ISSLOW) && off(*tp, ISHASTE) && !(tp->t_turn)) ||
                   1244:         (rnd(10) < 9))
                   1245:         return (FALSE);
                   1246:
                   1247:     /* Initialize the spots as illegal */
                   1248:
                   1249:     do
                   1250:     {
                   1251:         spots[--index] = FALSE;
                   1252:     }
                   1253:     while (index > 0);
                   1254:
                   1255:     /* Find a suitable spot next to the player */
                   1256:
                   1257:     for (y = hero.y - 1; y < hero.y + 2; y++)
                   1258:         for (x = hero.x - 1; x < hero.x + 2; x++, index++)
                   1259:         {
                   1260:             /*
                   1261:              * Make sure x coordinate is in range and that we are
                   1262:              * not at the player's position
                   1263:              */
                   1264:
                   1265:             if (x < 0 || x >= COLS || index == 4)
                   1266:                 continue;
                   1267:
                   1268:             /* Is it OK to move there? */
                   1269:
                   1270:             if (!step_ok(y, x, NOMONST, tp))
                   1271:                 spots[index] = FALSE;
                   1272:            else
                   1273:            {
                   1274:
                   1275:                 /*
                   1276:                  * OK, we can go here.  But don't go there if
                   1277:                  * monster can't get at player from there
                   1278:                  */
                   1279:
                   1280:                 tryp.y = y;
                   1281:                 tryp.x = x;
                   1282:                 if (diag_ok(&tryp, &hero, tp))
                   1283:                 {
                   1284:                     spots[index] = TRUE;
                   1285:                     found_one = TRUE;
                   1286:                 }
                   1287:             }
                   1288:         }
                   1289:
                   1290:     /* If we found one, go to it */
                   1291:
                   1292:     if (found_one)
                   1293:     {
                   1294:         /* Find a legal spot */
                   1295:
                   1296:         while (spots[index = rnd(9)] == FALSE)
                   1297:             continue;
                   1298:
                   1299:         /* Get the coordinates */
                   1300:
                   1301:         y = hero.y + (index / 3) - 1;
                   1302:         x = hero.x + (index % 3) - 1;
                   1303:
                   1304:         /* Move the monster from the old space */
                   1305:
                   1306:         mvwaddch(cw, tp->t_pos.y, tp->t_pos.x, tp->t_oldch);
                   1307:
                   1308:         /* Move it to the new space */
                   1309:
                   1310:         tp->t_oldch = CCHAR( mvwinch(cw, y, x) );
                   1311:
                   1312:         if (cansee(y, x) &&
                   1313:             off(*tp, ISINWALL) &&
                   1314:             ((off(*tp, ISINVIS) &&
                   1315:               (off(*tp, ISSHADOW) || rnd(100) < 10)) || on(player, CANSEE)) &&
                   1316:             off(*tp, CANSURPRISE))
                   1317:             mvwaddch(cw, y, x, tp->t_type);
                   1318:
                   1319:         mvwaddch(mw, tp->t_pos.y,tp->t_pos.x,' '); /*Clear old position */
                   1320:         mvwaddch(mw, y, x, tp->t_type);
                   1321:         tp->t_pos.y = y;
                   1322:         tp->t_pos.x = x;
                   1323:     }
                   1324:
                   1325:     return (found_one);
                   1326: }

CVSweb