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