Annotation of 43BSDReno/games/rogue/move.c, revision 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.