OSDN Git Service

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