From: PatR Date: Tue, 11 Jun 2019 16:29:14 +0000 (-0700) Subject: 3.7: automatic annotation for vibrating square X-Git-Tag: NetHack-3.7.0_WIP~374 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9125b5943e1ad26250cc89f4bda29e9566b1151f;p=nethack 3.7: automatic annotation for vibrating square 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 at ." 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+. --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 8e034afad..2cd323116 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -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 diff --git a/include/dungeon.h b/include/dungeon.h index 197d42ae9..4037511e4 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -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; diff --git a/src/dungeon.c b/src/dungeon.c index 8cf395abe..2701731ef 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -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); }