adopt pull request #328 - steam clouds
This adds a superset of the code from github pull request #328 to create a short-lived cloud of steam when fire hits a pool or fountain. The original code required C99; this doesn't. It also allowed vapor clouds on the Plane of Water where they don't work sanely becaure regions don't understand air bubble movement and/or vice versa. This inhibits the clouds there [the same ought to be done for scrolls of stinking cloud]. It also left as-is the code that reported when fountains got used up even though conceptually the steam should interfere with being able to see that. This adds a glyph-check hack to augment cansee() so that fountains that boil away entirely are hidden at the time. Regions that block line of slight should be calling block_point() when created and unblock_point() when removed but a naive attempt to introduce that didn't work as expected so I'm giving up on. Fixes #328
This commit is contained in:
@@ -268,6 +268,7 @@ wizard mode #wizborn command
|
|||||||
include more skill information in ^X output when dual-wielding
|
include more skill information in ^X output when dual-wielding
|
||||||
item-using monsters will zap wand of undead turning at corpse-wielding hero
|
item-using monsters will zap wand of undead turning at corpse-wielding hero
|
||||||
when the corpse is harmful
|
when the corpse is harmful
|
||||||
|
boiling a pool or fountain now creates a temporary cloud of steam
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific New Features
|
Platform- and/or Interface-Specific New Features
|
||||||
|
|||||||
@@ -204,15 +204,22 @@ boolean isyou;
|
|||||||
if (yn("Dry up fountain?") == 'n')
|
if (yn("Dry up fountain?") == 'n')
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* FIXME: sight-blocking clouds should use block_point() when
|
||||||
|
being created and unblock_point() when going away, then this
|
||||||
|
glyph hackery wouldn't be necessary */
|
||||||
|
if (cansee(x, y)) {
|
||||||
|
int glyph = glyph_at(x, y);
|
||||||
|
|
||||||
|
if (!glyph_is_cmap(glyph) || glyph_to_cmap(glyph) != S_cloud)
|
||||||
|
pline_The("fountain dries up!");
|
||||||
|
}
|
||||||
/* replace the fountain with ordinary floor */
|
/* replace the fountain with ordinary floor */
|
||||||
levl[x][y].typ = ROOM, levl[x][y].flags = 0;
|
levl[x][y].typ = ROOM, levl[x][y].flags = 0;
|
||||||
levl[x][y].blessedftn = 0;
|
levl[x][y].blessedftn = 0;
|
||||||
if (cansee(x, y))
|
g.level.flags.nfountains--;
|
||||||
pline_The("fountain dries up!");
|
|
||||||
/* The location is seen if the hero/monster is invisible
|
/* The location is seen if the hero/monster is invisible
|
||||||
or felt if the hero is blind. */
|
or felt if the hero is blind. */
|
||||||
newsym(x, y);
|
newsym(x, y);
|
||||||
g.level.flags.nfountains--;
|
|
||||||
if (isyou && in_town(x, y))
|
if (isyou && in_town(x, y))
|
||||||
(void) angry_guards(FALSE);
|
(void) angry_guards(FALSE);
|
||||||
}
|
}
|
||||||
|
|||||||
32
src/region.c
32
src/region.c
@@ -310,8 +310,11 @@ NhRegion *reg;
|
|||||||
continue;
|
continue;
|
||||||
if (MON_AT(i, j) && inside_region(reg, i, j))
|
if (MON_AT(i, j) && inside_region(reg, i, j))
|
||||||
add_mon_to_reg(reg, g.level.monsters[i][j]);
|
add_mon_to_reg(reg, g.level.monsters[i][j]);
|
||||||
if (reg->visible && cansee(i, j))
|
if (reg->visible) {
|
||||||
newsym(i, j);
|
/*block_point(i, j);*/
|
||||||
|
if (cansee(i, j))
|
||||||
|
newsym(i, j);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Check for player now... */
|
/* Check for player now... */
|
||||||
if (inside_region(reg, u.ux, u.uy))
|
if (inside_region(reg, u.ux, u.uy))
|
||||||
@@ -345,8 +348,12 @@ NhRegion *reg;
|
|||||||
if (reg->visible)
|
if (reg->visible)
|
||||||
for (x = reg->bounding_box.lx; x <= reg->bounding_box.hx; x++)
|
for (x = reg->bounding_box.lx; x <= reg->bounding_box.hx; x++)
|
||||||
for (y = reg->bounding_box.ly; y <= reg->bounding_box.hy; y++)
|
for (y = reg->bounding_box.ly; y <= reg->bounding_box.hy; y++)
|
||||||
if (isok(x, y) && inside_region(reg, x, y) && cansee(x, y))
|
if (isok(x, y) && inside_region(reg, x, y)) {
|
||||||
newsym(x, y);
|
/*if (!sobj_at(BOULDER, x, y))
|
||||||
|
unblock_point(x, y);*/
|
||||||
|
if (cansee(x, y))
|
||||||
|
newsym(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
free_region(reg);
|
free_region(reg);
|
||||||
}
|
}
|
||||||
@@ -532,7 +539,8 @@ update_player_regions()
|
|||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
for (i = 0; i < g.n_regions; i++)
|
for (i = 0; i < g.n_regions; i++)
|
||||||
if (!g.regions[i]->attach_2_u && inside_region(g.regions[i], u.ux, u.uy))
|
if (!g.regions[i]->attach_2_u
|
||||||
|
&& inside_region(g.regions[i], u.ux, u.uy))
|
||||||
set_hero_inside(g.regions[i]);
|
set_hero_inside(g.regions[i]);
|
||||||
else
|
else
|
||||||
clear_hero_inside(g.regions[i]);
|
clear_hero_inside(g.regions[i]);
|
||||||
@@ -996,23 +1004,25 @@ genericptr_t p2 UNUSED;
|
|||||||
return TRUE; /* OK, it's gone, you can free it! */
|
return TRUE; /* OK, it's gone, you can free it! */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns True if p2 is killed by region p1, False otherwise */
|
||||||
boolean
|
boolean
|
||||||
inside_gas_cloud(p1, p2)
|
inside_gas_cloud(p1, p2)
|
||||||
genericptr_t p1;
|
genericptr_t p1;
|
||||||
genericptr_t p2;
|
genericptr_t p2;
|
||||||
{
|
{
|
||||||
NhRegion *reg;
|
NhRegion *reg = (NhRegion *) p1;
|
||||||
struct monst *mtmp;
|
struct monst *mtmp = (struct monst *) p2;
|
||||||
int dam;
|
int dam = reg->arg.a_int;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gas clouds can't be targetted at water locations, but they can
|
* Gas clouds can't be targetted at water locations, but they can
|
||||||
* start next to water and spread over it.
|
* start next to water and spread over it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
reg = (NhRegion *) p1;
|
if (dam < 1)
|
||||||
dam = reg->arg.a_int;
|
return FALSE; /* if no damage then there's nothing to do here... */
|
||||||
if (p2 == (genericptr_t) 0) { /* This means *YOU* Bozo! */
|
|
||||||
|
if (!mtmp) { /* hero is indicated by Null rather than by &youmonst */
|
||||||
if (m_poisongas_ok(&g.youmonst) == M_POISONGAS_OK)
|
if (m_poisongas_ok(&g.youmonst) == M_POISONGAS_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!Blind) {
|
if (!Blind) {
|
||||||
|
|||||||
25
src/zap.c
25
src/zap.c
@@ -4475,21 +4475,29 @@ short exploding_wand_typ;
|
|||||||
if (is_ice(x, y)) {
|
if (is_ice(x, y)) {
|
||||||
melt_ice(x, y, (char *) 0);
|
melt_ice(x, y, (char *) 0);
|
||||||
} else if (is_pool(x, y)) {
|
} else if (is_pool(x, y)) {
|
||||||
|
boolean on_water_level = Is_waterlevel(&u.uz);
|
||||||
const char *msgtxt = (!Deaf)
|
const char *msgtxt = (!Deaf)
|
||||||
? "You hear hissing gas." /* Deaf-aware */
|
? "You hear hissing gas." /* Deaf-aware */
|
||||||
: (type >= 0)
|
: (type >= 0)
|
||||||
? "That seemed remarkably uneventful."
|
? "That seemed remarkably uneventful."
|
||||||
: (const char *) 0;
|
: (char *) 0;
|
||||||
|
|
||||||
if (lev->typ != POOL) { /* MOAT or DRAWBRIDGE_UP */
|
/* don't create steam clouds on Plane of Water; air bubble
|
||||||
if (see_it)
|
movement and gas regions don't understand each other */
|
||||||
|
if (!on_water_level)
|
||||||
|
create_gas_cloud(x, y, rnd(3), 0); /* radius 1..3, no damg */
|
||||||
|
|
||||||
|
if (lev->typ != POOL) { /* MOAT or DRAWBRIDGE_UP or WATER */
|
||||||
|
if (on_water_level)
|
||||||
|
msgtxt = (see_it || !Deaf) ? "Some water boils." : 0;
|
||||||
|
else if (see_it)
|
||||||
msgtxt = "Some water evaporates.";
|
msgtxt = "Some water evaporates.";
|
||||||
} else {
|
} else {
|
||||||
rangemod -= 3;
|
rangemod -= 3;
|
||||||
lev->typ = ROOM, lev->flags = 0;
|
lev->typ = ROOM, lev->flags = 0;
|
||||||
t = maketrap(x, y, PIT);
|
t = maketrap(x, y, PIT);
|
||||||
if (t)
|
/*if (t) -- this was before the vapor cloud was added --
|
||||||
t->tseen = 1;
|
t->tseen = 1;*/
|
||||||
if (see_it)
|
if (see_it)
|
||||||
msgtxt = "The water evaporates.";
|
msgtxt = "The water evaporates.";
|
||||||
}
|
}
|
||||||
@@ -4498,6 +4506,7 @@ short exploding_wand_typ;
|
|||||||
if (lev->typ == ROOM)
|
if (lev->typ == ROOM)
|
||||||
newsym(x, y);
|
newsym(x, y);
|
||||||
} else if (IS_FOUNTAIN(lev->typ)) {
|
} else if (IS_FOUNTAIN(lev->typ)) {
|
||||||
|
create_gas_cloud(x, y, rnd(2), 0); /* radius 1..2, no damage */
|
||||||
if (see_it)
|
if (see_it)
|
||||||
pline("Steam billows from the fountain.");
|
pline("Steam billows from the fountain.");
|
||||||
rangemod -= 1;
|
rangemod -= 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user