OSDN Git Service

v3.0.0 Alpha5 OSDN最終版
[hengband/hengband.git] / src / xtra2.c
1 /*!
2  * @file xtra2.c
3  * @brief 雑多なその他の処理2 / effects of various "objects"
4  * @date 2014/02/06
5  * @author
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke\n
7  * This software may be copied and distributed for educational, research, and\n
8  * not for profit purposes provided that this copyright and statement are\n
9  * included in all such copies.\n
10  * 2014 Deskull rearranged comment for Doxygen.
11  */
12
13
14 #include "angband.h"
15 #include "cmd-pet.h"
16 #include "object-curse.h"
17 #include "monster.h"
18 #include "monsterrace-hook.h"
19 #include "objectkind-hook.h"
20 #include "sort.h"
21 #include "projection.h"
22 #include "spells-summon.h"
23 #include "patron.h"
24 #include "mutation.h"
25 #include "floor-events.h"
26
27 #define REWARD_CHANCE 10
28
29
30 /*!
31  * @brief プレイヤーの経験値について整合性のためのチェックと調整を行う /
32  * Advance experience levels and print experience
33  * @return なし
34  */
35 void check_experience(void)
36 {
37         bool level_reward = FALSE;
38         bool level_mutation = FALSE;
39         bool level_inc_stat = FALSE;
40         bool android = (p_ptr->prace == RACE_ANDROID ? TRUE : FALSE);
41         PLAYER_LEVEL old_lev = p_ptr->lev;
42
43         /* Hack -- lower limit */
44         if (p_ptr->exp < 0) p_ptr->exp = 0;
45         if (p_ptr->max_exp < 0) p_ptr->max_exp = 0;
46         if (p_ptr->max_max_exp < 0) p_ptr->max_max_exp = 0;
47
48         /* Hack -- upper limit */
49         if (p_ptr->exp > PY_MAX_EXP) p_ptr->exp = PY_MAX_EXP;
50         if (p_ptr->max_exp > PY_MAX_EXP) p_ptr->max_exp = PY_MAX_EXP;
51         if (p_ptr->max_max_exp > PY_MAX_EXP) p_ptr->max_max_exp = PY_MAX_EXP;
52
53         /* Hack -- maintain "max" experience */
54         if (p_ptr->exp > p_ptr->max_exp) p_ptr->max_exp = p_ptr->exp;
55
56         /* Hack -- maintain "max max" experience */
57         if (p_ptr->max_exp > p_ptr->max_max_exp) p_ptr->max_max_exp = p_ptr->max_exp;
58
59         /* Redraw experience */
60         p_ptr->redraw |= (PR_EXP);
61         handle_stuff();
62
63
64         /* Lose levels while possible */
65         while ((p_ptr->lev > 1) &&
66                (p_ptr->exp < ((android ? player_exp_a : player_exp)[p_ptr->lev - 2] * p_ptr->expfact / 100L)))
67         {
68                 /* Lose a level */
69                 p_ptr->lev--;
70                 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
71                 p_ptr->redraw |= (PR_LEV | PR_TITLE);
72                 p_ptr->window |= (PW_PLAYER);
73                 handle_stuff();
74         }
75
76
77         /* Gain levels while possible */
78         while ((p_ptr->lev < PY_MAX_LEVEL) &&
79                (p_ptr->exp >= ((android ? player_exp_a : player_exp)[p_ptr->lev-1] * p_ptr->expfact / 100L)))
80         {
81                 /* Gain a level */
82                 p_ptr->lev++;
83
84                 /* Save the highest level */
85                 if (p_ptr->lev > p_ptr->max_plv)
86                 {
87                         p_ptr->max_plv = p_ptr->lev;
88
89                         if ((p_ptr->pclass == CLASS_CHAOS_WARRIOR) ||
90                             (p_ptr->muta2 & MUT2_CHAOS_GIFT))
91                         {
92                                 level_reward = TRUE;
93                         }
94                         if (p_ptr->prace == RACE_BEASTMAN)
95                         {
96                                 if (one_in_(5)) level_mutation = TRUE;
97                         }
98                         level_inc_stat = TRUE;
99
100                         do_cmd_write_nikki(NIKKI_LEVELUP, p_ptr->lev, NULL);
101                 }
102
103                 sound(SOUND_LEVEL);
104
105                 msg_format(_("レベル %d にようこそ。", "Welcome to level %d."), p_ptr->lev);
106
107                 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
108                 p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);
109                 p_ptr->window |= (PW_PLAYER | PW_SPELL | PW_INVEN);
110
111                 /* HPとMPの上昇量を表示 */
112                 level_up = 1;
113                 handle_stuff();
114
115                 level_up = 0;
116
117                 if (level_inc_stat)
118                 {
119                         if(!(p_ptr->max_plv % 10))
120                         {
121                                 int choice;
122                                 screen_save();
123                                 while(1)
124                                 {
125                                         int n;
126                                         char tmp[32];
127
128                                         cnv_stat(p_ptr->stat_max[0], tmp);
129                                         prt(format(_("        a) 腕力 (現在値 %s)", "        a) Str (cur %s)"), tmp), 2, 14);
130                                         cnv_stat(p_ptr->stat_max[1], tmp);
131                                         prt(format(_("        b) 知能 (現在値 %s)", "        a) Int (cur %s)"), tmp), 3, 14);
132                                         cnv_stat(p_ptr->stat_max[2], tmp);
133                                         prt(format(_("        c) 賢さ (現在値 %s)", "        a) Wis (cur %s)"), tmp), 4, 14);
134                                         cnv_stat(p_ptr->stat_max[3], tmp);
135                                         prt(format(_("        d) 器用 (現在値 %s)", "        a) Dex (cur %s)"), tmp), 5, 14);
136                                         cnv_stat(p_ptr->stat_max[4], tmp);
137                                         prt(format(_("        e) 耐久 (現在値 %s)", "        a) Con (cur %s)"), tmp), 6, 14);
138                                         cnv_stat(p_ptr->stat_max[5], tmp);
139                                         prt(format(_("        f) 魅力 (現在値 %s)", "        a) Chr (cur %s)"), tmp), 7, 14);
140
141                                         prt("", 8, 14);
142                                         prt(_("        どの能力値を上げますか?", "        Which stat do you want to raise?"), 1, 14);
143
144                                         while(1)
145                                         {
146                                                 choice = inkey();
147                                                 if ((choice >= 'a') && (choice <= 'f')) break;
148                                         }
149                                         for(n = 0; n < A_MAX; n++)
150                                                 if (n != choice - 'a')
151                                                         prt("",n+2,14);
152                                         if (get_check(_("よろしいですか?", "Are you sure? "))) break;
153                                 }
154                                 do_inc_stat(choice - 'a');
155                                 screen_load();
156                         }
157                         else if(!(p_ptr->max_plv % 2))
158                                 do_inc_stat(randint0(6));
159                 }
160
161                 if (level_mutation)
162                 {
163                         msg_print(_("あなたは変わった気がする...", "You feel different..."));
164                         (void)gain_random_mutation(0);
165                         level_mutation = FALSE;
166                 }
167
168                 /*
169                  * 報酬でレベルが上ると再帰的に check_experience() が
170                  * 呼ばれるので順番を最後にする。
171                  */
172                 if (level_reward)
173                 {
174                         gain_level_reward(0);
175                         level_reward = FALSE;
176                 }
177
178                 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
179                 p_ptr->redraw |= (PR_LEV | PR_TITLE);
180                 p_ptr->window |= (PW_PLAYER | PW_SPELL);
181                 handle_stuff();
182         }
183
184         /* Load an autopick preference file */
185         if (old_lev != p_ptr->lev) autopick_load_pref(FALSE);
186 }
187
188
189
190 /*!
191  * @brief モンスターを撃破した際の述語メッセージを返す /
192  * Return monster death string
193  * @param r_ptr 撃破されたモンスターの種族情報を持つ構造体の参照ポインタ
194  * @return 撃破されたモンスターの述語
195  */
196 concptr extract_note_dies(MONRACE_IDX r_idx)
197 {
198         monster_race *r_ptr = &r_info[r_idx];
199         /* Some monsters get "destroyed" */
200         if (!monster_living(r_idx))
201         {
202                 int i;
203
204                 for (i = 0; i < 4; i++)
205                 {
206                         if (r_ptr->blow[i].method == RBM_EXPLODE)
207                         {
208                                 return _("は爆発して粉々になった。", " explodes into tiny shreds.");
209                         }
210                 }
211                 return _("を倒した。", " is destroyed.");
212         }
213
214         return _("は死んだ。", " dies.");
215 }
216
217
218
219 /*!
220  * @brief 現在のコンソール表示の縦横を返す。 /
221  * Get term size and calculate screen size
222  * @param wid_p コンソールの表示幅文字数を返す
223  * @param hgt_p コンソールの表示行数を返す
224  * @return なし
225  */
226 void get_screen_size(TERM_LEN *wid_p, TERM_LEN *hgt_p)
227 {
228         Term_get_size(wid_p, hgt_p);
229         *hgt_p -= ROW_MAP + 2;
230         *wid_p -= COL_MAP + 2;
231         if (use_bigtile) *wid_p /= 2;
232 }
233
234
235 /*!
236  * @brief コンソール上におけるマップ表示の左上位置を返す /
237  * Calculates current boundaries Called below and from "do_cmd_locate()".
238  * @return なし
239  */
240 void panel_bounds_center(void)
241 {
242         TERM_LEN wid, hgt;
243
244         get_screen_size(&wid, &hgt);
245
246         panel_row_max = panel_row_min + hgt - 1;
247         panel_row_prt = panel_row_min - 1;
248         panel_col_max = panel_col_min + wid - 1;
249         panel_col_prt = panel_col_min - 13;
250 }
251
252 /*!
253  * @brief フォーカスを当てるべきマップ描画の基準座標を指定する
254  * @param y 変更先のフロアY座標
255  * @param x 変更先のフロアX座標
256  * @details
257  * Handle a request to change the current panel
258  * Return TRUE if the panel was changed.
259  * Also used in do_cmd_locate
260  * @return 実際に再描画が必要だった場合TRUEを返す
261  */
262 static bool change_panel_xy(POSITION y, POSITION x)
263 {
264         POSITION dy = 0, dx = 0;
265         TERM_LEN wid, hgt;
266
267         get_screen_size(&wid, &hgt);
268
269         if (y < panel_row_min) dy = -1;
270         if (y > panel_row_max) dy = 1;
271         if (x < panel_col_min) dx = -1;
272         if (x > panel_col_max) dx = 1;
273
274         if (!dy && !dx) return (FALSE);
275
276         return change_panel(dy, dx);
277 }
278
279
280 /*!
281  * @brief マップ描画のフォーカスを当てるべき座標を更新する
282  * @details
283  * Given an row (y) and col (x), this routine detects when a move
284  * off the screen has occurred and figures new borders. -RAK-
285  * "Update" forces a "full update" to take place.
286  * The map is reprinted if necessary, and "TRUE" is returned.
287  * @return 実際に再描画が必要だった場合TRUEを返す
288  */
289 void verify_panel(void)
290 {
291         POSITION y = p_ptr->y;
292         POSITION x = p_ptr->x;
293         TERM_LEN wid, hgt;
294
295         int prow_min;
296         int pcol_min;
297         int max_prow_min;
298         int max_pcol_min;
299
300         get_screen_size(&wid, &hgt);
301
302         max_prow_min = cur_hgt - hgt;
303         max_pcol_min = cur_wid - wid;
304
305         /* Bounds checking */
306         if (max_prow_min < 0) max_prow_min = 0;
307         if (max_pcol_min < 0) max_pcol_min = 0;
308
309                 /* Center on player */
310         if (center_player && (center_running || !running))
311         {
312                 /* Center vertically */
313                 prow_min = y - hgt / 2;
314                 if (prow_min < 0) prow_min = 0;
315                 else if (prow_min > max_prow_min) prow_min = max_prow_min;
316
317                 /* Center horizontally */
318                 pcol_min = x - wid / 2;
319                 if (pcol_min < 0) pcol_min = 0;
320                 else if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
321         }
322         else
323         {
324                 prow_min = panel_row_min;
325                 pcol_min = panel_col_min;
326
327                 /* Scroll screen when 2 grids from top/bottom edge */
328                 if (y > panel_row_max - 2)
329                 {
330                         while (y > prow_min + hgt-1 - 2)
331                         {
332                                 prow_min += (hgt / 2);
333                         }
334                 }
335
336                 if (y < panel_row_min + 2)
337                 {
338                         while (y < prow_min + 2)
339                         {
340                                 prow_min -= (hgt / 2);
341                         }
342                 }
343
344                 if (prow_min > max_prow_min) prow_min = max_prow_min;
345                 if (prow_min < 0) prow_min = 0;
346
347                 /* Scroll screen when 4 grids from left/right edge */
348                 if (x > panel_col_max - 4)
349                 {
350                         while (x > pcol_min + wid-1 - 4)
351                         {
352                                 pcol_min += (wid / 2);
353                         }
354                 }
355                 
356                 if (x < panel_col_min + 4)
357                 {
358                         while (x < pcol_min + 4)
359                         {
360                                 pcol_min -= (wid / 2);
361                         }
362                 }
363
364                 if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
365                 if (pcol_min < 0) pcol_min = 0;
366         }
367
368         /* Check for "no change" */
369         if ((prow_min == panel_row_min) && (pcol_min == panel_col_min)) return;
370
371         /* Save the new panel info */
372         panel_row_min = prow_min;
373         panel_col_min = pcol_min;
374
375         /* Hack -- optional disturb on "panel change" */
376         if (disturb_panel && !center_player) disturb(FALSE, FALSE);
377
378         /* Recalculate the boundaries */
379         panel_bounds_center();
380
381         p_ptr->update |= (PU_MONSTERS);
382         p_ptr->redraw |= (PR_MAP);
383         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
384 }
385
386
387 /*
388  * Monster health description
389  */
390 concptr look_mon_desc(monster_type *m_ptr, BIT_FLAGS mode)
391 {
392         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
393         bool living;
394         int perc;
395         concptr desc;
396         concptr attitude;
397         concptr clone;
398
399         /* Determine if the monster is "living" */
400         living = monster_living(m_ptr->ap_r_idx);
401
402         /* Calculate a health "percentage" */
403         perc = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->maxhp : 0;
404
405         /* Healthy monsters */
406         if (m_ptr->hp >= m_ptr->maxhp)
407         {
408                 desc = living ? _("無傷", "unhurt") : _("無ダメージ", "undamaged");
409         }
410
411         else if (perc >= 60)
412         {
413                 desc = living ? _("軽傷", "somewhat wounded") : _("小ダメージ", "somewhat damaged");
414         }
415
416         else if (perc >= 25)
417         {
418                 desc = living ? _("負傷", "wounded") : _("中ダメージ", "damaged");
419         }
420
421         else if (perc >= 10)
422         {
423                 desc = living ? _("重傷", "badly wounded") : _("大ダメージ", "badly damaged");
424         }
425
426         else 
427         {
428                 desc = living ? _("半死半生", "almost dead") : _("倒れかけ", "almost destroyed");
429         }
430
431         /* Need attitude information? */
432         if (!(mode & 0x01))
433         {
434                 /* Full information is not needed */
435                 attitude = "";
436         }
437         else if (is_pet(m_ptr))
438         {
439                 attitude = _(", ペット", ", pet");
440         }
441         else if (is_friendly(m_ptr))
442         {
443                 attitude = _(", 友好的", ", friendly");
444         }
445         else
446         {
447                 attitude = _("", "");
448         }
449
450         /* Clone monster? */
451         if (m_ptr->smart & SM_CLONED)
452         {
453                 clone = ", clone";
454         }
455         else
456         {
457                 clone = "";
458         }
459
460         /* Display monster's level --- idea borrowed from ToME */
461         if (ap_r_ptr->r_tkills && !(m_ptr->mflag2 & MFLAG2_KAGE))
462         {
463                 return format(_("レベル%d, %s%s%s", "Level %d, %s%s%s"), ap_r_ptr->level, desc, attitude, clone);
464         }
465         else 
466         {
467                 return format(_("レベル???, %s%s%s", "Level ???, %s%s%s"), desc, attitude, clone);
468         }
469
470 }
471
472
473
474 /*** Targeting Code ***/
475
476
477 /*
478  * Determine is a monster makes a reasonable target
479  *
480  * The concept of "targeting" was stolen from "Morgul" (?)
481  *
482  * The player can target any location, or any "target-able" monster.
483  *
484  * Currently, a monster is "target_able" if it is visible, and if
485  * the player can hit it with a projection, and the player is not
486  * hallucinating.  This allows use of "use closest target" macros.
487  *
488  * Future versions may restrict the ability to target "trappers"
489  * and "mimics", but the semantics is a little bit weird.
490  */
491 bool target_able(MONSTER_IDX m_idx)
492 {
493         monster_type *m_ptr = &m_list[m_idx];
494
495         /* Monster must be alive */
496         if (!m_ptr->r_idx) return (FALSE);
497
498         /* Hack -- no targeting hallucinations */
499         if (p_ptr->image) return (FALSE);
500
501         /* Monster must be visible */
502         if (!m_ptr->ml) return (FALSE);
503
504         if (p_ptr->riding && (p_ptr->riding == m_idx)) return (TRUE);
505
506         /* Monster must be projectable */
507         if (!projectable(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx)) return (FALSE);
508
509         /* Hack -- Never target trappers */
510         /* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */
511
512         /* Assume okay */
513         return (TRUE);
514 }
515
516
517
518
519 /*
520  * Update (if necessary) and verify (if possible) the target.
521  *
522  * We return TRUE if the target is "okay" and FALSE otherwise.
523  */
524 bool target_okay(void)
525 {
526         /* Accept stationary targets */
527         if (target_who < 0) return (TRUE);
528
529         /* Check moving targets */
530         if (target_who > 0)
531         {
532                 /* Accept reasonable targets */
533                 if (target_able(target_who))
534                 {
535                         monster_type *m_ptr = &m_list[target_who];
536
537                         /* Acquire monster location */
538                         target_row = m_ptr->fy;
539                         target_col = m_ptr->fx;
540
541                         /* Good target */
542                         return (TRUE);
543                 }
544         }
545
546         /* Assume no target */
547         return (FALSE);
548 }
549
550
551 /*
552  * Sorting hook -- comp function -- by "distance to player"
553  *
554  * We use "u" and "v" to point to arrays of "x" and "y" positions,
555  * and sort the arrays by double-distance to the player.
556  */
557 static bool ang_sort_comp_distance(vptr u, vptr v, int a, int b)
558 {
559         POSITION *x = (POSITION*)(u);
560         POSITION *y = (POSITION*)(v);
561
562         POSITION da, db, kx, ky;
563
564         /* Absolute distance components */
565         kx = x[a]; kx -= p_ptr->x; kx = ABS(kx);
566         ky = y[a]; ky -= p_ptr->y; ky = ABS(ky);
567
568         /* Approximate Double Distance to the first point */
569         da = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
570
571         /* Absolute distance components */
572         kx = x[b]; kx -= p_ptr->x; kx = ABS(kx);
573         ky = y[b]; ky -= p_ptr->y; ky = ABS(ky);
574
575         /* Approximate Double Distance to the first point */
576         db = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
577
578         /* Compare the distances */
579         return (da <= db);
580 }
581
582
583 /*
584  * Sorting hook -- comp function -- by importance level of grids
585  *
586  * We use "u" and "v" to point to arrays of "x" and "y" positions,
587  * and sort the arrays by level of monster
588  */
589 static bool ang_sort_comp_importance(vptr u, vptr v, int a, int b)
590 {
591         POSITION *x = (POSITION*)(u);
592         POSITION *y = (POSITION*)(v);
593         cave_type *ca_ptr = &cave[y[a]][x[a]];
594         cave_type *cb_ptr = &cave[y[b]][x[b]];
595         monster_type *ma_ptr = &m_list[ca_ptr->m_idx];
596         monster_type *mb_ptr = &m_list[cb_ptr->m_idx];
597         monster_race *ap_ra_ptr, *ap_rb_ptr;
598
599         /* The player grid */
600         if (y[a] == p_ptr->y && x[a] == p_ptr->x) return TRUE;
601         if (y[b] == p_ptr->y && x[b] == p_ptr->x) return FALSE;
602
603         /* Extract monster race */
604         if (ca_ptr->m_idx && ma_ptr->ml) ap_ra_ptr = &r_info[ma_ptr->ap_r_idx];
605         else ap_ra_ptr = NULL;
606         if (cb_ptr->m_idx && mb_ptr->ml) ap_rb_ptr = &r_info[mb_ptr->ap_r_idx];
607         else ap_rb_ptr = NULL;
608
609         if (ap_ra_ptr && !ap_rb_ptr) return TRUE;
610         if (!ap_ra_ptr && ap_rb_ptr) return FALSE;
611
612         /* Compare two monsters */
613         if (ap_ra_ptr && ap_rb_ptr)
614         {
615                 /* Unique monsters first */
616                 if ((ap_ra_ptr->flags1 & RF1_UNIQUE) && !(ap_rb_ptr->flags1 & RF1_UNIQUE)) return TRUE;
617                 if (!(ap_ra_ptr->flags1 & RF1_UNIQUE) && (ap_rb_ptr->flags1 & RF1_UNIQUE)) return FALSE;
618
619                 /* Shadowers first (あやしい影) */
620                 if ((ma_ptr->mflag2 & MFLAG2_KAGE) && !(mb_ptr->mflag2 & MFLAG2_KAGE)) return TRUE;
621                 if (!(ma_ptr->mflag2 & MFLAG2_KAGE) && (mb_ptr->mflag2 & MFLAG2_KAGE)) return FALSE;
622
623                 /* Unknown monsters first */
624                 if (!ap_ra_ptr->r_tkills && ap_rb_ptr->r_tkills) return TRUE;
625                 if (ap_ra_ptr->r_tkills && !ap_rb_ptr->r_tkills) return FALSE;
626
627                 /* Higher level monsters first (if known) */
628                 if (ap_ra_ptr->r_tkills && ap_rb_ptr->r_tkills)
629                 {
630                         if (ap_ra_ptr->level > ap_rb_ptr->level) return TRUE;
631                         if (ap_ra_ptr->level < ap_rb_ptr->level) return FALSE;
632                 }
633
634                 /* Sort by index if all conditions are same */
635                 if (ma_ptr->ap_r_idx > mb_ptr->ap_r_idx) return TRUE;
636                 if (ma_ptr->ap_r_idx < mb_ptr->ap_r_idx) return FALSE;
637         }
638
639         /* An object get higher priority */
640         if (cave[y[a]][x[a]].o_idx && !cave[y[b]][x[b]].o_idx) return TRUE;
641         if (!cave[y[a]][x[a]].o_idx && cave[y[b]][x[b]].o_idx) return FALSE;
642
643         /* Priority from the terrain */
644         if (f_info[ca_ptr->feat].priority > f_info[cb_ptr->feat].priority) return TRUE;
645         if (f_info[ca_ptr->feat].priority < f_info[cb_ptr->feat].priority) return FALSE;
646
647         /* If all conditions are same, compare distance */
648         return ang_sort_comp_distance(u, v, a, b);
649 }
650
651
652 /*
653  * Sorting hook -- swap function -- by "distance to player"
654  *
655  * We use "u" and "v" to point to arrays of "x" and "y" positions,
656  * and sort the arrays by distance to the player.
657  */
658 static void ang_sort_swap_distance(vptr u, vptr v, int a, int b)
659 {
660         POSITION *x = (POSITION*)(u);
661         POSITION *y = (POSITION*)(v);
662
663         POSITION temp;
664
665         /* Swap "x" */
666         temp = x[a];
667         x[a] = x[b];
668         x[b] = temp;
669
670         /* Swap "y" */
671         temp = y[a];
672         y[a] = y[b];
673         y[b] = temp;
674 }
675
676
677
678 /*
679  * Hack -- help "select" a location (see below)
680  */
681 static POSITION_IDX target_pick(POSITION y1, POSITION x1, POSITION dy, POSITION dx)
682 {
683         POSITION_IDX i, v;
684         POSITION x2, y2, x3, y3, x4, y4;
685         POSITION_IDX b_i = -1, b_v = 9999;
686
687
688         /* Scan the locations */
689         for (i = 0; i < temp_n; i++)
690         {
691                 /* Point 2 */
692                 x2 = temp_x[i];
693                 y2 = temp_y[i];
694
695                 /* Directed distance */
696                 x3 = (x2 - x1);
697                 y3 = (y2 - y1);
698
699                 /* Verify quadrant */
700                 if (dx && (x3 * dx <= 0)) continue;
701                 if (dy && (y3 * dy <= 0)) continue;
702
703                 /* Absolute distance */
704                 x4 = ABS(x3);
705                 y4 = ABS(y3);
706
707                 /* Verify quadrant */
708                 if (dy && !dx && (x4 > y4)) continue;
709                 if (dx && !dy && (y4 > x4)) continue;
710
711                 /* Approximate Double Distance */
712                 v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4));
713
714                 /* Penalize location */
715
716                 /* Track best */
717                 if ((b_i >= 0) && (v >= b_v)) continue;
718
719                 /* Track best */
720                 b_i = i; b_v = v;
721         }
722         return (b_i);
723 }
724
725
726 /*
727  * Hack -- determine if a given location is "interesting"
728  */
729 static bool target_set_accept(POSITION y, POSITION x)
730 {
731         cave_type *c_ptr;
732         OBJECT_IDX this_o_idx, next_o_idx = 0;
733
734         /* Bounds */
735         if (!(in_bounds(y, x))) return (FALSE);
736
737         /* Player grid is always interesting */
738         if (player_bold(y, x)) return (TRUE);
739
740         /* Handle hallucination */
741         if (p_ptr->image) return (FALSE);
742
743         /* Examine the grid */
744         c_ptr = &cave[y][x];
745
746         /* Visible monsters */
747         if (c_ptr->m_idx)
748         {
749                 monster_type *m_ptr = &m_list[c_ptr->m_idx];
750
751                 /* Visible monsters */
752                 if (m_ptr->ml) return (TRUE);
753         }
754
755         /* Scan all objects in the grid */
756         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
757         {
758                 object_type *o_ptr;
759                 o_ptr = &o_list[this_o_idx];
760
761                 /* Acquire next object */
762                 next_o_idx = o_ptr->next_o_idx;
763
764                 /* Memorized object */
765                 if (o_ptr->marked & OM_FOUND) return (TRUE);
766         }
767
768         /* Interesting memorized features */
769         if (c_ptr->info & (CAVE_MARK))
770         {
771                 /* Notice object features */
772                 if (c_ptr->info & CAVE_OBJECT) return (TRUE);
773
774                 /* Feature code (applying "mimic" field) */
775                 if (have_flag(f_info[get_feat_mimic(c_ptr)].flags, FF_NOTICE)) return TRUE;
776         }
777
778         return (FALSE);
779 }
780
781
782 /*
783  * Prepare the "temp" array for "target_set"
784  *
785  * Return the number of target_able monsters in the set.
786  */
787 static void target_set_prepare(BIT_FLAGS mode)
788 {
789         POSITION y, x;
790         POSITION min_hgt, max_hgt, min_wid, max_wid;
791
792         if (mode & TARGET_KILL)
793         {
794                 /* Inner range */
795                 min_hgt = MAX((p_ptr->y - MAX_RANGE), 0);
796                 max_hgt = MIN((p_ptr->y + MAX_RANGE), cur_hgt - 1);
797                 min_wid = MAX((p_ptr->x - MAX_RANGE), 0);
798                 max_wid = MIN((p_ptr->x + MAX_RANGE), cur_wid - 1);
799         }
800         else /* not targetting */
801         {
802                 /* Inner panel */
803                 min_hgt = panel_row_min;
804                 max_hgt = panel_row_max;
805                 min_wid = panel_col_min;
806                 max_wid = panel_col_max;
807         }
808
809         /* Reset "temp" array */
810         temp_n = 0;
811
812         /* Scan the current panel */
813         for (y = min_hgt; y <= max_hgt; y++)
814         {
815                 for (x = min_wid; x <= max_wid; x++)
816                 {
817                         cave_type *c_ptr;
818
819                         /* Require "interesting" contents */
820                         if (!target_set_accept(y, x)) continue;
821
822                         c_ptr = &cave[y][x];
823
824                         /* Require target_able monsters for "TARGET_KILL" */
825                         if ((mode & (TARGET_KILL)) && !target_able(c_ptr->m_idx)) continue;
826
827                         if ((mode & (TARGET_KILL)) && !target_pet && is_pet(&m_list[c_ptr->m_idx])) continue;
828
829                         /* Save the location */
830                         temp_x[temp_n] = x;
831                         temp_y[temp_n] = y;
832                         temp_n++;
833                 }
834         }
835
836         /* Set the sort hooks */
837         if (mode & (TARGET_KILL))
838         {
839                 /* Target the nearest monster for shooting */
840                 ang_sort_comp = ang_sort_comp_distance;
841                 ang_sort_swap = ang_sort_swap_distance;
842         }
843         else
844         {
845                 /* Look important grids first in Look command */
846                 ang_sort_comp = ang_sort_comp_importance;
847                 ang_sort_swap = ang_sort_swap_distance;
848         }
849
850         /* Sort the positions */
851         ang_sort(temp_x, temp_y, temp_n);
852
853         if (p_ptr->riding && target_pet && (temp_n > 1) && (mode & (TARGET_KILL)))
854         {
855                 POSITION tmp;
856
857                 tmp = temp_y[0];
858                 temp_y[0] = temp_y[1];
859                 temp_y[1] = tmp;
860                 tmp = temp_x[0];
861                 temp_x[0] = temp_x[1];
862                 temp_x[1] = tmp;
863         }
864 }
865
866 void target_set_prepare_look(void){
867         target_set_prepare(TARGET_LOOK);
868 }
869
870
871 /*
872  * Evaluate number of kill needed to gain level
873  */
874 static void evaluate_monster_exp(char *buf, monster_type *m_ptr)
875 {
876         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
877         u32b num;
878         s32b exp_mon, exp_adv;
879         u32b exp_mon_frac, exp_adv_frac;
880
881         if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->prace == RACE_ANDROID))
882         {
883                 sprintf(buf,"**");
884                 return;
885         }
886         else if (!ap_r_ptr->r_tkills || (m_ptr->mflag2 & MFLAG2_KAGE))
887         {
888                 if (!p_ptr->wizard)
889                 {
890                         sprintf(buf,"??");
891                         return;
892                 }
893         }
894
895
896         /* The monster's experience point (assuming average monster speed) */
897         exp_mon = ap_r_ptr->mexp * ap_r_ptr->level;
898         exp_mon_frac = 0;
899         s64b_div(&exp_mon, &exp_mon_frac, 0, (p_ptr->max_plv + 2));
900
901
902         /* Total experience value for next level */
903         exp_adv = player_exp[p_ptr->lev -1] * p_ptr->expfact;
904         exp_adv_frac = 0;
905         s64b_div(&exp_adv, &exp_adv_frac, 0, 100);
906
907         /* Experience value need to get */
908         s64b_sub(&exp_adv, &exp_adv_frac, p_ptr->exp, p_ptr->exp_frac);
909
910
911         /* You need to kill at least one monster to get any experience */
912         s64b_add(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
913         s64b_sub(&exp_adv, &exp_adv_frac, 0, 1);
914
915         /* Extract number of monsters needed */
916         s64b_div(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
917
918         /* If 999 or more monsters needed, only display "999". */
919         num = MIN(999, exp_adv_frac);
920
921         /* Display the number */
922         sprintf(buf,"%03ld", (long int)num);
923 }
924
925
926 bool show_gold_on_floor = FALSE;
927
928 /*
929  * Examine a grid, return a keypress.
930  *
931  * The "mode" argument contains the "TARGET_LOOK" bit flag, which
932  * indicates that the "space" key should scan through the contents
933  * of the grid, instead of simply returning immediately.  This lets
934  * the "look" command get complete information, without making the
935  * "target" command annoying.
936  *
937  * The "info" argument contains the "commands" which should be shown
938  * inside the "[xxx]" text.  This string must never be empty, or grids
939  * containing monsters will be displayed with an extra comma.
940  *
941  * Note that if a monster is in the grid, we update both the monster
942  * recall info and the health bar info to track that monster.
943  *
944  * Eventually, we may allow multiple objects per grid, or objects
945  * and terrain features in the same grid. 
946  *
947  * This function must handle blindness/hallucination.
948  */
949 static char target_set_aux(POSITION y, POSITION x, BIT_FLAGS mode, concptr info)
950 {
951         cave_type *c_ptr = &cave[y][x];
952         OBJECT_IDX this_o_idx, next_o_idx = 0;
953         concptr s1 = "", s2 = "", s3 = "", x_info = "";
954         bool boring = TRUE;
955         FEAT_IDX feat;
956         feature_type *f_ptr;
957         char query = '\001';
958         char out_val[MAX_NLEN+80];
959         OBJECT_IDX floor_list[23];
960         ITEM_NUMBER floor_num = 0;
961
962         /* Scan all objects in the grid */
963         if (easy_floor)
964         {
965                 floor_num = scan_floor(floor_list, y, x, 0x02);
966
967                 if (floor_num)
968                 {
969                         x_info = _("x物 ", "x,");
970                 }
971         }
972
973         /* Hack -- under the player */
974         if (player_bold(y, x))
975         {
976 #ifdef JP
977                 s1 = "あなたは";
978                 s2 = "の上";
979                 s3 = "にいる";
980 #else
981                 s1 = "You are ";
982                 s2 = "on ";
983 #endif
984         }
985         else
986         {
987                 s1 = _("ターゲット:", "Target:");
988         }
989
990         /* Hack -- hallucination */
991         if (p_ptr->image)
992         {
993                 concptr name = _("何か奇妙な物", "something strange");
994
995                 /* Display a message */
996 #ifdef JP
997                 sprintf(out_val, "%s%s%s%s [%s]", s1, name, s2, s3, info);
998 #else
999                 sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
1000 #endif
1001
1002                 prt(out_val, 0, 0);
1003                 move_cursor_relative(y, x);
1004                 query = inkey();
1005
1006                 /* Stop on everything but "return" */
1007                 if ((query != '\r') && (query != '\n')) return query;
1008
1009                 /* Repeat forever */
1010                 return 0;
1011         }
1012
1013
1014         /* Actual monsters */
1015         if (c_ptr->m_idx && m_list[c_ptr->m_idx].ml)
1016         {
1017                 monster_type *m_ptr = &m_list[c_ptr->m_idx];
1018                 monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1019                 GAME_TEXT m_name[MAX_NLEN];
1020                 bool recall = FALSE;
1021
1022                 /* Not boring */
1023                 boring = FALSE;
1024
1025                 monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE);
1026                 monster_race_track(m_ptr->ap_r_idx);
1027                 health_track(c_ptr->m_idx);
1028                 handle_stuff();
1029
1030                 /* Interact */
1031                 while (1)
1032                 {
1033                         char acount[10];
1034
1035                         /* Recall */
1036                         if (recall)
1037                         {
1038                                 screen_save();
1039
1040                                 /* Recall on screen */
1041                                 screen_roff(m_ptr->ap_r_idx, 0);
1042
1043                                 /* Hack -- Complete the prompt (again) */
1044                                 Term_addstr(-1, TERM_WHITE, format(_("  [r思 %s%s]", "  [r,%s%s]"), x_info, info));
1045
1046                                 /* Command */
1047                                 query = inkey();
1048
1049                                 screen_load();
1050
1051                                 /* Normal commands */
1052                                 if (query != 'r') break;
1053
1054                                 /* Toggle recall */
1055                                 recall = FALSE;
1056
1057                                 /* Cleare recall text and repeat */
1058                                 continue;
1059                         }
1060
1061                         /*** Normal ***/
1062
1063                         /* Describe, and prompt for recall */
1064                         evaluate_monster_exp(acount, m_ptr);
1065
1066 #ifdef JP
1067                         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);
1068 #else
1069                         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);
1070 #endif
1071
1072                         prt(out_val, 0, 0);
1073
1074                         /* Place cursor */
1075                         move_cursor_relative(y, x);
1076
1077                         /* Command */
1078                         query = inkey();
1079
1080                         /* Normal commands */
1081                         if (query != 'r') break;
1082
1083                         /* Toggle recall */
1084                         recall = TRUE;
1085                 }
1086
1087                 /* Always stop at "normal" keys */
1088                 if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x')) return query;
1089
1090                 /* Sometimes stop at "space" key */
1091                 if ((query == ' ') && !(mode & (TARGET_LOOK))) return query;
1092
1093                 /* Change the intro */
1094                 s1 = _("それは", "It is ");
1095
1096                 /* Hack -- take account of gender */
1097                 if (ap_r_ptr->flags1 & (RF1_FEMALE)) s1 = _("彼女は", "She is ");
1098                 else if (ap_r_ptr->flags1 & (RF1_MALE)) s1 = _("彼は", "He is ");
1099
1100                 /* Use a preposition */
1101 #ifdef JP
1102                 s2 = "を";
1103                 s3 = "持っている";
1104 #else
1105                 s2 = "carrying ";
1106 #endif
1107
1108
1109                 /* Scan all objects being carried */
1110                 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
1111                 {
1112                         GAME_TEXT o_name[MAX_NLEN];
1113
1114                         object_type *o_ptr;
1115                         o_ptr = &o_list[this_o_idx];
1116
1117                         /* Acquire next object */
1118                         next_o_idx = o_ptr->next_o_idx;
1119
1120                         /* Obtain an object description */
1121                         object_desc(o_name, o_ptr, 0);
1122
1123 #ifdef JP
1124                         sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
1125 #else
1126                         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
1127 #endif
1128
1129                         prt(out_val, 0, 0);
1130                         move_cursor_relative(y, x);
1131                         query = inkey();
1132
1133                         /* Always stop at "normal" keys */
1134                         if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x')) return query;
1135
1136                         /* Sometimes stop at "space" key */
1137                         if ((query == ' ') && !(mode & (TARGET_LOOK))) return query;
1138
1139                         /* Change the intro */
1140                         s2 = _("をまた", "also carrying ");
1141                 }
1142
1143                 /* Use a preposition */
1144 #ifdef JP
1145                 s2 = "の上";
1146                 s3 = "にいる";
1147 #else
1148                 s2 = "on ";
1149 #endif
1150         }
1151
1152         if (floor_num)
1153         {
1154                 int min_width = 0;
1155
1156                 while (1)
1157                 {
1158                         if (floor_num == 1)
1159                         {
1160                                 GAME_TEXT o_name[MAX_NLEN];
1161
1162                                 object_type *o_ptr;
1163                                 o_ptr = &o_list[floor_list[0]];
1164
1165                                 object_desc(o_name, o_ptr, 0);
1166
1167 #ifdef JP
1168                                 sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
1169 #else
1170                                 sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
1171 #endif
1172
1173                                 prt(out_val, 0, 0);
1174                                 move_cursor_relative(y, x);
1175
1176                                 /* Command */
1177                                 query = inkey();
1178
1179                                 /* End this grid */
1180                                 return query;
1181                         }
1182
1183                         /* Provide one cushion before item listing  */
1184                         if (boring)
1185                         {
1186                                 /* Display rough information about items */
1187 #ifdef JP
1188                                 sprintf(out_val, "%s %d個のアイテム%s%s ['x'で一覧, %s]", s1, (int)floor_num, s2, s3, info);
1189 #else
1190                                 sprintf(out_val, "%s%s%sa pile of %d items [x,%s]", s1, s2, s3, (int)floor_num, info);
1191 #endif
1192
1193                                 prt(out_val, 0, 0);
1194                                 move_cursor_relative(y, x);
1195
1196                                 /* Command */
1197                                 query = inkey();
1198
1199                                 /* No request for listing */
1200                                 if (query != 'x' && query != ' ') return query;
1201                         }
1202
1203
1204                         /** Display list of items **/
1205
1206                         /* Continue scrolling list if requested */
1207                         while (1)
1208                         {
1209                                 int i;
1210                                 OBJECT_IDX o_idx;
1211                                 screen_save();
1212
1213                                 /* Display */
1214                                 show_gold_on_floor = TRUE;
1215                                 (void)show_floor(0, y, x, &min_width);
1216                                 show_gold_on_floor = FALSE;
1217
1218                                 /* Prompt */
1219 #ifdef JP
1220                                 sprintf(out_val, "%s %d個のアイテム%s%s [Enterで次へ, %s]", s1, (int)floor_num, s2, s3, info);
1221 #else
1222                                 sprintf(out_val, "%s%s%sa pile of %d items [Enter,%s]", s1, s2, s3, (int)floor_num, info);
1223 #endif
1224                                 prt(out_val, 0, 0);
1225
1226                                 query = inkey();
1227                                 screen_load();
1228
1229                                 /* Exit unless 'Enter' */
1230                                 if (query != '\n' && query != '\r')
1231                                 {
1232                                         return query;
1233                                 }
1234
1235                                 /* Get the object being moved. */
1236                                 o_idx = c_ptr->o_idx;
1237  
1238                                 /* Only rotate a pile of two or more objects. */
1239                                 if (!(o_idx && o_list[o_idx].next_o_idx)) continue;
1240
1241                                 /* Remove the first object from the list. */
1242                                 excise_object_idx(o_idx);
1243
1244                                 /* Find end of the list. */
1245                                 i = c_ptr->o_idx;
1246                                 while (o_list[i].next_o_idx)
1247                                         i = o_list[i].next_o_idx;
1248
1249                                 /* Add after the last object. */
1250                                 o_list[i].next_o_idx = o_idx;
1251
1252                                 /* Loop and re-display the list */
1253                         }
1254                 }
1255
1256                 /* NOTREACHED */
1257         }
1258
1259         /* Scan all objects in the grid */
1260         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1261         {
1262                 object_type *o_ptr;
1263                 o_ptr = &o_list[this_o_idx];
1264
1265                 /* Acquire next object */
1266                 next_o_idx = o_ptr->next_o_idx;
1267
1268                 if (o_ptr->marked & OM_FOUND)
1269                 {
1270                         GAME_TEXT o_name[MAX_NLEN];
1271
1272                         /* Not boring */
1273                         boring = FALSE;
1274
1275                         /* Obtain an object description */
1276                         object_desc(o_name, o_ptr, 0);
1277
1278 #ifdef JP
1279                         sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
1280 #else
1281                         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
1282 #endif
1283
1284                         prt(out_val, 0, 0);
1285                         move_cursor_relative(y, x);
1286                         query = inkey();
1287
1288                         /* Always stop at "normal" keys */
1289                         if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x')) return query;
1290
1291                         /* Sometimes stop at "space" key */
1292                         if ((query == ' ') && !(mode & TARGET_LOOK)) return query;
1293
1294                         /* Change the intro */
1295                         s1 = _("それは", "It is ");
1296
1297                         /* Plurals */
1298                         if (o_ptr->number != 1) s1 = _("それらは", "They are ");
1299
1300                         /* Preposition */
1301 #ifdef JP
1302                         s2 = "の上";
1303                         s3 = "に見える";
1304 #else
1305                         s2 = "on ";
1306 #endif
1307
1308                 }
1309         }
1310
1311
1312         /* Feature code (applying "mimic" field) */
1313         feat = get_feat_mimic(c_ptr);
1314
1315         /* Require knowledge about grid, or ability to see grid */
1316         if (!(c_ptr->info & CAVE_MARK) && !player_can_see_bold(y, x))
1317         {
1318                 /* Forget feature */
1319                 feat = feat_none;
1320         }
1321
1322         f_ptr = &f_info[feat];
1323
1324         /* Terrain feature if needed */
1325         if (boring || have_flag(f_ptr->flags, FF_REMEMBER))
1326         {
1327                 concptr name;
1328
1329                 /* Hack -- special handling for quest entrances */
1330                 if (have_flag(f_ptr->flags, FF_QUEST_ENTER))
1331                 {
1332                         /* Set the quest number temporary */
1333                         IDX old_quest = p_ptr->inside_quest;
1334                         int j;
1335
1336                         /* Clear the text */
1337                         for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
1338                         quest_text_line = 0;
1339
1340                         p_ptr->inside_quest = c_ptr->special;
1341
1342                         /* Get the quest text */
1343                         init_flags = INIT_NAME_ONLY;
1344
1345                         process_dungeon_file("q_info.txt", 0, 0, 0, 0);
1346
1347                         name = format(_("クエスト「%s」(%d階相当)", "the entrance to the quest '%s'(level %d)"), 
1348                                                 quest[c_ptr->special].name, quest[c_ptr->special].level);
1349
1350                         /* Reset the old quest number */
1351                         p_ptr->inside_quest = old_quest;
1352                 }
1353
1354                 /* Hack -- special handling for building doors */
1355                 else if (have_flag(f_ptr->flags, FF_BLDG) && !p_ptr->inside_arena)
1356                 {
1357                         name = building[f_ptr->subtype].name;
1358                 }
1359                 else if (have_flag(f_ptr->flags, FF_ENTRANCE))
1360                 {
1361                         name = format(_("%s(%d階相当)", "%s(level %d)"), d_text + d_info[c_ptr->special].text, d_info[c_ptr->special].mindepth);
1362                 }
1363                 else if (have_flag(f_ptr->flags, FF_TOWN))
1364                 {
1365                         name = town_info[c_ptr->special].name;
1366                 }
1367                 else if (p_ptr->wild_mode && (feat == feat_floor))
1368                 {
1369                         name = _("道", "road");
1370                 }
1371                 else
1372                 {
1373                         name = f_name + f_ptr->name;
1374                 }
1375
1376
1377                 /* Pick a prefix */
1378                 if (*s2 &&
1379                     ((!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) ||
1380                      (!have_flag(f_ptr->flags, FF_LOS) && !have_flag(f_ptr->flags, FF_TREE)) ||
1381                      have_flag(f_ptr->flags, FF_TOWN)))
1382                 {
1383                         s2 = _("の中", "in ");
1384                 }
1385
1386                 /* Hack -- special introduction for store & building doors -KMW- */
1387                 if (have_flag(f_ptr->flags, FF_STORE) ||
1388                     have_flag(f_ptr->flags, FF_QUEST_ENTER) ||
1389                     (have_flag(f_ptr->flags, FF_BLDG) && !p_ptr->inside_arena) ||
1390                     have_flag(f_ptr->flags, FF_ENTRANCE))
1391                 {
1392                         s2 = _("の入口", "");
1393                 }
1394 #ifndef JP
1395                 else if (have_flag(f_ptr->flags, FF_FLOOR) ||
1396                          have_flag(f_ptr->flags, FF_TOWN) ||
1397                          have_flag(f_ptr->flags, FF_SHALLOW) ||
1398                          have_flag(f_ptr->flags, FF_DEEP))
1399                 {
1400                         s3 ="";
1401                 }
1402                 else
1403                 {
1404                         /* Pick proper indefinite article */
1405                         s3 = (is_a_vowel(name[0])) ? "an " : "a ";
1406                 }
1407 #endif
1408
1409                 /* Display a message */
1410                 if (p_ptr->wizard)
1411                 {
1412                         char f_idx_str[32];
1413                         if (c_ptr->mimic) sprintf(f_idx_str, "%d/%d", c_ptr->feat, c_ptr->mimic);
1414                         else sprintf(f_idx_str, "%d", c_ptr->feat);
1415 #ifdef JP
1416                         sprintf(out_val, "%s%s%s%s[%s] %x %s %d %d %d (%d,%d) %d", s1, name, s2, s3, info, (unsigned int)c_ptr->info, f_idx_str, c_ptr->dist, c_ptr->cost, c_ptr->when, (int)y, (int)x, travel.cost[y][x]);
1417 #else
1418                         sprintf(out_val, "%s%s%s%s [%s] %x %s %d %d %d (%d,%d)", s1, s2, s3, name, info, c_ptr->info, f_idx_str, c_ptr->dist, c_ptr->cost, c_ptr->when, (int)y, (int)x);
1419 #endif
1420                 }
1421                 else
1422 #ifdef JP
1423                         sprintf(out_val, "%s%s%s%s[%s]", s1, name, s2, s3, info);
1424 #else
1425                         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
1426 #endif
1427
1428                 prt(out_val, 0, 0);
1429                 move_cursor_relative(y, x);
1430                 query = inkey();
1431
1432                 /* Always stop at "normal" keys */
1433                 if ((query != '\r') && (query != '\n') && (query != ' ')) return query;
1434         }
1435
1436         /* Stop on everything but "return" */
1437         if ((query != '\r') && (query != '\n')) return query;
1438
1439         /* Repeat forever */
1440         return 0;
1441 }
1442
1443
1444 /*
1445  * Handle "target" and "look".
1446  *
1447  * Note that this code can be called from "get_aim_dir()".
1448  *
1449  * All locations must be on the current panel.  Consider the use of
1450  * "panel_bounds()" to allow "off-panel" targets, perhaps by using
1451  * some form of "scrolling" the map around the cursor.  
1452  * That is, consider the possibility of "auto-scrolling" the screen
1453  * while the cursor moves around.  This may require changes in the
1454  * "update_monster()" code to allow "visibility" even if off panel, and
1455  * may require dynamic recalculation of the "temp" grid set.
1456  *
1457  * Hack -- targeting/observing an "outer border grid" may induce
1458  * problems, so this is not currently allowed.
1459  *
1460  * The player can use the direction keys to move among "interesting"
1461  * grids in a heuristic manner, or the "space", "+", and "-" keys to
1462  * move through the "interesting" grids in a sequential manner, or
1463  * can enter "location" mode, and use the direction keys to move one
1464  * grid at a time in any direction.  The "t" (set target) command will
1465  * only target a monster (as opposed to a location) if the monster is
1466  * target_able and the "interesting" mode is being used.
1467  *
1468  * The current grid is described using the "look" method above, and
1469  * a new command may be entered at any time, but note that if the
1470  * "TARGET_LOOK" bit flag is set (or if we are in "location" mode,
1471  * where "space" has no obvious meaning) then "space" will scan
1472  * through the description of the current grid until done, instead
1473  * of immediately jumping to the next "interesting" grid.  This
1474  * allows the "target" command to retain its old semantics.
1475  *
1476  * The "*", "+", and "-" keys may always be used to jump immediately
1477  * to the next (or previous) interesting grid, in the proper mode.
1478  *
1479  * The "return" key may always be used to scan through a complete
1480  * grid description (forever).
1481  *
1482  * This command will cancel any old target, even if used from
1483  * inside the "look" command.
1484  */
1485 bool target_set(BIT_FLAGS mode)
1486 {
1487         int i, d, m, t, bd;
1488         POSITION y = p_ptr->y;
1489         POSITION x = p_ptr->x;
1490
1491         bool done = FALSE;
1492         bool flag = TRUE;
1493         char query;
1494         char info[80];
1495         char same_key;
1496         cave_type *c_ptr;
1497         TERM_LEN wid, hgt;
1498         
1499         get_screen_size(&wid, &hgt);
1500
1501         /* Cancel target */
1502         target_who = 0;
1503
1504         if (rogue_like_commands)
1505         {
1506                 same_key = 'x';
1507         }
1508         else
1509         {
1510                 same_key = 'l';
1511         }
1512
1513         /* Prepare the "temp" array */
1514         target_set_prepare(mode);
1515
1516         /* Start near the player */
1517         m = 0;
1518
1519         /* Interact */
1520         while (!done)
1521         {
1522                 /* Interesting grids */
1523                 if (flag && temp_n)
1524                 {
1525                         y = temp_y[m];
1526                         x = temp_x[m];
1527
1528                         /* Set forcus */
1529                         change_panel_xy(y, x);
1530
1531                         if (!(mode & TARGET_LOOK)) prt_path(y, x);
1532
1533                         /* Access */
1534                         c_ptr = &cave[y][x];
1535
1536                         /* Allow target */
1537                         if (target_able(c_ptr->m_idx))
1538                         {
1539                                 strcpy(info, _("q止 t決 p自 o現 +次 -前", "q,t,p,o,+,-,<dir>"));
1540                         }
1541
1542                         /* Dis-allow target */
1543                         else
1544                         {
1545                                 strcpy(info, _("q止 p自 o現 +次 -前", "q,p,o,+,-,<dir>"));
1546                         }
1547
1548                         if (cheat_sight)
1549                         {
1550                                 char cheatinfo[30];
1551                                 sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d",
1552                                         los(p_ptr->y, p_ptr->x, y, x), projectable(p_ptr->y, p_ptr->x, y, x));
1553                                 strcat(info, cheatinfo);
1554                         }
1555                         
1556                         /* Describe and Prompt */
1557                         while (TRUE){
1558                                 query = target_set_aux(y, x, mode, info);
1559                                 if(query)break;
1560                         }
1561
1562                         /* Assume no "direction" */
1563                         d = 0;
1564
1565                         if (use_menu)
1566                         {
1567                                 if (query == '\r') query = 't';
1568                         }  
1569
1570                         /* Analyze */
1571                         switch (query)
1572                         {
1573                                 case ESCAPE:
1574                                 case 'q':
1575                                 {
1576                                         done = TRUE;
1577                                         break;
1578                                 }
1579
1580                                 case 't':
1581                                 case '.':
1582                                 case '5':
1583                                 case '0':
1584                                 {
1585                                         if (target_able(c_ptr->m_idx))
1586                                         {
1587                                                 health_track(c_ptr->m_idx);
1588                                                 target_who = c_ptr->m_idx;
1589                                                 target_row = y;
1590                                                 target_col = x;
1591                                                 done = TRUE;
1592                                         }
1593                                         else
1594                                         {
1595                                                 bell();
1596                                         }
1597                                         break;
1598                                 }
1599
1600                                 case ' ':
1601                                 case '*':
1602                                 case '+':
1603                                 {
1604                                         if (++m == temp_n)
1605                                         {
1606                                                 m = 0;
1607                                                 if (!expand_list) done = TRUE;
1608                                         }
1609                                         break;
1610                                 }
1611
1612                                 case '-':
1613                                 {
1614                                         if (m-- == 0)
1615                                         {
1616                                                 m = temp_n - 1;
1617                                                 if (!expand_list) done = TRUE;
1618                                         }
1619                                         break;
1620                                 }
1621
1622                                 case 'p':
1623                                 {
1624                                         /* Recenter the map around the player */
1625                                         verify_panel();
1626                                         p_ptr->update |= (PU_MONSTERS);
1627                                         p_ptr->redraw |= (PR_MAP);
1628                                         p_ptr->window |= (PW_OVERHEAD);
1629                                         handle_stuff();
1630
1631                                         /* Recalculate interesting grids */
1632                                         target_set_prepare(mode);
1633
1634                                         y = p_ptr->y;
1635                                         x = p_ptr->x;
1636                                 }
1637
1638                                 case 'o':
1639                                 {
1640                                         flag = FALSE;
1641                                         break;
1642                                 }
1643
1644                                 case 'm':
1645                                 {
1646                                         break;
1647                                 }
1648
1649                                 default:
1650                                 {
1651                                         if(query == same_key)
1652                                         {
1653                                                 if (++m == temp_n)
1654                                                 {
1655                                                         m = 0;
1656                                                         if (!expand_list) done = TRUE;
1657                                                 }
1658                                         }
1659                                         else
1660                                         {
1661                                                 /* Extract the action (if any) */
1662                                                 d = get_keymap_dir(query);
1663
1664                                                 if (!d) bell();
1665                                                 break;
1666                                         }
1667                                 }
1668                         }
1669                         /* Hack -- move around */
1670                         if (d)
1671                         {
1672                                 /* Modified to scroll to monster */
1673                                 POSITION y2 = panel_row_min;
1674                                 POSITION x2 = panel_col_min;
1675
1676                                 /* Find a new monster */
1677                                 i = target_pick(temp_y[m], temp_x[m], ddy[d], ddx[d]);
1678
1679                                 /* Request to target past last interesting grid */
1680                                 while (flag && (i < 0))
1681                                 {
1682                                         /* Note the change */
1683                                         if (change_panel(ddy[d], ddx[d]))
1684                                         {
1685                                                 int v = temp_y[m];
1686                                                 int u = temp_x[m];
1687
1688                                                 /* Recalculate interesting grids */
1689                                                 target_set_prepare(mode);
1690
1691                                                 /* Look at interesting grids */
1692                                                 flag = TRUE;
1693
1694                                                 /* Find a new monster */
1695                                                 i = target_pick(v, u, ddy[d], ddx[d]);
1696
1697                                                 /* Use that grid */
1698                                                 if (i >= 0) m = i;
1699                                         }
1700
1701                                         /* Nothing interesting */
1702                                         else
1703                                         {
1704                                                 POSITION dx = ddx[d];
1705                                                 POSITION dy = ddy[d];
1706
1707                                                 /* Restore previous position */
1708                                                 panel_row_min = y2;
1709                                                 panel_col_min = x2;
1710                                                 panel_bounds_center();
1711
1712                                                 p_ptr->update |= (PU_MONSTERS);
1713                                                 p_ptr->redraw |= (PR_MAP);
1714                                                 p_ptr->window |= (PW_OVERHEAD);
1715                                                 handle_stuff();
1716
1717                                                 /* Recalculate interesting grids */
1718                                                 target_set_prepare(mode);
1719
1720                                                 /* Look at boring grids */
1721                                                 flag = FALSE;
1722
1723                                                 /* Move */
1724                                                 x += dx;
1725                                                 y += dy;
1726
1727                                                 /* Do not move horizontally if unnecessary */
1728                                                 if (((x < panel_col_min + wid / 2) && (dx > 0)) ||
1729                                                          ((x > panel_col_min + wid / 2) && (dx < 0)))
1730                                                 {
1731                                                         dx = 0;
1732                                                 }
1733
1734                                                 /* Do not move vertically if unnecessary */
1735                                                 if (((y < panel_row_min + hgt / 2) && (dy > 0)) ||
1736                                                          ((y > panel_row_min + hgt / 2) && (dy < 0)))
1737                                                 {
1738                                                         dy = 0;
1739                                                 }
1740
1741                                                 /* Apply the motion */
1742                                                 if ((y >= panel_row_min+hgt) || (y < panel_row_min) ||
1743                                                     (x >= panel_col_min+wid) || (x < panel_col_min))
1744                                                 {
1745                                                         if (change_panel(dy, dx)) target_set_prepare(mode);
1746                                                 }
1747
1748                                                 /* Slide into legality */
1749                                                 if (x >= cur_wid-1) x = cur_wid - 2;
1750                                                 else if (x <= 0) x = 1;
1751
1752                                                 /* Slide into legality */
1753                                                 if (y >= cur_hgt-1) y = cur_hgt- 2;
1754                                                 else if (y <= 0) y = 1;
1755                                         }
1756                                 }
1757
1758                                 /* Use that grid */
1759                                 m = i;
1760                         }
1761                 }
1762
1763                 /* Arbitrary grids */
1764                 else
1765                 {
1766                         bool move_fast = FALSE;
1767
1768                         if (!(mode & TARGET_LOOK)) prt_path(y, x);
1769
1770                         /* Access */
1771                         c_ptr = &cave[y][x];
1772
1773                         /* Default prompt */
1774                         strcpy(info, _("q止 t決 p自 m近 +次 -前", "q,t,p,m,+,-,<dir>"));
1775
1776                         if (cheat_sight)
1777                         {
1778                                 char cheatinfo[30];
1779                                 sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d",
1780                                         los(p_ptr->y, p_ptr->x, y, x),
1781                                         projectable(p_ptr->y, p_ptr->x, y, x));
1782                                 strcat(info, cheatinfo);
1783                         }
1784
1785                         /* Describe and Prompt (enable "TARGET_LOOK") */
1786                         while ((query = target_set_aux(y, x, mode | TARGET_LOOK, info)) == 0);
1787
1788                         /* Assume no direction */
1789                         d = 0;
1790
1791                         if (use_menu)
1792                         {
1793                                 if (query == '\r') query = 't';
1794                         }  
1795
1796                         /* Analyze the keypress */
1797                         switch (query)
1798                         {
1799                                 case ESCAPE:
1800                                 case 'q':
1801                                 {
1802                                         done = TRUE;
1803                                         break;
1804                                 }
1805
1806                                 case 't':
1807                                 case '.':
1808                                 case '5':
1809                                 case '0':
1810                                 {
1811                                         target_who = -1;
1812                                         target_row = y;
1813                                         target_col = x;
1814                                         done = TRUE;
1815                                         break;
1816                                 }
1817
1818                                 case 'p':
1819                                 {
1820                                         /* Recenter the map around the player */
1821                                         verify_panel();
1822                                         p_ptr->update |= (PU_MONSTERS);
1823                                         p_ptr->redraw |= (PR_MAP);
1824                                         p_ptr->window |= (PW_OVERHEAD);
1825                                         handle_stuff();
1826
1827                                         /* Recalculate interesting grids */
1828                                         target_set_prepare(mode);
1829
1830                                         y = p_ptr->y;
1831                                         x = p_ptr->x;
1832                                 }
1833
1834                                 case 'o':
1835                                 {
1836                                         break;
1837                                 }
1838
1839                                 case ' ':
1840                                 case '*':
1841                                 case '+':
1842                                 case '-':
1843                                 case 'm':
1844                                 {
1845                                         flag = TRUE;
1846
1847                                         m = 0;
1848                                         bd = 999;
1849
1850                                         /* Pick a nearby monster */
1851                                         for (i = 0; i < temp_n; i++)
1852                                         {
1853                                                 t = distance(y, x, temp_y[i], temp_x[i]);
1854
1855                                                 /* Pick closest */
1856                                                 if (t < bd)
1857                                                 {
1858                                                         m = i;
1859                                                         bd = t;
1860                                                 }
1861                                         }
1862
1863                                         /* Nothing interesting */
1864                                         if (bd == 999) flag = FALSE;
1865
1866                                         break;
1867                                 }
1868
1869                                 default:
1870                                 {
1871                                         /* Extract the action (if any) */
1872                                         d = get_keymap_dir(query);
1873
1874                                         /* XTRA HACK MOVEFAST */
1875                                         if (isupper(query)) move_fast = TRUE;
1876
1877                                         if (!d) bell();
1878                                         break;
1879                                 }
1880                         }
1881
1882                         /* Handle "direction" */
1883                         if (d)
1884                         {
1885                                 POSITION dx = ddx[d];
1886                                 POSITION dy = ddy[d];
1887
1888                                 /* XTRA HACK MOVEFAST */
1889                                 if (move_fast)
1890                                 {
1891                                         int mag = MIN(wid / 2, hgt / 2);
1892                                         x += dx * mag;
1893                                         y += dy * mag;
1894                                 }
1895                                 else
1896                                 {
1897                                         x += dx;
1898                                         y += dy;
1899                                 }
1900
1901                                 /* Do not move horizontally if unnecessary */
1902                                 if (((x < panel_col_min + wid / 2) && (dx > 0)) ||
1903                                          ((x > panel_col_min + wid / 2) && (dx < 0)))
1904                                 {
1905                                         dx = 0;
1906                                 }
1907
1908                                 /* Do not move vertically if unnecessary */
1909                                 if (((y < panel_row_min + hgt / 2) && (dy > 0)) ||
1910                                          ((y > panel_row_min + hgt / 2) && (dy < 0)))
1911                                 {
1912                                         dy = 0;
1913                                 }
1914
1915                                 /* Apply the motion */
1916                                 if ((y >= panel_row_min + hgt) || (y < panel_row_min) ||
1917                                          (x >= panel_col_min + wid) || (x < panel_col_min))
1918                                 {
1919                                         if (change_panel(dy, dx)) target_set_prepare(mode);
1920                                 }
1921
1922                                 /* Slide into legality */
1923                                 if (x >= cur_wid-1) x = cur_wid - 2;
1924                                 else if (x <= 0) x = 1;
1925
1926                                 /* Slide into legality */
1927                                 if (y >= cur_hgt-1) y = cur_hgt- 2;
1928                                 else if (y <= 0) y = 1;
1929                         }
1930                 }
1931         }
1932
1933         /* Forget */
1934         temp_n = 0;
1935
1936         /* Clear the top line */
1937         prt("", 0, 0);
1938
1939         /* Recenter the map around the player */
1940         verify_panel();
1941         p_ptr->update |= (PU_MONSTERS);
1942         p_ptr->redraw |= (PR_MAP);
1943         p_ptr->window |= (PW_OVERHEAD);
1944         handle_stuff();
1945
1946         /* Failure to set target */
1947         if (!target_who) return (FALSE);
1948
1949         /* Success */
1950         return (TRUE);
1951 }
1952
1953
1954 /*
1955  * Get an "aiming direction" from the user.
1956  *
1957  * The "dir" is loaded with 1,2,3,4,6,7,8,9 for "actual direction", and
1958  * "0" for "current target", and "-1" for "entry aborted".
1959  *
1960  * Note that "Force Target", if set, will pre-empt user interaction,
1961  * if there is a usable target already set.
1962  *
1963  * Note that confusion over-rides any (explicit?) user choice.
1964  */
1965 bool get_aim_dir(DIRECTION *dp)
1966 {
1967         DIRECTION dir;
1968         char    command;
1969         concptr p;
1970         COMMAND_CODE code;
1971
1972         (*dp) = 0;
1973
1974         /* Global direction */
1975         dir = command_dir;
1976
1977         /* Hack -- auto-target if requested */
1978         if (use_old_target && target_okay()) dir = 5;
1979
1980         if (repeat_pull(&code))
1981         {
1982                 /* Confusion? */
1983
1984                 /* Verify */
1985                 if (!(code == 5 && !target_okay()))
1986                 {
1987 /*                      return (TRUE); */
1988                         dir = (DIRECTION)code;
1989                 }
1990         }
1991         *dp = (DIRECTION)code;
1992
1993         /* Ask until satisfied */
1994         while (!dir)
1995         {
1996                 /* Choose a prompt */
1997                 if (!target_okay())
1998                 {
1999                         p = _("方向 ('*'でターゲット選択, ESCで中断)? ", "Direction ('*' to choose a target, Escape to cancel)? ");
2000                 }
2001                 else
2002                 {
2003                         p = _("方向 ('5'でターゲットへ, '*'でターゲット再選択, ESCで中断)? ", "Direction ('5' for target, '*' to re-target, Escape to cancel)? ");
2004                 }
2005
2006                 /* Get a command (or Cancel) */
2007                 if (!get_com(p, &command, TRUE)) break;
2008
2009                 if (use_menu)
2010                 {
2011                         if (command == '\r') command = 't';
2012                 }  
2013
2014                 /* Convert various keys to "standard" keys */
2015                 switch (command)
2016                 {
2017                         /* Use current target */
2018                         case 'T':
2019                         case 't':
2020                         case '.':
2021                         case '5':
2022                         case '0':
2023                         {
2024                                 dir = 5;
2025                                 break;
2026                         }
2027
2028                         /* Set new target */
2029                         case '*':
2030                         case ' ':
2031                         case '\r':
2032                         {
2033                                 if (target_set(TARGET_KILL)) dir = 5;
2034                                 break;
2035                         }
2036
2037                         default:
2038                         {
2039                                 /* Extract the action (if any) */
2040                                 dir = get_keymap_dir(command);
2041
2042                                 break;
2043                         }
2044                 }
2045
2046                 /* Verify requested targets */
2047                 if ((dir == 5) && !target_okay()) dir = 0;
2048
2049                 /* Error */
2050                 if (!dir) bell();
2051         }
2052
2053         /* No direction */
2054         if (!dir)
2055         {
2056                 project_length = 0; /* reset to default */
2057                 return (FALSE);
2058         }
2059
2060         /* Save the direction */
2061         command_dir = dir;
2062
2063         /* Check for confusion */
2064         if (p_ptr->confused)
2065         {
2066                 /* Random direction */
2067                 dir = ddd[randint0(8)];
2068         }
2069
2070         /* Notice confusion */
2071         if (command_dir != dir)
2072         {
2073                 /* Warn the user */
2074                 msg_print(_("あなたは混乱している。", "You are confused."));
2075         }
2076
2077         /* Save direction */
2078         (*dp) = dir;
2079
2080 /*      repeat_push(dir); */
2081         repeat_push((COMMAND_CODE)command_dir);
2082
2083         /* A "valid" direction was entered */
2084         return (TRUE);
2085 }
2086
2087
2088 bool get_direction(DIRECTION *dp, bool allow_under, bool with_steed)
2089 {
2090         DIRECTION dir;
2091         concptr prompt;
2092         COMMAND_CODE code;
2093
2094         (*dp) = 0;
2095
2096         /* Global direction */
2097         dir = command_dir;
2098
2099         if (repeat_pull(&code))
2100         {
2101                 dir = (DIRECTION)code;
2102                 /*              return (TRUE); */
2103         }
2104         *dp = (DIRECTION)code;
2105
2106         if (allow_under)
2107         {
2108                 prompt = _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ");
2109         }
2110         else
2111         {
2112                 prompt = _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
2113         }
2114
2115         /* Get a direction */
2116         while (!dir)
2117         {
2118                 char ch;
2119
2120                 /* Get a command (or Cancel) */
2121                 if (!get_com(prompt, &ch, TRUE)) break;
2122
2123                 /* Look down */
2124                 if ((allow_under) && ((ch == '5') || (ch == '-') || (ch == '.')))
2125                 {
2126                         dir = 5;
2127                 }
2128                 else
2129                 {
2130                         /* Look up the direction */
2131                         dir = get_keymap_dir(ch);
2132
2133                         if (!dir) bell();
2134                 }
2135         }
2136
2137         /* Prevent weirdness */
2138         if ((dir == 5) && (!allow_under)) dir = 0;
2139
2140         /* Aborted */
2141         if (!dir) return (FALSE);
2142
2143         /* Save desired direction */
2144         command_dir = dir;
2145
2146         /* Apply "confusion" */
2147         if (p_ptr->confused)
2148         {
2149                 /* Standard confusion */
2150                 if (randint0(100) < 75)
2151                 {
2152                         /* Random direction */
2153                         dir = ddd[randint0(8)];
2154                 }
2155         }
2156         else if (p_ptr->riding && with_steed)
2157         {
2158                 monster_type *m_ptr = &m_list[p_ptr->riding];
2159                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
2160
2161                 if (MON_CONFUSED(m_ptr))
2162                 {
2163                         /* Standard confusion */
2164                         if (randint0(100) < 75)
2165                         {
2166                                 /* Random direction */
2167                                 dir = ddd[randint0(8)];
2168                         }
2169                 }
2170                 else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
2171                 {
2172                         /* Random direction */
2173                         dir = ddd[randint0(8)];
2174                 }
2175                 else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
2176                 {
2177                         /* Random direction */
2178                         dir = ddd[randint0(8)];
2179                 }
2180         }
2181
2182         /* Notice confusion */
2183         if (command_dir != dir)
2184         {
2185                 if (p_ptr->confused)
2186                 {
2187                         /* Warn the user */
2188                         msg_print(_("あなたは混乱している。", "You are confused."));
2189                 }
2190                 else
2191                 {
2192                         GAME_TEXT m_name[MAX_NLEN];
2193                         monster_type *m_ptr = &m_list[p_ptr->riding];
2194
2195                         monster_desc(m_name, m_ptr, 0);
2196                         if (MON_CONFUSED(m_ptr))
2197                         {
2198                                 msg_format(_("%sは混乱している。", "%^s is confusing."), m_name);
2199                         }
2200                         else
2201                         {
2202                                 msg_format(_("%sは思い通りに動いてくれない。", "You cannot control %s."), m_name);
2203                         }
2204                 }
2205         }
2206
2207         /* Save direction */
2208         (*dp) = dir;
2209
2210         /*      repeat_push(dir); */
2211         repeat_push((COMMAND_CODE)command_dir);
2212
2213         /* Success */
2214         return (TRUE);
2215 }
2216
2217 /*
2218  * @brief 進行方向を指定する(騎乗対象の混乱の影響を受ける) / Request a "movement" direction (1,2,3,4,6,7,8,9) from the user,
2219  * and place it into "command_dir", unless we already have one.
2220  *
2221  * This function should be used for all "repeatable" commands, such as
2222  * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well
2223  * as all commands which must reference a grid adjacent to the player,
2224  * and which may not reference the grid under the player.  Note that,
2225  * for example, it is no longer possible to "disarm" or "open" chests
2226  * in the same grid as the player.
2227  *
2228  * Direction "5" is illegal and will (cleanly) abort the command.
2229  *
2230  * This function tracks and uses the "global direction", and uses
2231  * that as the "desired direction", to which "confusion" is applied.
2232  */
2233 bool get_rep_dir(DIRECTION *dp, bool under)
2234 {
2235         DIRECTION dir;
2236         concptr prompt;
2237         COMMAND_CODE code;
2238
2239         (*dp) = 0;
2240
2241         /* Global direction */
2242         dir = command_dir;
2243
2244         if (repeat_pull(&code))
2245         {
2246                 dir = (DIRECTION)code;
2247 /*              return (TRUE); */
2248         }
2249         *dp = (DIRECTION)code;
2250
2251         if (under)
2252         {
2253                 prompt = _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ");
2254         }
2255         else
2256         {
2257                 prompt = _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
2258         }
2259         
2260         /* Get a direction */
2261         while (!dir)
2262         {
2263                 char ch;
2264
2265                 /* Get a command (or Cancel) */
2266                 if (!get_com(prompt, &ch, TRUE)) break;
2267
2268                 /* Look down */
2269                 if ((under) && ((ch == '5') || (ch == '-') || (ch == '.')))
2270                 {
2271                         dir = 5;
2272                 }
2273                 else
2274                 {
2275                         /* Look up the direction */
2276                         dir = get_keymap_dir(ch);
2277
2278                         if (!dir) bell();
2279                 }
2280         }
2281
2282         /* Prevent weirdness */
2283         if ((dir == 5) && (!under)) dir = 0;
2284
2285         /* Aborted */
2286         if (!dir) return (FALSE);
2287
2288         /* Save desired direction */
2289         command_dir = dir;
2290
2291         /* Apply "confusion" */
2292         if (p_ptr->confused)
2293         {
2294                 /* Standard confusion */
2295                 if (randint0(100) < 75)
2296                 {
2297                         /* Random direction */
2298                         dir = ddd[randint0(8)];
2299                 }
2300         }
2301         else if (p_ptr->riding)
2302         {
2303                 monster_type *m_ptr = &m_list[p_ptr->riding];
2304                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
2305
2306                 if (MON_CONFUSED(m_ptr))
2307                 {
2308                         /* Standard confusion */
2309                         if (randint0(100) < 75)
2310                         {
2311                                 /* Random direction */
2312                                 dir = ddd[randint0(8)];
2313                         }
2314                 }
2315                 else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
2316                 {
2317                         /* Random direction */
2318                         dir = ddd[randint0(8)];
2319                 }
2320                 else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
2321                 {
2322                         /* Random direction */
2323                         dir = ddd[randint0(8)];
2324                 }
2325         }
2326
2327         /* Notice confusion */
2328         if (command_dir != dir)
2329         {
2330                 if (p_ptr->confused)
2331                 {
2332                         /* Warn the user */
2333                         msg_print(_("あなたは混乱している。", "You are confused."));
2334                 }
2335                 else
2336                 {
2337                         GAME_TEXT m_name[MAX_NLEN];
2338                         monster_type *m_ptr = &m_list[p_ptr->riding];
2339
2340                         monster_desc(m_name, m_ptr, 0);
2341                         if (MON_CONFUSED(m_ptr))
2342                         {
2343                                 msg_format(_("%sは混乱している。", "%^s is confusing."), m_name);
2344                         }
2345                         else
2346                         {
2347                                 msg_format(_("%sは思い通りに動いてくれない。", "You cannot control %s."), m_name);
2348                         }
2349                 }
2350         }
2351
2352         /* Save direction */
2353         (*dp) = dir;
2354
2355 /*      repeat_push(dir); */
2356         repeat_push((COMMAND_CODE)command_dir);
2357
2358         /* Success */
2359         return (TRUE);
2360 }
2361
2362
2363 /*
2364  * XAngband: determine if a given location is "interesting"
2365  * based on target_set_accept function.
2366  */
2367 static bool tgt_pt_accept(POSITION y, POSITION x)
2368 {
2369         cave_type *c_ptr;
2370
2371         /* Bounds */
2372         if (!(in_bounds(y, x))) return (FALSE);
2373
2374         /* Player grid is always interesting */
2375         if ((y == p_ptr->y) && (x == p_ptr->x)) return (TRUE);
2376
2377         /* Handle hallucination */
2378         if (p_ptr->image) return (FALSE);
2379
2380         /* Examine the grid */
2381         c_ptr = &cave[y][x];
2382
2383         /* Interesting memorized features */
2384         if (c_ptr->info & (CAVE_MARK))
2385         {
2386                 /* Notice stairs */
2387                 if (cave_have_flag_grid(c_ptr, FF_LESS)) return (TRUE);
2388                 if (cave_have_flag_grid(c_ptr, FF_MORE)) return (TRUE);
2389
2390                 /* Notice quest features */
2391                 if (cave_have_flag_grid(c_ptr, FF_QUEST_ENTER)) return (TRUE);
2392                 if (cave_have_flag_grid(c_ptr, FF_QUEST_EXIT)) return (TRUE);
2393         }
2394
2395         return (FALSE);
2396 }
2397
2398
2399 /*
2400  * XAngband: Prepare the "temp" array for "tget_pt"
2401  * based on target_set_prepare funciton.
2402  */
2403 static void tgt_pt_prepare(void)
2404 {
2405         POSITION y, x;
2406
2407         /* Reset "temp" array */
2408         temp_n = 0;
2409
2410         if (!expand_list) return;
2411
2412         /* Scan the current panel */
2413         for (y = 1; y < cur_hgt; y++)
2414         {
2415                 for (x = 1; x < cur_wid; x++)
2416                 {
2417                         /* Require "interesting" contents */
2418                         if (!tgt_pt_accept(y, x)) continue;
2419
2420                         /* Save the location */
2421                         temp_x[temp_n] = x;
2422                         temp_y[temp_n] = y;
2423                         temp_n++;
2424                 }
2425         }
2426
2427         /* Target the nearest monster for shooting */
2428         ang_sort_comp = ang_sort_comp_distance;
2429         ang_sort_swap = ang_sort_swap_distance;
2430
2431         /* Sort the positions */
2432         ang_sort(temp_x, temp_y, temp_n);
2433 }
2434
2435 /*
2436  * old -- from PsiAngband.
2437  */
2438 bool tgt_pt(POSITION *x_ptr, POSITION *y_ptr)
2439 {
2440         char ch = 0;
2441         int d, n = 0;
2442         POSITION x, y;
2443         bool success = FALSE;
2444
2445         TERM_LEN wid, hgt;
2446
2447         get_screen_size(&wid, &hgt);
2448
2449         x = p_ptr->x;
2450         y = p_ptr->y;
2451
2452         if (expand_list) 
2453         {
2454                 tgt_pt_prepare();
2455         }
2456
2457         msg_print(_("場所を選んでスペースキーを押して下さい。", "Select a point and press space."));
2458         msg_flag = FALSE; /* prevents "-more-" message. */
2459
2460         while ((ch != ESCAPE) && !success)
2461         {
2462                 bool move_fast = FALSE;
2463
2464                 move_cursor_relative(y, x);
2465                 ch = inkey();
2466                 switch (ch)
2467                 {
2468                 case ESCAPE:
2469                         break;
2470                 case ' ':
2471                 case 't':
2472                 case '.':
2473                 case '5':
2474                 case '0':
2475                         /* illegal place */
2476                         if (player_bold(y, x)) ch = 0;
2477
2478                         /* okay place */
2479                         else success = TRUE;
2480
2481                         break;
2482
2483                 /* XAngband: Move cursor to stairs */
2484                 case '>':
2485                 case '<':
2486                         if (expand_list && temp_n)
2487                         {
2488                                 int dx, dy;
2489                                 int cx = (panel_col_min + panel_col_max) / 2;
2490                                 int cy = (panel_row_min + panel_row_max) / 2;
2491
2492                                 n++;
2493
2494                                 /* Skip stairs which have defferent distance */
2495                                 for (; n < temp_n; ++ n)
2496                                 {
2497                                         cave_type *c_ptr = &cave[temp_y[n]][temp_x[n]];
2498
2499                                         if (cave_have_flag_grid(c_ptr, FF_STAIRS) &&
2500                                             cave_have_flag_grid(c_ptr, ch == '>' ? FF_MORE : FF_LESS))
2501                                         {
2502                                                 /* Found */
2503                                                 break;
2504                                         }
2505                                 }
2506
2507                                 if (n == temp_n)        /* Loop out taget list */
2508                                 {
2509                                         n = 0;
2510                                         y = p_ptr->y;
2511                                         x = p_ptr->x;
2512                                         verify_panel(); /* Move cursor to player */
2513
2514                                         p_ptr->update |= (PU_MONSTERS);
2515
2516                                         p_ptr->redraw |= (PR_MAP);
2517
2518                                         p_ptr->window |= (PW_OVERHEAD);
2519                                         handle_stuff();
2520                                 }
2521                                 else    /* move cursor to next stair and change panel */
2522                                 {
2523                                         y = temp_y[n];
2524                                         x = temp_x[n];
2525
2526                                         dy = 2 * (y - cy) / hgt;
2527                                         dx = 2 * (x - cx) / wid;
2528                                         if (dy || dx) change_panel(dy, dx);
2529                                 }
2530                         }
2531                         break;
2532
2533                 default:
2534                         /* Look up the direction */
2535                         d = get_keymap_dir(ch);
2536
2537                         /* XTRA HACK MOVEFAST */
2538                         if (isupper(ch)) move_fast = TRUE;
2539
2540                         /* Handle "direction" */
2541                         if (d)
2542                         {
2543                                 int dx = ddx[d];
2544                                 int dy = ddy[d];
2545
2546                                 /* XTRA HACK MOVEFAST */
2547                                 if (move_fast)
2548                                 {
2549                                         int mag = MIN(wid / 2, hgt / 2);
2550                                         x += dx * mag;
2551                                         y += dy * mag;
2552                                 }
2553                                 else
2554                                 {
2555                                         x += dx;
2556                                         y += dy;
2557                                 }
2558
2559                                 /* Do not move horizontally if unnecessary */
2560                                 if (((x < panel_col_min + wid / 2) && (dx > 0)) ||
2561                                          ((x > panel_col_min + wid / 2) && (dx < 0)))
2562                                 {
2563                                         dx = 0;
2564                                 }
2565
2566                                 /* Do not move vertically if unnecessary */
2567                                 if (((y < panel_row_min + hgt / 2) && (dy > 0)) ||
2568                                          ((y > panel_row_min + hgt / 2) && (dy < 0)))
2569                                 {
2570                                         dy = 0;
2571                                 }
2572
2573                                 /* Apply the motion */
2574                                 if ((y >= panel_row_min + hgt) || (y < panel_row_min) ||
2575                                          (x >= panel_col_min + wid) || (x < panel_col_min))
2576                                 {
2577                                         /* if (change_panel(dy, dx)) target_set_prepare(mode); */
2578                                         change_panel(dy, dx);
2579                                 }
2580
2581                                 /* Slide into legality */
2582                                 if (x >= cur_wid-1) x = cur_wid - 2;
2583                                 else if (x <= 0) x = 1;
2584
2585                                 /* Slide into legality */
2586                                 if (y >= cur_hgt-1) y = cur_hgt- 2;
2587                                 else if (y <= 0) y = 1;
2588
2589                         }
2590                         break;
2591                 }
2592         }
2593
2594         /* Clear the top line */
2595         prt("", 0, 0);
2596
2597         /* Recenter the map around the player */
2598         verify_panel();
2599
2600         p_ptr->update |= (PU_MONSTERS);
2601
2602         p_ptr->redraw |= (PR_MAP);
2603
2604         p_ptr->window |= (PW_OVERHEAD);
2605         handle_stuff();
2606
2607         *x_ptr = x;
2608         *y_ptr = y;
2609         return success;
2610 }
2611
2612
2613 bool get_hack_dir(DIRECTION *dp)
2614 {
2615         DIRECTION dir;
2616         concptr    p;
2617         char    command;
2618
2619         (*dp) = 0;
2620
2621         /* Global direction */
2622         dir = 0;
2623
2624         /* (No auto-targeting) */
2625
2626         /* Ask until satisfied */
2627         while (!dir)
2628         {
2629                 /* Choose a prompt */
2630                 if (!target_okay())
2631                 {
2632                         p = _("方向 ('*'でターゲット選択, ESCで中断)? ", "Direction ('*' to choose a target, Escape to cancel)? ");
2633                 }
2634                 else
2635                 {
2636                         p = _("方向 ('5'でターゲットへ, '*'でターゲット再選択, ESCで中断)? ", "Direction ('5' for target, '*' to re-target, Escape to cancel)? ");
2637                 }
2638
2639                 /* Get a command (or Cancel) */
2640                 if (!get_com(p, &command, TRUE)) break;
2641
2642                 if (use_menu)
2643                 {
2644                         if (command == '\r') command = 't';
2645                 }  
2646
2647                 /* Convert various keys to "standard" keys */
2648                 switch (command)
2649                 {
2650                         /* Use current target */
2651                         case 'T':
2652                         case 't':
2653                         case '.':
2654                         case '5':
2655                         case '0':
2656                         {
2657                                 dir = 5;
2658                                 break;
2659                         }
2660
2661                         /* Set new target */
2662                         case '*':
2663                         case ' ':
2664                         case '\r':
2665                         {
2666                                 if (target_set(TARGET_KILL)) dir = 5;
2667                                 break;
2668                         }
2669
2670                         default:
2671                         {
2672                                 /* Look up the direction */
2673                                 dir = get_keymap_dir(command);
2674
2675                                 break;
2676                         }
2677                 }
2678
2679                 /* Verify requested targets */
2680                 if ((dir == 5) && !target_okay()) dir = 0;
2681
2682                 /* Error */
2683                 if (!dir) bell();
2684         }
2685
2686         /* No direction */
2687         if (!dir) return (FALSE);
2688
2689         /* Save the direction */
2690         command_dir = dir;
2691
2692         /* Check for confusion */
2693         if (p_ptr->confused)
2694         {
2695                 /* Random direction */
2696                 dir = ddd[randint0(8)];
2697         }
2698
2699         /* Notice confusion */
2700         if (command_dir != dir)
2701         {
2702                 /* Warn the user */
2703                 msg_print(_("あなたは混乱している。", "You are confused."));
2704         }
2705
2706         /* Save direction */
2707         (*dp) = dir;
2708
2709         /* A "valid" direction was entered */
2710         return (TRUE);
2711 }