OSDN Git Service

[Refactor] #3286 Removed player-redraw-types.h
[hengbandforosx/hengbandosx.git] / src / cmd-visual / cmd-draw.cpp
1 #include "cmd-visual/cmd-draw.h"
2 #include "core/asking-player.h"
3 #include "core/stuff-handler.h"
4 #include "core/window-redrawer.h"
5 #include "io/files-util.h"
6 #include "io/input-key-acceptor.h"
7 #include "main/sound-of-music.h"
8 #include "player-base/player-race.h"
9 #include "player-info/race-types.h"
10 #include "player/process-name.h"
11 #include "racial/racial-android.h"
12 #include "system/player-type-definition.h"
13 #include "system/redrawing-flags-updater.h"
14 #include "term/gameterm.h"
15 #include "term/screen-processor.h"
16 #include "term/term-color-types.h"
17 #include "term/z-form.h"
18 #include "util/int-char-converter.h"
19 #include "util/string-processor.h"
20 #include "view/display-messages.h"
21 #include "view/display-player.h"
22 #include "world/world.h"
23
24 /*!
25  * @brief 画面を再描画するコマンドのメインルーチン
26  * Hack -- redraw the screen
27  * @param player_ptr プレイヤーへの参照ポインタ
28  * @details
29  * <pre>
30  * This command performs various low level updates, clears all the "extra"
31  * windows, does a total redraw of the main window, and requests all of the
32  * interesting updates and redraws that I can think of.
33  *
34  * This command is also used to "instantiate" the results of the user
35  * selecting various things, such as graphics mode, so it must call
36  * the "TERM_XTRA_REACT" hook before redrawing the windows.
37  * </pre>
38  */
39 void do_cmd_redraw(PlayerType *player_ptr)
40 {
41     term_xtra(TERM_XTRA_REACT, 0);
42
43     auto &rfu = RedrawingFlagsUpdater::get_instance();
44     const auto flags_srf = {
45         StatusRedrawingFlag::COMBINATION,
46         StatusRedrawingFlag::REORDER,
47         StatusRedrawingFlag::TORCH,
48         StatusRedrawingFlag::BONUS,
49         StatusRedrawingFlag::HP,
50         StatusRedrawingFlag::MP,
51         StatusRedrawingFlag::SPELLS,
52         StatusRedrawingFlag::UN_VIEW,
53         StatusRedrawingFlag::UN_LITE,
54         StatusRedrawingFlag::VIEW,
55         StatusRedrawingFlag::LITE,
56         StatusRedrawingFlag::MONSTER_LITE,
57         StatusRedrawingFlag::MONSTER_STATUSES,
58     };
59     rfu.set_flags(flags_srf);
60     const auto flags_mwrf = {
61         MainWindowRedrawingFlag::WIPE,
62         MainWindowRedrawingFlag::BASIC,
63         MainWindowRedrawingFlag::EXTRA,
64         MainWindowRedrawingFlag::EQUIPPY,
65         MainWindowRedrawingFlag::MAP,
66     };
67     rfu.set_flags(flags_mwrf);
68     player_ptr->window_flags |= (PW_INVENTORY | PW_EQUIPMENT | PW_SPELL | PW_PLAYER);
69     player_ptr->window_flags |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER_LORE | PW_ITEM_KNOWLEDGTE);
70     update_playtime();
71     handle_stuff(player_ptr);
72     if (PlayerRace(player_ptr).equals(PlayerRaceType::ANDROID)) {
73         calc_android_exp(player_ptr);
74     }
75
76     term_type *old = game_term;
77     for (auto i = 0U; i < angband_terms.size(); ++i) {
78         if (!angband_terms[i]) {
79             continue;
80         }
81
82         term_activate(angband_terms[i]);
83         term_redraw();
84         term_fresh();
85         term_activate(old);
86     }
87 }
88
89 /*!
90  * @brief プレイヤーのステータス表示
91  */
92 void do_cmd_player_status(PlayerType *player_ptr)
93 {
94     int mode = 0;
95     char tmp[160];
96     screen_save();
97     while (true) {
98         TermCenteredOffsetSetter tcos(MAIN_TERM_MIN_COLS, MAIN_TERM_MIN_ROWS);
99
100         update_playtime();
101         (void)display_player(player_ptr, mode);
102
103         if (mode == 5) {
104             mode = 0;
105             (void)display_player(player_ptr, mode);
106         }
107
108         term_putstr(2, 23, -1, TERM_WHITE,
109             _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
110         char c = inkey();
111         if (c == ESCAPE) {
112             break;
113         }
114
115         if (c == 'c') {
116             get_name(player_ptr);
117             process_player_name(player_ptr);
118         } else if (c == 'f') {
119             strnfmt(tmp, sizeof(tmp), "%s.txt", player_ptr->base_name);
120             if (get_string(_("ファイル名: ", "File name: "), tmp, 80)) {
121                 if (tmp[0] && (tmp[0] != ' ')) {
122                     update_playtime();
123                     file_character(player_ptr, tmp);
124                 }
125             }
126         } else if (c == 'h') {
127             mode++;
128         } else {
129             bell();
130         }
131
132         msg_erase();
133     }
134
135     screen_load();
136     auto &rfu = RedrawingFlagsUpdater::get_instance();
137     const auto flags_mwrf = {
138         MainWindowRedrawingFlag::WIPE,
139         MainWindowRedrawingFlag::BASIC,
140         MainWindowRedrawingFlag::EXTRA,
141         MainWindowRedrawingFlag::EQUIPPY,
142         MainWindowRedrawingFlag::MAP,
143     };
144     rfu.set_flags(flags_mwrf);
145     handle_stuff(player_ptr);
146 }
147
148 /*!
149  * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
150  * Recall the most recent message
151  */
152 void do_cmd_message_one(void)
153 {
154     prt(format("> %s", message_str(0)), 0, 0);
155 }
156
157 /*!
158  * @brief メッセージのログを表示するコマンドのメインルーチン
159  * Recall the most recent message
160  * @details
161  * <pre>
162  * Show previous messages to the user   -BEN-
163  *
164  * The screen format uses line 0 and 23 for headers and prompts,
165  * skips line 1 and 22, and uses line 2 thru 21 for old messages.
166  *
167  * This command shows you which commands you are viewing, and allows
168  * you to "search" for strings in the recall.
169  *
170  * Note that messages may be longer than 80 characters, but they are
171  * displayed using "infinite" length, with a special sub-command to
172  * "slide" the virtual display to the left or right.
173  *
174  * Attempt to only hilite the matching portions of the string.
175  * </pre>
176  */
177 void do_cmd_messages(int num_now)
178 {
179     char shower_str[81];
180     char finder_str[81];
181     char back_str[81];
182     concptr shower = nullptr;
183     int wid, hgt;
184     term_get_size(&wid, &hgt);
185     int num_lines = hgt - 4;
186     strcpy(finder_str, "");
187     strcpy(shower_str, "");
188     int n = message_num();
189     int i = 0;
190     screen_save();
191     term_clear();
192     while (true) {
193         int j;
194         int skey;
195         for (j = 0; (j < num_lines) && (i + j < n); j++) {
196             concptr msg = message_str(i + j);
197             c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
198             if (!shower || !shower[0]) {
199                 continue;
200             }
201
202             concptr str = msg;
203             while ((str = angband_strstr(str, shower)) != nullptr) {
204                 int len = strlen(shower);
205                 term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
206                 str += len;
207             }
208         }
209
210         for (; j < num_lines; j++) {
211             term_erase(0, num_lines + 1 - j, 255);
212         }
213
214         prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"), i, i + j - 1, n), 0, 0);
215         prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]", "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
216         skey = inkey_special(true);
217         if (skey == ESCAPE) {
218             break;
219         }
220
221         j = i;
222         switch (skey) {
223         case '=':
224             prt(_("強調: ", "Show: "), hgt - 1, 0);
225             strcpy(back_str, shower_str);
226             if (askfor(shower_str, 80)) {
227                 shower = shower_str[0] ? shower_str : nullptr;
228             } else {
229                 strcpy(shower_str, back_str);
230             }
231
232             continue;
233         case '/':
234         case KTRL('s'): {
235             prt(_("検索: ", "Find: "), hgt - 1, 0);
236             strcpy(back_str, finder_str);
237             if (!askfor(finder_str, 80)) {
238                 strcpy(finder_str, back_str);
239                 continue;
240             } else if (!finder_str[0]) {
241                 shower = nullptr;
242                 continue;
243             }
244
245             shower = finder_str;
246             for (int z = i + 1; z < n; z++) {
247                 concptr msg = message_str(z);
248                 if (angband_strstr(msg, finder_str)) {
249                     i = z;
250                     break;
251                 }
252             }
253         }
254
255         break;
256
257         case SKEY_TOP:
258             i = n - num_lines;
259             break;
260         case SKEY_BOTTOM:
261             i = 0;
262             break;
263         case '8':
264         case SKEY_UP:
265         case '\n':
266         case '\r':
267             i = std::min(i + 1, n - num_lines);
268             break;
269         case '+':
270             i = std::min(i + 10, n - num_lines);
271             break;
272         case 'p':
273         case KTRL('P'):
274         case ' ':
275         case SKEY_PGUP:
276             i = std::min(i + num_lines, n - num_lines);
277             break;
278         case 'n':
279         case KTRL('N'):
280         case SKEY_PGDOWN:
281             i = std::max(0, i - num_lines);
282             break;
283         case '-':
284             i = std::max(0, i - 10);
285             break;
286         case '2':
287         case SKEY_DOWN:
288             i = std::max(0, i - 1);
289             break;
290         }
291
292         if (i == j) {
293             bell();
294         }
295     }
296
297     screen_load();
298 }