#include "angband.h"
#include "util.h"
+#include "main/music-definitions-table.h"
-#include "core.h"
-#include "dungeon.h"
-#include "floor.h"
-#include "floor-save.h"
-#include "floor-events.h"
+#include "core/system-variables.h"
+#include "dungeon/dungeon.h"
+#include "floor/floor.h"
+#include "floor/floor-save.h"
+#include "floor/floor-events.h"
#include "grid.h"
#include "quest.h"
-#include "monsterrace-hook.h"
-#include "monster.h"
-#include "player-status.h"
-#include "player-personality.h"
+#include "monster/monsterrace-hook.h"
+#include "monster/monster.h"
+#include "player/player-status.h"
+#include "player/player-personality.h"
#include "artifact.h"
#include "feature.h"
-#include "world.h"
-#include "cmd-dump.h"
+#include "world/world.h"
+#include "io/write-diary.h"
+#include "cmd/cmd-dump.h"
#include "english.h"
-#include "view-mainwindow.h"
+#include "view/display-main-window.h"
quest_type *quest; /*!< Quest info */
QUEST_IDX max_q_idx; /*!< Maximum number of quests */
_("巻物を見つけた。メッセージが書いてある:", "You find a scroll with the following message"),
};
+
/*!
* @brief ランダムクエストの討伐ユニークを決める / Determine the random quest uniques
* @param q_ptr クエスト構造体の参照ポインタ
* @return なし
*/
-void determine_random_questor(quest_type *q_ptr)
+void determine_random_questor(player_type *player_ptr, quest_type *q_ptr)
{
- MONRACE_IDX r_idx;
- monster_race *r_ptr;
-
- get_mon_num_prep(mon_hook_quest, NULL);
+ get_mon_num_prep(player_ptr, mon_hook_quest, NULL);
+ MONRACE_IDX r_idx;
while (TRUE)
{
/*
* Random monster 5 - 10 levels out of depth
* (depending on level)
*/
- r_idx = get_mon_num(q_ptr->level + 5 + randint1(q_ptr->level / 10));
+ r_idx = get_mon_num(player_ptr, q_ptr->level + 5 + randint1(q_ptr->level / 10), GMN_ARENA);
+ monster_race *r_ptr;
r_ptr = &r_info[r_idx];
if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
q_ptr->r_idx = r_idx;
}
+
/*!
* @brief クエストを達成状態にする /
* @param player_ptr プレーヤーへの参照ポインタ
switch (q_ptr->type)
{
case QUEST_TYPE_RANDOM:
- if (record_rand_quest) exe_write_diary(player_ptr, NIKKI_RAND_QUEST_C, quest_num, NULL);
+ if (record_rand_quest) exe_write_diary(player_ptr, DIARY_RAND_QUEST_C, quest_num, NULL);
break;
default:
- if (record_fix_quest) exe_write_diary(player_ptr, NIKKI_FIX_QUEST_C, quest_num, NULL);
+ if (record_fix_quest) exe_write_diary(player_ptr, DIARY_FIX_QUEST_C, quest_num, NULL);
break;
}
update_playtime();
q_ptr->comptime = current_world_ptr->play_time;
- if (!(q_ptr->flags & QUEST_FLAG_SILENT))
- {
- play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_QUEST_CLEAR);
- msg_print(_("クエストを達成した!", "You just completed your quest!"));
- msg_print(NULL);
- }
-}
+ if (q_ptr->flags & QUEST_FLAG_SILENT) return;
+ play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_QUEST_CLEAR);
+ msg_print(_("クエストを達成した!", "You just completed your quest!"));
+ msg_print(NULL);
+}
/*!
*/
void check_quest_completion(player_type *player_ptr, monster_type *m_ptr)
{
- POSITION y, x;
-
- bool create_stairs = FALSE;
- bool reward = FALSE;
-
- object_type forge;
- object_type *o_ptr;
-
- y = m_ptr->fy;
- x = m_ptr->fx;
+ POSITION y = m_ptr->fy;
+ POSITION x = m_ptr->fx;
floor_type *floor_ptr = player_ptr->current_floor_ptr;
QUEST_IDX quest_num = floor_ptr->inside_quest;
if (!quest_num)
{
QUEST_IDX i;
-
for (i = max_q_idx - 1; i > 0; i--)
{
quest_type* const q_ptr = &quest[i];
}
/* Handle the current quest */
+ bool create_stairs = FALSE;
+ bool reward = FALSE;
if (quest_num && (quest[quest_num].status == QUEST_STATUS_TAKEN))
{
/* Current quest */
if (q_ptr->cur_num >= q_ptr->num_mon)
{
complete_quest(player_ptr, quest_num);
-
q_ptr->cur_num = 0;
}
+
break;
}
case QUEST_TYPE_KILL_ALL:
{
if (!is_hostile(m_ptr)) break;
- if (count_all_hostile_monsters(floor_ptr) == 1)
+ if (count_all_hostile_monsters(floor_ptr) != 1) break;
+
+ if (q_ptr->flags & QUEST_FLAG_SILENT)
{
- if (q_ptr->flags & QUEST_FLAG_SILENT)
- {
- q_ptr->status = QUEST_STATUS_FINISHED;
- }
- else
- {
- complete_quest(player_ptr, quest_num);
- }
+ q_ptr->status = QUEST_STATUS_FINISHED;
+ }
+ else
+ {
+ complete_quest(player_ptr, quest_num);
}
+
break;
}
case QUEST_TYPE_KILL_LEVEL:
q_ptr->cur_num++;
- if (q_ptr->cur_num >= q_ptr->max_num)
- {
- complete_quest(player_ptr, quest_num);
+ if (q_ptr->cur_num < q_ptr->max_num) break;
- if (!(q_ptr->flags & QUEST_FLAG_PRESET))
- {
- create_stairs = TRUE;
- floor_ptr->inside_quest = 0;
- }
+ complete_quest(player_ptr, quest_num);
- /* Finish the two main quests without rewarding */
- if ((quest_num == QUEST_OBERON) || (quest_num == QUEST_SERPENT))
- {
- q_ptr->status = QUEST_STATUS_FINISHED;
- }
+ if (!(q_ptr->flags & QUEST_FLAG_PRESET))
+ {
+ create_stairs = TRUE;
+ floor_ptr->inside_quest = 0;
+ }
- if (q_ptr->type == QUEST_TYPE_RANDOM)
- {
- reward = TRUE;
- q_ptr->status = QUEST_STATUS_FINISHED;
- }
+ /* Finish the two main quests without rewarding */
+ if ((quest_num == QUEST_OBERON) || (quest_num == QUEST_SERPENT))
+ {
+ q_ptr->status = QUEST_STATUS_FINISHED;
+ }
+
+ if (q_ptr->type == QUEST_TYPE_RANDOM)
+ {
+ reward = TRUE;
+ q_ptr->status = QUEST_STATUS_FINISHED;
}
+
break;
}
case QUEST_TYPE_KILL_ANY_LEVEL:
complete_quest(player_ptr, quest_num);
q_ptr->cur_num = 0;
}
+
break;
}
case QUEST_TYPE_TOWER:
complete_quest(player_ptr, QUEST_TOWER1);
}
}
+
break;
}
}
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))
{
/* Pick a location */
- scatter(floor_ptr, &ny, &nx, y, x, 1, 0);
+ scatter(player_ptr, &ny, &nx, y, x, 1, 0);
/* Stagger */
y = ny; x = nx;
msg_print(_("魔法の階段が現れた...", "A magical staircase appears..."));
/* Create stairs down */
- cave_set_feat(floor_ptr, y, x, feat_down_stair);
+ cave_set_feat(player_ptr, y, x, feat_down_stair);
/* Remember to update everything */
player_ptr->update |= (PU_FLOW);
}
- /*
- * Drop quest reward
- */
- if (reward)
- {
- int i;
+ if (!reward) return;
- for (i = 0; i < (floor_ptr->dun_level / 15) + 1; i++)
- {
- o_ptr = &forge;
- object_wipe(o_ptr);
+ object_type forge;
+ object_type *o_ptr;
+ for (int i = 0; i < (floor_ptr->dun_level / 15) + 1; i++)
+ {
+ o_ptr = &forge;
+ object_wipe(o_ptr);
- /* Make a great object */
- make_object(player_ptr, o_ptr, AM_GOOD | AM_GREAT);
- (void)drop_near(player_ptr, o_ptr, -1, y, x);
- }
+ /* Make a great object */
+ make_object(player_ptr, o_ptr, AM_GOOD | AM_GREAT);
+ (void)drop_near(player_ptr, o_ptr, -1, y, x);
}
}
+
/*!
* @brief 特定のアーティファクトを入手した際のクエスト達成処理 /
* Check for "Quest" completion when a quest monster is killed or charmed.
*/
void check_find_art_quest_completion(player_type *player_ptr, object_type *o_ptr)
{
- QUEST_IDX i;
/* Check if completed a quest */
- for (i = 0; i < max_q_idx; i++)
+ for (QUEST_IDX i = 0; i < max_q_idx; i++)
{
if ((quest[i].type == QUEST_TYPE_FIND_ARTIFACT) &&
(quest[i].status == QUEST_STATUS_TAKEN) &&
quest_type *q_ptr = &quest[q_idx];
monster_race *r_ptr = &r_info[q_ptr->r_idx];
MONSTER_NUMBER q_num = q_ptr->max_num;
- GAME_TEXT name[MAX_NLEN];
if (!q_idx) return;
+ GAME_TEXT name[MAX_NLEN];
strcpy(name, (r_name + r_ptr->name));
msg_print(find_quest[rand_range(0, 4)]);
msg_print(NULL);
- if (q_num == 1)
+ if (q_num != 1)
{
- if ((r_ptr->flags1 & RF1_UNIQUE) && (0 == r_ptr->max_num))
- {
- msg_print(_("この階は以前は誰かによって守られていたようだ…。", "It seems that this level was protected by someone before..."));
- /* The unique is already dead */
- quest[q_idx].status = QUEST_STATUS_FINISHED;
- q_ptr->complev = 0;
- update_playtime();
- q_ptr->comptime = current_world_ptr->play_time;
- }
- else
- {
- msg_format(_("注意せよ!この階は%sによって守られている!", "Beware, this level is protected by %s!"), name);
- }
- }
- else
- {
-#ifndef JP
+#ifdef JP
+#else
plural_aux(name);
#endif
msg_format(_("注意しろ!この階は%d体の%sによって守られている!", "Be warned, this level is guarded by %d %s!"), q_num, name);
+ return;
+ }
+ bool is_random_quest_skipped = (r_ptr->flags1 & RF1_UNIQUE) != 0;
+ is_random_quest_skipped &= r_ptr->max_num == 0;
+ if (!is_random_quest_skipped)
+ {
+ msg_format(_("注意せよ!この階は%sによって守られている!", "Beware, this level is protected by %s!"), name);
+ return;
}
+
+ msg_print(_("この階は以前は誰かによって守られていたようだ…。", "It seems that this level was protected by someone before..."));
+ quest[q_idx].status = QUEST_STATUS_FINISHED;
+ q_ptr->complev = 0;
+ update_playtime();
+ q_ptr->comptime = current_world_ptr->play_time;
}
/*!
* @brief 新しく入ったダンジョンの階層に固定されている一般のクエストを探し出しIDを返す。
* / Hack -- Check if a level is a "quest" level
+ * @param player_ptr プレーヤーへの参照ポインタ
* @param level 検索対象になる階
* @return クエストIDを返す。該当がない場合0を返す。
*/
QUEST_IDX quest_number(player_type *player_ptr, DEPTH level)
{
- QUEST_IDX i;
-
floor_type *floor_ptr = player_ptr->current_floor_ptr;
if (floor_ptr->inside_quest)
return (floor_ptr->inside_quest);
- for (i = 0; i < max_q_idx; i++)
+ for (QUEST_IDX i = 0; i < max_q_idx; i++)
{
if (quest[i].status != QUEST_STATUS_TAKEN) continue;
!(quest[i].flags & QUEST_FLAG_PRESET) &&
(quest[i].level == level) &&
(quest[i].dungeon == player_ptr->dungeon_idx))
- return (i);
+ return i;
}
- /* Check for random quest */
- return (random_quest_number(level));
+ return random_quest_number(player_ptr, level);
}
+
/*!
* @brief 新しく入ったダンジョンの階層に固定されているランダムクエストを探し出しIDを返す。
+ * @param player_ptr プレーヤーへの参照ポインタ
* @param level 検索対象になる階
* @return クエストIDを返す。該当がない場合0を返す。
*/
-QUEST_IDX random_quest_number(DEPTH level)
+QUEST_IDX random_quest_number(player_type *player_ptr, DEPTH level)
{
- QUEST_IDX i;
+ if (player_ptr->dungeon_idx != DUNGEON_ANGBAND) return 0;
- if (p_ptr->dungeon_idx != DUNGEON_ANGBAND) return 0;
-
- for (i = MIN_RANDOM_QUEST; i < MAX_RANDOM_QUEST + 1; i++)
+ for (QUEST_IDX i = MIN_RANDOM_QUEST; i < MAX_RANDOM_QUEST + 1; i++)
{
if ((quest[i].type == QUEST_TYPE_RANDOM) &&
(quest[i].status == QUEST_STATUS_TAKEN) &&
return 0;
}
+
/*!
* @brief クエスト階層から離脱する際の処理
* @param player_ptr プレーヤーへの参照ポインタ
quest_type* const q_ptr = &quest[leaving_quest];
bool is_one_time_quest = ((q_ptr->flags & QUEST_FLAG_ONCE) || (q_ptr->type == QUEST_TYPE_RANDOM)) &&
(q_ptr->status == QUEST_STATUS_TAKEN);
- if (is_one_time_quest) return;
+ if (!is_one_time_quest) return;
q_ptr->status = QUEST_STATUS_FAILED;
q_ptr->complev = player_ptr->lev;
/* Record finishing a quest */
if (q_ptr->type == QUEST_TYPE_RANDOM)
{
- if (record_rand_quest) exe_write_diary(player_ptr, NIKKI_RAND_QUEST_F, leaving_quest, NULL);
- }
- else
- {
- if (record_fix_quest) exe_write_diary(player_ptr, NIKKI_FIX_QUEST_F, leaving_quest, NULL);
+ if (record_rand_quest)
+ exe_write_diary(player_ptr, DIARY_RAND_QUEST_F, leaving_quest, NULL);
+ return;
}
+
+ if (record_fix_quest)
+ exe_write_diary(player_ptr, DIARY_FIX_QUEST_F, leaving_quest, NULL);
}
+
/*!
* @brief 「塔」クエストの各階層から離脱する際の処理
* @return なし
*/
-void leave_tower_check(void)
+void leave_tower_check(player_type *player_ptr)
{
- leaving_quest = p_ptr->current_floor_ptr->inside_quest;
- /* Check for Tower Quest */
- if (leaving_quest &&
- (quest[leaving_quest].type == QUEST_TYPE_TOWER) &&
- (quest[QUEST_TOWER1].status != QUEST_STATUS_COMPLETED))
- {
- if (quest[leaving_quest].type == QUEST_TYPE_TOWER)
- {
- quest[QUEST_TOWER1].status = QUEST_STATUS_FAILED;
- quest[QUEST_TOWER1].complev = p_ptr->lev;
- update_playtime();
- quest[QUEST_TOWER1].comptime = current_world_ptr->play_time;
- }
- }
+ leaving_quest = player_ptr->current_floor_ptr->inside_quest;
+ bool is_leaving_from_tower = leaving_quest != 0;
+ is_leaving_from_tower &= quest[leaving_quest].type == QUEST_TYPE_TOWER;
+ is_leaving_from_tower &= quest[QUEST_TOWER1].status != QUEST_STATUS_COMPLETED;
+ if (!is_leaving_from_tower) return;
+ if (quest[leaving_quest].type != QUEST_TYPE_TOWER) return;
+
+ quest[QUEST_TOWER1].status = QUEST_STATUS_FAILED;
+ quest[QUEST_TOWER1].complev = player_ptr->lev;
+ update_playtime();
+ quest[QUEST_TOWER1].comptime = current_world_ptr->play_time;
}
msg_print(_("ここにはクエストの入口はない。", "You see no quest level here."));
return;
}
- else
- {
- msg_print(_("ここにはクエストへの入口があります。", "There is an entry of a quest."));
- if (!get_check(_("クエストに入りますか?", "Do you enter? "))) return;
- if ((player_ptr->pseikaku == SEIKAKU_COMBAT) || (player_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON))
- msg_print(_("『とにかく入ってみようぜぇ。』", ""));
- else if (player_ptr->pseikaku == SEIKAKU_CHARGEMAN) msg_print("『全滅してやるぞ!』");
- /* Player enters a new quest */
- player_ptr->oldpy = 0;
- player_ptr->oldpx = 0;
+ msg_print(_("ここにはクエストへの入口があります。", "There is an entry of a quest."));
+ if (!get_check(_("クエストに入りますか?", "Do you enter? "))) return;
+ if (IS_ECHIZEN(player_ptr))
+ msg_print(_("『とにかく入ってみようぜぇ。』", ""));
+ else if (player_ptr->pseikaku == SEIKAKU_CHARGEMAN) msg_print("『全滅してやるぞ!』");
- leave_quest_check(player_ptr);
+ /* Player enters a new quest */
+ player_ptr->oldpy = 0;
+ player_ptr->oldpx = 0;
- if (quest[player_ptr->current_floor_ptr->inside_quest].type != QUEST_TYPE_RANDOM) player_ptr->current_floor_ptr->dun_level = 1;
- player_ptr->current_floor_ptr->inside_quest = player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x].special;
+ leave_quest_check(player_ptr);
- player_ptr->leaving = TRUE;
- }
-}
+ if (quest[player_ptr->current_floor_ptr->inside_quest].type != QUEST_TYPE_RANDOM) player_ptr->current_floor_ptr->dun_level = 1;
+ player_ptr->current_floor_ptr->inside_quest = player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x].special;
+ player_ptr->leaving = TRUE;
+}