OSDN Git Service

cbc414723a671b4e7c54eec540d4bd2ace121932
[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/player-redraw-types.h"
4 #include "core/player-update-types.h"
5 #include "core/stuff-handler.h"
6 #include "core/window-redrawer.h"
7 #include "io/files-util.h"
8 #include "io/input-key-acceptor.h"
9 #include "main/sound-of-music.h"
10 #include "player-base/player-race.h"
11 #include "player-info/race-types.h"
12 #include "player/process-name.h"
13 #include "racial/racial-android.h"
14 #include "system/player-type-definition.h"
15 #include "term/gameterm.h"
16 #include "term/screen-processor.h"
17 #include "term/term-color-types.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     player_ptr->update |= (PU_COMBINE | PU_REORDER);
44     player_ptr->update |= (PU_TORCH);
45     player_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
46     player_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
47     player_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
48     player_ptr->update |= (PU_MONSTERS);
49
50     player_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
51
52     player_ptr->window_flags |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
53     player_ptr->window_flags |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
54
55     update_playtime();
56     handle_stuff(player_ptr);
57     if (PlayerRace(player_ptr).equals(PlayerRaceType::ANDROID)) {
58         calc_android_exp(player_ptr);
59     }
60
61     term_type *old = game_term;
62     for (auto i = 0U; i < angband_terms.size(); ++i) {
63         if (!angband_terms[i]) {
64             continue;
65         }
66
67         term_activate(angband_terms[i]);
68         term_redraw();
69         term_fresh();
70         term_activate(old);
71     }
72 }
73
74 /*!
75  * @brief プレイヤーのステータス表示
76  */
77 void do_cmd_player_status(PlayerType *player_ptr)
78 {
79     int mode = 0;
80     char tmp[160];
81     screen_save();
82     while (true) {
83         update_playtime();
84         (void)display_player(player_ptr, mode);
85
86         if (mode == 5) {
87             mode = 0;
88             (void)display_player(player_ptr, mode);
89         }
90
91         term_putstr(2, 23, -1, TERM_WHITE,
92             _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
93         char c = inkey();
94         if (c == ESCAPE) {
95             break;
96         }
97
98         if (c == 'c') {
99             get_name(player_ptr);
100             process_player_name(player_ptr);
101         } else if (c == 'f') {
102             sprintf(tmp, "%s.txt", player_ptr->base_name);
103             if (get_string(_("ファイル名: ", "File name: "), tmp, 80)) {
104                 if (tmp[0] && (tmp[0] != ' ')) {
105                     update_playtime();
106                     file_character(player_ptr, tmp);
107                 }
108             }
109         } else if (c == 'h') {
110             mode++;
111         } else {
112             bell();
113         }
114
115         msg_erase();
116     }
117
118     screen_load();
119     player_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
120     handle_stuff(player_ptr);
121 }
122
123 /*!
124  * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
125  * Recall the most recent message
126  */
127 void do_cmd_message_one(void)
128 {
129     prt(format("> %s", message_str(0)), 0, 0);
130 }
131
132 /*!
133  * @brief メッセージのログを表示するコマンドのメインルーチン
134  * Recall the most recent message
135  * @details
136  * <pre>
137  * Show previous messages to the user   -BEN-
138  *
139  * The screen format uses line 0 and 23 for headers and prompts,
140  * skips line 1 and 22, and uses line 2 thru 21 for old messages.
141  *
142  * This command shows you which commands you are viewing, and allows
143  * you to "search" for strings in the recall.
144  *
145  * Note that messages may be longer than 80 characters, but they are
146  * displayed using "infinite" length, with a special sub-command to
147  * "slide" the virtual display to the left or right.
148  *
149  * Attempt to only hilite the matching portions of the string.
150  * </pre>
151  */
152 void do_cmd_messages(int num_now)
153 {
154     char shower_str[81];
155     char finder_str[81];
156     char back_str[81];
157     concptr shower = nullptr;
158     int wid, hgt;
159     term_get_size(&wid, &hgt);
160     int num_lines = hgt - 4;
161     strcpy(finder_str, "");
162     strcpy(shower_str, "");
163     int n = message_num();
164     int i = 0;
165     screen_save();
166     term_clear();
167     while (true) {
168         int j;
169         int skey;
170         for (j = 0; (j < num_lines) && (i + j < n); j++) {
171             concptr msg = message_str(i + j);
172             c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
173             if (!shower || !shower[0]) {
174                 continue;
175             }
176
177             concptr str = msg;
178             while ((str = angband_strstr(str, shower)) != nullptr) {
179                 int len = strlen(shower);
180                 term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
181                 str += len;
182             }
183         }
184
185         for (; j < num_lines; j++) {
186             term_erase(0, num_lines + 1 - j, 255);
187         }
188
189         prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"), i, i + j - 1, n), 0, 0);
190         prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]", "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
191         skey = inkey_special(true);
192         if (skey == ESCAPE) {
193             break;
194         }
195
196         j = i;
197         switch (skey) {
198         case '=':
199             prt(_("強調: ", "Show: "), hgt - 1, 0);
200             strcpy(back_str, shower_str);
201             if (askfor(shower_str, 80)) {
202                 shower = shower_str[0] ? shower_str : nullptr;
203             } else {
204                 strcpy(shower_str, back_str);
205             }
206
207             continue;
208         case '/':
209         case KTRL('s'): {
210             prt(_("検索: ", "Find: "), hgt - 1, 0);
211             strcpy(back_str, finder_str);
212             if (!askfor(finder_str, 80)) {
213                 strcpy(finder_str, back_str);
214                 continue;
215             } else if (!finder_str[0]) {
216                 shower = nullptr;
217                 continue;
218             }
219
220             shower = finder_str;
221             for (int z = i + 1; z < n; z++) {
222                 concptr msg = message_str(z);
223                 if (angband_strstr(msg, finder_str)) {
224                     i = z;
225                     break;
226                 }
227             }
228         }
229
230         break;
231
232         case SKEY_TOP:
233             i = n - num_lines;
234             break;
235         case SKEY_BOTTOM:
236             i = 0;
237             break;
238         case '8':
239         case SKEY_UP:
240         case '\n':
241         case '\r':
242             i = std::min(i + 1, n - num_lines);
243             break;
244         case '+':
245             i = std::min(i + 10, n - num_lines);
246             break;
247         case 'p':
248         case KTRL('P'):
249         case ' ':
250         case SKEY_PGUP:
251             i = std::min(i + num_lines, n - num_lines);
252             break;
253         case 'n':
254         case KTRL('N'):
255         case SKEY_PGDOWN:
256             i = std::max(0, i - num_lines);
257             break;
258         case '-':
259             i = std::max(0, i - 10);
260             break;
261         case '2':
262         case SKEY_DOWN:
263             i = std::max(0, i - 1);
264             break;
265         }
266
267         if (i == j) {
268             bell();
269         }
270     }
271
272     screen_load();
273 }