1 #include "world/world-movement-processor.h"
2 #include "cmd-io/cmd-save.h"
3 #include "core/disturbance.h"
4 #include "dungeon/quest.h"
5 #include "floor/floor-mode-changer.h"
6 #include "game-option/birth-options.h"
7 #include "game-option/play-record-options.h"
8 #include "game-option/special-options.h"
9 #include "io/write-diary.h"
10 #include "main/sound-definitions-table.h"
11 #include "main/sound-of-music.h"
12 #include "monster-race/monster-race.h"
13 #include "monster-race/race-flags1.h"
14 #include "system/dungeon-info.h"
15 #include "system/floor-type-definition.h"
16 #include "system/monster-race-info.h"
17 #include "system/player-type-definition.h"
18 #include "system/redrawing-flags-updater.h"
19 #include "util/enum-range.h"
20 #include "view/display-messages.h"
21 #include "world/world.h"
24 * @brief プレイヤーの現在ダンジョンIDと階層に応じて、ダンジョン内ランクエの自動放棄を行う
25 * @param player_ptr プレイヤーへの参照ポインタ
27 void check_random_quest_auto_failure(PlayerType *player_ptr)
29 auto &quest_list = QuestList::get_instance();
30 const auto &floor = *player_ptr->current_floor_ptr;
31 if (floor.dungeon_idx != DUNGEON_ANGBAND) {
34 for (auto q_idx : EnumRange(QuestId::RANDOM_QUEST1, QuestId::RANDOM_QUEST10)) {
35 auto &quest = quest_list[q_idx];
36 auto is_taken_quest = (quest.type == QuestKindType::RANDOM);
37 is_taken_quest &= (quest.status == QuestStatusType::TAKEN);
38 is_taken_quest &= (quest.level < floor.dun_level);
39 if (!is_taken_quest) {
43 quest.status = QuestStatusType::FAILED;
44 quest.complev = (byte)player_ptr->lev;
46 quest.comptime = w_ptr->play_time;
47 monraces_info[quest.r_idx].flags1 &= ~(RF1_QUESTOR);
52 * @brief 10ゲームターンが進行するごとに帰還の残り時間カウントダウンと発動を処理する。
53 * / Handle involuntary movement once every 10 game turns
54 * @param player_ptr プレイヤーへの参照ポインタ
56 * Autosave BEFORE resetting the recall counter (rr9)
57 * The player is yanked up/down as soon as he loads the autosaved game.
59 void execute_recall(PlayerType *player_ptr)
61 if (player_ptr->word_recall == 0) {
65 if (autosave_l && (player_ptr->word_recall == 1) && !player_ptr->phase_out) {
66 do_cmd_save_game(player_ptr, true);
69 player_ptr->word_recall--;
70 RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
71 if (player_ptr->word_recall != 0) {
75 disturb(player_ptr, false, true);
76 auto *floor_ptr = player_ptr->current_floor_ptr;
77 if (floor_ptr->dun_level || inside_quest(floor_ptr->quest_number) || player_ptr->enter_dungeon) {
78 msg_print(_("上に引っ張りあげられる感じがする!", "You feel yourself yanked upwards!"));
79 if (floor_ptr->dungeon_idx) {
80 player_ptr->recall_dungeon = floor_ptr->dungeon_idx;
83 exe_write_diary(player_ptr, DiaryKind::RECALL, floor_ptr->dun_level);
86 floor_ptr->dun_level = 0;
87 floor_ptr->reset_dungeon_index();
88 leave_quest_check(player_ptr);
89 leave_tower_check(player_ptr);
90 floor_ptr->quest_number = QuestId::NONE;
91 player_ptr->leaving = true;
96 msg_print(_("下に引きずり降ろされる感じがする!", "You feel yourself yanked downwards!"));
97 floor_ptr->set_dungeon_index(player_ptr->recall_dungeon);
99 exe_write_diary(player_ptr, DiaryKind::RECALL, floor_ptr->dun_level);
102 floor_ptr->dun_level = max_dlv[floor_ptr->dungeon_idx];
103 if (floor_ptr->dun_level < 1) {
104 floor_ptr->dun_level = 1;
106 if (ironman_nightmare && !randint0(666) && (floor_ptr->dungeon_idx == DUNGEON_ANGBAND)) {
107 if (floor_ptr->dun_level < 50) {
108 floor_ptr->dun_level *= 2;
109 } else if (floor_ptr->dun_level < 99) {
110 floor_ptr->dun_level = (floor_ptr->dun_level + 99) / 2;
111 } else if (floor_ptr->dun_level > 100) {
112 floor_ptr->dun_level = floor_ptr->get_dungeon_definition().maxdepth - 1;
116 if (player_ptr->wild_mode) {
117 player_ptr->wilderness_y = player_ptr->y;
118 player_ptr->wilderness_x = player_ptr->x;
120 player_ptr->oldpx = player_ptr->x;
121 player_ptr->oldpy = player_ptr->y;
124 player_ptr->wild_mode = false;
127 * Clear all saved floors
128 * and create a first saved floor
130 prepare_change_floor_mode(player_ptr, CFM_FIRST_FLOOR);
131 player_ptr->leaving = true;
133 check_random_quest_auto_failure(player_ptr);
134 sound(SOUND_TPLEVEL);
138 * @brief 10ゲームターンが進行するごとにフロア・リセット/現実変容の残り時間カウントダウンと発動を処理する。
139 * / Handle involuntary movement once every 10 game turns
140 * @param player_ptr プレイヤーへの参照ポインタ
142 void execute_floor_reset(PlayerType *player_ptr)
144 const auto &floor = *player_ptr->current_floor_ptr;
145 if (player_ptr->alter_reality == 0) {
149 if (autosave_l && (player_ptr->alter_reality == 1) && !player_ptr->phase_out) {
150 do_cmd_save_game(player_ptr, true);
153 player_ptr->alter_reality--;
154 RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
155 if (player_ptr->alter_reality != 0) {
159 disturb(player_ptr, false, true);
160 if (!inside_quest(quest_number(floor, floor.dun_level)) && floor.dun_level) {
161 msg_print(_("世界が変わった!", "The world changes!"));
164 * Clear all saved floors
165 * and create a first saved floor
167 prepare_change_floor_mode(player_ptr, CFM_FIRST_FLOOR);
168 player_ptr->leaving = true;
170 msg_print(_("世界が少しの間変化したようだ。", "The world seems to change for a moment!"));
173 sound(SOUND_TPLEVEL);