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