fix #HH5887 - Dark One / Eye message bug

Some roles' quest message when returning the nemesis lair refer to
sensing the presence/aura/whatever of the quest artifact, but it might
not be there anymore.  In reported case, the nemesis had picked it up
and later fled up the stairs to another level.  Other situations are
possible; it's feasible for the hero to already have it.  So provide
an alternate message, and some extra code to decide whether to use it.

Other anomalous messages, such as looking down on the dead body of a
nemesis who didn't leave a corpse, can still occur.
This commit is contained in:
PatR
2017-09-11 15:59:50 -07:00
parent d8f4c14c06
commit 2b8c2eac23
6 changed files with 110 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 quest.c $NHDT-Date: 1446191878 2015/10/30 07:57:58 $ $NHDT-Branch: master $:$NHDT-Revision: 1.20 $ */
/* NetHack 3.6 quest.c $NHDT-Date: 1505170343 2017/09/11 22:52:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.21 $ */
/* Copyright 1991, M. Stephenson */
/* NetHack may be freely redistributed. See license for details. */
@@ -68,7 +68,20 @@ on_goal()
qt_pager(QT_FIRSTGOAL);
Qstat(made_goal) = 1;
} else {
qt_pager(QT_NEXTGOAL);
/*
* Some QT_NEXTGOAL messages reference the quest artifact;
* find out if it is still present. If not, request an
* alternate message (qt_pager() will revert to delivery
* of QT_NEXTGOAL if current role doesn't have QT_ALTGOAL).
* Note: if hero is already carrying it, it is treated as
* being absent from the level for quest message purposes.
*/
unsigned whichobjchains = ((1 << OBJ_FLOOR)
| (1 << OBJ_MINVENT)
| (1 << OBJ_BURIED));
struct obj *qarti = find_quest_artifact(whichobjchains);
qt_pager(qarti ? QT_NEXTGOAL : QT_ALTGOAL);
if (Qstat(made_goal) < 7)
Qstat(made_goal)++;
}
@@ -179,6 +192,7 @@ boolean seal;
schedule_goto(dest, FALSE, FALSE, portal_flag, (char *) 0, (char *) 0);
if (seal) { /* remove the portal to the quest - sealing it off */
int reexpelled = u.uevent.qexpelled;
u.uevent.qexpelled = 1;
remdun_mapseen(quest_dnum);
/* Delete the near portal now; the far (main dungeon side)

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 questpgr.c $NHDT-Date: 1448541043 2015/11/26 12:30:43 $ $NHDT-Branch: master $:$NHDT-Revision: 1.36 $ */
/* NetHack 3.6 questpgr.c $NHDT-Date: 1505170344 2017/09/11 22:52:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.37 $ */
/* Copyright 1991, M. Stephenson */
/* NetHack may be freely redistributed. See license for details. */
@@ -22,6 +22,7 @@ static void NDECL(dump_qtlist);
static void FDECL(Fread, (genericptr_t, int, int, dlb *));
STATIC_DCL struct qtmsg *FDECL(construct_qtlist, (long));
STATIC_DCL const char *NDECL(intermed);
STATIC_DCL struct obj *FDECL(find_qarti, (struct obj *));
STATIC_DCL const char *NDECL(neminame);
STATIC_DCL const char *NDECL(guardname);
STATIC_DCL const char *NDECL(homebase);
@@ -196,6 +197,58 @@ struct obj *otmp;
return (boolean) (otmp->oartifact == urole.questarti);
}
STATIC_OVL struct obj *
find_qarti(ochain)
struct obj *ochain;
{
struct obj *otmp, *qarti;
for (otmp = ochain; otmp; otmp = otmp->nobj) {
if (is_quest_artifact(otmp))
return otmp;
if (Has_contents(otmp) && (qarti = find_qarti(otmp->cobj)) != 0)
return qarti;
}
return (struct obj *) 0;
}
/* check several object chains for the quest artifact to determine
whether it is present on the current level */
struct obj *
find_quest_artifact(whichchains)
unsigned whichchains;
{
struct monst *mtmp;
struct obj *qarti = 0;
if ((whichchains & (1 << OBJ_INVENT)) != 0)
qarti = find_qarti(invent);
if (!qarti && (whichchains & (1 << OBJ_FLOOR)) != 0)
qarti = find_qarti(fobj);
if (!qarti && (whichchains & (1 << OBJ_MINVENT)) != 0)
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp))
continue;
if ((qarti = find_qarti(fmon->minvent)) != 0)
break;
}
if (!qarti && (whichchains & (1 << OBJ_MIGRATING)) != 0) {
/* check migrating objects and minvent of migrating monsters */
for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp))
continue;
if ((qarti = find_qarti(fmon->minvent)) != 0)
break;
}
if (!qarti)
qarti = find_qarti(migrating_objs);
}
if (!qarti && (whichchains & (1 << OBJ_BURIED)) != 0)
qarti = find_qarti(level.buriedobjlist);
return qarti;
}
/* return your role nemesis' name */
STATIC_OVL const char *
neminame()
@@ -573,7 +626,18 @@ int msgnum;
if (skip_pager(FALSE))
return;
if (!(qt_msg = msg_in(qt_list.chrole, msgnum))) {
qt_msg = msg_in(qt_list.chrole, msgnum);
if (!qt_msg) {
/* some roles have an alternate message for return to the goal
level when the quest artifact is absent (handled by caller)
but some don't; for the latter, use the normal goal message;
note: for first visit, artifact is assumed to always be
present which might not be true for wizard mode but we don't
worry about quest message references in that situation */
if (msgnum == QT_ALTGOAL)
qt_msg = msg_in(qt_list.chrole, QT_NEXTGOAL);
}
if (!qt_msg) {
impossible("qt_pager: message %d not found.", msgnum);
return;
}