OSDN Git Service

fix #36659
[jnethack/source.git] / src / quest.c
1 /* NetHack 3.6  quest.c $NHDT-Date: 1446191878 2015/10/30 07:57:58 $  $NHDT-Branch: master $:$NHDT-Revision: 1.20 $ */
2 /*      Copyright 1991, M. Stephenson             */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10 #include "hack.h"
11
12 /*  quest dungeon branch routines. */
13
14 #include "quest.h"
15 #include "qtext.h"
16
17 #define Not_firsttime (on_level(&u.uz0, &u.uz))
18 #define Qstat(x) (quest_status.x)
19
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 *));
30
31 STATIC_OVL void
32 on_start()
33 {
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);
40         else
41             qt_pager(QT_OTHERTIME);
42     }
43 }
44
45 STATIC_OVL void
46 on_locate()
47 {
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);
51
52     if (Qstat(killed_nemesis)) {
53         return;
54     } else if (!Qstat(first_locate)) {
55         if (from_above)
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;
61     } else {
62         if (from_above)
63             qt_pager(QT_NEXTLOCATE);
64     }
65 }
66
67 STATIC_OVL void
68 on_goal()
69 {
70     if (Qstat(killed_nemesis)) {
71         return;
72     } else if (!Qstat(made_goal)) {
73         qt_pager(QT_FIRSTGOAL);
74         Qstat(made_goal) = 1;
75     } else {
76         qt_pager(QT_NEXTGOAL);
77         if (Qstat(made_goal) < 7)
78             Qstat(made_goal)++;
79     }
80 }
81
82 void
83 onquest()
84 {
85     if (u.uevent.qcompleted || Not_firsttime)
86         return;
87     if (!Is_special(&u.uz))
88         return;
89
90     if (Is_qstart(&u.uz))
91         on_start();
92     else if (Is_qlocate(&u.uz))
93         on_locate();
94     else if (Is_nemesis(&u.uz))
95         on_goal();
96     return;
97 }
98
99 void
100 nemdead()
101 {
102     if (!Qstat(killed_nemesis)) {
103         Qstat(killed_nemesis) = TRUE;
104         qt_pager(QT_KILLEDNEM);
105     }
106 }
107
108 void
109 artitouch(obj)
110 struct obj *obj;
111 {
112     if (!Qstat(touched_artifact)) {
113         /* in case we haven't seen the item yet (ie, currently blinded),
114            this quest message describes it by name so mark it as seen */
115         obj->dknown = 1;
116         /* only give this message once */
117         Qstat(touched_artifact) = TRUE;
118         qt_pager(QT_GOTIT);
119         exercise(A_WIS, TRUE);
120     }
121 }
122
123 /* external hook for do.c (level change check) */
124 boolean
125 ok_to_quest()
126 {
127     return (boolean) ((Qstat(got_quest) || Qstat(got_thanks))
128                       && is_pure(FALSE) > 0);
129 }
130
131 STATIC_OVL boolean
132 not_capable()
133 {
134     return (boolean) (u.ulevel < MIN_QUEST_LEVEL);
135 }
136
137 STATIC_OVL int
138 is_pure(talk)
139 boolean talk;
140 {
141     int purity;
142     aligntyp original_alignment = u.ualignbase[A_ORIGINAL];
143
144     if (wizard && talk) {
145         if (u.ualign.type != original_alignment) {
146 #if 0 /*JP*/
147             You("are currently %s instead of %s.", align_str(u.ualign.type),
148                 align_str(original_alignment));
149 #else
150             You("%s\82Å\82Í\82È\82­%s\82Ì\91®\90«\82Å\82 \82é\81D", align_str(original_alignment),
151                 align_str(u.ualign.type));
152 #endif
153         } else if (u.ualignbase[A_CURRENT] != original_alignment) {
154 /*JP
155             You("have converted.");
156 */
157             You("\93]\8cü\82µ\82Ä\82¢\82é\81D");
158         } else if (u.ualign.record < MIN_QUEST_ALIGN) {
159 #if 0 /*JP*/
160             You("are currently %d and require %d.", u.ualign.record,
161                 MIN_QUEST_ALIGN);
162 #else
163             Your("\91®\90«\92l\82Í\8c»\8dÝ%d\82Å%d\95K\97v\82¾\81D", u.ualign.record,
164                  MIN_QUEST_ALIGN);
165 #endif
166 /*JP
167             if (yn_function("adjust?", (char *) 0, 'y') == 'y')
168 */
169             if (yn_function("\92¼\82·\81H", (char *) 0, 'y') == 'y')
170                 u.ualign.record = MIN_QUEST_ALIGN;
171         }
172     }
173     purity = (u.ualign.record >= MIN_QUEST_ALIGN
174               && u.ualign.type == original_alignment
175               && u.ualignbase[A_CURRENT] == original_alignment)
176                  ? 1
177                  : (u.ualignbase[A_CURRENT] != original_alignment) ? -1 : 0;
178     return purity;
179 }
180
181 /*
182  * Expel the player to the stairs on the parent of the quest dungeon.
183  *
184  * This assumes that the hero is currently _in_ the quest dungeon and that
185  * there is a single branch to and from it.
186  */
187 STATIC_OVL void
188 expulsion(seal)
189 boolean seal;
190 {
191     branch *br;
192     d_level *dest;
193     struct trap *t;
194     int portal_flag;
195
196 /*JP
197     br = dungeon_branch("The Quest");
198 */
199     br = dungeon_branch("\83N\83G\83X\83g");
200     dest = (br->end1.dnum == u.uz.dnum) ? &br->end2 : &br->end1;
201     portal_flag = u.uevent.qexpelled ? 0 /* returned via artifact? */
202                                      : !seal ? 1 : -1;
203     schedule_goto(dest, FALSE, FALSE, portal_flag, (char *) 0, (char *) 0);
204     if (seal) { /* remove the portal to the quest - sealing it off */
205         int reexpelled = u.uevent.qexpelled;
206         u.uevent.qexpelled = 1;
207         remdun_mapseen(quest_dnum);
208         /* Delete the near portal now; the far (main dungeon side)
209            portal will be deleted as part of arrival on that level.
210            If monster movement is in progress, any who haven't moved
211            yet will now miss out on a chance to wander through it... */
212         for (t = ftrap; t; t = t->ntrap)
213             if (t->ttyp == MAGIC_PORTAL)
214                 break;
215         if (t)
216             deltrap(t); /* (display might be briefly out of sync) */
217         else if (!reexpelled)
218             impossible("quest portal already gone?");
219     }
220 }
221
222 /* Either you've returned to quest leader while carrying the quest
223    artifact or you've just thrown it to/at him or her.  If quest
224    completion text hasn't been given yet, give it now.  Otherwise
225    give another message about the character keeping the artifact
226    and using the magic portal to return to the dungeon. */
227 void
228 finish_quest(obj)
229 struct obj *obj; /* quest artifact; possibly null if carrying Amulet */
230 {
231     struct obj *otmp;
232
233     if (u.uhave.amulet) { /* unlikely but not impossible */
234         qt_pager(QT_HASAMULET);
235         /* leader IDs the real amulet but ignores any fakes */
236         if ((otmp = carrying(AMULET_OF_YENDOR)) != 0)
237             fully_identify_obj(otmp);
238     } else {
239         qt_pager(!Qstat(got_thanks) ? QT_OFFEREDIT : QT_OFFEREDIT2);
240         /* should have obtained bell during quest;
241            if not, suggest returning for it now */
242         if ((otmp = carrying(BELL_OF_OPENING)) == 0)
243             com_pager(5);
244     }
245     Qstat(got_thanks) = TRUE;
246
247     if (obj) {
248         u.uevent.qcompleted = 1; /* you did it! */
249         /* behave as if leader imparts sufficient info about the
250            quest artifact */
251         fully_identify_obj(obj);
252         update_inventory();
253     }
254 }
255
256 STATIC_OVL void
257 chat_with_leader()
258 {
259     /*  Rule 0: Cheater checks. */
260     if (u.uhave.questart && !Qstat(met_nemesis))
261         Qstat(cheater) = TRUE;
262
263     /*  It is possible for you to get the amulet without completing
264      *  the quest.  If so, try to induce the player to quest.
265      */
266     if (Qstat(got_thanks)) {
267         /* Rule 1: You've gone back with/without the amulet. */
268         if (u.uhave.amulet)
269             finish_quest((struct obj *) 0);
270
271         /* Rule 2: You've gone back before going for the amulet. */
272         else
273             qt_pager(QT_POSTHANKS);
274
275     /* Rule 3: You've got the artifact and are back to return it. */
276     } else if (u.uhave.questart) {
277         struct obj *otmp;
278
279         for (otmp = invent; otmp; otmp = otmp->nobj)
280             if (is_quest_artifact(otmp))
281                 break;
282
283         finish_quest(otmp);
284
285     /* Rule 4: You haven't got the artifact yet. */
286     } else if (Qstat(got_quest)) {
287         qt_pager(rn1(10, QT_ENCOURAGE));
288
289     /* Rule 5: You aren't yet acceptable - or are you? */
290     } else {
291         if (!Qstat(met_leader)) {
292             qt_pager(QT_FIRSTLEADER);
293             Qstat(met_leader) = TRUE;
294             Qstat(not_ready) = 0;
295         } else
296             qt_pager(QT_NEXTLEADER);
297
298         /* the quest leader might have passed through the portal into
299            the regular dungeon; none of the remaining make sense there */
300         if (!on_level(&u.uz, &qstart_level))
301             return;
302
303         if (not_capable()) {
304             qt_pager(QT_BADLEVEL);
305             exercise(A_WIS, TRUE);
306             expulsion(FALSE);
307         } else if (is_pure(TRUE) < 0) {
308             com_pager(QT_BANISHED);
309             expulsion(TRUE);
310         } else if (is_pure(TRUE) == 0) {
311             qt_pager(QT_BADALIGN);
312             if (Qstat(not_ready) == MAX_QUEST_TRIES) {
313                 qt_pager(QT_LASTLEADER);
314                 expulsion(TRUE);
315             } else {
316                 Qstat(not_ready)++;
317                 exercise(A_WIS, TRUE);
318                 expulsion(FALSE);
319             }
320         } else { /* You are worthy! */
321             qt_pager(QT_ASSIGNQUEST);
322             exercise(A_WIS, TRUE);
323             Qstat(got_quest) = TRUE;
324         }
325     }
326 }
327
328 void
329 leader_speaks(mtmp)
330 struct monst *mtmp;
331 {
332     /* maybe you attacked leader? */
333     if (!mtmp->mpeaceful) {
334         Qstat(pissed_off) = TRUE;
335         mtmp->mstrategy &= ~STRAT_WAITMASK; /* end the inaction */
336     }
337     /* the quest leader might have passed through the portal into the
338        regular dungeon; if so, mustn't perform "backwards expulsion" */
339     if (!on_level(&u.uz, &qstart_level))
340         return;
341
342     if (Qstat(pissed_off)) {
343         qt_pager(QT_LASTLEADER);
344         expulsion(TRUE);
345     } else
346         chat_with_leader();
347 }
348
349 STATIC_OVL void
350 chat_with_nemesis()
351 {
352     /*  The nemesis will do most of the talking, but... */
353     qt_pager(rn1(10, QT_DISCOURAGE));
354     if (!Qstat(met_nemesis))
355         Qstat(met_nemesis++);
356 }
357
358 void
359 nemesis_speaks()
360 {
361     if (!Qstat(in_battle)) {
362         if (u.uhave.questart)
363             qt_pager(QT_NEMWANTSIT);
364         else if (Qstat(made_goal) == 1 || !Qstat(met_nemesis))
365             qt_pager(QT_FIRSTNEMESIS);
366         else if (Qstat(made_goal) < 4)
367             qt_pager(QT_NEXTNEMESIS);
368         else if (Qstat(made_goal) < 7)
369             qt_pager(QT_OTHERNEMESIS);
370         else if (!rn2(5))
371             qt_pager(rn1(10, QT_DISCOURAGE));
372         if (Qstat(made_goal) < 7)
373             Qstat(made_goal)++;
374         Qstat(met_nemesis) = TRUE;
375     } else /* he will spit out random maledictions */
376         if (!rn2(5))
377         qt_pager(rn1(10, QT_DISCOURAGE));
378 }
379
380 STATIC_OVL void
381 chat_with_guardian()
382 {
383     /*  These guys/gals really don't have much to say... */
384     if (u.uhave.questart && Qstat(killed_nemesis))
385         qt_pager(rn1(5, QT_GUARDTALK2));
386     else
387         qt_pager(rn1(5, QT_GUARDTALK));
388 }
389
390 STATIC_OVL void
391 prisoner_speaks(mtmp)
392 struct monst *mtmp;
393 {
394     if (mtmp->data == &mons[PM_PRISONER]
395         && (mtmp->mstrategy & STRAT_WAITMASK)) {
396         /* Awaken the prisoner */
397         if (canseemon(mtmp))
398 /*JP
399             pline("%s speaks:", Monnam(mtmp));
400 */
401             pline("%s\82Í\98b\82µ\82½\81F", Monnam(mtmp));
402 /*JP
403         verbalize("I'm finally free!");
404 */
405         verbalize("\82Â\82¢\82É\8e©\97R\82¾\81I");
406         mtmp->mstrategy &= ~STRAT_WAITMASK;
407         mtmp->mpeaceful = 1;
408
409         /* Your god is happy... */
410         adjalign(3);
411
412         /* ...But the guards are not */
413         (void) angry_guards(FALSE);
414     }
415     return;
416 }
417
418 void
419 quest_chat(mtmp)
420 register struct monst *mtmp;
421 {
422     if (mtmp->m_id == Qstat(leader_m_id)) {
423         chat_with_leader();
424         return;
425     }
426     switch (mtmp->data->msound) {
427     case MS_NEMESIS:
428         chat_with_nemesis();
429         break;
430     case MS_GUARDIAN:
431         chat_with_guardian();
432         break;
433     default:
434         impossible("quest_chat: Unknown quest character %s.", mon_nam(mtmp));
435     }
436 }
437
438 void
439 quest_talk(mtmp)
440 struct monst *mtmp;
441 {
442     if (mtmp->m_id == Qstat(leader_m_id)) {
443         leader_speaks(mtmp);
444         return;
445     }
446     switch (mtmp->data->msound) {
447     case MS_NEMESIS:
448         nemesis_speaks();
449         break;
450     case MS_DJINNI:
451         prisoner_speaks(mtmp);
452         break;
453     default:
454         break;
455     }
456 }
457
458 void
459 quest_stat_check(mtmp)
460 struct monst *mtmp;
461 {
462     if (mtmp->data->msound == MS_NEMESIS)
463         Qstat(in_battle) = (mtmp->mcanmove && !mtmp->msleeping
464                             && monnear(mtmp, u.ux, u.uy));
465 }
466
467 /*quest.c*/