OSDN Git Service

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