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

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

1.1       rubenllo    1: /*
                      2:     move.c - Hero movement commands
                      3:
                      4:     XRogue: Expeditions into the Dungeons of Doom
                      5:     Copyright (C) 1991 Robert Pietkivitch
                      6:     All rights reserved.
                      7:
                      8:     Based on "Advanced Rogue"
                      9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
                     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 <curses.h>
                     20: #include <ctype.h>
                     21: #include <string.h>
                     22: #include "rogue.h"
                     23:
                     24: /*
                     25:  * Used to hold the new hero position
                     26:  */
                     27:
                     28: coord move_nh;
                     29:
                     30: static char Moves[3][3] = {
                     31:     { 'y', 'k', 'u' },
                     32:     { 'h', '.', 'l' },
                     33:     { 'b', 'j', 'n' }
                     34: };
                     35:
                     36: /*
                     37:  * be_trapped:
                     38:  *      The guy stepped on a trap.... Make him pay.
                     39:  */
                     40:
                     41: char
                     42: be_trapped(struct thing *th, coord *tc)
                     43: {
                     44:     register struct trap *tp;
                     45:     register char ch, *mname = NULL;
                     46:     register bool is_player = (th == &player),
                     47:                   can_see;
                     48:     register struct linked_list *mitem = NULL;
                     49:     register struct thing *mp;
                     50:
                     51:
                     52:     /* Can the player see the creature? */
                     53:     can_see = cansee(tc->y, tc->x);
                     54:     can_see &= (is_player || !invisible(th));
                     55:
                     56:     tp = trap_at(tc->y, tc->x);
                     57:     /*
                     58:      * if he's wearing boots of elvenkind, he won't set off the trap
                     59:      * unless its a magic pool (they're not really traps)
                     60:      */
                     61:     if (is_player                                       &&
                     62:         cur_misc[WEAR_BOOTS] != NULL                    &&
                     63:         cur_misc[WEAR_BOOTS]->o_which == MM_ELF_BOOTS   &&
                     64:         tp->tr_type != POOL)
                     65:             return '\0';
                     66:
                     67:     /*
                     68:      * if the creature is flying then it won't set off the trap
                     69:      */
                     70:      if (on(*th, ISFLY))
                     71:         return '\0';
                     72:
                     73:     tp->tr_flags |= ISFOUND;
                     74:
                     75:     if (!is_player) {
                     76:         mitem = find_mons(th->t_pos.y, th->t_pos.x);
                     77:         mname = monster_name(th);
                     78:     }
                     79:     else {
                     80:         count = running = FALSE;
                     81:         mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, tp->tr_type);
                     82:     }
                     83:     switch (ch = tp->tr_type) {
                     84:         case TRAPDOOR:
                     85:             if (is_player) {
                     86:                 level++;
                     87:                 pstats.s_hpt -= roll(1, 10);
                     88:                 if (pstats.s_hpt < 1) {
                     89:             pstats.s_hpt = -1;
                     90:             death(D_FALL);
                     91:         }
                     92:         wclear(cw);
                     93:         wclear(mw);
                     94:                 new_level(NORMLEV);
                     95:                 msg("You fell through a trap! ");
                     96:             }
                     97:             else {
                     98:                 if (can_see) msg("%s fell into a trap!", prname(mname, TRUE));
                     99:
                    100:                 /*
                    101:                  * See if the fall killed the monster
                    102:                  * don't let a UNIQUE die since it might have an artifact
                    103:                  * that we need
                    104:                  */
                    105:                 if (off(*th,ISUNIQUE) && (th->t_stats.s_hpt-=roll(1,10)) <= 0){
                    106:                     killed(mitem, FALSE, FALSE, FALSE);
                    107:                 }
                    108:                 else {  /* Just move monster to next level */
                    109:                     check_residue(th);
                    110:
                    111:                     /* Erase the monster from the old position */
                    112:                     if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
                    113:                         mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
                    114:                     mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
                    115:
                    116:                     /* let him summon on next lvl */
                    117:                     if (on (*th, HASSUMMONED)) {
                    118:                             turn_off(*th, HASSUMMONED);
                    119:                             turn_on(*th, CANSUMMON);
                    120:                     }
                    121:                     turn_on(*th,ISELSEWHERE);
                    122:                     detach(mlist, mitem);
                    123:                     attach(tlist, mitem);       /* remember him next level */
                    124:
                    125:                     /* Make sure that no one is still chasing us */
                    126:                     for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
                    127:                         mp = THINGPTR(mitem);
                    128:                         if (mp->t_dest == &th->t_pos) {
                    129:                             mp->t_dest = &hero;
                    130:                             mp->t_wasshot = FALSE;
                    131:                             turn_off(*mp, ISFLEE);      /* Don't run away! */
                    132:                         }
                    133:                     }
                    134:
                    135:                     /* Make sure we were not chasing a monster here */
                    136:                     th->t_dest = &hero;
                    137:                     if (on(*th, ISFRIENDLY)) turn_off(*th, ISFLEE);
                    138:                 }
                    139:             }
                    140:         /* worm hole trap to OUTSIDE */
                    141:         when WORMHOLE:
                    142:             if (is_player) {
                    143:                 prev_max = 1000;    /* flag used in n_level.c */
                    144:         level++;
                    145:                 pstats.s_hpt -= roll(1, 10);
                    146:                 if (pstats.s_hpt < 1) {
                    147:             pstats.s_hpt = -1;
                    148:             death(D_FALL);
                    149:         }
                    150:                 new_level(OUTSIDE);
                    151:                 msg("You suddenly find yourself in strange surroundings! ");
                    152:         return(ch);
                    153:             }
                    154:             else {
                    155:                 if (can_see) msg("%s fell into the worm hole! ", prname(mname, TRUE));
                    156:
                    157:                 /*
                    158:                  * See if the fall killed the monster
                    159:                  * don't let a UNIQUE die since it might have an artifact
                    160:                  * that we need
                    161:                  */
                    162:                 if (off(*th,ISUNIQUE) && (th->t_stats.s_hpt-=roll(1,10)) <= 0){
                    163:                     killed(mitem, FALSE, FALSE, FALSE);
                    164:                 }
                    165:                 else {  /* Just move monster to next level */
                    166:                     check_residue(th);
                    167:
                    168:                     /* Erase the monster from the old position */
                    169:                     if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
                    170:                         mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
                    171:                     mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
                    172:
                    173:                     /* let him summon on next lvl */
                    174:                     if (on (*th, HASSUMMONED)) {
                    175:                             turn_off(*th, HASSUMMONED);
                    176:                             turn_on(*th, CANSUMMON);
                    177:                     }
                    178:
                    179:                     turn_on(*th,ISELSEWHERE);
                    180:                     detach(mlist, mitem);
                    181:                     attach(tlist, mitem);       /* remember him next level */
                    182:
                    183:                     /* Make sure that no one is still chasing us */
                    184:                     for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
                    185:                         mp = THINGPTR(mitem);
                    186:                         if (mp->t_dest == &th->t_pos) {
                    187:                             mp->t_dest = &hero;
                    188:                             mp->t_wasshot = FALSE;
                    189:                             turn_off(*mp, ISFLEE);      /* Don't run away! */
                    190:                         }
                    191:                     }
                    192:
                    193:                     /* Make sure we were not chasing a monster here */
                    194:                     th->t_dest = &hero;
                    195:                     if (on(*th, ISFRIENDLY)) turn_off(*th, ISFLEE);
                    196:                 }
                    197:             }
                    198:         when BEARTRAP:
                    199:             if (is_stealth(th)) {
                    200:                 if (is_player) msg("You pass a bear trap.");
                    201:                 else if (can_see) msg("%s passes a bear trap.",
                    202:                                       prname(mname, TRUE));
                    203:             }
                    204:             else {
                    205:                 th->t_no_move += movement(&player) * BEARTIME;
                    206:                 th->t_action = A_FREEZE;
                    207:                 if (is_player) msg("You are caught in a bear trap.");
                    208:                 else if (can_see) msg("%s is caught in a bear trap.",
                    209:                                         prname(mname, TRUE));
                    210:             }
                    211:         when SLEEPTRAP:
                    212:             if (is_player) {
                    213:                 if (!ISWEARING(R_ALERT)) {
                    214:                     msg("A strange white mist envelops you.  You fall asleep. ");
                    215:                     player.t_no_move += movement(&player) * SLEEPTIME;
                    216:                     player.t_action = A_FREEZE;
                    217:                 }
                    218:         else {
                    219:             msg("The white mist invigorates you. ");
                    220:         }
                    221:             }
                    222:             else {
                    223:                 if (can_see)
                    224:                     msg("A strange white mist envelops %s. ",
                    225:                         prname(mname, FALSE));
                    226:                 if (on(*th, ISUNDEAD)) {
                    227:                     if (can_see)
                    228:                         msg("The mist doesn't seem to affect %s.",
                    229:                            prname(mname, FALSE));
                    230:                 }
                    231:                 else {
                    232:                     th->t_no_move += movement(th) * SLEEPTIME;
                    233:                     th->t_action = A_FREEZE;
                    234:                 }
                    235:             }
                    236:         when ARROWTRAP:
                    237:             if (swing(th->t_ctype, th->t_stats.s_lvl-1, th->t_stats.s_arm, 1))
                    238:             {
                    239:                 if (is_player) {
                    240:                     msg("Oh no! An arrow shot you.");
                    241:                     if ((pstats.s_hpt -= roll(1, 8)) < 1) {
                    242:             pstats.s_hpt = -1;
                    243:                         msg("The arrow killed you.  --More--");
                    244:             wait_for(' ');
                    245:                         death(D_ARROW);
                    246:                     }
                    247:                 }
                    248:                 else {
                    249:                     if (can_see)
                    250:                         msg("An arrow shot %s.", prname(mname, FALSE));
                    251:                     if ((th->t_stats.s_hpt -= roll(1, 8)) < 1) {
                    252:                         if (can_see)
                    253:                             msg("The arrow killed %s.", prname(mname, FALSE));
                    254:                         killed(mitem, FALSE, FALSE, TRUE);
                    255:                     }
                    256:                 }
                    257:             }
                    258:             else
                    259:             {
                    260:                 register struct linked_list *item;
                    261:                 register struct object *arrow;
                    262:
                    263:                 if (is_player) msg("An arrow shoots past you.");
                    264:                 else if (can_see)
                    265:                       msg("An arrow shoots by %s.", prname(mname, FALSE));
                    266:                 item = new_item(sizeof *arrow);
                    267:                 arrow = OBJPTR(item);
                    268:                 arrow->o_type = WEAPON;
                    269:                 arrow->contents = NULL;
                    270:                 arrow->o_which = ARROW;
                    271:                 arrow->o_hplus = rnd(7) - 1;
                    272:                 arrow->o_dplus = rnd(7) - 1;
                    273:                 init_weapon(arrow, ARROW);
                    274:                 arrow->o_count = 1;
                    275:                 arrow->o_pos = *tc;
                    276:                 arrow->o_mark[0] = '\0';
                    277:                 fall(item, FALSE);
                    278:             }
                    279:         when TELTRAP:
                    280:             if (is_player) teleport();
                    281:             else {
                    282:                 register int rm;
                    283:                 struct room *old_room;  /* old room of monster */
                    284:
                    285:                 /*
                    286:                  * Erase the monster from the old position
                    287:                  */
                    288:                 if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
                    289:                     mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
                    290:                 mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
                    291:                 /*
                    292:                  * check to see if room should go dark
                    293:                  */
                    294:                 if (on(*th, HASFIRE)) {
                    295:                     old_room=roomin(&th->t_pos);
                    296:                     if (old_room != NULL) {
                    297:                         register struct linked_list *fire_item;
                    298:
                    299:                         for (fire_item = old_room->r_fires; fire_item != NULL;
                    300:                              fire_item = next(fire_item)) {
                    301:                             if (THINGPTR(fire_item) == th) {
                    302:                                 detach(old_room->r_fires, fire_item);
                    303:                                 destroy_item(fire_item);
                    304:
                    305:                                 if (old_room->r_fires == NULL) {
                    306:                                     old_room->r_flags &= ~HASFIRE;
                    307:                                     if (can_see) light(&hero);
                    308:                                 }
                    309:                             }
                    310:                         }
                    311:                     }
                    312:                 }
                    313:
                    314:                 /* Get a new position */
                    315:                 do {
                    316:                     rm = rnd_room();
                    317:                     rnd_pos(&rooms[rm], &th->t_pos);
                    318:                 } until(winat(th->t_pos.y, th->t_pos.x) == FLOOR);
                    319:
                    320:                 /* Put it there */
                    321:                 mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type);
                    322:                 th->t_oldch = mvwinch(cw, th->t_pos.y, th->t_pos.x);
                    323:                 /*
                    324:                  * check to see if room that creature appears in should
                    325:                  * light up
                    326:                  */
                    327:                 if (on(*th, HASFIRE)) {
                    328:                     register struct linked_list *fire_item;
                    329:
                    330:                     fire_item = creat_item();
                    331:                     ldata(fire_item) = (char *) th;
                    332:                     attach(rooms[rm].r_fires, fire_item);
                    333:
                    334:                     rooms[rm].r_flags |= HASFIRE;
                    335:                     if(cansee(th->t_pos.y, th->t_pos.x) &&
                    336:                        next(rooms[rm].r_fires) == NULL)
                    337:                         light(&hero);
                    338:                 }
                    339:                 if (can_see)
                    340:                     msg("%s seems to have disappeared!", prname(mname, TRUE));
                    341:             }
                    342:         when DARTTRAP:
                    343:             if (swing(th->t_ctype, th->t_stats.s_lvl+1, th->t_stats.s_arm, 1)) {
                    344:                 if (is_player) {
                    345:                     msg("A small dart just hit you. ");
                    346:                     if ((pstats.s_hpt -= roll(1, 8)) < 1) {
                    347:             pstats.s_hpt = -1;
                    348:                         msg("The dart killed you.");
                    349:             wait_for(' ');
                    350:                         death(D_DART);
                    351:                     }
                    352:
                    353:                     /* Now the poison */
                    354:                     if (!save(VS_POISON, &player, 0)) {
                    355:                         /* 75% chance it will do point damage - else strength */
                    356:                         if (rnd(100) < 75) {
                    357:                             pstats.s_hpt /= 2;
                    358:                             if (pstats.s_hpt < 1) {
                    359:                 pstats.s_hpt = -1;
                    360:                 death(D_POISON);
                    361:                 }
                    362:                         }
                    363:                         else if (!ISWEARING(R_SUSABILITY))
                    364:                                 chg_str(-1);
                    365:                     }
                    366:                 }
                    367:                 else {
                    368:                     if (can_see)
                    369:                         msg("A small dart stabs the %s. ",
                    370:                                 prname(mname, FALSE));
                    371:                     if ((th->t_stats.s_hpt -= roll(1,8)) < 1) {
                    372:                         if (can_see)
                    373:                             msg("The dart killed %s.", prname(mname, FALSE));
                    374:                         killed(mitem, FALSE, FALSE, TRUE);
                    375:                     }
                    376:                     if (!save(VS_POISON, th, 0)) {
                    377:                         th->t_stats.s_hpt /= 2 + level;
                    378:                         if (th->t_stats.s_hpt < 1) {
                    379:                             if (can_see)
                    380:                                 msg("The dart killed %s.", prname(mname,FALSE));
                    381:                             killed(mitem, FALSE, FALSE, TRUE);
                    382:                         }
                    383:                     }
                    384:                 }
                    385:             }
                    386:             else {
                    387:                 if (is_player)
                    388:                     msg("A small dart whizzes by your ear and vanishes.");
                    389:                 else if (can_see)
                    390:                     msg("A small dart whizzes by %s's ear and vanishes.",
                    391:                         prname(mname, FALSE));
                    392:             }
                    393:         when POOL: {
                    394:             register int i;
                    395:
                    396:             i = rnd(100);
                    397:             if (is_player) {
                    398:                 if ((tp->tr_flags & ISGONE)) {
                    399:                     if (i < 56) {
                    400:                         teleport();        /* teleport away */
                    401:                         pool_teleport = TRUE;
                    402:                     }
                    403:                     else if((i < 72) && level > 4) {
                    404:                         level -= rnd(4) + 1;
                    405:                         cur_max = level;
                    406:                         new_level(NORMLEV);
                    407:                         pool_teleport = TRUE;
                    408:                         msg("You here a faint groan from below.");
                    409:                     }
                    410:                     else if(i < 85) {
                    411:                         level += rnd(4) + 1;
                    412:                         new_level(NORMLEV);
                    413:                         pool_teleport = TRUE;
                    414:                         msg("You find yourself in strange surroundings.");
                    415:                     }
                    416:                     else if(i > 96) {
                    417:                         msg("Oh no!!! You drown in the pool!!!  --More--");
                    418:                         wait_for(' ');
                    419:             pstats.s_hpt = -1;
                    420:                         death(D_DROWN);
                    421:                     }
                    422:             else {
                    423:             new_level(NORMLEV);
                    424:             pool_teleport = TRUE;
                    425:             msg("You are whisked away to another region.");
                    426:             }
                    427:                 }
                    428:             }
                    429:             else {
                    430:                 if (i < 60) {
                    431:                     if (can_see) {
                    432:                         /* Drowns */
                    433:                         if (i < 50)
                    434:                             msg("%s drowned in the pool!", prname(mname, TRUE));
                    435:
                    436:                         /* Teleported to another level */
                    437:                         else msg("%s disappeared!", prname(mname, TRUE));
                    438:                     }
                    439:                     killed(mitem, FALSE, FALSE, TRUE);
                    440:                 }
                    441:             }
                    442:         }
                    443:     when MAZETRAP:
                    444:         if (is_player) {
                    445:             pstats.s_hpt -= roll(1, 10);
                    446:             level++;
                    447:             if (pstats.s_hpt < 1) {
                    448:         pstats.s_hpt = -1;
                    449:         death(D_FALL);
                    450:         }
                    451:         wclear(cw);
                    452:         wclear(mw);
                    453:             new_level(MAZELEV);
                    454:             msg("You are surrounded by twisty passages! ");
                    455:         }
                    456:         else {
                    457:             if (can_see) msg("%s fell into a maze trap!", prname(mname, TRUE));
                    458:             if (on(*th, ISUNIQUE)) {
                    459:                     check_residue(th);
                    460:
                    461:                     /* Erase the monster from the old position */
                    462:                     if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
                    463:                         mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
                    464:                     mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
                    465:
                    466:                     /* let him summon on next lvl */
                    467:                     if (on (*th, HASSUMMONED)) {
                    468:                             turn_off(*th, HASSUMMONED);
                    469:                             turn_on(*th, CANSUMMON);
                    470:                     }
                    471:                     turn_on(*th,ISELSEWHERE);
                    472:                     detach(mlist, mitem);
                    473:                     attach(tlist, mitem);       /* remember him next level */
                    474:
                    475:                     /* Make sure that no one is still chasing us */
                    476:                     for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
                    477:                         mp = THINGPTR(mitem);
                    478:                         if (mp->t_dest == &th->t_pos) {
                    479:                             mp->t_dest = &hero;
                    480:                             mp->t_wasshot = FALSE;
                    481:                             turn_off(*mp, ISFLEE);      /* Don't run away! */
                    482:                         }
                    483:                     }
                    484:
                    485:                     /* Make sure we were not chasing a monster here */
                    486:                     th->t_dest = &hero;
                    487:                     if (on(*th, ISFRIENDLY)) turn_off(*th, ISFLEE);
                    488:             }
                    489:             else
                    490:                     killed(mitem, FALSE, FALSE, FALSE);
                    491:         }
                    492:     }
                    493:
                    494:     /* Move the cursor back onto the hero */
                    495:     wmove(cw, hero.y, hero.x);
                    496:
                    497:     flushinp();
                    498:     return(ch);
                    499: }
                    500:
                    501: /*
                    502:  * blue_light:
                    503:  *      magically light up a room (or level or make it dark)
                    504:  */
                    505:
                    506: bool
                    507: blue_light(bool blessed, bool cursed)
                    508: {
                    509:     register struct room *rp;
                    510:     bool ret_val=FALSE; /* Whether or not affect is known */
                    511:
                    512:     rp = roomin(&hero); /* What room is hero in? */
                    513:
                    514:     /* Darken the room if the magic is cursed */
                    515:     if (cursed) {
                    516:         if ((rp == NULL) || !lit_room(rp)) msg(nothing);
                    517:         else {
                    518:             rp->r_flags |= ISDARK;
                    519:             if (!lit_room(rp) && (levtype != OUTSIDE || !daytime) &&
                    520:         !ISWEARING(R_LIGHT))
                    521:                 msg("The %s suddenly goes dark.",
                    522:                     levtype == OUTSIDE ? "area" : "room");
                    523:             else msg(nothing);
                    524:             ret_val = TRUE;
                    525:         }
                    526:     }
                    527:     else {
                    528:         ret_val = TRUE;
                    529:         if (rp && !lit_room(rp) &&
                    530:             (levtype != OUTSIDE || !daytime)) {
                    531:             addmsg("The %s is lit", levtype == OUTSIDE ? "area" : "room");
                    532:             addmsg(" by a %s blue light.", blessed ? "bright" : "shimmering");
                    533:             endmsg();
                    534:         }
                    535:         else if (winat(hero.y, hero.x) == PASSAGE)
                    536:             msg("The corridor glows %sand then fades",
                    537:                     blessed ? "brightly " : "");
                    538:         else {
                    539:             ret_val = FALSE;
                    540:             msg(nothing);
                    541:         }
                    542:         if (blessed) {
                    543:             register int i;     /* Index through rooms */
                    544:
                    545:             for (i=0; i<MAXROOMS; i++)
                    546:                 rooms[i].r_flags &= ~ISDARK;
                    547:         }
                    548:         else if (rp) rp->r_flags &= ~ISDARK;
                    549:     }
                    550:
                    551:     /*
                    552:      * Light the room and put the player back up
                    553:      */
                    554:     light(&hero);
                    555:     mvwaddch(cw, hero.y, hero.x, PLAYER);
                    556:     return(ret_val);
                    557: }
                    558:
                    559: /*
                    560:  * corr_move:
                    561:  *      Check to see that a move is legal.  If so, return correct character.
                    562:  *      If not, if player came from a legal place, then try to turn him.
                    563:  */
                    564:
                    565: void
                    566: corr_move(int dy, int dx)
                    567: {
                    568:     int legal=0;                /* Number of legal alternatives */
                    569:     register int y, x,          /* Indexes though possible positions */
                    570:                  locy = 0, locx = 0;    /* Hold delta of chosen location */
                    571:
                    572:     /* New position */
                    573:     move_nh.y = hero.y + dy;
                    574:     move_nh.x = hero.x + dx;
                    575:
                    576:     /* If it is a legal move, just return */
                    577:     if (move_nh.x >= 0 && move_nh.x < cols && move_nh.y > 0 && move_nh.y < lines - 2) {
                    578:
                    579:         switch (winat(move_nh.y, move_nh.x)) {
                    580:             case WALL:
                    581:             case VERTWALL:
                    582:             case HORZWALL:
                    583:                 break;
                    584:             default:
                    585:                 if (diag_ok(&hero, &move_nh, &player))
                    586:                         return;
                    587:         }
                    588:     }
                    589:
                    590:     /* Check legal places surrounding the player -- ignore previous position */
                    591:     for (y = hero.y - 1; y <= hero.y + 1; y++) {
                    592:         if (y < 1 || y > lines - 3)
                    593:             continue;
                    594:         for (x = hero.x - 1; x <= hero.x + 1; x++) {
                    595:             /* Ignore borders of the screen */
                    596:             if (x < 0 || x > cols - 1)
                    597:                 continue;
                    598:
                    599:             /*
                    600:              * Ignore where we came from, where we are, and where we couldn't go
                    601:              */
                    602:             if ((x == hero.x - dx && y == hero.y - dy) ||
                    603:                 (x == hero.x + dx && y == hero.y + dy) ||
                    604:                 (x == hero.x && y == hero.y))
                    605:                 continue;
                    606:
                    607:             switch (winat(y, x)) {
                    608:                 case WALL:
                    609:                 case VERTWALL:
                    610:                 case HORZWALL:
                    611:                     break;
                    612:                 default:
                    613:                     move_nh.y = y;
                    614:                     move_nh.x = x;
                    615:                     if (diag_ok(&hero, &move_nh, &player)) {
                    616:                         legal++;
                    617:                         locy = y - (hero.y - 1);
                    618:                         locx = x - (hero.x - 1);
                    619:                     }
                    620:             }
                    621:         }
                    622:     }
                    623:
                    624:     /* If we have 2 or more legal moves, make no change */
                    625:     if (legal != 1) {
                    626:         return;
                    627:     }
                    628:
                    629:     runch = Moves[locy][locx];
                    630:
                    631:     /*
                    632:      * For mazes, pretend like it is the beginning of a new run at each turn
                    633:      * in order to get the lighting correct.
                    634:      */
                    635:     if (levtype == MAZELEV) firstmove = TRUE;
                    636:     return;
                    637: }
                    638:
                    639: /*
                    640:  * dip_it:
                    641:  *      Dip an object into a magic pool
                    642:  */
                    643:
                    644: void
                    645: dip_it(void)
                    646: {
                    647:         reg struct linked_list *what;
                    648:         reg struct object *ob;
                    649:         reg struct trap *tp;
                    650:         reg int wh, i;
                    651:
                    652:         tp = trap_at(hero.y,hero.x);
                    653:         if (tp == NULL || tp->tr_type != POOL) {
                    654:             msg("I see no shimmering pool here");
                    655:             return;
                    656:         }
                    657:         if (tp->tr_flags & ISGONE) {
                    658:             msg("This shimmering pool appears to have been used once already.");
                    659:             return;
                    660:         }
                    661:
                    662:         /* It takes 3 movement periods to dip something */
                    663:         if (player.t_action != C_DIP) {
                    664:             if ((what = get_item(pack, "dip", ALL, FALSE, FALSE)) == NULL) {
                    665:                 msg("");
                    666:                 after = FALSE;
                    667:                 return;
                    668:             }
                    669:
                    670:             ob = OBJPTR(what);
                    671:             if (ob == cur_armor               ||
                    672:                 ob == cur_misc[WEAR_BOOTS]    ||
                    673:                 ob == cur_misc[WEAR_JEWEL]    ||
                    674:                 ob == cur_misc[WEAR_GAUNTLET] ||
                    675:                 ob == cur_misc[WEAR_CLOAK]    ||
                    676:                 ob == cur_misc[WEAR_BRACERS]  ||
                    677:                 ob == cur_misc[WEAR_NECKLACE] ||
                    678:                 ob == cur_ring[LEFT_1]  || ob == cur_ring[LEFT_2]  ||
                    679:                 ob == cur_ring[LEFT_3]  || ob == cur_ring[LEFT_4]  ||
                    680:                 ob == cur_ring[RIGHT_1] || ob == cur_ring[RIGHT_2] ||
                    681:         ob == cur_ring[RIGHT_3] || ob == cur_ring[RIGHT_4]) {
                    682:                 mpos = 0;
                    683:                 msg("You'll have to take it off first.");
                    684:                 return;
                    685:             }
                    686:
                    687:             player.t_using = what;      /* Remember what it is */
                    688:             player.t_action = C_DIP;    /* We are dipping */
                    689:             player.t_no_move = 3 * movement(&player);
                    690:             return;
                    691:         }
                    692:
                    693:         /* We have waited our time, let's dip it */
                    694:         what = player.t_using;
                    695:         player.t_using = NULL;
                    696:         player.t_action = A_NIL;
                    697:
                    698:         ob = OBJPTR(what);
                    699:
                    700:         tp->tr_flags |= ISGONE;
                    701:         if (ob != NULL) {
                    702:             wh = ob->o_which;
                    703:             ob->o_flags |= ISKNOW;
                    704:             i = rnd(100);
                    705:             if (ob->o_group != 0)
                    706:                 ob->o_group = newgrp(); /* change the group */
                    707:             switch(ob->o_type) {
                    708:                 case WEAPON:
                    709:                     if(i < 60) {                /* enchant weapon here */
                    710:                         if ((ob->o_flags & ISCURSED) == 0) {
                    711:                                 ob->o_hplus += 1;
                    712:                                 ob->o_dplus += 1;
                    713:                         }
                    714:                         else {          /* weapon was prev cursed here */
                    715:                                 ob->o_hplus = rnd(2);
                    716:                                 ob->o_dplus = rnd(2);
                    717:                         }
                    718:                         ob->o_flags &= ~ISCURSED;
                    719:                         msg("The %s glows blue for a moment.",weaps[wh].w_name);
                    720:                     }
                    721:                     else if(i < 75) {   /* curse weapon here */
                    722:                         if ((ob->o_flags & ISCURSED) == 0) {
                    723:                                 ob->o_hplus = -(rnd(2)+1);
                    724:                                 ob->o_dplus = -(rnd(2)+1);
                    725:                         }
                    726:                         else {                  /* if already cursed */
                    727:                                 ob->o_hplus--;
                    728:                                 ob->o_dplus--;
                    729:                         }
                    730:                         ob->o_flags |= ISCURSED;
                    731:                         msg("The %s glows red for a moment.",weaps[wh].w_name);
                    732:                     }
                    733:                     else
                    734:                         msg(nothing);
                    735:                 when ARMOR:
                    736:                     if (i < 60) {       /* enchant armor */
                    737:                         if((ob->o_flags & ISCURSED) == 0)
                    738:                             ob->o_ac -= rnd(2) + 1;
                    739:                         else
                    740:                             ob->o_ac = -rnd(3)+ armors[wh].a_class;
                    741:                         ob->o_flags &= ~ISCURSED;
                    742:                         msg("The %s glows blue for a moment",armors[wh].a_name);
                    743:                     }
                    744:                     else if(i < 75){    /* curse armor */
                    745:                         if ((ob->o_flags & ISCURSED) == 0)
                    746:                             ob->o_ac = rnd(3)+ armors[wh].a_class;
                    747:                         else
                    748:                             ob->o_ac += rnd(2) + 1;
                    749:                         ob->o_flags |= ISCURSED;
                    750:                         msg("The %s glows red for a moment.",armors[wh].a_name);
                    751:                     }
                    752:                     else
                    753:                         msg(nothing);
                    754:                 when STICK: {
                    755:                     int j;
                    756:                     j = rnd(14) + 1;
                    757:                     if(i < 60) {                /* add charges */
                    758:                         ob->o_charges += j;
                    759:                         ws_know[wh] = TRUE;
                    760:                         if (ob->o_flags & ISCURSED)
                    761:                             ob->o_flags &= ~ISCURSED;
                    762:                         msg("The %s %s glows blue for a moment.",
                    763:                             ws_made[wh],ws_type[wh]);
                    764:                     }
                    765:                     else if(i < 75) {   /* remove charges */
                    766:                         if ((ob->o_charges -= i) < 0)
                    767:                             ob->o_charges = 0;
                    768:                         ws_know[wh] = TRUE;
                    769:                         if (ob->o_flags & ISBLESSED)
                    770:                             ob->o_flags &= ~ISBLESSED;
                    771:                         else
                    772:                             ob->o_flags |= ISCURSED;
                    773:                         msg("The %s %s glows red for a moment.",
                    774:                             ws_made[wh],ws_type[wh]);
                    775:                     }
                    776:                     else
                    777:                         msg(nothing);
                    778:                 }
                    779:                 when SCROLL:
                    780:                     s_know[wh] = TRUE;
                    781:                     msg("The '%s' scroll unfurls.",s_names[wh]);
                    782:                 when POTION:
                    783:                     p_know[wh] = TRUE;
                    784:                     msg("The %s potion bubbles for a moment.. ",p_colors[wh]);
                    785:                 when RING:
                    786:                     if(i < 60) {         /* enchant ring */
                    787:                         if ((ob->o_flags & ISCURSED) == 0)
                    788:                             ob->o_ac += rnd(2) + 1;
                    789:                         else
                    790:                             ob->o_ac = rnd(2) + 1;
                    791:                         ob->o_flags &= ~ISCURSED;
                    792:                     }
                    793:                     else if(i < 75) { /* curse ring */
                    794:                         if ((ob->o_flags & ISCURSED) == 0)
                    795:                             ob->o_ac = -(rnd(2) + 1);
                    796:                         else
                    797:                             ob->o_ac -= (rnd(2) + 1);
                    798:                         ob->o_flags |= ISCURSED;
                    799:                     }
                    800:                     r_know[wh] = TRUE;
                    801:                     msg("The %s ring vibrates for a moment.",r_stones[wh]);
                    802:                 when MM:
                    803:                     m_know[wh] = TRUE;
                    804:                     switch (ob->o_which) {
                    805:                     case MM_BRACERS:
                    806:                     case MM_PROTECT:
                    807:                         if(i < 60) {     /* enchant item */
                    808:                             if ((ob->o_flags & ISCURSED) == 0)
                    809:                                 ob->o_ac += rnd(2) + 1;
                    810:                             else
                    811:                                 ob->o_ac = rnd(2) + 1;
                    812:                             ob->o_flags &= ~ISCURSED;
                    813:                         }
                    814:                         else if(i < 75) { /* curse item */
                    815:                             if ((ob->o_flags & ISCURSED) == 0)
                    816:                                 ob->o_ac = -(rnd(2) + 1);
                    817:                             else
                    818:                                 ob->o_ac -= (rnd(2) + 1);
                    819:                             ob->o_flags |= ISCURSED;
                    820:                         }
                    821:                         msg("The item vibrates for a moment.");
                    822:                     when MM_CHOKE:
                    823:                     case MM_DISAPPEAR:
                    824:                         ob->o_ac = 0;
                    825:                         msg ("The dust dissolves in the pool!");
                    826:                     }
                    827:                 otherwise:
                    828:                 msg("The pool bubbles up for a moment.. ");
                    829:             }
                    830:             updpack(FALSE, &player);
                    831:         }
                    832:         else
                    833:             msg(nothing);
                    834: }
                    835:
                    836: /*
                    837:  * do_move:
                    838:  *      Check to see that a move is legal.  If it is handle the
                    839:  * consequences (fighting, picking up, etc.)
                    840:  */
                    841:
                    842: void
                    843: do_move(int dy, int dx)
                    844: {
                    845:     register struct room *rp, *orp;
                    846:     register unsigned char ch;
                    847:     struct linked_list *item;
                    848:     register struct thing *tp = NULL;
                    849:     coord old_hero;
                    850:     register int wasfirstmove, moved, num_hits;
                    851:     bool changed=FALSE;   /* Did we switch places with a friendly monster? */
                    852:
                    853:     wasfirstmove = firstmove;
                    854:     firstmove = FALSE;
                    855:     curprice = -1;        /* if in trading post, we've moved off obj */
                    856:
                    857:     /*
                    858:      * Do a confused move (maybe)
                    859:      */
                    860:     if (player.t_action == A_NIL &&
                    861:         ((on(player, ISHUH) && rnd(100) < 80)   ||
                    862:          (on(player, ISDANCE) && rnd(100) < 90) ||
                    863:          (ISWEARING(R_DELUSION) && rnd(100) < 70)))
                    864:     {
                    865:         /* Get a random move */
                    866:         move_nh = rndmove(&player);
                    867:         dy = move_nh.y - hero.y;
                    868:         dx = move_nh.x - hero.x;
                    869:     }
                    870:     else {
                    871:         move_nh.y = hero.y + dy;
                    872:         move_nh.x = hero.x + dx;
                    873:     }
                    874:
                    875:     /*
                    876:      * Check if he tried to move off the screen or make an illegal
                    877:      * diagonal move, and stop him if he did.
                    878:      */
                    879:     if (move_nh.x < 0 || move_nh.x > cols-1 || move_nh.y < 1 || move_nh.y >= lines - 2
                    880:         || !diag_ok(&hero, &move_nh, &player))
                    881:     {
                    882:         after = running = FALSE;
                    883:         player.t_action = A_NIL;
                    884:         return;
                    885:     }
                    886:     if (running && ce(hero, move_nh))
                    887:         after = running = FALSE;
                    888:     ch = winat(move_nh.y, move_nh.x);
                    889:
                    890:     /* Take care of hero trying to move close to something frightening */
                    891:     if (on(player, ISFLEE)) {
                    892:         if (rnd(100) < 12) {
                    893:             turn_off(player, ISFLEE);
                    894:             msg("You regain your composure.");
                    895:         }
                    896:         else if (DISTANCE(move_nh.y, move_nh.x, player.t_dest->y, player.t_dest->x) <
                    897:                  DISTANCE(hero.y, hero.x, player.t_dest->y, player.t_dest->x)) {
                    898:                         running = FALSE;
                    899:                         msg("You are too terrified to move that way");
                    900:                         player.t_action = A_NIL;
                    901:                         player.t_no_move = movement(&player);
                    902:                         return;
                    903:         }
                    904:     }
                    905:
                    906:     /* If we want to move to a monster, see what it is */
                    907:     if (isalpha(ch)) {
                    908:         item = find_mons(move_nh.y, move_nh.x);
                    909:         if (item == NULL) {
                    910:             debug("Cannot find monster in move.");
                    911:             player.t_action = A_NIL;
                    912:             return;
                    913:         }
                    914:         tp = THINGPTR(item);
                    915:     }
                    916:
                    917:     /*
                    918:      * Take care of hero being held.  If the player is being held, he
                    919:      * can't move unless he is either attacking a non-friendly monster
                    920:      * or attacking a friendly monster that can't move.
                    921:      */
                    922:     if (on(player, ISHELD) &&
                    923:         (!isalpha(ch) || (on(*tp, ISFRIENDLY) && off(*tp, ISHELD)))) {
                    924:         msg("You are being held.");
                    925:         player.t_action = A_NIL;
                    926:         return;
                    927:     }
                    928:
                    929:     /* See if we have to wait for our movement rate */
                    930:     if (player.t_action == A_NIL) {
                    931:         after = FALSE;
                    932:         firstmove = wasfirstmove;       /* Remember if this is first move */
                    933:         player.t_no_move = movement(&player);
                    934:         if (player.t_ctype == C_MONK)
                    935:             player.t_no_move -= pstats.s_lvl/6;
                    936:         if (on(player, ISFLY))
                    937:             player.t_no_move /= 2; /* If flying, speed him up */
                    938:
                    939:         if (player.t_no_move < 1) player.t_no_move = 1;
                    940:
                    941:         /* Remember our action */
                    942:         player.t_action = Moves[dy+1][dx+1];
                    943:         return;
                    944:     }
                    945:
                    946:     /* Now let's forget the old move and just do it */
                    947:     player.t_action = A_NIL;
                    948:
                    949:     /* If we're moving onto a friendly monster, let's change places. */
                    950:     if (isalpha(ch) && on(*tp, ISFRIENDLY) && off(*tp, ISHELD)) {
                    951:         coord tpos,     /* Where monster may have been going */
                    952:               current;  /* Current hero position */
                    953:         int action;     /* The monster's action */
                    954:
                    955:         current = hero;
                    956:         tpos = tp->t_newpos;
                    957:         action = tp->t_action;
                    958:
                    959:         /* Disrupt whatever our friend was doing */
                    960:         tp->t_action = A_NIL;
                    961:
                    962:         /* Tentatively move us to where he is */
                    963:         hero = tp->t_pos;
                    964:
                    965:         /* See if we can move him to where we were */
                    966:         tp->t_newpos = current;
                    967:         do_chase(tp);
                    968:
                    969:         /* Did we succeed? */
                    970:         if (ce(tp->t_pos, current)) {
                    971:             /* Reset our idea of what ch is */
                    972:             ch = winat(move_nh.y, move_nh.x);
                    973:
                    974:             /* Let it be known that we made the switch */
                    975:             changed = TRUE;
                    976:             old_hero = current;
                    977:
                    978:             /* Make the monster think it didn't move */
                    979:             tp->t_oldpos = current;
                    980:             tp->t_doorgoal.x = tp->t_doorgoal.y = -1;
                    981:
                    982:             /* Let the player know something funny happened. */
                    983:             msg("What a sidestep!");
                    984:         }
                    985:         else {
                    986:             /* Restore things -- we couldn't move */
                    987:             hero = current;
                    988:             tp->t_newpos = tpos;
                    989:             tp->t_action = action;
                    990:         }
                    991:     }
                    992:
                    993:     /* assume he's not in a wall */
                    994:     if (!isalpha(ch)) turn_off(player, ISINWALL);
                    995:
                    996:     switch (ch) {
                    997:         case VERTWALL:
                    998:         case HORZWALL:
                    999:             if (levtype == OUTSIDE) {
                   1000:                 hero = move_nh;
                   1001:                 new_level(OUTSIDE);
                   1002:                 return;
                   1003:             }
                   1004:         case WALL:
                   1005:         case SECRETDOOR:
                   1006:             if (off(player, CANINWALL) || running) {
                   1007:                 after = running = FALSE;
                   1008:
                   1009:                 /* Light if finishing run */
                   1010:                 if (levtype == MAZELEV && lit_room(&rooms[0]))
                   1011:                     look(FALSE, TRUE);
                   1012:
                   1013:                 after = running = FALSE;
                   1014:
                   1015:                 return;
                   1016:             }
                   1017:             turn_on(player, ISINWALL);
                   1018:             break;
                   1019:         case POOL:
                   1020:             if (levtype == OUTSIDE) {
                   1021:                 /* lake_check(&move_nh); */  /* not implemented yet */
                   1022:                 running = FALSE;
                   1023:                 break;
                   1024:             }
                   1025:         case MAZETRAP:
                   1026:             if (levtype == OUTSIDE) {
                   1027:             running = FALSE;
                   1028:             break;
                   1029:         }
                   1030:         case TRAPDOOR:
                   1031:         case TELTRAP:
                   1032:         case BEARTRAP:
                   1033:         case SLEEPTRAP:
                   1034:         case ARROWTRAP:
                   1035:         case DARTTRAP:
                   1036:         case WORMHOLE:
                   1037:             ch = be_trapped(&player, &move_nh);
                   1038:             if (ch == TRAPDOOR || ch == TELTRAP ||
                   1039:                 pool_teleport  || ch == MAZETRAP) {
                   1040:                 pool_teleport = FALSE;
                   1041:                 return;
                   1042:             }
                   1043:             break;
                   1044:         case GOLD:
                   1045:         case POTION:
                   1046:         case SCROLL:
                   1047:         case FOOD:
                   1048:         case WEAPON:
                   1049:         case ARMOR:
                   1050:         case RING:
                   1051:         case MM:
                   1052:         case RELIC:
                   1053:         case STICK:
                   1054:             running = FALSE;
                   1055:             take = ch;
                   1056:             break;
                   1057:         case DOOR:
                   1058:         case STAIRS:
                   1059:         case POST:
                   1060:             running = FALSE;
                   1061:             break;
                   1062:         default:
                   1063:             break;
                   1064:     }
                   1065:
                   1066:     if (isalpha(ch)) { /* if its a monster then fight it */
                   1067:         /*
                   1068:          * If we were running down a corridor and didn't start right
                   1069:          * next to the critter, don't do anything.
                   1070:          */
                   1071:         if (running && wasfirstmove == FALSE && roomin(&hero) == NULL) {
                   1072:             struct linked_list *item;
                   1073:
                   1074:             item = find_mons(move_nh.y, move_nh.x);
                   1075:             if (item != NULL && !invisible(THINGPTR(item))) {
                   1076:                 after = running = FALSE;
                   1077:                 return;
                   1078:             }
                   1079:         }
                   1080:
                   1081:         /* We have to add time because we're attacking */
                   1082:         player.t_no_move = FIGHTBASE;
                   1083:         player.t_no_move += weap_move(&player, cur_weapon);
                   1084:         if (on(player, ISHASTE))
                   1085:                 player.t_no_move /= 2;
                   1086:         else if (on(player, ISSLOW))
                   1087:                 player.t_no_move *= 2;
                   1088:
                   1089:         /* We may attack faster if we're high enough level
                   1090:          * and the right class
                   1091:          */
                   1092:         switch(player.t_ctype) {
                   1093:             case C_FIGHTER: num_hits = player.t_stats.s_lvl/25 + 1;
                   1094:             when C_PALADIN: num_hits = player.t_stats.s_lvl/35 + 1;
                   1095:             when C_RANGER:  num_hits = player.t_stats.s_lvl/35 + 1;
                   1096:             when C_MONK:  if(cur_weapon) num_hits = player.t_stats.s_lvl/40 + 1;
                   1097:                           else     num_hits = player.t_stats.s_lvl/30 + 1;
                   1098:             otherwise:      num_hits = player.t_stats.s_lvl/60 + 1;
                   1099:         }
                   1100:
                   1101:         /*
                   1102:          * The player has already moved the initial movement period.
                   1103:          * Let's add that in, do our division, and then subtract it
                   1104:          * out so that the total time is divided, not just the
                   1105:          * additional attack time.
                   1106:          */
                   1107:         moved = movement(&player),
                   1108:         player.t_no_move += moved;
                   1109:         player.t_no_move /= num_hits;
                   1110:         player.t_no_move -= moved;
                   1111:         running = FALSE;
                   1112:
                   1113:         /* Mark that we are attacking and save the attack coordinate */
                   1114:         player.t_action = A_ATTACK;
                   1115:         player.t_newpos = move_nh;
                   1116:         runch = Moves[dy+1][dx+1];      /* Remember the direction */
                   1117:
                   1118:         if (player.t_no_move <= 0) after = FALSE;
                   1119:         return;
                   1120:     }
                   1121:
                   1122:     /*
                   1123:      * if not fighting then move the hero
                   1124:      */
                   1125:     if (changed == FALSE) {
                   1126:         old_hero = hero;        /* Save hero's old position */
                   1127:         hero = move_nh;              /* Move the hero */
                   1128:     }
                   1129:     rp = roomin(&hero);
                   1130:     orp = roomin(&old_hero);
                   1131:
                   1132:     /* Unlight any possible cross-corridor */
                   1133:     if (levtype == MAZELEV) {
                   1134:         register bool call_light = FALSE;
                   1135:         register unsigned char wall_check;
                   1136:
                   1137:         if (wasfirstmove && lit_room(&rooms[0])) {
                   1138:             /* Are we moving out of a corridor? */
                   1139:             switch (runch) {
                   1140:                 case 'h':
                   1141:                 case 'l':
                   1142:                     if (old_hero.y + 1 < lines - 2) {
                   1143:                         wall_check = winat(old_hero.y + 1, old_hero.x);
                   1144:                         if (!isrock(wall_check)) call_light = TRUE;
                   1145:                     }
                   1146:                     if (old_hero.y - 1 > 0) {
                   1147:                         wall_check = winat(old_hero.y - 1, old_hero.x);
                   1148:                         if (!isrock(wall_check)) call_light = TRUE;
                   1149:                     }
                   1150:                     break;
                   1151:                 case 'j':
                   1152:                 case 'k':
                   1153:                     if (old_hero.x + 1 < cols) {
                   1154:                         wall_check = winat(old_hero.y, old_hero.x + 1);
                   1155:                         if (!isrock(wall_check)) call_light = TRUE;
                   1156:                     }
                   1157:                     if (old_hero.x - 1 >= 0) {
                   1158:                         wall_check = winat(old_hero.y, old_hero.x - 1);
                   1159:                         if (!isrock(wall_check)) call_light = TRUE;
                   1160:                     }
                   1161:                     break;
                   1162:                 default:
                   1163:                     call_light = TRUE;
                   1164:             }
                   1165:             player.t_oldpos = old_hero;
                   1166:             if (call_light) light(&old_hero);
                   1167:         }
                   1168:     }
                   1169:
                   1170:     else if (orp != NULL && rp == NULL) {    /* Leaving a room -- darken it */
                   1171:         orp->r_flags |= FORCEDARK;      /* Fake darkness */
                   1172:         light(&old_hero);
                   1173:         orp->r_flags &= ~FORCEDARK;     /* Restore light state */
                   1174:     }
                   1175:     else if (rp != NULL && orp == NULL){/* Entering a room */
                   1176:         light(&hero);
                   1177:         if (rp->r_flags & ISTREAS)
                   1178:             wake_room(rp);
                   1179:     }
                   1180:     ch = winat(old_hero.y, old_hero.x);
                   1181:     wmove(cw, unc(old_hero));
                   1182:     waddch(cw, ch);
                   1183:     wmove(cw, unc(hero));
                   1184:     waddch(cw, PLAYER);
                   1185: }
                   1186:
                   1187: /*
                   1188:  * do_run:
                   1189:  *      Start the hero running
                   1190:  */
                   1191:
                   1192: void
                   1193: do_run(char ch)
                   1194: {
                   1195:     firstmove = TRUE;
                   1196:     running = TRUE;
                   1197:     after = FALSE;
                   1198:     runch = ch;
                   1199: }
                   1200:
                   1201: /*
                   1202:  * getdelta:
                   1203:  *      Takes a movement character (eg. h, j, k, l) and returns the
                   1204:  *      y and x delta corresponding to it in the remaining arguments.
                   1205:  *      Returns TRUE if it could find it, FALSE otherwise.
                   1206:  */
                   1207:
                   1208: bool
                   1209: getdelta(char match, int *dy, int *dx)
                   1210: {
                   1211:     register int y, x;
                   1212:
                   1213:     for (y = 0; y < 3; y++)
                   1214:         for (x = 0; x < 3; x++)
                   1215:             if (Moves[y][x] == match) {
                   1216:                 *dy = y - 1;
                   1217:                 *dx = x - 1;
                   1218:                 return(TRUE);
                   1219:             }
                   1220:
                   1221:     return(FALSE);
                   1222: }
                   1223:
                   1224: /*
                   1225:  * isatrap:
                   1226:  *      Returns TRUE if this character is some kind of trap
                   1227:  */
                   1228:
                   1229: bool
                   1230: isatrap(char ch)
                   1231: {
                   1232:         switch(ch) {
                   1233:                 case WORMHOLE:
                   1234:                 case DARTTRAP:
                   1235:                 case TELTRAP:
                   1236:                 case TRAPDOOR:
                   1237:                 case ARROWTRAP:
                   1238:                 case SLEEPTRAP:
                   1239:                 case BEARTRAP:  return(TRUE);
                   1240:                 case MAZETRAP:
                   1241:                 case POOL:      return(levtype != OUTSIDE);
                   1242:                 default:        return(FALSE);
                   1243:         }
                   1244: }
                   1245:
                   1246: /*
                   1247:  * Called to illuminate a room.
                   1248:  * If it is dark, remove anything that might move.
                   1249:  */
                   1250:
                   1251: void
                   1252: light(coord *cp)
                   1253: {
                   1254:     register struct room *rp;
                   1255:     register int j, k, x, y;
                   1256:     register unsigned char ch, rch, sch;
                   1257:     register struct linked_list *item;
                   1258:     int jlow, jhigh, klow, khigh;       /* Boundaries of lit area */
                   1259:
                   1260:     if ((rp = roomin(cp)) != NULL) {
                   1261:         /*
                   1262:          * is he wearing ring of illumination?
                   1263:          */
                   1264:         if (&hero == cp && ISWEARING(R_LIGHT)) /* Must be hero's room */
                   1265:             rp->r_flags &= ~ISDARK;
                   1266:
                   1267:         /* If we are in a maze, don't look at the whole room (level) */
                   1268:         if (levtype == MAZELEV) {
                   1269:             int see_radius;
                   1270:
                   1271:             see_radius = 1;
                   1272:
                   1273:             /* If we are looking at the hero in a rock, broaden our sights */
                   1274:             if (&hero == cp || &player.t_oldpos == cp) {
                   1275:                 ch = winat(hero.y, hero.x);
                   1276:                 if (isrock(ch)) see_radius = 2;
                   1277:                 ch = winat(player.t_oldpos.y, player.t_oldpos.x);
                   1278:                 if (isrock(ch)) see_radius = 2;
                   1279:             }
                   1280:
                   1281:             jlow = max(0, cp->y - see_radius - rp->r_pos.y);
                   1282:             jhigh = min(rp->r_max.y, cp->y + see_radius + 1 - rp->r_pos.y);
                   1283:             klow = max(0, cp->x - see_radius - rp->r_pos.x);
                   1284:             khigh = min(rp->r_max.x, cp->x + see_radius + 1 - rp->r_pos.x);
                   1285:         }
                   1286:         else {
                   1287:             jlow = klow = 0;
                   1288:             jhigh = rp->r_max.y;
                   1289:             khigh = rp->r_max.x;
                   1290:         }
                   1291:         for (j = 0; j < rp->r_max.y; j++)
                   1292:         {
                   1293:             for (k = 0; k < rp->r_max.x; k++)
                   1294:             {
                   1295:                 bool see_here = 0, see_before = 0;
                   1296:
                   1297:                 /* Is this in the give area -- needed for maze */
                   1298:                 if ((j < jlow || j >= jhigh) && (k < klow || k >= khigh))
                   1299:                     continue;
                   1300:
                   1301:                 y = rp->r_pos.y + j;
                   1302:                 x = rp->r_pos.x + k;
                   1303:
                   1304:                 /*
                   1305:                  * If we are in a maze do not look at this area unless
                   1306:                  * we can see it from where we are or where we last were
                   1307:                  * (for erasing purposes).
                   1308:                  */
                   1309:                 if (levtype == MAZELEV) {
                   1310:                     /* If we can't see it from here, could we see it before? */
                   1311:                     if ((see_here = maze_view(y, x)) == FALSE) {
                   1312:                         coord savhero;
                   1313:
                   1314:                         /* Could we see it from where we were? */
                   1315:                         savhero = hero;
                   1316:                         hero = player.t_oldpos;
                   1317:                         see_before = maze_view(y, x);
                   1318:                         hero = savhero;
                   1319:
                   1320:                         if (!see_before) continue;
                   1321:                     }
                   1322:                 }
                   1323:
                   1324:                 ch = show(y, x);
                   1325:                 wmove(cw, y, x);
                   1326:                 /*
                   1327:                  * Figure out how to display a secret door
                   1328:                  */
                   1329:                 if (ch == SECRETDOOR) {
                   1330:                     if (j == 0 || j == rp->r_max.y - 1)
                   1331:                         ch = HORZWALL;
                   1332:                     else
                   1333:                         ch = VERTWALL;
                   1334:                 }
                   1335:                 /* For monsters, if they were previously not seen and
                   1336:                  * now can be seen, or vice-versa, make sure that will
                   1337:                  * happen.  This is for dark rooms as opposed to invisibility.
                   1338:                  *
                   1339:                  * Call winat() in the test because ch will not reveal
                   1340:                  * invisible monsters.
                   1341:                  */
                   1342:                 if (isalpha(winat(y, x))) {
                   1343:                     struct thing *tp;   /* The monster */
                   1344:
                   1345:                     item = wake_monster(y, x);
                   1346:                     tp = THINGPTR(item);
                   1347:
                   1348:                     /* Previously not seen -- now can see it */
                   1349:                     if (tp->t_oldch == ' ' && cansee(tp->t_pos.y, tp->t_pos.x))
                   1350:                         tp->t_oldch = mvinch(y, x);
                   1351:
                   1352:                     /* Previously seen -- now can't see it */
                   1353:                     else if (!cansee(tp->t_pos.y, tp->t_pos.x) &&
                   1354:                              roomin(&tp->t_pos) != NULL)
                   1355:                         switch (tp->t_oldch) {
                   1356:                             /*
                   1357:                              * Only blank it out if it is in a room and not
                   1358:                              * the border (or other wall) of the room.
                   1359:                              */
                   1360:                              case DOOR:
                   1361:                              case SECRETDOOR:
                   1362:                              case HORZWALL:
                   1363:                              case VERTWALL:
                   1364:                                 break;
                   1365:
                   1366:                              otherwise:
                   1367:                                 tp->t_oldch = ' ';
                   1368:                         }
                   1369:                 }
                   1370:
                   1371:                 /*
                   1372:                  * If the room is a dark room, we might want to remove
                   1373:                  * monsters and the like from it (since they might
                   1374:                  * move).
                   1375:                  * A dark room.
                   1376:                  */
                   1377:                 if ((!lit_room(rp) && (levtype != OUTSIDE)) ||
                   1378:                     (levtype == OUTSIDE && !daytime) ||
                   1379:                     on(player, ISBLIND)         ||
                   1380:                     (rp->r_flags & FORCEDARK)   ||
                   1381:                     (levtype == MAZELEV && !see_here && see_before)) {
                   1382:                     sch = mvwinch(cw, y, x);    /* What's seen */
                   1383:                     rch = mvinch(y, x); /* What's really there */
                   1384:                     switch (rch) {
                   1385:                         case DOOR:
                   1386:                         case SECRETDOOR:
                   1387:                         case STAIRS:
                   1388:                         case TRAPDOOR:
                   1389:                         case WORMHOLE:
                   1390:                         case TELTRAP:
                   1391:                         case BEARTRAP:
                   1392:                         case SLEEPTRAP:
                   1393:                         case ARROWTRAP:
                   1394:                         case DARTTRAP:
                   1395:                         case MAZETRAP:
                   1396:                         case POOL:
                   1397:                         case POST:
                   1398:                         case VERTWALL:
                   1399:                         case HORZWALL:
                   1400:                         case WALL:
                   1401:                             if (isalpha(sch)) ch = rch;
                   1402:                             else if (sch != FLOOR) ch = sch;
                   1403:                             else ch = ' '; /* Hide undiscoverd things */
                   1404:                         when FLOOR:
                   1405:                             ch = ' ';
                   1406:                         otherwise:
                   1407:                             ch = ' ';
                   1408:                     }
                   1409:                     /* Take care of our magic bookkeeping. */
                   1410:                     switch (sch) {
                   1411:                         case MAGIC:
                   1412:                         case BMAGIC:
                   1413:                         case CMAGIC:
                   1414:                             ch = sch;
                   1415:                     }
                   1416:                 }
                   1417:                 mvwaddch(cw, y, x, ch);
                   1418:             }
                   1419:         }
                   1420:     }
                   1421: }
                   1422:
                   1423: /*
                   1424:  * lit_room:
                   1425:  *      Called to see if the specified room is lit up or not.
                   1426:  */
                   1427:
                   1428: bool
                   1429: lit_room(struct room *rp)
                   1430: {
                   1431:     register struct linked_list *fire_item;
                   1432:     register struct thing *fire_creature;
                   1433:
                   1434:     if (!(rp->r_flags & ISDARK)) return(TRUE);  /* A definitely lit room */
                   1435:
                   1436:     /* Is it lit by fire light? */
                   1437:     if (rp->r_flags & HASFIRE) {
                   1438:         switch ((int)levtype) {
                   1439:             case MAZELEV:
                   1440:                 /* See if a fire creature is in line of sight */
                   1441:                 for (fire_item = rp->r_fires; fire_item != NULL;
                   1442:                      fire_item = next(fire_item)) {
                   1443:                     fire_creature = THINGPTR(fire_item);
                   1444:                     if (maze_view(fire_creature->t_pos.y,
                   1445:                                   fire_creature->t_pos.x)) return(TRUE);
                   1446:                 }
                   1447:
                   1448:                 /* Couldn't find any in line-of-sight */
                   1449:                 return(FALSE);
                   1450:
                   1451:             /* We should probably do something special for the outside */
                   1452:             otherwise:
                   1453:                 return TRUE;
                   1454:         }
                   1455:     }
                   1456:     return(FALSE);
                   1457: }
                   1458:
                   1459: /*
                   1460:  * movement:
                   1461:  *      Given a pointer to a player/monster structure, calculate the
                   1462:  *      movement rate for that character.
                   1463:  */
                   1464:
                   1465: short
                   1466: movement(struct thing *tp)
                   1467: {
                   1468:     register int result;
                   1469:     register int carry;         /* Percentage carried */
                   1470:
                   1471:     result = 0;
                   1472:
                   1473:     /* Adjust for armor (player only) */
                   1474:     if (tp == &player && cur_armor) {
                   1475:         int diff;  /* Now armor class differs from normal one of same type */
                   1476:
                   1477:         /* Blessed armor adds less */
                   1478:         diff = cur_armor->o_ac - armors[cur_armor->o_which].a_class;
                   1479:         switch (cur_armor->o_which) {
                   1480:             case LEATHER:
                   1481:             case RING_MAIL:
                   1482:             case CHAIN_MAIL:
                   1483:             case SCALE_MAIL:
                   1484:             case PADDED_ARMOR:
                   1485:                 diff += 1;
                   1486:             when STUDDED_LEATHER:
                   1487:             case SPLINT_MAIL:
                   1488:             case BANDED_MAIL:
                   1489:             case PLATE_MAIL:
                   1490:                 diff += 2;
                   1491:             when PLATE_ARMOR:
                   1492:                 diff += 3;
                   1493:             otherwise:
                   1494:                 debug("forgot an armor in movement()");
                   1495:         }
                   1496:         if (diff < 0) diff = 0;
                   1497:         result += diff;
                   1498:
                   1499:     }
                   1500:
                   1501:     /* Adjust for the pack */
                   1502:     carry = 100 * tp->t_stats.s_pack / tp->t_stats.s_carry;
                   1503:     if (carry > 75) result++;
                   1504:
                   1505:     /* Get a bonus for dexterity */
                   1506:     result -= dext_plus(tp == &player ? dex_compute() : tp->t_stats.s_dext);
                   1507:
                   1508:     /* only allow adjust for the minus's */
                   1509:     if (result < 0) result = 0;
                   1510:     result += tp->t_movement; /* now add in movement rate */
                   1511:
                   1512:     /* Is the character slowed? */
                   1513:     if (on(*tp, ISSLOW) || on(*tp, ISDANCE)) result *= 2;
                   1514:
                   1515:     /* Is the character hasted? */
                   1516:     if (on(*tp, ISHASTE)) result /= 2;
                   1517:
                   1518:     /* We have a minimum of 1 */
                   1519:     if (result < 1) result = 1;
                   1520:
                   1521:     return(result);
                   1522: }
                   1523:
                   1524: /*
                   1525:  * rndmove:
                   1526:  *      move in a random direction if the monster/person is confused
                   1527:  */
                   1528:
                   1529: coord
                   1530: rndmove(struct thing *who)
                   1531: {
                   1532:     register int x, y;
                   1533:     register int ex, ey, nopen = 0;
                   1534:     coord ret;  /* what we will be returning */
                   1535:     coord dest;
                   1536:
                   1537:     ret = who->t_pos;
                   1538:     /*
                   1539:      * Now go through the spaces surrounding the player and
                   1540:      * set that place in the array to true if the space can be
                   1541:      * moved into
                   1542:      */
                   1543:     ey = ret.y + 1;
                   1544:     ex = ret.x + 1;
                   1545:     for (y = who->t_pos.y - 1; y <= ey; y++)
                   1546:         if (y > 0 && y < lines - 2)
                   1547:             for (x = who->t_pos.x - 1; x <= ex; x++)
                   1548:             {
                   1549:                 if (x < 0 || x >= cols)
                   1550:                     continue;
                   1551:                 if (step_ok(y, x, NOMONST, who) == TRUE)
                   1552:                 {
                   1553:                     dest.y = y;
                   1554:                     dest.x = x;
                   1555:                     if (!diag_ok(&who->t_pos, &dest, who))
                   1556:                         continue;
                   1557:                     if (rnd(++nopen) == 0)
                   1558:                         ret = dest;
                   1559:                 }
                   1560:             }
                   1561:     return ret;
                   1562: }
                   1563:
                   1564: #define TRAPTYPES 9             /* 9 total trap types that can be set */
                   1565: #define WIZARDTRAPS 3           /* Only wizards can set the last 3 */
                   1566:                 /* CTRL(C) to level 400 for POST level */
                   1567: static const char *trap_types[TRAPTYPES] = {
                   1568:     "Trap Door",
                   1569:     "Bear Trap",
                   1570:     "Sleep Trap",
                   1571:     "Arrow Trap",
                   1572:     "Teleport Trap",
                   1573:     "Dart Trap",
                   1574:     "Magic pool",
                   1575:     "Maze Trap",
                   1576:     "Worm Hole"
                   1577: };
                   1578:
                   1579: /*
                   1580:  * set_trap:
                   1581:  *      set a trap at (y, x) on screen.
                   1582:  */
                   1583:
                   1584: void
                   1585: set_trap(struct thing *tp, int y, int x)
                   1586: {
                   1587:     register bool is_player = (tp == &player);
                   1588:     register int selection = rnd(TRAPTYPES-WIZARDTRAPS) + '1';
                   1589:     register int i, num_traps;
                   1590:     register unsigned char ch = 0, och;
                   1591:     int thief_bonus = 0;
                   1592:     int s_dext;
                   1593:
                   1594:     /* let wizard in on this too */
                   1595:     if (wizard) goto can_traps;
                   1596:     if (is_player && player.t_ctype != C_THIEF && player.t_ctype !=C_ASSASSIN) {
                   1597:         msg("Only thieves and assassins can set traps. ");
                   1598:         return;
                   1599:     }
                   1600:     can_traps:
                   1601:     switch (och = mvinch(y, x)) {
                   1602:         case WALL:
                   1603:         case FLOOR:
                   1604:         case PASSAGE:
                   1605:             break;
                   1606:         default:
                   1607:             if (is_player) msg("The trap failed!");
                   1608:             return;
                   1609:     }
                   1610:
                   1611:     if (is_player) {
                   1612:         int state = 0, /* 0 -> current screen, 1 -> prompt screen, 2 -> done */
                   1613:             units;     /* Number of movement units for the given trap */
                   1614:
                   1615:         if (player.t_action == C_SETTRAP) {
                   1616:             selection = player.t_selection;
                   1617:             player.t_selection = 0;
                   1618:             player.t_action = A_NIL;
                   1619:         }
                   1620:         else {
                   1621:             msg("Which kind of trap do you wish to set? (* for a list): ");
                   1622:             num_traps = TRAPTYPES - (wizard ? 0 : WIZARDTRAPS);
                   1623:             do {
                   1624:                 selection = wgetch(cw);
                   1625:                 switch (selection) {
                   1626:                     case '*':
                   1627:                       if (state != 1) {
                   1628:                         wclear(hw);
                   1629:                         touchwin(hw);
                   1630:                         for (i=0; i<num_traps; i++) {
                   1631:                             wmove(hw, i+2, 0);
                   1632:                             wprintw(hw, "[%d] %s", i+1, trap_types[i]);
                   1633:                         }
                   1634:                         mvwaddstr(hw, 0, 0,
                   1635:                                 "Which kind of trap do you wish to set? ");
                   1636:
                   1637:                         if (menu_overlay)
                   1638:                             /*
                   1639:                              * Put out the selection.  The longest line is
                   1640:                              * the prompt line (39 characters long).
                   1641:                              */
                   1642:                             over_win(cw, hw, num_traps + 3, 41, 0, 39, '\0');
                   1643:                         else
                   1644:                             draw(hw);
                   1645:                         state = 1;      /* Now in prompt window */
                   1646:                       }
                   1647:                       break;
                   1648:
                   1649:                     case ESC:
                   1650:                         if (state == 1) {
                   1651:                             clearok(cw, FALSE);
                   1652:                             touchwin(cw);
                   1653:                         }
                   1654:                         msg("");
                   1655:
                   1656:                         trap_tries--;   /* Don't count this one */
                   1657:                         after = FALSE;
                   1658:                         return;
                   1659:
                   1660:                     case '1':
                   1661:                     case '2':
                   1662:                     case '3':
                   1663:                     case '4':
                   1664:                     case '5':
                   1665:                     case '6':
                   1666:                     case '7':
                   1667:                     case '8':
                   1668:                     case '9':
                   1669:                         if (selection < '7' || wizard) {
                   1670:                             if (state == 1) {   /* In prompt window */
                   1671:                                 clearok(cw, FALSE); /* Set up for redraw */
                   1672:                                 touchwin(cw);
                   1673:                             }
                   1674:
                   1675:                             msg("");
                   1676:
                   1677:                             /*
                   1678:                              * Make sure there is a floor below us for trap
                   1679:                              * doors.
                   1680:                              */
                   1681:                             if (selection == '1' && level >= nfloors) {
                   1682:                                 if (state == 1) draw(cw);
                   1683:                                 msg("There is no level below this one.");
                   1684:                                 return;
                   1685:                             }
                   1686:                             state = 2;  /* Finished */
                   1687:                             break;
                   1688:                         }
                   1689:
                   1690:                         /* Fall through for non-wizard, unusual trap case */
                   1691:                     default:
                   1692:                         if (state == 1) {       /* In the prompt window */
                   1693:                             wmove(hw, 0, 0);
                   1694:                             wprintw(hw,
                   1695:                                 "Please enter a selection between 1 and %d:  ",
                   1696:                                 num_traps);
                   1697:                             if (menu_overlay)
                   1698:                                 /*
                   1699:                                  * Put out the selection.  The longest line is
                   1700:                                  * the prompt line (43 characters long).
                   1701:                                  */
                   1702:                                 over_win(cw, hw, num_traps+3, 45, 0, 43, '\0');
                   1703:                             else
                   1704:                                 draw(hw);
                   1705:                         }
                   1706:                         else {  /* Normal window */
                   1707:                             mpos = 0;
                   1708:                             msg("Please enter a selection between 1 and %d:  ",
                   1709:                                 num_traps);
                   1710:                         }
                   1711:                 }
                   1712:             } while (state != 2);
                   1713:
                   1714:             player.t_selection = selection;
                   1715:
                   1716:             switch (selection) {
                   1717:                 case '1': units = 10;   /* Trap door */
                   1718:                 when '2': units = 5;    /* Bear trap */
                   1719:                 when '3': units = 7;    /* Sleeping gas trap */
                   1720:                 when '4': units = 5;    /* Arrow trap */
                   1721:                 when '5': units = 10;   /* Teleport trap */
                   1722:                 when '6': units = 7;    /* Dart trap */
                   1723:                 otherwise: units = 5;   /* Unknown trap */
                   1724:             }
                   1725:             player.t_no_move = units * movement(&player);
                   1726:             player.t_action = C_SETTRAP;
                   1727:             return;
                   1728:         }
                   1729:     }
                   1730:
                   1731:     if (is_player && player.t_ctype == C_THIEF)   thief_bonus = 20;
                   1732:     if (is_player && player.t_ctype == C_ASSASSIN) thief_bonus = 15;
                   1733:     if (is_player && player.t_ctype == C_FIGHTER) thief_bonus = 10;
                   1734:
                   1735:     s_dext = (tp == &player) ? dex_compute() : tp->t_stats.s_dext;
                   1736:
                   1737:     if (ntraps >= MAXTRAPS || ++trap_tries >= MAXTRPTRY ||
                   1738:         levtype == POSTLEV || levtype == OUTSIDE ||
                   1739:         rnd(80) >= (s_dext + tp->t_stats.s_lvl/2 + thief_bonus)) {
                   1740:         if (is_player) msg("The trap failed!");
                   1741:         return;
                   1742:     }
                   1743:
                   1744:     switch (selection) {
                   1745:         case '1': ch = TRAPDOOR;
                   1746:         when '2': ch = BEARTRAP;
                   1747:         when '3': ch = SLEEPTRAP;
                   1748:         when '4': ch = ARROWTRAP;
                   1749:         when '5': ch = TELTRAP;
                   1750:         when '6': ch = DARTTRAP;
                   1751:         when '7': ch = POOL;
                   1752:         when '8': ch = MAZETRAP;
                   1753:         when '9': ch = WORMHOLE;
                   1754:     }
                   1755:
                   1756:     mvaddch(y, x, ch);
                   1757:     traps[ntraps].tr_show = och;
                   1758:     traps[ntraps].tr_type = ch;
                   1759:     traps[ntraps].tr_pos.y = y;
                   1760:     traps[ntraps].tr_pos.x = x;
                   1761:     if (is_player)
                   1762:         traps[ntraps].tr_flags = ISTHIEFSET;
                   1763:     if (ch == POOL || ch == POST) {
                   1764:         traps[ntraps].tr_flags |= ISFOUND;
                   1765:     }
                   1766:
                   1767:     ntraps++;
                   1768: }
                   1769:
                   1770: /*
                   1771:  * show:
                   1772:  *      returns what a certain thing will display as to the un-initiated
                   1773:  */
                   1774:
                   1775: char
                   1776: show(int y, int x)
                   1777: {
                   1778:     register unsigned char ch = winat(y, x);
                   1779:     register struct linked_list *it;
                   1780:     register struct thing *tp;
                   1781:
                   1782:     if (isatrap(ch)) {
                   1783:         register struct trap *trp = trap_at(y, x);
                   1784:
                   1785:         return (trp->tr_flags & ISFOUND) ? ch : trp->tr_show;
                   1786:     }
                   1787:     else if (isalpha(ch)) {
                   1788:         if ((it = find_mons(y, x)) == NULL) {
                   1789:             msg("Show:  Can't find monster in show (%d, %d)", y, x);
                   1790:             return(mvwinch(stdscr, y, x));
                   1791:         }
                   1792:         tp = THINGPTR(it);
                   1793:
                   1794:         if (on(*tp, ISDISGUISE)) ch = tp->t_disguise; /* As a mimic */
                   1795:
                   1796:         /* Hide invisible creatures */
                   1797:         else if (invisible(tp)) {
                   1798:             /* We can't see surprise-type creatures through "see invisible" */
                   1799:             if (off(player,CANSEE) || on(*tp,CANSURPRISE))
                   1800:                 ch = mvwinch(stdscr, y, x); /* Invisible */
                   1801:         }
                   1802:         else if (on(*tp, CANINWALL)) {
                   1803:             if (isrock(mvwinch(stdscr, y, x))) ch = winch(stdscr); /* As Xorn */
                   1804:         }
                   1805:     }
                   1806:     return ch;
                   1807: }
                   1808:
                   1809:
                   1810: /*
                   1811:  * trap_at:
                   1812:  *      find the trap at (y,x) on screen.
                   1813:  */
                   1814:
                   1815: struct trap *
                   1816: trap_at(int y, int x)
                   1817: {
                   1818:     register struct trap *tp, *ep;
                   1819:
                   1820:     ep = &traps[ntraps];
                   1821:     for (tp = traps; tp < ep; tp++)
                   1822:         if (tp->tr_pos.y == y && tp->tr_pos.x == x)
                   1823:             break;
                   1824:     if (tp == ep)
                   1825:         debug((sprintf(prbuf, "Trap at %d,%d not in array", y, x), prbuf));
                   1826:     return tp;
                   1827: }
                   1828:
                   1829: /*
                   1830:  * weap_move:
                   1831:  *      Calculate how many segments it will take to swing the given
                   1832:  *      weapon (note that the weapon may actually be a stick or
                   1833:  *      even something else).
                   1834:  * wielder: Who's wielding the weapon
                   1835:  * weap: The weapon
                   1836:  */
                   1837:
                   1838: int
                   1839: weap_move(struct thing *wielder, struct object *weap)
                   1840: {
                   1841:     register int weap_rate;
                   1842:     int          dexterity;
                   1843:     int          strength;
                   1844:
                   1845:     if (weap == NULL) return(1); /* hand, claw, bite attacks are quick */
                   1846:
                   1847:     switch (weap->o_type) {
                   1848:         case STICK:
                   1849:             if (EQUAL(ws_type[weap->o_which], "staff"))
                   1850:                 weap_rate = 2;
                   1851:             else weap_rate = 1; /* A wand */
                   1852:
                   1853:         when WEAPON:
                   1854:             weap_rate = weaps[weap->o_which].w_rate;
                   1855:
                   1856:             /* Adjust for blessed or cursed weapon */
                   1857:             if (weap->o_hplus < 0)      /* Cursed */
                   1858:                 weap_rate -= (weap->o_hplus - 2) / 3;
                   1859:             else if (weap_rate > 0)     /* Blessed */
                   1860:                 weap_rate -= (2*weap->o_hplus + weap_rate - 1) / weap_rate;
                   1861:
                   1862:         when RELIC:
                   1863:             switch (weap->o_which) {
                   1864:                 case MUSTY_DAGGER:
                   1865:                 case HRUGGEK_MSTAR:
                   1866:                 case AXE_AKLAD:
                   1867:                 case YEENOGHU_FLAIL:
                   1868:                 case MING_STAFF:
                   1869:                 case ORCUS_WAND:
                   1870:                 case ASMO_ROD:
                   1871:                     /* These operate in the blink of an eye */
                   1872:                     weap_rate = 1;
                   1873:                 otherwise:
                   1874:                     /* What is it? */
                   1875:                     weap_rate = 10;
                   1876:                     debug("unknown weapon in weap_move()");
                   1877:             }
                   1878:         otherwise:
                   1879:             /* What is it? */
                   1880:             weap_rate = 10;
                   1881:             debug("unknown weapon in weap_move()");
                   1882:     }
                   1883:
                   1884:     /* Put in a dexterity bonus */
                   1885:     if (wielder == &player) dexterity = dex_compute();
                   1886:     else dexterity = wielder->t_stats.s_dext;
                   1887:     weap_rate -= dext_plus(dexterity) / 2;
                   1888:
                   1889:     /* Put in a strength bonus */
                   1890:     if (wielder == &player) strength = str_compute();
                   1891:     else strength = wielder->t_stats.s_str;
                   1892:     weap_rate -= str_plus(strength) / 2;
                   1893:
                   1894:     /* It can't speed you up and it must take SOME time */
                   1895:     if (weap_rate <= 0) weap_rate = 1;
                   1896:
                   1897:     /* Do we need to adjust for fast/slow movement? */
                   1898:     if (on(*wielder, ISSLOW) || on(*wielder, ISDANCE)) weap_rate *= 2;
                   1899:     if (on(*wielder, ISHASTE)) weap_rate /= 2;
                   1900:
                   1901:     /* Return the result */
                   1902:     return(weap_rate);
                   1903: }
                   1904:

CVSweb