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

Comparing deliantra/server/random_maps/layout.C (file contents):
Revision 1.21 by root, Sun Jul 4 01:01:42 2010 UTC vs.
Revision 1.24 by root, Mon Jul 5 00:07:21 2010 UTC

23 23
24#include <global.h> 24#include <global.h>
25#include <random_map.h> 25#include <random_map.h>
26#include <rproto.h> 26#include <rproto.h>
27 27
28void 28void noinline
29layout::alloc (int w, int h) 29layout::alloc (int w, int h)
30{ 30{
31 assert (sizeof (cell) == 1); 31 assert (sizeof (cell) == 1);
32 32
33 this->w = w; 33 this->w = w;
74layout::~layout () 74layout::~layout ()
75{ 75{
76 sfree ((char *)data, size); 76 sfree ((char *)data, size);
77} 77}
78 78
79void 79void noinline
80layout::fill (char fill) 80layout::fill (char fill)
81{ 81{
82 //memset (data [0], fill, w * h); // only when contiguous :/ 82 //memset (data [0], fill, w * h); // only when contiguous :/
83 fill_rect (0, 0, w, h, fill); 83 fill_rect (0, 0, w, h, fill);
84} 84}
85 85
86void 86void noinline
87layout::replace (char from, char to)
88{
89 for (int x = 0; x < w; ++x)
90 for (int y = 0; y < h; ++y)
91 if (data [x][y] == from)
92 data [x][y] = to;
93}
94
95void noinline
87layout::rect (int x1, int y1, int x2, int y2, char fill) 96layout::rect (int x1, int y1, int x2, int y2, char fill)
88{ 97{
89 --x2; 98 --x2;
90 99
91 memset (data [x1] + y1, fill, y2 - y1); 100 memset (data [x1] + y1, fill, y2 - y1);
93 102
94 while (++x1 < x2) 103 while (++x1 < x2)
95 data [x1][y1] = data [x1][y2 - 1] = fill; 104 data [x1][y1] = data [x1][y2 - 1] = fill;
96} 105}
97 106
98void 107void noinline
99layout::fill_rect (int x1, int y1, int x2, int y2, char fill) 108layout::fill_rect (int x1, int y1, int x2, int y2, char fill)
100{ 109{
101 for (; x1 < x2; ++x1) 110 for (; x1 < x2; ++x1)
102 memset (data [x1] + y1, fill, y2 - y1); 111 memset (data [x1] + y1, fill, y2 - y1);
103} 112}
104 113
114void
105void layout::border (char fill) 115layout::border (char fill)
106{ 116{
107 rect (0, 0, w, h, fill); 117 rect (0, 0, w, h, fill);
108} 118}
109 119
110void 120void noinline
111layout::fill_rand (int percent) 121layout::fill_rand (int percent)
112{ 122{
113 percent = lerp (percent, 0, 100, 0, 256); 123 percent = lerp (percent, 0, 100, 0, 256);
114 124
115 for (int x = w - 1; --x > 0; ) 125 for (int x = 0; x < w; ++x)
116 for (int y = h - 1; --y > 0; ) 126 for (int y = 0; y < h; ++y)
117 data [x][y] = rmg_rndm (256) > percent ? 0 : '#'; 127 data [x][y] = rmg_rndm (256) > percent ? 0 : '#';
118} 128}
119 129
120///////////////////////////////////////////////////////////////////////////// 130/////////////////////////////////////////////////////////////////////////////
121 131
122// erode by cellular automata 132// erode by cellular automata
123void 133void noinline
124layout::erode_1_2 (int c1, int c2, int repeat) 134layout::erode_1_2 (int c1, int c2, int repeat)
125{ 135{
126 layout neu (w, h); 136 layout neu (w, h);
127 137
128 while (repeat--) 138 while (repeat--)
220 if (x > 0 && !dist [x - 1][y]) push_flood_fill (dist, seeds, x - 1, y); 230 if (x > 0 && !dist [x - 1][y]) push_flood_fill (dist, seeds, x - 1, y);
221 if (x < dist.w - 1 && !dist [x + 1][y]) push_flood_fill (dist, seeds, x + 1, y); 231 if (x < dist.w - 1 && !dist [x + 1][y]) push_flood_fill (dist, seeds, x + 1, y);
222 } 232 }
223} 233}
224 234
225static inline void 235static void inline
226make_tunnel (layout &dist, pointlist &seeds, int x, int y, U8 d, int perturb) 236make_tunnel (layout &dist, pointlist &seeds, int x, int y, U8 d, int perturb)
227{ 237{
228 for (;;) 238 for (;;)
229 { 239 {
230 point neigh[4]; 240 point neigh[4];
358void 368void
359layout::doorify () 369layout::doorify ()
360{ 370{
361 int ndoors = w * h / 60; /* reasonable number of doors. */ 371 int ndoors = w * h / 60; /* reasonable number of doors. */
362 372
373 coroapi::cede_to_tick ();
374
363 fixed_stack<point> doorloc (w * h); 375 fixed_stack<point> doorloc (w * h);
364 376
365 /* make a list of possible door locations */ 377 /* make a list of possible door locations */
366 for (int i = 1; i < w - 1; i++) 378 for (int i = 1; i < w - 1; i++)
367 for (int j = 1; j < h - 1; j++) 379 for (int j = 1; j < h - 1; j++)
449//-GPL 461//-GPL
450 462
451void 463void
452layout::rotate (int rotation) 464layout::rotate (int rotation)
453{ 465{
466 coroapi::cede_to_tick ();
467
454 switch (rotation & 3) 468 switch (rotation & 3)
455 { 469 {
456 case 2: /* a reflection */ 470 case 2: /* a reflection */
457 { 471 {
458 layout new_layout (w, h); 472 layout new_layout (w, h);
610{ 624{
611 layout new_layout (w * 2 - 1, h * 2 - 1); 625 layout new_layout (w * 2 - 1, h * 2 - 1);
612 626
613 new_layout.clear (); 627 new_layout.clear ();
614 628
629 coroapi::cede_to_tick ();
630
615 for (int i = 0; i < w; i++) 631 for (int i = 0; i < w; i++)
616 for (int j = 0; j < h; j++) 632 for (int j = 0; j < h; j++)
617 switch (data [i][j]) 633 switch (data [i][j])
618 { 634 {
619 case '#': expand_wall (new_layout, i, j, *this); break; 635 case '#': expand_wall (new_layout, i, j, *this); break;
701 717
702 return -1; 718 return -1;
703} 719}
704 720
705int 721int
706make_wall (char **maze, int x, int y, int dir) 722make_wall (layout &maze, int x, int y, int dir)
707{ 723{
708 maze[x][y] = 'D'; /* mark a door */ 724 maze[x][y] = 'D'; /* mark a door */
709 725
710 switch (dir) 726 switch (dir)
711 { 727 {
728 744
729void 745void
730layout::roomify () 746layout::roomify ()
731{ 747{
732 int tries = w * h / 30; 748 int tries = w * h / 30;
749
750 coroapi::cede_to_tick ();
733 751
734 for (int ti = 0; ti < tries; ti++) 752 for (int ti = 0; ti < tries; ti++)
735 { 753 {
736 /* starting location for looking at creating a door */ 754 /* starting location for looking at creating a door */
737 int dx = rmg_rndm (w); 755 int dx = rmg_rndm (w);
829} 847}
830 848
831static void 849static void
832gen_mixed_ (layout &maze, random_map_params *RP) 850gen_mixed_ (layout &maze, random_map_params *RP)
833{ 851{
834 int dir; 852 if (maze.w > maze.h && maze.w > 16)
835
836 if (maze.w < 20 && maze.h < 20 && !rmg_rndm (3))
837 dir = 2; // stop recursion randomly
838 else
839 dir = maze.w > maze.h;
840
841 if (dir == 0 && maze.w > 16)
842 { 853 {
843 int m = rmg_rndm (8, maze.w - 8); 854 int m = rmg_rndm (8, maze.w - 8);
844 855
845 layout m1 (maze, 0, 0, m , maze.h); gen_mixed_ (m1, RP); 856 layout m1 (maze, 0, 0, m , maze.h); gen_mixed_ (m1, RP);
846 layout m2 (maze, m, 0, maze.w, maze.h); gen_mixed_ (m2, RP); 857 layout m2 (maze, m, 0, maze.w, maze.h); gen_mixed_ (m2, RP);
847 } 858 }
848 else if (dir == 1 && maze.h > 16) 859 else if (maze.h > 16)
849 { 860 {
850 int m = rmg_rndm (8, maze.h - 8); 861 int m = rmg_rndm (8, maze.h - 8);
851 862
852 layout m1 (maze, 0, 0, maze.w, m ); gen_mixed_ (m1, RP); 863 layout m1 (maze, 0, 0, maze.w, m ); gen_mixed_ (m1, RP);
853 layout m2 (maze, 0, m, maze.w, maze.h); gen_mixed_ (m2, RP); 864 layout m2 (maze, 0, m, maze.w, maze.h); gen_mixed_ (m2, RP);
859 if (RP->map_layout_style == LAYOUT_MULTIPLE) 870 if (RP->map_layout_style == LAYOUT_MULTIPLE)
860 ++RP->map_layout_style; 871 ++RP->map_layout_style;
861 872
862 maze.generate (RP); 873 maze.generate (RP);
863 } 874 }
875
876 coroapi::cede_to_tick ();
864} 877}
865 878
866// recursive subdivision with random sublayouts 879// recursive subdivision with random sublayouts
867static void 880static void
868gen_mixed (layout &maze, random_map_params *RP) 881gen_mixed (layout &maze, random_map_params *RP)
870 random_map_params &rp = *new random_map_params (RP); 883 random_map_params &rp = *new random_map_params (RP);
871 gen_mixed_ (maze, &rp); 884 gen_mixed_ (maze, &rp);
872 delete &rp; 885 delete &rp;
873 886
874 maze.border (); 887 maze.border ();
888
889 // exits currently do not work so well, as they
890 // are currently often found together, so nuke entrances
891 maze.replace ('<', ' ');
892
875 maze.isolation_remover (0); 893 maze.isolation_remover (0);
876} 894}
877 895
878//+GPL 896//+GPL
879 897

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines