--- deliantra/server/random_maps/layout.C 2010/07/04 22:12:26 1.23 +++ deliantra/server/random_maps/layout.C 2017/01/29 02:47:05 1.32 @@ -1,31 +1,31 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. - * - * Copyright (©) 2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team - * Copyright (©) Crossfire Development Team (restored, original file without copyright notice) - * + * + * Copyright (©) 2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * Copyright (©) 1994-2004 Crossfire Development Team (restored, original file without copyright notice) + * * Deliantra is free software: you can redistribute it and/or modify it under * the terms of the Affero GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the Affero GNU General Public License * and the GNU General Public License along with this program. If not, see * . - * + * * The authors can be reached via e-mail to */ #include -#include +#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,19 +104,20 @@ 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); @@ -120,7 +130,7 @@ ///////////////////////////////////////////////////////////////////////////// // 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,12 +632,14 @@ 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]) { - case '#': expand_wall (new_layout, i, j, *this); break; - case 'D': expand_door (new_layout, i, j, *this); break; + case '#': expand_wall (new_layout, i, j, *this); break; + case 'D': expand_door (new_layout, i, j, *this); break; default: expand_misc (new_layout, i, j, *this); break; } @@ -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 */ @@ -854,6 +878,8 @@ maze.generate (RP); } + + coroapi::cede_to_tick (); } // recursive subdivision with random sublayouts @@ -865,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); } @@ -984,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);