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