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"
26 * @brief 画面を再描画するコマンドのメインルーチン
27 * Hack -- redraw the screen
28 * @param player_ptr プレイヤーへの参照ポインタ
31 * This command performs various low level updates, clears all the "extra"
32 * windows, does a total redraw of the main window, and requests all of the
33 * interesting updates and redraws that I can think of.
35 * This command is also used to "instantiate" the results of the user
36 * selecting various things, such as graphics mode, so it must call
37 * the "TERM_XTRA_REACT" hook before redrawing the windows.
40 void do_cmd_redraw(PlayerType *player_ptr)
42 term_xtra(TERM_XTRA_REACT, 0);
44 auto &rfu = RedrawingFlagsUpdater::get_instance();
45 static constexpr auto flags_srf = {
46 StatusRecalculatingFlag::COMBINATION,
47 StatusRecalculatingFlag::REORDER,
48 StatusRecalculatingFlag::TORCH,
49 StatusRecalculatingFlag::BONUS,
50 StatusRecalculatingFlag::HP,
51 StatusRecalculatingFlag::MP,
52 StatusRecalculatingFlag::SPELLS,
53 StatusRecalculatingFlag::UN_VIEW,
54 StatusRecalculatingFlag::UN_LITE,
55 StatusRecalculatingFlag::VIEW,
56 StatusRecalculatingFlag::LITE,
57 StatusRecalculatingFlag::MONSTER_LITE,
58 StatusRecalculatingFlag::MONSTER_STATUSES,
60 rfu.set_flags(flags_srf);
61 static constexpr auto flags_mwrf = {
62 MainWindowRedrawingFlag::WIPE,
63 MainWindowRedrawingFlag::BASIC,
64 MainWindowRedrawingFlag::EXTRA,
65 MainWindowRedrawingFlag::EQUIPPY,
66 MainWindowRedrawingFlag::MAP,
68 rfu.set_flags(flags_mwrf);
69 static constexpr auto flags_swrf = {
70 SubWindowRedrawingFlag::INVENTORY,
71 SubWindowRedrawingFlag::EQUIPMENT,
72 SubWindowRedrawingFlag::SPELL,
73 SubWindowRedrawingFlag::PLAYER,
74 SubWindowRedrawingFlag::MESSAGE,
75 SubWindowRedrawingFlag::OVERHEAD,
76 SubWindowRedrawingFlag::DUNGEON,
77 SubWindowRedrawingFlag::MONSTER_LORE,
78 SubWindowRedrawingFlag::ITEM_KNOWLEDGE,
80 rfu.set_flags(flags_swrf);
82 handle_stuff(player_ptr);
83 if (PlayerRace(player_ptr).equals(PlayerRaceType::ANDROID)) {
84 calc_android_exp(player_ptr);
87 term_type *old = game_term;
88 for (auto i = 0U; i < angband_terms.size(); ++i) {
89 if (!angband_terms[i]) {
93 term_activate(angband_terms[i]);
100 static std::optional<int> input_status_command(PlayerType *player_ptr, int page)
105 get_name(player_ptr);
106 process_player_name(player_ptr);
109 const auto initial_filename = format("%s.txt", player_ptr->base_name);
110 const auto input_filename = input_string(_("ファイル名: ", "File name: "), 80, initial_filename);
111 if (!input_filename) {
115 const auto &filename = str_ltrim(input_filename.value());
116 if (!filename.empty()) {
118 file_character(player_ptr, filename);
134 * @brief プレイヤーのステータス表示
136 void do_cmd_player_status(PlayerType *player_ptr)
140 constexpr auto prompt = _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
142 TermCenteredOffsetSetter tcos(MAIN_TERM_MIN_COLS, MAIN_TERM_MIN_ROWS);
145 (void)display_player(player_ptr, page);
148 (void)display_player(player_ptr, page);
151 term_putstr(2, 23, -1, TERM_WHITE, prompt);
152 auto next_page = input_status_command(player_ptr, page);
157 page = next_page.value();
162 auto &rfu = RedrawingFlagsUpdater::get_instance();
163 static constexpr auto flags_mwrf = {
164 MainWindowRedrawingFlag::WIPE,
165 MainWindowRedrawingFlag::BASIC,
166 MainWindowRedrawingFlag::EXTRA,
167 MainWindowRedrawingFlag::EQUIPPY,
168 MainWindowRedrawingFlag::MAP,
170 rfu.set_flags(flags_mwrf);
171 handle_stuff(player_ptr);
175 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
176 * Recall the most recent message
178 void do_cmd_message_one(void)
180 prt(format("> %s", message_str(0)->data()), 0, 0);
184 * @brief メッセージのログを表示するコマンドのメインルーチン
185 * Recall the most recent message
188 * Show previous messages to the user -BEN-
190 * The screen format uses line 0 and 23 for headers and prompts,
191 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
193 * This command shows you which commands you are viewing, and allows
194 * you to "search" for strings in the recall.
196 * Note that messages may be longer than 80 characters, but they are
197 * displayed using "infinite" length, with a special sub-command to
198 * "slide" the virtual display to the left or right.
200 * Attempt to only hilite the matching portions of the string.
203 void do_cmd_messages(int num_now)
205 std::string shower_str("");
206 std::string finder_str("");
207 std::string shower("");
208 const auto &[wid, hgt] = term_get_size();
209 auto num_lines = hgt - 4;
210 auto n = message_num();
217 for (j = 0; (j < num_lines) && (i + j < n); j++) {
218 const auto msg_str = message_str(i + j);
219 const auto *msg = msg_str->data();
220 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
221 if (shower.empty()) {
225 // @details ダメ文字対策でstringを使わない.
226 const auto *str = msg;
228 str = angband_strstr(str, shower);
229 if (str == nullptr) {
233 const auto len = shower.length();
234 term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
239 for (; j < num_lines; j++) {
240 term_erase(0, num_lines + 1 - j);
243 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"), i, i + j - 1, n), 0, 0);
244 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]", "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
245 skey = inkey_special(true);
246 if (skey == ESCAPE) {
253 prt(_("強調: ", "Show: "), hgt - 1, 0);
254 const auto ask_result = askfor(80, shower_str);
256 shower = *ask_result;
257 shower_str = *ask_result;
264 prt(_("検索: ", "Find: "), hgt - 1, 0);
265 const auto ask_result = askfor(80, finder_str);
270 finder_str = *ask_result;
271 if (finder_str.empty()) {
277 for (int z = i + 1; z < n; z++) {
278 // @details ダメ文字対策でstringを使わない.
279 const auto msg = message_str(z);
280 if (str_find(*msg, finder_str)) {
298 i = std::min(i + 1, n - num_lines);
301 i = std::min(i + 10, n - num_lines);
307 i = std::min(i + num_lines, n - num_lines);
312 i = std::max(0, i - num_lines);
315 i = std::max(0, i - 10);
319 i = std::max(0, i - 1);