OSDN Git Service

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