OSDN Git Service

[Refactor] #37353 コメント整理 / Refactor comments.
[hengband/hengband.git] / src / cmd2.c
1 /*!
2  *  @file cmd2.c
3  *  @brief プレイヤーのコマンド処理2 / Movement commands (part 2)
4  *  @date 2014/01/02
5  *  @author
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research,
9  * and not for profit purposes provided that this copyright and statement
10  * are included in all such copies.  Other copyrights may also apply.
11  */
12
13 #include "angband.h"
14 #include "chest.h"
15 #include "object-hook.h"
16
17 /*!
18  * @brief フロア脱出時に出戻りが不可能だった場合に警告を加える処理
19  * @param down_stair TRUEならば階段を降りる処理、FALSEなら階段を昇る処理による内容
20  * @return フロア移動を実際に行うならTRUE、キャンセルする場合はFALSE
21  */
22 bool confirm_leave_level(bool down_stair)
23 {
24         quest_type *q_ptr = &quest[p_ptr->inside_quest];
25
26         /* Confirm leaving from once only quest */
27         if (confirm_quest && p_ptr->inside_quest &&
28             (q_ptr->type == QUEST_TYPE_RANDOM ||
29              (q_ptr->flags & QUEST_FLAG_ONCE &&
30                                                 q_ptr->status != QUEST_STATUS_COMPLETED) ||
31                  (q_ptr->flags & QUEST_FLAG_TOWER &&
32                                                 ((q_ptr->status != QUEST_STATUS_STAGE_COMPLETED) ||
33                                                  (down_stair && (quest[QUEST_TOWER1].status != QUEST_STATUS_COMPLETED))))))
34         {
35                 msg_print(_("この階を一度去ると二度と戻って来られません。", "You can't come back here once you leave this floor."));
36                 if (get_check(_("本当にこの階を去りますか?", "Really leave this floor? "))) return TRUE;
37         }
38         else
39         {
40                 return TRUE;
41         }
42         return FALSE;
43 }
44
45 /*!
46  * @brief 階段を使って階層を昇る処理 / Go up one level
47  * @return なし
48  */
49 void do_cmd_go_up(void)
50 {
51         bool go_up = FALSE;
52
53         /* Player grid */
54         cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x];
55         feature_type *f_ptr = &f_info[c_ptr->feat];
56
57         int up_num = 0;
58
59         if (p_ptr->special_defense & KATA_MUSOU)
60         {
61                 set_action(ACTION_NONE);
62         }
63
64         /* Verify stairs */
65         if (!have_flag(f_ptr->flags, FF_LESS))
66         {
67                 msg_print(_("ここには上り階段が見当たらない。", "I see no up staircase here."));
68                 return;
69         }
70
71         /* Quest up stairs */
72         if (have_flag(f_ptr->flags, FF_QUEST))
73         {
74                 /* Cancel the command */
75                 if (!confirm_leave_level(FALSE)) return;
76         
77                 
78                 /* Success */
79                 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
80                         msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
81                 else
82                         msg_print(_("上の階に登った。", "You enter the up staircase."));
83
84                 leave_quest_check();
85
86                 p_ptr->inside_quest = c_ptr->special;
87
88                 /* Activate the quest */
89                 if (!quest[p_ptr->inside_quest].status)
90                 {
91                         if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
92                         {
93                                 init_flags = INIT_ASSIGN;
94                                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
95                         }
96                         quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
97                 }
98
99                 /* Leaving a quest */
100                 if (!p_ptr->inside_quest)
101                 {
102                         dun_level = 0;
103                 }
104
105                 /* Leaving */
106                 p_ptr->leaving = TRUE;
107
108                 p_ptr->oldpx = 0;
109                 p_ptr->oldpy = 0;
110                 
111                 /* Hack -- take a turn */
112                 p_ptr->energy_use = 100;
113
114                 /* End the command */
115                 return;
116         }
117
118         if (!dun_level)
119         {
120                 go_up = TRUE;
121         }
122         else
123         {
124                 go_up = confirm_leave_level(FALSE);
125         }
126
127         /* Cancel the command */
128         if (!go_up) return;
129
130         /* Hack -- take a turn */
131         p_ptr->energy_use = 100;
132
133         if (autosave_l) do_cmd_save_game(TRUE);
134
135         /* For a random quest */
136         if (p_ptr->inside_quest &&
137             quest[p_ptr->inside_quest].type == QUEST_TYPE_RANDOM)
138         {
139                 leave_quest_check();
140
141                 p_ptr->inside_quest = 0;
142         }
143
144         /* For a fixed quest */
145         if (p_ptr->inside_quest &&
146             quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
147         {
148                 leave_quest_check();
149
150                 p_ptr->inside_quest = c_ptr->special;
151                 dun_level = 0;
152                 up_num = 0;
153         }
154
155         /* For normal dungeon and random quest */
156         else
157         {
158                 /* New depth */
159                 if (have_flag(f_ptr->flags, FF_SHAFT))
160                 {
161                         /* Create a way back */
162                         prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP | CFM_SHAFT);
163
164                         up_num = 2;
165                 }
166                 else
167                 {
168                         /* Create a way back */
169                         prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP);
170
171                         up_num = 1;
172                 }
173
174                 /* Get out from current dungeon */
175                 if (dun_level - up_num < d_info[dungeon_type].mindepth)
176                         up_num = dun_level;
177         }
178         if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, _("階段を上った", "climbed up the stairs to"));
179
180         /* Success */
181         if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
182                 msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
183         else if (up_num == dun_level)
184                 msg_print(_("地上に戻った。", "You go back to the surface."));
185         else
186                 msg_print(_("階段を上って新たなる迷宮へと足を踏み入れた。", "You enter a maze of up staircases."));
187
188         /* Leaving */
189         p_ptr->leaving = TRUE;
190 }
191
192
193 /*!
194  * @brief 階段を使って階層を降りる処理 / Go down one level
195  * @return なし
196  */
197 void do_cmd_go_down(void)
198 {
199         /* Player grid */
200         cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x];
201         feature_type *f_ptr = &f_info[c_ptr->feat];
202
203         bool fall_trap = FALSE;
204         int down_num = 0;
205
206         if (p_ptr->special_defense & KATA_MUSOU)
207         {
208                 set_action(ACTION_NONE);
209         }
210
211         /* Verify stairs */
212         if (!have_flag(f_ptr->flags, FF_MORE))
213         {
214                 msg_print(_("ここには下り階段が見当たらない。", "I see no down staircase here."));
215                 return;
216         }
217
218         if (have_flag(f_ptr->flags, FF_TRAP)) fall_trap = TRUE;
219
220         /* Quest entrance */
221         if (have_flag(f_ptr->flags, FF_QUEST_ENTER))
222         {
223                 do_cmd_quest();
224         }
225
226         /* Quest down stairs */
227         else if (have_flag(f_ptr->flags, FF_QUEST))
228         {
229                 /* Confirm Leaving */
230                 if(!confirm_leave_level(TRUE)) return;
231                 
232                 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
233                         msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
234                 else
235                         msg_print(_("下の階に降りた。", "You enter the down staircase."));
236
237                 leave_quest_check();
238                 leave_tower_check();
239
240                 p_ptr->inside_quest = c_ptr->special;
241
242                 /* Activate the quest */
243                 if (!quest[p_ptr->inside_quest].status)
244                 {
245                         if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
246                         {
247                                 init_flags = INIT_ASSIGN;
248                                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
249                         }
250                         quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
251                 }
252
253                 /* Leaving a quest */
254                 if (!p_ptr->inside_quest)
255                 {
256                         dun_level = 0;
257                 }
258
259                 /* Leaving */
260                 p_ptr->leaving = TRUE;
261
262                 p_ptr->oldpx = 0;
263                 p_ptr->oldpy = 0;
264                 
265                 
266         /* Hack -- take a turn */
267         p_ptr->energy_use = 100;
268         }
269
270         else
271         {
272                 int target_dungeon = 0;
273
274                 if (!dun_level)
275                 {
276                         target_dungeon = have_flag(f_ptr->flags, FF_ENTRANCE) ? c_ptr->special : DUNGEON_ANGBAND;
277
278                         if (ironman_downward && (target_dungeon != DUNGEON_ANGBAND))
279                         {
280                                 msg_print(_("ダンジョンの入口は塞がれている!", "The entrance of this dungeon is closed!"));
281                                 return;
282                         }
283                         if (!max_dlv[target_dungeon])
284                         {
285                                 msg_format(_("ここには%sの入り口(%d階相当)があります", "There is the entrance of %s (Danger level: %d)"),
286                                                         d_name+d_info[target_dungeon].name, d_info[target_dungeon].mindepth);
287                                 if (!get_check(_("本当にこのダンジョンに入りますか?", "Do you really get in this dungeon? "))) return;
288                         }
289
290                         /* Save old player position */
291                         p_ptr->oldpx = p_ptr->x;
292                         p_ptr->oldpy = p_ptr->y;
293                         dungeon_type = (byte)target_dungeon;
294
295                         /*
296                          * Clear all saved floors
297                          * and create a first saved floor
298                          */
299                         prepare_change_floor_mode(CFM_FIRST_FLOOR);
300                 }
301
302                 /* Hack -- take a turn */
303                 p_ptr->energy_use = 100;
304
305                 if (autosave_l) do_cmd_save_game(TRUE);
306
307                 /* Go down */
308                 if (have_flag(f_ptr->flags, FF_SHAFT)) down_num += 2;
309                 else down_num += 1;
310
311                 if (!dun_level)
312                 {
313                         /* Enter the dungeon just now */
314                         p_ptr->enter_dungeon = TRUE;
315                         down_num = d_info[dungeon_type].mindepth;
316                 }
317
318                 if (record_stair)
319                 {
320                         if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, _("落とし戸に落ちた", "fell through a trap door"));
321                         else do_cmd_write_nikki(NIKKI_STAIR, down_num, _("階段を下りた", "climbed down the stairs to"));
322                 }
323
324                 if (fall_trap)
325                 {
326                         msg_print(_("わざと落とし戸に落ちた。", "You deliberately jump through the trap door."));
327                 }
328                 else
329                 {
330                         /* Success */
331                         if (target_dungeon)
332                         {
333                                 msg_format(_("%sへ入った。", "You entered %s."), d_text + d_info[dungeon_type].text);
334                         }
335                         else
336                         {
337                                 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
338                                         msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
339                                 else
340                                         msg_print(_("階段を下りて新たなる迷宮へと足を踏み入れた。", "You enter a maze of down staircases."));
341                         }
342                 }
343
344
345                 /* Leaving */
346                 p_ptr->leaving = TRUE;
347
348                 if (fall_trap)
349                 {
350                         prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
351                 }
352                 else
353                 {
354                         if (have_flag(f_ptr->flags, FF_SHAFT))
355                         {
356                                 /* Create a way back */
357                                 prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_SHAFT);
358                         }
359                         else
360                         {
361                                 /* Create a way back */
362                                 prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN);
363                         }
364                 }
365         }
366 }
367
368
369 /*!
370  * @brief 探索コマンドのメインルーチン / Simple command to "search" for one turn
371  * @return なし
372  */
373 void do_cmd_search(void)
374 {
375         /* Allow repeated command */
376         if (command_arg)
377         {
378                 /* Set repeat count */
379                 command_rep = command_arg - 1;
380
381                 /* Redraw the state */
382                 p_ptr->redraw |= (PR_STATE);
383
384                 /* Cancel the arg */
385                 command_arg = 0;
386         }
387         p_ptr->energy_use = 100;
388
389         /* Search */
390         search();
391 }
392
393
394 /*!
395  * @brief 該当のマスに存在している箱のオブジェクトIDを返す。
396  * @param y 走査対象にしたいマスのY座標
397  * @param x 走査対象にしたいマスのX座標
398  * @param trapped TRUEならばトラップが存在する箱のみ、FALSEならば空でない箱全てを対象にする
399  * @return 箱が存在する場合そのオブジェクトID、存在しない場合0を返す。
400  */
401 static OBJECT_IDX chest_check(POSITION y, POSITION x, bool trapped)
402 {
403         cave_type *c_ptr = &cave[y][x];
404         OBJECT_IDX this_o_idx, next_o_idx = 0;
405
406         /* Scan all objects in the grid */
407         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
408         {
409                 object_type *o_ptr;
410
411                 o_ptr = &o_list[this_o_idx];
412                 next_o_idx = o_ptr->next_o_idx;
413
414                 /* Skip unknown chests XXX XXX */
415                 /* if (!(o_ptr->marked & OM_FOUND)) continue; */
416
417                 /* Check for non empty chest */
418                 if ((o_ptr->tval == TV_CHEST) &&
419                         (((!trapped) && (o_ptr->pval)) || /* non empty */
420                         ((trapped) && (o_ptr->pval > 0)))) /* trapped only */
421                 {
422                         return (this_o_idx);
423                 }
424         }
425         return (0);
426 }
427
428 /*!
429  * @brief 箱を開けるコマンドのメインルーチン /
430  * Attempt to open the given chest at the given location
431  * @param y 箱の存在するマスのY座標
432  * @param x 箱の存在するマスのX座標
433  * @param o_idx 箱のオブジェクトID
434  * @return 箱が開かなかった場合TRUE / Returns TRUE if repeated commands may continue
435  * @details
436  * Assume there is no monster blocking the destination
437  */
438 static bool do_cmd_open_chest(POSITION y, POSITION x, OBJECT_IDX o_idx)
439 {
440         int i, j;
441         bool flag = TRUE;
442         bool more = FALSE;
443         object_type *o_ptr = &o_list[o_idx];
444
445         p_ptr->energy_use = 100;
446
447         /* Attempt to unlock it */
448         if (o_ptr->pval > 0)
449         {
450                 /* Assume locked, and thus not open */
451                 flag = FALSE;
452
453                 /* Get the "disarm" factor */
454                 i = p_ptr->skill_dis;
455
456                 /* Penalize some conditions */
457                 if (p_ptr->blind || no_lite()) i = i / 10;
458                 if (p_ptr->confused || p_ptr->image) i = i / 10;
459
460                 /* Extract the difficulty */
461                 j = i - o_ptr->pval;
462
463                 /* Always have a small chance of success */
464                 if (j < 2) j = 2;
465
466                 /* Success -- May still have traps */
467                 if (randint0(100) < j)
468                 {
469                         msg_print(_("鍵をはずした。", "You have picked the lock."));
470                         gain_exp(1);
471                         flag = TRUE;
472                 }
473
474                 /* Failure -- Keep trying */
475                 else
476                 {
477                         /* We may continue repeating */
478                         more = TRUE;
479                         if (flush_failure) flush();
480                         msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
481
482                 }
483         }
484
485         /* Allowed to open */
486         if (flag)
487         {
488                 /* Apply chest traps, if any */
489                 chest_trap(y, x, o_idx);
490
491                 /* Let the Chest drop items */
492                 chest_death(FALSE, y, x, o_idx);
493         }
494
495         /* Result */
496         return (more);
497 }
498
499 /*!
500  * @brief 地形は開くものであって、かつ開かれているかを返す /
501  * Attempt to open the given chest at the given location
502  * @param feat 地形ID
503  * @return 開いた地形である場合TRUEを返す /  Return TRUE if the given feature is an open door
504  */
505 static bool is_open(IDX feat)
506 {
507         return have_flag(f_info[feat].flags, FF_CLOSE) && (feat != feat_state(feat, FF_CLOSE));
508 }
509
510
511 /*!
512  * @brief プレイヤーの周辺9マスに該当する地形がいくつあるかを返す /
513  * Attempt to open the given chest at the given location
514  * @param y 該当する地形の中から1つのY座標を返す参照ポインタ
515  * @param x 該当する地形の中から1つのX座標を返す参照ポインタ
516  * @param test 地形条件を判定するための関数ポインタ
517  * @param under TRUEならばプレイヤーの直下の座標も走査対象にする
518  * @return 該当する地形の数
519  * @details Return the number of features around (or under) the character.
520  * Usually look for doors and floor traps.
521  */
522 static int count_dt(POSITION *y, POSITION *x, bool (*test)(IDX feat), bool under)
523 {
524         int d, count, xx, yy;
525
526         /* Count how many matches */
527         count = 0;
528
529         /* Check around (and under) the character */
530         for (d = 0; d < 9; d++)
531         {
532                 cave_type *c_ptr;
533                 FEAT_IDX feat;
534
535                 /* if not searching under player continue */
536                 if ((d == 8) && !under) continue;
537
538                 /* Extract adjacent (legal) location */
539                 yy = p_ptr->y + ddy_ddd[d];
540                 xx = p_ptr->x + ddx_ddd[d];
541
542                 /* Get the cave */
543                 c_ptr = &cave[yy][xx];
544
545                 /* Must have knowledge */
546                 if (!(c_ptr->info & (CAVE_MARK))) continue;
547
548                 /* Feature code (applying "mimic" field) */
549                 feat = get_feat_mimic(c_ptr);
550
551                 /* Not looking for this feature */
552                 if (!((*test)(feat))) continue;
553
554                 /* OK */
555                 ++count;
556
557                 /* Remember the location. Only useful if only one match */
558                 *y = yy;
559                 *x = xx;
560         }
561
562         /* All done */
563         return count;
564 }
565
566
567 /*!
568  * @brief プレイヤーの周辺9マスに箱のあるマスがいくつあるかを返す /
569  * Return the number of chests around (or under) the character.
570  * @param y 該当するマスの中から1つのY座標を返す参照ポインタ
571  * @param x 該当するマスの中から1つのX座標を返す参照ポインタ
572  * @param trapped TRUEならばトラップの存在が判明している箱のみ対象にする
573  * @return 該当する地形の数
574  * @details
575  * If requested, count only trapped chests.
576  */
577 static int count_chests(POSITION *y, POSITION *x, bool trapped)
578 {
579         int d, count;
580         OBJECT_IDX o_idx;
581
582         object_type *o_ptr;
583
584         /* Count how many matches */
585         count = 0;
586
587         /* Check around (and under) the character */
588         for (d = 0; d < 9; d++)
589         {
590                 /* Extract adjacent (legal) location */
591                 POSITION yy = p_ptr->y + ddy_ddd[d];
592                 POSITION xx = p_ptr->x + ddx_ddd[d];
593
594                 /* No (visible) chest is there */
595                 if ((o_idx = chest_check(yy, xx, FALSE)) == 0) continue;
596
597                 /* Grab the object */
598                 o_ptr = &o_list[o_idx];
599
600                 /* Already open */
601                 if (o_ptr->pval == 0) continue;
602
603                 /* No (known) traps here */
604                 if (trapped && (!object_is_known(o_ptr) ||
605                         !chest_traps[o_ptr->pval])) continue;
606
607                 /* OK */
608                 ++count;
609
610                 /* Remember the location. Only useful if only one match */
611                 *y = yy;
612                 *x = xx;
613         }
614
615         /* All done */
616         return count;
617 }
618
619
620 /*!
621  * @brief プレイヤーから指定の座標がどの方角にあるかを返す /
622  * Convert an adjacent location to a direction.
623  * @param y 方角を確認したY座標
624  * @param x 方角を確認したX座標
625  * @return 方向ID
626  */
627 static DIRECTION coords_to_dir(POSITION y, POSITION x)
628 {
629         int d[3][3] = { {7, 4, 1}, {8, 5, 2}, {9, 6, 3} };
630         int dy, dx;
631
632         dy = y - p_ptr->y;
633         dx = x - p_ptr->x;
634
635         /* Paranoia */
636         if (ABS(dx) > 1 || ABS(dy) > 1) return (0);
637
638         return d[dx + 1][dy + 1];
639 }
640
641 /*!
642  * @brief 「開ける」動作コマンドのサブルーチン /
643  * Perform the basic "open" command on doors
644  * @param y 対象を行うマスのY座標
645  * @param x 対象を行うマスのX座標
646  * @return 実際に処理が行われた場合TRUEを返す。
647  * @details
648  * Assume destination is a closed/locked/jammed door
649  * Assume there is no monster blocking the destination
650  * Returns TRUE if repeated commands may continue
651  */
652 static bool do_cmd_open_aux(POSITION y, POSITION x)
653 {
654         int i, j;
655
656         /* Get requested grid */
657         cave_type *c_ptr = &cave[y][x];
658         feature_type *f_ptr = &f_info[c_ptr->feat];
659         bool more = FALSE;
660
661         p_ptr->energy_use = 100;
662
663         /* Seeing true feature code (ignore mimic) */
664
665         /* Jammed door */
666         if (!have_flag(f_ptr->flags, FF_OPEN))
667         {
668                 /* Stuck */
669                 msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_name + f_info[get_feat_mimic(c_ptr)].name);
670         }
671
672         /* Locked door */
673         else if (f_ptr->power)
674         {
675                 /* Disarm factor */
676                 i = p_ptr->skill_dis;
677
678                 /* Penalize some conditions */
679                 if (p_ptr->blind || no_lite()) i = i / 10;
680                 if (p_ptr->confused || p_ptr->image) i = i / 10;
681
682                 /* Extract the lock power */
683                 j = f_ptr->power;
684
685                 /* Extract the difficulty */
686                 j = i - (j * 4);
687
688                 /* Always have a small chance of success */
689                 if (j < 2) j = 2;
690
691                 /* Success */
692                 if (randint0(100) < j)
693                 {
694                         msg_print(_("鍵をはずした。", "You have picked the lock."));
695
696                         /* Open the door */
697                         cave_alter_feat(y, x, FF_OPEN);
698
699                         sound(SOUND_OPENDOOR);
700
701                         /* Experience */
702                         gain_exp(1);
703                 }
704
705                 /* Failure */
706                 else
707                 {
708                         /* Failure */
709                         if (flush_failure) flush();
710
711                         msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
712
713                         /* We may keep trying */
714                         more = TRUE;
715                 }
716         }
717
718         /* Closed door */
719         else
720         {
721                 /* Open the door */
722                 cave_alter_feat(y, x, FF_OPEN);
723
724                 sound(SOUND_OPENDOOR);
725         }
726
727         /* Result */
728         return (more);
729 }
730
731 /*!
732  * @brief 「開ける」コマンドのメインルーチン /
733  * Open a closed/locked/jammed door or a closed/locked chest.
734  * @return なし
735  * @details
736  * Unlocking a locked door/chest is worth one experience point.
737  */
738 void do_cmd_open(void)
739 {
740         POSITION y, x;
741         DIRECTION dir;
742         OBJECT_IDX o_idx;
743
744         bool more = FALSE;
745
746         if (p_ptr->special_defense & KATA_MUSOU)
747         {
748                 set_action(ACTION_NONE);
749         }
750
751         /* Option: Pick a direction */
752         if (easy_open)
753         {
754                 int num_doors, num_chests;
755
756                 /* Count closed doors (locked or jammed) */
757                 num_doors = count_dt(&y, &x, is_closed_door, FALSE);
758
759                 /* Count chests (locked) */
760                 num_chests = count_chests(&y, &x, FALSE);
761
762                 /* See if only one target */
763                 if (num_doors || num_chests)
764                 {
765                         bool too_many = (num_doors && num_chests) || (num_doors > 1) ||
766                             (num_chests > 1);
767                         if (!too_many) command_dir = coords_to_dir(y, x);
768                 }
769         }
770
771         /* Allow repeated command */
772         if (command_arg)
773         {
774                 /* Set repeat count */
775                 command_rep = command_arg - 1;
776
777                 /* Redraw the state */
778                 p_ptr->redraw |= (PR_STATE);
779
780                 /* Cancel the arg */
781                 command_arg = 0;
782         }
783
784         /* Get a "repeated" direction */
785         if (get_rep_dir(&dir, TRUE))
786         {
787                 FEAT_IDX feat;
788                 cave_type *c_ptr;
789
790                 /* Get requested location */
791                 y = p_ptr->y + ddy[dir];
792                 x = p_ptr->x + ddx[dir];
793
794                 /* Get requested grid */
795                 c_ptr = &cave[y][x];
796
797                 /* Feature code (applying "mimic" field) */
798                 feat = get_feat_mimic(c_ptr);
799
800                 /* Check for chest */
801                 o_idx = chest_check(y, x, FALSE);
802
803                 /* Nothing useful */
804                 if (!have_flag(f_info[feat].flags, FF_OPEN) && !o_idx)
805                 {
806                         msg_print(_("そこには開けるものが見当たらない。", "You see nothing there to open."));
807                 }
808
809                 /* Monster in the way */
810                 else if (c_ptr->m_idx && p_ptr->riding != c_ptr->m_idx)
811                 {
812                         p_ptr->energy_use = 100;
813
814                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
815                         
816                         /* Attack */
817                         py_attack(y, x, 0);
818                 }
819
820                 /* Handle chests */
821                 else if (o_idx)
822                 {
823                         /* Open the chest */
824                         more = do_cmd_open_chest(y, x, o_idx);
825                 }
826
827                 /* Handle doors */
828                 else
829                 {
830                         /* Open the door */
831                         more = do_cmd_open_aux(y, x);
832                 }
833         }
834
835         /* Cancel repeat unless we may continue */
836         if (!more) disturb(FALSE, FALSE);
837 }
838
839
840
841 /*!
842  * @brief 「閉じる」動作コマンドのサブルーチン /
843  * Perform the basic "close" command
844  * @param y 対象を行うマスのY座標
845  * @param x 対象を行うマスのX座標
846  * @return 実際に処理が行われた場合TRUEを返す。
847  * @details
848  * Assume destination is an open/broken door
849  * Assume there is no monster blocking the destination
850  * Returns TRUE if repeated commands may continue
851  */
852 static bool do_cmd_close_aux(POSITION y, POSITION x)
853 {
854         /* Get grid and contents */
855         cave_type *c_ptr = &cave[y][x];
856         FEAT_IDX old_feat = c_ptr->feat;
857         bool more = FALSE;
858
859         p_ptr->energy_use = 100;
860
861         /* Seeing true feature code (ignore mimic) */
862
863         /* Open door */
864         if (have_flag(f_info[old_feat].flags, FF_CLOSE))
865         {
866                 s16b closed_feat = feat_state(old_feat, FF_CLOSE);
867
868                 /* Hack -- object in the way */
869                 if ((c_ptr->o_idx || (c_ptr->info & CAVE_OBJECT)) &&
870                     (closed_feat != old_feat) && !have_flag(f_info[closed_feat].flags, FF_DROP))
871                 {
872                         msg_print(_("何かがつっかえて閉まらない。", "There seems stuck."));
873                 }
874                 else
875                 {
876                         /* Close the door */
877                         cave_alter_feat(y, x, FF_CLOSE);
878
879                         /* Broken door */
880                         if (old_feat == c_ptr->feat)
881                         {
882                                 msg_print(_("ドアは壊れてしまっている。", "The door appears to be broken."));
883                         }
884                         else
885                         {
886                                 sound(SOUND_SHUTDOOR);
887                         }
888                 }
889         }
890
891         /* Result */
892         return (more);
893 }
894
895
896 /*!
897  * @brief 「閉じる」コマンドのメインルーチン /
898  * Close an open door.
899  * @return なし
900  * @details
901  * Unlocking a locked door/chest is worth one experience point.
902  */
903 void do_cmd_close(void)
904 {
905         POSITION y, x;
906         DIRECTION dir;
907
908         bool more = FALSE;
909
910         if (p_ptr->special_defense & KATA_MUSOU)
911         {
912                 set_action(ACTION_NONE);
913         }
914
915         /* Option: Pick a direction */
916         if (easy_open)
917         {
918                 /* Count open doors */
919                 if (count_dt(&y, &x, is_open, FALSE) == 1)
920                 {
921                         command_dir = coords_to_dir(y, x);
922                 }
923         }
924
925         /* Allow repeated command */
926         if (command_arg)
927         {
928                 /* Set repeat count */
929                 command_rep = command_arg - 1;
930
931                 /* Redraw the state */
932                 p_ptr->redraw |= (PR_STATE);
933
934                 /* Cancel the arg */
935                 command_arg = 0;
936         }
937
938         /* Get a "repeated" direction */
939         if (get_rep_dir(&dir, FALSE))
940         {
941                 cave_type *c_ptr;
942                 FEAT_IDX feat;
943
944                 /* Get requested location */
945                 y = p_ptr->y + ddy[dir];
946                 x = p_ptr->x + ddx[dir];
947
948                 /* Get grid and contents */
949                 c_ptr = &cave[y][x];
950
951                 /* Feature code (applying "mimic" field) */
952                 feat = get_feat_mimic(c_ptr);
953
954                 /* Require open/broken door */
955                 if (!have_flag(f_info[feat].flags, FF_CLOSE))
956                 {
957                         msg_print(_("そこには閉じるものが見当たらない。", "You see nothing there to close."));
958                 }
959
960                 /* Monster in the way */
961                 else if (c_ptr->m_idx)
962                 {
963                         p_ptr->energy_use = 100;
964
965                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
966
967                         /* Attack */
968                         py_attack(y, x, 0);
969                 }
970
971                 /* Close the door */
972                 else
973                 {
974                         /* Close the door */
975                         more = do_cmd_close_aux(y, x);
976                 }
977         }
978
979         /* Cancel repeat unless we may continue */
980         if (!more) disturb(FALSE, FALSE);
981 }
982
983
984 /*!
985  * @brief 「掘る」コマンドを該当のマスに行えるかの判定と結果メッセージの表示 /
986  * Determine if a given grid may be "tunneled"
987  * @param y 対象を行うマスのY座標
988  * @param x 対象を行うマスのX座標
989  * @return 
990  */
991 static bool do_cmd_tunnel_test(POSITION y, POSITION x)
992 {
993         cave_type *c_ptr = &cave[y][x];
994
995         /* Must have knowledge */
996         if (!(c_ptr->info & CAVE_MARK))
997         {
998                 msg_print(_("そこには何も見当たらない。", "You see nothing there."));
999
1000                 return (FALSE);
1001         }
1002
1003         /* Must be a wall/door/etc */
1004         if (!cave_have_flag_grid(c_ptr, FF_TUNNEL))
1005         {
1006                 msg_print(_("そこには掘るものが見当たらない。", "You see nothing there to tunnel."));
1007
1008                 return (FALSE);
1009         }
1010
1011         return (TRUE);
1012 }
1013
1014
1015 /*!
1016  * @brief 「掘る」動作コマンドのサブルーチン /
1017  * Perform the basic "tunnel" command
1018  * @param y 対象を行うマスのY座標
1019  * @param x 対象を行うマスのX座標
1020  * @return 実際に処理が行われた場合TRUEを返す。
1021  * @details
1022  * Assumes that no monster is blocking the destination
1023  * Do not use twall anymore
1024  * Returns TRUE if repeated commands may continue
1025  */
1026 static bool do_cmd_tunnel_aux(POSITION y, POSITION x)
1027 {
1028         cave_type *c_ptr;
1029         feature_type *f_ptr, *mimic_f_ptr;
1030         int power;
1031         cptr name;
1032         bool more = FALSE;
1033
1034         /* Verify legality */
1035         if (!do_cmd_tunnel_test(y, x)) return (FALSE);
1036
1037         p_ptr->energy_use = 100;
1038
1039         /* Get grid */
1040         c_ptr = &cave[y][x];
1041         f_ptr = &f_info[c_ptr->feat];
1042         power = f_ptr->power;
1043
1044         /* Feature code (applying "mimic" field) */
1045         mimic_f_ptr = &f_info[get_feat_mimic(c_ptr)];
1046
1047         name = f_name + mimic_f_ptr->name;
1048
1049         sound(SOUND_DIG);
1050
1051         if (have_flag(f_ptr->flags, FF_PERMANENT))
1052         {
1053                 /* Titanium */
1054                 if (have_flag(mimic_f_ptr->flags, FF_PERMANENT))
1055                 {
1056                         msg_print(_("この岩は硬すぎて掘れないようだ。", "This seems to be permanent rock."));
1057                 }
1058
1059                 /* Map border (mimiccing Permanent wall) */
1060                 else
1061                 {
1062                         msg_print(_("そこは掘れない!", "You can't tunnel through that!"));
1063                 }
1064         }
1065
1066         /* Dig or tunnel */
1067         else if (have_flag(f_ptr->flags, FF_CAN_DIG))
1068         {
1069                 /* Dig */
1070                 if (p_ptr->skill_dig > randint0(20 * power))
1071                 {
1072                         msg_format(_("%sをくずした。", "You have removed the %s."), name);
1073
1074                         /* Remove the feature */
1075                         cave_alter_feat(y, x, FF_TUNNEL);
1076
1077                         /* Update some things */
1078                         p_ptr->update |= (PU_FLOW);
1079                 }
1080                 else
1081                 {
1082                         /* Message, keep digging */
1083                         msg_format(_("%sをくずしている。", "You dig into the %s."), name);
1084                         
1085                         more = TRUE;
1086                 }
1087         }
1088
1089         else
1090         {
1091                 bool tree = have_flag(mimic_f_ptr->flags, FF_TREE);
1092
1093                 /* Tunnel */
1094                 if (p_ptr->skill_dig > power + randint0(40 * power))
1095                 {
1096                         if (tree) msg_format(_("%sを切り払った。", "You have cleared away the %s."), name);
1097                         else
1098                         {
1099                                 msg_print(_("穴を掘り終えた。", "You have finished the tunnel."));
1100                                 p_ptr->update |= (PU_FLOW);
1101                         }
1102                         
1103                         if (have_flag(f_ptr->flags, FF_GLASS)) sound(SOUND_GLASS);
1104
1105                         /* Remove the feature */
1106                         cave_alter_feat(y, x, FF_TUNNEL);
1107
1108                         chg_virtue(V_DILIGENCE, 1);
1109                         chg_virtue(V_NATURE, -1);
1110                 }
1111
1112                 /* Keep trying */
1113                 else
1114                 {
1115                         if (tree)
1116                         {
1117                                 /* We may continue chopping */
1118                                 msg_format(_("%sを切っている。", "You chop away at the %s."), name);
1119                                 /* Occasional Search XXX XXX */
1120                                 if (randint0(100) < 25) search();
1121                         }
1122                         else
1123                         {
1124                                 /* We may continue tunelling */
1125                                 msg_format(_("%sに穴を掘っている。", "You tunnel into the %s."), name);
1126                         }
1127
1128                         more = TRUE;
1129                 }
1130         }
1131
1132         if (is_hidden_door(c_ptr))
1133         {
1134                 /* Occasional Search XXX XXX */
1135                 if (randint0(100) < 25) search();
1136         }
1137
1138         /* Result */
1139         return more;
1140 }
1141
1142
1143 /*!
1144  * @brief 「掘る」動作コマンドのメインルーチン /
1145  * Tunnels through "walls" (including rubble and closed doors)
1146  * @return なし
1147  * @details
1148  * <pre>
1149  * Note that you must tunnel in order to hit invisible monsters
1150  * in walls, though moving into walls still takes a turn anyway.
1151  *
1152  * Digging is very difficult without a "digger" weapon, but can be
1153  * accomplished by strong players using heavy weapons.
1154  * </pre>
1155  */
1156 void do_cmd_tunnel(void)
1157 {
1158         int                     y, x, dir;
1159
1160         cave_type       *c_ptr;
1161         FEAT_IDX feat;
1162
1163         bool            more = FALSE;
1164
1165
1166         if (p_ptr->special_defense & KATA_MUSOU)
1167         {
1168                 set_action(ACTION_NONE);
1169         }
1170
1171         /* Allow repeated command */
1172         if (command_arg)
1173         {
1174                 /* Set repeat count */
1175                 command_rep = command_arg - 1;
1176
1177                 /* Redraw the state */
1178                 p_ptr->redraw |= (PR_STATE);
1179
1180                 /* Cancel the arg */
1181                 command_arg = 0;
1182         }
1183
1184         /* Get a direction to tunnel, or Abort */
1185         if (get_rep_dir(&dir,FALSE))
1186         {
1187                 /* Get location */
1188                 y = p_ptr->y + ddy[dir];
1189                 x = p_ptr->x + ddx[dir];
1190
1191                 /* Get grid */
1192                 c_ptr = &cave[y][x];
1193
1194                 /* Feature code (applying "mimic" field) */
1195                 feat = get_feat_mimic(c_ptr);
1196
1197                 /* No tunnelling through doors */
1198                 if (have_flag(f_info[feat].flags, FF_DOOR))
1199                 {
1200                         msg_print(_("ドアは掘れない。", "You cannot tunnel through doors."));
1201                 }
1202
1203                 /* No tunnelling through most features */
1204                 else if (!have_flag(f_info[feat].flags, FF_TUNNEL))
1205                 {
1206                         msg_print(_("そこは掘れない。", "You can't tunnel through that."));
1207                 }
1208
1209                 /* A monster is in the way */
1210                 else if (c_ptr->m_idx)
1211                 {
1212                         p_ptr->energy_use = 100;
1213
1214                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1215
1216                         /* Attack */
1217                         py_attack(y, x, 0);
1218                 }
1219
1220                 /* Try digging */
1221                 else
1222                 {
1223                         /* Tunnel through walls */
1224                         more = do_cmd_tunnel_aux(y, x);
1225                 }
1226         }
1227
1228         /* Cancel repetition unless we can continue */
1229         if (!more) disturb(FALSE, FALSE);
1230 }
1231
1232 /*!
1233  * @brief 移動処理による簡易な「開く」処理 /
1234  * easy_open_door --
1235  * @return 開く処理が実際に試みられた場合TRUEを返す
1236  * @details
1237  * <pre>
1238  *      If there is a jammed/closed/locked door at the given location,
1239  *      then attempt to unlock/open it. Return TRUE if an attempt was
1240  *      made (successful or not), otherwise return FALSE.
1241  *
1242  *      The code here should be nearly identical to that in
1243  *      do_cmd_open_test() and do_cmd_open_aux().
1244  * </pre>
1245  */
1246 bool easy_open_door(POSITION y, POSITION x)
1247 {
1248         int i, j;
1249
1250         cave_type *c_ptr = &cave[y][x];
1251         feature_type *f_ptr = &f_info[c_ptr->feat];
1252
1253         /* Must be a closed door */
1254         if (!is_closed_door(c_ptr->feat))
1255         {
1256                 return (FALSE);
1257         }
1258
1259         /* Jammed door */
1260         if (!have_flag(f_ptr->flags, FF_OPEN))
1261         {
1262                 /* Stuck */
1263                 msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_name + f_info[get_feat_mimic(c_ptr)].name);
1264
1265         }
1266
1267         /* Locked door */
1268         else if (f_ptr->power)
1269         {
1270                 /* Disarm factor */
1271                 i = p_ptr->skill_dis;
1272
1273                 /* Penalize some conditions */
1274                 if (p_ptr->blind || no_lite()) i = i / 10;
1275                 if (p_ptr->confused || p_ptr->image) i = i / 10;
1276
1277                 /* Extract the lock power */
1278                 j = f_ptr->power;
1279
1280                 /* Extract the difficulty */
1281                 j = i - (j * 4);
1282
1283                 /* Always have a small chance of success */
1284                 if (j < 2) j = 2;
1285
1286                 /* Success */
1287                 if (randint0(100) < j)
1288                 {
1289                         msg_print(_("鍵をはずした。", "You have picked the lock."));
1290
1291                         /* Open the door */
1292                         cave_alter_feat(y, x, FF_OPEN);
1293
1294                         sound(SOUND_OPENDOOR);
1295
1296                         /* Experience */
1297                         gain_exp(1);
1298                 }
1299
1300                 /* Failure */
1301                 else
1302                 {
1303                         /* Failure */
1304                         if (flush_failure) flush();
1305
1306                         msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
1307
1308                 }
1309         }
1310
1311         /* Closed door */
1312         else
1313         {
1314                 /* Open the door */
1315                 cave_alter_feat(y, x, FF_OPEN);
1316
1317                 sound(SOUND_OPENDOOR);
1318         }
1319
1320         /* Result */
1321         return (TRUE);
1322 }
1323
1324 /*!
1325  * @brief 箱のトラップを解除するコマンドのメインルーチン /
1326  * Perform the basic "disarm" command
1327  * @param y 解除を行うマスのY座標
1328  * @param x 解除を行うマスのX座標
1329  * @param o_idx 箱のオブジェクトID
1330  * @return ターンを消費する処理が行われた場合TRUEを返す
1331  * @details
1332  * <pre>
1333  * Assume destination is a visible trap
1334  * Assume there is no monster blocking the destination
1335  * Returns TRUE if repeated commands may continue
1336  * </pre>
1337  */
1338 static bool do_cmd_disarm_chest(POSITION y, POSITION x, OBJECT_IDX o_idx)
1339 {
1340         int i, j;
1341         bool more = FALSE;
1342         object_type *o_ptr = &o_list[o_idx];
1343
1344         p_ptr->energy_use = 100;
1345
1346         /* Get the "disarm" factor */
1347         i = p_ptr->skill_dis;
1348
1349         /* Penalize some conditions */
1350         if (p_ptr->blind || no_lite()) i = i / 10;
1351         if (p_ptr->confused || p_ptr->image) i = i / 10;
1352
1353         /* Extract the difficulty */
1354         j = i - o_ptr->pval;
1355
1356         /* Always have a small chance of success */
1357         if (j < 2) j = 2;
1358
1359         /* Must find the trap first. */
1360         if (!object_is_known(o_ptr))
1361         {
1362                 msg_print(_("トラップが見あたらない。", "I don't see any traps."));
1363
1364         }
1365
1366         /* Already disarmed/unlocked */
1367         else if (o_ptr->pval <= 0)
1368         {
1369                 msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped."));
1370         }
1371
1372         /* No traps to find. */
1373         else if (!chest_traps[o_ptr->pval])
1374         {
1375                 msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped."));
1376         }
1377
1378         /* Success (get a lot of experience) */
1379         else if (randint0(100) < j)
1380         {
1381                 msg_print(_("箱に仕掛けられていたトラップを解除した。", "You have disarmed the chest."));
1382                 gain_exp(o_ptr->pval);
1383                 o_ptr->pval = (0 - o_ptr->pval);
1384         }
1385
1386         /* Failure -- Keep trying */
1387         else if ((i > 5) && (randint1(i) > 5))
1388         {
1389                 /* We may keep trying */
1390                 more = TRUE;
1391                 if (flush_failure) flush();
1392                 msg_print(_("箱のトラップ解除に失敗した。", "You failed to disarm the chest."));
1393         }
1394
1395         /* Failure -- Set off the trap */
1396         else
1397         {
1398                 msg_print(_("トラップを作動させてしまった!", "You set off a trap!"));
1399                 sound(SOUND_FAIL);
1400                 chest_trap(y, x, o_idx);
1401         }
1402
1403         /* Result */
1404         return (more);
1405 }
1406
1407
1408 /*!
1409  * @brief 箱のトラップを解除するコマンドのサブルーチン /
1410  * Perform the basic "disarm" command
1411  * @param y 解除を行うマスのY座標
1412  * @param x 解除を行うマスのX座標
1413  * @param dir プレイヤーからみた方向ID
1414  * @return ターンを消費する処理が行われた場合TRUEを返す
1415  * @details
1416  * <pre>
1417  * Assume destination is a visible trap
1418  * Assume there is no monster blocking the destination
1419  * Returns TRUE if repeated commands may continue
1420  * </pre>
1421  */
1422
1423 bool do_cmd_disarm_aux(POSITION y, POSITION x, DIRECTION dir)
1424 {
1425         /* Get grid and contents */
1426         cave_type *c_ptr = &cave[y][x];
1427
1428         /* Get feature */
1429         feature_type *f_ptr = &f_info[c_ptr->feat];
1430
1431         /* Access trap name */
1432         cptr name = (f_name + f_ptr->name);
1433
1434         /* Extract trap "power" */
1435         int power = f_ptr->power;
1436         bool more = FALSE;
1437
1438         /* Get the "disarm" factor */
1439         int i = p_ptr->skill_dis;
1440         int j;
1441
1442         p_ptr->energy_use = 100;
1443
1444         /* Penalize some conditions */
1445         if (p_ptr->blind || no_lite()) i = i / 10;
1446         if (p_ptr->confused || p_ptr->image) i = i / 10;
1447
1448         /* Extract the difficulty */
1449         j = i - power;
1450
1451         /* Always have a small chance of success */
1452         if (j < 2) j = 2;
1453
1454         /* Success */
1455         if (randint0(100) < j)
1456         {
1457                 msg_format(_("%sを解除した。", "You have disarmed the %s."), name);
1458                 
1459                 /* Reward */
1460                 gain_exp(power);
1461
1462                 /* Remove the trap */
1463                 cave_alter_feat(y, x, FF_DISARM);
1464
1465                 /* Move the player onto the trap */
1466                 move_player(dir, easy_disarm, FALSE);
1467         }
1468
1469         /* Failure -- Keep trying */
1470         else if ((i > 5) && (randint1(i) > 5))
1471         {
1472                 /* Failure */
1473                 if (flush_failure) flush();
1474
1475                 msg_format(_("%sの解除に失敗した。", "You failed to disarm the %s."), name);
1476
1477                 /* We may keep trying */
1478                 more = TRUE;
1479         }
1480
1481         /* Failure -- Set off the trap */
1482         else
1483         {
1484                 msg_format(_("%sを作動させてしまった!", "You set off the %s!"), name);
1485                 /* Move the player onto the trap */
1486                 move_player(dir, easy_disarm, FALSE);
1487         }
1488
1489         /* Result */
1490         return (more);
1491 }
1492
1493
1494 /*!
1495  * @brief 箱、床のトラップ解除処理双方の統合メインルーチン /
1496  * Disarms a trap, or chest
1497  * @return なし
1498  */
1499 void do_cmd_disarm(void)
1500 {
1501         POSITION y, x;
1502         DIRECTION dir;
1503         s16b o_idx;
1504
1505         bool more = FALSE;
1506
1507         if (p_ptr->special_defense & KATA_MUSOU)
1508         {
1509                 set_action(ACTION_NONE);
1510         }
1511
1512
1513         /* Option: Pick a direction */
1514         if (easy_disarm)
1515         {
1516                 int num_traps, num_chests;
1517
1518                 /* Count visible traps */
1519                 num_traps = count_dt(&y, &x, is_trap, TRUE);
1520
1521                 /* Count chests (trapped) */
1522                 num_chests = count_chests(&y, &x, TRUE);
1523
1524                 /* See if only one target */
1525                 if (num_traps || num_chests)
1526                 {
1527                         bool too_many = (num_traps && num_chests) || (num_traps > 1) || (num_chests > 1);
1528                         if (!too_many) command_dir = coords_to_dir(y, x);
1529                 }
1530         }
1531
1532
1533         /* Allow repeated command */
1534         if (command_arg)
1535         {
1536                 /* Set repeat count */
1537                 command_rep = command_arg - 1;
1538
1539                 /* Redraw the state */
1540                 p_ptr->redraw |= (PR_STATE);
1541
1542                 /* Cancel the arg */
1543                 command_arg = 0;
1544         }
1545
1546         /* Get a direction (or abort) */
1547         if (get_rep_dir(&dir,TRUE))
1548         {
1549                 cave_type *c_ptr;
1550                 FEAT_IDX feat;
1551
1552                 /* Get location */
1553                 y = p_ptr->y + ddy[dir];
1554                 x = p_ptr->x + ddx[dir];
1555
1556                 /* Get grid and contents */
1557                 c_ptr = &cave[y][x];
1558
1559                 /* Feature code (applying "mimic" field) */
1560                 feat = get_feat_mimic(c_ptr);
1561
1562                 /* Check for chests */
1563                 o_idx = chest_check(y, x, TRUE);
1564
1565                 /* Disarm a trap */
1566                 if (!is_trap(feat) && !o_idx)
1567                 {
1568                         msg_print(_("そこには解除するものが見当たらない。", "You see nothing there to disarm."));
1569                 }
1570
1571                 /* Monster in the way */
1572                 else if (c_ptr->m_idx && p_ptr->riding != c_ptr->m_idx)
1573                 {
1574                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1575
1576                         /* Attack */
1577                         py_attack(y, x, 0);
1578                 }
1579
1580                 /* Disarm chest */
1581                 else if (o_idx)
1582                 {
1583                         /* Disarm the chest */
1584                         more = do_cmd_disarm_chest(y, x, o_idx);
1585                 }
1586
1587                 /* Disarm trap */
1588                 else
1589                 {
1590                         /* Disarm the trap */
1591                         more = do_cmd_disarm_aux(y, x, dir);
1592                 }
1593         }
1594
1595         /* Cancel repeat unless told not to */
1596         if (!more) disturb(FALSE, FALSE);
1597 }
1598
1599
1600 /*!
1601  * @brief 「打ち破る」動作コマンドのサブルーチン /
1602  * Perform the basic "bash" command
1603  * @param y 対象を行うマスのY座標
1604  * @param x 対象を行うマスのX座標
1605  * @param dir プレイヤーから見たターゲットの方角ID
1606  * @return 実際に処理が行われた場合TRUEを返す。
1607  * @details
1608  * <pre>
1609  * Assume destination is a closed/locked/jammed door
1610  * Assume there is no monster blocking the destination
1611  * Returns TRUE if repeated commands may continue
1612  * </pre>
1613  */
1614 static bool do_cmd_bash_aux(POSITION y, POSITION x, DIRECTION dir)
1615 {
1616         /* Get grid */
1617         cave_type       *c_ptr = &cave[y][x];
1618
1619         /* Get feature */
1620         feature_type *f_ptr = &f_info[c_ptr->feat];
1621
1622         /* Hack -- Bash power based on strength */
1623         /* (Ranges from 3 to 20 to 100 to 200) */
1624         int bash = adj_str_blow[p_ptr->stat_ind[A_STR]];
1625
1626         /* Extract door power */
1627         int temp = f_ptr->power;
1628
1629         bool            more = FALSE;
1630
1631         cptr name = f_name + f_info[get_feat_mimic(c_ptr)].name;
1632
1633         p_ptr->energy_use = 100;
1634
1635         msg_format(_("%sに体当たりをした!", "You smash into the %s!"), name);
1636
1637         /* Compare bash power to door power */
1638         temp = (bash - (temp * 10));
1639
1640         if (p_ptr->pclass == CLASS_BERSERKER) temp *= 2;
1641
1642         /* Hack -- always have a chance */
1643         if (temp < 1) temp = 1;
1644
1645         /* Hack -- attempt to bash down the door */
1646         if (randint0(100) < temp)
1647         {
1648                 msg_format(_("%sを壊した!", "The %s crashes open!"), name);
1649
1650                 sound(have_flag(f_ptr->flags, FF_GLASS) ? SOUND_GLASS : SOUND_OPENDOOR);
1651
1652                 /* Break down the door */
1653                 if ((randint0(100) < 50) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS))
1654                 {
1655                         cave_alter_feat(y, x, FF_BASH);
1656                 }
1657
1658                 /* Open the door */
1659                 else
1660                 {
1661                         cave_alter_feat(y, x, FF_OPEN);
1662                 }
1663
1664                 /* Hack -- Fall through the door */
1665                 move_player(dir, FALSE, FALSE);
1666         }
1667
1668         /* Saving throw against stun */
1669         else if (randint0(100) < adj_dex_safe[p_ptr->stat_ind[A_DEX]] +
1670                  p_ptr->lev)
1671         {
1672                 msg_format(_("この%sは頑丈だ。", "The %s holds firm."), name);
1673
1674                 /* Allow repeated bashing */
1675                 more = TRUE;
1676         }
1677
1678         /* High dexterity yields coolness */
1679         else
1680         {
1681                 msg_print(_("体のバランスをくずしてしまった。", "You are off-balance."));
1682
1683                 /* Hack -- Lose balance ala paralysis */
1684                 (void)set_paralyzed(p_ptr->paralyzed + 2 + randint0(2));
1685         }
1686
1687         /* Result */
1688         return (more);
1689 }
1690
1691
1692 /*!
1693  * @brief 「打ち破る」動作コマンドのメインルーチン /
1694  * Bash open a door, success based on character strength
1695  * @return なし
1696  * @details
1697  * <pre>
1698  * For a closed door, pval is positive if locked; negative if stuck.
1699  *
1700  * For an open door, pval is positive for a broken door.
1701  *
1702  * A closed door can be opened - harder if locked. Any door might be
1703  * bashed open (and thereby broken). Bashing a door is (potentially)
1704  * faster! You move into the door way. To open a stuck door, it must
1705  * be bashed. A closed door can be jammed (see do_cmd_spike()).
1706  *
1707  * Creatures can also open or bash doors, see elsewhere.
1708  * </pre>
1709  */
1710 void do_cmd_bash(void)
1711 {
1712         int                     y, x, dir;
1713
1714         cave_type       *c_ptr;
1715
1716         bool            more = FALSE;
1717
1718
1719         if (p_ptr->special_defense & KATA_MUSOU)
1720         {
1721                 set_action(ACTION_NONE);
1722         }
1723
1724         /* Allow repeated command */
1725         if (command_arg)
1726         {
1727                 /* Set repeat count */
1728                 command_rep = command_arg - 1;
1729
1730                 /* Redraw the state */
1731                 p_ptr->redraw |= (PR_STATE);
1732
1733                 /* Cancel the arg */
1734                 command_arg = 0;
1735         }
1736
1737         /* Get a "repeated" direction */
1738         if (get_rep_dir(&dir,FALSE))
1739         {
1740                 FEAT_IDX feat;
1741
1742                 /* Bash location */
1743                 y = p_ptr->y + ddy[dir];
1744                 x = p_ptr->x + ddx[dir];
1745
1746                 /* Get grid */
1747                 c_ptr = &cave[y][x];
1748
1749                 /* Feature code (applying "mimic" field) */
1750                 feat = get_feat_mimic(c_ptr);
1751
1752                 /* Nothing useful */
1753                 if (!have_flag(f_info[feat].flags, FF_BASH))
1754                 {
1755                         msg_print(_("そこには体当たりするものが見当たらない。", "You see nothing there to bash."));
1756                 }
1757
1758                 /* Monster in the way */
1759                 else if (c_ptr->m_idx)
1760                 {
1761                         p_ptr->energy_use = 100;
1762
1763                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1764
1765                         /* Attack */
1766                         py_attack(y, x, 0);
1767                 }
1768
1769                 /* Bash a closed door */
1770                 else
1771                 {
1772                         /* Bash the door */
1773                         more = do_cmd_bash_aux(y, x, dir);
1774                 }
1775         }
1776
1777         /* Unless valid action taken, cancel bash */
1778         if (!more) disturb(FALSE, FALSE);
1779 }
1780
1781
1782 /*!
1783  * @brief 特定のマスに影響を及ぼすための汎用的コマンド
1784  * @return なし
1785  * @details
1786  * <pre>
1787  * Manipulate an adjacent grid in some way
1788  *
1789  * Attack monsters, tunnel through walls, disarm traps, open doors.
1790  *
1791  * Consider confusion 
1792  *
1793  * This command must always take a turn, to prevent free detection
1794  * of invisible monsters.
1795  * </pre>
1796  */
1797 void do_cmd_alter(void)
1798 {
1799         int                     y, x, dir;
1800
1801         cave_type       *c_ptr;
1802
1803         bool            more = FALSE;
1804
1805
1806         if (p_ptr->special_defense & KATA_MUSOU)
1807         {
1808                 set_action(ACTION_NONE);
1809         }
1810
1811         /* Allow repeated command */
1812         if (command_arg)
1813         {
1814                 /* Set repeat count */
1815                 command_rep = command_arg - 1;
1816
1817                 /* Redraw the state */
1818                 p_ptr->redraw |= (PR_STATE);
1819
1820                 /* Cancel the arg */
1821                 command_arg = 0;
1822         }
1823
1824         /* Get a direction */
1825         if (get_rep_dir(&dir,TRUE))
1826         {
1827                 FEAT_IDX feat;
1828                 feature_type *f_ptr;
1829
1830                 /* Get location */
1831                 y = p_ptr->y + ddy[dir];
1832                 x = p_ptr->x + ddx[dir];
1833
1834                 /* Get grid */
1835                 c_ptr = &cave[y][x];
1836
1837                 /* Feature code (applying "mimic" field) */
1838                 feat = get_feat_mimic(c_ptr);
1839                 f_ptr = &f_info[feat];
1840
1841                 p_ptr->energy_use = 100;
1842
1843                 /* Attack monsters */
1844                 if (c_ptr->m_idx)
1845                 {
1846                         /* Attack */
1847                         py_attack(y, x, 0);
1848                 }
1849
1850                 /* Locked doors */
1851                 else if (have_flag(f_ptr->flags, FF_OPEN))
1852                 {
1853                         more = do_cmd_open_aux(y, x);
1854                 }
1855
1856                 /* Bash jammed doors */
1857                 else if (have_flag(f_ptr->flags, FF_BASH))
1858                 {
1859                         more = do_cmd_bash_aux(y, x, dir);
1860                 }
1861
1862                 /* Tunnel through walls */
1863                 else if (have_flag(f_ptr->flags, FF_TUNNEL))
1864                 {
1865                         more = do_cmd_tunnel_aux(y, x);
1866                 }
1867
1868                 /* Close open doors */
1869                 else if (have_flag(f_ptr->flags, FF_CLOSE))
1870                 {
1871                         more = do_cmd_close_aux(y, x);
1872                 }
1873
1874                 /* Disarm traps */
1875                 else if (have_flag(f_ptr->flags, FF_DISARM))
1876                 {
1877                         more = do_cmd_disarm_aux(y, x, dir);
1878                 }
1879
1880                 else
1881                 {
1882                         msg_print(_("何もない空中を攻撃した。", "You attack the empty air."));
1883                 }
1884         }
1885
1886         /* Cancel repetition unless we can continue */
1887         if (!more) disturb(FALSE, FALSE);
1888 }
1889
1890
1891
1892 /*!
1893  * @brief 「くさびを打つ」ために必要なオブジェクトがあるかどうかの判定を返す /
1894  * Find the index of some "spikes", if possible.
1895  * @param ip くさびとして打てるオブジェクトのID
1896  * @return オブジェクトがある場合TRUEを返す
1897  * @details
1898  * <pre>
1899  * Let user choose a pile of spikes, perhaps?
1900  * </pre>
1901  */
1902 static bool get_spike(INVENTORY_IDX *ip)
1903 {
1904         INVENTORY_IDX i;
1905
1906         /* Check every item in the pack */
1907         for (i = 0; i < INVEN_PACK; i++)
1908         {
1909                 object_type *o_ptr = &inventory[i];
1910
1911                 /* Skip non-objects */
1912                 if (!o_ptr->k_idx) continue;
1913
1914                 /* Check the "tval" code */
1915                 if (o_ptr->tval == TV_SPIKE)
1916                 {
1917                         /* Save the spike index */
1918                         (*ip) = i;
1919
1920                         /* Success */
1921                         return (TRUE);
1922                 }
1923         }
1924
1925         return (FALSE);
1926 }
1927
1928
1929 /*!
1930  * @brief 「くさびを打つ」動作コマンドのメインルーチン /
1931  * Jam a closed door with a spike
1932  * @return なし
1933  * @details
1934  * <pre>
1935  * This command may NOT be repeated
1936  * </pre>
1937  */
1938 void do_cmd_spike(void)
1939 {
1940         DIRECTION dir;
1941
1942         if (p_ptr->special_defense & KATA_MUSOU)
1943         {
1944                 set_action(ACTION_NONE);
1945         }
1946
1947         /* Get a "repeated" direction */
1948         if (get_rep_dir(&dir,FALSE))
1949         {
1950                 POSITION y, x;
1951                 INVENTORY_IDX item;
1952                 cave_type *c_ptr;
1953                 FEAT_IDX feat;
1954
1955                 /* Get location */
1956                 y = p_ptr->y + ddy[dir];
1957                 x = p_ptr->x + ddx[dir];
1958
1959                 /* Get grid and contents */
1960                 c_ptr = &cave[y][x];
1961
1962                 /* Feature code (applying "mimic" field) */
1963                 feat = get_feat_mimic(c_ptr);
1964
1965                 /* Require closed door */
1966                 if (!have_flag(f_info[feat].flags, FF_SPIKE))
1967                 {
1968                         msg_print(_("そこにはくさびを打てるものが見当たらない。", "You see nothing there to spike."));
1969                 }
1970
1971                 /* Get a spike */
1972                 else if (!get_spike(&item))
1973                 {
1974                         msg_print(_("くさびを持っていない!", "You have no spikes!"));
1975                 }
1976
1977                 /* Is a monster in the way? */
1978                 else if (c_ptr->m_idx)
1979                 {
1980                         p_ptr->energy_use = 100;
1981
1982                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1983
1984                         /* Attack */
1985                         py_attack(y, x, 0);
1986                 }
1987
1988                 /* Go for it */
1989                 else
1990                 {
1991                         p_ptr->energy_use = 100;
1992
1993                         /* Successful jamming */
1994                         msg_format(_("%sにくさびを打ち込んだ。", "You jam the %s with a spike."), f_name + f_info[feat].name);
1995                         cave_alter_feat(y, x, FF_SPIKE);
1996
1997                         /* Use up, and describe, a single spike, from the bottom */
1998                         inven_item_increase(item, -1);
1999                         inven_item_describe(item);
2000                         inven_item_optimize(item);
2001                 }
2002         }
2003 }
2004
2005
2006
2007 /*!
2008  * @brief 「歩く」動作コマンドのメインルーチン /
2009  * Support code for the "Walk" and "Jump" commands
2010  * @param pickup アイテムの自動拾いを行うならTRUE
2011  * @return なし
2012  */
2013 void do_cmd_walk(bool pickup)
2014 {
2015         DIRECTION dir;
2016
2017         bool more = FALSE;
2018
2019
2020         /* Allow repeated command */
2021         if (command_arg)
2022         {
2023                 /* Set repeat count */
2024                 command_rep = command_arg - 1;
2025
2026                 /* Redraw the state */
2027                 p_ptr->redraw |= (PR_STATE);
2028
2029                 /* Cancel the arg */
2030                 command_arg = 0;
2031         }
2032
2033         /* Get a "repeated" direction */
2034         if (get_rep_dir(&dir, FALSE))
2035         {
2036                 p_ptr->energy_use = 100;
2037
2038                 if ((dir != 5) && (p_ptr->special_defense & KATA_MUSOU))
2039                 {
2040                         set_action(ACTION_NONE);
2041                 }
2042
2043                 /* Hack -- In small scale wilderness it takes MUCH more time to move */
2044                 if (p_ptr->wild_mode) p_ptr->energy_use *= ((MAX_HGT + MAX_WID) / 2);
2045                 if (p_ptr->action == ACTION_HAYAGAKE) p_ptr->energy_use = p_ptr->energy_use * (45-(p_ptr->lev/2)) / 100;
2046
2047                 /* Actually move the character */
2048                 move_player(dir, pickup, FALSE);
2049
2050                 /* Allow more walking */
2051                 more = TRUE;
2052         }
2053
2054         /* Hack again -- Is there a special encounter ??? */
2055         if (p_ptr->wild_mode && !cave_have_flag_bold(p_ptr->y, p_ptr->x, FF_TOWN))
2056         {
2057                 int tmp = 120 + p_ptr->lev*10 - wilderness[p_ptr->y][p_ptr->x].level + 5;
2058                 if (tmp < 1) 
2059                         tmp = 1;
2060                 if (((wilderness[p_ptr->y][p_ptr->x].level + 5) > (p_ptr->lev / 2)) && randint0(tmp) < (21-p_ptr->skill_stl))
2061                 {
2062                         /* Inform the player of his horrible fate :=) */
2063                         msg_print(_("襲撃だ!", "You are ambushed !"));
2064
2065                         /* Go into large wilderness view */
2066                         p_ptr->oldpy = randint1(MAX_HGT-2);
2067                         p_ptr->oldpx = randint1(MAX_WID-2);
2068                         change_wild_mode();
2069
2070                         /* Give first move to monsters */
2071                         p_ptr->energy_use = 100;
2072
2073                         /* HACk -- set the encouter flag for the wilderness generation */
2074                         generate_encounter = TRUE;
2075                 }
2076         }
2077
2078         /* Cancel repeat unless we may continue */
2079         if (!more) disturb(FALSE, FALSE);
2080 }
2081
2082
2083 /*!
2084  * @brief 「走る」動作コマンドのメインルーチン /
2085  * Start running.
2086  * @return なし
2087  */
2088 void do_cmd_run(void)
2089 {
2090         DIRECTION dir;
2091
2092         /* Hack -- no running when confused */
2093         if (p_ptr->confused)
2094         {
2095                 msg_print(_("混乱していて走れない!", "You are too confused!"));
2096                 return;
2097         }
2098
2099         if (p_ptr->special_defense & KATA_MUSOU)
2100         {
2101                 set_action(ACTION_NONE);
2102         }
2103
2104         /* Get a "repeated" direction */
2105         if (get_rep_dir(&dir,FALSE))
2106         {
2107                 /* Hack -- Set the run counter */
2108                 running = (command_arg ? command_arg : 1000);
2109
2110                 /* First step */
2111                 run_step(dir);
2112         }
2113 }
2114
2115
2116 /*!
2117  * @brief 「留まる」動作コマンドのメインルーチン /
2118  * Stay still.  Search.  Enter stores.
2119  * Pick up treasure if "pickup" is true.
2120  * @param pickup アイテムの自動拾いを行うならTRUE
2121  * @return なし
2122  */
2123 void do_cmd_stay(bool pickup)
2124 {
2125         u32b mpe_mode = MPE_STAYING | MPE_ENERGY_USE;
2126
2127         /* Allow repeated command */
2128         if (command_arg)
2129         {
2130                 /* Set repeat count */
2131                 command_rep = command_arg - 1;
2132
2133                 /* Redraw the state */
2134                 p_ptr->redraw |= (PR_STATE);
2135
2136                 /* Cancel the arg */
2137                 command_arg = 0;
2138         }
2139
2140         p_ptr->energy_use = 100;
2141
2142         if (pickup) mpe_mode |= MPE_DO_PICKUP;
2143         (void)move_player_effect(p_ptr->y, p_ptr->x, mpe_mode);
2144 }
2145
2146
2147 /*!
2148  * @brief 「休む」動作コマンドのメインルーチン /
2149  * Resting allows a player to safely restore his hp     -RAK-
2150  * @return なし
2151  */
2152 void do_cmd_rest(void)
2153 {
2154
2155         set_action(ACTION_NONE);
2156
2157         if ((p_ptr->pclass == CLASS_BARD) && (SINGING_SONG_EFFECT(p_ptr) || INTERUPTING_SONG_EFFECT(p_ptr)))
2158         {
2159                 stop_singing();
2160         }
2161
2162         /* Hex */
2163         if (hex_spelling_any()) stop_hex_spell_all();
2164
2165         /* Prompt for time if needed */
2166         if (command_arg <= 0)
2167         {
2168                 cptr p = _("休憩 (0-9999, '*' で HP/MP全快, '&' で必要なだけ): ", 
2169                                    "Rest (0-9999, '*' for HP/SP, '&' as needed): ");
2170
2171
2172                 char out_val[80];
2173
2174                 /* Default */
2175                 strcpy(out_val, "&");
2176
2177                 /* Ask for duration */
2178                 if (!get_string(p, out_val, 4)) return;
2179
2180                 /* Rest until done */
2181                 if (out_val[0] == '&')
2182                 {
2183                         command_arg = COMMAND_ARG_REST_UNTIL_DONE;
2184                 }
2185
2186                 /* Rest a lot */
2187                 else if (out_val[0] == '*')
2188                 {
2189                         command_arg = COMMAND_ARG_REST_FULL_HEALING;
2190                 }
2191
2192                 /* Rest some */
2193                 else
2194                 {
2195                         command_arg = (COMMAND_ARG)atoi(out_val);
2196                         if (command_arg <= 0) return;
2197                 }
2198         }
2199
2200
2201         /* Paranoia */
2202         if (command_arg > 9999) command_arg = 9999;
2203
2204         if (p_ptr->special_defense & NINJA_S_STEALTH) set_superstealth(FALSE);
2205
2206         /* Take a turn (?) */
2207         p_ptr->energy_use = 100;
2208
2209         /* The sin of sloth */
2210         if (command_arg > 100)
2211                 chg_virtue(V_DILIGENCE, -1);
2212         
2213         /* Why are you sleeping when there's no need?  WAKE UP!*/
2214         if ((p_ptr->chp == p_ptr->mhp) &&
2215             (p_ptr->csp == p_ptr->msp) &&
2216             !p_ptr->blind && !p_ptr->confused &&
2217             !p_ptr->poisoned && !p_ptr->afraid &&
2218             !p_ptr->stun && !p_ptr->cut &&
2219             !p_ptr->slow && !p_ptr->paralyzed &&
2220             !p_ptr->image && !p_ptr->word_recall &&
2221             !p_ptr->alter_reality)
2222                         chg_virtue(V_DILIGENCE, -1);
2223
2224         /* Save the rest code */
2225         resting = command_arg;
2226         p_ptr->action = ACTION_REST;
2227
2228         /* Recalculate bonuses */
2229         p_ptr->update |= (PU_BONUS);
2230
2231         /* Redraw the state */
2232         p_ptr->redraw |= (PR_STATE);
2233
2234         /* Handle stuff */
2235         handle_stuff();
2236
2237         /* Refresh */
2238         Term_fresh();
2239 }
2240
2241
2242 /*!
2243  * @brief 矢弾を射撃した場合の破損確率を返す /
2244  * Determines the odds of an object breaking when thrown at a monster
2245  * @param o_ptr 矢弾のオブジェクト構造体参照ポインタ
2246  * @return 破損確率(%)
2247  * @details
2248  * Note that artifacts never break, see the "drop_near()" function.
2249  */
2250 static PERCENTAGE breakage_chance(object_type *o_ptr)
2251 {
2252         PERCENTAGE archer_bonus = (p_ptr->pclass == CLASS_ARCHER ? (PERCENTAGE)(p_ptr->lev-1)/7 + 4: 0);
2253
2254         /* Examine the snipe type */
2255         if (snipe_type)
2256         {
2257                 if (snipe_type == SP_KILL_WALL) return (100);
2258                 if (snipe_type == SP_EXPLODE) return (100);
2259                 if (snipe_type == SP_PIERCE) return (100);
2260                 if (snipe_type == SP_FINAL) return (100);
2261                 if (snipe_type == SP_NEEDLE) return (100);
2262                 if (snipe_type == SP_EVILNESS) return (40);
2263                 if (snipe_type == SP_HOLYNESS) return (40);
2264         }
2265
2266         /* Examine the item type */
2267         switch (o_ptr->tval)
2268         {
2269                 /* Always break */
2270                 case TV_FLASK:
2271                 case TV_POTION:
2272                 case TV_BOTTLE:
2273                 case TV_FOOD:
2274                 case TV_JUNK:
2275                         return (100);
2276
2277                 /* Often break */
2278                 case TV_LITE:
2279                 case TV_SCROLL:
2280                 case TV_SKELETON:
2281                         return (50);
2282
2283                 /* Sometimes break */
2284                 case TV_WAND:
2285                 case TV_SPIKE:
2286                         return (25);
2287                 case TV_ARROW:
2288                         return (20 - archer_bonus * 2);
2289
2290                 /* Rarely break */
2291                 case TV_SHOT:
2292                 case TV_BOLT:
2293                         return (10 - archer_bonus);
2294                 default:
2295                         return (10);
2296         }
2297 }
2298
2299
2300 /*!
2301  * @brief 矢弾を射撃した際のスレイ倍率をかけた結果を返す /
2302  * Determines the odds of an object breaking when thrown at a monster
2303  * @param o_ptr 矢弾のオブジェクト構造体参照ポインタ
2304  * @param tdam 計算途中のダメージ量
2305  * @param m_ptr 目標モンスターの構造体参照ポインタ
2306  * @return スレイ倍率をかけたダメージ量
2307  */
2308 static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
2309 {
2310         int mult = 10;
2311
2312         monster_race *r_ptr = &r_info[m_ptr->r_idx];
2313
2314         BIT_FLAGS flgs[TR_FLAG_SIZE];
2315
2316         /* Extract the flags */
2317         object_flags(o_ptr, flgs);
2318
2319         /* Some "weapons" and "ammo" do extra damage */
2320         switch (o_ptr->tval)
2321         {
2322                 case TV_SHOT:
2323                 case TV_ARROW:
2324                 case TV_BOLT:
2325                 {
2326                         /* Slay Animal */
2327                         if ((have_flag(flgs, TR_SLAY_ANIMAL)) &&
2328                             (r_ptr->flags3 & RF3_ANIMAL))
2329                         {
2330                                 if (is_original_ap_and_seen(m_ptr))
2331                                 {
2332                                         r_ptr->r_flags3 |= RF3_ANIMAL;
2333                                 }
2334
2335                                 if (mult < 17) mult = 17;
2336                         }
2337
2338                         /* Kill Animal */
2339                         if ((have_flag(flgs, TR_KILL_ANIMAL)) &&
2340                             (r_ptr->flags3 & RF3_ANIMAL))
2341                         {
2342                                 if (is_original_ap_and_seen(m_ptr))
2343                                 {
2344                                         r_ptr->r_flags3 |= RF3_ANIMAL;
2345                                 }
2346
2347                                 if (mult < 27) mult = 27;
2348                         }
2349
2350                         /* Slay Evil */
2351                         if ((have_flag(flgs, TR_SLAY_EVIL)) &&
2352                             (r_ptr->flags3 & RF3_EVIL))
2353                         {
2354                                 if (is_original_ap_and_seen(m_ptr))
2355                                 {
2356                                         r_ptr->r_flags3 |= RF3_EVIL;
2357                                 }
2358
2359                                 if (mult < 15) mult = 15;
2360                         }
2361
2362                         /* Kill Evil */
2363                         if ((have_flag(flgs, TR_KILL_EVIL)) &&
2364                             (r_ptr->flags3 & RF3_EVIL))
2365                         {
2366                                 if (is_original_ap_and_seen(m_ptr))
2367                                 {
2368                                         r_ptr->r_flags3 |= RF3_EVIL;
2369                                 }
2370
2371                                 if (mult < 25) mult = 25;
2372                         }
2373
2374                         /* Slay Human */
2375                         if ((have_flag(flgs, TR_SLAY_HUMAN)) &&
2376                             (r_ptr->flags2 & RF2_HUMAN))
2377                         {
2378                                 if (is_original_ap_and_seen(m_ptr))
2379                                 {
2380                                         r_ptr->r_flags2 |= RF2_HUMAN;
2381                                 }
2382
2383                                 if (mult < 17) mult = 17;
2384                         }
2385
2386                         /* Kill Human */
2387                         if ((have_flag(flgs, TR_KILL_HUMAN)) &&
2388                             (r_ptr->flags2 & RF2_HUMAN))
2389                         {
2390                                 if (is_original_ap_and_seen(m_ptr))
2391                                 {
2392                                         r_ptr->r_flags2 |= RF2_HUMAN;
2393                                 }
2394
2395                                 if (mult < 27) mult = 27;
2396                         }
2397
2398                         /* Slay Undead */
2399                         if ((have_flag(flgs, TR_SLAY_UNDEAD)) &&
2400                             (r_ptr->flags3 & RF3_UNDEAD))
2401                         {
2402                                 if (is_original_ap_and_seen(m_ptr))
2403                                 {
2404                                         r_ptr->r_flags3 |= RF3_UNDEAD;
2405                                 }
2406
2407                                 if (mult < 20) mult = 20;
2408                         }
2409
2410                         /* Kill Undead */
2411                         if ((have_flag(flgs, TR_KILL_UNDEAD)) &&
2412                             (r_ptr->flags3 & RF3_UNDEAD))
2413                         {
2414                                 if (is_original_ap_and_seen(m_ptr))
2415                                 {
2416                                         r_ptr->r_flags3 |= RF3_UNDEAD;
2417                                 }
2418
2419                                 if (mult < 30) mult = 30;
2420                         }
2421
2422                         /* Slay Demon */
2423                         if ((have_flag(flgs, TR_SLAY_DEMON)) &&
2424                             (r_ptr->flags3 & RF3_DEMON))
2425                         {
2426                                 if (is_original_ap_and_seen(m_ptr))
2427                                 {
2428                                         r_ptr->r_flags3 |= RF3_DEMON;
2429                                 }
2430
2431                                 if (mult < 20) mult = 20;
2432                         }
2433
2434                         /* Kill Demon */
2435                         if ((have_flag(flgs, TR_KILL_DEMON)) &&
2436                             (r_ptr->flags3 & RF3_DEMON))
2437                         {
2438                                 if (is_original_ap_and_seen(m_ptr))
2439                                 {
2440                                         r_ptr->r_flags3 |= RF3_DEMON;
2441                                 }
2442
2443                                 if (mult < 30) mult = 30;
2444                         }
2445
2446                         /* Slay Orc */
2447                         if ((have_flag(flgs, TR_SLAY_ORC)) &&
2448                             (r_ptr->flags3 & RF3_ORC))
2449                         {
2450                                 if (is_original_ap_and_seen(m_ptr))
2451                                 {
2452                                         r_ptr->r_flags3 |= RF3_ORC;
2453                                 }
2454
2455                                 if (mult < 20) mult = 20;
2456                         }
2457
2458                         /* Kill Orc */
2459                         if ((have_flag(flgs, TR_KILL_ORC)) &&
2460                             (r_ptr->flags3 & RF3_ORC))
2461                         {
2462                                 if (is_original_ap_and_seen(m_ptr))
2463                                 {
2464                                         r_ptr->r_flags3 |= RF3_ORC;
2465                                 }
2466
2467                                 if (mult < 30) mult = 30;
2468                         }
2469
2470                         /* Slay Troll */
2471                         if ((have_flag(flgs, TR_SLAY_TROLL)) &&
2472                             (r_ptr->flags3 & RF3_TROLL))
2473                         {
2474                                 if (is_original_ap_and_seen(m_ptr))
2475                                 {
2476                                         r_ptr->r_flags3 |= RF3_TROLL;
2477                                 }
2478
2479                                 if (mult < 20) mult = 20;
2480                         }
2481
2482                         /* Kill Troll */
2483                         if ((have_flag(flgs, TR_KILL_TROLL)) &&
2484                             (r_ptr->flags3 & RF3_TROLL))
2485                         {
2486                                 if (is_original_ap_and_seen(m_ptr))
2487                                 {
2488                                         r_ptr->r_flags3 |= RF3_TROLL;
2489                                 }
2490
2491                                 if (mult < 30) mult = 30;
2492                         }
2493
2494                         /* Slay Giant */
2495                         if ((have_flag(flgs, TR_SLAY_GIANT)) &&
2496                             (r_ptr->flags3 & RF3_GIANT))
2497                         {
2498                                 if (is_original_ap_and_seen(m_ptr))
2499                                 {
2500                                         r_ptr->r_flags3 |= RF3_GIANT;
2501                                 }
2502
2503                                 if (mult < 20) mult = 20;
2504                         }
2505
2506                         /* Kill Giant */
2507                         if ((have_flag(flgs, TR_KILL_GIANT)) &&
2508                             (r_ptr->flags3 & RF3_GIANT))
2509                         {
2510                                 if (is_original_ap_and_seen(m_ptr))
2511                                 {
2512                                         r_ptr->r_flags3 |= RF3_GIANT;
2513                                 }
2514
2515                                 if (mult < 30) mult = 30;
2516                         }
2517
2518                         /* Slay Dragon  */
2519                         if ((have_flag(flgs, TR_SLAY_DRAGON)) &&
2520                             (r_ptr->flags3 & RF3_DRAGON))
2521                         {
2522                                 if (is_original_ap_and_seen(m_ptr))
2523                                 {
2524                                         r_ptr->r_flags3 |= RF3_DRAGON;
2525                                 }
2526
2527                                 if (mult < 20) mult = 20;
2528                         }
2529
2530                         /* Execute Dragon */
2531                         if ((have_flag(flgs, TR_KILL_DRAGON)) &&
2532                             (r_ptr->flags3 & RF3_DRAGON))
2533                         {
2534                                 if (is_original_ap_and_seen(m_ptr))
2535                                 {
2536                                         r_ptr->r_flags3 |= RF3_DRAGON;
2537                                 }
2538
2539                                 if (mult < 30) mult = 30;
2540
2541                                 if ((o_ptr->name1 == ART_BARD_ARROW) &&
2542                                     (m_ptr->r_idx == MON_SMAUG) &&
2543                                     (inventory[INVEN_BOW].name1 == ART_BARD))
2544                                         mult *= 5;
2545                         }
2546
2547                         /* Brand (Acid) */
2548                         if (have_flag(flgs, TR_BRAND_ACID))
2549                         {
2550                                 /* Notice immunity */
2551                                 if (r_ptr->flagsr & RFR_EFF_IM_ACID_MASK)
2552                                 {
2553                                         if (is_original_ap_and_seen(m_ptr))
2554                                         {
2555                                                 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ACID_MASK);
2556                                         }
2557                                 }
2558
2559                                 /* Otherwise, take the damage */
2560                                 else
2561                                 {
2562                                         if (mult < 17) mult = 17;
2563                                 }
2564                         }
2565
2566                         /* Brand (Elec) */
2567                         if (have_flag(flgs, TR_BRAND_ELEC))
2568                         {
2569                                 /* Notice immunity */
2570                                 if (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)
2571                                 {
2572                                         if (is_original_ap_and_seen(m_ptr))
2573                                         {
2574                                                 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
2575                                         }
2576                                 }
2577
2578                                 /* Otherwise, take the damage */
2579                                 else
2580                                 {
2581                                         if (mult < 17) mult = 17;
2582                                 }
2583                         }
2584
2585                         /* Brand (Fire) */
2586                         if (have_flag(flgs, TR_BRAND_FIRE))
2587                         {
2588                                 /* Notice immunity */
2589                                 if (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)
2590                                 {
2591                                         if (is_original_ap_and_seen(m_ptr))
2592                                         {
2593                                                 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
2594                                         }
2595                                 }
2596
2597                                 /* Otherwise, take the damage */
2598                                 else
2599                                 {
2600                                         if (r_ptr->flags3 & RF3_HURT_FIRE)
2601                                         {
2602                                                 if (mult < 25) mult = 25;
2603                                                 if (is_original_ap_and_seen(m_ptr))
2604                                                 {
2605                                                         r_ptr->r_flags3 |= RF3_HURT_FIRE;
2606                                                 }
2607                                         }
2608                                         else if (mult < 17) mult = 17;
2609                                 }
2610                         }
2611
2612                         /* Brand (Cold) */
2613                         if (have_flag(flgs, TR_BRAND_COLD))
2614                         {
2615                                 /* Notice immunity */
2616                                 if (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)
2617                                 {
2618                                         if (is_original_ap_and_seen(m_ptr))
2619                                         {
2620                                                 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
2621                                         }
2622                                 }
2623                                 /* Otherwise, take the damage */
2624                                 else
2625                                 {
2626                                         if (r_ptr->flags3 & RF3_HURT_COLD)
2627                                         {
2628                                                 if (mult < 25) mult = 25;
2629                                                 if (is_original_ap_and_seen(m_ptr))
2630                                                 {
2631                                                         r_ptr->r_flags3 |= RF3_HURT_COLD;
2632                                                 }
2633                                         }
2634                                         else if (mult < 17) mult = 17;
2635                                 }
2636                         }
2637
2638                         /* Brand (Poison) */
2639                         if (have_flag(flgs, TR_BRAND_POIS))
2640                         {
2641                                 /* Notice immunity */
2642                                 if (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK)
2643                                 {
2644                                         if (is_original_ap_and_seen(m_ptr))
2645                                         {
2646                                                 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK);
2647                                         }
2648                                 }
2649
2650                                 /* Otherwise, take the damage */
2651                                 else
2652                                 {
2653                                         if (mult < 17) mult = 17;
2654                                 }
2655                         }
2656
2657                         if ((have_flag(flgs, TR_FORCE_WEAPON)) && (p_ptr->csp > (p_ptr->msp / 30)))
2658                         {
2659                                 p_ptr->csp -= (1+(p_ptr->msp / 30));
2660                                 p_ptr->redraw |= (PR_MANA);
2661                                 mult = mult * 5 / 2;
2662                         }
2663                         break;
2664                 }
2665         }
2666
2667         /* Sniper */
2668         if (snipe_type) mult = tot_dam_aux_snipe(mult, m_ptr);
2669
2670         /* Return the total damage */
2671         return (tdam * mult / 10);
2672 }
2673
2674
2675 /*!
2676  * @brief 射撃処理のサブルーチン /
2677  * Fire an object from the pack or floor.
2678  * @param item 射撃するオブジェクトの所持ID
2679  * @param j_ptr 射撃武器のオブジェクト参照ポインタ
2680  * @return なし
2681  * @details
2682  * <pre>
2683  * You may only fire items that "match" your missile launcher.
2684  *
2685  * You must use slings + pebbles/shots, bows + arrows, xbows + bolts.
2686  *
2687  * See "calc_bonuses()" for more calculations and such.
2688  *
2689  * Note that "firing" a missile is MUCH better than "throwing" it.
2690  *
2691  * Note: "unseen" monsters are very hard to hit.
2692  *
2693  * Objects are more likely to break if they "attempt" to hit a monster.
2694  *
2695  * Rangers (with Bows) and Anyone (with "Extra Shots") get extra shots.
2696  *
2697  * The "extra shot" code works by decreasing the amount of energy
2698  * required to make each shot, spreading the shots out over time.
2699  *
2700  * Note that when firing missiles, the launcher multiplier is applied
2701  * after all the bonuses are added in, making multipliers very useful.
2702  *
2703  * Note that Bows of "Extra Might" get extra range and an extra bonus
2704  * for the damage multiplier.
2705  *
2706  * Note that Bows of "Extra Shots" give an extra shot.
2707  * </pre>
2708  */
2709 void do_cmd_fire_aux(INVENTORY_IDX item, object_type *j_ptr)
2710 {
2711         DIRECTION dir;
2712         int i;
2713         POSITION y, x, ny, nx, ty, tx, prev_y, prev_x;
2714         int tdam_base, tdis, thits, tmul;
2715         int bonus, chance;
2716         int cur_dis, visible;
2717         PERCENTAGE j;
2718
2719         object_type forge;
2720         object_type *q_ptr;
2721
2722         object_type *o_ptr;
2723
2724         bool hit_body = FALSE;
2725
2726         char o_name[MAX_NLEN];
2727
2728         u16b path_g[512];       /* For calcuration of path length */
2729
2730         int msec = delay_factor * delay_factor * delay_factor;
2731
2732         /* STICK TO */
2733         bool stick_to = FALSE;
2734
2735         /* Access the item (if in the pack) */
2736         if (item >= 0)
2737         {
2738                 o_ptr = &inventory[item];
2739         }
2740         else
2741         {
2742                 o_ptr = &o_list[0 - item];
2743         }
2744
2745         /* Sniper - Cannot shot a single arrow twice */
2746         if ((snipe_type == SP_DOUBLE) && (o_ptr->number < 2)) snipe_type = SP_NONE;
2747
2748         /* Describe the object */
2749         object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
2750
2751         /* Use the proper number of shots */
2752         thits = p_ptr->num_fire;
2753
2754         /* Use a base distance */
2755         tdis = 10;
2756
2757         /* Base damage from thrown object plus launcher bonus */
2758         tdam_base = damroll(o_ptr->dd, o_ptr->ds) + o_ptr->to_d + j_ptr->to_d;
2759
2760         /* Actually "fire" the object */
2761         bonus = (p_ptr->to_h_b + o_ptr->to_h + j_ptr->to_h);
2762         if ((j_ptr->sval == SV_LIGHT_XBOW) || (j_ptr->sval == SV_HEAVY_XBOW))
2763                 chance = (p_ptr->skill_thb + (p_ptr->weapon_exp[0][j_ptr->sval] / 400 + bonus) * BTH_PLUS_ADJ);
2764         else
2765                 chance = (p_ptr->skill_thb + ((p_ptr->weapon_exp[0][j_ptr->sval] - (WEAPON_EXP_MASTER / 2)) / 200 + bonus) * BTH_PLUS_ADJ);
2766
2767         p_ptr->energy_use = bow_energy(j_ptr->sval);
2768         tmul = bow_tmul(j_ptr->sval);
2769
2770         /* Get extra "power" from "extra might" */
2771         if (p_ptr->xtra_might) tmul++;
2772
2773         tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
2774
2775         /* Boost the damage */
2776         tdam_base *= tmul;
2777         tdam_base /= 100;
2778
2779         /* Base range */
2780         tdis = 13 + tmul/80;
2781         if ((j_ptr->sval == SV_LIGHT_XBOW) || (j_ptr->sval == SV_HEAVY_XBOW))
2782         {
2783                 if (p_ptr->concent)
2784                         tdis -= (5 - (p_ptr->concent + 1) / 2);
2785                 else
2786                         tdis -= 5;
2787         }
2788
2789         project_length = tdis + 1;
2790
2791         /* Get a direction (or cancel) */
2792         if (!get_aim_dir(&dir))
2793         {
2794                 p_ptr->energy_use = 0;
2795
2796                 if (snipe_type == SP_AWAY) snipe_type = SP_NONE;
2797
2798                 /* need not to reset project_length (already did)*/
2799
2800                 return;
2801         }
2802
2803         /* Predict the "target" location */
2804         tx = p_ptr->x + 99 * ddx[dir];
2805         ty = p_ptr->y + 99 * ddy[dir];
2806
2807         /* Check for "target request" */
2808         if ((dir == 5) && target_okay())
2809         {
2810                 tx = target_col;
2811                 ty = target_row;
2812         }
2813
2814         /* Get projection path length */
2815         tdis = project_path(path_g, project_length, p_ptr->y, p_ptr->x, ty, tx, PROJECT_PATH|PROJECT_THRU) - 1;
2816
2817         project_length = 0; /* reset to default */
2818
2819         /* Don't shoot at my feet */
2820         if (tx == p_ptr->x && ty == p_ptr->y)
2821         {
2822                 p_ptr->energy_use = 0;
2823
2824                 /* project_length is already reset to 0 */
2825
2826                 return;
2827         }
2828
2829
2830         /* Take a (partial) turn */
2831         p_ptr->energy_use = (p_ptr->energy_use / thits);
2832         is_fired = TRUE;
2833
2834         /* Sniper - Difficult to shot twice at 1 turn */
2835         if (snipe_type == SP_DOUBLE)  p_ptr->concent = (p_ptr->concent + 1) / 2;
2836
2837         /* Sniper - Repeat shooting when double shots */
2838         for (i = 0; i < ((snipe_type == SP_DOUBLE) ? 2 : 1); i++)
2839         {
2840
2841         /* Start at the player */
2842         y = p_ptr->y;
2843         x = p_ptr->x;
2844
2845         /* Get local object */
2846         q_ptr = &forge;
2847
2848         /* Obtain a local object */
2849         object_copy(q_ptr, o_ptr);
2850
2851         /* Single object */
2852         q_ptr->number = 1;
2853
2854         /* Reduce and describe inventory */
2855         if (item >= 0)
2856         {
2857                 inven_item_increase(item, -1);
2858                 inven_item_describe(item);
2859                 inven_item_optimize(item);
2860         }
2861
2862         /* Reduce and describe floor item */
2863         else
2864         {
2865                 floor_item_increase(0 - item, -1);
2866                 floor_item_optimize(0 - item);
2867         }
2868
2869         sound(SOUND_SHOOT);
2870
2871         /* Hack -- Handle stuff */
2872         handle_stuff();
2873
2874         /* Save the old location */
2875         prev_y = y;
2876         prev_x = x;
2877
2878         /* The shot does not hit yet */
2879         hit_body = FALSE;
2880
2881         /* Travel until stopped */
2882         for (cur_dis = 0; cur_dis <= tdis; )
2883         {
2884                 cave_type *c_ptr;
2885
2886                 /* Hack -- Stop at the target */
2887                 if ((y == ty) && (x == tx)) break;
2888
2889                 /* Calculate the new location (see "project()") */
2890                 ny = y;
2891                 nx = x;
2892                 mmove2(&ny, &nx, p_ptr->y, p_ptr->x, ty, tx);
2893
2894                 /* Shatter Arrow */
2895                 if (snipe_type == SP_KILL_WALL)
2896                 {
2897                         c_ptr = &cave[ny][nx];
2898
2899                         if (cave_have_flag_grid(c_ptr, FF_HURT_ROCK) && !c_ptr->m_idx)
2900                         {
2901                                 if (c_ptr->info & (CAVE_MARK)) msg_print(_("岩が砕け散った。", "Wall rocks were shattered."));
2902                                 /* Forget the wall */
2903                                 c_ptr->info &= ~(CAVE_MARK);
2904
2905                                 p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE);
2906
2907                                 /* Destroy the wall */
2908                                 cave_alter_feat(ny, nx, FF_HURT_ROCK);
2909
2910                                 hit_body = TRUE;
2911                                 break;
2912                         }
2913                 }
2914
2915                 /* Stopped by walls/doors */
2916                 if (!cave_have_flag_bold(ny, nx, FF_PROJECT) && !cave[ny][nx].m_idx) break;
2917
2918                 /* Advance the distance */
2919                 cur_dis++;
2920
2921                 /* Sniper */
2922                 if (snipe_type == SP_LITE)
2923                 {
2924                         cave[ny][nx].info |= (CAVE_GLOW);
2925
2926                         note_spot(ny, nx);
2927
2928                         /* Redraw */
2929                         lite_spot(ny, nx);
2930                 }
2931
2932                 /* The player can see the (on screen) missile */
2933                 if (panel_contains(ny, nx) && player_can_see_bold(ny, nx))
2934                 {
2935                         char c = object_char(q_ptr);
2936                         byte a = object_attr(q_ptr);
2937
2938                         /* Draw, Hilite, Fresh, Pause, Erase */
2939                         print_rel(c, a, ny, nx);
2940                         move_cursor_relative(ny, nx);
2941                         Term_fresh();
2942                         Term_xtra(TERM_XTRA_DELAY, msec);
2943                         lite_spot(ny, nx);
2944                         Term_fresh();
2945                 }
2946
2947                 /* The player cannot see the missile */
2948                 else
2949                 {
2950                         /* Pause anyway, for consistancy */
2951                         Term_xtra(TERM_XTRA_DELAY, msec);
2952                 }
2953
2954                 /* Sniper */
2955                 if (snipe_type == SP_KILL_TRAP)
2956                 {
2957                         project(0, 0, ny, nx, 0, GF_KILL_TRAP,
2958                                 (PROJECT_JUMP | PROJECT_HIDE | PROJECT_GRID | PROJECT_ITEM), -1);
2959                 }
2960
2961                 /* Sniper */
2962                 if (snipe_type == SP_EVILNESS)
2963                 {
2964                         cave[ny][nx].info &= ~(CAVE_GLOW | CAVE_MARK);
2965
2966                         note_spot(ny, nx);
2967
2968                         /* Redraw */
2969                         lite_spot(ny, nx);
2970                 }
2971
2972                 /* Save the old location */
2973                 prev_y = y;
2974                 prev_x = x;
2975
2976                 /* Save the new location */
2977                 x = nx;
2978                 y = ny;
2979
2980
2981                 /* Monster here, Try to hit it */
2982                 if (cave[y][x].m_idx)
2983                 {
2984                         cave_type *c_mon_ptr = &cave[y][x];
2985
2986                         monster_type *m_ptr = &m_list[c_mon_ptr->m_idx];
2987                         monster_race *r_ptr = &r_info[m_ptr->r_idx];
2988
2989                         /* Check the visibility */
2990                         visible = m_ptr->ml;
2991
2992                         /* Note the collision */
2993                         hit_body = TRUE;
2994
2995                         if (MON_CSLEEP(m_ptr))
2996                         {
2997                                 if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_COMPASSION, -1);
2998                                 if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_HONOUR, -1);
2999                         }
3000
3001                         if ((r_ptr->level + 10) > p_ptr->lev)
3002                         {
3003                                 int now_exp = p_ptr->weapon_exp[0][j_ptr->sval];
3004                                 if (now_exp < s_info[p_ptr->pclass].w_max[0][j_ptr->sval])
3005                                 {
3006                                         SUB_EXP amount = 0;
3007                                         if (now_exp < WEAPON_EXP_BEGINNER) amount = 80;
3008                                         else if (now_exp < WEAPON_EXP_SKILLED) amount = 25;
3009                                         else if ((now_exp < WEAPON_EXP_EXPERT) && (p_ptr->lev > 19)) amount = 10;
3010                                         else if (p_ptr->lev > 34) amount = 2;
3011                                         p_ptr->weapon_exp[0][j_ptr->sval] += amount;
3012                                         p_ptr->update |= (PU_BONUS);
3013                                 }
3014                         }
3015
3016                         if (p_ptr->riding)
3017                         {
3018                                 if ((p_ptr->skill_exp[GINOU_RIDING] < s_info[p_ptr->pclass].s_max[GINOU_RIDING])
3019                                         && ((p_ptr->skill_exp[GINOU_RIDING] - (RIDING_EXP_BEGINNER * 2)) / 200 < r_info[m_list[p_ptr->riding].r_idx].level)
3020                                         && one_in_(2))
3021                                 {
3022                                         p_ptr->skill_exp[GINOU_RIDING] += 1;
3023                                         p_ptr->update |= (PU_BONUS);
3024                                 }
3025                         }
3026
3027                         /* Did we hit it (penalize range) */
3028                         if (test_hit_fire(chance - cur_dis, m_ptr, m_ptr->ml, o_name))
3029                         {
3030                                 bool fear = FALSE;
3031                                 int tdam = tdam_base;
3032
3033                                 /* Get extra damage from concentration */
3034                                 if (p_ptr->concent) tdam = boost_concentration_damage(tdam);
3035
3036                                 /* Handle unseen monster */
3037                                 if (!visible)
3038                                 {
3039                                         /* Invisible monster */
3040                                         msg_format(_("%sが敵を捕捉した。", "The %s finds a mark."), o_name);
3041                                 }
3042
3043                                 /* Handle visible monster */
3044                                 else
3045                                 {
3046                                         char m_name[80];
3047
3048                                         /* Get "the monster" or "it" */
3049                                         monster_desc(m_name, m_ptr, 0);
3050
3051                                         msg_format(_("%sが%sに命中した。", "The %s hits %s."), o_name, m_name);
3052
3053                                         if (m_ptr->ml)
3054                                         {
3055                                                 /* Hack -- Track this monster race */
3056                                                 if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
3057
3058                                                 /* Hack -- Track this monster */
3059                                                 health_track(c_mon_ptr->m_idx);
3060                                         }
3061                                 }
3062
3063                                 if (snipe_type == SP_NEEDLE)
3064                                 {
3065                                         if ((randint1(randint1(r_ptr->level / (3 + p_ptr->concent)) + (8 - p_ptr->concent)) == 1)
3066                                                 && !(r_ptr->flags1 & RF1_UNIQUE) && !(r_ptr->flags7 & RF7_UNIQUE2))
3067                                         {
3068                                                 char m_name[80];
3069
3070                                                 /* Get "the monster" or "it" */
3071                                                 monster_desc(m_name, m_ptr, 0);
3072
3073                                                 tdam = m_ptr->hp + 1;
3074                                                 msg_format(_("%sの急所に突き刺さった!", "Your shot sticked on a fatal spot of %s!"), m_name);
3075                                         }
3076                                         else tdam = 1;
3077                                 }
3078                                 else
3079                                 {
3080                                         /* Apply special damage */
3081                                         tdam = tot_dam_aux_shot(q_ptr, tdam, m_ptr);
3082                                         tdam = critical_shot(q_ptr->weight, q_ptr->to_h, j_ptr->to_h, tdam);
3083
3084                                         /* No negative damage */
3085                                         if (tdam < 0) tdam = 0;
3086
3087                                         /* Modify the damage */
3088                                         tdam = mon_damage_mod(m_ptr, tdam, FALSE);
3089                                 }
3090
3091                                 msg_format_wizard(CHEAT_MONSTER,
3092                                         _("%dのダメージを与えた。(残りHP %d/%d(%d))", "You do %d damage. (left HP %d/%d(%d))"),
3093                                         tdam, m_ptr->hp - tdam, m_ptr->maxhp, m_ptr->max_maxhp);
3094
3095                                 /* Sniper */
3096                                 if (snipe_type == SP_EXPLODE)
3097                                 {
3098                                         u16b flg = (PROJECT_STOP | PROJECT_JUMP | PROJECT_KILL | PROJECT_GRID);
3099
3100                                         sound(SOUND_EXPLODE); /* No explode sound - use breath fire instead */
3101                                         project(0, ((p_ptr->concent + 1) / 2 + 1), ny, nx, tdam, GF_MISSILE, flg, -1);
3102                                         break;
3103                                 }
3104
3105                                 /* Sniper */
3106                                 if (snipe_type == SP_HOLYNESS)
3107                                 {
3108                                         cave[ny][nx].info |= (CAVE_GLOW);
3109
3110                                         note_spot(ny, nx);
3111
3112                                         /* Redraw */
3113                                         lite_spot(ny, nx);
3114                                 }
3115
3116                                 /* Hit the monster, check for death */
3117                                 if (mon_take_hit(c_mon_ptr->m_idx, tdam, &fear, extract_note_dies(real_r_ptr(m_ptr))))
3118                                 {
3119                                         /* Dead monster */
3120                                 }
3121
3122                                 /* No death */
3123                                 else
3124                                 {
3125                                         /* STICK TO */
3126                                         if (object_is_fixed_artifact(q_ptr) &&
3127                                                 (p_ptr->pclass != CLASS_SNIPER || p_ptr->concent == 0))
3128                                         {
3129                                                 char m_name[80];
3130
3131                                                 monster_desc(m_name, m_ptr, 0);
3132
3133                                                 stick_to = TRUE;
3134                                                 msg_format(_("%sは%sに突き刺さった!", "%^s have stuck into %s!"),o_name, m_name);
3135                                         }
3136
3137                                         message_pain(c_mon_ptr->m_idx, tdam);
3138
3139                                         /* Anger the monster */
3140                                         if (tdam > 0) anger_monster(m_ptr);
3141
3142                                         /* Take note */
3143                                         if (fear && m_ptr->ml)
3144                                         {
3145                                                 char m_name[80];
3146
3147                                                 sound(SOUND_FLEE);
3148
3149                                                 /* Get the monster name (or "it") */
3150                                                 monster_desc(m_name, m_ptr, 0);
3151
3152                                                 msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), m_name);
3153                                         }
3154
3155                                         set_target(m_ptr, p_ptr->y, p_ptr->x);
3156
3157                                         /* Sniper */
3158                                         if (snipe_type == SP_RUSH)
3159                                         {
3160                                                 int n = randint1(5) + 3;
3161                                                 MONSTER_IDX m_idx = c_mon_ptr->m_idx;
3162
3163                                                 for ( ; cur_dis <= tdis; )
3164                                                 {
3165                                                         POSITION ox = nx;
3166                                                         POSITION oy = ny;
3167
3168                                                         if (!n) break;
3169
3170                                                         /* Calculate the new location (see "project()") */
3171                                                         mmove2(&ny, &nx, p_ptr->y, p_ptr->x, ty, tx);
3172
3173                                                         /* Stopped by wilderness boundary */
3174                                                         if (!in_bounds2(ny, nx)) break;
3175
3176                                                         /* Stopped by walls/doors */
3177                                                         if (!player_can_enter(cave[ny][nx].feat, 0)) break;
3178
3179                                                         /* Stopped by monsters */
3180                                                         if (!cave_empty_bold(ny, nx)) break;
3181
3182                                                         cave[ny][nx].m_idx = m_idx;
3183                                                         cave[oy][ox].m_idx = 0;
3184
3185                                                         m_ptr->fx = nx;
3186                                                         m_ptr->fy = ny;
3187
3188                                                         /* Update the monster (new location) */
3189                                                         update_mon(c_mon_ptr->m_idx, TRUE);
3190
3191                                                         lite_spot(ny, nx);
3192                                                         lite_spot(oy, ox);
3193
3194                                                         Term_fresh();
3195                                                         Term_xtra(TERM_XTRA_DELAY, msec);
3196
3197                                                         x = nx;
3198                                                         y = ny;
3199                                                         cur_dis++;
3200                                                         n--;
3201                                                 }
3202                                         }
3203                                 }
3204                         }
3205
3206                         /* Sniper */
3207                         if (snipe_type == SP_PIERCE)
3208                         {
3209                                 if(p_ptr->concent < 1) break;
3210                                 p_ptr->concent--;
3211                                 continue;
3212                         }
3213
3214                         /* Stop looking */
3215                         break;
3216                 }
3217         }
3218
3219         /* Chance of breakage (during attacks) */
3220         j = (hit_body ? breakage_chance(q_ptr) : 0);
3221
3222         if (stick_to)
3223         {
3224                 MONSTER_IDX m_idx = cave[y][x].m_idx;
3225                 monster_type *m_ptr = &m_list[m_idx];
3226                 OBJECT_IDX o_idx = o_pop();
3227
3228                 if (!o_idx)
3229                 {
3230                         msg_format(_("%sはどこかへ行った。", "The %s have gone to somewhere."), o_name);
3231                         if (object_is_fixed_artifact(q_ptr))
3232                         {
3233                                 a_info[j_ptr->name1].cur_num = 0;
3234                         }
3235                         return;
3236                 }
3237
3238                 o_ptr = &o_list[o_idx];
3239                 object_copy(o_ptr, q_ptr);
3240
3241                 /* Forget mark */
3242                 o_ptr->marked &= OM_TOUCHED;
3243
3244                 /* Forget location */
3245                 o_ptr->iy = o_ptr->ix = 0;
3246
3247                 /* Memorize monster */
3248                 o_ptr->held_m_idx = m_idx;
3249
3250                 /* Build a stack */
3251                 o_ptr->next_o_idx = m_ptr->hold_o_idx;
3252
3253                 /* Carry object */
3254                 m_ptr->hold_o_idx = o_idx;
3255         }
3256         else if (cave_have_flag_bold(y, x, FF_PROJECT))
3257         {
3258                 /* Drop (or break) near that location */
3259                 (void)drop_near(q_ptr, j, y, x);
3260         }
3261         else
3262         {
3263                 /* Drop (or break) near that location */
3264                 (void)drop_near(q_ptr, j, prev_y, prev_x);
3265         }
3266
3267         /* Sniper - Repeat shooting when double shots */
3268         }
3269
3270         /* Sniper - Loose his/her concentration after any shot */
3271         if (p_ptr->concent) reset_concentration(FALSE);
3272 }
3273
3274 /*!
3275  * @brief 射撃処理のメインルーチン
3276  * @return なし
3277  */
3278 void do_cmd_fire(void)
3279 {
3280         OBJECT_IDX item;
3281         object_type *j_ptr;
3282         cptr q, s;
3283
3284         is_fired = FALSE;       /* not fired yet */
3285
3286         /* Get the "bow" (if any) */
3287         j_ptr = &inventory[INVEN_BOW];
3288
3289         /* Require a launcher */
3290         if (!j_ptr->tval)
3291         {
3292                 msg_print(_("射撃用の武器を持っていない。", "You have nothing to fire with."));
3293                 flush();
3294                 return;
3295         }
3296
3297         if (j_ptr->sval == SV_CRIMSON)
3298         {
3299                 msg_print(_("この武器は発動して使うもののようだ。", "Do activate."));
3300                 flush();
3301                 return;
3302         }
3303
3304         if (j_ptr->sval == SV_HARP)
3305         {
3306                 msg_print(_("この武器で射撃はできない。", "It's not for firing."));
3307                 flush();
3308                 return;
3309         }
3310
3311
3312         if (p_ptr->special_defense & KATA_MUSOU)
3313         {
3314                 set_action(ACTION_NONE);
3315         }
3316
3317         /* Require proper missile */
3318         item_tester_tval = p_ptr->tval_ammo;
3319
3320         q = _("どれを撃ちますか? ", "Fire which item? ");
3321         s = _("発射されるアイテムがありません。", "You have nothing to fire.");
3322         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR)))
3323         {
3324                 flush();
3325                 return;
3326         }
3327
3328         /* Fire the item */
3329         do_cmd_fire_aux(item, j_ptr);
3330
3331         if (!is_fired || p_ptr->pclass != CLASS_SNIPER) return;
3332
3333         /* Sniper actions after some shootings */
3334         if (snipe_type == SP_AWAY)
3335         {
3336                 teleport_player(10 + (p_ptr->concent * 2), 0L);
3337         }
3338         if (snipe_type == SP_FINAL)
3339         {
3340                 msg_print(_("射撃の反動が体を襲った。", "A reactionary of shooting attacked you. "));
3341                 (void)set_slow(p_ptr->slow + randint0(7) + 7, FALSE);
3342                 (void)set_stun(p_ptr->stun + randint1(25));
3343         }
3344 }
3345
3346
3347 /*!
3348  * @brief 投射処理メインルーチン /
3349  * Throw an object from the pack or floor.
3350  * @param mult 威力の倍率
3351  * @param boomerang ブーメラン処理ならばTRUE
3352  * @param shuriken 忍者の手裏剣処理ならばTRUE
3353  * @return ターンを消費した場合TRUEを返す
3354  * @details
3355  * <pre>
3356  * Note: "unseen" monsters are very hard to hit.
3357  *
3358  * Should throwing a weapon do full damage?  Should it allow the magic
3359  * to hit bonus of the weapon to have an effect?  Should it ever cause
3360  * the item to be destroyed?  Should it do any damage at all?
3361  * </pre>
3362  */
3363 bool do_cmd_throw(int mult, bool boomerang, OBJECT_IDX shuriken)
3364 {
3365         DIRECTION dir;
3366         OBJECT_IDX item;
3367         int i;
3368         POSITION y, x, ty, tx, prev_y, prev_x;
3369         POSITION ny[19], nx[19];
3370         int chance, tdam, tdis;
3371         int mul, div, dd, ds;
3372         int cur_dis, visible;
3373         PERCENTAGE j;
3374
3375         object_type forge;
3376         object_type *q_ptr;
3377
3378         object_type *o_ptr;
3379
3380         bool hit_body = FALSE;
3381         bool hit_wall = FALSE;
3382         bool equiped_item = FALSE;
3383         bool return_when_thrown = FALSE;
3384
3385         char o_name[MAX_NLEN];
3386
3387         int msec = delay_factor * delay_factor * delay_factor;
3388
3389         BIT_FLAGS flgs[TR_FLAG_SIZE];
3390         cptr q, s;
3391         bool come_back = FALSE;
3392         bool do_drop = TRUE;
3393
3394
3395         if (p_ptr->special_defense & KATA_MUSOU)
3396         {
3397                 set_action(ACTION_NONE);
3398         }
3399
3400         if (shuriken >= 0)
3401         {
3402                 item = shuriken;
3403         }
3404         else if (boomerang)
3405         {
3406                 if (buki_motteruka(INVEN_RARM) && buki_motteruka(INVEN_LARM))
3407                 {
3408                         item_tester_hook = item_tester_hook_boomerang;
3409                         q = _("どの武器を投げますか? ", "Throw which item? ");
3410                         s = _("投げる武器がない。", "You have nothing to throw.");
3411                         if (!get_item(&item, q, s, (USE_EQUIP)))
3412                         {
3413                                 flush();
3414                                 return FALSE;
3415                         }
3416                 }
3417                 else if (buki_motteruka(INVEN_LARM)) item = INVEN_LARM;
3418                 else item = INVEN_RARM;
3419         }
3420         else
3421         {
3422                 q = _("どのアイテムを投げますか? ", "Throw which item? ");
3423                 s = _("投げるアイテムがない。", "You have nothing to throw.");
3424                 if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP)))
3425                 {
3426                         flush();
3427                         return FALSE;
3428                 }
3429         }
3430
3431         /* Access the item (if in the pack) */
3432         if (item >= 0)
3433         {
3434                 o_ptr = &inventory[item];
3435         }
3436         else
3437         {
3438                 o_ptr = &o_list[0 - item];
3439         }
3440
3441         /* Item is cursed */
3442         if (object_is_cursed(o_ptr) && (item >= INVEN_RARM))
3443         {
3444                 msg_print(_("ふーむ、どうやら呪われているようだ。", "Hmmm, it seems to be cursed."));
3445
3446                 return FALSE;
3447         }
3448
3449         if (p_ptr->inside_arena && !boomerang)
3450         {
3451                 if (o_ptr->tval != TV_SPIKE)
3452                 {
3453                         msg_print(_("アリーナではアイテムを使えない!", "You're in the arena now. This is hand-to-hand!"));
3454                         msg_print(NULL);
3455
3456                         return FALSE;
3457                 }
3458
3459         }
3460
3461         /* Get local object */
3462         q_ptr = &forge;
3463
3464         /* Obtain a local object */
3465         object_copy(q_ptr, o_ptr);
3466
3467         /* Extract the thrown object's flags. */
3468         object_flags(q_ptr, flgs);
3469         torch_flags(q_ptr, flgs);
3470
3471         /* Distribute the charges of rods/wands between the stacks */
3472         distribute_charges(o_ptr, q_ptr, 1);
3473
3474         /* Single object */
3475         q_ptr->number = 1;
3476
3477         /* Description */
3478         object_desc(o_name, q_ptr, OD_OMIT_PREFIX);
3479
3480         if (p_ptr->mighty_throw) mult += 3;
3481
3482         /* Extract a "distance multiplier" */
3483         /* Changed for 'launcher' mutation */
3484         mul = 10 + 2 * (mult - 1);
3485
3486         /* Enforce a minimum "weight" of one pound */
3487         div = ((q_ptr->weight > 10) ? q_ptr->weight : 10);
3488         if ((have_flag(flgs, TR_THROW)) || boomerang) div /= 2;
3489
3490         /* Hack -- Distance -- Reward strength, penalize weight */
3491         tdis = (adj_str_blow[p_ptr->stat_ind[A_STR]] + 20) * mul / div;
3492
3493         /* Max distance of 10-18 */
3494         if (tdis > mul) tdis = mul;
3495
3496         if (shuriken >= 0)
3497         {
3498                 ty = randint0(101) - 50 + p_ptr->y;
3499                 tx = randint0(101) - 50 + p_ptr->x;
3500         }
3501         else
3502         {
3503                 project_length = tdis + 1;
3504
3505                 /* Get a direction (or cancel) */
3506                 if (!get_aim_dir(&dir)) return FALSE;
3507
3508                 /* Predict the "target" location */
3509                 tx = p_ptr->x + 99 * ddx[dir];
3510                 ty = p_ptr->y + 99 * ddy[dir];
3511
3512                 /* Check for "target request" */
3513                 if ((dir == 5) && target_okay())
3514                 {
3515                         tx = target_col;
3516                         ty = target_row;
3517                 }
3518
3519                 project_length = 0;  /* reset to default */
3520         }
3521
3522         if ((q_ptr->name1 == ART_MJOLLNIR) ||
3523             (q_ptr->name1 == ART_AEGISFANG) || boomerang)
3524                 return_when_thrown = TRUE;
3525
3526         /* Reduce and describe inventory */
3527         if (item >= 0)
3528         {
3529                 inven_item_increase(item, -1);
3530                 if (!return_when_thrown)
3531                         inven_item_describe(item);
3532                 inven_item_optimize(item);
3533         }
3534
3535         /* Reduce and describe floor item */
3536         else
3537         {
3538                 floor_item_increase(0 - item, -1);
3539                 floor_item_optimize(0 - item);
3540         }
3541         if (item >= INVEN_RARM)
3542         {
3543                 equiped_item = TRUE;
3544                 p_ptr->redraw |= (PR_EQUIPPY);
3545         }
3546
3547         p_ptr->energy_use = 100;
3548
3549         /* Rogue and Ninja gets bonus */
3550         if ((p_ptr->pclass == CLASS_ROGUE) || (p_ptr->pclass == CLASS_NINJA))
3551                 p_ptr->energy_use -= p_ptr->lev;
3552
3553         /* Start at the player */
3554         y = p_ptr->y;
3555         x = p_ptr->x;
3556
3557
3558         /* Hack -- Handle stuff */
3559         handle_stuff();
3560
3561         if ((p_ptr->pclass == CLASS_NINJA) && ((q_ptr->tval == TV_SPIKE) || ((have_flag(flgs, TR_THROW)) && (q_ptr->tval == TV_SWORD)))) shuriken = TRUE;
3562         else shuriken = FALSE;
3563
3564         /* Chance of hitting */
3565         if (have_flag(flgs, TR_THROW)) chance = ((p_ptr->skill_tht) +
3566                 ((p_ptr->to_h_b + q_ptr->to_h) * BTH_PLUS_ADJ));
3567         else chance = (p_ptr->skill_tht + (p_ptr->to_h_b * BTH_PLUS_ADJ));
3568
3569         if (shuriken) chance *= 2;
3570
3571         /* Save the old location */
3572         prev_y = y;
3573         prev_x = x;
3574
3575         /* Travel until stopped */
3576         for (cur_dis = 0; cur_dis <= tdis; )
3577         {
3578                 /* Hack -- Stop at the target */
3579                 if ((y == ty) && (x == tx)) break;
3580
3581                 /* Calculate the new location (see "project()") */
3582                 ny[cur_dis] = y;
3583                 nx[cur_dis] = x;
3584                 mmove2(&ny[cur_dis], &nx[cur_dis], p_ptr->y, p_ptr->x, ty, tx);
3585
3586                 /* Stopped by walls/doors */
3587                 if (!cave_have_flag_bold(ny[cur_dis], nx[cur_dis], FF_PROJECT))
3588                 {
3589                         hit_wall = TRUE;
3590                         if ((q_ptr->tval == TV_FIGURINE) || object_is_potion(q_ptr) || !cave[ny[cur_dis]][nx[cur_dis]].m_idx) break;
3591                 }
3592
3593                 /* The player can see the (on screen) missile */
3594                 if (panel_contains(ny[cur_dis], nx[cur_dis]) && player_can_see_bold(ny[cur_dis], nx[cur_dis]))
3595                 {
3596                         char c = object_char(q_ptr);
3597                         byte a = object_attr(q_ptr);
3598
3599                         /* Draw, Hilite, Fresh, Pause, Erase */
3600                         print_rel(c, a, ny[cur_dis], nx[cur_dis]);
3601                         move_cursor_relative(ny[cur_dis], nx[cur_dis]);
3602                         Term_fresh();
3603                         Term_xtra(TERM_XTRA_DELAY, msec);
3604                         lite_spot(ny[cur_dis], nx[cur_dis]);
3605                         Term_fresh();
3606                 }
3607
3608                 /* The player cannot see the missile */
3609                 else
3610                 {
3611                         /* Pause anyway, for consistancy */
3612                         Term_xtra(TERM_XTRA_DELAY, msec);
3613                 }
3614
3615                 /* Save the old location */
3616                 prev_y = y;
3617                 prev_x = x;
3618
3619                 /* Save the new location */
3620                 x = nx[cur_dis];
3621                 y = ny[cur_dis];
3622
3623                 /* Advance the distance */
3624                 cur_dis++;
3625
3626                 /* Monster here, Try to hit it */
3627                 if (cave[y][x].m_idx)
3628                 {
3629                         cave_type *c_ptr = &cave[y][x];
3630                         monster_type *m_ptr = &m_list[c_ptr->m_idx];
3631
3632                         /* Check the visibility */
3633                         visible = m_ptr->ml;
3634
3635                         /* Note the collision */
3636                         hit_body = TRUE;
3637
3638                         /* Did we hit it (penalize range) */
3639                         if (test_hit_fire(chance - cur_dis, m_ptr, m_ptr->ml, o_name))
3640                         {
3641                                 bool fear = FALSE;
3642
3643                                 /* Handle unseen monster */
3644                                 if (!visible)
3645                                 {
3646                                         /* Invisible monster */
3647                                         msg_format(_("%sが敵を捕捉した。", "The %s finds a mark."), o_name);
3648                                 }
3649
3650                                 /* Handle visible monster */
3651                                 else
3652                                 {
3653                                         char m_name[80];
3654
3655                                         /* Get "the monster" or "it" */
3656                                         monster_desc(m_name, m_ptr, 0);
3657
3658                                         msg_format(_("%sが%sに命中した。", "The %s hits %s."), o_name, m_name);
3659
3660                                         if (m_ptr->ml)
3661                                         {
3662                                                 /* Hack -- Track this monster race */
3663                                                 if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
3664
3665                                                 /* Hack -- Track this monster */
3666                                                 health_track(c_ptr->m_idx);
3667                                         }
3668                                 }
3669
3670                                 /* Hack -- Base damage from thrown object */
3671                                 dd = q_ptr->dd;
3672                                 ds = q_ptr->ds;
3673                                 torch_dice(q_ptr, &dd, &ds); /* throwing a torch */
3674                                 tdam = damroll(dd, ds);
3675                                 /* Apply special damage */
3676                                 tdam = tot_dam_aux(q_ptr, tdam, m_ptr, 0, TRUE);
3677                                 tdam = critical_shot(q_ptr->weight, q_ptr->to_h, 0, tdam);
3678                                 if (q_ptr->to_d > 0)
3679                                         tdam += q_ptr->to_d;
3680                                 else
3681                                         tdam += -q_ptr->to_d;
3682
3683                                 if (boomerang)
3684                                 {
3685                                         tdam *= (mult+p_ptr->num_blow[item - INVEN_RARM]);
3686                                         tdam += p_ptr->to_d_m;
3687                                 }
3688                                 else if (have_flag(flgs, TR_THROW))
3689                                 {
3690                                         tdam *= (3+mult);
3691                                         tdam += p_ptr->to_d_m;
3692                                 }
3693                                 else
3694                                 {
3695                                         tdam *= mult;
3696                                 }
3697                                 if (shuriken)
3698                                 {
3699                                         tdam += ((p_ptr->lev+30)*(p_ptr->lev+30)-900)/55;
3700                                 }
3701
3702                                 /* No negative damage */
3703                                 if (tdam < 0) tdam = 0;
3704
3705                                 /* Modify the damage */
3706                                 tdam = mon_damage_mod(m_ptr, tdam, FALSE);
3707
3708                                 msg_format_wizard(CHEAT_MONSTER, _("%dのダメージを与えた。(残りHP %d/%d(%d))", "You do %d damage. (left HP %d/%d(%d))"),
3709                                         tdam, m_ptr->hp - tdam, m_ptr->maxhp, m_ptr->max_maxhp);
3710
3711                                 /* Hit the monster, check for death */
3712                                 if (mon_take_hit(c_ptr->m_idx, tdam, &fear, extract_note_dies(real_r_ptr(m_ptr))))
3713                                 {
3714                                         /* Dead monster */
3715                                 }
3716
3717                                 /* No death */
3718                                 else
3719                                 {
3720                                         message_pain(c_ptr->m_idx, tdam);
3721
3722                                         /* Anger the monster */
3723                                         if ((tdam > 0) && !object_is_potion(q_ptr))
3724                                                 anger_monster(m_ptr);
3725
3726                                         /* Take note */
3727                                         if (fear && m_ptr->ml)
3728                                         {
3729                                                 char m_name[80];
3730
3731                                                 sound(SOUND_FLEE);
3732
3733                                                 /* Get the monster name (or "it") */
3734                                                 monster_desc(m_name, m_ptr, 0);
3735
3736                                                 msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), m_name);
3737                                         }
3738                                 }
3739                         }
3740
3741                         /* Stop looking */
3742                         break;
3743                 }
3744         }
3745
3746         /* decrease toach's fuel */
3747         if (hit_body) torch_lost_fuel(q_ptr);
3748
3749         /* Chance of breakage (during attacks) */
3750         j = (hit_body ? breakage_chance(q_ptr) : 0);
3751
3752         /* Figurines transform */
3753         if ((q_ptr->tval == TV_FIGURINE) && !(p_ptr->inside_arena))
3754         {
3755                 j = 100;
3756
3757                 if (!(summon_named_creature(0, y, x, q_ptr->pval,
3758                                             !(object_is_cursed(q_ptr)) ? PM_FORCE_PET : 0L)))
3759                         msg_print(_("人形は捻じ曲がり砕け散ってしまった!", "The Figurine writhes and then shatters."));
3760                 else if (object_is_cursed(q_ptr))
3761                         msg_print(_("これはあまり良くない気がする。", "You have a bad feeling about this."));
3762
3763         }
3764
3765
3766         /* Potions smash open */
3767         if (object_is_potion(q_ptr))
3768         {
3769                 if (hit_body || hit_wall || (randint1(100) < j))
3770                 {
3771                         msg_format(_("%sは砕け散った!", "The %s shatters!"), o_name);
3772
3773                         if (potion_smash_effect(0, y, x, q_ptr->k_idx))
3774                         {
3775                                 monster_type *m_ptr = &m_list[cave[y][x].m_idx];
3776
3777                                 /* ToDo (Robert): fix the invulnerability */
3778                                 if (cave[y][x].m_idx &&
3779                                     is_friendly(&m_list[cave[y][x].m_idx]) &&
3780                                     !MON_INVULNER(m_ptr))
3781                                 {
3782                                         char m_name[80];
3783                                         monster_desc(m_name, &m_list[cave[y][x].m_idx], 0);
3784                                         msg_format(_("%sは怒った!", "%^s gets angry!"), m_name);
3785                                         set_hostile(&m_list[cave[y][x].m_idx]);
3786                                 }
3787                         }
3788                         do_drop = FALSE;
3789                 }
3790                 else
3791                 {
3792                         j = 0;
3793                 }
3794         }
3795
3796         if (return_when_thrown)
3797         {
3798                 int back_chance = randint1(30)+20+((int)(adj_dex_th[p_ptr->stat_ind[A_DEX]]) - 128);
3799                 char o2_name[MAX_NLEN];
3800                 bool super_boomerang = (((q_ptr->name1 == ART_MJOLLNIR) || (q_ptr->name1 == ART_AEGISFANG)) && boomerang);
3801
3802                 j = -1;
3803                 if (boomerang) back_chance += 4+randint1(5);
3804                 if (super_boomerang) back_chance += 100;
3805                 object_desc(o2_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
3806
3807                 if((back_chance > 30) && (!one_in_(100) || super_boomerang))
3808                 {
3809                         for (i = cur_dis - 1; i > 0; i--)
3810                         {
3811                                 if (panel_contains(ny[i], nx[i]) && player_can_see_bold(ny[i], nx[i]))
3812                                 {
3813                                         char c = object_char(q_ptr);
3814                                         byte a = object_attr(q_ptr);
3815
3816                                         /* Draw, Hilite, Fresh, Pause, Erase */
3817                                         print_rel(c, a, ny[i], nx[i]);
3818                                         move_cursor_relative(ny[i], nx[i]);
3819                                         Term_fresh();
3820                                         Term_xtra(TERM_XTRA_DELAY, msec);
3821                                         lite_spot(ny[i], nx[i]);
3822                                         Term_fresh();
3823                                 }
3824                                 else
3825                                 {
3826                                         /* Pause anyway, for consistancy */
3827                                         Term_xtra(TERM_XTRA_DELAY, msec);
3828                                 }
3829                         }
3830                         if((back_chance > 37) && !p_ptr->blind && (item >= 0))
3831                         {
3832                                 msg_format(_("%sが手元に返ってきた。", "%s comes back to you."), o2_name);
3833                                 come_back = TRUE;
3834                         }
3835                         else
3836                         {
3837                                 if (item >= 0)
3838                                 {
3839                                         msg_format(_("%sを受け損ねた!", "%s backs, but you can't catch!"), o2_name);
3840                                 }
3841                                 else
3842                                 {
3843                                         msg_format(_("%sが返ってきた。", "%s comes back."), o2_name);
3844                                 }
3845                                 y = p_ptr->y;
3846                                 x = p_ptr->x;
3847                         }
3848                 }
3849                 else
3850                 {
3851                         msg_format(_("%sが返ってこなかった!", "%s doesn't back!"), o2_name);
3852                 }
3853         }
3854
3855         if (come_back)
3856         {
3857                 if (item == INVEN_RARM || item == INVEN_LARM)
3858                 {
3859                         /* Access the wield slot */
3860                         o_ptr = &inventory[item];
3861
3862                         /* Wear the new stuff */
3863                         object_copy(o_ptr, q_ptr);
3864
3865                         /* Increase the weight */
3866                         p_ptr->total_weight += q_ptr->weight;
3867
3868                         /* Increment the equip counter by hand */
3869                         equip_cnt++;
3870
3871                         /* Recalculate bonuses */
3872                         p_ptr->update |= (PU_BONUS);
3873
3874                         /* Recalculate torch */
3875                         p_ptr->update |= (PU_TORCH);
3876
3877                         /* Recalculate mana XXX */
3878                         p_ptr->update |= (PU_MANA);
3879
3880                         p_ptr->window |= (PW_EQUIP);
3881                 }
3882                 else
3883                 {
3884                         inven_carry(q_ptr);
3885                 }
3886                 do_drop = FALSE;
3887         }
3888         else if (equiped_item)
3889         {
3890                 kamaenaoshi(item);
3891                 calc_android_exp();
3892         }
3893
3894         /* Drop (or break) near that location */
3895         if (do_drop)
3896         {
3897                 if (cave_have_flag_bold(y, x, FF_PROJECT))
3898                 {
3899                         /* Drop (or break) near that location */
3900                         (void)drop_near(q_ptr, j, y, x);
3901                 }
3902                 else
3903                 {
3904                         /* Drop (or break) near that location */
3905                         (void)drop_near(q_ptr, j, prev_y, prev_x);
3906                 }
3907         }
3908
3909         return TRUE;
3910 }
3911
3912
3913 #ifdef TRAVEL
3914 /*
3915  * Hack: travel command
3916  */
3917 #define TRAVEL_UNABLE 9999
3918
3919 static int flow_head = 0;
3920 static int flow_tail = 0;
3921 static POSITION temp2_x[MAX_SHORT];
3922 static POSITION temp2_y[MAX_SHORT];
3923
3924 /*!
3925  * @brief トラベル処理の記憶配列を初期化する Hack: forget the "flow" information 
3926  * @return なし
3927  */
3928 void forget_travel_flow(void)
3929 {
3930         POSITION x, y;
3931
3932         /* Check the entire dungeon */
3933         for (y = 0; y < cur_hgt; y++)
3934         {
3935                 for (x = 0; x < cur_wid; x++)
3936                 {
3937                         /* Forget the old data */
3938                         travel.cost[y][x] = MAX_SHORT;
3939                 }
3940         }
3941
3942         travel.y = travel.x = 0;
3943 }
3944
3945 /*!
3946  * @brief トラベル処理中に地形に応じた移動コスト基準を返す
3947  * @param y 該当地点のY座標
3948  * @param x 該当地点のX座標
3949  * @return コスト値
3950  */
3951 static int travel_flow_cost(POSITION y, POSITION x)
3952 {
3953         feature_type *f_ptr = &f_info[cave[y][x].feat];
3954         int cost = 1;
3955
3956         /* Avoid obstacles (ex. trees) */
3957         if (have_flag(f_ptr->flags, FF_AVOID_RUN)) cost += 1;
3958
3959         /* Water */
3960         if (have_flag(f_ptr->flags, FF_WATER))
3961         {
3962                 if (have_flag(f_ptr->flags, FF_DEEP) && !p_ptr->levitation) cost += 5;
3963         }
3964
3965         /* Lava */
3966         if (have_flag(f_ptr->flags, FF_LAVA))
3967         {
3968                 int lava = 2;
3969                 if (!p_ptr->resist_fire) lava *= 2;
3970                 if (!p_ptr->levitation) lava *= 2;
3971                 if (have_flag(f_ptr->flags, FF_DEEP)) lava *= 2;
3972
3973                 cost += lava;
3974         }
3975
3976         /* Detected traps and doors */
3977         if (cave[y][x].info & (CAVE_MARK))
3978         {
3979                 if (have_flag(f_ptr->flags, FF_DOOR)) cost += 1;
3980                 if (have_flag(f_ptr->flags, FF_TRAP)) cost += 10;
3981         }
3982
3983         return (cost);
3984 }
3985
3986 /*!
3987  * @brief トラベル処理の到達地点までの行程を得る処理のサブルーチン
3988  * @param y 目標地点のY座標
3989  * @param x 目標地点のX座標
3990  * @param n 現在のコスト
3991  * @param wall プレイヤーが壁の中にいるならばTRUE
3992  * @return なし
3993  */
3994 static void travel_flow_aux(POSITION y, POSITION x, int n, bool wall)
3995 {
3996         cave_type *c_ptr = &cave[y][x];
3997         feature_type *f_ptr = &f_info[c_ptr->feat];
3998         int old_head = flow_head;
3999         int add_cost = 1;
4000         int base_cost = (n % TRAVEL_UNABLE);
4001         int from_wall = (n / TRAVEL_UNABLE);
4002         int cost;
4003
4004         /* Ignore out of bounds */
4005         if (!in_bounds(y, x)) return;
4006
4007         /* Ignore unknown grid except in wilderness */
4008         if (dun_level > 0 && !(c_ptr->info & CAVE_KNOWN)) return;
4009
4010         /* Ignore "walls" and "rubble" (include "secret doors") */
4011         if (have_flag(f_ptr->flags, FF_WALL) ||
4012                 have_flag(f_ptr->flags, FF_CAN_DIG) ||
4013                 (have_flag(f_ptr->flags, FF_DOOR) && cave[y][x].mimic) ||
4014                 (!have_flag(f_ptr->flags, FF_MOVE) && have_flag(f_ptr->flags, FF_CAN_FLY) && !p_ptr->levitation))
4015         {
4016                 if (!wall || !from_wall) return;
4017                 add_cost += TRAVEL_UNABLE;
4018         }
4019         else
4020         {
4021                 add_cost = travel_flow_cost(y, x);
4022         }
4023
4024         cost = base_cost + add_cost;
4025
4026         /* Ignore lower cost entries */
4027         if (travel.cost[y][x] <= cost) return;
4028
4029         /* Save the flow cost */
4030         travel.cost[y][x] = cost;
4031
4032         /* Enqueue that entry */
4033         temp2_y[flow_head] = y;
4034         temp2_x[flow_head] = x;
4035
4036         /* Advance the queue */
4037         if (++flow_head == MAX_SHORT) flow_head = 0;
4038
4039         /* Hack -- notice overflow by forgetting new entry */
4040         if (flow_head == flow_tail) flow_head = old_head;
4041
4042         return;
4043 }
4044
4045 /*!
4046  * @brief トラベル処理の到達地点までの行程を得る処理のメインルーチン
4047  * @param ty 目標地点のY座標
4048  * @param tx 目標地点のX座標
4049  * @return なし
4050  */
4051 static void travel_flow(POSITION ty, POSITION tx)
4052 {
4053         POSITION x, y, d;
4054         bool wall = FALSE;
4055         feature_type *f_ptr = &f_info[cave[p_ptr->y][p_ptr->x].feat];
4056
4057         /* Reset the "queue" */
4058         flow_head = flow_tail = 0;
4059
4060         /* is player in the wall? */
4061         if (!have_flag(f_ptr->flags, FF_MOVE)) wall = TRUE;
4062
4063         /* Start at the target grid */
4064         travel_flow_aux(ty, tx, 0, wall);
4065
4066         /* Now process the queue */
4067         while (flow_head != flow_tail)
4068         {
4069                 /* Extract the next entry */
4070                 y = temp2_y[flow_tail];
4071                 x = temp2_x[flow_tail];
4072
4073                 /* Forget that entry */
4074                 if (++flow_tail == MAX_SHORT) flow_tail = 0;
4075
4076                 /* Ignore too far entries */
4077                 //if (distance(ty, tx, y, x) > 100) continue;
4078
4079                 /* Add the "children" */
4080                 for (d = 0; d < 8; d++)
4081                 {
4082                         /* Add that child if "legal" */
4083                         travel_flow_aux(y + ddy_ddd[d], x + ddx_ddd[d], travel.cost[y][x], wall);
4084                 }
4085         }
4086
4087         /* Forget the flow info */
4088         flow_head = flow_tail = 0;
4089 }
4090
4091 /*!
4092  * @brief トラベル処理のメインルーチン
4093  * @return なし
4094  */
4095 void do_cmd_travel(void)
4096 {
4097         POSITION x, y;
4098         int i;
4099         int dx, dy, sx, sy;
4100         feature_type *f_ptr;
4101
4102         if (travel.x != 0 && travel.y != 0 &&
4103             get_check(_("トラベルを継続しますか?", "Do you continue to travel?")))
4104         {
4105                 y = travel.y;
4106                 x = travel.x;
4107         }
4108         else if (!tgt_pt(&x, &y)) return;
4109
4110         if ((x == p_ptr->x) && (y == p_ptr->y))
4111         {
4112                 msg_print(_("すでにそこにいます!", "You are already there!!"));
4113                 return;
4114         }
4115
4116         f_ptr = &f_info[cave[y][x].feat];
4117
4118         if ((cave[y][x].info & CAVE_MARK) &&
4119                 (have_flag(f_ptr->flags, FF_WALL) ||
4120                         have_flag(f_ptr->flags, FF_CAN_DIG) ||
4121                         (have_flag(f_ptr->flags, FF_DOOR) && cave[y][x].mimic)))
4122         {
4123                 msg_print(_("そこには行くことができません!", "You cannot travel there!"));
4124                 return;
4125         }
4126
4127         forget_travel_flow();
4128         travel_flow(y, x);
4129
4130         travel.x = x;
4131         travel.y = y;
4132
4133         /* Travel till 255 steps */
4134         travel.run = 255;
4135
4136         /* Paranoia */
4137         travel.dir = 0;
4138
4139         /* Decides first direction */
4140         dx = abs(p_ptr->x - x);
4141         dy = abs(p_ptr->y - y);
4142         sx = ((x == p_ptr->x) || (dx < dy)) ? 0 : ((x > p_ptr->x) ? 1 : -1);
4143         sy = ((y == p_ptr->y) || (dy < dx)) ? 0 : ((y > p_ptr->y) ? 1 : -1);
4144
4145         for (i = 1; i <= 9; i++)
4146         {
4147                 if ((sx == ddx[i]) && (sy == ddy[i])) travel.dir = i;
4148         }
4149 }
4150 #endif