OSDN Git Service

[Refactor] r_info 配列に対するループを range-based for に置き換える
[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-definition.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(player_type *player_ptr)
38 {
39     MONRACE_IDX i;
40     int n;
41     MONRACE_IDX r_idx;
42     char sym, query;
43     char buf[256];
44
45     bool all = false;
46     bool uniq = false;
47     bool norm = false;
48     bool ride = false;
49     char temp[MAX_MONSTER_NAME] = "";
50
51     bool recall = false;
52
53     uint16_t why = 0;
54     MONRACE_IDX *who;
55
56     if (!get_com(_("知りたい文字を入力して下さい(記号 or ^A全,^Uユ,^N非ユ,^R乗馬,^M名前): ",
57                      "Enter character to be identified(^A:All,^U:Uniqs,^N:Non uniqs,^M:Name): "),
58             &sym, false))
59         return;
60
61     for (i = 0; ident_info[i]; ++i) {
62         if (sym == ident_info[i][0])
63             break;
64     }
65
66     if (sym == KTRL('A')) {
67         all = true;
68         strcpy(buf, _("全モンスターのリスト", "Full monster list."));
69     } else if (sym == KTRL('U')) {
70         all = uniq = true;
71         strcpy(buf, _("ユニーク・モンスターのリスト", "Unique monster list."));
72     } else if (sym == KTRL('N')) {
73         all = norm = true;
74         strcpy(buf, _("ユニーク外モンスターのリスト", "Non-unique monster list."));
75     } else if (sym == KTRL('R')) {
76         all = ride = true;
77         strcpy(buf, _("乗馬可能モンスターのリスト", "Ridable monster list."));
78     } else if (sym == KTRL('M')) {
79         all = true;
80         if (!get_string(_("名前(英語の場合小文字で可)", "Enter name:"), temp, 70)) {
81             temp[0] = 0;
82             return;
83         }
84         sprintf(buf, _("名前:%sにマッチ", "Monsters' names with \"%s\""), temp);
85     } else if (ident_info[i]) {
86         sprintf(buf, "%c - %s.", sym, ident_info[i] + 2);
87     } else {
88         sprintf(buf, "%c - %s", sym, _("無効な文字", "Unknown Symbol"));
89     }
90
91     prt(buf, 0, 0);
92     C_MAKE(who, max_r_idx, MONRACE_IDX);
93     n = 0;
94     for (const auto &r_ref : r_info) {
95         if (!cheat_know && !r_ref.r_sights)
96             continue;
97
98         if (norm && (r_ref.flags1 & (RF1_UNIQUE)))
99             continue;
100
101         if (uniq && !(r_ref.flags1 & (RF1_UNIQUE)))
102             continue;
103
104         if (ride && !(r_ref.flags7 & (RF7_RIDING)))
105             continue;
106
107         if (temp[0]) {
108             TERM_LEN xx;
109             char temp2[MAX_MONSTER_NAME];
110
111             for (xx = 0; temp[xx] && xx < MAX_MONSTER_NAME; xx++) {
112 #ifdef JP
113                 if (iskanji(temp[xx])) {
114                     xx++;
115                     continue;
116                 }
117 #endif
118                 if (isupper(temp[xx]))
119                     temp[xx] = (char)tolower(temp[xx]);
120             }
121
122 #ifdef JP
123             strcpy(temp2, r_ref.E_name.c_str());
124 #else
125             strcpy(temp2, r_ref.name.c_str());
126 #endif
127             for (xx = 0; temp2[xx] && xx < MAX_MONSTER_NAME; xx++)
128                 if (isupper(temp2[xx]))
129                     temp2[xx] = (char)tolower(temp2[xx]);
130
131 #ifdef JP
132             if (angband_strstr(temp2, temp) || angband_strstr(r_ref.name.c_str(), temp))
133 #else
134             if (angband_strstr(temp2, temp))
135 #endif
136                 who[n++] = i;
137         }
138
139         else if (all || (r_ref.d_char == sym))
140             who[n++] = i;
141     }
142
143     if (!n) {
144         C_KILL(who, max_r_idx, MONRACE_IDX);
145         return;
146     }
147
148     put_str(_("思い出を見ますか? (k:殺害順/y/n): ", "Recall details? (k/y/n): "), 0, _(36, 40));
149     query = inkey();
150     prt(buf, 0, 0);
151     why = 2;
152     ang_sort(player_ptr, who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
153     if (query == 'k') {
154         why = 4;
155         query = 'y';
156     }
157
158     if (query != 'y') {
159         C_KILL(who, max_r_idx, MONRACE_IDX);
160         return;
161     }
162
163     if (why == 4) {
164         ang_sort(player_ptr, who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
165     }
166
167     i = n - 1;
168     while (true) {
169         r_idx = who[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, who[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             recall = !recall;
188         }
189
190         if (query == ESCAPE)
191             break;
192
193         if (query == '-') {
194             if (++i == n) {
195                 i = 0;
196                 if (!expand_list)
197                     break;
198             }
199         } else {
200             if (i-- == 0) {
201                 i = n - 1;
202                 if (!expand_list)
203                     break;
204             }
205         }
206     }
207
208     C_KILL(who, max_r_idx, MONRACE_IDX);
209     prt(buf, 0, 0);
210 }