1 #include "world/world-movement-processor.h"
2 #include "cmd-io/cmd-save.h"
3 #include "core/disturbance.h"
4 #include "core/player-redraw-types.h"
5 #include "dungeon/quest.h"
6 #include "floor/floor-mode-changer.h"
7 #include "game-option/birth-options.h"
8 #include "game-option/play-record-options.h"
9 #include "game-option/special-options.h"
10 #include "io/write-diary.h"
11 #include "main/sound-definitions-table.h"
12 #include "main/sound-of-music.h"
13 #include "monster-race/monster-race.h"
14 #include "monster-race/race-flags1.h"
15 #include "system/dungeon-info.h"
16 #include "system/floor-type-definition.h"
17 #include "system/monster-race-definition.h"
18 #include "system/player-type-definition.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 if (player_ptr->dungeon_idx != DUNGEON_ANGBAND) {
33 for (auto q_idx : EnumRange(QuestId::RANDOM_QUEST1, QuestId::RANDOM_QUEST10)) {
34 auto &q_ref = quest_list[q_idx];
35 auto is_taken_quest = (q_ref.type == QuestKindType::RANDOM);
36 is_taken_quest &= (q_ref.status == QuestStatusType::TAKEN);
37 is_taken_quest &= (q_ref.level < player_ptr->current_floor_ptr->dun_level);
38 if (!is_taken_quest) {
42 q_ref.status = QuestStatusType::FAILED;
43 q_ref.complev = (byte)player_ptr->lev;
45 q_ref.comptime = w_ptr->play_time;
46 monraces_info[q_ref.r_idx].flags1 &= ~(RF1_QUESTOR);
51 * @brief 10ゲームターンが進行するごとに帰還の残り時間カウントダウンと発動を処理する。
52 * / Handle involuntary movement once every 10 game turns
53 * @param player_ptr プレイヤーへの参照ポインタ
55 * Autosave BEFORE resetting the recall counter (rr9)
56 * The player is yanked up/down as soon as he loads the autosaved game.
58 void execute_recall(PlayerType *player_ptr)
60 if (player_ptr->word_recall == 0) {
64 if (autosave_l && (player_ptr->word_recall == 1) && !player_ptr->phase_out) {
65 do_cmd_save_game(player_ptr, true);
68 player_ptr->word_recall--;
69 player_ptr->redraw |= (PR_STATUS);
70 if (player_ptr->word_recall != 0) {
74 disturb(player_ptr, false, true);
75 auto *floor_ptr = player_ptr->current_floor_ptr;
76 if (floor_ptr->dun_level || inside_quest(player_ptr->current_floor_ptr->quest_number) || player_ptr->enter_dungeon) {
77 msg_print(_("上に引っ張りあげられる感じがする!", "You feel yourself yanked upwards!"));
78 if (player_ptr->dungeon_idx) {
79 player_ptr->recall_dungeon = player_ptr->dungeon_idx;
82 exe_write_diary(player_ptr, DIARY_RECALL, floor_ptr->dun_level, nullptr);
85 floor_ptr->dun_level = 0;
86 player_ptr->dungeon_idx = 0;
87 leave_quest_check(player_ptr);
88 leave_tower_check(player_ptr);
89 player_ptr->current_floor_ptr->quest_number = QuestId::NONE;
90 player_ptr->leaving = true;
95 msg_print(_("下に引きずり降ろされる感じがする!", "You feel yourself yanked downwards!"));
96 player_ptr->dungeon_idx = player_ptr->recall_dungeon;
98 exe_write_diary(player_ptr, DIARY_RECALL, floor_ptr->dun_level, nullptr);
101 floor_ptr->dun_level = max_dlv[player_ptr->dungeon_idx];
102 if (floor_ptr->dun_level < 1) {
103 floor_ptr->dun_level = 1;
105 if (ironman_nightmare && !randint0(666) && (player_ptr->dungeon_idx == DUNGEON_ANGBAND)) {
106 if (floor_ptr->dun_level < 50) {
107 floor_ptr->dun_level *= 2;
108 } else if (floor_ptr->dun_level < 99) {
109 floor_ptr->dun_level = (floor_ptr->dun_level + 99) / 2;
110 } else if (floor_ptr->dun_level > 100) {
111 floor_ptr->dun_level = dungeons_info[player_ptr->dungeon_idx].maxdepth - 1;
115 if (player_ptr->wild_mode) {
116 player_ptr->wilderness_y = player_ptr->y;
117 player_ptr->wilderness_x = player_ptr->x;
119 player_ptr->oldpx = player_ptr->x;
120 player_ptr->oldpy = player_ptr->y;
123 player_ptr->wild_mode = false;
126 * Clear all saved floors
127 * and create a first saved floor
129 prepare_change_floor_mode(player_ptr, CFM_FIRST_FLOOR);
130 player_ptr->leaving = true;
132 check_random_quest_auto_failure(player_ptr);
133 sound(SOUND_TPLEVEL);
137 * @brief 10ゲームターンが進行するごとにフロア・リセット/現実変容の残り時間カウントダウンと発動を処理する。
138 * / Handle involuntary movement once every 10 game turns
139 * @param player_ptr プレイヤーへの参照ポインタ
141 void execute_floor_reset(PlayerType *player_ptr)
143 auto *floor_ptr = player_ptr->current_floor_ptr;
144 if (player_ptr->alter_reality == 0) {
148 if (autosave_l && (player_ptr->alter_reality == 1) && !player_ptr->phase_out) {
149 do_cmd_save_game(player_ptr, true);
152 player_ptr->alter_reality--;
153 player_ptr->redraw |= (PR_STATUS);
154 if (player_ptr->alter_reality != 0) {
158 disturb(player_ptr, false, true);
159 if (!inside_quest(quest_number(player_ptr, floor_ptr->dun_level)) && floor_ptr->dun_level) {
160 msg_print(_("世界が変わった!", "The world changes!"));
163 * Clear all saved floors
164 * and create a first saved floor
166 prepare_change_floor_mode(player_ptr, CFM_FIRST_FLOOR);
167 player_ptr->leaving = true;
169 msg_print(_("世界が少しの間変化したようだ。", "The world seems to change for a moment!"));
172 sound(SOUND_TPLEVEL);