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

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

unix.superglobalmegacorp.com

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