Stinking clouds block line of sight
... you will also get a message when a seen stinking cloud or the one surrounding the hero dissipates. Original feature comes from Fourk, but this version (with some minor changes) comes from xnethack by copperwater <aosdict@gmail.com>
This commit is contained in:
@@ -762,6 +762,7 @@ when already at level 30 and gaining another level--which doesn't increase
|
||||
don't stop running when next to a peaceful, unless it blocks the way
|
||||
mindless monsters shouldn't cringe stepping on squeaky boards
|
||||
falling down a hole or trapdoor will cause damage proportional to fall height
|
||||
stinking gas clouds block line-of-sight
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||
|
||||
@@ -1113,6 +1113,8 @@ struct instance_globals {
|
||||
NhRegion **regions;
|
||||
int n_regions;
|
||||
int max_regions;
|
||||
boolean gas_cloud_diss_within;
|
||||
int gas_cloud_diss_seen;
|
||||
|
||||
/* restore.c */
|
||||
int n_ids_mapped;
|
||||
|
||||
@@ -2220,6 +2220,7 @@ extern void split_rects(NhRect *, NhRect *);
|
||||
|
||||
/* ## region.c ### */
|
||||
|
||||
extern boolean inside_region(NhRegion *, int, int);
|
||||
extern void clear_regions(void);
|
||||
extern void run_regions(void);
|
||||
extern boolean in_out_region(xchar, xchar);
|
||||
|
||||
@@ -577,6 +577,8 @@ const struct instance_globals g_init = {
|
||||
NULL, /* regions */
|
||||
0, /* n_regions */
|
||||
0, /* max_regions */
|
||||
FALSE, /* gas_cloud_diss_within */
|
||||
0, /* gas_cloud_diss_seen */
|
||||
|
||||
/* restore.c */
|
||||
0, /* n_ids_mapped */
|
||||
|
||||
35
src/region.c
35
src/region.c
@@ -15,7 +15,6 @@
|
||||
boolean inside_gas_cloud(genericptr, genericptr);
|
||||
boolean expire_gas_cloud(genericptr, genericptr);
|
||||
boolean inside_rect(NhRect *, int, int);
|
||||
boolean inside_region(NhRegion *, int, int);
|
||||
NhRegion *create_region(NhRect *, int);
|
||||
void add_rect_to_reg(NhRegion *, NhRect *);
|
||||
void add_mon_to_reg(NhRegion *, struct monst *);
|
||||
@@ -290,13 +289,16 @@ add_region(NhRegion *reg)
|
||||
/* Check for monsters inside the region */
|
||||
for (i = reg->bounding_box.lx; i <= reg->bounding_box.hx; i++)
|
||||
for (j = reg->bounding_box.ly; j <= reg->bounding_box.hy; j++) {
|
||||
boolean is_inside = inside_region(reg, i, j);
|
||||
|
||||
/* Some regions can cross the level boundaries */
|
||||
if (!isok(i, j))
|
||||
continue;
|
||||
if (MON_AT(i, j) && inside_region(reg, i, j))
|
||||
if (is_inside && MON_AT(i, j))
|
||||
add_mon_to_reg(reg, g.level.monsters[i][j]);
|
||||
if (reg->visible) {
|
||||
/*block_point(i, j);*/
|
||||
if (is_inside)
|
||||
block_point(i, j);
|
||||
if (cansee(i, j))
|
||||
newsym(i, j);
|
||||
}
|
||||
@@ -371,6 +373,10 @@ run_regions(void)
|
||||
register int i, j, k;
|
||||
int f_indx;
|
||||
|
||||
/* reset some messaging variables */
|
||||
g.gas_cloud_diss_within = FALSE;
|
||||
g.gas_cloud_diss_seen = 0;
|
||||
|
||||
/* End of life ? */
|
||||
/* Do it backward because the array will be modified */
|
||||
for (i = g.n_regions - 1; i >= 0; i--) {
|
||||
@@ -407,6 +413,13 @@ run_regions(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g.gas_cloud_diss_within)
|
||||
pline_The("gas cloud around you dissipates.");
|
||||
if (g.gas_cloud_diss_seen)
|
||||
You_see("%s dissipate.",
|
||||
g.gas_cloud_diss_seen == 1
|
||||
? "a gas cloud" : "some gas clouds");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -952,6 +965,7 @@ expire_gas_cloud(genericptr_t p1, genericptr_t p2 UNUSED)
|
||||
{
|
||||
NhRegion *reg;
|
||||
int damage;
|
||||
xchar x, y;
|
||||
|
||||
reg = (NhRegion *) p1;
|
||||
damage = reg->arg.a_int;
|
||||
@@ -964,6 +978,21 @@ expire_gas_cloud(genericptr_t p1, genericptr_t p2 UNUSED)
|
||||
reg->ttl = 2L; /* Here's the trick : reset ttl */
|
||||
return FALSE; /* THEN return FALSE, means "still there" */
|
||||
}
|
||||
|
||||
/* The cloud no longer blocks vision. */
|
||||
for (x = reg->bounding_box.lx; x <= reg->bounding_box.hx; x++) {
|
||||
for (y = reg->bounding_box.ly; y <= reg->bounding_box.hy; y++) {
|
||||
if (inside_region(reg, x, y)) {
|
||||
if (!does_block(x, y, &levl[x][y]))
|
||||
unblock_point(x, y);
|
||||
if (x == u.ux && y == u.uy)
|
||||
g.gas_cloud_diss_within = TRUE;
|
||||
if (cansee(x, y))
|
||||
g.gas_cloud_diss_seen++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE; /* OK, it's gone, you can free it! */
|
||||
}
|
||||
|
||||
|
||||
14
src/vision.c
14
src/vision.c
@@ -134,14 +134,14 @@ vision_init(void)
|
||||
/*
|
||||
* does_block()
|
||||
*
|
||||
* Returns true if the level feature, object, or monster at (x,y) blocks
|
||||
* sight.
|
||||
* Returns true if something at (x,y) blocks sight.
|
||||
*/
|
||||
int
|
||||
does_block(int x, int y, struct rm *lev)
|
||||
{
|
||||
struct obj *obj;
|
||||
struct monst *mon;
|
||||
int i;
|
||||
|
||||
/* Features that block . . */
|
||||
if (IS_ROCK(lev->typ) || lev->typ == TREE
|
||||
@@ -163,6 +163,16 @@ does_block(int x, int y, struct rm *lev)
|
||||
&& is_lightblocker_mappear(mon))
|
||||
return 1;
|
||||
|
||||
/* Clouds (poisonous or not) block light. */
|
||||
for (i = 0; i < g.n_regions; i++) {
|
||||
/* Ignore regions with ttl == 0 - expire_gas_cloud must unblock its
|
||||
* points prior to being removed itself. */
|
||||
if (g.regions[i]->ttl > 0 && g.regions[i]->visible
|
||||
&& inside_region(g.regions[i], x, y)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user