1 #include "dungeon/dungeon-processor.h"
2 #include "cmd-building/cmd-building.h"
3 #include "cmd-io/cmd-dump.h"
4 #include "core/disturbance.h"
5 #include "core/object-compressor.h"
6 #include "core/player-processor.h"
7 #include "core/player-redraw-types.h"
8 #include "core/player-update-types.h"
9 #include "core/stuff-handler.h"
10 #include "core/turn-compensator.h"
11 #include "core/window-redrawer.h"
12 #include "dungeon/dungeon.h"
13 #include "dungeon/quest.h"
14 #include "floor/floor-leaver.h"
15 #include "floor/floor-save-util.h"
16 #include "floor/floor-save.h"
17 #include "game-option/cheat-options.h"
18 #include "game-option/map-screen-options.h"
19 #include "game-option/play-record-options.h"
20 #include "hpmp/hp-mp-regenerator.h"
21 #include "io/cursor.h"
22 #include "io/input-key-requester.h"
23 #include "io/write-diary.h"
24 #include "market/arena.h"
25 #include "mind/mind-ninja.h"
26 #include "monster-race/monster-race.h"
27 #include "monster-race/race-flags1.h"
28 #include "monster/monster-compaction.h"
29 #include "monster/monster-processor.h"
30 #include "monster/monster-status.h"
31 #include "monster/monster-util.h"
32 #include "pet/pet-util.h"
33 #include "player-base/player-class.h"
34 #include "player/special-defense-types.h"
35 #include "realm/realm-song-numbers.h"
36 #include "realm/realm-song.h"
37 #include "spell-realm/spells-song.h"
38 #include "system/floor-type-definition.h"
39 #include "system/monster-race-definition.h"
40 #include "system/player-type-definition.h"
41 #include "target/target-checker.h"
42 #include "util/bit-flags-calculator.h"
43 #include "view/display-messages.h"
44 #include "world/world-turn-processor.h"
45 #include "world/world.h"
48 * process_player()、process_world() をcore.c から移設するのが先.
49 * process_upkeep_with_speed() はこの関数と同じところでOK
50 * @brief 現在プレイヤーがいるダンジョンの全体処理 / Interact with the current dungeon level.
53 * この関数から現在の階層を出る、プレイヤーがキャラが死ぬ、
54 * ゲームを終了するかのいずれかまでループする。
57 * This function will not exit until the level is completed,\n
58 * the user dies, or the game is terminated.\n
61 void process_dungeon(PlayerType *player_ptr, bool load_game)
63 auto *floor_ptr = player_ptr->current_floor_ptr;
64 floor_ptr->base_level = floor_ptr->dun_level;
65 w_ptr->is_loading_now = false;
66 player_ptr->leaving = false;
74 player_ptr->pet_t_m_idx = 0;
75 player_ptr->riding_t_m_idx = 0;
76 player_ptr->ambush_flag = false;
77 health_track(player_ptr, 0);
79 disturb(player_ptr, true, true);
80 auto quest_num = quest_number(player_ptr, floor_ptr->dun_level);
81 if (inside_quest(quest_num)) {
82 r_info[quest[enum2i(quest_num)].r_idx].flags1 |= RF1_QUESTOR;
85 if (player_ptr->max_plv < player_ptr->lev) {
86 player_ptr->max_plv = player_ptr->lev;
89 if ((max_dlv[player_ptr->dungeon_idx] < floor_ptr->dun_level) && !inside_quest(floor_ptr->quest_number)) {
90 max_dlv[player_ptr->dungeon_idx] = floor_ptr->dun_level;
92 exe_write_diary(player_ptr, DIARY_MAXDEAPTH, floor_ptr->dun_level, nullptr);
95 (void)calculate_upkeep(player_ptr);
96 panel_bounds_center();
97 verify_panel(player_ptr);
100 w_ptr->character_xtra = true;
101 player_ptr->window_flags |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER | PW_MONSTER | PW_OVERHEAD | PW_DUNGEON);
102 player_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_EQUIPPY | PR_MAP);
103 player_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_VIEW | PU_LITE | PU_MON_LITE | PU_TORCH | PU_MONSTERS | PU_DISTANCE | PU_FLOW);
104 handle_stuff(player_ptr);
106 w_ptr->character_xtra = false;
107 player_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
108 player_ptr->update |= (PU_COMBINE | PU_REORDER);
109 handle_stuff(player_ptr);
112 if (inside_quest(quest_num) && (quest_type::is_fixed(quest_num) && !((quest_num == QuestId::OBERON) || (quest_num == QuestId::SERPENT) || !(quest[enum2i(quest_num)].flags & QUEST_FLAG_PRESET))))
113 do_cmd_feeling(player_ptr);
115 if (player_ptr->phase_out) {
117 player_ptr->energy_need = 0;
118 update_gambling_monsters(player_ptr);
120 msg_print(_("試合開始!", "Ready..Fight!"));
125 if (PlayerClass(player_ptr).equals(PlayerClassType::BARD) && (get_singing_song_effect(player_ptr) > MUSIC_DETECT))
126 set_singing_song_effect(player_ptr, MUSIC_DETECT);
128 if (!player_ptr->playing || player_ptr->is_dead)
131 if (!inside_quest(floor_ptr->quest_number) && (player_ptr->dungeon_idx == DUNGEON_ANGBAND)) {
132 quest_discovery(random_quest_number(player_ptr, floor_ptr->dun_level));
133 floor_ptr->quest_number = random_quest_number(player_ptr, floor_ptr->dun_level);
135 if ((floor_ptr->dun_level == d_info[player_ptr->dungeon_idx].maxdepth) && d_info[player_ptr->dungeon_idx].final_guardian) {
136 if (r_info[d_info[player_ptr->dungeon_idx].final_guardian].max_num)
138 msg_format("この階には%sの主である%sが棲んでいる。", d_info[player_ptr->dungeon_idx].name.c_str(),
139 r_info[d_info[player_ptr->dungeon_idx].final_guardian].name.c_str());
141 msg_format("%^s lives in this level as the keeper of %s.", r_info[d_info[player_ptr->dungeon_idx].final_guardian].name.c_str(),
142 d_info[player_ptr->dungeon_idx].name.c_str());
147 set_superstealth(player_ptr, false);
149 floor_ptr->monster_level = floor_ptr->base_level;
150 floor_ptr->object_level = floor_ptr->base_level;
151 w_ptr->is_loading_now = true;
152 if (player_ptr->energy_need > 0 && !player_ptr->phase_out && (floor_ptr->dun_level || player_ptr->leaving_dungeon || floor_ptr->inside_arena))
153 player_ptr->energy_need = 0;
155 player_ptr->leaving_dungeon = false;
156 mproc_init(floor_ptr);
159 if ((floor_ptr->m_cnt + 32 > w_ptr->max_m_idx) && !player_ptr->phase_out)
160 compact_monsters(player_ptr, 64);
162 if ((floor_ptr->m_cnt + 32 < floor_ptr->m_max) && !player_ptr->phase_out)
163 compact_monsters(player_ptr, 0);
165 if (floor_ptr->o_cnt + 32 > w_ptr->max_o_idx)
166 compact_objects(player_ptr, 64);
168 if (floor_ptr->o_cnt + 32 < floor_ptr->o_max)
169 compact_objects(player_ptr, 0);
171 process_player(player_ptr);
172 process_upkeep_with_speed(player_ptr);
173 handle_stuff(player_ptr);
175 move_cursor_relative(player_ptr->y, player_ptr->x);
179 if (!player_ptr->playing || player_ptr->is_dead)
182 process_monsters(player_ptr);
183 handle_stuff(player_ptr);
185 move_cursor_relative(player_ptr->y, player_ptr->x);
189 if (!player_ptr->playing || player_ptr->is_dead)
192 WorldTurnProcessor(player_ptr).process_world();
193 handle_stuff(player_ptr);
195 move_cursor_relative(player_ptr->y, player_ptr->x);
200 if (!player_ptr->playing || player_ptr->is_dead)
204 if (w_ptr->dungeon_turn < w_ptr->dungeon_turn_limit) {
205 if (!player_ptr->wild_mode || wild_regen)
206 w_ptr->dungeon_turn++;
207 else if (player_ptr->wild_mode && !(w_ptr->game_turn % ((MAX_HGT + MAX_WID) / 2)))
208 w_ptr->dungeon_turn++;
211 prevent_turn_overflow(player_ptr);
213 if (player_ptr->leaving)
220 if ((inside_quest(quest_num)) && none_bits(r_info[quest[enum2i(quest_num)].r_idx].flags1, RF1_UNIQUE)) {
221 r_info[quest[enum2i(quest_num)].r_idx].flags1 &= ~RF1_QUESTOR;
224 if (player_ptr->playing && !player_ptr->is_dead) {
226 * Maintain Unique monsters and artifact, save current
227 * floor, then prepare next floor
229 leave_floor(player_ptr);
230 reinit_wilderness = false;