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

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

1.1       rubenllo    1: /*
                      2:     move.c - Hero movement commands
                      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 "rogue.h"
                     22:
                     23: /*
                     24:     do_run()
                     25:         Start the hero running
                     26: */
                     27:
                     28: void
                     29: do_run(char ch)
                     30: {
                     31:     running = TRUE;
                     32:     after = FALSE;
                     33:     runch = ch;
                     34:
                     35:     if (doorstop && !on(player, ISBLIND))
                     36:     {
                     37:         door_stop = TRUE;
                     38:         firstmove = TRUE;
                     39:     }
                     40: }
                     41:
                     42: /*
                     43:     step_ok()
                     44:         returns true if it is ok for type to step on ch flgptr will be
                     45:         NULL if we don't know what the monster is yet!
                     46: */
                     47:
                     48: int
                     49: step_ok(int y, int x, int can_on_monst, struct thing *flgptr)
                     50: {
                     51:     struct linked_list *item;
                     52:     char ch;
                     53:
                     54:     /* What is here?  Don't check monster window if MONSTOK is set */
                     55:
                     56:     if (can_on_monst == MONSTOK)
                     57:         ch = CCHAR( mvinch(y, x) );
                     58:     else
                     59:         ch = winat(y, x);
                     60:
                     61:     switch (ch)
                     62:     {
                     63:         case ' ':
                     64:         case '|':
                     65:         case '-':
                     66:         case SECRETDOOR:
                     67:             if (flgptr && on(*flgptr, CANINWALL))
                     68:                 return(TRUE);
                     69:
                     70:             return(FALSE);
                     71:
                     72:         case SCROLL:
                     73:             /*
                     74:              * If it is a scroll, it might be a scare monster scroll so
                     75:              * we need to look it up to see what type it is.
                     76:              */
                     77:
                     78:             if (flgptr && flgptr->t_ctype == C_MONSTER)
                     79:             {
                     80:                 item = find_obj(y, x);
                     81:
                     82:                 if (item != NULL && (OBJPTR(item))->o_type == SCROLL
                     83:                      && (OBJPTR(item))->o_which == S_SCARE
                     84:                      && rnd(flgptr->t_stats.s_intel) < 12)
                     85:                 return(FALSE); /* All but smart ones are scared */
                     86:             }
                     87:             return(TRUE);
                     88:
                     89:         default:
                     90:             return(!isalpha(ch));
                     91:     }
                     92: }
                     93:
                     94: /*
                     95:     corr_move()
                     96:         Check to see that a move is legal.  If so, return correct
                     97:         character. If not, if player came from a legal place, then try to turn
                     98:         him.
                     99: */
                    100:
                    101: void
                    102: corr_move(int dy, int dx)
                    103: {
                    104:     char    ch;
                    105:     short   legal = 0;  /* Number of legal alternatives */
                    106:     int     y = 0, x = 0;   /* Holds legal new position */
                    107:     int    *ny, *nx;    /* Point to which direction to change */
                    108:
                    109:     /* New position */
                    110:
                    111:     player.t_nxtpos.y = hero.y + dy;
                    112:     player.t_nxtpos.x = hero.x + dx;
                    113:
                    114:     /* A bad diagonal move is illegal */
                    115:
                    116:     if (!diag_ok(&hero, &player.t_nxtpos, &player))
                    117:         return;
                    118:
                    119:     /* If it is a legal move, just return */
                    120:
                    121:     if (player.t_nxtpos.x >= 0 && player.t_nxtpos.x < COLS && player.t_nxtpos.y > 0 && player.t_nxtpos.y < LINES - 2)
                    122:     {
                    123:         ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
                    124:
                    125:         switch (ch)
                    126:         {
                    127:             case ' ':
                    128:             case '|':
                    129:             case '-':
                    130:                 break;
                    131:             default:
                    132:                 return;
                    133:         }
                    134:     }
                    135:
                    136:     /* Check the legal alternatives */
                    137:
                    138:     if (dy == 0)
                    139:     {
                    140:         ny = &dy;
                    141:         nx = &dx;
                    142:     }
                    143:     else
                    144:     {
                    145:         ny = &dx;
                    146:         nx = &dy;
                    147:     }
                    148:
                    149:     for (*nx = 0, *ny = -1; *ny < 2; *ny += 2)
                    150:     {
                    151:         /* New position */
                    152:         player.t_nxtpos.y = hero.y + dy;
                    153:         player.t_nxtpos.x = hero.x + dx;
                    154:
                    155:         if (player.t_nxtpos.x < 0 || player.t_nxtpos.x > COLS - 1 || player.t_nxtpos.y < 1 || player.t_nxtpos.y > LINES - 3)
                    156:             continue;
                    157:
                    158:         ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
                    159:
                    160:         switch (ch)
                    161:         {
                    162:             case ' ':
                    163:             case '|':
                    164:             case '-':
                    165:                 break;
                    166:             default:
                    167:                 legal++;
                    168:                 y = dy;
                    169:                 x = dx;
                    170:         }
                    171:     }
                    172:
                    173:     /* If we have 2 legal moves, make no change */
                    174:
                    175:     if (legal != 1)
                    176:         return;
                    177:
                    178:     /* Make the change */
                    179:
                    180:     if (y == 0)         /* Move horizontally */
                    181:     {
                    182:         if (x == 1)
                    183:             runch = 'l';
                    184:         else
                    185:             runch = 'h';
                    186:     }
                    187:     else            /* Move vertically */
                    188:     {
                    189:         if (y == 1)
                    190:             runch = 'j';
                    191:         else
                    192:             runch = 'k';
                    193:     }
                    194:
                    195:     return;
                    196: }
                    197:
                    198:
                    199: /*
                    200:     do_move()
                    201:         Check to see that a move is legal.  If it is handle the
                    202:         consequences (fighting, picking up, etc.)
                    203: */
                    204:
                    205: void
                    206: do_move(int dy, int dx)
                    207: {
                    208:     char    ch;
                    209:     coord   old_hero;
                    210:     char    hch;
                    211:
                    212:     firstmove = FALSE;
                    213:
                    214:     if (player.t_no_move)
                    215:     {
                    216:         player.t_no_move--;
                    217:         msg("You are still stuck in the bear trap.");
                    218:         return;
                    219:     }
                    220:
                    221:     /* Do a confused move (maybe) */
                    222:
                    223:     if ((rnd(100) < 80 && on(player, ISHUH)) ||
                    224:         (is_wearing(R_DELUSION) && rnd(100) < 25) ||
                    225:         on(player, STUMBLER) && rnd(40) == 0)
                    226:         player.t_nxtpos = rndmove(&player);
                    227:     else
                    228:     {
                    229:         player.t_nxtpos.y = hero.y + dy;
                    230:         player.t_nxtpos.x = hero.x + dx;
                    231:     }
                    232:
                    233:     /*
                    234:      * Check if he tried to move off the screen or make an illegal
                    235:      * diagonal move, and stop him if he did.
                    236:      */
                    237:
                    238:     if (player.t_nxtpos.x < 0 || player.t_nxtpos.x > COLS - 1 || player.t_nxtpos.y < 1 || player.t_nxtpos.y >= LINES - 2
                    239:         || !diag_ok(&hero, &player.t_nxtpos, &player))
                    240:     {
                    241:         after = fighting = running = FALSE;
                    242:         return;
                    243:     }
                    244:
                    245:     if (running && ce(hero, player.t_nxtpos))
                    246:         after = running = FALSE;
                    247:
                    248:     ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
                    249:
                    250:        if (isalpha(ch))
                    251:            debug("Moving onto monster %c",ch);
                    252:
                    253:        /* Take care of hero trying to move close to something frightening */
                    254:
                    255:        if (on(player, ISFLEE))
                    256:     {
                    257:         if (rnd(10) < 1)
                    258:         {
                    259:             turn_off(player, ISFLEE);
                    260:             msg("You regain your composure.");
                    261:         }
                    262:         else if (DISTANCE(player.t_nxtpos, player.t_chasee->t_pos) <
                    263:                  DISTANCE(hero,player.t_chasee->t_pos))
                    264:             return;
                    265:     }
                    266:
                    267:     /* Take care of hero being held */
                    268:
                    269:     if (on(player, ISHELD) && !isalpha(ch))
                    270:     {
                    271:         if (rnd(pstats.s_str) > 14)
                    272:         {
                    273:             msg("You break free of the hold.");
                    274:
                    275:             if (--hold_count == 0)
                    276:                 turn_off(player, ISHELD);
                    277:         }
                    278:         else
                    279:         {
                    280:             msg("You are being held.");
                    281:             return;
                    282:         }
                    283:     }
                    284:
                    285:     /* Might lose disguise */
                    286:
                    287:     if (on(player, ISDISGUISE) && rnd(11 * pstats.s_dext) == 0)
                    288:     {
                    289:         extinguish_fuse(FUSE_UNDISGUISE);
                    290:         undisguise(NULL);
                    291:     }
                    292:
                    293:     /* assume he's not in a wall */
                    294:
                    295:     if (!isalpha(ch))
                    296:         turn_off(player, ISINWALL);
                    297:
                    298:     hch = CCHAR( mvinch(hero.y, hero.x) );   /* Where hero was */
                    299:     old_hero = hero;    /* Save hero's old position */
                    300:
                    301:     switch (ch)
                    302:     {
                    303:         case ' ':
                    304:         case '|':
                    305:         case '-':
                    306:         case SECRETDOOR:
                    307:             if (off(player, CANINWALL))
                    308:             {
                    309:                 after = running = FALSE;
                    310:                 return;
                    311:             }
                    312:             else if (running)
                    313:             {
                    314:                 after = running = FALSE;
                    315:                 return;
                    316:             }
                    317:             turn_on(player, ISINWALL);
                    318:             break;
                    319:
                    320:         case TRAPDOOR:
                    321:         case TELTRAP:
                    322:         case BEARTRAP:
                    323:         case SLEEPTRAP:
                    324:         case ARROWTRAP:
                    325:         case DARTTRAP:
                    326:         case POOL:
                    327:         case MAZETRAP:
                    328:         case FIRETRAP:
                    329:         case POISONTRAP:
                    330:         case LAIR:
                    331:         case RUSTTRAP:
                    332:             ch = be_trapped(&player, player.t_nxtpos);
                    333:
                    334:             if (!is_wearing(R_LEVITATION) && off(player, CANFLY) &&
                    335:                 (old_hero.x != hero.x || old_hero.y != hero.y
                    336:                  || pool_teleport))
                    337:             {
                    338:                 pool_teleport = FALSE;
                    339:                 return;
                    340:             }
                    341:
                    342:             break;
                    343:
                    344:         case GOLD:
                    345:         case POTION:
                    346:         case SCROLL:
                    347:         case FOOD:
                    348:         case WEAPON:
                    349:         case ARMOR:
                    350:         case RING:
                    351:         case ARTIFACT:
                    352:         case STICK:
                    353:             running = FALSE;
                    354:             take = ch;
                    355:             break;
                    356:
                    357:         default:
                    358:             break;
                    359:     }
                    360:
                    361:     if (ch == FIRETRAP)
                    362:         light(&hero);
                    363:
                    364:     hero = player.t_nxtpos;      /* Move the hero */
                    365:
                    366:        /* adjust lighting */
                    367:
                    368:     if (roomin(hero) == NULL && (hch == '-' || hch == '|' ||
                    369:         hch == DOOR || hch == SECRETDOOR))
                    370:     {
                    371:         /* Leaving a room -- darken it */
                    372:         struct room *rp = roomin(old_hero);
                    373:         int    is_lit = FALSE;
                    374:
                    375:         if (!(rp->r_flags & ISDARK))
                    376:             is_lit = TRUE;
                    377:
                    378:         rp->r_flags |= ISDARK;  /* Fake darkness */
                    379:         light(&old_hero);
                    380:
                    381:         if (is_lit)
                    382:             rp->r_flags &= ~ISDARK; /* Restore light state */
                    383:     }
                    384:     else if (ch == DOOR || ch == SECRETDOOR || ch == '|' || ch == '-')
                    385:     {
                    386:         /* Entering a room */
                    387:         running = FALSE;
                    388:         if (hch != '|' && hch != '-')
                    389:             light(&hero);   /* knows whether the hero can see things in */
                    390:     }
                    391:
                    392:        /* handle other situations */
                    393:
                    394:     if (ch == STAIRS)
                    395:         running = FALSE;
                    396:     else if (ch == POST)
                    397:     {
                    398:         running = FALSE;
                    399:         new_level(POSTLEV,0);
                    400:         return;
                    401:     }
                    402:     else if (isalpha(ch))
                    403:     {
                    404:         struct linked_list  *mp;
                    405:         struct thing    *tp;
                    406:         char t;
                    407:
                    408:         running = FALSE;
                    409:
                    410:         mp = find_mons(hero.y, hero.x);
                    411:
                    412:         if (mp == NULL)
                    413:             return;
                    414:
                    415:         tp = THINGPTR(mp);
                    416:
                    417:         if (good_monster(*tp))  /* Exchange places with your buddy */
                    418:         {
                    419:             mvwaddch(cw, old_hero.y, old_hero.x, ch);
                    420:             mvwaddch(mw, old_hero.y, old_hero.x, ch);
                    421:             mvwaddch(mw, hero.y, hero.x, ' ');
                    422:             mvwaddch(cw, hero.y, hero.x, tp->t_oldch);
                    423:
                    424:             (*tp).t_pos.x = old_hero.x; /* Update monster position variables */
                    425:             (*tp).t_pos.y = old_hero.y;
                    426:             (*tp).t_oldpos.x = old_hero.x;
                    427:             (*tp).t_oldpos.y = old_hero.y;
                    428:
                    429:             t = (*tp).t_oldch;
                    430:             (*tp).t_oldch = player.t_oldch;
                    431:             player.t_oldch = t;
                    432:
                    433:             turn_on(*tp, ISRUN);
                    434:
                    435:             mvwaddch(cw, hero.y, hero.x, PLAYER);
                    436:
                    437:                        /* make sure that the room shows OK */
                    438:
                    439:                        light(&hero);
                    440:
                    441:             wrefresh(cw);
                    442:             return;
                    443:         }
                    444:         else
                    445:         {
                    446:             hero = old_hero; /* Restore hero -- we'll fight instead of move */
                    447:
                    448:                        /* make sure that the room shows OK */
                    449:                light(&hero);
                    450:
                    451:             fight(&player.t_nxtpos, cur_weapon, NOTHROWN);
                    452:
                    453:             return;
                    454:         }
                    455:     }
                    456:     else
                    457:         fighting = FALSE;
                    458:
                    459:     ch = winat(old_hero.y, old_hero.x);
                    460:     mvwaddch(cw, old_hero.y, old_hero.x, ch);
                    461:     mvwaddch(cw, hero.y, hero.x, PLAYER);
                    462: }
                    463:
                    464: /*
                    465:     light()
                    466:         Called to illuminate a room. If it is dark, remove anything that might
                    467:         move.
                    468: */
                    469:
                    470: void
                    471: light(coord *cp)
                    472: {
                    473:     struct room *rp;
                    474:     int j, k, x, y;
                    475:     char    ch, rch;
                    476:     struct linked_list  *item;
                    477:     int jlow, jhigh, klow, khigh;   /* Boundaries of lit area */
                    478:
                    479:     if ((rp = roomin(*cp)) != NULL && !on(player, ISBLIND))
                    480:     {
                    481:
                    482:         /* is he wearing ring of illumination and in same room? */
                    483:
                    484:         if ((is_wearing(R_LIGHT) || on(player, ISELECTRIC)) &&
                    485:             cp == &hero)
                    486:             rp->r_flags &= ~ISDARK;
                    487:
                    488:         /* If we are in a maze, don't look at the whole room (level) */
                    489:
                    490:         if (levtype == MAZELEV)
                    491:         {
                    492:             jlow = max(0, hero.y - 2 - rp->r_pos.y);
                    493:             jhigh = min(rp->r_max.y, hero.y + 2 - rp->r_pos.y + 1);
                    494:             klow = max(0, hero.x - 2 - rp->r_pos.x);
                    495:             khigh = min(rp->r_max.x, hero.x + 2 - rp->r_pos.x + 1);
                    496:         }
                    497:         else
                    498:         {
                    499:             jlow = klow = 0;
                    500:             jhigh = rp->r_max.y;
                    501:             khigh = rp->r_max.x;
                    502:         }
                    503:
                    504:         for (j = 0; j < rp->r_max.y; j++)
                    505:         {
                    506:             for (k = 0; k < rp->r_max.x; k++)
                    507:             {
                    508:                 /* Is this in the given area -- needed for maze */
                    509:
                    510:                 if ((j < jlow || j >= jhigh) && (k < klow || k >= khigh))
                    511:                     continue;
                    512:
                    513:                 y = rp->r_pos.y + j;
                    514:                 x = rp->r_pos.x + k;
                    515:
                    516:                 ch = show(y, x);
                    517:                 wmove(cw, y, x);
                    518:
                    519:                 /* Figure out how to display a secret door */
                    520:
                    521:                 if (ch == SECRETDOOR)
                    522:                 {
                    523:                     if (j == 0 || j == rp->r_max.y - 1)
                    524:                         ch = '-';
                    525:                     else
                    526:                         ch = '|';
                    527:                 }
                    528:
                    529:                 /*
                    530:                  * For monsters, if they were previously not
                    531:                  * seen and now can be seen, or vice-versa,
                    532:                  * make sure that will happen.
                    533:                  */
                    534:
                    535:                 if (isalpha(ch))
                    536:                 {
                    537:                     struct thing    *tp;
                    538:
                    539:                     item = wake_monster(y, x);
                    540:
                    541:                     if (item == NULL)
                    542:                         continue;
                    543:
                    544:                     tp = THINGPTR(item);
                    545:
                    546:                     /* Previously not seen -- now can see it */
                    547:
                    548:                     if (tp->t_oldch == ' ' && cansee(tp->t_pos.y, tp->t_pos.x))
                    549:                         tp->t_oldch = CCHAR( mvinch(y, x) );
                    550:
                    551:                     /* Previously seen -- now can't see it */
                    552:
                    553:                     else if (off(player, ISBLIND) && tp->t_oldch != ' ' &&
                    554:                          !cansee(tp->t_pos.y, tp->t_pos.x))
                    555:                         tp->t_oldch = ' ';
                    556:                 }
                    557:
                    558:                 /*
                    559:                  * If the room is a dark room, we might want
                    560:                  * to remove monsters and the like from it
                    561:                  * (since they might move). A dark room or
                    562:                  * not in line-of-sight in a maze.
                    563:                  */
                    564:
                    565:                 if (((rp->r_flags & ISDARK) &&
                    566:                     !(rp->r_flags & HASFIRE)) ||
                    567:                     (levtype == MAZELEV &&
                    568:                      !maze_view(y, x)))
                    569:                 {
                    570:                     rch = CCHAR( mvwinch(cw, y, x) );
                    571:
                    572:                     switch (rch)
                    573:                     {
                    574:                         case DOOR:
                    575:                         case STAIRS:
                    576:                         case TRAPDOOR:
                    577:                         case TELTRAP:
                    578:                         case BEARTRAP:
                    579:                         case SLEEPTRAP:
                    580:                         case ARROWTRAP:
                    581:                         case DARTTRAP:
                    582:                         case POOL:
                    583:                         case MAZETRAP:
                    584:                         case FIRETRAP:
                    585:                         case POISONTRAP:
                    586:                         case LAIR:
                    587:                         case RUSTTRAP:
                    588:                         case POST:
                    589:                         case '|':
                    590:                         case '-':
                    591:                         case ' ':
                    592:                             ch = rch;
                    593:                             break;
                    594:
                    595:                         case    FLOOR:
                    596:                             ch = (on(player, ISBLIND) ? FLOOR : ' ');
                    597:                             break;
                    598:                         default:
                    599:                             ch = ' ';
                    600:                             break;
                    601:                     }
                    602:                 }
                    603:                 mvwaddch(cw, y, x, ch);
                    604:             }
                    605:         }
                    606:     }
                    607: }
                    608:
                    609: /*
                    610:     blue_light()
                    611:         magically light up a room (or level or make it dark)
                    612: */
                    613:
                    614: int
                    615: blue_light(int flags)
                    616: {
                    617:     struct room *rp;
                    618:     int  blessed = (flags & ISBLESSED);
                    619:     int  cursed = (flags & ISCURSED);
                    620:     int  ret_val = FALSE;   /* Whether or not affect is known */
                    621:
                    622:     rp = roomin(hero); /* What room is hero in? */
                    623:
                    624:     /* Darken the room if the magic is cursed */
                    625:
                    626:     if (cursed)
                    627:     {
                    628:         if ((rp == NULL) || (rp->r_flags & ISDARK))
                    629:             nothing_message(flags);
                    630:         else
                    631:         {
                    632:             if (!(rp->r_flags & HASFIRE))
                    633:                 msg("The room suddenly goes dark.");
                    634:             else
                    635:                 nothing_message(flags);
                    636:
                    637:             rp->r_flags |= ISDARK;
                    638:             ret_val = TRUE;
                    639:         }
                    640:     }
                    641:     else
                    642:     {
                    643:         ret_val = TRUE;
                    644:
                    645:         if (rp && (rp->r_flags & ISDARK) && !(rp->r_flags & HASFIRE))
                    646:         {
                    647:             msg("The room is lit by a %s blue light.",
                    648:                  blessed ? "bright" : "shimmering");
                    649:         }
                    650:         else if (winat(hero.y, hero.x) == PASSAGE)
                    651:             msg("The corridor glows %sand then fades.", blessed ? "brightly " : "");
                    652:         else
                    653:         {
                    654:             ret_val = FALSE;
                    655:             nothing_message(flags);
                    656:         }
                    657:
                    658:         if (blessed)
                    659:         {
                    660:             short   i;  /* Index through rooms */
                    661:
                    662:             for (i = 0; i < MAXROOMS; i++)
                    663:                 rooms[i].r_flags &= ~ISDARK;
                    664:         }
                    665:         else if (rp)
                    666:             rp->r_flags &= ~ISDARK;
                    667:     }
                    668:
                    669:     /* Light the room and put the player back up */
                    670:
                    671:     light(&hero);
                    672:     mvwaddch(cw, hero.y, hero.x, PLAYER);
                    673:
                    674:     return (ret_val);
                    675: }
                    676:
                    677: /*
                    678:     show()
                    679:         returns what a certain thing will display as to the un-initiated
                    680: */
                    681:
                    682: char
                    683: show(int y, int x)
                    684: {
                    685:     char    ch = winat(y, x);
                    686:     struct linked_list  *it;
                    687:     struct thing    *tp;
                    688:
                    689:     if (isatrap(ch))
                    690:     {
                    691:         struct trap *trp = trap_at(y, x);
                    692:         return (trp->tr_flags & ISFOUND) ? ch : trp->tr_show;
                    693:     }
                    694:     else if (isalpha(ch))
                    695:     {
                    696:         if ((it = find_mons(y, x)) == NULL)
                    697:         {
                    698:             debug("Can't find monster in move.");
                    699:             return ' ';
                    700:         }
                    701:         tp = THINGPTR(it);
                    702:
                    703:         if (on(*tp, ISDISGUISE))
                    704:             ch = tp->t_disguise;    /* As a mimic */
                    705:         else if (on(*tp, ISINVIS) || (on(*tp, ISSHADOW) &&
                    706:             rnd(100) < 90) || on(*tp, CANSURPRISE))
                    707:         {
                    708:             if (off(player, CANSEE) || on(*tp, CANSURPRISE))
                    709:                 ch = CCHAR( mvwinch(stdscr, y, x) ); /* Invisible */
                    710:         }
                    711:         else if (on(*tp, CANINWALL))
                    712:         {
                    713:             char    tch;
                    714:
                    715:             tch = CCHAR( mvwinch(stdscr, y, x) );
                    716:
                    717:             if (tch == WALL || tch == '-' || tch == '|')
                    718:                 ch = CCHAR( winch(stdscr) ); /* As Xorn */
                    719:         }
                    720:     }
                    721:     return(ch);
                    722: }
                    723:
                    724: /*
                    725:     be_trapped()
                    726:         The guy stepped on a trap.... Make him pay.
                    727: */
                    728:
                    729: char
                    730: be_trapped(struct thing *th, coord tc)
                    731: {
                    732:     struct trap *tp;
                    733:     char   ch, *mname = NULL;
                    734:     int    is_player = (th == &player), can_see = cansee(tc.y, tc.x);
                    735:     struct linked_list  *mitem = NULL;
                    736:
                    737:     tp = trap_at(tc.y, tc.x);
                    738:     ch = tp->tr_type;
                    739:
                    740:     if (!is_player)
                    741:     {
                    742:         mitem = find_mons(th->t_pos.y, th->t_pos.x);
                    743:         mname = monsters[th->t_index].m_name;
                    744:
                    745:         /* Flying monsters do not set off traps */
                    746:
                    747:         if (!mitem || (on(*th, CANFLY) &&
                    748:              (ch == BEARTRAP || ch == MAZETRAP || ch == TRAPDOOR
                    749:               || ch == ARROWTRAP || ch == DARTTRAP)))
                    750:         {
                    751:             debug("%s avoided trap.", mname);
                    752:             return(ch);
                    753:         }
                    754:     }
                    755:     else
                    756:     {
                    757:         short   thief_bonus = -50;
                    758:
                    759:         count = running = FALSE;
                    760:         mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, tp->tr_type);
                    761:
                    762:         if (no_command)
                    763:             return(ch);
                    764:
                    765:         if (player.t_ctype == C_THIEF || player.t_ctype == C_NINJA)
                    766:             thief_bonus = 10;
                    767:
                    768:         if (((is_wearing(R_LEVITATION) || on(player, CANFLY)) &&
                    769:             (ch != FIRETRAP ||
                    770:                  (ch == FIRETRAP && !(tp->tr_flags & ISFOUND))))
                    771:             || (moving && (tp->tr_flags & ISFOUND) && rnd(100) <
                    772:               thief_bonus + 2 * pstats.s_dext + 5 * pstats.s_lvl) &&
                    773:             (ch == BEARTRAP || ch == MAZETRAP || ch == TRAPDOOR
                    774:              || ch == ARROWTRAP || ch == DARTTRAP))
                    775:         {
                    776:             static char trname[1024];
                    777:             msg(tr_name(ch,trname));
                    778:             tp->tr_flags |= ISFOUND;
                    779:             return(ch);
                    780:         }
                    781:
                    782:         if (moving)
                    783:             msg("Your attempt fails.");
                    784:     }
                    785:
                    786:     tp->tr_flags |= ISFOUND;
                    787:
                    788:     switch(ch)
                    789:     {
                    790:         case TRAPDOOR:
                    791:             if (is_player)
                    792:             {
                    793:                 level++;
                    794:                 new_level(NORMLEV,0);
                    795:                 addmsg("You fell into a trap");
                    796:
                    797:                 if (player.t_ctype != C_THIEF
                    798:                     && player.t_ctype != C_ASSASIN
                    799:                     && player.t_ctype != C_NINJA
                    800:                     && rnd(pstats.s_dext) < 4)
                    801:                 {
                    802:                     addmsg(" and were damaged by the fall");
                    803:
                    804:                     if ((pstats.s_hpt -= roll(1, 6)) <= 0)
                    805:                     {
                    806:                         addmsg("!  The fall killed you.");
                    807:                         endmsg();
                    808:                         death(D_FALL);
                    809:
                    810:                         return(ch);
                    811:                     }
                    812:                 }
                    813:
                    814:                 addmsg("!");
                    815:                 endmsg();
                    816:
                    817:                 if (off(player, ISCLEAR) && rnd(4) < 3)
                    818:                 {
                    819:                     if (on(player, ISHUH))
                    820:                         lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
                    821:                     else
                    822:                         light_fuse(FUSE_UNCONFUSE,0,rnd(8)+HUHDURATION, AFTER);
                    823:
                    824:                     turn_on(player, ISHUH);
                    825:                 }
                    826:                 else
                    827:                     msg("You feel dizzy for a moment, but it quickly passes.");
                    828:             }
                    829:             else
                    830:             {
                    831:                 if (can_see)
                    832:                     msg("The %s fell into a trap!", mname);
                    833:
                    834:                 if (on(*th, ISFAMILIAR))
                    835:                                    turn_off(player, HASFAMILIAR);
                    836:
                    837:                 killed(NULL,mitem,NOMESSAGE,NOPOINTS);
                    838:             }
                    839:             break;
                    840:
                    841:         case BEARTRAP:
                    842:             if (is_stealth(th))
                    843:             {
                    844:                 if (is_player)
                    845:                     msg("You pass a bear trap.");
                    846:                 else if (can_see)
                    847:                     msg("The %s passes a bear trap.", mname);
                    848:             }
                    849:             else
                    850:             {
                    851:                 th->t_no_move += BEARTIME;
                    852:
                    853:                 if (is_player)
                    854:                     msg("You are caught in a bear trap.");
                    855:                 else if (can_see)
                    856:                     msg("The %s is caught in a bear trap.", mname);
                    857:             }
                    858:             break;
                    859:
                    860:         case SLEEPTRAP:
                    861:             if (is_player)
                    862:             {
                    863:                 msg("A strange white mist envelops you.");
                    864:
                    865:                 if (!is_wearing(R_ALERT))
                    866:                 {
                    867:                     if (!is_wearing(R_BREATHE) && off(player, HASOXYGEN))
                    868:                     {
                    869:                         msg("You fall asleep.");
                    870:                         no_command += SLEEPTIME;
                    871:                     }
                    872:                 }
                    873:             }
                    874:             else
                    875:             {
                    876:                 if (can_see)
                    877:                     msg("A strange white mist envelops the %s.", mname);
                    878:
                    879:                 if (on(*th, ISUNDEAD))
                    880:                 {
                    881:                     if (can_see)
                    882:                         msg("The mist doesn't seem to affect the %s.", mname);
                    883:                 }
                    884:
                    885:                 if (on(*th, ISUNDEAD) || on(*th, HASOXYGEN))
                    886:                 {
                    887:                     if (can_see)
                    888:                         msg("The mist doesn't seem to affect the %s.", mname);
                    889:                 }
                    890:                 else
                    891:                 {
                    892:                     th->t_no_move += SLEEPTIME;
                    893:                 }
                    894:             }
                    895:             break;
                    896:
                    897:         case ARROWTRAP:
                    898:             if (swing(th->t_ctype, th->t_stats.s_lvl - 1, th->t_stats.s_arm, 1))
                    899:             {
                    900:                 if (is_player)
                    901:                 {
                    902:                     msg("Oh no! An arrow shot you.");
                    903:
                    904:                     if ((pstats.s_hpt -= roll(1, 6)) <= 0)
                    905:                     {
                    906:                         msg("The arrow killed you.");
                    907:                         death(D_ARROW);
                    908:                         return(ch);
                    909:                     }
                    910:                 }
                    911:                 else
                    912:                 {
                    913:                     if (can_see)
                    914:                         msg("An arrow shot the %s.", mname);
                    915:
                    916:                     if (on(*th, NOSHARP))
                    917:                     {
                    918:                         if (can_see)
                    919:                             msg("The arrow has no effect!");
                    920:                     }
                    921:                     else
                    922:                     {
                    923:                         if ((th->t_stats.s_hpt -= roll(1, 6)) <= 0)
                    924:                         {
                    925:                             if (can_see)
                    926:                                 msg("The arrow killed the %s.", mname);
                    927:
                    928:                                                        if (on(*th, ISFAMILIAR))
                    929:                                                            turn_off(player, HASFAMILIAR);
                    930:
                    931:                             killed(NULL, mitem, NOMESSAGE, NOPOINTS);
                    932:                         }
                    933:                     }
                    934:                 }
                    935:             }
                    936:             else
                    937:             {
                    938:                 struct linked_list  *itm;
                    939:                 struct object *an_arrow;
                    940:
                    941:                 if (is_player)
                    942:                     msg("An arrow shoots past you.");
                    943:                 else if (can_see)
                    944:                     msg("An arrow shoots by the %s.", mname);
                    945:
                    946:                 itm = new_item(sizeof *an_arrow);
                    947:                 an_arrow = OBJPTR(itm);
                    948:                 an_arrow->o_type = WEAPON;
                    949:                 an_arrow->o_which = ARROW;
                    950:                 an_arrow->o_hplus = rnd(3) - 1;
                    951:                 an_arrow->o_dplus = rnd(3) - 1;
                    952:                 init_weapon(an_arrow, ARROW);
                    953:                 an_arrow->o_count = 1;
                    954:                 an_arrow->o_pos = tc;
                    955:                 an_arrow->o_mark[0] = '\0';
                    956:                 fall(&player, itm, FALSE, FALSE);
                    957:             }
                    958:             break;
                    959:
                    960:         case TELTRAP:
                    961:             if (is_player)
                    962:             {
                    963:                 teleport();
                    964:
                    965:                 if (off(player, ISCLEAR))
                    966:                 {
                    967:                     msg("Wait, what's going on here. Huh? What? Who?");
                    968:
                    969:                     if (on(player, ISHUH))
                    970:                         lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
                    971:                     else
                    972:                         light_fuse(FUSE_UNCONFUSE,0,rnd(8)+HUHDURATION, AFTER);
                    973:
                    974:                     turn_on(player, ISHUH);
                    975:                 }
                    976:                 else
                    977:                     msg("You feel dizzy for a moment, but it quickly passes.");
                    978:             }
                    979:             else
                    980:             {
                    981:                 int rm;
                    982:
                    983:                 /* Erase the monster from the old position */
                    984:
                    985:                 if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
                    986:                     mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
                    987:
                    988:                 mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
                    989:
                    990:                 /* Get a new position */
                    991:
                    992:                 do
                    993:                 {
                    994:                     rm = rnd_room();
                    995:                     rnd_pos(&rooms[rm], &th->t_pos);
                    996:                 }
                    997:                 while(winat(th->t_pos.y, th->t_pos.x) != FLOOR);
                    998:
                    999:                 /* Put it there */
                   1000:
                   1001:                 mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type);
                   1002:                 th->t_oldch = CCHAR( mvwinch(cw, th->t_pos.y, th->t_pos.x) );
                   1003:
                   1004:                 if (can_see)
                   1005:                     msg("The %s seems to have disappeared!", mname);
                   1006:             }
                   1007:             break;
                   1008:
                   1009:         case DARTTRAP:
                   1010:
                   1011:             if (swing(th->t_ctype, th->t_stats.s_lvl + 1,th->t_stats.s_arm, 1))
                   1012:             {
                   1013:                 if (is_player)
                   1014:                 {
                   1015:                     msg("A small dart just hit you in the shoulder.");
                   1016:
                   1017:                     if ((pstats.s_hpt -= roll(1, 4)) <= 0)
                   1018:                     {
                   1019:                         msg("The dart killed you.");
                   1020:                         death(D_DART);
                   1021:                         return(ch);
                   1022:                     }
                   1023:
                   1024:                     /* Now the poison */
                   1025:
                   1026:                     if (player.t_ctype != C_PALADIN
                   1027:                         && !(player.t_ctype == C_NINJA &&
                   1028:                         pstats.s_lvl > 12) && !save(VS_POISON))
                   1029:                     {
                   1030:
                   1031:                         /*
                   1032:                          * 75% chance it will do point
                   1033:                          * damage - else strength
                   1034:                          */
                   1035:
                   1036:                         if (rnd(100) < 75)
                   1037:                         {
                   1038:                             pstats.s_hpt /= 2;
                   1039:
                   1040:                             if (pstats.s_hpt == 0)
                   1041:                             {
                   1042:                                 death(D_POISON);
                   1043:                                 return(ch);
                   1044:                             }
                   1045:                         }
                   1046:                         else if (!is_wearing(R_SUSABILITY))
                   1047:                             chg_str(-1, FALSE, FALSE);
                   1048:                     }
                   1049:                 }
                   1050:                 else
                   1051:                 {
                   1052:                     int orig_hp = th->t_stats.s_hpt;
                   1053:
                   1054:                     if (can_see)
                   1055:                         msg("A small dart just hit the %s.", mname);
                   1056:
                   1057:                     /*
                   1058:                      * Poison has no effect on poisonous or
                   1059:                      * undead monsters
                   1060:                      */
                   1061:
                   1062:                     if (off(*th, CANPOISON) &&
                   1063:                         off(*th, ISUNDEAD) &&
                   1064:                         !save_throw(VS_POISON, th))
                   1065:                         th->t_stats.s_hpt /= 2;
                   1066:
                   1067:                     /* Now the dart damage */
                   1068:
                   1069:                     if (off(*th, NOSHARP))
                   1070:                         th->t_stats.s_hpt -= roll(1, 4);
                   1071:
                   1072:                     if (orig_hp == th->t_stats.s_hpt)
                   1073:                         if (can_see)
                   1074:                             msg("The dart has not effect!");
                   1075:                         else if (th->t_stats.s_hpt < 0)
                   1076:                         {
                   1077:                             if (can_see)
                   1078:                                 msg("The dart killed the %s.", mname);
                   1079:
                   1080:                                                        if (on(*th, ISFAMILIAR))
                   1081:                                                            turn_off(player, HASFAMILIAR);
                   1082:
                   1083:                             killed(NULL, mitem, NOMESSAGE, NOPOINTS);
                   1084:                         }
                   1085:                 }
                   1086:             }
                   1087:             else
                   1088:             {
                   1089:                 if (is_player)
                   1090:                     msg("A small dart whizzes by your ear and vanishes.");
                   1091:                 else if (can_see)
                   1092:                     msg("A small dart whizzes by the %s and vanishes.", mname);
                   1093:             }
                   1094:             break;
                   1095:
                   1096:         case POOL:
                   1097:         {
                   1098:             int i;
                   1099:
                   1100:             i = rnd(100);
                   1101:
                   1102:             if (is_player)
                   1103:             {
                   1104:                 if (on(player, ISELECTRIC))
                   1105:                 {
                   1106:                     msg("Oh no!!! The water shorts you out");
                   1107:                     extinguish_fuse(FUSE_UNELECTRIFY);
                   1108:                     turn_off(player, ISELECTRIC);
                   1109:
                   1110:                     if (!is_wearing(R_ELECTRESIST))
                   1111:                     {
                   1112:                         if ((pstats.s_hpt -= roll(1, 10)) <= 0)
                   1113:                         {
                   1114:                             addmsg("!  The shock killed you.");
                   1115:                             endmsg();
                   1116:                             death(D_DROWN);
                   1117:                             return(ch);
                   1118:                         }
                   1119:                     }
                   1120:                 }
                   1121:
                   1122:                 if ((tp->tr_flags & ISGONE))
                   1123:                 {
                   1124:                     if (i < 30)
                   1125:                     {
                   1126:                         teleport(); /* teleport away */
                   1127:
                   1128:                         if (off(player, ISCLEAR))
                   1129:                         {
                   1130:                             if (on(player, ISHUH))
                   1131:                                lengthen_fuse(FUSE_UNCONFUSE,rnd(8)+HUHDURATION);
                   1132:                             else
                   1133:                                light_fuse(FUSE_UNCONFUSE,0,rnd(8)+HUHDURATION,AFTER);
                   1134:                             turn_on(player, ISHUH);
                   1135:                         }
                   1136:                         else
                   1137:                             msg("You feel dizzy for a moment, but it quickly passes.");
                   1138:
                   1139:                         pool_teleport = TRUE;
                   1140:                     }
                   1141:                     else if ((i < 45) && level > 2)
                   1142:                     {
                   1143:                         level -= rnd(2) + 1;
                   1144:                         new_level(NORMLEV,0);
                   1145:                         pool_teleport = TRUE;
                   1146:                         msg("You here a faint groan from below.");
                   1147:
                   1148:                         if (off(player, ISCLEAR))
                   1149:                         {
                   1150:                             if (on(player, ISHUH))
                   1151:                                 lengthen_fuse(FUSE_UNCONFUSE,rnd(8)+HUHDURATION);
                   1152:                             else
                   1153:                                 light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
                   1154:
                   1155:                             turn_on(player, ISHUH);
                   1156:                         }
                   1157:                         else
                   1158:                             msg("You feel dizzy for a moment, but it quickly passes.");
                   1159:                     }
                   1160:                     else if (i < 70)
                   1161:                     {
                   1162:                         level += rnd(4) + 1;
                   1163:                         new_level(NORMLEV,0);
                   1164:                         pool_teleport = TRUE;
                   1165:                         msg("You find yourself in strange surroundings.");
                   1166:
                   1167:                         if (off(player, ISCLEAR))
                   1168:                         {
                   1169:                             if (on(player, ISHUH))
                   1170:                                 lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
                   1171:                             else
                   1172:                                 light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
                   1173:
                   1174:                             turn_on(player, ISHUH);
                   1175:                         }
                   1176:                         else
                   1177:                             msg("You feel dizzy for a moment, but it quickly passes.");
                   1178:                     }
                   1179:                     else if (i > 95)
                   1180:                     {
                   1181:                         if (is_wearing(R_BREATHE) || on(player, HASOXYGEN))
                   1182:                             msg("You splash in the pool unharmed.");
                   1183:                         else
                   1184:                         {
                   1185:                             msg("Oh no!!! You drown in the pool!!! --More--");
                   1186:                             wait_for(' ');
                   1187:                             death(D_DROWN);
                   1188:                             return(ch);
                   1189:                         }
                   1190:                     }
                   1191:                 }
                   1192:             }
                   1193:             else
                   1194:             {
                   1195:                 if (can_see)
                   1196:                     msg("The %s fell into the pool!", mname);
                   1197:
                   1198:                 if (i < 15)
                   1199:                 {
                   1200:                     if (off(*th, HASOXYGEN))
                   1201:                     {
                   1202:                         if (can_see)
                   1203:                             msg("The %s has drowned!", mname);
                   1204:
                   1205:                         if (on(*th, ISFAMILIAR))
                   1206:                                                    turn_off(player, HASFAMILIAR);
                   1207:
                   1208:                         killed(NULL, mitem, NOMESSAGE, NOPOINTS);
                   1209:                     }
                   1210:                 }
                   1211:             }
                   1212:         }
                   1213:         break;
                   1214:
                   1215:         case MAZETRAP:
                   1216:
                   1217:             if (is_player)
                   1218:             {
                   1219:                 level++;
                   1220:                 new_level(MAZELEV,0);
                   1221:                 addmsg("You are surrounded by twisty passages");
                   1222:
                   1223:                 if (rnd(4) < 1)
                   1224:                 {
                   1225:                     addmsg(" and were damaged by the fall");
                   1226:
                   1227:                     if ((pstats.s_hpt -= roll(1, 6)) <= 0)
                   1228:                     {
                   1229:                         addmsg("!  The fall killed you.");
                   1230:                         endmsg();
                   1231:                         death(D_FALL);
                   1232:                         return(ch);
                   1233:                     }
                   1234:                 }
                   1235:
                   1236:                 addmsg("!");
                   1237:                 endmsg();
                   1238:
                   1239:                 if (off(player, ISCLEAR))
                   1240:                 {
                   1241:                     if (on(player, ISHUH))
                   1242:                         lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
                   1243:                     else
                   1244:                     {
                   1245:                         light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
                   1246:                         turn_on(player, ISHUH);
                   1247:                     }
                   1248:                 }
                   1249:                 else
                   1250:                     msg("You feel dizzy for a moment, but it quickly passes.");
                   1251:             }
                   1252:             else
                   1253:             {
                   1254:                 if (can_see)
                   1255:                     msg("The %s fell into a trap!", mname);
                   1256:
                   1257:                 if (on(*th, ISFAMILIAR))
                   1258:                                        turn_off(player, HASFAMILIAR);
                   1259:
                   1260:                 killed(NULL, mitem, NOMESSAGE, NOPOINTS);
                   1261:             }
                   1262:             break;
                   1263:
                   1264:         case FIRETRAP:
                   1265:         {
                   1266:             struct room *rp = roomin(hero);
                   1267:
                   1268:             if (is_player)
                   1269:             {
                   1270:                 if (is_wearing(R_FIRERESIST) || on(player, NOFIRE))
                   1271:                     msg("You pass through the flames unharmed.");
                   1272:                 else
                   1273:                 {
                   1274:                     addmsg("You are burned by the flames");
                   1275:
                   1276:                     if ((pstats.s_hpt -= roll(pstats.s_lvl, 2)) <= 0)
                   1277:                     {
                   1278:                         addmsg("!  The flames killed you.");
                   1279:                         endmsg();
                   1280:                         death(D_FIRE);
                   1281:                         return(ch);
                   1282:                     }
                   1283:
                   1284:                     addmsg("!");
                   1285:
                   1286:                     endmsg();
                   1287:                 }
                   1288:             }
                   1289:             else
                   1290:             {
                   1291:                 if (on(*th, CANBBURN))
                   1292:                 {
                   1293:                     if (can_see)
                   1294:                         msg("The %s is burned to death by the flames.", mname);
                   1295:
                   1296:                     killed(NULL, mitem, NOMESSAGE, NOPOINTS);
                   1297:                 }
                   1298:                 else if (on(*th, NOFIRE))
                   1299:                 {
                   1300:                     if (can_see)
                   1301:                         msg("The %s passes through the flames unharmed.", mname);
                   1302:                 }
                   1303:                 else
                   1304:                 {
                   1305:                     if (can_see)
                   1306:                         msg("The %s is burned by the flames.", mname);
                   1307:
                   1308:                     if ((th->t_stats.s_hpt -= roll(th->t_stats.s_lvl, 3)) < 0)
                   1309:                     {
                   1310:                         if (can_see)
                   1311:                             msg("The %s is burned to death by the flames.", mname);
                   1312:
                   1313:                         if (on(*th, ISFAMILIAR))
                   1314:                                                    turn_off(player, HASFAMILIAR);
                   1315:
                   1316:                                                killed(NULL, mitem, NOMESSAGE, NOPOINTS);
                   1317:                     }
                   1318:                     else if (th->t_stats.s_intel < rnd(20))
                   1319:                     {
                   1320:                         if (can_see)
                   1321:                             msg("The %s turns and runs away in fear.", mname);
                   1322:
                   1323:                         turn_on(*th, ISFLEE);
                   1324:                     }
                   1325:                 }
                   1326:             }
                   1327:
                   1328:             if (rp != NULL)
                   1329:             {
                   1330:                 rp->r_flags &= ~ISDARK;
                   1331:                 light(&hero);
                   1332:             }
                   1333:         }
                   1334:         break;
                   1335:
                   1336:         case POISONTRAP:
                   1337:             if (is_player)
                   1338:             {
                   1339:                 msg("You fall into a pool of poison.");
                   1340:
                   1341:                 if (rnd(4) > 0)
                   1342:                 {
                   1343:                     msg("You swallow some of the liquid and feel very sick.");
                   1344:                     pstats.s_hpt -= pstats.s_hpt / 3;
                   1345:
                   1346:                     if (player.t_ctype != C_PALADIN
                   1347:                         && !(player.t_ctype == C_NINJA &&
                   1348:                         pstats.s_lvl > 12)
                   1349:                             && !is_wearing(R_SUSABILITY))
                   1350:                         chg_str(-2, FALSE, FALSE);
                   1351:                 }
                   1352:                 else
                   1353:                     msg("The stuff tastes horrible.");
                   1354:             }
                   1355:             else
                   1356:             {
                   1357:                 if (can_see)
                   1358:                     msg("The %s falls into the pool of poison.", mname);
                   1359:
                   1360:                 if (rnd(4) > 0 && off(*th, ISUNDEAD))
                   1361:                     if (th->t_stats.s_hpt *= 2.0 / 3.0 < 0)
                   1362:                                        {
                   1363:                                            if (can_see)
                   1364:                                                    msg("The %s dies from the poison.", mname);
                   1365:
                   1366:                                                if (on(*th, ISFAMILIAR))
                   1367:                                                    turn_off(player, HASFAMILIAR);
                   1368:
                   1369:                                                killed(NULL, mitem, NOMESSAGE, NOPOINTS);
                   1370:                                        }
                   1371:             }
                   1372:             break;
                   1373:
                   1374:         case LAIR:
                   1375:             if (is_player)
                   1376:             {
                   1377:                 msg("You found a monster lair!");
                   1378:                 mpos = 0;
                   1379:                 new_level(THRONE,0);
                   1380:             }
                   1381:             else
                   1382:             {
                   1383:                 if (can_see)
                   1384:                     msg("The %s fell into a trap!", mname);
                   1385:
                   1386:                 if (on(*th, ISFAMILIAR))
                   1387:                                    turn_off(player, HASFAMILIAR);
                   1388:
                   1389:                 killed(NULL, mitem, NOMESSAGE, NOPOINTS);
                   1390:             }
                   1391:             break;
                   1392:
                   1393:         case RUSTTRAP:
                   1394:             if (is_player)
                   1395:             {
                   1396:                 msg("You are splashed by water.");
                   1397:
                   1398:                 if (cur_armor != NULL &&
                   1399:                     cur_armor->o_which != SOFT_LEATHER &&
                   1400:                     cur_armor->o_which != HEAVY_LEATHER &&
                   1401:                     cur_armor->o_which != CUIRBOLILLI &&
                   1402:                     cur_armor->o_which != PADDED_ARMOR &&
                   1403:                     cur_armor->o_which != CRYSTAL_ARMOR &&
                   1404:                     cur_armor->o_which != MITHRIL &&
                   1405:                     !(cur_armor->o_flags & ISPROT) &&
                   1406:                     cur_armor->o_ac < pstats.s_arm + 1)
                   1407:                 {
                   1408:                     msg("Your armor weakens!");
                   1409:                     cur_armor->o_ac++;
                   1410:                 }
                   1411:                 else if (cur_armor != NULL && (cur_armor->o_flags & ISPROT))
                   1412:                     msg("The rust vanishes instantly!");
                   1413:             }
                   1414:             else
                   1415:             {
                   1416:                 if (can_see)
                   1417:                     msg("The %s is splashed by water.", mname);
                   1418:             }
                   1419:     }
                   1420:
                   1421:     return(ch);
                   1422: }
                   1423:
                   1424: /*
                   1425:     dip_it()
                   1426:         Dip an object into a magic pool
                   1427: */
                   1428:
                   1429: void
                   1430: dip_it(void)
                   1431: {
                   1432:     struct linked_list  *what;
                   1433:     struct object   *ob;
                   1434:     struct trap *tp;
                   1435:     int wh, i;
                   1436:
                   1437:     tp = trap_at(hero.y, hero.x);
                   1438:
                   1439:     if (tp == NULL || !(tp->tr_type == POOL || tp->tr_type == POISONTRAP))
                   1440:     {
                   1441:         msg("I see no pools here.");
                   1442:         return;
                   1443:     }
                   1444:
                   1445:     if (tp->tr_flags & ISGONE)
                   1446:     {
                   1447:         msg("This %s appears to have been used once already.",
                   1448:          (tp->tr_type == POOL ? "shimmering pool" : "poison pool"));
                   1449:         return;
                   1450:     }
                   1451:
                   1452:     if ((what = get_item("dip", 0)) == NULL)
                   1453:     {
                   1454:         msg("");
                   1455:         after = FALSE;
                   1456:         return;
                   1457:     }
                   1458:
                   1459:     ob = OBJPTR(what);
                   1460:     mpos = 0;
                   1461:
                   1462:     if (ob == cur_armor)
                   1463:     {
                   1464:         msg("You have to take off your armor before you can dip it.");
                   1465:         return;
                   1466:     }
                   1467:     else if (ob == cur_ring[LEFT_1] || ob == cur_ring[LEFT_2] ||
                   1468:          ob == cur_ring[LEFT_3] || ob == cur_ring[LEFT_4] ||
                   1469:          ob == cur_ring[RIGHT_1] || ob == cur_ring[RIGHT_2] ||
                   1470:          ob == cur_ring[RIGHT_3] || ob == cur_ring[RIGHT_4])
                   1471:     {
                   1472:         msg("You have to take that ring off before you can dip it.");
                   1473:         return;
                   1474:     }
                   1475:
                   1476:     tp->tr_flags |= ISGONE;
                   1477:
                   1478:     if (ob != NULL && tp->tr_type == POOL)
                   1479:     {
                   1480:         wh = ob->o_which;
                   1481:         ob->o_flags |= ISKNOW;
                   1482:         i = rnd(100);
                   1483:
                   1484:         switch (ob->o_type)
                   1485:         {
                   1486:             case WEAPON:
                   1487:                 if (i < 50)
                   1488:                 {
                   1489:                     if (!(ob->o_flags & ISCURSED))
                   1490:                     {
                   1491:                         ob->o_hplus += 1;
                   1492:                         ob->o_dplus += 1;
                   1493:                     }
                   1494:                     else
                   1495:                     {
                   1496:                         ob->o_hplus = rnd(2);
                   1497:                         ob->o_dplus = rnd(2);
                   1498:                     }
                   1499:
                   1500:                     ob->o_flags &= ~ISCURSED;
                   1501:                     msg("The %s glows blue for a moment.", weaps[wh].w_name);
                   1502:                 }
                   1503:                 else if (i < 70)    /* curse weapon here */
                   1504:                 {
                   1505:                     if (!(ob->o_flags & ISCURSED))
                   1506:                     {
                   1507:                         ob->o_hplus = -(rnd(2) + 1);
                   1508:                         ob->o_dplus = -(rnd(2) + 1);
                   1509:                     }
                   1510:                     else    /* if already cursed */
                   1511:                     {
                   1512:                         ob->o_hplus--;
                   1513:                         ob->o_dplus--;
                   1514:                     }
                   1515:
                   1516:                     ob->o_flags |= ISCURSED;
                   1517:                     msg("The %s glows red for a moment.", weaps[wh].w_name);
                   1518:                 }
                   1519:                 else
                   1520:                     msg("Nothing seems to happen.");
                   1521:                 break;
                   1522:
                   1523:             case ARMOR:
                   1524:
                   1525:                 if (i < 50)     /* enchant armor */
                   1526:                 {
                   1527:                     if (!(ob->o_flags & ISCURSED))
                   1528:                         ob->o_ac -= rnd(2) + 1;
                   1529:                     else
                   1530:                         ob->o_ac = -rnd(3) + armors[wh].a_class;
                   1531:
                   1532:                     ob->o_flags &= ~ISCURSED;
                   1533:                     msg("The %s glows blue for a moment.", armors[wh].a_name);
                   1534:                 }
                   1535:                 else if (i < 75)   /* curse armor */
                   1536:                 {
                   1537:                     if (!(ob->o_flags & ISCURSED))
                   1538:                         ob->o_ac = rnd(3) + armors[wh].a_class;
                   1539:                     else
                   1540:                         ob->o_ac += rnd(2) + 1;
                   1541:
                   1542:                     ob->o_flags |= ISCURSED;
                   1543:                     msg("The %s glows red for a moment.", armors[wh].a_name);
                   1544:                 }
                   1545:                 else
                   1546:                     msg("Nothing seems to happen");
                   1547:                 break;
                   1548:
                   1549:             case STICK:
                   1550:             {
                   1551:                 int j;
                   1552:
                   1553:                 j = rnd(8) + 1;
                   1554:
                   1555:                 if (i < 50)     /* add charges */
                   1556:                 {
                   1557:                     ob->o_charges += j;
                   1558:                     know_items[TYP_STICK][wh] = TRUE;
                   1559:
                   1560:                     if (ob->o_flags & ISCURSED)
                   1561:                         ob->o_flags &= ~ISCURSED;
                   1562:
                   1563:                     msg("The %s %s glows blue for a moment.",
                   1564:                         ws_made[wh], ws_type[wh]);
                   1565:                 }
                   1566:                 else if (i < 65)    /* remove charges */
                   1567:                 {
                   1568:                     if ((ob->o_charges -= i) < 0)
                   1569:                         ob->o_charges = 0;
                   1570:
                   1571:                     know_items[TYP_STICK][wh] = TRUE;
                   1572:
                   1573:                     if (ob->o_flags & ISBLESSED)
                   1574:                         ob->o_flags &= ~ISBLESSED;
                   1575:                     else
                   1576:                         ob->o_flags |= ISCURSED;
                   1577:
                   1578:                     msg("The %s %s glows red for a moment.",
                   1579:                         ws_made[wh], ws_type[wh]);
                   1580:                 }
                   1581:                 else
                   1582:                     msg("Nothing seems to happen.");
                   1583:             }
                   1584:             break;
                   1585:
                   1586:             case SCROLL:
                   1587:
                   1588:                 know_items[TYP_SCROLL][wh] = TRUE;
                   1589:                 msg("The '%s' scroll unfurls.", s_names[wh]);
                   1590:                 break;
                   1591:
                   1592:             case POTION:
                   1593:
                   1594:                 know_items[TYP_POTION][wh] = TRUE;
                   1595:                 msg("The %s potion bubbles for a moment.", p_colors[wh]);
                   1596:                 break;
                   1597:
                   1598:             case RING:
                   1599:                 if (i < 50)     /* enchant ring */
                   1600:                 {
                   1601:                     if (!(ob->o_flags & ISCURSED))
                   1602:                         ob->o_ac += rnd(2) + 1;
                   1603:                     else
                   1604:                         ob->o_ac = rnd(2) + 1;
                   1605:
                   1606:                     ob->o_flags &= ~ISCURSED;
                   1607:                 }
                   1608:                 else if (i < 80)    /* curse ring */
                   1609:                 {
                   1610:                     if (!(ob->o_flags & ISCURSED))
                   1611:                         ob->o_ac = -(rnd(2) + 1);
                   1612:                     else
                   1613:                         ob->o_ac -= (rnd(2) + 1);
                   1614:
                   1615:                     ob->o_flags |= ISCURSED;
                   1616:                 }
                   1617:
                   1618:                 know_items[TYP_RING][wh] = TRUE;
                   1619:                 msg("The %s ring vibrates for a moment.", r_stones[wh]);
                   1620:                 break;
                   1621:
                   1622:             default:
                   1623:                 msg("The pool bubbles for a moment.");
                   1624:         }
                   1625:     }
                   1626:     else if (ob != NULL && tp->tr_type == POISONTRAP)
                   1627:     {
                   1628:         if ((player.t_ctype == C_PALADIN) ||
                   1629:             (player.t_ctype == C_CLERIC && rnd(2)))
                   1630:         {
                   1631:             msg("Trying to use poison is evil.");
                   1632:             luck += 2;
                   1633:         }
                   1634:
                   1635:         if (ob->o_type != WEAPON || rnd(10) > 0)
                   1636:             msg("Nothing seems to happen.");
                   1637:         else
                   1638:         {
                   1639:             msg("Your %s is covered with a black sticky liquid.",
                   1640:                 weaps[ob->o_which].w_name);
                   1641:             ob->o_flags |= ISPOISON;
                   1642:         }
                   1643:     }
                   1644:     else
                   1645:         msg("Nothing seems to happen.");
                   1646: }
                   1647:
                   1648: /*
                   1649:     trap_at()
                   1650:         find the trap at (y,x) on screen.
                   1651: */
                   1652:
                   1653: struct trap *
                   1654: trap_at(int y, int x)
                   1655: {
                   1656:     struct trap *tp, *ep;
                   1657:
                   1658:     ep = &traps[ntraps];
                   1659:
                   1660:     for (tp = traps; tp < ep; tp++)
                   1661:         if (tp->tr_pos.y == y && tp->tr_pos.x == x)
                   1662:             break;
                   1663:
                   1664:     if (tp == ep)
                   1665:     {
                   1666:         debug((sprintf(prbuf, "Trap at %d,%d not in array", y, x), prbuf));
                   1667:         tp = NULL;
                   1668:     }
                   1669:
                   1670:     return(tp);
                   1671: }
                   1672:
                   1673: /*
                   1674:     set_trap()
                   1675:         set a trap at (y, x) on screen.
                   1676: */
                   1677:
                   1678: void
                   1679: set_trap(struct thing *tp, int y, int x)
                   1680: {
                   1681:     int is_player = (tp == &player);
                   1682:     int selection = rnd(7) + 1;
                   1683:     char  ch = 0, och;
                   1684:     int  thief_bonus = 0;
                   1685:
                   1686:     switch(och = CCHAR( mvinch(y, x) ))
                   1687:     {
                   1688:         case WALL:
                   1689:         case FLOOR:
                   1690:         case PASSAGE:
                   1691:             break;
                   1692:         default:
                   1693:             msg("The trap failed!");
                   1694:             return;
                   1695:     }
                   1696:
                   1697:     if (is_player && (player.t_ctype == C_THIEF ||
                   1698:         player.t_ctype == C_NINJA))
                   1699:         thief_bonus = 10;
                   1700:
                   1701:     if (ntraps >= 2 * MAXTRAPS || ++trap_tries >= MAXTRPTRY ||
                   1702:         rnd(60) >= (tp->t_stats.s_dext + tp->t_stats.s_lvl / 2 +
                   1703:         thief_bonus))
                   1704:     {
                   1705:         if (is_player)
                   1706:             msg("The trap failed!");
                   1707:
                   1708:         return;
                   1709:     }
                   1710:
                   1711:     /* Set up for redraw */
                   1712:
                   1713:     clearok(cw, TRUE);
                   1714:     touchwin(cw);
                   1715:
                   1716:     if (is_player)
                   1717:     {
                   1718:         add_line("[1] Trap Door");
                   1719:         add_line("[2] Bear Trap");
                   1720:         add_line("[3] Sleep Trap");
                   1721:         add_line("[4] Arrow Trap");
                   1722:         add_line("[5] Teleport Trap");
                   1723:         add_line("[6] Dart Trap");
                   1724:         add_line("[7] Fire Trap");
                   1725:         end_line();
                   1726:         msg("Which trap? ");
                   1727:
                   1728:         selection = (short) ((readchar() & 0177) - '0');
                   1729:
                   1730:         while (selection < 1 || selection > 7)
                   1731:         {
                   1732:             if (selection == (short) ESCAPE - (short) '0')
                   1733:             {
                   1734:                 after = FALSE;
                   1735:                 return;
                   1736:             }
                   1737:
                   1738:             msg("");
                   1739:             msg("Please enter a selection between 1 and 7:  ");
                   1740:             selection = (short) ((readchar() & 0177) - '0');
                   1741:         }
                   1742:     }
                   1743:
                   1744:     switch (selection)
                   1745:     {
                   1746:         case 1: ch = TRAPDOOR; break;
                   1747:         case 2: ch = BEARTRAP; break;
                   1748:         case 3: ch = SLEEPTRAP;break;
                   1749:         case 4: ch = ARROWTRAP;break;
                   1750:         case 5: ch = TELTRAP;   break;
                   1751:         case 6: ch = DARTTRAP;  break;
                   1752:         case 7: ch = FIRETRAP;  break;
                   1753:     }
                   1754:
                   1755:     mvaddch(y, x, ch);
                   1756:
                   1757:     traps[ntraps].tr_type = ch;
                   1758:     traps[ntraps].tr_flags = ISTHIEFSET;
                   1759:     traps[ntraps].tr_show = och;
                   1760:     traps[ntraps].tr_pos.y = y;
                   1761:     traps[ntraps++].tr_pos.x = x;
                   1762: }
                   1763:
                   1764:
                   1765: /*
                   1766:     rndmove()
                   1767:         move in a random direction if the monster/person is confused
                   1768: */
                   1769:
                   1770: coord
                   1771: rndmove(struct thing *who)
                   1772: {
                   1773:     int x, y;
                   1774:     int ex, ey, nopen = 0;
                   1775:     coord    ret;    /* what we will be returning */
                   1776:     coord    dest;
                   1777:
                   1778:     ret = who->t_pos;
                   1779:
                   1780:     /*
                   1781:      * Now go through the spaces surrounding the player and set that
                   1782:      * place in the array to true if the space can be moved into
                   1783:      */
                   1784:
                   1785:     ey = ret.y + 1;
                   1786:     ex = ret.x + 1;
                   1787:
                   1788:     for (y = who->t_pos.y - 1; y <= ey; y++)
                   1789:         if (y > 0 && y < LINES - 2)
                   1790:             for (x = who->t_pos.x - 1; x <= ex; x++)
                   1791:             {
                   1792:                 if (x < 0 || x >= COLS)
                   1793:                     continue;
                   1794:
                   1795:                 if (step_ok(y, x, NOMONST, who))
                   1796:                 {
                   1797:                     dest.y = y;
                   1798:                     dest.x = x;
                   1799:
                   1800:                     if (!diag_ok(&who->t_pos, &dest, who))
                   1801:                         continue;
                   1802:
                   1803:                     if (rnd(++nopen) == 0)
                   1804:                         ret = dest;
                   1805:                 }
                   1806:             }
                   1807:
                   1808:     return(ret);
                   1809: }
                   1810:
                   1811: /*
                   1812:     isatrap()
                   1813:         Returns TRUE if this character is some kind of trap
                   1814: */
                   1815:
                   1816: int
                   1817: isatrap(int ch)
                   1818: {
                   1819:     switch(ch)
                   1820:     {
                   1821:         case DARTTRAP:
                   1822:         case TELTRAP:
                   1823:         case TRAPDOOR:
                   1824:         case ARROWTRAP:
                   1825:         case SLEEPTRAP:
                   1826:         case POOL:
                   1827:         case MAZETRAP:
                   1828:         case FIRETRAP:
                   1829:         case POISONTRAP:
                   1830:         case LAIR:
                   1831:         case RUSTTRAP:
                   1832:         case BEARTRAP:
                   1833:             return (TRUE);
                   1834:         default:
                   1835:             return (FALSE);
                   1836:     }
                   1837: }

CVSweb