OSDN Git Service

[Refactor] Changed player_race_type to Pascal case: PlayerRaceType
[hengbandforosx/hengbandosx.git] / src / target / target-describer.cpp
1 #include "target/target-describer.h"
2 #include "action/travel-execution.h"
3 #include "core/stuff-handler.h"
4 #include "dungeon/dungeon.h"
5 #include "dungeon/quest.h"
6 #include "flavor/flavor-describer.h"
7 #include "floor/cave.h"
8 #include "floor/floor-object.h"
9 #include "floor/floor-town.h"
10 #include "floor/geometry.h"
11 #include "floor/object-scanner.h"
12 #include "game-option/game-play-options.h"
13 #include "game-option/input-options.h"
14 #include "grid/feature.h"
15 #include "grid/grid.h"
16 #include "info-reader/fixed-map-parser.h"
17 #include "io/cursor.h"
18 #include "io/input-key-acceptor.h"
19 #include "lore/lore-util.h"
20 #include "monster-race/monster-race.h"
21 #include "monster-race/race-flags1.h"
22 #include "monster/monster-describer.h"
23 #include "monster/monster-description-types.h"
24 #include "monster/monster-flag-types.h"
25 #include "object/item-tester-hooker.h"
26 #include "object/object-mark-types.h"
27 #include "player/player-status-table.h"
28 #include "system/building-type-definition.h"
29 #include "system/floor-type-definition.h"
30 #include "system/grid-type-definition.h"
31 #include "system/monster-race-definition.h"
32 #include "system/monster-type-definition.h"
33 #include "system/object-type-definition.h"
34 #include "system/player-type-definition.h"
35 #include "system/system-variables.h"
36 #include "target/target-types.h"
37 #include "term/screen-processor.h"
38 #include "term/term-color-types.h"
39 #include "util/bit-flags-calculator.h"
40 #include "view/display-lore.h"
41 #include "view/display-messages.h"
42 #include "view/display-monster-status.h"
43 #include "window/display-sub-windows.h"
44
45 #ifdef JP
46 #else
47 #include "locale/english.h"
48 #endif
49
50 static const int16_t CONTINUOUS_DESCRIPTION = 256;
51
52 bool show_gold_on_floor = false;
53
54 // Examine grid
55 typedef struct eg_type {
56     POSITION y;
57     POSITION x;
58     target_type mode;
59     bool boring;
60     concptr info;
61     concptr s1;
62     concptr s2;
63     concptr s3;
64     concptr x_info;
65     char query;
66     char out_val[MAX_NLEN + 80];
67     OBJECT_IDX floor_list[23];
68     ITEM_NUMBER floor_num;
69     grid_type *g_ptr;
70     monster_type *m_ptr;
71     OBJECT_IDX next_o_idx;
72     FEAT_IDX feat;
73     feature_type *f_ptr;
74     concptr name;
75 } eg_type;
76
77 static eg_type *initialize_eg_type(player_type *player_ptr, eg_type *eg_ptr, POSITION y, POSITION x, target_type mode, concptr info)
78 {
79     eg_ptr->y = y;
80     eg_ptr->x = x;
81     eg_ptr->boring = true;
82     eg_ptr->mode = mode;
83     eg_ptr->info = info;
84     eg_ptr->s1 = "";
85     eg_ptr->s2 = "";
86     eg_ptr->s3 = "";
87     eg_ptr->x_info = "";
88     eg_ptr->query = '\001';
89     eg_ptr->floor_num = 0;
90
91     floor_type *floor_ptr = player_ptr->current_floor_ptr;
92     eg_ptr->g_ptr = &floor_ptr->grid_array[y][x];
93     eg_ptr->m_ptr = &floor_ptr->m_list[eg_ptr->g_ptr->m_idx];
94     eg_ptr->next_o_idx = 0;
95     return eg_ptr;
96 }
97
98 /*
99  * Evaluate number of kill needed to gain level
100  */
101 static void evaluate_monster_exp(player_type *player_ptr, char *buf, monster_type *m_ptr)
102 {
103     monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
104     if ((player_ptr->lev >= PY_MAX_LEVEL) || (player_ptr->prace == PlayerRaceType::ANDROID)) {
105         sprintf(buf, "**");
106         return;
107     }
108
109     if (!ap_r_ptr->r_tkills || m_ptr->mflag2.has(MFLAG2::KAGE)) {
110         if (!allow_debug_options) {
111             sprintf(buf, "??");
112             return;
113         }
114     }
115
116     int32_t exp_mon = ap_r_ptr->mexp * ap_r_ptr->level;
117     uint32_t exp_mon_frac = 0;
118     s64b_div(&exp_mon, &exp_mon_frac, 0, (player_ptr->max_plv + 2));
119
120     int32_t exp_adv = player_exp[player_ptr->lev - 1] * player_ptr->expfact;
121     uint32_t exp_adv_frac = 0;
122     s64b_div(&exp_adv, &exp_adv_frac, 0, 100);
123
124     s64b_sub(&exp_adv, &exp_adv_frac, player_ptr->exp, player_ptr->exp_frac);
125
126     s64b_add(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
127     s64b_sub(&exp_adv, &exp_adv_frac, 0, 1);
128
129     s64b_div(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
130
131     uint32_t num = MIN(999, exp_adv_frac);
132     sprintf(buf, "%03ld", (long int)num);
133 }
134
135 static void describe_scan_result(player_type *player_ptr, eg_type *eg_ptr)
136 {
137     if (!easy_floor)
138         return;
139
140     eg_ptr->floor_num = scan_floor_items(player_ptr, eg_ptr->floor_list, eg_ptr->y, eg_ptr->x, SCAN_FLOOR_ONLY_MARKED, AllMatchItemTester());
141     if (eg_ptr->floor_num > 0)
142         eg_ptr->x_info = _("x物 ", "x,");
143 }
144
145 static void describe_target(player_type *player_ptr, eg_type *eg_ptr)
146 {
147     if (!player_bold(player_ptr, eg_ptr->y, eg_ptr->x)) {
148         eg_ptr->s1 = _("ターゲット:", "Target:");
149         return;
150     }
151
152 #ifdef JP
153     eg_ptr->s1 = "あなたは";
154     eg_ptr->s2 = "の上";
155     eg_ptr->s3 = "にいる";
156 #else
157     eg_ptr->s1 = "You are ";
158     eg_ptr->s2 = "on ";
159 #endif
160 }
161
162 static process_result describe_hallucinated_target(player_type *player_ptr, eg_type *eg_ptr)
163 {
164     if (!player_ptr->hallucinated)
165         return PROCESS_CONTINUE;
166
167     concptr name = _("何か奇妙な物", "something strange");
168 #ifdef JP
169     sprintf(eg_ptr->out_val, "%s%s%s%s [%s]", eg_ptr->s1, name, eg_ptr->s2, eg_ptr->s3, eg_ptr->info);
170 #else
171     sprintf(eg_ptr->out_val, "%s%s%s%s [%s]", eg_ptr->s1, eg_ptr->s2, eg_ptr->s3, name, eg_ptr->info);
172 #endif
173     prt(eg_ptr->out_val, 0, 0);
174     move_cursor_relative(eg_ptr->y, eg_ptr->x);
175     eg_ptr->query = inkey();
176     if ((eg_ptr->query != '\r') && (eg_ptr->query != '\n'))
177         return PROCESS_TRUE;
178
179     return PROCESS_FALSE;
180 }
181
182 static bool describe_grid_lore(player_type *player_ptr, eg_type *eg_ptr)
183 {
184     screen_save();
185     screen_roff(player_ptr, eg_ptr->m_ptr->ap_r_idx, MONSTER_LORE_NORMAL);
186     term_addstr(-1, TERM_WHITE, format(_("  [r思 %s%s]", "  [r,%s%s]"), eg_ptr->x_info, eg_ptr->info));
187     eg_ptr->query = inkey();
188     screen_load();
189     return eg_ptr->query != 'r';
190 }
191
192 static void describe_grid_monster(player_type *player_ptr, eg_type *eg_ptr)
193 {
194     bool recall = false;
195     GAME_TEXT m_name[MAX_NLEN];
196     monster_desc(player_ptr, m_name, eg_ptr->m_ptr, MD_INDEF_VISIBLE);
197     while (true) {
198         char acount[10];
199         if (recall) {
200             if (describe_grid_lore(player_ptr, eg_ptr))
201                 return;
202
203             recall = false;
204             continue;
205         }
206
207         evaluate_monster_exp(player_ptr, acount, eg_ptr->m_ptr);
208 #ifdef JP
209         sprintf(eg_ptr->out_val, "[%s]%s%s(%s)%s%s [r思 %s%s]", acount, eg_ptr->s1, m_name, look_mon_desc(eg_ptr->m_ptr, 0x01), eg_ptr->s2, eg_ptr->s3,
210             eg_ptr->x_info, eg_ptr->info);
211 #else
212         sprintf(eg_ptr->out_val, "[%s]%s%s%s%s(%s) [r, %s%s]", acount, eg_ptr->s1, eg_ptr->s2, eg_ptr->s3, m_name, look_mon_desc(eg_ptr->m_ptr, 0x01),
213             eg_ptr->x_info, eg_ptr->info);
214 #endif
215         prt(eg_ptr->out_val, 0, 0);
216         move_cursor_relative(eg_ptr->y, eg_ptr->x);
217         eg_ptr->query = inkey();
218         if (eg_ptr->query != 'r')
219             return;
220
221         recall = true;
222     }
223 }
224
225 static void describe_monster_person(eg_type *eg_ptr)
226 {
227     monster_race *ap_r_ptr = &r_info[eg_ptr->m_ptr->ap_r_idx];
228     eg_ptr->s1 = _("それは", "It is ");
229     if (ap_r_ptr->flags1 & RF1_FEMALE)
230         eg_ptr->s1 = _("彼女は", "She is ");
231     else if (ap_r_ptr->flags1 & RF1_MALE)
232         eg_ptr->s1 = _("彼は", "He is ");
233
234 #ifdef JP
235     eg_ptr->s2 = "を";
236     eg_ptr->s3 = "持っている";
237 #else
238     eg_ptr->s2 = "carrying ";
239 #endif
240 }
241
242 static uint16_t describe_monster_item(player_type *player_ptr, eg_type *eg_ptr)
243 {
244     for (const auto this_o_idx : eg_ptr->m_ptr->hold_o_idx_list) {
245         GAME_TEXT o_name[MAX_NLEN];
246         object_type *o_ptr;
247         o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
248         describe_flavor(player_ptr, o_name, o_ptr, 0);
249 #ifdef JP
250         sprintf(eg_ptr->out_val, "%s%s%s%s[%s]", eg_ptr->s1, o_name, eg_ptr->s2, eg_ptr->s3, eg_ptr->info);
251 #else
252         sprintf(eg_ptr->out_val, "%s%s%s%s [%s]", eg_ptr->s1, eg_ptr->s2, eg_ptr->s3, o_name, eg_ptr->info);
253 #endif
254         prt(eg_ptr->out_val, 0, 0);
255         move_cursor_relative(eg_ptr->y, eg_ptr->x);
256         eg_ptr->query = inkey();
257         if ((eg_ptr->query != '\r') && (eg_ptr->query != '\n') && (eg_ptr->query != ' ') && (eg_ptr->query != 'x'))
258             return eg_ptr->query;
259
260         if ((eg_ptr->query == ' ') && !(eg_ptr->mode & TARGET_LOOK))
261             return eg_ptr->query;
262
263         eg_ptr->s2 = _("をまた", "also carrying ");
264     }
265
266     return CONTINUOUS_DESCRIPTION;
267 }
268
269 static bool within_char_util(int16_t input)
270 {
271     return (input > -127) && (input < 128);
272 }
273
274 static int16_t describe_grid(player_type *player_ptr, eg_type *eg_ptr)
275 {
276     if ((eg_ptr->g_ptr->m_idx == 0) || !player_ptr->current_floor_ptr->m_list[eg_ptr->g_ptr->m_idx].ml)
277         return CONTINUOUS_DESCRIPTION;
278
279     eg_ptr->boring = false;
280     monster_race_track(player_ptr, eg_ptr->m_ptr->ap_r_idx);
281     health_track(player_ptr, eg_ptr->g_ptr->m_idx);
282     handle_stuff(player_ptr);
283     describe_grid_monster(player_ptr, eg_ptr);
284     if ((eg_ptr->query != '\r') && (eg_ptr->query != '\n') && (eg_ptr->query != ' ') && (eg_ptr->query != 'x'))
285         return eg_ptr->query;
286
287     if ((eg_ptr->query == ' ') && !(eg_ptr->mode & TARGET_LOOK))
288         return eg_ptr->query;
289
290     describe_monster_person(eg_ptr);
291     uint16_t monster_item_description = describe_monster_item(player_ptr, eg_ptr);
292     if (within_char_util(monster_item_description))
293         return (char)monster_item_description;
294
295 #ifdef JP
296     eg_ptr->s2 = "の上";
297     eg_ptr->s3 = "にいる";
298 #else
299     eg_ptr->s2 = "on ";
300 #endif
301     return CONTINUOUS_DESCRIPTION;
302 }
303
304 static int16_t describe_footing(player_type *player_ptr, eg_type *eg_ptr)
305 {
306     if (eg_ptr->floor_num != 1)
307         return CONTINUOUS_DESCRIPTION;
308
309     GAME_TEXT o_name[MAX_NLEN];
310     object_type *o_ptr;
311     o_ptr = &player_ptr->current_floor_ptr->o_list[eg_ptr->floor_list[0]];
312     describe_flavor(player_ptr, o_name, o_ptr, 0);
313 #ifdef JP
314     sprintf(eg_ptr->out_val, "%s%s%s%s[%s]", eg_ptr->s1, o_name, eg_ptr->s2, eg_ptr->s3, eg_ptr->info);
315 #else
316     sprintf(eg_ptr->out_val, "%s%s%s%s [%s]", eg_ptr->s1, eg_ptr->s2, eg_ptr->s3, o_name, eg_ptr->info);
317 #endif
318     prt(eg_ptr->out_val, 0, 0);
319     move_cursor_relative(eg_ptr->y, eg_ptr->x);
320     eg_ptr->query = inkey();
321     return eg_ptr->query;
322 }
323
324 static int16_t describe_footing_items(eg_type *eg_ptr)
325 {
326     if (!eg_ptr->boring)
327         return CONTINUOUS_DESCRIPTION;
328
329 #ifdef JP
330     sprintf(eg_ptr->out_val, "%s %d個のアイテム%s%s ['x'で一覧, %s]", eg_ptr->s1, (int)eg_ptr->floor_num, eg_ptr->s2, eg_ptr->s3, eg_ptr->info);
331 #else
332     sprintf(eg_ptr->out_val, "%s%s%sa pile of %d items [x,%s]", eg_ptr->s1, eg_ptr->s2, eg_ptr->s3, (int)eg_ptr->floor_num, eg_ptr->info);
333 #endif
334     prt(eg_ptr->out_val, 0, 0);
335     move_cursor_relative(eg_ptr->y, eg_ptr->x);
336     eg_ptr->query = inkey();
337     if (eg_ptr->query != 'x' && eg_ptr->query != ' ')
338         return eg_ptr->query;
339
340     return CONTINUOUS_DESCRIPTION;
341 }
342
343 static char describe_footing_many_items(player_type *player_ptr, eg_type *eg_ptr, int *min_width)
344 {
345     while (true) {
346         screen_save();
347         show_gold_on_floor = true;
348         (void)show_floor_items(player_ptr, 0, eg_ptr->y, eg_ptr->x, min_width, AllMatchItemTester());
349         show_gold_on_floor = false;
350 #ifdef JP
351         sprintf(eg_ptr->out_val, "%s %d個のアイテム%s%s [Enterで次へ, %s]", eg_ptr->s1, (int)eg_ptr->floor_num, eg_ptr->s2, eg_ptr->s3, eg_ptr->info);
352 #else
353         sprintf(eg_ptr->out_val, "%s%s%sa pile of %d items [Enter,%s]", eg_ptr->s1, eg_ptr->s2, eg_ptr->s3, (int)eg_ptr->floor_num, eg_ptr->info);
354 #endif
355         prt(eg_ptr->out_val, 0, 0);
356         eg_ptr->query = inkey();
357         screen_load();
358         if (eg_ptr->query != '\n' && eg_ptr->query != '\r')
359             return eg_ptr->query;
360
361         if (eg_ptr->g_ptr->o_idx_list.size() < 2)
362             continue;
363
364         eg_ptr->g_ptr->o_idx_list.rotate(player_ptr->current_floor_ptr);
365
366         // ターゲットしている床の座標を渡す必要があるので、window_stuff経由ではなく直接呼び出す
367         fix_floor_item_list(player_ptr, eg_ptr->y, eg_ptr->x);
368     }
369 }
370
371 static int16_t loop_describing_grid(player_type *player_ptr, eg_type *eg_ptr)
372 {
373     if (eg_ptr->floor_num == 0)
374         return CONTINUOUS_DESCRIPTION;
375
376     int min_width = 0;
377     while (true) {
378         int16_t footing_description = describe_footing(player_ptr, eg_ptr);
379         if (within_char_util(footing_description))
380             return (char)footing_description;
381
382         int16_t footing_descriptions = describe_footing_items(eg_ptr);
383         if (within_char_util(footing_descriptions))
384             return (char)footing_descriptions;
385
386         return describe_footing_many_items(player_ptr, eg_ptr, &min_width);
387     }
388 }
389
390 static int16_t describe_footing_sight(player_type *player_ptr, eg_type *eg_ptr, object_type *o_ptr)
391 {
392     if ((o_ptr->marked & OM_FOUND) == 0)
393         return CONTINUOUS_DESCRIPTION;
394
395     GAME_TEXT o_name[MAX_NLEN];
396     eg_ptr->boring = false;
397     describe_flavor(player_ptr, o_name, o_ptr, 0);
398 #ifdef JP
399     sprintf(eg_ptr->out_val, "%s%s%s%s[%s]", eg_ptr->s1, o_name, eg_ptr->s2, eg_ptr->s3, eg_ptr->info);
400 #else
401     sprintf(eg_ptr->out_val, "%s%s%s%s [%s]", eg_ptr->s1, eg_ptr->s2, eg_ptr->s3, o_name, eg_ptr->info);
402 #endif
403     prt(eg_ptr->out_val, 0, 0);
404     move_cursor_relative(eg_ptr->y, eg_ptr->x);
405     eg_ptr->query = inkey();
406     if ((eg_ptr->query != '\r') && (eg_ptr->query != '\n') && (eg_ptr->query != ' ') && (eg_ptr->query != 'x'))
407         return eg_ptr->query;
408
409     if ((eg_ptr->query == ' ') && !(eg_ptr->mode & TARGET_LOOK))
410         return eg_ptr->query;
411
412     eg_ptr->s1 = _("それは", "It is ");
413     if (o_ptr->number != 1)
414         eg_ptr->s1 = _("それらは", "They are ");
415
416 #ifdef JP
417     eg_ptr->s2 = "の上";
418     eg_ptr->s3 = "に見える";
419 #else
420     eg_ptr->s2 = "on ";
421 #endif
422     return CONTINUOUS_DESCRIPTION;
423 }
424
425 static int16_t sweep_footing_items(player_type *player_ptr, eg_type *eg_ptr)
426 {
427     for (const auto this_o_idx : eg_ptr->g_ptr->o_idx_list) {
428         object_type *o_ptr;
429         o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
430         int16_t ret = describe_footing_sight(player_ptr, eg_ptr, o_ptr);
431         if (within_char_util(ret))
432             return (char)ret;
433     }
434
435     return CONTINUOUS_DESCRIPTION;
436 }
437
438 static concptr decide_target_floor(player_type *player_ptr, eg_type *eg_ptr)
439 {
440     if (eg_ptr->f_ptr->flags.has(FF::QUEST_ENTER)) {
441         QUEST_IDX old_quest = player_ptr->current_floor_ptr->inside_quest;
442         for (int j = 0; j < 10; j++)
443             quest_text[j][0] = '\0';
444
445         quest_text_line = 0;
446         player_ptr->current_floor_ptr->inside_quest = eg_ptr->g_ptr->special;
447         init_flags = INIT_NAME_ONLY;
448         parse_fixed_map(player_ptr, "q_info.txt", 0, 0, 0, 0);
449         player_ptr->current_floor_ptr->inside_quest = old_quest;
450         return format(
451             _("クエスト「%s」(%d階相当)", "the entrance to the quest '%s'(level %d)"), quest[eg_ptr->g_ptr->special].name, quest[eg_ptr->g_ptr->special].level);
452     }
453
454     if (eg_ptr->f_ptr->flags.has(FF::BLDG) && !player_ptr->current_floor_ptr->inside_arena)
455         return building[eg_ptr->f_ptr->subtype].name;
456
457     if (eg_ptr->f_ptr->flags.has(FF::ENTRANCE))
458         return format(_("%s(%d階相当)", "%s(level %d)"), d_info[eg_ptr->g_ptr->special].text.c_str(), d_info[eg_ptr->g_ptr->special].mindepth);
459
460     if (eg_ptr->f_ptr->flags.has(FF::TOWN))
461         return town_info[eg_ptr->g_ptr->special].name;
462
463     if (player_ptr->wild_mode && (eg_ptr->feat == feat_floor))
464         return _("道", "road");
465
466     return eg_ptr->f_ptr->name.c_str();
467 }
468
469 static void describe_grid_monster_all(eg_type *eg_ptr)
470 {
471     if (!allow_debug_options) {
472 #ifdef JP
473         sprintf(eg_ptr->out_val, "%s%s%s%s[%s]", eg_ptr->s1, eg_ptr->name, eg_ptr->s2, eg_ptr->s3, eg_ptr->info);
474 #else
475         sprintf(eg_ptr->out_val, "%s%s%s%s [%s]", eg_ptr->s1, eg_ptr->s2, eg_ptr->s3, eg_ptr->name, eg_ptr->info);
476 #endif
477         return;
478     }
479
480     char f_idx_str[32];
481     if (eg_ptr->g_ptr->mimic)
482         sprintf(f_idx_str, "%d/%d", eg_ptr->g_ptr->feat, eg_ptr->g_ptr->mimic);
483     else
484         sprintf(f_idx_str, "%d", eg_ptr->g_ptr->feat);
485
486 #ifdef JP
487     sprintf(eg_ptr->out_val, "%s%s%s%s[%s] %x %s %d %d %d (%d,%d) %d", eg_ptr->s1, eg_ptr->name, eg_ptr->s2, eg_ptr->s3, eg_ptr->info,
488         (uint)eg_ptr->g_ptr->info, f_idx_str, eg_ptr->g_ptr->dists[FLOW_NORMAL], eg_ptr->g_ptr->costs[FLOW_NORMAL], eg_ptr->g_ptr->when, (int)eg_ptr->y,
489         (int)eg_ptr->x, travel.cost[eg_ptr->y][eg_ptr->x]);
490 #else
491     sprintf(eg_ptr->out_val, "%s%s%s%s [%s] %x %s %d %d %d (%d,%d)", eg_ptr->s1, eg_ptr->s2, eg_ptr->s3, eg_ptr->name, eg_ptr->info, eg_ptr->g_ptr->info,
492         f_idx_str, eg_ptr->g_ptr->dists[FLOW_NORMAL], eg_ptr->g_ptr->costs[FLOW_NORMAL], eg_ptr->g_ptr->when, (int)eg_ptr->y, (int)eg_ptr->x);
493 #endif
494 }
495
496 /*!
497  * @brief xまたはlで指定したグリッドにあるアイテムやモンスターの説明を記述する
498  * @param player_ptr プレイヤーへの参照ポインタ
499  * @param y 指定グリッドのY座標
500  * @param x 指定グリッドのX座標
501  * @param mode x (KILL)かl (LOOK)
502  * @param info 記述用文字列
503  * @return 入力キー
504  * @todo xとlで処理を分ける?
505  */
506 char examine_grid(player_type *player_ptr, const POSITION y, const POSITION x, target_type mode, concptr info)
507 {
508     eg_type tmp_eg;
509     eg_type *eg_ptr = initialize_eg_type(player_ptr, &tmp_eg, y, x, mode, info);
510     describe_scan_result(player_ptr, eg_ptr);
511     describe_target(player_ptr, eg_ptr);
512     process_result next_target = describe_hallucinated_target(player_ptr, eg_ptr);
513     switch (next_target) {
514     case PROCESS_FALSE:
515         return 0;
516     case PROCESS_TRUE:
517         return eg_ptr->query;
518     case PROCESS_CONTINUE:
519         break;
520     }
521
522     int16_t description_grid = describe_grid(player_ptr, eg_ptr);
523     if (within_char_util(description_grid))
524         return (char)description_grid;
525
526     int16_t loop_description = loop_describing_grid(player_ptr, eg_ptr);
527     if (within_char_util(loop_description))
528         return (char)loop_description;
529
530     int16_t footing_items_description = sweep_footing_items(player_ptr, eg_ptr);
531     if (within_char_util(footing_items_description))
532         return (char)footing_items_description;
533
534     eg_ptr->feat = eg_ptr->g_ptr->get_feat_mimic();
535     if (!eg_ptr->g_ptr->is_mark() && !player_can_see_bold(player_ptr, y, x))
536         eg_ptr->feat = feat_none;
537
538     eg_ptr->f_ptr = &f_info[eg_ptr->feat];
539     if (!eg_ptr->boring && eg_ptr->f_ptr->flags.has_not(FF::REMEMBER))
540         return (eg_ptr->query != '\r') && (eg_ptr->query != '\n') ? eg_ptr->query : 0;
541
542     /*
543      * グローバル変数への代入をここで行っているので動かしたくない
544      * 安全を確保できたら構造体から外すことも検討する
545      */
546     eg_ptr->name = decide_target_floor(player_ptr, eg_ptr);
547     if (*eg_ptr->s2
548         && (eg_ptr->f_ptr->flags.has_none_of({FF::MOVE, FF::CAN_FLY})
549             || eg_ptr->f_ptr->flags.has_none_of({FF::LOS, FF::TREE}) || eg_ptr->f_ptr->flags.has(FF::TOWN))) {
550         eg_ptr->s2 = _("の中", "in ");
551     }
552
553     if (eg_ptr->f_ptr->flags.has(FF::STORE) || eg_ptr->f_ptr->flags.has(FF::QUEST_ENTER)
554         || (eg_ptr->f_ptr->flags.has(FF::BLDG) && !player_ptr->current_floor_ptr->inside_arena) || eg_ptr->f_ptr->flags.has(FF::ENTRANCE))
555         eg_ptr->s2 = _("の入口", "");
556 #ifdef JP
557 #else
558     else if (eg_ptr->f_ptr->flags.has(FF::FLOOR) || eg_ptr->f_ptr->flags.has(FF::TOWN) || eg_ptr->f_ptr->flags.has(FF::SHALLOW)
559         || eg_ptr->f_ptr->flags.has(FF::DEEP))
560         eg_ptr->s3 = "";
561     else
562         eg_ptr->s3 = (is_a_vowel(eg_ptr->name[0])) ? "an " : "a ";
563 #endif
564
565     describe_grid_monster_all(eg_ptr);
566     prt(eg_ptr->out_val, 0, 0);
567     move_cursor_relative(y, x);
568     eg_ptr->query = inkey();
569     if ((eg_ptr->query != '\r') && (eg_ptr->query != '\n'))
570         return eg_ptr->query;
571
572     return 0;
573 }