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