diff options
Diffstat (limited to 'crawl-ref/source/luadgn.cc')
-rw-r--r-- | crawl-ref/source/luadgn.cc | 200 |
1 files changed, 149 insertions, 51 deletions
diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc index 229fc9946d..60834c3c64 100644 --- a/crawl-ref/source/luadgn.cc +++ b/crawl-ref/source/luadgn.cc @@ -26,6 +26,7 @@ #include "mapmark.h" #include "maps.h" #include "misc.h" +#include "mon-util.h" #include "spl-util.h" #include "stuff.h" #include "tags.h" @@ -315,6 +316,8 @@ std::string dlua_chunk::get_chunk_prefix(const std::string &sorig) const #define MAPMARKER(ls, n, var) \ map_marker *var = *(map_marker **) luaL_checkudata(ls, n, MAPMARK_METATABLE) +#define LUAFN(name) static int name(lua_State *ls) + static dungeon_feature_type _get_lua_feature(lua_State *ls, int idx) { dungeon_feature_type feat = (dungeon_feature_type)0; @@ -336,15 +339,19 @@ static dungeon_feature_type _check_lua_feature(lua_State *ls, int idx) return (f); } -#define COORDS(c, p1, p2) \ +#define GETCOORD(c, p1, p2, boundfn) \ coord_def c; \ c.x = luaL_checkint(ls, p1); \ c.y = luaL_checkint(ls, p2); \ - if (!in_bounds(c)) \ - luaL_error( \ + if (!boundfn(c)) \ + luaL_error( \ ls, \ - make_stringf("Point (%d,%d) is out of map bounds", \ - c.x, c.y).c_str()); + make_stringf("Point (%d,%d) is out of bounds", \ + c.x, c.y).c_str()); \ + else ; \ + +#define COORDS(c, p1, p2) \ + GETCOORD(c, p1, p2, in_bounds) #define FEAT(f, pos) \ dungeon_feature_type f = _check_lua_feature(ls, pos) @@ -908,7 +915,7 @@ static int dgn_welcome(lua_State *ls) static int dgn_grid(lua_State *ls) { - COORDS(c, 1, 2); + GETCOORD(c, 1, 2, map_bounds); if (!lua_isnone(ls, 3)) { @@ -1094,70 +1101,53 @@ static int dgn_get_rock_colour(lua_State *ls) PLUARET(string, colour_to_str(env.rock_colour).c_str()); } -static int dgn_change_floor_colour(lua_State *ls) +static int _lua_colour(lua_State *ls, int ndx, + int forbidden_colour = -1) { - const char *s = luaL_checkstring(ls, 1); - int colour = str_to_colour(s); - - if (colour < 0 || colour == BLACK) + if (lua_isnumber(ls, ndx)) + return lua_tonumber(ls, ndx); + else if (const char *s = luaL_checkstring(ls, ndx)) { - std::string error; + const int colour = str_to_colour(s); - if (colour == BLACK) - { - error = "Can't set floor to black."; - } - else + if (colour < 0 || colour == forbidden_colour) { - error = "No such colour as '"; - error += s; - error += "'"; + std::string error; + if (colour == forbidden_colour) + error = std::string("Can't set floor to ") + s; + else + error = std::string("Unknown colour: '") + s + "'"; + return luaL_argerror(ls, 1, error.c_str()); } - - luaL_argerror(ls, 1, error.c_str()); - - return (0); + return (colour); } + return luaL_argerror(ls, ndx, "Expected colour name or number"); +} +static int dgn_change_floor_colour(lua_State *ls) +{ + const int colour = _lua_colour(ls, 1, BLACK); env.floor_colour = (unsigned char) colour; - viewwindow(true, false); - return (0); } static int dgn_change_rock_colour(lua_State *ls) { - const char *s = luaL_checkstring(ls, 1); - int colour = str_to_colour(s); - - if (colour < 0 || colour == BLACK) - { - std::string error; - - if (colour == BLACK) - { - error = "Can't set rock to black."; - } - else - { - error = "No such colour as '"; - error += s; - error += "'"; - } - - luaL_argerror(ls, 1, error.c_str()); - - return (0); - } - + const int colour = _lua_colour(ls, 1, BLACK); env.rock_colour = (unsigned char) colour; - viewwindow(true, false); - return (0); } +static int dgn_colour_at(lua_State *ls) +{ + COORDS(c, 1, 2); + if (!lua_isnone(ls, 3)) + env.grid_colours(c) = _lua_colour(ls, 3); + PLUARET(string, colour_to_str(env.grid_colours(c)).c_str()); +} + const char *dngn_feature_names[] = { "unseen", "closed_door", "secret_door", "wax_wall", "metal_wall", @@ -1437,6 +1427,25 @@ static int dgn_mons_from_index(lua_State *ls) return (1); } +static int dgn_mons_at(lua_State *ls) +{ + COORDS(c, 1, 2); + + monsters *mon = monster_at(c); + if (mon && mon->alive()) + push_monster(ls, mon); + else + lua_pushnil(ls); + return (1); +} + +static int dgn_items_at(lua_State *ls) +{ + COORDS(c, 1, 2); + lua_push_items(ls, env.igrid(c)); + return (1); +} + static int lua_dgn_set_lt_callback(lua_State *ls) { const char *level_type = luaL_checkstring(ls, 1); @@ -2054,6 +2063,13 @@ static int dgn_fill_disconnected_zones(lua_State *ls) return 0; } +static int _dgn_is_passable(lua_State *ls) +{ + COORDS(c, 1, 2); + lua_pushboolean(ls, is_travelsafe_square(c.x, c.y, false, true)); + return (1); +} + static int dgn_register_feature_marker(lua_State *ls) { COORDS(c, 1, 2); @@ -2075,6 +2091,74 @@ static int dgn_register_lua_marker(lua_State *ls) return (0); } +static int dgn_create_monster(lua_State *ls) +{ + COORDS(c, 1, 2); + + if (const char *spec = lua_tostring(ls, 3)) + { + mons_list mlist; + const std::string err = mlist.add_mons(spec); + if (!err.empty()) + luaL_error(ls, err.c_str()); + + for (int i = 0, size = mlist.size(); i < size; ++i) + { + mons_spec mspec = mlist.get_monster(i); + if (dgn_place_monster(mspec, you.your_level, c, + false, false, false)) + { + push_monster(ls, &menv[mgrd(c)]); + return (1); + } + } + } + lua_pushnil(ls); + return (1); +} + +static int dgn_create_item(lua_State *ls) +{ + COORDS(c, 1, 2); + + if (const char *spec = lua_tostring(ls, 3)) + { + item_list ilist; + const std::string err = ilist.add_item(spec); + if (!err.empty()) + luaL_error(ls, err.c_str()); + + const int level = + lua_isnumber(ls, 4) ? lua_tointeger(ls, 4) : you.your_level; + + dgn_place_multiple_items(ilist, c, level); + link_items(); + } + return (0); +} + + +#define BRANCH(br, pos) \ + const char *branch_name = luaL_checkstring(ls, pos); \ + branch_type req_branch_type = str_to_branch(branch_name); \ + if (req_branch_type == NUM_BRANCHES) \ + luaL_error(ls, "Expected branch name"); \ + Branch &br = branches[req_branch_type] + +#define BRANCHFN(name, type, expr) \ + LUAFN(dgn_br_##name) { \ + BRANCH(br, 1); \ + PLUARET(type, expr); \ + } + +BRANCHFN(floorcol, number, br.floor_colour) +BRANCHFN(rockcol, number, br.rock_colour) +BRANCHFN(has_shops, boolean, br.has_shops) +BRANCHFN(has_uniques, boolean, br.has_uniques) +BRANCHFN(parent_branch, string, + br.parent_branch == NUM_BRANCHES ? "" + : branches[br.parent_branch].abbrevname) + static int dgn_debug_dump_map(lua_State *ls) { const int pos = lua_isuserdata(ls, 1) ? 2 : 1; @@ -2118,6 +2202,7 @@ static const struct luaL_reg dgn_lib[] = { "grid", dgn_grid }, { "max_bounds", dgn_max_bounds }, + { "colour_at", dgn_colour_at }, { "terrain_changed", dgn_terrain_changed }, { "points_connected", dgn_points_connected }, @@ -2138,6 +2223,8 @@ static const struct luaL_reg dgn_lib[] = { "feature_desc_at", dgn_feature_desc_at }, { "item_from_index", dgn_item_from_index }, { "mons_from_index", dgn_mons_from_index }, + { "mons_at", dgn_mons_at }, + { "items_at", dgn_items_at }, { "change_level_flags", dgn_change_level_flags }, { "change_branch_flags", dgn_change_branch_flags }, { "get_floor_colour", dgn_get_floor_colour }, @@ -2169,9 +2256,20 @@ static const struct luaL_reg dgn_lib[] = { "join_the_dots", dgn_join_the_dots }, { "fill_disconnected_zones", dgn_fill_disconnected_zones }, + { "is_passable", _dgn_is_passable }, + { "register_feature_marker", dgn_register_feature_marker }, { "register_lua_marker", dgn_register_lua_marker }, + { "create_monster", dgn_create_monster }, + { "create_item", dgn_create_item }, + + { "br_floorcol", dgn_br_floorcol }, + { "br_rockcol", dgn_br_rockcol }, + { "br_has_shops", dgn_br_has_shops }, + { "br_has_uniques", dgn_br_has_uniques }, + { "br_parent_branch", dgn_br_parent_branch }, + { "debug_dump_map", dgn_debug_dump_map }, { NULL, NULL } |