OSDN Git Service

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