OSDN Git Service

[Refactor] #38997 complete_quest() と check_find_art_quest_completion() にplayer_type...
[hengband/hengband.git] / src / quest.c
1 #include "angband.h"
2 #include "util.h"
3
4 #include "core.h"
5 #include "dungeon.h"
6 #include "floor.h"
7 #include "floor-save.h"
8 #include "floor-events.h"
9 #include "grid.h"
10 #include "quest.h"
11 #include "monsterrace-hook.h"
12 #include "monster.h"
13 #include "player-status.h"
14 #include "player-personality.h"
15 #include "artifact.h"
16 #include "feature.h"
17 #include "world.h"
18 #include "cmd-dump.h"
19 #include "english.h"
20 #include "view-mainwindow.h"
21
22 quest_type *quest; /*!< Quest info */
23 QUEST_IDX max_q_idx; /*!< Maximum number of quests */
24 char quest_text[10][80]; /*!< Quest text */
25 int quest_text_line; /*!< Current line of the quest text */
26 int leaving_quest = 0;
27
28 /*!
29  * @brief クエスト突入時のメッセージテーブル / Array of places to find an inscription
30  */
31 static concptr find_quest[] =
32 {
33         _("床にメッセージが刻まれている:", "You find the following inscription in the floor"),
34         _("壁にメッセージが刻まれている:", "You see a message inscribed in the wall"),
35         _("メッセージを見つけた:", "There is a sign saying"),
36         _("何かが階段の上に書いてある:", "Something is written on the staircase"),
37         _("巻物を見つけた。メッセージが書いてある:", "You find a scroll with the following message"),
38 };
39
40 /*!
41  * @brief ランダムクエストの討伐ユニークを決める / Determine the random quest uniques
42  * @param q_ptr クエスト構造体の参照ポインタ
43  * @return なし
44  */
45 void determine_random_questor(quest_type *q_ptr)
46 {
47         MONRACE_IDX r_idx;
48         monster_race *r_ptr;
49
50         get_mon_num_prep(mon_hook_quest, NULL);
51
52         while (TRUE)
53         {
54                 /*
55                  * Random monster 5 - 10 levels out of depth
56                  * (depending on level)
57                  */
58                 r_idx = get_mon_num(q_ptr->level + 5 + randint1(q_ptr->level / 10));
59                 r_ptr = &r_info[r_idx];
60
61                 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
62                 if (r_ptr->flags1 & RF1_QUESTOR) continue;
63                 if (r_ptr->rarity > 100) continue;
64                 if (r_ptr->flags7 & RF7_FRIENDLY) continue;
65                 if (r_ptr->flags7 & RF7_AQUATIC) continue;
66                 if (r_ptr->flags8 & RF8_WILD_ONLY) continue;
67                 if (no_questor_or_bounty_uniques(r_idx)) continue;
68
69                 /*
70                  * Accept monsters that are 2 - 6 levels
71                  * out of depth depending on the quest level
72                  */
73                 if (r_ptr->level > (q_ptr->level + (q_ptr->level / 20))) break;
74         }
75
76         q_ptr->r_idx = r_idx;
77 }
78
79 /*!
80  * @brief クエストを達成状態にする /
81  * @param player_ptr プレーヤーへの参照ポインタ
82  * @param quest_num 達成状態にしたいクエストのID
83  * @return なし
84  */
85 void complete_quest(player_type *player_ptr, QUEST_IDX quest_num)
86 {
87         quest_type* const q_ptr = &quest[quest_num];
88
89         switch (q_ptr->type)
90         {
91         case QUEST_TYPE_RANDOM:
92                 if (record_rand_quest) exe_write_diary(player_ptr, NIKKI_RAND_QUEST_C, quest_num, NULL);
93                 break;
94         default:
95                 if (record_fix_quest) exe_write_diary(player_ptr, NIKKI_FIX_QUEST_C, quest_num, NULL);
96                 break;
97         }
98
99         q_ptr->status = QUEST_STATUS_COMPLETED;
100         q_ptr->complev = player_ptr->lev;
101         update_playtime();
102         q_ptr->comptime = current_world_ptr->play_time;
103
104         if (!(q_ptr->flags & QUEST_FLAG_SILENT))
105         {
106                 play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_QUEST_CLEAR);
107                 msg_print(_("クエストを達成した!", "You just completed your quest!"));
108                 msg_print(NULL);
109         }
110 }
111
112
113
114 /*!
115  * @brief 特定の敵を倒した際にクエスト達成処理 /
116  * Check for "Quest" completion when a quest monster is killed or charmed.
117  * @param player_ptr プレーヤーへの参照ポインタ
118  * @param m_ptr 撃破したモンスターの構造体参照ポインタ
119  * @return なし
120  */
121 void check_quest_completion(player_type *player_ptr, monster_type *m_ptr)
122 {
123         POSITION y, x;
124
125         bool create_stairs = FALSE;
126         bool reward = FALSE;
127
128         object_type forge;
129         object_type *o_ptr;
130
131         y = m_ptr->fy;
132         x = m_ptr->fx;
133
134         floor_type *floor_ptr = player_ptr->current_floor_ptr;
135         QUEST_IDX quest_num = floor_ptr->inside_quest;
136
137         /* Search for an active quest on this dungeon level */
138         if (!quest_num)
139         {
140                 QUEST_IDX i;
141
142                 for (i = max_q_idx - 1; i > 0; i--)
143                 {
144                         quest_type* const q_ptr = &quest[i];
145
146                         /* Quest is not active */
147                         if (q_ptr->status != QUEST_STATUS_TAKEN)
148                                 continue;
149
150                         /* Quest is not a dungeon quest */
151                         if (q_ptr->flags & QUEST_FLAG_PRESET)
152                                 continue;
153
154                         /* Quest is not on this level */
155                         if ((q_ptr->level != floor_ptr->dun_level) &&
156                                 (q_ptr->type != QUEST_TYPE_KILL_ANY_LEVEL))
157                                 continue;
158
159                         /* Not a "kill monster" quest */
160                         if ((q_ptr->type == QUEST_TYPE_FIND_ARTIFACT) ||
161                                 (q_ptr->type == QUEST_TYPE_FIND_EXIT))
162                                 continue;
163
164                         /* Interesting quest */
165                         if ((q_ptr->type == QUEST_TYPE_KILL_NUMBER) ||
166                                 (q_ptr->type == QUEST_TYPE_TOWER) ||
167                                 (q_ptr->type == QUEST_TYPE_KILL_ALL))
168                                 break;
169
170                         /* Interesting quest */
171                         if (((q_ptr->type == QUEST_TYPE_KILL_LEVEL) ||
172                                 (q_ptr->type == QUEST_TYPE_KILL_ANY_LEVEL) ||
173                                 (q_ptr->type == QUEST_TYPE_RANDOM)) &&
174                                 (q_ptr->r_idx == m_ptr->r_idx))
175                                 break;
176                 }
177
178                 quest_num = i;
179         }
180
181         /* Handle the current quest */
182         if (quest_num && (quest[quest_num].status == QUEST_STATUS_TAKEN))
183         {
184                 /* Current quest */
185                 quest_type* const q_ptr = &quest[quest_num];
186
187                 switch (q_ptr->type)
188                 {
189                 case QUEST_TYPE_KILL_NUMBER:
190                 {
191                         q_ptr->cur_num++;
192
193                         if (q_ptr->cur_num >= q_ptr->num_mon)
194                         {
195                                 complete_quest(player_ptr, quest_num);
196
197                                 q_ptr->cur_num = 0;
198                         }
199                         break;
200                 }
201                 case QUEST_TYPE_KILL_ALL:
202                 {
203                         if (!is_hostile(m_ptr)) break;
204
205                         if (count_all_hostile_monsters(floor_ptr) == 1)
206                         {
207                                 if (q_ptr->flags & QUEST_FLAG_SILENT)
208                                 {
209                                         q_ptr->status = QUEST_STATUS_FINISHED;
210                                 }
211                                 else
212                                 {
213                                         complete_quest(player_ptr, quest_num);
214                                 }
215                         }
216                         break;
217                 }
218                 case QUEST_TYPE_KILL_LEVEL:
219                 case QUEST_TYPE_RANDOM:
220                 {
221                         /* Only count valid monsters */
222                         if (q_ptr->r_idx != m_ptr->r_idx)
223                                 break;
224
225                         q_ptr->cur_num++;
226
227                         if (q_ptr->cur_num >= q_ptr->max_num)
228                         {
229                                 complete_quest(player_ptr, quest_num);
230
231                                 if (!(q_ptr->flags & QUEST_FLAG_PRESET))
232                                 {
233                                         create_stairs = TRUE;
234                                         floor_ptr->inside_quest = 0;
235                                 }
236
237                                 /* Finish the two main quests without rewarding */
238                                 if ((quest_num == QUEST_OBERON) || (quest_num == QUEST_SERPENT))
239                                 {
240                                         q_ptr->status = QUEST_STATUS_FINISHED;
241                                 }
242
243                                 if (q_ptr->type == QUEST_TYPE_RANDOM)
244                                 {
245                                         reward = TRUE;
246                                         q_ptr->status = QUEST_STATUS_FINISHED;
247                                 }
248                         }
249                         break;
250                 }
251                 case QUEST_TYPE_KILL_ANY_LEVEL:
252                 {
253                         q_ptr->cur_num++;
254                         if (q_ptr->cur_num >= q_ptr->max_num)
255                         {
256                                 complete_quest(player_ptr, quest_num);
257                                 q_ptr->cur_num = 0;
258                         }
259                         break;
260                 }
261                 case QUEST_TYPE_TOWER:
262                 {
263                         if (!is_hostile(m_ptr)) break;
264
265                         if (count_all_hostile_monsters(floor_ptr) == 1)
266                         {
267                                 q_ptr->status = QUEST_STATUS_STAGE_COMPLETED;
268
269                                 if ((quest[QUEST_TOWER1].status == QUEST_STATUS_STAGE_COMPLETED) &&
270                                         (quest[QUEST_TOWER2].status == QUEST_STATUS_STAGE_COMPLETED) &&
271                                         (quest[QUEST_TOWER3].status == QUEST_STATUS_STAGE_COMPLETED))
272                                 {
273
274                                         complete_quest(player_ptr, QUEST_TOWER1);
275                                 }
276                         }
277                         break;
278                 }
279                 }
280         }
281
282         /* Create a magical staircase */
283         if (create_stairs)
284         {
285                 POSITION ny, nx;
286
287                 /* Stagger around */
288                 while (cave_perma_bold(floor_ptr, y, x) || floor_ptr->grid_array[y][x].o_idx || (floor_ptr->grid_array[y][x].info & CAVE_OBJECT))
289                 {
290                         /* Pick a location */
291                         scatter(floor_ptr, &ny, &nx, y, x, 1, 0);
292
293                         /* Stagger */
294                         y = ny; x = nx;
295                 }
296
297                 /* Explain the staircase */
298                 msg_print(_("魔法の階段が現れた...", "A magical staircase appears..."));
299
300                 /* Create stairs down */
301                 cave_set_feat(floor_ptr, y, x, feat_down_stair);
302
303                 /* Remember to update everything */
304                 player_ptr->update |= (PU_FLOW);
305         }
306
307         /*
308          * Drop quest reward
309          */
310         if (reward)
311         {
312                 int i;
313
314                 for (i = 0; i < (floor_ptr->dun_level / 15) + 1; i++)
315                 {
316                         o_ptr = &forge;
317                         object_wipe(o_ptr);
318
319                         /* Make a great object */
320                         make_object(player_ptr, o_ptr, AM_GOOD | AM_GREAT);
321                         (void)drop_near(player_ptr, o_ptr, -1, y, x);
322                 }
323         }
324 }
325
326 /*!
327  * @brief 特定のアーティファクトを入手した際のクエスト達成処理 /
328  * Check for "Quest" completion when a quest monster is killed or charmed.
329  * @param player_ptr プレーヤーへの参照ポインタ
330  * @param o_ptr 入手したオブジェクトの構造体参照ポインタ
331  * @return なし
332  */
333 void check_find_art_quest_completion(player_type *player_ptr, object_type *o_ptr)
334 {
335         QUEST_IDX i;
336         /* Check if completed a quest */
337         for (i = 0; i < max_q_idx; i++)
338         {
339                 if ((quest[i].type == QUEST_TYPE_FIND_ARTIFACT) &&
340                         (quest[i].status == QUEST_STATUS_TAKEN) &&
341                         (quest[i].k_idx == o_ptr->name1))
342                 {
343                         complete_quest(player_ptr, i);
344                 }
345         }
346 }
347
348
349 /*!
350  * @brief クエストの導入メッセージを表示する / Discover quest
351  * @param q_idx 開始されたクエストのID
352  */
353 void quest_discovery(QUEST_IDX q_idx)
354 {
355         quest_type *q_ptr = &quest[q_idx];
356         monster_race *r_ptr = &r_info[q_ptr->r_idx];
357         MONSTER_NUMBER q_num = q_ptr->max_num;
358         GAME_TEXT name[MAX_NLEN];
359
360         if (!q_idx) return;
361
362         strcpy(name, (r_name + r_ptr->name));
363
364         msg_print(find_quest[rand_range(0, 4)]);
365         msg_print(NULL);
366
367         if (q_num == 1)
368         {
369                 if ((r_ptr->flags1 & RF1_UNIQUE) && (0 == r_ptr->max_num))
370                 {
371                         msg_print(_("この階は以前は誰かによって守られていたようだ…。", "It seems that this level was protected by someone before..."));
372                         /* The unique is already dead */
373                         quest[q_idx].status = QUEST_STATUS_FINISHED;
374                         q_ptr->complev = 0;
375                         update_playtime();
376                         q_ptr->comptime = current_world_ptr->play_time;
377                 }
378                 else
379                 {
380                         msg_format(_("注意せよ!この階は%sによって守られている!", "Beware, this level is protected by %s!"), name);
381                 }
382         }
383         else
384         {
385 #ifndef JP
386                 plural_aux(name);
387 #endif
388                 msg_format(_("注意しろ!この階は%d体の%sによって守られている!", "Be warned, this level is guarded by %d %s!"), q_num, name);
389
390         }
391 }
392
393
394 /*!
395  * @brief 新しく入ったダンジョンの階層に固定されている一般のクエストを探し出しIDを返す。
396  * / Hack -- Check if a level is a "quest" level
397  * @param level 検索対象になる階
398  * @return クエストIDを返す。該当がない場合0を返す。
399  */
400 QUEST_IDX quest_number(DEPTH level)
401 {
402         QUEST_IDX i;
403
404         /* Check quests */
405         if (p_ptr->current_floor_ptr->inside_quest)
406                 return (p_ptr->current_floor_ptr->inside_quest);
407
408         for (i = 0; i < max_q_idx; i++)
409         {
410                 if (quest[i].status != QUEST_STATUS_TAKEN) continue;
411
412                 if ((quest[i].type == QUEST_TYPE_KILL_LEVEL) &&
413                         !(quest[i].flags & QUEST_FLAG_PRESET) &&
414                         (quest[i].level == level) &&
415                         (quest[i].dungeon == p_ptr->dungeon_idx))
416                         return (i);
417         }
418
419         /* Check for random quest */
420         return (random_quest_number(level));
421 }
422
423 /*!
424  * @brief 新しく入ったダンジョンの階層に固定されているランダムクエストを探し出しIDを返す。
425  * @param level 検索対象になる階
426  * @return クエストIDを返す。該当がない場合0を返す。
427  */
428 QUEST_IDX random_quest_number(DEPTH level)
429 {
430         QUEST_IDX i;
431
432         if (p_ptr->dungeon_idx != DUNGEON_ANGBAND) return 0;
433
434         for (i = MIN_RANDOM_QUEST; i < MAX_RANDOM_QUEST + 1; i++)
435         {
436                 if ((quest[i].type == QUEST_TYPE_RANDOM) &&
437                         (quest[i].status == QUEST_STATUS_TAKEN) &&
438                         (quest[i].level == level) &&
439                         (quest[i].dungeon == DUNGEON_ANGBAND))
440                 {
441                         return i;
442                 }
443         }
444
445         return 0;
446 }
447
448 /*!
449  * @brief クエスト階層から離脱する際の処理
450  * @param player_ptr プレーヤーへの参照ポインタ
451  * @return なし
452  */
453 void leave_quest_check(player_type *player_ptr)
454 {
455         leaving_quest = player_ptr->current_floor_ptr->inside_quest;
456         if (!leaving_quest) return;
457
458         quest_type* const q_ptr = &quest[leaving_quest];
459         bool is_one_time_quest = ((q_ptr->flags & QUEST_FLAG_ONCE) || (q_ptr->type == QUEST_TYPE_RANDOM)) &&
460                 (q_ptr->status == QUEST_STATUS_TAKEN);
461         if (is_one_time_quest) return;
462
463         q_ptr->status = QUEST_STATUS_FAILED;
464         q_ptr->complev = player_ptr->lev;
465         update_playtime();
466         q_ptr->comptime = current_world_ptr->play_time;
467
468         /* Additional settings */
469         switch (q_ptr->type)
470         {
471         case QUEST_TYPE_TOWER:
472                 quest[QUEST_TOWER1].status = QUEST_STATUS_FAILED;
473                 quest[QUEST_TOWER1].complev = player_ptr->lev;
474                 break;
475         case QUEST_TYPE_FIND_ARTIFACT:
476                 a_info[q_ptr->k_idx].gen_flags &= ~(TRG_QUESTITEM);
477                 break;
478         case QUEST_TYPE_RANDOM:
479                 r_info[q_ptr->r_idx].flags1 &= ~(RF1_QUESTOR);
480
481                 /* Floor of random quest will be blocked */
482                 prepare_change_floor_mode(player_ptr, CFM_NO_RETURN);
483                 break;
484         }
485
486         /* Record finishing a quest */
487         if (q_ptr->type == QUEST_TYPE_RANDOM)
488         {
489                 if (record_rand_quest) exe_write_diary(player_ptr, NIKKI_RAND_QUEST_F, leaving_quest, NULL);
490         }
491         else
492         {
493                 if (record_fix_quest) exe_write_diary(player_ptr, NIKKI_FIX_QUEST_F, leaving_quest, NULL);
494         }
495 }
496
497 /*!
498  * @brief 「塔」クエストの各階層から離脱する際の処理
499  * @return なし
500  */
501 void leave_tower_check(void)
502 {
503         leaving_quest = p_ptr->current_floor_ptr->inside_quest;
504         /* Check for Tower Quest */
505         if (leaving_quest &&
506                 (quest[leaving_quest].type == QUEST_TYPE_TOWER) &&
507                 (quest[QUEST_TOWER1].status != QUEST_STATUS_COMPLETED))
508         {
509                 if (quest[leaving_quest].type == QUEST_TYPE_TOWER)
510                 {
511                         quest[QUEST_TOWER1].status = QUEST_STATUS_FAILED;
512                         quest[QUEST_TOWER1].complev = p_ptr->lev;
513                         update_playtime();
514                         quest[QUEST_TOWER1].comptime = current_world_ptr->play_time;
515                 }
516         }
517 }
518
519
520 /*!
521  * @brief クエスト入り口にプレイヤーが乗った際の処理 / Do building commands
522  * @param player_ptr プレーヤーへの参照ポインタ
523  * @return なし
524  */
525 void do_cmd_quest(player_type *player_ptr)
526 {
527         if (player_ptr->wild_mode) return;
528
529         take_turn(player_ptr, 100);
530
531         if (!cave_have_flag_bold(player_ptr->current_floor_ptr, player_ptr->y, player_ptr->x, FF_QUEST_ENTER))
532         {
533                 msg_print(_("ここにはクエストの入口はない。", "You see no quest level here."));
534                 return;
535         }
536         else
537         {
538                 msg_print(_("ここにはクエストへの入口があります。", "There is an entry of a quest."));
539                 if (!get_check(_("クエストに入りますか?", "Do you enter? "))) return;
540                 if ((player_ptr->pseikaku == SEIKAKU_COMBAT) || (player_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON))
541                         msg_print(_("『とにかく入ってみようぜぇ。』", ""));
542                 else if (player_ptr->pseikaku == SEIKAKU_CHARGEMAN) msg_print("『全滅してやるぞ!』");
543
544                 /* Player enters a new quest */
545                 player_ptr->oldpy = 0;
546                 player_ptr->oldpx = 0;
547
548                 leave_quest_check(player_ptr);
549
550                 if (quest[player_ptr->current_floor_ptr->inside_quest].type != QUEST_TYPE_RANDOM) player_ptr->current_floor_ptr->dun_level = 1;
551                 player_ptr->current_floor_ptr->inside_quest = player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x].special;
552
553                 player_ptr->leaving = TRUE;
554         }
555 }
556