]> granicus.if.org Git - nethack/commitdiff
Lua: Add contents function to room and map
authorPasi Kallinen <paxed@alt.org>
Wed, 4 Mar 2020 18:04:01 +0000 (20:04 +0200)
committerPasi Kallinen <paxed@alt.org>
Wed, 4 Mar 2020 18:05:15 +0000 (20:05 +0200)
The function will get the map/room width and height as a parameter.

doc/lua.adoc
src/sp_lev.c

index 56cb2e4a7be8a4aee0547208cb377938234dbab5..1d9007ab9fc6f5f2fe2d57e73be78f829be432f7 100644 (file)
@@ -316,12 +316,33 @@ Example:
 
 === map
 
+Construct a piece of the level from text map. Takes one parameter, either a text string
+describing the map, or a table with multiple parameters.
+
+[options="header"]
+|===
+| parameter | description
+| x, y      | Coordinates on the level.
+| coord     | Coordinates in table format.
+| halign    | Horizontal alignment on a rough 3x3 grid.
+| valign    | Vertical alignment on a rough 3x3 grid.
+| map       | Multi-line string describing the map.
+| contents  | A function called with one parameter, a table with "width" and "height", the map width and height. All coordinates in the function will be relative to the map.
+|===
+
 Example:
 
  des.map({ x = 10, y = 10, map = [[...]] });
  des.map({ coord = {10, 10}, map = [[...]] });
  des.map({ halign = "center", valign = "center", map = [[...]] });
- des.map([[...]])
+ des.map([[...]]);
+ des.map({ halign = "center", valign = "center", map = [[
+ ....
+ ....
+ ....]], contents = function(map)
+   des.terrain(0,0, "L");
+   des.terrain(map.width-1, map.height-1, "T");
+ end });
 
 === mazewalk
 
@@ -409,10 +430,34 @@ Example:
 
 === room
 
+Create a room of certain type and size. Takes one parameter, a table with the following
+fields:
+
+[options="header"]
+|===
+| parameter | description
+| type      | The room type. Default is "ordinary"
+| chance    | Percentage chance this room is of type, otherwise it will be created as ordinary room. Default is 100.
+| x,y       | Room coordinates.
+| coord     | Room coordinates, in table format.
+| w, h      | Width and height. Both default to -1 (random). If one is set, then both must be set.
+| xalign    | Horizontal alignment on a rough 3x3 grid. Default is "random".
+| yalign    | Vertical alignment on a rough 3x3 grid. Default is "random".
+| lit       | Is the room lit or unlit? Defaults to -1 (random).
+| filled    | Is the room filled as per the room type. Defaults to 1 (filled).
+| joined    | Is the room joined to the rest of the level with corridors? Default is 1 (joined).
+| contents  | A function called with one parameter, a table with "width" and "height", the room width and height, excluding the walls. All coordinates in the function will be relative to the room.
+|===
+
+
 Example:
 
  des.room({ type="ordinary", lit=1, x=3,y=3, xalign="center",yalign="center", w=11,h=9 });
  des.room({ lit=1, coord={3,3}, xalign="center",yalign="center", w=11,h=9 });
+ des.room({ type="ordinary", contents=function(room)
+    des.terrain(0,0, "L");
+    des.terrain(room.width, room.height, "T");
+ end });
 
 === stair
 
index 079c0747a2f58076a87b2d4fb6cdbf2648fdf1c3..9c4ba3e96519bef2ece13e8945a80146eb60f77f 100755 (executable)
@@ -99,6 +99,7 @@ static int FDECL(get_table_region, (lua_State *, const char *,
 static void FDECL(set_wallprop_in_selection, (lua_State *, int));
 static int FDECL(floodfillchk_match_under, (int, int));
 static int FDECL(floodfillchk_match_accessible, (int, int));
+static void FDECL(l_push_wid_hei_table, (lua_State *, int, int));
 
 /* lua_CFunction prototypes */
 int FDECL(lspo_altar, (lua_State *));
@@ -2799,6 +2800,23 @@ spo_pop_container()
     }
 }
 
+/* push a table on lua stack: {width=wid, height=hei} */
+static void
+l_push_wid_hei_table(L, wid, hei)
+lua_State *L;
+int wid, hei;
+{
+    lua_newtable(L);
+
+    lua_pushstring(L, "width");
+    lua_pushinteger(L, wid);
+    lua_rawset(L, -3);
+
+    lua_pushstring(L, "height");
+    lua_pushinteger(L, hei);
+    lua_rawset(L, -3);
+}
+
 /* message("What a strange feeling!"); */
 int
 lspo_message(L)
@@ -3570,6 +3588,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 }); */
+/* room({ coord={3,3}, xalign="center",yalign="center", w=11,h=9, contents=function(room) ... end }); */
 int
 lspo_room(L)
 lua_State *L;
@@ -3627,7 +3646,8 @@ lua_State *L;
                 lua_getfield(L, 1, "contents");
                 if (lua_type(L, -1) == LUA_TFUNCTION) {
                     lua_remove(L, -2);
-                    lua_call(L, 0, 0);
+                    l_push_wid_hei_table(L, tmpcr->hx - tmpcr->lx, tmpcr->hy - tmpcr->ly);
+                    lua_call(L, 1, 0);
                 } else
                     lua_pop(L, 1);
                 spo_endroom(g.coder);
@@ -5851,6 +5871,7 @@ lua_State *L UNUSED;
 /* map({ x = 10, y = 10, map = [[...]] }); */
 /* map({ coord = {10, 10}, map = [[...]] }); */
 /* map({ halign = "center", valign = "center", map = [[...]] }); */
+/* map({ map = [[...]], contents = function(map) ... end }); */
 /* map([[...]]) */
 int
 lspo_map(L)
@@ -5874,9 +5895,10 @@ TODO: g.coder->croom needs to be updated
         "top", "center", "bottom", "none", NULL
     };
     static const int t_or_b2i[] = { TOP, CENTER, BOTTOM, -1, -1 };
-    int lr, tb, keepregion = 1, x = -1, y = -1;
+    int lr, tb, x = -1, y = -1;
     struct mapfragment *mf;
     int argc = lua_gettop(L);
+    boolean has_contents = FALSE;
 
     create_des_coder();
 
@@ -5890,9 +5912,15 @@ TODO: g.coder->croom needs to be updated
         lcheck_param_table(L);
         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? */
         get_table_xy_or_coord(L, &x, &y);
         tmpstr = get_table_str(L, "map");
+        lua_getfield(L, 1, "contents");
+        if (lua_type(L, -1) == LUA_TFUNCTION) {
+            lua_remove(L, -2);
+            has_contents = TRUE;
+        } else {
+            lua_pop(L, 1);
+        }
         mf = mapfrag_fromstr(tmpstr);
         free(tmpstr);
     }
@@ -5902,15 +5930,11 @@ TODO: g.coder->croom needs to be updated
         return 0;
     }
 
-    /* keepregion restricts the coordinates of the commands coming after
-       the map into the map region */
-    /* for keepregion */
     tmpxsize = g.xsize;
     tmpysize = g.ysize;
     tmpxstart = g.xstart;
     tmpystart = g.ystart;
 
-
     g.xsize = mf->wid;
     g.ysize = mf->hei;
 
@@ -6033,15 +6057,19 @@ TODO: g.coder->croom needs to be updated
             remove_rooms(g.xstart, g.ystart,
                          g.xstart + g.xsize, g.ystart + g.ysize);
     }
-    if (!keepregion) {
-        g.xstart = tmpxstart;
-        g.ystart = tmpystart;
-        g.xsize = tmpxsize;
-        g.ysize = tmpysize;
-    }
 
     mapfrag_free(&mf);
 
+    if (has_contents) {
+        l_push_wid_hei_table(L, g.xsize, g.ysize);
+        lua_call(L, 1, 0);
+    }
+
+    tmpxsize = g.xsize;
+    tmpysize = g.ysize;
+    tmpxstart = g.xstart;
+    tmpystart = g.ystart;
+
     return 0;
 }