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