OSDN Git Service

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