summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/dlua.cc1
-rw-r--r--crawl-ref/source/l_dgn.cc352
-rw-r--r--crawl-ref/source/l_dgn_bf.cc2
-rw-r--r--crawl-ref/source/l_dgnbld.cc365
-rw-r--r--crawl-ref/source/l_libs.h2
-rw-r--r--crawl-ref/source/makefile.obj1
6 files changed, 372 insertions, 351 deletions
diff --git a/crawl-ref/source/dlua.cc b/crawl-ref/source/dlua.cc
index 81a97cc485..027537ec84 100644
--- a/crawl-ref/source/dlua.cc
+++ b/crawl-ref/source/dlua.cc
@@ -307,6 +307,7 @@ void init_dungeon_lua()
lua_stack_cleaner clean(dlua);
luaL_openlib(dlua, "dgn", dgn_lib, 0);
+ luaL_openlib(dlua, "dgn", dgn_build_lib, 0);
luaL_openlib(dlua, "dgn", dgn_event_lib, 0);
luaL_openlib(dlua, "dgn", dgn_item_lib, 0);
luaL_openlib(dlua, "dgn", dgn_level_lib, 0);
diff --git a/crawl-ref/source/l_dgn.cc b/crawl-ref/source/l_dgn.cc
index 994d44c75a..99d33a57b6 100644
--- a/crawl-ref/source/l_dgn.cc
+++ b/crawl-ref/source/l_dgn.cc
@@ -32,7 +32,7 @@ static dungeon_feature_type _get_lua_feature(lua_State *ls, int idx)
return feat;
}
-static dungeon_feature_type _check_lua_feature(lua_State *ls, int idx)
+dungeon_feature_type check_lua_feature(lua_State *ls, int idx)
{
const dungeon_feature_type f = _get_lua_feature(ls, idx);
if (!f)
@@ -46,7 +46,7 @@ static inline bool _lua_boolean(lua_State *ls, int ndx, bool defval)
}
#define FEAT(f, pos) \
-dungeon_feature_type f = _check_lua_feature(ls, pos)
+dungeon_feature_type f = check_lua_feature(ls, pos)
void dgn_reset_default_depth()
{
@@ -1457,332 +1457,6 @@ static int dgn_apply_area_cloud(lua_State *ls)
return (0);
}
-static void _clamp_to_bounds(int &x, int &y, bool edge_ok = false)
-{
- const int edge_offset = edge_ok ? 0 : 1;
- x = std::min(std::max(x, X_BOUND_1 + edge_offset), X_BOUND_2 - edge_offset);
- y = std::min(std::max(y, Y_BOUND_1 + edge_offset), Y_BOUND_2 - edge_offset);
-}
-
-// Return a metatable for a point on the map_lines grid.
-static int dgn_grd_table(lua_State *ls)
-{
- MAP(ls, 1, map);
-
- map_def **mapref = clua_new_userdata<map_def *>(ls, GRD_METATABLE);
- *mapref = map;
-
- return (1);
-}
-
-static int dgn_width(lua_State *ls)
-{
- MAP(ls, 1, map);
-
- lua_pushnumber(ls, map->map.width());
- return (1);
-}
-
-static int dgn_height(lua_State *ls)
-{
- MAP(ls, 1, map);
-
- lua_pushnumber(ls, map->map.height());
- return (1);
-}
-
-static int dgn_fill_area(lua_State *ls)
-{
- int x1 = luaL_checkint(ls, 1);
- int y1 = luaL_checkint(ls, 2);
- int x2 = luaL_checkint(ls, 3);
- int y2 = luaL_checkint(ls, 4);
- dungeon_feature_type feat = _check_lua_feature(ls, 5);
-
- _clamp_to_bounds(x1, y1);
- _clamp_to_bounds(x2, y2);
- if (x2 < x1)
- std::swap(x1, x2);
- if (y2 < y1)
- std::swap(y1, y2);
-
- for (int y = y1; y <= y2; y++)
- for (int x = x1; x <= x2; x++)
- grd[x][y] = feat;
-
- return 0;
-}
-
-static int dgn_replace_area(lua_State *ls)
-{
- int x1 = luaL_checkint(ls, 1);
- int y1 = luaL_checkint(ls, 2);
- int x2 = luaL_checkint(ls, 3);
- int y2 = luaL_checkint(ls, 4);
- dungeon_feature_type search = _check_lua_feature(ls, 5);
- dungeon_feature_type replace = _check_lua_feature(ls, 6);
-
- // gracefully handle out of bound areas by truncating them.
- _clamp_to_bounds(x1, y1);
- _clamp_to_bounds(x2, y2);
- if (x2 < x1)
- std::swap(x1, x2);
- if (y2 < y1)
- std::swap(y1, y2);
-
- for (int y = y1; y <= y2; y++)
- for (int x = x1; x <= x2; x++)
- if (grd[x][y] == search)
- grd[x][y] = replace;
-
- return 0;
-}
-
-static int dgn_octa_room(lua_State *ls)
-{
- int x1 = luaL_checkint(ls, 1);
- int y1 = luaL_checkint(ls, 2);
- int x2 = luaL_checkint(ls, 3);
- int y2 = luaL_checkint(ls, 4);
- int oblique = luaL_checkint(ls, 5);
- dungeon_feature_type fill = _check_lua_feature(ls, 6);
-
- spec_room sr;
- sr.tl.x = x1;
- sr.br.x = x2;
- sr.tl.y = y1;
- sr.br.y = y2;
-
- octa_room(sr, oblique, fill);
-
- return 0;
-}
-
-static int dgn_make_pillars(lua_State *ls)
-{
- int center_x = luaL_checkint(ls, 1);
- int center_y = luaL_checkint(ls, 2);
- int num = luaL_checkint(ls, 3);
- int scale_x = luaL_checkint(ls, 4);
- int big_radius = luaL_checkint(ls, 5);
- int pillar_radius = luaL_checkint(ls, 6);
- dungeon_feature_type fill = _check_lua_feature(ls, 8);
-
- // [enne] The underscore is for DJGPP's brain damage.
- const float _PI = 3.14159265f;
- for (int n = 0; n < num; n++)
- {
- float angle = n * 2 * _PI / (float)num;
- int x = (int)std::floor(std::cos(angle) * big_radius * scale_x + 0.5f);
- int y = (int)std::floor(std::sin(angle) * big_radius + 0.5f);
-
- lua_pushvalue(ls, 7);
- lua_pushnumber(ls, center_x + x);
- lua_pushnumber(ls, center_y + y);
- lua_pushnumber(ls, pillar_radius);
- lua_pushnumber(ls, fill);
-
- lua_call(ls, 4, 0);
- }
-
- return 0;
-}
-
-static int dgn_make_square(lua_State *ls)
-{
- int center_x = luaL_checkint(ls, 1);
- int center_y = luaL_checkint(ls, 2);
- int radius = std::abs(luaL_checkint(ls, 3));
- dungeon_feature_type fill = _check_lua_feature(ls, 4);
-
- for (int x = -radius; x <= radius; x++)
- for (int y = -radius; y <= radius; y++)
- grd[center_x + x][center_y + y] = fill;
-
- return 0;
-}
-
-static int dgn_make_rounded_square(lua_State *ls)
-{
- int center_x = luaL_checkint(ls, 1);
- int center_y = luaL_checkint(ls, 2);
- int radius = std::abs(luaL_checkint(ls, 3));
- dungeon_feature_type fill = _check_lua_feature(ls, 4);
-
- for (int x = -radius; x <= radius; x++)
- for (int y = -radius; y <= radius; y++)
- if (std::abs(x) != radius || std::abs(y) != radius)
- grd[center_x + x][center_y + y] = fill;
-
- return 0;
-}
-
-static int dgn_make_circle(lua_State *ls)
-{
- int center_x = luaL_checkint(ls, 1);
- int center_y = luaL_checkint(ls, 2);
- int radius = std::abs(luaL_checkint(ls, 3));
- dungeon_feature_type fill = _check_lua_feature(ls, 4);
-
- for (int x = -radius; x <= radius; x++)
- for (int y = -radius; y <= radius; y++)
- if (x * x + y * y < radius * radius)
- grd[center_x + x][center_y + y] = fill;
-
- return 0;
-}
-
-static int dgn_in_bounds(lua_State *ls)
-{
- int x = luaL_checkint(ls, 1);
- int y = luaL_checkint(ls, 2);
-
- lua_pushboolean(ls, in_bounds(x, y));
- return 1;
-}
-
-static int dgn_replace_first(lua_State *ls)
-{
- int x = luaL_checkint(ls, 1);
- int y = luaL_checkint(ls, 2);
- int dx = luaL_checkint(ls, 3);
- int dy = luaL_checkint(ls, 4);
- dungeon_feature_type search = _check_lua_feature(ls, 5);
- dungeon_feature_type replace = _check_lua_feature(ls, 6);
-
- _clamp_to_bounds(x, y);
- bool found = false;
- while (in_bounds(x, y))
- {
- if (grd[x][y] == search)
- {
- grd[x][y] = replace;
- found = true;
- break;
- }
-
- x += dx;
- y += dy;
- }
-
- lua_pushboolean(ls, found);
- return 1;
-}
-
-static int dgn_replace_random(lua_State *ls)
-{
- dungeon_feature_type search = _check_lua_feature(ls, 1);
- dungeon_feature_type replace = _check_lua_feature(ls, 2);
-
- int x, y;
- do
- {
- x = random2(GXM);
- y = random2(GYM);
- }
- while (grd[x][y] != search);
-
- grd[x][y] = replace;
-
- return 0;
-}
-
-static int dgn_spotty_level(lua_State *ls)
-{
- bool seeded = lua_toboolean(ls, 1);
- int iterations = luaL_checkint(ls, 2);
- bool boxy = lua_toboolean(ls, 3);
-
- spotty_level(seeded, iterations, boxy);
- return 0;
-}
-
-static int dgn_smear_feature(lua_State *ls)
-{
- int iterations = luaL_checkint(ls, 1);
- bool boxy = lua_toboolean(ls, 2);
- dungeon_feature_type feat = _check_lua_feature(ls, 3);
-
- int x1 = luaL_checkint(ls, 4);
- int y1 = luaL_checkint(ls, 5);
- int x2 = luaL_checkint(ls, 6);
- int y2 = luaL_checkint(ls, 7);
-
- _clamp_to_bounds(x1, y1, true);
- _clamp_to_bounds(x2, y2, true);
-
- smear_feature(iterations, boxy, feat, x1, y1, x2, y2);
-
- return 0;
-}
-
-static int dgn_count_feature_in_box(lua_State *ls)
-{
- int x1 = luaL_checkint(ls, 1);
- int y1 = luaL_checkint(ls, 2);
- int x2 = luaL_checkint(ls, 3);
- int y2 = luaL_checkint(ls, 4);
- dungeon_feature_type feat = _check_lua_feature(ls, 5);
-
- lua_pushnumber(ls, count_feature_in_box(x1, y1, x2, y2, feat));
- return 1;
-}
-
-static int dgn_count_antifeature_in_box(lua_State *ls)
-{
- int x1 = luaL_checkint(ls, 1);
- int y1 = luaL_checkint(ls, 2);
- int x2 = luaL_checkint(ls, 3);
- int y2 = luaL_checkint(ls, 4);
- dungeon_feature_type feat = _check_lua_feature(ls, 5);
-
- lua_pushnumber(ls, count_antifeature_in_box(x1, y1, x2, y2, feat));
- return 1;
-}
-
-static int dgn_count_neighbours(lua_State *ls)
-{
- int x = luaL_checkint(ls, 1);
- int y = luaL_checkint(ls, 2);
- dungeon_feature_type feat = _check_lua_feature(ls, 3);
-
- lua_pushnumber(ls, count_neighbours(x, y, feat));
- return 1;
-}
-
-static int dgn_join_the_dots(lua_State *ls)
-{
- int from_x = luaL_checkint(ls, 1);
- int from_y = luaL_checkint(ls, 2);
- int to_x = luaL_checkint(ls, 3);
- int to_y = luaL_checkint(ls, 4);
- // TODO enne - push map masks to lua?
- unsigned map_mask = MMT_VAULT;
- bool early_exit = lua_toboolean(ls, 5);
-
- coord_def from(from_x, from_y);
- coord_def to(to_x, to_y);
-
- bool ret = join_the_dots(from, to, map_mask, early_exit);
- lua_pushboolean(ls, ret);
-
- return 1;
-}
-
-static int dgn_fill_disconnected_zones(lua_State *ls)
-{
- int from_x = luaL_checkint(ls, 1);
- int from_y = luaL_checkint(ls, 2);
- int to_x = luaL_checkint(ls, 3);
- int to_y = luaL_checkint(ls, 4);
-
- dungeon_feature_type feat = _check_lua_feature(ls, 5);
-
- process_disconnected_zones(from_x, from_y, to_x, to_y, true, feat);
-
- return 0;
-}
-
LUAFN(_dgn_is_opaque)
{
COORDS(c, 1, 2);
@@ -2169,28 +1843,6 @@ const struct luaL_reg dgn_lib[] =
{ "random_walk", dgn_random_walk },
{ "apply_area_cloud", dgn_apply_area_cloud },
-// building routines
-{ "grd_table", dgn_grd_table },
-{ "width", dgn_width },
-{ "height", dgn_height },
-{ "fill_area", dgn_fill_area },
-{ "replace_area", dgn_replace_area },
-{ "octa_room", dgn_octa_room },
-{ "make_pillars", dgn_make_pillars },
-{ "make_square", dgn_make_square },
-{ "make_rounded_square", dgn_make_rounded_square },
-{ "make_circle", dgn_make_circle },
-{ "in_bounds", dgn_in_bounds },
-{ "replace_first", dgn_replace_first },
-{ "replace_random", dgn_replace_random },
-{ "spotty_level", dgn_spotty_level },
-{ "smear_feature", dgn_smear_feature },
-{ "count_feature_in_box", dgn_count_feature_in_box },
-{ "count_antifeature_in_box", dgn_count_antifeature_in_box },
-{ "count_neighbours", dgn_count_neighbours },
-{ "join_the_dots", dgn_join_the_dots },
-{ "fill_disconnected_zones", dgn_fill_disconnected_zones },
-
{ "is_opaque", _dgn_is_opaque },
{ "is_passable", _dgn_is_passable },
diff --git a/crawl-ref/source/l_dgn_bf.cc b/crawl-ref/source/l_dgn_bf.cc
index ac7fd04a42..8c4d471fc9 100644
--- a/crawl-ref/source/l_dgn_bf.cc
+++ b/crawl-ref/source/l_dgn_bf.cc
@@ -1,5 +1,5 @@
/*
- * File: l_dgnbf.cc
+ * File: l_dgn_bf.cc
* Summary: Dungeon lua builder functions.
*/
diff --git a/crawl-ref/source/l_dgnbld.cc b/crawl-ref/source/l_dgnbld.cc
new file mode 100644
index 0000000000..a13a59f56a
--- /dev/null
+++ b/crawl-ref/source/l_dgnbld.cc
@@ -0,0 +1,365 @@
+/*
+ * File: l_dgnbld.cc
+ * Summary: Building routines (library "dgn").
+ */
+
+#include "AppHdr.h"
+
+#include <cmath>
+
+#include "dlua.h"
+#include "l_libs.h"
+
+#include "dungeon.h"
+
+// Return a metatable for a point on the map_lines grid.
+static int dgn_grd_table(lua_State *ls)
+{
+ MAP(ls, 1, map);
+
+ map_def **mapref = clua_new_userdata<map_def *>(ls, GRD_METATABLE);
+ *mapref = map;
+
+ return (1);
+}
+
+static int dgn_width(lua_State *ls)
+{
+ MAP(ls, 1, map);
+
+ lua_pushnumber(ls, map->map.width());
+ return (1);
+}
+
+static int dgn_height(lua_State *ls)
+{
+ MAP(ls, 1, map);
+
+ lua_pushnumber(ls, map->map.height());
+ return (1);
+}
+
+static void _clamp_to_bounds(int &x, int &y, bool edge_ok = false)
+{
+ const int edge_offset = edge_ok ? 0 : 1;
+ x = std::min(std::max(x, X_BOUND_1 + edge_offset), X_BOUND_2 - edge_offset);
+ y = std::min(std::max(y, Y_BOUND_1 + edge_offset), Y_BOUND_2 - edge_offset);
+}
+
+static int dgn_fill_area(lua_State *ls)
+{
+ int x1 = luaL_checkint(ls, 1);
+ int y1 = luaL_checkint(ls, 2);
+ int x2 = luaL_checkint(ls, 3);
+ int y2 = luaL_checkint(ls, 4);
+ dungeon_feature_type feat = check_lua_feature(ls, 5);
+
+ _clamp_to_bounds(x1, y1);
+ _clamp_to_bounds(x2, y2);
+ if (x2 < x1)
+ std::swap(x1, x2);
+ if (y2 < y1)
+ std::swap(y1, y2);
+
+ for (int y = y1; y <= y2; y++)
+ for (int x = x1; x <= x2; x++)
+ grd[x][y] = feat;
+
+ return 0;
+}
+
+static int dgn_replace_area(lua_State *ls)
+{
+ int x1 = luaL_checkint(ls, 1);
+ int y1 = luaL_checkint(ls, 2);
+ int x2 = luaL_checkint(ls, 3);
+ int y2 = luaL_checkint(ls, 4);
+ dungeon_feature_type search = check_lua_feature(ls, 5);
+ dungeon_feature_type replace = check_lua_feature(ls, 6);
+
+ // gracefully handle out of bound areas by truncating them.
+ _clamp_to_bounds(x1, y1);
+ _clamp_to_bounds(x2, y2);
+ if (x2 < x1)
+ std::swap(x1, x2);
+ if (y2 < y1)
+ std::swap(y1, y2);
+
+ for (int y = y1; y <= y2; y++)
+ for (int x = x1; x <= x2; x++)
+ if (grd[x][y] == search)
+ grd[x][y] = replace;
+
+ return 0;
+}
+
+static int dgn_octa_room(lua_State *ls)
+{
+ int x1 = luaL_checkint(ls, 1);
+ int y1 = luaL_checkint(ls, 2);
+ int x2 = luaL_checkint(ls, 3);
+ int y2 = luaL_checkint(ls, 4);
+ int oblique = luaL_checkint(ls, 5);
+ dungeon_feature_type fill = check_lua_feature(ls, 6);
+
+ spec_room sr;
+ sr.tl.x = x1;
+ sr.br.x = x2;
+ sr.tl.y = y1;
+ sr.br.y = y2;
+
+ octa_room(sr, oblique, fill);
+
+ return 0;
+}
+
+static int dgn_make_pillars(lua_State *ls)
+{
+ int center_x = luaL_checkint(ls, 1);
+ int center_y = luaL_checkint(ls, 2);
+ int num = luaL_checkint(ls, 3);
+ int scale_x = luaL_checkint(ls, 4);
+ int big_radius = luaL_checkint(ls, 5);
+ int pillar_radius = luaL_checkint(ls, 6);
+ dungeon_feature_type fill = check_lua_feature(ls, 8);
+
+ // [enne] The underscore is for DJGPP's brain damage.
+ const float _PI = 3.14159265f;
+ for (int n = 0; n < num; n++)
+ {
+ float angle = n * 2 * _PI / (float)num;
+ int x = (int)std::floor(std::cos(angle) * big_radius * scale_x + 0.5f);
+ int y = (int)std::floor(std::sin(angle) * big_radius + 0.5f);
+
+ lua_pushvalue(ls, 7);
+ lua_pushnumber(ls, center_x + x);
+ lua_pushnumber(ls, center_y + y);
+ lua_pushnumber(ls, pillar_radius);
+ lua_pushnumber(ls, fill);
+
+ lua_call(ls, 4, 0);
+ }
+
+ return 0;
+}
+
+static int dgn_make_square(lua_State *ls)
+{
+ int center_x = luaL_checkint(ls, 1);
+ int center_y = luaL_checkint(ls, 2);
+ int radius = std::abs(luaL_checkint(ls, 3));
+ dungeon_feature_type fill = check_lua_feature(ls, 4);
+
+ for (int x = -radius; x <= radius; x++)
+ for (int y = -radius; y <= radius; y++)
+ grd[center_x + x][center_y + y] = fill;
+
+ return 0;
+}
+
+static int dgn_make_rounded_square(lua_State *ls)
+{
+ int center_x = luaL_checkint(ls, 1);
+ int center_y = luaL_checkint(ls, 2);
+ int radius = std::abs(luaL_checkint(ls, 3));
+ dungeon_feature_type fill = check_lua_feature(ls, 4);
+
+ for (int x = -radius; x <= radius; x++)
+ for (int y = -radius; y <= radius; y++)
+ if (std::abs(x) != radius || std::abs(y) != radius)
+ grd[center_x + x][center_y + y] = fill;
+
+ return 0;
+}
+
+static int dgn_make_circle(lua_State *ls)
+{
+ int center_x = luaL_checkint(ls, 1);
+ int center_y = luaL_checkint(ls, 2);
+ int radius = std::abs(luaL_checkint(ls, 3));
+ dungeon_feature_type fill = check_lua_feature(ls, 4);
+
+ for (int x = -radius; x <= radius; x++)
+ for (int y = -radius; y <= radius; y++)
+ if (x * x + y * y < radius * radius)
+ grd[center_x + x][center_y + y] = fill;
+
+ return 0;
+}
+
+static int dgn_in_bounds(lua_State *ls)
+{
+ int x = luaL_checkint(ls, 1);
+ int y = luaL_checkint(ls, 2);
+
+ lua_pushboolean(ls, in_bounds(x, y));
+ return 1;
+}
+
+static int dgn_replace_first(lua_State *ls)
+{
+ int x = luaL_checkint(ls, 1);
+ int y = luaL_checkint(ls, 2);
+ int dx = luaL_checkint(ls, 3);
+ int dy = luaL_checkint(ls, 4);
+ dungeon_feature_type search = check_lua_feature(ls, 5);
+ dungeon_feature_type replace = check_lua_feature(ls, 6);
+
+ _clamp_to_bounds(x, y);
+ bool found = false;
+ while (in_bounds(x, y))
+ {
+ if (grd[x][y] == search)
+ {
+ grd[x][y] = replace;
+ found = true;
+ break;
+ }
+
+ x += dx;
+ y += dy;
+ }
+
+ lua_pushboolean(ls, found);
+ return 1;
+}
+
+static int dgn_replace_random(lua_State *ls)
+{
+ dungeon_feature_type search = check_lua_feature(ls, 1);
+ dungeon_feature_type replace = check_lua_feature(ls, 2);
+
+ int x, y;
+ do
+ {
+ x = random2(GXM);
+ y = random2(GYM);
+ }
+ while (grd[x][y] != search);
+
+ grd[x][y] = replace;
+
+ return 0;
+}
+
+static int dgn_spotty_level(lua_State *ls)
+{
+ bool seeded = lua_toboolean(ls, 1);
+ int iterations = luaL_checkint(ls, 2);
+ bool boxy = lua_toboolean(ls, 3);
+
+ spotty_level(seeded, iterations, boxy);
+ return 0;
+}
+
+static int dgn_smear_feature(lua_State *ls)
+{
+ int iterations = luaL_checkint(ls, 1);
+ bool boxy = lua_toboolean(ls, 2);
+ dungeon_feature_type feat = check_lua_feature(ls, 3);
+
+ int x1 = luaL_checkint(ls, 4);
+ int y1 = luaL_checkint(ls, 5);
+ int x2 = luaL_checkint(ls, 6);
+ int y2 = luaL_checkint(ls, 7);
+
+ _clamp_to_bounds(x1, y1, true);
+ _clamp_to_bounds(x2, y2, true);
+
+ smear_feature(iterations, boxy, feat, x1, y1, x2, y2);
+
+ return 0;
+}
+
+static int dgn_count_feature_in_box(lua_State *ls)
+{
+ int x1 = luaL_checkint(ls, 1);
+ int y1 = luaL_checkint(ls, 2);
+ int x2 = luaL_checkint(ls, 3);
+ int y2 = luaL_checkint(ls, 4);
+ dungeon_feature_type feat = check_lua_feature(ls, 5);
+
+ lua_pushnumber(ls, count_feature_in_box(x1, y1, x2, y2, feat));
+ return 1;
+}
+
+static int dgn_count_antifeature_in_box(lua_State *ls)
+{
+ int x1 = luaL_checkint(ls, 1);
+ int y1 = luaL_checkint(ls, 2);
+ int x2 = luaL_checkint(ls, 3);
+ int y2 = luaL_checkint(ls, 4);
+ dungeon_feature_type feat = check_lua_feature(ls, 5);
+
+ lua_pushnumber(ls, count_antifeature_in_box(x1, y1, x2, y2, feat));
+ return 1;
+}
+
+static int dgn_count_neighbours(lua_State *ls)
+{
+ int x = luaL_checkint(ls, 1);
+ int y = luaL_checkint(ls, 2);
+ dungeon_feature_type feat = check_lua_feature(ls, 3);
+
+ lua_pushnumber(ls, count_neighbours(x, y, feat));
+ return 1;
+}
+
+static int dgn_join_the_dots(lua_State *ls)
+{
+ int from_x = luaL_checkint(ls, 1);
+ int from_y = luaL_checkint(ls, 2);
+ int to_x = luaL_checkint(ls, 3);
+ int to_y = luaL_checkint(ls, 4);
+ // TODO enne - push map masks to lua?
+ unsigned map_mask = MMT_VAULT;
+ bool early_exit = lua_toboolean(ls, 5);
+
+ coord_def from(from_x, from_y);
+ coord_def to(to_x, to_y);
+
+ bool ret = join_the_dots(from, to, map_mask, early_exit);
+ lua_pushboolean(ls, ret);
+
+ return 1;
+}
+
+static int dgn_fill_disconnected_zones(lua_State *ls)
+{
+ int from_x = luaL_checkint(ls, 1);
+ int from_y = luaL_checkint(ls, 2);
+ int to_x = luaL_checkint(ls, 3);
+ int to_y = luaL_checkint(ls, 4);
+
+ dungeon_feature_type feat = check_lua_feature(ls, 5);
+
+ process_disconnected_zones(from_x, from_y, to_x, to_y, true, feat);
+
+ return 0;
+}
+
+const struct luaL_reg dgn_build_lib[] =
+{
+{ "grd_table", dgn_grd_table },
+{ "width", dgn_width },
+{ "height", dgn_height },
+{ "fill_area", dgn_fill_area },
+{ "replace_area", dgn_replace_area },
+{ "octa_room", dgn_octa_room },
+{ "make_pillars", dgn_make_pillars },
+{ "make_square", dgn_make_square },
+{ "make_rounded_square", dgn_make_rounded_square },
+{ "make_circle", dgn_make_circle },
+{ "in_bounds", dgn_in_bounds },
+{ "replace_first", dgn_replace_first },
+{ "replace_random", dgn_replace_random },
+{ "spotty_level", dgn_spotty_level },
+{ "smear_feature", dgn_smear_feature },
+{ "count_feature_in_box", dgn_count_feature_in_box },
+{ "count_antifeature_in_box", dgn_count_antifeature_in_box },
+{ "count_neighbours", dgn_count_neighbours },
+{ "join_the_dots", dgn_join_the_dots },
+{ "fill_disconnected_zones", dgn_fill_disconnected_zones },
+
+{ NULL, NULL }
+};
diff --git a/crawl-ref/source/l_libs.h b/crawl-ref/source/l_libs.h
index fa5f0561d0..030c5fd056 100644
--- a/crawl-ref/source/l_libs.h
+++ b/crawl-ref/source/l_libs.h
@@ -14,6 +14,7 @@
extern const struct luaL_reg crawl_lib[];
extern const struct luaL_reg dgn_lib[];
+extern const struct luaL_reg dgn_build_lib[];
extern const struct luaL_reg dgn_event_lib[];
extern const struct luaL_reg dgn_item_lib[];
extern const struct luaL_reg dgn_level_lib[];
@@ -76,5 +77,6 @@ int dgn_map_add_transform(lua_State *ls,
std::string (map_lines::*add)(const std::string &s));
unsigned int get_tile_idx(lua_State *ls, int arg);
level_id dlua_level_id(lua_State *ls, int ndx);
+dungeon_feature_type check_lua_feature(lua_State *ls, int idx);
#endif
diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj
index 242a5370c4..ed01986860 100644
--- a/crawl-ref/source/makefile.obj
+++ b/crawl-ref/source/makefile.obj
@@ -40,6 +40,7 @@ lev-pand.o \
libutil.o \
l_crawl.o \
l_dgn.o \
+l_dgnbld.o \
l_dgnevt.o \
l_dgnit.o \
l_dgnlvl.o \