3 * @brief プレイヤーのコマンド処理2 / Movement commands (part 2)
6 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
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.
17 #include "object-hook.h"
18 #include "projection.h"
21 * @brief フロア脱出時に出戻りが不可能だった場合に警告を加える処理
22 * @param down_stair TRUEならば階段を降りる処理、FALSEなら階段を昇る処理による内容
23 * @return フロア移動を実際に行うならTRUE、キャンセルする場合はFALSE
25 bool confirm_leave_level(bool down_stair)
27 quest_type *q_ptr = &quest[p_ptr->inside_quest];
29 /* Confirm leaving from once only quest */
30 if (confirm_quest && p_ptr->inside_quest &&
31 (q_ptr->type == QUEST_TYPE_RANDOM ||
32 (q_ptr->flags & QUEST_FLAG_ONCE &&
33 q_ptr->status != QUEST_STATUS_COMPLETED) ||
34 (q_ptr->flags & QUEST_FLAG_TOWER &&
35 ((q_ptr->status != QUEST_STATUS_STAGE_COMPLETED) ||
36 (down_stair && (quest[QUEST_TOWER1].status != QUEST_STATUS_COMPLETED))))))
38 msg_print(_("この階を一度去ると二度と戻って来られません。", "You can't come back here once you leave this floor."));
39 if (get_check(_("本当にこの階を去りますか?", "Really leave this floor? "))) return TRUE;
49 * @brief 階段を使って階層を昇る処理 / Go up one level
52 void do_cmd_go_up(void)
57 cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x];
58 feature_type *f_ptr = &f_info[c_ptr->feat];
62 if (p_ptr->special_defense & KATA_MUSOU)
64 set_action(ACTION_NONE);
68 if (!have_flag(f_ptr->flags, FF_LESS))
70 msg_print(_("ここには上り階段が見当たらない。", "I see no up staircase here."));
75 if (have_flag(f_ptr->flags, FF_QUEST))
77 /* Cancel the command */
78 if (!confirm_leave_level(FALSE)) return;
82 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
83 msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
85 msg_print(_("上の階に登った。", "You enter the up staircase."));
89 p_ptr->inside_quest = c_ptr->special;
91 /* Activate the quest */
92 if (!quest[p_ptr->inside_quest].status)
94 if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
96 init_flags = INIT_ASSIGN;
97 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
99 quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
102 /* Leaving a quest */
103 if (!p_ptr->inside_quest)
109 p_ptr->leaving = TRUE;
114 /* Hack -- take a turn */
115 p_ptr->energy_use = 100;
117 /* End the command */
127 go_up = confirm_leave_level(FALSE);
130 /* Cancel the command */
133 /* Hack -- take a turn */
134 p_ptr->energy_use = 100;
136 if (autosave_l) do_cmd_save_game(TRUE);
138 /* For a random quest */
139 if (p_ptr->inside_quest &&
140 quest[p_ptr->inside_quest].type == QUEST_TYPE_RANDOM)
144 p_ptr->inside_quest = 0;
147 /* For a fixed quest */
148 if (p_ptr->inside_quest &&
149 quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
153 p_ptr->inside_quest = c_ptr->special;
158 /* For normal dungeon and random quest */
162 if (have_flag(f_ptr->flags, FF_SHAFT))
164 /* Create a way back */
165 prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP | CFM_SHAFT);
171 /* Create a way back */
172 prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP);
177 /* Get out from current dungeon */
178 if (dun_level - up_num < d_info[dungeon_type].mindepth)
181 if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, _("階段を上った", "climbed up the stairs to"));
184 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
185 msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
186 else if (up_num == dun_level)
187 msg_print(_("地上に戻った。", "You go back to the surface."));
189 msg_print(_("階段を上って新たなる迷宮へと足を踏み入れた。", "You enter a maze of up staircases."));
192 p_ptr->leaving = TRUE;
197 * @brief 階段を使って階層を降りる処理 / Go down one level
200 void do_cmd_go_down(void)
203 cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x];
204 feature_type *f_ptr = &f_info[c_ptr->feat];
206 bool fall_trap = FALSE;
209 if (p_ptr->special_defense & KATA_MUSOU)
211 set_action(ACTION_NONE);
215 if (!have_flag(f_ptr->flags, FF_MORE))
217 msg_print(_("ここには下り階段が見当たらない。", "I see no down staircase here."));
221 if (have_flag(f_ptr->flags, FF_TRAP)) fall_trap = TRUE;
224 if (have_flag(f_ptr->flags, FF_QUEST_ENTER))
229 /* Quest down stairs */
230 else if (have_flag(f_ptr->flags, FF_QUEST))
232 /* Confirm Leaving */
233 if(!confirm_leave_level(TRUE)) return;
235 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
236 msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
238 msg_print(_("下の階に降りた。", "You enter the down staircase."));
243 p_ptr->inside_quest = c_ptr->special;
245 /* Activate the quest */
246 if (!quest[p_ptr->inside_quest].status)
248 if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM)
250 init_flags = INIT_ASSIGN;
251 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
253 quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
256 /* Leaving a quest */
257 if (!p_ptr->inside_quest)
263 p_ptr->leaving = TRUE;
269 /* Hack -- take a turn */
270 p_ptr->energy_use = 100;
275 int target_dungeon = 0;
279 target_dungeon = have_flag(f_ptr->flags, FF_ENTRANCE) ? c_ptr->special : DUNGEON_ANGBAND;
281 if (ironman_downward && (target_dungeon != DUNGEON_ANGBAND))
283 msg_print(_("ダンジョンの入口は塞がれている!", "The entrance of this dungeon is closed!"));
286 if (!max_dlv[target_dungeon])
288 msg_format(_("ここには%sの入り口(%d階相当)があります", "There is the entrance of %s (Danger level: %d)"),
289 d_name+d_info[target_dungeon].name, d_info[target_dungeon].mindepth);
290 if (!get_check(_("本当にこのダンジョンに入りますか?", "Do you really get in this dungeon? "))) return;
293 /* Save old player position */
294 p_ptr->oldpx = p_ptr->x;
295 p_ptr->oldpy = p_ptr->y;
296 dungeon_type = (byte)target_dungeon;
299 * Clear all saved floors
300 * and create a first saved floor
302 prepare_change_floor_mode(CFM_FIRST_FLOOR);
305 /* Hack -- take a turn */
306 p_ptr->energy_use = 100;
308 if (autosave_l) do_cmd_save_game(TRUE);
311 if (have_flag(f_ptr->flags, FF_SHAFT)) down_num += 2;
316 /* Enter the dungeon just now */
317 p_ptr->enter_dungeon = TRUE;
318 down_num = d_info[dungeon_type].mindepth;
323 if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, _("落とし戸に落ちた", "fell through a trap door"));
324 else do_cmd_write_nikki(NIKKI_STAIR, down_num, _("階段を下りた", "climbed down the stairs to"));
329 msg_print(_("わざと落とし戸に落ちた。", "You deliberately jump through the trap door."));
336 msg_format(_("%sへ入った。", "You entered %s."), d_text + d_info[dungeon_type].text);
340 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
341 msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
343 msg_print(_("階段を下りて新たなる迷宮へと足を踏み入れた。", "You enter a maze of down staircases."));
349 p_ptr->leaving = TRUE;
353 prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
357 if (have_flag(f_ptr->flags, FF_SHAFT))
359 /* Create a way back */
360 prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_SHAFT);
364 /* Create a way back */
365 prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN);
373 * @brief 探索コマンドのメインルーチン / Simple command to "search" for one turn
376 void do_cmd_search(void)
378 /* Allow repeated command */
381 /* Set repeat count */
382 command_rep = command_arg - 1;
383 p_ptr->redraw |= (PR_STATE);
388 p_ptr->energy_use = 100;
396 * @brief 該当のマスに存在している箱のオブジェクトIDを返す。
397 * @param y 走査対象にしたいマスのY座標
398 * @param x 走査対象にしたいマスのX座標
399 * @param trapped TRUEならばトラップが存在する箱のみ、FALSEならば空でない箱全てを対象にする
400 * @return 箱が存在する場合そのオブジェクトID、存在しない場合0を返す。
402 static OBJECT_IDX chest_check(POSITION y, POSITION x, bool trapped)
404 cave_type *c_ptr = &cave[y][x];
405 OBJECT_IDX this_o_idx, next_o_idx = 0;
407 /* Scan all objects in the grid */
408 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
412 o_ptr = &o_list[this_o_idx];
413 next_o_idx = o_ptr->next_o_idx;
415 /* Skip unknown chests XXX XXX */
416 /* if (!(o_ptr->marked & OM_FOUND)) continue; */
418 /* Check for non empty chest */
419 if ((o_ptr->tval == TV_CHEST) &&
420 (((!trapped) && (o_ptr->pval)) || /* non empty */
421 ((trapped) && (o_ptr->pval > 0)))) /* trapped only */
430 * @brief 箱を開けるコマンドのメインルーチン /
431 * Attempt to open the given chest at the given location
432 * @param y 箱の存在するマスのY座標
433 * @param x 箱の存在するマスのX座標
434 * @param o_idx 箱のオブジェクトID
435 * @return 箱が開かなかった場合TRUE / Returns TRUE if repeated commands may continue
437 * Assume there is no monster blocking the destination
439 static bool do_cmd_open_chest(POSITION y, POSITION x, OBJECT_IDX o_idx)
444 object_type *o_ptr = &o_list[o_idx];
446 p_ptr->energy_use = 100;
448 /* Attempt to unlock it */
451 /* Assume locked, and thus not open */
454 /* Get the "disarm" factor */
455 i = p_ptr->skill_dis;
457 /* Penalize some conditions */
458 if (p_ptr->blind || no_lite()) i = i / 10;
459 if (p_ptr->confused || p_ptr->image) i = i / 10;
461 /* Extract the difficulty */
464 /* Always have a small chance of success */
467 /* Success -- May still have traps */
468 if (randint0(100) < j)
470 msg_print(_("鍵をはずした。", "You have picked the lock."));
475 /* Failure -- Keep trying */
478 /* We may continue repeating */
480 if (flush_failure) flush();
481 msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
486 /* Allowed to open */
489 /* Apply chest traps, if any */
490 chest_trap(y, x, o_idx);
492 /* Let the Chest drop items */
493 chest_death(FALSE, y, x, o_idx);
499 * @brief 地形は開くものであって、かつ開かれているかを返す /
500 * Attempt to open the given chest at the given location
502 * @return 開いた地形である場合TRUEを返す / Return TRUE if the given feature is an open door
504 static bool is_open(IDX feat)
506 return have_flag(f_info[feat].flags, FF_CLOSE) && (feat != feat_state(feat, FF_CLOSE));
511 * @brief プレイヤーの周辺9マスに該当する地形がいくつあるかを返す /
512 * Attempt to open the given chest at the given location
513 * @param y 該当する地形の中から1つのY座標を返す参照ポインタ
514 * @param x 該当する地形の中から1つのX座標を返す参照ポインタ
515 * @param test 地形条件を判定するための関数ポインタ
516 * @param under TRUEならばプレイヤーの直下の座標も走査対象にする
518 * @details Return the number of features around (or under) the character.
519 * Usually look for doors and floor traps.
521 static int count_dt(POSITION *y, POSITION *x, bool (*test)(IDX feat), bool under)
523 int d, count, xx, yy;
525 /* Count how many matches */
528 /* Check around (and under) the character */
529 for (d = 0; d < 9; d++)
534 /* if not searching under player continue */
535 if ((d == 8) && !under) continue;
537 /* Extract adjacent (legal) location */
538 yy = p_ptr->y + ddy_ddd[d];
539 xx = p_ptr->x + ddx_ddd[d];
542 c_ptr = &cave[yy][xx];
544 /* Must have knowledge */
545 if (!(c_ptr->info & (CAVE_MARK))) continue;
547 /* Feature code (applying "mimic" field) */
548 feat = get_feat_mimic(c_ptr);
550 /* Not looking for this feature */
551 if (!((*test)(feat))) continue;
556 /* Remember the location. Only useful if only one match */
567 * @brief プレイヤーの周辺9マスに箱のあるマスがいくつあるかを返す /
568 * Return the number of chests around (or under) the character.
569 * @param y 該当するマスの中から1つのY座標を返す参照ポインタ
570 * @param x 該当するマスの中から1つのX座標を返す参照ポインタ
571 * @param trapped TRUEならばトラップの存在が判明している箱のみ対象にする
574 * If requested, count only trapped chests.
576 static int count_chests(POSITION *y, POSITION *x, bool trapped)
583 /* Count how many matches */
586 /* Check around (and under) the character */
587 for (d = 0; d < 9; d++)
589 /* Extract adjacent (legal) location */
590 POSITION yy = p_ptr->y + ddy_ddd[d];
591 POSITION xx = p_ptr->x + ddx_ddd[d];
593 /* No (visible) chest is there */
594 if ((o_idx = chest_check(yy, xx, FALSE)) == 0) continue;
596 /* Grab the object */
597 o_ptr = &o_list[o_idx];
600 if (o_ptr->pval == 0) continue;
602 /* No (known) traps here */
603 if (trapped && (!object_is_known(o_ptr) ||
604 !chest_traps[o_ptr->pval])) continue;
609 /* Remember the location. Only useful if only one match */
620 * @brief プレイヤーから指定の座標がどの方角にあるかを返す /
621 * Convert an adjacent location to a direction.
622 * @param y 方角を確認したY座標
623 * @param x 方角を確認したX座標
626 static DIRECTION coords_to_dir(POSITION y, POSITION x)
628 int d[3][3] = { {7, 4, 1}, {8, 5, 2}, {9, 6, 3} };
635 if (ABS(dx) > 1 || ABS(dy) > 1) return (0);
637 return d[dx + 1][dy + 1];
641 * @brief 「開ける」動作コマンドのサブルーチン /
642 * Perform the basic "open" command on doors
643 * @param y 対象を行うマスのY座標
644 * @param x 対象を行うマスのX座標
645 * @return 実際に処理が行われた場合TRUEを返す。
647 * Assume destination is a closed/locked/jammed door
648 * Assume there is no monster blocking the destination
649 * Returns TRUE if repeated commands may continue
651 static bool do_cmd_open_aux(POSITION y, POSITION x)
655 /* Get requested grid */
656 cave_type *c_ptr = &cave[y][x];
657 feature_type *f_ptr = &f_info[c_ptr->feat];
660 p_ptr->energy_use = 100;
662 /* Seeing true feature code (ignore mimic) */
665 if (!have_flag(f_ptr->flags, FF_OPEN))
668 msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_name + f_info[get_feat_mimic(c_ptr)].name);
672 else if (f_ptr->power)
675 i = p_ptr->skill_dis;
677 /* Penalize some conditions */
678 if (p_ptr->blind || no_lite()) i = i / 10;
679 if (p_ptr->confused || p_ptr->image) i = i / 10;
681 /* Extract the lock power */
684 /* Extract the difficulty */
687 /* Always have a small chance of success */
691 if (randint0(100) < j)
693 msg_print(_("鍵をはずした。", "You have picked the lock."));
696 cave_alter_feat(y, x, FF_OPEN);
698 sound(SOUND_OPENDOOR);
708 if (flush_failure) flush();
710 msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
712 /* We may keep trying */
721 cave_alter_feat(y, x, FF_OPEN);
723 sound(SOUND_OPENDOOR);
729 * @brief 「開ける」コマンドのメインルーチン /
730 * Open a closed/locked/jammed door or a closed/locked chest.
733 * Unlocking a locked door/chest is worth one experience point.
735 void do_cmd_open(void)
743 if (p_ptr->wild_mode) return;
745 if (p_ptr->special_defense & KATA_MUSOU)
747 set_action(ACTION_NONE);
750 /* Option: Pick a direction */
753 int num_doors, num_chests;
755 /* Count closed doors (locked or jammed) */
756 num_doors = count_dt(&y, &x, is_closed_door, FALSE);
758 /* Count chests (locked) */
759 num_chests = count_chests(&y, &x, FALSE);
761 /* See if only one target */
762 if (num_doors || num_chests)
764 bool too_many = (num_doors && num_chests) || (num_doors > 1) ||
766 if (!too_many) command_dir = coords_to_dir(y, x);
770 /* Allow repeated command */
773 /* Set repeat count */
774 command_rep = command_arg - 1;
775 p_ptr->redraw |= (PR_STATE);
781 /* Get a "repeated" direction */
782 if (get_rep_dir(&dir, TRUE))
787 /* Get requested location */
788 y = p_ptr->y + ddy[dir];
789 x = p_ptr->x + ddx[dir];
791 /* Get requested grid */
794 /* Feature code (applying "mimic" field) */
795 feat = get_feat_mimic(c_ptr);
797 /* Check for chest */
798 o_idx = chest_check(y, x, FALSE);
801 if (!have_flag(f_info[feat].flags, FF_OPEN) && !o_idx)
803 msg_print(_("そこには開けるものが見当たらない。", "You see nothing there to open."));
806 /* Monster in the way */
807 else if (c_ptr->m_idx && p_ptr->riding != c_ptr->m_idx)
809 p_ptr->energy_use = 100;
810 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
818 more = do_cmd_open_chest(y, x, o_idx);
825 more = do_cmd_open_aux(y, x);
829 /* Cancel repeat unless we may continue */
830 if (!more) disturb(FALSE, FALSE);
836 * @brief 「閉じる」動作コマンドのサブルーチン /
837 * Perform the basic "close" command
838 * @param y 対象を行うマスのY座標
839 * @param x 対象を行うマスのX座標
840 * @return 実際に処理が行われた場合TRUEを返す。
842 * Assume destination is an open/broken door
843 * Assume there is no monster blocking the destination
844 * Returns TRUE if repeated commands may continue
846 static bool do_cmd_close_aux(POSITION y, POSITION x)
848 cave_type *c_ptr = &cave[y][x];
849 FEAT_IDX old_feat = c_ptr->feat;
852 p_ptr->energy_use = 100;
854 /* Seeing true feature code (ignore mimic) */
857 if (have_flag(f_info[old_feat].flags, FF_CLOSE))
859 s16b closed_feat = feat_state(old_feat, FF_CLOSE);
861 /* Hack -- object in the way */
862 if ((c_ptr->o_idx || (c_ptr->info & CAVE_OBJECT)) &&
863 (closed_feat != old_feat) && !have_flag(f_info[closed_feat].flags, FF_DROP))
865 msg_print(_("何かがつっかえて閉まらない。", "There seems stuck."));
870 cave_alter_feat(y, x, FF_CLOSE);
873 if (old_feat == c_ptr->feat)
875 msg_print(_("ドアは壊れてしまっている。", "The door appears to be broken."));
879 sound(SOUND_SHUTDOOR);
888 * @brief 「閉じる」コマンドのメインルーチン /
889 * Close an open door.
892 * Unlocking a locked door/chest is worth one experience point.
894 void do_cmd_close(void)
901 if (p_ptr->wild_mode) return;
903 if (p_ptr->special_defense & KATA_MUSOU)
905 set_action(ACTION_NONE);
908 /* Option: Pick a direction */
911 /* Count open doors */
912 if (count_dt(&y, &x, is_open, FALSE) == 1)
914 command_dir = coords_to_dir(y, x);
918 /* Allow repeated command */
921 /* Set repeat count */
922 command_rep = command_arg - 1;
923 p_ptr->redraw |= (PR_STATE);
929 /* Get a "repeated" direction */
930 if (get_rep_dir(&dir, FALSE))
935 y = p_ptr->y + ddy[dir];
936 x = p_ptr->x + ddx[dir];
939 /* Feature code (applying "mimic" field) */
940 feat = get_feat_mimic(c_ptr);
942 /* Require open/broken door */
943 if (!have_flag(f_info[feat].flags, FF_CLOSE))
945 msg_print(_("そこには閉じるものが見当たらない。", "You see nothing there to close."));
948 /* Monster in the way */
949 else if (c_ptr->m_idx)
951 p_ptr->energy_use = 100;
953 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
963 more = do_cmd_close_aux(y, x);
967 /* Cancel repeat unless we may continue */
968 if (!more) disturb(FALSE, FALSE);
973 * @brief 「掘る」コマンドを該当のマスに行えるかの判定と結果メッセージの表示 /
974 * Determine if a given grid may be "tunneled"
975 * @param y 対象を行うマスのY座標
976 * @param x 対象を行うマスのX座標
979 static bool do_cmd_tunnel_test(POSITION y, POSITION x)
981 cave_type *c_ptr = &cave[y][x];
983 /* Must have knowledge */
984 if (!(c_ptr->info & CAVE_MARK))
986 msg_print(_("そこには何も見当たらない。", "You see nothing there."));
991 /* Must be a wall/door/etc */
992 if (!cave_have_flag_grid(c_ptr, FF_TUNNEL))
994 msg_print(_("そこには掘るものが見当たらない。", "You see nothing there to tunnel."));
1004 * @brief 「掘る」動作コマンドのサブルーチン /
1005 * Perform the basic "tunnel" command
1006 * @param y 対象を行うマスのY座標
1007 * @param x 対象を行うマスのX座標
1008 * @return 実際に処理が行われた場合TRUEを返す。
1010 * Assumes that no monster is blocking the destination
1011 * Do not use twall anymore
1012 * Returns TRUE if repeated commands may continue
1014 static bool do_cmd_tunnel_aux(POSITION y, POSITION x)
1017 feature_type *f_ptr, *mimic_f_ptr;
1022 /* Verify legality */
1023 if (!do_cmd_tunnel_test(y, x)) return (FALSE);
1025 p_ptr->energy_use = 100;
1028 c_ptr = &cave[y][x];
1029 f_ptr = &f_info[c_ptr->feat];
1030 power = f_ptr->power;
1032 /* Feature code (applying "mimic" field) */
1033 mimic_f_ptr = &f_info[get_feat_mimic(c_ptr)];
1035 name = f_name + mimic_f_ptr->name;
1039 if (have_flag(f_ptr->flags, FF_PERMANENT))
1042 if (have_flag(mimic_f_ptr->flags, FF_PERMANENT))
1044 msg_print(_("この岩は硬すぎて掘れないようだ。", "This seems to be permanent rock."));
1047 /* Map border (mimiccing Permanent wall) */
1050 msg_print(_("そこは掘れない!", "You can't tunnel through that!"));
1055 else if (have_flag(f_ptr->flags, FF_CAN_DIG))
1058 if (p_ptr->skill_dig > randint0(20 * power))
1060 msg_format(_("%sをくずした。", "You have removed the %s."), name);
1062 /* Remove the feature */
1063 cave_alter_feat(y, x, FF_TUNNEL);
1065 /* Update some things */
1066 p_ptr->update |= (PU_FLOW);
1070 /* Message, keep digging */
1071 msg_format(_("%sをくずしている。", "You dig into the %s."), name);
1079 bool tree = have_flag(mimic_f_ptr->flags, FF_TREE);
1082 if (p_ptr->skill_dig > power + randint0(40 * power))
1084 if (tree) msg_format(_("%sを切り払った。", "You have cleared away the %s."), name);
1087 msg_print(_("穴を掘り終えた。", "You have finished the tunnel."));
1088 p_ptr->update |= (PU_FLOW);
1091 if (have_flag(f_ptr->flags, FF_GLASS)) sound(SOUND_GLASS);
1093 /* Remove the feature */
1094 cave_alter_feat(y, x, FF_TUNNEL);
1096 chg_virtue(V_DILIGENCE, 1);
1097 chg_virtue(V_NATURE, -1);
1105 /* We may continue chopping */
1106 msg_format(_("%sを切っている。", "You chop away at the %s."), name);
1107 /* Occasional Search XXX XXX */
1108 if (randint0(100) < 25) search();
1112 /* We may continue tunelling */
1113 msg_format(_("%sに穴を掘っている。", "You tunnel into the %s."), name);
1120 if (is_hidden_door(c_ptr))
1122 /* Occasional Search XXX XXX */
1123 if (randint0(100) < 25) search();
1130 * @brief 「掘る」動作コマンドのメインルーチン /
1131 * Tunnels through "walls" (including rubble and closed doors)
1135 * Note that you must tunnel in order to hit invisible monsters
1136 * in walls, though moving into walls still takes a turn anyway.
1138 * Digging is very difficult without a "digger" weapon, but can be
1139 * accomplished by strong players using heavy weapons.
1142 void do_cmd_tunnel(void)
1152 if (p_ptr->special_defense & KATA_MUSOU)
1154 set_action(ACTION_NONE);
1157 /* Allow repeated command */
1160 /* Set repeat count */
1161 command_rep = command_arg - 1;
1162 p_ptr->redraw |= (PR_STATE);
1164 /* Cancel the arg */
1168 /* Get a direction to tunnel, or Abort */
1169 if (get_rep_dir(&dir,FALSE))
1172 y = p_ptr->y + ddy[dir];
1173 x = p_ptr->x + ddx[dir];
1176 c_ptr = &cave[y][x];
1178 /* Feature code (applying "mimic" field) */
1179 feat = get_feat_mimic(c_ptr);
1181 /* No tunnelling through doors */
1182 if (have_flag(f_info[feat].flags, FF_DOOR))
1184 msg_print(_("ドアは掘れない。", "You cannot tunnel through doors."));
1187 /* No tunnelling through most features */
1188 else if (!have_flag(f_info[feat].flags, FF_TUNNEL))
1190 msg_print(_("そこは掘れない。", "You can't tunnel through that."));
1193 /* A monster is in the way */
1194 else if (c_ptr->m_idx)
1196 p_ptr->energy_use = 100;
1198 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1207 /* Tunnel through walls */
1208 more = do_cmd_tunnel_aux(y, x);
1212 /* Cancel repetition unless we can continue */
1213 if (!more) disturb(FALSE, FALSE);
1217 * @brief 移動処理による簡易な「開く」処理 /
1219 * @return 開く処理が実際に試みられた場合TRUEを返す
1222 * If there is a jammed/closed/locked door at the given location,
1223 * then attempt to unlock/open it. Return TRUE if an attempt was
1224 * made (successful or not), otherwise return FALSE.
1226 * The code here should be nearly identical to that in
1227 * do_cmd_open_test() and do_cmd_open_aux().
1230 bool easy_open_door(POSITION y, POSITION x)
1234 cave_type *c_ptr = &cave[y][x];
1235 feature_type *f_ptr = &f_info[c_ptr->feat];
1237 /* Must be a closed door */
1238 if (!is_closed_door(c_ptr->feat))
1244 if (!have_flag(f_ptr->flags, FF_OPEN))
1247 msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_name + f_info[get_feat_mimic(c_ptr)].name);
1252 else if (f_ptr->power)
1255 i = p_ptr->skill_dis;
1257 /* Penalize some conditions */
1258 if (p_ptr->blind || no_lite()) i = i / 10;
1259 if (p_ptr->confused || p_ptr->image) i = i / 10;
1261 /* Extract the lock power */
1264 /* Extract the difficulty */
1267 /* Always have a small chance of success */
1271 if (randint0(100) < j)
1273 msg_print(_("鍵をはずした。", "You have picked the lock."));
1276 cave_alter_feat(y, x, FF_OPEN);
1278 sound(SOUND_OPENDOOR);
1288 if (flush_failure) flush();
1290 msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
1299 cave_alter_feat(y, x, FF_OPEN);
1301 sound(SOUND_OPENDOOR);
1307 * @brief 箱のトラップを解除するコマンドのメインルーチン /
1308 * Perform the basic "disarm" command
1309 * @param y 解除を行うマスのY座標
1310 * @param x 解除を行うマスのX座標
1311 * @param o_idx 箱のオブジェクトID
1312 * @return ターンを消費する処理が行われた場合TRUEを返す
1315 * Assume destination is a visible trap
1316 * Assume there is no monster blocking the destination
1317 * Returns TRUE if repeated commands may continue
1320 static bool do_cmd_disarm_chest(POSITION y, POSITION x, OBJECT_IDX o_idx)
1324 object_type *o_ptr = &o_list[o_idx];
1326 p_ptr->energy_use = 100;
1328 /* Get the "disarm" factor */
1329 i = p_ptr->skill_dis;
1331 /* Penalize some conditions */
1332 if (p_ptr->blind || no_lite()) i = i / 10;
1333 if (p_ptr->confused || p_ptr->image) i = i / 10;
1335 /* Extract the difficulty */
1336 j = i - o_ptr->pval;
1338 /* Always have a small chance of success */
1341 /* Must find the trap first. */
1342 if (!object_is_known(o_ptr))
1344 msg_print(_("トラップが見あたらない。", "I don't see any traps."));
1348 /* Already disarmed/unlocked */
1349 else if (o_ptr->pval <= 0)
1351 msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped."));
1354 /* No traps to find. */
1355 else if (!chest_traps[o_ptr->pval])
1357 msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped."));
1360 /* Success (get a lot of experience) */
1361 else if (randint0(100) < j)
1363 msg_print(_("箱に仕掛けられていたトラップを解除した。", "You have disarmed the chest."));
1364 gain_exp(o_ptr->pval);
1365 o_ptr->pval = (0 - o_ptr->pval);
1368 /* Failure -- Keep trying */
1369 else if ((i > 5) && (randint1(i) > 5))
1371 /* We may keep trying */
1373 if (flush_failure) flush();
1374 msg_print(_("箱のトラップ解除に失敗した。", "You failed to disarm the chest."));
1377 /* Failure -- Set off the trap */
1380 msg_print(_("トラップを作動させてしまった!", "You set off a trap!"));
1382 chest_trap(y, x, o_idx);
1389 * @brief 箱のトラップを解除するコマンドのサブルーチン /
1390 * Perform the basic "disarm" command
1391 * @param y 解除を行うマスのY座標
1392 * @param x 解除を行うマスのX座標
1393 * @param dir プレイヤーからみた方向ID
1394 * @return ターンを消費する処理が行われた場合TRUEを返す
1397 * Assume destination is a visible trap
1398 * Assume there is no monster blocking the destination
1399 * Returns TRUE if repeated commands may continue
1403 bool do_cmd_disarm_aux(POSITION y, POSITION x, DIRECTION dir)
1405 cave_type *c_ptr = &cave[y][x];
1408 feature_type *f_ptr = &f_info[c_ptr->feat];
1410 /* Access trap name */
1411 concptr name = (f_name + f_ptr->name);
1413 /* Extract trap "power" */
1414 int power = f_ptr->power;
1417 /* Get the "disarm" factor */
1418 int i = p_ptr->skill_dis;
1421 p_ptr->energy_use = 100;
1423 /* Penalize some conditions */
1424 if (p_ptr->blind || no_lite()) i = i / 10;
1425 if (p_ptr->confused || p_ptr->image) i = i / 10;
1427 /* Extract the difficulty */
1430 /* Always have a small chance of success */
1434 if (randint0(100) < j)
1436 msg_format(_("%sを解除した。", "You have disarmed the %s."), name);
1441 /* Remove the trap */
1442 cave_alter_feat(y, x, FF_DISARM);
1444 /* Move the player onto the trap */
1445 move_player(dir, easy_disarm, FALSE);
1448 /* Failure -- Keep trying */
1449 else if ((i > 5) && (randint1(i) > 5))
1452 if (flush_failure) flush();
1454 msg_format(_("%sの解除に失敗した。", "You failed to disarm the %s."), name);
1456 /* We may keep trying */
1460 /* Failure -- Set off the trap */
1463 msg_format(_("%sを作動させてしまった!", "You set off the %s!"), name);
1464 /* Move the player onto the trap */
1465 move_player(dir, easy_disarm, FALSE);
1472 * @brief 箱、床のトラップ解除処理双方の統合メインルーチン /
1473 * Disarms a trap, or chest
1476 void do_cmd_disarm(void)
1484 if (p_ptr->wild_mode) return;
1486 if (p_ptr->special_defense & KATA_MUSOU)
1488 set_action(ACTION_NONE);
1491 /* Option: Pick a direction */
1494 int num_traps, num_chests;
1496 /* Count visible traps */
1497 num_traps = count_dt(&y, &x, is_trap, TRUE);
1499 /* Count chests (trapped) */
1500 num_chests = count_chests(&y, &x, TRUE);
1502 /* See if only one target */
1503 if (num_traps || num_chests)
1505 bool too_many = (num_traps && num_chests) || (num_traps > 1) || (num_chests > 1);
1506 if (!too_many) command_dir = coords_to_dir(y, x);
1511 /* Allow repeated command */
1514 /* Set repeat count */
1515 command_rep = command_arg - 1;
1516 p_ptr->redraw |= (PR_STATE);
1518 /* Cancel the arg */
1522 /* Get a direction (or abort) */
1523 if (get_rep_dir(&dir,TRUE))
1528 y = p_ptr->y + ddy[dir];
1529 x = p_ptr->x + ddx[dir];
1530 c_ptr = &cave[y][x];
1532 /* Feature code (applying "mimic" field) */
1533 feat = get_feat_mimic(c_ptr);
1535 /* Check for chests */
1536 o_idx = chest_check(y, x, TRUE);
1539 if (!is_trap(feat) && !o_idx)
1541 msg_print(_("そこには解除するものが見当たらない。", "You see nothing there to disarm."));
1544 /* Monster in the way */
1545 else if (c_ptr->m_idx && p_ptr->riding != c_ptr->m_idx)
1547 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1556 more = do_cmd_disarm_chest(y, x, o_idx);
1562 more = do_cmd_disarm_aux(y, x, dir);
1566 /* Cancel repeat unless told not to */
1567 if (!more) disturb(FALSE, FALSE);
1572 * @brief 「打ち破る」動作コマンドのサブルーチン /
1573 * Perform the basic "bash" command
1574 * @param y 対象を行うマスのY座標
1575 * @param x 対象を行うマスのX座標
1576 * @param dir プレイヤーから見たターゲットの方角ID
1577 * @return 実際に処理が行われた場合TRUEを返す。
1580 * Assume destination is a closed/locked/jammed door
1581 * Assume there is no monster blocking the destination
1582 * Returns TRUE if repeated commands may continue
1585 static bool do_cmd_bash_aux(POSITION y, POSITION x, DIRECTION dir)
1588 cave_type *c_ptr = &cave[y][x];
1591 feature_type *f_ptr = &f_info[c_ptr->feat];
1593 /* Hack -- Bash power based on strength */
1594 /* (Ranges from 3 to 20 to 100 to 200) */
1595 int bash = adj_str_blow[p_ptr->stat_ind[A_STR]];
1597 /* Extract door power */
1598 int temp = f_ptr->power;
1602 concptr name = f_name + f_info[get_feat_mimic(c_ptr)].name;
1604 p_ptr->energy_use = 100;
1606 msg_format(_("%sに体当たりをした!", "You smash into the %s!"), name);
1608 /* Compare bash power to door power */
1609 temp = (bash - (temp * 10));
1611 if (p_ptr->pclass == CLASS_BERSERKER) temp *= 2;
1613 /* Hack -- always have a chance */
1614 if (temp < 1) temp = 1;
1616 /* Hack -- attempt to bash down the door */
1617 if (randint0(100) < temp)
1619 msg_format(_("%sを壊した!", "The %s crashes open!"), name);
1621 sound(have_flag(f_ptr->flags, FF_GLASS) ? SOUND_GLASS : SOUND_OPENDOOR);
1623 /* Break down the door */
1624 if ((randint0(100) < 50) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS))
1626 cave_alter_feat(y, x, FF_BASH);
1632 cave_alter_feat(y, x, FF_OPEN);
1635 /* Hack -- Fall through the door */
1636 move_player(dir, FALSE, FALSE);
1639 /* Saving throw against stun */
1640 else if (randint0(100) < adj_dex_safe[p_ptr->stat_ind[A_DEX]] +
1643 msg_format(_("この%sは頑丈だ。", "The %s holds firm."), name);
1645 /* Allow repeated bashing */
1649 /* High dexterity yields coolness */
1652 msg_print(_("体のバランスをくずしてしまった。", "You are off-balance."));
1654 /* Hack -- Lose balance ala paralysis */
1655 (void)set_paralyzed(p_ptr->paralyzed + 2 + randint0(2));
1662 * @brief 「打ち破る」動作コマンドのメインルーチン /
1663 * Bash open a door, success based on character strength
1667 * For a closed door, pval is positive if locked; negative if stuck.
1669 * For an open door, pval is positive for a broken door.
1671 * A closed door can be opened - harder if locked. Any door might be
1672 * bashed open (and thereby broken). Bashing a door is (potentially)
1673 * faster! You move into the door way. To open a stuck door, it must
1674 * be bashed. A closed door can be jammed (see do_cmd_spike()).
1676 * Creatures can also open or bash doors, see elsewhere.
1679 void do_cmd_bash(void)
1685 if (p_ptr->wild_mode) return;
1687 if (p_ptr->special_defense & KATA_MUSOU)
1689 set_action(ACTION_NONE);
1692 /* Allow repeated command */
1695 /* Set repeat count */
1696 command_rep = command_arg - 1;
1697 p_ptr->redraw |= (PR_STATE);
1699 /* Cancel the arg */
1703 /* Get a "repeated" direction */
1704 if (get_rep_dir(&dir,FALSE))
1709 y = p_ptr->y + ddy[dir];
1710 x = p_ptr->x + ddx[dir];
1713 c_ptr = &cave[y][x];
1715 /* Feature code (applying "mimic" field) */
1716 feat = get_feat_mimic(c_ptr);
1718 /* Nothing useful */
1719 if (!have_flag(f_info[feat].flags, FF_BASH))
1721 msg_print(_("そこには体当たりするものが見当たらない。", "You see nothing there to bash."));
1724 /* Monster in the way */
1725 else if (c_ptr->m_idx)
1727 p_ptr->energy_use = 100;
1729 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1735 /* Bash a closed door */
1739 more = do_cmd_bash_aux(y, x, dir);
1743 /* Unless valid action taken, cancel bash */
1744 if (!more) disturb(FALSE, FALSE);
1749 * @brief 特定のマスに影響を及ぼすための汎用的コマンド
1753 * Manipulate an adjacent grid in some way
1755 * Attack monsters, tunnel through walls, disarm traps, open doors.
1757 * Consider confusion
1759 * This command must always take a turn, to prevent free detection
1760 * of invisible monsters.
1763 void do_cmd_alter(void)
1770 if (p_ptr->special_defense & KATA_MUSOU)
1772 set_action(ACTION_NONE);
1775 /* Allow repeated command */
1778 /* Set repeat count */
1779 command_rep = command_arg - 1;
1780 p_ptr->redraw |= (PR_STATE);
1782 /* Cancel the arg */
1786 /* Get a direction */
1787 if (get_rep_dir(&dir,TRUE))
1790 feature_type *f_ptr;
1792 y = p_ptr->y + ddy[dir];
1793 x = p_ptr->x + ddx[dir];
1796 c_ptr = &cave[y][x];
1798 /* Feature code (applying "mimic" field) */
1799 feat = get_feat_mimic(c_ptr);
1800 f_ptr = &f_info[feat];
1802 p_ptr->energy_use = 100;
1810 else if (have_flag(f_ptr->flags, FF_OPEN))
1812 more = do_cmd_open_aux(y, x);
1815 /* Bash jammed doors */
1816 else if (have_flag(f_ptr->flags, FF_BASH))
1818 more = do_cmd_bash_aux(y, x, dir);
1821 /* Tunnel through walls */
1822 else if (have_flag(f_ptr->flags, FF_TUNNEL))
1824 more = do_cmd_tunnel_aux(y, x);
1827 /* Close open doors */
1828 else if (have_flag(f_ptr->flags, FF_CLOSE))
1830 more = do_cmd_close_aux(y, x);
1834 else if (have_flag(f_ptr->flags, FF_DISARM))
1836 more = do_cmd_disarm_aux(y, x, dir);
1841 msg_print(_("何もない空中を攻撃した。", "You attack the empty air."));
1845 /* Cancel repetition unless we can continue */
1846 if (!more) disturb(FALSE, FALSE);
1852 * @brief 「くさびを打つ」ために必要なオブジェクトがあるかどうかの判定を返す /
1853 * Find the index of some "spikes", if possible.
1854 * @param ip くさびとして打てるオブジェクトのID
1855 * @return オブジェクトがある場合TRUEを返す
1858 * Let user choose a pile of spikes, perhaps?
1861 static bool get_spike(INVENTORY_IDX *ip)
1865 /* Check every item in the pack */
1866 for (i = 0; i < INVEN_PACK; i++)
1868 object_type *o_ptr = &inventory[i];
1870 /* Skip non-objects */
1871 if (!o_ptr->k_idx) continue;
1873 /* Check the "tval" code */
1874 if (o_ptr->tval == TV_SPIKE)
1876 /* Save the spike index */
1889 * @brief 「くさびを打つ」動作コマンドのメインルーチン /
1890 * Jam a closed door with a spike
1894 * This command may NOT be repeated
1897 void do_cmd_spike(void)
1901 if (p_ptr->wild_mode) return;
1903 if (p_ptr->special_defense & KATA_MUSOU)
1905 set_action(ACTION_NONE);
1908 /* Get a "repeated" direction */
1909 if (get_rep_dir(&dir, FALSE))
1916 y = p_ptr->y + ddy[dir];
1917 x = p_ptr->x + ddx[dir];
1918 c_ptr = &cave[y][x];
1920 /* Feature code (applying "mimic" field) */
1921 feat = get_feat_mimic(c_ptr);
1923 /* Require closed door */
1924 if (!have_flag(f_info[feat].flags, FF_SPIKE))
1926 msg_print(_("そこにはくさびを打てるものが見当たらない。", "You see nothing there to spike."));
1930 else if (!get_spike(&item))
1932 msg_print(_("くさびを持っていない!", "You have no spikes!"));
1935 /* Is a monster in the way? */
1936 else if (c_ptr->m_idx)
1938 p_ptr->energy_use = 100;
1940 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
1949 p_ptr->energy_use = 100;
1951 /* Successful jamming */
1952 msg_format(_("%sにくさびを打ち込んだ。", "You jam the %s with a spike."), f_name + f_info[feat].name);
1953 cave_alter_feat(y, x, FF_SPIKE);
1955 /* Use up, and describe, a single spike, from the bottom */
1956 inven_item_increase(item, -1);
1957 inven_item_describe(item);
1958 inven_item_optimize(item);
1966 * @brief 「歩く」動作コマンドのメインルーチン /
1967 * Support code for the "Walk" and "Jump" commands
1968 * @param pickup アイテムの自動拾いを行うならTRUE
1971 void do_cmd_walk(bool pickup)
1978 /* Allow repeated command */
1981 /* Set repeat count */
1982 command_rep = command_arg - 1;
1983 p_ptr->redraw |= (PR_STATE);
1985 /* Cancel the arg */
1989 /* Get a "repeated" direction */
1990 if (get_rep_dir(&dir, FALSE))
1992 p_ptr->energy_use = 100;
1994 if ((dir != 5) && (p_ptr->special_defense & KATA_MUSOU))
1996 set_action(ACTION_NONE);
1999 /* Hack -- In small scale wilderness it takes MUCH more time to move */
2000 if (p_ptr->wild_mode) p_ptr->energy_use *= ((MAX_HGT + MAX_WID) / 2);
2001 if (p_ptr->action == ACTION_HAYAGAKE) p_ptr->energy_use = p_ptr->energy_use * (45-(p_ptr->lev/2)) / 100;
2003 /* Actually move the character */
2004 move_player(dir, pickup, FALSE);
2006 /* Allow more walking */
2010 /* Hack again -- Is there a special encounter ??? */
2011 if (p_ptr->wild_mode && !cave_have_flag_bold(p_ptr->y, p_ptr->x, FF_TOWN))
2013 int tmp = 120 + p_ptr->lev*10 - wilderness[p_ptr->y][p_ptr->x].level + 5;
2016 if (((wilderness[p_ptr->y][p_ptr->x].level + 5) > (p_ptr->lev / 2)) && randint0(tmp) < (21-p_ptr->skill_stl))
2018 /* Inform the player of his horrible fate :=) */
2019 msg_print(_("襲撃だ!", "You are ambushed !"));
2021 /* Go into large wilderness view */
2022 p_ptr->oldpy = randint1(MAX_HGT-2);
2023 p_ptr->oldpx = randint1(MAX_WID-2);
2026 /* Give first move to monsters */
2027 p_ptr->energy_use = 100;
2029 /* HACk -- set the encouter flag for the wilderness generation */
2030 generate_encounter = TRUE;
2034 /* Cancel repeat unless we may continue */
2035 if (!more) disturb(FALSE, FALSE);
2040 * @brief 「走る」動作コマンドのメインルーチン /
2044 void do_cmd_run(void)
2048 /* Hack -- no running when confused */
2049 if (p_ptr->confused)
2051 msg_print(_("混乱していて走れない!", "You are too confused!"));
2055 if (p_ptr->special_defense & KATA_MUSOU)
2057 set_action(ACTION_NONE);
2060 /* Get a "repeated" direction */
2061 if (get_rep_dir(&dir,FALSE))
2063 /* Hack -- Set the run counter */
2064 running = (command_arg ? command_arg : 1000);
2073 * @brief 「留まる」動作コマンドのメインルーチン /
2074 * Stay still. Search. Enter stores.
2075 * Pick up treasure if "pickup" is true.
2076 * @param pickup アイテムの自動拾いを行うならTRUE
2079 void do_cmd_stay(bool pickup)
2081 u32b mpe_mode = MPE_STAYING | MPE_ENERGY_USE;
2083 /* Allow repeated command */
2086 /* Set repeat count */
2087 command_rep = command_arg - 1;
2088 p_ptr->redraw |= (PR_STATE);
2090 /* Cancel the arg */
2094 p_ptr->energy_use = 100;
2096 if (pickup) mpe_mode |= MPE_DO_PICKUP;
2097 (void)move_player_effect(p_ptr->y, p_ptr->x, mpe_mode);
2102 * @brief 「休む」動作コマンドのメインルーチン /
2103 * Resting allows a player to safely restore his hp -RAK-
2106 void do_cmd_rest(void)
2109 set_action(ACTION_NONE);
2111 if ((p_ptr->pclass == CLASS_BARD) && (SINGING_SONG_EFFECT(p_ptr) || INTERUPTING_SONG_EFFECT(p_ptr)))
2117 if (hex_spelling_any()) stop_hex_spell_all();
2119 /* Prompt for time if needed */
2120 if (command_arg <= 0)
2122 concptr p = _("休憩 (0-9999, '*' で HP/MP全快, '&' で必要なだけ): ",
2123 "Rest (0-9999, '*' for HP/SP, '&' as needed): ");
2129 strcpy(out_val, "&");
2131 /* Ask for duration */
2132 if (!get_string(p, out_val, 4)) return;
2134 /* Rest until done */
2135 if (out_val[0] == '&')
2137 command_arg = COMMAND_ARG_REST_UNTIL_DONE;
2141 else if (out_val[0] == '*')
2143 command_arg = COMMAND_ARG_REST_FULL_HEALING;
2149 command_arg = (COMMAND_ARG)atoi(out_val);
2150 if (command_arg <= 0) return;
2156 if (command_arg > 9999) command_arg = 9999;
2158 if (p_ptr->special_defense & NINJA_S_STEALTH) set_superstealth(FALSE);
2160 /* Take a turn (?) */
2161 p_ptr->energy_use = 100;
2163 /* The sin of sloth */
2164 if (command_arg > 100) chg_virtue(V_DILIGENCE, -1);
2166 /* Why are you sleeping when there's no need? WAKE UP!*/
2167 if ((p_ptr->chp == p_ptr->mhp) &&
2168 (p_ptr->csp == p_ptr->msp) &&
2169 !p_ptr->blind && !p_ptr->confused &&
2170 !p_ptr->poisoned && !p_ptr->afraid &&
2171 !p_ptr->stun && !p_ptr->cut &&
2172 !p_ptr->slow && !p_ptr->paralyzed &&
2173 !p_ptr->image && !p_ptr->word_recall &&
2174 !p_ptr->alter_reality)
2175 chg_virtue(V_DILIGENCE, -1);
2177 /* Save the rest code */
2178 resting = command_arg;
2179 p_ptr->action = ACTION_REST;
2180 p_ptr->update |= (PU_BONUS);
2181 update_creature(p_ptr);
2183 p_ptr->redraw |= (PR_STATE);
2191 * @brief 矢弾を射撃した場合の破損確率を返す /
2192 * Determines the odds of an object breaking when thrown at a monster
2193 * @param o_ptr 矢弾のオブジェクト構造体参照ポインタ
2196 * Note that artifacts never break, see the "drop_near()" function.
2198 static PERCENTAGE breakage_chance(object_type *o_ptr)
2200 PERCENTAGE archer_bonus = (p_ptr->pclass == CLASS_ARCHER ? (PERCENTAGE)(p_ptr->lev-1)/7 + 4: 0);
2202 /* Examine the snipe type */
2205 if (snipe_type == SP_KILL_WALL) return (100);
2206 if (snipe_type == SP_EXPLODE) return (100);
2207 if (snipe_type == SP_PIERCE) return (100);
2208 if (snipe_type == SP_FINAL) return (100);
2209 if (snipe_type == SP_NEEDLE) return (100);
2210 if (snipe_type == SP_EVILNESS) return (40);
2211 if (snipe_type == SP_HOLYNESS) return (40);
2214 /* Examine the item type */
2215 switch (o_ptr->tval)
2231 /* Sometimes break */
2236 return (20 - archer_bonus * 2);
2241 return (10 - archer_bonus);
2249 * @brief 矢弾を射撃した際のスレイ倍率をかけた結果を返す /
2250 * Determines the odds of an object breaking when thrown at a monster
2251 * @param o_ptr 矢弾のオブジェクト構造体参照ポインタ
2252 * @param tdam 計算途中のダメージ量
2253 * @param m_ptr 目標モンスターの構造体参照ポインタ
2254 * @return スレイ倍率をかけたダメージ量
2256 static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
2260 monster_race *r_ptr = &r_info[m_ptr->r_idx];
2262 BIT_FLAGS flgs[TR_FLAG_SIZE];
2263 object_flags(o_ptr, flgs);
2265 /* Some "weapons" and "ammo" do extra damage */
2266 switch (o_ptr->tval)
2272 if ((have_flag(flgs, TR_SLAY_ANIMAL)) && (r_ptr->flags3 & RF3_ANIMAL))
2274 if (is_original_ap_and_seen(m_ptr))
2276 r_ptr->r_flags3 |= RF3_ANIMAL;
2278 if (mult < 17) mult = 17;
2281 if ((have_flag(flgs, TR_KILL_ANIMAL)) && (r_ptr->flags3 & RF3_ANIMAL))
2283 if (is_original_ap_and_seen(m_ptr))
2285 r_ptr->r_flags3 |= RF3_ANIMAL;
2287 if (mult < 27) mult = 27;
2290 if ((have_flag(flgs, TR_SLAY_EVIL)) && (r_ptr->flags3 & RF3_EVIL))
2292 if (is_original_ap_and_seen(m_ptr))
2294 r_ptr->r_flags3 |= RF3_EVIL;
2296 if (mult < 15) mult = 15;
2299 if ((have_flag(flgs, TR_KILL_EVIL)) && (r_ptr->flags3 & RF3_EVIL))
2301 if (is_original_ap_and_seen(m_ptr))
2303 r_ptr->r_flags3 |= RF3_EVIL;
2305 if (mult < 25) mult = 25;
2308 if ((have_flag(flgs, TR_SLAY_HUMAN)) && (r_ptr->flags2 & RF2_HUMAN))
2310 if (is_original_ap_and_seen(m_ptr))
2312 r_ptr->r_flags2 |= RF2_HUMAN;
2314 if (mult < 17) mult = 17;
2317 if ((have_flag(flgs, TR_KILL_HUMAN)) && (r_ptr->flags2 & RF2_HUMAN))
2319 if (is_original_ap_and_seen(m_ptr))
2321 r_ptr->r_flags2 |= RF2_HUMAN;
2323 if (mult < 27) mult = 27;
2326 if ((have_flag(flgs, TR_SLAY_UNDEAD)) && (r_ptr->flags3 & RF3_UNDEAD))
2328 if (is_original_ap_and_seen(m_ptr))
2330 r_ptr->r_flags3 |= RF3_UNDEAD;
2332 if (mult < 20) mult = 20;
2335 if ((have_flag(flgs, TR_KILL_UNDEAD)) && (r_ptr->flags3 & RF3_UNDEAD))
2337 if (is_original_ap_and_seen(m_ptr))
2339 r_ptr->r_flags3 |= RF3_UNDEAD;
2341 if (mult < 30) mult = 30;
2344 if ((have_flag(flgs, TR_SLAY_DEMON)) && (r_ptr->flags3 & RF3_DEMON))
2346 if (is_original_ap_and_seen(m_ptr))
2348 r_ptr->r_flags3 |= RF3_DEMON;
2350 if (mult < 20) mult = 20;
2353 if ((have_flag(flgs, TR_KILL_DEMON)) && (r_ptr->flags3 & RF3_DEMON))
2355 if (is_original_ap_and_seen(m_ptr))
2357 r_ptr->r_flags3 |= RF3_DEMON;
2359 if (mult < 30) mult = 30;
2362 if ((have_flag(flgs, TR_SLAY_ORC)) && (r_ptr->flags3 & RF3_ORC))
2364 if (is_original_ap_and_seen(m_ptr))
2366 r_ptr->r_flags3 |= RF3_ORC;
2368 if (mult < 20) mult = 20;
2371 if ((have_flag(flgs, TR_KILL_ORC)) && (r_ptr->flags3 & RF3_ORC))
2373 if (is_original_ap_and_seen(m_ptr))
2375 r_ptr->r_flags3 |= RF3_ORC;
2377 if (mult < 30) mult = 30;
2380 if ((have_flag(flgs, TR_SLAY_TROLL)) && (r_ptr->flags3 & RF3_TROLL))
2382 if (is_original_ap_and_seen(m_ptr))
2384 r_ptr->r_flags3 |= RF3_TROLL;
2387 if (mult < 20) mult = 20;
2390 if ((have_flag(flgs, TR_KILL_TROLL)) && (r_ptr->flags3 & RF3_TROLL))
2392 if (is_original_ap_and_seen(m_ptr))
2394 r_ptr->r_flags3 |= RF3_TROLL;
2396 if (mult < 30) mult = 30;
2399 if ((have_flag(flgs, TR_SLAY_GIANT)) && (r_ptr->flags3 & RF3_GIANT))
2401 if (is_original_ap_and_seen(m_ptr))
2403 r_ptr->r_flags3 |= RF3_GIANT;
2405 if (mult < 20) mult = 20;
2408 if ((have_flag(flgs, TR_KILL_GIANT)) && (r_ptr->flags3 & RF3_GIANT))
2410 if (is_original_ap_and_seen(m_ptr))
2412 r_ptr->r_flags3 |= RF3_GIANT;
2414 if (mult < 30) mult = 30;
2417 if ((have_flag(flgs, TR_SLAY_DRAGON)) && (r_ptr->flags3 & RF3_DRAGON))
2419 if (is_original_ap_and_seen(m_ptr))
2421 r_ptr->r_flags3 |= RF3_DRAGON;
2423 if (mult < 20) mult = 20;
2426 if ((have_flag(flgs, TR_KILL_DRAGON)) && (r_ptr->flags3 & RF3_DRAGON))
2428 if (is_original_ap_and_seen(m_ptr))
2430 r_ptr->r_flags3 |= RF3_DRAGON;
2432 if (mult < 30) mult = 30;
2433 if ((o_ptr->name1 == ART_BARD_ARROW) && (m_ptr->r_idx == MON_SMAUG) &&
2434 (inventory[INVEN_BOW].name1 == ART_BARD))
2438 if (have_flag(flgs, TR_BRAND_ACID))
2440 /* Notice immunity */
2441 if (r_ptr->flagsr & RFR_EFF_IM_ACID_MASK)
2443 if (is_original_ap_and_seen(m_ptr))
2445 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ACID_MASK);
2450 if (mult < 17) mult = 17;
2454 if (have_flag(flgs, TR_BRAND_ELEC))
2456 /* Notice immunity */
2457 if (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)
2459 if (is_original_ap_and_seen(m_ptr))
2461 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
2466 if (mult < 17) mult = 17;
2470 if (have_flag(flgs, TR_BRAND_FIRE))
2472 /* Notice immunity */
2473 if (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)
2475 if (is_original_ap_and_seen(m_ptr))
2477 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
2480 /* Otherwise, take the damage */
2483 if (r_ptr->flags3 & RF3_HURT_FIRE)
2485 if (mult < 25) mult = 25;
2486 if (is_original_ap_and_seen(m_ptr))
2488 r_ptr->r_flags3 |= RF3_HURT_FIRE;
2491 else if (mult < 17) mult = 17;
2495 if (have_flag(flgs, TR_BRAND_COLD))
2497 /* Notice immunity */
2498 if (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)
2500 if (is_original_ap_and_seen(m_ptr))
2502 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
2505 /* Otherwise, take the damage */
2508 if (r_ptr->flags3 & RF3_HURT_COLD)
2510 if (mult < 25) mult = 25;
2511 if (is_original_ap_and_seen(m_ptr))
2513 r_ptr->r_flags3 |= RF3_HURT_COLD;
2516 else if (mult < 17) mult = 17;
2520 if (have_flag(flgs, TR_BRAND_POIS))
2522 /* Notice immunity */
2523 if (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK)
2525 if (is_original_ap_and_seen(m_ptr))
2527 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK);
2530 /* Otherwise, take the damage */
2533 if (mult < 17) mult = 17;
2537 if ((have_flag(flgs, TR_FORCE_WEAPON)) && (p_ptr->csp > (p_ptr->msp / 30)))
2539 p_ptr->csp -= (1+(p_ptr->msp / 30));
2540 p_ptr->redraw |= (PR_MANA);
2541 mult = mult * 5 / 2;
2548 if (snipe_type) mult = tot_dam_aux_snipe(mult, m_ptr);
2550 /* Return the total damage */
2551 return (tdam * mult / 10);
2556 * @brief 射撃処理のサブルーチン /
2557 * Fire an object from the pack or floor.
2558 * @param item 射撃するオブジェクトの所持ID
2559 * @param j_ptr 射撃武器のオブジェクト参照ポインタ
2563 * You may only fire items that "match" your missile launcher.
2565 * You must use slings + pebbles/shots, bows + arrows, xbows + bolts.
2567 * See "calc_bonuses()" for more calculations and such.
2569 * Note that "firing" a missile is MUCH better than "throwing" it.
2571 * Note: "unseen" monsters are very hard to hit.
2573 * Objects are more likely to break if they "attempt" to hit a monster.
2575 * Rangers (with Bows) and Anyone (with "Extra Shots") get extra shots.
2577 * The "extra shot" code works by decreasing the amount of energy
2578 * required to make each shot, spreading the shots out over time.
2580 * Note that when firing missiles, the launcher multiplier is applied
2581 * after all the bonuses are added in, making multipliers very useful.
2583 * Note that Bows of "Extra Might" get extra range and an extra bonus
2584 * for the damage multiplier.
2586 * Note that Bows of "Extra Shots" give an extra shot.
2589 void do_cmd_fire_aux(INVENTORY_IDX item, object_type *j_ptr)
2593 POSITION y, x, ny, nx, ty, tx, prev_y, prev_x;
2594 int tdam_base, tdis, thits, tmul;
2596 int cur_dis, visible;
2604 bool hit_body = FALSE;
2606 GAME_TEXT o_name[MAX_NLEN];
2608 u16b path_g[512]; /* For calcuration of path length */
2610 int msec = delay_factor * delay_factor * delay_factor;
2613 bool stick_to = FALSE;
2615 /* Access the item (if in the pack) */
2618 o_ptr = &inventory[item];
2622 o_ptr = &o_list[0 - item];
2625 /* Sniper - Cannot shot a single arrow twice */
2626 if ((snipe_type == SP_DOUBLE) && (o_ptr->number < 2)) snipe_type = SP_NONE;
2628 object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
2630 /* Use the proper number of shots */
2631 thits = p_ptr->num_fire;
2633 /* Use a base distance */
2636 /* Base damage from thrown object plus launcher bonus */
2637 tdam_base = damroll(o_ptr->dd, o_ptr->ds) + o_ptr->to_d + j_ptr->to_d;
2639 /* Actually "fire" the object */
2640 bonus = (p_ptr->to_h_b + o_ptr->to_h + j_ptr->to_h);
2641 if ((j_ptr->sval == SV_LIGHT_XBOW) || (j_ptr->sval == SV_HEAVY_XBOW))
2642 chance = (p_ptr->skill_thb + (p_ptr->weapon_exp[0][j_ptr->sval] / 400 + bonus) * BTH_PLUS_ADJ);
2644 chance = (p_ptr->skill_thb + ((p_ptr->weapon_exp[0][j_ptr->sval] - (WEAPON_EXP_MASTER / 2)) / 200 + bonus) * BTH_PLUS_ADJ);
2646 p_ptr->energy_use = bow_energy(j_ptr->sval);
2647 tmul = bow_tmul(j_ptr->sval);
2649 /* Get extra "power" from "extra might" */
2650 if (p_ptr->xtra_might) tmul++;
2652 tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
2654 /* Boost the damage */
2659 tdis = 13 + tmul/80;
2660 if ((j_ptr->sval == SV_LIGHT_XBOW) || (j_ptr->sval == SV_HEAVY_XBOW))
2663 tdis -= (5 - (p_ptr->concent + 1) / 2);
2668 project_length = tdis + 1;
2670 /* Get a direction (or cancel) */
2671 if (!get_aim_dir(&dir))
2673 p_ptr->energy_use = 0;
2675 if (snipe_type == SP_AWAY) snipe_type = SP_NONE;
2677 /* need not to reset project_length (already did)*/
2682 /* Predict the "target" location */
2683 tx = p_ptr->x + 99 * ddx[dir];
2684 ty = p_ptr->y + 99 * ddy[dir];
2686 /* Check for "target request" */
2687 if ((dir == 5) && target_okay())
2693 /* Get projection path length */
2694 tdis = project_path(path_g, project_length, p_ptr->y, p_ptr->x, ty, tx, PROJECT_PATH|PROJECT_THRU) - 1;
2696 project_length = 0; /* reset to default */
2698 /* Don't shoot at my feet */
2699 if (tx == p_ptr->x && ty == p_ptr->y)
2701 p_ptr->energy_use = 0;
2703 /* project_length is already reset to 0 */
2709 /* Take a (partial) turn */
2710 p_ptr->energy_use = (p_ptr->energy_use / thits);
2713 /* Sniper - Difficult to shot twice at 1 turn */
2714 if (snipe_type == SP_DOUBLE) p_ptr->concent = (p_ptr->concent + 1) / 2;
2716 /* Sniper - Repeat shooting when double shots */
2717 for (i = 0; i < ((snipe_type == SP_DOUBLE) ? 2 : 1); i++)
2720 /* Start at the player */
2725 /* Obtain a local object */
2726 object_copy(q_ptr, o_ptr);
2731 /* Reduce and describe inventory */
2734 inven_item_increase(item, -1);
2735 inven_item_describe(item);
2736 inven_item_optimize(item);
2739 /* Reduce and describe floor item */
2742 floor_item_increase(0 - item, -1);
2743 floor_item_optimize(0 - item);
2749 /* Save the old location */
2753 /* The shot does not hit yet */
2756 /* Travel until stopped */
2757 for (cur_dis = 0; cur_dis <= tdis; )
2761 /* Hack -- Stop at the target */
2762 if ((y == ty) && (x == tx)) break;
2764 /* Calculate the new location (see "project()") */
2767 mmove2(&ny, &nx, p_ptr->y, p_ptr->x, ty, tx);
2770 if (snipe_type == SP_KILL_WALL)
2772 c_ptr = &cave[ny][nx];
2774 if (cave_have_flag_grid(c_ptr, FF_HURT_ROCK) && !c_ptr->m_idx)
2776 if (c_ptr->info & (CAVE_MARK)) msg_print(_("岩が砕け散った。", "Wall rocks were shattered."));
2777 /* Forget the wall */
2778 c_ptr->info &= ~(CAVE_MARK);
2779 p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE);
2781 /* Destroy the wall */
2782 cave_alter_feat(ny, nx, FF_HURT_ROCK);
2789 /* Stopped by walls/doors */
2790 if (!cave_have_flag_bold(ny, nx, FF_PROJECT) && !cave[ny][nx].m_idx) break;
2792 /* Advance the distance */
2796 if (snipe_type == SP_LITE)
2798 cave[ny][nx].info |= (CAVE_GLOW);
2803 /* The player can see the (on screen) missile */
2804 if (panel_contains(ny, nx) && player_can_see_bold(ny, nx))
2806 char c = object_char(q_ptr);
2807 byte a = object_attr(q_ptr);
2809 /* Draw, Hilite, Fresh, Pause, Erase */
2810 print_rel(c, a, ny, nx);
2811 move_cursor_relative(ny, nx);
2813 Term_xtra(TERM_XTRA_DELAY, msec);
2818 /* The player cannot see the missile */
2821 /* Pause anyway, for consistancy */
2822 Term_xtra(TERM_XTRA_DELAY, msec);
2826 if (snipe_type == SP_KILL_TRAP)
2828 project(0, 0, ny, nx, 0, GF_KILL_TRAP,
2829 (PROJECT_JUMP | PROJECT_HIDE | PROJECT_GRID | PROJECT_ITEM), -1);
2833 if (snipe_type == SP_EVILNESS)
2835 cave[ny][nx].info &= ~(CAVE_GLOW | CAVE_MARK);
2840 /* Save the old location */
2844 /* Save the new location */
2848 /* Monster here, Try to hit it */
2849 if (cave[y][x].m_idx)
2851 cave_type *c_mon_ptr = &cave[y][x];
2853 monster_type *m_ptr = &m_list[c_mon_ptr->m_idx];
2854 monster_race *r_ptr = &r_info[m_ptr->r_idx];
2856 /* Check the visibility */
2857 visible = m_ptr->ml;
2859 /* Note the collision */
2862 if (MON_CSLEEP(m_ptr))
2864 if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_COMPASSION, -1);
2865 if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_HONOUR, -1);
2868 if ((r_ptr->level + 10) > p_ptr->lev)
2870 int now_exp = p_ptr->weapon_exp[0][j_ptr->sval];
2871 if (now_exp < s_info[p_ptr->pclass].w_max[0][j_ptr->sval])
2874 if (now_exp < WEAPON_EXP_BEGINNER) amount = 80;
2875 else if (now_exp < WEAPON_EXP_SKILLED) amount = 25;
2876 else if ((now_exp < WEAPON_EXP_EXPERT) && (p_ptr->lev > 19)) amount = 10;
2877 else if (p_ptr->lev > 34) amount = 2;
2878 p_ptr->weapon_exp[0][j_ptr->sval] += amount;
2879 p_ptr->update |= (PU_BONUS);
2885 if ((p_ptr->skill_exp[GINOU_RIDING] < s_info[p_ptr->pclass].s_max[GINOU_RIDING])
2886 && ((p_ptr->skill_exp[GINOU_RIDING] - (RIDING_EXP_BEGINNER * 2)) / 200 < r_info[m_list[p_ptr->riding].r_idx].level)
2889 p_ptr->skill_exp[GINOU_RIDING] += 1;
2890 p_ptr->update |= (PU_BONUS);
2894 /* Did we hit it (penalize range) */
2895 if (test_hit_fire(chance - cur_dis, m_ptr, m_ptr->ml, o_name))
2898 int tdam = tdam_base;
2900 /* Get extra damage from concentration */
2901 if (p_ptr->concent) tdam = boost_concentration_damage(tdam);
2903 /* Handle unseen monster */
2906 /* Invisible monster */
2907 msg_format(_("%sが敵を捕捉した。", "The %s finds a mark."), o_name);
2910 /* Handle visible monster */
2913 GAME_TEXT m_name[MAX_NLEN];
2915 /* Get "the monster" or "it" */
2916 monster_desc(m_name, m_ptr, 0);
2918 msg_format(_("%sが%sに命中した。", "The %s hits %s."), o_name, m_name);
2922 if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
2923 health_track(c_mon_ptr->m_idx);
2927 if (snipe_type == SP_NEEDLE)
2929 if ((randint1(randint1(r_ptr->level / (3 + p_ptr->concent)) + (8 - p_ptr->concent)) == 1)
2930 && !(r_ptr->flags1 & RF1_UNIQUE) && !(r_ptr->flags7 & RF7_UNIQUE2))
2932 GAME_TEXT m_name[MAX_NLEN];
2934 /* Get "the monster" or "it" */
2935 monster_desc(m_name, m_ptr, 0);
2937 tdam = m_ptr->hp + 1;
2938 msg_format(_("%sの急所に突き刺さった!", "Your shot sticked on a fatal spot of %s!"), m_name);
2944 /* Apply special damage */
2945 tdam = tot_dam_aux_shot(q_ptr, tdam, m_ptr);
2946 tdam = critical_shot(q_ptr->weight, q_ptr->to_h, j_ptr->to_h, tdam);
2948 /* No negative damage */
2949 if (tdam < 0) tdam = 0;
2951 /* Modify the damage */
2952 tdam = mon_damage_mod(m_ptr, tdam, FALSE);
2955 msg_format_wizard(CHEAT_MONSTER,
2956 _("%dのダメージを与えた。(残りHP %d/%d(%d))", "You do %d damage. (left HP %d/%d(%d))"),
2957 tdam, m_ptr->hp - tdam, m_ptr->maxhp, m_ptr->max_maxhp);
2960 if (snipe_type == SP_EXPLODE)
2962 u16b flg = (PROJECT_STOP | PROJECT_JUMP | PROJECT_KILL | PROJECT_GRID);
2964 sound(SOUND_EXPLODE); /* No explode sound - use breath fire instead */
2965 project(0, ((p_ptr->concent + 1) / 2 + 1), ny, nx, tdam, GF_MISSILE, flg, -1);
2970 if (snipe_type == SP_HOLYNESS)
2972 cave[ny][nx].info |= (CAVE_GLOW);
2977 /* Hit the monster, check for death */
2978 if (mon_take_hit(c_mon_ptr->m_idx, tdam, &fear, extract_note_dies(real_r_idx(m_ptr))))
2987 if (object_is_fixed_artifact(q_ptr) &&
2988 (p_ptr->pclass != CLASS_SNIPER || p_ptr->concent == 0))
2990 GAME_TEXT m_name[MAX_NLEN];
2992 monster_desc(m_name, m_ptr, 0);
2995 msg_format(_("%sは%sに突き刺さった!", "%^s have stuck into %s!"),o_name, m_name);
2998 message_pain(c_mon_ptr->m_idx, tdam);
3000 /* Anger the monster */
3001 if (tdam > 0) anger_monster(m_ptr);
3003 if (fear && m_ptr->ml)
3005 GAME_TEXT m_name[MAX_NLEN];
3007 monster_desc(m_name, m_ptr, 0);
3008 msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), m_name);
3011 set_target(m_ptr, p_ptr->y, p_ptr->x);
3014 if (snipe_type == SP_RUSH)
3016 int n = randint1(5) + 3;
3017 MONSTER_IDX m_idx = c_mon_ptr->m_idx;
3019 for ( ; cur_dis <= tdis; )
3026 /* Calculate the new location (see "project()") */
3027 mmove2(&ny, &nx, p_ptr->y, p_ptr->x, ty, tx);
3029 /* Stopped by wilderness boundary */
3030 if (!in_bounds2(ny, nx)) break;
3032 /* Stopped by walls/doors */
3033 if (!player_can_enter(cave[ny][nx].feat, 0)) break;
3035 /* Stopped by monsters */
3036 if (!cave_empty_bold(ny, nx)) break;
3038 cave[ny][nx].m_idx = m_idx;
3039 cave[oy][ox].m_idx = 0;
3044 update_monster(c_mon_ptr->m_idx, TRUE);
3050 Term_xtra(TERM_XTRA_DELAY, msec);
3062 if (snipe_type == SP_PIERCE)
3064 if(p_ptr->concent < 1) break;
3074 /* Chance of breakage (during attacks) */
3075 j = (hit_body ? breakage_chance(q_ptr) : 0);
3079 MONSTER_IDX m_idx = cave[y][x].m_idx;
3080 monster_type *m_ptr = &m_list[m_idx];
3081 OBJECT_IDX o_idx = o_pop();
3085 msg_format(_("%sはどこかへ行った。", "The %s have gone to somewhere."), o_name);
3086 if (object_is_fixed_artifact(q_ptr))
3088 a_info[j_ptr->name1].cur_num = 0;
3093 o_ptr = &o_list[o_idx];
3094 object_copy(o_ptr, q_ptr);
3097 o_ptr->marked &= OM_TOUCHED;
3099 /* Forget location */
3100 o_ptr->iy = o_ptr->ix = 0;
3102 /* Memorize monster */
3103 o_ptr->held_m_idx = m_idx;
3106 o_ptr->next_o_idx = m_ptr->hold_o_idx;
3109 m_ptr->hold_o_idx = o_idx;
3111 else if (cave_have_flag_bold(y, x, FF_PROJECT))
3113 /* Drop (or break) near that location */
3114 (void)drop_near(q_ptr, j, y, x);
3118 /* Drop (or break) near that location */
3119 (void)drop_near(q_ptr, j, prev_y, prev_x);
3122 /* Sniper - Repeat shooting when double shots */
3125 /* Sniper - Loose his/her concentration after any shot */
3126 if (p_ptr->concent) reset_concentration(FALSE);
3130 * @brief 射撃処理のメインルーチン
3133 void do_cmd_fire(void)
3136 object_type *j_ptr, *ammo_ptr;
3139 if(p_ptr->wild_mode) return;
3141 is_fired = FALSE; /* not fired yet */
3143 /* Get the "bow" (if any) */
3144 j_ptr = &inventory[INVEN_BOW];
3146 /* Require a launcher */
3149 msg_print(_("射撃用の武器を持っていない。", "You have nothing to fire with."));
3154 if (j_ptr->sval == SV_CRIMSON)
3156 msg_print(_("この武器は発動して使うもののようだ。", "Do activate."));
3161 if (j_ptr->sval == SV_HARP)
3163 msg_print(_("この武器で射撃はできない。", "It's not for firing."));
3169 if (p_ptr->special_defense & KATA_MUSOU)
3171 set_action(ACTION_NONE);
3174 /* Require proper missile */
3175 item_tester_tval = p_ptr->tval_ammo;
3177 q = _("どれを撃ちますか? ", "Fire which item? ");
3178 s = _("発射されるアイテムがありません。", "You have nothing to fire.");
3181 ammo_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
3189 do_cmd_fire_aux(item, j_ptr);
3191 if (!is_fired || p_ptr->pclass != CLASS_SNIPER) return;
3193 /* Sniper actions after some shootings */
3194 if (snipe_type == SP_AWAY)
3196 teleport_player(10 + (p_ptr->concent * 2), 0L);
3198 if (snipe_type == SP_FINAL)
3200 msg_print(_("射撃の反動が体を襲った。", "A reactionary of shooting attacked you. "));
3201 (void)set_slow(p_ptr->slow + randint0(7) + 7, FALSE);
3202 (void)set_stun(p_ptr->stun + randint1(25));
3208 * @brief 投射処理メインルーチン /
3209 * Throw an object from the pack or floor.
3211 * @param boomerang ブーメラン処理ならばTRUE
3212 * @param shuriken 忍者の手裏剣処理ならばTRUE
3213 * @return ターンを消費した場合TRUEを返す
3216 * Note: "unseen" monsters are very hard to hit.
3218 * Should throwing a weapon do full damage? Should it allow the magic
3219 * to hit bonus of the weapon to have an effect? Should it ever cause
3220 * the item to be destroyed? Should it do any damage at all?
3223 bool do_cmd_throw(int mult, bool boomerang, OBJECT_IDX shuriken)
3228 POSITION y, x, ty, tx, prev_y, prev_x;
3229 POSITION ny[19], nx[19];
3230 int chance, tdam, tdis;
3231 int mul, div, dd, ds;
3232 int cur_dis, visible;
3239 bool hit_body = FALSE;
3240 bool hit_wall = FALSE;
3241 bool equiped_item = FALSE;
3242 bool return_when_thrown = FALSE;
3244 GAME_TEXT o_name[MAX_NLEN];
3246 int msec = delay_factor * delay_factor * delay_factor;
3248 BIT_FLAGS flgs[TR_FLAG_SIZE];
3250 bool come_back = FALSE;
3251 bool do_drop = TRUE;
3253 if (p_ptr->wild_mode) return FALSE;
3255 if (p_ptr->special_defense & KATA_MUSOU)
3257 set_action(ACTION_NONE);
3263 o_ptr = &inventory[item];
3267 if (buki_motteruka(INVEN_RARM) && buki_motteruka(INVEN_LARM))
3269 item_tester_hook = item_tester_hook_boomerang;
3270 q = _("どの武器を投げますか? ", "Throw which item? ");
3271 s = _("投げる武器がない。", "You have nothing to throw.");
3272 o_ptr = choose_object(&item, q, s, (USE_EQUIP));
3279 else if (buki_motteruka(INVEN_LARM))
3282 o_ptr = &inventory[item];
3287 o_ptr = &inventory[item];
3292 q = _("どのアイテムを投げますか? ", "Throw which item? ");
3293 s = _("投げるアイテムがない。", "You have nothing to throw.");
3294 o_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP));
3302 /* Item is cursed */
3303 if (object_is_cursed(o_ptr) && (item >= INVEN_RARM))
3305 msg_print(_("ふーむ、どうやら呪われているようだ。", "Hmmm, it seems to be cursed."));
3310 if (p_ptr->inside_arena && !boomerang)
3312 if (o_ptr->tval != TV_SPIKE)
3314 msg_print(_("アリーナではアイテムを使えない!", "You're in the arena now. This is hand-to-hand!"));
3323 /* Obtain a local object */
3324 object_copy(q_ptr, o_ptr);
3326 /* Extract the thrown object's flags. */
3327 object_flags(q_ptr, flgs);
3328 torch_flags(q_ptr, flgs);
3330 /* Distribute the charges of rods/wands between the stacks */
3331 distribute_charges(o_ptr, q_ptr, 1);
3336 object_desc(o_name, q_ptr, OD_OMIT_PREFIX);
3338 if (p_ptr->mighty_throw) mult += 3;
3340 /* Extract a "distance multiplier" */
3341 /* Changed for 'launcher' mutation */
3342 mul = 10 + 2 * (mult - 1);
3344 /* Enforce a minimum "weight" of one pound */
3345 div = ((q_ptr->weight > 10) ? q_ptr->weight : 10);
3346 if ((have_flag(flgs, TR_THROW)) || boomerang) div /= 2;
3348 /* Hack -- Distance -- Reward strength, penalize weight */
3349 tdis = (adj_str_blow[p_ptr->stat_ind[A_STR]] + 20) * mul / div;
3351 /* Max distance of 10-18 */
3352 if (tdis > mul) tdis = mul;
3356 ty = randint0(101) - 50 + p_ptr->y;
3357 tx = randint0(101) - 50 + p_ptr->x;
3361 project_length = tdis + 1;
3363 /* Get a direction (or cancel) */
3364 if (!get_aim_dir(&dir)) return FALSE;
3366 /* Predict the "target" location */
3367 tx = p_ptr->x + 99 * ddx[dir];
3368 ty = p_ptr->y + 99 * ddy[dir];
3370 /* Check for "target request" */
3371 if ((dir == 5) && target_okay())
3377 project_length = 0; /* reset to default */
3380 if ((q_ptr->name1 == ART_MJOLLNIR) ||
3381 (q_ptr->name1 == ART_AEGISFANG) || boomerang)
3382 return_when_thrown = TRUE;
3384 /* Reduce and describe inventory */
3387 inven_item_increase(item, -1);
3388 if (!return_when_thrown)
3389 inven_item_describe(item);
3390 inven_item_optimize(item);
3393 /* Reduce and describe floor item */
3396 floor_item_increase(0 - item, -1);
3397 floor_item_optimize(0 - item);
3399 if (item >= INVEN_RARM)
3401 equiped_item = TRUE;
3402 p_ptr->redraw |= (PR_EQUIPPY);
3405 p_ptr->energy_use = 100;
3407 /* Rogue and Ninja gets bonus */
3408 if ((p_ptr->pclass == CLASS_ROGUE) || (p_ptr->pclass == CLASS_NINJA))
3409 p_ptr->energy_use -= p_ptr->lev;
3411 /* Start at the player */
3417 if ((p_ptr->pclass == CLASS_NINJA) && ((q_ptr->tval == TV_SPIKE) || ((have_flag(flgs, TR_THROW)) && (q_ptr->tval == TV_SWORD)))) shuriken = TRUE;
3418 else shuriken = FALSE;
3420 /* Chance of hitting */
3421 if (have_flag(flgs, TR_THROW)) chance = ((p_ptr->skill_tht) +
3422 ((p_ptr->to_h_b + q_ptr->to_h) * BTH_PLUS_ADJ));
3423 else chance = (p_ptr->skill_tht + (p_ptr->to_h_b * BTH_PLUS_ADJ));
3425 if (shuriken) chance *= 2;
3427 /* Save the old location */
3431 /* Travel until stopped */
3432 for (cur_dis = 0; cur_dis <= tdis; )
3434 /* Hack -- Stop at the target */
3435 if ((y == ty) && (x == tx)) break;
3437 /* Calculate the new location (see "project()") */
3440 mmove2(&ny[cur_dis], &nx[cur_dis], p_ptr->y, p_ptr->x, ty, tx);
3442 /* Stopped by walls/doors */
3443 if (!cave_have_flag_bold(ny[cur_dis], nx[cur_dis], FF_PROJECT))
3446 if ((q_ptr->tval == TV_FIGURINE) || object_is_potion(q_ptr) || !cave[ny[cur_dis]][nx[cur_dis]].m_idx) break;
3449 /* The player can see the (on screen) missile */
3450 if (panel_contains(ny[cur_dis], nx[cur_dis]) && player_can_see_bold(ny[cur_dis], nx[cur_dis]))
3452 SYMBOL_CODE c = object_char(q_ptr);
3453 TERM_COLOR a = object_attr(q_ptr);
3455 /* Draw, Hilite, Fresh, Pause, Erase */
3456 print_rel(c, a, ny[cur_dis], nx[cur_dis]);
3457 move_cursor_relative(ny[cur_dis], nx[cur_dis]);
3459 Term_xtra(TERM_XTRA_DELAY, msec);
3460 lite_spot(ny[cur_dis], nx[cur_dis]);
3464 /* The player cannot see the missile */
3467 /* Pause anyway, for consistancy */
3468 Term_xtra(TERM_XTRA_DELAY, msec);
3471 /* Save the old location */
3475 /* Save the new location */
3479 /* Advance the distance */
3482 /* Monster here, Try to hit it */
3483 if (cave[y][x].m_idx)
3485 cave_type *c_ptr = &cave[y][x];
3486 monster_type *m_ptr = &m_list[c_ptr->m_idx];
3488 /* Check the visibility */
3489 visible = m_ptr->ml;
3491 /* Note the collision */
3494 /* Did we hit it (penalize range) */
3495 if (test_hit_fire(chance - cur_dis, m_ptr, m_ptr->ml, o_name))
3499 /* Handle unseen monster */
3502 /* Invisible monster */
3503 msg_format(_("%sが敵を捕捉した。", "The %s finds a mark."), o_name);
3506 /* Handle visible monster */
3509 GAME_TEXT m_name[MAX_NLEN];
3510 monster_desc(m_name, m_ptr, 0);
3511 msg_format(_("%sが%sに命中した。", "The %s hits %s."), o_name, m_name);
3515 if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
3516 health_track(c_ptr->m_idx);
3520 /* Hack -- Base damage from thrown object */
3523 torch_dice(q_ptr, &dd, &ds); /* throwing a torch */
3524 tdam = damroll(dd, ds);
3525 /* Apply special damage */
3526 tdam = tot_dam_aux(q_ptr, tdam, m_ptr, 0, TRUE);
3527 tdam = critical_shot(q_ptr->weight, q_ptr->to_h, 0, tdam);
3528 if (q_ptr->to_d > 0)
3529 tdam += q_ptr->to_d;
3531 tdam += -q_ptr->to_d;
3535 tdam *= (mult+p_ptr->num_blow[item - INVEN_RARM]);
3536 tdam += p_ptr->to_d_m;
3538 else if (have_flag(flgs, TR_THROW))
3541 tdam += p_ptr->to_d_m;
3549 tdam += ((p_ptr->lev+30)*(p_ptr->lev+30)-900)/55;
3552 /* No negative damage */
3553 if (tdam < 0) tdam = 0;
3555 /* Modify the damage */
3556 tdam = mon_damage_mod(m_ptr, tdam, FALSE);
3558 msg_format_wizard(CHEAT_MONSTER, _("%dのダメージを与えた。(残りHP %d/%d(%d))", "You do %d damage. (left HP %d/%d(%d))"),
3559 tdam, m_ptr->hp - tdam, m_ptr->maxhp, m_ptr->max_maxhp);
3561 /* Hit the monster, check for death */
3562 if (mon_take_hit(c_ptr->m_idx, tdam, &fear, extract_note_dies(real_r_idx(m_ptr))))
3570 message_pain(c_ptr->m_idx, tdam);
3572 /* Anger the monster */
3573 if ((tdam > 0) && !object_is_potion(q_ptr))
3574 anger_monster(m_ptr);
3576 if (fear && m_ptr->ml)
3579 GAME_TEXT m_name[MAX_NLEN];
3580 monster_desc(m_name, m_ptr, 0);
3581 msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), m_name);
3591 /* decrease toach's fuel */
3592 if (hit_body) torch_lost_fuel(q_ptr);
3594 /* Chance of breakage (during attacks) */
3595 j = (hit_body ? breakage_chance(q_ptr) : 0);
3597 /* Figurines transform */
3598 if ((q_ptr->tval == TV_FIGURINE) && !(p_ptr->inside_arena))
3602 if (!(summon_named_creature(0, y, x, q_ptr->pval, !(object_is_cursed(q_ptr)) ? PM_FORCE_PET : 0L)))
3603 msg_print(_("人形は捻じ曲がり砕け散ってしまった!", "The Figurine writhes and then shatters."));
3604 else if (object_is_cursed(q_ptr))
3605 msg_print(_("これはあまり良くない気がする。", "You have a bad feeling about this."));
3610 /* Potions smash open */
3611 if (object_is_potion(q_ptr))
3613 if (hit_body || hit_wall || (randint1(100) < j))
3615 msg_format(_("%sは砕け散った!", "The %s shatters!"), o_name);
3617 if (potion_smash_effect(0, y, x, q_ptr->k_idx))
3619 monster_type *m_ptr = &m_list[cave[y][x].m_idx];
3621 /* ToDo (Robert): fix the invulnerability */
3622 if (cave[y][x].m_idx &&
3623 is_friendly(&m_list[cave[y][x].m_idx]) &&
3624 !MON_INVULNER(m_ptr))
3626 GAME_TEXT m_name[MAX_NLEN];
3627 monster_desc(m_name, &m_list[cave[y][x].m_idx], 0);
3628 msg_format(_("%sは怒った!", "%^s gets angry!"), m_name);
3629 set_hostile(&m_list[cave[y][x].m_idx]);
3640 if (return_when_thrown)
3642 int back_chance = randint1(30)+20+((int)(adj_dex_th[p_ptr->stat_ind[A_DEX]]) - 128);
3643 char o2_name[MAX_NLEN];
3644 bool super_boomerang = (((q_ptr->name1 == ART_MJOLLNIR) || (q_ptr->name1 == ART_AEGISFANG)) && boomerang);
3647 if (boomerang) back_chance += 4+randint1(5);
3648 if (super_boomerang) back_chance += 100;
3649 object_desc(o2_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
3651 if((back_chance > 30) && (!one_in_(100) || super_boomerang))
3653 for (i = cur_dis - 1; i > 0; i--)
3655 if (panel_contains(ny[i], nx[i]) && player_can_see_bold(ny[i], nx[i]))
3657 char c = object_char(q_ptr);
3658 byte a = object_attr(q_ptr);
3660 /* Draw, Hilite, Fresh, Pause, Erase */
3661 print_rel(c, a, ny[i], nx[i]);
3662 move_cursor_relative(ny[i], nx[i]);
3664 Term_xtra(TERM_XTRA_DELAY, msec);
3665 lite_spot(ny[i], nx[i]);
3670 /* Pause anyway, for consistancy */
3671 Term_xtra(TERM_XTRA_DELAY, msec);
3674 if((back_chance > 37) && !p_ptr->blind && (item >= 0))
3676 msg_format(_("%sが手元に返ってきた。", "%s comes back to you."), o2_name);
3683 msg_format(_("%sを受け損ねた!", "%s backs, but you can't catch!"), o2_name);
3687 msg_format(_("%sが返ってきた。", "%s comes back."), o2_name);
3695 msg_format(_("%sが返ってこなかった!", "%s doesn't back!"), o2_name);
3701 if (item == INVEN_RARM || item == INVEN_LARM)
3703 /* Access the wield slot */
3704 o_ptr = &inventory[item];
3706 /* Wear the new stuff */
3707 object_copy(o_ptr, q_ptr);
3709 p_ptr->total_weight += q_ptr->weight;
3711 /* Increment the equip counter by hand */
3714 /* Recalculate torch */
3715 p_ptr->update |= (PU_BONUS | PU_TORCH | PU_MANA);
3716 p_ptr->window |= (PW_EQUIP);
3724 else if (equiped_item)
3732 if (cave_have_flag_bold(y, x, FF_PROJECT))
3734 (void)drop_near(q_ptr, j, y, x);
3738 (void)drop_near(q_ptr, j, prev_y, prev_x);
3748 * Hack: travel command
3750 #define TRAVEL_UNABLE 9999
3752 static int flow_head = 0;
3753 static int flow_tail = 0;
3754 static POSITION temp2_x[MAX_SHORT];
3755 static POSITION temp2_y[MAX_SHORT];
3758 * @brief トラベル処理の記憶配列を初期化する Hack: forget the "flow" information
3761 void forget_travel_flow(void)
3764 /* Check the entire dungeon / Forget the old data */
3765 for (y = 0; y < cur_hgt; y++)
3767 for (x = 0; x < cur_wid; x++)
3770 travel.cost[y][x] = MAX_SHORT;
3773 travel.y = travel.x = 0;
3777 * @brief トラベル処理中に地形に応じた移動コスト基準を返す
3782 static int travel_flow_cost(POSITION y, POSITION x)
3784 feature_type *f_ptr = &f_info[cave[y][x].feat];
3787 /* Avoid obstacles (ex. trees) */
3788 if (have_flag(f_ptr->flags, FF_AVOID_RUN)) cost += 1;
3791 if (have_flag(f_ptr->flags, FF_WATER))
3793 if (have_flag(f_ptr->flags, FF_DEEP) && !p_ptr->levitation) cost += 5;
3797 if (have_flag(f_ptr->flags, FF_LAVA))
3800 if (!p_ptr->resist_fire) lava *= 2;
3801 if (!p_ptr->levitation) lava *= 2;
3802 if (have_flag(f_ptr->flags, FF_DEEP)) lava *= 2;
3807 /* Detected traps and doors */
3808 if (cave[y][x].info & (CAVE_MARK))
3810 if (have_flag(f_ptr->flags, FF_DOOR)) cost += 1;
3811 if (have_flag(f_ptr->flags, FF_TRAP)) cost += 10;
3818 * @brief トラベル処理の到達地点までの行程を得る処理のサブルーチン
3822 * @param wall プレイヤーが壁の中にいるならばTRUE
3825 static void travel_flow_aux(POSITION y, POSITION x, int n, bool wall)
3827 cave_type *c_ptr = &cave[y][x];
3828 feature_type *f_ptr = &f_info[c_ptr->feat];
3829 int old_head = flow_head;
3831 int base_cost = (n % TRAVEL_UNABLE);
3832 int from_wall = (n / TRAVEL_UNABLE);
3835 /* Ignore out of bounds */
3836 if (!in_bounds(y, x)) return;
3838 /* Ignore unknown grid except in wilderness */
3839 if (dun_level > 0 && !(c_ptr->info & CAVE_KNOWN)) return;
3841 /* Ignore "walls" and "rubble" (include "secret doors") */
3842 if (have_flag(f_ptr->flags, FF_WALL) ||
3843 have_flag(f_ptr->flags, FF_CAN_DIG) ||
3844 (have_flag(f_ptr->flags, FF_DOOR) && cave[y][x].mimic) ||
3845 (!have_flag(f_ptr->flags, FF_MOVE) && have_flag(f_ptr->flags, FF_CAN_FLY) && !p_ptr->levitation))
3847 if (!wall || !from_wall) return;
3848 add_cost += TRAVEL_UNABLE;
3852 add_cost = travel_flow_cost(y, x);
3855 cost = base_cost + add_cost;
3857 /* Ignore lower cost entries */
3858 if (travel.cost[y][x] <= cost) return;
3860 /* Save the flow cost */
3861 travel.cost[y][x] = cost;
3863 /* Enqueue that entry */
3864 temp2_y[flow_head] = y;
3865 temp2_x[flow_head] = x;
3867 /* Advance the queue */
3868 if (++flow_head == MAX_SHORT) flow_head = 0;
3870 /* Hack -- notice overflow by forgetting new entry */
3871 if (flow_head == flow_tail) flow_head = old_head;
3877 * @brief トラベル処理の到達地点までの行程を得る処理のメインルーチン
3878 * @param ty 目標地点のY座標
3879 * @param tx 目標地点のX座標
3882 static void travel_flow(POSITION ty, POSITION tx)
3886 feature_type *f_ptr = &f_info[cave[p_ptr->y][p_ptr->x].feat];
3888 /* Reset the "queue" */
3889 flow_head = flow_tail = 0;
3891 /* is player in the wall? */
3892 if (!have_flag(f_ptr->flags, FF_MOVE)) wall = TRUE;
3894 /* Start at the target grid */
3895 travel_flow_aux(ty, tx, 0, wall);
3897 /* Now process the queue */
3898 while (flow_head != flow_tail)
3900 /* Extract the next entry */
3901 y = temp2_y[flow_tail];
3902 x = temp2_x[flow_tail];
3904 /* Forget that entry */
3905 if (++flow_tail == MAX_SHORT) flow_tail = 0;
3907 /* Ignore too far entries */
3908 //if (distance(ty, tx, y, x) > 100) continue;
3910 /* Add the "children" */
3911 for (d = 0; d < 8; d++)
3913 /* Add that child if "legal" */
3914 travel_flow_aux(y + ddy_ddd[d], x + ddx_ddd[d], travel.cost[y][x], wall);
3918 /* Forget the flow info */
3919 flow_head = flow_tail = 0;
3923 * @brief トラベル処理のメインルーチン
3926 void do_cmd_travel(void)
3930 POSITION dx, dy, sx, sy;
3931 feature_type *f_ptr;
3933 if (travel.x != 0 && travel.y != 0 &&
3934 get_check(_("トラベルを継続しますか?", "Do you continue to travel?")))
3939 else if (!tgt_pt(&x, &y)) return;
3941 if ((x == p_ptr->x) && (y == p_ptr->y))
3943 msg_print(_("すでにそこにいます!", "You are already there!!"));
3947 f_ptr = &f_info[cave[y][x].feat];
3949 if ((cave[y][x].info & CAVE_MARK) &&
3950 (have_flag(f_ptr->flags, FF_WALL) ||
3951 have_flag(f_ptr->flags, FF_CAN_DIG) ||
3952 (have_flag(f_ptr->flags, FF_DOOR) && cave[y][x].mimic)))
3954 msg_print(_("そこには行くことができません!", "You cannot travel there!"));
3958 forget_travel_flow();
3964 /* Travel till 255 steps */
3970 /* Decides first direction */
3971 dx = abs(p_ptr->x - x);
3972 dy = abs(p_ptr->y - y);
3973 sx = ((x == p_ptr->x) || (dx < dy)) ? 0 : ((x > p_ptr->x) ? 1 : -1);
3974 sy = ((y == p_ptr->y) || (dy < dx)) ? 0 : ((y > p_ptr->y) ? 1 : -1);
3976 for (i = 1; i <= 9; i++)
3978 if ((sx == ddx[i]) && (sy == ddy[i])) travel.dir = i;