]> granicus.if.org Git - nethack/commitdiff
3.7: automatic annotation for vibrating square
authorPatR <rankin@nethack.org>
Tue, 11 Jun 2019 16:29:14 +0000 (09:29 -0700)
committerPatR <rankin@nethack.org>
Tue, 11 Jun 2019 16:29:14 +0000 (09:29 -0700)
Add "Gateway to Moloch's Sanctum" to the vibrating square level if you
step on the square or detect/magic map it as a pseudo-trap, an extra
hint for players who manage to get that far but then don't know what
to do next.  (I think I may also add a randomly placed floor engraving
along the lines of "For a good time, consult the Oracle of Delphi."
as a gag variant of "For a good time, call <name> at <phone number>."
Not very thematic for Gehennom but could conceivably nudge someone in
the right direction.  But it could give away the level for experienced
players who haven't located the vibrating square yet.)

The annotation sticks until the one for "Moloch's Sanctum" gets added.
That happens when the temple on the sanctum level is entered or the
altar there has become mapped (in view or via magic mapping).

Could break existing 3.7.0- save files (but probably won't, since
at least two bits were available unless using an ancient 'Bitfield()
allocates whole bytes' configuration).  That's the reason I didn't
put this into 3.6.2+.

doc/fixes37.0
include/dungeon.h
src/dungeon.c

index 8e034afad8c12c4778958e9984e3e629e93584c9..2cd32311637ba676a9cd4c6f96349bf7b695901a 100644 (file)
@@ -3,6 +3,10 @@ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ $NHDT-Date: 1557663358 2019/05
 General Fixes and Modified Features
 -----------------------------------
 fix compile when DLB isn't defined
+hero polymorphed into a vampire can use #monster to shape-shift rather than
+       just do a one-shot polymorph into bat/cloud/wolf and shifted vampire
+       hero can use #monster again to take on another form (randomly chosen
+       among the shiftable shapes and true vampire form)
 
 
 Fixes to Pre-3.7.0 Problems that Were Exposed Via git Repository
@@ -17,6 +21,9 @@ General New Features
 --------------------
 if a killer bee encounters a lump of royal jelly and there is no queen bee on
        the level, the bee will eat the jelly and become a new queen
+automatic annotation "gateway to Moloch's Sanctum" for vibrating square level
+       once that square's location becomes known (found or magic mapped);
+       goes away once sanctum temple is found (entered or high altar mapped)
 
 
 Platform- and/or Interface-Specific New Features
index 197d42ae9988e8a932846e4bb723138cba3dbde8..4037511e4b91133bfad1a4b7c3d961197eb352b8 100644 (file)
@@ -237,6 +237,13 @@ typedef struct mapseen {
            questing is for quest home (level 1) */
         Bitfield(quest_summons, 1); /* heard summons from leader */
         Bitfield(questing, 1); /* quest leader has unlocked quest stairs */
+        /* "gateway to sanctum" */
+        Bitfield(vibrating_square, 1); /* found vibrating square 'trap';
+                                        * flag cleared once the msanctum
+                                        * annotation has been added (on
+                                        * the next dungeon level; temple
+                                        * entered or high altar mapped) */
+        Bitfield(spare1, 1); /* not used */
     } flags;
     /* custom naming */
     char *custom;
index 8cf395abee7faf39f52995e79cf4d195a72200ff..2701731efe05b7363853e1ad2c489a9b8bdf31df 100644 (file)
@@ -1702,11 +1702,12 @@ const char *nam;
         if (idx >= 0) {
             idxtoo = (idx >> 8) & 0x00FF;
             idx &= 0x00FF;
-            if (/* either wizard mode, or else _both_ sides of branch seen */
-                wizard
-                || ((g.level_info[idx].flags & (FORGOTTEN | VISITED)) == VISITED
-                    && (g.level_info[idxtoo].flags & (FORGOTTEN | VISITED))
-                           == VISITED)) {
+            /* either wizard mode, or else _both_ sides of branch seen */
+            if (wizard
+                || (((g.level_info[idx].flags & (FORGOTTEN | VISITED))
+                     == VISITED)
+                    && ((g.level_info[idxtoo].flags & (FORGOTTEN | VISITED))
+                        == VISITED))) {
                 if (ledger_to_dnum(idxtoo) == u.uz.dnum)
                     idx = idxtoo;
                 dlev.dnum = ledger_to_dnum(idx);
@@ -2369,7 +2370,8 @@ mapseen *mptr;
         return FALSE;
     /* level is of interest if it has an auto-generated annotation */
     if (mptr->flags.oracle || mptr->flags.bigroom || mptr->flags.roguelevel
-        || mptr->flags.castle || mptr->flags.valley || mptr->flags.msanctum
+        || mptr->flags.castle || mptr->flags.valley
+        || mptr->flags.msanctum || mptr->flags.vibrating_square
         || mptr->flags.quest_summons || mptr->flags.questing)
         return TRUE;
     /* when in Sokoban, list all sokoban levels visited; when not in it,
@@ -2400,9 +2402,10 @@ mapseen *mptr;
 void
 recalc_mapseen()
 {
-    mapseen *mptr;
+    mapseen *mptr, *oth_mptr;
     struct monst *mtmp;
     struct cemetery *bp, **bonesaddr;
+    struct trap *t;
     unsigned i, ridx;
     int x, y, ltyp, count, atmp;
 
@@ -2443,7 +2446,7 @@ recalc_mapseen()
     mptr->flags.roguelevel = Is_rogue_level(&u.uz);
     mptr->flags.oracle = 0; /* recalculated during room traversal below */
     mptr->flags.castletune = 0;
-    /* flags.castle, flags.valley, flags.msanctum retain previous value */
+    /* flags.castle retains previous value */
     mptr->flags.forgot = 0;
     /* flags.quest_summons disabled once quest finished */
     mptr->flags.quest_summons = (at_dgn_entrance("The Quest")
@@ -2453,6 +2456,7 @@ recalc_mapseen()
                                       || g.quest_status.leader_is_dead));
     mptr->flags.questing = (on_level(&u.uz, &qstart_level)
                             && g.quest_status.got_quest);
+    /* flags.msanctum, .valley, and .vibrating_square handled below */
 
     /* track rooms the hero is in */
     for (i = 0; i < SIZE(u.urooms); ++i) {
@@ -2633,6 +2637,46 @@ recalc_mapseen()
         }
     }
 
+    /* Moloch's Sanctum and the Valley of the Dead are normally given an
+       automatic annotation when you enter a temple attended by a priest,
+       but it is possible for the priest to be killed prior to that; we
+       assume that both of those levels only contain one altar, so add the
+       annotation if that altar has been mapped (seen or magic mapping) */
+    if (Is_valley(&u.uz)) {
+        /* don't clear valley if naltar==0; maybe altar got destroyed? */
+        if (mptr->feat.naltar > 0)
+            mptr->flags.valley = 1;
+
+    /* Sanctum and Gateway-to-Sanctum are mutually exclusive automatic
+       annotations but handling that is tricky because they're stored
+       with data for different levels */
+    } else if (Is_sanctum(&u.uz)) {
+        if (mptr->feat.naltar > 0)
+            mptr->flags.msanctum = 1;
+
+        if (mptr->flags.msanctum) {
+            d_level invocat_lvl;
+
+            invocat_lvl = u.uz;
+            invocat_lvl.dlevel -= 1;
+            if ((oth_mptr = find_mapseen(&invocat_lvl)) != 0)
+                oth_mptr->flags.vibrating_square = 0;
+        }
+    } else if (Invocation_lev(&u.uz)) {
+        /* annotate vibrating square's level if vibr_sqr 'trap' has been
+           found or if that trap is gone (indicating that invocation has
+           happened) provided that the sanctum's annotation hasn't been
+           added (either hero hasn't descended to that level yet or hasn't
+           mapped its temple) */
+        for (t = g.ftrap; t; t = t->ntrap)
+            if (t->ttyp == VIBRATING_SQUARE)
+                break;
+        mptr->flags.vibrating_square = t ? t->tseen
+                      /* no trap implies that invocation has been performed */
+                             : ((oth_mptr = find_mapseen(&sanctum_level)) == 0
+                                || !oth_mptr->flags.msanctum);
+    }
+
     if (g.level.bonesinfo && !mptr->final_resting_place) {
         /* clone the bonesinfo so we aren't dependent upon this
            level being in memory */
@@ -3042,6 +3086,8 @@ boolean printdun;
         Sprintf(buf, "%sThe castle%s.", PREFIX, tunesuffix(mptr, tmpbuf));
     } else if (mptr->flags.valley) {
         Sprintf(buf, "%sValley of the Dead.", PREFIX);
+    } else if (mptr->flags.vibrating_square) {
+        Sprintf(buf, "%sGateway to Moloch's Sanctum.", PREFIX);
     } else if (mptr->flags.msanctum) {
         Sprintf(buf, "%sMoloch's Sanctum.", PREFIX);
     }