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

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

unix.superglobalmegacorp.com

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