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

1.1       root        1: /*
                      2:  * room.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[] = "@(#)room.c     5.1 (Berkeley) 11/25/87";
                     15: #endif /* not lint */
                     16: 
                     17: #include "rogue.h"
                     18: 
                     19: room rooms[MAXROOMS];
                     20: boolean rooms_visited[MAXROOMS];
                     21: 
                     22: extern short blind;
                     23: extern boolean detect_monster, jump, passgo, no_skull, ask_quit;
                     24: extern char *nick_name, *fruit, *save_file, *press_space;
                     25: 
                     26: #define NOPTS 7
                     27: 
                     28: struct option {
                     29:        char *prompt;
                     30:        boolean is_bool;
                     31:        char **strval;
                     32:        boolean *bval;
                     33: } options[NOPTS] = {
                     34:        {
                     35:                "Show position only at end of run (\"jump\"): ",
                     36:                1, (char **) 0, &jump
                     37:        },
                     38:        {
                     39:                "Follow turnings in passageways (\"passgo\"): ",
                     40:                1, (char **) 0, &passgo
                     41:        },
                     42:        {
                     43:                "Don't print skull when killed (\"noskull\" or \"notombstone\"): ",
                     44:                1, (char **) 0, &no_skull
                     45:        },
                     46:        {
                     47:                "Ask player before saying 'Okay, bye-bye!' (\"askquit\"): ",
                     48:                1, (char **) 0, &ask_quit
                     49:        },
                     50:        {
                     51:                "Name (\"name\"): ",
                     52:                0, &nick_name
                     53:        },
                     54:        {
                     55:                "Fruit (\"fruit\"): ",
                     56:                0, &fruit
                     57:        },
                     58:        {
                     59:                "Save file (\"file\"): ",
                     60:                0, &save_file
                     61:        }
                     62: };
                     63: 
                     64: light_up_room(rn)
                     65: int rn;
                     66: {
                     67:        short i, j;
                     68: 
                     69:        if (!blind) {
                     70:                for (i = rooms[rn].top_row;
                     71:                        i <= rooms[rn].bottom_row; i++) {
                     72:                        for (j = rooms[rn].left_col;
                     73:                                j <= rooms[rn].right_col; j++) {
                     74:                                if (dungeon[i][j] & MONSTER) {
                     75:                                        object *monster;
                     76: 
                     77:                                        if (monster = object_at(&level_monsters, i, j)) {
                     78:                                                dungeon[monster->row][monster->col] &= (~MONSTER);
                     79:                                                monster->trail_char =
                     80:                                                        get_dungeon_char(monster->row, monster->col);
                     81:                                                dungeon[monster->row][monster->col] |= MONSTER;
                     82:                                        }
                     83:                                }
                     84:                                mvaddch(i, j, get_dungeon_char(i, j));
                     85:                        }
                     86:                }
                     87:                mvaddch(rogue.row, rogue.col, rogue.fchar);
                     88:        }
                     89: }
                     90: 
                     91: light_passage(row, col)
                     92: {
                     93:        short i, j, i_end, j_end;
                     94: 
                     95:        if (blind) {
                     96:                return;
                     97:        }
                     98:        i_end = (row < (DROWS-2)) ? 1 : 0;
                     99:        j_end = (col < (DCOLS-1)) ? 1 : 0;
                    100: 
                    101:        for (i = ((row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
                    102:                for (j = ((col > 0) ? -1 : 0); j <= j_end; j++) {
                    103:                        if (can_move(row, col, row+i, col+j)) {
                    104:                                mvaddch(row+i, col+j, get_dungeon_char(row+i, col+j));
                    105:                        }
                    106:                }
                    107:        }
                    108: }
                    109: 
                    110: darken_room(rn)
                    111: short rn;
                    112: {
                    113:        short i, j;
                    114: 
                    115:        for (i = rooms[rn].top_row + 1; i < rooms[rn].bottom_row; i++) {
                    116:                for (j = rooms[rn].left_col + 1; j < rooms[rn].right_col; j++) {
                    117:                        if (blind) {
                    118:                                mvaddch(i, j, ' ');
                    119:                        } else {
                    120:                                if (!(dungeon[i][j] & (OBJECT | STAIRS)) &&
                    121:                                        !(detect_monster && (dungeon[i][j] & MONSTER))) {
                    122:                                        if (!imitating(i, j)) {
                    123:                                                mvaddch(i, j, ' ');
                    124:                                        }
                    125:                                        if ((dungeon[i][j] & TRAP) && (!(dungeon[i][j] & HIDDEN))) {
                    126:                                                mvaddch(i, j, '^');
                    127:                                        }
                    128:                                }
                    129:                        }
                    130:                }
                    131:        }
                    132: }
                    133: 
                    134: get_dungeon_char(row, col)
                    135: register row, col;
                    136: {
                    137:        register unsigned short mask = dungeon[row][col];
                    138: 
                    139:        if (mask & MONSTER) {
                    140:                return(gmc_row_col(row, col));
                    141:        }
                    142:        if (mask & OBJECT) {
                    143:                object *obj;
                    144: 
                    145:                obj = object_at(&level_objects, row, col);
                    146:                return(get_mask_char(obj->what_is));
                    147:        }
                    148:        if (mask & (TUNNEL | STAIRS | HORWALL | VERTWALL | FLOOR | DOOR)) {
                    149:                if ((mask & (TUNNEL| STAIRS)) && (!(mask & HIDDEN))) {
                    150:                        return(((mask & STAIRS) ? '%' : '#'));
                    151:                }
                    152:                if (mask & HORWALL) {
                    153:                        return('-');
                    154:                }
                    155:                if (mask & VERTWALL) {
                    156:                        return('|');
                    157:                }
                    158:                if (mask & FLOOR) {
                    159:                        if (mask & TRAP) {
                    160:                                if (!(dungeon[row][col] & HIDDEN)) {
                    161:                                        return('^');
                    162:                                }
                    163:                        }
                    164:                        return('.');
                    165:                }
                    166:                if (mask & DOOR) {
                    167:                        if (mask & HIDDEN) {
                    168:                                if (((col > 0) && (dungeon[row][col-1] & HORWALL)) ||
                    169:                                        ((col < (DCOLS-1)) && (dungeon[row][col+1] & HORWALL))) {
                    170:                                        return('-');
                    171:                                } else {
                    172:                                        return('|');
                    173:                                }
                    174:                        } else {
                    175:                                return('+');
                    176:                        }
                    177:                }
                    178:        }
                    179:        return(' ');
                    180: }
                    181: 
                    182: get_mask_char(mask)
                    183: register unsigned short mask;
                    184: {
                    185:                switch(mask) {
                    186:                case SCROL:
                    187:                        return('?');
                    188:                case POTION:
                    189:                        return('!');
                    190:                case GOLD:
                    191:                        return('*');
                    192:                case FOOD:
                    193:                        return(':');
                    194:                case WAND:
                    195:                        return('/');
                    196:                case ARMOR:
                    197:                        return(']');
                    198:                case WEAPON:
                    199:                        return(')');
                    200:                case RING:
                    201:                        return('=');
                    202:                case AMULET:
                    203:                        return(',');
                    204:                default:
                    205:                        return('~');    /* unknown, something is wrong */
                    206:                }
                    207: }
                    208: 
                    209: gr_row_col(row, col, mask)
                    210: short *row, *col;
                    211: unsigned short mask;
                    212: {
                    213:        short rn;
                    214:        short r, c;
                    215: 
                    216:        do {
                    217:                r = get_rand(MIN_ROW, DROWS-2);
                    218:                c = get_rand(0, DCOLS-1);
                    219:                rn = get_room_number(r, c);
                    220:        } while ((rn == NO_ROOM) ||
                    221:                (!(dungeon[r][c] & mask)) ||
                    222:                (dungeon[r][c] & (~mask)) ||
                    223:                (!(rooms[rn].is_room & (R_ROOM | R_MAZE))) ||
                    224:                ((r == rogue.row) && (c == rogue.col)));
                    225: 
                    226:        *row = r;
                    227:        *col = c;
                    228: }
                    229: 
                    230: gr_room()
                    231: {
                    232:        short i;
                    233: 
                    234:        do {
                    235:                i = get_rand(0, MAXROOMS-1);
                    236:        } while (!(rooms[i].is_room & (R_ROOM | R_MAZE)));
                    237: 
                    238:        return(i);
                    239: }
                    240: 
                    241: party_objects(rn)
                    242: {
                    243:        short i, j, nf = 0;
                    244:        object *obj;
                    245:        short n, N, row, col;
                    246:        boolean found;
                    247: 
                    248:        N = ((rooms[rn].bottom_row - rooms[rn].top_row) - 1) *
                    249:                ((rooms[rn].right_col - rooms[rn].left_col) - 1);
                    250:        n =  get_rand(5, 10);
                    251:        if (n > N) {
                    252:                n = N - 2;
                    253:        }
                    254:        for (i = 0; i < n; i++) {
                    255:                for (j = found = 0; ((!found) && (j < 250)); j++) {
                    256:                        row = get_rand(rooms[rn].top_row+1,
                    257:                                           rooms[rn].bottom_row-1);
                    258:                        col = get_rand(rooms[rn].left_col+1,
                    259:                                           rooms[rn].right_col-1);
                    260:                        if ((dungeon[row][col] == FLOOR) || (dungeon[row][col] == TUNNEL)) {
                    261:                                found = 1;
                    262:                        }
                    263:                }
                    264:                if (found) {
                    265:                        obj = gr_object();
                    266:                        place_at(obj, row, col);
                    267:                        nf++;
                    268:                }
                    269:        }
                    270:        return(nf);
                    271: }
                    272: 
                    273: get_room_number(row, col)
                    274: register row, col;
                    275: {
                    276:        short i;
                    277: 
                    278:        for (i = 0; i < MAXROOMS; i++) {
                    279:                if ((row >= rooms[i].top_row) && (row <= rooms[i].bottom_row) &&
                    280:                        (col >= rooms[i].left_col) && (col <= rooms[i].right_col)) {
                    281:                        return(i);
                    282:                }
                    283:        }
                    284:        return(NO_ROOM);
                    285: }
                    286: 
                    287: is_all_connected()
                    288: {
                    289:        short i, starting_room;
                    290: 
                    291:        for (i = 0; i < MAXROOMS; i++) {
                    292:                rooms_visited[i] = 0;
                    293:                if (rooms[i].is_room & (R_ROOM | R_MAZE)) {
                    294:                        starting_room = i;
                    295:                }
                    296:        }
                    297: 
                    298:        visit_rooms(starting_room);
                    299: 
                    300:        for (i = 0; i < MAXROOMS; i++) {
                    301:                if ((rooms[i].is_room & (R_ROOM | R_MAZE)) && (!rooms_visited[i])) {
                    302:                        return(0);
                    303:                }
                    304:        }
                    305:        return(1);
                    306: }
                    307: 
                    308: visit_rooms(rn)
                    309: int rn;
                    310: {
                    311:        short i;
                    312:        short oth_rn;
                    313: 
                    314:        rooms_visited[rn] = 1;
                    315: 
                    316:        for (i = 0; i < 4; i++) {
                    317:                oth_rn = rooms[rn].doors[i].oth_room;
                    318:                if ((oth_rn >= 0) && (!rooms_visited[oth_rn])) {
                    319:                        visit_rooms(oth_rn);
                    320:                }
                    321:        }
                    322: }
                    323: 
                    324: draw_magic_map()
                    325: {
                    326:        short i, j, ch, och;
                    327:        unsigned short mask = (HORWALL | VERTWALL | DOOR | TUNNEL | TRAP | STAIRS |
                    328:                        MONSTER);
                    329:        unsigned short s;
                    330: 
                    331:        for (i = 0; i < DROWS; i++) {
                    332:                for (j = 0; j < DCOLS; j++) {
                    333:                        s = dungeon[i][j];
                    334:                        if (s & mask) {
                    335:                                if (((ch = mvinch(i, j)) == ' ') ||
                    336:                                        ((ch >= 'A') && (ch <= 'Z')) || (s & (TRAP | HIDDEN))) {
                    337:                                        och = ch;
                    338:                                        dungeon[i][j] &= (~HIDDEN);
                    339:                                        if (s & HORWALL) {
                    340:                                                ch = '-';
                    341:                                        } else if (s & VERTWALL) {
                    342:                                                ch = '|';
                    343:                                        } else if (s & DOOR) {
                    344:                                                ch = '+';
                    345:                                        } else if (s & TRAP) {
                    346:                                                ch = '^';
                    347:                                        } else if (s & STAIRS) {
                    348:                                                ch = '%';
                    349:                                        } else if (s & TUNNEL) {
                    350:                                                ch = '#';
                    351:                                        } else {
                    352:                                                continue;
                    353:                                        }
                    354:                                        if ((!(s & MONSTER)) || (och == ' ')) {
                    355:                                                addch(ch);
                    356:                                        }
                    357:                                        if (s & MONSTER) {
                    358:                                                object *monster;
                    359: 
                    360:                                                if (monster = object_at(&level_monsters, i, j)) {
                    361:                                                        monster->trail_char = ch;
                    362:                                                }
                    363:                                        }
                    364:                                }
                    365:                        }
                    366:                }
                    367:        }
                    368: }
                    369: 
                    370: dr_course(monster, entering, row, col)
                    371: object *monster;
                    372: boolean entering;
                    373: short row, col;
                    374: {
                    375:        short i, j, k, rn;
                    376:        short r, rr;
                    377: 
                    378:        monster->row = row;
                    379:        monster->col = col;
                    380: 
                    381:        if (mon_sees(monster, rogue.row, rogue.col)) {
                    382:                monster->trow = NO_ROOM;
                    383:                return;
                    384:        }
                    385:        rn = get_room_number(row, col);
                    386: 
                    387:        if (entering) {         /* entering room */
                    388:                /* look for door to some other room */
                    389:                r = get_rand(0, MAXROOMS-1);
                    390:                for (i = 0; i < MAXROOMS; i++) {
                    391:                        rr = (r + i) % MAXROOMS;
                    392:                        if ((!(rooms[rr].is_room & (R_ROOM | R_MAZE))) || (rr == rn)) {
                    393:                                continue;
                    394:                        }
                    395:                        for (k = 0; k < 4; k++) {
                    396:                                if (rooms[rr].doors[k].oth_room == rn) {
                    397:                                        monster->trow = rooms[rr].doors[k].oth_row;
                    398:                                        monster->tcol = rooms[rr].doors[k].oth_col;
                    399:                                        if ((monster->trow == row) &&
                    400:                                                (monster->tcol == col)) {
                    401:                                                continue;
                    402:                                        }
                    403:                                        return;
                    404:                                }
                    405:                        }
                    406:                }
                    407:                /* look for door to dead end */
                    408:                for (i = rooms[rn].top_row; i <= rooms[rn].bottom_row; i++) {
                    409:                        for (j = rooms[rn].left_col; j <= rooms[rn].right_col; j++) {
                    410:                                if ((i != monster->row) && (j != monster->col) &&
                    411:                                        (dungeon[i][j] & DOOR)) {
                    412:                                        monster->trow = i;
                    413:                                        monster->tcol = j;
                    414:                                        return;
                    415:                                }
                    416:                        }
                    417:                }
                    418:                /* return monster to room that he came from */
                    419:                for (i = 0; i < MAXROOMS; i++) {
                    420:                        for (j = 0; j < 4; j++) {
                    421:                                if (rooms[i].doors[j].oth_room == rn) {
                    422:                                        for (k = 0; k < 4; k++) {
                    423:                                                if (rooms[rn].doors[k].oth_room == i) {
                    424:                                                        monster->trow = rooms[rn].doors[k].oth_row;
                    425:                                                        monster->tcol = rooms[rn].doors[k].oth_col;
                    426:                                                        return;
                    427:                                                }
                    428:                                        }
                    429:                                }
                    430:                        }
                    431:                }
                    432:                /* no place to send monster */
                    433:                monster->trow = NO_ROOM;
                    434:        } else {                /* exiting room */
                    435:                if (!get_oth_room(rn, &row, &col)) {
                    436:                        monster->trow = NO_ROOM;
                    437:                } else {
                    438:                        monster->trow = row;
                    439:                        monster->tcol = col;
                    440:                }
                    441:        }
                    442: }
                    443: 
                    444: get_oth_room(rn, row, col)
                    445: short rn, *row, *col;
                    446: {
                    447:        short d = -1;
                    448: 
                    449:        if (*row == rooms[rn].top_row) {
                    450:                d = UPWARD/2;
                    451:        } else if (*row == rooms[rn].bottom_row) {
                    452:                d = DOWN/2;
                    453:        } else if (*col == rooms[rn].left_col) {
                    454:                d = LEFT/2;
                    455:        } else if (*col == rooms[rn].right_col) {
                    456:                d = RIGHT/2;
                    457:        }
                    458:        if ((d != -1) && (rooms[rn].doors[d].oth_room >= 0)) {
                    459:                *row = rooms[rn].doors[d].oth_row;
                    460:                *col = rooms[rn].doors[d].oth_col;
                    461:                return(1);
                    462:        }
                    463:        return(0);
                    464: }
                    465: 
                    466: edit_opts()
                    467: {
                    468:        char save[NOPTS+1][DCOLS];
                    469:        short i, j;
                    470:        short ch;
                    471:        boolean done = 0;
                    472:        char buf[MAX_OPT_LEN + 2];
                    473: 
                    474:        for (i = 0; i < NOPTS+1; i++) {
                    475:                for (j = 0; j < DCOLS; j++) {
                    476:                        save[i][j] = mvinch(i, j);
                    477:                }
                    478:                if (i < NOPTS) {
                    479:                        opt_show(i);
                    480:                }
                    481:        }
                    482:        opt_go(0);
                    483:        i = 0;
                    484: 
                    485:        while (!done) {
                    486:                refresh();
                    487:                ch = rgetchar();
                    488: CH:
                    489:                switch(ch) {
                    490:                case '\033':
                    491:                        done = 1;
                    492:                        break;
                    493:                case '\012':
                    494:                case '\015':
                    495:                        if (i == (NOPTS - 1)) {
                    496:                                mvaddstr(NOPTS, 0, press_space);
                    497:                                refresh();
                    498:                                wait_for_ack();
                    499:                                done = 1;
                    500:                        } else {
                    501:                                i++;
                    502:                                opt_go(i);
                    503:                        }
                    504:                        break;
                    505:                case '-':
                    506:                        if (i > 0) {
                    507:                                opt_go(--i);
                    508:                        } else {
                    509:                                sound_bell();
                    510:                        }
                    511:                        break;
                    512:                case 't':
                    513:                case 'T':
                    514:                case 'f':
                    515:                case 'F':
                    516:                        if (options[i].is_bool) {
                    517:                                *(options[i].bval) = (((ch == 't') || (ch == 'T')) ? 1 : 0);
                    518:                                opt_show(i);
                    519:                                opt_go(++i);
                    520:                                break;
                    521:                        }
                    522:                default:
                    523:                        if (options[i].is_bool) {
                    524:                                sound_bell();
                    525:                                break;
                    526:                        }
                    527:                        j = 0;
                    528:                        if ((ch == '\010') || ((ch >= ' ') && (ch <= '~'))) {
                    529:                                opt_erase(i);
                    530:                                do {
                    531:                                        if ((ch >= ' ') && (ch <= '~') && (j < MAX_OPT_LEN)) {
                    532:                                                buf[j++] = ch;
                    533:                                                buf[j] = '\0';
                    534:                                                addch(ch);
                    535:                                        } else if ((ch == '\010') && (j > 0)) {
                    536:                                                buf[--j] = '\0';
                    537:                                                move(i, j + strlen(options[i].prompt));
                    538:                                                addch(' ');
                    539:                                                move(i, j + strlen(options[i].prompt));
                    540:                                        }
                    541:                                        refresh();
                    542:                                        ch = rgetchar();
                    543:                                } while ((ch != '\012') && (ch != '\015') && (ch != '\033'));
                    544:                                if (j != 0) {
                    545:                                        (void) strcpy(*(options[i].strval), buf);
                    546:                                }
                    547:                                opt_show(i);
                    548:                                goto CH;
                    549:                        } else {
                    550:                                sound_bell();
                    551:                        }
                    552:                        break;
                    553:                }
                    554:        }
                    555: 
                    556:        for (i = 0; i < NOPTS+1; i++) {
                    557:                move(i, 0);
                    558:                for (j = 0; j < DCOLS; j++) {
                    559:                        addch(save[i][j]);
                    560:                }
                    561:        }
                    562: }
                    563: 
                    564: opt_show(i)
                    565: int i;
                    566: {
                    567:        char *s;
                    568:        struct option *opt = &options[i];
                    569: 
                    570:        opt_erase(i);
                    571: 
                    572:        if (opt->is_bool) {
                    573:                s = *(opt->bval) ? "True" : "False";
                    574:        } else {
                    575:                s = *(opt->strval);
                    576:        }
                    577:        addstr(s);
                    578: }
                    579: 
                    580: opt_erase(i)
                    581: int i;
                    582: {
                    583:        struct option *opt = &options[i];
                    584: 
                    585:        mvaddstr(i, 0, opt->prompt);
                    586:        clrtoeol();
                    587: }
                    588: 
                    589: opt_go(i)
                    590: int i;
                    591: {
                    592:        move(i, strlen(options[i].prompt));
                    593: }
                    594: 
                    595: do_shell()
                    596: {
                    597: #ifdef UNIX
                    598:        char *sh;
                    599: 
                    600:        md_ignore_signals();
                    601:        if (!(sh = md_getenv("SHELL"))) {
                    602:                sh = "/bin/sh";
                    603:        }
                    604:        move(LINES-1, 0);
                    605:        refresh();
                    606:        stop_window();
                    607:        printf("\nCreating new shell...\n");
                    608:        md_shell(sh);
                    609:        start_window();
                    610:        wrefresh(curscr);
                    611:        md_heed_signals();
                    612: #endif
                    613: }

unix.superglobalmegacorp.com

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