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

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

1.1       rubenllo    1: /*
                      2:  * hero movement commands
                      3:  *
                      4:  * @(#)move.c  4.49 (Berkeley) 02/05/99
                      5:  *
                      6:  * Rogue: Exploring the Dungeons of Doom
                      7:  * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
                      8:  * All rights reserved.
                      9:  *
                     10:  * See the file LICENSE.TXT for full copyright and licensing information.
                     11:  */
                     12:
                     13: #include <curses.h>
                     14: #include <ctype.h>
                     15: #include "rogue.h"
                     16:
                     17: /*
                     18:  * used to hold the new hero position
                     19:  */
                     20:
                     21:
                     22: /*
                     23:  * do_run:
                     24:  *     Start the hero running
                     25:  */
                     26:
                     27: void
                     28: do_run(int ch)
                     29: {
                     30:     running = TRUE;
                     31:     after = FALSE;
                     32:     runch = ch;
                     33: }
                     34:
                     35: /*
                     36:  * do_move:
                     37:  *     Check to see that a move is legal.  If it is handle the
                     38:  * consequences (fighting, picking up, etc.)
                     39:  */
                     40:
                     41: void
                     42: do_move(int dy, int dx)
                     43: {
                     44:     int ch, fl;
                     45:     coord nh;
                     46:
                     47:     firstmove = FALSE;
                     48:     if (no_move)
                     49:     {
                     50:        no_move--;
                     51:        msg("you are still stuck in the bear trap");
                     52:        return;
                     53:     }
                     54:     /*
                     55:      * Do a confused move (maybe)
                     56:      */
                     57:     if (on(player, ISHUH) && rnd(5) != 0)
                     58:     {
                     59:        nh = rndmove(&player);
                     60:        if (ce(nh, hero))
                     61:        {
                     62:            after = FALSE;
                     63:            running = FALSE;
                     64:            to_death = FALSE;
                     65:            return;
                     66:        }
                     67:     }
                     68:     else
                     69:     {
                     70: over:
                     71:        nh.y = hero.y + dy;
                     72:        nh.x = hero.x + dx;
                     73:     }
                     74:
                     75:     /*
                     76:      * Check if he tried to move off the screen or make an illegal
                     77:      * diagonal move, and stop him if he did.
                     78:      */
                     79:     if (nh.x < 0 || nh.x >= NUMCOLS || nh.y <= 0 || nh.y >= NUMLINES - 1)
                     80:        goto hit_bound;
                     81:     if (!diag_ok(&hero, &nh))
                     82:     {
                     83:        after = FALSE;
                     84:        running = FALSE;
                     85:        return;
                     86:     }
                     87:     if (running && ce(hero, nh))
                     88:        after = running = FALSE;
                     89:     fl = flat(nh.y, nh.x);
                     90:     ch = winat(nh.y, nh.x);
                     91:     if (!(fl & F_REAL) && ch == FLOOR)
                     92:     {
                     93:        if (!on(player, ISLEVIT))
                     94:        {
                     95:            chat(nh.y, nh.x) = ch = TRAP;
                     96:            flat(nh.y, nh.x) |= F_REAL;
                     97:        }
                     98:     }
                     99:     else if (on(player, ISHELD) && ch != 'F')
                    100:     {
                    101:        msg("you are being held");
                    102:        return;
                    103:     }
                    104:     switch (ch)
                    105:     {
                    106:        case ' ':
                    107:        case '|':
                    108:        case '-':
                    109: hit_bound:
                    110:            if (passgo && running && (proom->r_flags & ISGONE)
                    111:                && !on(player, ISBLIND))
                    112:            {
                    113:                int     b1, b2;
                    114:
                    115:                switch (runch)
                    116:                {
                    117:                    case 'h':
                    118:                    case 'l':
                    119:                        b1 = (hero.y != 1 && turn_ok(hero.y - 1, hero.x));
                    120:                        b2 = (hero.y != NUMLINES - 2 && turn_ok(hero.y + 1, hero.x));
                    121:                        if (!(b1 ^ b2))
                    122:                            break;
                    123:                        if (b1)
                    124:                        {
                    125:                            runch = 'k';
                    126:                            dy = -1;
                    127:                        }
                    128:                        else
                    129:                        {
                    130:                            runch = 'j';
                    131:                            dy = 1;
                    132:                        }
                    133:                        dx = 0;
                    134:                        turnref();
                    135:                        goto over;
                    136:                    case 'j':
                    137:                    case 'k':
                    138:                        b1 = (hero.x != 0 && turn_ok(hero.y, hero.x - 1));
                    139:                        b2 = (hero.x != NUMCOLS - 1 && turn_ok(hero.y, hero.x + 1));
                    140:                        if (!(b1 ^ b2))
                    141:                            break;
                    142:                        if (b1)
                    143:                        {
                    144:                            runch = 'h';
                    145:                            dx = -1;
                    146:                        }
                    147:                        else
                    148:                        {
                    149:                            runch = 'l';
                    150:                            dx = 1;
                    151:                        }
                    152:                        dy = 0;
                    153:                        turnref();
                    154:                        goto over;
                    155:                }
                    156:            }
                    157:            running = FALSE;
                    158:            after = FALSE;
                    159:            break;
                    160:        case DOOR:
                    161:            running = FALSE;
                    162:            if (flat(hero.y, hero.x) & F_PASS)
                    163:                enter_room(&nh);
                    164:            goto move_stuff;
                    165:        case TRAP:
                    166:            ch = be_trapped(&nh);
                    167:            if (ch == T_DOOR || ch == T_TELEP)
                    168:                return;
                    169:            goto move_stuff;
                    170:        case PASSAGE:
                    171:            /*
                    172:             * when you're in a corridor, you don't know if you're in
                    173:             * a maze room or not, and there ain't no way to find out
                    174:             * if you're leaving a maze room, so it is necessary to
                    175:             * always recalculate proom.
                    176:             */
                    177:            proom = roomin(&hero);
                    178:            goto move_stuff;
                    179:        case FLOOR:
                    180:            if (!(fl & F_REAL))
                    181:                be_trapped(&hero);
                    182:            goto move_stuff;
                    183:        case STAIRS:
                    184:            seenstairs = TRUE;
                    185:            /* FALLTHROUGH */
                    186:        default:
                    187:            running = FALSE;
                    188:            if (isupper(ch) || moat(nh.y, nh.x))
                    189:                fight(&nh, cur_weapon, FALSE);
                    190:            else
                    191:            {
                    192:                if (ch != STAIRS)
                    193:                    take = ch;
                    194: move_stuff:
                    195:                mvaddch(hero.y, hero.x, floor_at());
                    196:                if ((fl & F_PASS) && chat(oldpos.y, oldpos.x) == DOOR)
                    197:                    leave_room(&nh);
                    198:                hero = nh;
                    199:            }
                    200:     }
                    201: }
                    202:
                    203: /*
                    204:  * turn_ok:
                    205:  *     Decide whether it is legal to turn onto the given space
                    206:  */
                    207: int
                    208: turn_ok(int y, int x)
                    209: {
                    210:     PLACE *pp;
                    211:
                    212:     pp = INDEX(y, x);
                    213:     return (pp->p_ch == DOOR
                    214:        || (pp->p_flags & (F_REAL|F_PASS)) == (F_REAL|F_PASS));
                    215: }
                    216:
                    217: /*
                    218:  * turnref:
                    219:  *     Decide whether to refresh at a passage turning or not
                    220:  */
                    221:
                    222: void
                    223: turnref(void)
                    224: {
                    225:     PLACE *pp;
                    226:
                    227:     pp = INDEX(hero.y, hero.x);
                    228:     if (!(pp->p_flags & F_SEEN))
                    229:     {
                    230:        if (jump)
                    231:        {
                    232:            leaveok(stdscr, TRUE);
                    233:            refresh();
                    234:            leaveok(stdscr, FALSE);
                    235:        }
                    236:        pp->p_flags |= F_SEEN;
                    237:     }
                    238: }
                    239:
                    240: /*
                    241:  * door_open:
                    242:  *     Called to illuminate a room.  If it is dark, remove anything
                    243:  *     that might move.
                    244:  */
                    245:
                    246: void
                    247: door_open(const struct room *rp)
                    248: {
                    249:     int y, x;
                    250:
                    251:     if (!(rp->r_flags & ISGONE))
                    252:        for (y = rp->r_pos.y; y < rp->r_pos.y + rp->r_max.y; y++)
                    253:            for (x = rp->r_pos.x; x < rp->r_pos.x + rp->r_max.x; x++)
                    254:                if (isupper(winat(y, x)))
                    255:                    wake_monster(y, x);
                    256: }
                    257:
                    258: /*
                    259:  * be_trapped:
                    260:  *     The guy stepped on a trap.... Make him pay.
                    261:  */
                    262: int
                    263: be_trapped(const coord *tc)
                    264: {
                    265:     PLACE *pp;
                    266:     THING *arrow;
                    267:     int tr;
                    268:
                    269:     if (on(player, ISLEVIT))
                    270:        return T_RUST;  /* anything that's not a door or teleport */
                    271:     running = FALSE;
                    272:     count = FALSE;
                    273:     pp = INDEX(tc->y, tc->x);
                    274:     pp->p_ch = TRAP;
                    275:     tr = pp->p_flags & F_TMASK;
                    276:     pp->p_flags |= F_SEEN;
                    277:     switch (tr)
                    278:     {
                    279:        case T_DOOR:
                    280:            level++;
                    281:            new_level();
                    282:            msg("you fell into a trap!");
                    283:        when T_BEAR:
                    284:            no_move += BEARTIME;
                    285:            msg("you are caught in a bear trap");
                    286:         when T_MYST:
                    287:             switch(rnd(11))
                    288:             {
                    289:                 case 0: msg("you are suddenly in a parallel dimension");
                    290:                 when 1: msg("the light in here suddenly seems %s", rainbow[rnd(cNCOLORS)]);
                    291:                 when 2: msg("you feel a sting in the side of your neck");
                    292:                 when 3: msg("multi-colored lines swirl around you, then fade");
                    293:                 when 4: msg("a %s light flashes in your eyes", rainbow[rnd(cNCOLORS)]);
                    294:                 when 5: msg("a spike shoots past your ear!");
                    295:                 when 6: msg("%s sparks dance across your armor", rainbow[rnd(cNCOLORS)]);
                    296:                 when 7: msg("you suddenly feel very thirsty");
                    297:                 when 8: msg("you feel time speed up suddenly");
                    298:                 when 9: msg("time now seems to be going slower");
                    299:                 when 10: msg("you pack turns %s!", rainbow[rnd(cNCOLORS)]);
                    300:             }
                    301:        when T_SLEEP:
                    302:            no_command += SLEEPTIME;
                    303:            player.t_flags &= ~ISRUN;
                    304:            msg("a strange white mist envelops you and you fall asleep");
                    305:        when T_ARROW:
                    306:            if (swing(pstats.s_lvl - 1, pstats.s_arm, 1))
                    307:            {
                    308:                pstats.s_hpt -= roll(1, 6);
                    309:                if (pstats.s_hpt <= 0)
                    310:                {
                    311:                    msg("an arrow killed you");
                    312:                    death('a');
                    313:                }
                    314:                else
                    315:                    msg("oh no! An arrow shot you");
                    316:            }
                    317:            else
                    318:            {
                    319:                arrow = new_item();
                    320:                init_weapon(arrow, ARROW);
                    321:                arrow->o_count = 1;
                    322:                arrow->o_pos = hero;
                    323:                fall(arrow, FALSE);
                    324:                msg("an arrow shoots past you");
                    325:            }
                    326:        when T_TELEP:
                    327:            /*
                    328:             * since the hero's leaving, look() won't put a TRAP
                    329:             * down for us, so we have to do it ourself
                    330:             */
                    331:            teleport();
                    332:            mvaddch(tc->y, tc->x, TRAP);
                    333:        when T_DART:
                    334:            if (!swing(pstats.s_lvl+1, pstats.s_arm, 1))
                    335:                msg("a small dart whizzes by your ear and vanishes");
                    336:            else
                    337:            {
                    338:                pstats.s_hpt -= roll(1, 4);
                    339:                if (pstats.s_hpt <= 0)
                    340:                {
                    341:                    msg("a poisoned dart killed you");
                    342:                    death('d');
                    343:                }
                    344:                if (!ISWEARING(R_SUSTSTR) && !save(VS_POISON))
                    345:                    chg_str(-1);
                    346:                msg("a small dart just hit you in the shoulder");
                    347:            }
                    348:        when T_RUST:
                    349:            msg("a gush of water hits you on the head");
                    350:            rust_armor(cur_armor);
                    351:     }
                    352:     flush_type();
                    353:     return tr;
                    354: }
                    355:
                    356: /*
                    357:  * rndmove:
                    358:  *     Move in a random direction if the monster/person is confused
                    359:  */
                    360: coord
                    361: rndmove(const THING *who)
                    362: {
                    363:     THING *obj;
                    364:     int x, y;
                    365:     int ch;
                    366:     coord ret;  /* what we will be returning */
                    367:
                    368:     y = ret.y = who->t_pos.y + rnd(3) - 1;
                    369:     x = ret.x = who->t_pos.x + rnd(3) - 1;
                    370:     /*
                    371:      * Now check to see if that's a legal move.  If not, don't move.
                    372:      * (I.e., bump into the wall or whatever)
                    373:      */
                    374:     if (y == who->t_pos.y && x == who->t_pos.x)
                    375:        return ret;
                    376:     if (!diag_ok(&who->t_pos, &ret))
                    377:        goto bad;
                    378:     else
                    379:     {
                    380:        ch = winat(y, x);
                    381:        if (!step_ok(ch))
                    382:            goto bad;
                    383:        if (ch == SCROLL)
                    384:        {
                    385:            for (obj = lvl_obj; obj != NULL; obj = next(obj))
                    386:                if (y == obj->o_pos.y && x == obj->o_pos.x)
                    387:                    break;
                    388:            if (obj != NULL && obj->o_which == S_SCARE)
                    389:                goto bad;
                    390:        }
                    391:     }
                    392:     return ret;
                    393:
                    394: bad:
                    395:     ret = who->t_pos;
                    396:     return ret;
                    397: }
                    398:
                    399: /*
                    400:  * rust_armor:
                    401:  *     Rust the given armor, if it is a legal kind to rust, and we
                    402:  *     aren't wearing a magic ring.
                    403:  */
                    404:
                    405: void
                    406: rust_armor(THING *arm)
                    407: {
                    408:     if (arm == NULL || arm->o_type != ARMOR || arm->o_which == LEATHER ||
                    409:        arm->o_arm >= 9)
                    410:            return;
                    411:
                    412:     if ((arm->o_flags & ISPROT) || ISWEARING(R_SUSTARM))
                    413:     {
                    414:        if (!to_death)
                    415:            msg("the rust vanishes instantly");
                    416:     }
                    417:     else
                    418:     {
                    419:        arm->o_arm++;
                    420:        if (!terse)
                    421:            msg("your armor appears to be weaker now. Oh my!");
                    422:        else
                    423:            msg("your armor weakens");
                    424:     }
                    425: }

CVSweb