OSDN Git Service

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