OSDN Git Service

Merge pull request #2390 from Slimebreath6078/hotfix/random_quest_50F
[hengbandforosx/hengbandosx.git] / src / market / building-monster.cpp
1 #include "market/building-monster.h"
2 #include "core/asking-player.h"
3 #include "core/stuff-handler.h"
4 #include "game-option/game-play-options.h"
5 #include "io/input-key-acceptor.h"
6 #include "lore/lore-store.h"
7 #include "lore/lore-util.h"
8 #include "monster-race/monster-race.h"
9 #include "monster-race/race-flags1.h"
10 #include "system/monster-race-definition.h"
11 #include "term/gameterm.h"
12 #include "term/screen-processor.h"
13 #include "term/term-color-types.h"
14 #include "util/int-char-converter.h"
15 #include "util/sort.h"
16 #include "util/string-processor.h"
17 #include "view/display-lore.h"
18
19 /*!
20  * @brief 施設でモンスターの情報を知るメインルーチン / research_mon -KMW-
21  * @param player_ptr プレイヤーへの参照ポインタ
22  * @return 常にTRUEを返す。
23  * @todo 返り値が意味不明なので直した方が良いかもしれない。
24  */
25 bool research_mon(PlayerType *player_ptr)
26 {
27     char buf[256];
28     bool notpicked;
29     bool recall = false;
30     uint16_t why = 0;
31
32     bool all = false;
33     bool uniq = false;
34     bool norm = false;
35     char temp[MAX_MONSTER_NAME] = "";
36
37     screen_save();
38
39     char sym;
40     if (!get_com(
41             _("モンスターの文字を入力して下さい(記号 or ^A全,^Uユ,^N非ユ,^M名前):", "Enter character to be identified(^A:All,^U:Uniqs,^N:Non uniqs,^M:Name): "),
42             &sym, false))
43
44     {
45         screen_load();
46         return false;
47     }
48
49     IDX ident_i;
50     for (ident_i = 0; ident_info[ident_i]; ++ident_i) {
51         if (sym == ident_info[ident_i][0]) {
52             break;
53         }
54     }
55
56     /* XTRA HACK WHATSEARCH */
57     if (sym == KTRL('A')) {
58         all = true;
59         strcpy(buf, _("全モンスターのリスト", "Full monster list."));
60     } else if (sym == KTRL('U')) {
61         all = uniq = true;
62         strcpy(buf, _("ユニーク・モンスターのリスト", "Unique monster list."));
63     } else if (sym == KTRL('N')) {
64         all = norm = true;
65         strcpy(buf, _("ユニーク外モンスターのリスト", "Non-unique monster list."));
66     } else if (sym == KTRL('M')) {
67         all = true;
68         if (!get_string(_("名前(英語の場合小文字で可)", "Enter name:"), temp, 70)) {
69             temp[0] = 0;
70             screen_load();
71
72             return false;
73         }
74
75         sprintf(buf, _("名前:%sにマッチ", "Monsters' names with \"%s\""), temp);
76     } else if (ident_info[ident_i]) {
77         sprintf(buf, "%c - %s.", sym, ident_info[ident_i] + 2);
78     } else {
79         sprintf(buf, "%c - %s", sym, _("無効な文字", "Unknown Symbol"));
80     }
81
82     /* Display the result */
83     prt(buf, 16, 10);
84
85     /* Allocate the "who" array */
86     std::vector<MonsterRaceId> who;
87
88     /* Collect matching monsters */
89     for (const auto &[r_idx, r_ref] : r_info) {
90         /* Empty monster */
91         if (!MonsterRace(r_ref.idx).is_valid() || r_ref.name.empty()) {
92             continue;
93         }
94
95         /* XTRA HACK WHATSEARCH */
96         /* Require non-unique monsters if needed */
97         if (norm && r_ref.kind_flags.has(MonsterKindType::UNIQUE)) {
98             continue;
99         }
100
101         /* Require unique monsters if needed */
102         if (uniq && r_ref.kind_flags.has_not(MonsterKindType::UNIQUE)) {
103             continue;
104         }
105
106         /* 名前検索 */
107         if (temp[0]) {
108             for (int xx = 0; temp[xx] && xx < 80; xx++) {
109 #ifdef JP
110                 if (iskanji(temp[xx])) {
111                     xx++;
112                     continue;
113                 }
114 #endif
115                 if (isupper(temp[xx])) {
116                     temp[xx] = (char)tolower(temp[xx]);
117                 }
118             }
119
120             char temp2[MAX_MONSTER_NAME];
121 #ifdef JP
122             strcpy(temp2, r_ref.E_name.c_str());
123 #else
124             strcpy(temp2, r_ref.name.c_str());
125 #endif
126             for (int xx = 0; temp2[xx] && xx < 80; xx++) {
127                 if (isupper(temp2[xx])) {
128                     temp2[xx] = (char)tolower(temp2[xx]);
129                 }
130             }
131
132 #ifdef JP
133             if (angband_strstr(temp2, temp) || angband_strstr(r_ref.name.c_str(), temp))
134 #else
135             if (angband_strstr(temp2, temp))
136 #endif
137                 who.push_back(r_ref.idx);
138         } else if (all || (r_ref.d_char == sym)) {
139             who.push_back(r_ref.idx);
140         }
141     }
142
143     if (who.empty()) {
144         screen_load();
145
146         return false;
147     }
148
149     why = 2;
150     char query = 'y';
151
152     if (why) {
153         ang_sort(player_ptr, who.data(), &why, who.size(), ang_sort_comp_hook, ang_sort_swap_hook);
154     }
155
156     uint i;
157     static int old_sym = '\0';
158     static uint old_i = 0;
159     if (old_sym == sym && old_i < who.size()) {
160         i = old_i;
161     } else {
162         i = who.size() - 1;
163     }
164
165     notpicked = true;
166     while (notpicked) {
167         auto r_idx = who[i];
168         roff_top(r_idx);
169         term_addstr(-1, TERM_WHITE, _(" ['r'思い出, ' 'で続行, ESC]", " [(r)ecall, ESC, space to continue]"));
170         while (true) {
171             if (recall) {
172                 lore_do_probe(player_ptr, r_idx);
173                 monster_race_track(player_ptr, r_idx);
174                 handle_stuff(player_ptr);
175                 screen_roff(player_ptr, r_idx, MONSTER_LORE_RESEARCH);
176                 notpicked = false;
177                 old_sym = sym;
178                 old_i = i;
179             }
180
181             query = inkey();
182             if (query != 'r') {
183                 break;
184             }
185
186             recall = !recall;
187         }
188
189         if (query == ESCAPE) {
190             break;
191         }
192
193         if (query == '-') {
194             if (++i == who.size()) {
195                 i = 0;
196                 if (!expand_list) {
197                     break;
198                 }
199             }
200
201             continue;
202         }
203
204         if (i-- == 0) {
205             i = who.size() - 1;
206             if (!expand_list) {
207                 break;
208             }
209         }
210     }
211
212     screen_load();
213     return !notpicked;
214 }