OSDN Git Service

[Refactor] #40413 Separated display-messages.c/h from util.c/h
[hengbandforosx/hengbandosx.git] / src / dungeon / dungeon-processor.c
1 #include "dungeon/dungeon-processor.h"
2 #include "cmd-io/cmd-dump.h"
3 #include "core/hp-mp-regenerator.h"
4 #include "core/player-processor.h"
5 #include "core/stuff-handler.h"
6 #include "core/turn-compensator.h"
7 #include "dungeon/dungeon.h"
8 #include "dungeon/quest.h"
9 #include "floor/floor-save.h"
10 #include "game-option/map-screen-options.h"
11 #include "game-option/play-record-options.h"
12 #include "io/targeting.h"
13 #include "io/write-diary.h"
14 #include "market/arena.h"
15 #include "monster-race/race-flags1.h"
16 #include "monster/monster-compaction.h"
17 #include "monster/monster-processor.h"
18 #include "monster/monster-status.h"
19 #include "monster/monster-util.h"
20 #include "player/player-effects.h"
21 #include "player/player-move.h"
22 #include "realm/realm-song-numbers.h"
23 #include "realm/realm-song.h"
24 #include "view/display-main-window.h"
25 #include "view/display-messages.h"
26 #include "world/world-turn-processor.h"
27 #include "world/world.h"
28
29 /*!
30  * process_player()、process_world() をcore.c から移設するのが先.
31  * process_upkeep_with_speed() はこの関数と同じところでOK
32  * @brief 現在プレイヤーがいるダンジョンの全体処理 / Interact with the current dungeon level.
33  * @return なし
34  * @details
35  * <p>
36  * この関数から現在の階層を出る、プレイヤーがキャラが死ぬ、
37  * ゲームを終了するかのいずれかまでループする。
38  * </p>
39  * <p>
40  * This function will not exit until the level is completed,\n
41  * the user dies, or the game is terminated.\n
42  * </p>
43  */
44 void process_dungeon(player_type *player_ptr, bool load_game)
45 {
46     floor_type *floor_ptr = player_ptr->current_floor_ptr;
47     floor_ptr->base_level = floor_ptr->dun_level;
48     current_world_ptr->is_loading_now = FALSE;
49     player_ptr->leaving = FALSE;
50
51     command_cmd = 0;
52     command_rep = 0;
53     command_arg = 0;
54     command_dir = 0;
55
56     target_who = 0;
57     player_ptr->pet_t_m_idx = 0;
58     player_ptr->riding_t_m_idx = 0;
59     player_ptr->ambush_flag = FALSE;
60     health_track(player_ptr, 0);
61     repair_monsters = TRUE;
62
63     disturb(player_ptr, TRUE, TRUE);
64     int quest_num = quest_num = quest_number(player_ptr, floor_ptr->dun_level);
65     if (quest_num) {
66         r_info[quest[quest_num].r_idx].flags1 |= RF1_QUESTOR;
67     }
68
69     if (player_ptr->max_plv < player_ptr->lev) {
70         player_ptr->max_plv = player_ptr->lev;
71     }
72
73     if ((max_dlv[player_ptr->dungeon_idx] < floor_ptr->dun_level) && !floor_ptr->inside_quest) {
74         max_dlv[player_ptr->dungeon_idx] = floor_ptr->dun_level;
75         if (record_maxdepth)
76             exe_write_diary(player_ptr, DIARY_MAXDEAPTH, floor_ptr->dun_level, NULL);
77     }
78
79     (void)calculate_upkeep(player_ptr);
80     panel_bounds_center();
81     verify_panel(player_ptr);
82     msg_erase();
83
84     current_world_ptr->character_xtra = TRUE;
85     player_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER | PW_MONSTER | PW_OVERHEAD | PW_DUNGEON);
86     player_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_EQUIPPY | PR_MAP);
87     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);
88     handle_stuff(player_ptr);
89
90     current_world_ptr->character_xtra = FALSE;
91     player_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
92     player_ptr->update |= (PU_COMBINE | PU_REORDER);
93     handle_stuff(player_ptr);
94     Term_fresh();
95
96     if (quest_num
97         && (is_fixed_quest_idx(quest_num) && !((quest_num == QUEST_OBERON) || (quest_num == QUEST_SERPENT) || !(quest[quest_num].flags & QUEST_FLAG_PRESET))))
98         do_cmd_feeling(player_ptr);
99
100     if (player_ptr->phase_out) {
101         if (load_game) {
102             player_ptr->energy_need = 0;
103             update_gambling_monsters(player_ptr);
104         } else {
105             msg_print(_("試合開始!", "Ready..Fight!"));
106             msg_print(NULL);
107         }
108     }
109
110     if ((player_ptr->pclass == CLASS_BARD) && (SINGING_SONG_EFFECT(player_ptr) > MUSIC_DETECT))
111         SINGING_SONG_EFFECT(player_ptr) = MUSIC_DETECT;
112
113     if (!player_ptr->playing || player_ptr->is_dead)
114         return;
115
116     if (!floor_ptr->inside_quest && (player_ptr->dungeon_idx == DUNGEON_ANGBAND)) {
117         quest_discovery(random_quest_number(player_ptr, floor_ptr->dun_level));
118         floor_ptr->inside_quest = random_quest_number(player_ptr, floor_ptr->dun_level);
119     }
120     if ((floor_ptr->dun_level == d_info[player_ptr->dungeon_idx].maxdepth) && d_info[player_ptr->dungeon_idx].final_guardian) {
121         if (r_info[d_info[player_ptr->dungeon_idx].final_guardian].max_num)
122 #ifdef JP
123             msg_format("この階には%sの主である%sが棲んでいる。", d_name + d_info[player_ptr->dungeon_idx].name,
124                 r_name + r_info[d_info[player_ptr->dungeon_idx].final_guardian].name);
125 #else
126             msg_format("%^s lives in this level as the keeper of %s.", r_name + r_info[d_info[player_ptr->dungeon_idx].final_guardian].name,
127                 d_name + d_info[player_ptr->dungeon_idx].name);
128 #endif
129     }
130
131     if (!load_game && (player_ptr->special_defense & NINJA_S_STEALTH))
132         set_superstealth(player_ptr, FALSE);
133
134     floor_ptr->monster_level = floor_ptr->base_level;
135     floor_ptr->object_level = floor_ptr->base_level;
136     current_world_ptr->is_loading_now = TRUE;
137     if (player_ptr->energy_need > 0 && !player_ptr->phase_out && (floor_ptr->dun_level || player_ptr->leaving_dungeon || floor_ptr->inside_arena))
138         player_ptr->energy_need = 0;
139
140     player_ptr->leaving_dungeon = FALSE;
141     mproc_init(floor_ptr);
142
143     while (TRUE) {
144         if ((floor_ptr->m_cnt + 32 > current_world_ptr->max_m_idx) && !player_ptr->phase_out)
145             compact_monsters(player_ptr, 64);
146
147         if ((floor_ptr->m_cnt + 32 < floor_ptr->m_max) && !player_ptr->phase_out)
148             compact_monsters(player_ptr, 0);
149
150         if (floor_ptr->o_cnt + 32 > current_world_ptr->max_o_idx)
151             compact_objects(player_ptr, 64);
152
153         if (floor_ptr->o_cnt + 32 < floor_ptr->o_max)
154             compact_objects(player_ptr, 0);
155
156         process_player(player_ptr);
157         process_upkeep_with_speed(player_ptr);
158         handle_stuff(player_ptr);
159
160         move_cursor_relative(player_ptr->y, player_ptr->x);
161         if (fresh_after)
162             Term_fresh();
163
164         if (!player_ptr->playing || player_ptr->is_dead)
165             break;
166
167         process_monsters(player_ptr);
168         handle_stuff(player_ptr);
169
170         move_cursor_relative(player_ptr->y, player_ptr->x);
171         if (fresh_after)
172             Term_fresh();
173
174         if (!player_ptr->playing || player_ptr->is_dead)
175             break;
176
177         process_world(player_ptr);
178         handle_stuff(player_ptr);
179
180         move_cursor_relative(player_ptr->y, player_ptr->x);
181         if (fresh_after)
182             Term_fresh();
183
184         if (!player_ptr->playing || player_ptr->is_dead)
185             break;
186
187         current_world_ptr->game_turn++;
188         if (current_world_ptr->dungeon_turn < current_world_ptr->dungeon_turn_limit) {
189             if (!player_ptr->wild_mode || wild_regen)
190                 current_world_ptr->dungeon_turn++;
191             else if (player_ptr->wild_mode && !(current_world_ptr->game_turn % ((MAX_HGT + MAX_WID) / 2)))
192                 current_world_ptr->dungeon_turn++;
193         }
194
195         prevent_turn_overflow(player_ptr);
196
197         if (player_ptr->leaving)
198             break;
199
200         if (wild_regen)
201             wild_regen--;
202     }
203
204     if (quest_num && !(r_info[quest[quest_num].r_idx].flags1 & RF1_UNIQUE)) {
205         r_info[quest[quest_num].r_idx].flags1 &= ~RF1_QUESTOR;
206     }
207
208     if (player_ptr->playing && !player_ptr->is_dead) {
209         /*
210          * Maintain Unique monsters and artifact, save current
211          * floor, then prepare next floor
212          */
213         leave_floor(player_ptr);
214         reinit_wilderness = FALSE;
215     }
216
217     write_level = TRUE;
218 }