OSDN Git Service

[Refactor] #37353 mon_take_hit() と関連処理を monster-status.c/h へ移動。 / Move mon_take_hit...
[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
26 #define REWARD_CHANCE 10
27
28
29 /*!
30  * @brief プレイヤーの経験値について整合性のためのチェックと調整を行う /
31  * Advance experience levels and print experience
32  * @return なし
33  */
34 void check_experience(void)
35 {
36         bool level_reward = FALSE;
37         bool level_mutation = FALSE;
38         bool level_inc_stat = FALSE;
39         bool android = (p_ptr->prace == RACE_ANDROID ? TRUE : FALSE);
40         PLAYER_LEVEL old_lev = p_ptr->lev;
41
42         /* Hack -- lower limit */
43         if (p_ptr->exp < 0) p_ptr->exp = 0;
44         if (p_ptr->max_exp < 0) p_ptr->max_exp = 0;
45         if (p_ptr->max_max_exp < 0) p_ptr->max_max_exp = 0;
46
47         /* Hack -- upper limit */
48         if (p_ptr->exp > PY_MAX_EXP) p_ptr->exp = PY_MAX_EXP;
49         if (p_ptr->max_exp > PY_MAX_EXP) p_ptr->max_exp = PY_MAX_EXP;
50         if (p_ptr->max_max_exp > PY_MAX_EXP) p_ptr->max_max_exp = PY_MAX_EXP;
51
52         /* Hack -- maintain "max" experience */
53         if (p_ptr->exp > p_ptr->max_exp) p_ptr->max_exp = p_ptr->exp;
54
55         /* Hack -- maintain "max max" experience */
56         if (p_ptr->max_exp > p_ptr->max_max_exp) p_ptr->max_max_exp = p_ptr->max_exp;
57
58         /* Redraw experience */
59         p_ptr->redraw |= (PR_EXP);
60         handle_stuff();
61
62
63         /* Lose levels while possible */
64         while ((p_ptr->lev > 1) &&
65                (p_ptr->exp < ((android ? player_exp_a : player_exp)[p_ptr->lev - 2] * p_ptr->expfact / 100L)))
66         {
67                 /* Lose a level */
68                 p_ptr->lev--;
69                 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
70                 p_ptr->redraw |= (PR_LEV | PR_TITLE);
71                 p_ptr->window |= (PW_PLAYER);
72                 handle_stuff();
73         }
74
75
76         /* Gain levels while possible */
77         while ((p_ptr->lev < PY_MAX_LEVEL) &&
78                (p_ptr->exp >= ((android ? player_exp_a : player_exp)[p_ptr->lev-1] * p_ptr->expfact / 100L)))
79         {
80                 /* Gain a level */
81                 p_ptr->lev++;
82
83                 /* Save the highest level */
84                 if (p_ptr->lev > p_ptr->max_plv)
85                 {
86                         p_ptr->max_plv = p_ptr->lev;
87
88                         if ((p_ptr->pclass == CLASS_CHAOS_WARRIOR) ||
89                             (p_ptr->muta2 & MUT2_CHAOS_GIFT))
90                         {
91                                 level_reward = TRUE;
92                         }
93                         if (p_ptr->prace == RACE_BEASTMAN)
94                         {
95                                 if (one_in_(5)) level_mutation = TRUE;
96                         }
97                         level_inc_stat = TRUE;
98
99                         do_cmd_write_nikki(NIKKI_LEVELUP, p_ptr->lev, NULL);
100                 }
101
102                 sound(SOUND_LEVEL);
103
104                 msg_format(_("レベル %d にようこそ。", "Welcome to level %d."), p_ptr->lev);
105
106                 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
107                 p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);
108                 p_ptr->window |= (PW_PLAYER | PW_SPELL | PW_INVEN);
109
110                 /* HPとMPの上昇量を表示 */
111                 level_up = 1;
112                 handle_stuff();
113
114                 level_up = 0;
115
116                 if (level_inc_stat)
117                 {
118                         if(!(p_ptr->max_plv % 10))
119                         {
120                                 int choice;
121                                 screen_save();
122                                 while(1)
123                                 {
124                                         int n;
125                                         char tmp[32];
126
127                                         cnv_stat(p_ptr->stat_max[0], tmp);
128                                         prt(format(_("        a) 腕力 (現在値 %s)", "        a) Str (cur %s)"), tmp), 2, 14);
129                                         cnv_stat(p_ptr->stat_max[1], tmp);
130                                         prt(format(_("        b) 知能 (現在値 %s)", "        a) Int (cur %s)"), tmp), 3, 14);
131                                         cnv_stat(p_ptr->stat_max[2], tmp);
132                                         prt(format(_("        c) 賢さ (現在値 %s)", "        a) Wis (cur %s)"), tmp), 4, 14);
133                                         cnv_stat(p_ptr->stat_max[3], tmp);
134                                         prt(format(_("        d) 器用 (現在値 %s)", "        a) Dex (cur %s)"), tmp), 5, 14);
135                                         cnv_stat(p_ptr->stat_max[4], tmp);
136                                         prt(format(_("        e) 耐久 (現在値 %s)", "        a) Con (cur %s)"), tmp), 6, 14);
137                                         cnv_stat(p_ptr->stat_max[5], tmp);
138                                         prt(format(_("        f) 魅力 (現在値 %s)", "        a) Chr (cur %s)"), tmp), 7, 14);
139
140                                         prt("", 8, 14);
141                                         prt(_("        どの能力値を上げますか?", "        Which stat do you want to raise?"), 1, 14);
142
143                                         while(1)
144                                         {
145                                                 choice = inkey();
146                                                 if ((choice >= 'a') && (choice <= 'f')) break;
147                                         }
148                                         for(n = 0; n < A_MAX; n++)
149                                                 if (n != choice - 'a')
150                                                         prt("",n+2,14);
151                                         if (get_check(_("よろしいですか?", "Are you sure? "))) break;
152                                 }
153                                 do_inc_stat(choice - 'a');
154                                 screen_load();
155                         }
156                         else if(!(p_ptr->max_plv % 2))
157                                 do_inc_stat(randint0(6));
158                 }
159
160                 if (level_mutation)
161                 {
162                         msg_print(_("あなたは変わった気がする...", "You feel different..."));
163                         (void)gain_random_mutation(0);
164                         level_mutation = FALSE;
165                 }
166
167                 /*
168                  * 報酬でレベルが上ると再帰的に check_experience() が
169                  * 呼ばれるので順番を最後にする。
170                  */
171                 if (level_reward)
172                 {
173                         gain_level_reward(0);
174                         level_reward = FALSE;
175                 }
176
177                 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
178                 p_ptr->redraw |= (PR_LEV | PR_TITLE);
179                 p_ptr->window |= (PW_PLAYER | PW_SPELL);
180                 handle_stuff();
181         }
182
183         /* Load an autopick preference file */
184         if (old_lev != p_ptr->lev) autopick_load_pref(FALSE);
185 }
186
187
188
189 /*!
190  * @brief クエストを達成状態にする /
191  * @param quest_num 達成状態にしたいクエストのID
192  * @return なし
193  */
194 void complete_quest(QUEST_IDX quest_num)
195 {
196         quest_type* const q_ptr = &quest[quest_num];
197
198         switch (q_ptr->type)
199         {
200         case QUEST_TYPE_RANDOM:
201                 if (record_rand_quest) do_cmd_write_nikki(NIKKI_RAND_QUEST_C, quest_num, NULL);
202                 break;
203         default:
204                 if (record_fix_quest) do_cmd_write_nikki(NIKKI_FIX_QUEST_C, quest_num, NULL);
205                 break;
206         }
207
208         q_ptr->status = QUEST_STATUS_COMPLETED;
209         q_ptr->complev = p_ptr->lev;
210         update_playtime();
211         q_ptr->comptime = playtime;
212
213         if (!(q_ptr->flags & QUEST_FLAG_SILENT))
214         {
215                 play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_QUEST_CLEAR);
216                 msg_print(_("クエストを達成した!", "You just completed your quest!"));
217                 msg_print(NULL);
218         }
219 }
220
221 /*!
222  * @brief 現在フロアに残っている敵モンスターの数を返す /
223  * @return 現在の敵モンスターの数
224  */
225 static MONSTER_NUMBER count_all_hostile_monsters(void)
226 {
227         POSITION x, y;
228         MONSTER_NUMBER number_mon = 0;
229
230         for (x = 0; x < cur_wid; ++ x)
231         {
232                 for (y = 0; y < cur_hgt; ++ y)
233                 {
234                         MONSTER_IDX m_idx = cave[y][x].m_idx;
235
236                         if (m_idx > 0 && is_hostile(&m_list[m_idx]))
237                         {
238                                 ++number_mon;
239                         }
240                 }
241         }
242
243         return number_mon;
244 }
245
246 /*!
247  * @brief 特定の敵を倒した際にクエスト達成処理 /
248  * Check for "Quest" completion when a quest monster is killed or charmed.
249  * @param m_ptr 撃破したモンスターの構造体参照ポインタ
250  * @return なし
251  */
252 void check_quest_completion(monster_type *m_ptr)
253 {
254         POSITION y, x;
255         QUEST_IDX quest_num;
256
257         bool create_stairs = FALSE;
258         bool reward = FALSE;
259
260         object_type forge;
261         object_type *o_ptr;
262
263         y = m_ptr->fy;
264         x = m_ptr->fx;
265
266         /* Inside a quest */
267         quest_num = p_ptr->inside_quest;
268
269         /* Search for an active quest on this dungeon level */
270         if (!quest_num)
271         {
272                 QUEST_IDX i;
273
274                 for (i = max_q_idx - 1; i > 0; i--)
275                 {
276                         quest_type* const q_ptr = &quest[i];
277                         
278                         /* Quest is not active */
279                         if (q_ptr->status != QUEST_STATUS_TAKEN)
280                                 continue;
281
282                         /* Quest is not a dungeon quest */
283                         if (q_ptr->flags & QUEST_FLAG_PRESET)
284                                 continue;
285
286                         /* Quest is not on this level */
287                         if ((q_ptr->level != dun_level) &&
288                             (q_ptr->type != QUEST_TYPE_KILL_ANY_LEVEL))
289                                 continue;
290
291                         /* Not a "kill monster" quest */
292                         if ((q_ptr->type == QUEST_TYPE_FIND_ARTIFACT) ||
293                             (q_ptr->type == QUEST_TYPE_FIND_EXIT))
294                                 continue;
295
296                         /* Interesting quest */
297                         if ((q_ptr->type == QUEST_TYPE_KILL_NUMBER) ||
298                             (q_ptr->type == QUEST_TYPE_TOWER) ||
299                             (q_ptr->type == QUEST_TYPE_KILL_ALL))
300                                 break;
301
302                         /* Interesting quest */
303                         if (((q_ptr->type == QUEST_TYPE_KILL_LEVEL) ||
304                              (q_ptr->type == QUEST_TYPE_KILL_ANY_LEVEL) ||
305                              (q_ptr->type == QUEST_TYPE_RANDOM)) &&
306                              (q_ptr->r_idx == m_ptr->r_idx))
307                                 break;
308                 }
309
310                 quest_num = i;
311         }
312
313         /* Handle the current quest */
314         if (quest_num && (quest[quest_num].status == QUEST_STATUS_TAKEN))
315         {
316                 /* Current quest */
317                 quest_type* const q_ptr = &quest[quest_num];
318
319                 switch (q_ptr->type)
320                 {
321                         case QUEST_TYPE_KILL_NUMBER:
322                         {
323                                 q_ptr->cur_num++;
324
325                                 if (q_ptr->cur_num >= q_ptr->num_mon)
326                                 {
327                                         complete_quest(quest_num);
328
329                                         q_ptr->cur_num = 0;
330                                 }
331                                 break;
332                         }
333                         case QUEST_TYPE_KILL_ALL:
334                         {
335                                 if (!is_hostile(m_ptr)) break;
336
337                                 if (count_all_hostile_monsters() == 1)
338                                 {
339                                         if (q_ptr->flags & QUEST_FLAG_SILENT)
340                                         {
341                                                 q_ptr->status = QUEST_STATUS_FINISHED;
342                                         }
343                                         else
344                                         {
345                                                 complete_quest(quest_num);
346                                         }
347                                 }
348                                 break;
349                         }
350                         case QUEST_TYPE_KILL_LEVEL:
351                         case QUEST_TYPE_RANDOM:
352                         {
353                                 /* Only count valid monsters */
354                                 if (q_ptr->r_idx != m_ptr->r_idx)
355                                         break;
356
357                                 q_ptr->cur_num++;
358
359                                 if (q_ptr->cur_num >= q_ptr->max_num)
360                                 {
361                                         complete_quest(quest_num);
362
363                                         if (!(q_ptr->flags & QUEST_FLAG_PRESET))
364                                         {
365                                                 create_stairs = TRUE;
366                                                 p_ptr->inside_quest = 0;
367                                         }
368
369                                         /* Finish the two main quests without rewarding */
370                                         if ((quest_num == QUEST_OBERON) || (quest_num == QUEST_SERPENT))
371                                         {
372                                                 q_ptr->status = QUEST_STATUS_FINISHED;
373                                         }
374
375                                         if (q_ptr->type == QUEST_TYPE_RANDOM)
376                                         {
377                                                 reward = TRUE;
378                                                 q_ptr->status = QUEST_STATUS_FINISHED;
379                                         }
380                                 }
381                                 break;
382                         }
383                         case QUEST_TYPE_KILL_ANY_LEVEL:
384                         {
385                                 q_ptr->cur_num++;
386                                 if (q_ptr->cur_num >= q_ptr->max_num)
387                                 {
388                                         complete_quest(quest_num);
389                                         q_ptr->cur_num = 0;
390                                 }
391                                 break;
392                         }
393                         case QUEST_TYPE_TOWER:
394                         {
395                                 if (!is_hostile(m_ptr)) break;
396
397                                 if (count_all_hostile_monsters() == 1)
398                                 {
399                                         q_ptr->status = QUEST_STATUS_STAGE_COMPLETED;
400
401                                         if((quest[QUEST_TOWER1].status == QUEST_STATUS_STAGE_COMPLETED) &&
402                                            (quest[QUEST_TOWER2].status == QUEST_STATUS_STAGE_COMPLETED) &&
403                                            (quest[QUEST_TOWER3].status == QUEST_STATUS_STAGE_COMPLETED))
404                                         {
405
406                                                 complete_quest(QUEST_TOWER1);
407                                         }
408                                 }
409                                 break;
410                         }
411                 }
412         }
413
414         /* Create a magical staircase */
415         if (create_stairs)
416         {
417                 POSITION ny, nx;
418
419                 /* Stagger around */
420                 while (cave_perma_bold(y, x) || cave[y][x].o_idx || (cave[y][x].info & CAVE_OBJECT) )
421                 {
422                         /* Pick a location */
423                         scatter(&ny, &nx, y, x, 1, 0);
424
425                         /* Stagger */
426                         y = ny; x = nx;
427                 }
428
429                 /* Explain the staircase */
430                 msg_print(_("魔法の階段が現れた...", "A magical staircase appears..."));
431
432                 /* Create stairs down */
433                 cave_set_feat(y, x, feat_down_stair);
434
435                 /* Remember to update everything */
436                 p_ptr->update |= (PU_FLOW);
437         }
438
439         /*
440          * Drop quest reward
441          */
442         if (reward)
443         {
444                 int i;
445
446                 for (i = 0; i < (dun_level / 15)+1; i++)
447                 {
448                         o_ptr = &forge;
449                         object_wipe(o_ptr);
450
451                         /* Make a great object */
452                         make_object(o_ptr, AM_GOOD | AM_GREAT);
453                         (void)drop_near(o_ptr, -1, y, x);
454                 }
455         }
456 }
457
458 /*!
459  * @brief 特定のアーティファクトを入手した際のクエスト達成処理 /
460  * Check for "Quest" completion when a quest monster is killed or charmed.
461  * @param o_ptr 入手したオブジェクトの構造体参照ポインタ
462  * @return なし
463  */
464 void check_find_art_quest_completion(object_type *o_ptr)
465 {
466         QUEST_IDX i;
467         /* Check if completed a quest */
468         for (i = 0; i < max_q_idx; i++)
469         {
470                 if((quest[i].type == QUEST_TYPE_FIND_ARTIFACT) &&
471                         (quest[i].status == QUEST_STATUS_TAKEN) &&
472                         (quest[i].k_idx == o_ptr->name1))
473                 {
474                         complete_quest(i);
475                 }
476         }
477 }
478
479
480 /*!
481  * @brief モンスターを撃破した際の述語メッセージを返す /
482  * Return monster death string
483  * @param r_ptr 撃破されたモンスターの種族情報を持つ構造体の参照ポインタ
484  * @return 撃破されたモンスターの述語
485  */
486 concptr extract_note_dies(MONRACE_IDX r_idx)
487 {
488         monster_race *r_ptr = &r_info[r_idx];
489         /* Some monsters get "destroyed" */
490         if (!monster_living(r_idx))
491         {
492                 int i;
493
494                 for (i = 0; i < 4; i++)
495                 {
496                         if (r_ptr->blow[i].method == RBM_EXPLODE)
497                         {
498                                 return _("は爆発して粉々になった。", " explodes into tiny shreds.");
499                         }
500                 }
501                 return _("を倒した。", " is destroyed.");
502         }
503
504         /* Assume a default death */
505         return _("は死んだ。", " dies.");
506 }
507
508
509 /*!
510  * @brief モンスターに与えたダメージの修正処理 /
511  * Modify the physical damage done to the monster.
512  * @param m_ptr ダメージを受けるモンスターの構造体参照ポインタ
513  * @param dam ダメージ基本値
514  * @param is_psy_spear 攻撃手段が光の剣ならばTRUE
515  * @return 修正を行った結果のダメージ量
516  * @details
517  * <pre>
518  * (for example when it's invulnerable or shielded)
519  * ToDo: Accept a damage-type to calculate the modified damage from
520  * things like fire, frost, lightning, poison, ... attacks.
521  * "type" is not yet used and should be 0.
522  * </pre>
523  */
524 HIT_POINT mon_damage_mod(monster_type *m_ptr, HIT_POINT dam, bool is_psy_spear)
525 {
526         monster_race    *r_ptr = &r_info[m_ptr->r_idx];
527
528         if ((r_ptr->flagsr & RFR_RES_ALL) && dam > 0)
529         {
530                 dam /= 100;
531                 if ((dam == 0) && one_in_(3)) dam = 1;
532         }
533
534         if (MON_INVULNER(m_ptr))
535         {
536                 if (is_psy_spear)
537                 {
538                         if (!p_ptr->blind && is_seen(m_ptr))
539                         {
540                                 msg_print(_("バリアを切り裂いた!", "The barrier is penetrated!"));
541                         }
542                 }
543                 else if (!one_in_(PENETRATE_INVULNERABILITY))
544                 {
545                         return (0);
546                 }
547         }
548         return (dam);
549 }
550
551
552
553
554 /*!
555  * @brief 現在のコンソール表示の縦横を返す。 /
556  * Get term size and calculate screen size
557  * @param wid_p コンソールの表示幅文字数を返す
558  * @param hgt_p コンソールの表示行数を返す
559  * @return なし
560  */
561 void get_screen_size(TERM_LEN *wid_p, TERM_LEN *hgt_p)
562 {
563         Term_get_size(wid_p, hgt_p);
564         *hgt_p -= ROW_MAP + 2;
565         *wid_p -= COL_MAP + 2;
566         if (use_bigtile) *wid_p /= 2;
567 }
568
569
570 /*!
571  * @brief コンソール上におけるマップ表示の左上位置を返す /
572  * Calculates current boundaries Called below and from "do_cmd_locate()".
573  * @return なし
574  */
575 void panel_bounds_center(void)
576 {
577         TERM_LEN wid, hgt;
578
579         get_screen_size(&wid, &hgt);
580
581         panel_row_max = panel_row_min + hgt - 1;
582         panel_row_prt = panel_row_min - 1;
583         panel_col_max = panel_col_min + wid - 1;
584         panel_col_prt = panel_col_min - 13;
585 }
586
587
588 /*!
589  * @brief コンソールのリサイズに合わせてマップを再描画する /
590  * Map resizing whenever the main term changes size
591  * @return なし
592  */
593 void resize_map(void)
594 {
595         /* Only if the dungeon exists */
596         if (!character_dungeon) return;
597         
598         /* Mega-Hack -- no panel yet */
599         panel_row_max = 0;
600         panel_col_max = 0;
601
602         /* Reset the panels */
603         panel_row_min = cur_hgt;
604         panel_col_min = cur_wid;
605                                 
606         verify_panel();
607
608         p_ptr->update |= (PU_TORCH | PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
609         p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
610         p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
611         p_ptr->update |= (PU_MONSTERS);
612         p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
613
614         handle_stuff();
615         Term_redraw();
616
617         /*
618          * Waiting command;
619          * Place the cursor on the player
620          */
621         if (can_save) move_cursor_relative(p_ptr->y, p_ptr->x);
622
623         Term_fresh();
624 }
625
626 /*!
627  * @brief コンソールを再描画する /
628  * Redraw a term when it is resized
629  * @return なし
630  */
631 void redraw_window(void)
632 {
633         /* Only if the dungeon exists */
634         if (!character_dungeon) return;
635
636         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
637         p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
638
639         handle_stuff();
640         Term_redraw();
641 }
642
643
644 /*!
645  * @brief フォーカスを当てるべきマップ描画の基準座標を指定する(サブルーチン)
646  * @param dy 変更先のフロアY座標
647  * @param dx 変更先のフロアX座標
648  * Handle a request to change the current panel
649  * Return TRUE if the panel was changed.
650  * Also used in do_cmd_locate
651  * @return 実際に再描画が必要だった場合TRUEを返す
652  */
653 bool change_panel(POSITION dy, POSITION dx)
654 {
655         POSITION y, x;
656         TERM_LEN wid, hgt;
657
658         get_screen_size(&wid, &hgt);
659
660         /* Apply the motion */
661         y = panel_row_min + dy * hgt / 2;
662         x = panel_col_min + dx * wid / 2;
663
664         /* Verify the row */
665         if (y > cur_hgt - hgt) y = cur_hgt - hgt;
666         if (y < 0) y = 0;
667
668         /* Verify the col */
669         if (x > cur_wid - wid) x = cur_wid - wid;
670         if (x < 0) x = 0;
671
672         /* Handle "changes" */
673         if ((y != panel_row_min) || (x != panel_col_min))
674         {
675                 /* Save the new panel info */
676                 panel_row_min = y;
677                 panel_col_min = x;
678
679                 /* Recalculate the boundaries */
680                 panel_bounds_center();
681
682                 p_ptr->update |= (PU_MONSTERS);
683                 p_ptr->redraw |= (PR_MAP);
684                 handle_stuff();
685
686                 /* Success */
687                 return (TRUE);
688         }
689
690         /* No change */
691         return (FALSE);
692 }
693
694 /*!
695  * @brief フォーカスを当てるべきマップ描画の基準座標を指定する
696  * @param y 変更先のフロアY座標
697  * @param x 変更先のフロアX座標
698  * @details
699  * Handle a request to change the current panel
700  * Return TRUE if the panel was changed.
701  * Also used in do_cmd_locate
702  * @return 実際に再描画が必要だった場合TRUEを返す
703  */
704 static bool change_panel_xy(POSITION y, POSITION x)
705 {
706         POSITION dy = 0, dx = 0;
707         TERM_LEN wid, hgt;
708
709         get_screen_size(&wid, &hgt);
710
711         if (y < panel_row_min) dy = -1;
712         if (y > panel_row_max) dy = 1;
713         if (x < panel_col_min) dx = -1;
714         if (x > panel_col_max) dx = 1;
715
716         if (!dy && !dx) return (FALSE);
717
718         return change_panel(dy, dx);
719 }
720
721
722 /*!
723  * @brief マップ描画のフォーカスを当てるべき座標を更新する
724  * @details
725  * Given an row (y) and col (x), this routine detects when a move
726  * off the screen has occurred and figures new borders. -RAK-
727  * "Update" forces a "full update" to take place.
728  * The map is reprinted if necessary, and "TRUE" is returned.
729  * @return 実際に再描画が必要だった場合TRUEを返す
730  */
731 void verify_panel(void)
732 {
733         POSITION y = p_ptr->y;
734         POSITION x = p_ptr->x;
735         TERM_LEN wid, hgt;
736
737         int prow_min;
738         int pcol_min;
739         int max_prow_min;
740         int max_pcol_min;
741
742         get_screen_size(&wid, &hgt);
743
744         max_prow_min = cur_hgt - hgt;
745         max_pcol_min = cur_wid - wid;
746
747         /* Bounds checking */
748         if (max_prow_min < 0) max_prow_min = 0;
749         if (max_pcol_min < 0) max_pcol_min = 0;
750
751                 /* Center on player */
752         if (center_player && (center_running || !running))
753         {
754                 /* Center vertically */
755                 prow_min = y - hgt / 2;
756                 if (prow_min < 0) prow_min = 0;
757                 else if (prow_min > max_prow_min) prow_min = max_prow_min;
758
759                 /* Center horizontally */
760                 pcol_min = x - wid / 2;
761                 if (pcol_min < 0) pcol_min = 0;
762                 else if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
763         }
764         else
765         {
766                 prow_min = panel_row_min;
767                 pcol_min = panel_col_min;
768
769                 /* Scroll screen when 2 grids from top/bottom edge */
770                 if (y > panel_row_max - 2)
771                 {
772                         while (y > prow_min + hgt-1 - 2)
773                         {
774                                 prow_min += (hgt / 2);
775                         }
776                 }
777
778                 if (y < panel_row_min + 2)
779                 {
780                         while (y < prow_min + 2)
781                         {
782                                 prow_min -= (hgt / 2);
783                         }
784                 }
785
786                 if (prow_min > max_prow_min) prow_min = max_prow_min;
787                 if (prow_min < 0) prow_min = 0;
788
789                 /* Scroll screen when 4 grids from left/right edge */
790                 if (x > panel_col_max - 4)
791                 {
792                         while (x > pcol_min + wid-1 - 4)
793                         {
794                                 pcol_min += (wid / 2);
795                         }
796                 }
797                 
798                 if (x < panel_col_min + 4)
799                 {
800                         while (x < pcol_min + 4)
801                         {
802                                 pcol_min -= (wid / 2);
803                         }
804                 }
805
806                 if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
807                 if (pcol_min < 0) pcol_min = 0;
808         }
809
810         /* Check for "no change" */
811         if ((prow_min == panel_row_min) && (pcol_min == panel_col_min)) return;
812
813         /* Save the new panel info */
814         panel_row_min = prow_min;
815         panel_col_min = pcol_min;
816
817         /* Hack -- optional disturb on "panel change" */
818         if (disturb_panel && !center_player) disturb(FALSE, FALSE);
819
820         /* Recalculate the boundaries */
821         panel_bounds_center();
822
823         p_ptr->update |= (PU_MONSTERS);
824         p_ptr->redraw |= (PR_MAP);
825         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
826 }
827
828
829 /*
830  * Monster health description
831  */
832 concptr look_mon_desc(monster_type *m_ptr, BIT_FLAGS mode)
833 {
834         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
835         bool living;
836         int perc;
837         concptr desc;
838         concptr attitude;
839         concptr clone;
840
841         /* Determine if the monster is "living" */
842         living = monster_living(m_ptr->ap_r_idx);
843
844         /* Calculate a health "percentage" */
845         perc = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->maxhp : 0;
846
847         /* Healthy monsters */
848         if (m_ptr->hp >= m_ptr->maxhp)
849         {
850                 desc = living ? _("無傷", "unhurt") : _("無ダメージ", "undamaged");
851         }
852
853         else if (perc >= 60)
854         {
855                 desc = living ? _("軽傷", "somewhat wounded") : _("小ダメージ", "somewhat damaged");
856         }
857
858         else if (perc >= 25)
859         {
860                 desc = living ? _("負傷", "wounded") : _("中ダメージ", "damaged");
861         }
862
863         else if (perc >= 10)
864         {
865                 desc = living ? _("重傷", "badly wounded") : _("大ダメージ", "badly damaged");
866         }
867
868         else 
869         {
870                 desc = living ? _("半死半生", "almost dead") : _("倒れかけ", "almost destroyed");
871         }
872
873         /* Need attitude information? */
874         if (!(mode & 0x01))
875         {
876                 /* Full information is not needed */
877                 attitude = "";
878         }
879         else if (is_pet(m_ptr))
880         {
881                 attitude = _(", ペット", ", pet");
882         }
883         else if (is_friendly(m_ptr))
884         {
885                 attitude = _(", 友好的", ", friendly");
886         }
887         else
888         {
889                 attitude = _("", "");
890         }
891
892         /* Clone monster? */
893         if (m_ptr->smart & SM_CLONED)
894         {
895                 clone = ", clone";
896         }
897         else
898         {
899                 clone = "";
900         }
901
902         /* Display monster's level --- idea borrowed from ToME */
903         if (ap_r_ptr->r_tkills && !(m_ptr->mflag2 & MFLAG2_KAGE))
904         {
905                 return format(_("レベル%d, %s%s%s", "Level %d, %s%s%s"), ap_r_ptr->level, desc, attitude, clone);
906         }
907         else 
908         {
909                 return format(_("レベル???, %s%s%s", "Level ???, %s%s%s"), desc, attitude, clone);
910         }
911
912 }
913
914
915
916 /*** Targeting Code ***/
917
918
919 /*
920  * Determine is a monster makes a reasonable target
921  *
922  * The concept of "targeting" was stolen from "Morgul" (?)
923  *
924  * The player can target any location, or any "target-able" monster.
925  *
926  * Currently, a monster is "target_able" if it is visible, and if
927  * the player can hit it with a projection, and the player is not
928  * hallucinating.  This allows use of "use closest target" macros.
929  *
930  * Future versions may restrict the ability to target "trappers"
931  * and "mimics", but the semantics is a little bit weird.
932  */
933 bool target_able(MONSTER_IDX m_idx)
934 {
935         monster_type *m_ptr = &m_list[m_idx];
936
937         /* Monster must be alive */
938         if (!m_ptr->r_idx) return (FALSE);
939
940         /* Hack -- no targeting hallucinations */
941         if (p_ptr->image) return (FALSE);
942
943         /* Monster must be visible */
944         if (!m_ptr->ml) return (FALSE);
945
946         if (p_ptr->riding && (p_ptr->riding == m_idx)) return (TRUE);
947
948         /* Monster must be projectable */
949         if (!projectable(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx)) return (FALSE);
950
951         /* Hack -- Never target trappers */
952         /* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */
953
954         /* Assume okay */
955         return (TRUE);
956 }
957
958
959
960
961 /*
962  * Update (if necessary) and verify (if possible) the target.
963  *
964  * We return TRUE if the target is "okay" and FALSE otherwise.
965  */
966 bool target_okay(void)
967 {
968         /* Accept stationary targets */
969         if (target_who < 0) return (TRUE);
970
971         /* Check moving targets */
972         if (target_who > 0)
973         {
974                 /* Accept reasonable targets */
975                 if (target_able(target_who))
976                 {
977                         monster_type *m_ptr = &m_list[target_who];
978
979                         /* Acquire monster location */
980                         target_row = m_ptr->fy;
981                         target_col = m_ptr->fx;
982
983                         /* Good target */
984                         return (TRUE);
985                 }
986         }
987
988         /* Assume no target */
989         return (FALSE);
990 }
991
992
993 /*
994  * Sorting hook -- comp function -- by "distance to player"
995  *
996  * We use "u" and "v" to point to arrays of "x" and "y" positions,
997  * and sort the arrays by double-distance to the player.
998  */
999 static bool ang_sort_comp_distance(vptr u, vptr v, int a, int b)
1000 {
1001         POSITION *x = (POSITION*)(u);
1002         POSITION *y = (POSITION*)(v);
1003
1004         POSITION da, db, kx, ky;
1005
1006         /* Absolute distance components */
1007         kx = x[a]; kx -= p_ptr->x; kx = ABS(kx);
1008         ky = y[a]; ky -= p_ptr->y; ky = ABS(ky);
1009
1010         /* Approximate Double Distance to the first point */
1011         da = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
1012
1013         /* Absolute distance components */
1014         kx = x[b]; kx -= p_ptr->x; kx = ABS(kx);
1015         ky = y[b]; ky -= p_ptr->y; ky = ABS(ky);
1016
1017         /* Approximate Double Distance to the first point */
1018         db = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
1019
1020         /* Compare the distances */
1021         return (da <= db);
1022 }
1023
1024
1025 /*
1026  * Sorting hook -- comp function -- by importance level of grids
1027  *
1028  * We use "u" and "v" to point to arrays of "x" and "y" positions,
1029  * and sort the arrays by level of monster
1030  */
1031 static bool ang_sort_comp_importance(vptr u, vptr v, int a, int b)
1032 {
1033         POSITION *x = (POSITION*)(u);
1034         POSITION *y = (POSITION*)(v);
1035         cave_type *ca_ptr = &cave[y[a]][x[a]];
1036         cave_type *cb_ptr = &cave[y[b]][x[b]];
1037         monster_type *ma_ptr = &m_list[ca_ptr->m_idx];
1038         monster_type *mb_ptr = &m_list[cb_ptr->m_idx];
1039         monster_race *ap_ra_ptr, *ap_rb_ptr;
1040
1041         /* The player grid */
1042         if (y[a] == p_ptr->y && x[a] == p_ptr->x) return TRUE;
1043         if (y[b] == p_ptr->y && x[b] == p_ptr->x) return FALSE;
1044
1045         /* Extract monster race */
1046         if (ca_ptr->m_idx && ma_ptr->ml) ap_ra_ptr = &r_info[ma_ptr->ap_r_idx];
1047         else ap_ra_ptr = NULL;
1048         if (cb_ptr->m_idx && mb_ptr->ml) ap_rb_ptr = &r_info[mb_ptr->ap_r_idx];
1049         else ap_rb_ptr = NULL;
1050
1051         if (ap_ra_ptr && !ap_rb_ptr) return TRUE;
1052         if (!ap_ra_ptr && ap_rb_ptr) return FALSE;
1053
1054         /* Compare two monsters */
1055         if (ap_ra_ptr && ap_rb_ptr)
1056         {
1057                 /* Unique monsters first */
1058                 if ((ap_ra_ptr->flags1 & RF1_UNIQUE) && !(ap_rb_ptr->flags1 & RF1_UNIQUE)) return TRUE;
1059                 if (!(ap_ra_ptr->flags1 & RF1_UNIQUE) && (ap_rb_ptr->flags1 & RF1_UNIQUE)) return FALSE;
1060
1061                 /* Shadowers first (あやしい影) */
1062                 if ((ma_ptr->mflag2 & MFLAG2_KAGE) && !(mb_ptr->mflag2 & MFLAG2_KAGE)) return TRUE;
1063                 if (!(ma_ptr->mflag2 & MFLAG2_KAGE) && (mb_ptr->mflag2 & MFLAG2_KAGE)) return FALSE;
1064
1065                 /* Unknown monsters first */
1066                 if (!ap_ra_ptr->r_tkills && ap_rb_ptr->r_tkills) return TRUE;
1067                 if (ap_ra_ptr->r_tkills && !ap_rb_ptr->r_tkills) return FALSE;
1068
1069                 /* Higher level monsters first (if known) */
1070                 if (ap_ra_ptr->r_tkills && ap_rb_ptr->r_tkills)
1071                 {
1072                         if (ap_ra_ptr->level > ap_rb_ptr->level) return TRUE;
1073                         if (ap_ra_ptr->level < ap_rb_ptr->level) return FALSE;
1074                 }
1075
1076                 /* Sort by index if all conditions are same */
1077                 if (ma_ptr->ap_r_idx > mb_ptr->ap_r_idx) return TRUE;
1078                 if (ma_ptr->ap_r_idx < mb_ptr->ap_r_idx) return FALSE;
1079         }
1080
1081         /* An object get higher priority */
1082         if (cave[y[a]][x[a]].o_idx && !cave[y[b]][x[b]].o_idx) return TRUE;
1083         if (!cave[y[a]][x[a]].o_idx && cave[y[b]][x[b]].o_idx) return FALSE;
1084
1085         /* Priority from the terrain */
1086         if (f_info[ca_ptr->feat].priority > f_info[cb_ptr->feat].priority) return TRUE;
1087         if (f_info[ca_ptr->feat].priority < f_info[cb_ptr->feat].priority) return FALSE;
1088
1089         /* If all conditions are same, compare distance */
1090         return ang_sort_comp_distance(u, v, a, b);
1091 }
1092
1093
1094 /*
1095  * Sorting hook -- swap function -- by "distance to player"
1096  *
1097  * We use "u" and "v" to point to arrays of "x" and "y" positions,
1098  * and sort the arrays by distance to the player.
1099  */
1100 static void ang_sort_swap_distance(vptr u, vptr v, int a, int b)
1101 {
1102         POSITION *x = (POSITION*)(u);
1103         POSITION *y = (POSITION*)(v);
1104
1105         POSITION temp;
1106
1107         /* Swap "x" */
1108         temp = x[a];
1109         x[a] = x[b];
1110         x[b] = temp;
1111
1112         /* Swap "y" */
1113         temp = y[a];
1114         y[a] = y[b];
1115         y[b] = temp;
1116 }
1117
1118
1119
1120 /*
1121  * Hack -- help "select" a location (see below)
1122  */
1123 static POSITION_IDX target_pick(POSITION y1, POSITION x1, POSITION dy, POSITION dx)
1124 {
1125         POSITION_IDX i, v;
1126         POSITION x2, y2, x3, y3, x4, y4;
1127         POSITION_IDX b_i = -1, b_v = 9999;
1128
1129
1130         /* Scan the locations */
1131         for (i = 0; i < temp_n; i++)
1132         {
1133                 /* Point 2 */
1134                 x2 = temp_x[i];
1135                 y2 = temp_y[i];
1136
1137                 /* Directed distance */
1138                 x3 = (x2 - x1);
1139                 y3 = (y2 - y1);
1140
1141                 /* Verify quadrant */
1142                 if (dx && (x3 * dx <= 0)) continue;
1143                 if (dy && (y3 * dy <= 0)) continue;
1144
1145                 /* Absolute distance */
1146                 x4 = ABS(x3);
1147                 y4 = ABS(y3);
1148
1149                 /* Verify quadrant */
1150                 if (dy && !dx && (x4 > y4)) continue;
1151                 if (dx && !dy && (y4 > x4)) continue;
1152
1153                 /* Approximate Double Distance */
1154                 v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4));
1155
1156                 /* Penalize location */
1157
1158                 /* Track best */
1159                 if ((b_i >= 0) && (v >= b_v)) continue;
1160
1161                 /* Track best */
1162                 b_i = i; b_v = v;
1163         }
1164         return (b_i);
1165 }
1166
1167
1168 /*
1169  * Hack -- determine if a given location is "interesting"
1170  */
1171 static bool target_set_accept(POSITION y, POSITION x)
1172 {
1173         cave_type *c_ptr;
1174         OBJECT_IDX this_o_idx, next_o_idx = 0;
1175
1176         /* Bounds */
1177         if (!(in_bounds(y, x))) return (FALSE);
1178
1179         /* Player grid is always interesting */
1180         if (player_bold(y, x)) return (TRUE);
1181
1182         /* Handle hallucination */
1183         if (p_ptr->image) return (FALSE);
1184
1185         /* Examine the grid */
1186         c_ptr = &cave[y][x];
1187
1188         /* Visible monsters */
1189         if (c_ptr->m_idx)
1190         {
1191                 monster_type *m_ptr = &m_list[c_ptr->m_idx];
1192
1193                 /* Visible monsters */
1194                 if (m_ptr->ml) return (TRUE);
1195         }
1196
1197         /* Scan all objects in the grid */
1198         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1199         {
1200                 object_type *o_ptr;
1201                 o_ptr = &o_list[this_o_idx];
1202
1203                 /* Acquire next object */
1204                 next_o_idx = o_ptr->next_o_idx;
1205
1206                 /* Memorized object */
1207                 if (o_ptr->marked & OM_FOUND) return (TRUE);
1208         }
1209
1210         /* Interesting memorized features */
1211         if (c_ptr->info & (CAVE_MARK))
1212         {
1213                 /* Notice object features */
1214                 if (c_ptr->info & CAVE_OBJECT) return (TRUE);
1215
1216                 /* Feature code (applying "mimic" field) */
1217                 if (have_flag(f_info[get_feat_mimic(c_ptr)].flags, FF_NOTICE)) return TRUE;
1218         }
1219
1220         return (FALSE);
1221 }
1222
1223
1224 /*
1225  * Prepare the "temp" array for "target_set"
1226  *
1227  * Return the number of target_able monsters in the set.
1228  */
1229 static void target_set_prepare(BIT_FLAGS mode)
1230 {
1231         POSITION y, x;
1232         POSITION min_hgt, max_hgt, min_wid, max_wid;
1233
1234         if (mode & TARGET_KILL)
1235         {
1236                 /* Inner range */
1237                 min_hgt = MAX((p_ptr->y - MAX_RANGE), 0);
1238                 max_hgt = MIN((p_ptr->y + MAX_RANGE), cur_hgt - 1);
1239                 min_wid = MAX((p_ptr->x - MAX_RANGE), 0);
1240                 max_wid = MIN((p_ptr->x + MAX_RANGE), cur_wid - 1);
1241         }
1242         else /* not targetting */
1243         {
1244                 /* Inner panel */
1245                 min_hgt = panel_row_min;
1246                 max_hgt = panel_row_max;
1247                 min_wid = panel_col_min;
1248                 max_wid = panel_col_max;
1249         }
1250
1251         /* Reset "temp" array */
1252         temp_n = 0;
1253
1254         /* Scan the current panel */
1255         for (y = min_hgt; y <= max_hgt; y++)
1256         {
1257                 for (x = min_wid; x <= max_wid; x++)
1258                 {
1259                         cave_type *c_ptr;
1260
1261                         /* Require "interesting" contents */
1262                         if (!target_set_accept(y, x)) continue;
1263
1264                         c_ptr = &cave[y][x];
1265
1266                         /* Require target_able monsters for "TARGET_KILL" */
1267                         if ((mode & (TARGET_KILL)) && !target_able(c_ptr->m_idx)) continue;
1268
1269                         if ((mode & (TARGET_KILL)) && !target_pet && is_pet(&m_list[c_ptr->m_idx])) continue;
1270
1271                         /* Save the location */
1272                         temp_x[temp_n] = x;
1273                         temp_y[temp_n] = y;
1274                         temp_n++;
1275                 }
1276         }
1277
1278         /* Set the sort hooks */
1279         if (mode & (TARGET_KILL))
1280         {
1281                 /* Target the nearest monster for shooting */
1282                 ang_sort_comp = ang_sort_comp_distance;
1283                 ang_sort_swap = ang_sort_swap_distance;
1284         }
1285         else
1286         {
1287                 /* Look important grids first in Look command */
1288                 ang_sort_comp = ang_sort_comp_importance;
1289                 ang_sort_swap = ang_sort_swap_distance;
1290         }
1291
1292         /* Sort the positions */
1293         ang_sort(temp_x, temp_y, temp_n);
1294
1295         if (p_ptr->riding && target_pet && (temp_n > 1) && (mode & (TARGET_KILL)))
1296         {
1297                 POSITION tmp;
1298
1299                 tmp = temp_y[0];
1300                 temp_y[0] = temp_y[1];
1301                 temp_y[1] = tmp;
1302                 tmp = temp_x[0];
1303                 temp_x[0] = temp_x[1];
1304                 temp_x[1] = tmp;
1305         }
1306 }
1307
1308 void target_set_prepare_look(void){
1309         target_set_prepare(TARGET_LOOK);
1310 }
1311
1312
1313 /*
1314  * Evaluate number of kill needed to gain level
1315  */
1316 static void evaluate_monster_exp(char *buf, monster_type *m_ptr)
1317 {
1318         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1319         u32b num;
1320         s32b exp_mon, exp_adv;
1321         u32b exp_mon_frac, exp_adv_frac;
1322
1323         if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->prace == RACE_ANDROID))
1324         {
1325                 sprintf(buf,"**");
1326                 return;
1327         }
1328         else if (!ap_r_ptr->r_tkills || (m_ptr->mflag2 & MFLAG2_KAGE))
1329         {
1330                 if (!p_ptr->wizard)
1331                 {
1332                         sprintf(buf,"??");
1333                         return;
1334                 }
1335         }
1336
1337
1338         /* The monster's experience point (assuming average monster speed) */
1339         exp_mon = ap_r_ptr->mexp * ap_r_ptr->level;
1340         exp_mon_frac = 0;
1341         s64b_div(&exp_mon, &exp_mon_frac, 0, (p_ptr->max_plv + 2));
1342
1343
1344         /* Total experience value for next level */
1345         exp_adv = player_exp[p_ptr->lev -1] * p_ptr->expfact;
1346         exp_adv_frac = 0;
1347         s64b_div(&exp_adv, &exp_adv_frac, 0, 100);
1348
1349         /* Experience value need to get */
1350         s64b_sub(&exp_adv, &exp_adv_frac, p_ptr->exp, p_ptr->exp_frac);
1351
1352
1353         /* You need to kill at least one monster to get any experience */
1354         s64b_add(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
1355         s64b_sub(&exp_adv, &exp_adv_frac, 0, 1);
1356
1357         /* Extract number of monsters needed */
1358         s64b_div(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
1359
1360         /* If 999 or more monsters needed, only display "999". */
1361         num = MIN(999, exp_adv_frac);
1362
1363         /* Display the number */
1364         sprintf(buf,"%03ld", (long int)num);
1365 }
1366
1367
1368 bool show_gold_on_floor = FALSE;
1369
1370 /*
1371  * Examine a grid, return a keypress.
1372  *
1373  * The "mode" argument contains the "TARGET_LOOK" bit flag, which
1374  * indicates that the "space" key should scan through the contents
1375  * of the grid, instead of simply returning immediately.  This lets
1376  * the "look" command get complete information, without making the
1377  * "target" command annoying.
1378  *
1379  * The "info" argument contains the "commands" which should be shown
1380  * inside the "[xxx]" text.  This string must never be empty, or grids
1381  * containing monsters will be displayed with an extra comma.
1382  *
1383  * Note that if a monster is in the grid, we update both the monster
1384  * recall info and the health bar info to track that monster.
1385  *
1386  * Eventually, we may allow multiple objects per grid, or objects
1387  * and terrain features in the same grid. 
1388  *
1389  * This function must handle blindness/hallucination.
1390  */
1391 static char target_set_aux(POSITION y, POSITION x, BIT_FLAGS mode, concptr info)
1392 {
1393         cave_type *c_ptr = &cave[y][x];
1394         OBJECT_IDX this_o_idx, next_o_idx = 0;
1395         concptr s1 = "", s2 = "", s3 = "", x_info = "";
1396         bool boring = TRUE;
1397         FEAT_IDX feat;
1398         feature_type *f_ptr;
1399         char query = '\001';
1400         char out_val[MAX_NLEN+80];
1401         OBJECT_IDX floor_list[23];
1402         ITEM_NUMBER floor_num = 0;
1403
1404         /* Scan all objects in the grid */
1405         if (easy_floor)
1406         {
1407                 floor_num = scan_floor(floor_list, y, x, 0x02);
1408
1409                 if (floor_num)
1410                 {
1411                         x_info = _("x物 ", "x,");
1412                 }
1413         }
1414
1415         /* Hack -- under the player */
1416         if (player_bold(y, x))
1417         {
1418 #ifdef JP
1419                 s1 = "あなたは";
1420                 s2 = "の上";
1421                 s3 = "にいる";
1422 #else
1423                 s1 = "You are ";
1424                 s2 = "on ";
1425 #endif
1426         }
1427         else
1428         {
1429                 s1 = _("ターゲット:", "Target:");
1430         }
1431
1432         /* Hack -- hallucination */
1433         if (p_ptr->image)
1434         {
1435                 concptr name = _("何か奇妙な物", "something strange");
1436
1437                 /* Display a message */
1438 #ifdef JP
1439                 sprintf(out_val, "%s%s%s%s [%s]", s1, name, s2, s3, info);
1440 #else
1441                 sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
1442 #endif
1443
1444                 prt(out_val, 0, 0);
1445                 move_cursor_relative(y, x);
1446                 query = inkey();
1447
1448                 /* Stop on everything but "return" */
1449                 if ((query != '\r') && (query != '\n')) return query;
1450
1451                 /* Repeat forever */
1452                 return 0;
1453         }
1454
1455
1456         /* Actual monsters */
1457         if (c_ptr->m_idx && m_list[c_ptr->m_idx].ml)
1458         {
1459                 monster_type *m_ptr = &m_list[c_ptr->m_idx];
1460                 monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1461                 GAME_TEXT m_name[MAX_NLEN];
1462                 bool recall = FALSE;
1463
1464                 /* Not boring */
1465                 boring = FALSE;
1466
1467                 monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE);
1468                 monster_race_track(m_ptr->ap_r_idx);
1469                 health_track(c_ptr->m_idx);
1470                 handle_stuff();
1471
1472                 /* Interact */
1473                 while (1)
1474                 {
1475                         char acount[10];
1476
1477                         /* Recall */
1478                         if (recall)
1479                         {
1480                                 screen_save();
1481
1482                                 /* Recall on screen */
1483                                 screen_roff(m_ptr->ap_r_idx, 0);
1484
1485                                 /* Hack -- Complete the prompt (again) */
1486                                 Term_addstr(-1, TERM_WHITE, format(_("  [r思 %s%s]", "  [r,%s%s]"), x_info, info));
1487
1488                                 /* Command */
1489                                 query = inkey();
1490
1491                                 screen_load();
1492
1493                                 /* Normal commands */
1494                                 if (query != 'r') break;
1495
1496                                 /* Toggle recall */
1497                                 recall = FALSE;
1498
1499                                 /* Cleare recall text and repeat */
1500                                 continue;
1501                         }
1502
1503                         /*** Normal ***/
1504
1505                         /* Describe, and prompt for recall */
1506                         evaluate_monster_exp(acount, m_ptr);
1507
1508 #ifdef JP
1509                         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);
1510 #else
1511                         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);
1512 #endif
1513
1514                         prt(out_val, 0, 0);
1515
1516                         /* Place cursor */
1517                         move_cursor_relative(y, x);
1518
1519                         /* Command */
1520                         query = inkey();
1521
1522                         /* Normal commands */
1523                         if (query != 'r') break;
1524
1525                         /* Toggle recall */
1526                         recall = TRUE;
1527                 }
1528
1529                 /* Always stop at "normal" keys */
1530                 if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x')) return query;
1531
1532                 /* Sometimes stop at "space" key */
1533                 if ((query == ' ') && !(mode & (TARGET_LOOK))) return query;
1534
1535                 /* Change the intro */
1536                 s1 = _("それは", "It is ");
1537
1538                 /* Hack -- take account of gender */
1539                 if (ap_r_ptr->flags1 & (RF1_FEMALE)) s1 = _("彼女は", "She is ");
1540                 else if (ap_r_ptr->flags1 & (RF1_MALE)) s1 = _("彼は", "He is ");
1541
1542                 /* Use a preposition */
1543 #ifdef JP
1544                 s2 = "を";
1545                 s3 = "持っている";
1546 #else
1547                 s2 = "carrying ";
1548 #endif
1549
1550
1551                 /* Scan all objects being carried */
1552                 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
1553                 {
1554                         GAME_TEXT o_name[MAX_NLEN];
1555
1556                         object_type *o_ptr;
1557                         o_ptr = &o_list[this_o_idx];
1558
1559                         /* Acquire next object */
1560                         next_o_idx = o_ptr->next_o_idx;
1561
1562                         /* Obtain an object description */
1563                         object_desc(o_name, o_ptr, 0);
1564
1565 #ifdef JP
1566                         sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
1567 #else
1568                         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
1569 #endif
1570
1571                         prt(out_val, 0, 0);
1572                         move_cursor_relative(y, x);
1573                         query = inkey();
1574
1575                         /* Always stop at "normal" keys */
1576                         if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x')) return query;
1577
1578                         /* Sometimes stop at "space" key */
1579                         if ((query == ' ') && !(mode & (TARGET_LOOK))) return query;
1580
1581                         /* Change the intro */
1582                         s2 = _("をまた", "also carrying ");
1583                 }
1584
1585                 /* Use a preposition */
1586 #ifdef JP
1587                 s2 = "の上";
1588                 s3 = "にいる";
1589 #else
1590                 s2 = "on ";
1591 #endif
1592         }
1593
1594         if (floor_num)
1595         {
1596                 int min_width = 0;
1597
1598                 while (1)
1599                 {
1600                         if (floor_num == 1)
1601                         {
1602                                 GAME_TEXT o_name[MAX_NLEN];
1603
1604                                 object_type *o_ptr;
1605                                 o_ptr = &o_list[floor_list[0]];
1606
1607                                 object_desc(o_name, o_ptr, 0);
1608
1609 #ifdef JP
1610                                 sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
1611 #else
1612                                 sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
1613 #endif
1614
1615                                 prt(out_val, 0, 0);
1616                                 move_cursor_relative(y, x);
1617
1618                                 /* Command */
1619                                 query = inkey();
1620
1621                                 /* End this grid */
1622                                 return query;
1623                         }
1624
1625                         /* Provide one cushion before item listing  */
1626                         if (boring)
1627                         {
1628                                 /* Display rough information about items */
1629 #ifdef JP
1630                                 sprintf(out_val, "%s %d個のアイテム%s%s ['x'で一覧, %s]", s1, (int)floor_num, s2, s3, info);
1631 #else
1632                                 sprintf(out_val, "%s%s%sa pile of %d items [x,%s]", s1, s2, s3, (int)floor_num, info);
1633 #endif
1634
1635                                 prt(out_val, 0, 0);
1636                                 move_cursor_relative(y, x);
1637
1638                                 /* Command */
1639                                 query = inkey();
1640
1641                                 /* No request for listing */
1642                                 if (query != 'x' && query != ' ') return query;
1643                         }
1644
1645
1646                         /** Display list of items **/
1647
1648                         /* Continue scrolling list if requested */
1649                         while (1)
1650                         {
1651                                 int i;
1652                                 OBJECT_IDX o_idx;
1653                                 screen_save();
1654
1655                                 /* Display */
1656                                 show_gold_on_floor = TRUE;
1657                                 (void)show_floor(0, y, x, &min_width);
1658                                 show_gold_on_floor = FALSE;
1659
1660                                 /* Prompt */
1661 #ifdef JP
1662                                 sprintf(out_val, "%s %d個のアイテム%s%s [Enterで次へ, %s]", s1, (int)floor_num, s2, s3, info);
1663 #else
1664                                 sprintf(out_val, "%s%s%sa pile of %d items [Enter,%s]", s1, s2, s3, (int)floor_num, info);
1665 #endif
1666                                 prt(out_val, 0, 0);
1667
1668                                 query = inkey();
1669                                 screen_load();
1670
1671                                 /* Exit unless 'Enter' */
1672                                 if (query != '\n' && query != '\r')
1673                                 {
1674                                         return query;
1675                                 }
1676
1677                                 /* Get the object being moved. */
1678                                 o_idx = c_ptr->o_idx;
1679  
1680                                 /* Only rotate a pile of two or more objects. */
1681                                 if (!(o_idx && o_list[o_idx].next_o_idx)) continue;
1682
1683                                 /* Remove the first object from the list. */
1684                                 excise_object_idx(o_idx);
1685
1686                                 /* Find end of the list. */
1687                                 i = c_ptr->o_idx;
1688                                 while (o_list[i].next_o_idx)
1689                                         i = o_list[i].next_o_idx;
1690
1691                                 /* Add after the last object. */
1692                                 o_list[i].next_o_idx = o_idx;
1693
1694                                 /* Loop and re-display the list */
1695                         }
1696                 }
1697
1698                 /* NOTREACHED */
1699         }
1700
1701         /* Scan all objects in the grid */
1702         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1703         {
1704                 object_type *o_ptr;
1705                 o_ptr = &o_list[this_o_idx];
1706
1707                 /* Acquire next object */
1708                 next_o_idx = o_ptr->next_o_idx;
1709
1710                 if (o_ptr->marked & OM_FOUND)
1711                 {
1712                         GAME_TEXT o_name[MAX_NLEN];
1713
1714                         /* Not boring */
1715                         boring = FALSE;
1716
1717                         /* Obtain an object description */
1718                         object_desc(o_name, o_ptr, 0);
1719
1720 #ifdef JP
1721                         sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
1722 #else
1723                         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
1724 #endif
1725
1726                         prt(out_val, 0, 0);
1727                         move_cursor_relative(y, x);
1728                         query = inkey();
1729
1730                         /* Always stop at "normal" keys */
1731                         if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x')) return query;
1732
1733                         /* Sometimes stop at "space" key */
1734                         if ((query == ' ') && !(mode & TARGET_LOOK)) return query;
1735
1736                         /* Change the intro */
1737                         s1 = _("それは", "It is ");
1738
1739                         /* Plurals */
1740                         if (o_ptr->number != 1) s1 = _("それらは", "They are ");
1741
1742                         /* Preposition */
1743 #ifdef JP
1744                         s2 = "の上";
1745                         s3 = "に見える";
1746 #else
1747                         s2 = "on ";
1748 #endif
1749
1750                 }
1751         }
1752
1753
1754         /* Feature code (applying "mimic" field) */
1755         feat = get_feat_mimic(c_ptr);
1756
1757         /* Require knowledge about grid, or ability to see grid */
1758         if (!(c_ptr->info & CAVE_MARK) && !player_can_see_bold(y, x))
1759         {
1760                 /* Forget feature */
1761                 feat = feat_none;
1762         }
1763
1764         f_ptr = &f_info[feat];
1765
1766         /* Terrain feature if needed */
1767         if (boring || have_flag(f_ptr->flags, FF_REMEMBER))
1768         {
1769                 concptr name;
1770
1771                 /* Hack -- special handling for quest entrances */
1772                 if (have_flag(f_ptr->flags, FF_QUEST_ENTER))
1773                 {
1774                         /* Set the quest number temporary */
1775                         IDX old_quest = p_ptr->inside_quest;
1776                         int j;
1777
1778                         /* Clear the text */
1779                         for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
1780                         quest_text_line = 0;
1781
1782                         p_ptr->inside_quest = c_ptr->special;
1783
1784                         /* Get the quest text */
1785                         init_flags = INIT_NAME_ONLY;
1786
1787                         process_dungeon_file("q_info.txt", 0, 0, 0, 0);
1788
1789                         name = format(_("クエスト「%s」(%d階相当)", "the entrance to the quest '%s'(level %d)"), 
1790                                                 quest[c_ptr->special].name, quest[c_ptr->special].level);
1791
1792                         /* Reset the old quest number */
1793                         p_ptr->inside_quest = old_quest;
1794                 }
1795
1796                 /* Hack -- special handling for building doors */
1797                 else if (have_flag(f_ptr->flags, FF_BLDG) && !p_ptr->inside_arena)
1798                 {
1799                         name = building[f_ptr->subtype].name;
1800                 }
1801                 else if (have_flag(f_ptr->flags, FF_ENTRANCE))
1802                 {
1803                         name = format(_("%s(%d階相当)", "%s(level %d)"), d_text + d_info[c_ptr->special].text, d_info[c_ptr->special].mindepth);
1804                 }
1805                 else if (have_flag(f_ptr->flags, FF_TOWN))
1806                 {
1807                         name = town[c_ptr->special].name;
1808                 }
1809                 else if (p_ptr->wild_mode && (feat == feat_floor))
1810                 {
1811                         name = _("道", "road");
1812                 }
1813                 else
1814                 {
1815                         name = f_name + f_ptr->name;
1816                 }
1817
1818
1819                 /* Pick a prefix */
1820                 if (*s2 &&
1821                     ((!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) ||
1822                      (!have_flag(f_ptr->flags, FF_LOS) && !have_flag(f_ptr->flags, FF_TREE)) ||
1823                      have_flag(f_ptr->flags, FF_TOWN)))
1824                 {
1825                         s2 = _("の中", "in ");
1826                 }
1827
1828                 /* Hack -- special introduction for store & building doors -KMW- */
1829                 if (have_flag(f_ptr->flags, FF_STORE) ||
1830                     have_flag(f_ptr->flags, FF_QUEST_ENTER) ||
1831                     (have_flag(f_ptr->flags, FF_BLDG) && !p_ptr->inside_arena) ||
1832                     have_flag(f_ptr->flags, FF_ENTRANCE))
1833                 {
1834                         s2 = _("の入口", "");
1835                 }
1836 #ifndef JP
1837                 else if (have_flag(f_ptr->flags, FF_FLOOR) ||
1838                          have_flag(f_ptr->flags, FF_TOWN) ||
1839                          have_flag(f_ptr->flags, FF_SHALLOW) ||
1840                          have_flag(f_ptr->flags, FF_DEEP))
1841                 {
1842                         s3 ="";
1843                 }
1844                 else
1845                 {
1846                         /* Pick proper indefinite article */
1847                         s3 = (is_a_vowel(name[0])) ? "an " : "a ";
1848                 }
1849 #endif
1850
1851                 /* Display a message */
1852                 if (p_ptr->wizard)
1853                 {
1854                         char f_idx_str[32];
1855                         if (c_ptr->mimic) sprintf(f_idx_str, "%d/%d", c_ptr->feat, c_ptr->mimic);
1856                         else sprintf(f_idx_str, "%d", c_ptr->feat);
1857 #ifdef JP
1858                         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]);
1859 #else
1860                         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);
1861 #endif
1862                 }
1863                 else
1864 #ifdef JP
1865                         sprintf(out_val, "%s%s%s%s[%s]", s1, name, s2, s3, info);
1866 #else
1867                         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
1868 #endif
1869
1870                 prt(out_val, 0, 0);
1871                 move_cursor_relative(y, x);
1872                 query = inkey();
1873
1874                 /* Always stop at "normal" keys */
1875                 if ((query != '\r') && (query != '\n') && (query != ' ')) return query;
1876         }
1877
1878         /* Stop on everything but "return" */
1879         if ((query != '\r') && (query != '\n')) return query;
1880
1881         /* Repeat forever */
1882         return 0;
1883 }
1884
1885
1886 /*
1887  * Handle "target" and "look".
1888  *
1889  * Note that this code can be called from "get_aim_dir()".
1890  *
1891  * All locations must be on the current panel.  Consider the use of
1892  * "panel_bounds()" to allow "off-panel" targets, perhaps by using
1893  * some form of "scrolling" the map around the cursor.  
1894  * That is, consider the possibility of "auto-scrolling" the screen
1895  * while the cursor moves around.  This may require changes in the
1896  * "update_monster()" code to allow "visibility" even if off panel, and
1897  * may require dynamic recalculation of the "temp" grid set.
1898  *
1899  * Hack -- targeting/observing an "outer border grid" may induce
1900  * problems, so this is not currently allowed.
1901  *
1902  * The player can use the direction keys to move among "interesting"
1903  * grids in a heuristic manner, or the "space", "+", and "-" keys to
1904  * move through the "interesting" grids in a sequential manner, or
1905  * can enter "location" mode, and use the direction keys to move one
1906  * grid at a time in any direction.  The "t" (set target) command will
1907  * only target a monster (as opposed to a location) if the monster is
1908  * target_able and the "interesting" mode is being used.
1909  *
1910  * The current grid is described using the "look" method above, and
1911  * a new command may be entered at any time, but note that if the
1912  * "TARGET_LOOK" bit flag is set (or if we are in "location" mode,
1913  * where "space" has no obvious meaning) then "space" will scan
1914  * through the description of the current grid until done, instead
1915  * of immediately jumping to the next "interesting" grid.  This
1916  * allows the "target" command to retain its old semantics.
1917  *
1918  * The "*", "+", and "-" keys may always be used to jump immediately
1919  * to the next (or previous) interesting grid, in the proper mode.
1920  *
1921  * The "return" key may always be used to scan through a complete
1922  * grid description (forever).
1923  *
1924  * This command will cancel any old target, even if used from
1925  * inside the "look" command.
1926  */
1927 bool target_set(BIT_FLAGS mode)
1928 {
1929         int i, d, m, t, bd;
1930         POSITION y = p_ptr->y;
1931         POSITION x = p_ptr->x;
1932
1933         bool done = FALSE;
1934         bool flag = TRUE;
1935         char query;
1936         char info[80];
1937         char same_key;
1938         cave_type *c_ptr;
1939         TERM_LEN wid, hgt;
1940         
1941         get_screen_size(&wid, &hgt);
1942
1943         /* Cancel target */
1944         target_who = 0;
1945
1946         if (rogue_like_commands)
1947         {
1948                 same_key = 'x';
1949         }
1950         else
1951         {
1952                 same_key = 'l';
1953         }
1954
1955         /* Prepare the "temp" array */
1956         target_set_prepare(mode);
1957
1958         /* Start near the player */
1959         m = 0;
1960
1961         /* Interact */
1962         while (!done)
1963         {
1964                 /* Interesting grids */
1965                 if (flag && temp_n)
1966                 {
1967                         y = temp_y[m];
1968                         x = temp_x[m];
1969
1970                         /* Set forcus */
1971                         change_panel_xy(y, x);
1972
1973                         if (!(mode & TARGET_LOOK)) prt_path(y, x);
1974
1975                         /* Access */
1976                         c_ptr = &cave[y][x];
1977
1978                         /* Allow target */
1979                         if (target_able(c_ptr->m_idx))
1980                         {
1981                                 strcpy(info, _("q止 t決 p自 o現 +次 -前", "q,t,p,o,+,-,<dir>"));
1982                         }
1983
1984                         /* Dis-allow target */
1985                         else
1986                         {
1987                                 strcpy(info, _("q止 p自 o現 +次 -前", "q,p,o,+,-,<dir>"));
1988                         }
1989
1990                         if (cheat_sight)
1991                         {
1992                                 char cheatinfo[30];
1993                                 sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d",
1994                                         los(p_ptr->y, p_ptr->x, y, x), projectable(p_ptr->y, p_ptr->x, y, x));
1995                                 strcat(info, cheatinfo);
1996                         }
1997                         
1998                         /* Describe and Prompt */
1999                         while (TRUE){
2000                                 query = target_set_aux(y, x, mode, info);
2001                                 if(query)break;
2002                         }
2003
2004                         /* Assume no "direction" */
2005                         d = 0;
2006
2007                         if (use_menu)
2008                         {
2009                                 if (query == '\r') query = 't';
2010                         }  
2011
2012                         /* Analyze */
2013                         switch (query)
2014                         {
2015                                 case ESCAPE:
2016                                 case 'q':
2017                                 {
2018                                         done = TRUE;
2019                                         break;
2020                                 }
2021
2022                                 case 't':
2023                                 case '.':
2024                                 case '5':
2025                                 case '0':
2026                                 {
2027                                         if (target_able(c_ptr->m_idx))
2028                                         {
2029                                                 health_track(c_ptr->m_idx);
2030                                                 target_who = c_ptr->m_idx;
2031                                                 target_row = y;
2032                                                 target_col = x;
2033                                                 done = TRUE;
2034                                         }
2035                                         else
2036                                         {
2037                                                 bell();
2038                                         }
2039                                         break;
2040                                 }
2041
2042                                 case ' ':
2043                                 case '*':
2044                                 case '+':
2045                                 {
2046                                         if (++m == temp_n)
2047                                         {
2048                                                 m = 0;
2049                                                 if (!expand_list) done = TRUE;
2050                                         }
2051                                         break;
2052                                 }
2053
2054                                 case '-':
2055                                 {
2056                                         if (m-- == 0)
2057                                         {
2058                                                 m = temp_n - 1;
2059                                                 if (!expand_list) done = TRUE;
2060                                         }
2061                                         break;
2062                                 }
2063
2064                                 case 'p':
2065                                 {
2066                                         /* Recenter the map around the player */
2067                                         verify_panel();
2068                                         p_ptr->update |= (PU_MONSTERS);
2069                                         p_ptr->redraw |= (PR_MAP);
2070                                         p_ptr->window |= (PW_OVERHEAD);
2071                                         handle_stuff();
2072
2073                                         /* Recalculate interesting grids */
2074                                         target_set_prepare(mode);
2075
2076                                         y = p_ptr->y;
2077                                         x = p_ptr->x;
2078                                 }
2079
2080                                 case 'o':
2081                                 {
2082                                         flag = FALSE;
2083                                         break;
2084                                 }
2085
2086                                 case 'm':
2087                                 {
2088                                         break;
2089                                 }
2090
2091                                 default:
2092                                 {
2093                                         if(query == same_key)
2094                                         {
2095                                                 if (++m == temp_n)
2096                                                 {
2097                                                         m = 0;
2098                                                         if (!expand_list) done = TRUE;
2099                                                 }
2100                                         }
2101                                         else
2102                                         {
2103                                                 /* Extract the action (if any) */
2104                                                 d = get_keymap_dir(query);
2105
2106                                                 if (!d) bell();
2107                                                 break;
2108                                         }
2109                                 }
2110                         }
2111                         /* Hack -- move around */
2112                         if (d)
2113                         {
2114                                 /* Modified to scroll to monster */
2115                                 POSITION y2 = panel_row_min;
2116                                 POSITION x2 = panel_col_min;
2117
2118                                 /* Find a new monster */
2119                                 i = target_pick(temp_y[m], temp_x[m], ddy[d], ddx[d]);
2120
2121                                 /* Request to target past last interesting grid */
2122                                 while (flag && (i < 0))
2123                                 {
2124                                         /* Note the change */
2125                                         if (change_panel(ddy[d], ddx[d]))
2126                                         {
2127                                                 int v = temp_y[m];
2128                                                 int u = temp_x[m];
2129
2130                                                 /* Recalculate interesting grids */
2131                                                 target_set_prepare(mode);
2132
2133                                                 /* Look at interesting grids */
2134                                                 flag = TRUE;
2135
2136                                                 /* Find a new monster */
2137                                                 i = target_pick(v, u, ddy[d], ddx[d]);
2138
2139                                                 /* Use that grid */
2140                                                 if (i >= 0) m = i;
2141                                         }
2142
2143                                         /* Nothing interesting */
2144                                         else
2145                                         {
2146                                                 POSITION dx = ddx[d];
2147                                                 POSITION dy = ddy[d];
2148
2149                                                 /* Restore previous position */
2150                                                 panel_row_min = y2;
2151                                                 panel_col_min = x2;
2152                                                 panel_bounds_center();
2153
2154                                                 p_ptr->update |= (PU_MONSTERS);
2155                                                 p_ptr->redraw |= (PR_MAP);
2156                                                 p_ptr->window |= (PW_OVERHEAD);
2157                                                 handle_stuff();
2158
2159                                                 /* Recalculate interesting grids */
2160                                                 target_set_prepare(mode);
2161
2162                                                 /* Look at boring grids */
2163                                                 flag = FALSE;
2164
2165                                                 /* Move */
2166                                                 x += dx;
2167                                                 y += dy;
2168
2169                                                 /* Do not move horizontally if unnecessary */
2170                                                 if (((x < panel_col_min + wid / 2) && (dx > 0)) ||
2171                                                          ((x > panel_col_min + wid / 2) && (dx < 0)))
2172                                                 {
2173                                                         dx = 0;
2174                                                 }
2175
2176                                                 /* Do not move vertically if unnecessary */
2177                                                 if (((y < panel_row_min + hgt / 2) && (dy > 0)) ||
2178                                                          ((y > panel_row_min + hgt / 2) && (dy < 0)))
2179                                                 {
2180                                                         dy = 0;
2181                                                 }
2182
2183                                                 /* Apply the motion */
2184                                                 if ((y >= panel_row_min+hgt) || (y < panel_row_min) ||
2185                                                     (x >= panel_col_min+wid) || (x < panel_col_min))
2186                                                 {
2187                                                         if (change_panel(dy, dx)) target_set_prepare(mode);
2188                                                 }
2189
2190                                                 /* Slide into legality */
2191                                                 if (x >= cur_wid-1) x = cur_wid - 2;
2192                                                 else if (x <= 0) x = 1;
2193
2194                                                 /* Slide into legality */
2195                                                 if (y >= cur_hgt-1) y = cur_hgt- 2;
2196                                                 else if (y <= 0) y = 1;
2197                                         }
2198                                 }
2199
2200                                 /* Use that grid */
2201                                 m = i;
2202                         }
2203                 }
2204
2205                 /* Arbitrary grids */
2206                 else
2207                 {
2208                         bool move_fast = FALSE;
2209
2210                         if (!(mode & TARGET_LOOK)) prt_path(y, x);
2211
2212                         /* Access */
2213                         c_ptr = &cave[y][x];
2214
2215                         /* Default prompt */
2216                         strcpy(info, _("q止 t決 p自 m近 +次 -前", "q,t,p,m,+,-,<dir>"));
2217
2218                         if (cheat_sight)
2219                         {
2220                                 char cheatinfo[30];
2221                                 sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d",
2222                                         los(p_ptr->y, p_ptr->x, y, x),
2223                                         projectable(p_ptr->y, p_ptr->x, y, x));
2224                                 strcat(info, cheatinfo);
2225                         }
2226
2227                         /* Describe and Prompt (enable "TARGET_LOOK") */
2228                         while ((query = target_set_aux(y, x, mode | TARGET_LOOK, info)) == 0);
2229
2230                         /* Assume no direction */
2231                         d = 0;
2232
2233                         if (use_menu)
2234                         {
2235                                 if (query == '\r') query = 't';
2236                         }  
2237
2238                         /* Analyze the keypress */
2239                         switch (query)
2240                         {
2241                                 case ESCAPE:
2242                                 case 'q':
2243                                 {
2244                                         done = TRUE;
2245                                         break;
2246                                 }
2247
2248                                 case 't':
2249                                 case '.':
2250                                 case '5':
2251                                 case '0':
2252                                 {
2253                                         target_who = -1;
2254                                         target_row = y;
2255                                         target_col = x;
2256                                         done = TRUE;
2257                                         break;
2258                                 }
2259
2260                                 case 'p':
2261                                 {
2262                                         /* Recenter the map around the player */
2263                                         verify_panel();
2264                                         p_ptr->update |= (PU_MONSTERS);
2265                                         p_ptr->redraw |= (PR_MAP);
2266                                         p_ptr->window |= (PW_OVERHEAD);
2267                                         handle_stuff();
2268
2269                                         /* Recalculate interesting grids */
2270                                         target_set_prepare(mode);
2271
2272                                         y = p_ptr->y;
2273                                         x = p_ptr->x;
2274                                 }
2275
2276                                 case 'o':
2277                                 {
2278                                         break;
2279                                 }
2280
2281                                 case ' ':
2282                                 case '*':
2283                                 case '+':
2284                                 case '-':
2285                                 case 'm':
2286                                 {
2287                                         flag = TRUE;
2288
2289                                         m = 0;
2290                                         bd = 999;
2291
2292                                         /* Pick a nearby monster */
2293                                         for (i = 0; i < temp_n; i++)
2294                                         {
2295                                                 t = distance(y, x, temp_y[i], temp_x[i]);
2296
2297                                                 /* Pick closest */
2298                                                 if (t < bd)
2299                                                 {
2300                                                         m = i;
2301                                                         bd = t;
2302                                                 }
2303                                         }
2304
2305                                         /* Nothing interesting */
2306                                         if (bd == 999) flag = FALSE;
2307
2308                                         break;
2309                                 }
2310
2311                                 default:
2312                                 {
2313                                         /* Extract the action (if any) */
2314                                         d = get_keymap_dir(query);
2315
2316                                         /* XTRA HACK MOVEFAST */
2317                                         if (isupper(query)) move_fast = TRUE;
2318
2319                                         if (!d) bell();
2320                                         break;
2321                                 }
2322                         }
2323
2324                         /* Handle "direction" */
2325                         if (d)
2326                         {
2327                                 POSITION dx = ddx[d];
2328                                 POSITION dy = ddy[d];
2329
2330                                 /* XTRA HACK MOVEFAST */
2331                                 if (move_fast)
2332                                 {
2333                                         int mag = MIN(wid / 2, hgt / 2);
2334                                         x += dx * mag;
2335                                         y += dy * mag;
2336                                 }
2337                                 else
2338                                 {
2339                                         x += dx;
2340                                         y += dy;
2341                                 }
2342
2343                                 /* Do not move horizontally if unnecessary */
2344                                 if (((x < panel_col_min + wid / 2) && (dx > 0)) ||
2345                                          ((x > panel_col_min + wid / 2) && (dx < 0)))
2346                                 {
2347                                         dx = 0;
2348                                 }
2349
2350                                 /* Do not move vertically if unnecessary */
2351                                 if (((y < panel_row_min + hgt / 2) && (dy > 0)) ||
2352                                          ((y > panel_row_min + hgt / 2) && (dy < 0)))
2353                                 {
2354                                         dy = 0;
2355                                 }
2356
2357                                 /* Apply the motion */
2358                                 if ((y >= panel_row_min + hgt) || (y < panel_row_min) ||
2359                                          (x >= panel_col_min + wid) || (x < panel_col_min))
2360                                 {
2361                                         if (change_panel(dy, dx)) target_set_prepare(mode);
2362                                 }
2363
2364                                 /* Slide into legality */
2365                                 if (x >= cur_wid-1) x = cur_wid - 2;
2366                                 else if (x <= 0) x = 1;
2367
2368                                 /* Slide into legality */
2369                                 if (y >= cur_hgt-1) y = cur_hgt- 2;
2370                                 else if (y <= 0) y = 1;
2371                         }
2372                 }
2373         }
2374
2375         /* Forget */
2376         temp_n = 0;
2377
2378         /* Clear the top line */
2379         prt("", 0, 0);
2380
2381         /* Recenter the map around the player */
2382         verify_panel();
2383         p_ptr->update |= (PU_MONSTERS);
2384         p_ptr->redraw |= (PR_MAP);
2385         p_ptr->window |= (PW_OVERHEAD);
2386         handle_stuff();
2387
2388         /* Failure to set target */
2389         if (!target_who) return (FALSE);
2390
2391         /* Success */
2392         return (TRUE);
2393 }
2394
2395
2396 /*
2397  * Get an "aiming direction" from the user.
2398  *
2399  * The "dir" is loaded with 1,2,3,4,6,7,8,9 for "actual direction", and
2400  * "0" for "current target", and "-1" for "entry aborted".
2401  *
2402  * Note that "Force Target", if set, will pre-empt user interaction,
2403  * if there is a usable target already set.
2404  *
2405  * Note that confusion over-rides any (explicit?) user choice.
2406  */
2407 bool get_aim_dir(DIRECTION *dp)
2408 {
2409         DIRECTION dir;
2410         char    command;
2411         concptr p;
2412         COMMAND_CODE code;
2413
2414         (*dp) = 0;
2415
2416         /* Global direction */
2417         dir = command_dir;
2418
2419         /* Hack -- auto-target if requested */
2420         if (use_old_target && target_okay()) dir = 5;
2421
2422         if (repeat_pull(&code))
2423         {
2424                 /* Confusion? */
2425
2426                 /* Verify */
2427                 if (!(code == 5 && !target_okay()))
2428                 {
2429 /*                      return (TRUE); */
2430                         dir = (DIRECTION)code;
2431                 }
2432         }
2433         *dp = (DIRECTION)code;
2434
2435         /* Ask until satisfied */
2436         while (!dir)
2437         {
2438                 /* Choose a prompt */
2439                 if (!target_okay())
2440                 {
2441                         p = _("方向 ('*'でターゲット選択, ESCで中断)? ", "Direction ('*' to choose a target, Escape to cancel)? ");
2442                 }
2443                 else
2444                 {
2445                         p = _("方向 ('5'でターゲットへ, '*'でターゲット再選択, ESCで中断)? ", "Direction ('5' for target, '*' to re-target, Escape to cancel)? ");
2446                 }
2447
2448                 /* Get a command (or Cancel) */
2449                 if (!get_com(p, &command, TRUE)) break;
2450
2451                 if (use_menu)
2452                 {
2453                         if (command == '\r') command = 't';
2454                 }  
2455
2456                 /* Convert various keys to "standard" keys */
2457                 switch (command)
2458                 {
2459                         /* Use current target */
2460                         case 'T':
2461                         case 't':
2462                         case '.':
2463                         case '5':
2464                         case '0':
2465                         {
2466                                 dir = 5;
2467                                 break;
2468                         }
2469
2470                         /* Set new target */
2471                         case '*':
2472                         case ' ':
2473                         case '\r':
2474                         {
2475                                 if (target_set(TARGET_KILL)) dir = 5;
2476                                 break;
2477                         }
2478
2479                         default:
2480                         {
2481                                 /* Extract the action (if any) */
2482                                 dir = get_keymap_dir(command);
2483
2484                                 break;
2485                         }
2486                 }
2487
2488                 /* Verify requested targets */
2489                 if ((dir == 5) && !target_okay()) dir = 0;
2490
2491                 /* Error */
2492                 if (!dir) bell();
2493         }
2494
2495         /* No direction */
2496         if (!dir)
2497         {
2498                 project_length = 0; /* reset to default */
2499                 return (FALSE);
2500         }
2501
2502         /* Save the direction */
2503         command_dir = dir;
2504
2505         /* Check for confusion */
2506         if (p_ptr->confused)
2507         {
2508                 /* Random direction */
2509                 dir = ddd[randint0(8)];
2510         }
2511
2512         /* Notice confusion */
2513         if (command_dir != dir)
2514         {
2515                 /* Warn the user */
2516                 msg_print(_("あなたは混乱している。", "You are confused."));
2517         }
2518
2519         /* Save direction */
2520         (*dp) = dir;
2521
2522 /*      repeat_push(dir); */
2523         repeat_push((COMMAND_CODE)command_dir);
2524
2525         /* A "valid" direction was entered */
2526         return (TRUE);
2527 }
2528
2529
2530 bool get_direction(DIRECTION *dp, bool allow_under, bool with_steed)
2531 {
2532         DIRECTION dir;
2533         concptr prompt;
2534         COMMAND_CODE code;
2535
2536         (*dp) = 0;
2537
2538         /* Global direction */
2539         dir = command_dir;
2540
2541         if (repeat_pull(&code))
2542         {
2543                 dir = (DIRECTION)code;
2544                 /*              return (TRUE); */
2545         }
2546         *dp = (DIRECTION)code;
2547
2548         if (allow_under)
2549         {
2550                 prompt = _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ");
2551         }
2552         else
2553         {
2554                 prompt = _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
2555         }
2556
2557         /* Get a direction */
2558         while (!dir)
2559         {
2560                 char ch;
2561
2562                 /* Get a command (or Cancel) */
2563                 if (!get_com(prompt, &ch, TRUE)) break;
2564
2565                 /* Look down */
2566                 if ((allow_under) && ((ch == '5') || (ch == '-') || (ch == '.')))
2567                 {
2568                         dir = 5;
2569                 }
2570                 else
2571                 {
2572                         /* Look up the direction */
2573                         dir = get_keymap_dir(ch);
2574
2575                         if (!dir) bell();
2576                 }
2577         }
2578
2579         /* Prevent weirdness */
2580         if ((dir == 5) && (!allow_under)) dir = 0;
2581
2582         /* Aborted */
2583         if (!dir) return (FALSE);
2584
2585         /* Save desired direction */
2586         command_dir = dir;
2587
2588         /* Apply "confusion" */
2589         if (p_ptr->confused)
2590         {
2591                 /* Standard confusion */
2592                 if (randint0(100) < 75)
2593                 {
2594                         /* Random direction */
2595                         dir = ddd[randint0(8)];
2596                 }
2597         }
2598         else if (p_ptr->riding && with_steed)
2599         {
2600                 monster_type *m_ptr = &m_list[p_ptr->riding];
2601                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
2602
2603                 if (MON_CONFUSED(m_ptr))
2604                 {
2605                         /* Standard confusion */
2606                         if (randint0(100) < 75)
2607                         {
2608                                 /* Random direction */
2609                                 dir = ddd[randint0(8)];
2610                         }
2611                 }
2612                 else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
2613                 {
2614                         /* Random direction */
2615                         dir = ddd[randint0(8)];
2616                 }
2617                 else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
2618                 {
2619                         /* Random direction */
2620                         dir = ddd[randint0(8)];
2621                 }
2622         }
2623
2624         /* Notice confusion */
2625         if (command_dir != dir)
2626         {
2627                 if (p_ptr->confused)
2628                 {
2629                         /* Warn the user */
2630                         msg_print(_("あなたは混乱している。", "You are confused."));
2631                 }
2632                 else
2633                 {
2634                         GAME_TEXT m_name[MAX_NLEN];
2635                         monster_type *m_ptr = &m_list[p_ptr->riding];
2636
2637                         monster_desc(m_name, m_ptr, 0);
2638                         if (MON_CONFUSED(m_ptr))
2639                         {
2640                                 msg_format(_("%sは混乱している。", "%^s is confusing."), m_name);
2641                         }
2642                         else
2643                         {
2644                                 msg_format(_("%sは思い通りに動いてくれない。", "You cannot control %s."), m_name);
2645                         }
2646                 }
2647         }
2648
2649         /* Save direction */
2650         (*dp) = dir;
2651
2652         /*      repeat_push(dir); */
2653         repeat_push((COMMAND_CODE)command_dir);
2654
2655         /* Success */
2656         return (TRUE);
2657 }
2658
2659 /*
2660  * @brief 進行方向を指定する(騎乗対象の混乱の影響を受ける) / Request a "movement" direction (1,2,3,4,6,7,8,9) from the user,
2661  * and place it into "command_dir", unless we already have one.
2662  *
2663  * This function should be used for all "repeatable" commands, such as
2664  * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well
2665  * as all commands which must reference a grid adjacent to the player,
2666  * and which may not reference the grid under the player.  Note that,
2667  * for example, it is no longer possible to "disarm" or "open" chests
2668  * in the same grid as the player.
2669  *
2670  * Direction "5" is illegal and will (cleanly) abort the command.
2671  *
2672  * This function tracks and uses the "global direction", and uses
2673  * that as the "desired direction", to which "confusion" is applied.
2674  */
2675 bool get_rep_dir(DIRECTION *dp, bool under)
2676 {
2677         DIRECTION dir;
2678         concptr prompt;
2679         COMMAND_CODE code;
2680
2681         (*dp) = 0;
2682
2683         /* Global direction */
2684         dir = command_dir;
2685
2686         if (repeat_pull(&code))
2687         {
2688                 dir = (DIRECTION)code;
2689 /*              return (TRUE); */
2690         }
2691         *dp = (DIRECTION)code;
2692
2693         if (under)
2694         {
2695                 prompt = _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ");
2696         }
2697         else
2698         {
2699                 prompt = _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
2700         }
2701         
2702         /* Get a direction */
2703         while (!dir)
2704         {
2705                 char ch;
2706
2707                 /* Get a command (or Cancel) */
2708                 if (!get_com(prompt, &ch, TRUE)) break;
2709
2710                 /* Look down */
2711                 if ((under) && ((ch == '5') || (ch == '-') || (ch == '.')))
2712                 {
2713                         dir = 5;
2714                 }
2715                 else
2716                 {
2717                         /* Look up the direction */
2718                         dir = get_keymap_dir(ch);
2719
2720                         if (!dir) bell();
2721                 }
2722         }
2723
2724         /* Prevent weirdness */
2725         if ((dir == 5) && (!under)) dir = 0;
2726
2727         /* Aborted */
2728         if (!dir) return (FALSE);
2729
2730         /* Save desired direction */
2731         command_dir = dir;
2732
2733         /* Apply "confusion" */
2734         if (p_ptr->confused)
2735         {
2736                 /* Standard confusion */
2737                 if (randint0(100) < 75)
2738                 {
2739                         /* Random direction */
2740                         dir = ddd[randint0(8)];
2741                 }
2742         }
2743         else if (p_ptr->riding)
2744         {
2745                 monster_type *m_ptr = &m_list[p_ptr->riding];
2746                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
2747
2748                 if (MON_CONFUSED(m_ptr))
2749                 {
2750                         /* Standard confusion */
2751                         if (randint0(100) < 75)
2752                         {
2753                                 /* Random direction */
2754                                 dir = ddd[randint0(8)];
2755                         }
2756                 }
2757                 else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
2758                 {
2759                         /* Random direction */
2760                         dir = ddd[randint0(8)];
2761                 }
2762                 else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
2763                 {
2764                         /* Random direction */
2765                         dir = ddd[randint0(8)];
2766                 }
2767         }
2768
2769         /* Notice confusion */
2770         if (command_dir != dir)
2771         {
2772                 if (p_ptr->confused)
2773                 {
2774                         /* Warn the user */
2775                         msg_print(_("あなたは混乱している。", "You are confused."));
2776                 }
2777                 else
2778                 {
2779                         GAME_TEXT m_name[MAX_NLEN];
2780                         monster_type *m_ptr = &m_list[p_ptr->riding];
2781
2782                         monster_desc(m_name, m_ptr, 0);
2783                         if (MON_CONFUSED(m_ptr))
2784                         {
2785                                 msg_format(_("%sは混乱している。", "%^s is confusing."), m_name);
2786                         }
2787                         else
2788                         {
2789                                 msg_format(_("%sは思い通りに動いてくれない。", "You cannot control %s."), m_name);
2790                         }
2791                 }
2792         }
2793
2794         /* Save direction */
2795         (*dp) = dir;
2796
2797 /*      repeat_push(dir); */
2798         repeat_push((COMMAND_CODE)command_dir);
2799
2800         /* Success */
2801         return (TRUE);
2802 }
2803
2804
2805 /*
2806  * XAngband: determine if a given location is "interesting"
2807  * based on target_set_accept function.
2808  */
2809 static bool tgt_pt_accept(POSITION y, POSITION x)
2810 {
2811         cave_type *c_ptr;
2812
2813         /* Bounds */
2814         if (!(in_bounds(y, x))) return (FALSE);
2815
2816         /* Player grid is always interesting */
2817         if ((y == p_ptr->y) && (x == p_ptr->x)) return (TRUE);
2818
2819         /* Handle hallucination */
2820         if (p_ptr->image) return (FALSE);
2821
2822         /* Examine the grid */
2823         c_ptr = &cave[y][x];
2824
2825         /* Interesting memorized features */
2826         if (c_ptr->info & (CAVE_MARK))
2827         {
2828                 /* Notice stairs */
2829                 if (cave_have_flag_grid(c_ptr, FF_LESS)) return (TRUE);
2830                 if (cave_have_flag_grid(c_ptr, FF_MORE)) return (TRUE);
2831
2832                 /* Notice quest features */
2833                 if (cave_have_flag_grid(c_ptr, FF_QUEST_ENTER)) return (TRUE);
2834                 if (cave_have_flag_grid(c_ptr, FF_QUEST_EXIT)) return (TRUE);
2835         }
2836
2837         return (FALSE);
2838 }
2839
2840
2841 /*
2842  * XAngband: Prepare the "temp" array for "tget_pt"
2843  * based on target_set_prepare funciton.
2844  */
2845 static void tgt_pt_prepare(void)
2846 {
2847         POSITION y, x;
2848
2849         /* Reset "temp" array */
2850         temp_n = 0;
2851
2852         if (!expand_list) return;
2853
2854         /* Scan the current panel */
2855         for (y = 1; y < cur_hgt; y++)
2856         {
2857                 for (x = 1; x < cur_wid; x++)
2858                 {
2859                         /* Require "interesting" contents */
2860                         if (!tgt_pt_accept(y, x)) continue;
2861
2862                         /* Save the location */
2863                         temp_x[temp_n] = x;
2864                         temp_y[temp_n] = y;
2865                         temp_n++;
2866                 }
2867         }
2868
2869         /* Target the nearest monster for shooting */
2870         ang_sort_comp = ang_sort_comp_distance;
2871         ang_sort_swap = ang_sort_swap_distance;
2872
2873         /* Sort the positions */
2874         ang_sort(temp_x, temp_y, temp_n);
2875 }
2876
2877 /*
2878  * old -- from PsiAngband.
2879  */
2880 bool tgt_pt(POSITION *x_ptr, POSITION *y_ptr)
2881 {
2882         char ch = 0;
2883         int d, n = 0;
2884         POSITION x, y;
2885         bool success = FALSE;
2886
2887         TERM_LEN wid, hgt;
2888
2889         get_screen_size(&wid, &hgt);
2890
2891         x = p_ptr->x;
2892         y = p_ptr->y;
2893
2894         if (expand_list) 
2895         {
2896                 tgt_pt_prepare();
2897         }
2898
2899         msg_print(_("場所を選んでスペースキーを押して下さい。", "Select a point and press space."));
2900         msg_flag = FALSE; /* prevents "-more-" message. */
2901
2902         while ((ch != ESCAPE) && !success)
2903         {
2904                 bool move_fast = FALSE;
2905
2906                 move_cursor_relative(y, x);
2907                 ch = inkey();
2908                 switch (ch)
2909                 {
2910                 case ESCAPE:
2911                         break;
2912                 case ' ':
2913                 case 't':
2914                 case '.':
2915                 case '5':
2916                 case '0':
2917                         /* illegal place */
2918                         if (player_bold(y, x)) ch = 0;
2919
2920                         /* okay place */
2921                         else success = TRUE;
2922
2923                         break;
2924
2925                 /* XAngband: Move cursor to stairs */
2926                 case '>':
2927                 case '<':
2928                         if (expand_list && temp_n)
2929                         {
2930                                 int dx, dy;
2931                                 int cx = (panel_col_min + panel_col_max) / 2;
2932                                 int cy = (panel_row_min + panel_row_max) / 2;
2933
2934                                 n++;
2935
2936                                 /* Skip stairs which have defferent distance */
2937                                 for (; n < temp_n; ++ n)
2938                                 {
2939                                         cave_type *c_ptr = &cave[temp_y[n]][temp_x[n]];
2940
2941                                         if (cave_have_flag_grid(c_ptr, FF_STAIRS) &&
2942                                             cave_have_flag_grid(c_ptr, ch == '>' ? FF_MORE : FF_LESS))
2943                                         {
2944                                                 /* Found */
2945                                                 break;
2946                                         }
2947                                 }
2948
2949                                 if (n == temp_n)        /* Loop out taget list */
2950                                 {
2951                                         n = 0;
2952                                         y = p_ptr->y;
2953                                         x = p_ptr->x;
2954                                         verify_panel(); /* Move cursor to player */
2955
2956                                         p_ptr->update |= (PU_MONSTERS);
2957
2958                                         p_ptr->redraw |= (PR_MAP);
2959
2960                                         p_ptr->window |= (PW_OVERHEAD);
2961                                         handle_stuff();
2962                                 }
2963                                 else    /* move cursor to next stair and change panel */
2964                                 {
2965                                         y = temp_y[n];
2966                                         x = temp_x[n];
2967
2968                                         dy = 2 * (y - cy) / hgt;
2969                                         dx = 2 * (x - cx) / wid;
2970                                         if (dy || dx) change_panel(dy, dx);
2971                                 }
2972                         }
2973                         break;
2974
2975                 default:
2976                         /* Look up the direction */
2977                         d = get_keymap_dir(ch);
2978
2979                         /* XTRA HACK MOVEFAST */
2980                         if (isupper(ch)) move_fast = TRUE;
2981
2982                         /* Handle "direction" */
2983                         if (d)
2984                         {
2985                                 int dx = ddx[d];
2986                                 int dy = ddy[d];
2987
2988                                 /* XTRA HACK MOVEFAST */
2989                                 if (move_fast)
2990                                 {
2991                                         int mag = MIN(wid / 2, hgt / 2);
2992                                         x += dx * mag;
2993                                         y += dy * mag;
2994                                 }
2995                                 else
2996                                 {
2997                                         x += dx;
2998                                         y += dy;
2999                                 }
3000
3001                                 /* Do not move horizontally if unnecessary */
3002                                 if (((x < panel_col_min + wid / 2) && (dx > 0)) ||
3003                                          ((x > panel_col_min + wid / 2) && (dx < 0)))
3004                                 {
3005                                         dx = 0;
3006                                 }
3007
3008                                 /* Do not move vertically if unnecessary */
3009                                 if (((y < panel_row_min + hgt / 2) && (dy > 0)) ||
3010                                          ((y > panel_row_min + hgt / 2) && (dy < 0)))
3011                                 {
3012                                         dy = 0;
3013                                 }
3014
3015                                 /* Apply the motion */
3016                                 if ((y >= panel_row_min + hgt) || (y < panel_row_min) ||
3017                                          (x >= panel_col_min + wid) || (x < panel_col_min))
3018                                 {
3019                                         /* if (change_panel(dy, dx)) target_set_prepare(mode); */
3020                                         change_panel(dy, dx);
3021                                 }
3022
3023                                 /* Slide into legality */
3024                                 if (x >= cur_wid-1) x = cur_wid - 2;
3025                                 else if (x <= 0) x = 1;
3026
3027                                 /* Slide into legality */
3028                                 if (y >= cur_hgt-1) y = cur_hgt- 2;
3029                                 else if (y <= 0) y = 1;
3030
3031                         }
3032                         break;
3033                 }
3034         }
3035
3036         /* Clear the top line */
3037         prt("", 0, 0);
3038
3039         /* Recenter the map around the player */
3040         verify_panel();
3041
3042         p_ptr->update |= (PU_MONSTERS);
3043
3044         p_ptr->redraw |= (PR_MAP);
3045
3046         p_ptr->window |= (PW_OVERHEAD);
3047         handle_stuff();
3048
3049         *x_ptr = x;
3050         *y_ptr = y;
3051         return success;
3052 }
3053
3054
3055 bool get_hack_dir(DIRECTION *dp)
3056 {
3057         DIRECTION dir;
3058         concptr    p;
3059         char    command;
3060
3061         (*dp) = 0;
3062
3063         /* Global direction */
3064         dir = 0;
3065
3066         /* (No auto-targeting) */
3067
3068         /* Ask until satisfied */
3069         while (!dir)
3070         {
3071                 /* Choose a prompt */
3072                 if (!target_okay())
3073                 {
3074                         p = _("方向 ('*'でターゲット選択, ESCで中断)? ", "Direction ('*' to choose a target, Escape to cancel)? ");
3075                 }
3076                 else
3077                 {
3078                         p = _("方向 ('5'でターゲットへ, '*'でターゲット再選択, ESCで中断)? ", "Direction ('5' for target, '*' to re-target, Escape to cancel)? ");
3079                 }
3080
3081                 /* Get a command (or Cancel) */
3082                 if (!get_com(p, &command, TRUE)) break;
3083
3084                 if (use_menu)
3085                 {
3086                         if (command == '\r') command = 't';
3087                 }  
3088
3089                 /* Convert various keys to "standard" keys */
3090                 switch (command)
3091                 {
3092                         /* Use current target */
3093                         case 'T':
3094                         case 't':
3095                         case '.':
3096                         case '5':
3097                         case '0':
3098                         {
3099                                 dir = 5;
3100                                 break;
3101                         }
3102
3103                         /* Set new target */
3104                         case '*':
3105                         case ' ':
3106                         case '\r':
3107                         {
3108                                 if (target_set(TARGET_KILL)) dir = 5;
3109                                 break;
3110                         }
3111
3112                         default:
3113                         {
3114                                 /* Look up the direction */
3115                                 dir = get_keymap_dir(command);
3116
3117                                 break;
3118                         }
3119                 }
3120
3121                 /* Verify requested targets */
3122                 if ((dir == 5) && !target_okay()) dir = 0;
3123
3124                 /* Error */
3125                 if (!dir) bell();
3126         }
3127
3128         /* No direction */
3129         if (!dir) return (FALSE);
3130
3131         /* Save the direction */
3132         command_dir = dir;
3133
3134         /* Check for confusion */
3135         if (p_ptr->confused)
3136         {
3137                 /* Random direction */
3138                 dir = ddd[randint0(8)];
3139         }
3140
3141         /* Notice confusion */
3142         if (command_dir != dir)
3143         {
3144                 /* Warn the user */
3145                 msg_print(_("あなたは混乱している。", "You are confused."));
3146         }
3147
3148         /* Save direction */
3149         (*dp) = dir;
3150
3151         /* A "valid" direction was entered */
3152         return (TRUE);
3153 }
3154
3155
3156 /*!
3157  * @brief 射撃武器の攻撃に必要な基本消費エネルギーを返す/Return bow energy
3158  * @param sval 射撃武器のアイテム副分類ID 
3159  * @return 消費する基本エネルギー
3160  */
3161 ENERGY bow_energy(OBJECT_SUBTYPE_VALUE sval)
3162 {
3163         ENERGY energy = 10000;
3164
3165         /* Analyze the launcher */
3166         switch (sval)
3167         {
3168                 /* Sling and ammo */
3169                 case SV_SLING:
3170                 {
3171                         energy = 8000;
3172                         break;
3173                 }
3174
3175                 /* Short Bow and Arrow */
3176                 case SV_SHORT_BOW:
3177                 {
3178                         energy = 10000;
3179                         break;
3180                 }
3181
3182                 /* Long Bow and Arrow */
3183                 case SV_LONG_BOW:
3184                 {
3185                         energy = 10000;
3186                         break;
3187                 }
3188
3189                 /* Bow of irresponsiblity and Arrow */
3190                 case SV_NAMAKE_BOW:
3191                 {
3192                         energy = 7777;
3193                         break;
3194                 }
3195
3196                 /* Light Crossbow and Bolt */
3197                 case SV_LIGHT_XBOW:
3198                 {
3199                         energy = 12000;
3200                         break;
3201                 }
3202
3203                 /* Heavy Crossbow and Bolt */
3204                 case SV_HEAVY_XBOW:
3205                 {
3206                         energy = 13333;
3207                         break;
3208                 }
3209         }
3210
3211         return (energy);
3212 }
3213
3214
3215 /*
3216  * Return bow tmul
3217  */
3218 int bow_tmul(OBJECT_SUBTYPE_VALUE sval)
3219 {
3220         int tmul = 0;
3221
3222         /* Analyze the launcher */
3223         switch (sval)
3224         {
3225                 /* Sling and ammo */
3226                 case SV_SLING:
3227                 {
3228                         tmul = 2;
3229                         break;
3230                 }
3231
3232                 /* Short Bow and Arrow */
3233                 case SV_SHORT_BOW:
3234                 {
3235                         tmul = 2;
3236                         break;
3237                 }
3238
3239                 /* Long Bow and Arrow */
3240                 case SV_LONG_BOW:
3241                 {
3242                         tmul = 3;
3243                         break;
3244                 }
3245
3246                 /* Bow of irresponsiblity and Arrow */
3247                 case SV_NAMAKE_BOW:
3248                 {
3249                         tmul = 3;
3250                         break;
3251                 }
3252
3253                 /* Light Crossbow and Bolt */
3254                 case SV_LIGHT_XBOW:
3255                 {
3256                         tmul = 3;
3257                         break;
3258                 }
3259
3260                 /* Heavy Crossbow and Bolt */
3261                 case SV_HEAVY_XBOW:
3262                 {
3263                         tmul = 4;
3264                         break;
3265                 }
3266         }
3267
3268         return (tmul);
3269 }
3270
3271
3272 /*
3273  * Display a rumor and apply its effects
3274  */
3275
3276 IDX rumor_num(char *zz, IDX max_idx)
3277 {
3278         if (strcmp(zz, "*") == 0) return randint1(max_idx - 1);
3279         return (IDX)atoi(zz);
3280 }
3281
3282 concptr rumor_bind_name(char *base, concptr fullname)
3283 {
3284         char *s, *v;
3285
3286         s = strstr(base, "{Name}");
3287         if (s)
3288         {
3289                 s[0] = '\0';
3290                 v = format("%s%s%s", base, fullname, (s + 6));
3291         }
3292         else
3293         {
3294                 v = base;
3295         }
3296
3297         return v;
3298 }
3299
3300 void display_rumor(bool ex)
3301 {
3302         errr err;
3303         int section = 0;
3304         char Rumor[1024];
3305
3306         if (ex)
3307         {
3308                 if (randint0(3) == 0) section = 1;
3309         }
3310
3311         err = _(get_rnd_line_jonly("rumors_j.txt", section, Rumor, 10),
3312                         get_rnd_line("rumors.txt", section, Rumor));
3313         if (err) strcpy(Rumor, _("嘘の噂もある。", "Some rumors are wrong."));
3314
3315         err = TRUE;
3316
3317         if (strncmp(Rumor, "R:", 2) == 0)
3318         {
3319                 char *zz[4];
3320                 concptr rumor_msg = NULL;
3321                 concptr rumor_eff_format = NULL;
3322                 char fullname[1024] = "";
3323
3324                 if (tokenize(Rumor + 2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
3325                 {
3326                         if (strcmp(zz[0], "ARTIFACT") == 0)
3327                         {
3328                                 IDX a_idx, k_idx;
3329                                 object_type forge;
3330                                 object_type *q_ptr = &forge;
3331                                 artifact_type *a_ptr;
3332
3333                                 while (1)
3334                                 {
3335                                         a_idx = rumor_num(zz[1], max_a_idx);
3336
3337                                         a_ptr = &a_info[a_idx];
3338                                         if (a_ptr->name) break;
3339                                 }
3340
3341                                 k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
3342                                 object_prep(q_ptr, k_idx);
3343                                 q_ptr->name1 = a_idx;
3344                                 q_ptr->ident = IDENT_STORE;
3345                                 object_desc(fullname, q_ptr, OD_NAME_ONLY);
3346                         }
3347                         else if  (strcmp(zz[0], "MONSTER") == 0)
3348                         {
3349                                 MONRACE_IDX r_idx;
3350                                 monster_race *r_ptr;
3351
3352                                 while(1)
3353                                 {
3354                                         r_idx = rumor_num(zz[1], max_r_idx);
3355                                         r_ptr = &r_info[r_idx];
3356                                         if (r_ptr->name) break;
3357                                 }
3358
3359                                 strcpy(fullname, r_name + r_ptr->name);
3360
3361                                 /* Remember this monster */
3362                                 if (!r_ptr->r_sights)
3363                                 {
3364                                         r_ptr->r_sights++;
3365                                 }
3366                         }
3367                         else if (strcmp(zz[0], "DUNGEON") == 0)
3368                         {
3369                                 DUNGEON_IDX d_idx;
3370                                 dungeon_info_type *d_ptr;
3371
3372                                 while (1)
3373                                 {
3374                                         d_idx = rumor_num(zz[1], max_d_idx);
3375                                         d_ptr = &d_info[d_idx];
3376                                         if (d_ptr->name) break;
3377                                 }
3378
3379                                 strcpy(fullname, d_name + d_ptr->name);
3380
3381                                 if (!max_dlv[d_idx])
3382                                 {
3383                                         max_dlv[d_idx] = d_ptr->mindepth;
3384                                         rumor_eff_format = _("%sに帰還できるようになった。", "You can recall to %s.");
3385                                 }
3386                         }
3387                         else if  (strcmp(zz[0], "TOWN") == 0)
3388                         {
3389                                 IDX t_idx;
3390                                 s32b visit;
3391
3392                                 while(1)
3393                                 {
3394                                         t_idx = rumor_num(zz[1], NO_TOWN);
3395                                         if (town[t_idx].name) break;
3396                                 }
3397
3398                                 strcpy(fullname, town[t_idx].name);
3399
3400                                 visit = (1L << (t_idx - 1));
3401                                 if ((t_idx != SECRET_TOWN) && !(p_ptr->visit & visit))
3402                                 {
3403                                         p_ptr->visit |= visit;
3404                                         rumor_eff_format = _("%sに行ったことがある気がする。", "You feel you have been to %s.");
3405                                 }
3406                         }
3407
3408                         rumor_msg = rumor_bind_name(zz[2], fullname);
3409                         msg_print(rumor_msg);
3410                         if (rumor_eff_format)
3411                         {
3412                                 msg_print(NULL);
3413                                 msg_format(rumor_eff_format, fullname);
3414                         }
3415                         err = FALSE;
3416                 }
3417         /* error */
3418         if (err) msg_print(_("この情報は間違っている。", "This information is wrong."));
3419         }
3420                         else
3421         {
3422                 msg_format("%s", Rumor);
3423         }
3424 }