OSDN Git Service

Merge pull request #3740 from hengband/release/3.0.1.1-Beta
[hengbandforosx/hengbandosx.git] / src / cmd-io / cmd-lore.cpp
1 #include "cmd-io/cmd-lore.h"
2 #include "core/asking-player.h"
3 #include "core/stuff-handler.h"
4 #include "game-option/cheat-options.h"
5 #include "game-option/game-play-options.h"
6 #include "io/input-key-acceptor.h"
7 #include "lore/lore-util.h"
8 #include "monster-race/monster-race.h"
9 #include "monster-race/race-flags1.h"
10 #include "monster-race/race-flags7.h"
11 #include "system/monster-race-info.h"
12 #include "system/player-type-definition.h"
13 #include "term/gameterm.h"
14 #include "term/screen-processor.h"
15 #include "term/term-color-types.h"
16 #include "term/z-form.h"
17 #include "util/int-char-converter.h"
18 #include "util/sort.h"
19 #include "util/string-processor.h"
20 #include "view/display-lore.h"
21
22 /*!
23  * @brief モンスターの思い出を見るコマンドのメインルーチン
24  * Identify a character, allow recall of monsters
25  * @param player_ptr プレイヤーへの参照ポインタ
26  * @details
27  * <pre>
28  * Several "special" responses recall "multiple" monsters:
29  *   ^A (all monsters)
30  *   ^U (all unique monsters)
31  *   ^N (all non-unique monsters)
32  *
33  * The responses may be sorted in several ways, see below.
34  *
35  * Note that the player ghosts are ignored.
36  * </pre>
37  */
38 void do_cmd_query_symbol(PlayerType *player_ptr)
39 {
40     bool all = false;
41     bool uniq = false;
42     bool norm = false;
43     bool ride = false;
44     bool recall = false;
45
46     uint16_t why = 0;
47
48     constexpr auto prompt = _("知りたい文字を入力して下さい(記号 or ^A全,^Uユ,^N非ユ,^R乗馬,^M名前): ",
49         "Enter character to be identified(^A:All,^U:Uniqs,^N:Non uniqs,^M:Name): ");
50     const auto sym_opt = input_command(prompt);
51     if (!sym_opt) {
52         return;
53     }
54
55     const auto sym = sym_opt.value();
56     int ident_i;
57     for (ident_i = 0; ident_info[ident_i]; ++ident_i) {
58         if (sym == ident_info[ident_i][0]) {
59             break;
60         }
61     }
62
63     std::string buf;
64     std::string monster_name("");
65     if (sym == KTRL('A')) {
66         all = true;
67         buf = _("全モンスターのリスト", "Full monster list.");
68     } else if (sym == KTRL('U')) {
69         all = uniq = true;
70         buf = _("ユニーク・モンスターのリスト", "Unique monster list.");
71     } else if (sym == KTRL('N')) {
72         all = norm = true;
73         buf = _("ユニーク外モンスターのリスト", "Non-unique monster list.");
74     } else if (sym == KTRL('R')) {
75         all = ride = true;
76         buf = _("乗馬可能モンスターのリスト", "Ridable monster list.");
77     } else if (sym == KTRL('M')) {
78         all = true;
79         const auto monster_name_opt = input_string(_("名前(英語の場合小文字で可)", "Enter name:"), MAX_MONSTER_NAME);
80         if (!monster_name_opt) {
81             return;
82         }
83
84         monster_name = monster_name_opt.value();
85         buf = format(_("名前:%sにマッチ", "Monsters' names with \"%s\""), monster_name.data());
86     } else if (ident_info[ident_i]) {
87         buf = format("%c - %s.", sym, ident_info[ident_i] + 2);
88     } else {
89         buf = format("%c - %s", sym, _("無効な文字", "Unknown Symbol"));
90     }
91
92     prt(buf, 0, 0);
93     std::vector<MonsterRaceId> monraces;
94     for (const auto &[monrace_id, monrace] : monraces_info) {
95         if (!cheat_know && !monrace.r_sights) {
96             continue;
97         }
98
99         if (norm && monrace.kind_flags.has(MonsterKindType::UNIQUE)) {
100             continue;
101         }
102
103         if (uniq && monrace.kind_flags.has_not(MonsterKindType::UNIQUE)) {
104             continue;
105         }
106
107         if (ride && !(monrace.flags7 & (RF7_RIDING))) {
108             continue;
109         }
110
111         if (!monster_name.empty()) {
112             for (size_t xx = 0; xx < monster_name.length(); xx++) {
113 #ifdef JP
114                 if (iskanji(monster_name[xx])) {
115                     xx++;
116                     continue;
117                 }
118 #endif
119                 if (isupper(monster_name[xx])) {
120                     monster_name[xx] = (char)tolower(monster_name[xx]);
121                 }
122             }
123
124 #ifdef JP
125             auto temp2(monrace.E_name);
126 #else
127             auto temp2(monrace.name);
128 #endif
129             for (size_t xx = 0; xx < temp2.length(); xx++) {
130                 if (isupper(temp2[xx])) {
131                     temp2[xx] = (char)tolower(temp2[xx]);
132                 }
133             }
134
135 #ifdef JP
136             if (str_find(temp2, monster_name) || str_find(monrace.name, monster_name))
137 #else
138             if (str_find(temp2, monster_name))
139 #endif
140                 monraces.push_back(monrace_id);
141         }
142
143         else if (all || (monrace.d_char == sym)) {
144             monraces.push_back(monrace_id);
145         }
146     }
147
148     if (monraces.empty()) {
149         return;
150     }
151
152     put_str(_("思い出を見ますか? (k:殺害順/y/n): ", "Recall details? (k/y/n): "), 0, _(36, 40));
153     auto query = inkey();
154     prt(buf, 0, 0);
155     why = 2;
156     ang_sort(player_ptr, monraces.data(), &why, monraces.size(), ang_sort_comp_hook, ang_sort_swap_hook);
157     if (query == 'k') {
158         why = 4;
159         query = 'y';
160     }
161
162     if (query != 'y') {
163         return;
164     }
165
166     if (why == 4) {
167         ang_sort(player_ptr, monraces.data(), &why, monraces.size(), ang_sort_comp_hook, ang_sort_swap_hook);
168     }
169
170     auto i = monraces.size() - 1;
171     while (true) {
172         auto r_idx = monraces[i];
173         monster_race_track(player_ptr, r_idx);
174         handle_stuff(player_ptr);
175         while (true) {
176             if (recall) {
177                 screen_save();
178                 screen_roff(player_ptr, monraces[i], MONSTER_LORE_NORMAL);
179             }
180
181             roff_top(r_idx);
182             term_addstr(-1, TERM_WHITE, _(" ['r'思い出, ESC]", " [(r)ecall, ESC]"));
183             query = inkey();
184             if (recall) {
185                 screen_load();
186             }
187
188             if (query != 'r') {
189                 break;
190             }
191             recall = !recall;
192         }
193
194         if (query == ESCAPE) {
195             break;
196         }
197
198         if (query == '-') {
199             if (++i == monraces.size()) {
200                 i = 0;
201                 if (!expand_list) {
202                     break;
203                 }
204             }
205         } else {
206             if (i-- == 0) {
207                 i = monraces.size() - 1;
208                 if (!expand_list) {
209                     break;
210                 }
211             }
212         }
213     }
214
215     prt(buf, 0, 0);
216 }