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