OSDN Git Service

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