Lua: Allow creating gas clouds
Use the gas clouds in the Clouds themeroom. Use the existing visible_region_at() in the vision code.
This commit is contained in:
@@ -43,10 +43,10 @@ themeroom_fills = {
|
|||||||
-- Cloud room
|
-- Cloud room
|
||||||
function(rm)
|
function(rm)
|
||||||
local fog = selection.room();
|
local fog = selection.room();
|
||||||
des.terrain(fog, "C");
|
|
||||||
for i = 1, (fog:numpoints() / 4) do
|
for i = 1, (fog:numpoints() / 4) do
|
||||||
des.monster({ id = "fog cloud", asleep = true });
|
des.monster({ id = "fog cloud", asleep = true });
|
||||||
end
|
end
|
||||||
|
des.gas_cloud({ selection = fog });
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- Boulder room
|
-- Boulder room
|
||||||
|
|||||||
15
doc/lua.adoc
15
doc/lua.adoc
@@ -569,6 +569,21 @@ Example:
|
|||||||
des.finalize_level();
|
des.finalize_level();
|
||||||
|
|
||||||
|
|
||||||
|
=== gas_cloud
|
||||||
|
|
||||||
|
Create a gas cloud.
|
||||||
|
The `damage` and `ttl` fields are optional.
|
||||||
|
Defaults to non-poisonous and infinite lifetime.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
des.gas_cloud({ x = XX, y = YY });
|
||||||
|
des.gas_cloud({ coord = { XX, YY } });
|
||||||
|
des.gas_cloud({ selection = SEL });
|
||||||
|
des.gas_cloud({ selection = SEL, damage = 5 });
|
||||||
|
des.gas_cloud({ selection = SEL, damage = 5, ttl = 200 });
|
||||||
|
|
||||||
|
|
||||||
=== gold
|
=== gold
|
||||||
|
|
||||||
Create a pile of gold.
|
Create a pile of gold.
|
||||||
|
|||||||
@@ -2560,6 +2560,7 @@ extern void save_regions(NHFILE *) NONNULLARG1;
|
|||||||
extern void rest_regions(NHFILE *) NONNULLARG1;
|
extern void rest_regions(NHFILE *) NONNULLARG1;
|
||||||
extern void region_stats(const char *, char *, long *, long *) NONNULLPTRS;
|
extern void region_stats(const char *, char *, long *, long *) NONNULLPTRS;
|
||||||
extern NhRegion *create_gas_cloud(coordxy, coordxy, int, int);
|
extern NhRegion *create_gas_cloud(coordxy, coordxy, int, int);
|
||||||
|
extern NhRegion *create_gas_cloud_selection(struct selectionvar *, int);
|
||||||
extern boolean region_danger(void);
|
extern boolean region_danger(void);
|
||||||
extern void region_safety(void);
|
extern void region_safety(void);
|
||||||
|
|
||||||
|
|||||||
38
src/region.c
38
src/region.c
@@ -1189,6 +1189,44 @@ create_gas_cloud(coordxy x, coordxy y, int cloudsize, int damage)
|
|||||||
return cloud;
|
return cloud;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* create a single gas cloud from selection */
|
||||||
|
NhRegion *
|
||||||
|
create_gas_cloud_selection(struct selectionvar *sel, int damage)
|
||||||
|
{
|
||||||
|
NhRegion *cloud;
|
||||||
|
NhRect tmprect;
|
||||||
|
coordxy x, y;
|
||||||
|
NhRect r;
|
||||||
|
boolean inside_cloud = is_hero_inside_gas_cloud();
|
||||||
|
|
||||||
|
selection_getbounds(sel, &r);
|
||||||
|
|
||||||
|
cloud = create_region((NhRect *) 0, 0);
|
||||||
|
for (x = r.lx; x <= r.hx; x++)
|
||||||
|
for (y = r.ly; y <= r.hy; y++)
|
||||||
|
if (selection_getpoint(x, y, sel)) {
|
||||||
|
tmprect.lx = tmprect.hx = x;
|
||||||
|
tmprect.ly = tmprect.hy = y;
|
||||||
|
add_rect_to_reg(cloud, &tmprect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gi.in_mklev && !gc.context.mon_moving)
|
||||||
|
set_heros_fault(cloud); /* assume player has created it */
|
||||||
|
cloud->inside_f = INSIDE_GAS_CLOUD;
|
||||||
|
cloud->expire_f = EXPIRE_GAS_CLOUD;
|
||||||
|
cloud->arg = cg.zeroany;
|
||||||
|
cloud->arg.a_int = damage;
|
||||||
|
cloud->visible = TRUE;
|
||||||
|
cloud->glyph = cmap_to_glyph(damage ? S_poisoncloud : S_cloud);
|
||||||
|
add_region(cloud);
|
||||||
|
|
||||||
|
if (!gi.in_mklev && !inside_cloud && is_hero_inside_gas_cloud())
|
||||||
|
You("are enveloped in a cloud of %s!",
|
||||||
|
damage ? "noxious gas" : "steam");
|
||||||
|
return cloud;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* for checking troubles during prayer; is hero at risk? */
|
/* for checking troubles during prayer; is hero at risk? */
|
||||||
boolean
|
boolean
|
||||||
region_danger(void)
|
region_danger(void)
|
||||||
|
|||||||
45
src/sp_lev.c
45
src/sp_lev.c
@@ -159,6 +159,7 @@ int lspo_finalize_level(lua_State *);
|
|||||||
int lspo_room(lua_State *);
|
int lspo_room(lua_State *);
|
||||||
int lspo_stair(lua_State *);
|
int lspo_stair(lua_State *);
|
||||||
int lspo_teleport_region(lua_State *);
|
int lspo_teleport_region(lua_State *);
|
||||||
|
int lspo_gas_cloud(lua_State *);
|
||||||
int lspo_terrain(lua_State *);
|
int lspo_terrain(lua_State *);
|
||||||
int lspo_trap(lua_State *);
|
int lspo_trap(lua_State *);
|
||||||
int lspo_wall_property(lua_State *);
|
int lspo_wall_property(lua_State *);
|
||||||
@@ -5545,6 +5546,49 @@ lspo_feature(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* gas_cloud({ selection=SELECTION }); */
|
||||||
|
/* gas_cloud({ selection=SELECTION, damage=N }); */
|
||||||
|
/* gas_cloud({ selection=SELECTION, damage=N, ttl=N }); */
|
||||||
|
int
|
||||||
|
lspo_gas_cloud(lua_State *L)
|
||||||
|
{
|
||||||
|
coordxy x = 0, y = 0;
|
||||||
|
struct selectionvar *sel = NULL;
|
||||||
|
int argc = lua_gettop(L);
|
||||||
|
int damage = 0;
|
||||||
|
int ttl = -2;
|
||||||
|
|
||||||
|
create_des_coder();
|
||||||
|
|
||||||
|
if (argc == 1 && lua_type(L, 1) == LUA_TTABLE) {
|
||||||
|
lua_Integer tx, ty;
|
||||||
|
NhRegion *reg;
|
||||||
|
|
||||||
|
lcheck_param_table(L);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
damage = get_table_int_opt(L, "damage", 0);
|
||||||
|
ttl = get_table_int_opt(L, "ttl", -2);
|
||||||
|
if (!sel) {
|
||||||
|
reg = create_gas_cloud(x, y, 1, damage);
|
||||||
|
} else
|
||||||
|
reg = create_gas_cloud_selection(sel, damage);
|
||||||
|
if (ttl > -2)
|
||||||
|
reg->ttl = ttl;
|
||||||
|
} else {
|
||||||
|
nhl_error(L, "wrong parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* [lit_state: 1 On, 0 Off, -1 random, -2 leave as-is]
|
* [lit_state: 1 On, 0 Off, -1 random, -2 leave as-is]
|
||||||
* terrain({ x=NN, y=NN, typ=MAPCHAR, lit=lit_state });
|
* terrain({ x=NN, y=NN, typ=MAPCHAR, lit=lit_state });
|
||||||
@@ -6995,6 +7039,7 @@ static const struct luaL_Reg nhl_functions[] = {
|
|||||||
{ "teleport_region", lspo_teleport_region },
|
{ "teleport_region", lspo_teleport_region },
|
||||||
{ "reset_level", lspo_reset_level },
|
{ "reset_level", lspo_reset_level },
|
||||||
{ "finalize_level", lspo_finalize_level },
|
{ "finalize_level", lspo_finalize_level },
|
||||||
|
{ "gas_cloud", lspo_gas_cloud },
|
||||||
/* TODO: { "branch", lspo_branch }, */
|
/* TODO: { "branch", lspo_branch }, */
|
||||||
/* TODO: { "portal", lspo_portal }, */
|
/* TODO: { "portal", lspo_portal }, */
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
|
|||||||
11
src/vision.c
11
src/vision.c
@@ -141,7 +141,6 @@ does_block(int x, int y, struct rm *lev)
|
|||||||
{
|
{
|
||||||
struct obj *obj;
|
struct obj *obj;
|
||||||
struct monst *mon;
|
struct monst *mon;
|
||||||
int i;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* set DEBUGFILES=seethru in environment to see through bubbles */
|
/* set DEBUGFILES=seethru in environment to see through bubbles */
|
||||||
@@ -181,14 +180,8 @@ does_block(int x, int y, struct rm *lev)
|
|||||||
if (gs.seethru != 1) {
|
if (gs.seethru != 1) {
|
||||||
#endif
|
#endif
|
||||||
/* Clouds (poisonous or not) block light. */
|
/* Clouds (poisonous or not) block light. */
|
||||||
for (i = 0; i < gn.n_regions; i++) {
|
if (visible_region_at(x, y))
|
||||||
/* Ignore regions with ttl == 0 - expire_gas_cloud must unblock its
|
return 1;
|
||||||
* points prior to being removed itself. */
|
|
||||||
if (gr.regions[i]->ttl > 0 && gr.regions[i]->visible
|
|
||||||
&& inside_region(gr.regions[i], x, y)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
} /* gs.seethru */
|
} /* gs.seethru */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user