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

Annotation of early-roguelike/arogue7/move.c, Revision 1.1

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

CVSweb