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. */
4
5 #include "hack.h"
6
7 /* quest dungeon branch routines. */
8
9 #include "quest.h"
10 #include "qtext.h"
11
12 #define Not_firsttime (on_level(&u.uz0, &u.uz))
13 #define Qstat(x) (quest_status.x)
14
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 *));
25
26
27 STATIC_OVL void
on_start()28 on_start()
29 {
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);
36 }
37 }
38
39 STATIC_OVL void
on_locate()40 on_locate()
41 {
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);
47 }
48
49 STATIC_OVL void
on_goal()50 on_goal()
51 {
52 if (Qstat(killed_nemesis)) {
53 return;
54 } else if (!Qstat(made_goal)) {
55 qt_pager(QT_FIRSTGOAL);
56 Qstat(made_goal) = 1;
57 } else {
58 qt_pager(QT_NEXTGOAL);
59 if(Qstat(made_goal) < 7) Qstat(made_goal)++;
60 }
61 }
62
63 void
onquest()64 onquest()
65 {
66 if(u.uevent.qcompleted || Not_firsttime) return;
67 if(!Is_special(&u.uz)) return;
68
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();
72 return;
73 }
74
75 void
nemdead()76 nemdead()
77 {
78 if(!Qstat(killed_nemesis)) {
79 Qstat(killed_nemesis) = TRUE;
80 qt_pager(QT_KILLEDNEM);
81 }
82 }
83
84 void
artitouch()85 artitouch()
86 {
87 if(!Qstat(touched_artifact)) {
88 Qstat(touched_artifact) = TRUE;
89 qt_pager(QT_GOTIT);
90 exercise(A_WIS, TRUE);
91 }
92 }
93
94 /* external hook for do.c (level change check) */
95 boolean
ok_to_quest()96 ok_to_quest()
97 {
98 return((boolean)((Qstat(got_quest) || Qstat(got_thanks)))
99 && (is_pure(FALSE) > 0));
100 }
101
102 STATIC_OVL boolean
not_capable()103 not_capable()
104 {
105 return((boolean)(u.ulevel < MIN_QUEST_LEVEL));
106 }
107
108 STATIC_OVL int
is_pure(talk)109 is_pure(talk)
110 boolean talk;
111 {
112 int purity;
113 aligntyp original_alignment = u.ualignbase[A_ORIGINAL];
114
115 #ifdef WIZARD
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;
127 }
128 }
129 #endif
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;
134 return purity;
135 }
136
137 /*
138 * Expell the player to the stairs on the parent of the quest dungeon.
139 *
140 * This assumes that the hero is currently _in_ the quest dungeon and that
141 * there is a single branch to and from it.
142 */
143 STATIC_OVL void
expulsion(seal)144 expulsion(seal)
145 boolean seal;
146 {
147 branch *br;
148 d_level *dest;
149 struct trap *t;
150 int portal_flag;
151
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? */
155 !seal ? 1 : -1;
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?");
168 }
169 }
170
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. */
176 void
finish_quest(obj)177 finish_quest(obj)
178 struct obj *obj; /* quest artifact; possibly null if carrying Amulet */
179 {
180 struct obj *otmp;
181
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);
187 } else {
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)
192 com_pager(5);
193 }
194 Qstat(got_thanks) = TRUE;
195
196 if (obj) {
197 u.uevent.qcompleted = 1; /* you did it! */
198 /* behave as if leader imparts sufficient info about the
199 quest artifact */
200 fully_identify_obj(obj);
201 update_inventory();
202 }
203 }
204
205 STATIC_OVL void
chat_with_leader()206 chat_with_leader()
207 {
208 /* Rule 0: Cheater checks. */
209 if(u.uhave.questart && !Qstat(met_nemesis))
210 Qstat(cheater) = TRUE;
211
212 /* It is possible for you to get the amulet without completing
213 * the quest. If so, try to induce the player to quest.
214 */
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);
218
219 /* Rule 2: You've gone back before going for the amulet. */
220 else qt_pager(QT_POSTHANKS);
221 }
222
223 /* Rule 3: You've got the artifact and are back to return it. */
224 else if(u.uhave.questart) {
225 struct obj *otmp;
226
227 for (otmp = invent; otmp; otmp = otmp->nobj)
228 if (is_quest_artifact(otmp)) break;
229
230 finish_quest(otmp);
231
232 /* Rule 4: You haven't got the artifact yet. */
233 } else if(Qstat(got_quest)) {
234 qt_pager(rn1(10, QT_ENCOURAGE));
235
236 /* Rule 5: You aren't yet acceptable - or are you? */
237 } else {
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;
246
247 if(not_capable()) {
248 qt_pager(QT_BADLEVEL);
249 exercise(A_WIS, TRUE);
250 expulsion(FALSE);
251 } else if(is_pure(TRUE) < 0) {
252 com_pager(QT_BANISHED);
253 expulsion(TRUE);
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);
258 expulsion(TRUE);
259 } else {
260 Qstat(not_ready)++;
261 exercise(A_WIS, TRUE);
262 expulsion(FALSE);
263 }
264 } else { /* You are worthy! */
265 qt_pager(QT_ASSIGNQUEST);
266 exercise(A_WIS, TRUE);
267 Qstat(got_quest) = TRUE;
268 }
269 }
270 }
271
272 void
leader_speaks(mtmp)273 leader_speaks(mtmp)
274 register struct monst *mtmp;
275 {
276 /* maybe you attacked leader? */
277 if(!mtmp->mpeaceful) {
278 Qstat(pissed_off) = TRUE;
279 mtmp->mstrategy &= ~STRAT_WAITMASK; /* end the inaction */
280 }
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;
284
285 if(Qstat(pissed_off)) {
286 qt_pager(QT_LASTLEADER);
287 expulsion(TRUE);
288 } else chat_with_leader();
289 }
290
291 STATIC_OVL void
chat_with_nemesis()292 chat_with_nemesis()
293 {
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++);
297 }
298
299 void
nemesis_speaks()300 nemesis_speaks()
301 {
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));
313 }
314
315 STATIC_OVL void
chat_with_guardian()316 chat_with_guardian()
317 {
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));
321 else
322 qt_pager(rn1(5, QT_GUARDTALK));
323 }
324
325 STATIC_OVL void
prisoner_speaks(mtmp)326 prisoner_speaks (mtmp)
327 register struct monst *mtmp;
328 {
329 if (mtmp->data == &mons[PM_PRISONER] &&
330 (mtmp->mstrategy & STRAT_WAITMASK)) {
331 /* Awaken the prisoner */
332 if (canseemon(mtmp))
333 pline("%s speaks:", Monnam(mtmp));
334 verbalize("I'm finally free!");
335 mtmp->mstrategy &= ~STRAT_WAITMASK;
336 mtmp->mpeaceful = 1;
337
338 /* Your god is happy... */
339 adjalign(3);
340
341 /* ...But the guards are not */
342 (void) angry_guards(FALSE);
343 }
344 return;
345 }
346
347 void
quest_chat(mtmp)348 quest_chat(mtmp)
349 register struct monst *mtmp;
350 {
351 if (mtmp->m_id == Qstat(leader_m_id)) {
352 chat_with_leader();
353 return;
354 }
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.",
359 mon_nam(mtmp));
360 }
361 }
362
363 void
quest_talk(mtmp)364 quest_talk(mtmp)
365 register struct monst *mtmp;
366 {
367 if (mtmp->m_id == Qstat(leader_m_id)) {
368 leader_speaks(mtmp);
369 return;
370 }
371 switch(mtmp->data->msound) {
372 case MS_NEMESIS: nemesis_speaks(); break;
373 case MS_DJINNI: prisoner_speaks(mtmp); break;
374 default: break;
375 }
376 }
377
378 void
quest_stat_check(mtmp)379 quest_stat_check(mtmp)
380 struct monst *mtmp;
381 {
382 if(mtmp->data->msound == MS_NEMESIS)
383 Qstat(in_battle) = (mtmp->mcanmove && !mtmp->msleeping &&
384 monnear(mtmp, u.ux, u.uy));
385 }
386
387 /*quest.c*/
388