Annotation of 43BSDReno/games/rogue/move.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Timothy C. Stoehr.
                      7:  *
                      8:  * Redistribution and use in source and binary forms are permitted
                      9:  * provided that: (1) source distributions retain this entire copyright
                     10:  * notice and comment, and (2) distributions including binaries display
                     11:  * the following acknowledgement:  ``This product includes software
                     12:  * developed by the University of California, Berkeley and its contributors''
                     13:  * in the documentation or other materials provided with the distribution
                     14:  * and in all advertising materials mentioning features or use of this
                     15:  * software. Neither the name of the University nor the names of its
                     16:  * contributors may be used to endorse or promote products derived
                     17:  * from this software without specific prior written permission.
                     18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     20:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     21:  */
                     22: 
                     23: #ifndef lint
                     24: static char sccsid[] = "@(#)move.c     5.3 (Berkeley) 6/1/90";
                     25: #endif /* not lint */
                     26: 
                     27: /*
                     28:  * move.c
                     29:  *
                     30:  * This source herein may be modified and/or distributed by anybody who
                     31:  * so desires, with the following restrictions:
                     32:  *    1.)  No portion of this notice shall be removed.
                     33:  *    2.)  Credit shall not be taken for the creation of this source.
                     34:  *    3.)  This code is not to be traded, sold, or used for personal
                     35:  *         gain or profit.
                     36:  *
                     37:  */
                     38: 
                     39: #include "rogue.h"
                     40: 
                     41: short m_moves = 0;
                     42: boolean jump = 0;
                     43: char *you_can_move_again = "you can move again";
                     44: 
                     45: extern short cur_room, halluc, blind, levitate;
                     46: extern short cur_level, max_level;
                     47: extern short bear_trap, haste_self, confused;
                     48: extern short e_rings, regeneration, auto_search;
                     49: extern char hunger_str[];
                     50: extern boolean being_held, interrupted, r_teleport, passgo;
                     51: 
                     52: one_move_rogue(dirch, pickup)
                     53: short dirch, pickup;
                     54: {
                     55:        short row, col;
                     56:        object *obj;
                     57:        char desc[DCOLS];
                     58:        short n, status, d;
                     59: 
                     60:        row = rogue.row;
                     61:        col = rogue.col;
                     62: 
                     63:        if (confused) {
                     64:                dirch = gr_dir();
                     65:        }
                     66:        (void) is_direction(dirch, &d);
                     67:        get_dir_rc(d, &row, &col, 1);
                     68: 
                     69:        if (!can_move(rogue.row, rogue.col, row, col)) {
                     70:                return(MOVE_FAILED);
                     71:        }
                     72:        if (being_held || bear_trap) {
                     73:                if (!(dungeon[row][col] & MONSTER)) {
                     74:                        if (being_held) {
                     75:                                message("you are being held", 1);
                     76:                        } else {
                     77:                                message("you are still stuck in the bear trap", 0);
                     78:                                (void) reg_move();
                     79:                        }
                     80:                        return(MOVE_FAILED);
                     81:                }
                     82:        }
                     83:        if (r_teleport) {
                     84:                if (rand_percent(R_TELE_PERCENT)) {
                     85:                        tele();
                     86:                        return(STOPPED_ON_SOMETHING);
                     87:                }
                     88:        }
                     89:        if (dungeon[row][col] & MONSTER) {
                     90:                rogue_hit(object_at(&level_monsters, row, col), 0);
                     91:                (void) reg_move();
                     92:                return(MOVE_FAILED);
                     93:        }
                     94:        if (dungeon[row][col] & DOOR) {
                     95:                if (cur_room == PASSAGE) {
                     96:                        cur_room = get_room_number(row, col);
                     97:                        light_up_room(cur_room);
                     98:                        wake_room(cur_room, 1, row, col);
                     99:                } else {
                    100:                        light_passage(row, col);
                    101:                }
                    102:        } else if ((dungeon[rogue.row][rogue.col] & DOOR) &&
                    103:                   (dungeon[row][col] & TUNNEL)) {
                    104:                light_passage(row, col);
                    105:                wake_room(cur_room, 0, rogue.row, rogue.col);
                    106:                darken_room(cur_room);
                    107:                cur_room = PASSAGE;
                    108:        } else if (dungeon[row][col] & TUNNEL) {
                    109:                        light_passage(row, col);
                    110:        }
                    111:        mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col));
                    112:        mvaddch(row, col, rogue.fchar);
                    113: 
                    114:        if (!jump) {
                    115:                refresh();
                    116:        }
                    117:        rogue.row = row;
                    118:        rogue.col = col;
                    119:        if (dungeon[row][col] & OBJECT) {
                    120:                if (levitate && pickup) {
                    121:                        return(STOPPED_ON_SOMETHING);
                    122:                }
                    123:                if (pickup && !levitate) {
                    124:                        if (obj = pick_up(row, col, &status)) {
                    125:                                get_desc(obj, desc);
                    126:                                if (obj->what_is == GOLD) {
                    127:                                        free_object(obj);
                    128:                                        goto NOT_IN_PACK;
                    129:                                }
                    130:                        } else if (!status) {
                    131:                                goto MVED;
                    132:                        } else {
                    133:                                goto MOVE_ON;
                    134:                        }
                    135:                } else {
                    136: MOVE_ON:
                    137:                        obj = object_at(&level_objects, row, col);
                    138:                        (void) strcpy(desc, "moved onto ");
                    139:                        get_desc(obj, desc+11);
                    140:                        goto NOT_IN_PACK;
                    141:                }
                    142:                n = strlen(desc);
                    143:                desc[n] = '(';
                    144:                desc[n+1] = obj->ichar;
                    145:                desc[n+2] = ')';
                    146:                desc[n+3] = 0;
                    147: NOT_IN_PACK:
                    148:                message(desc, 1);
                    149:                (void) reg_move();
                    150:                return(STOPPED_ON_SOMETHING);
                    151:        }
                    152:        if (dungeon[row][col] & (DOOR | STAIRS | TRAP)) {
                    153:                if ((!levitate) && (dungeon[row][col] & TRAP)) {
                    154:                        trap_player(row, col);
                    155:                }
                    156:                (void) reg_move();
                    157:                return(STOPPED_ON_SOMETHING);
                    158:        }
                    159: MVED:  if (reg_move()) {                       /* fainted from hunger */
                    160:                        return(STOPPED_ON_SOMETHING);
                    161:        }
                    162:        return((confused ? STOPPED_ON_SOMETHING : MOVED));
                    163: }
                    164: 
                    165: multiple_move_rogue(dirch)
                    166: short dirch;
                    167: {
                    168:        short row, col;
                    169:        short m;
                    170: 
                    171:        switch(dirch) {
                    172:        case '\010':
                    173:        case '\012':
                    174:        case '\013':
                    175:        case '\014':
                    176:        case '\031':
                    177:        case '\025':
                    178:        case '\016':
                    179:        case '\002':
                    180:                do {
                    181:                        row = rogue.row;
                    182:                        col = rogue.col;
                    183:                        if (((m = one_move_rogue((dirch + 96), 1)) == MOVE_FAILED) ||
                    184:                                (m == STOPPED_ON_SOMETHING) ||
                    185:                                interrupted) {
                    186:                                break;
                    187:                        }
                    188:                } while (!next_to_something(row, col));
                    189:                if (    (!interrupted) && passgo && (m == MOVE_FAILED) &&
                    190:                                (dungeon[rogue.row][rogue.col] & TUNNEL)) {
                    191:                        turn_passage(dirch + 96, 0);
                    192:                }
                    193:                break;
                    194:        case 'H':
                    195:        case 'J':
                    196:        case 'K':
                    197:        case 'L':
                    198:        case 'B':
                    199:        case 'Y':
                    200:        case 'U':
                    201:        case 'N':
                    202:                while ((!interrupted) && (one_move_rogue((dirch + 32), 1) == MOVED)) ;
                    203: 
                    204:                if (    (!interrupted) && passgo &&
                    205:                                (dungeon[rogue.row][rogue.col] & TUNNEL)) {
                    206:                        turn_passage(dirch + 32, 1);
                    207:                }
                    208:                break;
                    209:        }
                    210: }
                    211: 
                    212: is_passable(row, col)
                    213: register row, col;
                    214: {
                    215:        if ((row < MIN_ROW) || (row > (DROWS - 2)) || (col < 0) ||
                    216:                (col > (DCOLS-1))) {
                    217:                return(0);
                    218:        }
                    219:        if (dungeon[row][col] & HIDDEN) {
                    220:                return((dungeon[row][col] & TRAP) ? 1 : 0);
                    221:        }
                    222:        return(dungeon[row][col] & (FLOOR | TUNNEL | DOOR | STAIRS | TRAP));
                    223: }
                    224: 
                    225: next_to_something(drow, dcol)
                    226: register drow, dcol;
                    227: {
                    228:        short i, j, i_end, j_end, row, col;
                    229:        short pass_count = 0;
                    230:        unsigned short s;
                    231: 
                    232:        if (confused) {
                    233:                return(1);
                    234:        }
                    235:        if (blind) {
                    236:                return(0);
                    237:        }
                    238:        i_end = (rogue.row < (DROWS-2)) ? 1 : 0;
                    239:        j_end = (rogue.col < (DCOLS-1)) ? 1 : 0;
                    240: 
                    241:        for (i = ((rogue.row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
                    242:                for (j = ((rogue.col > 0) ? -1 : 0); j <= j_end; j++) {
                    243:                        if ((i == 0) && (j == 0)) {
                    244:                                continue;
                    245:                        }
                    246:                        if (((rogue.row+i) == drow) && ((rogue.col+j) == dcol)) {
                    247:                                continue;
                    248:                        }
                    249:                        row = rogue.row + i;
                    250:                        col = rogue.col + j;
                    251:                        s = dungeon[row][col];
                    252:                        if (s & HIDDEN) {
                    253:                                continue;
                    254:                        }
                    255:                        /* If the rogue used to be right, up, left, down, or right of
                    256:                         * row,col, and now isn't, then don't stop */
                    257:                        if (s & (MONSTER | OBJECT | STAIRS)) {
                    258:                                if (((row == drow) || (col == dcol)) &&
                    259:                                        (!((row == rogue.row) || (col == rogue.col)))) {
                    260:                                        continue;
                    261:                                }
                    262:                                return(1);
                    263:                        }
                    264:                        if (s & TRAP) {
                    265:                                if (!(s & HIDDEN)) {
                    266:                                        if (((row == drow) || (col == dcol)) &&
                    267:                                                (!((row == rogue.row) || (col == rogue.col)))) {
                    268:                                                continue;
                    269:                                        }
                    270:                                        return(1);
                    271:                                }
                    272:                        }
                    273:                        if ((((i - j) == 1) || ((i - j) == -1)) && (s & TUNNEL)) {
                    274:                                if (++pass_count > 1) {
                    275:                                        return(1);
                    276:                                }
                    277:                        }
                    278:                        if ((s & DOOR) && ((i == 0) || (j == 0))) {
                    279:                                        return(1);
                    280:                        }
                    281:                }
                    282:        }
                    283:        return(0);
                    284: }
                    285: 
                    286: can_move(row1, col1, row2, col2) 
                    287: {
                    288:        if (!is_passable(row2, col2)) {
                    289:                return(0);
                    290:        }
                    291:        if ((row1 != row2) && (col1 != col2)) {
                    292:                if ((dungeon[row1][col1] & DOOR) || (dungeon[row2][col2] & DOOR)) {
                    293:                        return(0);
                    294:                }
                    295:                if ((!dungeon[row1][col2]) || (!dungeon[row2][col1])) {
                    296:                        return(0);
                    297:                }
                    298:        }
                    299:        return(1);
                    300: }
                    301: 
                    302: move_onto()
                    303: {
                    304:        short ch, d;
                    305:        boolean first_miss = 1;
                    306: 
                    307:        while (!is_direction(ch = rgetchar(), &d)) {
                    308:                sound_bell();
                    309:                if (first_miss) {
                    310:                        message("direction? ", 0);
                    311:                        first_miss = 0;
                    312:                }
                    313:        }
                    314:        check_message();
                    315:        if (ch != CANCEL) {
                    316:                (void) one_move_rogue(ch, 0);
                    317:        }
                    318: }
                    319: 
                    320: boolean
                    321: is_direction(c, d)
                    322: short c;
                    323: short *d;
                    324: {
                    325:        switch(c) {
                    326:        case 'h':
                    327:                *d = LEFT;
                    328:                break;
                    329:        case 'j':
                    330:                *d = DOWN;
                    331:                break;
                    332:        case 'k':
                    333:                *d = UPWARD;
                    334:                break;
                    335:        case 'l':
                    336:                *d = RIGHT;
                    337:                break;
                    338:        case 'b':
                    339:                *d = DOWNLEFT;
                    340:                break;
                    341:        case 'y':
                    342:                *d = UPLEFT;
                    343:                break;
                    344:        case 'u':
                    345:                *d = UPRIGHT;
                    346:                break;
                    347:        case 'n':
                    348:                *d = DOWNRIGHT;
                    349:                break;
                    350:        case CANCEL:
                    351:                break;
                    352:        default:
                    353:                return(0);
                    354:        }
                    355:        return(1);
                    356: }
                    357: 
                    358: boolean
                    359: check_hunger(msg_only)
                    360: boolean msg_only;
                    361: {
                    362:        register short i, n;
                    363:        boolean fainted = 0;
                    364: 
                    365:        if (rogue.moves_left == HUNGRY) {
                    366:                (void) strcpy(hunger_str, "hungry");
                    367:                message(hunger_str, 0);
                    368:                print_stats(STAT_HUNGER);
                    369:        }
                    370:        if (rogue.moves_left == WEAK) {
                    371:                (void) strcpy(hunger_str, "weak");
                    372:                message(hunger_str, 1);
                    373:                print_stats(STAT_HUNGER);
                    374:        }
                    375:        if (rogue.moves_left <= FAINT) {
                    376:                if (rogue.moves_left == FAINT) {
                    377:                        (void) strcpy(hunger_str, "faint");
                    378:                        message(hunger_str, 1);
                    379:                        print_stats(STAT_HUNGER);
                    380:                }
                    381:                n = get_rand(0, (FAINT - rogue.moves_left));
                    382:                if (n > 0) {
                    383:                        fainted = 1;
                    384:                        if (rand_percent(40)) {
                    385:                                rogue.moves_left++;
                    386:                        }
                    387:                        message("you faint", 1);
                    388:                        for (i = 0; i < n; i++) {
                    389:                                if (coin_toss()) {
                    390:                                        mv_mons();
                    391:                                }
                    392:                        }
                    393:                        message(you_can_move_again, 1);
                    394:                }
                    395:        }
                    396:        if (msg_only) {
                    397:                return(fainted);
                    398:        }
                    399:        if (rogue.moves_left <= STARVE) {
                    400:                killed_by((object *) 0, STARVATION);
                    401:        }
                    402: 
                    403:        switch(e_rings) {
                    404:        /*case -2:
                    405:                Subtract 0, i.e. do nothing.
                    406:                break;*/
                    407:        case -1:
                    408:                rogue.moves_left -= (rogue.moves_left % 2);
                    409:                break;
                    410:        case 0:
                    411:                rogue.moves_left--;
                    412:                break;
                    413:        case 1:
                    414:                rogue.moves_left--;
                    415:                (void) check_hunger(1);
                    416:                rogue.moves_left -= (rogue.moves_left % 2);
                    417:                break;
                    418:        case 2:
                    419:                rogue.moves_left--;
                    420:                (void) check_hunger(1);
                    421:                rogue.moves_left--;
                    422:                break;
                    423:        }
                    424:        return(fainted);
                    425: }
                    426: 
                    427: boolean
                    428: reg_move()
                    429: {
                    430:        boolean fainted;
                    431: 
                    432:        if ((rogue.moves_left <= HUNGRY) || (cur_level >= max_level)) {
                    433:                fainted = check_hunger(0);
                    434:        } else {
                    435:                fainted = 0;
                    436:        }
                    437: 
                    438:        mv_mons();
                    439: 
                    440:        if (++m_moves >= 120) {
                    441:                m_moves = 0;
                    442:                wanderer();
                    443:        }
                    444:        if (halluc) {
                    445:                if (!(--halluc)) {
                    446:                        unhallucinate();
                    447:                } else {
                    448:                        hallucinate();
                    449:                }
                    450:        }
                    451:        if (blind) {
                    452:                if (!(--blind)) {
                    453:                        unblind();
                    454:                }
                    455:        }
                    456:        if (confused) {
                    457:                if (!(--confused)) {
                    458:                        unconfuse();
                    459:                }
                    460:        }
                    461:        if (bear_trap) {
                    462:                bear_trap--;
                    463:        }
                    464:        if (levitate) {
                    465:                if (!(--levitate)) {
                    466:                        message("you float gently to the ground", 1);
                    467:                        if (dungeon[rogue.row][rogue.col] & TRAP) {
                    468:                                trap_player(rogue.row, rogue.col);
                    469:                        }
                    470:                }
                    471:        }
                    472:        if (haste_self) {
                    473:                if (!(--haste_self)) {
                    474:                        message("you feel yourself slowing down", 0);
                    475:                }
                    476:        }
                    477:        heal();
                    478:        if (auto_search > 0) {
                    479:                search(auto_search, auto_search);
                    480:        }
                    481:        return(fainted);
                    482: }
                    483: 
                    484: rest(count)
                    485: {
                    486:        int i;
                    487: 
                    488:        interrupted = 0;
                    489: 
                    490:        for (i = 0; i < count; i++) {
                    491:                if (interrupted) {
                    492:                        break;
                    493:                }
                    494:                (void) reg_move();
                    495:        }
                    496: }
                    497: 
                    498: gr_dir()
                    499: {
                    500:        short d;
                    501: 
                    502:        d = get_rand(1, 8);
                    503: 
                    504:        switch(d) {
                    505:                case 1:
                    506:                        d = 'j';
                    507:                        break;
                    508:                case 2:
                    509:                        d = 'k';
                    510:                        break;
                    511:                case 3:
                    512:                        d = 'l';
                    513:                        break;
                    514:                case 4:
                    515:                        d = 'h';
                    516:                        break;
                    517:                case 5:
                    518:                        d = 'y';
                    519:                        break;
                    520:                case 6:
                    521:                        d = 'u';
                    522:                        break;
                    523:                case 7:
                    524:                        d = 'b';
                    525:                        break;
                    526:                case 8:
                    527:                        d = 'n';
                    528:                        break;
                    529:        }
                    530:        return(d);
                    531: }
                    532: 
                    533: heal()
                    534: {
                    535:        static short heal_exp = -1, n, c = 0;
                    536:        static boolean alt;
                    537: 
                    538:        if (rogue.hp_current == rogue.hp_max) {
                    539:                c = 0;
                    540:                return;
                    541:        }
                    542:        if (rogue.exp != heal_exp) {
                    543:                heal_exp = rogue.exp;
                    544: 
                    545:                switch(heal_exp) {
                    546:                case 1:
                    547:                        n = 20;
                    548:                        break;
                    549:                case 2:
                    550:                        n = 18;
                    551:                        break;
                    552:                case 3:
                    553:                        n = 17;
                    554:                        break;
                    555:                case 4:
                    556:                        n = 14;
                    557:                        break;
                    558:                case 5:
                    559:                        n = 13;
                    560:                        break;
                    561:                case 6:
                    562:                        n = 10;
                    563:                        break;
                    564:                case 7:
                    565:                        n = 9;
                    566:                        break;
                    567:                case 8:
                    568:                        n = 8;
                    569:                        break;
                    570:                case 9:
                    571:                        n = 7;
                    572:                        break;
                    573:                case 10:
                    574:                        n = 4;
                    575:                        break;
                    576:                case 11:
                    577:                        n = 3;
                    578:                        break;
                    579:                case 12:
                    580:                default:
                    581:                        n = 2;
                    582:                }
                    583:        }
                    584:        if (++c >= n) {
                    585:                c = 0;
                    586:                rogue.hp_current++;
                    587:                if (alt = !alt) {
                    588:                        rogue.hp_current++;
                    589:                }
                    590:                if ((rogue.hp_current += regeneration) > rogue.hp_max) {
                    591:                        rogue.hp_current = rogue.hp_max;
                    592:                }
                    593:                print_stats(STAT_HP);
                    594:        }
                    595: }
                    596: 
                    597: static boolean
                    598: can_turn(nrow, ncol)
                    599: short nrow, ncol;
                    600: {
                    601:        if ((dungeon[nrow][ncol] & TUNNEL) && is_passable(nrow, ncol)) {
                    602:                return(1);
                    603:        }
                    604:        return(0);
                    605: }
                    606: 
                    607: turn_passage(dir, fast)
                    608: short dir;
                    609: boolean fast;
                    610: {
                    611:        short crow = rogue.row, ccol = rogue.col, turns = 0;
                    612:        short ndir;
                    613: 
                    614:        if ((dir != 'h') && can_turn(crow, ccol + 1)) {
                    615:                turns++;
                    616:                ndir = 'l';
                    617:        }
                    618:        if ((dir != 'l') && can_turn(crow, ccol - 1)) {
                    619:                turns++;
                    620:                ndir = 'h';
                    621:        }
                    622:        if ((dir != 'k') && can_turn(crow + 1, ccol)) {
                    623:                turns++;
                    624:                ndir = 'j';
                    625:        }
                    626:        if ((dir != 'j') && can_turn(crow - 1, ccol)) {
                    627:                turns++;
                    628:                ndir = 'k';
                    629:        }
                    630:        if (turns == 1) {
                    631:                multiple_move_rogue(ndir - (fast ? 32 : 96));
                    632:        }
                    633: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.