OSDN Git Service

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