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