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.46 by root, Fri Mar 26 00:59:21 2010 UTC vs.
Revision 1.59 by root, Thu Jul 1 01:22:44 2010 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 9 * the terms of the Affero GNU General Public License as published by the
29#include <rproto.h> 29#include <rproto.h>
30#include <sproto.h> 30#include <sproto.h>
31 31
32#define CEDE coroapi::cede_to_tick () 32#define CEDE coroapi::cede_to_tick ()
33 33
34static void symmetrize_layout (Layout maze, random_map_params *RP); 34static void symmetrize_layout (Layout &maze, random_map_params *RP);
35static void rotate_layout (Layout maze, int rotation); 35static void rotate_layout (Layout &maze, int rotation);
36
37noinline SV *
38random_map_params::get_sv (const char *option) const
39{
40 SV **he = hv_fetch (hv, option, strlen (option), 0);
41
42 return he ? *he : 0;
43}
44
45noinline const_utf8_string
46random_map_params::get_str (const char *option, const_utf8_string fallback) const
47{
48 SV *sv = get_sv (option);
49 return sv ? cfSvPVutf8_nolen (sv) : fallback;
50}
51
52noinline IV
53random_map_params::get_iv (const char *option, IV fallback) const
54{
55 SV *sv = get_sv (option);
56 return sv ? SvIV (sv) : fallback;
57}
58
59noinline UV
60random_map_params::get_uv (const char *option, UV fallback) const
61{
62 SV *sv = get_sv (option);
63 return sv ? SvUV (sv) : fallback;
64}
65
66noinline NV
67random_map_params::get_nv (const char *option, NV fallback) const
68{
69 SV *sv = get_sv (option);
70 return sv ? SvNV (sv) : fallback;
71}
72
73noinline void
74random_map_params::set (const char *option, SV *value) const
75{
76 int len = strlen (option);
77
78 if (value)
79 hv_store (hv, option, len, value, 0);
80 else
81 hv_delete (hv, option, len, G_DISCARD);
82}
83
84noinline void
85random_map_params::set (const char *option, const_utf8_string value) const
86{
87 set (option, value && *value ? newSVpvn_utf8 (value, strlen (value), 1) : 0);
88}
36 89
37void 90void
38dump_layout (Layout layout) 91random_map_params::set (const char *option, IV value) const
39{ 92{
40 for (int j = 0; j < layout->h; j++) 93 set (option, newSViv (value));
41 { 94}
42 for (int i = 0; i < layout->w; i++)
43 putc (layout[i][j] ? layout[i][j] : ' ', stdout);
44 95
45 putc ('\n', stdout); 96void
97random_map_params::set (const char *option, UV value) const
98{
99 set (option, newSVuv (value));
100}
101
102void
103random_map_params::set (const char *option, NV value) const
104{
105 set (option, newSVnv (value));
106}
107
108void
109random_map_params::hv_clone ()
110{
111 HV *copy = newHV ();
112
113 hv_iterinit (hv);
114
115 // does not work for utf-8 keys
116 while (HE *he = hv_iternext (hv))
46 } 117 {
118 STRLEN klen; const char *key = HePV (he, klen);
119 hv_store (copy, key, klen, newSVsv (HeVAL (he)), HeHASH (he));
120 }
47 121
48 putc ('\n', stdout); 122 SvREFCNT_dec (hv);
123 hv = copy;
124}
125
126shstr_tmp
127random_map_params::as_shstr () const
128{
129 set ("xsize" , xsize);
130 set ("ysize" , ysize);
131 set ("monsterstyle" , monsterstyle);
132 set ("exit_on_final_map" , exit_on_final_map);
133 set ("layoutstyle" , layoutstyle);
134 set ("doorstyle" , doorstyle);
135 set ("final_map" , final_map);
136 set ("this_map" , this_map);
137 set ("expand2x" , expand2x);
138 set ("layoutoptions1" , layoutoptions1);
139 set ("layoutoptions2" , layoutoptions2);
140 set ("layoutoptions3" , layoutoptions3);
141 set ("symmetry" , symmetry);
142 set ("dungeon_depth" , dungeon_depth);
143 set ("orientation" , orientation);
144 set ("origin_x" , origin_x);
145 set ("origin_y" , origin_y);
146 set ("random_seed" , (UV)random_seed);
147 set ("difficulty" , difficulty && difficulty_given ? difficulty : 0);
148 set ("difficulty_increase", difficulty_increase);
149 set ("dungeon_level" , dungeon_level);
150
151 dynbuf_text buf;
152 hv_iterinit (hv);
153
154 // does not work for utf-8 keys
155 while (HE *he = hv_iternext (hv))
156 {
157 STRLEN klen; const char *key = HePV (he, klen);
158 STRLEN vlen; const char *value = SvPVutf8 (HeVAL (he), vlen);
159
160 buf.fadd (key, klen);
161 buf << ' ';
162 buf.fadd (value, vlen);
163 buf << '\n';
164 }
165
166 return shstr (buf);
167}
168
169random_map_params::~random_map_params ()
170{
171 SvREFCNT_dec (hv);
49} 172}
50 173
51/* takes a map and makes it symmetric: adjusts Xsize and 174/* takes a map and makes it symmetric: adjusts Xsize and
52 * Ysize to produce a symmetric map. 175 * Ysize to produce a symmetric map.
53 */ 176 */
54static void 177static void
55symmetrize_layout (Layout layout, random_map_params *RP) 178symmetrize_layout (Layout &layout, random_map_params *RP)
56{ 179{
57 if (RP->symmetry_used == SYMMETRY_NONE) 180 if (RP->symmetry_used == SYMMETRY_NONE)
58 return; 181 return;
59 182
60 Layout sym_layout ( 183 Layout sym_layout (
61 RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY ? layout->w * 2 - 3 : layout->w, 184 RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY ? layout.w * 2 - 3 : layout.w,
62 RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY ? layout->h * 2 - 3 : layout->h 185 RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY ? layout.h * 2 - 3 : layout.h
63 ); 186 );
64 187
65 if (RP->symmetry_used == SYMMETRY_X) 188 if (RP->symmetry_used == SYMMETRY_X)
66 for (int i = 0; i < sym_layout->w / 2 + 1; i++) 189 for (int i = 0; i < sym_layout.w / 2 + 1; i++)
67 for (int j = 0; j < sym_layout->h; j++) 190 for (int j = 0; j < sym_layout.h; j++)
68 { 191 {
69 sym_layout[i ][j] = 192 sym_layout[i ][j] =
70 sym_layout[sym_layout->w - i - 1][j] = layout[i][j]; 193 sym_layout[sym_layout.w - i - 1][j] = layout[i][j];
71 } 194 }
72 195
73 if (RP->symmetry_used == SYMMETRY_Y) 196 if (RP->symmetry_used == SYMMETRY_Y)
74 for (int i = 0; i < sym_layout->w; i++) 197 for (int i = 0; i < sym_layout.w; i++)
75 for (int j = 0; j < sym_layout->h / 2 + 1; j++) 198 for (int j = 0; j < sym_layout.h / 2 + 1; j++)
76 { 199 {
77 sym_layout[i][j ] = 200 sym_layout[i][j ] =
78 sym_layout[i][sym_layout->h - j - 1] = layout[i][j]; 201 sym_layout[i][sym_layout.h - j - 1] = layout[i][j];
79 } 202 }
80 203
81 if (RP->symmetry_used == SYMMETRY_XY) 204 if (RP->symmetry_used == SYMMETRY_XY)
82 for (int i = 0; i < sym_layout->w / 2 + 1; i++) 205 for (int i = 0; i < sym_layout.w / 2 + 1; i++)
83 for (int j = 0; j < sym_layout->h / 2 + 1; j++) 206 for (int j = 0; j < sym_layout.h / 2 + 1; j++)
84 { 207 {
85 sym_layout[i ][j ] = 208 sym_layout[i ][j ] =
86 sym_layout[i ][sym_layout->h - j - 1] = 209 sym_layout[i ][sym_layout.h - j - 1] =
87 sym_layout[sym_layout->w - i - 1][j ] = 210 sym_layout[sym_layout.w - i - 1][j ] =
88 sym_layout[sym_layout->w - i - 1][sym_layout->h - j - 1] = layout[i][j]; 211 sym_layout[sym_layout.w - i - 1][sym_layout.h - j - 1] = layout[i][j];
89 } 212 }
213
214 /* need to run the isolation remover for some layouts */
215 switch (RP->map_layout_style)
216 {
217 case LAYOUT_ONION:
218 case LAYOUT_SNAKE:
219 case LAYOUT_SQUARE_SPIRAL:
220 // safe
221 break;
222
223 default:
224 sym_layout.isolation_remover ();
225 break;
226 }
90 227
91 layout.swap (sym_layout); 228 layout.swap (sym_layout);
92 sym_layout.free ();
93
94 /* reconnect disjointed spirals */
95 /* reconnect disjointed nethacklayouts: the routine for
96 spirals will do the trick? */
97 if (RP->map_layout_style == LAYOUT_SPIRAL
98 || RP->map_layout_style == LAYOUT_ROGUELIKE)
99 connect_spirals (layout->w, layout->h, RP->symmetry_used, layout);
100} 229}
101 230
102/* takes a map and rotates it. This completes the 231/* takes a map and rotates it. This completes the
103 onion layouts, making them possibly centered on any wall. 232 onion layouts, making them possibly centered on any wall.
104 It'll modify Xsize and Ysize if they're swapped. 233 It'll modify Xsize and Ysize if they're swapped.
105*/ 234*/
106static void 235static void
107rotate_layout (Layout layout, int rotation) 236rotate_layout (Layout &layout, int rotation)
108{ 237{
109 int w = layout->w; 238 int w = layout.w;
110 int h = layout->h; 239 int h = layout.h;
111 240
112 switch (rotation) 241 switch (rotation)
113 { 242 {
114 case 2: /* a reflection */ 243 case 2: /* a reflection */
115 { 244 {
118 for (int i = 0; i < w; i++) /* copy a reflection back */ 247 for (int i = 0; i < w; i++) /* copy a reflection back */
119 for (int j = 0; j < h; j++) 248 for (int j = 0; j < h; j++)
120 new_layout[i][j] = layout[w - i - 1][h - j - 1]; 249 new_layout[i][j] = layout[w - i - 1][h - j - 1];
121 250
122 layout.swap (new_layout); 251 layout.swap (new_layout);
123 new_layout.free ();
124 } 252 }
125 break; 253 break;
126 254
127 case 1: 255 case 1:
128 case 3: 256 case 3:
138 for (int i = 0; i < w; i++) 266 for (int i = 0; i < w; i++)
139 for (int j = 0; j < h; j++) 267 for (int j = 0; j < h; j++)
140 new_layout[j][i] = layout[w - i - 1][h - j - 1]; 268 new_layout[j][i] = layout[w - i - 1][h - j - 1];
141 269
142 layout.swap (new_layout); 270 layout.swap (new_layout);
143 new_layout.free ();
144 } 271 }
145 break; 272 break;
146 } 273 }
147} 274}
148 275
234 --works best on onions.*/ 361 --works best on onions.*/
235static void 362static void
236roomify_layout (char **maze, random_map_params *RP) 363roomify_layout (char **maze, random_map_params *RP)
237{ 364{
238 int tries = RP->Xsize * RP->Ysize / 30; 365 int tries = RP->Xsize * RP->Ysize / 30;
239 int ti;
240 366
241 for (ti = 0; ti < tries; ti++) 367 for (int ti = 0; ti < tries; ti++)
242 { 368 {
243 int dx, dy; /* starting location for looking at creating a door */ 369 /* starting location for looking at creating a door */
244 int cx, cy; /* results of checking on creating walls. */
245
246 dx = rmg_rndm (RP->Xsize); 370 int dx = rmg_rndm (RP->Xsize);
247 dy = rmg_rndm (RP->Ysize); 371 int dy = rmg_rndm (RP->Ysize);
248 372
373 /* results of checking on creating walls. */
249 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */ 374 int cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */
250 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */ 375 int cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */
376
251 if (cx == -1) 377 if (cx == -1)
252 { 378 {
253 if (cy != -1) 379 if (cy != -1)
254 make_wall (maze, dx, dy, 1); 380 make_wall (maze, dx, dy, 1);
255 381
271 397
272int 398int
273make_wall (char **maze, int x, int y, int dir) 399make_wall (char **maze, int x, int y, int dir)
274{ 400{
275 maze[x][y] = 'D'; /* mark a door */ 401 maze[x][y] = 'D'; /* mark a door */
402
276 switch (dir) 403 switch (dir)
277 { 404 {
278 case 0: /* horizontal */ 405 case 0: /* horizontal */
279 { 406 {
280 int i1;
281
282 for (i1 = x - 1; maze[i1][y] == 0; i1--) 407 for (int i1 = x - 1; maze[i1][y] == 0; --i1) maze[i1][y] = '#';
283 maze[i1][y] = '#';
284 for (i1 = x + 1; maze[i1][y] == 0; i1++) 408 for (int i1 = x + 1; maze[i1][y] == 0; ++i1) maze[i1][y] = '#';
285 maze[i1][y] = '#';
286 break; 409 break;
287 } 410 }
288 case 1: /* vertical */ 411 case 1: /* vertical */
289 { 412 {
290 int i1;
291
292 for (i1 = y - 1; maze[x][i1] == 0; i1--) 413 for (int i1 = y - 1; maze[x][i1] == 0; --i1) maze[x][i1] = '#';
293 maze[x][i1] = '#';
294 for (i1 = y + 1; maze[x][i1] == 0; i1++) 414 for (int i1 = y + 1; maze[x][i1] == 0; ++i1) maze[x][i1] = '#';
295 maze[x][i1] = '#';
296 break; 415 break;
297 } 416 }
298 } 417 }
299 418
300 return 0; 419 return 0;
345 464
346 sfree (doorlist_x, RP->Xsize * RP->Ysize); 465 sfree (doorlist_x, RP->Xsize * RP->Ysize);
347 sfree (doorlist_y, RP->Xsize * RP->Ysize); 466 sfree (doorlist_y, RP->Xsize * RP->Ysize);
348} 467}
349 468
350void
351write_map_parameters_to_string (char *buf, random_map_params *RP)
352{
353 char small_buf[16384];
354
355 sprintf (buf, "xsize %d\nysize %d\n", RP->xsize, RP->ysize);
356
357 if (RP->wallstyle[0])
358 {
359 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle);
360 strcat (buf, small_buf);
361 }
362
363 if (RP->floorstyle[0])
364 {
365 sprintf (small_buf, "floorstyle %s\n", RP->floorstyle);
366 strcat (buf, small_buf);
367 }
368
369 if (RP->monsterstyle[0])
370 {
371 sprintf (small_buf, "monsterstyle %s\n", RP->monsterstyle);
372 strcat (buf, small_buf);
373 }
374
375 if (RP->treasurestyle[0])
376 {
377 sprintf (small_buf, "treasurestyle %s\n", RP->treasurestyle);
378 strcat (buf, small_buf);
379 }
380
381 if (RP->layoutstyle[0])
382 {
383 sprintf (small_buf, "layoutstyle %s\n", RP->layoutstyle);
384 strcat (buf, small_buf);
385 }
386
387 if (RP->decorstyle[0])
388 {
389 sprintf (small_buf, "decorstyle %s\n", RP->decorstyle);
390 strcat (buf, small_buf);
391 }
392
393 if (RP->doorstyle[0])
394 {
395 sprintf (small_buf, "doorstyle %s\n", RP->doorstyle);
396 strcat (buf, small_buf);
397 }
398
399 if (RP->exitstyle[0])
400 {
401 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle);
402 strcat (buf, small_buf);
403 }
404
405 if (RP->final_map.length ())
406 {
407 sprintf (small_buf, "final_map %s\n", &RP->final_map);
408 strcat (buf, small_buf);
409 }
410
411 if (RP->exit_on_final_map[0])
412 {
413 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map);
414 strcat (buf, small_buf);
415 }
416
417 if (RP->this_map.length ())
418 {
419 sprintf (small_buf, "origin_map %s\n", &RP->this_map);
420 strcat (buf, small_buf);
421 }
422
423 if (RP->expand2x)
424 {
425 sprintf (small_buf, "expand2x %d\n", RP->expand2x);
426 strcat (buf, small_buf);
427 }
428
429 if (RP->layoutoptions1)
430 {
431 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1);
432 strcat (buf, small_buf);
433 }
434
435 if (RP->layoutoptions2)
436 {
437 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2);
438 strcat (buf, small_buf);
439 }
440
441 if (RP->layoutoptions3)
442 {
443 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3);
444 strcat (buf, small_buf);
445 }
446
447 if (RP->symmetry)
448 {
449 sprintf (small_buf, "symmetry %d\n", RP->symmetry);
450 strcat (buf, small_buf);
451 }
452
453 if (RP->difficulty && RP->difficulty_given)
454 {
455 sprintf (small_buf, "difficulty %d\n", RP->difficulty);
456 strcat (buf, small_buf);
457 }
458
459 if (fabs (RP->difficulty_increase - 1.f) >= (1.f / 1024.f))
460 {
461 sprintf (small_buf, "difficulty_increase %f\n", RP->difficulty_increase);
462 strcat (buf, small_buf);
463 }
464
465 sprintf (small_buf, "dungeon_level %d\n", RP->dungeon_level);
466 strcat (buf, small_buf);
467
468 if (RP->dungeon_depth)
469 {
470 sprintf (small_buf, "dungeon_depth %d\n", RP->dungeon_depth);
471 strcat (buf, small_buf);
472 }
473
474 if (RP->decoroptions)
475 {
476 sprintf (small_buf, "decoroptions %d\n", RP->decoroptions);
477 strcat (buf, small_buf);
478 }
479
480 if (RP->orientation)
481 {
482 sprintf (small_buf, "orientation %d\n", RP->orientation);
483 strcat (buf, small_buf);
484 }
485
486 if (RP->origin_x)
487 {
488 sprintf (small_buf, "origin_x %d\n", RP->origin_x);
489 strcat (buf, small_buf);
490 }
491
492 if (RP->origin_y)
493 {
494 sprintf (small_buf, "origin_y %d\n", RP->origin_y);
495 strcat (buf, small_buf);
496 }
497
498 if (RP->treasureoptions)
499 {
500 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions);
501 strcat (buf, small_buf);
502 }
503
504 if (RP->random_seed)
505 {
506 sprintf (small_buf, "random_seed %u\n", RP->random_seed);
507 strcat (buf, small_buf);
508 }
509
510 if (RP->custom)
511 {
512 sprintf (small_buf, "custom %s\n", RP->custom);
513 strcat (buf, small_buf);
514 }
515}
516
517void
518write_parameters_to_string (char *buf,
519 int xsize_n,
520 int ysize_n,
521 const char *wallstyle_n,
522 const char *floorstyle_n,
523 const char *monsterstyle_n,
524 const char *treasurestyle_n,
525 const char *layoutstyle_n,
526 const char *decorstyle_n,
527 const char *doorstyle_n,
528 const char *exitstyle_n,
529 const char *final_map_n,
530 const char *exit_on_final_map_n,
531 const char *this_map_n,
532 int layoutoptions1_n,
533 int layoutoptions2_n,
534 int layoutoptions3_n,
535 int symmetry_n,
536 int dungeon_depth_n,
537 int dungeon_level_n,
538 int difficulty_n,
539 int difficulty_given_n,
540 int decoroptions_n,
541 int orientation_n,
542 int origin_x_n,
543 int origin_y_n,
544 uint32_t random_seed_n,
545 int treasureoptions_n,
546 float difficulty_increase)
547{
548 char small_buf[16384];
549
550 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
551
552 if (wallstyle_n && wallstyle_n[0])
553 {
554 sprintf (small_buf, "wallstyle %s\n", wallstyle_n);
555 strcat (buf, small_buf);
556 }
557
558 if (floorstyle_n && floorstyle_n[0])
559 {
560 sprintf (small_buf, "floorstyle %s\n", floorstyle_n);
561 strcat (buf, small_buf);
562 }
563
564 if (monsterstyle_n && monsterstyle_n[0])
565 {
566 sprintf (small_buf, "monsterstyle %s\n", monsterstyle_n);
567 strcat (buf, small_buf);
568 }
569
570 if (treasurestyle_n && treasurestyle_n[0])
571 {
572 sprintf (small_buf, "treasurestyle %s\n", treasurestyle_n);
573 strcat (buf, small_buf);
574 }
575
576 if (layoutstyle_n && layoutstyle_n[0])
577 {
578 sprintf (small_buf, "layoutstyle %s\n", layoutstyle_n);
579 strcat (buf, small_buf);
580 }
581
582 if (decorstyle_n && decorstyle_n[0])
583 {
584 sprintf (small_buf, "decorstyle %s\n", decorstyle_n);
585 strcat (buf, small_buf);
586 }
587
588 if (doorstyle_n && doorstyle_n[0])
589 {
590 sprintf (small_buf, "doorstyle %s\n", doorstyle_n);
591 strcat (buf, small_buf);
592 }
593
594 if (exitstyle_n && exitstyle_n[0])
595 {
596 sprintf (small_buf, "exitstyle %s\n", exitstyle_n);
597 strcat (buf, small_buf);
598 }
599
600 if (final_map_n && final_map_n[0])
601 {
602 sprintf (small_buf, "final_map %s\n", final_map_n);
603 strcat (buf, small_buf);
604 }
605
606 if (exit_on_final_map_n && exit_on_final_map_n[0])
607 {
608 sprintf (small_buf, "exit_on_final_map %s\n", exit_on_final_map_n);
609 strcat (buf, small_buf);
610 }
611
612 if (this_map_n && this_map_n[0])
613 {
614 sprintf (small_buf, "origin_map %s\n", this_map_n);
615 strcat (buf, small_buf);
616 }
617
618 if (layoutoptions1_n)
619 {
620 sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n);
621 strcat (buf, small_buf);
622 }
623
624 if (layoutoptions2_n)
625 {
626 sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n);
627 strcat (buf, small_buf);
628 }
629
630
631 if (layoutoptions3_n)
632 {
633 sprintf (small_buf, "layoutoptions3 %d\n", layoutoptions3_n);
634 strcat (buf, small_buf);
635 }
636
637 if (symmetry_n)
638 {
639 sprintf (small_buf, "symmetry %d\n", symmetry_n);
640 strcat (buf, small_buf);
641 }
642
643
644 if (difficulty_n && difficulty_given_n)
645 {
646 sprintf (small_buf, "difficulty %d\n", difficulty_n);
647 strcat (buf, small_buf);
648 }
649
650 if (difficulty_increase > 0.001)
651 {
652 sprintf (small_buf, "difficulty_increase %f\n", difficulty_increase);
653 strcat (buf, small_buf);
654 }
655
656 sprintf (small_buf, "dungeon_level %d\n", dungeon_level_n);
657 strcat (buf, small_buf);
658
659 if (dungeon_depth_n)
660 {
661 sprintf (small_buf, "dungeon_depth %d\n", dungeon_depth_n);
662 strcat (buf, small_buf);
663 }
664
665 if (decoroptions_n)
666 {
667 sprintf (small_buf, "decoroptions %d\n", decoroptions_n);
668 strcat (buf, small_buf);
669 }
670
671 if (orientation_n)
672 {
673 sprintf (small_buf, "orientation %d\n", orientation_n);
674 strcat (buf, small_buf);
675 }
676
677 if (origin_x_n)
678 {
679 sprintf (small_buf, "origin_x %d\n", origin_x_n);
680 strcat (buf, small_buf);
681 }
682
683 if (origin_y_n)
684 {
685 sprintf (small_buf, "origin_y %d\n", origin_y_n);
686 strcat (buf, small_buf);
687 }
688
689 if (random_seed_n)
690 {
691 /* Add one so that the next map is a bit different */
692 sprintf (small_buf, "random_seed %u\n", random_seed_n + 1);
693 strcat (buf, small_buf);
694 }
695
696 if (treasureoptions_n)
697 {
698 sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n);
699 strcat (buf, small_buf);
700 }
701}
702
703/////////////////////////////////////////////////////////////////////////////
704
705LayoutData::LayoutData (int w, int h)
706: w(w), h(h)
707{
708 int size = (sizeof (char *) + sizeof (char) * h) * w;
709
710 col = (char **)salloc<char> (size);
711
712 char *data = (char *)(col + w);
713
714 for (int x = w; x--; )
715 col [x] = data + x * h;
716}
717
718LayoutData::~LayoutData ()
719{
720 int size = (sizeof (char *) + sizeof (char) * h) * w;
721
722 sfree ((char *)col, size);
723}
724
725void LayoutData::clear (char fill)
726{
727 memset (col [0], fill, w * h);
728}
729
730void LayoutData::border (char fill)
731{
732 for (int i = 0; i < w; i++) col [i][0] = col [i][h - 1] = fill;
733 for (int j = 0; j < h; j++) col [0][j] = col [w - 1][j] = fill;
734}
735
736/* function selects the layout function and gives it whatever 469/* function selects the layout function and gives it whatever
737 arguments it needs. */ 470 arguments it needs. */
738static Layout 471void
739layoutgen (random_map_params *RP) 472Layout::generate (random_map_params *RP)
740{ 473{
741 Layout layout (RP);
742
743 switch (RP->map_layout_style) 474 switch (RP->map_layout_style)
744 { 475 {
745 case LAYOUT_ONION: 476 case LAYOUT_ONION:
746 map_gen_onion (layout, RP->layoutoptions1, RP->layoutoptions2); 477 map_gen_onion (*this, RP->layoutoptions1, RP->layoutoptions2);
747 478
748 if (!(rmg_rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) 479 if (!(rmg_rndm (3)) && !(RP->layoutoptions1 & (RMOPT_WALLS_ONLY | RMOPT_WALL_OFF)))
749 roomify_layout (layout, RP); 480 roomify_layout (*this, RP);
750 481
751 break; 482 break;
752 483
753 case LAYOUT_MAZE: 484 case LAYOUT_MAZE:
754 maze_gen (layout, rmg_rndm (2)); 485 maze_gen (*this, RP->get_iv ("maze_type", rmg_rndm (4)));
755 486
756 if (!(rmg_rndm (2))) 487 if (!(rmg_rndm (2)))
757 doorify_layout (layout, RP); 488 doorify_layout (*this, RP);
758 489
759 break; 490 break;
760 491
761 case LAYOUT_SPIRAL: 492 case LAYOUT_SPIRAL:
762 map_gen_spiral (layout, RP->layoutoptions1); 493 map_gen_spiral (*this, RP->layoutoptions1);
763 494
764 if (!(rmg_rndm (2))) 495 if (!(rmg_rndm (2)))
765 doorify_layout (layout, RP); 496 doorify_layout (*this, RP);
766 497
767 break; 498 break;
768 499
769 case LAYOUT_ROGUELIKE: 500 case LAYOUT_ROGUELIKE:
770 /* Don't put symmetry in rogue maps. There isn't much reason to 501 /* Don't put symmetry in rogue maps. There isn't much reason to
773 * spirals, or maps with lots of passages - making a symmetric rogue 504 * spirals, or maps with lots of passages - making a symmetric rogue
774 * map fails because its likely that the passages the symmetry process 505 * map fails because its likely that the passages the symmetry process
775 * creates may not connect the rooms. 506 * creates may not connect the rooms.
776 */ 507 */
777 RP->symmetry_used = SYMMETRY_NONE; 508 RP->symmetry_used = SYMMETRY_NONE;
778 roguelike_layout_gen (layout, RP->layoutoptions1); 509 roguelike_layout_gen (*this, RP->layoutoptions1);
779 /* no doorifying... done already */ 510 /* no doorifying... done already */
780 break; 511 break;
781 512
782 case LAYOUT_SNAKE: 513 case LAYOUT_SNAKE:
783 make_snake_layout (layout, RP->layoutoptions1); 514 make_snake_layout (*this, RP->layoutoptions1);
784 515
785 if (rmg_rndm (2)) 516 if (rmg_rndm (2))
786 roomify_layout (layout, RP); 517 roomify_layout (*this, RP);
787 518
788 break; 519 break;
789 520
790 case LAYOUT_SQUARE_SPIRAL: 521 case LAYOUT_SQUARE_SPIRAL:
791 make_square_spiral_layout (layout, RP->layoutoptions1); 522 make_square_spiral_layout (*this, RP->layoutoptions1);
792 523
793 if (rmg_rndm (2)) 524 if (rmg_rndm (2))
794 roomify_layout (layout, RP); 525 roomify_layout (*this, RP);
526
527 break;
528
529 case LAYOUT_CAVE:
530 gen_cave (RP->get_iv ("cave_type", rmg_rndm (4)));
531
532 if (!(rmg_rndm (2)))
533 doorify_layout (*this, RP);
795 534
796 break; 535 break;
797 536
798 default: 537 default:
799 abort (); 538 abort ();
800 } 539 }
801 540
802 /* rotate the layout randomly */ 541 /* rotate the layout randomly */
803 rotate_layout (layout, rmg_rndm (4)); 542 rotate_layout (*this, rmg_rndm (4));
804 543
805 symmetrize_layout (layout, RP); 544 symmetrize_layout (*this, RP);
806 545
807#ifdef RMAP_DEBUG 546#if 0
808 dump_layout (layout); 547 print ();//D
809#endif 548#endif
810 549
811 if (RP->expand2x) 550 if (RP->expand2x)
812 expand2x (layout); 551 expand2x (*this);
813
814 return layout;
815} 552}
816 553
817bool 554bool
818maptile::generate_random_map (random_map_params *RP) 555maptile::generate_random_map (random_map_params *RP)
819{ 556{
820 char buf[16384];
821 int i;
822
823 RP->Xsize = RP->xsize; 557 RP->Xsize = RP->xsize;
824 RP->Ysize = RP->ysize; 558 RP->Ysize = RP->ysize;
825 559
826 /* pick a random seed, or use the one from the input file */ 560 /* pick a random seed, or use the one from the input file */
827 RP->random_seed = RP->random_seed 561 RP->random_seed = RP->random_seed
829 : time (0); 563 : time (0);
830 564
831 // we run "single-threaded" 565 // we run "single-threaded"
832 rmg_rndm.seed (RP->random_seed); 566 rmg_rndm.seed (RP->random_seed);
833 567
834 write_map_parameters_to_string (buf, RP); 568 shstr buf = RP->as_shstr ();
835 569
836 if (RP->difficulty == 0) 570 if (RP->difficulty == 0)
837 { 571 {
838 RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */ 572 RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */
839 573
849 if (RP->Xsize < MIN_RANDOM_MAP_SIZE) 583 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
850 RP->Xsize = MIN_RANDOM_MAP_SIZE + rmg_rndm (25) + 5; 584 RP->Xsize = MIN_RANDOM_MAP_SIZE + rmg_rndm (25) + 5;
851 585
852 if (RP->Ysize < MIN_RANDOM_MAP_SIZE) 586 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
853 RP->Ysize = MIN_RANDOM_MAP_SIZE + rmg_rndm (25) + 5; 587 RP->Ysize = MIN_RANDOM_MAP_SIZE + rmg_rndm (25) + 5;
588
589 min_it (RP->Xsize, MAX_RANDOM_MAP_SIZE);
590 min_it (RP->Ysize, MAX_RANDOM_MAP_SIZE);
854 591
855 if (RP->symmetry == SYMMETRY_RANDOM) 592 if (RP->symmetry == SYMMETRY_RANDOM)
856 RP->symmetry_used = rmg_rndm (SYMMETRY_XY) + 1; 593 RP->symmetry_used = rmg_rndm (SYMMETRY_XY) + 1;
857 else 594 else
858 RP->symmetry_used = RP->symmetry; 595 RP->symmetry_used = RP->symmetry;
867 { 604 {
868 RP->Xsize /= 2; 605 RP->Xsize /= 2;
869 RP->Ysize /= 2; 606 RP->Ysize /= 2;
870 } 607 }
871 608
872 RP->map_layout_style = LAYOUT_NONE;
873
874 /* Redo this - there was a lot of redundant code of checking for preset
875 * layout style and then random layout style. Instead, figure out
876 * the numeric layoutstyle, so there is only one area that actually
877 * calls the code to make the maps.
878 */
879 if (strstr (RP->layoutstyle, "onion")) 609 if (strstr (RP->layoutstyle, "onion"))
880 RP->map_layout_style = LAYOUT_ONION; 610 RP->map_layout_style = LAYOUT_ONION;
881 else if (strstr (RP->layoutstyle, "maze")) 611 else if (strstr (RP->layoutstyle, "maze"))
882 RP->map_layout_style = LAYOUT_MAZE; 612 RP->map_layout_style = LAYOUT_MAZE;
883 else if (strstr (RP->layoutstyle, "spiral")) 613 else if (strstr (RP->layoutstyle, "spiral"))
886 RP->map_layout_style = LAYOUT_ROGUELIKE; 616 RP->map_layout_style = LAYOUT_ROGUELIKE;
887 else if (strstr (RP->layoutstyle, "snake")) 617 else if (strstr (RP->layoutstyle, "snake"))
888 RP->map_layout_style = LAYOUT_SNAKE; 618 RP->map_layout_style = LAYOUT_SNAKE;
889 else if (strstr (RP->layoutstyle, "squarespiral")) 619 else if (strstr (RP->layoutstyle, "squarespiral"))
890 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL; 620 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
621 else if (strstr (RP->layoutstyle, "cave"))
891 else if (RP->map_layout_style == LAYOUT_NONE) 622 RP->map_layout_style = LAYOUT_CAVE;
623 else
892 RP->map_layout_style = rmg_rndm (NROFLAYOUTS - 1) + 1; /* No style found - choose one randomly */ 624 RP->map_layout_style = rmg_rndm (NROFLAYOUTS - 1) + 1; /* No style found - choose one randomly */
893 else
894 abort ();
895 625
896 Layout layout = layoutgen (RP); 626 Layout layout (RP->Xsize, RP->Ysize);
897 627 layout.generate (RP);
898#ifdef RMAP_DEBUG
899 dump_layout (layout);
900#endif
901 628
902 /* increment these for the current map */ 629 /* increment these for the current map */
903 ++RP->dungeon_level; 630 ++RP->dungeon_level;
904 631
905 // need to patch RP becasue following code doesn't use the Layout object 632 // need to patch RP becasue following code doesn't use the Layout object
906 RP->Xsize = layout->w; 633 RP->Xsize = layout.w;
907 RP->Ysize = layout->h; 634 RP->Ysize = layout.h;
908 635
909 /* allocate the map and set the floor */ 636 /* allocate the map and set the floor */
910 make_map_floor (layout, RP->floorstyle, RP); 637 make_map_floor (layout, RP->get_str ("floorstyle", ""), RP);
911 638
912 /* set region */ 639 /* set region */
913 default_region = RP->region; 640 default_region = RP->region;
914 641
915 CEDE; 642 CEDE;
916 643
917 place_specials_in_map (this, layout, RP); 644 place_specials_in_map (this, layout, RP);
918 645
919 CEDE; 646 CEDE;
920 647
648 const char *wallstyle = RP->get_str ("wallstyle", 0);
649
921 /* create walls unless the wallstyle is "none" */ 650 /* create walls unless the wallstyle is "none" */
922 if (strcmp (RP->wallstyle, "none")) 651 if (strcmp (wallstyle, "none"))
923 { 652 {
924 make_map_walls (this, layout, RP->wallstyle, RP); 653 make_map_walls (this, layout, wallstyle, RP->get_str ("miningstyle", ""), RP);
925 654
926 /* place doors unless doorstyle or wallstyle is "none" */ 655 /* place doors unless doorstyle or wallstyle is "none" */
927 if (strcmp (RP->doorstyle, "none")) 656 if (strcmp (RP->doorstyle, "none"))
928 put_doors (this, layout, RP->doorstyle, RP); 657 put_doors (this, layout, RP->doorstyle, RP);
929 } 658 }
930 659
931 CEDE; 660 CEDE;
932 661
662 const char *exitstyle = RP->get_str ("exitstyle", "");
663
933 /* create exits unless the exitstyle is "none" */ 664 /* create exits unless the exitstyle is "none" */
934 if (strcmp (RP->exitstyle, "none")) 665 if (strcmp (exitstyle, "none"))
935 place_exits (this, layout, RP->exitstyle, RP->orientation, RP); 666 place_exits (this, layout, exitstyle, RP->orientation, RP);
936 667
937 CEDE; 668 CEDE;
938 669
939 /* create monsters unless the monsterstyle is "none" */ 670 /* create monsters unless the monsterstyle is "none" */
940 if (strcmp (RP->monsterstyle, "none")) 671 if (strcmp (RP->monsterstyle, "none"))
945 /* treasures needs to have a proper difficulty set for the map. */ 676 /* treasures needs to have a proper difficulty set for the map. */
946 difficulty = estimate_difficulty (); 677 difficulty = estimate_difficulty ();
947 678
948 CEDE; 679 CEDE;
949 680
681 const char *treasurestyle = RP->get_str ("treasurestyle", "");
682
950 /* create treasure unless the treasurestyle is "none" */ 683 /* create treasure unless the treasurestyle is "none" */
951 place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP); 684 place_treasure (this, layout, treasurestyle, RP->get_iv ("treasureoptions"), RP);
952 685
953 CEDE; 686 CEDE;
687
688 const char *decorstyle = RP->get_str ("treasurestyle", "");
954 689
955 /* create decor unless the decorstyle is "none" */ 690 /* create decor unless the decorstyle is "none" */
956 if (strcmp (RP->decorstyle, "none")) 691 if (strcmp (decorstyle, "none"))
957 put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP); 692 put_decor (this, layout, decorstyle, RP->get_iv ("decoroptions"), RP);
958 693
959 CEDE; 694 CEDE;
960 695
961 /* generate treasures, etc. */ 696 /* generate treasures, etc. */
962 fix_auto_apply (); 697 fix_auto_apply ();
963 698
964 CEDE; 699 CEDE;
965 700
966 unblock_exits (this, layout, RP); 701 unblock_exits (this, layout, RP);
967 702
968 msg = strdup (buf); 703 msg = buf;
969 in_memory = MAP_ACTIVE; 704 in_memory = MAP_ACTIVE;
970 705
971 CEDE; 706 CEDE;
972 707
973 return 1; 708 return 1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines