From: Pasi Kallinen Date: Fri, 6 Mar 2020 18:17:23 +0000 (+0200) Subject: lua special level feature flags X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2fc9c02f88e2c700bd06f41f5ca972f884a1f3e4;p=nethack lua special level feature flags Allow des.feature() to set rm flags for the special features. --- diff --git a/doc/lua.adoc b/doc/lua.adoc index 1d9007ab9..0677a9211 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -232,7 +232,10 @@ Example: === feature -Create a fountain, a sink, or a pool. +Create a feature, and set flags for it. +Valid features are a fountain, a sink, a pool, a throne, or a tree. +Throne has `looted` flag, tree has `looted` and `swarm`, fountain has `looted` and `warned`, +sink has `pudding`, `dishwasher`, and `ring`. Example: @@ -240,6 +243,8 @@ Example: des.feature("fountain", {4, 5}); des.feature({ type = "fountain", x = 12, y = 6 }); des.feature({ type = "fountain", coord = {4, 6} }); + des.feature({ type = "throne", coord = {4, 6}, looted = true }); + des.feature({ type = "tree", coord = {4, 6}, looted = true, swarm = false }); === gold diff --git a/src/sp_lev.c b/src/sp_lev.c index 9c4ba3e96..2c282caf7 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -89,6 +89,7 @@ static void FDECL(sel_set_wallify, (int, int, genericptr_t)); static void NDECL(spo_end_moninvent); static void NDECL(spo_pop_container); static void FDECL(spo_endroom, (struct sp_coder *)); +static void FDECL(l_table_getset_feature_flag, (lua_State *, int, int, const char *, int)); static void FDECL(sel_set_ter, (int, int, genericptr_t)); static void FDECL(sel_set_door, (int, int, genericptr_t)); static void FDECL(sel_set_feature, (int, int, genericptr_t)); @@ -4883,19 +4884,41 @@ lua_State *L; return 0; } +static void +l_table_getset_feature_flag(L, x,y, name, flag) +lua_State *L; +int x, y; +const char *name; +int flag; +{ + int val = get_table_boolean_opt(L, name, -2); + + if (val != -2) { + if (val == -1) val = rn2(2); + if (val) + levl[x][y].flags |= flag; + else + levl[x][y].flags &= ~flag; + } +} + /* feature("fountain", x, y); */ /* feature("fountain", {x,y}); */ /* feature({ type="fountain", x=NN, y=NN }); */ /* feature({ type="fountain", coord={NN, NN} }); */ +/* feature({ type="tree", coord={NN, NN}, swarm=true, looted=false }); */ int lspo_feature(L) lua_State *L; { - static const char *const features[] = { "fountain", "sink", "pool", NULL }; - static const int features2i[] = { FOUNTAIN, SINK, POOL, STONE }; + static const char *const features[] = { "fountain", "sink", "pool", + "throne", "tree", NULL }; + static const int features2i[] = { FOUNTAIN, SINK, POOL, + THRONE, TREE, STONE }; schar x,y; int typ; int argc = lua_gettop(L); + boolean can_have_flags = FALSE; create_des_coder(); @@ -4917,27 +4940,39 @@ lua_State *L; get_table_xy_or_coord(L, &fx, &fy); x = fx, y = fy; typ = features2i[get_table_option(L, "type", NULL, features)]; + can_have_flags = TRUE; } get_location_coord(&x, &y, ANY_LOC, g.coder->croom, SP_COORD_PACK(x,y)); + if (typ == STONE) + impossible("feature has unknown type param."); + else + sel_set_feature(x, y, (genericptr_t) &typ); + + if (levl[x][y].typ != typ || !can_have_flags) + return 0; + switch (typ) { default: break; case FOUNTAIN: - typ = FOUNTAIN; + l_table_getset_feature_flag(L, x, y, "looted", F_LOOTED); + l_table_getset_feature_flag(L, x, y, "warned", F_WARNED); break; case SINK: - typ = SINK; + l_table_getset_feature_flag(L, x, y, "pudding", S_LPUDDING); + l_table_getset_feature_flag(L, x, y, "dishwasher", S_LDWASHER); + l_table_getset_feature_flag(L, x, y, "ring", S_LRING); break; - case POOL: - typ = POOL; + case THRONE: + l_table_getset_feature_flag(L, x, y, "looted", T_LOOTED); + break; + case TREE: + l_table_getset_feature_flag(L, x, y, "looted", TREE_LOOTED); + l_table_getset_feature_flag(L, x, y, "swarm", TREE_SWARM); break; } - if (typ == STONE) - impossible("feature has unknown type param."); - else - sel_set_feature(x, y, (genericptr_t) &typ); return 0; } diff --git a/test/test_des.lua b/test/test_des.lua index 5159c5e0a..4c549c965 100644 --- a/test/test_des.lua +++ b/test/test_des.lua @@ -21,6 +21,13 @@ function check_loc_name(x, y, name) end end +function check_loc_flag(x, y, flag, value) + local loc = nh.getmap(x, y); + if (loc.flags[flag] ~= value) then + error(loc.typ_name .. " at (" .. x .. "," .. y .. ") flag " .. flag .. " is " .. tostring(loc.flags[flag]) .. ", not " .. tostring(value)); + end +end + function check_trap_at(x,y, name) local t = nh.gettrap(x + 1, y); -- + 1 == g.xstart if (t.ttyp_name ~= name) then @@ -226,6 +233,8 @@ III]] }) end function test_feature() + des.reset_level(); + des.level_init({ style = "solidfill", fg = ".", lit = 1 }); des.feature("fountain", 40, 08); check_loc_name(40 + 1, 08, "fountain"); des.feature("sink", {41, 08}); @@ -234,6 +243,35 @@ function test_feature() check_loc_name(42 + 1, 08, "pool"); des.feature({ type = "sink", coord = {43, 08} }); check_loc_name(43 + 1, 08, "sink"); + + des.feature({ type = "throne", coord = {44, 08}, looted=true }); + check_loc_name(44 + 1, 08, "throne"); + check_loc_flag(44 + 1, 08, "looted", true); + + des.feature({ type = "throne", coord = {44, 08}, looted=false }); + check_loc_name(44 + 1, 08, "throne"); + check_loc_flag(44 + 1, 08, "looted", false); + + des.feature({ type = "tree", coord = {45, 08}, looted=true, swarm=false }); + check_loc_name(45 + 1, 08, "tree"); + check_loc_flag(45 + 1, 08, "looted", true); + check_loc_flag(45 + 1, 08, "swarm", false); + + des.feature({ type = "tree", coord = {45, 08}, looted=false, swarm=true }); + check_loc_name(45 + 1, 08, "tree"); + check_loc_flag(45 + 1, 08, "looted", false); + check_loc_flag(45 + 1, 08, "swarm", true); + + des.feature({ type = "fountain", coord = {46, 08}, looted=false, warned=true }); + check_loc_name(46 + 1, 08, "fountain"); + check_loc_flag(46 + 1, 08, "looted", false); + check_loc_flag(46 + 1, 08, "warned", true); + + des.feature({ type = "sink", coord = {47, 08}, pudding=false, dishwasher=true, ring=true }); + check_loc_name(47 + 1, 08, "sink"); + check_loc_flag(47 + 1, 08, "pudding", false); + check_loc_flag(47 + 1, 08, "dishwasher", true); + check_loc_flag(47 + 1, 08, "ring", true); end function test_gold()