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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines