]> granicus.if.org Git - nethack/commitdiff
lua special level feature flags
authorPasi Kallinen <paxed@alt.org>
Fri, 6 Mar 2020 18:17:23 +0000 (20:17 +0200)
committerPasi Kallinen <paxed@alt.org>
Fri, 6 Mar 2020 18:30:15 +0000 (20:30 +0200)
Allow des.feature() to set rm flags for the special features.

doc/lua.adoc
src/sp_lev.c
test/test_des.lua

index 1d9007ab9fc6f5f2fe2d57e73be78f829be432f7..0677a921113845f4b74aa6a270f47cf53adf25ae 100644 (file)
@@ -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
 
index 9c4ba3e96519bef2ece13e8945a80146eb60f77f..2c282caf7ad0eac3029990c551fde4943309d814 100755 (executable)
@@ -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;
 }
index 5159c5e0a22925b15fd758df74b287c8b47674c9..4c549c9659f2c117b463d9edcc88ac94e73d4816 100644 (file)
@@ -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()