Annotation of early-roguelike/srogue/passages.c, Revision 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