OSDN Git Service

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