summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/coordit.cc83
-rw-r--r--crawl-ref/source/coordit.h29
-rw-r--r--crawl-ref/source/dat/des/builder/layout_pools.des46
-rw-r--r--crawl-ref/source/l_dgnbld.cc69
4 files changed, 195 insertions, 32 deletions
diff --git a/crawl-ref/source/coordit.cc b/crawl-ref/source/coordit.cc
index 5851283ff3..78fb358a65 100644
--- a/crawl-ref/source/coordit.cc
+++ b/crawl-ref/source/coordit.cc
@@ -58,12 +58,93 @@ void rectangle_iterator::operator ++()
current.x++;
}
-
void rectangle_iterator::operator++(int dummy)
{
++(*this);
}
+
+random_rectangle_iterator::random_rectangle_iterator(const coord_def& corner1,
+ const coord_def& corner2)
+{
+ int left = min(corner1.x, corner2.x);
+ int right = max(corner1.x, corner2.x);
+ int top = min(corner1.y, corner2.y);
+ int bottom = max(corner1.y, corner2.y);
+
+ top_left.x = left;
+ top_left.y = top;
+
+ for(int y = top; y <= bottom; y++)
+ for(int x = left; x <= right; x++)
+ remaining.push_back(coord_def(x, y));
+
+ if(remaining.empty())
+ current = 0;
+ else
+ current = random2(remaining.size());
+}
+
+random_rectangle_iterator::random_rectangle_iterator(int x_border_dist,
+ int y_border_dist)
+{
+ if (y_border_dist < 0)
+ y_border_dist = x_border_dist;
+
+ int right = GXM - x_border_dist - 1;
+ int bottom = GYM - y_border_dist - 1;
+
+ top_left.x = x_border_dist;
+ top_left.y = y_border_dist;
+
+ for(int y = y_border_dist; y <= bottom; y++)
+ for(int x = x_border_dist; x <= right; x++)
+ remaining.push_back(coord_def(x, y));
+
+ if(remaining.empty())
+ current = 0;
+ else
+ current = random2(remaining.size());
+}
+
+random_rectangle_iterator::operator bool() const
+{
+ return !remaining.empty();
+}
+
+coord_def random_rectangle_iterator::operator *() const
+{
+ if(remaining.empty())
+ return top_left;
+ else
+ return remaining[current];
+}
+
+const coord_def* random_rectangle_iterator::operator->() const
+{
+ if(remaining.empty())
+ return &top_left;
+ else
+ return &(remaining[current]);
+}
+
+void random_rectangle_iterator::operator ++()
+{
+ if(!remaining.empty())
+ {
+ remaining[current] = remaining.back();
+ remaining.pop_back();
+ if(!remaining.empty())
+ current = random2(remaining.size());
+ }
+}
+
+void random_rectangle_iterator::operator++(int dummy)
+{
+ ++(*this);
+}
+
+
/*
* circle iterator
*/
diff --git a/crawl-ref/source/coordit.h b/crawl-ref/source/coordit.h
index 74ae22d878..9c9695882a 100644
--- a/crawl-ref/source/coordit.h
+++ b/crawl-ref/source/coordit.h
@@ -18,6 +18,35 @@ private:
coord_def current, topleft, bottomright;
};
+/**
+ * @class random_rectangle_iterator
+ * Iterator over coordinates in a rectangular region in a
+ * random order. This interator does not favour any given
+ * direction, but is slower than rectangle_iterator.
+ *
+ * When this iterator has returned all elements, it will just
+ * return the top left corner forever.
+ */
+class random_rectangle_iterator : public iterator<forward_iterator_tag,
+ coord_def>
+{
+public:
+ random_rectangle_iterator(const coord_def& corner1,
+ const coord_def& corner2);
+ explicit random_rectangle_iterator(int x_border_dist,
+ int y_border_dist = -1);
+ operator bool() const PURE;
+ coord_def operator *() const PURE;
+ const coord_def* operator->() const PURE;
+
+ void operator ++ ();
+ void operator ++ (int);
+private:
+ coord_def top_left;
+ vector<coord_def> remaining;
+ int current;
+};
+
class circle_iterator
{
const circle_def &circle;
diff --git a/crawl-ref/source/dat/des/builder/layout_pools.des b/crawl-ref/source/dat/des/builder/layout_pools.des
index 2a066f4087..b18f81e8a1 100644
--- a/crawl-ref/source/dat/des/builder/layout_pools.des
+++ b/crawl-ref/source/dat/des/builder/layout_pools.des
@@ -8,6 +8,8 @@
# that the dungeon builder can add other vaults on top of them.
#
+: require("dlua/layout/zonify.lua")
+
##############################################################
@@ -148,7 +150,7 @@ ENDMAP
# by doors and sometimes just by holes in the wall.
#
NAME: layout_honeycomb
-DEPTH: D:12-,Snake:1-4,Dis
+DEPTH: D:12-, Snake:1-4, Dis
WEIGHT: 10
ORIENT: encompass
TAGS: overwritable layout allow_dup unrand
@@ -160,42 +162,24 @@ TAGS: overwritable layout allow_dup unrand
make_circle { x = gxm/2, y = gym/2, radius = 10 }
mapgrd[gxm/2][gym/2] = '.'
- spotty_map { boxy = true, iterations = 1200 }
+ spotty_map { boxy = true, iterations = 1500 }
widen_paths { find = "x", percent = 50 }
remove_isolated_glyphs { find = "x", percent = 100 }
- local fill = '.'
- local border = 'x'
- local connection = crawl.random_element({[fill] = 1, ["+"] = 2})
+ local connection = {}
+ if you.in_branch("snake") then
+ connection = '.'
+ else
+ connection = crawl.random_element({['.'] = 1, ['+'] = 2})
+ end
add_pools { replace = ".",
- contents = {[fill] = 1},
+ contents = {['.'] = 1},
pool_size = 25 + crawl.random2(25),
- border = border }
-
- -- connect rooms
- for i = 1, crawl.random_range(800, 1200) do
- local x = crawl.random_range(1, gxm - 2)
- local y = crawl.random_range(1, gym - 2)
-
- if mapgrd[x][y] == border then
- if mapgrd[x + 1][y] == border and
- mapgrd[x - 1][y] == border and
- mapgrd[x][y + 1] == fill and
- mapgrd[x][y - 1] == fill then
- mapgrd[x][y] = connection
- elseif mapgrd[x + 1][y] == fill and
- mapgrd[x - 1][y] == fill and
- mapgrd[x][y + 1] == border and
- mapgrd[x][y - 1] == border then
- mapgrd[x][y] = connection
- end
- end
- end
-
- replace_closest { x = gxm/2, y = gym/2, find = fill, replace = '@' }
- fill_disconnected{wanted = '@'}
- subst("@ = " .. fill)
+ border = 'x' }
+ connect_adjacent_rooms { wall = "x", floor = ".", replace = connection,
+ min = 1000, max = 1500 }
+ zonify.map_fill_zones(_G, 1, 'x')
random_wall_material(_G)
}}
diff --git a/crawl-ref/source/l_dgnbld.cc b/crawl-ref/source/l_dgnbld.cc
index 7a4a199eb5..e2912afd87 100644
--- a/crawl-ref/source/l_dgnbld.cc
+++ b/crawl-ref/source/l_dgnbld.cc
@@ -926,6 +926,74 @@ LUAFN(dgn_widen_paths)
return 0;
}
+LUAFN(dgn_connect_adjacent_rooms)
+{
+ LINES(ls, 1, lines);
+
+ TABLE_STR(ls, wall, "x");
+ TABLE_STR(ls, floor, ".");
+ TABLE_CHAR(ls, replace, '.');
+ TABLE_INT(ls, max, 1);
+ TABLE_INT(ls, min, max);
+
+ int x1, y1, x2, y2;
+ if (!_coords(ls, lines, x1, y1, x2, y2))
+ return 0;
+
+ // we never go right up to the border to avoid looking off the map edge
+ if(x1 < 1)
+ x1 = 1;
+ if(x2 >= lines.width() - 1)
+ x2 = lines.width() - 2;
+ if(y1 < 1)
+ y1 = 1;
+ if(y2 >= lines.height() - 1)
+ y2 = lines.height() - 2;
+
+ if (min < 0)
+ return luaL_error(ls, "Invalid min connections: %i", min);
+ if (max < min)
+ {
+ return luaL_error(ls, "Invalid max connections: %i (min is %i)",
+ max, min);
+ }
+
+ int count = min + random2(max - min + 1);
+ for (random_rectangle_iterator ri(coord_def(x1, y1),
+ coord_def(x2, y2)); ri; ++ri)
+ {
+ if(count <= 0)
+ {
+ // stop when have checked enough spots
+ return 0;
+ }
+
+ int x = ri->x;
+ int y = ri->y;
+
+ if (strchr(wall, lines(*ri)))
+ {
+ if ( strchr(wall, lines(x - 1, y))
+ && strchr(wall, lines(x + 1, y))
+ && strchr(floor, lines(x, y - 1))
+ && strchr(floor, lines(x, y + 1)))
+ {
+ lines(*ri) = replace;
+ }
+ else if ( strchr(floor, lines(x - 1, y))
+ && strchr(floor, lines(x + 1, y))
+ && strchr(wall, lines(x, y - 1))
+ && strchr(wall, lines(x, y + 1)))
+ {
+ lines(*ri) = replace;
+ }
+ }
+ count--;
+ }
+
+ return 0;
+}
+
LUAFN(dgn_replace_area)
{
LINES(ls, 1, lines);
@@ -1501,6 +1569,7 @@ const struct luaL_reg dgn_build_dlib[] =
{ "octa_room", &dgn_octa_room },
{ "remove_isolated_glyphs", &dgn_remove_isolated_glyphs },
{ "widen_paths", &dgn_widen_paths },
+ { "connect_adjacent_rooms", &dgn_connect_adjacent_rooms },
{ "replace_area", &dgn_replace_area },
{ "replace_first", &dgn_replace_first },
{ "replace_random", &dgn_replace_random },