OSDN Git Service

[Refactor] #40571 Reshaped targetinc.c
[hengband/hengband.git] / src / io / targeting.c
1 /*!
2  * @brief 雑多なその他の処理2 / effects of various "objects"
3  * @date 2014/02/06
4  * @author
5  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke\n
6  * This software may be copied and distributed for educational, research, and\n
7  * not for profit purposes provided that this copyright and statement are\n
8  * included in all such copies.\n
9  * 2014 Deskull rearranged comment for Doxygen.
10  */
11
12 #include "io/targeting.h"
13 #include "action/travel-execution.h"
14 #include "cmd-action/cmd-pet.h"
15 #include "cmd-building/cmd-building.h"
16 #include "core/asking-player.h"
17 #include "core/disturbance.h"
18 #include "core/player-redraw-types.h"
19 #include "core/player-update-types.h"
20 #include "core/stuff-handler.h"
21 #include "core/window-redrawer.h"
22 #include "dungeon/dungeon.h"
23 #include "dungeon/quest.h"
24 #include "effect/spells-effect-util.h"
25 #include "flavor/flavor-describer.h"
26 #include "floor/cave.h"
27 #include "floor/floor-events.h"
28 #include "floor/floor-object.h"
29 #include "floor/floor-town.h"
30 #include "floor/floor.h"
31 #include "floor/object-scanner.h"
32 #include "game-option/cheat-options.h"
33 #include "game-option/disturbance-options.h"
34 #include "game-option/game-play-options.h"
35 #include "game-option/input-options.h"
36 #include "game-option/keymap-directory-getter.h"
37 #include "game-option/map-screen-options.h"
38 #include "grid/feature.h"
39 #include "grid/grid.h"
40 #include "info-reader/fixed-map-parser.h"
41 #include "io/command-repeater.h"
42 #include "io/cursor.h"
43 #include "io/input-key-acceptor.h"
44 #include "io/input-key-requester.h"
45 #include "io/screen-util.h"
46 #include "main/sound-of-music.h"
47 #include "monster-race/monster-race-hook.h"
48 #include "monster-race/monster-race.h"
49 #include "monster-race/race-flags1.h"
50 #include "monster/monster-describer.h"
51 #include "monster/monster-description-types.h"
52 #include "monster/monster-flag-types.h"
53 #include "monster/monster-info.h"
54 #include "monster/monster-status.h"
55 #include "monster/monster-update.h"
56 #include "monster/smart-learn-types.h"
57 #include "object-enchant/object-curse.h"
58 #include "object/object-kind-hook.h"
59 #include "object/object-mark-types.h"
60 #include "player/player-race-types.h"
61 #include "player/player-status.h"
62 #include "spell/spells-summon.h"
63 #include "system/building-type-definition.h"
64 #include "system/floor-type-definition.h"
65 #include "system/system-variables.h"
66 #include "term/screen-processor.h"
67 #include "term/term-color-types.h"
68 #include "util/bit-flags-calculator.h"
69 #include "util/int-char-converter.h"
70 #include "util/sort.h"
71 #include "view/display-lore.h"
72 #include "view/display-messages.h"
73 #include "view/display-monster-status.h"
74 #include "window/main-window-util.h"
75 #include "world/world.h"
76 #ifdef JP
77 #else
78 #include "locale/english.h"
79 #endif
80
81 /*!
82  * @brief コンソール上におけるマップ表示の左上位置を返す /
83  * Calculates current boundaries Called below and from "do_cmd_locate()".
84  * @return なし
85  */
86 void panel_bounds_center(void)
87 {
88     TERM_LEN wid, hgt;
89     get_screen_size(&wid, &hgt);
90     panel_row_max = panel_row_min + hgt - 1;
91     panel_row_prt = panel_row_min - 1;
92     panel_col_max = panel_col_min + wid - 1;
93     panel_col_prt = panel_col_min - 13;
94 }
95
96 /*!
97  * @brief フォーカスを当てるべきマップ描画の基準座標を指定する
98  * @param creature_ptr プレーヤーへの参照ポインタ
99  * @param y 変更先のフロアY座標
100  * @param x 変更先のフロアX座標
101  * @details
102  * Handle a request to change the current panel
103  * Return TRUE if the panel was changed.
104  * Also used in do_cmd_locate
105  * @return 実際に再描画が必要だった場合TRUEを返す
106  */
107 static bool change_panel_xy(player_type *creature_ptr, POSITION y, POSITION x)
108 {
109     POSITION dy = 0, dx = 0;
110     TERM_LEN wid, hgt;
111     get_screen_size(&wid, &hgt);
112     if (y < panel_row_min)
113         dy = -1;
114
115     if (y > panel_row_max)
116         dy = 1;
117
118     if (x < panel_col_min)
119         dx = -1;
120
121     if (x > panel_col_max)
122         dx = 1;
123
124     if (!dy && !dx)
125         return FALSE;
126
127     return change_panel(creature_ptr, dy, dx);
128 }
129
130 /*!
131  * @brief マップ描画のフォーカスを当てるべき座標を更新する
132  * @param creature_ptr プレーヤーへの参照ポインタ
133  * @details
134  * Given an row (y) and col (x), this routine detects when a move
135  * off the screen has occurred and figures new borders. -RAK-
136  * "Update" forces a "full update" to take place.
137  * The map is reprinted if necessary, and "TRUE" is returned.
138  * @return 実際に再描画が必要だった場合TRUEを返す
139  */
140 void verify_panel(player_type *creature_ptr)
141 {
142     POSITION y = creature_ptr->y;
143     POSITION x = creature_ptr->x;
144     TERM_LEN wid, hgt;
145     get_screen_size(&wid, &hgt);
146     int max_prow_min = creature_ptr->current_floor_ptr->height - hgt;
147     int max_pcol_min = creature_ptr->current_floor_ptr->width - wid;
148     if (max_prow_min < 0)
149         max_prow_min = 0;
150     if (max_pcol_min < 0)
151         max_pcol_min = 0;
152
153     int prow_min;
154     int pcol_min;
155     if (center_player && (center_running || !creature_ptr->running)) {
156         prow_min = y - hgt / 2;
157         if (prow_min < 0)
158             prow_min = 0;
159         else if (prow_min > max_prow_min)
160             prow_min = max_prow_min;
161
162         pcol_min = x - wid / 2;
163         if (pcol_min < 0)
164             pcol_min = 0;
165         else if (pcol_min > max_pcol_min)
166             pcol_min = max_pcol_min;
167     } else {
168         prow_min = panel_row_min;
169         pcol_min = panel_col_min;
170         if (y > panel_row_max - 2)
171             while (y > prow_min + hgt - 1 - 2)
172                 prow_min += (hgt / 2);
173
174         if (y < panel_row_min + 2)
175             while (y < prow_min + 2)
176                 prow_min -= (hgt / 2);
177
178         if (prow_min > max_prow_min)
179             prow_min = max_prow_min;
180
181         if (prow_min < 0)
182             prow_min = 0;
183
184         if (x > panel_col_max - 4)
185             while (x > pcol_min + wid - 1 - 4)
186                 pcol_min += (wid / 2);
187
188         if (x < panel_col_min + 4)
189             while (x < pcol_min + 4)
190                 pcol_min -= (wid / 2);
191
192         if (pcol_min > max_pcol_min)
193             pcol_min = max_pcol_min;
194
195         if (pcol_min < 0)
196             pcol_min = 0;
197     }
198
199     if ((prow_min == panel_row_min) && (pcol_min == panel_col_min))
200         return;
201
202     panel_row_min = prow_min;
203     panel_col_min = pcol_min;
204     if (disturb_panel && !center_player)
205         disturb(creature_ptr, FALSE, FALSE);
206
207     panel_bounds_center();
208     creature_ptr->update |= (PU_MONSTERS);
209     creature_ptr->redraw |= (PR_MAP);
210     creature_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
211 }
212
213 /*
214  * Determine is a monster makes a reasonable target
215  *
216  * The concept of "targeting" was stolen from "Morgul" (?)
217  *
218  * The player can target any location, or any "target-able" monster.
219  *
220  * Currently, a monster is "target_able" if it is visible, and if
221  * the player can hit it with a projection, and the player is not
222  * hallucinating.  This allows use of "use closest target" macros.
223  *
224  * Future versions may restrict the ability to target "trappers"
225  * and "mimics", but the semantics is a little bit weird.
226  */
227 bool target_able(player_type *creature_ptr, MONSTER_IDX m_idx)
228 {
229     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
230     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
231     if (!monster_is_valid(m_ptr))
232         return FALSE;
233
234     if (creature_ptr->image)
235         return FALSE;
236
237     if (!m_ptr->ml)
238         return FALSE;
239
240     if (creature_ptr->riding && (creature_ptr->riding == m_idx))
241         return TRUE;
242
243     if (!projectable(creature_ptr, creature_ptr->y, creature_ptr->x, m_ptr->fy, m_ptr->fx))
244         return FALSE;
245
246     return TRUE;
247 }
248
249 /* Targetting variables */
250 MONSTER_IDX target_who;
251 POSITION target_col;
252 POSITION target_row;
253
254 /*
255  * Update (if necessary) and verify (if possible) the target.
256  * We return TRUE if the target is "okay" and FALSE otherwise.
257  */
258 bool target_okay(player_type *creature_ptr)
259 {
260     if (target_who < 0)
261         return TRUE;
262
263     if (target_who <= 0)
264         return FALSE;
265
266     if (!target_able(creature_ptr, target_who))
267         return FALSE;
268
269     monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[target_who];
270     target_row = m_ptr->fy;
271     target_col = m_ptr->fx;
272     return TRUE;
273 }
274
275 /*
276  * Help "select" a location (see below)
277  */
278 static POSITION_IDX target_pick(POSITION y1, POSITION x1, POSITION dy, POSITION dx)
279 {
280     POSITION_IDX b_i = -1, b_v = 9999;
281     for (POSITION_IDX i = 0; i < tmp_pos.n; i++) {
282         POSITION x2 = tmp_pos.x[i];
283         POSITION y2 = tmp_pos.y[i];
284         POSITION x3 = (x2 - x1);
285         POSITION y3 = (y2 - y1);
286         if (dx && (x3 * dx <= 0))
287             continue;
288
289         if (dy && (y3 * dy <= 0))
290             continue;
291
292         POSITION x4 = ABS(x3);
293         POSITION y4 = ABS(y3);
294         if (dy && !dx && (x4 > y4))
295             continue;
296
297         if (dx && !dy && (y4 > x4))
298             continue;
299
300         POSITION_IDX v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4));
301         if ((b_i >= 0) && (v >= b_v))
302             continue;
303
304         b_i = i;
305         b_v = v;
306     }
307
308     return b_i;
309 }
310
311 /*
312  * Determine if a given location is "interesting"
313  */
314 static bool target_set_accept(player_type *creature_ptr, POSITION y, POSITION x)
315 {
316     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
317     if (!(in_bounds(floor_ptr, y, x)))
318         return FALSE;
319
320     if (player_bold(creature_ptr, y, x))
321         return TRUE;
322
323     if (creature_ptr->image)
324         return FALSE;
325
326     grid_type *g_ptr;
327     g_ptr = &floor_ptr->grid_array[y][x];
328     if (g_ptr->m_idx) {
329         monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
330         if (m_ptr->ml)
331             return TRUE;
332     }
333
334     OBJECT_IDX next_o_idx = 0;
335     for (OBJECT_IDX this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) {
336         object_type *o_ptr;
337         o_ptr = &floor_ptr->o_list[this_o_idx];
338         next_o_idx = o_ptr->next_o_idx;
339         if (o_ptr->marked & OM_FOUND)
340             return TRUE;
341     }
342
343     if (g_ptr->info & (CAVE_MARK)) {
344         if (g_ptr->info & CAVE_OBJECT)
345             return TRUE;
346
347         if (have_flag(f_info[get_feat_mimic(g_ptr)].flags, FF_NOTICE))
348             return TRUE;
349     }
350
351     return FALSE;
352 }
353
354 /*
355  * Prepare the "temp" array for "target_set"
356  *
357  * Return the number of target_able monsters in the set.
358  */
359 static void target_set_prepare(player_type *creature_ptr, BIT_FLAGS mode)
360 {
361     POSITION min_hgt, max_hgt, min_wid, max_wid;
362     if (mode & TARGET_KILL) {
363         min_hgt = MAX((creature_ptr->y - get_max_range(creature_ptr)), 0);
364         max_hgt = MIN((creature_ptr->y + get_max_range(creature_ptr)), creature_ptr->current_floor_ptr->height - 1);
365         min_wid = MAX((creature_ptr->x - get_max_range(creature_ptr)), 0);
366         max_wid = MIN((creature_ptr->x + get_max_range(creature_ptr)), creature_ptr->current_floor_ptr->width - 1);
367     } else {
368         min_hgt = panel_row_min;
369         max_hgt = panel_row_max;
370         min_wid = panel_col_min;
371         max_wid = panel_col_max;
372     }
373
374     tmp_pos.n = 0;
375     for (POSITION y = min_hgt; y <= max_hgt; y++) {
376         for (POSITION x = min_wid; x <= max_wid; x++) {
377             grid_type *g_ptr;
378             if (!target_set_accept(creature_ptr, y, x))
379                 continue;
380
381             g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
382             if ((mode & (TARGET_KILL)) && !target_able(creature_ptr, g_ptr->m_idx))
383                 continue;
384
385             if ((mode & (TARGET_KILL)) && !target_pet && is_pet(&creature_ptr->current_floor_ptr->m_list[g_ptr->m_idx]))
386                 continue;
387
388             tmp_pos.x[tmp_pos.n] = x;
389             tmp_pos.y[tmp_pos.n] = y;
390             tmp_pos.n++;
391         }
392     }
393
394     if (mode & (TARGET_KILL)) {
395         ang_sort(creature_ptr, tmp_pos.x, tmp_pos.y, tmp_pos.n, ang_sort_comp_distance, ang_sort_swap_distance);
396     } else {
397         ang_sort(creature_ptr, tmp_pos.x, tmp_pos.y, tmp_pos.n, ang_sort_comp_importance, ang_sort_swap_distance);
398     }
399
400     if (creature_ptr->riding == 0 || !target_pet || (tmp_pos.n <= 1) || !(mode & (TARGET_KILL)))
401         return;
402
403     POSITION tmp = tmp_pos.y[0];
404     tmp_pos.y[0] = tmp_pos.y[1];
405     tmp_pos.y[1] = tmp;
406     tmp = tmp_pos.x[0];
407     tmp_pos.x[0] = tmp_pos.x[1];
408     tmp_pos.x[1] = tmp;
409 }
410
411 void target_set_prepare_look(player_type *creature_ptr) { target_set_prepare(creature_ptr, TARGET_LOOK); }
412
413 /*
414  * Evaluate number of kill needed to gain level
415  */
416 static void evaluate_monster_exp(player_type *creature_ptr, char *buf, monster_type *m_ptr)
417 {
418     monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
419     if ((creature_ptr->lev >= PY_MAX_LEVEL) || (creature_ptr->prace == RACE_ANDROID)) {
420         sprintf(buf, "**");
421         return;
422     }
423
424     if (!ap_r_ptr->r_tkills || (m_ptr->mflag2 & MFLAG2_KAGE)) {
425         if (!current_world_ptr->wizard) {
426             sprintf(buf, "??");
427             return;
428         }
429     }
430
431     s32b exp_mon = ap_r_ptr->mexp * ap_r_ptr->level;
432     u32b exp_mon_frac = 0;
433     s64b_div(&exp_mon, &exp_mon_frac, 0, (creature_ptr->max_plv + 2));
434
435     s32b exp_adv = player_exp[creature_ptr->lev - 1] * creature_ptr->expfact;
436     u32b exp_adv_frac = 0;
437     s64b_div(&exp_adv, &exp_adv_frac, 0, 100);
438
439     s64b_sub(&exp_adv, &exp_adv_frac, creature_ptr->exp, creature_ptr->exp_frac);
440
441     s64b_add(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
442     s64b_sub(&exp_adv, &exp_adv_frac, 0, 1);
443
444     s64b_div(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
445
446     u32b num = MIN(999, exp_adv_frac);
447     sprintf(buf, "%03ld", (long int)num);
448 }
449
450 bool show_gold_on_floor = FALSE;
451
452 /*
453  * Examine a grid, return a keypress.
454  *
455  * The "mode" argument contains the "TARGET_LOOK" bit flag, which
456  * indicates that the "space" key should scan through the contents
457  * of the grid, instead of simply returning immediately.  This lets
458  * the "look" command get complete information, without making the
459  * "target" command annoying.
460  *
461  * The "info" argument contains the "commands" which should be shown
462  * inside the "[xxx]" text.  This string must never be empty, or grids
463  * containing monsters will be displayed with an extra comma.
464  *
465  * Note that if a monster is in the grid, we update both the monster
466  * recall info and the health bar info to track that monster.
467  *
468  * Eventually, we may allow multiple objects per grid, or objects
469  * and terrain features in the same grid.
470  *
471  * This function must handle blindness/hallucination.
472  */
473 static char target_set_aux(player_type *subject_ptr, POSITION y, POSITION x, BIT_FLAGS mode, concptr info)
474 {
475     OBJECT_IDX next_o_idx = 0;
476     concptr s1 = "", s2 = "", s3 = "", x_info = "";
477     bool boring = TRUE;
478     FEAT_IDX feat;
479     feature_type *f_ptr;
480     char query = '\001';
481     char out_val[MAX_NLEN + 80];
482     OBJECT_IDX floor_list[23];
483     ITEM_NUMBER floor_num = 0;
484     if (easy_floor) {
485         floor_num = scan_floor_items(subject_ptr, floor_list, y, x, 0x02, 0);
486
487         if (floor_num) {
488             x_info = _("x物 ", "x,");
489         }
490     }
491
492     if (player_bold(subject_ptr, y, x)) {
493 #ifdef JP
494         s1 = "あなたは";
495         s2 = "の上";
496         s3 = "にいる";
497 #else
498         s1 = "You are ";
499         s2 = "on ";
500 #endif
501     } else {
502         s1 = _("ターゲット:", "Target:");
503     }
504
505     if (subject_ptr->image) {
506         concptr name = _("何か奇妙な物", "something strange");
507 #ifdef JP
508         sprintf(out_val, "%s%s%s%s [%s]", s1, name, s2, s3, info);
509 #else
510         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
511 #endif
512         prt(out_val, 0, 0);
513         move_cursor_relative(y, x);
514         query = inkey();
515         if ((query != '\r') && (query != '\n'))
516             return query;
517
518         return 0;
519     }
520
521     grid_type *g_ptr = &subject_ptr->current_floor_ptr->grid_array[y][x];
522     if (g_ptr->m_idx && subject_ptr->current_floor_ptr->m_list[g_ptr->m_idx].ml) {
523         monster_type *m_ptr = &subject_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
524         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
525         GAME_TEXT m_name[MAX_NLEN];
526         bool recall = FALSE;
527         boring = FALSE;
528         monster_race_track(subject_ptr, m_ptr->ap_r_idx);
529         health_track(subject_ptr, g_ptr->m_idx);
530         handle_stuff(subject_ptr);
531         while (TRUE) {
532             char acount[10];
533             if (recall) {
534                 screen_save();
535                 screen_roff(subject_ptr, m_ptr->ap_r_idx, 0);
536                 term_addstr(-1, TERM_WHITE, format(_("  [r思 %s%s]", "  [r,%s%s]"), x_info, info));
537                 query = inkey();
538                 screen_load();
539                 if (query != 'r')
540                     break;
541
542                 recall = FALSE;
543                 continue;
544             }
545
546             evaluate_monster_exp(subject_ptr, acount, m_ptr);
547 #ifdef JP
548             sprintf(out_val, "[%s]%s%s(%s)%s%s [r思 %s%s]", acount, s1, m_name, look_mon_desc(m_ptr, 0x01), s2, s3, x_info, info);
549 #else
550             sprintf(out_val, "[%s]%s%s%s%s(%s) [r, %s%s]", acount, s1, s2, s3, m_name, look_mon_desc(m_ptr, 0x01), x_info, info);
551 #endif
552             prt(out_val, 0, 0);
553             move_cursor_relative(y, x);
554             query = inkey();
555             if (query != 'r')
556                 break;
557
558             recall = TRUE;
559         }
560
561         if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x'))
562             return query;
563
564         if ((query == ' ') && !(mode & (TARGET_LOOK)))
565             return query;
566
567         s1 = _("それは", "It is ");
568         if (ap_r_ptr->flags1 & (RF1_FEMALE))
569             s1 = _("彼女は", "She is ");
570         else if (ap_r_ptr->flags1 & (RF1_MALE))
571             s1 = _("彼は", "He is ");
572
573 #ifdef JP
574         s2 = "を";
575         s3 = "持っている";
576 #else
577         s2 = "carrying ";
578 #endif
579
580         for (OBJECT_IDX this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) {
581             GAME_TEXT o_name[MAX_NLEN];
582             object_type *o_ptr;
583             o_ptr = &subject_ptr->current_floor_ptr->o_list[this_o_idx];
584             next_o_idx = o_ptr->next_o_idx;
585             describe_flavor(subject_ptr, o_name, o_ptr, 0);
586 #ifdef JP
587             sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
588 #else
589             sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
590 #endif
591             prt(out_val, 0, 0);
592             move_cursor_relative(y, x);
593             query = inkey();
594             if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x'))
595                 return query;
596
597             if ((query == ' ') && !(mode & (TARGET_LOOK)))
598                 return query;
599
600             s2 = _("をまた", "also carrying ");
601         }
602
603 #ifdef JP
604         s2 = "の上";
605         s3 = "にいる";
606 #else
607         s2 = "on ";
608 #endif
609     }
610
611     if (floor_num) {
612         int min_width = 0;
613         while (TRUE) {
614             if (floor_num == 1) {
615                 GAME_TEXT o_name[MAX_NLEN];
616                 object_type *o_ptr;
617                 o_ptr = &subject_ptr->current_floor_ptr->o_list[floor_list[0]];
618                 describe_flavor(subject_ptr, o_name, o_ptr, 0);
619 #ifdef JP
620                 sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
621 #else
622                 sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
623 #endif
624                 prt(out_val, 0, 0);
625                 move_cursor_relative(y, x);
626                 query = inkey();
627                 return query;
628             }
629
630             if (boring) {
631 #ifdef JP
632                 sprintf(out_val, "%s %d個のアイテム%s%s ['x'で一覧, %s]", s1, (int)floor_num, s2, s3, info);
633 #else
634                 sprintf(out_val, "%s%s%sa pile of %d items [x,%s]", s1, s2, s3, (int)floor_num, info);
635 #endif
636                 prt(out_val, 0, 0);
637                 move_cursor_relative(y, x);
638                 query = inkey();
639                 if (query != 'x' && query != ' ')
640                     return query;
641             }
642
643             while (TRUE) {
644                 int i;
645                 OBJECT_IDX o_idx;
646                 screen_save();
647                 show_gold_on_floor = TRUE;
648                 (void)show_floor_items(subject_ptr, 0, y, x, &min_width, 0);
649                 show_gold_on_floor = FALSE;
650 #ifdef JP
651                 sprintf(out_val, "%s %d個のアイテム%s%s [Enterで次へ, %s]", s1, (int)floor_num, s2, s3, info);
652 #else
653                 sprintf(out_val, "%s%s%sa pile of %d items [Enter,%s]", s1, s2, s3, (int)floor_num, info);
654 #endif
655                 prt(out_val, 0, 0);
656                 query = inkey();
657                 screen_load();
658                 if (query != '\n' && query != '\r')
659                     return query;
660
661                 o_idx = g_ptr->o_idx;
662                 if (!(o_idx && subject_ptr->current_floor_ptr->o_list[o_idx].next_o_idx))
663                     continue;
664
665                 excise_object_idx(subject_ptr->current_floor_ptr, o_idx);
666                 i = g_ptr->o_idx;
667                 while (subject_ptr->current_floor_ptr->o_list[i].next_o_idx)
668                     i = subject_ptr->current_floor_ptr->o_list[i].next_o_idx;
669
670                 subject_ptr->current_floor_ptr->o_list[i].next_o_idx = o_idx;
671             }
672         }
673     }
674
675     for (OBJECT_IDX this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) {
676         object_type *o_ptr;
677         o_ptr = &subject_ptr->current_floor_ptr->o_list[this_o_idx];
678         next_o_idx = o_ptr->next_o_idx;
679         if (o_ptr->marked & OM_FOUND) {
680             GAME_TEXT o_name[MAX_NLEN];
681             boring = FALSE;
682             describe_flavor(subject_ptr, o_name, o_ptr, 0);
683 #ifdef JP
684             sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
685 #else
686             sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
687 #endif
688             prt(out_val, 0, 0);
689             move_cursor_relative(y, x);
690             query = inkey();
691             if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x'))
692                 return query;
693
694             if ((query == ' ') && !(mode & TARGET_LOOK))
695                 return query;
696
697             s1 = _("それは", "It is ");
698             if (o_ptr->number != 1)
699                 s1 = _("それらは", "They are ");
700
701 #ifdef JP
702             s2 = "の上";
703             s3 = "に見える";
704 #else
705             s2 = "on ";
706 #endif
707         }
708     }
709
710     feat = get_feat_mimic(g_ptr);
711     if (!(g_ptr->info & CAVE_MARK) && !player_can_see_bold(subject_ptr, y, x))
712         feat = feat_none;
713
714     f_ptr = &f_info[feat];
715     if (!boring && !have_flag(f_ptr->flags, FF_REMEMBER)) {
716         if ((query != '\r') && (query != '\n'))
717             return query;
718
719         return 0;
720     }
721
722     concptr name;
723     if (have_flag(f_ptr->flags, FF_QUEST_ENTER)) {
724         IDX old_quest = subject_ptr->current_floor_ptr->inside_quest;
725         for (int j = 0; j < 10; j++)
726             quest_text[j][0] = '\0';
727
728         quest_text_line = 0;
729         subject_ptr->current_floor_ptr->inside_quest = g_ptr->special;
730         init_flags = INIT_NAME_ONLY;
731         parse_fixed_map(subject_ptr, "q_info.txt", 0, 0, 0, 0);
732         name = format(_("クエスト「%s」(%d階相当)", "the entrance to the quest '%s'(level %d)"), quest[g_ptr->special].name, quest[g_ptr->special].level);
733         subject_ptr->current_floor_ptr->inside_quest = old_quest;
734     } else if (have_flag(f_ptr->flags, FF_BLDG) && !subject_ptr->current_floor_ptr->inside_arena) {
735         name = building[f_ptr->subtype].name;
736     } else if (have_flag(f_ptr->flags, FF_ENTRANCE)) {
737         name = format(_("%s(%d階相当)", "%s(level %d)"), d_text + d_info[g_ptr->special].text, d_info[g_ptr->special].mindepth);
738     } else if (have_flag(f_ptr->flags, FF_TOWN)) {
739         name = town_info[g_ptr->special].name;
740     } else if (subject_ptr->wild_mode && (feat == feat_floor)) {
741         name = _("道", "road");
742     } else {
743         name = f_name + f_ptr->name;
744     }
745
746     if (*s2
747         && ((!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY))
748             || (!have_flag(f_ptr->flags, FF_LOS) && !have_flag(f_ptr->flags, FF_TREE)) || have_flag(f_ptr->flags, FF_TOWN))) {
749         s2 = _("の中", "in ");
750     }
751
752     if (have_flag(f_ptr->flags, FF_STORE) || have_flag(f_ptr->flags, FF_QUEST_ENTER)
753         || (have_flag(f_ptr->flags, FF_BLDG) && !subject_ptr->current_floor_ptr->inside_arena) || have_flag(f_ptr->flags, FF_ENTRANCE))
754         s2 = _("の入口", "");
755 #ifdef JP
756 #else
757     else if (have_flag(f_ptr->flags, FF_FLOOR) || have_flag(f_ptr->flags, FF_TOWN) || have_flag(f_ptr->flags, FF_SHALLOW) || have_flag(f_ptr->flags, FF_DEEP))
758         s3 = "";
759     else
760         s3 = (is_a_vowel(name[0])) ? "an " : "a ";
761 #endif
762
763     if (current_world_ptr->wizard) {
764         char f_idx_str[32];
765         if (g_ptr->mimic)
766             sprintf(f_idx_str, "%d/%d", g_ptr->feat, g_ptr->mimic);
767         else
768             sprintf(f_idx_str, "%d", g_ptr->feat);
769
770 #ifdef JP
771         sprintf(out_val, "%s%s%s%s[%s] %x %s %d %d %d (%d,%d) %d", s1, name, s2, s3, info, (unsigned int)g_ptr->info, f_idx_str, g_ptr->dist, g_ptr->cost,
772             g_ptr->when, (int)y, (int)x, travel.cost[y][x]);
773 #else
774         sprintf(out_val, "%s%s%s%s [%s] %x %s %d %d %d (%d,%d)", s1, s2, s3, name, info, g_ptr->info, f_idx_str, g_ptr->dist, g_ptr->cost, g_ptr->when, (int)y,
775             (int)x);
776 #endif
777     } else
778 #ifdef JP
779         sprintf(out_val, "%s%s%s%s[%s]", s1, name, s2, s3, info);
780 #else
781         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
782 #endif
783
784     prt(out_val, 0, 0);
785     move_cursor_relative(y, x);
786     query = inkey();
787     if ((query != '\r') && (query != '\n') && (query != ' '))
788         return query;
789
790     return 0;
791 }
792
793 /*
794  * Handle "target" and "look".
795  */
796 bool target_set(player_type *creature_ptr, BIT_FLAGS mode)
797 {
798     int i, d, t, bd;
799     POSITION y = creature_ptr->y;
800     POSITION x = creature_ptr->x;
801     bool done = FALSE;
802     bool flag = TRUE;
803     char query;
804     char info[80];
805     grid_type *g_ptr;
806     TERM_LEN wid, hgt;
807     get_screen_size(&wid, &hgt);
808     target_who = 0;
809     const char same_key = rogue_like_commands ? 'x' : 'l';
810     target_set_prepare(creature_ptr, mode);
811     int m = 0;
812     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
813     while (!done) {
814         if (flag && tmp_pos.n) {
815             y = tmp_pos.y[m];
816             x = tmp_pos.x[m];
817             change_panel_xy(creature_ptr, y, x);
818             if (!(mode & TARGET_LOOK))
819                 print_path(creature_ptr, y, x);
820
821             g_ptr = &floor_ptr->grid_array[y][x];
822             if (target_able(creature_ptr, g_ptr->m_idx))
823                 strcpy(info, _("q止 t決 p自 o現 +次 -前", "q,t,p,o,+,-,<dir>"));
824             else
825                 strcpy(info, _("q止 p自 o現 +次 -前", "q,p,o,+,-,<dir>"));
826
827             if (cheat_sight) {
828                 char cheatinfo[30];
829                 sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d", los(creature_ptr, creature_ptr->y, creature_ptr->x, y, x),
830                     projectable(creature_ptr, creature_ptr->y, creature_ptr->x, y, x));
831                 strcat(info, cheatinfo);
832             }
833
834             while (TRUE) {
835                 query = target_set_aux(creature_ptr, y, x, mode, info);
836                 if (query)
837                     break;
838             }
839
840             d = 0;
841             if (use_menu) {
842                 if (query == '\r')
843                     query = 't';
844             }
845
846             switch (query) {
847             case ESCAPE:
848             case 'q': {
849                 done = TRUE;
850                 break;
851             }
852             case 't':
853             case '.':
854             case '5':
855             case '0': {
856                 if (!target_able(creature_ptr, g_ptr->m_idx)) {
857                     bell();
858                     break;
859                 }
860
861                 health_track(creature_ptr, g_ptr->m_idx);
862                 target_who = g_ptr->m_idx;
863                 target_row = y;
864                 target_col = x;
865                 done = TRUE;
866                 break;
867             }
868             case ' ':
869             case '*':
870             case '+': {
871                 if (++m == tmp_pos.n) {
872                     m = 0;
873                     if (!expand_list)
874                         done = TRUE;
875                 }
876
877                 break;
878             }
879             case '-': {
880                 if (m-- == 0) {
881                     m = tmp_pos.n - 1;
882                     if (!expand_list)
883                         done = TRUE;
884                 }
885
886                 break;
887             }
888             case 'p': {
889                 verify_panel(creature_ptr);
890                 creature_ptr->update |= (PU_MONSTERS);
891                 creature_ptr->redraw |= (PR_MAP);
892                 creature_ptr->window |= (PW_OVERHEAD);
893                 handle_stuff(creature_ptr);
894                 target_set_prepare(creature_ptr, mode);
895                 y = creature_ptr->y;
896                 x = creature_ptr->x;
897             }
898                 /* Fall through */
899             case 'o':
900                 flag = FALSE;
901                 break;
902             case 'm':
903                 break;
904             default: {
905                 if (query == same_key) {
906                     if (++m == tmp_pos.n) {
907                         m = 0;
908                         if (!expand_list)
909                             done = TRUE;
910                     }
911                 } else {
912                     d = get_keymap_dir(query);
913                     if (!d)
914                         bell();
915
916                     break;
917                 }
918             }
919             }
920
921             if (d) {
922                 POSITION y2 = panel_row_min;
923                 POSITION x2 = panel_col_min;
924                 i = target_pick(tmp_pos.y[m], tmp_pos.x[m], ddy[d], ddx[d]);
925                 while (flag && (i < 0)) {
926                     if (change_panel(creature_ptr, ddy[d], ddx[d])) {
927                         int v = tmp_pos.y[m];
928                         int u = tmp_pos.x[m];
929                         target_set_prepare(creature_ptr, mode);
930                         flag = TRUE;
931                         i = target_pick(v, u, ddy[d], ddx[d]);
932                         if (i >= 0)
933                             m = i;
934
935                         continue;
936                     }
937
938                     POSITION dx = ddx[d];
939                     POSITION dy = ddy[d];
940                     panel_row_min = y2;
941                     panel_col_min = x2;
942                     panel_bounds_center();
943                     creature_ptr->update |= (PU_MONSTERS);
944                     creature_ptr->redraw |= (PR_MAP);
945                     creature_ptr->window |= (PW_OVERHEAD);
946                     handle_stuff(creature_ptr);
947                     target_set_prepare(creature_ptr, mode);
948                     flag = FALSE;
949                     x += dx;
950                     y += dy;
951                     if (((x < panel_col_min + wid / 2) && (dx > 0)) || ((x > panel_col_min + wid / 2) && (dx < 0)))
952                         dx = 0;
953
954                     if (((y < panel_row_min + hgt / 2) && (dy > 0)) || ((y > panel_row_min + hgt / 2) && (dy < 0)))
955                         dy = 0;
956
957                     if ((y >= panel_row_min + hgt) || (y < panel_row_min) || (x >= panel_col_min + wid) || (x < panel_col_min)) {
958                         if (change_panel(creature_ptr, dy, dx))
959                             target_set_prepare(creature_ptr, mode);
960                     }
961
962                     if (x >= floor_ptr->width - 1)
963                         x = floor_ptr->width - 2;
964                     else if (x <= 0)
965                         x = 1;
966
967                     if (y >= floor_ptr->height - 1)
968                         y = floor_ptr->height - 2;
969                     else if (y <= 0)
970                         y = 1;
971                 }
972
973                 m = i;
974             }
975
976             continue;
977         }
978
979         bool move_fast = FALSE;
980         if (!(mode & TARGET_LOOK))
981             print_path(creature_ptr, y, x);
982
983         g_ptr = &floor_ptr->grid_array[y][x];
984         strcpy(info, _("q止 t決 p自 m近 +次 -前", "q,t,p,m,+,-,<dir>"));
985         if (cheat_sight) {
986             char cheatinfo[100];
987             sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d, SPECIAL:%d", los(creature_ptr, creature_ptr->y, creature_ptr->x, y, x),
988                 projectable(creature_ptr, creature_ptr->y, creature_ptr->x, y, x), g_ptr->special);
989             strcat(info, cheatinfo);
990         }
991
992         /* Describe and Prompt (enable "TARGET_LOOK") */
993         while ((query = target_set_aux(creature_ptr, y, x, mode | TARGET_LOOK, info)) == 0)
994             ;
995
996         d = 0;
997         if (use_menu && (query == '\r'))
998             query = 't';
999
1000         switch (query) {
1001         case ESCAPE:
1002         case 'q':
1003             done = TRUE;
1004             break;
1005         case 't':
1006         case '.':
1007         case '5':
1008         case '0':
1009             target_who = -1;
1010             target_row = y;
1011             target_col = x;
1012             done = TRUE;
1013             break;
1014         case 'p':
1015             verify_panel(creature_ptr);
1016             creature_ptr->update |= (PU_MONSTERS);
1017             creature_ptr->redraw |= (PR_MAP);
1018             creature_ptr->window |= (PW_OVERHEAD);
1019             handle_stuff(creature_ptr);
1020             target_set_prepare(creature_ptr, mode);
1021             y = creature_ptr->y;
1022             x = creature_ptr->x;
1023         case 'o':
1024             break;
1025         case ' ':
1026         case '*':
1027         case '+':
1028         case '-':
1029         case 'm': {
1030             flag = TRUE;
1031             m = 0;
1032             bd = 999;
1033             for (i = 0; i < tmp_pos.n; i++) {
1034                 t = distance(y, x, tmp_pos.y[i], tmp_pos.x[i]);
1035                 if (t < bd) {
1036                     m = i;
1037                     bd = t;
1038                 }
1039             }
1040
1041             if (bd == 999)
1042                 flag = FALSE;
1043
1044             break;
1045         }
1046         default: {
1047             d = get_keymap_dir(query);
1048             if (isupper(query))
1049                 move_fast = TRUE;
1050
1051             if (!d)
1052                 bell();
1053             break;
1054         }
1055         }
1056
1057         if (d) {
1058             POSITION dx = ddx[d];
1059             POSITION dy = ddy[d];
1060             if (move_fast) {
1061                 int mag = MIN(wid / 2, hgt / 2);
1062                 x += dx * mag;
1063                 y += dy * mag;
1064             } else {
1065                 x += dx;
1066                 y += dy;
1067             }
1068
1069             if (((x < panel_col_min + wid / 2) && (dx > 0)) || ((x > panel_col_min + wid / 2) && (dx < 0)))
1070                 dx = 0;
1071
1072             if (((y < panel_row_min + hgt / 2) && (dy > 0)) || ((y > panel_row_min + hgt / 2) && (dy < 0)))
1073                 dy = 0;
1074
1075             if ((y >= panel_row_min + hgt) || (y < panel_row_min) || (x >= panel_col_min + wid) || (x < panel_col_min)) {
1076                 if (change_panel(creature_ptr, dy, dx))
1077                     target_set_prepare(creature_ptr, mode);
1078             }
1079
1080             if (x >= floor_ptr->width - 1)
1081                 x = floor_ptr->width - 2;
1082             else if (x <= 0)
1083                 x = 1;
1084
1085             if (y >= floor_ptr->height - 1)
1086                 y = floor_ptr->height - 2;
1087             else if (y <= 0)
1088                 y = 1;
1089         }
1090     }
1091
1092     tmp_pos.n = 0;
1093     prt("", 0, 0);
1094     verify_panel(creature_ptr);
1095     creature_ptr->update |= (PU_MONSTERS);
1096     creature_ptr->redraw |= (PR_MAP);
1097     creature_ptr->window |= (PW_OVERHEAD);
1098     handle_stuff(creature_ptr);
1099     return target_who != 0;
1100 }
1101
1102 /*
1103  * Get an "aiming direction" from the user.
1104  *
1105  * The "dir" is loaded with 1,2,3,4,6,7,8,9 for "actual direction", and
1106  * "0" for "current target", and "-1" for "entry aborted".
1107  *
1108  * Note that "Force Target", if set, will pre-empt user interaction,
1109  * if there is a usable target already set.
1110  *
1111  * Note that confusion over-rides any (explicit?) user choice.
1112  */
1113 bool get_aim_dir(player_type *creature_ptr, DIRECTION *dp)
1114 {
1115     DIRECTION dir = command_dir;
1116     if (use_old_target && target_okay(creature_ptr))
1117         dir = 5;
1118
1119     COMMAND_CODE code;
1120     if (repeat_pull(&code))
1121         if (!(code == 5 && !target_okay(creature_ptr)))
1122             dir = (DIRECTION)code;
1123
1124     *dp = (DIRECTION)code;
1125     char command;
1126     while (!dir) {
1127         concptr p;
1128         if (!target_okay(creature_ptr))
1129             p = _("方向 ('*'でターゲット選択, ESCで中断)? ", "Direction ('*' to choose a target, Escape to cancel)? ");
1130         else
1131             p = _("方向 ('5'でターゲットへ, '*'でターゲット再選択, ESCで中断)? ", "Direction ('5' for target, '*' to re-target, Escape to cancel)? ");
1132
1133         if (!get_com(p, &command, TRUE))
1134             break;
1135
1136         if (use_menu && (command == '\r'))
1137             command = 't';
1138
1139         switch (command) {
1140         case 'T':
1141         case 't':
1142         case '.':
1143         case '5':
1144         case '0':
1145             dir = 5;
1146             break;
1147         case '*':
1148         case ' ':
1149         case '\r':
1150             if (target_set(creature_ptr, TARGET_KILL))
1151                 dir = 5;
1152
1153             break;
1154         default:
1155             dir = get_keymap_dir(command);
1156             break;
1157         }
1158
1159         if ((dir == 5) && !target_okay(creature_ptr))
1160             dir = 0;
1161
1162         if (!dir)
1163             bell();
1164     }
1165
1166     if (!dir) {
1167         project_length = 0;
1168         return FALSE;
1169     }
1170
1171     command_dir = dir;
1172     if (creature_ptr->confused)
1173         dir = ddd[randint0(8)];
1174
1175     if (command_dir != dir)
1176         msg_print(_("あなたは混乱している。", "You are confused."));
1177
1178     *dp = dir;
1179     repeat_push((COMMAND_CODE)command_dir);
1180     return TRUE;
1181 }
1182
1183 bool get_direction(player_type *creature_ptr, DIRECTION *dp, bool allow_under, bool with_steed)
1184 {
1185     DIRECTION dir = command_dir;
1186     COMMAND_CODE code;
1187     if (repeat_pull(&code))
1188         dir = (DIRECTION)code;
1189
1190     *dp = (DIRECTION)code;
1191     concptr prompt = allow_under ? _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ")
1192                                  : _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
1193
1194     while (!dir) {
1195         char ch;
1196         if (!get_com(prompt, &ch, TRUE))
1197             break;
1198
1199         if ((allow_under) && ((ch == '5') || (ch == '-') || (ch == '.'))) {
1200             dir = 5;
1201             continue;
1202         }
1203
1204         dir = get_keymap_dir(ch);
1205         if (!dir)
1206             bell();
1207     }
1208
1209     if ((dir == 5) && (!allow_under))
1210         dir = 0;
1211
1212     if (!dir)
1213         return FALSE;
1214
1215     command_dir = dir;
1216     if (creature_ptr->confused) {
1217         if (randint0(100) < 75) {
1218             dir = ddd[randint0(8)];
1219         }
1220     } else if (creature_ptr->riding && with_steed) {
1221         monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[creature_ptr->riding];
1222         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1223         if (monster_confused_remaining(m_ptr)) {
1224             if (randint0(100) < 75)
1225                 dir = ddd[randint0(8)];
1226         } else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
1227             dir = ddd[randint0(8)];
1228         else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
1229             dir = ddd[randint0(8)];
1230     }
1231
1232     if (command_dir != dir) {
1233         if (creature_ptr->confused) {
1234             msg_print(_("あなたは混乱している。", "You are confused."));
1235         } else {
1236             GAME_TEXT m_name[MAX_NLEN];
1237             monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[creature_ptr->riding];
1238
1239             monster_desc(creature_ptr, m_name, m_ptr, 0);
1240             if (monster_confused_remaining(m_ptr)) {
1241                 msg_format(_("%sは混乱している。", "%^s is confused."), m_name);
1242             } else {
1243                 msg_format(_("%sは思い通りに動いてくれない。", "You cannot control %s."), m_name);
1244             }
1245         }
1246     }
1247
1248     *dp = dir;
1249     repeat_push((COMMAND_CODE)command_dir);
1250     return TRUE;
1251 }
1252
1253 /*
1254  * @brief 進行方向を指定する(騎乗対象の混乱の影響を受ける) / Request a "movement" direction (1,2,3,4,6,7,8,9) from the user,
1255  * and place it into "command_dir", unless we already have one.
1256  *
1257  * This function should be used for all "repeatable" commands, such as
1258  * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well
1259  * as all commands which must reference a grid adjacent to the player,
1260  * and which may not reference the grid under the player.  Note that,
1261  * for example, it is no longer possible to "disarm" or "open" chests
1262  * in the same grid as the player.
1263  *
1264  * Direction "5" is illegal and will (cleanly) abort the command.
1265  *
1266  * This function tracks and uses the "global direction", and uses
1267  * that as the "desired direction", to which "confusion" is applied.
1268  */
1269 bool get_rep_dir(player_type *creature_ptr, DIRECTION *dp, bool under)
1270 {
1271     DIRECTION dir = command_dir;
1272     COMMAND_CODE code;
1273     if (repeat_pull(&code))
1274         dir = (DIRECTION)code;
1275
1276     *dp = (DIRECTION)code;
1277     concptr prompt
1278         = under ? _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ") : _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
1279     while (!dir) {
1280         char ch;
1281         if (!get_com(prompt, &ch, TRUE))
1282             break;
1283
1284         if ((under) && ((ch == '5') || (ch == '-') || (ch == '.'))) {
1285             dir = 5;
1286             continue;
1287         }
1288
1289         dir = get_keymap_dir(ch);
1290         if (!dir)
1291             bell();
1292     }
1293
1294     if ((dir == 5) && (!under))
1295         dir = 0;
1296
1297     if (!dir)
1298         return FALSE;
1299
1300     command_dir = dir;
1301     if (creature_ptr->confused) {
1302         if (randint0(100) < 75)
1303             dir = ddd[randint0(8)];
1304     } else if (creature_ptr->riding) {
1305         monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[creature_ptr->riding];
1306         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1307         if (monster_confused_remaining(m_ptr)) {
1308             if (randint0(100) < 75)
1309                 dir = ddd[randint0(8)];
1310         } else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
1311             dir = ddd[randint0(8)];
1312         else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
1313             dir = ddd[randint0(8)];
1314     }
1315
1316     if (command_dir != dir) {
1317         if (creature_ptr->confused) {
1318             msg_print(_("あなたは混乱している。", "You are confused."));
1319         } else {
1320             GAME_TEXT m_name[MAX_NLEN];
1321             monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[creature_ptr->riding];
1322             monster_desc(creature_ptr, m_name, m_ptr, 0);
1323             if (monster_confused_remaining(m_ptr))
1324                 msg_format(_("%sは混乱している。", "%^s is confused."), m_name);
1325             else
1326                 msg_format(_("%sは思い通りに動いてくれない。", "You cannot control %s."), m_name);
1327         }
1328     }
1329
1330     *dp = dir;
1331     repeat_push((COMMAND_CODE)command_dir);
1332     return TRUE;
1333 }
1334
1335 /*
1336  * XAngband: determine if a given location is "interesting"
1337  * based on target_set_accept function.
1338  */
1339 static bool tgt_pt_accept(player_type *creature_ptr, POSITION y, POSITION x)
1340 {
1341     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
1342     if (!(in_bounds(floor_ptr, y, x)))
1343         return FALSE;
1344
1345     if ((y == creature_ptr->y) && (x == creature_ptr->x))
1346         return TRUE;
1347
1348     if (creature_ptr->image)
1349         return FALSE;
1350
1351     grid_type *g_ptr;
1352     g_ptr = &floor_ptr->grid_array[y][x];
1353     if (!(g_ptr->info & (CAVE_MARK)))
1354         return FALSE;
1355
1356     if (cave_have_flag_grid(g_ptr, FF_LESS) || cave_have_flag_grid(g_ptr, FF_MORE) || cave_have_flag_grid(g_ptr, FF_QUEST_ENTER)
1357         || cave_have_flag_grid(g_ptr, FF_QUEST_EXIT))
1358         return TRUE;
1359
1360     return FALSE;
1361 }
1362
1363 /*
1364  * XAngband: Prepare the "temp" array for "tget_pt"
1365  * based on target_set_prepare funciton.
1366  */
1367 static void tgt_pt_prepare(player_type *creature_ptr)
1368 {
1369     tmp_pos.n = 0;
1370     if (!expand_list)
1371         return;
1372
1373     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
1374     for (POSITION y = 1; y < floor_ptr->height; y++) {
1375         for (POSITION x = 1; x < floor_ptr->width; x++) {
1376             if (!tgt_pt_accept(creature_ptr, y, x))
1377                 continue;
1378
1379             tmp_pos.x[tmp_pos.n] = x;
1380             tmp_pos.y[tmp_pos.n] = y;
1381             tmp_pos.n++;
1382         }
1383     }
1384
1385     ang_sort(creature_ptr, tmp_pos.x, tmp_pos.y, tmp_pos.n, ang_sort_comp_distance, ang_sort_swap_distance);
1386 }
1387
1388 /*
1389  * old -- from PsiAngband.
1390  */
1391 bool tgt_pt(player_type *creature_ptr, POSITION *x_ptr, POSITION *y_ptr)
1392 {
1393     TERM_LEN wid, hgt;
1394     get_screen_size(&wid, &hgt);
1395
1396     POSITION x = creature_ptr->x;
1397     POSITION y = creature_ptr->y;
1398     if (expand_list)
1399         tgt_pt_prepare(creature_ptr);
1400
1401     msg_print(_("場所を選んでスペースキーを押して下さい。", "Select a point and press space."));
1402     msg_flag = FALSE;
1403
1404     char ch = 0;
1405     int n = 0;
1406     bool success = FALSE;
1407     while ((ch != ESCAPE) && !success) {
1408         bool move_fast = FALSE;
1409         move_cursor_relative(y, x);
1410         ch = inkey();
1411         switch (ch) {
1412         case ESCAPE:
1413             break;
1414         case ' ':
1415         case 't':
1416         case '.':
1417         case '5':
1418         case '0':
1419             if (player_bold(creature_ptr, y, x))
1420                 ch = 0;
1421             else
1422                 success = TRUE;
1423
1424             break;
1425         case '>':
1426         case '<': {
1427             if (!expand_list || !tmp_pos.n)
1428                 break;
1429
1430             int dx, dy;
1431             int cx = (panel_col_min + panel_col_max) / 2;
1432             int cy = (panel_row_min + panel_row_max) / 2;
1433             n++;
1434             for (; n < tmp_pos.n; ++n) {
1435                 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[tmp_pos.y[n]][tmp_pos.x[n]];
1436                 if (cave_have_flag_grid(g_ptr, FF_STAIRS) && cave_have_flag_grid(g_ptr, ch == '>' ? FF_MORE : FF_LESS))
1437                     break;
1438             }
1439
1440             if (n == tmp_pos.n) {
1441                 n = 0;
1442                 y = creature_ptr->y;
1443                 x = creature_ptr->x;
1444                 verify_panel(creature_ptr);
1445                 creature_ptr->update |= PU_MONSTERS;
1446                 creature_ptr->redraw |= PR_MAP;
1447                 creature_ptr->window |= PW_OVERHEAD;
1448                 handle_stuff(creature_ptr);
1449             } else {
1450                 y = tmp_pos.y[n];
1451                 x = tmp_pos.x[n];
1452                 dy = 2 * (y - cy) / hgt;
1453                 dx = 2 * (x - cx) / wid;
1454                 if (dy || dx)
1455                     change_panel(creature_ptr, dy, dx);
1456             }
1457
1458             break;
1459         }
1460         default: {
1461             int d = get_keymap_dir(ch);
1462             if (isupper(ch))
1463                 move_fast = TRUE;
1464
1465             if (d == 0)
1466                 break;
1467
1468             int dx = ddx[d];
1469             int dy = ddy[d];
1470             if (move_fast) {
1471                 int mag = MIN(wid / 2, hgt / 2);
1472                 x += dx * mag;
1473                 y += dy * mag;
1474             } else {
1475                 x += dx;
1476                 y += dy;
1477             }
1478
1479             if (((x < panel_col_min + wid / 2) && (dx > 0)) || ((x > panel_col_min + wid / 2) && (dx < 0)))
1480                 dx = 0;
1481
1482             if (((y < panel_row_min + hgt / 2) && (dy > 0)) || ((y > panel_row_min + hgt / 2) && (dy < 0)))
1483                 dy = 0;
1484
1485             if ((y >= panel_row_min + hgt) || (y < panel_row_min) || (x >= panel_col_min + wid) || (x < panel_col_min))
1486                 change_panel(creature_ptr, dy, dx);
1487
1488             if (x >= creature_ptr->current_floor_ptr->width - 1)
1489                 x = creature_ptr->current_floor_ptr->width - 2;
1490             else if (x <= 0)
1491                 x = 1;
1492
1493             if (y >= creature_ptr->current_floor_ptr->height - 1)
1494                 y = creature_ptr->current_floor_ptr->height - 2;
1495             else if (y <= 0)
1496                 y = 1;
1497
1498             break;
1499         }
1500         }
1501     }
1502
1503     prt("", 0, 0);
1504     verify_panel(creature_ptr);
1505     creature_ptr->update |= (PU_MONSTERS);
1506     creature_ptr->redraw |= (PR_MAP);
1507     creature_ptr->window |= (PW_OVERHEAD);
1508     handle_stuff(creature_ptr);
1509     *x_ptr = x;
1510     *y_ptr = y;
1511     return success;
1512 }
1513
1514 bool get_hack_dir(player_type *creature_ptr, DIRECTION *dp)
1515 {
1516     *dp = 0;
1517     char command;
1518     DIRECTION dir = 0;
1519     while (!dir) {
1520         concptr p = target_okay(creature_ptr)
1521             ? _("方向 ('5'でターゲットへ, '*'でターゲット再選択, ESCで中断)? ", "Direction ('5' for target, '*' to re-target, Escape to cancel)? ")
1522             : _("方向 ('*'でターゲット選択, ESCで中断)? ", "Direction ('*' to choose a target, Escape to cancel)? ");
1523         if (!get_com(p, &command, TRUE))
1524             break;
1525
1526         if (use_menu && (command == '\r'))
1527             command = 't';
1528
1529         switch (command) {
1530         case 'T':
1531         case 't':
1532         case '.':
1533         case '5':
1534         case '0':
1535             dir = 5;
1536             break;
1537         case '*':
1538         case ' ':
1539         case '\r':
1540             if (target_set(creature_ptr, TARGET_KILL))
1541                 dir = 5;
1542
1543             break;
1544         default:
1545             dir = get_keymap_dir(command);
1546             break;
1547         }
1548
1549         if ((dir == 5) && !target_okay(creature_ptr))
1550             dir = 0;
1551
1552         if (!dir)
1553             bell();
1554     }
1555
1556     if (!dir)
1557         return FALSE;
1558
1559     command_dir = dir;
1560     if (creature_ptr->confused)
1561         dir = ddd[randint0(8)];
1562
1563     if (command_dir != dir)
1564         msg_print(_("あなたは混乱している。", "You are confused."));
1565
1566     *dp = dir;
1567     return TRUE;
1568 }
1569
1570 /*!
1571  * @briefプレイヤーの攻撃射程(マス) / Maximum range (spells, etc)
1572  * @param creature_ptr プレーヤーへの参照ポインタ
1573  * @return 射程
1574  */
1575 int get_max_range(player_type *creature_ptr) { return creature_ptr->phase_out ? 36 : 18; }