diff options
author | ennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-05-22 13:18:50 +0000 |
---|---|---|
committer | ennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-05-22 13:18:50 +0000 |
commit | 9a1e7565ec8802a38a9649744920923fc262dff7 (patch) | |
tree | 700f62fb01028913c0d99ab99645a004d4f42fa7 /crawl-ref/source/luadgn.cc | |
parent | 0d4f7611a414a3f92ade376733eb51bda0328000 (diff) | |
download | crawl-ref-9a1e7565ec8802a38a9649744920923fc262dff7.tar.gz crawl-ref-9a1e7565ec8802a38a9649744920923fc262dff7.zip |
Pushing some dungeon-related lua functions back into C++.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5176 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/luadgn.cc')
-rw-r--r-- | crawl-ref/source/luadgn.cc | 424 |
1 files changed, 412 insertions, 12 deletions
diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc index f99ea111d5..32dbbfb9d3 100644 --- a/crawl-ref/source/luadgn.cc +++ b/crawl-ref/source/luadgn.cc @@ -10,6 +10,7 @@ #include <sstream> #include <algorithm> +#include <cmath> #include "branch.h" #include "clua.h" @@ -1668,6 +1669,387 @@ static int dgn_apply_area_cloud(lua_State *ls) return (0); } +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)); + else + luaL_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; +} + static const struct luaL_reg dgn_lib[] = { { "default_depth", dgn_default_depth }, @@ -1716,22 +2098,40 @@ static const struct luaL_reg dgn_lib[] = { "register_listener", dgn_register_listener }, { "remove_listener", dgn_remove_listener }, { "remove_marker", dgn_remove_marker }, - { "num_matching_markers", dgn_num_matching_markers}, + { "num_matching_markers", dgn_num_matching_markers }, { "feature_desc", dgn_feature_desc }, { "feature_desc_at", dgn_feature_desc_at }, { "item_from_index", dgn_item_from_index }, { "mons_from_index", dgn_mons_from_index }, - { "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 }, { NULL, NULL } }; |