]> granicus.if.org Git - nethack/commitdiff
adopt pull request #328 - steam clouds
authorPatR <rankin@nethack.org>
Fri, 17 Apr 2020 21:56:47 +0000 (14:56 -0700)
committerPatR <rankin@nethack.org>
Fri, 17 Apr 2020 21:56:47 +0000 (14:56 -0700)
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

doc/fixes37.0
src/fountain.c
src/region.c
src/zap.c

index 681fc31a3ec98848de7ad719128db910c0a3ec25..a88a792092c742fa8402b7768e6a6622418e8d57 100644 (file)
@@ -268,6 +268,7 @@ wizard mode #wizborn command
 include more skill information in ^X output when dual-wielding
 item-using monsters will zap wand of undead turning at corpse-wielding hero
        when the corpse is harmful
+boiling a pool or fountain now creates a temporary cloud of steam
 
 
 Platform- and/or Interface-Specific New Features
index 8d6d3de101428b46fc561f23bbaf1d4be17dc166..14b5a5a9fb19f3abe6f01af447500ef85f98a458 100644 (file)
@@ -204,15 +204,22 @@ boolean isyou;
             if (yn("Dry up fountain?") == 'n')
                 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 */
         levl[x][y].typ = ROOM, levl[x][y].flags = 0;
         levl[x][y].blessedftn = 0;
-        if (cansee(x, y))
-            pline_The("fountain dries up!");
+        g.level.flags.nfountains--;
         /* The location is seen if the hero/monster is invisible
            or felt if the hero is blind. */
         newsym(x, y);
-        g.level.flags.nfountains--;
         if (isyou && in_town(x, y))
             (void) angry_guards(FALSE);
     }
index b1fefd649cfe58cfed97196827821b15595689a3..9dfe9150d4aaccff04af9cd459e91375e75821a0 100644 (file)
@@ -310,8 +310,11 @@ NhRegion *reg;
                 continue;
             if (MON_AT(i, j) && inside_region(reg, i, j))
                 add_mon_to_reg(reg, g.level.monsters[i][j]);
-            if (reg->visible && cansee(i, j))
-                newsym(i, j);
+            if (reg->visible) {
+                /*block_point(i, j);*/
+                if (cansee(i, j))
+                    newsym(i, j);
+            }
         }
     /* Check for player now... */
     if (inside_region(reg, u.ux, u.uy))
@@ -345,8 +348,12 @@ NhRegion *reg;
     if (reg->visible)
         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 (isok(x, y) && inside_region(reg, x, y) && cansee(x, y))
-                    newsym(x, y);
+                if (isok(x, y) && inside_region(reg, x, y)) {
+                    /*if (!sobj_at(BOULDER, x, y))
+                          unblock_point(x, y);*/
+                    if (cansee(x, y))
+                        newsym(x, y);
+                }
 
     free_region(reg);
 }
@@ -532,7 +539,8 @@ update_player_regions()
     register int 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]);
         else
             clear_hero_inside(g.regions[i]);
@@ -996,23 +1004,25 @@ genericptr_t p2 UNUSED;
     return TRUE; /* OK, it's gone, you can free it! */
 }
 
+/* returns True if p2 is killed by region p1, False otherwise */
 boolean
 inside_gas_cloud(p1, p2)
 genericptr_t p1;
 genericptr_t p2;
 {
-    NhRegion *reg;
-    struct monst *mtmp;
-    int dam;
+    NhRegion *reg = (NhRegion *) p1;
+    struct monst *mtmp = (struct monst *) p2;
+    int dam = reg->arg.a_int;
 
     /*
      * Gas clouds can't be targetted at water locations, but they can
      * start next to water and spread over it.
      */
 
-    reg = (NhRegion *) p1;
-    dam = reg->arg.a_int;
-    if (p2 == (genericptr_t) 0) { /* This means *YOU* Bozo! */
+    if (dam < 1)
+        return FALSE; /* if no damage then there's nothing to do here... */
+
+    if (!mtmp) { /* hero is indicated by Null rather than by &youmonst */
         if (m_poisongas_ok(&g.youmonst) == M_POISONGAS_OK)
             return FALSE;
         if (!Blind) {
index 52c65cb34e58597e39f80cf7ad7612078a38c848..a0d3807c1b83e2bbe9d13d4a57a51e18e1493054 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -4475,21 +4475,29 @@ short exploding_wand_typ;
         if (is_ice(x, y)) {
             melt_ice(x, y, (char *) 0);
         } else if (is_pool(x, y)) {
+            boolean on_water_level = Is_waterlevel(&u.uz);
             const char *msgtxt = (!Deaf)
-                                     ? "You hear hissing gas." /* Deaf-aware */
-                                     : (type >= 0)
-                                         ? "That seemed remarkably uneventful."
-                                         : (const char *) 0;
-
-            if (lev->typ != POOL) { /* MOAT or DRAWBRIDGE_UP */
-                if (see_it)
+                                 ? "You hear hissing gas." /* Deaf-aware */
+                                 : (type >= 0)
+                                   ? "That seemed remarkably uneventful."
+                                   : (char *) 0;
+
+            /* don't create steam clouds on Plane of Water; air bubble
+               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.";
             } else {
                 rangemod -= 3;
                 lev->typ = ROOM, lev->flags = 0;
                 t = maketrap(x, y, PIT);
-                if (t)
-                    t->tseen = 1;
+                /*if (t) -- this was before the vapor cloud was added --
+                      t->tseen = 1;*/
                 if (see_it)
                     msgtxt = "The water evaporates.";
             }
@@ -4498,6 +4506,7 @@ short exploding_wand_typ;
             if (lev->typ == ROOM)
                 newsym(x, y);
         } else if (IS_FOUNTAIN(lev->typ)) {
+            create_gas_cloud(x, y, rnd(2), 0); /* radius 1..2, no damage */
             if (see_it)
                 pline("Steam billows from the fountain.");
             rangemod -= 1;