--- deliantra/server/random_maps/layout.C 2010/07/04 01:01:42 1.21 +++ deliantra/server/random_maps/layout.C 2010/07/06 20:00:46 1.26 @@ -25,7 +25,7 @@ #include #include -void +void noinline layout::alloc (int w, int h) { assert (sizeof (cell) == 1); @@ -76,14 +76,23 @@ sfree ((char *)data, size); } -void +void noinline layout::fill (char fill) { //memset (data [0], fill, w * h); // only when contiguous :/ fill_rect (0, 0, w, h, fill); } -void +void noinline +layout::replace (char from, char to) +{ + for (int x = 0; x < w; ++x) + for (int y = 0; y < h; ++y) + if (data [x][y] == from) + data [x][y] = to; +} + +void noinline layout::rect (int x1, int y1, int x2, int y2, char fill) { --x2; @@ -95,32 +104,33 @@ data [x1][y1] = data [x1][y2 - 1] = fill; } -void +void noinline layout::fill_rect (int x1, int y1, int x2, int y2, char fill) { for (; x1 < x2; ++x1) memset (data [x1] + y1, fill, y2 - y1); } -void layout::border (char fill) +void +layout::border (char fill) { rect (0, 0, w, h, fill); } -void +void noinline layout::fill_rand (int percent) { percent = lerp (percent, 0, 100, 0, 256); - for (int x = w - 1; --x > 0; ) - for (int y = h - 1; --y > 0; ) + for (int x = 0; x < w; ++x) + for (int y = 0; y < h; ++y) data [x][y] = rmg_rndm (256) > percent ? 0 : '#'; } ///////////////////////////////////////////////////////////////////////////// // erode by cellular automata -void +void noinline layout::erode_1_2 (int c1, int c2, int repeat) { layout neu (w, h); @@ -222,7 +232,7 @@ } } -static inline void +static void inline make_tunnel (layout &dist, pointlist &seeds, int x, int y, U8 d, int perturb) { for (;;) @@ -304,11 +314,17 @@ // phase 2, while we have seeds, if // seed is empty, floodfill, else grow + int rem_index = 0; // used to remove "somewhat ordered" + while (seeds.size) { coroapi::cede_to_tick (); - point p = seeds.remove (rmg_rndm (seeds.size)); + int i = perturb + ? rmg_rndm (max (0, seeds.size - 8), seeds.size - 1) + : rem_index ++ % seeds.size; + + point p = seeds.remove (i); x = p.x; y = p.y; @@ -360,6 +376,8 @@ { int ndoors = w * h / 60; /* reasonable number of doors. */ + coroapi::cede_to_tick (); + fixed_stack doorloc (w * h); /* make a list of possible door locations */ @@ -451,6 +469,8 @@ void layout::rotate (int rotation) { + coroapi::cede_to_tick (); + switch (rotation & 3) { case 2: /* a reflection */ @@ -612,6 +632,8 @@ new_layout.clear (); + coroapi::cede_to_tick (); + for (int i = 0; i < w; i++) for (int j = 0; j < h; j++) switch (data [i][j]) @@ -703,7 +725,7 @@ } int -make_wall (char **maze, int x, int y, int dir) +make_wall (layout &maze, int x, int y, int dir) { maze[x][y] = 'D'; /* mark a door */ @@ -731,6 +753,8 @@ { int tries = w * h / 30; + coroapi::cede_to_tick (); + for (int ti = 0; ti < tries; ti++) { /* starting location for looking at creating a door */ @@ -831,21 +855,14 @@ static void gen_mixed_ (layout &maze, random_map_params *RP) { - int dir; - - if (maze.w < 20 && maze.h < 20 && !rmg_rndm (3)) - dir = 2; // stop recursion randomly - else - dir = maze.w > maze.h; - - if (dir == 0 && maze.w > 16) + if (maze.w > maze.h && maze.w > 16) { int m = rmg_rndm (8, maze.w - 8); layout m1 (maze, 0, 0, m , maze.h); gen_mixed_ (m1, RP); layout m2 (maze, m, 0, maze.w, maze.h); gen_mixed_ (m2, RP); } - else if (dir == 1 && maze.h > 16) + else if (maze.h > 16) { int m = rmg_rndm (8, maze.h - 8); @@ -861,6 +878,8 @@ maze.generate (RP); } + + coroapi::cede_to_tick (); } // recursive subdivision with random sublayouts @@ -872,6 +891,11 @@ delete &rp; maze.border (); + + // exits currently do not work so well, as they + // are currently often found together, so nuke entrances + maze.replace ('<', ' '); + maze.isolation_remover (0); } @@ -991,14 +1015,15 @@ demo () { rmg_rndm.seed (time (0)); + extern void hack();hack (); for(int i=1;i<100;i++) { layout maze (40, 30); - gen_village (maze); - maze.doorify (); + maze.fill_rand (99); + maze.border (); + maze.isolation_remover (2); maze.print (); - exit(0); } exit (1);