]> granicus.if.org Git - nethack/commitdiff
Planes of Water and Air
authorPatR <rankin@nethack.org>
Fri, 31 May 2019 10:42:06 +0000 (03:42 -0700)
committerPatR <rankin@nethack.org>
Fri, 31 May 2019 10:42:06 +0000 (03:42 -0700)
Make the Plane of Water be water all the way to edge instead of having
stone on left, top, and right.  The Plane of Air already has air all
the way to edge (including unused/unuseable column #0) but does so via
code rather than the level description file so Water does that now too.

The edges of the Plane of Air were cloudless (3 columns on the left,
2 rows on the top, and 2 columns on the right; don't recall about the
bottom) and that looked pretty strange.  Those rows and columns are
beyond the range of bubble/cloud movement so just make some of those
spots randomly be sight-blocking cloud terrain instead of all open air.
It isn't integrated with the moving clouds but looks fairly good when
the hero moves along the edge of the level.

Using wizard mode to leave Water or Air and later return resulted in
no clouds on the Air level and bubbles as usual on the Water level.
I still don't understand why, but on return to those levels run the
bubble creation routine as if the old discarded bubbles or clouds were
being restored.

doc/fixes36.3
src/do.c
src/mkmaze.c

index 640903d5b872680bd088611affce3051dbe96110..fbb80dd0768f95b337d44403ca71b137904b2f44 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.27 $ $NHDT-Date: 1559130050 2019/05/29 11:40:50 $
+$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.28 $ $NHDT-Date: 1559299314 2019/05/31 10:41:54 $
 
 This fixes36.3 file is here to capture information about updates in the 3.6.x
 lineage following the release of 3.6.2 in May 2019. Please note, however,
@@ -33,6 +33,8 @@ if hero dies while a thrown or kicked object is in transit, put that object
 fix a memory leak that occurred if player used wizard mode to leave and return
        to the Plane of Air or Plane of Water (not possible in normal play)
 free sortloot data if object handling is short-circuited by cockatrice corpse
+on the Plane of Water, make water go all the way to the edges of the level
+on the Plane of Air, make clouds disrupt line of sight along the edges
 
 
 Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
index 9c887c037b6ce8b95489a680e5bdfdd0b72dcbcb..c899676ef97169bd954d3fcbe44766a4038516b6 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -1,4 +1,4 @@
-/* NetHack 3.6 do.c    $NHDT-Date: 1559088523 2019/05/29 00:08:43 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.190 $ */
+/* NetHack 3.6 do.c    $NHDT-Date: 1559299314 2019/05/31 10:41:54 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.191 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1374,7 +1374,7 @@ boolean at_stairs, falling, portal;
        created instead), we need to discard them to avoid a memory leak;
        so bubbles are now discarded as we leave the level they're used on */
     if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz))
-        save_waterlevel(fd, FREE_SAVE); /* note: doesn't use 'fd' */
+        save_waterlevel(-1, FREE_SAVE);
     bclose(fd);
     if (cant_go_back) {
         /* discard unreachable levels; keep #0 */
@@ -1434,6 +1434,11 @@ boolean at_stairs, falling, portal;
         reseed_random(rn2_on_display_rng);
         minit(); /* ZEROCOMP */
         getlev(fd, hackpid, new_ledger, FALSE);
+        /* when in wizard mode, it is possible to leave from and return to
+           any level in the endgame; above, we discarded bubble/cloud info
+           when leaving Plane of Water or Air so recreate some now */
+        if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz))
+            restore_waterlevel(-1);
         (void) nhclose(fd);
         oinit(); /* reassign level dependent obj probabilities */
     }
index a660faf99b063c6b6eca7080c8ff132c039aa836..bdab684ef39fed12ba4a606d554e1fcc315938d0 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 mkmaze.c        $NHDT-Date: 1559227829 2019/05/30 14:50:29 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.72 $ */
+/* NetHack 3.6 mkmaze.c        $NHDT-Date: 1559299316 2019/05/31 10:41:56 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.73 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Pasi Kallinen, 2018. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1493,10 +1493,22 @@ movebubbles()
                     }
         }
     } else if (Is_airlevel(&u.uz)) {
-        for (x = 0; x < COLNO; x++)
-            for (y = 0; y < ROWNO; y++) {
+        boolean xedge, yedge;
+
+        for (x = 1; x <= (COLNO - 1); x++)
+            for (y = 0; y <= (ROWNO - 1); y++) {
                 levl[x][y] = air_pos;
                 unblock_point(x, y);
+                /* all air or all cloud around the perimeter of the Air
+                   level tends to look strange; break up the pattern */
+                xedge = (boolean) (x < bxmin || x > bxmax);
+                yedge = (boolean) (y < bymin || y > bymax);
+                if (xedge || yedge) {
+                    if (!rn2(xedge ? 3 : 5)) {
+                        levl[x][y].typ = CLOUD;
+                        block_point(x, y);
+                    }
+                }
             }
     }
 
@@ -1589,6 +1601,14 @@ int fd;
     if (!Is_waterlevel(&u.uz) && !Is_airlevel(&u.uz))
         return;
 
+    if (fd == -1) { /* special handling for restore in goto_level() */
+        if (!wizard)
+            impossible("restore_waterlevel: returning to %s?",
+                       Is_waterlevel(&u.uz) ? "Water" : "Air");
+        setup_waterlevel();
+        return;
+    }
+
     set_wportal();
     mread(fd, (genericptr_t) &n, sizeof n);
     mread(fd, (genericptr_t) &xmin, sizeof xmin);
@@ -1655,26 +1675,37 @@ set_wportal()
 STATIC_OVL void
 setup_waterlevel()
 {
-    int x, y;
-    int xskip, yskip;
-    int water_glyph = cmap_to_glyph(S_water),
-        air_glyph = cmap_to_glyph(S_air);
+    int x, y, xskip, yskip, typ, glyph;
 
-    /* ouch, hardcoded... */
+    if (!Is_waterlevel(&u.uz) && !Is_airlevel(&u.uz))
+        panic("setup_waterlevel(): [%d:%d] neither 'Water' nor 'Air'",
+              (int) u.uz.dnum, (int) u.uz.dlevel);
 
+    /* ouch, hardcoded... (file scope statics and used in bxmin,bymax,&c) */
     xmin = 3;
     ymin = 1;
+    /* use separate statements so that compiler won't complain about min()
+       comparing two constants; the alternative is to do this in the
+       preprocessor: #if (20 > ROWNO-1) ymax=ROWNO-1 #else ymax=20 #endif */
     xmax = 78;
+    xmax = min(xmax, (COLNO - 1) - 1);
     ymax = 20;
-
-    /* set hero's memory to water */
-
-    for (x = xmin; x <= xmax; x++)
-        for (y = ymin; y <= ymax; y++)
-            levl[x][y].glyph = Is_waterlevel(&u.uz) ? water_glyph : air_glyph;
+    ymax = min(ymax, (ROWNO - 1));
+
+    /* entire level is remembered as one glyph and any unspecified portion
+       should default to level's base element rather than to usual stone */
+    glyph = cmap_to_glyph(Is_waterlevel(&u.uz) ? S_water : S_air);
+    typ = Is_waterlevel(&u.uz) ? WATER : AIR;
+
+    /* set unspecified terrain (stone) and hero's memory to water or air */
+    for (x = 1; x <= COLNO - 1; x++)
+        for (y = 0; y <= ROWNO - 1; y++) {
+            levl[x][y].glyph = glyph;
+            if (levl[x][y].typ == STONE)
+                levl[x][y].typ = typ;
+        }
 
     /* make bubbles */
-
     if (Is_waterlevel(&u.uz)) {
         xskip = 10 + rn2(10);
         yskip = 4 + rn2(4);
@@ -1694,7 +1725,6 @@ unsetup_waterlevel()
     struct bubble *b, *bb;
 
     /* free bubbles */
-
     for (b = bbubbles; b; b = bb) {
         bb = b->next;
         free((genericptr_t) b);
@@ -1713,14 +1743,15 @@ int x, y, n;
      * in situ, either.  The first two elements tell the dimensions of
      * the bubble's bounding box.
      */
-    static uchar bm2[] = { 2, 1, 0x3 },
-                 bm3[] = { 3, 2, 0x7, 0x7 },
-                 bm4[] = { 4, 3, 0x6, 0xf, 0x6 },
-                 bm5[] = { 5, 3, 0xe, 0x1f, 0xe },
-                 bm6[] = { 6, 4, 0x1e, 0x3f, 0x3f, 0x1e },
-                 bm7[] = { 7, 4, 0x3e, 0x7f, 0x7f, 0x3e },
-                 bm8[] = { 8, 4, 0x7e, 0xff, 0xff, 0x7e },
-                 *bmask[] = { bm2, bm3, bm4, bm5, bm6, bm7, bm8 };
+    static const uchar
+        bm2[] = { 2, 1, 0x3 },
+        bm3[] = { 3, 2, 0x7, 0x7 },
+        bm4[] = { 4, 3, 0x6, 0xf, 0x6 },
+        bm5[] = { 5, 3, 0xe, 0x1f, 0xe },
+        bm6[] = { 6, 4, 0x1e, 0x3f, 0x3f, 0x1e },
+        bm7[] = { 7, 4, 0x3e, 0x7f, 0x7f, 0x3e },
+        bm8[] = { 8, 4, 0x7e, 0xff, 0xff, 0x7e },
+        *const bmask[] = { bm2, bm3, bm4, bm5, bm6, bm7, bm8 };
     struct bubble *b;
 
     if (x >= bxmax || y >= bymax)
@@ -1911,7 +1942,8 @@ boolean ini;
         b->dy = -b->dy;
         break;
     case 3:
-        b->dy = -b->dy; /* fall through */
+        b->dy = -b->dy;
+        /*FALLTHRU*/
     case 2:
         b->dx = -b->dx;
         break;