1 /* SCCS Id: @(#)quest.c 3.4 2000/05/05 */
2 /* Copyright 1991, M. Stephenson */
3 /* NetHack may be freely redistributed. See license for details. */
7 /* quest dungeon branch routines. */
12 #define Not_firsttime (on_level(&u.uz0, &u.uz))
13 #define Qstat(x) (quest_status.x)
15 STATIC_DCL void NDECL(on_start);
16 STATIC_DCL void NDECL(on_locate);
17 STATIC_DCL void NDECL(on_goal);
18 STATIC_DCL boolean NDECL(not_capable);
19 STATIC_DCL int FDECL(is_pure, (BOOLEAN_P));
20 STATIC_DCL void FDECL(expulsion, (BOOLEAN_P));
21 STATIC_DCL void NDECL(chat_with_leader);
22 STATIC_DCL void NDECL(chat_with_nemesis);
23 STATIC_DCL void NDECL(chat_with_guardian);
24 STATIC_DCL void FDECL(prisoner_speaks, (struct monst *));
30 if(!Qstat(first_start)) {
31 qt_pager(QT_FIRSTTIME);
32 Qstat(first_start) = TRUE;
33 } else if((u.uz0.dnum != u.uz.dnum) || (u.uz0.dlevel < u.uz.dlevel)) {
34 if(Qstat(not_ready) <= 2) qt_pager(QT_NEXTTIME);
35 else qt_pager(QT_OTHERTIME);
42 if(!Qstat(first_locate)) {
43 qt_pager(QT_FIRSTLOCATE);
44 Qstat(first_locate) = TRUE;
45 } else if(u.uz0.dlevel < u.uz.dlevel && !Qstat(killed_nemesis))
46 qt_pager(QT_NEXTLOCATE);
52 if (Qstat(killed_nemesis)) {
54 } else if (!Qstat(made_goal)) {
55 qt_pager(QT_FIRSTGOAL);
58 qt_pager(QT_NEXTGOAL);
59 if(Qstat(made_goal) < 7) Qstat(made_goal)++;
66 if(u.uevent.qcompleted || Not_firsttime) return;
67 if(!Is_special(&u.uz)) return;
69 if(Is_qstart(&u.uz)) on_start();
70 else if(Is_qlocate(&u.uz) && u.uz.dlevel > u.uz0.dlevel) on_locate();
71 else if(Is_nemesis(&u.uz)) on_goal();
78 if(!Qstat(killed_nemesis)) {
79 Qstat(killed_nemesis) = TRUE;
80 qt_pager(QT_KILLEDNEM);
87 if(!Qstat(touched_artifact)) {
88 Qstat(touched_artifact) = TRUE;
90 exercise(A_WIS, TRUE);
94 /* external hook for do.c (level change check) */
98 return((boolean)((Qstat(got_quest) || Qstat(got_thanks)))
99 && (is_pure(FALSE) > 0));
105 return((boolean)(u.ulevel < MIN_QUEST_LEVEL));
113 aligntyp original_alignment = u.ualignbase[A_ORIGINAL];
116 if (wizard && talk) {
117 if (u.ualign.type != original_alignment) {
118 You("are currently %s instead of %s.",
119 align_str(u.ualign.type), align_str(original_alignment));
120 } else if (u.ualignbase[A_CURRENT] != original_alignment) {
121 You("have converted.");
122 } else if (u.ualign.record < MIN_QUEST_ALIGN) {
123 You("are currently %d and require %d.",
124 u.ualign.record, MIN_QUEST_ALIGN);
125 if (yn_function("adjust?", (char *)0, 'y') == 'y')
126 u.ualign.record = MIN_QUEST_ALIGN;
130 purity = (u.ualign.record >= MIN_QUEST_ALIGN &&
131 u.ualign.type == original_alignment &&
132 u.ualignbase[A_CURRENT] == original_alignment) ? 1 :
133 (u.ualignbase[A_CURRENT] != original_alignment) ? -1 : 0;
138 * Expell the player to the stairs on the parent of the quest dungeon.
140 * This assumes that the hero is currently _in_ the quest dungeon and that
141 * there is a single branch to and from it.
152 br = dungeon_branch("The Quest");
153 dest = (br->end1.dnum == u.uz.dnum) ? &br->end2 : &br->end1;
154 portal_flag = u.uevent.qexpelled ? 0 : /* returned via artifact? */
156 schedule_goto(dest, FALSE, FALSE, portal_flag, (char *)0, (char *)0);
157 if (seal) { /* remove the portal to the quest - sealing it off */
158 int reexpelled = u.uevent.qexpelled;
159 u.uevent.qexpelled = 1;
160 /* Delete the near portal now; the far (main dungeon side)
161 portal will be deleted as part of arrival on that level.
162 If monster movement is in progress, any who haven't moved
163 yet will now miss out on a chance to wander through it... */
164 for (t = ftrap; t; t = t->ntrap)
165 if (t->ttyp == MAGIC_PORTAL) break;
166 if (t) deltrap(t); /* (display might be briefly out of sync) */
167 else if (!reexpelled) impossible("quest portal already gone?");
171 /* Either you've returned to quest leader while carrying the quest
172 artifact or you've just thrown it to/at him or her. If quest
173 completion text hasn't been given yet, give it now. Otherwise
174 give another message about the character keeping the artifact
175 and using the magic portal to return to the dungeon. */
178 struct obj *obj; /* quest artifact; possibly null if carrying Amulet */
182 if (u.uhave.amulet) { /* unlikely but not impossible */
183 qt_pager(QT_HASAMULET);
184 /* leader IDs the real amulet but ignores any fakes */
185 if ((otmp = carrying(AMULET_OF_YENDOR)) != 0)
186 fully_identify_obj(otmp);
188 qt_pager(!Qstat(got_thanks) ? QT_OFFEREDIT : QT_OFFEREDIT2);
189 /* should have obtained bell during quest;
190 if not, suggest returning for it now */
191 if ((otmp = carrying(BELL_OF_OPENING)) == 0)
194 Qstat(got_thanks) = TRUE;
197 u.uevent.qcompleted = 1; /* you did it! */
198 /* behave as if leader imparts sufficient info about the
200 fully_identify_obj(obj);
208 /* Rule 0: Cheater checks. */
209 if(u.uhave.questart && !Qstat(met_nemesis))
210 Qstat(cheater) = TRUE;
212 /* It is possible for you to get the amulet without completing
213 * the quest. If so, try to induce the player to quest.
215 if(Qstat(got_thanks)) {
216 /* Rule 1: You've gone back with/without the amulet. */
217 if(u.uhave.amulet) finish_quest((struct obj *)0);
219 /* Rule 2: You've gone back before going for the amulet. */
220 else qt_pager(QT_POSTHANKS);
223 /* Rule 3: You've got the artifact and are back to return it. */
224 else if(u.uhave.questart) {
227 for (otmp = invent; otmp; otmp = otmp->nobj)
228 if (is_quest_artifact(otmp)) break;
232 /* Rule 4: You haven't got the artifact yet. */
233 } else if(Qstat(got_quest)) {
234 qt_pager(rn1(10, QT_ENCOURAGE));
236 /* Rule 5: You aren't yet acceptable - or are you? */
238 if(!Qstat(met_leader)) {
239 qt_pager(QT_FIRSTLEADER);
240 Qstat(met_leader) = TRUE;
241 Qstat(not_ready) = 0;
242 } else qt_pager(QT_NEXTLEADER);
243 /* the quest leader might have passed through the portal into
244 the regular dungeon; none of the remaining make sense there */
245 if (!on_level(&u.uz, &qstart_level)) return;
248 qt_pager(QT_BADLEVEL);
249 exercise(A_WIS, TRUE);
251 } else if(is_pure(TRUE) < 0) {
252 com_pager(QT_BANISHED);
254 } else if(is_pure(TRUE) == 0) {
255 qt_pager(QT_BADALIGN);
256 if(Qstat(not_ready) == MAX_QUEST_TRIES) {
257 qt_pager(QT_LASTLEADER);
261 exercise(A_WIS, TRUE);
264 } else { /* You are worthy! */
265 qt_pager(QT_ASSIGNQUEST);
266 exercise(A_WIS, TRUE);
267 Qstat(got_quest) = TRUE;
274 register struct monst *mtmp;
276 /* maybe you attacked leader? */
277 if(!mtmp->mpeaceful) {
278 Qstat(pissed_off) = TRUE;
279 mtmp->mstrategy &= ~STRAT_WAITMASK; /* end the inaction */
281 /* the quest leader might have passed through the portal into the
282 regular dungeon; if so, mustn't perform "backwards expulsion" */
283 if (!on_level(&u.uz, &qstart_level)) return;
285 if(Qstat(pissed_off)) {
286 qt_pager(QT_LASTLEADER);
288 } else chat_with_leader();
294 /* The nemesis will do most of the talking, but... */
295 qt_pager(rn1(10, QT_DISCOURAGE));
296 if(!Qstat(met_nemesis)) Qstat(met_nemesis++);
302 if(!Qstat(in_battle)) {
303 if(u.uhave.questart) qt_pager(QT_NEMWANTSIT);
304 else if(Qstat(made_goal) == 1 || !Qstat(met_nemesis))
305 qt_pager(QT_FIRSTNEMESIS);
306 else if(Qstat(made_goal) < 4) qt_pager(QT_NEXTNEMESIS);
307 else if(Qstat(made_goal) < 7) qt_pager(QT_OTHERNEMESIS);
308 else if(!rn2(5)) qt_pager(rn1(10, QT_DISCOURAGE));
309 if(Qstat(made_goal) < 7) Qstat(made_goal)++;
310 Qstat(met_nemesis) = TRUE;
311 } else /* he will spit out random maledictions */
312 if(!rn2(5)) qt_pager(rn1(10, QT_DISCOURAGE));
318 /* These guys/gals really don't have much to say... */
319 if (u.uhave.questart && Qstat(killed_nemesis))
320 qt_pager(rn1(5, QT_GUARDTALK2));
322 qt_pager(rn1(5, QT_GUARDTALK));
326 prisoner_speaks (mtmp)
327 register struct monst *mtmp;
329 if (mtmp->data == &mons[PM_PRISONER] &&
330 (mtmp->mstrategy & STRAT_WAITMASK)) {
331 /* Awaken the prisoner */
333 pline("%s speaks:", Monnam(mtmp));
334 verbalize("I'm finally free!");
335 mtmp->mstrategy &= ~STRAT_WAITMASK;
338 /* Your god is happy... */
341 /* ...But the guards are not */
342 (void) angry_guards(FALSE);
349 register struct monst *mtmp;
351 if (mtmp->m_id == Qstat(leader_m_id)) {
355 switch(mtmp->data->msound) {
356 case MS_NEMESIS: chat_with_nemesis(); break;
357 case MS_GUARDIAN: chat_with_guardian(); break;
358 default: impossible("quest_chat: Unknown quest character %s.",
365 register struct monst *mtmp;
367 if (mtmp->m_id == Qstat(leader_m_id)) {
371 switch(mtmp->data->msound) {
372 case MS_NEMESIS: nemesis_speaks(); break;
373 case MS_DJINNI: prisoner_speaks(mtmp); break;
379 quest_stat_check(mtmp)
382 if(mtmp->data->msound == MS_NEMESIS)
383 Qstat(in_battle) = (mtmp->mcanmove && !mtmp->msleeping &&
384 monnear(mtmp, u.ux, u.uy));