OSDN Git Service

[Refactor] #37353 型の置換。 / Type replacement.
[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 "monsterrace-hook.h"
18 #include "objectkind-hook.h"
19 #include "sort.h"
20 #include "projection.h"
21
22 #define REWARD_CHANCE 10
23
24
25 /*!
26  * @brief プレイヤーの経験値について整合性のためのチェックと調整を行う /
27  * Advance experience levels and print experience
28  * @return なし
29  */
30 void check_experience(void)
31 {
32         bool level_reward = FALSE;
33         bool level_mutation = FALSE;
34         bool level_inc_stat = FALSE;
35         bool android = (p_ptr->prace == RACE_ANDROID ? TRUE : FALSE);
36         PLAYER_LEVEL old_lev = p_ptr->lev;
37
38         /* Hack -- lower limit */
39         if (p_ptr->exp < 0) p_ptr->exp = 0;
40         if (p_ptr->max_exp < 0) p_ptr->max_exp = 0;
41         if (p_ptr->max_max_exp < 0) p_ptr->max_max_exp = 0;
42
43         /* Hack -- upper limit */
44         if (p_ptr->exp > PY_MAX_EXP) p_ptr->exp = PY_MAX_EXP;
45         if (p_ptr->max_exp > PY_MAX_EXP) p_ptr->max_exp = PY_MAX_EXP;
46         if (p_ptr->max_max_exp > PY_MAX_EXP) p_ptr->max_max_exp = PY_MAX_EXP;
47
48         /* Hack -- maintain "max" experience */
49         if (p_ptr->exp > p_ptr->max_exp) p_ptr->max_exp = p_ptr->exp;
50
51         /* Hack -- maintain "max max" experience */
52         if (p_ptr->max_exp > p_ptr->max_max_exp) p_ptr->max_max_exp = p_ptr->max_exp;
53
54         /* Redraw experience */
55         p_ptr->redraw |= (PR_EXP);
56         handle_stuff();
57
58
59         /* Lose levels while possible */
60         while ((p_ptr->lev > 1) &&
61                (p_ptr->exp < ((android ? player_exp_a : player_exp)[p_ptr->lev - 2] * p_ptr->expfact / 100L)))
62         {
63                 /* Lose a level */
64                 p_ptr->lev--;
65                 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
66                 p_ptr->redraw |= (PR_LEV | PR_TITLE);
67                 p_ptr->window |= (PW_PLAYER);
68                 handle_stuff();
69         }
70
71
72         /* Gain levels while possible */
73         while ((p_ptr->lev < PY_MAX_LEVEL) &&
74                (p_ptr->exp >= ((android ? player_exp_a : player_exp)[p_ptr->lev-1] * p_ptr->expfact / 100L)))
75         {
76                 /* Gain a level */
77                 p_ptr->lev++;
78
79                 /* Save the highest level */
80                 if (p_ptr->lev > p_ptr->max_plv)
81                 {
82                         p_ptr->max_plv = p_ptr->lev;
83
84                         if ((p_ptr->pclass == CLASS_CHAOS_WARRIOR) ||
85                             (p_ptr->muta2 & MUT2_CHAOS_GIFT))
86                         {
87                                 level_reward = TRUE;
88                         }
89                         if (p_ptr->prace == RACE_BEASTMAN)
90                         {
91                                 if (one_in_(5)) level_mutation = TRUE;
92                         }
93                         level_inc_stat = TRUE;
94
95                         do_cmd_write_nikki(NIKKI_LEVELUP, p_ptr->lev, NULL);
96                 }
97
98                 sound(SOUND_LEVEL);
99
100                 msg_format(_("レベル %d にようこそ。", "Welcome to level %d."), p_ptr->lev);
101
102                 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
103                 p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);
104                 p_ptr->window |= (PW_PLAYER | PW_SPELL | PW_INVEN);
105
106                 /* HPとMPの上昇量を表示 */
107                 level_up = 1;
108                 handle_stuff();
109
110                 level_up = 0;
111
112                 if (level_inc_stat)
113                 {
114                         if(!(p_ptr->max_plv % 10))
115                         {
116                                 int choice;
117                                 screen_save();
118                                 while(1)
119                                 {
120                                         int n;
121                                         char tmp[32];
122
123                                         cnv_stat(p_ptr->stat_max[0], tmp);
124                                         prt(format(_("        a) 腕力 (現在値 %s)", "        a) Str (cur %s)"), tmp), 2, 14);
125                                         cnv_stat(p_ptr->stat_max[1], tmp);
126                                         prt(format(_("        b) 知能 (現在値 %s)", "        a) Int (cur %s)"), tmp), 3, 14);
127                                         cnv_stat(p_ptr->stat_max[2], tmp);
128                                         prt(format(_("        c) 賢さ (現在値 %s)", "        a) Wis (cur %s)"), tmp), 4, 14);
129                                         cnv_stat(p_ptr->stat_max[3], tmp);
130                                         prt(format(_("        d) 器用 (現在値 %s)", "        a) Dex (cur %s)"), tmp), 5, 14);
131                                         cnv_stat(p_ptr->stat_max[4], tmp);
132                                         prt(format(_("        e) 耐久 (現在値 %s)", "        a) Con (cur %s)"), tmp), 6, 14);
133                                         cnv_stat(p_ptr->stat_max[5], tmp);
134                                         prt(format(_("        f) 魅力 (現在値 %s)", "        a) Chr (cur %s)"), tmp), 7, 14);
135
136                                         prt("", 8, 14);
137                                         prt(_("        どの能力値を上げますか?", "        Which stat do you want to raise?"), 1, 14);
138
139                                         while(1)
140                                         {
141                                                 choice = inkey();
142                                                 if ((choice >= 'a') && (choice <= 'f')) break;
143                                         }
144                                         for(n = 0; n < A_MAX; n++)
145                                                 if (n != choice - 'a')
146                                                         prt("",n+2,14);
147                                         if (get_check(_("よろしいですか?", "Are you sure? "))) break;
148                                 }
149                                 do_inc_stat(choice - 'a');
150                                 screen_load();
151                         }
152                         else if(!(p_ptr->max_plv % 2))
153                                 do_inc_stat(randint0(6));
154                 }
155
156                 if (level_mutation)
157                 {
158                         msg_print(_("あなたは変わった気がする...", "You feel different..."));
159                         (void)gain_random_mutation(0);
160                         level_mutation = FALSE;
161                 }
162
163                 /*
164                  * 報酬でレベルが上ると再帰的に check_experience() が
165                  * 呼ばれるので順番を最後にする。
166                  */
167                 if (level_reward)
168                 {
169                         gain_level_reward(0);
170                         level_reward = FALSE;
171                 }
172
173                 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
174                 p_ptr->redraw |= (PR_LEV | PR_TITLE);
175                 p_ptr->window |= (PW_PLAYER | PW_SPELL);
176                 handle_stuff();
177         }
178
179         /* Load an autopick preference file */
180         if (old_lev != p_ptr->lev) autopick_load_pref(FALSE);
181 }
182
183
184
185 /*!
186  * @brief クエストを達成状態にする /
187  * @param quest_num 達成状態にしたいクエストのID
188  * @return なし
189  */
190 void complete_quest(QUEST_IDX quest_num)
191 {
192         quest_type* const q_ptr = &quest[quest_num];
193
194         switch (q_ptr->type)
195         {
196         case QUEST_TYPE_RANDOM:
197                 if (record_rand_quest) do_cmd_write_nikki(NIKKI_RAND_QUEST_C, quest_num, NULL);
198                 break;
199         default:
200                 if (record_fix_quest) do_cmd_write_nikki(NIKKI_FIX_QUEST_C, quest_num, NULL);
201                 break;
202         }
203
204         q_ptr->status = QUEST_STATUS_COMPLETED;
205         q_ptr->complev = p_ptr->lev;
206         update_playtime();
207         q_ptr->comptime = playtime;
208
209         if (!(q_ptr->flags & QUEST_FLAG_SILENT))
210         {
211                 play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_QUEST_CLEAR);
212                 msg_print(_("クエストを達成した!", "You just completed your quest!"));
213                 msg_print(NULL);
214         }
215 }
216
217 /*!
218  * @brief 現在フロアに残っている敵モンスターの数を返す /
219  * @return 現在の敵モンスターの数
220  */
221 static MONSTER_NUMBER count_all_hostile_monsters(void)
222 {
223         POSITION x, y;
224         MONSTER_NUMBER number_mon = 0;
225
226         for (x = 0; x < cur_wid; ++ x)
227         {
228                 for (y = 0; y < cur_hgt; ++ y)
229                 {
230                         MONSTER_IDX m_idx = cave[y][x].m_idx;
231
232                         if (m_idx > 0 && is_hostile(&m_list[m_idx]))
233                         {
234                                 ++number_mon;
235                         }
236                 }
237         }
238
239         return number_mon;
240 }
241
242 /*!
243  * @brief 特定の敵を倒した際にクエスト達成処理 /
244  * Check for "Quest" completion when a quest monster is killed or charmed.
245  * @param m_ptr 撃破したモンスターの構造体参照ポインタ
246  * @return なし
247  */
248 void check_quest_completion(monster_type *m_ptr)
249 {
250         POSITION y, x;
251         QUEST_IDX quest_num;
252
253         bool create_stairs = FALSE;
254         bool reward = FALSE;
255
256         object_type forge;
257         object_type *o_ptr;
258
259         y = m_ptr->fy;
260         x = m_ptr->fx;
261
262         /* Inside a quest */
263         quest_num = p_ptr->inside_quest;
264
265         /* Search for an active quest on this dungeon level */
266         if (!quest_num)
267         {
268                 QUEST_IDX i;
269
270                 for (i = max_q_idx - 1; i > 0; i--)
271                 {
272                         quest_type* const q_ptr = &quest[i];
273                         
274                         /* Quest is not active */
275                         if (q_ptr->status != QUEST_STATUS_TAKEN)
276                                 continue;
277
278                         /* Quest is not a dungeon quest */
279                         if (q_ptr->flags & QUEST_FLAG_PRESET)
280                                 continue;
281
282                         /* Quest is not on this level */
283                         if ((q_ptr->level != dun_level) &&
284                             (q_ptr->type != QUEST_TYPE_KILL_ANY_LEVEL))
285                                 continue;
286
287                         /* Not a "kill monster" quest */
288                         if ((q_ptr->type == QUEST_TYPE_FIND_ARTIFACT) ||
289                             (q_ptr->type == QUEST_TYPE_FIND_EXIT))
290                                 continue;
291
292                         /* Interesting quest */
293                         if ((q_ptr->type == QUEST_TYPE_KILL_NUMBER) ||
294                             (q_ptr->type == QUEST_TYPE_TOWER) ||
295                             (q_ptr->type == QUEST_TYPE_KILL_ALL))
296                                 break;
297
298                         /* Interesting quest */
299                         if (((q_ptr->type == QUEST_TYPE_KILL_LEVEL) ||
300                              (q_ptr->type == QUEST_TYPE_KILL_ANY_LEVEL) ||
301                              (q_ptr->type == QUEST_TYPE_RANDOM)) &&
302                              (q_ptr->r_idx == m_ptr->r_idx))
303                                 break;
304                 }
305
306                 quest_num = i;
307         }
308
309         /* Handle the current quest */
310         if (quest_num && (quest[quest_num].status == QUEST_STATUS_TAKEN))
311         {
312                 /* Current quest */
313                 quest_type* const q_ptr = &quest[quest_num];
314
315                 switch (q_ptr->type)
316                 {
317                         case QUEST_TYPE_KILL_NUMBER:
318                         {
319                                 q_ptr->cur_num++;
320
321                                 if (q_ptr->cur_num >= q_ptr->num_mon)
322                                 {
323                                         complete_quest(quest_num);
324
325                                         q_ptr->cur_num = 0;
326                                 }
327                                 break;
328                         }
329                         case QUEST_TYPE_KILL_ALL:
330                         {
331                                 if (!is_hostile(m_ptr)) break;
332
333                                 if (count_all_hostile_monsters() == 1)
334                                 {
335                                         if (q_ptr->flags & QUEST_FLAG_SILENT)
336                                         {
337                                                 q_ptr->status = QUEST_STATUS_FINISHED;
338                                         }
339                                         else
340                                         {
341                                                 complete_quest(quest_num);
342                                         }
343                                 }
344                                 break;
345                         }
346                         case QUEST_TYPE_KILL_LEVEL:
347                         case QUEST_TYPE_RANDOM:
348                         {
349                                 /* Only count valid monsters */
350                                 if (q_ptr->r_idx != m_ptr->r_idx)
351                                         break;
352
353                                 q_ptr->cur_num++;
354
355                                 if (q_ptr->cur_num >= q_ptr->max_num)
356                                 {
357                                         complete_quest(quest_num);
358
359                                         if (!(q_ptr->flags & QUEST_FLAG_PRESET))
360                                         {
361                                                 create_stairs = TRUE;
362                                                 p_ptr->inside_quest = 0;
363                                         }
364
365                                         /* Finish the two main quests without rewarding */
366                                         if ((quest_num == QUEST_OBERON) || (quest_num == QUEST_SERPENT))
367                                         {
368                                                 q_ptr->status = QUEST_STATUS_FINISHED;
369                                         }
370
371                                         if (q_ptr->type == QUEST_TYPE_RANDOM)
372                                         {
373                                                 reward = TRUE;
374                                                 q_ptr->status = QUEST_STATUS_FINISHED;
375                                         }
376                                 }
377                                 break;
378                         }
379                         case QUEST_TYPE_KILL_ANY_LEVEL:
380                         {
381                                 q_ptr->cur_num++;
382                                 if (q_ptr->cur_num >= q_ptr->max_num)
383                                 {
384                                         complete_quest(quest_num);
385                                         q_ptr->cur_num = 0;
386                                 }
387                                 break;
388                         }
389                         case QUEST_TYPE_TOWER:
390                         {
391                                 if (!is_hostile(m_ptr)) break;
392
393                                 if (count_all_hostile_monsters() == 1)
394                                 {
395                                         q_ptr->status = QUEST_STATUS_STAGE_COMPLETED;
396
397                                         if((quest[QUEST_TOWER1].status == QUEST_STATUS_STAGE_COMPLETED) &&
398                                            (quest[QUEST_TOWER2].status == QUEST_STATUS_STAGE_COMPLETED) &&
399                                            (quest[QUEST_TOWER3].status == QUEST_STATUS_STAGE_COMPLETED))
400                                         {
401
402                                                 complete_quest(QUEST_TOWER1);
403                                         }
404                                 }
405                                 break;
406                         }
407                 }
408         }
409
410         /* Create a magical staircase */
411         if (create_stairs)
412         {
413                 POSITION ny, nx;
414
415                 /* Stagger around */
416                 while (cave_perma_bold(y, x) || cave[y][x].o_idx || (cave[y][x].info & CAVE_OBJECT) )
417                 {
418                         /* Pick a location */
419                         scatter(&ny, &nx, y, x, 1, 0);
420
421                         /* Stagger */
422                         y = ny; x = nx;
423                 }
424
425                 /* Explain the staircase */
426                 msg_print(_("魔法の階段が現れた...", "A magical staircase appears..."));
427
428                 /* Create stairs down */
429                 cave_set_feat(y, x, feat_down_stair);
430
431                 /* Remember to update everything */
432                 p_ptr->update |= (PU_FLOW);
433         }
434
435         /*
436          * Drop quest reward
437          */
438         if (reward)
439         {
440                 int i;
441
442                 for (i = 0; i < (dun_level / 15)+1; i++)
443                 {
444                         o_ptr = &forge;
445                         object_wipe(o_ptr);
446
447                         /* Make a great object */
448                         make_object(o_ptr, AM_GOOD | AM_GREAT);
449                         (void)drop_near(o_ptr, -1, y, x);
450                 }
451         }
452 }
453
454 /*!
455  * @brief 特定のアーティファクトを入手した際のクエスト達成処理 /
456  * Check for "Quest" completion when a quest monster is killed or charmed.
457  * @param o_ptr 入手したオブジェクトの構造体参照ポインタ
458  * @return なし
459  */
460 void check_find_art_quest_completion(object_type *o_ptr)
461 {
462         QUEST_IDX i;
463         /* Check if completed a quest */
464         for (i = 0; i < max_q_idx; i++)
465         {
466                 if((quest[i].type == QUEST_TYPE_FIND_ARTIFACT) &&
467                         (quest[i].status == QUEST_STATUS_TAKEN) &&
468                         (quest[i].k_idx == o_ptr->name1))
469                 {
470                         complete_quest(i);
471                 }
472         }
473 }
474
475
476 /*!
477  * @brief モンスターを撃破した際の述語メッセージを返す /
478  * Return monster death string
479  * @param r_ptr 撃破されたモンスターの種族情報を持つ構造体の参照ポインタ
480  * @return 撃破されたモンスターの述語
481  */
482 concptr extract_note_dies(MONRACE_IDX r_idx)
483 {
484         monster_race *r_ptr = &r_info[r_idx];
485         /* Some monsters get "destroyed" */
486         if (!monster_living(r_idx))
487         {
488                 int i;
489
490                 for (i = 0; i < 4; i++)
491                 {
492                         if (r_ptr->blow[i].method == RBM_EXPLODE)
493                         {
494                                 return _("は爆発して粉々になった。", " explodes into tiny shreds.");
495                         }
496                 }
497                 return _("を倒した。", " is destroyed.");
498         }
499
500         /* Assume a default death */
501         return _("は死んだ。", " dies.");
502 }
503
504
505 /*!
506  * @brief モンスターに与えたダメージの修正処理 /
507  * Modify the physical damage done to the monster.
508  * @param m_ptr ダメージを受けるモンスターの構造体参照ポインタ
509  * @param dam ダメージ基本値
510  * @param is_psy_spear 攻撃手段が光の剣ならばTRUE
511  * @return 修正を行った結果のダメージ量
512  * @details
513  * <pre>
514  * (for example when it's invulnerable or shielded)
515  * ToDo: Accept a damage-type to calculate the modified damage from
516  * things like fire, frost, lightning, poison, ... attacks.
517  * "type" is not yet used and should be 0.
518  * </pre>
519  */
520 HIT_POINT mon_damage_mod(monster_type *m_ptr, HIT_POINT dam, bool is_psy_spear)
521 {
522         monster_race    *r_ptr = &r_info[m_ptr->r_idx];
523
524         if ((r_ptr->flagsr & RFR_RES_ALL) && dam > 0)
525         {
526                 dam /= 100;
527                 if ((dam == 0) && one_in_(3)) dam = 1;
528         }
529
530         if (MON_INVULNER(m_ptr))
531         {
532                 if (is_psy_spear)
533                 {
534                         if (!p_ptr->blind && is_seen(m_ptr))
535                         {
536                                 msg_print(_("バリアを切り裂いた!", "The barrier is penetrated!"));
537                         }
538                 }
539                 else if (!one_in_(PENETRATE_INVULNERABILITY))
540                 {
541                         return (0);
542                 }
543         }
544         return (dam);
545 }
546
547
548 /*!
549  * @brief モンスターに与えたダメージを元に経験値を加算する /
550  * Calculate experience point to be get
551  * @param dam 与えたダメージ量
552  * @param m_ptr ダメージを与えたモンスターの構造体参照ポインタ
553  * @return なし
554  * @details
555  * <pre>
556  * Even the 64 bit operation is not big enough to avoid overflaw
557  * unless we carefully choose orders of multiplication and division.
558  * Get the coefficient first, and multiply (potentially huge) base
559  * experience point of a monster later.
560  * </pre>
561  */
562 static void get_exp_from_mon(HIT_POINT dam, monster_type *m_ptr)
563 {
564         monster_race *r_ptr = &r_info[m_ptr->r_idx];
565
566         s32b new_exp;
567         u32b new_exp_frac;
568         s32b div_h;
569         u32b div_l;
570
571         if (!m_ptr->r_idx) return;
572         if (is_pet(m_ptr) || p_ptr->inside_battle) return;
573
574         /*
575          * - Ratio of monster's level to player's level effects
576          * - Varying speed effects
577          * - Get a fraction in proportion of damage point
578          */
579         new_exp = r_ptr->level * SPEED_TO_ENERGY(m_ptr->mspeed) * dam;
580         new_exp_frac = 0;
581         div_h = 0L;
582         div_l = (p_ptr->max_plv+2) * SPEED_TO_ENERGY(r_ptr->speed);
583
584         /* Use (average maxhp * 2) as a denominator */
585         if (!(r_ptr->flags1 & RF1_FORCE_MAXHP))
586                 s64b_mul(&div_h, &div_l, 0, r_ptr->hdice * (ironman_nightmare ? 2 : 1) * (r_ptr->hside + 1));
587         else
588                 s64b_mul(&div_h, &div_l, 0, r_ptr->hdice * (ironman_nightmare ? 2 : 1) * r_ptr->hside * 2);
589
590         /* Special penalty in the wilderness */
591         if (!dun_level && (!(r_ptr->flags8 & RF8_WILD_ONLY) || !(r_ptr->flags1 & RF1_UNIQUE)))
592                 s64b_mul(&div_h, &div_l, 0, 5);
593
594         /* Do division first to prevent overflaw */
595         s64b_div(&new_exp, &new_exp_frac, div_h, div_l);
596
597         /* Special penalty for mutiply-monster */
598         if ((r_ptr->flags2 & RF2_MULTIPLY) || (m_ptr->r_idx == MON_DAWN))
599         {
600                 int monnum_penarty = r_ptr->r_akills / 400;
601                 if (monnum_penarty > 8) monnum_penarty = 8;
602
603                 while (monnum_penarty--)
604                 {
605                         /* Divide by 4 */
606                         s64b_RSHIFT(new_exp, new_exp_frac, 2);
607                 }
608         }
609         
610         /* Special penalty for rest_and_shoot exp scum */
611         if ((m_ptr->dealt_damage > m_ptr->max_maxhp) && (m_ptr->hp >= 0))
612         {
613                 int over_damage = m_ptr->dealt_damage / m_ptr->max_maxhp;
614                 if (over_damage > 32) over_damage = 32;
615
616                 while (over_damage--)
617                 {
618                         /* 9/10 for once */
619                         s64b_mul(&new_exp, &new_exp_frac, 0, 9);
620                         s64b_div(&new_exp, &new_exp_frac, 0, 10);
621                 }
622         }
623
624         /* Finally multiply base experience point of the monster */
625         s64b_mul(&new_exp, &new_exp_frac, 0, r_ptr->mexp);
626
627         /* Gain experience */
628         gain_exp_64(new_exp, new_exp_frac);
629 }
630
631
632 /*!
633  * @brief モンスターのHPをダメージに応じて減算する /
634  * Decreases monsters hit points, handling monster death.
635  * @param dam 与えたダメージ量
636  * @param m_idx ダメージを与えたモンスターのID
637  * @param fear ダメージによってモンスターが恐慌状態に陥ったならばTRUEを返す
638  * @param note モンスターが倒された際の特別なメッセージ述語
639  * @return なし
640  * @details
641  * <pre>
642  * We return TRUE if the monster has been killed (and deleted).
643  * We announce monster death (using an optional "death message"
644  * if given, and a otherwise a generic killed/destroyed message).
645  * Only "physical attacks" can induce the "You have slain" message.
646  * Missile and Spell attacks will induce the "dies" message, or
647  * various "specialized" messages.  Note that "You have destroyed"
648  * and "is destroyed" are synonyms for "You have slain" and "dies".
649  * Hack -- unseen monsters yield "You have killed it." message.
650  * Added fear (DGK) and check whether to print fear messages -CWS
651  * Made name, sex, and capitalization generic -BEN-
652  * As always, the "ghost" processing is a total hack.
653  * Hack -- we "delay" fear messages by passing around a "fear" flag.
654  * Consider decreasing monster experience over time, say,
655  * by using "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))"
656  * instead of simply "(m_exp * m_lev) / (p_lev)", to make the first
657  * monster worth more than subsequent monsters.  This would also need
658  * to induce changes in the monster recall code.
659  * </pre>
660  */
661 bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
662 {
663         monster_type *m_ptr = &m_list[m_idx];
664         monster_race *r_ptr = &r_info[m_ptr->r_idx];
665         monster_type exp_mon;
666
667         /* Innocent until proven otherwise */
668         bool innocent = TRUE, thief = FALSE;
669         int i;
670         HIT_POINT expdam;
671
672         (void)COPY(&exp_mon, m_ptr, monster_type);
673         
674         expdam = (m_ptr->hp > dam) ? dam : m_ptr->hp;
675
676         get_exp_from_mon(expdam, &exp_mon);
677
678         /* Genocided by chaos patron */
679         if (!m_ptr->r_idx) m_idx = 0;
680         
681         /* Redraw (later) if needed */
682         if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
683         if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
684
685         (void)set_monster_csleep(m_idx, 0);
686
687         /* Hack - Cancel any special player stealth magics. -LM- */
688         if (p_ptr->special_defense & NINJA_S_STEALTH)
689         {
690                 set_superstealth(FALSE);
691         }
692
693         /* Genocided by chaos patron */
694         if (!m_idx) return TRUE;
695         
696         m_ptr->hp -= dam;
697         m_ptr->dealt_damage += dam;
698
699         if(m_ptr->dealt_damage > m_ptr->max_maxhp * 100) m_ptr->dealt_damage = m_ptr->max_maxhp * 100;
700
701         if (p_ptr->wizard)
702         {
703                 msg_format( _("合計%d/%dのダメージを与えた。","You do %d (out of %d) damage."), m_ptr->dealt_damage, m_ptr->maxhp);
704         }
705
706         /* It is dead now */
707         if (m_ptr->hp < 0)
708         {
709                 GAME_TEXT m_name[MAX_NLEN];
710
711                 if (r_info[m_ptr->r_idx].flags7 & RF7_TANUKI)
712                 {
713                         /* You might have unmasked Tanuki first time */
714                         r_ptr = &r_info[m_ptr->r_idx];
715                         m_ptr->ap_r_idx = m_ptr->r_idx;
716                         if (r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++;
717                 }
718
719                 if (m_ptr->mflag2 & MFLAG2_CHAMELEON)
720                 {
721                         /* You might have unmasked Chameleon first time */
722                         r_ptr = real_r_ptr(m_ptr);
723                         if (r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++;
724                 }
725
726                 if (!(m_ptr->smart & SM_CLONED))
727                 {
728                         /* When the player kills a Unique, it stays dead */
729                         if (r_ptr->flags1 & RF1_UNIQUE)
730                         {
731                                 r_ptr->max_num = 0;
732
733                                 /* Mega-Hack -- Banor & Lupart */
734                                 if ((m_ptr->r_idx == MON_BANOR) || (m_ptr->r_idx == MON_LUPART))
735                                 {
736                                         r_info[MON_BANORLUPART].max_num = 0;
737                                         r_info[MON_BANORLUPART].r_pkills++;
738                                         r_info[MON_BANORLUPART].r_akills++;
739                                         if (r_info[MON_BANORLUPART].r_tkills < MAX_SHORT) r_info[MON_BANORLUPART].r_tkills++;
740                                 }
741                                 else if (m_ptr->r_idx == MON_BANORLUPART)
742                                 {
743                                         r_info[MON_BANOR].max_num = 0;
744                                         r_info[MON_BANOR].r_pkills++;
745                                         r_info[MON_BANOR].r_akills++;
746                                         if (r_info[MON_BANOR].r_tkills < MAX_SHORT) r_info[MON_BANOR].r_tkills++;
747                                         r_info[MON_LUPART].max_num = 0;
748                                         r_info[MON_LUPART].r_pkills++;
749                                         r_info[MON_LUPART].r_akills++;
750                                         if (r_info[MON_LUPART].r_tkills < MAX_SHORT) r_info[MON_LUPART].r_tkills++;
751                                 }
752                         }
753
754                         /* When the player kills a Nazgul, it stays dead */
755                         else if (r_ptr->flags7 & RF7_NAZGUL) r_ptr->max_num--;
756                 }
757
758                 /* Count all monsters killed */
759                 if (r_ptr->r_akills < MAX_SHORT) r_ptr->r_akills++;
760
761                 /* Recall even invisible uniques or winners */
762                 if ((m_ptr->ml && !p_ptr->image) || (r_ptr->flags1 & RF1_UNIQUE))
763                 {
764                         /* Count kills this life */
765                         if ((m_ptr->mflag2 & MFLAG2_KAGE) && (r_info[MON_KAGE].r_pkills < MAX_SHORT)) r_info[MON_KAGE].r_pkills++;
766                         else if (r_ptr->r_pkills < MAX_SHORT) r_ptr->r_pkills++;
767
768                         /* Count kills in all lives */
769                         if ((m_ptr->mflag2 & MFLAG2_KAGE) && (r_info[MON_KAGE].r_tkills < MAX_SHORT)) r_info[MON_KAGE].r_tkills++;
770                         else if (r_ptr->r_tkills < MAX_SHORT) r_ptr->r_tkills++;
771
772                         /* Hack -- Auto-recall */
773                         monster_race_track(m_ptr->ap_r_idx);
774                 }
775
776                 /* Extract monster name */
777                 monster_desc(m_name, m_ptr, MD_TRUE_NAME);
778
779                 /* Don't kill Amberites */
780                 if ((r_ptr->flags3 & RF3_AMBERITE) && one_in_(2))
781                 {
782                         int curses = 1 + randint1(3);
783                         bool stop_ty = FALSE;
784                         int count = 0;
785
786                         msg_format(_("%^sは恐ろしい血の呪いをあなたにかけた!", "%^s puts a terrible blood curse on you!"), m_name);
787                         curse_equipment(100, 50);
788
789                         do
790                         {
791                                 stop_ty = activate_ty_curse(stop_ty, &count);
792                         }
793                         while (--curses);
794                 }
795
796                 if (r_ptr->flags2 & RF2_CAN_SPEAK)
797                 {
798                         char line_got[1024];
799                         if (!get_rnd_line(_("mondeath_j.txt", "mondeath.txt"), m_ptr->r_idx, line_got))
800                         {
801                                 msg_format("%^s %s", m_name, line_got);
802                         }
803
804 #ifdef WORLD_SCORE
805                         if (m_ptr->r_idx == MON_SERPENT)
806                         {
807                                 screen_dump = make_screen_dump();
808                         }
809 #endif
810                 }
811
812                 if (!(d_info[dungeon_type].flags1 & DF1_BEGINNER))
813                 {
814                         if (!dun_level && !ambush_flag && !p_ptr->inside_arena)
815                         {
816                                 chg_virtue(V_VALOUR, -1);
817                         }
818                         else if (r_ptr->level > dun_level)
819                         {
820                                 if (randint1(10) <= (r_ptr->level - dun_level))
821                                         chg_virtue(V_VALOUR, 1);
822                         }
823                         if (r_ptr->level > 60)
824                         {
825                                 chg_virtue(V_VALOUR, 1);
826                         }
827                         if (r_ptr->level >= 2 * (p_ptr->lev+1))
828                                 chg_virtue(V_VALOUR, 2);
829                 }
830
831                 if (r_ptr->flags1 & RF1_UNIQUE)
832                 {
833                         if (r_ptr->flags3 & (RF3_EVIL | RF3_GOOD)) chg_virtue(V_HARMONY, 2);
834
835                         if (r_ptr->flags3 & RF3_GOOD)
836                         {
837                                 chg_virtue(V_UNLIFE, 2);
838                                 chg_virtue(V_VITALITY, -2);
839                         }
840
841                         if (one_in_(3)) chg_virtue(V_INDIVIDUALISM, -1);
842                 }
843
844                 if (m_ptr->r_idx == MON_BEGGAR || m_ptr->r_idx == MON_LEPER)
845                 {
846                         chg_virtue(V_COMPASSION, -1);
847                 }
848
849                 if ((r_ptr->flags3 & RF3_GOOD) && ((r_ptr->level) / 10 + (3 * dun_level) >= randint1(100)))
850                         chg_virtue(V_UNLIFE, 1);
851
852                 if (r_ptr->d_char == 'A')
853                 {
854                         if (r_ptr->flags1 & RF1_UNIQUE)
855                                 chg_virtue(V_FAITH, -2);
856                         else if ((r_ptr->level) / 10 + (3 * dun_level) >= randint1(100))
857                         {
858                                 if (r_ptr->flags3 & RF3_GOOD) chg_virtue(V_FAITH, -1);
859                                 else chg_virtue(V_FAITH, 1);
860                         }
861                 }
862                 else if (r_ptr->flags3 & RF3_DEMON)
863                 {
864                         if (r_ptr->flags1 & RF1_UNIQUE)
865                                 chg_virtue(V_FAITH, 2);
866                         else if ((r_ptr->level) / 10 + (3 * dun_level) >= randint1(100))
867                                 chg_virtue(V_FAITH, 1);
868                 }
869
870                 if ((r_ptr->flags3 & RF3_UNDEAD) && (r_ptr->flags1 & RF1_UNIQUE))
871                         chg_virtue(V_VITALITY, 2);
872
873                 if (r_ptr->r_deaths)
874                 {
875                         if (r_ptr->flags1 & RF1_UNIQUE)
876                         {
877                                 chg_virtue(V_HONOUR, 10);
878                         }
879                         else if ((r_ptr->level) / 10 + (2 * dun_level) >= randint1(100))
880                         {
881                                 chg_virtue(V_HONOUR, 1);
882                         }
883                 }
884                 if ((r_ptr->flags2 & RF2_MULTIPLY) && (r_ptr->r_akills > 1000) && one_in_(10))
885                 {
886                         chg_virtue(V_VALOUR, -1);
887                 }
888
889                 for (i = 0; i < 4; i++)
890                 {
891                         if (r_ptr->blow[i].d_dice != 0) innocent = FALSE; /* Murderer! */
892
893                         if ((r_ptr->blow[i].effect == RBE_EAT_ITEM)
894                                 || (r_ptr->blow[i].effect == RBE_EAT_GOLD))
895
896                                 thief = TRUE; /* Thief! */
897                 }
898
899                 /* The new law says it is illegal to live in the dungeon */
900                 if (r_ptr->level != 0) innocent = FALSE;
901
902                 if (thief)
903                 {
904                         if (r_ptr->flags1 & RF1_UNIQUE)
905                                 chg_virtue(V_JUSTICE, 3);
906                         else if (1+((r_ptr->level) / 10 + (2 * dun_level)) >= randint1(100))
907                                 chg_virtue(V_JUSTICE, 1);
908                 }
909                 else if (innocent)
910                 {
911                         chg_virtue (V_JUSTICE, -1);
912                 }
913
914                 if ((r_ptr->flags3 & RF3_ANIMAL) && !(r_ptr->flags3 & RF3_EVIL) && !(r_ptr->flags4 & ~(RF4_NOMAGIC_MASK))  && !(r_ptr->a_ability_flags1 & ~(RF5_NOMAGIC_MASK)) && !(r_ptr->a_ability_flags2 & ~(RF6_NOMAGIC_MASK)))
915                 {
916                         if (one_in_(4)) chg_virtue(V_NATURE, -1);
917                 }
918
919                 if ((r_ptr->flags1 & RF1_UNIQUE) && record_destroy_uniq)
920                 {
921                         char note_buf[160];
922                         sprintf(note_buf, "%s%s", r_name + r_ptr->name, (m_ptr->smart & SM_CLONED) ? _("(クローン)", "(Clone)") : "");
923                         do_cmd_write_nikki(NIKKI_UNIQUE, 0, note_buf);
924                 }
925
926                 /* Make a sound */
927                 sound(SOUND_KILL);
928
929                 /* Death by Missile/Spell attack */
930                 if (note)
931                 {
932                         msg_format("%^s%s", m_name, note);
933                 }
934
935                 /* Death by physical attack -- invisible monster */
936                 else if (!m_ptr->ml)
937                 {
938 #ifdef JP
939                         if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
940                                 msg_format("せっかくだから%sを殺した。", m_name);
941                         else
942                                 msg_format("%sを殺した。", m_name);
943 #else
944                                 msg_format("You have killed %s.", m_name);
945 #endif
946
947                 }
948
949                 /* Death by Physical attack -- non-living monster */
950                 else if (!monster_living(m_ptr->r_idx))
951                 {
952                         bool explode = FALSE;
953
954                         for (i = 0; i < 4; i++)
955                         {
956                                 if (r_ptr->blow[i].method == RBM_EXPLODE) explode = TRUE;
957                         }
958
959                         /* Special note at death */
960                         if (explode)
961                                 msg_format(_("%sは爆発して粉々になった。", "%^s explodes into tiny shreds."), m_name);
962                         else
963                         {
964 #ifdef JP
965                                 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
966                                         msg_format("せっかくだから%sを倒した。", m_name);
967                                 else
968                                 msg_format("%sを倒した。", m_name);
969 #else
970                                 msg_format("You have destroyed %s.", m_name);
971 #endif
972                         }
973                 }
974
975                 /* Death by Physical attack -- living monster */
976                 else
977                 {
978 #ifdef JP
979                         if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
980                                 msg_format("せっかくだから%sを葬り去った。", m_name);
981                         else
982                                 msg_format("%sを葬り去った。", m_name);
983 #else
984                                 msg_format("You have slain %s.", m_name);
985 #endif
986
987                 }
988                 if ((r_ptr->flags1 & RF1_UNIQUE) && !(m_ptr->smart & SM_CLONED) && !vanilla_town)
989                 {
990                         for (i = 0; i < MAX_KUBI; i++)
991                         {
992                                 if ((kubi_r_idx[i] == m_ptr->r_idx) && !(m_ptr->mflag2 & MFLAG2_CHAMELEON))
993                                 {
994                                         msg_format(_("%sの首には賞金がかかっている。", "There is a price on %s's head."), m_name);
995                                         break;
996                                 }
997                         }
998                 }
999
1000                 /* Generate treasure */
1001                 monster_death(m_idx, TRUE);
1002
1003                 /* Mega hack : replace IKETA to BIKETAL */
1004                 if ((m_ptr->r_idx == MON_IKETA) && !(p_ptr->inside_arena || p_ptr->inside_battle))
1005                 {
1006                         POSITION dummy_y = m_ptr->fy;
1007                         POSITION dummy_x = m_ptr->fx;
1008                         BIT_FLAGS mode = 0L;
1009                         if (is_pet(m_ptr)) mode |= PM_FORCE_PET;
1010                         delete_monster_idx(m_idx);
1011                         if (summon_named_creature(0, dummy_y, dummy_x, MON_BIKETAL, mode))
1012                         {
1013                                 msg_print(_("「ハァッハッハッハ!!私がバイケタルだ!!」", "Uwa-hahaha!  *I* am Biketal!"));
1014                         }
1015                 }
1016                 else
1017                 {
1018                         delete_monster_idx(m_idx);
1019                 }
1020
1021                 get_exp_from_mon((long)exp_mon.max_maxhp*2, &exp_mon);
1022
1023                 /* Not afraid */
1024                 (*fear) = FALSE;
1025
1026                 /* Monster is dead */
1027                 return (TRUE);
1028         }
1029
1030
1031 #ifdef ALLOW_FEAR
1032
1033         /* Mega-Hack -- Pain cancels fear */
1034         if (MON_MONFEAR(m_ptr) && (dam > 0))
1035         {
1036                 /* Cure fear */
1037                 if (set_monster_monfear(m_idx, MON_MONFEAR(m_ptr) - randint1(dam)))
1038                 {
1039                         /* No more fear */
1040                         (*fear) = FALSE;
1041                 }
1042         }
1043
1044         /* Sometimes a monster gets scared by damage */
1045         if (!MON_MONFEAR(m_ptr) && !(r_ptr->flags3 & (RF3_NO_FEAR)))
1046         {
1047                 /* Percentage of fully healthy */
1048                 int percentage = (100L * m_ptr->hp) / m_ptr->maxhp;
1049
1050                 /*
1051                  * Run (sometimes) if at 10% or less of max hit points,
1052                  * or (usually) when hit for half its current hit points
1053                  */
1054                 if ((randint1(10) >= percentage) || ((dam >= m_ptr->hp) && (randint0(100) < 80)))
1055                 {
1056                         /* Hack -- note fear */
1057                         (*fear) = TRUE;
1058
1059                         /* Hack -- Add some timed fear */
1060                         (void)set_monster_monfear(m_idx, (randint1(10) +
1061                                           (((dam >= m_ptr->hp) && (percentage > 7)) ?
1062                                            20 : ((11 - percentage) * 5))));
1063                 }
1064         }
1065
1066 #endif
1067
1068         /* Not dead yet */
1069         return (FALSE);
1070 }
1071
1072
1073 /*!
1074  * @brief 現在のコンソール表示の縦横を返す。 /
1075  * Get term size and calculate screen size
1076  * @param wid_p コンソールの表示幅文字数を返す
1077  * @param hgt_p コンソールの表示行数を返す
1078  * @return なし
1079  */
1080 void get_screen_size(TERM_LEN *wid_p, TERM_LEN *hgt_p)
1081 {
1082         Term_get_size(wid_p, hgt_p);
1083         *hgt_p -= ROW_MAP + 2;
1084         *wid_p -= COL_MAP + 2;
1085         if (use_bigtile) *wid_p /= 2;
1086 }
1087
1088
1089 /*!
1090  * @brief コンソール上におけるマップ表示の左上位置を返す /
1091  * Calculates current boundaries Called below and from "do_cmd_locate()".
1092  * @return なし
1093  */
1094 void panel_bounds_center(void)
1095 {
1096         TERM_LEN wid, hgt;
1097
1098         get_screen_size(&wid, &hgt);
1099
1100         panel_row_max = panel_row_min + hgt - 1;
1101         panel_row_prt = panel_row_min - 1;
1102         panel_col_max = panel_col_min + wid - 1;
1103         panel_col_prt = panel_col_min - 13;
1104 }
1105
1106
1107 /*!
1108  * @brief コンソールのリサイズに合わせてマップを再描画する /
1109  * Map resizing whenever the main term changes size
1110  * @return なし
1111  */
1112 void resize_map(void)
1113 {
1114         /* Only if the dungeon exists */
1115         if (!character_dungeon) return;
1116         
1117         /* Mega-Hack -- no panel yet */
1118         panel_row_max = 0;
1119         panel_col_max = 0;
1120
1121         /* Reset the panels */
1122         panel_row_min = cur_hgt;
1123         panel_col_min = cur_wid;
1124                                 
1125         verify_panel();
1126
1127         p_ptr->update |= (PU_TORCH | PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1128         p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1129         p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1130         p_ptr->update |= (PU_MONSTERS);
1131         p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1132
1133         handle_stuff();
1134         Term_redraw();
1135
1136         /*
1137          * Waiting command;
1138          * Place the cursor on the player
1139          */
1140         if (can_save) move_cursor_relative(p_ptr->y, p_ptr->x);
1141
1142         Term_fresh();
1143 }
1144
1145 /*!
1146  * @brief コンソールを再描画する /
1147  * Redraw a term when it is resized
1148  * @return なし
1149  */
1150 void redraw_window(void)
1151 {
1152         /* Only if the dungeon exists */
1153         if (!character_dungeon) return;
1154
1155         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1156         p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1157
1158         handle_stuff();
1159         Term_redraw();
1160 }
1161
1162
1163 /*!
1164  * @brief フォーカスを当てるべきマップ描画の基準座標を指定する(サブルーチン)
1165  * @param dy 変更先のフロアY座標
1166  * @param dx 変更先のフロアX座標
1167  * Handle a request to change the current panel
1168  * Return TRUE if the panel was changed.
1169  * Also used in do_cmd_locate
1170  * @return 実際に再描画が必要だった場合TRUEを返す
1171  */
1172 bool change_panel(POSITION dy, POSITION dx)
1173 {
1174         POSITION y, x;
1175         TERM_LEN wid, hgt;
1176
1177         get_screen_size(&wid, &hgt);
1178
1179         /* Apply the motion */
1180         y = panel_row_min + dy * hgt / 2;
1181         x = panel_col_min + dx * wid / 2;
1182
1183         /* Verify the row */
1184         if (y > cur_hgt - hgt) y = cur_hgt - hgt;
1185         if (y < 0) y = 0;
1186
1187         /* Verify the col */
1188         if (x > cur_wid - wid) x = cur_wid - wid;
1189         if (x < 0) x = 0;
1190
1191         /* Handle "changes" */
1192         if ((y != panel_row_min) || (x != panel_col_min))
1193         {
1194                 /* Save the new panel info */
1195                 panel_row_min = y;
1196                 panel_col_min = x;
1197
1198                 /* Recalculate the boundaries */
1199                 panel_bounds_center();
1200
1201                 p_ptr->update |= (PU_MONSTERS);
1202                 p_ptr->redraw |= (PR_MAP);
1203                 handle_stuff();
1204
1205                 /* Success */
1206                 return (TRUE);
1207         }
1208
1209         /* No change */
1210         return (FALSE);
1211 }
1212
1213 /*!
1214  * @brief フォーカスを当てるべきマップ描画の基準座標を指定する
1215  * @param y 変更先のフロアY座標
1216  * @param x 変更先のフロアX座標
1217  * @details
1218  * Handle a request to change the current panel
1219  * Return TRUE if the panel was changed.
1220  * Also used in do_cmd_locate
1221  * @return 実際に再描画が必要だった場合TRUEを返す
1222  */
1223 static bool change_panel_xy(POSITION y, POSITION x)
1224 {
1225         POSITION dy = 0, dx = 0;
1226         TERM_LEN wid, hgt;
1227
1228         get_screen_size(&wid, &hgt);
1229
1230         if (y < panel_row_min) dy = -1;
1231         if (y > panel_row_max) dy = 1;
1232         if (x < panel_col_min) dx = -1;
1233         if (x > panel_col_max) dx = 1;
1234
1235         if (!dy && !dx) return (FALSE);
1236
1237         return change_panel(dy, dx);
1238 }
1239
1240
1241 /*!
1242  * @brief マップ描画のフォーカスを当てるべき座標を更新する
1243  * @details
1244  * Given an row (y) and col (x), this routine detects when a move
1245  * off the screen has occurred and figures new borders. -RAK-
1246  * "Update" forces a "full update" to take place.
1247  * The map is reprinted if necessary, and "TRUE" is returned.
1248  * @return 実際に再描画が必要だった場合TRUEを返す
1249  */
1250 void verify_panel(void)
1251 {
1252         POSITION y = p_ptr->y;
1253         POSITION x = p_ptr->x;
1254         TERM_LEN wid, hgt;
1255
1256         int prow_min;
1257         int pcol_min;
1258         int max_prow_min;
1259         int max_pcol_min;
1260
1261         get_screen_size(&wid, &hgt);
1262
1263         max_prow_min = cur_hgt - hgt;
1264         max_pcol_min = cur_wid - wid;
1265
1266         /* Bounds checking */
1267         if (max_prow_min < 0) max_prow_min = 0;
1268         if (max_pcol_min < 0) max_pcol_min = 0;
1269
1270                 /* Center on player */
1271         if (center_player && (center_running || !running))
1272         {
1273                 /* Center vertically */
1274                 prow_min = y - hgt / 2;
1275                 if (prow_min < 0) prow_min = 0;
1276                 else if (prow_min > max_prow_min) prow_min = max_prow_min;
1277
1278                 /* Center horizontally */
1279                 pcol_min = x - wid / 2;
1280                 if (pcol_min < 0) pcol_min = 0;
1281                 else if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
1282         }
1283         else
1284         {
1285                 prow_min = panel_row_min;
1286                 pcol_min = panel_col_min;
1287
1288                 /* Scroll screen when 2 grids from top/bottom edge */
1289                 if (y > panel_row_max - 2)
1290                 {
1291                         while (y > prow_min + hgt-1 - 2)
1292                         {
1293                                 prow_min += (hgt / 2);
1294                         }
1295                 }
1296
1297                 if (y < panel_row_min + 2)
1298                 {
1299                         while (y < prow_min + 2)
1300                         {
1301                                 prow_min -= (hgt / 2);
1302                         }
1303                 }
1304
1305                 if (prow_min > max_prow_min) prow_min = max_prow_min;
1306                 if (prow_min < 0) prow_min = 0;
1307
1308                 /* Scroll screen when 4 grids from left/right edge */
1309                 if (x > panel_col_max - 4)
1310                 {
1311                         while (x > pcol_min + wid-1 - 4)
1312                         {
1313                                 pcol_min += (wid / 2);
1314                         }
1315                 }
1316                 
1317                 if (x < panel_col_min + 4)
1318                 {
1319                         while (x < pcol_min + 4)
1320                         {
1321                                 pcol_min -= (wid / 2);
1322                         }
1323                 }
1324
1325                 if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
1326                 if (pcol_min < 0) pcol_min = 0;
1327         }
1328
1329         /* Check for "no change" */
1330         if ((prow_min == panel_row_min) && (pcol_min == panel_col_min)) return;
1331
1332         /* Save the new panel info */
1333         panel_row_min = prow_min;
1334         panel_col_min = pcol_min;
1335
1336         /* Hack -- optional disturb on "panel change" */
1337         if (disturb_panel && !center_player) disturb(FALSE, FALSE);
1338
1339         /* Recalculate the boundaries */
1340         panel_bounds_center();
1341
1342         p_ptr->update |= (PU_MONSTERS);
1343         p_ptr->redraw |= (PR_MAP);
1344         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1345 }
1346
1347
1348 /*
1349  * Monster health description
1350  */
1351 concptr look_mon_desc(monster_type *m_ptr, BIT_FLAGS mode)
1352 {
1353         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1354         bool living;
1355         int perc;
1356         concptr desc;
1357         concptr attitude;
1358         concptr clone;
1359
1360         /* Determine if the monster is "living" */
1361         living = monster_living(m_ptr->ap_r_idx);
1362
1363         /* Calculate a health "percentage" */
1364         perc = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->maxhp : 0;
1365
1366         /* Healthy monsters */
1367         if (m_ptr->hp >= m_ptr->maxhp)
1368         {
1369                 desc = living ? _("無傷", "unhurt") : _("無ダメージ", "undamaged");
1370         }
1371
1372         else if (perc >= 60)
1373         {
1374                 desc = living ? _("軽傷", "somewhat wounded") : _("小ダメージ", "somewhat damaged");
1375         }
1376
1377         else if (perc >= 25)
1378         {
1379                 desc = living ? _("負傷", "wounded") : _("中ダメージ", "damaged");
1380         }
1381
1382         else if (perc >= 10)
1383         {
1384                 desc = living ? _("重傷", "badly wounded") : _("大ダメージ", "badly damaged");
1385         }
1386
1387         else 
1388         {
1389                 desc = living ? _("半死半生", "almost dead") : _("倒れかけ", "almost destroyed");
1390         }
1391
1392         /* Need attitude information? */
1393         if (!(mode & 0x01))
1394         {
1395                 /* Full information is not needed */
1396                 attitude = "";
1397         }
1398         else if (is_pet(m_ptr))
1399         {
1400                 attitude = _(", ペット", ", pet");
1401         }
1402         else if (is_friendly(m_ptr))
1403         {
1404                 attitude = _(", 友好的", ", friendly");
1405         }
1406         else
1407         {
1408                 attitude = _("", "");
1409         }
1410
1411         /* Clone monster? */
1412         if (m_ptr->smart & SM_CLONED)
1413         {
1414                 clone = ", clone";
1415         }
1416         else
1417         {
1418                 clone = "";
1419         }
1420
1421         /* Display monster's level --- idea borrowed from ToME */
1422         if (ap_r_ptr->r_tkills && !(m_ptr->mflag2 & MFLAG2_KAGE))
1423         {
1424                 return format(_("レベル%d, %s%s%s", "Level %d, %s%s%s"), ap_r_ptr->level, desc, attitude, clone);
1425         }
1426         else 
1427         {
1428                 return format(_("レベル???, %s%s%s", "Level ???, %s%s%s"), desc, attitude, clone);
1429         }
1430
1431 }
1432
1433
1434
1435 /*** Targeting Code ***/
1436
1437
1438 /*
1439  * Determine is a monster makes a reasonable target
1440  *
1441  * The concept of "targeting" was stolen from "Morgul" (?)
1442  *
1443  * The player can target any location, or any "target-able" monster.
1444  *
1445  * Currently, a monster is "target_able" if it is visible, and if
1446  * the player can hit it with a projection, and the player is not
1447  * hallucinating.  This allows use of "use closest target" macros.
1448  *
1449  * Future versions may restrict the ability to target "trappers"
1450  * and "mimics", but the semantics is a little bit weird.
1451  */
1452 bool target_able(MONSTER_IDX m_idx)
1453 {
1454         monster_type *m_ptr = &m_list[m_idx];
1455
1456         /* Monster must be alive */
1457         if (!m_ptr->r_idx) return (FALSE);
1458
1459         /* Hack -- no targeting hallucinations */
1460         if (p_ptr->image) return (FALSE);
1461
1462         /* Monster must be visible */
1463         if (!m_ptr->ml) return (FALSE);
1464
1465         if (p_ptr->riding && (p_ptr->riding == m_idx)) return (TRUE);
1466
1467         /* Monster must be projectable */
1468         if (!projectable(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx)) return (FALSE);
1469
1470         /* Hack -- Never target trappers */
1471         /* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */
1472
1473         /* Assume okay */
1474         return (TRUE);
1475 }
1476
1477
1478
1479
1480 /*
1481  * Update (if necessary) and verify (if possible) the target.
1482  *
1483  * We return TRUE if the target is "okay" and FALSE otherwise.
1484  */
1485 bool target_okay(void)
1486 {
1487         /* Accept stationary targets */
1488         if (target_who < 0) return (TRUE);
1489
1490         /* Check moving targets */
1491         if (target_who > 0)
1492         {
1493                 /* Accept reasonable targets */
1494                 if (target_able(target_who))
1495                 {
1496                         monster_type *m_ptr = &m_list[target_who];
1497
1498                         /* Acquire monster location */
1499                         target_row = m_ptr->fy;
1500                         target_col = m_ptr->fx;
1501
1502                         /* Good target */
1503                         return (TRUE);
1504                 }
1505         }
1506
1507         /* Assume no target */
1508         return (FALSE);
1509 }
1510
1511
1512 /*
1513  * Sorting hook -- comp function -- by "distance to player"
1514  *
1515  * We use "u" and "v" to point to arrays of "x" and "y" positions,
1516  * and sort the arrays by double-distance to the player.
1517  */
1518 static bool ang_sort_comp_distance(vptr u, vptr v, int a, int b)
1519 {
1520         POSITION *x = (POSITION*)(u);
1521         POSITION *y = (POSITION*)(v);
1522
1523         POSITION da, db, kx, ky;
1524
1525         /* Absolute distance components */
1526         kx = x[a]; kx -= p_ptr->x; kx = ABS(kx);
1527         ky = y[a]; ky -= p_ptr->y; ky = ABS(ky);
1528
1529         /* Approximate Double Distance to the first point */
1530         da = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
1531
1532         /* Absolute distance components */
1533         kx = x[b]; kx -= p_ptr->x; kx = ABS(kx);
1534         ky = y[b]; ky -= p_ptr->y; ky = ABS(ky);
1535
1536         /* Approximate Double Distance to the first point */
1537         db = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
1538
1539         /* Compare the distances */
1540         return (da <= db);
1541 }
1542
1543
1544 /*
1545  * Sorting hook -- comp function -- by importance level of grids
1546  *
1547  * We use "u" and "v" to point to arrays of "x" and "y" positions,
1548  * and sort the arrays by level of monster
1549  */
1550 static bool ang_sort_comp_importance(vptr u, vptr v, int a, int b)
1551 {
1552         POSITION *x = (POSITION*)(u);
1553         POSITION *y = (POSITION*)(v);
1554         cave_type *ca_ptr = &cave[y[a]][x[a]];
1555         cave_type *cb_ptr = &cave[y[b]][x[b]];
1556         monster_type *ma_ptr = &m_list[ca_ptr->m_idx];
1557         monster_type *mb_ptr = &m_list[cb_ptr->m_idx];
1558         monster_race *ap_ra_ptr, *ap_rb_ptr;
1559
1560         /* The player grid */
1561         if (y[a] == p_ptr->y && x[a] == p_ptr->x) return TRUE;
1562         if (y[b] == p_ptr->y && x[b] == p_ptr->x) return FALSE;
1563
1564         /* Extract monster race */
1565         if (ca_ptr->m_idx && ma_ptr->ml) ap_ra_ptr = &r_info[ma_ptr->ap_r_idx];
1566         else ap_ra_ptr = NULL;
1567         if (cb_ptr->m_idx && mb_ptr->ml) ap_rb_ptr = &r_info[mb_ptr->ap_r_idx];
1568         else ap_rb_ptr = NULL;
1569
1570         if (ap_ra_ptr && !ap_rb_ptr) return TRUE;
1571         if (!ap_ra_ptr && ap_rb_ptr) return FALSE;
1572
1573         /* Compare two monsters */
1574         if (ap_ra_ptr && ap_rb_ptr)
1575         {
1576                 /* Unique monsters first */
1577                 if ((ap_ra_ptr->flags1 & RF1_UNIQUE) && !(ap_rb_ptr->flags1 & RF1_UNIQUE)) return TRUE;
1578                 if (!(ap_ra_ptr->flags1 & RF1_UNIQUE) && (ap_rb_ptr->flags1 & RF1_UNIQUE)) return FALSE;
1579
1580                 /* Shadowers first (あやしい影) */
1581                 if ((ma_ptr->mflag2 & MFLAG2_KAGE) && !(mb_ptr->mflag2 & MFLAG2_KAGE)) return TRUE;
1582                 if (!(ma_ptr->mflag2 & MFLAG2_KAGE) && (mb_ptr->mflag2 & MFLAG2_KAGE)) return FALSE;
1583
1584                 /* Unknown monsters first */
1585                 if (!ap_ra_ptr->r_tkills && ap_rb_ptr->r_tkills) return TRUE;
1586                 if (ap_ra_ptr->r_tkills && !ap_rb_ptr->r_tkills) return FALSE;
1587
1588                 /* Higher level monsters first (if known) */
1589                 if (ap_ra_ptr->r_tkills && ap_rb_ptr->r_tkills)
1590                 {
1591                         if (ap_ra_ptr->level > ap_rb_ptr->level) return TRUE;
1592                         if (ap_ra_ptr->level < ap_rb_ptr->level) return FALSE;
1593                 }
1594
1595                 /* Sort by index if all conditions are same */
1596                 if (ma_ptr->ap_r_idx > mb_ptr->ap_r_idx) return TRUE;
1597                 if (ma_ptr->ap_r_idx < mb_ptr->ap_r_idx) return FALSE;
1598         }
1599
1600         /* An object get higher priority */
1601         if (cave[y[a]][x[a]].o_idx && !cave[y[b]][x[b]].o_idx) return TRUE;
1602         if (!cave[y[a]][x[a]].o_idx && cave[y[b]][x[b]].o_idx) return FALSE;
1603
1604         /* Priority from the terrain */
1605         if (f_info[ca_ptr->feat].priority > f_info[cb_ptr->feat].priority) return TRUE;
1606         if (f_info[ca_ptr->feat].priority < f_info[cb_ptr->feat].priority) return FALSE;
1607
1608         /* If all conditions are same, compare distance */
1609         return ang_sort_comp_distance(u, v, a, b);
1610 }
1611
1612
1613 /*
1614  * Sorting hook -- swap function -- by "distance to player"
1615  *
1616  * We use "u" and "v" to point to arrays of "x" and "y" positions,
1617  * and sort the arrays by distance to the player.
1618  */
1619 static void ang_sort_swap_distance(vptr u, vptr v, int a, int b)
1620 {
1621         POSITION *x = (POSITION*)(u);
1622         POSITION *y = (POSITION*)(v);
1623
1624         POSITION temp;
1625
1626         /* Swap "x" */
1627         temp = x[a];
1628         x[a] = x[b];
1629         x[b] = temp;
1630
1631         /* Swap "y" */
1632         temp = y[a];
1633         y[a] = y[b];
1634         y[b] = temp;
1635 }
1636
1637
1638
1639 /*
1640  * Hack -- help "select" a location (see below)
1641  */
1642 static POSITION_IDX target_pick(POSITION y1, POSITION x1, POSITION dy, POSITION dx)
1643 {
1644         POSITION_IDX i, v;
1645         POSITION x2, y2, x3, y3, x4, y4;
1646         POSITION_IDX b_i = -1, b_v = 9999;
1647
1648
1649         /* Scan the locations */
1650         for (i = 0; i < temp_n; i++)
1651         {
1652                 /* Point 2 */
1653                 x2 = temp_x[i];
1654                 y2 = temp_y[i];
1655
1656                 /* Directed distance */
1657                 x3 = (x2 - x1);
1658                 y3 = (y2 - y1);
1659
1660                 /* Verify quadrant */
1661                 if (dx && (x3 * dx <= 0)) continue;
1662                 if (dy && (y3 * dy <= 0)) continue;
1663
1664                 /* Absolute distance */
1665                 x4 = ABS(x3);
1666                 y4 = ABS(y3);
1667
1668                 /* Verify quadrant */
1669                 if (dy && !dx && (x4 > y4)) continue;
1670                 if (dx && !dy && (y4 > x4)) continue;
1671
1672                 /* Approximate Double Distance */
1673                 v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4));
1674
1675                 /* Penalize location */
1676
1677                 /* Track best */
1678                 if ((b_i >= 0) && (v >= b_v)) continue;
1679
1680                 /* Track best */
1681                 b_i = i; b_v = v;
1682         }
1683         return (b_i);
1684 }
1685
1686
1687 /*
1688  * Hack -- determine if a given location is "interesting"
1689  */
1690 static bool target_set_accept(POSITION y, POSITION x)
1691 {
1692         cave_type *c_ptr;
1693         OBJECT_IDX this_o_idx, next_o_idx = 0;
1694
1695         /* Bounds */
1696         if (!(in_bounds(y, x))) return (FALSE);
1697
1698         /* Player grid is always interesting */
1699         if (player_bold(y, x)) return (TRUE);
1700
1701         /* Handle hallucination */
1702         if (p_ptr->image) return (FALSE);
1703
1704         /* Examine the grid */
1705         c_ptr = &cave[y][x];
1706
1707         /* Visible monsters */
1708         if (c_ptr->m_idx)
1709         {
1710                 monster_type *m_ptr = &m_list[c_ptr->m_idx];
1711
1712                 /* Visible monsters */
1713                 if (m_ptr->ml) return (TRUE);
1714         }
1715
1716         /* Scan all objects in the grid */
1717         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1718         {
1719                 object_type *o_ptr;
1720                 o_ptr = &o_list[this_o_idx];
1721
1722                 /* Acquire next object */
1723                 next_o_idx = o_ptr->next_o_idx;
1724
1725                 /* Memorized object */
1726                 if (o_ptr->marked & OM_FOUND) return (TRUE);
1727         }
1728
1729         /* Interesting memorized features */
1730         if (c_ptr->info & (CAVE_MARK))
1731         {
1732                 /* Notice object features */
1733                 if (c_ptr->info & CAVE_OBJECT) return (TRUE);
1734
1735                 /* Feature code (applying "mimic" field) */
1736                 if (have_flag(f_info[get_feat_mimic(c_ptr)].flags, FF_NOTICE)) return TRUE;
1737         }
1738
1739         return (FALSE);
1740 }
1741
1742
1743 /*
1744  * Prepare the "temp" array for "target_set"
1745  *
1746  * Return the number of target_able monsters in the set.
1747  */
1748 static void target_set_prepare(BIT_FLAGS mode)
1749 {
1750         POSITION y, x;
1751         POSITION min_hgt, max_hgt, min_wid, max_wid;
1752
1753         if (mode & TARGET_KILL)
1754         {
1755                 /* Inner range */
1756                 min_hgt = MAX((p_ptr->y - MAX_RANGE), 0);
1757                 max_hgt = MIN((p_ptr->y + MAX_RANGE), cur_hgt - 1);
1758                 min_wid = MAX((p_ptr->x - MAX_RANGE), 0);
1759                 max_wid = MIN((p_ptr->x + MAX_RANGE), cur_wid - 1);
1760         }
1761         else /* not targetting */
1762         {
1763                 /* Inner panel */
1764                 min_hgt = panel_row_min;
1765                 max_hgt = panel_row_max;
1766                 min_wid = panel_col_min;
1767                 max_wid = panel_col_max;
1768         }
1769
1770         /* Reset "temp" array */
1771         temp_n = 0;
1772
1773         /* Scan the current panel */
1774         for (y = min_hgt; y <= max_hgt; y++)
1775         {
1776                 for (x = min_wid; x <= max_wid; x++)
1777                 {
1778                         cave_type *c_ptr;
1779
1780                         /* Require "interesting" contents */
1781                         if (!target_set_accept(y, x)) continue;
1782
1783                         c_ptr = &cave[y][x];
1784
1785                         /* Require target_able monsters for "TARGET_KILL" */
1786                         if ((mode & (TARGET_KILL)) && !target_able(c_ptr->m_idx)) continue;
1787
1788                         if ((mode & (TARGET_KILL)) && !target_pet && is_pet(&m_list[c_ptr->m_idx])) continue;
1789
1790                         /* Save the location */
1791                         temp_x[temp_n] = x;
1792                         temp_y[temp_n] = y;
1793                         temp_n++;
1794                 }
1795         }
1796
1797         /* Set the sort hooks */
1798         if (mode & (TARGET_KILL))
1799         {
1800                 /* Target the nearest monster for shooting */
1801                 ang_sort_comp = ang_sort_comp_distance;
1802                 ang_sort_swap = ang_sort_swap_distance;
1803         }
1804         else
1805         {
1806                 /* Look important grids first in Look command */
1807                 ang_sort_comp = ang_sort_comp_importance;
1808                 ang_sort_swap = ang_sort_swap_distance;
1809         }
1810
1811         /* Sort the positions */
1812         ang_sort(temp_x, temp_y, temp_n);
1813
1814         if (p_ptr->riding && target_pet && (temp_n > 1) && (mode & (TARGET_KILL)))
1815         {
1816                 POSITION tmp;
1817
1818                 tmp = temp_y[0];
1819                 temp_y[0] = temp_y[1];
1820                 temp_y[1] = tmp;
1821                 tmp = temp_x[0];
1822                 temp_x[0] = temp_x[1];
1823                 temp_x[1] = tmp;
1824         }
1825 }
1826
1827 void target_set_prepare_look(void){
1828         target_set_prepare(TARGET_LOOK);
1829 }
1830
1831
1832 /*
1833  * Evaluate number of kill needed to gain level
1834  */
1835 static void evaluate_monster_exp(char *buf, monster_type *m_ptr)
1836 {
1837         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1838         u32b num;
1839         s32b exp_mon, exp_adv;
1840         u32b exp_mon_frac, exp_adv_frac;
1841
1842         if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->prace == RACE_ANDROID))
1843         {
1844                 sprintf(buf,"**");
1845                 return;
1846         }
1847         else if (!ap_r_ptr->r_tkills || (m_ptr->mflag2 & MFLAG2_KAGE))
1848         {
1849                 if (!p_ptr->wizard)
1850                 {
1851                         sprintf(buf,"??");
1852                         return;
1853                 }
1854         }
1855
1856
1857         /* The monster's experience point (assuming average monster speed) */
1858         exp_mon = ap_r_ptr->mexp * ap_r_ptr->level;
1859         exp_mon_frac = 0;
1860         s64b_div(&exp_mon, &exp_mon_frac, 0, (p_ptr->max_plv + 2));
1861
1862
1863         /* Total experience value for next level */
1864         exp_adv = player_exp[p_ptr->lev -1] * p_ptr->expfact;
1865         exp_adv_frac = 0;
1866         s64b_div(&exp_adv, &exp_adv_frac, 0, 100);
1867
1868         /* Experience value need to get */
1869         s64b_sub(&exp_adv, &exp_adv_frac, p_ptr->exp, p_ptr->exp_frac);
1870
1871
1872         /* You need to kill at least one monster to get any experience */
1873         s64b_add(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
1874         s64b_sub(&exp_adv, &exp_adv_frac, 0, 1);
1875
1876         /* Extract number of monsters needed */
1877         s64b_div(&exp_adv, &exp_adv_frac, exp_mon, exp_mon_frac);
1878
1879         /* If 999 or more monsters needed, only display "999". */
1880         num = MIN(999, exp_adv_frac);
1881
1882         /* Display the number */
1883         sprintf(buf,"%03ld", (long int)num);
1884 }
1885
1886
1887 bool show_gold_on_floor = FALSE;
1888
1889 /*
1890  * Examine a grid, return a keypress.
1891  *
1892  * The "mode" argument contains the "TARGET_LOOK" bit flag, which
1893  * indicates that the "space" key should scan through the contents
1894  * of the grid, instead of simply returning immediately.  This lets
1895  * the "look" command get complete information, without making the
1896  * "target" command annoying.
1897  *
1898  * The "info" argument contains the "commands" which should be shown
1899  * inside the "[xxx]" text.  This string must never be empty, or grids
1900  * containing monsters will be displayed with an extra comma.
1901  *
1902  * Note that if a monster is in the grid, we update both the monster
1903  * recall info and the health bar info to track that monster.
1904  *
1905  * Eventually, we may allow multiple objects per grid, or objects
1906  * and terrain features in the same grid. 
1907  *
1908  * This function must handle blindness/hallucination.
1909  */
1910 static char target_set_aux(POSITION y, POSITION x, BIT_FLAGS mode, concptr info)
1911 {
1912         cave_type *c_ptr = &cave[y][x];
1913         OBJECT_IDX this_o_idx, next_o_idx = 0;
1914         concptr s1 = "", s2 = "", s3 = "", x_info = "";
1915         bool boring = TRUE;
1916         FEAT_IDX feat;
1917         feature_type *f_ptr;
1918         char query = '\001';
1919         char out_val[MAX_NLEN+80];
1920         OBJECT_IDX floor_list[23];
1921         ITEM_NUMBER floor_num = 0;
1922
1923         /* Scan all objects in the grid */
1924         if (easy_floor)
1925         {
1926                 floor_num = scan_floor(floor_list, y, x, 0x02);
1927
1928                 if (floor_num)
1929                 {
1930                         x_info = _("x物 ", "x,");
1931                 }
1932         }
1933
1934         /* Hack -- under the player */
1935         if (player_bold(y, x))
1936         {
1937 #ifdef JP
1938                 s1 = "あなたは";
1939                 s2 = "の上";
1940                 s3 = "にいる";
1941 #else
1942                 s1 = "You are ";
1943                 s2 = "on ";
1944 #endif
1945         }
1946         else
1947         {
1948                 s1 = _("ターゲット:", "Target:");
1949         }
1950
1951         /* Hack -- hallucination */
1952         if (p_ptr->image)
1953         {
1954                 concptr name = _("何か奇妙な物", "something strange");
1955
1956                 /* Display a message */
1957 #ifdef JP
1958                 sprintf(out_val, "%s%s%s%s [%s]", s1, name, s2, s3, info);
1959 #else
1960                 sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
1961 #endif
1962
1963                 prt(out_val, 0, 0);
1964                 move_cursor_relative(y, x);
1965                 query = inkey();
1966
1967                 /* Stop on everything but "return" */
1968                 if ((query != '\r') && (query != '\n')) return query;
1969
1970                 /* Repeat forever */
1971                 return 0;
1972         }
1973
1974
1975         /* Actual monsters */
1976         if (c_ptr->m_idx && m_list[c_ptr->m_idx].ml)
1977         {
1978                 monster_type *m_ptr = &m_list[c_ptr->m_idx];
1979                 monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1980                 GAME_TEXT m_name[MAX_NLEN];
1981                 bool recall = FALSE;
1982
1983                 /* Not boring */
1984                 boring = FALSE;
1985
1986                 monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE);
1987                 monster_race_track(m_ptr->ap_r_idx);
1988                 health_track(c_ptr->m_idx);
1989                 handle_stuff();
1990
1991                 /* Interact */
1992                 while (1)
1993                 {
1994                         char acount[10];
1995
1996                         /* Recall */
1997                         if (recall)
1998                         {
1999                                 screen_save();
2000
2001                                 /* Recall on screen */
2002                                 screen_roff(m_ptr->ap_r_idx, 0);
2003
2004                                 /* Hack -- Complete the prompt (again) */
2005                                 Term_addstr(-1, TERM_WHITE, format(_("  [r思 %s%s]", "  [r,%s%s]"), x_info, info));
2006
2007                                 /* Command */
2008                                 query = inkey();
2009
2010                                 screen_load();
2011
2012                                 /* Normal commands */
2013                                 if (query != 'r') break;
2014
2015                                 /* Toggle recall */
2016                                 recall = FALSE;
2017
2018                                 /* Cleare recall text and repeat */
2019                                 continue;
2020                         }
2021
2022                         /*** Normal ***/
2023
2024                         /* Describe, and prompt for recall */
2025                         evaluate_monster_exp(acount, m_ptr);
2026
2027 #ifdef JP
2028                         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);
2029 #else
2030                         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);
2031 #endif
2032
2033                         prt(out_val, 0, 0);
2034
2035                         /* Place cursor */
2036                         move_cursor_relative(y, x);
2037
2038                         /* Command */
2039                         query = inkey();
2040
2041                         /* Normal commands */
2042                         if (query != 'r') break;
2043
2044                         /* Toggle recall */
2045                         recall = TRUE;
2046                 }
2047
2048                 /* Always stop at "normal" keys */
2049                 if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x')) return query;
2050
2051                 /* Sometimes stop at "space" key */
2052                 if ((query == ' ') && !(mode & (TARGET_LOOK))) return query;
2053
2054                 /* Change the intro */
2055                 s1 = _("それは", "It is ");
2056
2057                 /* Hack -- take account of gender */
2058                 if (ap_r_ptr->flags1 & (RF1_FEMALE)) s1 = _("彼女は", "She is ");
2059                 else if (ap_r_ptr->flags1 & (RF1_MALE)) s1 = _("彼は", "He is ");
2060
2061                 /* Use a preposition */
2062 #ifdef JP
2063                 s2 = "を";
2064                 s3 = "持っている";
2065 #else
2066                 s2 = "carrying ";
2067 #endif
2068
2069
2070                 /* Scan all objects being carried */
2071                 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
2072                 {
2073                         GAME_TEXT o_name[MAX_NLEN];
2074
2075                         object_type *o_ptr;
2076                         o_ptr = &o_list[this_o_idx];
2077
2078                         /* Acquire next object */
2079                         next_o_idx = o_ptr->next_o_idx;
2080
2081                         /* Obtain an object description */
2082                         object_desc(o_name, o_ptr, 0);
2083
2084 #ifdef JP
2085                         sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
2086 #else
2087                         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
2088 #endif
2089
2090                         prt(out_val, 0, 0);
2091                         move_cursor_relative(y, x);
2092                         query = inkey();
2093
2094                         /* Always stop at "normal" keys */
2095                         if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x')) return query;
2096
2097                         /* Sometimes stop at "space" key */
2098                         if ((query == ' ') && !(mode & (TARGET_LOOK))) return query;
2099
2100                         /* Change the intro */
2101                         s2 = _("をまた", "also carrying ");
2102                 }
2103
2104                 /* Use a preposition */
2105 #ifdef JP
2106                 s2 = "の上";
2107                 s3 = "にいる";
2108 #else
2109                 s2 = "on ";
2110 #endif
2111         }
2112
2113         if (floor_num)
2114         {
2115                 int min_width = 0;
2116
2117                 while (1)
2118                 {
2119                         if (floor_num == 1)
2120                         {
2121                                 GAME_TEXT o_name[MAX_NLEN];
2122
2123                                 object_type *o_ptr;
2124                                 o_ptr = &o_list[floor_list[0]];
2125
2126                                 object_desc(o_name, o_ptr, 0);
2127
2128 #ifdef JP
2129                                 sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
2130 #else
2131                                 sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
2132 #endif
2133
2134                                 prt(out_val, 0, 0);
2135                                 move_cursor_relative(y, x);
2136
2137                                 /* Command */
2138                                 query = inkey();
2139
2140                                 /* End this grid */
2141                                 return query;
2142                         }
2143
2144                         /* Provide one cushion before item listing  */
2145                         if (boring)
2146                         {
2147                                 /* Display rough information about items */
2148 #ifdef JP
2149                                 sprintf(out_val, "%s %d個のアイテム%s%s ['x'で一覧, %s]", s1, (int)floor_num, s2, s3, info);
2150 #else
2151                                 sprintf(out_val, "%s%s%sa pile of %d items [x,%s]", s1, s2, s3, (int)floor_num, info);
2152 #endif
2153
2154                                 prt(out_val, 0, 0);
2155                                 move_cursor_relative(y, x);
2156
2157                                 /* Command */
2158                                 query = inkey();
2159
2160                                 /* No request for listing */
2161                                 if (query != 'x' && query != ' ') return query;
2162                         }
2163
2164
2165                         /** Display list of items **/
2166
2167                         /* Continue scrolling list if requested */
2168                         while (1)
2169                         {
2170                                 int i;
2171                                 OBJECT_IDX o_idx;
2172                                 screen_save();
2173
2174                                 /* Display */
2175                                 show_gold_on_floor = TRUE;
2176                                 (void)show_floor(0, y, x, &min_width);
2177                                 show_gold_on_floor = FALSE;
2178
2179                                 /* Prompt */
2180 #ifdef JP
2181                                 sprintf(out_val, "%s %d個のアイテム%s%s [Enterで次へ, %s]", s1, (int)floor_num, s2, s3, info);
2182 #else
2183                                 sprintf(out_val, "%s%s%sa pile of %d items [Enter,%s]", s1, s2, s3, (int)floor_num, info);
2184 #endif
2185                                 prt(out_val, 0, 0);
2186
2187                                 query = inkey();
2188                                 screen_load();
2189
2190                                 /* Exit unless 'Enter' */
2191                                 if (query != '\n' && query != '\r')
2192                                 {
2193                                         return query;
2194                                 }
2195
2196                                 /* Get the object being moved. */
2197                                 o_idx = c_ptr->o_idx;
2198  
2199                                 /* Only rotate a pile of two or more objects. */
2200                                 if (!(o_idx && o_list[o_idx].next_o_idx)) continue;
2201
2202                                 /* Remove the first object from the list. */
2203                                 excise_object_idx(o_idx);
2204
2205                                 /* Find end of the list. */
2206                                 i = c_ptr->o_idx;
2207                                 while (o_list[i].next_o_idx)
2208                                         i = o_list[i].next_o_idx;
2209
2210                                 /* Add after the last object. */
2211                                 o_list[i].next_o_idx = o_idx;
2212
2213                                 /* Loop and re-display the list */
2214                         }
2215                 }
2216
2217                 /* NOTREACHED */
2218         }
2219
2220         /* Scan all objects in the grid */
2221         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
2222         {
2223                 object_type *o_ptr;
2224                 o_ptr = &o_list[this_o_idx];
2225
2226                 /* Acquire next object */
2227                 next_o_idx = o_ptr->next_o_idx;
2228
2229                 if (o_ptr->marked & OM_FOUND)
2230                 {
2231                         GAME_TEXT o_name[MAX_NLEN];
2232
2233                         /* Not boring */
2234                         boring = FALSE;
2235
2236                         /* Obtain an object description */
2237                         object_desc(o_name, o_ptr, 0);
2238
2239 #ifdef JP
2240                         sprintf(out_val, "%s%s%s%s[%s]", s1, o_name, s2, s3, info);
2241 #else
2242                         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
2243 #endif
2244
2245                         prt(out_val, 0, 0);
2246                         move_cursor_relative(y, x);
2247                         query = inkey();
2248
2249                         /* Always stop at "normal" keys */
2250                         if ((query != '\r') && (query != '\n') && (query != ' ') && (query != 'x')) return query;
2251
2252                         /* Sometimes stop at "space" key */
2253                         if ((query == ' ') && !(mode & TARGET_LOOK)) return query;
2254
2255                         /* Change the intro */
2256                         s1 = _("それは", "It is ");
2257
2258                         /* Plurals */
2259                         if (o_ptr->number != 1) s1 = _("それらは", "They are ");
2260
2261                         /* Preposition */
2262 #ifdef JP
2263                         s2 = "の上";
2264                         s3 = "に見える";
2265 #else
2266                         s2 = "on ";
2267 #endif
2268
2269                 }
2270         }
2271
2272
2273         /* Feature code (applying "mimic" field) */
2274         feat = get_feat_mimic(c_ptr);
2275
2276         /* Require knowledge about grid, or ability to see grid */
2277         if (!(c_ptr->info & CAVE_MARK) && !player_can_see_bold(y, x))
2278         {
2279                 /* Forget feature */
2280                 feat = feat_none;
2281         }
2282
2283         f_ptr = &f_info[feat];
2284
2285         /* Terrain feature if needed */
2286         if (boring || have_flag(f_ptr->flags, FF_REMEMBER))
2287         {
2288                 concptr name;
2289
2290                 /* Hack -- special handling for quest entrances */
2291                 if (have_flag(f_ptr->flags, FF_QUEST_ENTER))
2292                 {
2293                         /* Set the quest number temporary */
2294                         IDX old_quest = p_ptr->inside_quest;
2295                         int j;
2296
2297                         /* Clear the text */
2298                         for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
2299                         quest_text_line = 0;
2300
2301                         p_ptr->inside_quest = c_ptr->special;
2302
2303                         /* Get the quest text */
2304                         init_flags = INIT_NAME_ONLY;
2305
2306                         process_dungeon_file("q_info.txt", 0, 0, 0, 0);
2307
2308                         name = format(_("クエスト「%s」(%d階相当)", "the entrance to the quest '%s'(level %d)"), 
2309                                                 quest[c_ptr->special].name, quest[c_ptr->special].level);
2310
2311                         /* Reset the old quest number */
2312                         p_ptr->inside_quest = old_quest;
2313                 }
2314
2315                 /* Hack -- special handling for building doors */
2316                 else if (have_flag(f_ptr->flags, FF_BLDG) && !p_ptr->inside_arena)
2317                 {
2318                         name = building[f_ptr->subtype].name;
2319                 }
2320                 else if (have_flag(f_ptr->flags, FF_ENTRANCE))
2321                 {
2322                         name = format(_("%s(%d階相当)", "%s(level %d)"), d_text + d_info[c_ptr->special].text, d_info[c_ptr->special].mindepth);
2323                 }
2324                 else if (have_flag(f_ptr->flags, FF_TOWN))
2325                 {
2326                         name = town[c_ptr->special].name;
2327                 }
2328                 else if (p_ptr->wild_mode && (feat == feat_floor))
2329                 {
2330                         name = _("道", "road");
2331                 }
2332                 else
2333                 {
2334                         name = f_name + f_ptr->name;
2335                 }
2336
2337
2338                 /* Pick a prefix */
2339                 if (*s2 &&
2340                     ((!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) ||
2341                      (!have_flag(f_ptr->flags, FF_LOS) && !have_flag(f_ptr->flags, FF_TREE)) ||
2342                      have_flag(f_ptr->flags, FF_TOWN)))
2343                 {
2344                         s2 = _("の中", "in ");
2345                 }
2346
2347                 /* Hack -- special introduction for store & building doors -KMW- */
2348                 if (have_flag(f_ptr->flags, FF_STORE) ||
2349                     have_flag(f_ptr->flags, FF_QUEST_ENTER) ||
2350                     (have_flag(f_ptr->flags, FF_BLDG) && !p_ptr->inside_arena) ||
2351                     have_flag(f_ptr->flags, FF_ENTRANCE))
2352                 {
2353                         s2 = _("の入口", "");
2354                 }
2355 #ifndef JP
2356                 else if (have_flag(f_ptr->flags, FF_FLOOR) ||
2357                          have_flag(f_ptr->flags, FF_TOWN) ||
2358                          have_flag(f_ptr->flags, FF_SHALLOW) ||
2359                          have_flag(f_ptr->flags, FF_DEEP))
2360                 {
2361                         s3 ="";
2362                 }
2363                 else
2364                 {
2365                         /* Pick proper indefinite article */
2366                         s3 = (is_a_vowel(name[0])) ? "an " : "a ";
2367                 }
2368 #endif
2369
2370                 /* Display a message */
2371                 if (p_ptr->wizard)
2372                 {
2373                         char f_idx_str[32];
2374                         if (c_ptr->mimic) sprintf(f_idx_str, "%d/%d", c_ptr->feat, c_ptr->mimic);
2375                         else sprintf(f_idx_str, "%d", c_ptr->feat);
2376 #ifdef JP
2377                         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]);
2378 #else
2379                         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);
2380 #endif
2381                 }
2382                 else
2383 #ifdef JP
2384                         sprintf(out_val, "%s%s%s%s[%s]", s1, name, s2, s3, info);
2385 #else
2386                         sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
2387 #endif
2388
2389                 prt(out_val, 0, 0);
2390                 move_cursor_relative(y, x);
2391                 query = inkey();
2392
2393                 /* Always stop at "normal" keys */
2394                 if ((query != '\r') && (query != '\n') && (query != ' ')) return query;
2395         }
2396
2397         /* Stop on everything but "return" */
2398         if ((query != '\r') && (query != '\n')) return query;
2399
2400         /* Repeat forever */
2401         return 0;
2402 }
2403
2404
2405 /*
2406  * Handle "target" and "look".
2407  *
2408  * Note that this code can be called from "get_aim_dir()".
2409  *
2410  * All locations must be on the current panel.  Consider the use of
2411  * "panel_bounds()" to allow "off-panel" targets, perhaps by using
2412  * some form of "scrolling" the map around the cursor.  
2413  * That is, consider the possibility of "auto-scrolling" the screen
2414  * while the cursor moves around.  This may require changes in the
2415  * "update_monster()" code to allow "visibility" even if off panel, and
2416  * may require dynamic recalculation of the "temp" grid set.
2417  *
2418  * Hack -- targeting/observing an "outer border grid" may induce
2419  * problems, so this is not currently allowed.
2420  *
2421  * The player can use the direction keys to move among "interesting"
2422  * grids in a heuristic manner, or the "space", "+", and "-" keys to
2423  * move through the "interesting" grids in a sequential manner, or
2424  * can enter "location" mode, and use the direction keys to move one
2425  * grid at a time in any direction.  The "t" (set target) command will
2426  * only target a monster (as opposed to a location) if the monster is
2427  * target_able and the "interesting" mode is being used.
2428  *
2429  * The current grid is described using the "look" method above, and
2430  * a new command may be entered at any time, but note that if the
2431  * "TARGET_LOOK" bit flag is set (or if we are in "location" mode,
2432  * where "space" has no obvious meaning) then "space" will scan
2433  * through the description of the current grid until done, instead
2434  * of immediately jumping to the next "interesting" grid.  This
2435  * allows the "target" command to retain its old semantics.
2436  *
2437  * The "*", "+", and "-" keys may always be used to jump immediately
2438  * to the next (or previous) interesting grid, in the proper mode.
2439  *
2440  * The "return" key may always be used to scan through a complete
2441  * grid description (forever).
2442  *
2443  * This command will cancel any old target, even if used from
2444  * inside the "look" command.
2445  */
2446 bool target_set(BIT_FLAGS mode)
2447 {
2448         int i, d, m, t, bd;
2449         POSITION y = p_ptr->y;
2450         POSITION x = p_ptr->x;
2451
2452         bool done = FALSE;
2453         bool flag = TRUE;
2454         char query;
2455         char info[80];
2456         char same_key;
2457         cave_type *c_ptr;
2458         TERM_LEN wid, hgt;
2459         
2460         get_screen_size(&wid, &hgt);
2461
2462         /* Cancel target */
2463         target_who = 0;
2464
2465         if (rogue_like_commands)
2466         {
2467                 same_key = 'x';
2468         }
2469         else
2470         {
2471                 same_key = 'l';
2472         }
2473
2474         /* Prepare the "temp" array */
2475         target_set_prepare(mode);
2476
2477         /* Start near the player */
2478         m = 0;
2479
2480         /* Interact */
2481         while (!done)
2482         {
2483                 /* Interesting grids */
2484                 if (flag && temp_n)
2485                 {
2486                         y = temp_y[m];
2487                         x = temp_x[m];
2488
2489                         /* Set forcus */
2490                         change_panel_xy(y, x);
2491
2492                         if (!(mode & TARGET_LOOK)) prt_path(y, x);
2493
2494                         /* Access */
2495                         c_ptr = &cave[y][x];
2496
2497                         /* Allow target */
2498                         if (target_able(c_ptr->m_idx))
2499                         {
2500                                 strcpy(info, _("q止 t決 p自 o現 +次 -前", "q,t,p,o,+,-,<dir>"));
2501                         }
2502
2503                         /* Dis-allow target */
2504                         else
2505                         {
2506                                 strcpy(info, _("q止 p自 o現 +次 -前", "q,p,o,+,-,<dir>"));
2507                         }
2508
2509                         if (cheat_sight)
2510                         {
2511                                 char cheatinfo[30];
2512                                 sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d",
2513                                         los(p_ptr->y, p_ptr->x, y, x), projectable(p_ptr->y, p_ptr->x, y, x));
2514                                 strcat(info, cheatinfo);
2515                         }
2516                         
2517                         /* Describe and Prompt */
2518                         while (TRUE){
2519                                 query = target_set_aux(y, x, mode, info);
2520                                 if(query)break;
2521                         }
2522
2523                         /* Assume no "direction" */
2524                         d = 0;
2525
2526                         if (use_menu)
2527                         {
2528                                 if (query == '\r') query = 't';
2529                         }  
2530
2531                         /* Analyze */
2532                         switch (query)
2533                         {
2534                                 case ESCAPE:
2535                                 case 'q':
2536                                 {
2537                                         done = TRUE;
2538                                         break;
2539                                 }
2540
2541                                 case 't':
2542                                 case '.':
2543                                 case '5':
2544                                 case '0':
2545                                 {
2546                                         if (target_able(c_ptr->m_idx))
2547                                         {
2548                                                 health_track(c_ptr->m_idx);
2549                                                 target_who = c_ptr->m_idx;
2550                                                 target_row = y;
2551                                                 target_col = x;
2552                                                 done = TRUE;
2553                                         }
2554                                         else
2555                                         {
2556                                                 bell();
2557                                         }
2558                                         break;
2559                                 }
2560
2561                                 case ' ':
2562                                 case '*':
2563                                 case '+':
2564                                 {
2565                                         if (++m == temp_n)
2566                                         {
2567                                                 m = 0;
2568                                                 if (!expand_list) done = TRUE;
2569                                         }
2570                                         break;
2571                                 }
2572
2573                                 case '-':
2574                                 {
2575                                         if (m-- == 0)
2576                                         {
2577                                                 m = temp_n - 1;
2578                                                 if (!expand_list) done = TRUE;
2579                                         }
2580                                         break;
2581                                 }
2582
2583                                 case 'p':
2584                                 {
2585                                         /* Recenter the map around the player */
2586                                         verify_panel();
2587                                         p_ptr->update |= (PU_MONSTERS);
2588                                         p_ptr->redraw |= (PR_MAP);
2589                                         p_ptr->window |= (PW_OVERHEAD);
2590                                         handle_stuff();
2591
2592                                         /* Recalculate interesting grids */
2593                                         target_set_prepare(mode);
2594
2595                                         y = p_ptr->y;
2596                                         x = p_ptr->x;
2597                                 }
2598
2599                                 case 'o':
2600                                 {
2601                                         flag = FALSE;
2602                                         break;
2603                                 }
2604
2605                                 case 'm':
2606                                 {
2607                                         break;
2608                                 }
2609
2610                                 default:
2611                                 {
2612                                         if(query == same_key)
2613                                         {
2614                                                 if (++m == temp_n)
2615                                                 {
2616                                                         m = 0;
2617                                                         if (!expand_list) done = TRUE;
2618                                                 }
2619                                         }
2620                                         else
2621                                         {
2622                                                 /* Extract the action (if any) */
2623                                                 d = get_keymap_dir(query);
2624
2625                                                 if (!d) bell();
2626                                                 break;
2627                                         }
2628                                 }
2629                         }
2630                         /* Hack -- move around */
2631                         if (d)
2632                         {
2633                                 /* Modified to scroll to monster */
2634                                 POSITION y2 = panel_row_min;
2635                                 POSITION x2 = panel_col_min;
2636
2637                                 /* Find a new monster */
2638                                 i = target_pick(temp_y[m], temp_x[m], ddy[d], ddx[d]);
2639
2640                                 /* Request to target past last interesting grid */
2641                                 while (flag && (i < 0))
2642                                 {
2643                                         /* Note the change */
2644                                         if (change_panel(ddy[d], ddx[d]))
2645                                         {
2646                                                 int v = temp_y[m];
2647                                                 int u = temp_x[m];
2648
2649                                                 /* Recalculate interesting grids */
2650                                                 target_set_prepare(mode);
2651
2652                                                 /* Look at interesting grids */
2653                                                 flag = TRUE;
2654
2655                                                 /* Find a new monster */
2656                                                 i = target_pick(v, u, ddy[d], ddx[d]);
2657
2658                                                 /* Use that grid */
2659                                                 if (i >= 0) m = i;
2660                                         }
2661
2662                                         /* Nothing interesting */
2663                                         else
2664                                         {
2665                                                 POSITION dx = ddx[d];
2666                                                 POSITION dy = ddy[d];
2667
2668                                                 /* Restore previous position */
2669                                                 panel_row_min = y2;
2670                                                 panel_col_min = x2;
2671                                                 panel_bounds_center();
2672
2673                                                 p_ptr->update |= (PU_MONSTERS);
2674                                                 p_ptr->redraw |= (PR_MAP);
2675                                                 p_ptr->window |= (PW_OVERHEAD);
2676                                                 handle_stuff();
2677
2678                                                 /* Recalculate interesting grids */
2679                                                 target_set_prepare(mode);
2680
2681                                                 /* Look at boring grids */
2682                                                 flag = FALSE;
2683
2684                                                 /* Move */
2685                                                 x += dx;
2686                                                 y += dy;
2687
2688                                                 /* Do not move horizontally if unnecessary */
2689                                                 if (((x < panel_col_min + wid / 2) && (dx > 0)) ||
2690                                                          ((x > panel_col_min + wid / 2) && (dx < 0)))
2691                                                 {
2692                                                         dx = 0;
2693                                                 }
2694
2695                                                 /* Do not move vertically if unnecessary */
2696                                                 if (((y < panel_row_min + hgt / 2) && (dy > 0)) ||
2697                                                          ((y > panel_row_min + hgt / 2) && (dy < 0)))
2698                                                 {
2699                                                         dy = 0;
2700                                                 }
2701
2702                                                 /* Apply the motion */
2703                                                 if ((y >= panel_row_min+hgt) || (y < panel_row_min) ||
2704                                                     (x >= panel_col_min+wid) || (x < panel_col_min))
2705                                                 {
2706                                                         if (change_panel(dy, dx)) target_set_prepare(mode);
2707                                                 }
2708
2709                                                 /* Slide into legality */
2710                                                 if (x >= cur_wid-1) x = cur_wid - 2;
2711                                                 else if (x <= 0) x = 1;
2712
2713                                                 /* Slide into legality */
2714                                                 if (y >= cur_hgt-1) y = cur_hgt- 2;
2715                                                 else if (y <= 0) y = 1;
2716                                         }
2717                                 }
2718
2719                                 /* Use that grid */
2720                                 m = i;
2721                         }
2722                 }
2723
2724                 /* Arbitrary grids */
2725                 else
2726                 {
2727                         bool move_fast = FALSE;
2728
2729                         if (!(mode & TARGET_LOOK)) prt_path(y, x);
2730
2731                         /* Access */
2732                         c_ptr = &cave[y][x];
2733
2734                         /* Default prompt */
2735                         strcpy(info, _("q止 t決 p自 m近 +次 -前", "q,t,p,m,+,-,<dir>"));
2736
2737                         if (cheat_sight)
2738                         {
2739                                 char cheatinfo[30];
2740                                 sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d",
2741                                         los(p_ptr->y, p_ptr->x, y, x),
2742                                         projectable(p_ptr->y, p_ptr->x, y, x));
2743                                 strcat(info, cheatinfo);
2744                         }
2745
2746                         /* Describe and Prompt (enable "TARGET_LOOK") */
2747                         while ((query = target_set_aux(y, x, mode | TARGET_LOOK, info)) == 0);
2748
2749                         /* Assume no direction */
2750                         d = 0;
2751
2752                         if (use_menu)
2753                         {
2754                                 if (query == '\r') query = 't';
2755                         }  
2756
2757                         /* Analyze the keypress */
2758                         switch (query)
2759                         {
2760                                 case ESCAPE:
2761                                 case 'q':
2762                                 {
2763                                         done = TRUE;
2764                                         break;
2765                                 }
2766
2767                                 case 't':
2768                                 case '.':
2769                                 case '5':
2770                                 case '0':
2771                                 {
2772                                         target_who = -1;
2773                                         target_row = y;
2774                                         target_col = x;
2775                                         done = TRUE;
2776                                         break;
2777                                 }
2778
2779                                 case 'p':
2780                                 {
2781                                         /* Recenter the map around the player */
2782                                         verify_panel();
2783                                         p_ptr->update |= (PU_MONSTERS);
2784                                         p_ptr->redraw |= (PR_MAP);
2785                                         p_ptr->window |= (PW_OVERHEAD);
2786                                         handle_stuff();
2787
2788                                         /* Recalculate interesting grids */
2789                                         target_set_prepare(mode);
2790
2791                                         y = p_ptr->y;
2792                                         x = p_ptr->x;
2793                                 }
2794
2795                                 case 'o':
2796                                 {
2797                                         break;
2798                                 }
2799
2800                                 case ' ':
2801                                 case '*':
2802                                 case '+':
2803                                 case '-':
2804                                 case 'm':
2805                                 {
2806                                         flag = TRUE;
2807
2808                                         m = 0;
2809                                         bd = 999;
2810
2811                                         /* Pick a nearby monster */
2812                                         for (i = 0; i < temp_n; i++)
2813                                         {
2814                                                 t = distance(y, x, temp_y[i], temp_x[i]);
2815
2816                                                 /* Pick closest */
2817                                                 if (t < bd)
2818                                                 {
2819                                                         m = i;
2820                                                         bd = t;
2821                                                 }
2822                                         }
2823
2824                                         /* Nothing interesting */
2825                                         if (bd == 999) flag = FALSE;
2826
2827                                         break;
2828                                 }
2829
2830                                 default:
2831                                 {
2832                                         /* Extract the action (if any) */
2833                                         d = get_keymap_dir(query);
2834
2835                                         /* XTRA HACK MOVEFAST */
2836                                         if (isupper(query)) move_fast = TRUE;
2837
2838                                         if (!d) bell();
2839                                         break;
2840                                 }
2841                         }
2842
2843                         /* Handle "direction" */
2844                         if (d)
2845                         {
2846                                 POSITION dx = ddx[d];
2847                                 POSITION dy = ddy[d];
2848
2849                                 /* XTRA HACK MOVEFAST */
2850                                 if (move_fast)
2851                                 {
2852                                         int mag = MIN(wid / 2, hgt / 2);
2853                                         x += dx * mag;
2854                                         y += dy * mag;
2855                                 }
2856                                 else
2857                                 {
2858                                         x += dx;
2859                                         y += dy;
2860                                 }
2861
2862                                 /* Do not move horizontally if unnecessary */
2863                                 if (((x < panel_col_min + wid / 2) && (dx > 0)) ||
2864                                          ((x > panel_col_min + wid / 2) && (dx < 0)))
2865                                 {
2866                                         dx = 0;
2867                                 }
2868
2869                                 /* Do not move vertically if unnecessary */
2870                                 if (((y < panel_row_min + hgt / 2) && (dy > 0)) ||
2871                                          ((y > panel_row_min + hgt / 2) && (dy < 0)))
2872                                 {
2873                                         dy = 0;
2874                                 }
2875
2876                                 /* Apply the motion */
2877                                 if ((y >= panel_row_min + hgt) || (y < panel_row_min) ||
2878                                          (x >= panel_col_min + wid) || (x < panel_col_min))
2879                                 {
2880                                         if (change_panel(dy, dx)) target_set_prepare(mode);
2881                                 }
2882
2883                                 /* Slide into legality */
2884                                 if (x >= cur_wid-1) x = cur_wid - 2;
2885                                 else if (x <= 0) x = 1;
2886
2887                                 /* Slide into legality */
2888                                 if (y >= cur_hgt-1) y = cur_hgt- 2;
2889                                 else if (y <= 0) y = 1;
2890                         }
2891                 }
2892         }
2893
2894         /* Forget */
2895         temp_n = 0;
2896
2897         /* Clear the top line */
2898         prt("", 0, 0);
2899
2900         /* Recenter the map around the player */
2901         verify_panel();
2902         p_ptr->update |= (PU_MONSTERS);
2903         p_ptr->redraw |= (PR_MAP);
2904         p_ptr->window |= (PW_OVERHEAD);
2905         handle_stuff();
2906
2907         /* Failure to set target */
2908         if (!target_who) return (FALSE);
2909
2910         /* Success */
2911         return (TRUE);
2912 }
2913
2914
2915 /*
2916  * Get an "aiming direction" from the user.
2917  *
2918  * The "dir" is loaded with 1,2,3,4,6,7,8,9 for "actual direction", and
2919  * "0" for "current target", and "-1" for "entry aborted".
2920  *
2921  * Note that "Force Target", if set, will pre-empt user interaction,
2922  * if there is a usable target already set.
2923  *
2924  * Note that confusion over-rides any (explicit?) user choice.
2925  */
2926 bool get_aim_dir(DIRECTION *dp)
2927 {
2928         DIRECTION dir;
2929         char    command;
2930         concptr p;
2931         COMMAND_CODE code;
2932
2933         (*dp) = 0;
2934
2935         /* Global direction */
2936         dir = command_dir;
2937
2938         /* Hack -- auto-target if requested */
2939         if (use_old_target && target_okay()) dir = 5;
2940
2941         if (repeat_pull(&code))
2942         {
2943                 /* Confusion? */
2944
2945                 /* Verify */
2946                 if (!(code == 5 && !target_okay()))
2947                 {
2948 /*                      return (TRUE); */
2949                         dir = (DIRECTION)code;
2950                 }
2951         }
2952         *dp = (DIRECTION)code;
2953
2954         /* Ask until satisfied */
2955         while (!dir)
2956         {
2957                 /* Choose a prompt */
2958                 if (!target_okay())
2959                 {
2960                         p = _("方向 ('*'でターゲット選択, ESCで中断)? ", "Direction ('*' to choose a target, Escape to cancel)? ");
2961                 }
2962                 else
2963                 {
2964                         p = _("方向 ('5'でターゲットへ, '*'でターゲット再選択, ESCで中断)? ", "Direction ('5' for target, '*' to re-target, Escape to cancel)? ");
2965                 }
2966
2967                 /* Get a command (or Cancel) */
2968                 if (!get_com(p, &command, TRUE)) break;
2969
2970                 if (use_menu)
2971                 {
2972                         if (command == '\r') command = 't';
2973                 }  
2974
2975                 /* Convert various keys to "standard" keys */
2976                 switch (command)
2977                 {
2978                         /* Use current target */
2979                         case 'T':
2980                         case 't':
2981                         case '.':
2982                         case '5':
2983                         case '0':
2984                         {
2985                                 dir = 5;
2986                                 break;
2987                         }
2988
2989                         /* Set new target */
2990                         case '*':
2991                         case ' ':
2992                         case '\r':
2993                         {
2994                                 if (target_set(TARGET_KILL)) dir = 5;
2995                                 break;
2996                         }
2997
2998                         default:
2999                         {
3000                                 /* Extract the action (if any) */
3001                                 dir = get_keymap_dir(command);
3002
3003                                 break;
3004                         }
3005                 }
3006
3007                 /* Verify requested targets */
3008                 if ((dir == 5) && !target_okay()) dir = 0;
3009
3010                 /* Error */
3011                 if (!dir) bell();
3012         }
3013
3014         /* No direction */
3015         if (!dir)
3016         {
3017                 project_length = 0; /* reset to default */
3018                 return (FALSE);
3019         }
3020
3021         /* Save the direction */
3022         command_dir = dir;
3023
3024         /* Check for confusion */
3025         if (p_ptr->confused)
3026         {
3027                 /* Random direction */
3028                 dir = ddd[randint0(8)];
3029         }
3030
3031         /* Notice confusion */
3032         if (command_dir != dir)
3033         {
3034                 /* Warn the user */
3035                 msg_print(_("あなたは混乱している。", "You are confused."));
3036         }
3037
3038         /* Save direction */
3039         (*dp) = dir;
3040
3041 /*      repeat_push(dir); */
3042         repeat_push((COMMAND_CODE)command_dir);
3043
3044         /* A "valid" direction was entered */
3045         return (TRUE);
3046 }
3047
3048
3049 bool get_direction(DIRECTION *dp, bool allow_under, bool with_steed)
3050 {
3051         DIRECTION dir;
3052         concptr prompt;
3053         COMMAND_CODE code;
3054
3055         (*dp) = 0;
3056
3057         /* Global direction */
3058         dir = command_dir;
3059
3060         if (repeat_pull(&code))
3061         {
3062                 dir = (DIRECTION)code;
3063                 /*              return (TRUE); */
3064         }
3065         *dp = (DIRECTION)code;
3066
3067         if (allow_under)
3068         {
3069                 prompt = _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ");
3070         }
3071         else
3072         {
3073                 prompt = _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
3074         }
3075
3076         /* Get a direction */
3077         while (!dir)
3078         {
3079                 char ch;
3080
3081                 /* Get a command (or Cancel) */
3082                 if (!get_com(prompt, &ch, TRUE)) break;
3083
3084                 /* Look down */
3085                 if ((allow_under) && ((ch == '5') || (ch == '-') || (ch == '.')))
3086                 {
3087                         dir = 5;
3088                 }
3089                 else
3090                 {
3091                         /* Look up the direction */
3092                         dir = get_keymap_dir(ch);
3093
3094                         if (!dir) bell();
3095                 }
3096         }
3097
3098         /* Prevent weirdness */
3099         if ((dir == 5) && (!allow_under)) dir = 0;
3100
3101         /* Aborted */
3102         if (!dir) return (FALSE);
3103
3104         /* Save desired direction */
3105         command_dir = dir;
3106
3107         /* Apply "confusion" */
3108         if (p_ptr->confused)
3109         {
3110                 /* Standard confusion */
3111                 if (randint0(100) < 75)
3112                 {
3113                         /* Random direction */
3114                         dir = ddd[randint0(8)];
3115                 }
3116         }
3117         else if (p_ptr->riding && with_steed)
3118         {
3119                 monster_type *m_ptr = &m_list[p_ptr->riding];
3120                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
3121
3122                 if (MON_CONFUSED(m_ptr))
3123                 {
3124                         /* Standard confusion */
3125                         if (randint0(100) < 75)
3126                         {
3127                                 /* Random direction */
3128                                 dir = ddd[randint0(8)];
3129                         }
3130                 }
3131                 else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
3132                 {
3133                         /* Random direction */
3134                         dir = ddd[randint0(8)];
3135                 }
3136                 else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
3137                 {
3138                         /* Random direction */
3139                         dir = ddd[randint0(8)];
3140                 }
3141         }
3142
3143         /* Notice confusion */
3144         if (command_dir != dir)
3145         {
3146                 if (p_ptr->confused)
3147                 {
3148                         /* Warn the user */
3149                         msg_print(_("あなたは混乱している。", "You are confused."));
3150                 }
3151                 else
3152                 {
3153                         GAME_TEXT m_name[MAX_NLEN];
3154                         monster_type *m_ptr = &m_list[p_ptr->riding];
3155
3156                         monster_desc(m_name, m_ptr, 0);
3157                         if (MON_CONFUSED(m_ptr))
3158                         {
3159                                 msg_format(_("%sは混乱している。", "%^s is confusing."), m_name);
3160                         }
3161                         else
3162                         {
3163                                 msg_format(_("%sは思い通りに動いてくれない。", "You cannot control %s."), m_name);
3164                         }
3165                 }
3166         }
3167
3168         /* Save direction */
3169         (*dp) = dir;
3170
3171         /*      repeat_push(dir); */
3172         repeat_push((COMMAND_CODE)command_dir);
3173
3174         /* Success */
3175         return (TRUE);
3176 }
3177
3178 /*
3179  * @brief 進行方向を指定する(騎乗対象の混乱の影響を受ける) / Request a "movement" direction (1,2,3,4,6,7,8,9) from the user,
3180  * and place it into "command_dir", unless we already have one.
3181  *
3182  * This function should be used for all "repeatable" commands, such as
3183  * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well
3184  * as all commands which must reference a grid adjacent to the player,
3185  * and which may not reference the grid under the player.  Note that,
3186  * for example, it is no longer possible to "disarm" or "open" chests
3187  * in the same grid as the player.
3188  *
3189  * Direction "5" is illegal and will (cleanly) abort the command.
3190  *
3191  * This function tracks and uses the "global direction", and uses
3192  * that as the "desired direction", to which "confusion" is applied.
3193  */
3194 bool get_rep_dir(DIRECTION *dp, bool under)
3195 {
3196         DIRECTION dir;
3197         concptr prompt;
3198         COMMAND_CODE code;
3199
3200         (*dp) = 0;
3201
3202         /* Global direction */
3203         dir = command_dir;
3204
3205         if (repeat_pull(&code))
3206         {
3207                 dir = (DIRECTION)code;
3208 /*              return (TRUE); */
3209         }
3210         *dp = (DIRECTION)code;
3211
3212         if (under)
3213         {
3214                 prompt = _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ");
3215         }
3216         else
3217         {
3218                 prompt = _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
3219         }
3220         
3221         /* Get a direction */
3222         while (!dir)
3223         {
3224                 char ch;
3225
3226                 /* Get a command (or Cancel) */
3227                 if (!get_com(prompt, &ch, TRUE)) break;
3228
3229                 /* Look down */
3230                 if ((under) && ((ch == '5') || (ch == '-') || (ch == '.')))
3231                 {
3232                         dir = 5;
3233                 }
3234                 else
3235                 {
3236                         /* Look up the direction */
3237                         dir = get_keymap_dir(ch);
3238
3239                         if (!dir) bell();
3240                 }
3241         }
3242
3243         /* Prevent weirdness */
3244         if ((dir == 5) && (!under)) dir = 0;
3245
3246         /* Aborted */
3247         if (!dir) return (FALSE);
3248
3249         /* Save desired direction */
3250         command_dir = dir;
3251
3252         /* Apply "confusion" */
3253         if (p_ptr->confused)
3254         {
3255                 /* Standard confusion */
3256                 if (randint0(100) < 75)
3257                 {
3258                         /* Random direction */
3259                         dir = ddd[randint0(8)];
3260                 }
3261         }
3262         else if (p_ptr->riding)
3263         {
3264                 monster_type *m_ptr = &m_list[p_ptr->riding];
3265                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
3266
3267                 if (MON_CONFUSED(m_ptr))
3268                 {
3269                         /* Standard confusion */
3270                         if (randint0(100) < 75)
3271                         {
3272                                 /* Random direction */
3273                                 dir = ddd[randint0(8)];
3274                         }
3275                 }
3276                 else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
3277                 {
3278                         /* Random direction */
3279                         dir = ddd[randint0(8)];
3280                 }
3281                 else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
3282                 {
3283                         /* Random direction */
3284                         dir = ddd[randint0(8)];
3285                 }
3286         }
3287
3288         /* Notice confusion */
3289         if (command_dir != dir)
3290         {
3291                 if (p_ptr->confused)
3292                 {
3293                         /* Warn the user */
3294                         msg_print(_("あなたは混乱している。", "You are confused."));
3295                 }
3296                 else
3297                 {
3298                         GAME_TEXT m_name[MAX_NLEN];
3299                         monster_type *m_ptr = &m_list[p_ptr->riding];
3300
3301                         monster_desc(m_name, m_ptr, 0);
3302                         if (MON_CONFUSED(m_ptr))
3303                         {
3304                                 msg_format(_("%sは混乱している。", "%^s is confusing."), m_name);
3305                         }
3306                         else
3307                         {
3308                                 msg_format(_("%sは思い通りに動いてくれない。", "You cannot control %s."), m_name);
3309                         }
3310                 }
3311         }
3312
3313         /* Save direction */
3314         (*dp) = dir;
3315
3316 /*      repeat_push(dir); */
3317         repeat_push((COMMAND_CODE)command_dir);
3318
3319         /* Success */
3320         return (TRUE);
3321 }
3322
3323 void gain_level_reward(int chosen_reward)
3324 {
3325         object_type *q_ptr;
3326         object_type forge;
3327         char        wrath_reason[32] = "";
3328         int         nasty_chance = 6;
3329         OBJECT_TYPE_VALUE dummy = 0;
3330         OBJECT_SUBTYPE_VALUE dummy2 = 0;
3331         int         type, effect;
3332         concptr        reward = NULL;
3333         GAME_TEXT o_name[MAX_NLEN];
3334
3335         int count = 0;
3336
3337         if (!chosen_reward)
3338         {
3339                 if (multi_rew) return;
3340                 else multi_rew = TRUE;
3341         }
3342
3343
3344         if (p_ptr->lev == 13) nasty_chance = 2;
3345         else if (!(p_ptr->lev % 13)) nasty_chance = 3;
3346         else if (!(p_ptr->lev % 14)) nasty_chance = 12;
3347
3348         if (one_in_(nasty_chance))
3349                 type = randint1(20); /* Allow the 'nasty' effects */
3350         else
3351                 type = randint1(15) + 5; /* Or disallow them */
3352
3353         if (type < 1) type = 1;
3354         if (type > 20) type = 20;
3355         type--;
3356
3357
3358         sprintf(wrath_reason, _("%sの怒り", "the Wrath of %s"), chaos_patrons[p_ptr->chaos_patron]);
3359
3360         effect = chaos_rewards[p_ptr->chaos_patron][type];
3361
3362         if (one_in_(6) && !chosen_reward)
3363         {
3364                 msg_format(_("%^sは褒美としてあなたを突然変異させた。", "%^s rewards you with a mutation!"), chaos_patrons[p_ptr->chaos_patron]);
3365                 (void)gain_random_mutation(0);
3366                 reward = _("変異した。", "mutation");
3367         }
3368         else
3369         {
3370         switch (chosen_reward ? chosen_reward : effect)
3371         {
3372
3373                 case REW_POLY_SLF:
3374
3375                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3376                         msg_print(_("「汝、新たなる姿を必要とせり!」", "'Thou needst a new form, mortal!'"));
3377
3378                         do_poly_self();
3379                         reward = _("変異した。", "polymorphing");
3380                         break;
3381
3382                 case REW_GAIN_EXP:
3383
3384                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3385                         msg_print(_("「汝は良く行いたり!続けよ!」", "'Well done, mortal! Lead on!'"));
3386
3387                         if (p_ptr->prace == RACE_ANDROID)
3388                         {
3389                                 msg_print(_("しかし何も起こらなかった。", "But, nothing happen."));
3390                         }
3391                         else if (p_ptr->exp < PY_MAX_EXP)
3392                         {
3393                                 s32b ee = (p_ptr->exp / 2) + 10;
3394                                 if (ee > 100000L) ee = 100000L;
3395                                 msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));
3396
3397                                 gain_exp(ee);
3398                                 reward = _("経験値を得た", "experience");
3399                         }
3400                         break;
3401
3402                 case REW_LOSE_EXP:
3403
3404                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3405                         msg_print(_("「下僕よ、汝それに値せず。」", "'Thou didst not deserve that, slave.'"));
3406
3407                         if (p_ptr->prace == RACE_ANDROID)
3408                         {
3409                                 msg_print(_("しかし何も起こらなかった。", "But, nothing happen."));
3410                         }
3411                         else
3412                         {
3413                                 lose_exp(p_ptr->exp / 6);
3414                                 reward = _("経験値を失った。", "losing experience");
3415                         }
3416                         break;
3417
3418                 case REW_GOOD_OBJ:
3419 #ifdef JP
3420                         msg_format("%sの声がささやいた:",
3421                                 chaos_patrons[p_ptr->chaos_patron]);
3422 #else
3423                         msg_format("The voice of %s whispers:",
3424                                 chaos_patrons[p_ptr->chaos_patron]);
3425 #endif
3426
3427                         msg_print(_("「我が与えし物を賢明に使うべし。」", "'Use my gift wisely.'"));
3428
3429                         acquirement(p_ptr->y, p_ptr->x, 1, FALSE, FALSE, FALSE);
3430                         reward = _("上質なアイテムを手に入れた。", "a good item");
3431                         break;
3432
3433                 case REW_GREA_OBJ:
3434
3435                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3436                         msg_print(_("「我が与えし物を賢明に使うべし。」", "'Use my gift wisely.'"));
3437
3438                         acquirement(p_ptr->y, p_ptr->x, 1, TRUE, FALSE, FALSE);
3439                         reward = _("高級品のアイテムを手に入れた。", "an excellent item");
3440                         break;
3441
3442                 case REW_CHAOS_WP:
3443
3444                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3445                         msg_print(_("「汝の行いは貴き剣に値せり。」", "'Thy deed hath earned thee a worthy blade.'"));
3446                         q_ptr = &forge;
3447                         dummy = TV_SWORD;
3448                         switch (randint1(p_ptr->lev))
3449                         {
3450                                 case 0: case 1:
3451                                         dummy2 = SV_DAGGER;
3452                                         break;
3453                                 case 2: case 3:
3454                                         dummy2 = SV_MAIN_GAUCHE;
3455                                         break;
3456                                 case 4:
3457                                         dummy2 = SV_TANTO;
3458                                         break;
3459                                 case 5: case 6:
3460                                         dummy2 = SV_RAPIER;
3461                                         break;
3462                                 case 7: case 8:
3463                                         dummy2 = SV_SMALL_SWORD;
3464                                         break;
3465                                 case 9: case 10:
3466                                         dummy2 = SV_BASILLARD;
3467                                         break;
3468                                 case 11: case 12: case 13:
3469                                         dummy2 = SV_SHORT_SWORD;
3470                                         break;
3471                                 case 14: case 15:
3472                                         dummy2 = SV_SABRE;
3473                                         break;
3474                                 case 16: case 17:
3475                                         dummy2 = SV_CUTLASS;
3476                                         break;
3477                                 case 18:
3478                                         dummy2 = SV_WAKIZASHI;
3479                                         break;
3480                                 case 19:
3481                                         dummy2 = SV_KHOPESH;
3482                                         break;
3483                                 case 20:
3484                                         dummy2 = SV_TULWAR;
3485                                         break;
3486                                 case 21:
3487                                         dummy2 = SV_BROAD_SWORD;
3488                                         break;
3489                                 case 22: case 23:
3490                                         dummy2 = SV_LONG_SWORD;
3491                                         break;
3492                                 case 24: case 25:
3493                                         dummy2 = SV_SCIMITAR;
3494                                         break;
3495                                 case 26:
3496                                         dummy2 = SV_NINJATO;
3497                                         break;
3498                                 case 27:
3499                                         dummy2 = SV_KATANA;
3500                                         break;
3501                                 case 28: case 29:
3502                                         dummy2 = SV_BASTARD_SWORD;
3503                                         break;
3504                                 case 30:
3505                                         dummy2 = SV_GREAT_SCIMITAR;
3506                                         break;
3507                                 case 31:
3508                                         dummy2 = SV_CLAYMORE;
3509                                         break;
3510                                 case 32:
3511                                         dummy2 = SV_ESPADON;
3512                                         break;
3513                                 case 33:
3514                                         dummy2 = SV_TWO_HANDED_SWORD;
3515                                         break;
3516                                 case 34:
3517                                         dummy2 = SV_FLAMBERGE;
3518                                         break;
3519                                 case 35:
3520                                         dummy2 = SV_NO_DACHI;
3521                                         break;
3522                                 case 36:
3523                                         dummy2 = SV_EXECUTIONERS_SWORD;
3524                                         break;
3525                                 case 37:
3526                                         dummy2 = SV_ZWEIHANDER;
3527                                         break;
3528                                 case 38:
3529                                         dummy2 = SV_HAYABUSA;
3530                                         break;
3531                                 default:
3532                                         dummy2 = SV_BLADE_OF_CHAOS;
3533                         }
3534
3535                         object_prep(q_ptr, lookup_kind(dummy, dummy2));
3536                         q_ptr->to_h = 3 + randint1(dun_level) % 10;
3537                         q_ptr->to_d = 3 + randint1(dun_level) % 10;
3538                         one_resistance(q_ptr);
3539                         q_ptr->name2 = EGO_CHAOTIC;
3540                         (void)drop_near(q_ptr, -1, p_ptr->y, p_ptr->x);
3541                         reward = _("(混沌)の武器を手に入れた。", "chaos weapon");
3542                         break;
3543
3544                 case REW_GOOD_OBS:
3545
3546                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3547                         msg_print(_("「汝の行いは貴き報いに値せり。」", "'Thy deed hath earned thee a worthy reward.'"));
3548
3549                         acquirement(p_ptr->y, p_ptr->x, randint1(2) + 1, FALSE, FALSE, FALSE);
3550                         reward = _("上質なアイテムを手に入れた。", "good items");
3551                         break;
3552
3553                 case REW_GREA_OBS:
3554
3555                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3556                         msg_print(_("「下僕よ、汝の献身への我が惜しみ無き報いを見るがよい。」", "'Behold, mortal, how generously I reward thy loyalty.'"));
3557
3558                         acquirement(p_ptr->y, p_ptr->x, randint1(2) + 1, TRUE, FALSE, FALSE);
3559                         reward = _("高級品のアイテムを手に入れた。", "excellent items");
3560                         break;
3561
3562                 case REW_TY_CURSE:
3563 #ifdef JP
3564                         msg_format("%sの声が轟き渡った:", chaos_patrons[p_ptr->chaos_patron]);
3565 #else
3566                         msg_format("The voice of %s thunders:", chaos_patrons[p_ptr->chaos_patron]);
3567 #endif
3568
3569                         msg_print(_("「下僕よ、汝傲慢なり。」", "'Thou art growing arrogant, mortal.'"));
3570
3571                         (void)activate_ty_curse(FALSE, &count);
3572                         reward = _("禍々しい呪いをかけられた。", "cursing");
3573                         break;
3574
3575                 case REW_SUMMON_M:
3576
3577                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3578                         msg_print(_("「我が下僕たちよ、かの傲慢なる者を倒すべし!」", "'My pets, destroy the arrogant mortal!'"));
3579
3580                         for (dummy = 0; dummy < randint1(5) + 1; dummy++)
3581                         {
3582                                 (void)summon_specific(0, p_ptr->y, p_ptr->x, dun_level, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
3583                         }
3584                         reward = _("モンスターを召喚された。", "summoning hostile monsters");
3585                         break;
3586
3587
3588                 case REW_H_SUMMON:
3589
3590                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3591                         msg_print(_("「汝、より強き敵を必要とせり!」", "'Thou needst worthier opponents!'"));
3592
3593                         activate_hi_summon(p_ptr->y, p_ptr->x, FALSE);
3594                         reward = _("モンスターを召喚された。", "summoning many hostile monsters");
3595                         break;
3596
3597
3598                 case REW_DO_HAVOC:
3599 #ifdef JP
3600                         msg_format("%sの声が響き渡った:",
3601                                 chaos_patrons[p_ptr->chaos_patron]);
3602 #else
3603                         msg_format("The voice of %s booms out:",
3604                                 chaos_patrons[p_ptr->chaos_patron]);
3605 #endif
3606
3607                         msg_print(_("「死と破壊こそ我が喜びなり!」", "'Death and destruction! This pleaseth me!'"));
3608
3609                         call_chaos();
3610                         reward = _("カオスの力が渦巻いた。", "calling chaos");
3611                         break;
3612
3613
3614                 case REW_GAIN_ABL:
3615 #ifdef JP
3616                         msg_format("%sの声が鳴り響いた:",
3617                                 chaos_patrons[p_ptr->chaos_patron]);
3618 #else
3619                         msg_format("The voice of %s rings out:",
3620                                 chaos_patrons[p_ptr->chaos_patron]);
3621 #endif
3622
3623                         msg_print(_("「留まるのだ、下僕よ。余が汝の肉体を鍛えん。」", "'Stay, mortal, and let me mold thee.'"));
3624
3625                         if (one_in_(3) && !(chaos_stats[p_ptr->chaos_patron] < 0))
3626                                 do_inc_stat(chaos_stats[p_ptr->chaos_patron]);
3627                         else
3628                                 do_inc_stat(randint0(6));
3629                         reward = _("能力値が上がった。", "increasing a stat");
3630                         break;
3631
3632
3633                 case REW_LOSE_ABL:
3634 #ifdef JP
3635                         msg_format("%sの声が響き渡った:",
3636                                 chaos_patrons[p_ptr->chaos_patron]);
3637 #else
3638                         msg_format("The voice of %s booms out:",
3639                                 chaos_patrons[p_ptr->chaos_patron]);
3640 #endif
3641
3642                         msg_print(_("「下僕よ、余は汝に飽みたり。」", "'I grow tired of thee, mortal.'"));
3643
3644                         if (one_in_(3) && !(chaos_stats[p_ptr->chaos_patron] < 0))
3645                                 do_dec_stat(chaos_stats[p_ptr->chaos_patron]);
3646                         else
3647                                 (void)do_dec_stat(randint0(6));
3648                         reward = _("能力値が下がった。", "decreasing a stat");
3649                         break;
3650
3651
3652                 case REW_RUIN_ABL:
3653
3654 #ifdef JP
3655                         msg_format("%sの声が轟き渡った:",
3656                                 chaos_patrons[p_ptr->chaos_patron]);
3657 #else
3658                         msg_format("The voice of %s thunders:",
3659                                 chaos_patrons[p_ptr->chaos_patron]);
3660 #endif
3661
3662                         msg_print(_("「汝、謙虚たることを学ぶべし!」", "'Thou needst a lesson in humility, mortal!'"));
3663                         msg_print(_("あなたは以前より弱くなった!", "You feel less powerful!"));
3664
3665                         for (dummy = 0; dummy < A_MAX; dummy++)
3666                         {
3667                                 (void)dec_stat(dummy, 10 + randint1(15), TRUE);
3668                         }
3669                         reward = _("全能力値が下がった。", "decreasing all stats");
3670                         break;
3671
3672                 case REW_POLY_WND:
3673
3674                         msg_format(_("%sの力が触れるのを感じた。", "You feel the power of %s touch you."),
3675                                 chaos_patrons[p_ptr->chaos_patron]);
3676                         do_poly_wounds();
3677                         reward = _("傷が変化した。", "polymorphing wounds");
3678                         break;
3679
3680                 case REW_AUGM_ABL:
3681
3682                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3683
3684                         msg_print(_("「我がささやかなる賜物を受けとるがよい!」", "'Receive this modest gift from me!'"));
3685
3686                         for (dummy = 0; dummy < A_MAX; dummy++)
3687                         {
3688                                 (void)do_inc_stat(dummy);
3689                         }
3690                         reward = _("全能力値が上がった。", "increasing all stats");
3691                         break;
3692
3693                 case REW_HURT_LOT:
3694
3695                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3696                         msg_print(_("「苦しむがよい、無能な愚か者よ!」", "'Suffer, pathetic fool!'"));
3697
3698                         fire_ball(GF_DISINTEGRATE, 0, p_ptr->lev * 4, 4);
3699                         take_hit(DAMAGE_NOESCAPE, p_ptr->lev * 4, wrath_reason, -1);
3700                         reward = _("分解の球が発生した。", "generating disintegration ball");
3701                         break;
3702
3703                 case REW_HEAL_FUL:
3704
3705                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3706                         (void)restore_level();
3707                         (void)restore_all_status();
3708                         (void)true_healing(5000);
3709                         reward = _("体力が回復した。", "healing");
3710                         break;
3711
3712                 case REW_CURSE_WP:
3713
3714                         if (!buki_motteruka(INVEN_RARM) && !buki_motteruka(INVEN_LARM)) break;
3715                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3716                         msg_print(_("「汝、武器に頼ることなかれ。」", "'Thou reliest too much on thy weapon.'"));
3717
3718                         dummy = INVEN_RARM;
3719                         if (buki_motteruka(INVEN_LARM))
3720                         {
3721                                 dummy = INVEN_LARM;
3722                                 if (buki_motteruka(INVEN_RARM) && one_in_(2)) dummy = INVEN_RARM;
3723                         }
3724                         object_desc(o_name, &inventory[dummy], OD_NAME_ONLY);
3725                         (void)curse_weapon(FALSE, dummy);
3726                         reward = format(_("%sが破壊された。", "destroying %s"), o_name);
3727                         break;
3728
3729                 case REW_CURSE_AR:
3730
3731                         if (!inventory[INVEN_BODY].k_idx) break;
3732                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3733                         msg_print(_("「汝、防具に頼ることなかれ。」", "'Thou reliest too much on thine equipment.'"));
3734
3735                         object_desc(o_name, &inventory[INVEN_BODY], OD_NAME_ONLY);
3736                         (void)curse_armor();
3737                         reward = format(_("%sが破壊された。", "destroying %s"), o_name);
3738                         break;
3739                 case REW_PISS_OFF:
3740
3741                         msg_format(_("%sの声がささやいた:", "The voice of %s whispers:"), chaos_patrons[p_ptr->chaos_patron]);
3742                         msg_print(_("「我を怒りしめた罪を償うべし。」", "'Now thou shalt pay for annoying me.'"));
3743
3744                         switch (randint1(4))
3745                         {
3746                                 case 1:
3747                                         (void)activate_ty_curse(FALSE, &count);
3748                                         reward = _("禍々しい呪いをかけられた。", "cursing");
3749                                         break;
3750                                 case 2:
3751                                         activate_hi_summon(p_ptr->y, p_ptr->x, FALSE);
3752                                         reward = _("モンスターを召喚された。", "summoning hostile monsters");
3753                                         break;
3754                                 case 3:
3755                                         if (one_in_(2))
3756                                         {
3757                                                 if (!buki_motteruka(INVEN_RARM) && !buki_motteruka(INVEN_LARM)) break;
3758                                                 dummy = INVEN_RARM;
3759                                                 if (buki_motteruka(INVEN_LARM))
3760                                                 {
3761                                                         dummy = INVEN_LARM;
3762                                                         if (buki_motteruka(INVEN_RARM) && one_in_(2)) dummy = INVEN_RARM;
3763                                                 }
3764                                                 object_desc(o_name, &inventory[dummy], OD_NAME_ONLY);
3765                                                 (void)curse_weapon(FALSE, dummy);
3766                                                 reward = format(_("%sが破壊された。", "destroying %s"), o_name);
3767                                         }
3768                                         else
3769                                         {
3770                                                 if (!inventory[INVEN_BODY].k_idx) break;
3771                                                 object_desc(o_name, &inventory[INVEN_BODY], OD_NAME_ONLY);
3772                                                 (void)curse_armor();
3773                                                 reward = format(_("%sが破壊された。", "destroying %s"), o_name);
3774                                         }
3775                                         break;
3776                                 default:
3777                                         for (dummy = 0; dummy < A_MAX; dummy++)
3778                                         {
3779                                                 (void)dec_stat(dummy, 10 + randint1(15), TRUE);
3780                                         }
3781                                         reward = _("全能力値が下がった。", "decreasing all stats");
3782                                         break;
3783                         }
3784                         break;
3785
3786                 case REW_WRATH:
3787
3788                         msg_format(_("%sの声が轟き渡った:", "The voice of %s thunders:"), chaos_patrons[p_ptr->chaos_patron]);
3789                         msg_print(_("「死ぬがよい、下僕よ!」", "'Die, mortal!'"));
3790
3791                         take_hit(DAMAGE_LOSELIFE, p_ptr->lev * 4, wrath_reason, -1);
3792                         for (dummy = 0; dummy < A_MAX; dummy++)
3793                         {
3794                                 (void)dec_stat(dummy, 10 + randint1(15), FALSE);
3795                         }
3796                         activate_hi_summon(p_ptr->y, p_ptr->x, FALSE);
3797                         (void)activate_ty_curse(FALSE, &count);
3798                         if (one_in_(2))
3799                         {
3800                                 dummy = 0;
3801
3802                                 if (buki_motteruka(INVEN_RARM))
3803                                 {
3804                                         dummy = INVEN_RARM;
3805                                         if (buki_motteruka(INVEN_LARM) && one_in_(2)) dummy = INVEN_LARM;
3806                                 }
3807                                 else if (buki_motteruka(INVEN_LARM)) dummy = INVEN_LARM;
3808
3809                                 if (dummy) (void)curse_weapon(FALSE, dummy);
3810                         }
3811                         if (one_in_(2)) (void)curse_armor();
3812                         break;
3813
3814                 case REW_DESTRUCT:
3815
3816                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3817                         msg_print(_("「死と破壊こそ我が喜びなり!」", "'Death and destruction! This pleaseth me!'"));
3818
3819                         (void)destroy_area(p_ptr->y, p_ptr->x, 25, FALSE);
3820                         reward = _("ダンジョンが*破壊*された。", "*destruct*ing dungeon");
3821                         break;
3822
3823                 case REW_GENOCIDE:
3824
3825                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3826                         msg_print(_("「我、汝の敵を抹殺せん!」", "'Let me relieve thee of thine oppressors!'"));
3827                         (void)symbol_genocide(0, FALSE);
3828                         reward = _("モンスターが抹殺された。", "genociding monsters");
3829                         break;
3830
3831                 case REW_MASS_GEN:
3832
3833                         msg_format(_("%sの声が響き渡った:", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
3834                         msg_print(_("「我、汝の敵を抹殺せん!」", "'Let me relieve thee of thine oppressors!'"));
3835
3836                         (void)mass_genocide(0, FALSE);
3837                         reward = _("モンスターが抹殺された。", "genociding nearby monsters");
3838                         break;
3839
3840                 case REW_DISPEL_C:
3841
3842                         msg_format(_("%sの力が敵を攻撃するのを感じた!", "You can feel the power of %s assault your enemies!"), chaos_patrons[p_ptr->chaos_patron]);
3843                         (void)dispel_monsters(p_ptr->lev * 4);
3844                         break;
3845
3846                 case REW_IGNORE:
3847
3848                         msg_format(_("%sはあなたを無視した。", "%s ignores you."), chaos_patrons[p_ptr->chaos_patron]);
3849                         break;
3850
3851                 case REW_SER_DEMO:
3852
3853                         msg_format(_("%sは褒美として悪魔の使いをよこした!", "%s rewards you with a demonic servant!"),chaos_patrons[p_ptr->chaos_patron]);
3854
3855                         if (!summon_specific(-1, p_ptr->y, p_ptr->x, dun_level, SUMMON_DEMON, PM_FORCE_PET, '\0'))
3856                                 msg_print(_("何も現れなかった...", "Nobody ever turns up..."));
3857                         else
3858                                 reward = _("悪魔がペットになった。", "a demonic servant");
3859
3860                         break;
3861
3862                 case REW_SER_MONS:
3863                         msg_format(_("%sは褒美として使いをよこした!", "%s rewards you with a servant!"),chaos_patrons[p_ptr->chaos_patron]);
3864
3865                         if (!summon_specific(-1, p_ptr->y, p_ptr->x, dun_level, 0, PM_FORCE_PET, '\0'))
3866                                 msg_print(_("何も現れなかった...", "Nobody ever turns up..."));
3867                         else
3868                                 reward = _("モンスターがペットになった。", "a servant");
3869
3870                         break;
3871
3872                 case REW_SER_UNDE:
3873                         msg_format(_("%sは褒美としてアンデッドの使いをよこした。", "%s rewards you with an undead servant!"),chaos_patrons[p_ptr->chaos_patron]);
3874
3875                         if (!summon_specific(-1, p_ptr->y, p_ptr->x, dun_level, SUMMON_UNDEAD, PM_FORCE_PET, '\0'))
3876                                 msg_print(_("何も現れなかった...", "Nobody ever turns up..."));
3877                         else
3878                                 reward = _("アンデッドがペットになった。", "an undead servant");
3879
3880                         break;
3881
3882                 default:
3883                         msg_format(_("%sの声がどもった:", "The voice of %s stammers:"),
3884
3885                                 chaos_patrons[p_ptr->chaos_patron]);
3886                         msg_format(_("「あー、あー、答えは %d/%d。質問は何?」", "'Uh... uh... the answer's %d/%d, what's the question?'"), type, effect);
3887
3888         }
3889         }
3890         if (reward)
3891         {
3892                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, format(_("パトロンの報酬で%s", "The patron rewards you with %s."), reward));
3893         }
3894 }
3895
3896
3897 /*
3898  * XAngband: determine if a given location is "interesting"
3899  * based on target_set_accept function.
3900  */
3901 static bool tgt_pt_accept(POSITION y, POSITION x)
3902 {
3903         cave_type *c_ptr;
3904
3905         /* Bounds */
3906         if (!(in_bounds(y, x))) return (FALSE);
3907
3908         /* Player grid is always interesting */
3909         if ((y == p_ptr->y) && (x == p_ptr->x)) return (TRUE);
3910
3911         /* Handle hallucination */
3912         if (p_ptr->image) return (FALSE);
3913
3914         /* Examine the grid */
3915         c_ptr = &cave[y][x];
3916
3917         /* Interesting memorized features */
3918         if (c_ptr->info & (CAVE_MARK))
3919         {
3920                 /* Notice stairs */
3921                 if (cave_have_flag_grid(c_ptr, FF_LESS)) return (TRUE);
3922                 if (cave_have_flag_grid(c_ptr, FF_MORE)) return (TRUE);
3923
3924                 /* Notice quest features */
3925                 if (cave_have_flag_grid(c_ptr, FF_QUEST_ENTER)) return (TRUE);
3926                 if (cave_have_flag_grid(c_ptr, FF_QUEST_EXIT)) return (TRUE);
3927         }
3928
3929         return (FALSE);
3930 }
3931
3932
3933 /*
3934  * XAngband: Prepare the "temp" array for "tget_pt"
3935  * based on target_set_prepare funciton.
3936  */
3937 static void tgt_pt_prepare(void)
3938 {
3939         POSITION y, x;
3940
3941         /* Reset "temp" array */
3942         temp_n = 0;
3943
3944         if (!expand_list) return;
3945
3946         /* Scan the current panel */
3947         for (y = 1; y < cur_hgt; y++)
3948         {
3949                 for (x = 1; x < cur_wid; x++)
3950                 {
3951                         /* Require "interesting" contents */
3952                         if (!tgt_pt_accept(y, x)) continue;
3953
3954                         /* Save the location */
3955                         temp_x[temp_n] = x;
3956                         temp_y[temp_n] = y;
3957                         temp_n++;
3958                 }
3959         }
3960
3961         /* Target the nearest monster for shooting */
3962         ang_sort_comp = ang_sort_comp_distance;
3963         ang_sort_swap = ang_sort_swap_distance;
3964
3965         /* Sort the positions */
3966         ang_sort(temp_x, temp_y, temp_n);
3967 }
3968
3969 /*
3970  * old -- from PsiAngband.
3971  */
3972 bool tgt_pt(POSITION *x_ptr, POSITION *y_ptr)
3973 {
3974         char ch = 0;
3975         int d, n = 0;
3976         POSITION x, y;
3977         bool success = FALSE;
3978
3979         TERM_LEN wid, hgt;
3980
3981         get_screen_size(&wid, &hgt);
3982
3983         x = p_ptr->x;
3984         y = p_ptr->y;
3985
3986         if (expand_list) 
3987         {
3988                 tgt_pt_prepare();
3989         }
3990
3991         msg_print(_("場所を選んでスペースキーを押して下さい。", "Select a point and press space."));
3992         msg_flag = FALSE; /* prevents "-more-" message. */
3993
3994         while ((ch != ESCAPE) && !success)
3995         {
3996                 bool move_fast = FALSE;
3997
3998                 move_cursor_relative(y, x);
3999                 ch = inkey();
4000                 switch (ch)
4001                 {
4002                 case ESCAPE:
4003                         break;
4004                 case ' ':
4005                 case 't':
4006                 case '.':
4007                 case '5':
4008                 case '0':
4009                         /* illegal place */
4010                         if (player_bold(y, x)) ch = 0;
4011
4012                         /* okay place */
4013                         else success = TRUE;
4014
4015                         break;
4016
4017                 /* XAngband: Move cursor to stairs */
4018                 case '>':
4019                 case '<':
4020                         if (expand_list && temp_n)
4021                         {
4022                                 int dx, dy;
4023                                 int cx = (panel_col_min + panel_col_max) / 2;
4024                                 int cy = (panel_row_min + panel_row_max) / 2;
4025
4026                                 n++;
4027
4028                                 /* Skip stairs which have defferent distance */
4029                                 for (; n < temp_n; ++ n)
4030                                 {
4031                                         cave_type *c_ptr = &cave[temp_y[n]][temp_x[n]];
4032
4033                                         if (cave_have_flag_grid(c_ptr, FF_STAIRS) &&
4034                                             cave_have_flag_grid(c_ptr, ch == '>' ? FF_MORE : FF_LESS))
4035                                         {
4036                                                 /* Found */
4037                                                 break;
4038                                         }
4039                                 }
4040
4041                                 if (n == temp_n)        /* Loop out taget list */
4042                                 {
4043                                         n = 0;
4044                                         y = p_ptr->y;
4045                                         x = p_ptr->x;
4046                                         verify_panel(); /* Move cursor to player */
4047
4048                                         p_ptr->update |= (PU_MONSTERS);
4049
4050                                         p_ptr->redraw |= (PR_MAP);
4051
4052                                         p_ptr->window |= (PW_OVERHEAD);
4053                                         handle_stuff();
4054                                 }
4055                                 else    /* move cursor to next stair and change panel */
4056                                 {
4057                                         y = temp_y[n];
4058                                         x = temp_x[n];
4059
4060                                         dy = 2 * (y - cy) / hgt;
4061                                         dx = 2 * (x - cx) / wid;
4062                                         if (dy || dx) change_panel(dy, dx);
4063                                 }
4064                         }
4065                         break;
4066
4067                 default:
4068                         /* Look up the direction */
4069                         d = get_keymap_dir(ch);
4070
4071                         /* XTRA HACK MOVEFAST */
4072                         if (isupper(ch)) move_fast = TRUE;
4073
4074                         /* Handle "direction" */
4075                         if (d)
4076                         {
4077                                 int dx = ddx[d];
4078                                 int dy = ddy[d];
4079
4080                                 /* XTRA HACK MOVEFAST */
4081                                 if (move_fast)
4082                                 {
4083                                         int mag = MIN(wid / 2, hgt / 2);
4084                                         x += dx * mag;
4085                                         y += dy * mag;
4086                                 }
4087                                 else
4088                                 {
4089                                         x += dx;
4090                                         y += dy;
4091                                 }
4092
4093                                 /* Do not move horizontally if unnecessary */
4094                                 if (((x < panel_col_min + wid / 2) && (dx > 0)) ||
4095                                          ((x > panel_col_min + wid / 2) && (dx < 0)))
4096                                 {
4097                                         dx = 0;
4098                                 }
4099
4100                                 /* Do not move vertically if unnecessary */
4101                                 if (((y < panel_row_min + hgt / 2) && (dy > 0)) ||
4102                                          ((y > panel_row_min + hgt / 2) && (dy < 0)))
4103                                 {
4104                                         dy = 0;
4105                                 }
4106
4107                                 /* Apply the motion */
4108                                 if ((y >= panel_row_min + hgt) || (y < panel_row_min) ||
4109                                          (x >= panel_col_min + wid) || (x < panel_col_min))
4110                                 {
4111                                         /* if (change_panel(dy, dx)) target_set_prepare(mode); */
4112                                         change_panel(dy, dx);
4113                                 }
4114
4115                                 /* Slide into legality */
4116                                 if (x >= cur_wid-1) x = cur_wid - 2;
4117                                 else if (x <= 0) x = 1;
4118
4119                                 /* Slide into legality */
4120                                 if (y >= cur_hgt-1) y = cur_hgt- 2;
4121                                 else if (y <= 0) y = 1;
4122
4123                         }
4124                         break;
4125                 }
4126         }
4127
4128         /* Clear the top line */
4129         prt("", 0, 0);
4130
4131         /* Recenter the map around the player */
4132         verify_panel();
4133
4134         p_ptr->update |= (PU_MONSTERS);
4135
4136         p_ptr->redraw |= (PR_MAP);
4137
4138         p_ptr->window |= (PW_OVERHEAD);
4139         handle_stuff();
4140
4141         *x_ptr = x;
4142         *y_ptr = y;
4143         return success;
4144 }
4145
4146
4147 bool get_hack_dir(DIRECTION *dp)
4148 {
4149         DIRECTION dir;
4150         concptr    p;
4151         char    command;
4152
4153         (*dp) = 0;
4154
4155         /* Global direction */
4156         dir = 0;
4157
4158         /* (No auto-targeting) */
4159
4160         /* Ask until satisfied */
4161         while (!dir)
4162         {
4163                 /* Choose a prompt */
4164                 if (!target_okay())
4165                 {
4166                         p = _("方向 ('*'でターゲット選択, ESCで中断)? ", "Direction ('*' to choose a target, Escape to cancel)? ");
4167                 }
4168                 else
4169                 {
4170                         p = _("方向 ('5'でターゲットへ, '*'でターゲット再選択, ESCで中断)? ", "Direction ('5' for target, '*' to re-target, Escape to cancel)? ");
4171                 }
4172
4173                 /* Get a command (or Cancel) */
4174                 if (!get_com(p, &command, TRUE)) break;
4175
4176                 if (use_menu)
4177                 {
4178                         if (command == '\r') command = 't';
4179                 }  
4180
4181                 /* Convert various keys to "standard" keys */
4182                 switch (command)
4183                 {
4184                         /* Use current target */
4185                         case 'T':
4186                         case 't':
4187                         case '.':
4188                         case '5':
4189                         case '0':
4190                         {
4191                                 dir = 5;
4192                                 break;
4193                         }
4194
4195                         /* Set new target */
4196                         case '*':
4197                         case ' ':
4198                         case '\r':
4199                         {
4200                                 if (target_set(TARGET_KILL)) dir = 5;
4201                                 break;
4202                         }
4203
4204                         default:
4205                         {
4206                                 /* Look up the direction */
4207                                 dir = get_keymap_dir(command);
4208
4209                                 break;
4210                         }
4211                 }
4212
4213                 /* Verify requested targets */
4214                 if ((dir == 5) && !target_okay()) dir = 0;
4215
4216                 /* Error */
4217                 if (!dir) bell();
4218         }
4219
4220         /* No direction */
4221         if (!dir) return (FALSE);
4222
4223         /* Save the direction */
4224         command_dir = dir;
4225
4226         /* Check for confusion */
4227         if (p_ptr->confused)
4228         {
4229                 /* Random direction */
4230                 dir = ddd[randint0(8)];
4231         }
4232
4233         /* Notice confusion */
4234         if (command_dir != dir)
4235         {
4236                 /* Warn the user */
4237                 msg_print(_("あなたは混乱している。", "You are confused."));
4238         }
4239
4240         /* Save direction */
4241         (*dp) = dir;
4242
4243         /* A "valid" direction was entered */
4244         return (TRUE);
4245 }
4246
4247
4248 /*!
4249  * @brief 射撃武器の攻撃に必要な基本消費エネルギーを返す/Return bow energy
4250  * @param sval 射撃武器のアイテム副分類ID 
4251  * @return 消費する基本エネルギー
4252  */
4253 ENERGY bow_energy(OBJECT_SUBTYPE_VALUE sval)
4254 {
4255         ENERGY energy = 10000;
4256
4257         /* Analyze the launcher */
4258         switch (sval)
4259         {
4260                 /* Sling and ammo */
4261                 case SV_SLING:
4262                 {
4263                         energy = 8000;
4264                         break;
4265                 }
4266
4267                 /* Short Bow and Arrow */
4268                 case SV_SHORT_BOW:
4269                 {
4270                         energy = 10000;
4271                         break;
4272                 }
4273
4274                 /* Long Bow and Arrow */
4275                 case SV_LONG_BOW:
4276                 {
4277                         energy = 10000;
4278                         break;
4279                 }
4280
4281                 /* Bow of irresponsiblity and Arrow */
4282                 case SV_NAMAKE_BOW:
4283                 {
4284                         energy = 7777;
4285                         break;
4286                 }
4287
4288                 /* Light Crossbow and Bolt */
4289                 case SV_LIGHT_XBOW:
4290                 {
4291                         energy = 12000;
4292                         break;
4293                 }
4294
4295                 /* Heavy Crossbow and Bolt */
4296                 case SV_HEAVY_XBOW:
4297                 {
4298                         energy = 13333;
4299                         break;
4300                 }
4301         }
4302
4303         return (energy);
4304 }
4305
4306
4307 /*
4308  * Return bow tmul
4309  */
4310 int bow_tmul(OBJECT_SUBTYPE_VALUE sval)
4311 {
4312         int tmul = 0;
4313
4314         /* Analyze the launcher */
4315         switch (sval)
4316         {
4317                 /* Sling and ammo */
4318                 case SV_SLING:
4319                 {
4320                         tmul = 2;
4321                         break;
4322                 }
4323
4324                 /* Short Bow and Arrow */
4325                 case SV_SHORT_BOW:
4326                 {
4327                         tmul = 2;
4328                         break;
4329                 }
4330
4331                 /* Long Bow and Arrow */
4332                 case SV_LONG_BOW:
4333                 {
4334                         tmul = 3;
4335                         break;
4336                 }
4337
4338                 /* Bow of irresponsiblity and Arrow */
4339                 case SV_NAMAKE_BOW:
4340                 {
4341                         tmul = 3;
4342                         break;
4343                 }
4344
4345                 /* Light Crossbow and Bolt */
4346                 case SV_LIGHT_XBOW:
4347                 {
4348                         tmul = 3;
4349                         break;
4350                 }
4351
4352                 /* Heavy Crossbow and Bolt */
4353                 case SV_HEAVY_XBOW:
4354                 {
4355                         tmul = 4;
4356                         break;
4357                 }
4358         }
4359
4360         return (tmul);
4361 }
4362
4363
4364 /*
4365  * Display a rumor and apply its effects
4366  */
4367
4368 IDX rumor_num(char *zz, IDX max_idx)
4369 {
4370         if (strcmp(zz, "*") == 0) return randint1(max_idx - 1);
4371         return (IDX)atoi(zz);
4372 }
4373
4374 concptr rumor_bind_name(char *base, concptr fullname)
4375 {
4376         char *s, *v;
4377
4378         s = strstr(base, "{Name}");
4379         if (s)
4380         {
4381                 s[0] = '\0';
4382                 v = format("%s%s%s", base, fullname, (s + 6));
4383         }
4384         else
4385         {
4386                 v = base;
4387         }
4388
4389         return v;
4390 }
4391
4392 void display_rumor(bool ex)
4393 {
4394         errr err;
4395         int section = 0;
4396         char Rumor[1024];
4397
4398         if (ex)
4399         {
4400                 if (randint0(3) == 0) section = 1;
4401         }
4402
4403         err = _(get_rnd_line_jonly("rumors_j.txt", section, Rumor, 10),
4404                         get_rnd_line("rumors.txt", section, Rumor));
4405         if (err) strcpy(Rumor, _("嘘の噂もある。", "Some rumors are wrong."));
4406
4407         err = TRUE;
4408
4409         if (strncmp(Rumor, "R:", 2) == 0)
4410         {
4411                 char *zz[4];
4412                 concptr rumor_msg = NULL;
4413                 concptr rumor_eff_format = NULL;
4414                 char fullname[1024] = "";
4415
4416                 if (tokenize(Rumor + 2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
4417                 {
4418                         if (strcmp(zz[0], "ARTIFACT") == 0)
4419                         {
4420                                 IDX a_idx, k_idx;
4421                                 object_type forge;
4422                                 object_type *q_ptr = &forge;
4423                                 artifact_type *a_ptr;
4424
4425                                 while (1)
4426                                 {
4427                                         a_idx = rumor_num(zz[1], max_a_idx);
4428
4429                                         a_ptr = &a_info[a_idx];
4430                                         if (a_ptr->name) break;
4431                                 }
4432
4433                                 k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
4434                                 object_prep(q_ptr, k_idx);
4435                                 q_ptr->name1 = a_idx;
4436                                 q_ptr->ident = IDENT_STORE;
4437                                 object_desc(fullname, q_ptr, OD_NAME_ONLY);
4438                         }
4439                         else if  (strcmp(zz[0], "MONSTER") == 0)
4440                         {
4441                                 MONRACE_IDX r_idx;
4442                                 monster_race *r_ptr;
4443
4444                                 while(1)
4445                                 {
4446                                         r_idx = rumor_num(zz[1], max_r_idx);
4447                                         r_ptr = &r_info[r_idx];
4448                                         if (r_ptr->name) break;
4449                                 }
4450
4451                                 strcpy(fullname, r_name + r_ptr->name);
4452
4453                                 /* Remember this monster */
4454                                 if (!r_ptr->r_sights)
4455                                 {
4456                                         r_ptr->r_sights++;
4457                                 }
4458                         }
4459                         else if (strcmp(zz[0], "DUNGEON") == 0)
4460                         {
4461                                 DUNGEON_IDX d_idx;
4462                                 dungeon_info_type *d_ptr;
4463
4464                                 while (1)
4465                                 {
4466                                         d_idx = rumor_num(zz[1], max_d_idx);
4467                                         d_ptr = &d_info[d_idx];
4468                                         if (d_ptr->name) break;
4469                                 }
4470
4471                                 strcpy(fullname, d_name + d_ptr->name);
4472
4473                                 if (!max_dlv[d_idx])
4474                                 {
4475                                         max_dlv[d_idx] = d_ptr->mindepth;
4476                                         rumor_eff_format = _("%sに帰還できるようになった。", "You can recall to %s.");
4477                                 }
4478                         }
4479                         else if  (strcmp(zz[0], "TOWN") == 0)
4480                         {
4481                                 IDX t_idx;
4482                                 s32b visit;
4483
4484                                 while(1)
4485                                 {
4486                                         t_idx = rumor_num(zz[1], NO_TOWN);
4487                                         if (town[t_idx].name) break;
4488                                 }
4489
4490                                 strcpy(fullname, town[t_idx].name);
4491
4492                                 visit = (1L << (t_idx - 1));
4493                                 if ((t_idx != SECRET_TOWN) && !(p_ptr->visit & visit))
4494                                 {
4495                                         p_ptr->visit |= visit;
4496                                         rumor_eff_format = _("%sに行ったことがある気がする。", "You feel you have been to %s.");
4497                                 }
4498                         }
4499
4500                         rumor_msg = rumor_bind_name(zz[2], fullname);
4501                         msg_print(rumor_msg);
4502                         if (rumor_eff_format)
4503                         {
4504                                 msg_print(NULL);
4505                                 msg_format(rumor_eff_format, fullname);
4506                         }
4507                         err = FALSE;
4508                 }
4509         /* error */
4510         if (err) msg_print(_("この情報は間違っている。", "This information is wrong."));
4511         }
4512                         else
4513         {
4514                 msg_format("%s", Rumor);
4515         }
4516 }