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 <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+.
This commit is contained in:
PatR
2019-06-11 09:29:14 -07:00
parent fea4fd0e00
commit 9125b5943e
3 changed files with 68 additions and 8 deletions

View 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

View 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;

View 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);
}