OSDN Git Service

8a193f03492a24a679ede4d5ad24f0826d070849
[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 "floor.h"
16 #include "melee.h"
17 #include "object-hook.h"
18 #include "projection.h"
19 #include "spells-summon.h"
20 #include "spells-status.h"
21 #include "monster-status.h"
22 #include "quest.h"
23 #include "artifact.h"
24 #include "avatar.h"
25 #include "player-status.h"
26 #include "realm-hex.h"
27
28 /*!
29  * @brief フロア脱出時に出戻りが不可能だった場合に警告を加える処理
30  * @param down_stair TRUEならば階段を降りる処理、FALSEなら階段を昇る処理による内容
31  * @return フロア移動を実際に行うならTRUE、キャンセルする場合はFALSE
32  */
33 bool confirm_leave_level(bool down_stair)
34 {
35         quest_type *q_ptr = &quest[p_ptr->inside_quest];
36
37         /* Confirm leaving from once only quest */
38         if (confirm_quest && p_ptr->inside_quest &&
39             (q_ptr->type == QUEST_TYPE_RANDOM ||
40              (q_ptr->flags & QUEST_FLAG_ONCE &&
41                                                 q_ptr->status != QUEST_STATUS_COMPLETED) ||
42                  (q_ptr->flags & QUEST_FLAG_TOWER &&
43                                                 ((q_ptr->status != QUEST_STATUS_STAGE_COMPLETED) ||
44                                                  (down_stair && (quest[QUEST_TOWER1].status != QUEST_STATUS_COMPLETED))))))
45         {
46                 msg_print(_("この階を一度去ると二度と戻って来られません。", "You can't come back here once you leave this floor."));
47                 if (get_check(_("本当にこの階を去りますか?", "Really leave this floor? "))) return TRUE;
48         }
49         else
50         {
51                 return TRUE;
52         }
53         return FALSE;
54 }
55
56 bool cmd_limit_arena(player_type *creature_ptr)
57 {
58         if (p_ptr->inside_arena)
59         {
60                 msg_print(_("アリーナが魔法を吸収した!", "The arena absorbs all attempted magic!"));
61                 msg_print(NULL);
62                 return TRUE;
63         }
64         return FALSE;
65 }
66
67 bool cmd_limit_time_walk(player_type *creature_ptr)
68 {
69         if (world_player)
70         {
71                 if (flush_failure) flush();
72                 msg_print(_("止まった時の中ではうまく働かないようだ。", "It shows no reaction."));
73                 sound(SOUND_FAIL);
74                 return TRUE;
75         }
76         return FALSE;
77 }
78
79 /*!
80  * @brief 階段を使って階層を昇る処理 / Go up one level
81  * @return なし
82  */
83 void do_cmd_go_up(void)
84 {
85         bool go_up = FALSE;
86
87         /* Player grid */
88         cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x];
89         feature_type *f_ptr = &f_info[c_ptr->feat];
90
91         int up_num = 0;
92
93         if (p_ptr->special_defense & KATA_MUSOU)
94         {
95                 set_action(ACTION_NONE);
96         }
97
98         /* Verify stairs */
99         if (!have_flag(f_ptr->flags, FF_LESS))
100         {
101                 msg_print(_("ここには上り階段が見当たらない。", "I see no up staircase here."));
102                 return;
103         }
104
105         /* Quest up stairs */
106         if (have_flag(f_ptr->flags, FF_QUEST))
107         {
108                 /* Cancel the command */
109                 if (!confirm_leave_level(FALSE)) return;
110         
111                 
112                 /* Success */
113                 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
114                         msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
115                 else
116                         msg_print(_("上の階に登った。", "You enter the up staircase."));
117
118                 leave_quest_check();
119
120                 p_ptr->inside_quest = c_ptr->special;
121
122                 /* Activate the quest */
123                 if (!quest[p_ptr->inside_quest].status)
124                 {
125                         if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
126                         {
127                                 init_flags = INIT_ASSIGN;
128                                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
129                         }
130                         quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
131                 }
132
133                 /* Leaving a quest */
134                 if (!p_ptr->inside_quest)
135                 {
136                         dun_level = 0;
137                 }
138
139                 /* Leaving */
140                 p_ptr->leaving = TRUE;
141
142                 p_ptr->oldpx = 0;
143                 p_ptr->oldpy = 0;
144                 
145                 /* Hack -- take a turn */
146                 p_ptr->energy_use = 100;
147
148                 /* End the command */
149                 return;
150         }
151
152         if (!dun_level)
153         {
154                 go_up = TRUE;
155         }
156         else
157         {
158                 go_up = confirm_leave_level(FALSE);
159         }
160
161         /* Cancel the command */
162         if (!go_up) return;
163
164         /* Hack -- take a turn */
165         p_ptr->energy_use = 100;
166
167         if (autosave_l) do_cmd_save_game(TRUE);
168
169         /* For a random quest */
170         if (p_ptr->inside_quest &&
171             quest[p_ptr->inside_quest].type == QUEST_TYPE_RANDOM)
172         {
173                 leave_quest_check();
174
175                 p_ptr->inside_quest = 0;
176         }
177
178         /* For a fixed quest */
179         if (p_ptr->inside_quest &&
180             quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
181         {
182                 leave_quest_check();
183
184                 p_ptr->inside_quest = c_ptr->special;
185                 dun_level = 0;
186                 up_num = 0;
187         }
188
189         /* For normal dungeon and random quest */
190         else
191         {
192                 /* New depth */
193                 if (have_flag(f_ptr->flags, FF_SHAFT))
194                 {
195                         /* Create a way back */
196                         prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP | CFM_SHAFT);
197
198                         up_num = 2;
199                 }
200                 else
201                 {
202                         /* Create a way back */
203                         prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP);
204
205                         up_num = 1;
206                 }
207
208                 /* Get out from current dungeon */
209                 if (dun_level - up_num < d_info[dungeon_type].mindepth)
210                         up_num = dun_level;
211         }
212         if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, _("階段を上った", "climbed up the stairs to"));
213
214         /* Success */
215         if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
216                 msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
217         else if (up_num == dun_level)
218                 msg_print(_("地上に戻った。", "You go back to the surface."));
219         else
220                 msg_print(_("階段を上って新たなる迷宮へと足を踏み入れた。", "You enter a maze of up staircases."));
221
222         /* Leaving */
223         p_ptr->leaving = TRUE;
224 }
225
226
227 /*!
228  * @brief 階段を使って階層を降りる処理 / Go down one level
229  * @return なし
230  */
231 void do_cmd_go_down(void)
232 {
233         /* Player grid */
234         cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x];
235         feature_type *f_ptr = &f_info[c_ptr->feat];
236
237         bool fall_trap = FALSE;
238         int down_num = 0;
239
240         if (p_ptr->special_defense & KATA_MUSOU)
241         {
242                 set_action(ACTION_NONE);
243         }
244
245         /* Verify stairs */
246         if (!have_flag(f_ptr->flags, FF_MORE))
247         {
248                 msg_print(_("ここには下り階段が見当たらない。", "I see no down staircase here."));
249                 return;
250         }
251
252         if (have_flag(f_ptr->flags, FF_TRAP)) fall_trap = TRUE;
253
254         /* Quest entrance */
255         if (have_flag(f_ptr->flags, FF_QUEST_ENTER))
256         {
257                 do_cmd_quest();
258         }
259
260         /* Quest down stairs */
261         else if (have_flag(f_ptr->flags, FF_QUEST))
262         {
263                 /* Confirm Leaving */
264                 if(!confirm_leave_level(TRUE)) return;
265                 
266                 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
267                         msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
268                 else
269                         msg_print(_("下の階に降りた。", "You enter the down staircase."));
270
271                 leave_quest_check();
272                 leave_tower_check();
273
274                 p_ptr->inside_quest = c_ptr->special;
275
276                 /* Activate the quest */
277                 if (!quest[p_ptr->inside_quest].status)
278                 {
279                         if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
280                         {
281                                 init_flags = INIT_ASSIGN;
282                                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
283                         }
284                         quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
285                 }
286
287                 /* Leaving a quest */
288                 if (!p_ptr->inside_quest)
289                 {
290                         dun_level = 0;
291                 }
292
293                 /* Leaving */
294                 p_ptr->leaving = TRUE;
295
296                 p_ptr->oldpx = 0;
297                 p_ptr->oldpy = 0;
298                 
299                 
300         /* Hack -- take a turn */
301         p_ptr->energy_use = 100;
302         }
303
304         else
305         {
306                 DUNGEON_IDX target_dungeon = 0;
307
308                 if (!dun_level)
309                 {
310                         target_dungeon = have_flag(f_ptr->flags, FF_ENTRANCE) ? c_ptr->special : DUNGEON_ANGBAND;
311
312                         if (ironman_downward && (target_dungeon != DUNGEON_ANGBAND))
313                         {
314                                 msg_print(_("ダンジョンの入口は塞がれている!", "The entrance of this dungeon is closed!"));
315                                 return;
316                         }
317                         if (!max_dlv[target_dungeon])
318                         {
319                                 msg_format(_("ここには%sの入り口(%d階相当)があります", "There is the entrance of %s (Danger level: %d)"),
320                                                         d_name+d_info[target_dungeon].name, d_info[target_dungeon].mindepth);
321                                 if (!get_check(_("本当にこのダンジョンに入りますか?", "Do you really get in this dungeon? "))) return;
322                         }
323
324                         /* Save old player position */
325                         p_ptr->oldpx = p_ptr->x;
326                         p_ptr->oldpy = p_ptr->y;
327                         dungeon_type = target_dungeon;
328
329                         /*
330                          * Clear all saved floors
331                          * and create a first saved floor
332                          */
333                         prepare_change_floor_mode(CFM_FIRST_FLOOR);
334                 }
335
336                 /* Hack -- take a turn */
337                 p_ptr->energy_use = 100;
338
339                 if (autosave_l) do_cmd_save_game(TRUE);
340
341                 /* Go down */
342                 if (have_flag(f_ptr->flags, FF_SHAFT)) down_num += 2;
343                 else down_num += 1;
344
345                 if (!dun_level)
346                 {
347                         /* Enter the dungeon just now */
348                         p_ptr->enter_dungeon = TRUE;
349                         down_num = d_info[dungeon_type].mindepth;
350                 }
351
352                 if (record_stair)
353                 {
354                         if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, _("落とし戸に落ちた", "fell through a trap door"));
355                         else do_cmd_write_nikki(NIKKI_STAIR, down_num, _("階段を下りた", "climbed down the stairs to"));
356                 }
357
358                 if (fall_trap)
359                 {
360                         msg_print(_("わざと落とし戸に落ちた。", "You deliberately jump through the trap door."));
361                 }
362                 else
363                 {
364                         /* Success */
365                         if (target_dungeon)
366                         {
367                                 msg_format(_("%sへ入った。", "You entered %s."), d_text + d_info[dungeon_type].text);
368                         }
369                         else
370                         {
371                                 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
372                                         msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
373                                 else
374                                         msg_print(_("階段を下りて新たなる迷宮へと足を踏み入れた。", "You enter a maze of down staircases."));
375                         }
376                 }
377
378
379                 /* Leaving */
380                 p_ptr->leaving = TRUE;
381
382                 if (fall_trap)
383                 {
384                         prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
385                 }
386                 else
387                 {
388                         if (have_flag(f_ptr->flags, FF_SHAFT))
389                         {
390                                 /* Create a way back */
391                                 prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_SHAFT);
392                         }
393                         else
394                         {
395                                 /* Create a way back */
396                                 prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN);
397                         }
398                 }
399         }
400 }
401
402
403 /*!
404  * @brief 探索コマンドのメインルーチン / Simple command to "search" for one turn
405  * @return なし
406  */
407 void do_cmd_search(void)
408 {
409         /* Allow repeated command */
410         if (command_arg)
411         {
412                 /* Set repeat count */
413                 command_rep = command_arg - 1;
414                 p_ptr->redraw |= (PR_STATE);
415
416                 /* Cancel the arg */
417                 command_arg = 0;
418         }
419         p_ptr->energy_use = 100;
420
421         /* Search */
422         search();
423 }
424
425
426 /*!
427  * @brief 該当のマスに存在している箱のオブジェクトIDを返す。
428  * @param y 走査対象にしたいマスのY座標
429  * @param x 走査対象にしたいマスのX座標
430  * @param trapped TRUEならばトラップが存在する箱のみ、FALSEならば空でない箱全てを対象にする
431  * @return 箱が存在する場合そのオブジェクトID、存在しない場合0を返す。
432  */
433 static OBJECT_IDX chest_check(POSITION y, POSITION x, bool trapped)
434 {
435         cave_type *c_ptr = &cave[y][x];
436         OBJECT_IDX this_o_idx, next_o_idx = 0;
437
438         /* Scan all objects in the grid */
439         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
440         {
441                 object_type *o_ptr;
442
443                 o_ptr = &o_list[this_o_idx];
444                 next_o_idx = o_ptr->next_o_idx;
445
446                 /* Skip unknown chests XXX XXX */
447                 /* if (!(o_ptr->marked & OM_FOUND)) continue; */
448
449                 /* Check for non empty chest */
450                 if ((o_ptr->tval == TV_CHEST) &&
451                         (((!trapped) && (o_ptr->pval)) || /* non empty */
452                         ((trapped) && (o_ptr->pval > 0)))) /* trapped only */
453                 {
454                         return (this_o_idx);
455                 }
456         }
457         return (0);
458 }
459
460 /*!
461  * @brief 箱を開けるコマンドのメインルーチン /
462  * Attempt to open the given chest at the given location
463  * @param y 箱の存在するマスのY座標
464  * @param x 箱の存在するマスのX座標
465  * @param o_idx 箱のオブジェクトID
466  * @return 箱が開かなかった場合TRUE / Returns TRUE if repeated commands may continue
467  * @details
468  * Assume there is no monster blocking the destination
469  */
470 static bool do_cmd_open_chest(POSITION y, POSITION x, OBJECT_IDX o_idx)
471 {
472         int i, j;
473         bool flag = TRUE;
474         bool more = FALSE;
475         object_type *o_ptr = &o_list[o_idx];
476
477         p_ptr->energy_use = 100;
478
479         /* Attempt to unlock it */
480         if (o_ptr->pval > 0)
481         {
482                 /* Assume locked, and thus not open */
483                 flag = FALSE;
484
485                 /* Get the "disarm" factor */
486                 i = p_ptr->skill_dis;
487
488                 /* Penalize some conditions */
489                 if (p_ptr->blind || no_lite()) i = i / 10;
490                 if (p_ptr->confused || p_ptr->image) i = i / 10;
491
492                 /* Extract the difficulty */
493                 j = i - o_ptr->pval;
494
495                 /* Always have a small chance of success */
496                 if (j < 2) j = 2;
497
498                 /* Success -- May still have traps */
499                 if (randint0(100) < j)
500                 {
501                         msg_print(_("鍵をはずした。", "You have picked the lock."));
502                         gain_exp(1);
503                         flag = TRUE;
504                 }
505
506                 /* Failure -- Keep trying */
507                 else
508                 {
509                         /* We may continue repeating */
510                         more = TRUE;
511                         if (flush_failure) flush();
512                         msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
513
514                 }
515         }
516
517         /* Allowed to open */
518         if (flag)
519         {
520                 /* Apply chest traps, if any */
521                 chest_trap(y, x, o_idx);
522
523                 /* Let the Chest drop items */
524                 chest_death(FALSE, y, x, o_idx);
525         }
526         return (more);
527 }
528
529 /*!
530  * @brief プレイヤーの周辺9マスに該当する地形がいくつあるかを返す /
531  * Attempt to open the given chest at the given location
532  * @param y 該当する地形の中から1つのY座標を返す参照ポインタ
533  * @param x 該当する地形の中から1つのX座標を返す参照ポインタ
534  * @param test 地形条件を判定するための関数ポインタ
535  * @param under TRUEならばプレイヤーの直下の座標も走査対象にする
536  * @return 該当する地形の数
537  * @details Return the number of features around (or under) the character.
538  * Usually look for doors and floor traps.
539  */
540 static int count_dt(POSITION *y, POSITION *x, bool (*test)(IDX feat), bool under)
541 {
542         int d, count, xx, yy;
543
544         /* Count how many matches */
545         count = 0;
546
547         /* Check around (and under) the character */
548         for (d = 0; d < 9; d++)
549         {
550                 cave_type *c_ptr;
551                 FEAT_IDX feat;
552
553                 /* if not searching under player continue */
554                 if ((d == 8) && !under) continue;
555
556                 /* Extract adjacent (legal) location */
557                 yy = p_ptr->y + ddy_ddd[d];
558                 xx = p_ptr->x + ddx_ddd[d];
559
560                 /* Get the cave */
561                 c_ptr = &cave[yy][xx];
562
563                 /* Must have knowledge */
564                 if (!(c_ptr->info & (CAVE_MARK))) continue;
565
566                 /* Feature code (applying "mimic" field) */
567                 feat = get_feat_mimic(c_ptr);
568
569                 /* Not looking for this feature */
570                 if (!((*test)(feat))) continue;
571
572                 /* OK */
573                 ++count;
574
575                 /* Remember the location. Only useful if only one match */
576                 *y = yy;
577                 *x = xx;
578         }
579
580         /* All done */
581         return count;
582 }
583
584
585 /*!
586  * @brief プレイヤーの周辺9マスに箱のあるマスがいくつあるかを返す /
587  * Return the number of chests around (or under) the character.
588  * @param y 該当するマスの中から1つのY座標を返す参照ポインタ
589  * @param x 該当するマスの中から1つのX座標を返す参照ポインタ
590  * @param trapped TRUEならばトラップの存在が判明している箱のみ対象にする
591  * @return 該当する地形の数
592  * @details
593  * If requested, count only trapped chests.
594  */
595 static int count_chests(POSITION *y, POSITION *x, bool trapped)
596 {
597         int d, count;
598         OBJECT_IDX o_idx;
599
600         object_type *o_ptr;
601
602         /* Count how many matches */
603         count = 0;
604
605         /* Check around (and under) the character */
606         for (d = 0; d < 9; d++)
607         {
608                 /* Extract adjacent (legal) location */
609                 POSITION yy = p_ptr->y + ddy_ddd[d];
610                 POSITION xx = p_ptr->x + ddx_ddd[d];
611
612                 /* No (visible) chest is there */
613                 if ((o_idx = chest_check(yy, xx, FALSE)) == 0) continue;
614
615                 /* Grab the object */
616                 o_ptr = &o_list[o_idx];
617
618                 /* Already open */
619                 if (o_ptr->pval == 0) continue;
620
621                 /* No (known) traps here */
622                 if (trapped && (!object_is_known(o_ptr) ||
623                         !chest_traps[o_ptr->pval])) continue;
624
625                 /* OK */
626                 ++count;
627
628                 /* Remember the location. Only useful if only one match */
629                 *y = yy;
630                 *x = xx;
631         }
632
633         /* All done */
634         return count;
635 }
636
637
638 /*!
639  * @brief プレイヤーから指定の座標がどの方角にあるかを返す /
640  * Convert an adjacent location to a direction.
641  * @param y 方角を確認したY座標
642  * @param x 方角を確認したX座標
643  * @return 方向ID
644  */
645 static DIRECTION coords_to_dir(POSITION y, POSITION x)
646 {
647         int d[3][3] = { {7, 4, 1}, {8, 5, 2}, {9, 6, 3} };
648         int dy, dx;
649
650         dy = y - p_ptr->y;
651         dx = x - p_ptr->x;
652
653         /* Paranoia */
654         if (ABS(dx) > 1 || ABS(dy) > 1) return (0);
655
656         return d[dx + 1][dy + 1];
657 }
658
659 /*!
660  * @brief 「開ける」動作コマンドのサブルーチン /
661  * Perform the basic "open" command on doors
662  * @param y 対象を行うマスのY座標
663  * @param x 対象を行うマスのX座標
664  * @return 実際に処理が行われた場合TRUEを返す。
665  * @details
666  * Assume destination is a closed/locked/jammed door
667  * Assume there is no monster blocking the destination
668  * Returns TRUE if repeated commands may continue
669  */
670 static bool do_cmd_open_aux(POSITION y, POSITION x)
671 {
672         int i, j;
673
674         /* Get requested grid */
675         cave_type *c_ptr = &cave[y][x];
676         feature_type *f_ptr = &f_info[c_ptr->feat];
677         bool more = FALSE;
678
679         p_ptr->energy_use = 100;
680
681         /* Seeing true feature code (ignore mimic) */
682
683         /* Jammed door */
684         if (!have_flag(f_ptr->flags, FF_OPEN))
685         {
686                 /* Stuck */
687                 msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_name + f_info[get_feat_mimic(c_ptr)].name);
688         }
689
690         /* Locked door */
691         else if (f_ptr->power)
692         {
693                 /* Disarm factor */
694                 i = p_ptr->skill_dis;
695
696                 /* Penalize some conditions */
697                 if (p_ptr->blind || no_lite()) i = i / 10;
698                 if (p_ptr->confused || p_ptr->image) i = i / 10;
699
700                 /* Extract the lock power */
701                 j = f_ptr->power;
702
703                 /* Extract the difficulty */
704                 j = i - (j * 4);
705
706                 /* Always have a small chance of success */
707                 if (j < 2) j = 2;
708
709                 /* Success */
710                 if (randint0(100) < j)
711                 {
712                         msg_print(_("鍵をはずした。", "You have picked the lock."));
713
714                         /* Open the door */
715                         cave_alter_feat(y, x, FF_OPEN);
716
717                         sound(SOUND_OPENDOOR);
718
719                         /* Experience */
720                         gain_exp(1);
721                 }
722
723                 /* Failure */
724                 else
725                 {
726                         /* Failure */
727                         if (flush_failure) flush();
728
729                         msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
730
731                         /* We may keep trying */
732                         more = TRUE;
733                 }
734         }
735
736         /* Closed door */
737         else
738         {
739                 /* Open the door */
740                 cave_alter_feat(y, x, FF_OPEN);
741
742                 sound(SOUND_OPENDOOR);
743         }
744         return (more);
745 }
746
747 /*!
748  * @brief 「開ける」コマンドのメインルーチン /
749  * Open a closed/locked/jammed door or a closed/locked chest.
750  * @return なし
751  * @details
752  * Unlocking a locked door/chest is worth one experience point.
753  */
754 void do_cmd_open(void)
755 {
756         POSITION y, x;
757         DIRECTION dir;
758         OBJECT_IDX o_idx;
759
760         bool more = FALSE;
761
762         if (p_ptr->wild_mode) return;
763
764         if (p_ptr->special_defense & KATA_MUSOU)
765         {
766                 set_action(ACTION_NONE);
767         }
768
769         /* Option: Pick a direction */
770         if (easy_open)
771         {
772                 int num_doors, num_chests;
773
774                 /* Count closed doors (locked or jammed) */
775                 num_doors = count_dt(&y, &x, is_closed_door, FALSE);
776
777                 /* Count chests (locked) */
778                 num_chests = count_chests(&y, &x, FALSE);
779
780                 /* See if only one target */
781                 if (num_doors || num_chests)
782                 {
783                         bool too_many = (num_doors && num_chests) || (num_doors > 1) ||
784                             (num_chests > 1);
785                         if (!too_many) command_dir = coords_to_dir(y, x);
786                 }
787         }
788
789         /* Allow repeated command */
790         if (command_arg)
791         {
792                 /* Set repeat count */
793                 command_rep = command_arg - 1;
794                 p_ptr->redraw |= (PR_STATE);
795
796                 /* Cancel the arg */
797                 command_arg = 0;
798         }
799
800         /* Get a "repeated" direction */
801         if (get_rep_dir(&dir, TRUE))
802         {
803                 FEAT_IDX feat;
804                 cave_type *c_ptr;
805
806                 /* Get requested location */
807                 y = p_ptr->y + ddy[dir];
808                 x = p_ptr->x + ddx[dir];
809
810                 /* Get requested grid */
811                 c_ptr = &cave[y][x];
812
813                 /* Feature code (applying "mimic" field) */
814                 feat = get_feat_mimic(c_ptr);
815
816                 /* Check for chest */
817                 o_idx = chest_check(y, x, FALSE);
818
819                 /* Nothing useful */
820                 if (!have_flag(f_info[feat].flags, FF_OPEN) && !o_idx)
821                 {
822                         msg_print(_("そこには開けるものが見当たらない。", "You see nothing there to open."));
823                 }
824
825                 /* Monster in the way */
826                 else if (c_ptr->m_idx && p_ptr->riding != c_ptr->m_idx)
827                 {
828                         p_ptr->energy_use = 100;
829                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
830                         py_attack(y, x, 0);
831                 }
832
833                 /* Handle chests */
834                 else if (o_idx)
835                 {
836                         /* Open the chest */
837                         more = do_cmd_open_chest(y, x, o_idx);
838                 }
839
840                 /* Handle doors */
841                 else
842                 {
843                         /* Open the door */
844                         more = do_cmd_open_aux(y, x);
845                 }
846         }
847
848         /* Cancel repeat unless we may continue */
849         if (!more) disturb(FALSE, FALSE);
850 }
851
852
853
854 /*!
855  * @brief 「閉じる」動作コマンドのサブルーチン /
856  * Perform the basic "close" command
857  * @param y 対象を行うマスのY座標
858  * @param x 対象を行うマスのX座標
859  * @return 実際に処理が行われた場合TRUEを返す。
860  * @details
861  * Assume destination is an open/broken door
862  * Assume there is no monster blocking the destination
863  * Returns TRUE if repeated commands may continue
864  */
865 static bool do_cmd_close_aux(POSITION y, POSITION x)
866 {
867         cave_type *c_ptr = &cave[y][x];
868         FEAT_IDX old_feat = c_ptr->feat;
869         bool more = FALSE;
870
871         p_ptr->energy_use = 100;
872
873         /* Seeing true feature code (ignore mimic) */
874
875         /* Open door */
876         if (have_flag(f_info[old_feat].flags, FF_CLOSE))
877         {
878                 s16b closed_feat = feat_state(old_feat, FF_CLOSE);
879
880                 /* Hack -- object in the way */
881                 if ((c_ptr->o_idx || (c_ptr->info & CAVE_OBJECT)) &&
882                     (closed_feat != old_feat) && !have_flag(f_info[closed_feat].flags, FF_DROP))
883                 {
884                         msg_print(_("何かがつっかえて閉まらない。", "There seems stuck."));
885                 }
886                 else
887                 {
888                         /* Close the door */
889                         cave_alter_feat(y, x, FF_CLOSE);
890
891                         /* Broken door */
892                         if (old_feat == c_ptr->feat)
893                         {
894                                 msg_print(_("ドアは壊れてしまっている。", "The door appears to be broken."));
895                         }
896                         else
897                         {
898                                 sound(SOUND_SHUTDOOR);
899                         }
900                 }
901         }
902         return (more);
903 }
904
905
906 /*!
907  * @brief 「閉じる」コマンドのメインルーチン /
908  * Close an open door.
909  * @return なし
910  * @details
911  * Unlocking a locked door/chest is worth one experience point.
912  */
913 void do_cmd_close(void)
914 {
915         POSITION y, x;
916         DIRECTION dir;
917
918         bool more = FALSE;
919
920         if (p_ptr->wild_mode) return;
921
922         if (p_ptr->special_defense & KATA_MUSOU)
923         {
924                 set_action(ACTION_NONE);
925         }
926
927         /* Option: Pick a direction */
928         if (easy_open)
929         {
930                 /* Count open doors */
931                 if (count_dt(&y, &x, is_open, FALSE) == 1)
932                 {
933                         command_dir = coords_to_dir(y, x);
934                 }
935         }
936
937         /* Allow repeated command */
938         if (command_arg)
939         {
940                 /* Set repeat count */
941                 command_rep = command_arg - 1;
942                 p_ptr->redraw |= (PR_STATE);
943
944                 /* Cancel the arg */
945                 command_arg = 0;
946         }
947
948         /* Get a "repeated" direction */
949         if (get_rep_dir(&dir, FALSE))
950         {
951                 cave_type *c_ptr;
952                 FEAT_IDX feat;
953
954                 y = p_ptr->y + ddy[dir];
955                 x = p_ptr->x + ddx[dir];
956                 c_ptr = &cave[y][x];
957
958                 /* Feature code (applying "mimic" field) */
959                 feat = get_feat_mimic(c_ptr);
960
961                 /* Require open/broken door */
962                 if (!have_flag(f_info[feat].flags, FF_CLOSE))
963                 {
964                         msg_print(_("そこには閉じるものが見当たらない。", "You see nothing there to close."));
965                 }
966
967                 /* Monster in the way */
968                 else if (c_ptr->m_idx)
969                 {
970                         p_ptr->energy_use = 100;
971
972                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
973
974                         /* Attack */
975                         py_attack(y, x, 0);
976                 }
977
978                 /* Close the door */
979                 else
980                 {
981                         /* Close the door */
982                         more = do_cmd_close_aux(y, x);
983                 }
984         }
985
986         /* Cancel repeat unless we may continue */
987         if (!more) disturb(FALSE, FALSE);
988 }
989
990
991 /*!
992  * @brief 「掘る」コマンドを該当のマスに行えるかの判定と結果メッセージの表示 /
993  * Determine if a given grid may be "tunneled"
994  * @param y 対象を行うマスのY座標
995  * @param x 対象を行うマスのX座標
996  * @return 
997  */
998 static bool do_cmd_tunnel_test(POSITION y, POSITION x)
999 {
1000         cave_type *c_ptr = &cave[y][x];
1001
1002         /* Must have knowledge */
1003         if (!(c_ptr->info & CAVE_MARK))
1004         {
1005                 msg_print(_("そこには何も見当たらない。", "You see nothing there."));
1006
1007                 return (FALSE);
1008         }
1009
1010         /* Must be a wall/door/etc */
1011         if (!cave_have_flag_grid(c_ptr, FF_TUNNEL))
1012         {
1013                 msg_print(_("そこには掘るものが見当たらない。", "You see nothing there to tunnel."));
1014
1015                 return (FALSE);
1016         }
1017
1018         return (TRUE);
1019 }
1020
1021
1022 /*!
1023  * @brief 「掘る」動作コマンドのサブルーチン /
1024  * Perform the basic "tunnel" command
1025  * @param y 対象を行うマスのY座標
1026  * @param x 対象を行うマスのX座標
1027  * @return 実際に処理が行われた場合TRUEを返す。
1028  * @details
1029  * Assumes that no monster is blocking the destination
1030  * Do not use twall anymore
1031  * Returns TRUE if repeated commands may continue
1032  */
1033 static bool do_cmd_tunnel_aux(POSITION y, POSITION x)
1034 {
1035         cave_type *c_ptr;
1036         feature_type *f_ptr, *mimic_f_ptr;
1037         int power;
1038         concptr name;
1039         bool more = FALSE;
1040
1041         /* Verify legality */
1042         if (!do_cmd_tunnel_test(y, x)) return (FALSE);
1043
1044         p_ptr->energy_use = 100;
1045
1046         /* Get grid */
1047         c_ptr = &cave[y][x];
1048         f_ptr = &f_info[c_ptr->feat];
1049         power = f_ptr->power;
1050
1051         /* Feature code (applying "mimic" field) */
1052         mimic_f_ptr = &f_info[get_feat_mimic(c_ptr)];
1053
1054         name = f_name + mimic_f_ptr->name;
1055
1056         sound(SOUND_DIG);
1057
1058         if (have_flag(f_ptr->flags, FF_PERMANENT))
1059         {
1060                 /* Titanium */
1061                 if (have_flag(mimic_f_ptr->flags, FF_PERMANENT))
1062                 {
1063                         msg_print(_("この岩は硬すぎて掘れないようだ。", "This seems to be permanent rock."));
1064                 }
1065
1066                 /* Map border (mimiccing Permanent wall) */
1067                 else
1068                 {
1069                         msg_print(_("そこは掘れない!", "You can't tunnel through that!"));
1070                 }
1071         }
1072
1073         /* Dig or tunnel */
1074         else if (have_flag(f_ptr->flags, FF_CAN_DIG))
1075         {
1076                 /* Dig */
1077                 if (p_ptr->skill_dig > randint0(20 * power))
1078                 {
1079                         msg_format(_("%sをくずした。", "You have removed the %s."), name);
1080
1081                         /* Remove the feature */
1082                         cave_alter_feat(y, x, FF_TUNNEL);
1083
1084                         /* Update some things */
1085                         p_ptr->update |= (PU_FLOW);
1086                 }
1087                 else
1088                 {
1089                         /* Message, keep digging */
1090                         msg_format(_("%sをくずしている。", "You dig into the %s."), name);
1091                         
1092                         more = TRUE;
1093                 }
1094         }
1095
1096         else
1097         {
1098                 bool tree = have_flag(mimic_f_ptr->flags, FF_TREE);
1099
1100                 /* Tunnel */
1101                 if (p_ptr->skill_dig > power + randint0(40 * power))
1102                 {
1103                         if (tree) msg_format(_("%sを切り払った。", "You have cleared away the %s."), name);
1104                         else
1105                         {
1106                                 msg_print(_("穴を掘り終えた。", "You have finished the tunnel."));
1107                                 p_ptr->update |= (PU_FLOW);
1108                         }
1109                         
1110                         if (have_flag(f_ptr->flags, FF_GLASS)) sound(SOUND_GLASS);
1111
1112                         /* Remove the feature */
1113                         cave_alter_feat(y, x, FF_TUNNEL);
1114
1115                         chg_virtue(V_DILIGENCE, 1);
1116                         chg_virtue(V_NATURE, -1);
1117                 }
1118
1119                 /* Keep trying */
1120                 else
1121                 {
1122                         if (tree)
1123                         {
1124                                 /* We may continue chopping */
1125                                 msg_format(_("%sを切っている。", "You chop away at the %s."), name);
1126                                 /* Occasional Search XXX XXX */
1127                                 if (randint0(100) < 25) search();
1128                         }
1129                         else
1130                         {
1131                                 /* We may continue tunelling */
1132                                 msg_format(_("%sに穴を掘っている。", "You tunnel into the %s."), name);
1133                         }
1134
1135                         more = TRUE;
1136                 }
1137         }
1138
1139         if (is_hidden_door(c_ptr))
1140         {
1141                 /* Occasional Search XXX XXX */
1142                 if (randint0(100) < 25) search();
1143         }
1144         return more;
1145 }
1146
1147
1148 /*!
1149  * @brief 「掘る」動作コマンドのメインルーチン /
1150  * Tunnels through "walls" (including rubble and closed doors)
1151  * @return なし
1152  * @details
1153  * <pre>
1154  * Note that you must tunnel in order to hit invisible monsters
1155  * in walls, though moving into walls still takes a turn anyway.
1156  *
1157  * Digging is very difficult without a "digger" weapon, but can be
1158  * accomplished by strong players using heavy weapons.
1159  * </pre>
1160  */
1161 void do_cmd_tunnel(void)
1162 {
1163         int                     y, x, dir;
1164
1165         cave_type       *c_ptr;
1166         FEAT_IDX feat;
1167
1168         bool            more = FALSE;
1169
1170
1171         if (p_ptr->special_defense & KATA_MUSOU)
1172         {
1173                 set_action(ACTION_NONE);
1174         }
1175
1176         /* Allow repeated command */
1177         if (command_arg)
1178         {
1179                 /* Set repeat count */
1180                 command_rep = command_arg - 1;
1181                 p_ptr->redraw |= (PR_STATE);
1182
1183                 /* Cancel the arg */
1184                 command_arg = 0;
1185         }
1186
1187         /* Get a direction to tunnel, or Abort */
1188         if (get_rep_dir(&dir,FALSE))
1189         {
1190                 /* Get location */
1191                 y = p_ptr->y + ddy[dir];
1192                 x = p_ptr->x + ddx[dir];
1193
1194                 /* Get grid */
1195                 c_ptr = &cave[y][x];
1196
1197                 /* Feature code (applying "mimic" field) */
1198                 feat = get_feat_mimic(c_ptr);
1199
1200                 /* No tunnelling through doors */
1201                 if (have_flag(f_info[feat].flags, FF_DOOR))
1202                 {
1203                         msg_print(_("ドアは掘れない。", "You cannot tunnel through doors."));
1204                 }
1205
1206                 /* No tunnelling through most features */
1207                 else if (!have_flag(f_info[feat].flags, FF_TUNNEL))
1208                 {
1209                         msg_print(_("そこは掘れない。", "You can't tunnel through that."));
1210                 }
1211
1212                 /* A monster is in the way */
1213                 else if (c_ptr->m_idx)
1214                 {
1215                         p_ptr->energy_use = 100;
1216
1217                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1218
1219                         /* Attack */
1220                         py_attack(y, x, 0);
1221                 }
1222
1223                 /* Try digging */
1224                 else
1225                 {
1226                         /* Tunnel through walls */
1227                         more = do_cmd_tunnel_aux(y, x);
1228                 }
1229         }
1230
1231         /* Cancel repetition unless we can continue */
1232         if (!more) disturb(FALSE, FALSE);
1233 }
1234
1235 /*!
1236  * @brief 移動処理による簡易な「開く」処理 /
1237  * easy_open_door --
1238  * @return 開く処理が実際に試みられた場合TRUEを返す
1239  * @details
1240  * <pre>
1241  *      If there is a jammed/closed/locked door at the given location,
1242  *      then attempt to unlock/open it. Return TRUE if an attempt was
1243  *      made (successful or not), otherwise return FALSE.
1244  *
1245  *      The code here should be nearly identical to that in
1246  *      do_cmd_open_test() and do_cmd_open_aux().
1247  * </pre>
1248  */
1249 bool easy_open_door(POSITION y, POSITION x)
1250 {
1251         int i, j;
1252
1253         cave_type *c_ptr = &cave[y][x];
1254         feature_type *f_ptr = &f_info[c_ptr->feat];
1255
1256         /* Must be a closed door */
1257         if (!is_closed_door(c_ptr->feat))
1258         {
1259                 return (FALSE);
1260         }
1261
1262         /* Jammed door */
1263         if (!have_flag(f_ptr->flags, FF_OPEN))
1264         {
1265                 /* Stuck */
1266                 msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_name + f_info[get_feat_mimic(c_ptr)].name);
1267
1268         }
1269
1270         /* Locked door */
1271         else if (f_ptr->power)
1272         {
1273                 /* Disarm factor */
1274                 i = p_ptr->skill_dis;
1275
1276                 /* Penalize some conditions */
1277                 if (p_ptr->blind || no_lite()) i = i / 10;
1278                 if (p_ptr->confused || p_ptr->image) i = i / 10;
1279
1280                 /* Extract the lock power */
1281                 j = f_ptr->power;
1282
1283                 /* Extract the difficulty */
1284                 j = i - (j * 4);
1285
1286                 /* Always have a small chance of success */
1287                 if (j < 2) j = 2;
1288
1289                 /* Success */
1290                 if (randint0(100) < j)
1291                 {
1292                         msg_print(_("鍵をはずした。", "You have picked the lock."));
1293
1294                         /* Open the door */
1295                         cave_alter_feat(y, x, FF_OPEN);
1296
1297                         sound(SOUND_OPENDOOR);
1298
1299                         /* Experience */
1300                         gain_exp(1);
1301                 }
1302
1303                 /* Failure */
1304                 else
1305                 {
1306                         /* Failure */
1307                         if (flush_failure) flush();
1308
1309                         msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
1310
1311                 }
1312         }
1313
1314         /* Closed door */
1315         else
1316         {
1317                 /* Open the door */
1318                 cave_alter_feat(y, x, FF_OPEN);
1319
1320                 sound(SOUND_OPENDOOR);
1321         }
1322         return (TRUE);
1323 }
1324
1325 /*!
1326  * @brief 箱のトラップを解除するコマンドのメインルーチン /
1327  * Perform the basic "disarm" command
1328  * @param y 解除を行うマスのY座標
1329  * @param x 解除を行うマスのX座標
1330  * @param o_idx 箱のオブジェクトID
1331  * @return ターンを消費する処理が行われた場合TRUEを返す
1332  * @details
1333  * <pre>
1334  * Assume destination is a visible trap
1335  * Assume there is no monster blocking the destination
1336  * Returns TRUE if repeated commands may continue
1337  * </pre>
1338  */
1339 static bool do_cmd_disarm_chest(POSITION y, POSITION x, OBJECT_IDX o_idx)
1340 {
1341         int i, j;
1342         bool more = FALSE;
1343         object_type *o_ptr = &o_list[o_idx];
1344
1345         p_ptr->energy_use = 100;
1346
1347         /* Get the "disarm" factor */
1348         i = p_ptr->skill_dis;
1349
1350         /* Penalize some conditions */
1351         if (p_ptr->blind || no_lite()) i = i / 10;
1352         if (p_ptr->confused || p_ptr->image) i = i / 10;
1353
1354         /* Extract the difficulty */
1355         j = i - o_ptr->pval;
1356
1357         /* Always have a small chance of success */
1358         if (j < 2) j = 2;
1359
1360         /* Must find the trap first. */
1361         if (!object_is_known(o_ptr))
1362         {
1363                 msg_print(_("トラップが見あたらない。", "I don't see any traps."));
1364
1365         }
1366
1367         /* Already disarmed/unlocked */
1368         else if (o_ptr->pval <= 0)
1369         {
1370                 msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped."));
1371         }
1372
1373         /* No traps to find. */
1374         else if (!chest_traps[o_ptr->pval])
1375         {
1376                 msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped."));
1377         }
1378
1379         /* Success (get a lot of experience) */
1380         else if (randint0(100) < j)
1381         {
1382                 msg_print(_("箱に仕掛けられていたトラップを解除した。", "You have disarmed the chest."));
1383                 gain_exp(o_ptr->pval);
1384                 o_ptr->pval = (0 - o_ptr->pval);
1385         }
1386
1387         /* Failure -- Keep trying */
1388         else if ((i > 5) && (randint1(i) > 5))
1389         {
1390                 /* We may keep trying */
1391                 more = TRUE;
1392                 if (flush_failure) flush();
1393                 msg_print(_("箱のトラップ解除に失敗した。", "You failed to disarm the chest."));
1394         }
1395
1396         /* Failure -- Set off the trap */
1397         else
1398         {
1399                 msg_print(_("トラップを作動させてしまった!", "You set off a trap!"));
1400                 sound(SOUND_FAIL);
1401                 chest_trap(y, x, o_idx);
1402         }
1403         return (more);
1404 }
1405
1406
1407 /*!
1408  * @brief 箱のトラップを解除するコマンドのサブルーチン /
1409  * Perform the basic "disarm" command
1410  * @param y 解除を行うマスのY座標
1411  * @param x 解除を行うマスのX座標
1412  * @param dir プレイヤーからみた方向ID
1413  * @return ターンを消費する処理が行われた場合TRUEを返す
1414  * @details
1415  * <pre>
1416  * Assume destination is a visible trap
1417  * Assume there is no monster blocking the destination
1418  * Returns TRUE if repeated commands may continue
1419  * </pre>
1420  */
1421
1422 bool do_cmd_disarm_aux(POSITION y, POSITION x, DIRECTION dir)
1423 {
1424         cave_type *c_ptr = &cave[y][x];
1425
1426         /* Get feature */
1427         feature_type *f_ptr = &f_info[c_ptr->feat];
1428
1429         /* Access trap name */
1430         concptr name = (f_name + f_ptr->name);
1431
1432         /* Extract trap "power" */
1433         int power = f_ptr->power;
1434         bool more = FALSE;
1435
1436         /* Get the "disarm" factor */
1437         int i = p_ptr->skill_dis;
1438         int j;
1439
1440         p_ptr->energy_use = 100;
1441
1442         /* Penalize some conditions */
1443         if (p_ptr->blind || no_lite()) i = i / 10;
1444         if (p_ptr->confused || p_ptr->image) i = i / 10;
1445
1446         /* Extract the difficulty */
1447         j = i - power;
1448
1449         /* Always have a small chance of success */
1450         if (j < 2) j = 2;
1451
1452         /* Success */
1453         if (randint0(100) < j)
1454         {
1455                 msg_format(_("%sを解除した。", "You have disarmed the %s."), name);
1456                 
1457                 /* Reward */
1458                 gain_exp(power);
1459
1460                 /* Remove the trap */
1461                 cave_alter_feat(y, x, FF_DISARM);
1462
1463                 /* Move the player onto the trap */
1464                 move_player(dir, easy_disarm, FALSE);
1465         }
1466
1467         /* Failure -- Keep trying */
1468         else if ((i > 5) && (randint1(i) > 5))
1469         {
1470                 /* Failure */
1471                 if (flush_failure) flush();
1472
1473                 msg_format(_("%sの解除に失敗した。", "You failed to disarm the %s."), name);
1474
1475                 /* We may keep trying */
1476                 more = TRUE;
1477         }
1478
1479         /* Failure -- Set off the trap */
1480         else
1481         {
1482                 msg_format(_("%sを作動させてしまった!", "You set off the %s!"), name);
1483                 /* Move the player onto the trap */
1484                 move_player(dir, easy_disarm, FALSE);
1485         }
1486         return (more);
1487 }
1488
1489
1490 /*!
1491  * @brief 箱、床のトラップ解除処理双方の統合メインルーチン /
1492  * Disarms a trap, or chest
1493  * @return なし
1494  */
1495 void do_cmd_disarm(void)
1496 {
1497         POSITION y, x;
1498         DIRECTION dir;
1499         OBJECT_IDX o_idx;
1500
1501         bool more = FALSE;
1502
1503         if (p_ptr->wild_mode) return;
1504
1505         if (p_ptr->special_defense & KATA_MUSOU)
1506         {
1507                 set_action(ACTION_NONE);
1508         }
1509
1510         /* Option: Pick a direction */
1511         if (easy_disarm)
1512         {
1513                 int num_traps, num_chests;
1514
1515                 /* Count visible traps */
1516                 num_traps = count_dt(&y, &x, is_trap, TRUE);
1517
1518                 /* Count chests (trapped) */
1519                 num_chests = count_chests(&y, &x, TRUE);
1520
1521                 /* See if only one target */
1522                 if (num_traps || num_chests)
1523                 {
1524                         bool too_many = (num_traps && num_chests) || (num_traps > 1) || (num_chests > 1);
1525                         if (!too_many) command_dir = coords_to_dir(y, x);
1526                 }
1527         }
1528
1529
1530         /* Allow repeated command */
1531         if (command_arg)
1532         {
1533                 /* Set repeat count */
1534                 command_rep = command_arg - 1;
1535                 p_ptr->redraw |= (PR_STATE);
1536
1537                 /* Cancel the arg */
1538                 command_arg = 0;
1539         }
1540
1541         /* Get a direction (or abort) */
1542         if (get_rep_dir(&dir,TRUE))
1543         {
1544                 cave_type *c_ptr;
1545                 FEAT_IDX feat;
1546
1547                 y = p_ptr->y + ddy[dir];
1548                 x = p_ptr->x + ddx[dir];
1549                 c_ptr = &cave[y][x];
1550
1551                 /* Feature code (applying "mimic" field) */
1552                 feat = get_feat_mimic(c_ptr);
1553
1554                 /* Check for chests */
1555                 o_idx = chest_check(y, x, TRUE);
1556
1557                 /* Disarm a trap */
1558                 if (!is_trap(feat) && !o_idx)
1559                 {
1560                         msg_print(_("そこには解除するものが見当たらない。", "You see nothing there to disarm."));
1561                 }
1562
1563                 /* Monster in the way */
1564                 else if (c_ptr->m_idx && p_ptr->riding != c_ptr->m_idx)
1565                 {
1566                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1567
1568                         /* Attack */
1569                         py_attack(y, x, 0);
1570                 }
1571
1572                 /* Disarm chest */
1573                 else if (o_idx)
1574                 {
1575                         more = do_cmd_disarm_chest(y, x, o_idx);
1576                 }
1577
1578                 /* Disarm trap */
1579                 else
1580                 {
1581                         more = do_cmd_disarm_aux(y, x, dir);
1582                 }
1583         }
1584
1585         /* Cancel repeat unless told not to */
1586         if (!more) disturb(FALSE, FALSE);
1587 }
1588
1589
1590 /*!
1591  * @brief 「打ち破る」動作コマンドのサブルーチン /
1592  * Perform the basic "bash" command
1593  * @param y 対象を行うマスのY座標
1594  * @param x 対象を行うマスのX座標
1595  * @param dir プレイヤーから見たターゲットの方角ID
1596  * @return 実際に処理が行われた場合TRUEを返す。
1597  * @details
1598  * <pre>
1599  * Assume destination is a closed/locked/jammed door
1600  * Assume there is no monster blocking the destination
1601  * Returns TRUE if repeated commands may continue
1602  * </pre>
1603  */
1604 static bool do_cmd_bash_aux(POSITION y, POSITION x, DIRECTION dir)
1605 {
1606         /* Get grid */
1607         cave_type       *c_ptr = &cave[y][x];
1608
1609         /* Get feature */
1610         feature_type *f_ptr = &f_info[c_ptr->feat];
1611
1612         /* Hack -- Bash power based on strength */
1613         /* (Ranges from 3 to 20 to 100 to 200) */
1614         int bash = adj_str_blow[p_ptr->stat_ind[A_STR]];
1615
1616         /* Extract door power */
1617         int temp = f_ptr->power;
1618
1619         bool            more = FALSE;
1620
1621         concptr name = f_name + f_info[get_feat_mimic(c_ptr)].name;
1622
1623         p_ptr->energy_use = 100;
1624
1625         msg_format(_("%sに体当たりをした!", "You smash into the %s!"), name);
1626
1627         /* Compare bash power to door power */
1628         temp = (bash - (temp * 10));
1629
1630         if (p_ptr->pclass == CLASS_BERSERKER) temp *= 2;
1631
1632         /* Hack -- always have a chance */
1633         if (temp < 1) temp = 1;
1634
1635         /* Hack -- attempt to bash down the door */
1636         if (randint0(100) < temp)
1637         {
1638                 msg_format(_("%sを壊した!", "The %s crashes open!"), name);
1639
1640                 sound(have_flag(f_ptr->flags, FF_GLASS) ? SOUND_GLASS : SOUND_OPENDOOR);
1641
1642                 /* Break down the door */
1643                 if ((randint0(100) < 50) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS))
1644                 {
1645                         cave_alter_feat(y, x, FF_BASH);
1646                 }
1647
1648                 /* Open the door */
1649                 else
1650                 {
1651                         cave_alter_feat(y, x, FF_OPEN);
1652                 }
1653
1654                 /* Hack -- Fall through the door */
1655                 move_player(dir, FALSE, FALSE);
1656         }
1657
1658         /* Saving throw against stun */
1659         else if (randint0(100) < adj_dex_safe[p_ptr->stat_ind[A_DEX]] +
1660                  p_ptr->lev)
1661         {
1662                 msg_format(_("この%sは頑丈だ。", "The %s holds firm."), name);
1663
1664                 /* Allow repeated bashing */
1665                 more = TRUE;
1666         }
1667
1668         /* High dexterity yields coolness */
1669         else
1670         {
1671                 msg_print(_("体のバランスをくずしてしまった。", "You are off-balance."));
1672
1673                 /* Hack -- Lose balance ala paralysis */
1674                 (void)set_paralyzed(p_ptr->paralyzed + 2 + randint0(2));
1675         }
1676         return (more);
1677 }
1678
1679
1680 /*!
1681  * @brief 「打ち破る」動作コマンドのメインルーチン /
1682  * Bash open a door, success based on character strength
1683  * @return なし
1684  * @details
1685  * <pre>
1686  * For a closed door, pval is positive if locked; negative if stuck.
1687  *
1688  * For an open door, pval is positive for a broken door.
1689  *
1690  * A closed door can be opened - harder if locked. Any door might be
1691  * bashed open (and thereby broken). Bashing a door is (potentially)
1692  * faster! You move into the door way. To open a stuck door, it must
1693  * be bashed. A closed door can be jammed (see do_cmd_spike()).
1694  *
1695  * Creatures can also open or bash doors, see elsewhere.
1696  * </pre>
1697  */
1698 void do_cmd_bash(void)
1699 {
1700         int     y, x, dir;
1701         cave_type       *c_ptr;
1702         bool            more = FALSE;
1703
1704         if (p_ptr->wild_mode) return;
1705
1706         if (p_ptr->special_defense & KATA_MUSOU)
1707         {
1708                 set_action(ACTION_NONE);
1709         }
1710
1711         /* Allow repeated command */
1712         if (command_arg)
1713         {
1714                 /* Set repeat count */
1715                 command_rep = command_arg - 1;
1716                 p_ptr->redraw |= (PR_STATE);
1717
1718                 /* Cancel the arg */
1719                 command_arg = 0;
1720         }
1721
1722         /* Get a "repeated" direction */
1723         if (get_rep_dir(&dir,FALSE))
1724         {
1725                 FEAT_IDX feat;
1726
1727                 /* Bash location */
1728                 y = p_ptr->y + ddy[dir];
1729                 x = p_ptr->x + ddx[dir];
1730
1731                 /* Get grid */
1732                 c_ptr = &cave[y][x];
1733
1734                 /* Feature code (applying "mimic" field) */
1735                 feat = get_feat_mimic(c_ptr);
1736
1737                 /* Nothing useful */
1738                 if (!have_flag(f_info[feat].flags, FF_BASH))
1739                 {
1740                         msg_print(_("そこには体当たりするものが見当たらない。", "You see nothing there to bash."));
1741                 }
1742
1743                 /* Monster in the way */
1744                 else if (c_ptr->m_idx)
1745                 {
1746                         p_ptr->energy_use = 100;
1747
1748                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1749
1750                         /* Attack */
1751                         py_attack(y, x, 0);
1752                 }
1753
1754                 /* Bash a closed door */
1755                 else
1756                 {
1757                         /* Bash the door */
1758                         more = do_cmd_bash_aux(y, x, dir);
1759                 }
1760         }
1761
1762         /* Unless valid action taken, cancel bash */
1763         if (!more) disturb(FALSE, FALSE);
1764 }
1765
1766
1767 /*!
1768  * @brief 特定のマスに影響を及ぼすための汎用的コマンド
1769  * @return なし
1770  * @details
1771  * <pre>
1772  * Manipulate an adjacent grid in some way
1773  *
1774  * Attack monsters, tunnel through walls, disarm traps, open doors.
1775  *
1776  * Consider confusion 
1777  *
1778  * This command must always take a turn, to prevent free detection
1779  * of invisible monsters.
1780  * </pre>
1781  */
1782 void do_cmd_alter(void)
1783 {
1784         POSITION y, x;
1785         DIRECTION dir;
1786         cave_type *c_ptr;
1787         bool more = FALSE;
1788
1789         if (p_ptr->special_defense & KATA_MUSOU)
1790         {
1791                 set_action(ACTION_NONE);
1792         }
1793
1794         /* Allow repeated command */
1795         if (command_arg)
1796         {
1797                 /* Set repeat count */
1798                 command_rep = command_arg - 1;
1799                 p_ptr->redraw |= (PR_STATE);
1800
1801                 /* Cancel the arg */
1802                 command_arg = 0;
1803         }
1804
1805         /* Get a direction */
1806         if (get_rep_dir(&dir,TRUE))
1807         {
1808                 FEAT_IDX feat;
1809                 feature_type *f_ptr;
1810
1811                 y = p_ptr->y + ddy[dir];
1812                 x = p_ptr->x + ddx[dir];
1813
1814                 /* Get grid */
1815                 c_ptr = &cave[y][x];
1816
1817                 /* Feature code (applying "mimic" field) */
1818                 feat = get_feat_mimic(c_ptr);
1819                 f_ptr = &f_info[feat];
1820
1821                 p_ptr->energy_use = 100;
1822
1823                 if (c_ptr->m_idx)
1824                 {
1825                         py_attack(y, x, 0);
1826                 }
1827
1828                 /* Locked doors */
1829                 else if (have_flag(f_ptr->flags, FF_OPEN))
1830                 {
1831                         more = do_cmd_open_aux(y, x);
1832                 }
1833
1834                 /* Bash jammed doors */
1835                 else if (have_flag(f_ptr->flags, FF_BASH))
1836                 {
1837                         more = do_cmd_bash_aux(y, x, dir);
1838                 }
1839
1840                 /* Tunnel through walls */
1841                 else if (have_flag(f_ptr->flags, FF_TUNNEL))
1842                 {
1843                         more = do_cmd_tunnel_aux(y, x);
1844                 }
1845
1846                 /* Close open doors */
1847                 else if (have_flag(f_ptr->flags, FF_CLOSE))
1848                 {
1849                         more = do_cmd_close_aux(y, x);
1850                 }
1851
1852                 /* Disarm traps */
1853                 else if (have_flag(f_ptr->flags, FF_DISARM))
1854                 {
1855                         more = do_cmd_disarm_aux(y, x, dir);
1856                 }
1857
1858                 else
1859                 {
1860                         msg_print(_("何もない空中を攻撃した。", "You attack the empty air."));
1861                 }
1862         }
1863
1864         /* Cancel repetition unless we can continue */
1865         if (!more) disturb(FALSE, FALSE);
1866 }
1867
1868
1869
1870 /*!
1871  * @brief 「くさびを打つ」ために必要なオブジェクトがあるかどうかの判定を返す /
1872  * Find the index of some "spikes", if possible.
1873  * @param ip くさびとして打てるオブジェクトのID
1874  * @return オブジェクトがある場合TRUEを返す
1875  * @details
1876  * <pre>
1877  * Let user choose a pile of spikes, perhaps?
1878  * </pre>
1879  */
1880 static bool get_spike(INVENTORY_IDX *ip)
1881 {
1882         INVENTORY_IDX i;
1883
1884         /* Check every item in the pack */
1885         for (i = 0; i < INVEN_PACK; i++)
1886         {
1887                 object_type *o_ptr = &inventory[i];
1888
1889                 /* Skip non-objects */
1890                 if (!o_ptr->k_idx) continue;
1891
1892                 /* Check the "tval" code */
1893                 if (o_ptr->tval == TV_SPIKE)
1894                 {
1895                         /* Save the spike index */
1896                         (*ip) = i;
1897
1898                         /* Success */
1899                         return (TRUE);
1900                 }
1901         }
1902
1903         return (FALSE);
1904 }
1905
1906
1907 /*!
1908  * @brief 「くさびを打つ」動作コマンドのメインルーチン /
1909  * Jam a closed door with a spike
1910  * @return なし
1911  * @details
1912  * <pre>
1913  * This command may NOT be repeated
1914  * </pre>
1915  */
1916 void do_cmd_spike(void)
1917 {
1918         DIRECTION dir;
1919
1920         if (p_ptr->wild_mode) return;
1921
1922         if (p_ptr->special_defense & KATA_MUSOU)
1923         {
1924                 set_action(ACTION_NONE);
1925         }
1926
1927         /* Get a "repeated" direction */
1928         if (get_rep_dir(&dir, FALSE))
1929         {
1930                 POSITION y, x;
1931                 INVENTORY_IDX item;
1932                 cave_type *c_ptr;
1933                 FEAT_IDX feat;
1934
1935                 y = p_ptr->y + ddy[dir];
1936                 x = p_ptr->x + ddx[dir];
1937                 c_ptr = &cave[y][x];
1938
1939                 /* Feature code (applying "mimic" field) */
1940                 feat = get_feat_mimic(c_ptr);
1941
1942                 /* Require closed door */
1943                 if (!have_flag(f_info[feat].flags, FF_SPIKE))
1944                 {
1945                         msg_print(_("そこにはくさびを打てるものが見当たらない。", "You see nothing there to spike."));
1946                 }
1947
1948                 /* Get a spike */
1949                 else if (!get_spike(&item))
1950                 {
1951                         msg_print(_("くさびを持っていない!", "You have no spikes!"));
1952                 }
1953
1954                 /* Is a monster in the way? */
1955                 else if (c_ptr->m_idx)
1956                 {
1957                         p_ptr->energy_use = 100;
1958
1959                         msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1960
1961                         /* Attack */
1962                         py_attack(y, x, 0);
1963                 }
1964
1965                 /* Go for it */
1966                 else
1967                 {
1968                         p_ptr->energy_use = 100;
1969
1970                         /* Successful jamming */
1971                         msg_format(_("%sにくさびを打ち込んだ。", "You jam the %s with a spike."), f_name + f_info[feat].name);
1972                         cave_alter_feat(y, x, FF_SPIKE);
1973
1974                         /* Use up, and describe, a single spike, from the bottom */
1975                         inven_item_increase(item, -1);
1976                         inven_item_describe(item);
1977                         inven_item_optimize(item);
1978                 }
1979         }
1980 }
1981
1982
1983
1984 /*!
1985  * @brief 「歩く」動作コマンドのメインルーチン /
1986  * Support code for the "Walk" and "Jump" commands
1987  * @param pickup アイテムの自動拾いを行うならTRUE
1988  * @return なし
1989  */
1990 void do_cmd_walk(bool pickup)
1991 {
1992         DIRECTION dir;
1993
1994         bool more = FALSE;
1995
1996
1997         /* Allow repeated command */
1998         if (command_arg)
1999         {
2000                 /* Set repeat count */
2001                 command_rep = command_arg - 1;
2002                 p_ptr->redraw |= (PR_STATE);
2003
2004                 /* Cancel the arg */
2005                 command_arg = 0;
2006         }
2007
2008         /* Get a "repeated" direction */
2009         if (get_rep_dir(&dir, FALSE))
2010         {
2011                 p_ptr->energy_use = 100;
2012
2013                 if ((dir != 5) && (p_ptr->special_defense & KATA_MUSOU))
2014                 {
2015                         set_action(ACTION_NONE);
2016                 }
2017
2018                 /* Hack -- In small scale wilderness it takes MUCH more time to move */
2019                 if (p_ptr->wild_mode) p_ptr->energy_use *= ((MAX_HGT + MAX_WID) / 2);
2020                 if (p_ptr->action == ACTION_HAYAGAKE) p_ptr->energy_use = p_ptr->energy_use * (45-(p_ptr->lev/2)) / 100;
2021
2022                 /* Actually move the character */
2023                 move_player(dir, pickup, FALSE);
2024
2025                 /* Allow more walking */
2026                 more = TRUE;
2027         }
2028
2029         /* Hack again -- Is there a special encounter ??? */
2030         if (p_ptr->wild_mode && !cave_have_flag_bold(p_ptr->y, p_ptr->x, FF_TOWN))
2031         {
2032                 int tmp = 120 + p_ptr->lev*10 - wilderness[p_ptr->y][p_ptr->x].level + 5;
2033                 if (tmp < 1) 
2034                         tmp = 1;
2035                 if (((wilderness[p_ptr->y][p_ptr->x].level + 5) > (p_ptr->lev / 2)) && randint0(tmp) < (21-p_ptr->skill_stl))
2036                 {
2037                         /* Inform the player of his horrible fate :=) */
2038                         msg_print(_("襲撃だ!", "You are ambushed !"));
2039
2040                         /* Go into large wilderness view */
2041                         p_ptr->oldpy = randint1(MAX_HGT-2);
2042                         p_ptr->oldpx = randint1(MAX_WID-2);
2043                         change_wild_mode();
2044
2045                         /* Give first move to monsters */
2046                         p_ptr->energy_use = 100;
2047
2048                         /* HACk -- set the encouter flag for the wilderness generation */
2049                         generate_encounter = TRUE;
2050                 }
2051         }
2052
2053         /* Cancel repeat unless we may continue */
2054         if (!more) disturb(FALSE, FALSE);
2055 }
2056
2057
2058 /*!
2059  * @brief 「走る」動作コマンドのメインルーチン /
2060  * Start running.
2061  * @return なし
2062  */
2063 void do_cmd_run(void)
2064 {
2065         DIRECTION dir;
2066
2067         /* Hack -- no running when confused */
2068         if (p_ptr->confused)
2069         {
2070                 msg_print(_("混乱していて走れない!", "You are too confused!"));
2071                 return;
2072         }
2073
2074         if (p_ptr->special_defense & KATA_MUSOU)
2075         {
2076                 set_action(ACTION_NONE);
2077         }
2078
2079         /* Get a "repeated" direction */
2080         if (get_rep_dir(&dir,FALSE))
2081         {
2082                 /* Hack -- Set the run counter */
2083                 running = (command_arg ? command_arg : 1000);
2084
2085                 /* First step */
2086                 run_step(dir);
2087         }
2088 }
2089
2090
2091 /*!
2092  * @brief 「留まる」動作コマンドのメインルーチン /
2093  * Stay still.  Search.  Enter stores.
2094  * Pick up treasure if "pickup" is true.
2095  * @param pickup アイテムの自動拾いを行うならTRUE
2096  * @return なし
2097  */
2098 void do_cmd_stay(bool pickup)
2099 {
2100         u32b mpe_mode = MPE_STAYING | MPE_ENERGY_USE;
2101
2102         /* Allow repeated command */
2103         if (command_arg)
2104         {
2105                 /* Set repeat count */
2106                 command_rep = command_arg - 1;
2107                 p_ptr->redraw |= (PR_STATE);
2108
2109                 /* Cancel the arg */
2110                 command_arg = 0;
2111         }
2112
2113         p_ptr->energy_use = 100;
2114
2115         if (pickup) mpe_mode |= MPE_DO_PICKUP;
2116         (void)move_player_effect(p_ptr->y, p_ptr->x, mpe_mode);
2117 }
2118
2119
2120 /*!
2121  * @brief 「休む」動作コマンドのメインルーチン /
2122  * Resting allows a player to safely restore his hp     -RAK-
2123  * @return なし
2124  */
2125 void do_cmd_rest(void)
2126 {
2127
2128         set_action(ACTION_NONE);
2129
2130         if ((p_ptr->pclass == CLASS_BARD) && (SINGING_SONG_EFFECT(p_ptr) || INTERUPTING_SONG_EFFECT(p_ptr)))
2131         {
2132                 stop_singing();
2133         }
2134
2135         /* Hex */
2136         if (hex_spelling_any()) stop_hex_spell_all();
2137
2138         /* Prompt for time if needed */
2139         if (command_arg <= 0)
2140         {
2141                 concptr p = _("休憩 (0-9999, '*' で HP/MP全快, '&' で必要なだけ): ", 
2142                                    "Rest (0-9999, '*' for HP/SP, '&' as needed): ");
2143
2144
2145                 char out_val[80];
2146
2147                 /* Default */
2148                 strcpy(out_val, "&");
2149
2150                 /* Ask for duration */
2151                 if (!get_string(p, out_val, 4)) return;
2152
2153                 /* Rest until done */
2154                 if (out_val[0] == '&')
2155                 {
2156                         command_arg = COMMAND_ARG_REST_UNTIL_DONE;
2157                 }
2158
2159                 /* Rest a lot */
2160                 else if (out_val[0] == '*')
2161                 {
2162                         command_arg = COMMAND_ARG_REST_FULL_HEALING;
2163                 }
2164
2165                 /* Rest some */
2166                 else
2167                 {
2168                         command_arg = (COMMAND_ARG)atoi(out_val);
2169                         if (command_arg <= 0) return;
2170                 }
2171         }
2172
2173
2174         /* Paranoia */
2175         if (command_arg > 9999) command_arg = 9999;
2176
2177         if (p_ptr->special_defense & NINJA_S_STEALTH) set_superstealth(FALSE);
2178
2179         /* Take a turn (?) */
2180         p_ptr->energy_use = 100;
2181
2182         /* The sin of sloth */
2183         if (command_arg > 100) chg_virtue(V_DILIGENCE, -1);
2184         
2185         /* Why are you sleeping when there's no need?  WAKE UP!*/
2186         if ((p_ptr->chp == p_ptr->mhp) &&
2187             (p_ptr->csp == p_ptr->msp) &&
2188             !p_ptr->blind && !p_ptr->confused &&
2189             !p_ptr->poisoned && !p_ptr->afraid &&
2190             !p_ptr->stun && !p_ptr->cut &&
2191             !p_ptr->slow && !p_ptr->paralyzed &&
2192             !p_ptr->image && !p_ptr->word_recall &&
2193             !p_ptr->alter_reality)
2194                         chg_virtue(V_DILIGENCE, -1);
2195
2196         /* Save the rest code */
2197         resting = command_arg;
2198         p_ptr->action = ACTION_REST;
2199         p_ptr->update |= (PU_BONUS);
2200         update_creature(p_ptr);
2201
2202         p_ptr->redraw |= (PR_STATE);
2203         update_output();
2204
2205         Term_fresh();
2206 }
2207
2208
2209
2210 /*!
2211  * @brief 射撃処理のメインルーチン
2212  * @return なし
2213  */
2214 void do_cmd_fire(void)
2215 {
2216         OBJECT_IDX item;
2217         object_type *j_ptr, *ammo_ptr;
2218         concptr q, s;
2219
2220         if(p_ptr->wild_mode) return;
2221
2222         is_fired = FALSE;       /* not fired yet */
2223
2224         /* Get the "bow" (if any) */
2225         j_ptr = &inventory[INVEN_BOW];
2226
2227         /* Require a launcher */
2228         if (!j_ptr->tval)
2229         {
2230                 msg_print(_("射撃用の武器を持っていない。", "You have nothing to fire with."));
2231                 flush();
2232                 return;
2233         }
2234
2235         if (j_ptr->sval == SV_CRIMSON)
2236         {
2237                 msg_print(_("この武器は発動して使うもののようだ。", "Do activate."));
2238                 flush();
2239                 return;
2240         }
2241
2242         if (j_ptr->sval == SV_HARP)
2243         {
2244                 msg_print(_("この武器で射撃はできない。", "It's not for firing."));
2245                 flush();
2246                 return;
2247         }
2248
2249
2250         if (p_ptr->special_defense & KATA_MUSOU)
2251         {
2252                 set_action(ACTION_NONE);
2253         }
2254
2255         /* Require proper missile */
2256         item_tester_tval = p_ptr->tval_ammo;
2257
2258         q = _("どれを撃ちますか? ", "Fire which item? ");
2259         s = _("発射されるアイテムがありません。", "You have nothing to fire.");
2260
2261
2262         ammo_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
2263         if (!ammo_ptr)
2264         {
2265                 flush();
2266                 return;
2267         }
2268
2269         /* Fire the item */
2270         exe_fire(item, j_ptr);
2271
2272         if (!is_fired || p_ptr->pclass != CLASS_SNIPER) return;
2273
2274         /* Sniper actions after some shootings */
2275         if (snipe_type == SP_AWAY)
2276         {
2277                 teleport_player(10 + (p_ptr->concent * 2), 0L);
2278         }
2279         if (snipe_type == SP_FINAL)
2280         {
2281                 msg_print(_("射撃の反動が体を襲った。", "A reactionary of shooting attacked you. "));
2282                 (void)set_slow(p_ptr->slow + randint0(7) + 7, FALSE);
2283                 (void)set_stun(p_ptr->stun + randint1(25));
2284         }
2285 }
2286
2287
2288 /*!
2289  * @brief 投射処理メインルーチン /
2290  * Throw an object from the pack or floor.
2291  * @param mult 威力の倍率
2292  * @param boomerang ブーメラン処理ならばTRUE
2293  * @param shuriken 忍者の手裏剣処理ならばTRUE
2294  * @return ターンを消費した場合TRUEを返す
2295  * @details
2296  * <pre>
2297  * Note: "unseen" monsters are very hard to hit.
2298  *
2299  * Should throwing a weapon do full damage?  Should it allow the magic
2300  * to hit bonus of the weapon to have an effect?  Should it ever cause
2301  * the item to be destroyed?  Should it do any damage at all?
2302  * </pre>
2303  */
2304 bool do_cmd_throw(int mult, bool boomerang, OBJECT_IDX shuriken)
2305 {
2306         DIRECTION dir;
2307         OBJECT_IDX item;
2308         int i;
2309         POSITION y, x, ty, tx, prev_y, prev_x;
2310         POSITION ny[19], nx[19];
2311         int chance, tdam, tdis;
2312         int mul, div, dd, ds;
2313         int cur_dis, visible;
2314         PERCENTAGE j;
2315
2316         object_type forge;
2317         object_type *q_ptr;
2318         object_type *o_ptr;
2319
2320         bool hit_body = FALSE;
2321         bool hit_wall = FALSE;
2322         bool equiped_item = FALSE;
2323         bool return_when_thrown = FALSE;
2324
2325         GAME_TEXT o_name[MAX_NLEN];
2326
2327         int msec = delay_factor * delay_factor * delay_factor;
2328
2329         BIT_FLAGS flgs[TR_FLAG_SIZE];
2330         concptr q, s;
2331         bool come_back = FALSE;
2332         bool do_drop = TRUE;
2333
2334         if (p_ptr->wild_mode) return FALSE;
2335
2336         if (p_ptr->special_defense & KATA_MUSOU)
2337         {
2338                 set_action(ACTION_NONE);
2339         }
2340
2341         if (shuriken >= 0)
2342         {
2343                 item = shuriken;
2344                 o_ptr = &inventory[item];
2345         }
2346         else if (boomerang)
2347         {
2348                 if (has_melee_weapon(INVEN_RARM) && has_melee_weapon(INVEN_LARM))
2349                 {
2350                         item_tester_hook = item_tester_hook_boomerang;
2351                         q = _("どの武器を投げますか? ", "Throw which item? ");
2352                         s = _("投げる武器がない。", "You have nothing to throw.");
2353                         o_ptr = choose_object(&item, q, s, (USE_EQUIP));
2354                         if (!o_ptr)
2355                         {
2356                                 flush();
2357                                 return FALSE;
2358                         }
2359                 }
2360                 else if (has_melee_weapon(INVEN_LARM))
2361                 {
2362                         item = INVEN_LARM;
2363                         o_ptr = &inventory[item];
2364                 }
2365                 else
2366                 {
2367                         item = INVEN_RARM;
2368                         o_ptr = &inventory[item];
2369                 }
2370         }
2371         else
2372         {
2373                 q = _("どのアイテムを投げますか? ", "Throw which item? ");
2374                 s = _("投げるアイテムがない。", "You have nothing to throw.");
2375                 o_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP));
2376                 if (!o_ptr)
2377                 {
2378                         flush();
2379                         return FALSE;
2380                 }
2381         }
2382
2383         /* Item is cursed */
2384         if (object_is_cursed(o_ptr) && (item >= INVEN_RARM))
2385         {
2386                 msg_print(_("ふーむ、どうやら呪われているようだ。", "Hmmm, it seems to be cursed."));
2387
2388                 return FALSE;
2389         }
2390
2391         if (p_ptr->inside_arena && !boomerang)
2392         {
2393                 if (o_ptr->tval != TV_SPIKE)
2394                 {
2395                         msg_print(_("アリーナではアイテムを使えない!", "You're in the arena now. This is hand-to-hand!"));
2396                         msg_print(NULL);
2397
2398                         return FALSE;
2399                 }
2400
2401         }
2402         q_ptr = &forge;
2403
2404         /* Obtain a local object */
2405         object_copy(q_ptr, o_ptr);
2406
2407         /* Extract the thrown object's flags. */
2408         object_flags(q_ptr, flgs);
2409         torch_flags(q_ptr, flgs);
2410
2411         /* Distribute the charges of rods/wands between the stacks */
2412         distribute_charges(o_ptr, q_ptr, 1);
2413
2414         /* Single object */
2415         q_ptr->number = 1;
2416
2417         object_desc(o_name, q_ptr, OD_OMIT_PREFIX);
2418
2419         if (p_ptr->mighty_throw) mult += 3;
2420
2421         /* Extract a "distance multiplier" */
2422         /* Changed for 'launcher' mutation */
2423         mul = 10 + 2 * (mult - 1);
2424
2425         /* Enforce a minimum "weight" of one pound */
2426         div = ((q_ptr->weight > 10) ? q_ptr->weight : 10);
2427         if ((have_flag(flgs, TR_THROW)) || boomerang) div /= 2;
2428
2429         /* Hack -- Distance -- Reward strength, penalize weight */
2430         tdis = (adj_str_blow[p_ptr->stat_ind[A_STR]] + 20) * mul / div;
2431
2432         /* Max distance of 10-18 */
2433         if (tdis > mul) tdis = mul;
2434
2435         if (shuriken >= 0)
2436         {
2437                 ty = randint0(101) - 50 + p_ptr->y;
2438                 tx = randint0(101) - 50 + p_ptr->x;
2439         }
2440         else
2441         {
2442                 project_length = tdis + 1;
2443
2444                 /* Get a direction (or cancel) */
2445                 if (!get_aim_dir(&dir)) return FALSE;
2446
2447                 /* Predict the "target" location */
2448                 tx = p_ptr->x + 99 * ddx[dir];
2449                 ty = p_ptr->y + 99 * ddy[dir];
2450
2451                 /* Check for "target request" */
2452                 if ((dir == 5) && target_okay())
2453                 {
2454                         tx = target_col;
2455                         ty = target_row;
2456                 }
2457
2458                 project_length = 0;  /* reset to default */
2459         }
2460
2461         if ((q_ptr->name1 == ART_MJOLLNIR) ||
2462             (q_ptr->name1 == ART_AEGISFANG) || boomerang)
2463                 return_when_thrown = TRUE;
2464
2465         /* Reduce and describe inventory */
2466         if (item >= 0)
2467         {
2468                 inven_item_increase(item, -1);
2469                 if (!return_when_thrown)
2470                         inven_item_describe(item);
2471                 inven_item_optimize(item);
2472         }
2473
2474         /* Reduce and describe floor item */
2475         else
2476         {
2477                 floor_item_increase(0 - item, -1);
2478                 floor_item_optimize(0 - item);
2479         }
2480         if (item >= INVEN_RARM)
2481         {
2482                 equiped_item = TRUE;
2483                 p_ptr->redraw |= (PR_EQUIPPY);
2484         }
2485
2486         p_ptr->energy_use = 100;
2487
2488         /* Rogue and Ninja gets bonus */
2489         if ((p_ptr->pclass == CLASS_ROGUE) || (p_ptr->pclass == CLASS_NINJA))
2490                 p_ptr->energy_use -= p_ptr->lev;
2491
2492         /* Start at the player */
2493         y = p_ptr->y;
2494         x = p_ptr->x;
2495
2496         handle_stuff();
2497
2498         if ((p_ptr->pclass == CLASS_NINJA) && ((q_ptr->tval == TV_SPIKE) || ((have_flag(flgs, TR_THROW)) && (q_ptr->tval == TV_SWORD)))) shuriken = TRUE;
2499         else shuriken = FALSE;
2500
2501         /* Chance of hitting */
2502         if (have_flag(flgs, TR_THROW)) chance = ((p_ptr->skill_tht) +
2503                 ((p_ptr->to_h_b + q_ptr->to_h) * BTH_PLUS_ADJ));
2504         else chance = (p_ptr->skill_tht + (p_ptr->to_h_b * BTH_PLUS_ADJ));
2505
2506         if (shuriken) chance *= 2;
2507
2508         prev_y = y;
2509         prev_x = x;
2510
2511         /* Travel until stopped */
2512         for (cur_dis = 0; cur_dis <= tdis; )
2513         {
2514                 /* Hack -- Stop at the target */
2515                 if ((y == ty) && (x == tx)) break;
2516
2517                 /* Calculate the new location (see "project()") */
2518                 ny[cur_dis] = y;
2519                 nx[cur_dis] = x;
2520                 mmove2(&ny[cur_dis], &nx[cur_dis], p_ptr->y, p_ptr->x, ty, tx);
2521
2522                 /* Stopped by walls/doors */
2523                 if (!cave_have_flag_bold(ny[cur_dis], nx[cur_dis], FF_PROJECT))
2524                 {
2525                         hit_wall = TRUE;
2526                         if ((q_ptr->tval == TV_FIGURINE) || object_is_potion(q_ptr) || !cave[ny[cur_dis]][nx[cur_dis]].m_idx) break;
2527                 }
2528
2529                 /* The player can see the (on screen) missile */
2530                 if (panel_contains(ny[cur_dis], nx[cur_dis]) && player_can_see_bold(ny[cur_dis], nx[cur_dis]))
2531                 {
2532                         SYMBOL_CODE c = object_char(q_ptr);
2533                         TERM_COLOR a = object_attr(q_ptr);
2534
2535                         /* Draw, Hilite, Fresh, Pause, Erase */
2536                         print_rel(c, a, ny[cur_dis], nx[cur_dis]);
2537                         move_cursor_relative(ny[cur_dis], nx[cur_dis]);
2538                         Term_fresh();
2539                         Term_xtra(TERM_XTRA_DELAY, msec);
2540                         lite_spot(ny[cur_dis], nx[cur_dis]);
2541                         Term_fresh();
2542                 }
2543
2544                 /* The player cannot see the missile */
2545                 else
2546                 {
2547                         /* Pause anyway, for consistancy */
2548                         Term_xtra(TERM_XTRA_DELAY, msec);
2549                 }
2550
2551                 prev_y = y;
2552                 prev_x = x;
2553
2554                 /* Save the new location */
2555                 x = nx[cur_dis];
2556                 y = ny[cur_dis];
2557
2558                 /* Advance the distance */
2559                 cur_dis++;
2560
2561                 /* Monster here, Try to hit it */
2562                 if (cave[y][x].m_idx)
2563                 {
2564                         cave_type *c_ptr = &cave[y][x];
2565                         monster_type *m_ptr = &m_list[c_ptr->m_idx];
2566
2567                         /* Check the visibility */
2568                         visible = m_ptr->ml;
2569
2570                         /* Note the collision */
2571                         hit_body = TRUE;
2572
2573                         /* Did we hit it (penalize range) */
2574                         if (test_hit_fire(chance - cur_dis, m_ptr, m_ptr->ml, o_name))
2575                         {
2576                                 bool fear = FALSE;
2577
2578                                 /* Handle unseen monster */
2579                                 if (!visible)
2580                                 {
2581                                         /* Invisible monster */
2582                                         msg_format(_("%sが敵を捕捉した。", "The %s finds a mark."), o_name);
2583                                 }
2584
2585                                 /* Handle visible monster */
2586                                 else
2587                                 {
2588                                         GAME_TEXT m_name[MAX_NLEN];
2589                                         monster_desc(m_name, m_ptr, 0);
2590                                         msg_format(_("%sが%sに命中した。", "The %s hits %s."), o_name, m_name);
2591
2592                                         if (m_ptr->ml)
2593                                         {
2594                                                 if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
2595                                                 health_track(c_ptr->m_idx);
2596                                         }
2597                                 }
2598
2599                                 /* Hack -- Base damage from thrown object */
2600                                 dd = q_ptr->dd;
2601                                 ds = q_ptr->ds;
2602                                 torch_dice(q_ptr, &dd, &ds); /* throwing a torch */
2603                                 tdam = damroll(dd, ds);
2604                                 /* Apply special damage */
2605                                 tdam = tot_dam_aux(q_ptr, tdam, m_ptr, 0, TRUE);
2606                                 tdam = critical_shot(q_ptr->weight, q_ptr->to_h, 0, tdam);
2607                                 if (q_ptr->to_d > 0)
2608                                         tdam += q_ptr->to_d;
2609                                 else
2610                                         tdam += -q_ptr->to_d;
2611
2612                                 if (boomerang)
2613                                 {
2614                                         tdam *= (mult+p_ptr->num_blow[item - INVEN_RARM]);
2615                                         tdam += p_ptr->to_d_m;
2616                                 }
2617                                 else if (have_flag(flgs, TR_THROW))
2618                                 {
2619                                         tdam *= (3+mult);
2620                                         tdam += p_ptr->to_d_m;
2621                                 }
2622                                 else
2623                                 {
2624                                         tdam *= mult;
2625                                 }
2626                                 if (shuriken)
2627                                 {
2628                                         tdam += ((p_ptr->lev+30)*(p_ptr->lev+30)-900)/55;
2629                                 }
2630
2631                                 /* No negative damage */
2632                                 if (tdam < 0) tdam = 0;
2633
2634                                 /* Modify the damage */
2635                                 tdam = mon_damage_mod(m_ptr, tdam, FALSE);
2636
2637                                 msg_format_wizard(CHEAT_MONSTER, _("%dのダメージを与えた。(残りHP %d/%d(%d))", "You do %d damage. (left HP %d/%d(%d))"),
2638                                         tdam, m_ptr->hp - tdam, m_ptr->maxhp, m_ptr->max_maxhp);
2639
2640                                 /* Hit the monster, check for death */
2641                                 if (mon_take_hit(c_ptr->m_idx, tdam, &fear, extract_note_dies(real_r_idx(m_ptr))))
2642                                 {
2643                                         /* Dead monster */
2644                                 }
2645
2646                                 /* No death */
2647                                 else
2648                                 {
2649                                         message_pain(c_ptr->m_idx, tdam);
2650
2651                                         /* Anger the monster */
2652                                         if ((tdam > 0) && !object_is_potion(q_ptr))
2653                                                 anger_monster(m_ptr);
2654
2655                                         if (fear && m_ptr->ml)
2656                                         {
2657                                                 sound(SOUND_FLEE);
2658                                                 GAME_TEXT m_name[MAX_NLEN];
2659                                                 monster_desc(m_name, m_ptr, 0);
2660                                                 msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), m_name);
2661                                         }
2662                                 }
2663                         }
2664
2665                         /* Stop looking */
2666                         break;
2667                 }
2668         }
2669
2670         /* decrease toach's fuel */
2671         if (hit_body) torch_lost_fuel(q_ptr);
2672
2673         /* Chance of breakage (during attacks) */
2674         j = (hit_body ? breakage_chance(q_ptr) : 0);
2675
2676         /* Figurines transform */
2677         if ((q_ptr->tval == TV_FIGURINE) && !(p_ptr->inside_arena))
2678         {
2679                 j = 100;
2680
2681                 if (!(summon_named_creature(0, y, x, q_ptr->pval, !(object_is_cursed(q_ptr)) ? PM_FORCE_PET : 0L)))
2682                         msg_print(_("人形は捻じ曲がり砕け散ってしまった!", "The Figurine writhes and then shatters."));
2683                 else if (object_is_cursed(q_ptr))
2684                         msg_print(_("これはあまり良くない気がする。", "You have a bad feeling about this."));
2685
2686         }
2687
2688
2689         /* Potions smash open */
2690         if (object_is_potion(q_ptr))
2691         {
2692                 if (hit_body || hit_wall || (randint1(100) < j))
2693                 {
2694                         msg_format(_("%sは砕け散った!", "The %s shatters!"), o_name);
2695
2696                         if (potion_smash_effect(0, y, x, q_ptr->k_idx))
2697                         {
2698                                 monster_type *m_ptr = &m_list[cave[y][x].m_idx];
2699
2700                                 /* ToDo (Robert): fix the invulnerability */
2701                                 if (cave[y][x].m_idx &&
2702                                     is_friendly(&m_list[cave[y][x].m_idx]) &&
2703                                     !MON_INVULNER(m_ptr))
2704                                 {
2705                                         GAME_TEXT m_name[MAX_NLEN];
2706                                         monster_desc(m_name, &m_list[cave[y][x].m_idx], 0);
2707                                         msg_format(_("%sは怒った!", "%^s gets angry!"), m_name);
2708                                         set_hostile(&m_list[cave[y][x].m_idx]);
2709                                 }
2710                         }
2711                         do_drop = FALSE;
2712                 }
2713                 else
2714                 {
2715                         j = 0;
2716                 }
2717         }
2718
2719         if (return_when_thrown)
2720         {
2721                 int back_chance = randint1(30)+20+((int)(adj_dex_th[p_ptr->stat_ind[A_DEX]]) - 128);
2722                 char o2_name[MAX_NLEN];
2723                 bool super_boomerang = (((q_ptr->name1 == ART_MJOLLNIR) || (q_ptr->name1 == ART_AEGISFANG)) && boomerang);
2724
2725                 j = -1;
2726                 if (boomerang) back_chance += 4+randint1(5);
2727                 if (super_boomerang) back_chance += 100;
2728                 object_desc(o2_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
2729
2730                 if((back_chance > 30) && (!one_in_(100) || super_boomerang))
2731                 {
2732                         for (i = cur_dis - 1; i > 0; i--)
2733                         {
2734                                 if (panel_contains(ny[i], nx[i]) && player_can_see_bold(ny[i], nx[i]))
2735                                 {
2736                                         char c = object_char(q_ptr);
2737                                         byte a = object_attr(q_ptr);
2738
2739                                         /* Draw, Hilite, Fresh, Pause, Erase */
2740                                         print_rel(c, a, ny[i], nx[i]);
2741                                         move_cursor_relative(ny[i], nx[i]);
2742                                         Term_fresh();
2743                                         Term_xtra(TERM_XTRA_DELAY, msec);
2744                                         lite_spot(ny[i], nx[i]);
2745                                         Term_fresh();
2746                                 }
2747                                 else
2748                                 {
2749                                         /* Pause anyway, for consistancy */
2750                                         Term_xtra(TERM_XTRA_DELAY, msec);
2751                                 }
2752                         }
2753                         if((back_chance > 37) && !p_ptr->blind && (item >= 0))
2754                         {
2755                                 msg_format(_("%sが手元に返ってきた。", "%s comes back to you."), o2_name);
2756                                 come_back = TRUE;
2757                         }
2758                         else
2759                         {
2760                                 if (item >= 0)
2761                                 {
2762                                         msg_format(_("%sを受け損ねた!", "%s backs, but you can't catch!"), o2_name);
2763                                 }
2764                                 else
2765                                 {
2766                                         msg_format(_("%sが返ってきた。", "%s comes back."), o2_name);
2767                                 }
2768                                 y = p_ptr->y;
2769                                 x = p_ptr->x;
2770                         }
2771                 }
2772                 else
2773                 {
2774                         msg_format(_("%sが返ってこなかった!", "%s doesn't back!"), o2_name);
2775                 }
2776         }
2777
2778         if (come_back)
2779         {
2780                 if (item == INVEN_RARM || item == INVEN_LARM)
2781                 {
2782                         /* Access the wield slot */
2783                         o_ptr = &inventory[item];
2784
2785                         /* Wear the new stuff */
2786                         object_copy(o_ptr, q_ptr);
2787
2788                         p_ptr->total_weight += q_ptr->weight;
2789
2790                         /* Increment the equip counter by hand */
2791                         equip_cnt++;
2792
2793                         /* Recalculate torch */
2794                         p_ptr->update |= (PU_BONUS | PU_TORCH | PU_MANA);
2795                         p_ptr->window |= (PW_EQUIP);
2796                 }
2797                 else
2798                 {
2799                         inven_carry(q_ptr);
2800                 }
2801                 do_drop = FALSE;
2802         }
2803         else if (equiped_item)
2804         {
2805                 kamaenaoshi(item);
2806                 calc_android_exp();
2807         }
2808
2809         if (do_drop)
2810         {
2811                 if (cave_have_flag_bold(y, x, FF_PROJECT))
2812                 {
2813                         (void)drop_near(q_ptr, j, y, x);
2814                 }
2815                 else
2816                 {
2817                         (void)drop_near(q_ptr, j, prev_y, prev_x);
2818                 }
2819         }
2820
2821         return TRUE;
2822 }
2823
2824
2825 #ifdef TRAVEL
2826 /*
2827  * Hack: travel command
2828  */
2829 #define TRAVEL_UNABLE 9999
2830
2831 static int flow_head = 0;
2832 static int flow_tail = 0;
2833 static POSITION temp2_x[MAX_SHORT];
2834 static POSITION temp2_y[MAX_SHORT];
2835
2836 /*!
2837  * @brief トラベル処理の記憶配列を初期化する Hack: forget the "flow" information 
2838  * @return なし
2839  */
2840 void forget_travel_flow(void)
2841 {
2842         POSITION x, y;
2843         /* Check the entire dungeon / Forget the old data */
2844         for (y = 0; y < cur_hgt; y++)
2845         {
2846                 for (x = 0; x < cur_wid; x++)
2847                 {
2848                         
2849                         travel.cost[y][x] = MAX_SHORT;
2850                 }
2851         }
2852         travel.y = travel.x = 0;
2853 }
2854
2855 /*!
2856  * @brief トラベル処理中に地形に応じた移動コスト基準を返す
2857  * @param y 該当地点のY座標
2858  * @param x 該当地点のX座標
2859  * @return コスト値
2860  */
2861 static int travel_flow_cost(POSITION y, POSITION x)
2862 {
2863         feature_type *f_ptr = &f_info[cave[y][x].feat];
2864         int cost = 1;
2865
2866         /* Avoid obstacles (ex. trees) */
2867         if (have_flag(f_ptr->flags, FF_AVOID_RUN)) cost += 1;
2868
2869         /* Water */
2870         if (have_flag(f_ptr->flags, FF_WATER))
2871         {
2872                 if (have_flag(f_ptr->flags, FF_DEEP) && !p_ptr->levitation) cost += 5;
2873         }
2874
2875         /* Lava */
2876         if (have_flag(f_ptr->flags, FF_LAVA))
2877         {
2878                 int lava = 2;
2879                 if (!p_ptr->resist_fire) lava *= 2;
2880                 if (!p_ptr->levitation) lava *= 2;
2881                 if (have_flag(f_ptr->flags, FF_DEEP)) lava *= 2;
2882
2883                 cost += lava;
2884         }
2885
2886         /* Detected traps and doors */
2887         if (cave[y][x].info & (CAVE_MARK))
2888         {
2889                 if (have_flag(f_ptr->flags, FF_DOOR)) cost += 1;
2890                 if (have_flag(f_ptr->flags, FF_TRAP)) cost += 10;
2891         }
2892
2893         return (cost);
2894 }
2895
2896 /*!
2897  * @brief トラベル処理の到達地点までの行程を得る処理のサブルーチン
2898  * @param y 目標地点のY座標
2899  * @param x 目標地点のX座標
2900  * @param n 現在のコスト
2901  * @param wall プレイヤーが壁の中にいるならばTRUE
2902  * @return なし
2903  */
2904 static void travel_flow_aux(POSITION y, POSITION x, int n, bool wall)
2905 {
2906         cave_type *c_ptr = &cave[y][x];
2907         feature_type *f_ptr = &f_info[c_ptr->feat];
2908         int old_head = flow_head;
2909         int add_cost = 1;
2910         int base_cost = (n % TRAVEL_UNABLE);
2911         int from_wall = (n / TRAVEL_UNABLE);
2912         int cost;
2913
2914         /* Ignore out of bounds */
2915         if (!in_bounds(y, x)) return;
2916
2917         /* Ignore unknown grid except in wilderness */
2918         if (dun_level > 0 && !(c_ptr->info & CAVE_KNOWN)) return;
2919
2920         /* Ignore "walls" and "rubble" (include "secret doors") */
2921         if (have_flag(f_ptr->flags, FF_WALL) ||
2922                 have_flag(f_ptr->flags, FF_CAN_DIG) ||
2923                 (have_flag(f_ptr->flags, FF_DOOR) && cave[y][x].mimic) ||
2924                 (!have_flag(f_ptr->flags, FF_MOVE) && have_flag(f_ptr->flags, FF_CAN_FLY) && !p_ptr->levitation))
2925         {
2926                 if (!wall || !from_wall) return;
2927                 add_cost += TRAVEL_UNABLE;
2928         }
2929         else
2930         {
2931                 add_cost = travel_flow_cost(y, x);
2932         }
2933
2934         cost = base_cost + add_cost;
2935
2936         /* Ignore lower cost entries */
2937         if (travel.cost[y][x] <= cost) return;
2938
2939         /* Save the flow cost */
2940         travel.cost[y][x] = cost;
2941
2942         /* Enqueue that entry */
2943         temp2_y[flow_head] = y;
2944         temp2_x[flow_head] = x;
2945
2946         /* Advance the queue */
2947         if (++flow_head == MAX_SHORT) flow_head = 0;
2948
2949         /* Hack -- notice overflow by forgetting new entry */
2950         if (flow_head == flow_tail) flow_head = old_head;
2951
2952         return;
2953 }
2954
2955 /*!
2956  * @brief トラベル処理の到達地点までの行程を得る処理のメインルーチン
2957  * @param ty 目標地点のY座標
2958  * @param tx 目標地点のX座標
2959  * @return なし
2960  */
2961 static void travel_flow(POSITION ty, POSITION tx)
2962 {
2963         POSITION x, y, d;
2964         bool wall = FALSE;
2965         feature_type *f_ptr = &f_info[cave[p_ptr->y][p_ptr->x].feat];
2966
2967         /* Reset the "queue" */
2968         flow_head = flow_tail = 0;
2969
2970         /* is player in the wall? */
2971         if (!have_flag(f_ptr->flags, FF_MOVE)) wall = TRUE;
2972
2973         /* Start at the target grid */
2974         travel_flow_aux(ty, tx, 0, wall);
2975
2976         /* Now process the queue */
2977         while (flow_head != flow_tail)
2978         {
2979                 /* Extract the next entry */
2980                 y = temp2_y[flow_tail];
2981                 x = temp2_x[flow_tail];
2982
2983                 /* Forget that entry */
2984                 if (++flow_tail == MAX_SHORT) flow_tail = 0;
2985
2986                 /* Ignore too far entries */
2987                 //if (distance(ty, tx, y, x) > 100) continue;
2988
2989                 /* Add the "children" */
2990                 for (d = 0; d < 8; d++)
2991                 {
2992                         /* Add that child if "legal" */
2993                         travel_flow_aux(y + ddy_ddd[d], x + ddx_ddd[d], travel.cost[y][x], wall);
2994                 }
2995         }
2996
2997         /* Forget the flow info */
2998         flow_head = flow_tail = 0;
2999 }
3000
3001 /*!
3002  * @brief トラベル処理のメインルーチン
3003  * @return なし
3004  */
3005 void do_cmd_travel(void)
3006 {
3007         POSITION x, y;
3008         int i;
3009         POSITION dx, dy, sx, sy;
3010         feature_type *f_ptr;
3011
3012         if (travel.x != 0 && travel.y != 0 &&
3013             get_check(_("トラベルを継続しますか?", "Do you continue to travel?")))
3014         {
3015                 y = travel.y;
3016                 x = travel.x;
3017         }
3018         else if (!tgt_pt(&x, &y)) return;
3019
3020         if ((x == p_ptr->x) && (y == p_ptr->y))
3021         {
3022                 msg_print(_("すでにそこにいます!", "You are already there!!"));
3023                 return;
3024         }
3025
3026         f_ptr = &f_info[cave[y][x].feat];
3027
3028         if ((cave[y][x].info & CAVE_MARK) &&
3029                 (have_flag(f_ptr->flags, FF_WALL) ||
3030                         have_flag(f_ptr->flags, FF_CAN_DIG) ||
3031                         (have_flag(f_ptr->flags, FF_DOOR) && cave[y][x].mimic)))
3032         {
3033                 msg_print(_("そこには行くことができません!", "You cannot travel there!"));
3034                 return;
3035         }
3036
3037         forget_travel_flow();
3038         travel_flow(y, x);
3039
3040         travel.x = x;
3041         travel.y = y;
3042
3043         /* Travel till 255 steps */
3044         travel.run = 255;
3045
3046         /* Paranoia */
3047         travel.dir = 0;
3048
3049         /* Decides first direction */
3050         dx = abs(p_ptr->x - x);
3051         dy = abs(p_ptr->y - y);
3052         sx = ((x == p_ptr->x) || (dx < dy)) ? 0 : ((x > p_ptr->x) ? 1 : -1);
3053         sy = ((y == p_ptr->y) || (dy < dx)) ? 0 : ((y > p_ptr->y) ? 1 : -1);
3054
3055         for (i = 1; i <= 9; i++)
3056         {
3057                 if ((sx == ddx[i]) && (sy == ddy[i])) travel.dir = i;
3058         }
3059 }
3060 #endif