Lua: Add contents function to room and map
The function will get the map/room width and height as a parameter.
This commit is contained in:
47
doc/lua.adoc
47
doc/lua.adoc
@@ -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
|
||||
|
||||
|
||||
54
src/sp_lev.c
54
src/sp_lev.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user