OSDN Git Service

c893db23254725b491d16d6eb649d8436b29dbae
[hengbandforosx/hengbandosx.git] / src / core / window-redrawer.cpp
1 /*!
2  * @brief ウィンドウの再描画処理
3  * @date 2020/06/27
4  * @author Hourier
5  */
6 #include "core/window-redrawer.h"
7 #include "core/player-redraw-types.h"
8 #include "core/stuff-handler.h"
9 #include "floor/floor-util.h"
10 #include "game-option/option-flags.h"
11 #include "object/item-tester-hooker.h"
12 #include "player-base/player-class.h"
13 #include "player-info/race-info.h"
14 #include "system/player-type-definition.h"
15 #include "system/redrawing-flags-updater.h"
16 #include "term/gameterm.h"
17 #include "term/screen-processor.h"
18 #include "term/term-color-types.h"
19 #include "util/bit-flags-calculator.h"
20 #include "view/display-messages.h"
21 #include "view/display-player.h"
22 #include "window/display-sub-windows.h"
23 #include "window/main-window-left-frame.h"
24 #include "window/main-window-row-column.h"
25 #include "window/main-window-stat-poster.h"
26 #include "window/main-window-util.h"
27 #include "world/world-turn-processor.h"
28 #include "world/world.h"
29
30 /*!
31  * @brief コンソールを再描画する /
32  * Redraw a term when it is resized
33  * @todo ここにPlayerType を追加するとz-termに影響が行くので保留
34  */
35 void redraw_window(void)
36 {
37     if (!w_ptr->character_dungeon) {
38         return;
39     }
40
41     p_ptr->window_flags = PW_ALL;
42
43     handle_stuff(p_ptr);
44     term_redraw();
45 }
46
47 /*!
48  * @brief 現在のマップ名を描画する / Print dungeon
49  * @param player_ptr プレイヤーへの参照ポインタ
50  */
51 static void print_dungeon(PlayerType *player_ptr)
52 {
53     TERM_LEN width, height;
54     term_get_size(&width, &height);
55
56     c_put_str(TERM_WHITE, "             ", height + ROW_DUNGEON, COL_DUNGEON);
57     const auto dungeon_name = map_name(player_ptr);
58     TERM_LEN col = COL_DUNGEON + 6 - dungeon_name.length() / 2;
59     if (col < 0) {
60         col = 0;
61     }
62
63     c_put_str(TERM_L_UMBER, dungeon_name, height + ROW_DUNGEON, col);
64 }
65
66 /*!
67  * @brief redraw のフラグに応じた更新をまとめて行う / Handle "redraw"
68  * @details 更新処理の対象はゲーム中の全描画処理
69  */
70 void redraw_stuff(PlayerType *player_ptr)
71 {
72     auto &rfu = RedrawingFlagsUpdater::get_instance();
73     if (!rfu.any_main()) {
74         return;
75     }
76
77     if (!w_ptr->character_generated) {
78         return;
79     }
80
81     if (w_ptr->character_icky_depth > 0) {
82         return;
83     }
84
85     if (rfu.has(MainWindowRedrawingFlag::WIPE)) {
86         rfu.reset_flag(MainWindowRedrawingFlag::WIPE);
87         msg_print(nullptr);
88         term_clear();
89     }
90
91     if (rfu.has(MainWindowRedrawingFlag::MAP)) {
92         rfu.reset_flag(MainWindowRedrawingFlag::MAP);
93         print_map(player_ptr);
94     }
95
96     if (rfu.has(MainWindowRedrawingFlag::BASIC)) {
97         const auto flags = {
98             MainWindowRedrawingFlag::BASIC,
99             MainWindowRedrawingFlag::TITLE,
100             MainWindowRedrawingFlag::ABILITY_SCORE,
101             MainWindowRedrawingFlag::LEVEL,
102             MainWindowRedrawingFlag::EXP,
103             MainWindowRedrawingFlag::GOLD,
104             MainWindowRedrawingFlag::AC,
105             MainWindowRedrawingFlag::HP,
106             MainWindowRedrawingFlag::MP,
107             MainWindowRedrawingFlag::DEPTH,
108             MainWindowRedrawingFlag::HEALTH,
109             MainWindowRedrawingFlag::UHEALTH,
110         };
111         rfu.reset_flags(flags);
112         print_frame_basic(player_ptr);
113         WorldTurnProcessor(player_ptr).print_time();
114         print_dungeon(player_ptr);
115     }
116
117     if (rfu.has(MainWindowRedrawingFlag::EQUIPPY)) {
118         rfu.reset_flag(MainWindowRedrawingFlag::EQUIPPY);
119         display_player_equippy(player_ptr, ROW_EQUIPPY, COL_EQUIPPY, 0);
120     }
121
122     if (rfu.has(MainWindowRedrawingFlag::TITLE)) {
123         rfu.reset_flag(MainWindowRedrawingFlag::TITLE);
124         print_title(player_ptr);
125     }
126
127     if (rfu.has(MainWindowRedrawingFlag::LEVEL)) {
128         rfu.reset_flag(MainWindowRedrawingFlag::LEVEL);
129         print_level(player_ptr);
130     }
131
132     if (rfu.has(MainWindowRedrawingFlag::EXP)) {
133         rfu.reset_flag(MainWindowRedrawingFlag::EXP);
134         print_exp(player_ptr);
135     }
136
137     if (rfu.has(MainWindowRedrawingFlag::ABILITY_SCORE)) {
138         rfu.reset_flag(MainWindowRedrawingFlag::ABILITY_SCORE);
139         print_stat(player_ptr, A_STR);
140         print_stat(player_ptr, A_INT);
141         print_stat(player_ptr, A_WIS);
142         print_stat(player_ptr, A_DEX);
143         print_stat(player_ptr, A_CON);
144         print_stat(player_ptr, A_CHR);
145     }
146
147     if (rfu.has(MainWindowRedrawingFlag::TIMED_EFFECT)) {
148         rfu.reset_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
149         print_status(player_ptr);
150     }
151
152     if (rfu.has(MainWindowRedrawingFlag::AC)) {
153         rfu.reset_flag(MainWindowRedrawingFlag::AC);
154         print_ac(player_ptr);
155     }
156
157     if (rfu.has(MainWindowRedrawingFlag::HP)) {
158         rfu.reset_flag(MainWindowRedrawingFlag::HP);
159         print_hp(player_ptr);
160     }
161
162     if (rfu.has(MainWindowRedrawingFlag::MP)) {
163         rfu.reset_flag(MainWindowRedrawingFlag::MP);
164         print_sp(player_ptr);
165     }
166
167     if (rfu.has(MainWindowRedrawingFlag::GOLD)) {
168         rfu.reset_flag(MainWindowRedrawingFlag::GOLD);
169         print_gold(player_ptr);
170     }
171
172     if (rfu.has(MainWindowRedrawingFlag::DEPTH)) {
173         rfu.reset_flag(MainWindowRedrawingFlag::DEPTH);
174         print_depth(player_ptr);
175     }
176
177     if (rfu.has(MainWindowRedrawingFlag::UHEALTH)) {
178         rfu.reset_flag(MainWindowRedrawingFlag::UHEALTH);
179         print_health(player_ptr, true);
180     }
181
182     if (rfu.has(MainWindowRedrawingFlag::HEALTH)) {
183         rfu.reset_flag(MainWindowRedrawingFlag::HEALTH);
184         print_health(player_ptr, false);
185     }
186
187     if (rfu.has(MainWindowRedrawingFlag::EXTRA)) {
188         const auto flags = {
189             MainWindowRedrawingFlag::EXTRA,
190             MainWindowRedrawingFlag::CUT,
191             MainWindowRedrawingFlag::STUN,
192             MainWindowRedrawingFlag::HUNGER,
193             MainWindowRedrawingFlag::ACTION,
194             MainWindowRedrawingFlag::SPEED,
195             MainWindowRedrawingFlag::STUDY,
196             MainWindowRedrawingFlag::IMITATION,
197             MainWindowRedrawingFlag::TIMED_EFFECT,
198         };
199         rfu.reset_flags(flags);
200         print_frame_extra(player_ptr);
201     }
202
203     if (rfu.has(MainWindowRedrawingFlag::CUT)) {
204         rfu.reset_flag(MainWindowRedrawingFlag::CUT);
205         print_cut(player_ptr);
206     }
207
208     if (rfu.has(MainWindowRedrawingFlag::STUN)) {
209         rfu.reset_flag(MainWindowRedrawingFlag::STUN);
210         print_stun(player_ptr);
211     }
212
213     if (rfu.has(MainWindowRedrawingFlag::HUNGER)) {
214         rfu.reset_flag(MainWindowRedrawingFlag::HUNGER);
215         print_hunger(player_ptr);
216     }
217
218     if (rfu.has(MainWindowRedrawingFlag::ACTION)) {
219         rfu.reset_flag(MainWindowRedrawingFlag::ACTION);
220         print_state(player_ptr);
221     }
222
223     if (rfu.has(MainWindowRedrawingFlag::SPEED)) {
224         rfu.reset_flag(MainWindowRedrawingFlag::SPEED);
225         print_speed(player_ptr);
226     }
227
228     if (PlayerClass(player_ptr).equals(PlayerClassType::IMITATOR)) {
229         if (rfu.has(MainWindowRedrawingFlag::IMITATION)) {
230             rfu.reset_flag(MainWindowRedrawingFlag::IMITATION);
231             print_imitation(player_ptr);
232         }
233
234         return;
235     }
236
237     if (rfu.has(MainWindowRedrawingFlag::STUDY)) {
238         rfu.reset_flag(MainWindowRedrawingFlag::STUDY);
239         print_study(player_ptr);
240     }
241 }
242
243 /*!
244  * @brief player_ptr->window のフラグに応じた更新をまとめて行う / Handle "player_ptr->window"
245  * @param player_ptr プレイヤーへの参照ポインタ
246  * @details 更新処理の対象はサブウィンドウ全般
247  */
248 void window_stuff(PlayerType *player_ptr)
249 {
250     if (!player_ptr->window_flags) {
251         return;
252     }
253
254     BIT_FLAGS mask = 0L;
255     for (auto i = 0U; i < angband_terms.size(); ++i) {
256         if (angband_terms[i] && !angband_terms[i]->never_fresh) {
257             mask |= window_flag[i];
258         }
259     }
260     BIT_FLAGS window_flags = player_ptr->window_flags & mask;
261
262     if (window_flags & (PW_INVENTORY)) {
263         player_ptr->window_flags &= ~(PW_INVENTORY);
264         fix_inventory(player_ptr);
265     }
266
267     if (window_flags & (PW_EQUIPMENT)) {
268         player_ptr->window_flags &= ~(PW_EQUIPMENT);
269         fix_equip(player_ptr);
270     }
271
272     if (window_flags & (PW_SPELL)) {
273         player_ptr->window_flags &= ~(PW_SPELL);
274         fix_spell(player_ptr);
275     }
276
277     if (window_flags & (PW_PLAYER)) {
278         player_ptr->window_flags &= ~(PW_PLAYER);
279         fix_player(player_ptr);
280     }
281
282     // モンスターBGM対応のため、視界内モンスター表示のサブウインドウなし時も処理を行う
283     if (player_ptr->window_flags & (PW_SIGHT_MONSTERS)) {
284         player_ptr->window_flags &= ~(PW_SIGHT_MONSTERS);
285         fix_monster_list(player_ptr);
286     }
287
288     if (window_flags & (PW_MESSAGE)) {
289         player_ptr->window_flags &= ~(PW_MESSAGE);
290         fix_message();
291     }
292
293     if (window_flags & (PW_OVERHEAD)) {
294         player_ptr->window_flags &= ~(PW_OVERHEAD);
295         fix_overhead(player_ptr);
296     }
297
298     if (window_flags & (PW_DUNGEON)) {
299         player_ptr->window_flags &= ~(PW_DUNGEON);
300         fix_dungeon(player_ptr);
301     }
302
303     if (window_flags & (PW_MONSTER_LORE)) {
304         player_ptr->window_flags &= ~(PW_MONSTER_LORE);
305         fix_monster(player_ptr);
306     }
307
308     if (window_flags & (PW_ITEM_KNOWLEDGTE)) {
309         player_ptr->window_flags &= ~(PW_ITEM_KNOWLEDGTE);
310         fix_object(player_ptr);
311     }
312
313     if (any_bits(window_flags, PW_FLOOR_ITEMS)) {
314         reset_bits(player_ptr->window_flags, PW_FLOOR_ITEMS);
315         // ウィンドウサイズ変更に対応できず。カーソル位置を取る必要がある。
316         fix_floor_item_list(player_ptr, player_ptr->y, player_ptr->x);
317     }
318
319     if (any_bits(window_flags, PW_FOUND_ITEMS)) {
320         reset_bits(player_ptr->window_flags, PW_FOUND_ITEMS);
321         fix_found_item_list(player_ptr);
322     }
323 }