diff --git a/dat/quest.txt b/dat/quest.txt index 58dc9d1cb..64bde2fe3 100644 --- a/dat/quest.txt +++ b/dat/quest.txt @@ -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 # NetHack may be freely redistributed. See license for details. # @@ -27,9 +27,11 @@ # QT_FIRSTLOCATE 35 # QT_NEXTLOCATE 36 # -# QT_FIRSTACQUIRE 40 -# QT_NEXTACQUIRE 41 -# +# QT_FIRSTGOAL 40 /* %n (nemesis) and %o (artifact) will always +# 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_NEXTNEMESIS 51 # QT_OTHERNEMESIS 52 @@ -195,6 +197,12 @@ You realize the feeling must be the presence of %o. %Cp Arc 00041 The familiar presence of %o is in the ether. %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 "So, %p, you think that you can succeed in recovering %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 turn only to %o. %E +%Cp Sam 00042 +As you arrive once again at the home of %n. +%E %Cp Sam 00050 "Ah, so it is to be you, %p-san. I offer you seppuku. 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 %o. %E +%Cp Tou 00042 +You have returned to %ns lair. +%E %Cc Tou 00050 "So, %p, %l thinks that you can wrest %o from me! @@ -3207,6 +3221,9 @@ You feel your mentor's presence; perhaps %o is nearby. %Cp Wiz 00041 The aura of %o tingles at the edge of your perception. %E +%Cp Wiz 00042 +You have returned to %ns lair. +%E %Cc Wiz 00050 "Ah, I recognize you, %p. So, %l has sent you to steal %o from me, hmmm? Well, %lh is a fool to send such diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 1f4c81969..f07eb50c6 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -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 "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 +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 diff --git a/include/extern.h b/include/extern.h index 02bb1d85f..50bb49618 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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. */ /* 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 const char *NDECL(ldrname); 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(qt_pager, (int)); E struct permonst *NDECL(qt_montype); diff --git a/include/qtext.h b/include/qtext.h index 11b414dd6..752938423 100644 --- a/include/qtext.h +++ b/include/qtext.h @@ -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. */ /* NetHack may be freely redistributed. See license for details. */ @@ -83,6 +83,7 @@ struct qtlists { #define QT_FIRSTGOAL 40 #define QT_NEXTGOAL 41 +#define QT_ALTGOAL 42 /* alternate to QT_NEXTGOAL if artifact is absent */ #define QT_FIRSTNEMESIS 50 #define QT_NEXTNEMESIS 51 diff --git a/src/quest.c b/src/quest.c index f1222fc69..df4b83155 100644 --- a/src/quest.c +++ b/src/quest.c @@ -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) diff --git a/src/questpgr.c b/src/questpgr.c index ed936d9e4..260a43eee 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -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; }