From 1d9ba3e2129402b96244d5306fcf171f05f5e456 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 12 Dec 2019 13:39:20 +0200 Subject: [PATCH] Expose objects array to lua --- src/nhlobj.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ test/test_obj.lua | 25 ++++++++++++++++ test/testwish.lua | 16 ++++++++--- 3 files changed, 110 insertions(+), 4 deletions(-) diff --git a/src/nhlobj.c b/src/nhlobj.c index eed6c1b77..736c3587e 100644 --- a/src/nhlobj.c +++ b/src/nhlobj.c @@ -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 }, diff --git a/test/test_obj.lua b/test/test_obj.lua index 7bda9bf0c..a72232465 100644 --- a/test/test_obj.lua +++ b/test/test_obj.lua @@ -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 diff --git a/test/testwish.lua b/test/testwish.lua index b63bb760b..0f301e25f 100644 --- a/test/testwish.lua +++ b/test/testwish.lua @@ -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