1 /* NetHack 3.6 quest.c $NHDT-Date: 1505170343 2017/09/11 22:52:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.21 $ */
2 /* Copyright 1991, M. Stephenson */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2023 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 /* quest dungeon branch routines. */
17 #define Not_firsttime (on_level(&u.uz0, &u.uz))
18 #define Qstat(x) (quest_status.x)
20 STATIC_DCL void NDECL(on_start);
21 STATIC_DCL void NDECL(on_locate);
22 STATIC_DCL void NDECL(on_goal);
23 STATIC_DCL boolean NDECL(not_capable);
24 STATIC_DCL int FDECL(is_pure, (BOOLEAN_P));
25 STATIC_DCL void FDECL(expulsion, (BOOLEAN_P));
26 STATIC_DCL void NDECL(chat_with_leader);
27 STATIC_DCL void NDECL(chat_with_nemesis);
28 STATIC_DCL void NDECL(chat_with_guardian);
29 STATIC_DCL void FDECL(prisoner_speaks, (struct monst *));
34 if (!Qstat(first_start)) {
35 qt_pager(QT_FIRSTTIME);
36 Qstat(first_start) = TRUE;
37 } else if ((u.uz0.dnum != u.uz.dnum) || (u.uz0.dlevel < u.uz.dlevel)) {
38 if (Qstat(not_ready) <= 2)
39 qt_pager(QT_NEXTTIME);
41 qt_pager(QT_OTHERTIME);
48 /* the locate messages are phrased in a manner such that they only
49 make sense when arriving on the level from above */
50 boolean from_above = (u.uz0.dlevel < u.uz.dlevel);
52 if (Qstat(killed_nemesis)) {
54 } else if (!Qstat(first_locate)) {
56 qt_pager(QT_FIRSTLOCATE);
57 /* if we've arrived from below this will be a lie, but there won't
58 be any point in delivering the message upon a return visit from
59 above later since the level has now been seen */
60 Qstat(first_locate) = TRUE;
63 qt_pager(QT_NEXTLOCATE);
70 if (Qstat(killed_nemesis)) {
72 } else if (!Qstat(made_goal)) {
73 qt_pager(QT_FIRSTGOAL);
77 * Some QT_NEXTGOAL messages reference the quest artifact;
78 * find out if it is still present. If not, request an
79 * alternate message (qt_pager() will revert to delivery
80 * of QT_NEXTGOAL if current role doesn't have QT_ALTGOAL).
81 * Note: if hero is already carrying it, it is treated as
82 * being absent from the level for quest message purposes.
84 unsigned whichobjchains = ((1 << OBJ_FLOOR)
87 struct obj *qarti = find_quest_artifact(whichobjchains);
89 qt_pager(qarti ? QT_NEXTGOAL : QT_ALTGOAL);
90 if (Qstat(made_goal) < 7)
98 if (u.uevent.qcompleted || Not_firsttime)
100 if (!Is_special(&u.uz))
103 if (Is_qstart(&u.uz))
105 else if (Is_qlocate(&u.uz))
107 else if (Is_nemesis(&u.uz))
115 if (!Qstat(killed_nemesis)) {
116 Qstat(killed_nemesis) = TRUE;
117 qt_pager(QT_KILLEDNEM);
125 if (!Qstat(touched_artifact)) {
126 /* in case we haven't seen the item yet (ie, currently blinded),
127 this quest message describes it by name so mark it as seen */
129 /* only give this message once */
130 Qstat(touched_artifact) = TRUE;
132 exercise(A_WIS, TRUE);
136 /* external hook for do.c (level change check) */
140 return (boolean) ((Qstat(got_quest) || Qstat(got_thanks))
141 && is_pure(FALSE) > 0);
147 return (boolean) (u.ulevel < MIN_QUEST_LEVEL);
155 aligntyp original_alignment = u.ualignbase[A_ORIGINAL];
157 if (wizard && talk) {
158 if (u.ualign.type != original_alignment) {
160 You("are currently %s instead of %s.", align_str(u.ualign.type),
161 align_str(original_alignment));
163 You("%s
\82Å
\82Í
\82È
\82%s
\82Ì
\91®
\90«
\82Å
\82 \82é
\81D", align_str(original_alignment),
164 align_str(u.ualign.type));
166 } else if (u.ualignbase[A_CURRENT] != original_alignment) {
168 You("have converted.");
170 You("
\93]
\8cü
\82µ
\82Ä
\82¢
\82é
\81D");
171 } else if (u.ualign.record < MIN_QUEST_ALIGN) {
173 You("are currently %d and require %d.", u.ualign.record,
176 Your("
\91®
\90«
\92l
\82Í
\8c»
\8dÝ%d
\82Å%d
\95K
\97v
\82¾
\81D", u.ualign.record,
180 if (yn_function("adjust?", (char *) 0, 'y') == 'y')
182 if (yn_function("
\92¼
\82·
\81H", (char *) 0, 'y') == 'y')
183 u.ualign.record = MIN_QUEST_ALIGN;
186 purity = (u.ualign.record >= MIN_QUEST_ALIGN
187 && u.ualign.type == original_alignment
188 && u.ualignbase[A_CURRENT] == original_alignment)
190 : (u.ualignbase[A_CURRENT] != original_alignment) ? -1 : 0;
195 * Expel the player to the stairs on the parent of the quest dungeon.
197 * This assumes that the hero is currently _in_ the quest dungeon and that
198 * there is a single branch to and from it.
210 br = dungeon_branch("The Quest");
212 br = dungeon_branch("
\83N
\83G
\83X
\83g");
213 dest = (br->end1.dnum == u.uz.dnum) ? &br->end2 : &br->end1;
214 portal_flag = u.uevent.qexpelled ? 0 /* returned via artifact? */
216 schedule_goto(dest, FALSE, FALSE, portal_flag, (char *) 0, (char *) 0);
217 if (seal) { /* remove the portal to the quest - sealing it off */
218 int reexpelled = u.uevent.qexpelled;
220 u.uevent.qexpelled = 1;
221 remdun_mapseen(quest_dnum);
222 /* Delete the near portal now; the far (main dungeon side)
223 portal will be deleted as part of arrival on that level.
224 If monster movement is in progress, any who haven't moved
225 yet will now miss out on a chance to wander through it... */
226 for (t = ftrap; t; t = t->ntrap)
227 if (t->ttyp == MAGIC_PORTAL)
230 deltrap(t); /* (display might be briefly out of sync) */
231 else if (!reexpelled)
232 impossible("quest portal already gone?");
236 /* Either you've returned to quest leader while carrying the quest
237 artifact or you've just thrown it to/at him or her. If quest
238 completion text hasn't been given yet, give it now. Otherwise
239 give another message about the character keeping the artifact
240 and using the magic portal to return to the dungeon. */
243 struct obj *obj; /* quest artifact; possibly null if carrying Amulet */
247 if (u.uhave.amulet) { /* unlikely but not impossible */
248 qt_pager(QT_HASAMULET);
249 /* leader IDs the real amulet but ignores any fakes */
250 if ((otmp = carrying(AMULET_OF_YENDOR)) != 0)
251 fully_identify_obj(otmp);
253 qt_pager(!Qstat(got_thanks) ? QT_OFFEREDIT : QT_OFFEREDIT2);
254 /* should have obtained bell during quest;
255 if not, suggest returning for it now */
256 if ((otmp = carrying(BELL_OF_OPENING)) == 0)
259 Qstat(got_thanks) = TRUE;
262 u.uevent.qcompleted = 1; /* you did it! */
263 /* behave as if leader imparts sufficient info about the
265 fully_identify_obj(obj);
273 /* Rule 0: Cheater checks. */
274 if (u.uhave.questart && !Qstat(met_nemesis))
275 Qstat(cheater) = TRUE;
277 /* It is possible for you to get the amulet without completing
278 * the quest. If so, try to induce the player to quest.
280 if (Qstat(got_thanks)) {
281 /* Rule 1: You've gone back with/without the amulet. */
283 finish_quest((struct obj *) 0);
285 /* Rule 2: You've gone back before going for the amulet. */
287 qt_pager(QT_POSTHANKS);
289 /* Rule 3: You've got the artifact and are back to return it. */
290 } else if (u.uhave.questart) {
293 for (otmp = invent; otmp; otmp = otmp->nobj)
294 if (is_quest_artifact(otmp))
299 /* Rule 4: You haven't got the artifact yet. */
300 } else if (Qstat(got_quest)) {
301 qt_pager(rn1(10, QT_ENCOURAGE));
303 /* Rule 5: You aren't yet acceptable - or are you? */
305 if (!Qstat(met_leader)) {
306 qt_pager(QT_FIRSTLEADER);
307 Qstat(met_leader) = TRUE;
308 Qstat(not_ready) = 0;
310 qt_pager(QT_NEXTLEADER);
312 /* the quest leader might have passed through the portal into
313 the regular dungeon; none of the remaining make sense there */
314 if (!on_level(&u.uz, &qstart_level))
318 qt_pager(QT_BADLEVEL);
319 exercise(A_WIS, TRUE);
321 } else if (is_pure(TRUE) < 0) {
322 com_pager(QT_BANISHED);
324 } else if (is_pure(TRUE) == 0) {
325 qt_pager(QT_BADALIGN);
326 if (Qstat(not_ready) == MAX_QUEST_TRIES) {
327 qt_pager(QT_LASTLEADER);
331 exercise(A_WIS, TRUE);
334 } else { /* You are worthy! */
335 qt_pager(QT_ASSIGNQUEST);
336 exercise(A_WIS, TRUE);
337 Qstat(got_quest) = TRUE;
346 /* maybe you attacked leader? */
347 if (!mtmp->mpeaceful) {
348 Qstat(pissed_off) = TRUE;
349 mtmp->mstrategy &= ~STRAT_WAITMASK; /* end the inaction */
351 /* the quest leader might have passed through the portal into the
352 regular dungeon; if so, mustn't perform "backwards expulsion" */
353 if (!on_level(&u.uz, &qstart_level))
356 if (Qstat(pissed_off)) {
357 qt_pager(QT_LASTLEADER);
366 /* The nemesis will do most of the talking, but... */
367 qt_pager(rn1(10, QT_DISCOURAGE));
368 if (!Qstat(met_nemesis))
369 Qstat(met_nemesis++);
375 if (!Qstat(in_battle)) {
376 if (u.uhave.questart)
377 qt_pager(QT_NEMWANTSIT);
378 else if (Qstat(made_goal) == 1 || !Qstat(met_nemesis))
379 qt_pager(QT_FIRSTNEMESIS);
380 else if (Qstat(made_goal) < 4)
381 qt_pager(QT_NEXTNEMESIS);
382 else if (Qstat(made_goal) < 7)
383 qt_pager(QT_OTHERNEMESIS);
385 qt_pager(rn1(10, QT_DISCOURAGE));
386 if (Qstat(made_goal) < 7)
388 Qstat(met_nemesis) = TRUE;
389 } else /* he will spit out random maledictions */
391 qt_pager(rn1(10, QT_DISCOURAGE));
397 /* These guys/gals really don't have much to say... */
398 if (u.uhave.questart && Qstat(killed_nemesis))
399 qt_pager(rn1(5, QT_GUARDTALK2));
401 qt_pager(rn1(5, QT_GUARDTALK));
405 prisoner_speaks(mtmp)
408 if (mtmp->data == &mons[PM_PRISONER]
409 && (mtmp->mstrategy & STRAT_WAITMASK)) {
410 /* Awaken the prisoner */
413 pline("%s speaks:", Monnam(mtmp));
415 pline("%s
\82Í
\98b
\82µ
\82½
\81F", Monnam(mtmp));
417 verbalize("I'm finally free!");
419 verbalize("
\82Â
\82¢
\82É
\8e©
\97R
\82¾
\81I");
420 mtmp->mstrategy &= ~STRAT_WAITMASK;
423 /* Your god is happy... */
426 /* ...But the guards are not */
427 (void) angry_guards(FALSE);
434 register struct monst *mtmp;
436 if (mtmp->m_id == Qstat(leader_m_id)) {
440 switch (mtmp->data->msound) {
445 chat_with_guardian();
448 impossible("quest_chat: Unknown quest character %s.", mon_nam(mtmp));
456 if (mtmp->m_id == Qstat(leader_m_id)) {
460 switch (mtmp->data->msound) {
465 prisoner_speaks(mtmp);
473 quest_stat_check(mtmp)
476 if (mtmp->data->msound == MS_NEMESIS)
477 Qstat(in_battle) = (mtmp->mcanmove && !mtmp->msleeping
478 && monnear(mtmp, u.ux, u.uy));