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

Comparing deliantra/server/random_maps/random_map.C (file contents):
Revision 1.33 by root, Mon Apr 14 22:41:17 2008 UTC vs.
Revision 1.34 by root, Tue Apr 15 03:00:24 2008 UTC

28#include <rproto.h> 28#include <rproto.h>
29#include <sproto.h> 29#include <sproto.h>
30 30
31#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__); 31#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__);
32 32
33static void symmetrize_layout (Maze maze, random_map_params *RP); 33static void symmetrize_layout (Layout maze, random_map_params *RP);
34static void rotate_layout (Maze maze, int rotation); 34static void rotate_layout (Layout maze, int rotation);
35 35
36void 36void
37dump_layout (char **layout, random_map_params *RP) 37dump_layout (Layout layout)
38{ 38{
39 { 39 for (int i = 0; i < layout->w; i++)
40 int i, j;
41
42 for (i = 0; i < RP->Xsize; i++)
43 { 40 {
44 for (j = 0; j < RP->Ysize; j++) 41 for (int j = 0; j < layout->h; j++)
45 { 42 putc (layout[i][j] ? layout[i][j] : ' ', stdout);
46 if (layout[i][j] == 0) 43
47 layout[i][j] = ' '; 44 putc ('\n', stdout);
48 printf ("%c", layout[i][j]);
49 if (layout[i][j] == ' ')
50 layout[i][j] = 0;
51 }
52 printf ("\n");
53 } 45 }
54 } 46
55 printf ("\n"); 47 putc ('\n', stdout);
56} 48}
57 49
58bool 50bool
59maptile::generate_random_map (random_map_params *RP) 51maptile::generate_random_map (random_map_params *RP)
60{ 52{
115 * the numeric layoutstyle, so there is only one area that actually 107 * the numeric layoutstyle, so there is only one area that actually
116 * calls the code to make the maps. 108 * calls the code to make the maps.
117 */ 109 */
118 if (strstr (RP->layoutstyle, "onion")) 110 if (strstr (RP->layoutstyle, "onion"))
119 RP->map_layout_style = LAYOUT_ONION; 111 RP->map_layout_style = LAYOUT_ONION;
120
121 if (strstr (RP->layoutstyle, "maze")) 112 else if (strstr (RP->layoutstyle, "maze"))
122 RP->map_layout_style = LAYOUT_MAZE; 113 RP->map_layout_style = LAYOUT_MAZE;
123
124 if (strstr (RP->layoutstyle, "spiral")) 114 else if (strstr (RP->layoutstyle, "spiral"))
125 RP->map_layout_style = LAYOUT_SPIRAL; 115 RP->map_layout_style = LAYOUT_SPIRAL;
126
127 if (strstr (RP->layoutstyle, "rogue")) 116 else if (strstr (RP->layoutstyle, "rogue"))
128 RP->map_layout_style = LAYOUT_ROGUELIKE; 117 RP->map_layout_style = LAYOUT_ROGUELIKE;
129
130 if (strstr (RP->layoutstyle, "snake")) 118 else if (strstr (RP->layoutstyle, "snake"))
131 RP->map_layout_style = LAYOUT_SNAKE; 119 RP->map_layout_style = LAYOUT_SNAKE;
132
133 if (strstr (RP->layoutstyle, "squarespiral")) 120 else if (strstr (RP->layoutstyle, "squarespiral"))
134 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL; 121 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
135
136 /* No style found - choose one randomly */
137 if (RP->map_layout_style == LAYOUT_NONE) 122 else if (RP->map_layout_style == LAYOUT_NONE)
138 RP->map_layout_style = rndm (NROFLAYOUTS - 1) + 1; 123 RP->map_layout_style = rndm (NROFLAYOUTS - 1) + 1; /* No style found - choose one randomly */
124 else
125 abort ();
139 126
140 Maze layout = layoutgen (RP); 127 Layout layout = layoutgen (RP);
141 128
142#ifdef RMAP_DEBUG 129#ifdef RMAP_DEBUG
143 dump_layout (layout, RP); 130 dump_layout (layout, RP);
144#endif 131#endif
145 132
146 /* increment these for the current map */ 133 /* increment these for the current map */
147 RP->dungeon_level += 1; 134 RP->dungeon_level += 1;
148 /* allow constant-difficulty maps. */ 135 /* allow constant-difficulty maps. */
149 /* difficulty+=1; */ 136 /* difficulty+=1; */
150 137
151 /* rotate the layout randomly */
152 rotate_layout (layout, rndm (4));
153#ifdef RMAP_DEBUG
154 dump_layout (layout, RP);
155#endif
156
157 // need to patch RP becasue following code doesn't use the Maze object 138 // need to patch RP becasue following code doesn't use the Layout object
158 RP->Xsize = layout->w; 139 RP->Xsize = layout->w;
159 RP->Ysize = layout->h; 140 RP->Ysize = layout->h;
160 141
161 /* allocate the map and set the floor */ 142 /* allocate the map and set the floor */
162 make_map_floor (layout, RP->floorstyle, RP); 143 make_map_floor (layout, RP->floorstyle, RP);
216 197
217 CEDE; 198 CEDE;
218 199
219 unblock_exits (this, layout, RP); 200 unblock_exits (this, layout, RP);
220 201
221 layout.free ();
222
223 msg = strdup (buf); 202 msg = strdup (buf);
224 in_memory = MAP_IN_MEMORY; 203 in_memory = MAP_IN_MEMORY;
225 204
226 CEDE; 205 CEDE;
227 206
228 return 1; 207 return 1;
229} 208}
230 209
231/* function selects the layout function and gives it whatever 210/* function selects the layout function and gives it whatever
232 arguments it needs. */ 211 arguments it needs. */
233Maze 212Layout
234layoutgen (random_map_params *RP) 213layoutgen (random_map_params *RP)
235{ 214{
236 Maze maze (RP); 215 Layout layout (RP);
237 216
238 switch (RP->map_layout_style) 217 switch (RP->map_layout_style)
239 { 218 {
240 case LAYOUT_ONION: 219 case LAYOUT_ONION:
241 map_gen_onion (maze, RP->layoutoptions1, RP->layoutoptions2); 220 map_gen_onion (layout, RP->layoutoptions1, RP->layoutoptions2);
242 221
243 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) 222 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
244 roomify_layout (maze, RP); 223 roomify_layout (layout, RP);
245 224
246 break; 225 break;
247 226
248 case LAYOUT_MAZE: 227 case LAYOUT_MAZE:
249 maze_gen (maze, rndm (2)); 228 maze_gen (layout, rndm (2));
250 229
251 if (!(rndm (2))) 230 if (!(rndm (2)))
252 doorify_layout (maze, RP); 231 doorify_layout (layout, RP);
253 232
254 break; 233 break;
255 234
256 case LAYOUT_SPIRAL: 235 case LAYOUT_SPIRAL:
257 map_gen_spiral (maze, RP->layoutoptions1); 236 map_gen_spiral (layout, RP->layoutoptions1);
258 237
259 if (!(rndm (2))) 238 if (!(rndm (2)))
260 doorify_layout (maze, RP); 239 doorify_layout (layout, RP);
261 240
262 break; 241 break;
263 242
264 case LAYOUT_ROGUELIKE: 243 case LAYOUT_ROGUELIKE:
265 /* Don't put symmetry in rogue maps. There isn't much reason to 244 /* Don't put symmetry in rogue maps. There isn't much reason to
268 * spirals, or maps with lots of passages - making a symmetric rogue 247 * spirals, or maps with lots of passages - making a symmetric rogue
269 * map fails because its likely that the passages the symmetry process 248 * map fails because its likely that the passages the symmetry process
270 * creates may not connect the rooms. 249 * creates may not connect the rooms.
271 */ 250 */
272 RP->symmetry_used = SYMMETRY_NONE; 251 RP->symmetry_used = SYMMETRY_NONE;
273 roguelike_layout_gen (maze, RP->layoutoptions1); 252 roguelike_layout_gen (layout, RP->layoutoptions1);
274 /* no doorifying... done already */ 253 /* no doorifying... done already */
275 break; 254 break;
276 255
277 case LAYOUT_SNAKE: 256 case LAYOUT_SNAKE:
278 make_snake_layout (maze, RP->layoutoptions1); 257 make_snake_layout (layout, RP->layoutoptions1);
279 258
280 if (rndm (2)) 259 if (rndm (2))
281 roomify_layout (maze, RP); 260 roomify_layout (layout, RP);
282 261
283 break; 262 break;
284 263
285 case LAYOUT_SQUARE_SPIRAL: 264 case LAYOUT_SQUARE_SPIRAL:
286 make_square_spiral_layout (maze, RP->layoutoptions1); 265 make_square_spiral_layout (layout, RP->layoutoptions1);
287 266
288 if (rndm (2)) 267 if (rndm (2))
289 roomify_layout (maze, RP); 268 roomify_layout (layout, RP);
290 269
291 break; 270 break;
292 271
293 default: 272 default:
294 abort (); 273 abort ();
295 } 274 }
296 275
276 /* rotate the layout randomly */
277 rotate_layout (layout, rndm (4));
278
297 symmetrize_layout (maze, RP); 279 symmetrize_layout (layout, RP);
298 280
299#ifdef RMAP_DEBUG 281#ifdef RMAP_DEBUG
300 dump_layout (maze, RP); 282 dump_layout (layout);
301#endif 283#endif
302 284
303 if (RP->expand2x) 285 if (RP->expand2x)
304 expand2x (maze); 286 expand2x (layout);
305 287
306 return maze; 288 return layout;
307} 289}
308 290
309/* takes a map and makes it symmetric: adjusts Xsize and 291/* takes a map and makes it symmetric: adjusts Xsize and
310Ysize to produce a symmetric map. */ 292 * Ysize to produce a symmetric map.
293 */
311static void 294static void
312symmetrize_layout (Maze maze, random_map_params *RP) 295symmetrize_layout (Layout layout, random_map_params *RP)
313{ 296{
314 if (RP->symmetry_used == SYMMETRY_NONE) 297 if (RP->symmetry_used == SYMMETRY_NONE)
315 return; 298 return;
316 299
317 Maze sym_maze ( 300 Layout sym_layout (
318 RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY ? maze->w * 2 - 3 : maze->w, 301 RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY ? layout->w * 2 - 3 : layout->w,
319 RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY ? maze->h * 2 - 3 : maze->h 302 RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY ? layout->h * 2 - 3 : layout->h
320 ); 303 );
321 304
322 if (RP->symmetry_used == SYMMETRY_X) 305 if (RP->symmetry_used == SYMMETRY_X)
323 for (int i = 0; i < sym_maze->w / 2 + 1; i++) 306 for (int i = 0; i < sym_layout->w / 2 + 1; i++)
324 for (int j = 0; j < sym_maze->h; j++) 307 for (int j = 0; j < sym_layout->h; j++)
325 { 308 {
326 sym_maze[i ][j] = 309 sym_layout[i ][j] =
327 sym_maze[sym_maze->w - i - 1][j] = maze[i][j]; 310 sym_layout[sym_layout->w - i - 1][j] = layout[i][j];
328 } 311 }
329 312
330 if (RP->symmetry_used == SYMMETRY_Y) 313 if (RP->symmetry_used == SYMMETRY_Y)
331 for (int i = 0; i < sym_maze->w; i++) 314 for (int i = 0; i < sym_layout->w; i++)
332 for (int j = 0; j < sym_maze->h / 2 + 1; j++) 315 for (int j = 0; j < sym_layout->h / 2 + 1; j++)
333 { 316 {
334 sym_maze[i][j ] = 317 sym_layout[i][j ] =
335 sym_maze[i][sym_maze->h - j - 1] = maze[i][j]; 318 sym_layout[i][sym_layout->h - j - 1] = layout[i][j];
336 } 319 }
337 320
338 if (RP->symmetry_used == SYMMETRY_XY) 321 if (RP->symmetry_used == SYMMETRY_XY)
339 for (int i = 0; i < sym_maze->w / 2 + 1; i++) 322 for (int i = 0; i < sym_layout->w / 2 + 1; i++)
340 for (int j = 0; j < sym_maze->h / 2 + 1; j++) 323 for (int j = 0; j < sym_layout->h / 2 + 1; j++)
341 { 324 {
342 sym_maze[i ][j ] = 325 sym_layout[i ][j ] =
343 sym_maze[i ][sym_maze->h - j - 1] = 326 sym_layout[i ][sym_layout->h - j - 1] =
344 sym_maze[sym_maze->w - i - 1][j ] = 327 sym_layout[sym_layout->w - i - 1][j ] =
345 sym_maze[sym_maze->w - i - 1][sym_maze->h - j - 1] = maze[i][j]; 328 sym_layout[sym_layout->w - i - 1][sym_layout->h - j - 1] = layout[i][j];
346 } 329 }
347 330
348 maze.swap (sym_maze); 331 layout.swap (sym_layout);
332 sym_layout.free ();
349 333
350 /* reconnect disjointed spirals */ 334 /* reconnect disjointed spirals */
351 /* reconnect disjointed nethackmazes: the routine for 335 /* reconnect disjointed nethacklayouts: the routine for
352 spirals will do the trick? */ 336 spirals will do the trick? */
353 if (RP->map_layout_style == LAYOUT_SPIRAL 337 if (RP->map_layout_style == LAYOUT_SPIRAL
354 || RP->map_layout_style == LAYOUT_ROGUELIKE) 338 || RP->map_layout_style == LAYOUT_ROGUELIKE)
355 connect_spirals (maze->w, maze->h, RP->symmetry_used, maze); 339 connect_spirals (layout->w, layout->h, RP->symmetry_used, layout);
356} 340}
357 341
358/* takes a map and rotates it. This completes the 342/* takes a map and rotates it. This completes the
359 onion layouts, making them possibly centered on any wall. 343 onion layouts, making them possibly centered on any wall.
360 It'll modify Xsize and Ysize if they're swapped. 344 It'll modify Xsize and Ysize if they're swapped.
361*/ 345*/
362static void 346static void
363rotate_layout (Maze maze, int rotation) 347rotate_layout (Layout layout, int rotation)
364{ 348{
349 int w = layout->w;
350 int h = layout->h;
351
365 switch (rotation) 352 switch (rotation)
366 { 353 {
367 case 2: /* a reflection */ 354 case 2: /* a reflection */
368 { 355 {
369 Maze new_maze (maze->w, maze->h); 356 Layout new_layout (w, h);
370 357
371 for (int i = 0; i < maze->w; i++) /* copy a reflection back */ 358 for (int i = 0; i < w; i++) /* copy a reflection back */
372 for (int j = 0; j < maze->h; j++) 359 for (int j = 0; j < h; j++)
373 new_maze[i][j] = maze[maze->w - i - 1][maze->h - j - 1]; 360 new_layout[i][j] = layout[w - i - 1][h - j - 1];
374 361
375 maze.swap (new_maze); 362 layout.swap (new_layout);
363 new_layout.free ();
376 } 364 }
365 break;
377 366
378 case 1: 367 case 1:
379 case 3: 368 case 3:
380 { 369 {
381 Maze new_maze (maze->h, maze->w); 370 Layout new_layout (h, w);
382 371
383 if (rotation == 1) /* swap x and y */ 372 if (rotation == 1) /* swap x and y */
384 for (int i = 0; i < maze->w; i++) 373 for (int i = 0; i < w; i++)
385 for (int j = 0; j < maze->h; j++) 374 for (int j = 0; j < h; j++)
386 new_maze[j][i] = maze[i][j]; 375 new_layout[j][i] = layout[i][j];
387 376
388 if (rotation == 3) /* swap x and y */ 377 if (rotation == 3) /* swap x and y */
389 for (int i = 0; i < maze->w; i++) 378 for (int i = 0; i < w; i++)
390 for (int j = 0; j < maze->h; j++) 379 for (int j = 0; j < h; j++)
391 new_maze[j][i] = maze[maze->w - i - 1][maze->h - j - 1]; 380 new_layout[j][i] = layout[w - i - 1][h - j - 1];
392 381
393 maze.swap (new_maze); 382 layout.swap (new_layout);
383 new_layout.free ();
394 } 384 }
385 break;
395 } 386 }
396} 387}
397 388
398/* take a layout and make some rooms in it. 389/* take a layout and make some rooms in it.
399 --works best on onions.*/ 390 --works best on onions.*/
968 walk->copy_to (tmp); 959 walk->copy_to (tmp);
969 insert_ob_in_ob (tmp, dest_ob); 960 insert_ob_in_ob (tmp, dest_ob);
970 } 961 }
971} 962}
972 963
964/////////////////////////////////////////////////////////////////////////////
965
973MazeData::MazeData (int w, int h) 966LayoutData::LayoutData (int w, int h)
974: w(w), h(h) 967: w(w), h(h)
975{ 968{
976 int size = (sizeof (char *) + sizeof (char) * h) * w; 969 int size = (sizeof (char *) + sizeof (char) * h) * w;
977 970
978 col = (char **)salloc<char> (size); 971 col = (char **)salloc<char> (size);
981 974
982 for (int x = w; x--; ) 975 for (int x = w; x--; )
983 col [x] = data + x * h; 976 col [x] = data + x * h;
984} 977}
985 978
986MazeData::~MazeData () 979LayoutData::~LayoutData ()
987{ 980{
988 int size = (sizeof (char *) + sizeof (char) * h) * w; 981 int size = (sizeof (char *) + sizeof (char) * h) * w;
989 982
990 sfree ((char *)col, size); 983 sfree ((char *)col, size);
991} 984}
992 985
993void MazeData::clear (char fill) 986void LayoutData::clear (char fill)
994{ 987{
995 memset (col [0], fill, w * h); 988 memset (col [0], fill, w * h);
996} 989}
997 990
998void MazeData::border (char fill) 991void LayoutData::border (char fill)
999{ 992{
1000 for (int i = 0; i < w; i++) col [i][0] = col [i][h - 1] = fill; 993 for (int i = 0; i < w; i++) col [i][0] = col [i][h - 1] = fill;
1001 for (int j = 0; j < h; j++) col [0][j] = col [w - 1][j] = fill; 994 for (int j = 0; j < h; j++) col [0][j] = col [w - 1][j] = fill;
1002} 995}
1003 996
1004

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines