git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5176 c06c8d41-db1a-0410-9941-cceddc491573
PRG7UT7G56GT4W3FQ3KG5JRPGMKKJBFDLVHDLYFQK6IZW25JQLBQC QTAXF435XPFZWNFZHMUKPQ7UVNLUK6TG5ER4MKDY25BZF5PZ4JLAC NVSFIV2ZKP44XHCSCXG6OZVGL67OIFINC34J2EMKTA4KULCERUEAC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC ZLQAAP55CJ77XIJN3DZVPT4GTTVLIBFJLIJJKI6L5UBSHX7VUK6AC 7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC ED62QWGKBPORWVKDFOQRKJXEIWZVNGR3O4KWQBDSRNPT36AYOQYAC TLA5UN6LZPXGKERI27EFY4HKIIU3VU5Y7ZU54WXL6ANBUV2VOTMQC W45PMU4HNPSAMMEBJ4XH4MTHLPVIASZT4FXTBPID5LFXKIMNUBKAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC KCHX2F3JFEWOZT3WMJVZAAQUU2QSZ5Q7RDCD7WUJ7VE65J52JFUQC 77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC B7MSPF6X2RLGWN4M6ZZF3WSOPKGYPTTD7LIJVST7DXN27DG6JHNAC TZ55IZNANEJO2WDTKYWVLY2W2VV6BR7WKIN7XLNISAMMFT6LG2WQC BTO5WE4OEK64DZQVNYLOESM74KKQNE7KSNMQVF5UDB26OBKP7ORQC 3XZOL3FFQZITUJIGDD6B6V6ZYMBN524JKNN6ZPJAXEC7RY433I3QC MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC 4WOHWWHMQPU22PK6TN5KIFCB4G22NDF5OQ3ZEYDK4Z5U7XCB5IWQC FSD7GIK3YLZXWLEH37BU6KV3IUCFGXPQL6IZ7H65YWNRBEKDBX5AC FZAQNANLZOQHX675KR5GE2ZAVNT4AWX4TWEUJXXEZMOXWQ5FDHOAC 2C6B6QRTOK2ZMK2ZOF3EPSFUZTKG5B3IZXWBWIUYC4ZOVGQ2OV2QC QIDA6PWWBPR6IJOXFCSPCGWV45PVRZ4TPWSL2TDATNVTYLDMVESQC B3SRWSFITQMJRVEBHGQQJARETYPSSDV6XKMQSSUTXEHTXRZKIQJQC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC }static dungeon_feature_type _get_lua_feature(lua_State *ls, int idx){dungeon_feature_type feat = (dungeon_feature_type)0;if (lua_isnumber(ls, idx))feat = (dungeon_feature_type)luaL_checkint(ls, idx);else if (lua_isstring(ls, idx))feat = dungeon_feature_by_name(luaL_checkstring(ls, idx));elseluaL_argerror(ls, idx, "Feature must be a string or a feature index.");return feat;}static void _clamp_to_bounds(int &x, int &y){x = std::min(std::max(x, X_BOUND_1+1), X_BOUND_2-1);y = std::min(std::max(y, Y_BOUND_1+1), Y_BOUND_2-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 = _get_lua_feature(ls, 5);if (!feat){luaL_argerror(ls, 5, "Invalid feature.");return 0;}_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 = _get_lua_feature(ls, 5);if (!search){luaL_argerror(ls, 5, "Invalid feature.");return 0;}dungeon_feature_type replace = _get_lua_feature(ls, 6);if (!replace){luaL_argerror(ls, 6, "Invalid feature.");return 0;}// 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 = _get_lua_feature(ls, 6);if (!fill){luaL_argerror(ls, 6, "Invalid feature.");return 0;}spec_room sr;sr.x1 = x1;sr.x2 = x2;sr.y1 = y1;sr.y2 = 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 = _get_lua_feature(ls, 8);if (!fill){luaL_argerror(ls, 8, "Invalid feature.");return 0;}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 = _get_lua_feature(ls, 4);if (!fill){luaL_argerror(ls, 4, "Invalid feature.");return 0;}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 = _get_lua_feature(ls, 4);if (!fill){luaL_argerror(ls, 4, "Invalid feature.");return 0;}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 = _get_lua_feature(ls, 4);if (!fill){luaL_argerror(ls, 4, "Invalid feature.");return 0;}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 = _get_lua_feature(ls, 5);if (!search){luaL_argerror(ls, 5, "Invalid feature.");lua_pushboolean(ls, false);return 1;}dungeon_feature_type replace = _get_lua_feature(ls, 6);if (!replace){luaL_argerror(ls, 6, "Invalid feature.");lua_pushboolean(ls, false);return 1;}_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 = _get_lua_feature(ls, 1);if (!search){luaL_argerror(ls, 1, "Invalid feature.");return 0;}dungeon_feature_type replace = _get_lua_feature(ls, 2);if (!replace){luaL_argerror(ls, 2, "Invalid feature.");return 0;}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 = _get_lua_feature(ls, 3);if (!feat){luaL_argerror(ls, 3, "Invalid feature.");return 0;}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);_clamp_to_bounds(x2, y2);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 = _get_lua_feature(ls, 5);if (!feat){luaL_argerror(ls, 5, "Invalid feature.");lua_pushnil(ls);return 1;}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 = _get_lua_feature(ls, 5);if (!feat){luaL_argerror(ls, 5, "Invalid feature.");lua_pushnil(ls);return 1;}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 = _get_lua_feature(ls, 3);if (!feat){luaL_argerror(ls, 3, "Invalid feature.");lua_pushnil(ls);return 1;}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;
{ "change_level_flags", dgn_change_level_flags},{ "change_branch_flags", dgn_change_branch_flags},{ "get_floor_colour", dgn_get_floor_colour},{ "get_rock_colour", dgn_get_rock_colour},{ "change_floor_colour", dgn_change_floor_colour},{ "change_rock_colour", dgn_change_rock_colour},{ "set_lt_callback", lua_dgn_set_lt_callback},{ "fixup_stairs", dgn_fixup_stairs},{ "floor_halo", dgn_floor_halo},{ "random_walk", dgn_random_walk},{ "apply_area_cloud", dgn_apply_area_cloud},
{ "change_level_flags", dgn_change_level_flags },{ "change_branch_flags", dgn_change_branch_flags },{ "get_floor_colour", dgn_get_floor_colour },{ "get_rock_colour", dgn_get_rock_colour },{ "change_floor_colour", dgn_change_floor_colour },{ "change_rock_colour", dgn_change_rock_colour },{ "set_lt_callback", lua_dgn_set_lt_callback },{ "fixup_stairs", dgn_fixup_stairs },{ "floor_halo", dgn_floor_halo },{ "random_walk", dgn_random_walk },{ "apply_area_cloud", dgn_apply_area_cloud },// building routines{ "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 },
struct spec_room{bool created;bool hooked_up;int x1;int y1;int x2;int y2;spec_room() : created(false), hooked_up(false), x1(0), y1(0), x2(0), y2(0){}};bool join_the_dots(const coord_def &from, const coord_def &to,unsigned mmask, bool early_exit = false);void spotty_level(bool seeded, int iterations, bool boxy);void smear_feature(int iterations, bool boxy, dungeon_feature_type feature,int x1, int y1, int x2, int y2);bool octa_room(spec_room &sr, int oblique_max,dungeon_feature_type type_floor);int count_feature_in_box(int x0, int y0, int x1, int y1,dungeon_feature_type feat);int count_antifeature_in_box(int x0, int y0, int x1, int y1,dungeon_feature_type feat);int count_neighbours(int x, int y, dungeon_feature_type feat);
};struct spec_room{bool created;bool hooked_up;int x1;int y1;int x2;int y2;spec_room() : created(false), hooked_up(false), x1(0), y1(0), x2(0), y2(0){}
_count_feature_in_box(px-2, py-2, px+3, py+3, DNGN_ROCK_WALL) +_count_feature_in_box(px-2, py-2, px+3, py+3, DNGN_CLOSED_DOOR) +_count_feature_in_box(px-2, py-2, px+3, py+3, DNGN_SECRET_DOOR) +_count_feature_in_box(px-2, py-2, px+3, py+3, DNGN_FLOOR);
count_feature_in_box(px-2, py-2, px+3, py+3, DNGN_ROCK_WALL) +count_feature_in_box(px-2, py-2, px+3, py+3, DNGN_CLOSED_DOOR) +count_feature_in_box(px-2, py-2, px+3, py+3, DNGN_SECRET_DOOR) +count_feature_in_box(px-2, py-2, px+3, py+3, DNGN_FLOOR);
void smear_feature(int iterations, bool boxy, dungeon_feature_type feature,int x1, int y1, int x2, int y2){for (int i = 0; i < iterations; i++){int x, y;bool diagonals, straights;do{x = random_range(x1+1, x2-1);y = random_range(y1+1, y2-1);diagonals = grd[x+1][y+1] == feature ||grd[x-1][y+1] == feature ||grd[x-1][y-1] == feature ||grd[x+1][y-1] == feature;straights = grd[x+1][y] == feature ||grd[x-1][y] == feature ||grd[x][y+1] == feature ||grd[x][y-1] == feature;}while (grd[x][y] == feature || !straights && (boxy || !diagonals));
lua {{-- TODO enne - most of these should probably get moved back into C++function fill_area(x1, y1, x2, y2, feature)for x = x1, x2 dofor y = y1, y2 dodgn.grid(x, y, feature)endendendfunction octa_room(x1, y1, x2, y2, oblique, fill)local ob_temp = obliquelocal rock_wall = dgn.feature_number("rock_wall")local shallow_water = dgn.feature_number("shallow_water")local deep_water = dgn.feature_number("deep_water")local floor = dgn.feature_number("floor")for x = x1, x2 dofor y = y1 + ob_temp, y2 - ob_temp doif dgn.grid(x, y) == rock_wall thendgn.grid(x, y, fill)endif dgn.grid(x, y) == floor and (fill == shallow_water or fill == deep_water) thendgn.grid(x, y, shallow_water)endendif x > x2 - oblique thenob_temp = ob_temp + 1elseif ob_temp > 0 thenob_temp = ob_temp - 1endendendfunction pillars(center_x, center_y, num, flip_x, big_radius,pillar_radius, pillar_routine, fill)for i = 0, num - 1 dolocal angle = i * 2 * math.pi / numlocal x = math.floor(math.cos(angle) * big_radius * flip_x + 0.5)local y = math.floor(math.sin(angle) * big_radius + 0.5)
pillar_routine(center_x + x, center_y + y, pillar_radius, fill)endend-- begin pillar functionsfunction pillar_square(center_x, center_y, radius, fill)for x = -radius, radius dofor y = -radius, radius dodgn.grid(center_x + x, center_y + y, fill)endendendfunction pillar_rounded_square(center_x, center_y, radius, fill)for x = -radius, radius dofor y = -radius, radius doif math.abs(x) ~= radius or math.abs(y) ~= radius thendgn.grid(center_x + x, center_y + y, fill)endendendendfunction pillar_circle(center_x, center_y, radius, fill)for x = -radius, radius dofor y = -radius, radius doif x * x + y * y < radius * radius thendgn.grid(center_x + x, center_y + y, fill)endendendend-- end pillar functionsfunction select_from_weighted_table(tb)local value = nillocal rollsize = 0for temp_val, temp_weight in pairs (tb) doif rollsize == 0 thenvalue = temp_valrollsize = temp_weightelserollsize = rollsize + temp_weightif crawl.random2(rollsize) < temp_weight thenvalue = temp_valendendendreturn valueend-- Randomly selects a grid with feature 'search' and sets it to 'replace'function replace_random(search, replace)local gxm, gym = dgn.max_bounds()local feature = nil, x, ywhile feature ~= search dox = crawl.random2(gxm)y = crawl.random2(gym)feature = dgn.grid(x, y)enddgn.grid(x, y, replace)endfunction valid(x, y)local gxm, gym = dgn.max_bounds()return (x >= 0 and y >= 0 and x < gxm and y < gym)end-- Walks from x, y along dx,dy until it finds 'search'function replace_first(x, y, dx, dy, search, replace)local feature = dgn.grid(x, y)while feature ~= search and valid(x,y) dox = x + dxy = y + dyfeature = dgn.grid(x, y)endif valid(x, y) thendgn.grid(x, y, replace)return trueelsereturn falseendendfunction spotty_level(boxy, x1, y1, x2, y2)local iterations-- boxy levels have more clearing, so they get fewer iterationsif boxy theniterations = 200 + crawl.random2(750)elseiterations = 200 + crawl.random2(1500)endmake_spotty(iterations, boxy, x1, y1, x2, y2)end-- randomly turns walls into floorsfunction make_spotty(iterations, boxy, x1, y1, x2, y2)if x2 - x1 - 8 <= 0 or y2 - y1 - 8 <= 0 thenreturnendlocal wall = dgn.feature_number("rock_wall")local floor = dgn.feature_number("floor")for i = 1, iterations dolocal x, yrepeatx = crawl.random2(x2 - x1 - 7) + x1 + 4y = crawl.random2(y2 - y1 - 7) + y1 + 4until dgn.grid(x, y) ~= wall ordgn.grid(x-1, y) ~= wall ordgn.grid(x+1, y) ~= wall ordgn.grid(x, y-1) ~= wall ordgn.grid(x, y+1) ~= wall ordgn.grid(x-2, y) ~= wall ordgn.grid(x+2, y) ~= wall ordgn.grid(x, y-2) ~= wall ordgn.grid(x, y+2) ~= wall-- convenience functionfunction replace_grid(x, y, search, replace)if dgn.grid(x, y) == search thendgn.grid(x, y, replace)endendreplace_grid(x, y, wall, floor)replace_grid(x, y-1, wall, floor)replace_grid(x, y+1, wall, floor)replace_grid(x-1, y, wall, floor)replace_grid(x+1, y, wall, floor)if boxy thenreplace_grid(x-1, y-1, wall, floor)replace_grid(x+1, y+1, wall, floor)replace_grid(x-1, y+1, wall, floor)replace_grid(x+1, y-1, wall, floor)endendend-- randomly extends walls onto floorsfunction smear_feature(iterations, boxy, feature, x1, y1, x2, y2)for i = 1, iterations dolocal x, yfunction check_box(x, y, feature)return dgn.grid(x+1, y) == feature ordgn.grid(x-1, y) == feature ordgn.grid(x, y+1) == feature ordgn.grid(x, y-1) == featureendfunction check_diagonal(x, y, feature)return dgn.grid(x+1, y+1) == feature ordgn.grid(x-1, y+1) == feature ordgn.grid(x-1, y-1) == feature ordgn.grid(x+1, y-1) == featureendrepeatx = crawl.random2(x2 - x1 - 2) + x1 + 1y = crawl.random2(y2 - y1 - 2) + y1 + 1until dgn.grid(x, y) ~= feature and(check_box(x, y, feature) ornot boxy and check_diagonal(x, y, feature))dgn.grid(x, y, feature)endend}}
fill_area(10, 10, gxm - 10, 10 + width, floor)fill_area(10, 60 - width, gxm - 10, gym - 10, floor)fill_area(10, 10, 10 + width, gym - 10, floor)fill_area(60 - width, 10, gxm - 10, gym - 10, floor)
dgn.fill_area(10, 10, gxm - 10, 10 + width, floor)dgn.fill_area(10, 60 - width, gxm - 10, gym - 10, floor)dgn.fill_area(10, 10, 10 + width, gym - 10, floor)dgn.fill_area(60 - width, 10, gxm - 10, gym - 10, floor)
fill_area(10, gym/2 - width2, gxm - 10, gym/2 + width2, floor)fill_area(gxm/2 - width2, 10, gxm/2 + width2, gym - 10, floor)
dgn.fill_area(10, gym/2 - width2, gxm - 10, gym/2 + width2, floor)dgn.fill_area(gxm/2 - width2, 10, gxm/2 + width2, gym - 10, floor)
fill_area(10, gym/2 - height - 1, gxm - 10, gym/2 - height - 1, clear)fill_area(10, gym/2 + height + 1, gxm - 10, gym/2 + height + 1, clear)fill_area(gxm/2 - width - 1, 10, gxm/2 - width - 1, gym - 10, clear)fill_area(gxm/2 + width + 1, 10, gxm/2 + width + 1, gym - 10, clear)
dgn.fill_area(10, gym/2 - height - 1, gxm - 10, gym/2 - height - 1, clear)dgn.fill_area(10, gym/2 + height + 1, gxm - 10, gym/2 + height + 1, clear)dgn.fill_area(gxm/2 - width - 1, 10, gxm/2 - width - 1, gym - 10, clear)dgn.fill_area(gxm/2 + width + 1, 10, gxm/2 + width + 1, gym - 10, clear)
fill_area(10, gym/2 - height, gxm - 10, gym/2 + height, floor)fill_area(gxm/2 - width, 10, gxm/2 + width, gym - 10, floor)
dgn.fill_area(10, gym/2 - height, gxm - 10, gym/2 + height, floor)dgn.fill_area(gxm/2 - width, 10, gxm/2 + width, gym - 10, floor)
// Only the first arg does anything now. Maybe this should// select from a variable number of table args?lua_pop(ls, lua_gettop(ls) - 1);// Keep max value on the stack, as it could be any type of value.lua_pushnil(ls);int rollsize = 0;lua_pushnil(ls);while (lua_next(ls, table_idx) != 0){const int weight_idx = -1;const int key_idx = -2;int this_weight = lua_isnil(ls, weight_idx) ?1 : (int)lua_tonumber(ls, weight_idx);if (rollsize > 0){rollsize += this_weight;if (random2(rollsize) < this_weight){lua_pushvalue(ls, key_idx);lua_replace(ls, value_idx);}}else{lua_pushvalue(ls, key_idx);lua_replace(ls, value_idx);rollsize = this_weight;}lua_pop(ls, 1);}lua_pushvalue(ls, value_idx);return 1;}