From: Pasi Kallinen Date: Fri, 28 Feb 2020 20:14:36 +0000 (+0200) Subject: Allow coord in place of x and y in special level lua script X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=22528d31f595c5102abef245f9835f3e3aa29b70;p=nethack Allow coord in place of x and y in special level lua script --- diff --git a/src/sp_lev.c b/src/sp_lev.c index 8b5a253d4..a17abfdcd 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -94,6 +94,7 @@ 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)); static int FDECL(get_coord, (lua_State *, int, int *, int *)); +static void FDECL(get_table_xy_or_coord, (lua_State *, int *, int *)); static int FDECL(get_table_region, (lua_State *, const char *, int *, int *, int *, int *, BOOLEAN_P)); static void FDECL(set_wallprop_in_selection, (lua_State *, int)); @@ -2831,6 +2832,24 @@ lua_State *L; return ret; } +static void +get_table_xy_or_coord(L, x,y) +lua_State *L; +int *x, *y; +{ + int mx = get_table_int_opt(L, "x", -1); + int my = get_table_int_opt(L, "y", -1); + + if (mx == -1 && my == -1) { + lua_getfield(L, 1, "coord"); + get_coord(L, -1, &mx, &my); + lua_pop(L, 1); + } + + *x = mx; + *y = my; +} + /* monster(); */ /* monster("wood nymph"); */ /* monster("D"); */ @@ -2942,14 +2961,7 @@ lua_State *L; Free(mappear); } - mx = get_table_int_opt(L, "x", -1); - my = get_table_int_opt(L, "y", -1); - - if (mx == -1 && my == -1) { - lua_getfield(L, 1, "coord"); - get_coord(L, -1, &mx, &my); - lua_pop(L, 1); - } + get_table_xy_or_coord(L, &mx, &my); tmpmons.id = get_table_montype(L); tmpmons.class = get_table_monclass(L); @@ -3181,14 +3193,7 @@ lua_State *L; tmpobj.broken = get_table_boolean_opt(L, "broken", 0); tmpobj.achievement = get_table_boolean_opt(L, "achievement", 0); - ox = get_table_int_opt(L, "x", -1); - oy = get_table_int_opt(L, "y", -1); - - if (ox == -1 && oy == -1) { - lua_getfield(L, 1, "coord"); - get_coord(L, -1, &ox, &oy); - lua_pop(L, 1); - } + get_table_xy_or_coord(L, &ox, &oy); tmpobj.id = get_table_objtype(L); tmpobj.class = get_table_objclass(L); @@ -3372,6 +3377,7 @@ lua_State *L; } /* engraving({ x = 1, y = 1, type="burn", text="Foo" }); */ +/* engraving({ coord={1, 1}, type="burn", text="Foo" }); */ /* engraving({x,y}, "engrave", "Foo"); */ int lspo_engraving(L) @@ -3392,11 +3398,13 @@ lua_State *L; create_des_coder(); if (argc == 1) { + int ex, ey; lcheck_param_table(L); + get_table_xy_or_coord(L, &ex, &ey); + x = ex; + y = ey; etyp = engrtypes2i[get_table_option(L, "type", "engrave", engrtypes)]; - x = get_table_int_opt(L, "x", -1); - y = get_table_int_opt(L, "y", -1); txt = get_table_str(L, "text"); } else if (argc == 3) { int ex, ey; @@ -3494,6 +3502,7 @@ int defval; } /* room({ type="ordinary", lit=1, x=3,y=3, xalign="center",yalign="center", w=11,h=9 }); */ +/* room({ lit=1, coord={3,3}, xalign="center",yalign="center", w=11,h=9 }); */ int lspo_room(L) lua_State *L; @@ -3518,9 +3527,10 @@ lua_State *L; static const int t_or_b2i[] = { TOP, CENTER, BOTTOM, -1, -1, -1 }; room tmproom; struct mkroom *tmpcr; + int rx, ry; - tmproom.x = get_table_int_opt(L, "x", -1); - tmproom.y = get_table_int_opt(L, "y", -1); + get_table_xy_or_coord(L, &rx, &ry); + tmproom.x = rx, tmproom.y = ry; if ((tmproom.x == -1 || tmproom.y == -1) && tmproom.x != tmproom.y) nhl_error(L, "Room must have both x and y"); @@ -3624,14 +3634,7 @@ lua_State *L; } else { lcheck_param_table(L); - ax = get_table_int_opt(L, "x", -1); - ay = get_table_int_opt(L, "y", -1); - - if (ax == -1 && ay == -1) { - lua_getfield(L, 1, "coord"); - get_coord(L, -1, &ax, &ay); - lua_pop(L, 1); - } + get_table_xy_or_coord(L, &ax, &ay); up = stairdirs2i[get_table_option(L, "dir", "down", stairdirs)]; } @@ -3682,14 +3685,7 @@ lua_State *L; } else { lcheck_param_table(L); - ax = get_table_int_opt(L, "x", -1); - ay = get_table_int_opt(L, "y", -1); - - if (ax == -1 && ay == -1) { - lua_getfield(L, 1, "coord"); - get_coord(L, -1, &ax, &ay); - lua_pop(L, 1); - } + get_table_xy_or_coord(L, &ax, &ay); up = stairdirs2i[get_table_option(L, "dir", "down", stairdirs)]; } @@ -3721,10 +3717,16 @@ lua_State *L; return 0; } +/* grave(); */ +/* grave(x,y, "text"); */ +/* grave({ x = 1, y = 1 }); */ +/* grave({ x = 1, y = 1, text = "Foo" }); */ +/* grave({ coord = {1, 1}, text = "Foo" }); */ int lspo_grave(L) lua_State *L; { + int argc = lua_gettop(L); schar x, y; long scoord; int ax,ay; @@ -3732,11 +3734,17 @@ lua_State *L; create_des_coder(); - lcheck_param_table(L); + if (argc == 3) { + x = ax = luaL_checkinteger(L, 1); + y = ay = luaL_checkinteger(L, 2); + txt = dupstr(luaL_checkstring(L, 3)); + } else { + lcheck_param_table(L); - x = ax = get_table_int_opt(L, "x", -1); - y = ay = get_table_int_opt(L, "y", -1); - txt = get_table_str_opt(L, "text", NULL); + get_table_xy_or_coord(L, &ax, &ay); + x = ax, y = ay; + txt = get_table_str_opt(L, "text", NULL); + } if (x == -1 && y == -1) scoord = SP_COORD_PACK_RANDOM(0); @@ -3775,14 +3783,7 @@ lua_State *L; lcheck_param_table(L); - x = get_table_int_opt(L, "x", -1); - y = get_table_int_opt(L, "y", -1); - - if (x == -1 && y == -1) { - lua_getfield(L, 1, "coord"); - get_coord(L, -1, &x, &y); - lua_pop(L, 1); - } + get_table_xy_or_coord(L, &x, &y); align = get_table_align(L); shrine = shrines2i[get_table_option(L, "type", "altar", shrines)]; @@ -3911,15 +3912,8 @@ lua_State *L; } else { lcheck_param_table(L); - x = get_table_int_opt(L, "x", -1); - y = get_table_int_opt(L, "y", -1); + get_table_xy_or_coord(L, &x, &y); tmptrap.type = get_table_traptype_opt(L, "type", -1); - - if (x == -1 && y == -1) { - lua_getfield(L, 1, "coord"); - get_coord(L, -1, &x, &y); - lua_pop(L, 1); - } } if (tmptrap.type == NO_TRAP) @@ -3938,6 +3932,7 @@ lua_State *L; /* gold(500, 3,5); */ /* gold(500, {5, 6}); */ /* gold({ amount = 500, x = 2, y = 5 });*/ +/* gold({ amount = 500, coord = {2, 5} });*/ /* gold(); */ int lspo_gold(L) @@ -3964,8 +3959,8 @@ lua_State *L; lcheck_param_table(L); amount = get_table_int_opt(L, "amount", -1); - x = gx = get_table_int_opt(L, "x", -1); - y = gy = get_table_int_opt(L, "y", -1); + get_table_xy_or_coord(L, &gx, &gy); + x = gx, y = gy; } else { nhl_error(L, "Wrong parameters"); return 0; @@ -4736,6 +4731,7 @@ genericptr_t arg; } /* door({ x = 1, y = 1, state = "nodoor" }); */ +/* door({ coord = {1, 1}, state = "nodoor" }); */ /* door({ wall = "north", pos = 3, state="secret" }); */ /* door("nodoor", 1, 2); */ int @@ -4762,10 +4758,11 @@ lua_State *L; y = luaL_checkinteger(L, 3); } else { + int dx, dy; lcheck_param_table(L); - x = get_table_int_opt(L, "x", -1); - y = get_table_int_opt(L, "y", -1); + get_table_xy_or_coord(L, &dx, &dy); + x = dx, y = dy; msk = doorstates2i[get_table_option(L, "state", "random", doorstates)]; } @@ -4802,6 +4799,7 @@ lua_State *L; /* feature("fountain", x, y); */ /* feature("fountain", {x,y}); */ /* feature({ type="fountain", x=NN, y=NN }); */ +/* feature({ type="fountain", coord={NN, NN} }); */ int lspo_feature(L) lua_State *L; @@ -4826,10 +4824,11 @@ lua_State *L; x = luaL_checkinteger(L, 2); y = luaL_checkinteger(L, 3); } else { + int fx, fy; lcheck_param_table(L); - x = get_table_int(L, "x"); - y = get_table_int(L, "y"); + get_table_xy_or_coord(L, &fx, &fy); + x = fx, y = fy; typ = features2i[get_table_option(L, "type", NULL, features)]; } @@ -4857,6 +4856,7 @@ lua_State *L; } /* terrain({ x=NN, y=NN, typ=MAPCHAR, lit=BOOL }); */ +/* terrain({ coord={X, Y}, typ=MAPCHAR, lit=BOOL }); */ /* terrain({ selection=SELECTION, typ=MAPCHAR, lit=BOOL }); */ /* terrain( SELECTION, MAPCHAR [, BOOL ] ); */ /* terrain({x,y}, MAPCHAR); */ @@ -4875,11 +4875,12 @@ lua_State *L; tmpterrain.ter = INVALID_TYPE; if (argc == 1) { + int tx, ty; lcheck_param_table(L); - x = get_table_int_opt(L, "x", -1); - y = get_table_int_opt(L, "y", -1); - if (x == -1 && y == -1) { + get_table_xy_or_coord(L, &tx, &ty); + x = tx, y = ty; + if (tx == -1 && ty == -1) { lua_getfield(L, 1, "selection"); sel = l_selection_check(L, -1); lua_pop(L, 1); @@ -5434,7 +5435,8 @@ lua_State *L; return 0; } -/* drawbridge({ dir="east", state="closed", x=05,y=08}); */ +/* drawbridge({ dir="east", state="closed", x=05,y=08 }); */ +/* drawbridge({ dir="east", state="closed", coord={05,08} }); */ int lspo_drawbridge(L) lua_State *L; @@ -5458,8 +5460,8 @@ lua_State *L; lcheck_param_table(L); - mx = get_table_int(L, "x"); - my = get_table_int(L, "y"); + get_table_xy_or_coord(L, &mx, &my); + dir = mwdirs2i[get_table_option(L, "dir", "random", mwdirs)]; dcoord = SP_COORD_PACK(mx, my); db_open = dbopens2i[get_table_option(L, "state", "random", dbopens)]; @@ -5477,6 +5479,7 @@ lua_State *L; } /* mazewalk({ x = NN, y = NN, typ = ".", dir = "north", stocked = 0 }); */ +/* mazewalk({ coord = {XX, YY}, typ = ".", dir = "north", stocked = 0 }); */ /* mazewalk(x,y,dir); */ int lspo_mazewalk(L) @@ -5502,8 +5505,7 @@ lua_State *L; } else { lcheck_param_table(L); - mx = get_table_int(L, "x"); - my = get_table_int(L, "y"); + get_table_xy_or_coord(L, &mx, &my); ftyp = get_table_mapchr_opt(L, "typ", ROOM); fstocked = get_table_boolean_opt(L, "stocked", 1); dir = mwdirs2i[get_table_option(L, "dir", "random", mwdirs)]; @@ -5725,6 +5727,7 @@ lua_State *L UNUSED; } /* map({ x = 10, y = 10, map = [[...]] }); */ +/* map({ coord = {10, 10}, map = [[...]] }); */ /* map({ halign = "center", valign = "center", map = [[...]] }); */ /* map([[...]]) */ int @@ -5765,8 +5768,7 @@ TODO: g.coder->croom needs to be updated lr = l_or_r2i[get_table_option(L, "halign", "none", left_or_right)]; tb = t_or_b2i[get_table_option(L, "valign", "none", top_or_bot)]; keepregion = get_table_boolean_opt(L, "keepregion", 1); /* TODO: maybe rename? */ - x = get_table_int_opt(L, "x", -1); - y = get_table_int_opt(L, "y", -1); + get_table_xy_or_coord(L, &x, &y); mapdata = get_table_str(L, "map"); } diff --git a/test/test_des.lua b/test/test_des.lua index c006cb057..7b2019d2d 100644 --- a/test/test_des.lua +++ b/test/test_des.lua @@ -148,6 +148,7 @@ end function test_engraving() des.engraving({02,04},"engrave","Trespassers will be persecuted!") des.engraving({ x = 1, y = 2, type = "burn", text = "Elbereth" }); + des.engraving({ coord = {1, 3}, type = "burn", text = "Elbereth" }); des.engraving({ type = "dust", text = "X marks the spot." }) des.engraving({ text = "Foobar" }) des.engraving({ type = "mark", text = "X" }) @@ -161,8 +162,10 @@ end function test_grave() des.grave(); + des.grave(39,10, "Foo is here"); des.grave({ text = "Lil Miss Marker" }); des.grave({ x = 40, y = 11 }); + des.grave({ coord = {40, 12} }); des.grave({ x = 41, y = 12, text = "Bongo" }); des.grave({ x = 42, y = 13, text = "" }); end @@ -194,6 +197,19 @@ FFF]] }) check_loc_name(x, y, nam); end end + des.map({ coord = {60, 5}, map = [[ +... +.T. +...]] }) + for x = 60, 62 do + for y = 5, 7 do + local nam = "room"; + if (x == 61 and y == 6) then + nam = "tree"; + end + check_loc_name(x, y, nam); + end + end des.map({ halign = "left", valign = "bottom", map = [[ III .I. @@ -207,11 +223,14 @@ function test_feature() check_loc_name(41 + 1, 08, "sink"); des.feature({ type = "pool", x = 42, y = 08 }); check_loc_name(42 + 1, 08, "pool"); + des.feature({ type = "sink", coord = {43, 08} }); + check_loc_name(43 + 1, 08, "sink"); end function test_gold() - des.gold({ amount = 999, x = 40, y = 07 }); des.gold(); + des.gold({ amount = 999, x = 40, y = 07 }); + des.gold({ amount = 999, coord = {40, 08} }); des.gold(666, 41,07); des.gold(123, {42,07}); end @@ -265,6 +284,7 @@ end function test_door() des.door("nodoor", 12,12); des.door({ x = 13, y = 12, state = "open" }); + des.door({ coord = {14, 12}, state = "open" }); des.room({ type = "graveyard", contents = function() des.door({ wall = "north", pos = 1 }); des.door({ wall = "random", state = "locked" }); @@ -280,6 +300,10 @@ function test_mazewalk() des.reset_level(); des.level_init({ style = "mazegrid", bg ="-" }); des.mazewalk({ x=2,y=10, dir="north", typ="L", stocked=true }); + + des.reset_level(); + des.level_init({ style = "mazegrid", bg ="-" }); + des.mazewalk({ coord={2,10}, dir="north", typ="L", stocked=true }); end function test_room() @@ -291,6 +315,7 @@ function test_room() des.room({ x=4, y=3, w=3,h=3 }); end }); + des.room({ type=" ordinary", coord={3, 3}, w=3, h=3 }); des.room(); des.room({ contents = function() des.object(); @@ -333,6 +358,9 @@ function test_terrain() des.terrain({ x = 5, y = 5, typ = "L" }); is_map_at(5,5, "L"); + des.terrain({ coord = {5, 5}, typ = "T" }); + is_map_at(5,5, "T"); + -- TODO: allow lit = false -- des.terrain({ x = 5, y = 5, typ = ".", lit = false }); -- is_map_at(5,5, ".", false);