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
15STATIC_DCL void NDECL(on_start);
16STATIC_DCL void NDECL(on_locate);
17STATIC_DCL void NDECL(on_goal);
18STATIC_DCL boolean NDECL(not_capable);
19STATIC_DCL int FDECL(is_pure, (BOOLEAN_P));
20STATIC_DCL void FDECL(expulsion, (BOOLEAN_P));
21STATIC_DCL void NDECL(chat_with_leader);
22STATIC_DCL void NDECL(chat_with_nemesis);
23STATIC_DCL void NDECL(chat_with_guardian);
24STATIC_DCL void FDECL(prisoner_speaks, (struct monst *));
25
26
27STATIC_OVL void
28on_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
39STATIC_OVL void
40on_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
49STATIC_OVL void
50on_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
63void
64onquest()
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
75void
76nemdead()
77{
78	if(!Qstat(killed_nemesis)) {
79	    Qstat(killed_nemesis) = TRUE;
80	    qt_pager(QT_KILLEDNEM);
81	}
82}
83
84void
85artitouch()
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) */
95boolean
96ok_to_quest()
97{
98	return((boolean)((Qstat(got_quest) || Qstat(got_thanks)))
99			&& (is_pure(FALSE) > 0));
100}
101
102STATIC_OVL boolean
103not_capable()
104{
105	return((boolean)(u.ulevel < MIN_QUEST_LEVEL));
106}
107
108STATIC_OVL int
109is_pure(talk)
110boolean 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 */
143STATIC_OVL void
144expulsion(seal)
145boolean 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. */
176void
177finish_quest(obj)
178struct 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
205STATIC_OVL void
206chat_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
272void
273leader_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
291STATIC_OVL void
292chat_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
299void
300nemesis_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
315STATIC_OVL void
316chat_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
325STATIC_OVL void
326prisoner_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
347void
348quest_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
363void
364quest_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
378void
379quest_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