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
+21 -4
View File
@@ -1,4 +1,4 @@
# NetHack 3.6 quest.txt $NHDT-Date: 1448540693 2015/11/26 12:24:53 $ $NHDT-Branch: master $:$NHDT-Revision: 1.32 $ # NetHack 3.6 quest.txt $NHDT-Date: 1505170340 2017/09/11 22:52:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.34 $
# Copyright (c) 1991 by M. Stephenson # Copyright (c) 1991 by M. Stephenson
# NetHack may be freely redistributed. See license for details. # NetHack may be freely redistributed. See license for details.
# #
@@ -27,9 +27,11 @@
# QT_FIRSTLOCATE 35 # QT_FIRSTLOCATE 35
# QT_NEXTLOCATE 36 # QT_NEXTLOCATE 36
# #
# QT_FIRSTACQUIRE 40 # QT_FIRSTGOAL 40 /* %n (nemesis) and %o (artifact) will always
# QT_NEXTACQUIRE 41 # be present on first visit in normal play */
# # QT_NEXTGOAL 41 /* subsequent visits to goal level */
# QT_ALTGOAL 42 /* alternate to NEXTGOAL if quest artifact
# is absent from the level (optional) */
# QT_FIRSTNEMESIS 50 # QT_FIRSTNEMESIS 50
# QT_NEXTNEMESIS 51 # QT_NEXTNEMESIS 51
# QT_OTHERNEMESIS 52 # QT_OTHERNEMESIS 52
@@ -195,6 +197,12 @@ You realize the feeling must be the presence of %o.
%Cp Arc 00041 %Cp Arc 00041
The familiar presence of %o is in the ether. The familiar presence of %o is in the ether.
%E %E
# delivered instead of 00041 if %o is not on the level anymore;
# hero might already be carrying it, so don't say anything like
# "%o's presence can't be felt"
%Cp Arc 00042
The have returned to %ns lair.
%E
%Cc Arc 00050 %Cc Arc 00050
"So, %p, you think that you can succeed in recovering "So, %p, you think that you can succeed in recovering
%o, when your teacher, %l, has already failed. %o, when your teacher, %l, has already failed.
@@ -2463,6 +2471,9 @@ proudly again. Putting your kami in the hands of fate, you advance.
As you arrive once again at the home of %n, your thoughts As you arrive once again at the home of %n, your thoughts
turn only to %o. turn only to %o.
%E %E
%Cp Sam 00042
As you arrive once again at the home of %n.
%E
%Cp Sam 00050 %Cp Sam 00050
"Ah, so it is to be you, %p-san. I offer you seppuku. "Ah, so it is to be you, %p-san. I offer you seppuku.
I will be your second if you wish." I will be your second if you wish."
@@ -2713,6 +2724,9 @@ You sense the presence of %o.
You gain confidence, knowing that you may soon be united with You gain confidence, knowing that you may soon be united with
%o. %o.
%E %E
%Cp Tou 00042
You have returned to %ns lair.
%E
%Cc Tou 00050 %Cc Tou 00050
"So, %p, %l thinks that you can wrest "So, %p, %l thinks that you can wrest
%o from me! %o from me!
@@ -3207,6 +3221,9 @@ You feel your mentor's presence; perhaps %o is nearby.
%Cp Wiz 00041 %Cp Wiz 00041
The aura of %o tingles at the edge of your perception. The aura of %o tingles at the edge of your perception.
%E %E
%Cp Wiz 00042
You have returned to %ns lair.
%E
%Cc Wiz 00050 %Cc Wiz 00050
"Ah, I recognize you, %p. So, %l has sent you to steal "Ah, I recognize you, %p. So, %l has sent you to steal
%o from me, hmmm? Well, %lh is a fool to send such %o from me, hmmm? Well, %lh is a fool to send such
+3
View File
@@ -426,6 +426,9 @@ when polymorphed into something with a passive counterattack, being 'killed'
continue after telling the player than the hero has reverted; change continue after telling the player than the hero has reverted; change
"Mon is splashed by your acid" to "Mon is splashed by acid" in that "Mon is splashed by your acid" to "Mon is splashed by acid" in that
situation so that the message sequence doesn't look quite so strange situation so that the message sequence doesn't look quite so strange
when returning to quest nemesis' level, the message for some roles (A,S,T,W)
referred to sensing presence of the quest artifact even if had been
removed from that level; give an alternate message in that situation
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
+2 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1502753404 2017/08/14 23:30:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.600 $ */ /* NetHack 3.6 extern.h $NHDT-Date: 1505170345 2017/09/11 22:52:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.604 $ */
/* Copyright (c) Steve Creps, 1988. */ /* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1957,6 +1957,7 @@ E void NDECL(unload_qtlist);
E short FDECL(quest_info, (int)); E short FDECL(quest_info, (int));
E const char *NDECL(ldrname); E const char *NDECL(ldrname);
E boolean FDECL(is_quest_artifact, (struct obj *)); E boolean FDECL(is_quest_artifact, (struct obj *));
E struct obj *FDECL(find_quest_artifact, (unsigned));
E void FDECL(com_pager, (int)); E void FDECL(com_pager, (int));
E void FDECL(qt_pager, (int)); E void FDECL(qt_pager, (int));
E struct permonst *NDECL(qt_montype); E struct permonst *NDECL(qt_montype);
+2 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 qtext.h $NHDT-Date: 1432594167 2015/05/25 22:49:27 $ $NHDT-Branch: master $:$NHDT-Revision: 1.17 $ */ /* NetHack 3.6 qtext.h $NHDT-Date: 1505170347 2017/09/11 22:52:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.18 $ */
/* Copyright (c) Mike Stephenson 1991. */ /* Copyright (c) Mike Stephenson 1991. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -83,6 +83,7 @@ struct qtlists {
#define QT_FIRSTGOAL 40 #define QT_FIRSTGOAL 40
#define QT_NEXTGOAL 41 #define QT_NEXTGOAL 41
#define QT_ALTGOAL 42 /* alternate to QT_NEXTGOAL if artifact is absent */
#define QT_FIRSTNEMESIS 50 #define QT_FIRSTNEMESIS 50
#define QT_NEXTNEMESIS 51 #define QT_NEXTNEMESIS 51
+16 -2
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 */ /* Copyright 1991, M. Stephenson */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -68,7 +68,20 @@ on_goal()
qt_pager(QT_FIRSTGOAL); qt_pager(QT_FIRSTGOAL);
Qstat(made_goal) = 1; Qstat(made_goal) = 1;
} else { } 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) if (Qstat(made_goal) < 7)
Qstat(made_goal)++; Qstat(made_goal)++;
} }
@@ -179,6 +192,7 @@ boolean seal;
schedule_goto(dest, FALSE, FALSE, portal_flag, (char *) 0, (char *) 0); schedule_goto(dest, FALSE, FALSE, portal_flag, (char *) 0, (char *) 0);
if (seal) { /* remove the portal to the quest - sealing it off */ if (seal) { /* remove the portal to the quest - sealing it off */
int reexpelled = u.uevent.qexpelled; int reexpelled = u.uevent.qexpelled;
u.uevent.qexpelled = 1; u.uevent.qexpelled = 1;
remdun_mapseen(quest_dnum); remdun_mapseen(quest_dnum);
/* Delete the near portal now; the far (main dungeon side) /* Delete the near portal now; the far (main dungeon side)
+66 -2
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 */ /* Copyright 1991, M. Stephenson */
/* NetHack may be freely redistributed. See license for details. */ /* 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 void FDECL(Fread, (genericptr_t, int, int, dlb *));
STATIC_DCL struct qtmsg *FDECL(construct_qtlist, (long)); STATIC_DCL struct qtmsg *FDECL(construct_qtlist, (long));
STATIC_DCL const char *NDECL(intermed); 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(neminame);
STATIC_DCL const char *NDECL(guardname); STATIC_DCL const char *NDECL(guardname);
STATIC_DCL const char *NDECL(homebase); STATIC_DCL const char *NDECL(homebase);
@@ -196,6 +197,58 @@ struct obj *otmp;
return (boolean) (otmp->oartifact == urole.questarti); 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 */ /* return your role nemesis' name */
STATIC_OVL const char * STATIC_OVL const char *
neminame() neminame()
@@ -573,7 +626,18 @@ int msgnum;
if (skip_pager(FALSE)) if (skip_pager(FALSE))
return; 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); impossible("qt_pager: message %d not found.", msgnum);
return; return;
} }