From b24f4c5929b1f90ce43b934723fea188407460b1 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 15 Dec 2019 18:16:41 +0200 Subject: [PATCH] Expose traps to lua --- include/extern.h | 2 ++ src/cmd.c | 11 ++++++- src/nhlua.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++ src/sp_lev.c | 13 ++++++++ test/test_des.lua | 38 ++++++++++++++++++++++-- 5 files changed, 136 insertions(+), 3 deletions(-) diff --git a/include/extern.h b/include/extern.h index 836784059..a73ba5821 100644 --- a/include/extern.h +++ b/include/extern.h @@ -202,6 +202,7 @@ E int NDECL(doconduct); E int NDECL(domonability); E char FDECL(cmd_from_func, (int NDECL((*)))); E boolean FDECL(redraw_cmd, (CHAR_P)); +E const char *FDECL(levltyp_to_name, (int)); #ifdef USE_TRAMPOLI E int NDECL(doextcmd); E int NDECL(domonability); @@ -2462,6 +2463,7 @@ E struct selectionvar *FDECL(selection_filter_mapchar, (struct selectionvar *, X E void FDECL(set_floodfillchk_match_under, (XCHAR_P)); E void FDECL(selection_do_ellipse, (struct selectionvar *, int, int, int, int, int)); E void NDECL(update_croom); +E const char *FDECL(get_trapname_bytype, (int)); E void FDECL(l_register_des, (lua_State *)); #endif /* !CROSSCOMPILE || CROSSCOMPILE_TARGET */ diff --git a/src/cmd.c b/src/cmd.c index b2d93f624..31b3397c7 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1350,7 +1350,7 @@ wiz_map_levltyp(VOID_ARGS) /* temporary? hack, since level type codes aren't the same as screen symbols and only the latter have easily accessible descriptions */ -static const char *levltyp[] = { +const char *levltyp[] = { "stone", "vertical wall", "horizontal wall", "top-left corner wall", "top-right corner wall", "bottom-left corner wall", "bottom-right corner wall", "cross wall", "tee-up wall", "tee-down wall", @@ -1366,6 +1366,15 @@ static const char *levltyp[] = { "" }; +const char * +levltyp_to_name(typ) +int typ; +{ + if (typ >= 0 && typ < MAX_TYPE) + return levltyp[typ]; + return NULL; +} + /* explanation of base-36 output from wiz_map_levltyp() */ static void wiz_levltyp_legend(VOID_ARGS) diff --git a/src/nhlua.c b/src/nhlua.c index d5dba8465..c47c8db96 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -222,6 +222,75 @@ schar typ; return 'x'; } +/* local t = gettrap(x,y); */ +static int +nhl_gettrap(L) +lua_State *L; +{ + int argc = lua_gettop(L); + + if (argc == 2) { + int x = (int) lua_tointeger(L, 1); + int y = (int) lua_tointeger(L, 2); + + if (x >= 0 && x < COLNO && y >= 0 && y < ROWNO) { + struct trap *ttmp = t_at(x,y); + + if (ttmp) { + lua_newtable(L); + + nhl_add_table_entry_int(L, "tx", ttmp->tx); + nhl_add_table_entry_int(L, "ty", ttmp->ty); + nhl_add_table_entry_int(L, "ttyp", ttmp->ttyp); + nhl_add_table_entry_str(L, "ttyp_name", get_trapname_bytype(ttmp->ttyp)); + nhl_add_table_entry_int(L, "tseen", ttmp->tseen); + nhl_add_table_entry_int(L, "madeby_u", ttmp->madeby_u); + switch (ttmp->ttyp) { + case SQKY_BOARD: + nhl_add_table_entry_int(L, "tnote", ttmp->tnote); + break; + case ROLLING_BOULDER_TRAP: + nhl_add_table_entry_int(L, "launchx", ttmp->launch.x); + nhl_add_table_entry_int(L, "launchy", ttmp->launch.y); + nhl_add_table_entry_int(L, "launch2x", ttmp->launch2.x); + nhl_add_table_entry_int(L, "launch2y", ttmp->launch2.y); + break; + case PIT: + case SPIKED_PIT: + nhl_add_table_entry_int(L, "conjoined", ttmp->conjoined); + break; + } + return 1; + } else + nhl_error(L, "No trap at location"); + } else + nhl_error(L, "Coordinates out of range"); + } else + nhl_error(L, "Wrong args"); + return 0; +} + +/* deltrap(x,y); */ +static int +nhl_deltrap(L) +lua_State *L; +{ + int argc = lua_gettop(L); + + if (argc == 2) { + int x = (int) lua_tointeger(L, 1); + int y = (int) lua_tointeger(L, 2); + + if (x >= 0 && x < COLNO && y >= 0 && y < ROWNO) { + struct trap *ttmp = t_at(x,y); + + if (ttmp) + deltrap(ttmp); + } + } + return 0; +} + /* local loc = getmap(x,y) */ static int nhl_getmap(L) @@ -240,6 +309,7 @@ lua_State *L; /* FIXME: some should be boolean values */ nhl_add_table_entry_int(L, "glyph", levl[x][y].glyph); nhl_add_table_entry_int(L, "typ", levl[x][y].typ); + nhl_add_table_entry_str(L, "typ_name", levltyp_to_name(levl[x][y].typ)); Sprintf(buf, "%c", splev_typ2chr(levl[x][y].typ)); nhl_add_table_entry_str(L, "mapchr", buf); nhl_add_table_entry_int(L, "seenv", levl[x][y].seenv); @@ -250,6 +320,8 @@ lua_State *L; nhl_add_table_entry_bool(L, "edge", levl[x][y].edge); nhl_add_table_entry_bool(L, "candig", levl[x][y].candig); + nhl_add_table_entry_int(L, "has_trap", t_at(x,y) ? 1 : 0); + /* TODO: FIXME: levl[x][y].flags */ lua_pushliteral(L, "flags"); @@ -670,6 +742,9 @@ static const struct luaL_Reg nhl_functions[] = { #if 0 {"setmap", nhl_setmap}, #endif + {"gettrap", nhl_gettrap}, + {"deltrap", nhl_deltrap}, + {"pline", nhl_pline}, {"verbalize", nhl_verbalize}, {"menu", nhl_menu}, diff --git a/src/sp_lev.c b/src/sp_lev.c index 5f0fcda92..68c6f3ac6 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -3351,6 +3351,19 @@ int defval; return defval; } +const char * +get_trapname_bytype(ttyp) +int ttyp; +{ + int i; + + for (i = 0; trap_types[i].name; i++) + if (ttyp == trap_types[i].type) + return trap_types[i].name; + + return NULL; +} + int get_traptype_byname(trapname) const char *trapname; diff --git a/test/test_des.lua b/test/test_des.lua index 5a82efb1d..1e8487530 100644 --- a/test/test_des.lua +++ b/test/test_des.lua @@ -14,6 +14,20 @@ function is_map_at(x,y, mapch, lit) end end +function check_loc_name(x, y, name) + local loc = nh.getmap(x,y); + if (loc.typ_name ~= name) then + error("No " .. name .. " at " .. x .. "," .. y .. " (" .. loc.typ_name .. ")"); + 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 + error("Trap at " .. x .. "," .. y .. " is " .. t.ttyp_name .. ", not " .. name); + end +end + function test_level_init() des.reset_level(); des.level_init(); @@ -171,6 +185,15 @@ LTL]]) FFF F.F FFF]] }) + for x = 60, 62 do + for y = 5, 7 do + local nam = "iron bars"; + if (x == 61 and y == 6) then + nam = "room"; + end + check_loc_name(x, y, nam); + end + end des.map({ halign = "left", valign = "bottom", map = [[ III .I. @@ -179,8 +202,11 @@ end function test_feature() des.feature("fountain", 40, 08); + check_loc_name(40 + 1, 08, "fountain"); des.feature("sink", {41, 08}); + check_loc_name(41 + 1, 08, "sink"); des.feature({ type = "pool", x = 42, y = 08 }); + check_loc_name(42 + 1, 08, "pool"); end function test_gold() @@ -189,9 +215,17 @@ end function test_trap() des.trap("pit", 41, 06); + check_trap_at(41, 06, "pit"); + des.trap("level teleport", {42, 06}); - des.trap({ type = "hole", x = 43, y = 06 }); - des.trap({ type = "hole", coord = {44, 06} }); + check_trap_at(42, 06, "level teleport"); + + des.trap({ type = "falling rock", x = 43, y = 06 }); + check_trap_at(43, 06, "falling rock"); + + des.trap({ type = "dart", coord = {44, 06} }); + check_trap_at(44, 06, "dart"); + des.trap(); des.trap("rust"); end