[BACK]Return to passages.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / srogue

Annotation of early-roguelike/srogue/passages.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * Draw the connecting passages
                      3:  *
                      4:  * @(#)passages.c      9.0     (rdk)    7/17/84
                      5:  *
                      6:  * Super-Rogue
                      7:  * Copyright (C) 1984 Robert D. Kindelberger
                      8:  * All rights reserved.
                      9:  *
                     10:  * Based on "Rogue: Exploring the Dungeons of Doom"
                     11:  * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     12:  * All rights reserved.
                     13:  *
                     14:  * See the file LICENSE.TXT for full copyright and licensing information.
                     15:  */
                     16:
                     17: #include <stdlib.h>
                     18: #include "rogue.h"
                     19: #include "rogue.ext"
                     20:
                     21: void conn(int r1, int r2);
                     22: void door(struct room *rm, struct coord *cp);
                     23:
                     24: /*
                     25:  * do_passages:
                     26:  *     Draw all the passages on a level.
                     27:  */
                     28:
                     29: void
                     30: do_passages(void)
                     31: {
                     32:        reg struct rdes *r1, *r2 = NULL;
                     33:        reg int i, j;
                     34:        reg int roomcount;
                     35:        static struct rdes {
                     36:                bool conn[MAXROOMS];            /* possible to connect to room i */
                     37:                bool isconn[MAXROOMS];          /* connection was made to room i */
                     38:                bool    ingraph;                        /* this room in graph already? */
                     39:        } rdes[MAXROOMS] = {
                     40:                {{ 0, 1, 0, 1, 0, 0, 0, 0, 0 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
                     41:                {{ 1, 0, 1, 0, 1, 0, 0, 0, 0 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
                     42:                {{ 0, 1, 0, 0, 0, 1, 0, 0, 0 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
                     43:                {{ 1, 0, 0, 0, 1, 0, 1, 0, 0 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
                     44:                {{ 0, 1, 0, 1, 0, 1, 0, 1, 0 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
                     45:                {{ 0, 0, 1, 0, 1, 0, 0, 0, 1 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
                     46:                {{ 0, 0, 0, 1, 0, 0, 0, 1, 0 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
                     47:                {{ 0, 0, 0, 0, 1, 0, 1, 0, 1 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
                     48:                {{ 0, 0, 0, 0, 0, 1, 0, 1, 0 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
                     49:        };
                     50:
                     51:        /*
                     52:         * reinitialize room graph description
                     53:         */
                     54:        for (r1 = rdes; r1 < &rdes[MAXROOMS]; r1++) {
                     55:                for (j = 0; j < MAXROOMS; j++)
                     56:                        r1->isconn[j] = FALSE;
                     57:                r1->ingraph = FALSE;
                     58:        }
                     59:
                     60:        /*
                     61:         * starting with one room, connect it to a random adjacent room and
                     62:         * then pick a new room to start with.
                     63:         */
                     64:        roomcount = 1;
                     65:        r1 = &rdes[rnd(MAXROOMS)];
                     66:        r1->ingraph = TRUE;
                     67:        do {
                     68:                /*
                     69:                 * find a room to connect with
                     70:                 */
                     71:                j = 0;
                     72:                for (i = 0; i < MAXROOMS; i++)
                     73:                        if (r1->conn[i] && !rdes[i].ingraph && rnd(++j) == 0)
                     74:                                r2 = &rdes[i];
                     75:                /*
                     76:                 * if no adjacent rooms are outside the graph, pick a new room
                     77:                 * to look from
                     78:                 */
                     79:                if (j == 0) {
                     80:                        do {
                     81:                                r1 = &rdes[rnd(MAXROOMS)];
                     82:                        } until (r1->ingraph);
                     83:                }
                     84:                /*
                     85:                 * otherwise, connect new room to the graph, and draw a tunnel
                     86:                 * to it
                     87:                 */
                     88:                else {
                     89:                        r2->ingraph = TRUE;
                     90:                        i = r1 - rdes;
                     91:                        j = r2 - rdes;
                     92:                        conn(i, j);
                     93:                        r1->isconn[j] = TRUE;
                     94:                        r2->isconn[i] = TRUE;
                     95:                        roomcount++;
                     96:                }
                     97:        } while (roomcount < MAXROOMS);
                     98:
                     99:        /*
                    100:         * attempt to add passages to the graph a random number of times so
                    101:         * that there isn't just one unique passage through it.
                    102:         */
                    103:        for (roomcount = rnd(5); roomcount > 0; roomcount--) {
                    104:                r1 = &rdes[rnd(MAXROOMS)];      /* a random room to look from */
                    105:                /*
                    106:                 * find an adjacent room not already connected
                    107:                 */
                    108:                j = 0;
                    109:                for (i = 0; i < MAXROOMS; i++)
                    110:                        if (r1->conn[i] && !r1->isconn[i] && rnd(++j) == 0)
                    111:                                r2 = &rdes[i];
                    112:                /*
                    113:                 * if there is one, connect it and look for the next added
                    114:                 * passage
                    115:                 */
                    116:                if (j != 0) {
                    117:                        i = r1 - rdes;
                    118:                        j = r2 - rdes;
                    119:                        conn(i, j);
                    120:                        r1->isconn[j] = TRUE;
                    121:                        r2->isconn[i] = TRUE;
                    122:                }
                    123:        }
                    124: }
                    125:
                    126: /*
                    127:  * conn:
                    128:  *     Cconnect two rooms.
                    129:  */
                    130:
                    131: void
                    132: conn(int r1, int r2)
                    133: {
                    134:        reg struct room *rpf, *rpt = NULL;
                    135:        reg char rmt, direc;
                    136:        reg int distance, turn_spot, turn_distance, rm;
                    137:        struct coord curr, turn_delta, spos, epos;
                    138:
                    139:        if (r1 < r2) {
                    140:                rm = r1;
                    141:                if (r1 + 1 == r2)
                    142:                        direc = 'r';
                    143:                else
                    144:                        direc = 'd';
                    145:        }
                    146:        else {
                    147:                rm = r2;
                    148:                if (r2 + 1 == r1)
                    149:                        direc = 'r';
                    150:                else
                    151:                        direc = 'd';
                    152:        }
                    153:        rpf = &rooms[rm];
                    154:        /*
                    155:         * Set up the movement variables, in two cases:
                    156:         * first drawing one down.
                    157:         */
                    158:        if (direc == 'd') {
                    159:                rmt = rm + 3;                           /* room # of dest */
                    160:                rpt = &rooms[rmt];                      /* room pointer of dest */
                    161:                delta.x = 0;                            /* direction of move */
                    162:                delta.y = 1;
                    163:                spos.x = rpf->r_pos.x;                  /* start of move */
                    164:                spos.y = rpf->r_pos.y;
                    165:                epos.x = rpt->r_pos.x;                  /* end of move */
                    166:                epos.y = rpt->r_pos.y;
                    167:                if (!rf_on(rpf,ISGONE)) {               /* if not gone pick door pos */
                    168:                        spos.x += rnd(rpf->r_max.x-2)+1;
                    169:                        spos.y += rpf->r_max.y-1;
                    170:                }
                    171:                if (!rf_on(rpt,ISGONE))
                    172:                        epos.x += rnd(rpt->r_max.x-2)+1;
                    173:                distance = abs(spos.y - epos.y) - 1;    /* distance to move */
                    174:                turn_delta.y = 0;                                               /* direction to turn */
                    175:                turn_delta.x = (spos.x < epos.x ? 1 : -1);
                    176:                turn_distance = abs(spos.x - epos.x);   /* how far to turn */
                    177:                turn_spot = rnd(distance-1) + 1;                /* where turn starts */
                    178:        }
                    179:        else if (direc == 'r') {                /* setup for moving right */
                    180:                rmt = rm + 1;
                    181:                rpt = &rooms[rmt];
                    182:                delta.x = 1;
                    183:                delta.y = 0;
                    184:                spos.x = rpf->r_pos.x;
                    185:                spos.y = rpf->r_pos.y;
                    186:                epos.x = rpt->r_pos.x;
                    187:                epos.y = rpt->r_pos.y;
                    188:                if (!rf_on(rpf,ISGONE)) {
                    189:                        spos.x += rpf->r_max.x-1;
                    190:                        spos.y += rnd(rpf->r_max.y-2)+1;
                    191:                }
                    192:                if (!rf_on(rpt,ISGONE))
                    193:                        epos.y += rnd(rpt->r_max.y-2)+1;
                    194:                distance = abs(spos.x - epos.x) - 1;
                    195:                turn_delta.y = (spos.y < epos.y ? 1 : -1);
                    196:                turn_delta.x = 0;
                    197:                turn_distance = abs(spos.y - epos.y);
                    198:                turn_spot = rnd(distance-1) + 1;
                    199:        }
                    200:        else {
                    201:                msg("Error in connection tables.");
                    202:        }
                    203:        /*
                    204:         * Draw in the doors on either side of the passage
                    205:         * or just put #'s if the rooms are gone. Set up
                    206:         * pointers to the connected room.
                    207:         */
                    208:        rpf->r_ptr[rpf->r_nexits] = rpt;
                    209:        if (rf_on(rpf,ISGONE)) {
                    210:                cmov(spos);
                    211:                addch('#');             /* gone "from" room */
                    212:        }
                    213:        else
                    214:                door(rpf, &spos);       /* add the door */
                    215:        rpt->r_ptr[rpt->r_nexits] = rpf;
                    216:        if (rf_on(rpt,ISGONE)) {
                    217:                cmov(epos);
                    218:                addch('#');             /* gone "to" room */
                    219:        }
                    220:        else
                    221:                door(rpt, &epos);       /* add door */
                    222:        /*
                    223:         * Get ready to move...
                    224:         */
                    225:        curr.x = spos.x;
                    226:        curr.y = spos.y;
                    227:        while(distance > 0) {
                    228:                /*
                    229:                 * Move to new position
                    230:                 */
                    231:                curr.x += delta.x;
                    232:                curr.y += delta.y;
                    233:                /*
                    234:                 * Check if we are at the turn place, if so do the turn
                    235:                 */
                    236:                if (distance == turn_spot && turn_distance > 0) {
                    237:                        while(turn_distance-- > 0) {
                    238:                                cmov(curr);
                    239:                                addch(PASSAGE);
                    240:                                curr.x += turn_delta.x;
                    241:                                curr.y += turn_delta.y;
                    242:                        }
                    243:                }
                    244:                /*
                    245:                 * Continue digging along
                    246:                 */
                    247:                cmov(curr);
                    248:                addch(PASSAGE);
                    249:                distance--;
                    250:        }
                    251:        curr.x += delta.x;
                    252:        curr.y += delta.y;
                    253:        if (!ce(curr, epos)) {
                    254:                msg("Warning, connectivity problem on this level.");
                    255:        }
                    256: }
                    257:
                    258: /*
                    259:  * Add a door or possibly a secret door
                    260:  * also enters the door in the exits array of the room.
                    261:  */
                    262:
                    263: void
                    264: door(struct room *rm, struct coord *cp)
                    265: {
                    266:        cmov(*cp);
                    267:        addch(rnd(10) < level - 1 && rnd(100) < 20 ? SECRETDOOR : DOOR);
                    268:        rm->r_exit[rm->r_nexits++] = *cp;
                    269: }
                    270:
                    271:
                    272: /*
                    273:  * add_pass:
                    274:  *     add the passages to the current window (wizard command)
                    275:  */
                    276: void
                    277: add_pass(void)
                    278: {
                    279:        reg int y, x, ch;
                    280:
                    281:        for (y = 1; y < LINES - 3; y++)
                    282:                for (x = 0; x < COLS; x++)
                    283:                        if ((ch = mvinch(y, x)) == PASSAGE || ch == DOOR ||
                    284:                          ch == SECRETDOOR)
                    285:                                mvwaddch(cw, y, x, ch);
                    286: }

CVSweb