ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/rogue_layout.C
(Generate patch)

Comparing deliantra/server/random_maps/rogue_layout.C (file contents):
Revision 1.5 by root, Thu Jan 18 19:42:10 2007 UTC vs.
Revision 1.8 by root, Mon Apr 14 22:41:17 2008 UTC

14 int ax, ay, zx, zy; /* coordinates of extrema of the rectangle */ 14 int ax, ay, zx, zy; /* coordinates of extrema of the rectangle */
15 15
16 int rtype; /* circle or rectangular */ 16 int rtype; /* circle or rectangular */
17} Room; 17} Room;
18 18
19static int roguelike_place_room (Room * Rooms, int xsize, int ysize, int nrooms); 19static int roguelike_place_room (Room *rooms, int xsize, int ysize, int nrooms);
20static void roguelike_make_rooms (Room * Rooms, char **maze, int options); 20static void roguelike_make_rooms (Room *rooms, char **maze, int options);
21static void roguelike_link_rooms (Room * Rooms, char **maze, int xsize, int ysize); 21static void roguelike_link_rooms (Room *rooms, char **maze, int xsize, int ysize);
22
23 22
24int 23int
25surround_check (char **layout, int i, int j, int Xsize, int Ysize) 24surround_check (char **layout, int i, int j, int Xsize, int Ysize)
26{ 25{
27 /* 1 = wall to left, 26 /* 1 = wall to left,
39 if ((j < Ysize - 1) && (layout[i][j + 1] != 0 && layout[i][j + 1] != '.')) 38 if ((j < Ysize - 1) && (layout[i][j + 1] != 0 && layout[i][j + 1] != '.'))
40 surround_index += 8; 39 surround_index += 8;
41 return surround_index; 40 return surround_index;
42} 41}
43 42
44
45/* actually make the layout: we work by a reduction process: 43/* actually make the layout: we work by a reduction process:
46 * first we make everything a wall, then we remove areas to make rooms 44 * first we make everything a wall, then we remove areas to make rooms
47 */ 45 */
48 46void
49char ** 47roguelike_layout_gen (Maze maze, int options)
50roguelike_layout_gen (int xsize, int ysize, int options)
51{ 48{
52 int i, j; 49 int i, j;
53 Room *Rooms = 0;
54 Room *walk; 50 Room *walk;
55 int nrooms = 0; 51 int nrooms = 0;
56 int tries = 0; 52 int tries = 0;
57 53
58 /* allocate that array, write walls everywhere up */ 54 int xsize = maze->w;
59 char **maze = (char **) malloc (sizeof (char *) * xsize); 55 int ysize = maze->h;
60
61 for (i = 0; i < xsize; i++)
62 {
63 maze[i] = (char *) malloc (sizeof (char) * ysize);
64 for (j = 0; j < ysize; j++)
65 maze[i][j] = '#';
66 }
67 56
68 /* minimum room size is basically 5x5: if xsize/ysize is 57 /* minimum room size is basically 5x5: if xsize/ysize is
69 less than 3x that then hollow things out, stick in 58 less than 3x that then hollow things out, stick in
70 a stairsup and stairs down, and exit */ 59 a stairsup and stairs down, and exit */
71
72 if (xsize < 11 || ysize < 11) 60 if (xsize < 11 || ysize < 11)
73 { 61 {
74 for (i = 1; i < xsize - 1; i++) 62 maze->clear ();
75 for (j = 1; j < ysize - 1; j++) 63 maze->border ();
76 maze[i][j] = 0; 64
77 maze[(xsize - 1) / 2][(ysize - 1) / 2] = '>'; 65 maze[(xsize - 1) / 2][(ysize - 1) / 2 ] = '>';
78 maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; 66 maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<';
67
79 return maze; 68 return;
80 } 69 }
70
71 maze->clear ('#');
81 72
82 /* decide on the number of rooms */ 73 /* decide on the number of rooms */
83 nrooms = rndm (10) + 6; 74 nrooms = rndm (10) + 6;
84 Rooms = (Room *) calloc (nrooms + 1, sizeof (Room)); 75 Room *rooms = salloc0<Room> (nrooms + 1);
85 76
86 /* actually place the rooms */ 77 /* actually place the rooms */
87 i = 0; 78 i = 0;
88 while (tries < 450 && i < nrooms) 79 while (tries < 450 && i < nrooms)
89 { 80 {
90 /* try to place the room */ 81 /* try to place the room */
91 if (!roguelike_place_room (Rooms, xsize, ysize, nrooms)) 82 if (!roguelike_place_room (rooms, xsize, ysize, nrooms))
92 tries++; 83 tries++;
93 else 84 else
94 i++; 85 i++;
95 } 86 }
96 87
97 if (i == 0) 88 if (i == 0)
98 { /* no can do! */ 89 { /* no can do! */
99 for (i = 1; i < xsize - 1; i++) 90 maze->clear ();
100 for (j = 1; j < ysize - 1; j++) 91 maze->border ();
101 maze[i][j] = 0; 92
102 maze[(xsize - 1) / 2][(ysize - 1) / 2] = '>'; 93 maze [(xsize - 1) / 2][(ysize - 1) / 2 ] = '>';
103 maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; 94 maze [(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<';
104 free (Rooms); 95
96 sfree (rooms, nrooms + 1);
105 return maze; 97 return;
106 } 98 }
107 99
108 100
109 /* erase the areas occupied by the rooms */ 101 /* erase the areas occupied by the rooms */
110 roguelike_make_rooms (Rooms, maze, options); 102 roguelike_make_rooms (rooms, maze, options);
111 103
112 roguelike_link_rooms (Rooms, maze, xsize, ysize); 104 roguelike_link_rooms (rooms, maze, xsize, ysize);
113 105
114 /* put in the stairs */ 106 /* put in the stairs */
115 107
116 maze[Rooms->x][Rooms->y] = '<'; 108 maze[rooms->x][rooms->y] = '<';
109
117 /* get the last one */ 110 /* get the last one */
118 for (walk = Rooms; walk->x != 0; walk++); 111 for (walk = rooms; walk->x != 0; walk++)
112 ;
113
119 /* back up one */ 114 /* back up one */
120 walk--; 115 walk--;
116
121 if (walk == Rooms) 117 if (walk == rooms)
122 { 118 {
123 /* In this case, there is only a single room. We don't want to 119 /* In this case, there is only a single room. We don't want to
124 * clobber are up exit (above) with a down exit, so put the 120 * clobber are up exit (above) with a down exit, so put the
125 * other exit one space up/down, depending which is a space 121 * other exit one space up/down, depending which is a space
126 * and not a wall. 122 * and not a wall.
137 for (i = 0; i < xsize; i++) 133 for (i = 0; i < xsize; i++)
138 for (j = 0; j < ysize; j++) 134 for (j = 0; j < ysize; j++)
139 { 135 {
140 if (maze[i][j] == '.') 136 if (maze[i][j] == '.')
141 maze[i][j] = 0; 137 maze[i][j] = 0;
138
142 if (maze[i][j] == 'D') 139 if (maze[i][j] == 'D')
143 { /* remove bad door. */ 140 { /* remove bad door. */
144 int si = surround_check (maze, i, j, xsize, ysize); 141 int si = surround_check (maze, i, j, xsize, ysize);
145 142
146 if (si != 3 && si != 12) 143 if (si != 3 && si != 12)
151 j = 0; 148 j = 0;
152 } 149 }
153 } 150 }
154 } 151 }
155 152
156 free (Rooms); 153 sfree (rooms, nrooms + 1);
157 return maze;
158} 154}
159
160
161 155
162static int 156static int
163roguelike_place_room (Room * Rooms, int xsize, int ysize, int nrooms) 157roguelike_place_room (Room *rooms, int xsize, int ysize, int nrooms)
164{ 158{
165
166 int tx, ty; /* trial center locations */ 159 int tx, ty; /* trial center locations */
167 int sx, sy; /* trial sizes */ 160 int sx, sy; /* trial sizes */
168 int ax, ay; /* min coords of rect */ 161 int ax, ay; /* min coords of rect */
169 int zx, zy; /* max coords of rect */ 162 int zx, zy; /* max coords of rect */
170 int x_basesize; 163 int x_basesize;
171 int y_basesize; 164 int y_basesize;
172 Room *walk; 165 Room *walk;
173 166
174 /* decide on the base x and y sizes */ 167 /* decide on the base x and y sizes */
175
176 x_basesize = xsize / isqrt (nrooms); 168 x_basesize = xsize / isqrt (nrooms);
177 y_basesize = ysize / isqrt (nrooms); 169 y_basesize = ysize / isqrt (nrooms);
178 170
179 171 tx = rndm (xsize);
180 tx = RANDOM () % xsize; 172 ty = rndm (ysize);
181 ty = RANDOM () % ysize;
182 173
183 /* generate a distribution of sizes centered about basesize */ 174 /* generate a distribution of sizes centered about basesize */
184 sx = (RANDOM () % x_basesize) + (RANDOM () % x_basesize) + (RANDOM () % x_basesize); 175 sx = rndm (x_basesize) + rndm (x_basesize) + rndm (x_basesize);
185 sy = (RANDOM () % y_basesize) + (RANDOM () % y_basesize) + (RANDOM () % y_basesize); 176 sy = rndm (y_basesize) + rndm (y_basesize) + rndm (y_basesize);
186 sy = (int) (sy * .5); /* renormalize */ 177 sy = (int) (sy * .5); /* renormalize */
187 178
188 /* find the corners */ 179 /* find the corners */
189 ax = tx - sx / 2; 180 ax = tx - sx / 2;
190 zx = tx + sx / 2 + sx % 2; 181 zx = tx + sx / 2 + sx % 2;
191 182
192 ay = ty - sy / 2; 183 ay = ty - sy / 2;
193 zy = ty + sy / 2 + sy % 2; 184 zy = ty + sy / 2 + sy % 2;
194 185
195 /* check to see if it's in the map */ 186 /* check to see if it's in the map */
196 if (zx > xsize - 1 || ax < 1) 187 if (zx > xsize - 1 || ax < 1) return 0;
197 return 0;
198 if (zy > ysize - 1 || ay < 1) 188 if (zy > ysize - 1 || ay < 1) return 0;
199 return 0;
200 189
201 /* no small fish */ 190 /* no small fish */
202 if (sx < 3 || sy < 3) 191 if (sx < 3 || sy < 3)
203 return 0; 192 return 0;
204 193
205 /* check overlap with existing rooms */ 194 /* check overlap with existing rooms */
206 for (walk = Rooms; walk->x != 0; walk++) 195 for (walk = rooms; walk->x != 0; walk++)
207 { 196 {
208 int dx = abs (tx - walk->x); 197 int dx = abs (tx - walk->x);
209 int dy = abs (ty - walk->y); 198 int dy = abs (ty - walk->y);
210 199
211 if ((dx < (walk->sx + sx) / 2 + 2) && (dy < (walk->sy + sy) / 2 + 2)) 200 if ((dx < (walk->sx + sx) / 2 + 2) && (dy < (walk->sy + sy) / 2 + 2))
213 } 202 }
214 203
215 /* if we've got here, presumably the room is OK. */ 204 /* if we've got here, presumably the room is OK. */
216 205
217 /* get a pointer to the first free room */ 206 /* get a pointer to the first free room */
218 for (walk = Rooms; walk->x != 0; walk++); 207 for (walk = rooms; walk->x != 0; walk++)
208 ;
209
219 walk->x = tx; 210 walk->x = tx;
220 walk->y = ty; 211 walk->y = ty;
221 walk->sx = sx; 212 walk->sx = sx;
222 walk->sy = sy; 213 walk->sy = sy;
223 walk->ax = ax; 214 walk->ax = ax;
224 walk->ay = ay; 215 walk->ay = ay;
225 walk->zx = zx; 216 walk->zx = zx;
226 walk->zy = zy; 217 walk->zy = zy;
218
227 return 1; /* success */ 219 return 1; /* success */
228
229} 220}
230
231 221
232/* write all the rooms into the maze */ 222/* write all the rooms into the maze */
233static void 223static void
234roguelike_make_rooms (Room * Rooms, char **maze, int options) 224roguelike_make_rooms (Room *rooms, char **maze, int options)
235{ 225{
236 int making_circle = 0; 226 int making_circle = 0;
237 int i, j; 227 int i, j;
238 int R; 228 int R;
239 Room *walk; 229 Room *walk;
240 230
241 for (walk = Rooms; walk->x != 0; walk++) 231 for (walk = rooms; walk->x != 0; walk++)
242 { 232 {
243 /* first decide what shape to make */ 233 /* first decide what shape to make */
244 switch (options) 234 switch (options)
245 { 235 {
246 case 1: 236 case 1:
260 R = walk->sy / 2; 250 R = walk->sy / 2;
261 251
262 /* enscribe a rectangle */ 252 /* enscribe a rectangle */
263 for (i = walk->ax; i < walk->zx; i++) 253 for (i = walk->ax; i < walk->zx; i++)
264 for (j = walk->ay; j < walk->zy; j++) 254 for (j = walk->ay; j < walk->zy; j++)
265 {
266 if (!making_circle || ((int) (0.5 + hypot (walk->x - i, walk->y - j))) <= R) 255 if (!making_circle || ((int) (0.5 + hypot (walk->x - i, walk->y - j))) <= R)
267 maze[i][j] = '.'; 256 maze[i][j] = '.';
268 }
269 } 257 }
270} 258}
271
272
273 259
274static void 260static void
275roguelike_link_rooms (Room * Rooms, char **maze, int xsize, int ysize) 261roguelike_link_rooms (Room *rooms, char **maze, int xsize, int ysize)
276{ 262{
277 Room *walk; 263 Room *walk;
278 int i, j; 264 int i, j;
279 265
280 /* link each room to the previous room */ 266 /* link each room to the previous room */
281 if (Rooms[1].x == 0) 267 if (rooms[1].x == 0)
282 return; /* only 1 room */ 268 return; /* only 1 room */
283 269
284 for (walk = Rooms + 1; walk->x != 0; walk++) 270 for (walk = rooms + 1; walk->x != 0; walk++)
285 { 271 {
286 int x1 = walk->x; 272 int x1 = walk->x;
287 int y1 = walk->y; 273 int y1 = walk->y;
288 int x2 = (walk - 1)->x; 274 int x2 = (walk - 1)->x;
289 int y2 = (walk - 1)->y; 275 int y2 = (walk - 1)->y;
398 384
399 } 385 }
400 386
401 } 387 }
402} 388}
389

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines