OSDN Git Service

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