]> granicus.if.org Git - nethack/commitdiff
Expose objects array to lua
authorPasi Kallinen <paxed@alt.org>
Thu, 12 Dec 2019 11:39:20 +0000 (13:39 +0200)
committerPasi Kallinen <paxed@alt.org>
Thu, 12 Dec 2019 11:39:20 +0000 (13:39 +0200)
src/nhlobj.c
test/test_obj.lua
test/testwish.lua

index eed6c1b772d3a32fa70a6fbd97dc1e4291f77afe..736c3587e23e2336e5eab3986ac1269d36e0dd54 100644 (file)
@@ -108,6 +108,78 @@ lua_State *L;
     return 0;
 }
 
+/* Get a table of object class data. */
+/* local odata = obj.class(otbl.otyp); */
+/* local odata = obj.class(obj.new("rock")); */
+static int
+l_obj_objects_to_table(L)
+lua_State *L;
+{
+    int argc = lua_gettop(L);
+    int otyp = -1;
+    struct objclass *o;
+
+    if (argc != 1) {
+        nhl_error(L, "l_obj_objects_to_table: Wrong args");
+        return 0;
+    }
+
+    if (lua_type(L, 1) == LUA_TNUMBER) {
+        otyp = luaL_checkinteger(L, 1);
+    } else if (lua_type(L, 1) == LUA_TUSERDATA) {
+        struct _lua_obj *lo = l_obj_check(L, 1);
+        if (lo && lo->obj)
+            otyp = lo->obj->otyp;
+    }
+    lua_pop(L, 1);
+
+    if (otyp == -1) {
+        nhl_error(L, "l_obj_objects_to_table: Wrong args");
+        return 0;
+    }
+
+    o = &objects[otyp];
+
+    lua_newtable(L);
+
+    if (OBJ_NAME(objects[otyp]))
+        nhl_add_table_entry_str(L, "name", OBJ_NAME(objects[otyp]));
+    if (OBJ_DESCR(objects[otyp]))
+        nhl_add_table_entry_str(L, "descr",
+                                OBJ_DESCR(objects[otyp]));
+    if (o->oc_uname)
+        nhl_add_table_entry_str(L, "uname", o->oc_uname);
+
+    nhl_add_table_entry_int(L, "name_known", o->oc_name_known);
+    nhl_add_table_entry_int(L, "merge", o->oc_merge);
+    nhl_add_table_entry_int(L, "uses_known", o->oc_uses_known);
+    nhl_add_table_entry_int(L, "pre_discovered", o->oc_pre_discovered);
+    nhl_add_table_entry_int(L, "magic", o->oc_magic);
+    nhl_add_table_entry_int(L, "charged", o->oc_charged);
+    nhl_add_table_entry_int(L, "unique", o->oc_unique);
+    nhl_add_table_entry_int(L, "nowish", o->oc_nowish);
+    nhl_add_table_entry_int(L, "big", o->oc_big);
+    /* TODO: oc_bimanual, oc_bulky */
+    nhl_add_table_entry_int(L, "tough", o->oc_tough);
+    nhl_add_table_entry_int(L, "dir", o->oc_dir); /* TODO: convert to text */
+    nhl_add_table_entry_int(L, "material", o->oc_material); /* TODO: convert to text */
+    /* TODO: oc_subtyp, oc_skill, oc_armcat */
+    nhl_add_table_entry_int(L, "oprop", o->oc_oprop);
+    nhl_add_table_entry_char(L, "class",
+                             def_oc_syms[(uchar) o->oc_class].sym);
+    nhl_add_table_entry_int(L, "delay", o->oc_delay);
+    nhl_add_table_entry_int(L, "color", o->oc_color); /* TODO: text? */
+    nhl_add_table_entry_int(L, "prob", o->oc_prob);
+    nhl_add_table_entry_int(L, "weight", o->oc_weight);
+    nhl_add_table_entry_int(L, "cost", o->oc_cost);
+    nhl_add_table_entry_int(L, "damage_small", o->oc_wsdam);
+    nhl_add_table_entry_int(L, "damage_large", o->oc_wldam);
+    /* TODO: oc_oc1, oc_oc2, oc_hitbon, a_ac, a_can, oc_level */
+    nhl_add_table_entry_int(L, "nutrition", o->oc_nutrition);
+
+    return 1;
+}
+
 /* Create a lua table representation of the object, unpacking all the
    object fields.
    local o = obj.new("rock");
@@ -322,6 +394,7 @@ static const struct luaL_Reg l_obj_methods[] = {
     { "at", l_obj_at },
     { "next", l_obj_nextobj },
     { "totable", l_obj_to_table },
+    { "class", l_obj_objects_to_table },
     { "placeobj", l_obj_placeobj },
     { "container", l_obj_container },
     { "contents", l_obj_getcontents },
index 7bda9bf0ce65dfa1c31339e11209c1f8abdf5302..a72232465d3b8516ee77dece383112c76edfce71 100644 (file)
@@ -39,3 +39,28 @@ local o4tbl = o4:totable();
 if (o4tbl.otyp_name ~= "rock") then
    error("no rock under the large box");
 end
+
+
+local oc = obj.class(o4tbl.otyp);
+if (oc.name ~= "rock") then
+   error("object class is not rock, part 1");
+end
+if (oc.class ~= "*") then
+   error("object class is not *, part 1");
+end
+
+local oc2 = obj.class(o);
+if (oc2.name ~= "rock") then
+   error("object class is not rock, part 2");
+end
+if (oc2.class ~= "*") then
+   error("object class is not *, part 2");
+end
+
+local oc3 = obj.class(obj.new("rock"));
+if (oc3.name ~= "rock") then
+   error("object class is not rock, part 3");
+end
+if (oc3.class ~= "*") then
+   error("object class is not *, part 3");
+end
index b63bb760b2a1157d7eaeb8613d3c561ccc5d279b..0f301e25fa0e220caa60ab42395ac2c8e3616993 100644 (file)
@@ -42,15 +42,23 @@ local wishtest_objects = {
    ["land mine"] = { otyp_name = "land mine", oclass = "(" },
    ["blessed historic statue of woodland-elf named Foo"] = { otyp_name = "statue", blessed = 1, historic = 1, corpsenm_name = "Woodland-elf", oname = "Foo" },
    ["blessed figurine of a ki-rin"] = { otyp_name = "figurine", blessed = 1, corpsenm_name = "ki-rin" },
-   -- ["partly eaten orange"] = { otyp_descr = "orange", oclass = "%", oeaten = ... },
+   ["partly eaten orange"] = { otyp_name = "orange", oclass = "%", oeaten = function ()
+                                  local oc = obj.class(obj.new("orange"));
+                                  return (oc.nutrition // 2);
+                             end },
 };
 
-
 for str, tbl in pairs(wishtest_objects) do
    local o = obj.new(str):totable();
    for field, value in pairs(tbl) do
-      if (o[field] ~= value) then
-         error("wished " .. str .. ", but " .. field .. " is " .. o[field] .. ", not " .. value);
+      local val;
+      if (type(value) == "function") then
+         val = value();
+      else
+         val = value;
+      end
+      if (o[field] ~= val) then
+         error("wished " .. str .. ", but " .. field .. " is " .. o[field] .. ", not " .. val);
       end
    end
 end