OSDN Git Service

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