X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fcmd2.c;h=6fc56c19cbe390eadf20035967f7259da6fcf7d4;hb=c9ae69fc940e86829baed7a9bcb5a54f03f1fb2e;hp=d3149bc3b04093be7d7fef1ba5eb991a630d3c63;hpb=245e1034927f5651cd696dcb88949c22dc8311f6;p=hengband%2Fhengband.git diff --git a/src/cmd2.c b/src/cmd2.c index d3149bc3b..6fc56c19c 100644 --- a/src/cmd2.c +++ b/src/cmd2.c @@ -1,6 +1,8 @@ -/* File: cmd2.c */ - -/* +/*! + * @file cmd2.c + * @brief プレイヤーのコマンド処理2 / Movement commands (part 2) + * @date 2014/01/02 + * @author * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke * * This software may be copied and distributed for educational, research, @@ -8,18 +10,54 @@ * are included in all such copies. Other copyrights may also apply. */ -/* Purpose: Movement commands (part 2) */ - #include "angband.h" -/* - * Go up one level +/*! + * @brief フロア脱出時に出戻りが不可能だった場合に警告を加える処理 + * @param down_stair TRUEならば階段を降りる処理、FALSEなら階段を昇る処理による内容 + * @return フロア移動を実際に行うならTRUE、キャンセルする場合はFALSE + */ +bool confirm_leave_level(bool down_stair) +{ + quest_type *q_ptr = &quest[p_ptr->inside_quest]; + + /* Confirm leaving from once only quest */ + if (confirm_quest && p_ptr->inside_quest && + (q_ptr->type == QUEST_TYPE_RANDOM || + (q_ptr->flags & QUEST_FLAG_ONCE && + q_ptr->status != QUEST_STATUS_COMPLETED) || + (q_ptr->flags & QUEST_FLAG_TOWER && + ((q_ptr->status != QUEST_STATUS_STAGE_COMPLETED) || + (down_stair && (quest[QUEST_TOWER1].status != QUEST_STATUS_COMPLETED)))))) + { +#ifdef JP + msg_print("この階を一度去ると二度と戻って来られません。"); + if (get_check("本当にこの階を去りますか?")) return TRUE; +#else + msg_print("You can't come back here once you leave this floor."); + if (get_check("Really leave this floor? ")) return TRUE; +#endif + } + else + { + return TRUE; + } + return FALSE; +} + +/*! + * @brief 階段を使って階層を昇る処理 / Go up one level + * @return なし */ void do_cmd_go_up(void) { bool go_up = FALSE; - cave_type *c_ptr; + + /* Player grid */ + cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x]; + feature_type *f_ptr = &f_info[c_ptr->feat]; + int up_num = 0; if (p_ptr->special_defense & KATA_MUSOU) @@ -27,18 +65,26 @@ void do_cmd_go_up(void) set_action(ACTION_NONE); } - /* Player grid */ - c_ptr = &cave[py][px]; + /* Verify stairs */ + if (!have_flag(f_ptr->flags, FF_LESS)) + { + msg_print(_("ここには上り階段が見当たらない。", "I see no up staircase here.")); + return; + } /* Quest up stairs */ - if (c_ptr->feat == FEAT_QUEST_UP) + if (have_flag(f_ptr->flags, FF_QUEST)) { + /* Cancel the command */ + if (!confirm_leave_level(FALSE)) return; + + /* Success */ #ifdef JP if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)) - msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª"); + msg_print("なんだこの階段は!"); else - msg_print("¾å¤Î³¬¤ËÅФä¿¡£"); + msg_print("上の階に登った。"); #else msg_print("You enter the up staircase."); #endif @@ -50,6 +96,11 @@ void do_cmd_go_up(void) /* Activate the quest */ if (!quest[p_ptr->inside_quest].status) { + if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM) + { + init_flags = INIT_ASSIGN; + process_dungeon_file("q_info.txt", 0, 0, 0, 0); + } quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN; } @@ -61,93 +112,69 @@ void do_cmd_go_up(void) /* Leaving */ p_ptr->leaving = TRUE; - p_ptr->leftbldg = TRUE; p_ptr->oldpx = 0; p_ptr->oldpy = 0; + + /* Hack -- take a turn */ + p_ptr->energy_use = 100; /* End the command */ return; } - /* Normal up stairs? */ - if (c_ptr->feat != FEAT_LESS && c_ptr->feat != FEAT_LESS_LESS) - { -#ifdef JP - msg_print("¤³¤³¤Ë¤Ï¾å¤ê³¬Ãʤ¬¸«Åö¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("I see no up staircase here."); -#endif - - return; - } - if (!dun_level) { go_up = TRUE; } else { - quest_type *q_ptr = &quest[p_ptr->inside_quest]; - - /* Confirm leaving from once only quest */ - if (confirm_quest && p_ptr->inside_quest && - (q_ptr->type == QUEST_TYPE_RANDOM || - (q_ptr->flags & QUEST_FLAG_ONCE && - q_ptr->status != QUEST_STATUS_COMPLETED))) - { -#ifdef JP - msg_print("¤³¤Î³¬¤ò°ìÅÙµî¤ë¤ÈÆóÅÙ¤ÈÌá¤Ã¤ÆÍè¤é¤ì¤Þ¤»¤ó¡£"); - if (get_check("ËÜÅö¤Ë¤³¤Î³¬¤òµî¤ê¤Þ¤¹¤«¡©")) go_up = TRUE; -#else - msg_print("You can't come back here once you leave this floor."); - if (get_check("Really leave this floor? ")) go_up = TRUE; -#endif - } - else - { - go_up = TRUE; - } + go_up = confirm_leave_level(FALSE); } /* Cancel the command */ if (!go_up) return; /* Hack -- take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; if (autosave_l) do_cmd_save_game(TRUE); - if (p_ptr->inside_quest) + /* For a random quest */ + if (p_ptr->inside_quest && + quest[p_ptr->inside_quest].type == QUEST_TYPE_RANDOM) { leave_quest_check(); - if (quest[leaving_quest].type != QUEST_TYPE_RANDOM) - { - p_ptr->inside_quest = c_ptr->special; - dun_level = 0; - } - else - { - p_ptr->inside_quest = 0; - } + p_ptr->inside_quest = 0; + } + /* For a fixed quest */ + if (p_ptr->inside_quest && + quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM) + { + leave_quest_check(); + + p_ptr->inside_quest = c_ptr->special; + dun_level = 0; up_num = 0; } + + /* For normal dungeon and random quest */ else { /* New depth */ - if (c_ptr->feat == FEAT_LESS_LESS) + if (have_flag(f_ptr->flags, FF_SHAFT)) { /* Create a way back */ - prepare_change_floor_mode(CFM_UP | CFM_SHAFT); + prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP | CFM_SHAFT); up_num = 2; } else { /* Create a way back */ - prepare_change_floor_mode(CFM_UP); + prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP); up_num = 1; } @@ -156,39 +183,31 @@ void do_cmd_go_up(void) if (dun_level - up_num < d_info[dungeon_type].mindepth) up_num = dun_level; } - -#ifdef JP - if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, "³¬Ãʤò¾å¤Ã¤¿"); -#else - if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, "go up the stairs to"); -#endif + if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, _("階段を上った", "climbed up the stairs to")); /* Success */ -#ifdef JP if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)) - msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª"); + msg_print(_("なんだこの階段は!", "")); else if (up_num == dun_level) - msg_print("ÃϾå¤ËÌá¤Ã¤¿¡£"); - else - msg_print("³¬Ãʤò¾å¤Ã¤Æ¿·¤¿¤Ê¤ë̵ܤؤÈ­¤òƧ¤ßÆþ¤ì¤¿¡£"); -#else - if (up_num == dun_level) - msg_print("You go back to the surface."); + msg_print(_("地上に戻った。", "You go back to the surface.")); else - msg_print("You enter a maze of up staircases."); -#endif + msg_print(_("階段を上って新たなる迷宮へと足を踏み入れた。", "You enter a maze of up staircases.")); /* Leaving */ p_ptr->leaving = TRUE; } -/* - * Go down one level +/*! + * @brief 階段を使って階層を降りる処理 / Go down one level + * @return なし */ void do_cmd_go_down(void) { - cave_type *c_ptr; + /* Player grid */ + cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x]; + feature_type *f_ptr = &f_info[c_ptr->feat]; + bool fall_trap = FALSE; int down_num = 0; @@ -197,31 +216,49 @@ void do_cmd_go_down(void) set_action(ACTION_NONE); } - /* Player grid */ - c_ptr = &cave[py][px]; + /* Verify stairs */ + if (!have_flag(f_ptr->flags, FF_MORE)) + { + msg_print(_("ここには下り階段が見当たらない。", "I see no down staircase here.")); + return; + } + + if (have_flag(f_ptr->flags, FF_TRAP)) fall_trap = TRUE; - if (c_ptr->feat == (FEAT_TRAP_TRAPDOOR)) fall_trap = TRUE; + /* Quest entrance */ + if (have_flag(f_ptr->flags, FF_QUEST_ENTER)) + { + do_cmd_quest(); + } /* Quest down stairs */ - if (c_ptr->feat == FEAT_QUEST_DOWN) + else if (have_flag(f_ptr->flags, FF_QUEST)) { + /* Confirm Leaving */ + if(!confirm_leave_level(TRUE)) return; + #ifdef JP if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)) - msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª"); + msg_print("なんだこの階段は!"); else - msg_print("²¼¤Î³¬¤Ë¹ß¤ê¤¿¡£"); + msg_print("下の階に降りた。"); #else msg_print("You enter the down staircase."); #endif - leave_quest_check(); + leave_tower_check(); p_ptr->inside_quest = c_ptr->special; /* Activate the quest */ if (!quest[p_ptr->inside_quest].status) { + if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM) + { + init_flags = INIT_ASSIGN; + process_dungeon_file("q_info.txt", 0, 0, 0, 0); + } quest[p_ptr->inside_quest].status = QUEST_STATUS_TAKEN; } @@ -233,109 +270,86 @@ void do_cmd_go_down(void) /* Leaving */ p_ptr->leaving = TRUE; - p_ptr->leftbldg = TRUE; p_ptr->oldpx = 0; p_ptr->oldpy = 0; + + + /* Hack -- take a turn */ + p_ptr->energy_use = 100; } - /* Verify stairs */ - else if ((c_ptr->feat != FEAT_MORE) && (c_ptr->feat != FEAT_MORE_MORE) && (c_ptr->feat != FEAT_ENTRANCE) && !fall_trap) - { -#ifdef JP - msg_print("¤³¤³¤Ë¤Ï²¼¤ê³¬Ãʤ¬¸«Åö¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("I see no down staircase here."); -#endif - return; - } else { + int target_dungeon = 0; + if (!dun_level) { - if (ironman_downward && (c_ptr->special != DUNGEON_ANGBAND)) + target_dungeon = have_flag(f_ptr->flags, FF_ENTRANCE) ? c_ptr->special : DUNGEON_ANGBAND; + + if (ironman_downward && (target_dungeon != DUNGEON_ANGBAND)) { -#ifdef JP - msg_print("¥À¥ó¥¸¥ç¥ó¤ÎÆþ¸ý¤ÏºÉ¤¬¤ì¤Æ¤¤¤ë¡ª"); -#else - msg_print("The entrance of this dungeon is closed!"); -#endif + msg_print(_("ダンジョンの入口は塞がれている!", "The entrance of this dungeon is closed!")); return; } - if (!max_dlv[c_ptr->special]) + if (!max_dlv[target_dungeon]) { -#ifdef JP - msg_format("¤³¤³¤Ë¤Ï%s¤ÎÆþ¤ê¸ý(%d³¬ÁêÅö)¤¬¤¢¤ê¤Þ¤¹", d_name+d_info[c_ptr->special].name, d_info[c_ptr->special].mindepth); - if (!get_check("ËÜÅö¤Ë¤³¤Î¥À¥ó¥¸¥ç¥ó¤ËÆþ¤ê¤Þ¤¹¤«¡©")) return; -#else - msg_format("There is the entrance of %s (Danger level: %d)", d_name+d_info[c_ptr->special].name, d_info[c_ptr->special].mindepth); - if (!get_check("Do you really get in this dungeon? ")) return; -#endif + msg_format(_("ここには%sの入り口(%d階相当)があります", "There is the entrance of %s (Danger level: %d)"), + d_name+d_info[target_dungeon].name, d_info[target_dungeon].mindepth); + if (!get_check(_("本当にこのダンジョンに入りますか?", "Do you really get in this dungeon? "))) return; } /* Save old player position */ - p_ptr->oldpx = px; - p_ptr->oldpy = py; - dungeon_type = (byte)c_ptr->special; + p_ptr->oldpx = p_ptr->x; + p_ptr->oldpy = p_ptr->y; + dungeon_type = (byte)target_dungeon; + + /* + * Clear all saved floors + * and create a first saved floor + */ + prepare_change_floor_mode(CFM_FIRST_FLOOR); } /* Hack -- take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; if (autosave_l) do_cmd_save_game(TRUE); /* Go down */ - if (c_ptr->feat == FEAT_MORE_MORE) down_num += 2; + if (have_flag(f_ptr->flags, FF_SHAFT)) down_num += 2; else down_num += 1; - if (!dun_level) { /* Enter the dungeon just now */ p_ptr->enter_dungeon = TRUE; - down_num = d_info[c_ptr->special].mindepth; + down_num = d_info[dungeon_type].mindepth; } if (record_stair) { -#ifdef JP - if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, "Í¸Í¤ËÍî¤Á¤¿"); - else do_cmd_write_nikki(NIKKI_STAIR, down_num, "³¬Ãʤò²¼¤ê¤¿"); -#else - if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, "fall from trap door"); - else do_cmd_write_nikki(NIKKI_STAIR, down_num, "go down the stairs to"); -#endif + if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, _("落とし戸に落ちた", "fell through a trap door")); + else do_cmd_write_nikki(NIKKI_STAIR, down_num, _("階段を下りた", "climbed down the stairs to")); } if (fall_trap) { -#ifdef JP - msg_print("¤ï¤¶¤ÈÍ¸Í¤ËÍî¤Á¤¿¡£"); -#else - msg_print("You deliberately jump through the trap door."); -#endif + msg_print(_("わざと落とし戸に落ちた。", "You deliberately jump through the trap door.")); } else { /* Success */ - if(c_ptr->feat == FEAT_ENTRANCE) + if (target_dungeon) { -#ifdef JP - msg_format("%s¤ØÆþ¤Ã¤¿¡£", d_text + d_info[dungeon_type].text); -#else - msg_format("You entered %s.", d_text + d_info[dungeon_type].text); -#endif + msg_format(_("%sへ入った。", "You entered %s."), d_text + d_info[dungeon_type].text); } else { -#ifdef JP if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)) - msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª"); + msg_print(_("なんだこの階段は!", "")); else - msg_print("³¬Ãʤò²¼¤ê¤Æ¿·¤¿¤Ê¤ë̵ܤؤÈ­¤òƧ¤ßÆþ¤ì¤¿¡£"); -#else - msg_print("You enter a maze of down staircases."); -#endif + msg_print(_("階段を下りて新たなる迷宮へと足を踏み入れた。", "You enter a maze of down staircases.")); } } @@ -345,28 +359,28 @@ void do_cmd_go_down(void) if (fall_trap) { - prepare_change_floor_mode(CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT); + prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT); } else { - if (c_ptr->feat == FEAT_MORE_MORE) + if (have_flag(f_ptr->flags, FF_SHAFT)) { /* Create a way back */ - prepare_change_floor_mode(CFM_DOWN | CFM_SHAFT); + prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_SHAFT); } else { /* Create a way back */ - prepare_change_floor_mode(CFM_DOWN); + prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN); } } } } - -/* - * Simple command to "search" for one turn +/*! + * @brief 探索コマンドのメインルーチン / Simple command to "search" for one turn + * @return なし */ void do_cmd_search(void) { @@ -384,17 +398,21 @@ void do_cmd_search(void) } /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Search */ search(); } -/* - * Determine if a grid contains a chest +/*! + * @brief 該当のマスに存在している箱のオブジェクトIDを返す。 + * @param y 走査対象にしたいマスのY座標 + * @param x 走査対象にしたいマスのX座標 + * @param trapped TRUEならばトラップが存在する箱のみ、FALSEならば空でない箱全てを対象にする + * @return 箱が存在する場合そのオブジェクトID、存在しない場合0を返す。 */ -static s16b chest_check(int y, int x) +static s16b chest_check(int y, int x, bool trapped) { cave_type *c_ptr = &cave[y][x]; @@ -413,10 +431,15 @@ static s16b chest_check(int y, int x) next_o_idx = o_ptr->next_o_idx; /* Skip unknown chests XXX XXX */ - /* if (!o_ptr->marked) continue; */ + /* if (!(o_ptr->marked & OM_FOUND)) continue; */ - /* Check for chest */ - if (o_ptr->tval == TV_CHEST) return (this_o_idx); + /* Check for non empty chest */ + if ((o_ptr->tval == TV_CHEST) && + (((!trapped) && (o_ptr->pval)) || /* non empty */ + ((trapped) && (o_ptr->pval > 0)))) /* trapped only */ + { + return (this_o_idx); + } } /* No chest */ @@ -424,9 +447,16 @@ static s16b chest_check(int y, int x) } -/* +/*! + * @brief 箱からアイテムを引き出す / * Allocates objects upon opening a chest -BEN- - * + * @param scatter TRUEならばトラップによるアイテムの拡散処理 + * @param y 箱の存在するマスのY座標 + * @param x 箱の存在するマスのX座標 + * @param o_idx 箱のオブジェクトID + * @return なし + * @details + *
  * Disperse treasures from the given chest, centered at (x,y).
  *
  * Small chests often contain "gold", while Large chests always contain
@@ -434,13 +464,14 @@ static s16b chest_check(int y, int x)
  * and Steel chests contain 6 items.  The "value" of the items in a
  * chest is based on the "power" of the chest, which is in turn based
  * on the level on which the chest is generated.
+ * 
*/ static void chest_death(bool scatter, int y, int x, s16b o_idx) { int number; bool small; - bool great = FALSE; + u32b mode = AM_GOOD; object_type forge; object_type *q_ptr; @@ -458,7 +489,7 @@ static void chest_death(bool scatter, int y, int x, s16b o_idx) { number = 5; small = FALSE; - great = TRUE; + mode |= AM_GREAT; object_level = o_ptr->xtra3; } else @@ -493,7 +524,7 @@ static void chest_death(bool scatter, int y, int x, s16b o_idx) else { /* Make a good object */ - if (!make_object(q_ptr, TRUE, great)) continue; + if (!make_object(q_ptr, mode)) continue; } /* If chest scatters its contents, pick any floor square. */ @@ -534,11 +565,18 @@ static void chest_death(bool scatter, int y, int x, s16b o_idx) } -/* +/*! + * @brief 箱のトラップ処理 / * Chests have traps too. - * + * @param y 箱の存在するマスのY座標 + * @param x 箱の存在するマスのX座標 + * @param o_idx 箱のオブジェクトID + * @return なし + * @details + *
  * Exploding chest destroys contents (and traps).
  * Note that the chest itself is never destroyed.
+ * 
*/ static void chest_trap(int y, int x, s16b o_idx) { @@ -558,8 +596,8 @@ static void chest_trap(int y, int x, s16b o_idx) if (trap & (CHEST_LOSE_STR)) { #ifdef JP - msg_print("»Å³Ý¤±¤é¤ì¤Æ¤¤¤¿¾®¤µ¤Ê¿Ë¤Ë»É¤µ¤ì¤Æ¤·¤Þ¤Ã¤¿¡ª"); - take_hit(DAMAGE_NOESCAPE, damroll(1, 4), "ÆÇ¿Ë", -1); + msg_print("仕掛けられていた小さな針に刺されてしまった!"); + take_hit(DAMAGE_NOESCAPE, damroll(1, 4), "毒針", -1); #else msg_print("A small needle has pricked you!"); take_hit(DAMAGE_NOESCAPE, damroll(1, 4), "a poison needle", -1); @@ -572,8 +610,8 @@ static void chest_trap(int y, int x, s16b o_idx) if (trap & (CHEST_LOSE_CON)) { #ifdef JP - msg_print("»Å³Ý¤±¤é¤ì¤Æ¤¤¤¿¾®¤µ¤Ê¿Ë¤Ë»É¤µ¤ì¤Æ¤·¤Þ¤Ã¤¿¡ª"); - take_hit(DAMAGE_NOESCAPE, damroll(1, 4), "ÆÇ¿Ë", -1); + msg_print("仕掛けられていた小さな針に刺されてしまった!"); + take_hit(DAMAGE_NOESCAPE, damroll(1, 4), "毒針", -1); #else msg_print("A small needle has pricked you!"); take_hit(DAMAGE_NOESCAPE, damroll(1, 4), "a poison needle", -1); @@ -585,13 +623,8 @@ static void chest_trap(int y, int x, s16b o_idx) /* Poison */ if (trap & (CHEST_POISON)) { -#ifdef JP - msg_print("ÆÍÇ¡¿á¤­½Ð¤·¤¿Îп§¤Î¥¬¥¹¤ËÊñ¤ß¹þ¤Þ¤ì¤¿¡ª"); -#else - msg_print("A puff of green gas surrounds you!"); -#endif - - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) + msg_print(_("突如吹き出した緑色のガスに包み込まれた!", "A puff of green gas surrounds you!")); + if (!(p_ptr->resist_pois || IS_OPPOSE_POIS())) { (void)set_poisoned(p_ptr->poisoned + 10 + randint1(20)); } @@ -600,13 +633,7 @@ static void chest_trap(int y, int x, s16b o_idx) /* Paralyze */ if (trap & (CHEST_PARALYZE)) { -#ifdef JP - msg_print("ÆÍÇ¡¿á¤­½Ð¤·¤¿²«¿§¤¤¥¬¥¹¤ËÊñ¤ß¹þ¤Þ¤ì¤¿¡ª"); -#else - msg_print("A puff of yellow gas surrounds you!"); -#endif - - + msg_print(_("突如吹き出した黄色いガスに包み込まれた!", "A puff of yellow gas surrounds you!")); if (!p_ptr->free_act) { (void)set_paralyzed(p_ptr->paralyzed + 10 + randint1(20)); @@ -617,17 +644,11 @@ static void chest_trap(int y, int x, s16b o_idx) if (trap & (CHEST_SUMMON)) { int num = 2 + randint1(3); -#ifdef JP - msg_print("ÆÍÇ¡¿á¤­½Ð¤·¤¿±ì¤ËÊñ¤ß¹þ¤Þ¤ì¤¿¡ª"); -#else - msg_print("You are enveloped in a cloud of smoke!"); -#endif - - + msg_print(_("突如吹き出した煙に包み込まれた!", "You are enveloped in a cloud of smoke!")); for (i = 0; i < num; i++) { if (randint1(100)y, p_ptr->x, FALSE); else (void)summon_specific(0, y, x, mon_level, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)); } @@ -636,11 +657,7 @@ static void chest_trap(int y, int x, s16b o_idx) /* Elemental summon. */ if (trap & (CHEST_E_SUMMON)) { -#ifdef JP - msg_print("Êõ¤ò¼é¤ë¤¿¤á¤Ë¥¨¥ì¥á¥ó¥¿¥ë¤¬¸½¤ì¤¿¡ª"); -#else - msg_print("Elemental beings appear to protect their treasures!"); -#endif + msg_print(_("宝を守るためにエレメンタルが現れた!", "Elemental beings appear to protect their treasures!")); for (i = 0; i < randint1(3) + 5; i++) { (void)summon_specific(0, y, x, mon_level, SUMMON_ELEMENTAL, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)); @@ -650,11 +667,7 @@ static void chest_trap(int y, int x, s16b o_idx) /* Force clouds, then summon birds. */ if (trap & (CHEST_BIRD_STORM)) { -#ifdef JP - msg_print("Ä»¤Î·²¤ì¤¬¤¢¤Ê¤¿¤ò¼è¤ê´¬¤¤¤¿¡ª"); -#else - msg_print("A storm of birds swirls around you!"); -#endif + msg_print(_("鳥の群れがあなたを取り巻いた!", "A storm of birds swirls around you!")); for (i = 0; i < randint1(3) + 3; i++) (void)fire_meteor(-1, GF_FORCE, y, x, o_ptr->pval / 5, 7); @@ -671,12 +684,7 @@ static void chest_trap(int y, int x, s16b o_idx) /* Summon demons. */ if (one_in_(4)) { -#ifdef JP - msg_print("±ê¤Èⲫ¤Î±À¤ÎÃæ¤Ë°­Ë⤬»Ñ¤ò¸½¤·¤¿¡ª"); -#else - msg_print("Demons materialize in clouds of fire and brimstone!"); -#endif - + msg_print(_("炎と硫黄の雲の中に悪魔が姿を現した!", "Demons materialize in clouds of fire and brimstone!")); for (i = 0; i < randint1(3) + 2; i++) { (void)fire_meteor(-1, GF_FIRE, y, x, 10, 5); @@ -687,12 +695,7 @@ static void chest_trap(int y, int x, s16b o_idx) /* Summon dragons. */ else if (one_in_(3)) { -#ifdef JP - msg_print("°Å°Ç¤Ë¥É¥é¥´¥ó¤Î±Æ¤¬¤Ü¤ó¤ä¤ê¤È¸½¤ì¤¿¡ª"); -#else - msg_print("Draconic forms loom out of the darkness!"); -#endif - + msg_print(_("暗闇にドラゴンの影がぼんやりと現れた!", "Draconic forms loom out of the darkness!")); for (i = 0; i < randint1(3) + 2; i++) { (void)summon_specific(0, y, x, mon_level, SUMMON_DRAGON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)); @@ -702,12 +705,7 @@ static void chest_trap(int y, int x, s16b o_idx) /* Summon hybrids. */ else if (one_in_(2)) { -#ifdef JP - msg_print("´ñ̯¤Ê»Ñ¤Î²øʪ¤¬½±¤Ã¤ÆÍ褿¡ª"); -#else - msg_print("Creatures strange and twisted assault you!"); -#endif - + msg_print(_("奇妙な姿の怪物が襲って来た!", "Creatures strange and twisted assault you!")); for (i = 0; i < randint1(5) + 3; i++) { (void)summon_specific(0, y, x, mon_level, SUMMON_HYBRID, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)); @@ -717,12 +715,7 @@ static void chest_trap(int y, int x, s16b o_idx) /* Summon vortices (scattered) */ else { -#ifdef JP - msg_print("±²´¬¤«¹çÂΤ·¡¢ÇËÎö¤·¤¿¡ª"); -#else - msg_print("Vortices coalesce and wreak destruction!"); -#endif - + msg_print(_("渦巻が合体し、破裂した!", "Vortices coalesce and wreak destruction!")); for (i = 0; i < randint1(3) + 2; i++) { (void)summon_specific(0, y, x, mon_level, SUMMON_VORTEX, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)); @@ -737,23 +730,14 @@ static void chest_trap(int y, int x, s16b o_idx) int nasty_tricks_count = 4 + randint0(3); /* Message. */ -#ifdef JP - msg_print("¶²¤·¤¤À¼¤¬¶Á¤¤¤¿: ¡Ö°Å°Ç¤¬Æò¤ò¤Ä¤Ä¤Þ¤ó¡ª¡×"); -#else - msg_print("Hideous voices bid: 'Let the darkness have thee!'"); -#endif - + msg_print(_("恐ろしい声が響いた: 「暗闇が汝をつつまん!」", "Hideous voices bid: 'Let the darkness have thee!'")); /* This is gonna hurt... */ for (; nasty_tricks_count > 0; nasty_tricks_count--) { /* ...but a high saving throw does help a little. */ if (randint1(100+o_ptr->pval*2) > p_ptr->skill_sav) { -#ifdef JP - if (one_in_(6)) take_hit(DAMAGE_NOESCAPE, damroll(5, 20), "ÇËÌǤΥȥé¥Ã¥×¤ÎÊõÈ¢", -1); -#else - if (one_in_(6)) take_hit(DAMAGE_NOESCAPE, damroll(5, 20), "a chest dispel-player trap", -1); -#endif + if (one_in_(6)) take_hit(DAMAGE_NOESCAPE, damroll(5, 20), _("破滅のトラップの宝箱", "a chest dispel-player trap"), -1); else if (one_in_(5)) (void)set_cut(p_ptr->cut + 200); else if (one_in_(4)) { @@ -782,54 +766,38 @@ static void chest_trap(int y, int x, s16b o_idx) /* Aggravate monsters. */ if (trap & (CHEST_ALARM)) { -#ifdef JP - msg_print("¤±¤¿¤¿¤Þ¤·¤¤²»¤¬ÌĤê¶Á¤¤¤¿¡ª"); -#else - msg_print("An alarm sounds!"); -#endif + msg_print(_("けたたましい音が鳴り響いた!", "An alarm sounds!")); aggravate_monsters(0); } /* Explode */ if ((trap & (CHEST_EXPLODE)) && o_ptr->k_idx) { -#ifdef JP - msg_print("ÆÍÁ³¡¢È¢¤¬Çúȯ¤·¤¿¡ª"); - msg_print("È¢¤ÎÃæ¤Îʪ¤Ï¤¹¤Ù¤ÆÊ´¡¹¤ËºÕ¤±»¶¤Ã¤¿¡ª"); -#else - msg_print("There is a sudden explosion!"); - msg_print("Everything inside the chest is destroyed!"); -#endif - + msg_print(_("突然、箱が爆発した!", "There is a sudden explosion!")); + msg_print(_("箱の中の物はすべて粉々に砕け散った!", "Everything inside the chest is destroyed!")); o_ptr->pval = 0; sound(SOUND_EXPLODE); -#ifdef JP - take_hit(DAMAGE_ATTACK, damroll(5, 8), "Çúȯ¤¹¤ëÈ¢", -1); -#else - take_hit(DAMAGE_ATTACK, damroll(5, 8), "an exploding chest", -1); -#endif - + take_hit(DAMAGE_ATTACK, damroll(5, 8), _("爆発する箱", "an exploding chest"), -1); } /* Scatter contents. */ if ((trap & (CHEST_SCATTER)) && o_ptr->k_idx) { -#ifdef JP - msg_print("ÊõÈ¢¤ÎÃæ¿È¤Ï¥À¥ó¥¸¥ç¥ó¤¸¤å¤¦¤Ë»¶Í𤷤¿¡ª"); -#else - msg_print("The contents of the chest scatter all over the dungeon!"); -#endif + msg_print(_("宝箱の中身はダンジョンじゅうに散乱した!", "The contents of the chest scatter all over the dungeon!")); chest_death(TRUE, y, x, o_idx); o_ptr->pval = 0; } } -/* +/*! + * @brief 箱を開けるコマンドのメインルーチン / * Attempt to open the given chest at the given location - * + * @param y 箱の存在するマスのY座標 + * @param x 箱の存在するマスのX座標 + * @param o_idx 箱のオブジェクトID + * @return 箱が開かなかった場合TRUE / Returns TRUE if repeated commands may continue + * @details * Assume there is no monster blocking the destination - * - * Returns TRUE if repeated commands may continue */ static bool do_cmd_open_chest(int y, int x, s16b o_idx) { @@ -843,7 +811,7 @@ static bool do_cmd_open_chest(int y, int x, s16b o_idx) /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Attempt to unlock it */ if (o_ptr->pval > 0) @@ -867,12 +835,7 @@ static bool do_cmd_open_chest(int y, int x, s16b o_idx) /* Success -- May still have traps */ if (randint0(100) < j) { -#ifdef JP - msg_print("¸°¤ò¤Ï¤º¤·¤¿¡£"); -#else - msg_print("You have picked the lock."); -#endif - + msg_print(_("鍵をはずした。", "You have picked the lock.")); gain_exp(1); flag = TRUE; } @@ -883,11 +846,7 @@ static bool do_cmd_open_chest(int y, int x, s16b o_idx) /* We may continue repeating */ more = TRUE; if (flush_failure) flush(); -#ifdef JP - msg_print("¸°¤ò¤Ï¤º¤»¤Ê¤«¤Ã¤¿¡£"); -#else - msg_print("You failed to pick the lock."); -#endif + msg_print(_("鍵をはずせなかった。", "You failed to pick the lock.")); } } @@ -909,17 +868,27 @@ static bool do_cmd_open_chest(int y, int x, s16b o_idx) #if defined(ALLOW_EASY_OPEN) || defined(ALLOW_EASY_DISARM) /* TNB */ -/* - * Return TRUE if the given feature is an open door +/*! + * @brief 地形は開くものであって、かつ開かれているかを返す / + * Attempt to open the given chest at the given location + * @param feat 地形ID + * @return 開いた地形である場合TRUEを返す / Return TRUE if the given feature is an open door */ static bool is_open(int feat) { - return (feat == FEAT_OPEN); + return have_flag(f_info[feat].flags, FF_CLOSE) && (feat != feat_state(feat, FF_CLOSE)); } -/* - * Return the number of features around (or under) the character. +/*! + * @brief プレイヤーの周辺9マスに該当する地形がいくつあるかを返す / + * Attempt to open the given chest at the given location + * @param y 該当する地形の中から1つのY座標を返す参照ポインタ + * @param x 該当する地形の中から1つのX座標を返す参照ポインタ + * @param test 地形条件を判定するための関数ポインタ + * @param under TRUEならばプレイヤーの直下の座標も走査対象にする + * @return 該当する地形の数 + * @details Return the number of features around (or under) the character. * Usually look for doors and floor traps. */ static int count_dt(int *y, int *x, bool (*test)(int feat), bool under) @@ -933,14 +902,14 @@ static int count_dt(int *y, int *x, bool (*test)(int feat), bool under) for (d = 0; d < 9; d++) { cave_type *c_ptr; - byte feat; + s16b feat; /* if not searching under player continue */ if ((d == 8) && !under) continue; /* Extract adjacent (legal) location */ - yy = py + ddy_ddd[d]; - xx = px + ddx_ddd[d]; + yy = p_ptr->y + ddy_ddd[d]; + xx = p_ptr->x + ddx_ddd[d]; /* Get the cave */ c_ptr = &cave[yy][xx]; @@ -949,8 +918,8 @@ static int count_dt(int *y, int *x, bool (*test)(int feat), bool under) if (!(c_ptr->info & (CAVE_MARK))) continue; /* Feature code (applying "mimic" field) */ - feat = c_ptr->mimic ? c_ptr->mimic : f_info[c_ptr->feat].mimic; - + feat = get_feat_mimic(c_ptr); + /* Not looking for this feature */ if (!((*test)(feat))) continue; @@ -967,8 +936,14 @@ static int count_dt(int *y, int *x, bool (*test)(int feat), bool under) } -/* +/*! + * @brief プレイヤーの周辺9マスに箱のあるマスがいくつあるかを返す / * Return the number of chests around (or under) the character. + * @param y 該当するマスの中から1つのY座標を返す参照ポインタ + * @param x 該当するマスの中から1つのX座標を返す参照ポインタ + * @param trapped TRUEならばトラップの存在が判明している箱のみ対象にする + * @return 該当する地形の数 + * @details * If requested, count only trapped chests. */ static int count_chests(int *y, int *x, bool trapped) @@ -984,11 +959,11 @@ static int count_chests(int *y, int *x, bool trapped) for (d = 0; d < 9; d++) { /* Extract adjacent (legal) location */ - int yy = py + ddy_ddd[d]; - int xx = px + ddx_ddd[d]; + int yy = p_ptr->y + ddy_ddd[d]; + int xx = p_ptr->x + ddx_ddd[d]; /* No (visible) chest is there */ - if ((o_idx = chest_check(yy, xx)) == 0) continue; + if ((o_idx = chest_check(yy, xx, FALSE)) == 0) continue; /* Grab the object */ o_ptr = &o_list[o_idx]; @@ -997,7 +972,7 @@ static int count_chests(int *y, int *x, bool trapped) if (o_ptr->pval == 0) continue; /* No (known) traps here */ - if (trapped && (!object_known_p(o_ptr) || + if (trapped && (!object_is_known(o_ptr) || !chest_traps[o_ptr->pval])) continue; /* OK */ @@ -1013,16 +988,20 @@ static int count_chests(int *y, int *x, bool trapped) } -/* +/*! + * @brief プレイヤーから指定の座標がどの方角にあるかを返す / * Convert an adjacent location to a direction. + * @param y 方角を確認したY座標 + * @param x 方角を確認したX座標 + * @return 方向ID */ static int coords_to_dir(int y, int x) { int d[3][3] = { {7, 4, 1}, {8, 5, 2}, {9, 6, 3} }; int dy, dx; - dy = y - py; - dx = x - px; + dy = y - p_ptr->y; + dx = x - p_ptr->x; /* Paranoia */ if (ABS(dx) > 1 || ABS(dy) > 1) return (0); @@ -1033,46 +1012,43 @@ static int coords_to_dir(int y, int x) #endif /* defined(ALLOW_EASY_OPEN) || defined(ALLOW_EASY_DISARM) -- TNB */ -/* +/*! + * @brief 「開ける」動作コマンドのサブルーチン / * Perform the basic "open" command on doors - * + * @param y 対象を行うマスのY座標 + * @param x 対象を行うマスのX座標 + * @return 実際に処理が行われた場合TRUEを返す。 + * @details * Assume destination is a closed/locked/jammed door - * * Assume there is no monster blocking the destination - * * Returns TRUE if repeated commands may continue */ static bool do_cmd_open_aux(int y, int x) { int i, j; - cave_type *c_ptr; + /* Get requested grid */ + cave_type *c_ptr = &cave[y][x]; + + feature_type *f_ptr = &f_info[c_ptr->feat]; bool more = FALSE; /* Take a turn */ - energy_use = 100; - - /* Get requested grid */ - c_ptr = &cave[y][x]; + p_ptr->energy_use = 100; /* Seeing true feature code (ignore mimic) */ - + /* Jammed door */ - if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x08) + if (!have_flag(f_ptr->flags, FF_OPEN)) { /* Stuck */ -#ifdef JP - msg_print("¥É¥¢¤Ï¤¬¤Ã¤Á¤ê¤ÈÊĤ¸¤é¤ì¤Æ¤¤¤ë¤è¤¦¤À¡£"); -#else - msg_print("The door appears to be stuck."); -#endif - + msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_name + f_info[get_feat_mimic(c_ptr)].name); } /* Locked door */ - else if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x01) + else if (f_ptr->power) { /* Disarm factor */ i = p_ptr->skill_dis; @@ -1082,7 +1058,7 @@ static bool do_cmd_open_aux(int y, int x) if (p_ptr->confused || p_ptr->image) i = i / 10; /* Extract the lock power */ - j = c_ptr->feat - FEAT_DOOR_HEAD; + j = f_ptr->power; /* Extract the difficulty XXX XXX XXX */ j = i - (j * 4); @@ -1094,18 +1070,10 @@ static bool do_cmd_open_aux(int y, int x) if (randint0(100) < j) { /* Message */ -#ifdef JP - msg_print("¸°¤ò¤Ï¤º¤·¤¿¡£"); -#else - msg_print("You have picked the lock."); -#endif - + msg_print(_("鍵をはずした。", "You have picked the lock.")); /* Open the door */ - cave_set_feat(y, x, FEAT_OPEN); - - /* Update some things */ - p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS | PU_MON_LITE); + cave_alter_feat(y, x, FF_OPEN); /* Sound */ sound(SOUND_OPENDOOR); @@ -1121,12 +1089,7 @@ static bool do_cmd_open_aux(int y, int x) if (flush_failure) flush(); /* Message */ -#ifdef JP - msg_print("¸°¤ò¤Ï¤º¤»¤Ê¤«¤Ã¤¿¡£"); -#else - msg_print("You failed to pick the lock."); -#endif - + msg_print(_("鍵をはずせなかった。", "You failed to pick the lock.")); /* We may keep trying */ more = TRUE; @@ -1134,13 +1097,10 @@ static bool do_cmd_open_aux(int y, int x) } /* Closed door */ - else if (c_ptr->feat == FEAT_DOOR_HEAD) + else { /* Open the door */ - cave_set_feat(y, x, FEAT_OPEN); - - /* Update some things */ - p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS | PU_MON_LITE); + cave_alter_feat(y, x, FF_OPEN); /* Sound */ sound(SOUND_OPENDOOR); @@ -1150,11 +1110,11 @@ static bool do_cmd_open_aux(int y, int x) return (more); } - - -/* +/*! + * @brief 「開ける」コマンドのメインルーチン / * Open a closed/locked/jammed door or a closed/locked chest. - * + * @return なし + * @details * Unlocking a locked door/chest is worth one experience point. */ void do_cmd_open(void) @@ -1210,48 +1170,38 @@ void do_cmd_open(void) /* Get a "repeated" direction */ if (get_rep_dir(&dir, TRUE)) { - byte feat; + s16b feat; cave_type *c_ptr; /* Get requested location */ - y = py + ddy[dir]; - x = px + ddx[dir]; + y = p_ptr->y + ddy[dir]; + x = p_ptr->x + ddx[dir]; /* Get requested grid */ c_ptr = &cave[y][x]; /* Feature code (applying "mimic" field) */ - feat = c_ptr->mimic ? c_ptr->mimic : f_info[c_ptr->feat].mimic; - + feat = get_feat_mimic(c_ptr); + /* Check for chest */ - o_idx = chest_check(y, x); + o_idx = chest_check(y, x, FALSE); /* Nothing useful */ - if (!is_closed_door(feat) && !o_idx) + if (!have_flag(f_info[feat].flags, FF_OPEN) && !o_idx) { /* Message */ -#ifdef JP - msg_print("¤½¤³¤Ë¤Ï³«¤±¤ë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("You see nothing there to open."); -#endif - + msg_print(_("そこには開けるものが見当たらない。", "You see nothing there to open.")); } /* Monster in the way */ else if (c_ptr->m_idx && p_ptr->riding != c_ptr->m_idx) { /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Message */ -#ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); -#else - msg_print("There is a monster in the way!"); -#endif - - + msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!")); + /* Attack */ py_attack(y, x, 0); } @@ -1277,51 +1227,58 @@ void do_cmd_open(void) -/* +/*! + * @brief 「閉じる」動作コマンドのサブルーチン / * Perform the basic "close" command - * + * @param y 対象を行うマスのY座標 + * @param x 対象を行うマスのX座標 + * @return 実際に処理が行われた場合TRUEを返す。 + * @details * Assume destination is an open/broken door - * * Assume there is no monster blocking the destination - * * Returns TRUE if repeated commands may continue */ static bool do_cmd_close_aux(int y, int x) { - cave_type *c_ptr; - bool more = FALSE; + /* Get grid and contents */ + cave_type *c_ptr = &cave[y][x]; + s16b old_feat = c_ptr->feat; + bool more = FALSE; /* Take a turn */ - energy_use = 100; - - /* Get grid and contents */ - c_ptr = &cave[y][x]; + p_ptr->energy_use = 100; /* Seeing true feature code (ignore mimic) */ - - /* Broken door */ - if (c_ptr->feat == FEAT_BROKEN) - { - /* Message */ -#ifdef JP - msg_print("¥É¥¢¤Ï²õ¤ì¤Æ¤·¤Þ¤Ã¤Æ¤¤¤ë¡£"); -#else - msg_print("The door appears to be broken."); -#endif - - } /* Open door */ - else if (c_ptr->feat == FEAT_OPEN) + if (have_flag(f_info[old_feat].flags, FF_CLOSE)) { - /* Close the door */ - cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x00); + s16b closed_feat = feat_state(old_feat, FF_CLOSE); - /* Update some things */ - p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS | PU_MON_LITE); + /* Hack -- object in the way */ + if ((c_ptr->o_idx || (c_ptr->info & CAVE_OBJECT)) && + (closed_feat != old_feat) && !have_flag(f_info[closed_feat].flags, FF_DROP)) + { + /* Message */ + msg_print(_("何かがつっかえて閉まらない。", "There seems stuck.")); + } + else + { + /* Close the door */ + cave_alter_feat(y, x, FF_CLOSE); - /* Sound */ - sound(SOUND_SHUTDOOR); + /* Broken door */ + if (old_feat == c_ptr->feat) + { + /* Message */ + msg_print(_("ドアは壊れてしまっている。", "The door appears to be broken.")); + } + else + { + /* Sound */ + sound(SOUND_SHUTDOOR); + } + } } /* Result */ @@ -1329,8 +1286,12 @@ static bool do_cmd_close_aux(int y, int x) } -/* +/*! + * @brief 「閉じる」コマンドのメインルーチン / * Close an open door. + * @return なし + * @details + * Unlocking a locked door/chest is worth one experience point. */ void do_cmd_close(void) { @@ -1374,43 +1335,33 @@ void do_cmd_close(void) if (get_rep_dir(&dir,FALSE)) { cave_type *c_ptr; - byte feat; + s16b feat; /* Get requested location */ - y = py + ddy[dir]; - x = px + ddx[dir]; + y = p_ptr->y + ddy[dir]; + x = p_ptr->x + ddx[dir]; /* Get grid and contents */ c_ptr = &cave[y][x]; /* Feature code (applying "mimic" field) */ - feat = c_ptr->mimic ? c_ptr->mimic : f_info[c_ptr->feat].mimic; - + feat = get_feat_mimic(c_ptr); + /* Require open/broken door */ - if ((feat != FEAT_OPEN) && (feat != FEAT_BROKEN)) + if (!have_flag(f_info[feat].flags, FF_CLOSE)) { /* Message */ -#ifdef JP - msg_print("¤½¤³¤Ë¤ÏÊĤ¸¤ë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("You see nothing there to close."); -#endif - + msg_print(_("そこには閉じるものが見当たらない。", "You see nothing there to close.")); } /* Monster in the way */ else if (c_ptr->m_idx) { /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Message */ -#ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); -#else - msg_print("There is a monster in the way!"); -#endif - + msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!")); /* Attack */ py_attack(y, x, 0); @@ -1429,36 +1380,32 @@ void do_cmd_close(void) } -/* +/*! + * @brief 「掘る」コマンドを該当のマスに行えるかの判定と結果メッセージの表示 / * Determine if a given grid may be "tunneled" + * @param y 対象を行うマスのY座標 + * @param x 対象を行うマスのX座標 + * @return */ static bool do_cmd_tunnel_test(int y, int x) { + cave_type *c_ptr = &cave[y][x]; + /* Must have knowledge */ - if (!(cave[y][x].info & (CAVE_MARK))) + if (!(c_ptr->info & CAVE_MARK)) { /* Message */ -#ifdef JP - msg_print("¤½¤³¤Ë¤Ï²¿¤â¸«Åö¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("You see nothing there."); -#endif - + msg_print(_("そこには何も見当たらない。", "You see nothing there.")); /* Nope */ return (FALSE); } /* Must be a wall/door/etc */ - if (cave_floor_bold(y, x)) + if (!cave_have_flag_grid(c_ptr, FF_TUNNEL)) { /* Message */ -#ifdef JP - msg_print("¤½¤³¤Ë¤Ï·¡¤ë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("You see nothing there to tunnel."); -#endif - + msg_print(_("そこには掘るものが見当たらない。", "You see nothing there to tunnel.")); /* Nope */ return (FALSE); @@ -1469,323 +1416,122 @@ static bool do_cmd_tunnel_test(int y, int x) } - -/* - * Tunnel through wall. Assumes valid location. - * - * Note that it is impossible to "extend" rooms past their - * outer walls (which are actually part of the room). - * - * This will, however, produce grids which are NOT illuminated - * (or darkened) along with the rest of the room. - */ -static bool twall(int y, int x, byte feat) -{ - cave_type *c_ptr = &cave[y][x]; - - /* Paranoia -- Require a wall or door or some such */ - if (cave_floor_bold(y, x)) return (FALSE); - - /* Forget the wall */ - c_ptr->info &= ~(CAVE_MARK); - - /* Remove the feature */ - cave_set_feat(y, x, feat); - - /* Update some things */ - p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS | PU_MON_LITE); - - /* Result */ - return (TRUE); -} - - - -/* +/*! + * @brief 「掘る」動作コマンドのサブルーチン / * Perform the basic "tunnel" command - * - * Assumes that the destination is a wall, a vein, a secret - * door, or rubble. - * + * @param y 対象を行うマスのY座標 + * @param x 対象を行うマスのX座標 + * @return 実際に処理が行われた場合TRUEを返す。 + * @details * Assumes that no monster is blocking the destination - * + * Do not use twall anymore * Returns TRUE if repeated commands may continue */ static bool do_cmd_tunnel_aux(int y, int x) { cave_type *c_ptr; - byte feat; - + feature_type *f_ptr, *mimic_f_ptr; + int power; + cptr name; bool more = FALSE; /* Verify legality */ if (!do_cmd_tunnel_test(y, x)) return (FALSE); /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Get grid */ c_ptr = &cave[y][x]; + f_ptr = &f_info[c_ptr->feat]; + power = f_ptr->power; /* Feature code (applying "mimic" field) */ - feat = c_ptr->mimic ? c_ptr->mimic : f_info[c_ptr->feat].mimic; + mimic_f_ptr = &f_info[get_feat_mimic(c_ptr)]; + + name = f_name + mimic_f_ptr->name; /* Sound */ sound(SOUND_DIG); - /* Titanium */ - if ((feat >= FEAT_PERM_EXTRA) && - (feat <= FEAT_PERM_SOLID)) - { -#ifdef JP - msg_print("¤³¤Î´ä¤Ï¹Å¤¹¤®¤Æ·¡¤ì¤Ê¤¤¤è¤¦¤À¡£"); -#else - msg_print("This seems to be permanent rock."); -#endif - - } - - /* No tunnelling through mountains */ - else if (feat == FEAT_MOUNTAIN) + if (have_flag(f_ptr->flags, FF_PERMANENT)) { -#ifdef JP - msg_print("¤½¤³¤Ï·¡¤ì¤Ê¤¤!"); -#else - msg_print("You can't tunnel through that!"); -#endif - - } - - /* Map border (mimiccing Permanent wall) */ - else if ((c_ptr->feat >= FEAT_PERM_EXTRA && - c_ptr->feat <= FEAT_PERM_SOLID) || - c_ptr->feat == FEAT_MOUNTAIN) - { -#ifdef JP - msg_print("¤½¤³¤Ï·¡¤ì¤Ê¤¤!"); -#else - msg_print("You can't tunnel through that!"); -#endif - - } - - else if (feat == FEAT_TREES) /* -KMW- */ - { - /* Chop Down */ - if ((p_ptr->skill_dig > 10 + randint0(400)) && twall(y, x, FEAT_GRASS)) + /* Titanium */ + if (have_flag(mimic_f_ptr->flags, FF_PERMANENT)) { -#ifdef JP - msg_print("ÌÚ¤òÀÚ¤êʧ¤Ã¤¿¡£"); -#else - msg_print("You have cleared away the trees."); -#endif - chg_virtue(V_DILIGENCE, 1); - chg_virtue(V_NATURE, -1); + msg_print(_("この岩は硬すぎて掘れないようだ。", "This seems to be permanent rock.")); } - /* Keep trying */ + /* Map border (mimiccing Permanent wall) */ else { - /* We may continue chopping */ -#ifdef JP - msg_print("ÌÚ¤òÀڤäƤ¤¤ë¡£"); -#else - msg_print("You chop away at the tree."); -#endif - - more = TRUE; - - /* Occasional Search XXX XXX */ - if (randint0(100) < 25) search(); - } - } - - - /* Granite */ - else if ((feat >= FEAT_WALL_EXTRA) && - (feat <= FEAT_WALL_SOLID)) - { - /* Tunnel */ - if ((p_ptr->skill_dig > 40 + randint0(1600)) && twall(y, x, floor_type[randint0(100)])) - { -#ifdef JP - msg_print("·ê¤ò·¡¤ê½ª¤¨¤¿¡£"); -#else - msg_print("You have finished the tunnel."); -#endif - chg_virtue(V_DILIGENCE, 1); - chg_virtue(V_NATURE, -1); - } - - /* Keep trying */ - else - { - /* We may continue tunelling */ -#ifdef JP - msg_print("²ÖÖ¾´ä¤ÎÊɤ˷ê¤ò·¡¤Ã¤Æ¤¤¤ë¡£"); -#else - msg_print("You tunnel into the granite wall."); -#endif - - more = TRUE; + msg_print(_("そこは掘れない!", "You can't tunnel through that!")); } } - - /* Quartz / Magma */ - else if ((feat >= FEAT_MAGMA) && - (feat <= FEAT_QUARTZ_K)) + /* Dig or tunnel */ + else if (have_flag(f_ptr->flags, FF_CAN_DIG)) { - bool okay = FALSE; - bool gold = FALSE; - bool hard = FALSE; - - /* Found gold (ignore mimic; maybe a hidden treasure) */ - if (c_ptr->feat >= FEAT_MAGMA_H && - c_ptr->feat <= FEAT_QUARTZ_K) gold = TRUE; - - /* Extract "quartz" flag XXX XXX XXX */ - if ((feat - FEAT_MAGMA) & 0x01) hard = TRUE; - - /* Quartz */ - if (hard) - { - okay = (p_ptr->skill_dig > 20 + randint0(800)); - } - - /* Magma */ - else - { - okay = (p_ptr->skill_dig > 10 + randint0(400)); - } - - /* Success */ - if (okay && twall(y, x, floor_type[randint0(100)])) - { - /* Found treasure */ - if (gold) - { - /* Place some gold */ - place_gold(y, x); - - /* Message */ -#ifdef JP - msg_print("²¿¤«¤òȯ¸«¤·¤¿¡ª"); -#else - msg_print("You have found something!"); -#endif - - } - - /* Found nothing */ - else - { - /* Message */ -#ifdef JP - msg_print("·ê¤ò·¡¤ê½ª¤¨¤¿¡£"); -#else - msg_print("You have finished the tunnel."); -#endif - chg_virtue(V_DILIGENCE, 1); - chg_virtue(V_NATURE, -1); - } - } - - /* Failure (quartz) */ - else if (hard) - { - /* Message, continue digging */ -#ifdef JP - msg_print("ÀбѤιÛÌ®¤Ë·ê¤ò·¡¤Ã¤Æ¤¤¤ë¡£"); -#else - msg_print("You tunnel into the quartz vein."); -#endif - - more = TRUE; - } - - /* Failure (magma) */ - else - { - /* Message, continue digging */ -#ifdef JP - msg_print("ÍÏ´ä¤Î¹ÛÌ®¤Ë·ê¤ò·¡¤Ã¤Æ¤¤¤ë¡£"); -#else - msg_print("You tunnel into the magma vein."); -#endif - - more = TRUE; - } - } - - /* Rubble */ - else if (feat == FEAT_RUBBLE) - { - /* Remove the rubble */ - if ((p_ptr->skill_dig > randint0(200)) && twall(y, x, floor_type[randint0(100)])) + /* Dig */ + if (p_ptr->skill_dig > randint0(20 * power)) { /* Message */ -#ifdef JP - msg_print("´äÀФò¤¯¤º¤·¤¿¡£"); -#else - msg_print("You have removed the rubble."); -#endif - - /* Hack -- place an object */ - if (randint0(100) < (15 - dun_level/2)) - { - /* Create a simple object */ - place_object(y, x, FALSE, FALSE); + msg_format(_("%sをくずした。", "You have removed the %s."), name); - /* Observe new object */ - if (player_can_see_bold(y, x)) - { -#ifdef JP - msg_print("²¿¤«¤òȯ¸«¤·¤¿¡ª"); -#else - msg_print("You have found something!"); -#endif + /* Remove the feature */ + cave_alter_feat(y, x, FF_TUNNEL); - } - } + /* Update some things */ + p_ptr->update |= (PU_FLOW); } - else { /* Message, keep digging */ -#ifdef JP - msg_print("´äÀФò¤¯¤º¤·¤Æ¤¤¤ë¡£"); -#else - msg_print("You dig in the rubble."); -#endif - + msg_format(_("%sをくずしている。", "You dig into the %s."), name); + more = TRUE; } } - /* Doors */ else { + bool tree = have_flag(mimic_f_ptr->flags, FF_TREE); + /* Tunnel */ - if ((p_ptr->skill_dig > 30 + randint0(1200)) && twall(y, x, floor_type[randint1(100)])) + if (p_ptr->skill_dig > power + randint0(40 * power)) { -#ifdef JP - msg_print("·ê¤ò·¡¤ê½ª¤¨¤¿¡£"); -#else - msg_print("You have finished the tunnel."); -#endif + if (tree) msg_format(_("%sを切り払った。", "You have cleared away the %s."), name); + else + { + msg_print(_("穴を掘り終えた。", "You have finished the tunnel.")); + p_ptr->update |= (PU_FLOW); + } + + /* Sound */ + if (have_flag(f_ptr->flags, FF_GLASS)) sound(SOUND_GLASS); + + /* Remove the feature */ + cave_alter_feat(y, x, FF_TUNNEL); + chg_virtue(V_DILIGENCE, 1); + chg_virtue(V_NATURE, -1); } /* Keep trying */ else { - /* We may continue tunelling */ -#ifdef JP - msg_print("¥É¥¢¤Ë·ê¤ò³«¤±¤Æ¤¤¤ë¡£"); -#else - msg_print("You tunnel into the door."); -#endif + if (tree) + { + /* We may continue chopping */ + msg_format(_("%sを切っている。", "You chop away at the %s."), name); + /* Occasional Search XXX XXX */ + if (randint0(100) < 25) search(); + } + else + { + /* We may continue tunelling */ + msg_format(_("%sに穴を掘っている。", "You tunnel into the %s."), name); + } more = TRUE; } @@ -1798,25 +1544,29 @@ static bool do_cmd_tunnel_aux(int y, int x) } /* Result */ - return (more); + return more; } -/* +/*! + * @brief 「掘る」動作コマンドのメインルーチン / * Tunnels through "walls" (including rubble and closed doors) - * + * @return なし + * @details + *
  * Note that you must tunnel in order to hit invisible monsters
  * in walls, though moving into walls still takes a turn anyway.
  *
  * Digging is very difficult without a "digger" weapon, but can be
  * accomplished by strong players using heavy weapons.
+ * 
*/ void do_cmd_tunnel(void) { int y, x, dir; cave_type *c_ptr; - byte feat; + s16b feat; bool more = FALSE; @@ -1843,67 +1593,36 @@ void do_cmd_tunnel(void) if (get_rep_dir(&dir,FALSE)) { /* Get location */ - y = py + ddy[dir]; - x = px + ddx[dir]; + y = p_ptr->y + ddy[dir]; + x = p_ptr->x + ddx[dir]; /* Get grid */ c_ptr = &cave[y][x]; /* Feature code (applying "mimic" field) */ - feat = c_ptr->mimic ? c_ptr->mimic : f_info[c_ptr->feat].mimic; + feat = get_feat_mimic(c_ptr); /* No tunnelling through doors */ - if (((feat >= FEAT_DOOR_HEAD) && (feat <= FEAT_DOOR_TAIL)) || - ((feat >= FEAT_BLDG_HEAD) && (feat <= FEAT_BLDG_TAIL)) || - ((feat >= FEAT_SHOP_HEAD) && (feat <= FEAT_SHOP_TAIL)) || - (feat == FEAT_MUSEUM)) - { - /* Message */ -#ifdef JP - msg_print("¥É¥¢¤Ï·¡¤ì¤Ê¤¤¡£"); -#else - msg_print("You cannot tunnel through doors."); -#endif - - } - - /* No tunnelling through air */ - else if (cave_floor_grid(c_ptr) || ((feat >= FEAT_MINOR_GLYPH) && - (feat <= FEAT_PATTERN_XTRA2))) + if (have_flag(f_info[feat].flags, FF_DOOR)) { /* Message */ -#ifdef JP - msg_print("¶õµ¤¤Ï·¡¤ì¤Ê¤¤¡£"); -#else - msg_print("You cannot tunnel through air."); -#endif - + msg_print(_("ドアは掘れない。", "You cannot tunnel through doors.")); } - /* No tunnelling through mountains */ - else if (feat == FEAT_MOUNTAIN) + /* No tunnelling through most features */ + else if (!have_flag(f_info[feat].flags, FF_TUNNEL)) { -#ifdef JP - msg_print("¤½¤³¤Ï·¡¤ì¤Ê¤¤¡£"); -#else - msg_print("You can't tunnel through that!"); -#endif - + msg_print(_("そこは掘れない。", "You can't tunnel through that.")); } /* A monster is in the way */ else if (c_ptr->m_idx) { /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Message */ -#ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); -#else - msg_print("There is a monster in the way!"); -#endif - + msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!")); /* Attack */ py_attack(y, x, 0); @@ -1924,44 +1643,44 @@ void do_cmd_tunnel(void) #ifdef ALLOW_EASY_OPEN /* TNB */ -/* +/*! + * @brief 移動処理による簡易な「開く」処理 / * easy_open_door -- - * + * @return 開く処理が実際に試みられた場合TRUEを返す + * @details + *
  *	If there is a jammed/closed/locked door at the given location,
  *	then attempt to unlock/open it. Return TRUE if an attempt was
  *	made (successful or not), otherwise return FALSE.
  *
  *	The code here should be nearly identical to that in
  *	do_cmd_open_test() and do_cmd_open_aux().
+ * 
*/ bool easy_open_door(int y, int x) { int i, j; cave_type *c_ptr = &cave[y][x]; + feature_type *f_ptr = &f_info[c_ptr->feat]; /* Must be a closed door */ - if (!((c_ptr->feat >= FEAT_DOOR_HEAD) && - (c_ptr->feat <= FEAT_DOOR_TAIL))) + if (!is_closed_door(c_ptr->feat)) { /* Nope */ return (FALSE); } /* Jammed door */ - if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x08) + if (!have_flag(f_ptr->flags, FF_OPEN)) { /* Stuck */ -#ifdef JP - msg_print("¥É¥¢¤Ï¤¬¤Ã¤Á¤ê¤ÈÊĤ¸¤é¤ì¤Æ¤¤¤ë¤è¤¦¤À¡£"); -#else - msg_print("The door appears to be stuck."); -#endif + msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_name + f_info[get_feat_mimic(c_ptr)].name); } /* Locked door */ - else if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x01) + else if (f_ptr->power) { /* Disarm factor */ i = p_ptr->skill_dis; @@ -1971,7 +1690,7 @@ bool easy_open_door(int y, int x) if (p_ptr->confused || p_ptr->image) i = i / 10; /* Extract the lock power */ - j = c_ptr->feat - FEAT_DOOR_HEAD; + j = f_ptr->power; /* Extract the difficulty XXX XXX XXX */ j = i - (j * 4); @@ -1983,18 +1702,10 @@ bool easy_open_door(int y, int x) if (randint0(100) < j) { /* Message */ -#ifdef JP - msg_print("¸°¤ò¤Ï¤º¤·¤¿¡£"); -#else - msg_print("You have picked the lock."); -#endif - + msg_print(_("鍵をはずした。", "You have picked the lock.")); /* Open the door */ - cave_set_feat(y, x, FEAT_OPEN); - - /* Update some things */ - p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS); + cave_alter_feat(y, x, FF_OPEN); /* Sound */ sound(SOUND_OPENDOOR); @@ -2010,11 +1721,7 @@ bool easy_open_door(int y, int x) if (flush_failure) flush(); /* Message */ -#ifdef JP - msg_print("¸°¤ò¤Ï¤º¤»¤Ê¤«¤Ã¤¿¡£"); -#else - msg_print("You failed to pick the lock."); -#endif + msg_print(_("鍵をはずせなかった。", "You failed to pick the lock.")); } } @@ -2023,10 +1730,7 @@ bool easy_open_door(int y, int x) else { /* Open the door */ - cave_set_feat(y, x, FEAT_OPEN); - - /* Update some things */ - p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS); + cave_alter_feat(y, x, FF_OPEN); /* Sound */ sound(SOUND_OPENDOOR); @@ -2039,14 +1743,19 @@ bool easy_open_door(int y, int x) #endif /* ALLOW_EASY_OPEN -- TNB */ -/* +/*! + * @brief 箱のトラップを解除するコマンドのメインルーチン / * Perform the basic "disarm" command - * + * @param y 解除を行うマスのY座標 + * @param x 解除を行うマスのX座標 + * @param o_idx 箱のオブジェクトID + * @return ターンを消費する処理が行われた場合TRUEを返す + * @details + *
  * Assume destination is a visible trap
- *
  * Assume there is no monster blocking the destination
- *
  * Returns TRUE if repeated commands may continue
+ * 
*/ static bool do_cmd_disarm_chest(int y, int x, s16b o_idx) { @@ -2058,7 +1767,7 @@ static bool do_cmd_disarm_chest(int y, int x, s16b o_idx) /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Get the "disarm" factor */ i = p_ptr->skill_dis; @@ -2074,47 +1783,28 @@ static bool do_cmd_disarm_chest(int y, int x, s16b o_idx) if (j < 2) j = 2; /* Must find the trap first. */ - if (!object_known_p(o_ptr)) + if (!object_is_known(o_ptr)) { -#ifdef JP - msg_print("¥È¥é¥Ã¥×¤¬¸«¤¢¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("I don't see any traps."); -#endif + msg_print(_("トラップが見あたらない。", "I don't see any traps.")); } /* Already disarmed/unlocked */ else if (o_ptr->pval <= 0) { -#ifdef JP - msg_print("È¢¤Ë¤Ï¥È¥é¥Ã¥×¤¬»Å³Ý¤±¤é¤ì¤Æ¤¤¤Ê¤¤¡£"); -#else - msg_print("The chest is not trapped."); -#endif - + msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped.")); } /* No traps to find. */ else if (!chest_traps[o_ptr->pval]) { -#ifdef JP - msg_print("È¢¤Ë¤Ï¥È¥é¥Ã¥×¤¬»Å³Ý¤±¤é¤ì¤Æ¤¤¤Ê¤¤¡£"); -#else - msg_print("The chest is not trapped."); -#endif - + msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped.")); } /* Success (get a lot of experience) */ else if (randint0(100) < j) { -#ifdef JP - msg_print("È¢¤Ë»Å³Ý¤±¤é¤ì¤Æ¤¤¤¿¥È¥é¥Ã¥×¤ò²ò½ü¤·¤¿¡£"); -#else - msg_print("You have disarmed the chest."); -#endif - + msg_print(_("箱に仕掛けられていたトラップを解除した。", "You have disarmed the chest.")); gain_exp(o_ptr->pval); o_ptr->pval = (0 - o_ptr->pval); } @@ -2125,23 +1815,13 @@ static bool do_cmd_disarm_chest(int y, int x, s16b o_idx) /* We may keep trying */ more = TRUE; if (flush_failure) flush(); -#ifdef JP - msg_print("È¢¤Î¥È¥é¥Ã¥×²ò½ü¤Ë¼ºÇÔ¤·¤¿¡£"); -#else - msg_print("You failed to disarm the chest."); -#endif - + msg_print(_("箱のトラップ解除に失敗した。", "You failed to disarm the chest.")); } /* Failure -- Set off the trap */ else { -#ifdef JP - msg_print("¥È¥é¥Ã¥×¤òºîÆ°¤µ¤»¤Æ¤·¤Þ¤Ã¤¿¡ª"); -#else - msg_print("You set off a trap!"); -#endif - + msg_print(_("トラップを作動させてしまった!", "You set off a trap!")); sound(SOUND_FAIL); chest_trap(y, x, o_idx); } @@ -2151,14 +1831,19 @@ static bool do_cmd_disarm_chest(int y, int x, s16b o_idx) } -/* +/*! + * @brief 箱のトラップを解除するコマンドのサブルーチン / * Perform the basic "disarm" command - * + * @param y 解除を行うマスのY座標 + * @param x 解除を行うマスのX座標 + * @param dir プレイヤーからみた方向ID + * @return ターンを消費する処理が行われた場合TRUEを返す + * @details + *
  * Assume destination is a visible trap
- *
  * Assume there is no monster blocking the destination
- *
  * Returns TRUE if repeated commands may continue
+ * 
*/ #ifdef ALLOW_EASY_DISARM /* TNB */ @@ -2170,47 +1855,32 @@ static bool do_cmd_disarm_aux(int y, int x, int dir) #endif /* ALLOW_EASY_DISARM -- TNB */ { - int i, j, power; - - cave_type *c_ptr; + /* Get grid and contents */ + cave_type *c_ptr = &cave[y][x]; - cptr name; + /* Get feature */ + feature_type *f_ptr = &f_info[c_ptr->feat]; - bool more = FALSE; + /* Access trap name */ + cptr name = (f_name + f_ptr->name); + /* Extract trap "power" */ + int power = f_ptr->power; - /* Take a turn */ - energy_use = 100; + bool more = FALSE; - /* Get grid and contents */ - c_ptr = &cave[y][x]; + /* Get the "disarm" factor */ + int i = p_ptr->skill_dis; - /* Access trap name */ - name = (f_name + f_info[c_ptr->feat].name); + int j; - /* Get the "disarm" factor */ - i = p_ptr->skill_dis; + /* Take a turn */ + p_ptr->energy_use = 100; /* Penalize some conditions */ if (p_ptr->blind || no_lite()) i = i / 10; if (p_ptr->confused || p_ptr->image) i = i / 10; - /* Variable power! */ - - /* Extract trap "power" */ - switch (c_ptr->feat) - { - case FEAT_TRAP_OPEN: - case FEAT_TRAP_ARMAGEDDON: - case FEAT_TRAP_PIRANHA: - /* Special traps are very difficult to disarm */ - power = 100; - break; - default: - power = 5; - break; - } - /* Extract the difficulty */ j = i - power; @@ -2221,21 +1891,13 @@ static bool do_cmd_disarm_aux(int y, int x, int dir) if (randint0(100) < j) { /* Message */ -#ifdef JP - msg_format("%s¤ò²ò½ü¤·¤¿¡£", name); -#else - msg_format("You have disarmed the %s.", name); -#endif - - + msg_format(_("%sを解除した。", "You have disarmed the %s."), name); + /* Reward */ gain_exp(power); - /* Forget the trap */ - c_ptr->info &= ~(CAVE_MARK); - /* Remove the trap */ - cave_set_feat(y, x, floor_type[randint0(100)]); + cave_alter_feat(y, x, FF_DISARM); #ifdef ALLOW_EASY_DISARM /* TNB */ @@ -2257,12 +1919,7 @@ static bool do_cmd_disarm_aux(int y, int x, int dir) if (flush_failure) flush(); /* Message */ -#ifdef JP - msg_format("%s¤Î²ò½ü¤Ë¼ºÇÔ¤·¤¿¡£", name); -#else - msg_format("You failed to disarm the %s.", name); -#endif - + msg_format(_("%sの解除に失敗した。", "You failed to disarm the %s."), name); /* We may keep trying */ more = TRUE; @@ -2272,12 +1929,7 @@ static bool do_cmd_disarm_aux(int y, int x, int dir) else { /* Message */ -#ifdef JP - msg_format("%s¤òºîÆ°¤µ¤»¤Æ¤·¤Þ¤Ã¤¿¡ª", name); -#else - msg_format("You set off the %s!", name); -#endif - + msg_format(_("%sを作動させてしまった!", "You set off the %s!"), name); #ifdef ALLOW_EASY_DISARM /* TNB */ @@ -2297,8 +1949,10 @@ static bool do_cmd_disarm_aux(int y, int x, int dir) } -/* +/*! + * @brief 箱、床のトラップ解除処理双方の統合メインルーチン / * Disarms a trap, or chest + * @return なし */ void do_cmd_disarm(void) { @@ -2354,43 +2008,33 @@ void do_cmd_disarm(void) if (get_rep_dir(&dir,TRUE)) { cave_type *c_ptr; - byte feat; + s16b feat; /* Get location */ - y = py + ddy[dir]; - x = px + ddx[dir]; + y = p_ptr->y + ddy[dir]; + x = p_ptr->x + ddx[dir]; /* Get grid and contents */ c_ptr = &cave[y][x]; /* Feature code (applying "mimic" field) */ - feat = c_ptr->mimic ? c_ptr->mimic : f_info[c_ptr->feat].mimic; + feat = get_feat_mimic(c_ptr); /* Check for chests */ - o_idx = chest_check(y, x); + o_idx = chest_check(y, x, TRUE); /* Disarm a trap */ if (!is_trap(feat) && !o_idx) { /* Message */ -#ifdef JP - msg_print("¤½¤³¤Ë¤Ï²ò½ü¤¹¤ë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("You see nothing there to disarm."); -#endif - + msg_print(_("そこには解除するものが見当たらない。", "You see nothing there to disarm.")); } /* Monster in the way */ else if (c_ptr->m_idx && p_ptr->riding != c_ptr->m_idx) { /* Message */ -#ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); -#else - msg_print("There is a monster in the way!"); -#endif - + msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!")); /* Attack */ py_attack(y, x, 0); @@ -2416,44 +2060,44 @@ void do_cmd_disarm(void) } -/* +/*! + * @brief 「打ち破る」動作コマンドのサブルーチン / * Perform the basic "bash" command - * + * @param y 対象を行うマスのY座標 + * @param x 対象を行うマスのX座標 + * @param dir プレイヤーから見たターゲットの方角ID + * @return 実際に処理が行われた場合TRUEを返す。 + * @details + *
  * Assume destination is a closed/locked/jammed door
- *
  * Assume there is no monster blocking the destination
- *
  * Returns TRUE if repeated commands may continue
+ * 
*/ static bool do_cmd_bash_aux(int y, int x, int dir) { - int bash, temp; + /* Get grid */ + cave_type *c_ptr = &cave[y][x]; - cave_type *c_ptr; + /* Get feature */ + feature_type *f_ptr = &f_info[c_ptr->feat]; + + /* Hack -- Bash power based on strength */ + /* (Ranges from 3 to 20 to 100 to 200) */ + int bash = adj_str_blow[p_ptr->stat_ind[A_STR]]; + + /* Extract door power */ + int temp = f_ptr->power; bool more = FALSE; + cptr name = f_name + f_info[get_feat_mimic(c_ptr)].name; /* Take a turn */ - energy_use = 100; - - /* Get grid */ - c_ptr = &cave[y][x]; + p_ptr->energy_use = 100; /* Message */ -#ifdef JP - msg_print("¥É¥¢¤ËÂÎÅö¤¿¤ê¤ò¤·¤¿¡ª"); -#else - msg_print("You smash into the door!"); -#endif - - - /* Hack -- Bash power based on strength */ - /* (Ranges from 3 to 20 to 100 to 200) */ - bash = adj_str_blow[p_ptr->stat_ind[A_STR]]; - - /* Extract door power */ - temp = ((c_ptr->feat - FEAT_DOOR_HEAD) & 0x07); + msg_format(_("%sに体当たりをした!", "You smash into the %s!"), name); /* Compare bash power to door power XXX XXX XXX */ temp = (bash - (temp * 10)); @@ -2467,34 +2111,25 @@ static bool do_cmd_bash_aux(int y, int x, int dir) if (randint0(100) < temp) { /* Message */ -#ifdef JP - msg_print("¥É¥¢¤ò²õ¤·¤¿¡ª"); -#else - msg_print("The door crashes open!"); -#endif + msg_format(_("%sを壊した!", "The %s crashes open!"), name); + /* Sound */ + sound(have_flag(f_ptr->flags, FF_GLASS) ? SOUND_GLASS : SOUND_OPENDOOR); /* Break down the door */ - if (randint0(100) < 50) + if ((randint0(100) < 50) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS)) { - cave_set_feat(y, x, FEAT_BROKEN); + cave_alter_feat(y, x, FF_BASH); } /* Open the door */ else { - cave_set_feat(y, x, FEAT_OPEN); + cave_alter_feat(y, x, FF_OPEN); } - /* Sound */ - sound(SOUND_OPENDOOR); - /* Hack -- Fall through the door */ move_player(dir, FALSE, FALSE); - - /* Update some things */ - p_ptr->update |= (PU_VIEW | PU_LITE); - p_ptr->update |= (PU_DISTANCE); } /* Saving throw against stun */ @@ -2502,12 +2137,7 @@ static bool do_cmd_bash_aux(int y, int x, int dir) p_ptr->lev) { /* Message */ -#ifdef JP - msg_print("¤³¤Î¥É¥¢¤Ï´è¾æ¤À¡£"); -#else - msg_print("The door holds firm."); -#endif - + msg_format(_("この%sは頑丈だ。", "The %s holds firm."), name); /* Allow repeated bashing */ more = TRUE; @@ -2517,12 +2147,7 @@ static bool do_cmd_bash_aux(int y, int x, int dir) else { /* Message */ -#ifdef JP - msg_print("ÂΤΥХé¥ó¥¹¤ò¤¯¤º¤·¤Æ¤·¤Þ¤Ã¤¿¡£"); -#else - msg_print("You are off-balance."); -#endif - + msg_print(_("体のバランスをくずしてしまった。", "You are off-balance.")); /* Hack -- Lose balance ala paralysis */ (void)set_paralyzed(p_ptr->paralyzed + 2 + randint0(2)); @@ -2533,9 +2158,12 @@ static bool do_cmd_bash_aux(int y, int x, int dir) } -/* +/*! + * @brief 「打ち破る」動作コマンドのメインルーチン / * Bash open a door, success based on character strength - * + * @return なし + * @details + *
  * For a closed door, pval is positive if locked; negative if stuck.
  *
  * For an open door, pval is positive for a broken door.
@@ -2546,6 +2174,7 @@ static bool do_cmd_bash_aux(int y, int x, int dir)
  * be bashed. A closed door can be jammed (see do_cmd_spike()).
  *
  * Creatures can also open or bash doors, see elsewhere.
+ * 
*/ void do_cmd_bash(void) { @@ -2577,44 +2206,33 @@ void do_cmd_bash(void) /* Get a "repeated" direction */ if (get_rep_dir(&dir,FALSE)) { - byte feat; + s16b feat; /* Bash location */ - y = py + ddy[dir]; - x = px + ddx[dir]; + y = p_ptr->y + ddy[dir]; + x = p_ptr->x + ddx[dir]; /* Get grid */ c_ptr = &cave[y][x]; /* Feature code (applying "mimic" field) */ - feat = c_ptr->mimic ? c_ptr->mimic : f_info[c_ptr->feat].mimic; + feat = get_feat_mimic(c_ptr); /* Nothing useful */ - if (!((feat >= FEAT_DOOR_HEAD) && - (feat <= FEAT_DOOR_TAIL))) + if (!have_flag(f_info[feat].flags, FF_BASH)) { /* Message */ -#ifdef JP - msg_print("¤½¤³¤Ë¤ÏÂÎÅö¤¿¤ê¤¹¤ë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("You see nothing there to bash."); -#endif - + msg_print(_("そこには体当たりするものが見当たらない。", "You see nothing there to bash.")); } /* Monster in the way */ else if (c_ptr->m_idx) { /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Message */ -#ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); -#else - msg_print("There is a monster in the way!"); -#endif - + msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!")); /* Attack */ py_attack(y, x, 0); @@ -2633,7 +2251,11 @@ void do_cmd_bash(void) } -/* +/*! + * @brief 特定のマスに影響を及ぼすための汎用的コマンド + * @return なし + * @details + *
  * Manipulate an adjacent grid in some way
  *
  * Attack monsters, tunnel through walls, disarm traps, open doors.
@@ -2642,6 +2264,7 @@ void do_cmd_bash(void)
  *
  * This command must always take a turn, to prevent free detection
  * of invisible monsters.
+ * 
*/ void do_cmd_alter(void) { @@ -2673,20 +2296,22 @@ void do_cmd_alter(void) /* Get a direction */ if (get_rep_dir(&dir,TRUE)) { - byte feat; + s16b feat; + feature_type *f_ptr; /* Get location */ - y = py + ddy[dir]; - x = px + ddx[dir]; + y = p_ptr->y + ddy[dir]; + x = p_ptr->x + ddx[dir]; /* Get grid */ c_ptr = &cave[y][x]; /* Feature code (applying "mimic" field) */ - feat = c_ptr->mimic ? c_ptr->mimic : f_info[c_ptr->feat].mimic; + feat = get_feat_mimic(c_ptr); + f_ptr = &f_info[feat]; /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Attack monsters */ if (c_ptr->m_idx) @@ -2695,39 +2320,32 @@ void do_cmd_alter(void) py_attack(y, x, 0); } - /* Tunnel through walls */ - else if (((feat >= FEAT_RUBBLE) && - (feat < FEAT_MINOR_GLYPH)) || - ((feat == FEAT_TREES) || - (feat == FEAT_MOUNTAIN))) + /* Locked doors */ + else if (have_flag(f_ptr->flags, FF_OPEN)) { - more = do_cmd_tunnel_aux(y, x); + more = do_cmd_open_aux(y, x); } - else if (is_closed_door(feat)) + /* Bash jammed doors */ + else if (have_flag(f_ptr->flags, FF_BASH)) { - /* Bash jammed doors */ - if (feat >= FEAT_DOOR_HEAD + 0x08) - { - more = do_cmd_bash_aux(y, x, dir); - } + more = do_cmd_bash_aux(y, x, dir); + } - /* Locked doors */ - else - { - more = do_cmd_open_aux(y, x); - } + /* Tunnel through walls */ + else if (have_flag(f_ptr->flags, FF_TUNNEL)) + { + more = do_cmd_tunnel_aux(y, x); } /* Close open doors */ - else if ((feat == FEAT_OPEN) || - (feat == FEAT_BROKEN)) + else if (have_flag(f_ptr->flags, FF_CLOSE)) { more = do_cmd_close_aux(y, x); } /* Disarm traps */ - else if (is_trap(feat)) + else if (have_flag(f_ptr->flags, FF_DISARM)) { more = do_cmd_disarm_aux(y, x, dir); } @@ -2735,13 +2353,8 @@ void do_cmd_alter(void) /* Oops */ else { - /* Oops */ -#ifdef JP - msg_print("²¿¤â¤Ê¤¤¶õÃæ¤ò¹¶·â¤·¤¿¡£"); -#else - msg_print("You attack the empty air."); -#endif - + /* Oops */ + msg_print(_("何もない空中を攻撃した。", "You attack the empty air.")); } } @@ -2750,10 +2363,16 @@ void do_cmd_alter(void) } -/* + +/*! + * @brief 「くさびを打つ」ために必要なオブジェクトがあるかどうかの判定を返す / * Find the index of some "spikes", if possible. - * + * @param ip くさびとして打てるオブジェクトのID + * @return オブジェクトがある場合TRUEを返す + * @details + *
  * XXX XXX XXX Let user choose a pile of spikes, perhaps?
+ * 
*/ static bool get_spike(int *ip) { @@ -2783,10 +2402,14 @@ static bool get_spike(int *ip) } -/* +/*! + * @brief 「くさびを打つ」動作コマンドのメインルーチン / * Jam a closed door with a spike - * + * @return なし + * @details + *
  * This command may NOT be repeated
+ * 
*/ void do_cmd_spike(void) { @@ -2802,56 +2425,40 @@ void do_cmd_spike(void) { int y, x, item; cave_type *c_ptr; - byte feat; + s16b feat; /* Get location */ - y = py + ddy[dir]; - x = px + ddx[dir]; + y = p_ptr->y + ddy[dir]; + x = p_ptr->x + ddx[dir]; /* Get grid and contents */ c_ptr = &cave[y][x]; /* Feature code (applying "mimic" field) */ - feat = c_ptr->mimic ? c_ptr->mimic : f_info[c_ptr->feat].mimic; + feat = get_feat_mimic(c_ptr); /* Require closed door */ - if (!((feat >= FEAT_DOOR_HEAD) && - (feat <= FEAT_DOOR_TAIL))) + if (!have_flag(f_info[feat].flags, FF_SPIKE)) { /* Message */ -#ifdef JP - msg_print("¤½¤³¤Ë¤Ï¤¯¤µ¤Ó¤òÂǤƤë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); -#else - msg_print("You see nothing there to spike."); -#endif - + msg_print(_("そこにはくさびを打てるものが見当たらない。", "You see nothing there to spike.")); } /* Get a spike */ else if (!get_spike(&item)) { /* Message */ -#ifdef JP - msg_print("¤¯¤µ¤Ó¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡ª"); -#else - msg_print("You have no spikes!"); -#endif - + msg_print(_("くさびを持っていない!", "You have no spikes!")); } /* Is a monster in the way? */ else if (c_ptr->m_idx) { /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Message */ -#ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); -#else - msg_print("There is a monster in the way!"); -#endif - + msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!")); /* Attack */ py_attack(y, x, 0); @@ -2861,21 +2468,11 @@ void do_cmd_spike(void) else { /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Successful jamming */ -#ifdef JP - msg_print("¥É¥¢¤Ë¤¯¤µ¤Ó¤òÂǤÁ¹þ¤ó¤À¡£"); -#else - msg_print("You jam the door with a spike."); -#endif - - - /* Convert "locked" to "stuck" XXX XXX XXX */ - if (c_ptr->feat < FEAT_DOOR_HEAD + 0x08) c_ptr->feat += 0x08; - - /* Add one spike to the door */ - if (c_ptr->feat < FEAT_DOOR_TAIL) c_ptr->feat++; + msg_format(_("%sにくさびを打ち込んだ。", "You jam the %s with a spike."), f_name + f_info[feat].name); + cave_alter_feat(y, x, FF_SPIKE); /* Use up, and describe, a single spike, from the bottom */ inven_item_increase(item, -1); @@ -2887,10 +2484,13 @@ void do_cmd_spike(void) -/* +/*! + * @brief 「歩く」動作コマンドのメインルーチン / * Support code for the "Walk" and "Jump" commands + * @param pickup アイテムの自動拾いを行うならTRUE + * @return なし */ -void do_cmd_walk(int pickup) +void do_cmd_walk(bool pickup) { int dir; @@ -2914,7 +2514,7 @@ void do_cmd_walk(int pickup) if (get_rep_dir(&dir,FALSE)) { /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; if ((dir != 5) && (p_ptr->special_defense & KATA_MUSOU)) { @@ -2922,8 +2522,8 @@ void do_cmd_walk(int pickup) } /* Hack -- In small scale wilderness it takes MUCH more time to move */ - if (p_ptr->wild_mode) energy_use *= ((MAX_HGT + MAX_WID) / 2); - if (p_ptr->action == ACTION_HAYAGAKE) energy_use = energy_use * (45-(p_ptr->lev/2)) / 100; + if (p_ptr->wild_mode) p_ptr->energy_use *= ((MAX_HGT + MAX_WID) / 2); + if (p_ptr->action == ACTION_HAYAGAKE) p_ptr->energy_use = p_ptr->energy_use * (45-(p_ptr->lev/2)) / 100; /* Actually move the character */ move_player(dir, pickup, FALSE); @@ -2933,28 +2533,24 @@ void do_cmd_walk(int pickup) } /* Hack again -- Is there a special encounter ??? */ - if(p_ptr->wild_mode && (cave[py][px].feat != FEAT_TOWN)) + if (p_ptr->wild_mode && !cave_have_flag_bold(p_ptr->y, p_ptr->x, FF_TOWN)) { - int tmp = 120 + p_ptr->lev*10 - wilderness[py][px].level + 5; + int tmp = 120 + p_ptr->lev*10 - wilderness[p_ptr->y][p_ptr->x].level + 5; if (tmp < 1) tmp = 1; - if (((wilderness[py][px].level + 5) > (p_ptr->lev / 2)) && randint0(tmp) < (21-p_ptr->skill_stl)) + if (((wilderness[p_ptr->y][p_ptr->x].level + 5) > (p_ptr->lev / 2)) && randint0(tmp) < (21-p_ptr->skill_stl)) { /* Inform the player of his horrible fate :=) */ -#ifdef JP - msg_print("½±·â¤À¡ª"); -#else - msg_print("You are ambushed !"); -#endif + msg_print(_("襲撃だ!", "You are ambushed !")); /* Go into large wilderness view */ - p_ptr->wilderness_x = px; - p_ptr->wilderness_y = py; p_ptr->oldpy = randint1(MAX_HGT-2); p_ptr->oldpx = randint1(MAX_WID-2); - energy_use = 100; change_wild_mode(); + /* Give first move to monsters */ + p_ptr->energy_use = 100; + /* HACk -- set the encouter flag for the wilderness generation */ generate_encounter = TRUE; } @@ -2965,9 +2561,10 @@ void do_cmd_walk(int pickup) } - -/* +/*! + * @brief 「走る」動作コマンドのメインルーチン / * Start running. + * @return なし */ void do_cmd_run(void) { @@ -2976,12 +2573,7 @@ void do_cmd_run(void) /* Hack -- no running when confused */ if (p_ptr->confused) { -#ifdef JP - msg_print("º®Í𤷤Ƥ¤¤ÆÁö¤ì¤Ê¤¤¡ª"); -#else - msg_print("You are too confused!"); -#endif - + msg_print(_("混乱していて走れない!", "You are too confused!")); return; } @@ -3002,15 +2594,16 @@ void do_cmd_run(void) } - -/* +/*! + * @brief 「留まる」動作コマンドのメインルーチン / * Stay still. Search. Enter stores. * Pick up treasure if "pickup" is true. + * @param pickup アイテムの自動拾いを行うならTRUE + * @return なし */ -void do_cmd_stay(int pickup) +void do_cmd_stay(bool pickup) { - cave_type *c_ptr = &cave[py][px]; - + u32b mpe_mode = MPE_STAYING | MPE_ENERGY_USE; /* Allow repeated command */ if (command_arg) @@ -3025,86 +2618,18 @@ void do_cmd_stay(int pickup) command_arg = 0; } - /* Take a turn */ - energy_use = 100; - - - /* Spontaneous Searching */ - if ((p_ptr->skill_fos >= 50) || (0 == randint0(50 - p_ptr->skill_fos))) - { - search(); - } - - /* Continuous Searching */ - if (p_ptr->action == ACTION_SEARCH) - { - search(); - } - - - /* Handle "objects" */ - carry(pickup); - - - /* Hack -- enter a store if we are on one */ - if (((c_ptr->feat >= FEAT_SHOP_HEAD) && - (c_ptr->feat <= FEAT_SHOP_TAIL)) || - (c_ptr->feat == FEAT_MUSEUM)) - { - /* Disturb */ - disturb(0, 0); - - energy_use = 0; - /* Hack -- enter store */ - command_new = SPECIAL_KEY_STORE; - } - - /* Hack -- enter a building if we are on one -KMW- */ - else if ((c_ptr->feat >= FEAT_BLDG_HEAD) && - (c_ptr->feat <= FEAT_BLDG_TAIL)) - { - /* Disturb */ - disturb(0, 0); - - energy_use = 0; - /* Hack -- enter building */ - command_new = SPECIAL_KEY_BUILDING; - } - - /* Exit a quest if reach the quest exit */ - else if (c_ptr->feat == FEAT_QUEST_EXIT) - { - int q_index = p_ptr->inside_quest; - - /* Was quest completed? */ - if (quest[q_index].type == QUEST_TYPE_FIND_EXIT) - { - quest[q_index].status = QUEST_STATUS_COMPLETED; - quest[q_index].complev = (byte)p_ptr->lev; -#ifdef JP - msg_print("¥¯¥¨¥¹¥È¤ò´°Î»¤·¤¿¡ª"); -#else - msg_print("You accomplished your quest!"); -#endif + p_ptr->energy_use = 100; - msg_print(NULL); - } - - leave_quest_check(); - - p_ptr->inside_quest = cave[py][px].special; - dun_level = 0; - p_ptr->oldpx = 0; - p_ptr->oldpy = 0; - p_ptr->leaving = TRUE; - } + if (pickup) mpe_mode |= MPE_DO_PICKUP; + (void)move_player_effect(p_ptr->y, p_ptr->x, mpe_mode); } - -/* +/*! + * @brief 「休む」動作コマンドのメインルーチン / * Resting allows a player to safely restore his hp -RAK- + * @return なし */ void do_cmd_rest(void) { @@ -3116,14 +2641,14 @@ void do_cmd_rest(void) stop_singing(); } + /* Hex */ + if (hex_spelling_any()) stop_hex_spell_all(); + /* Prompt for time if needed */ if (command_arg <= 0) { -#ifdef JP - cptr p = "µÙ·Æ (0-9999, '*' ¤Ç HP/MPÁ´²÷, '&' ¤ÇɬÍפʤÀ¤±): "; -#else - cptr p = "Rest (0-9999, '*' for HP/SP, '&' as needed): "; -#endif + cptr p = _("休憩 (0-9999, '*' で HP/MP全快, '&' で必要なだけ): ", + "Rest (0-9999, '*' for HP/SP, '&' as needed): "); char out_val[80]; @@ -3161,7 +2686,7 @@ void do_cmd_rest(void) if (p_ptr->special_defense & NINJA_S_STEALTH) set_superstealth(FALSE); /* Take a turn XXX XXX XXX (?) */ - energy_use = 100; + p_ptr->energy_use = 100; /* The sin of sloth */ if (command_arg > 100) @@ -3196,15 +2721,30 @@ void do_cmd_rest(void) } -/* +/*! + * @brief 矢弾を射撃した場合の破損確率を返す / * Determines the odds of an object breaking when thrown at a monster - * + * @param o_ptr 矢弾のオブジェクト構造体参照ポインタ + * @return 破損確率(%) + * @details * Note that artifacts never break, see the "drop_near()" function. */ static int breakage_chance(object_type *o_ptr) { int archer_bonus = (p_ptr->pclass == CLASS_ARCHER ? (p_ptr->lev-1)/7 + 4: 0); + /* Examine the snipe type */ + if (snipe_type) + { + if (snipe_type == SP_KILL_WALL) return (100); + if (snipe_type == SP_EXPLODE) return (100); + if (snipe_type == SP_PIERCE) return (100); + if (snipe_type == SP_FINAL) return (100); + if (snipe_type == SP_NEEDLE) return (100); + if (snipe_type == SP_EVILNESS) return (40); + if (snipe_type == SP_HOLYNESS) return (40); + } + /* Examine the item type */ switch (o_ptr->tval) { @@ -3239,6 +2779,14 @@ static int breakage_chance(object_type *o_ptr) } +/*! + * @brief 矢弾を射撃した際のスレイ倍率をかけた結果を返す / + * Determines the odds of an object breaking when thrown at a monster + * @param o_ptr 矢弾のオブジェクト構造体参照ポインタ + * @param tdam 計算途中のダメージ量 + * @param m_ptr 目標モンスターの構造体参照ポインタ + * @return スレイ倍率をかけたダメージ量 + */ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) { int mult = 10; @@ -3261,7 +2809,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_SLAY_ANIMAL)) && (r_ptr->flags3 & RF3_ANIMAL)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_ANIMAL; } @@ -3273,7 +2821,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_KILL_ANIMAL)) && (r_ptr->flags3 & RF3_ANIMAL)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_ANIMAL; } @@ -3285,7 +2833,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_SLAY_EVIL)) && (r_ptr->flags3 & RF3_EVIL)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_EVIL; } @@ -3297,7 +2845,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_KILL_EVIL)) && (r_ptr->flags3 & RF3_EVIL)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_EVIL; } @@ -3309,7 +2857,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_SLAY_HUMAN)) && (r_ptr->flags2 & RF2_HUMAN)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags2 |= RF2_HUMAN; } @@ -3321,7 +2869,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_KILL_HUMAN)) && (r_ptr->flags2 & RF2_HUMAN)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags2 |= RF2_HUMAN; } @@ -3333,7 +2881,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_SLAY_UNDEAD)) && (r_ptr->flags3 & RF3_UNDEAD)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_UNDEAD; } @@ -3345,7 +2893,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_KILL_UNDEAD)) && (r_ptr->flags3 & RF3_UNDEAD)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_UNDEAD; } @@ -3357,7 +2905,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_SLAY_DEMON)) && (r_ptr->flags3 & RF3_DEMON)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_DEMON; } @@ -3369,7 +2917,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_KILL_DEMON)) && (r_ptr->flags3 & RF3_DEMON)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_DEMON; } @@ -3381,7 +2929,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_SLAY_ORC)) && (r_ptr->flags3 & RF3_ORC)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_ORC; } @@ -3393,7 +2941,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_KILL_ORC)) && (r_ptr->flags3 & RF3_ORC)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_ORC; } @@ -3405,7 +2953,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_SLAY_TROLL)) && (r_ptr->flags3 & RF3_TROLL)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_TROLL; } @@ -3417,7 +2965,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_KILL_TROLL)) && (r_ptr->flags3 & RF3_TROLL)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_TROLL; } @@ -3429,7 +2977,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_SLAY_GIANT)) && (r_ptr->flags3 & RF3_GIANT)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_GIANT; } @@ -3441,7 +2989,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_KILL_GIANT)) && (r_ptr->flags3 & RF3_GIANT)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_GIANT; } @@ -3453,7 +3001,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_SLAY_DRAGON)) && (r_ptr->flags3 & RF3_DRAGON)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_DRAGON; } @@ -3465,7 +3013,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) if ((have_flag(flgs, TR_KILL_DRAGON)) && (r_ptr->flags3 & RF3_DRAGON)) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags3 |= RF3_DRAGON; } @@ -3479,14 +3027,14 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) } /* Brand (Acid) */ - if ((have_flag(flgs, TR_BRAND_ACID)) || (p_ptr->special_attack & (ATTACK_ACID))) + if (have_flag(flgs, TR_BRAND_ACID)) { /* Notice immunity */ - if (r_ptr->flags3 & RF3_IM_ACID) + if (r_ptr->flagsr & RFR_EFF_IM_ACID_MASK) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { - r_ptr->r_flags3 |= RF3_IM_ACID; + r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ACID_MASK); } } @@ -3498,14 +3046,14 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) } /* Brand (Elec) */ - if ((have_flag(flgs, TR_BRAND_ELEC)) || (p_ptr->special_attack & (ATTACK_ELEC))) + if (have_flag(flgs, TR_BRAND_ELEC)) { /* Notice immunity */ - if (r_ptr->flags3 & RF3_IM_ELEC) + if (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { - r_ptr->r_flags3 |= RF3_IM_ELEC; + r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK); } } @@ -3517,51 +3065,67 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) } /* Brand (Fire) */ - if ((have_flag(flgs, TR_BRAND_FIRE)) || (p_ptr->special_attack & (ATTACK_FIRE))) + if (have_flag(flgs, TR_BRAND_FIRE)) { /* Notice immunity */ - if (r_ptr->flags3 & RF3_IM_FIRE) + if (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { - r_ptr->r_flags3 |= RF3_IM_FIRE; + r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK); } } /* Otherwise, take the damage */ else { - if (mult < 17) mult = 17; + if (r_ptr->flags3 & RF3_HURT_FIRE) + { + if (mult < 25) mult = 25; + if (is_original_ap_and_seen(m_ptr)) + { + r_ptr->r_flags3 |= RF3_HURT_FIRE; + } + } + else if (mult < 17) mult = 17; } } /* Brand (Cold) */ - if ((have_flag(flgs, TR_BRAND_COLD)) || (p_ptr->special_attack & (ATTACK_COLD))) + if (have_flag(flgs, TR_BRAND_COLD)) { /* Notice immunity */ - if (r_ptr->flags3 & RF3_IM_COLD) + if (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { - r_ptr->r_flags3 |= RF3_IM_COLD; + r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK); } } /* Otherwise, take the damage */ else { - if (mult < 17) mult = 17; + if (r_ptr->flags3 & RF3_HURT_COLD) + { + if (mult < 25) mult = 25; + if (is_original_ap_and_seen(m_ptr)) + { + r_ptr->r_flags3 |= RF3_HURT_COLD; + } + } + else if (mult < 17) mult = 17; } } /* Brand (Poison) */ - if ((have_flag(flgs, TR_BRAND_POIS)) || (p_ptr->special_attack & (ATTACK_POIS))) + if (have_flag(flgs, TR_BRAND_POIS)) { /* Notice immunity */ - if (r_ptr->flags3 & RF3_IM_POIS) + if (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK) { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) { - r_ptr->r_flags3 |= RF3_IM_POIS; + r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK); } } @@ -3582,14 +3146,22 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) } } + /* Sniper */ + if (snipe_type) mult = tot_dam_aux_snipe(mult, m_ptr); + /* Return the total damage */ return (tdam * mult / 10); } -/* +/*! + * @brief 射撃処理のサブルーチン / * Fire an object from the pack or floor. - * + * @param item 射撃するオブジェクトの所持ID + * @param j_ptr 射撃武器のオブジェクト参照ポインタ + * @return なし + * @details + *
  * You may only fire items that "match" your missile launcher.
  *
  * You must use slings + pebbles/shots, bows + arrows, xbows + bolts.
@@ -3614,12 +3186,13 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
  * for the damage multiplier.
  *
  * Note that Bows of "Extra Shots" give an extra shot.
+ * 
*/ void do_cmd_fire_aux(int item, object_type *j_ptr) { int dir; - int j, y, x, ny, nx, ty, tx; - int tdam, tdis, thits, tmul; + int i, j, y, x, ny, nx, ty, tx, prev_y, prev_x; + int tdam_base, tdis, thits, tmul; int bonus, chance; int cur_dis, visible; @@ -3632,6 +3205,8 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) char o_name[MAX_NLEN]; + u16b path_g[512]; /* For calcuration of path length */ + int msec = delay_factor * delay_factor * delay_factor; /* STICK TO */ @@ -3647,9 +3222,11 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) o_ptr = &o_list[0 - item]; } - /* Describe the object */ - object_desc(o_name, o_ptr, FALSE, 3); + /* Sniper - Cannot shot a single arrow twice */ + if ((snipe_type == SP_DOUBLE) && (o_ptr->number < 2)) snipe_type = SP_NONE; + /* Describe the object */ + object_desc(o_name, o_ptr, OD_OMIT_PREFIX); /* Use the proper number of shots */ thits = p_ptr->num_fire; @@ -3658,7 +3235,7 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) tdis = 10; /* Base damage from thrown object plus launcher bonus */ - tdam = damroll(o_ptr->dd, o_ptr->ds) + o_ptr->to_d + j_ptr->to_d; + tdam_base = damroll(o_ptr->dd, o_ptr->ds) + o_ptr->to_d + j_ptr->to_d; /* Actually "fire" the object */ bonus = (p_ptr->to_h_b + o_ptr->to_h + j_ptr->to_h); @@ -3667,7 +3244,7 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) else chance = (p_ptr->skill_thb + ((p_ptr->weapon_exp[0][j_ptr->sval] - (WEAPON_EXP_MASTER / 2)) / 200 + bonus) * BTH_PLUS_ADJ); - energy_use = bow_energy(j_ptr->sval); + p_ptr->energy_use = bow_energy(j_ptr->sval); tmul = bow_tmul(j_ptr->sval); /* Get extra "power" from "extra might" */ @@ -3676,27 +3253,75 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128); /* Boost the damage */ - tdam *= tmul; - tdam /= 100; + tdam_base *= tmul; + tdam_base /= 100; /* Base range */ - tdis = 10 + tmul/40; + tdis = 13 + tmul/80; if ((j_ptr->sval == SV_LIGHT_XBOW) || (j_ptr->sval == SV_HEAVY_XBOW)) - tdis -= 5; + { + if (p_ptr->concent) + tdis -= (5 - (p_ptr->concent + 1) / 2); + else + tdis -= 5; + } project_length = tdis + 1; /* Get a direction (or cancel) */ if (!get_aim_dir(&dir)) { - energy_use = 0; + p_ptr->energy_use = 0; + + if (snipe_type == SP_AWAY) snipe_type = SP_NONE; /* need not to reset project_length (already did)*/ return; } + + /* Predict the "target" location */ + tx = p_ptr->x + 99 * ddx[dir]; + ty = p_ptr->y + 99 * ddy[dir]; + + /* Check for "target request" */ + if ((dir == 5) && target_okay()) + { + tx = target_col; + ty = target_row; + } + + /* Get projection path length */ + tdis = project_path(path_g, project_length, p_ptr->y, p_ptr->x, ty, tx, PROJECT_PATH|PROJECT_THRU) - 1; + project_length = 0; /* reset to default */ + /* Don't shoot at my feet */ + if (tx == p_ptr->x && ty == p_ptr->y) + { + p_ptr->energy_use = 0; + + /* project_length is already reset to 0 */ + + return; + } + + + /* Take a (partial) turn */ + p_ptr->energy_use = (p_ptr->energy_use / thits); + is_fired = TRUE; + + /* Sniper - Difficult to shot twice at 1 turn */ + if (snipe_type == SP_DOUBLE) p_ptr->concent = (p_ptr->concent + 1) / 2; + + /* Sniper - Repeat shooting when double shots */ + for (i = 0; i < ((snipe_type == SP_DOUBLE) ? 2 : 1); i++) + { + + /* Start at the player */ + y = p_ptr->y; + x = p_ptr->x; + /* Get local object */ q_ptr = &forge; @@ -3721,52 +3346,70 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) floor_item_optimize(0 - item); } - /* Sound */ sound(SOUND_SHOOT); - - /* Take a (partial) turn */ - energy_use = (energy_use / thits); - - - /* Start at the player */ - y = py; - x = px; - - /* Predict the "target" location */ - tx = px + 99 * ddx[dir]; - ty = py + 99 * ddy[dir]; - - /* Check for "target request" */ - if ((dir == 5) && target_okay()) - { - tx = target_col; - ty = target_row; - } - - /* Hack -- Handle stuff */ handle_stuff(); + /* Save the old location */ + prev_y = y; + prev_x = x; + + /* The shot does not hit yet */ + hit_body = FALSE; /* Travel until stopped */ for (cur_dis = 0; cur_dis <= tdis; ) { + cave_type *c_ptr; + /* Hack -- Stop at the target */ if ((y == ty) && (x == tx)) break; /* Calculate the new location (see "project()") */ ny = y; nx = x; - mmove2(&ny, &nx, py, px, ty, tx); + mmove2(&ny, &nx, p_ptr->y, p_ptr->x, ty, tx); + + /* Shatter Arrow */ + if (snipe_type == SP_KILL_WALL) + { + c_ptr = &cave[ny][nx]; + + if (cave_have_flag_grid(c_ptr, FF_HURT_ROCK) && !c_ptr->m_idx) + { + if (c_ptr->info & (CAVE_MARK)) msg_print(_("岩が砕け散った。", "Wall rocks were shattered.")); + /* Forget the wall */ + c_ptr->info &= ~(CAVE_MARK); + + p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE); + + /* Destroy the wall */ + cave_alter_feat(ny, nx, FF_HURT_ROCK); + + hit_body = TRUE; + break; + } + } /* Stopped by walls/doors */ - if (!cave_floor_bold(ny, nx) && !cave[ny][nx].m_idx) break; + if (!cave_have_flag_bold(ny, nx, FF_PROJECT) && !cave[ny][nx].m_idx) break; /* Advance the distance */ cur_dis++; + /* Sniper */ + if (snipe_type == SP_LITE) + { + cave[ny][nx].info |= (CAVE_GLOW); + + /* Notice */ + note_spot(ny, nx); + + /* Redraw */ + lite_spot(ny, nx); + } /* The player can see the (on screen) missile */ if (panel_contains(ny, nx) && player_can_see_bold(ny, nx)) @@ -3790,6 +3433,29 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) Term_xtra(TERM_XTRA_DELAY, msec); } + /* Sniper */ + if (snipe_type == SP_KILL_TRAP) + { + project(0, 0, ny, nx, 0, GF_KILL_TRAP, + (PROJECT_JUMP | PROJECT_HIDE | PROJECT_GRID | PROJECT_ITEM), -1); + } + + /* Sniper */ + if (snipe_type == SP_EVILNESS) + { + cave[ny][nx].info &= ~(CAVE_GLOW | CAVE_MARK); + + /* Notice */ + note_spot(ny, nx); + + /* Redraw */ + lite_spot(ny, nx); + } + + /* Save the old location */ + prev_y = y; + prev_x = x; + /* Save the new location */ x = nx; y = ny; @@ -3798,9 +3464,9 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) /* Monster here, Try to hit it */ if (cave[y][x].m_idx) { - cave_type *c_ptr = &cave[y][x]; + cave_type *c_mon_ptr = &cave[y][x]; - monster_type *m_ptr = &m_list[c_ptr->m_idx]; + monster_type *m_ptr = &m_list[c_mon_ptr->m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; /* Check the visibility */ @@ -3809,7 +3475,7 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) /* Note the collision */ hit_body = TRUE; - if (m_ptr->csleep) + if (MON_CSLEEP(m_ptr)) { if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_COMPASSION, -1); if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_HONOUR, -1); @@ -3821,9 +3487,9 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) if (now_exp < s_info[p_ptr->pclass].w_max[0][j_ptr->sval]) { int amount = 0; - if (now_exp < SPELL_EXP_BEGINNER) amount = 80; - else if (now_exp < SPELL_EXP_SKILLED) amount = 25; - else if ((now_exp < SPELL_EXP_EXPERT) && (p_ptr->lev > 19)) amount = 10; + if (now_exp < WEAPON_EXP_BEGINNER) amount = 80; + else if (now_exp < WEAPON_EXP_SKILLED) amount = 25; + else if ((now_exp < WEAPON_EXP_EXPERT) && (p_ptr->lev > 19)) amount = 10; else if (p_ptr->lev > 34) amount = 2; p_ptr->weapon_exp[0][j_ptr->sval] += amount; p_ptr->update |= (PU_BONUS); @@ -3842,54 +3508,19 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) } /* Did we hit it (penalize range) */ - if (test_hit_fire(chance - cur_dis, r_ptr->ac, m_ptr->ml)) + if (test_hit_fire(chance - cur_dis, m_ptr, m_ptr->ml, o_name)) { bool fear = FALSE; + int tdam = tdam_base; - /* Assume a default death */ -#ifdef JP - cptr note_dies = "¤Ï»à¤ó¤À¡£"; -#else - cptr note_dies = " dies."; -#endif - - /* Some monsters get "destroyed" */ - if (!monster_living(r_ptr)) - { - int i; - bool explode = FALSE; - - for (i = 0; i < 4; i++) - { - if (r_ptr->blow[i].method == RBM_EXPLODE) explode = TRUE; - } - - /* Special note at death */ - if (explode) -#ifdef JP -note_dies = "¤ÏÇúȯ¤·¤ÆÊ´¡¹¤Ë¤Ê¤Ã¤¿¡£"; -#else - note_dies = " explodes into tiny shreds."; -#endif - else -#ifdef JP - note_dies = "¤òÅݤ·¤¿¡£"; -#else - note_dies = " is destroyed."; -#endif - - } + /* Get extra damage from concentration */ + if (p_ptr->concent) tdam = boost_concentration_damage(tdam); /* Handle unseen monster */ if (!visible) { /* Invisible monster */ -#ifdef JP - msg_format("%s¤¬Å¨¤òÊ᪤·¤¿¡£", o_name); -#else - msg_format("The %s finds a mark.", o_name); -#endif - + msg_format(_("%sが敵を捕捉した。", "The %s finds a mark."), o_name); } /* Handle visible monster */ @@ -3901,45 +3532,76 @@ note_dies = " monster_desc(m_name, m_ptr, 0); /* Message */ -#ifdef JP - msg_format("%s¤¬%s¤ËÌ¿Ã椷¤¿¡£", o_name, m_name); -#else - msg_format("The %s hits %s.", o_name, m_name); -#endif + msg_format(_("%sが%sに命中した。", "The %s hits %s."), o_name, m_name); + if (m_ptr->ml) + { + /* Hack -- Track this monster race */ + if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx); - /* Hack -- Track this monster race */ - if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx); - - /* Hack -- Track this monster */ - if (m_ptr->ml) health_track(c_ptr->m_idx); + /* Hack -- Track this monster */ + health_track(c_mon_ptr->m_idx); + } } - /* Apply special damage XXX XXX XXX */ - tdam = tot_dam_aux_shot(q_ptr, tdam, m_ptr); - tdam = critical_shot(q_ptr->weight, q_ptr->to_h, tdam); + if (snipe_type == SP_NEEDLE) + { + if ((randint1(randint1(r_ptr->level / (3 + p_ptr->concent)) + (8 - p_ptr->concent)) == 1) + && !(r_ptr->flags1 & RF1_UNIQUE) && !(r_ptr->flags7 & RF7_UNIQUE2)) + { + char m_name[80]; - /* No negative damage */ - if (tdam < 0) tdam = 0; + /* Get "the monster" or "it" */ + monster_desc(m_name, m_ptr, 0); - /* Modify the damage */ - tdam = mon_damage_mod(m_ptr, tdam, FALSE); + tdam = m_ptr->hp + 1; + msg_format(_("%sの急所に突き刺さった!", "Your shot sticked on a fatal spot of %s!"), m_name); + } + else tdam = 1; + } + else + { + /* Apply special damage XXX XXX XXX */ + tdam = tot_dam_aux_shot(q_ptr, tdam, m_ptr); + tdam = critical_shot(q_ptr->weight, q_ptr->to_h, j_ptr->to_h, tdam); + + /* No negative damage */ + if (tdam < 0) tdam = 0; + + /* Modify the damage */ + tdam = mon_damage_mod(m_ptr, tdam, FALSE); + } /* Complex message */ if (p_ptr->wizard || cheat_xtra) { -#ifdef JP - msg_format("%d/%d ¤Î¥À¥á¡¼¥¸¤òÍ¿¤¨¤¿¡£", - tdam, m_ptr->hp); -#else - msg_format("You do %d (out of %d) damage.", - tdam, m_ptr->hp); -#endif + msg_format(_("%d/%d のダメージを与えた。", "You do %d (out of %d) damage."), tdam, m_ptr->hp); + } + + /* Sniper */ + if (snipe_type == SP_EXPLODE) + { + u16b flg = (PROJECT_STOP | PROJECT_JUMP | PROJECT_KILL | PROJECT_GRID); + + sound(SOUND_EXPLODE); /* No explode sound - use breath fire instead */ + project(0, ((p_ptr->concent + 1) / 2 + 1), ny, nx, tdam, GF_MISSILE, flg, -1); + break; + } + /* Sniper */ + if (snipe_type == SP_HOLYNESS) + { + cave[ny][nx].info |= (CAVE_GLOW); + + /* Notice */ + note_spot(ny, nx); + + /* Redraw */ + lite_spot(ny, nx); } /* Hit the monster, check for death */ - if (mon_take_hit(c_ptr->m_idx, tdam, &fear, note_dies)) + if (mon_take_hit(c_mon_ptr->m_idx, tdam, &fear, extract_note_dies(real_r_ptr(m_ptr)))) { /* Dead monster */ } @@ -3948,22 +3610,19 @@ note_dies = " else { /* STICK TO */ - if (q_ptr->name1) + if (object_is_fixed_artifact(q_ptr) && + (p_ptr->pclass != CLASS_SNIPER || p_ptr->concent == 0)) { char m_name[80]; monster_desc(m_name, m_ptr, 0); stick_to = TRUE; -#ifdef JP - msg_format("%s¤Ï%s¤ËÆͤ­»É¤µ¤Ã¤¿¡ª",o_name, m_name); -#else - msg_format("%^s have stuck into %s!",o_name, m_name); -#endif + msg_format(_("%sは%sに突き刺さった!", "%^s have stuck into %s!"),o_name, m_name); } /* Message */ - message_pain(c_ptr->m_idx, tdam); + message_pain(c_mon_ptr->m_idx, tdam); /* Anger the monster */ if (tdam > 0) anger_monster(m_ptr); @@ -3980,20 +3639,68 @@ note_dies = " monster_desc(m_name, m_ptr, 0); /* Message */ -#ifdef JP - msg_format("%^s¤Ï¶²Éݤ·¤Æƨ¤²½Ð¤·¤¿¡ª", m_name); -#else - msg_format("%^s flees in terror!", m_name); -#endif + msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), m_name); + } + + set_target(m_ptr, p_ptr->y, p_ptr->x); + + /* Sniper */ + if (snipe_type == SP_RUSH) + { + int n = randint1(5) + 3; + int m_idx = c_mon_ptr->m_idx; + + for ( ; cur_dis <= tdis; ) + { + int ox = nx; + int oy = ny; + + if (!n) break; + + /* Calculate the new location (see "project()") */ + mmove2(&ny, &nx, p_ptr->y, p_ptr->x, ty, tx); + + /* Stopped by wilderness boundary */ + if (!in_bounds2(ny, nx)) break; + + /* Stopped by walls/doors */ + if (!player_can_enter(cave[ny][nx].feat, 0)) break; + + /* Stopped by monsters */ + if (!cave_empty_bold(ny, nx)) break; + + cave[ny][nx].m_idx = m_idx; + cave[oy][ox].m_idx = 0; + + m_ptr->fx = nx; + m_ptr->fy = ny; + + /* Update the monster (new location) */ + update_mon(c_mon_ptr->m_idx, TRUE); + + lite_spot(ny, nx); + lite_spot(oy, ox); - } - if (!projectable(m_ptr->fy, m_ptr->fx, py, px)) - { - set_target(m_ptr, py, px); + Term_fresh(); + Term_xtra(TERM_XTRA_DELAY, msec); + + x = nx; + y = ny; + cur_dis++; + n--; + } } } } + /* Sniper */ + if (snipe_type == SP_PIERCE) + { + if(p_ptr->concent < 1) break; + p_ptr->concent--; + continue; + } + /* Stop looking */ break; } @@ -4002,31 +3709,27 @@ note_dies = " /* Chance of breakage (during attacks) */ j = (hit_body ? breakage_chance(q_ptr) : 0); - if(stick_to) + if (stick_to) { int m_idx = cave[y][x].m_idx; monster_type *m_ptr = &m_list[m_idx]; int o_idx = o_pop(); if (!o_idx) - { -#ifdef JP - msg_format("%s¤Ï¤É¤³¤«¤Ø¹Ô¤Ã¤¿¡£", o_name); -#else - msg_format("The %s have gone to somewhere.", o_name); -#endif - if (q_ptr->name1) - { - a_info[j_ptr->name1].cur_num = 0; - } - return; - } - - o_ptr = &o_list[ o_idx ]; + { + msg_format(_("%sはどこかへ行った。", "The %s have gone to somewhere."), o_name); + if (object_is_fixed_artifact(q_ptr)) + { + a_info[j_ptr->name1].cur_num = 0; + } + return; + } + + o_ptr = &o_list[o_idx]; object_copy(o_ptr, q_ptr); /* Forget mark */ - o_ptr->marked = 0; + o_ptr->marked &= OM_TOUCHED; /* Forget location */ o_ptr->iy = o_ptr->ix = 0; @@ -4039,42 +3742,58 @@ note_dies = " /* Carry object */ m_ptr->hold_o_idx = o_idx; - } - else + else if (cave_have_flag_bold(y, x, FF_PROJECT)) + { /* Drop (or break) near that location */ (void)drop_near(q_ptr, j, y, x); -} + } + else + { + /* Drop (or break) near that location */ + (void)drop_near(q_ptr, j, prev_y, prev_x); + } + /* Sniper - Repeat shooting when double shots */ + } + + /* Sniper - Loose his/her concentration after any shot */ + if (p_ptr->concent) reset_concentration(FALSE); +} +/*! + * @brief 射撃処理のメインルーチン + * @return なし + */ void do_cmd_fire(void) { int item; object_type *j_ptr; cptr q, s; + is_fired = FALSE; /* not fired yet */ + /* Get the "bow" (if any) */ j_ptr = &inventory[INVEN_BOW]; /* Require a launcher */ if (!j_ptr->tval) { -#ifdef JP - msg_print("¼Í·âÍѤÎÉð´ï¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£"); -#else - msg_print("You have nothing to fire with."); -#endif + msg_print(_("射撃用の武器を持っていない。", "You have nothing to fire with.")); flush(); return; } if (j_ptr->sval == SV_CRIMSON) { -#ifdef JP - msg_print("¤³¤ÎÉð´ï¤Ïȯư¤·¤Æ»È¤¦¤â¤Î¤Î¤è¤¦¤À¡£"); -#else - msg_print("Do activate."); -#endif + msg_print(_("この武器は発動して使うもののようだ。", "Do activate.")); + flush(); + return; + } + + if (j_ptr->sval == SV_HARP) + { + msg_print(_("この武器で射撃はできない。", "It's not for firing.")); flush(); return; } @@ -4089,14 +3808,8 @@ void do_cmd_fire(void) item_tester_tval = p_ptr->tval_ammo; /* Get an item */ -#ifdef JP - q = "¤É¤ì¤ò·â¤Á¤Þ¤¹¤«? "; - s = "ȯ¼Í¤µ¤ì¤ë¥¢¥¤¥Æ¥à¤¬¤¢¤ê¤Þ¤»¤ó¡£"; -#else - q = "Fire which item? "; - s = "You have nothing to fire."; -#endif - + q = _("どれを撃ちますか? ", "Fire which item? "); + s = _("発射されるアイテムがありません。", "You have nothing to fire."); if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) { flush(); @@ -4105,9 +3818,27 @@ void do_cmd_fire(void) /* Fire the item */ do_cmd_fire_aux(item, j_ptr); -} + if (!is_fired || p_ptr->pclass != CLASS_SNIPER) return; + + /* Sniper actions after some shootings */ + if (snipe_type == SP_AWAY) + { + teleport_player(10 + (p_ptr->concent * 2), 0L); + } + if (snipe_type == SP_FINAL) + { + msg_print(_("射撃の反動が体を襲った。", "A reactionary of shooting attacked you. ")); + (void)set_slow(p_ptr->slow + randint0(7) + 7, FALSE); + (void)set_stun(p_ptr->stun + randint1(25)); + } +} +/*! + * @brief オブジェクトが投射可能な武器かどうかを返す。 + * @param o_ptr 判定するオブジェクトの構造体参照ポインタ + * @return 投射可能な武器ならばTRUE + */ static bool item_tester_hook_boomerang(object_type *o_ptr) { if ((o_ptr->tval==TV_DIGGING) || (o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM) || (o_ptr->tval == TV_HAFTED)) return (TRUE); @@ -4117,22 +3848,29 @@ static bool item_tester_hook_boomerang(object_type *o_ptr) } -/* +/*! + * @brief 投射処理のサブルーチン / * Throw an object from the pack or floor. - * + * @param mult 威力の倍率 + * @param boomerang ブーメラン処理ならばTRUE + * @param shuriken 忍者の手裏剣処理ならばTRUE + * @return ターンを消費した場合TRUEを返す + * @details + *
  * Note: "unseen" monsters are very hard to hit.
  *
  * Should throwing a weapon do full damage?  Should it allow the magic
  * to hit bonus of the weapon to have an effect?  Should it ever cause
  * the item to be destroyed?  Should it do any damage at all?
+ * 
*/ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) { int dir, item; - int i, j, y, x, ty, tx; + int i, j, y, x, ty, tx, prev_y, prev_x; int ny[19], nx[19]; int chance, tdam, tdis; - int mul, div; + int mul, div, dd, ds; int cur_dis, visible; object_type forge; @@ -4160,45 +3898,31 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) set_action(ACTION_NONE); } - if (shuriken) + if (shuriken >= 0) { item = shuriken; } else if (boomerang) { - if (buki_motteruka(INVEN_LARM)) + if (buki_motteruka(INVEN_RARM) && buki_motteruka(INVEN_LARM)) { item_tester_hook = item_tester_hook_boomerang; -#ifdef JP - q = "¤É¤ÎÉð´ï¤òÅꤲ¤Þ¤¹¤«? "; - s = "Åꤲ¤ëÉð´ï¤¬¤Ê¤¤¡£"; -#else - q = "Throw which item? "; - s = "You have nothing to throw."; -#endif - + q = _("どの武器を投げますか? ", "Throw which item? "); + s = _("投げる武器がない。", "You have nothing to throw."); if (!get_item(&item, q, s, (USE_EQUIP))) { flush(); return FALSE; } } - else - { - item = INVEN_RARM; - } + else if (buki_motteruka(INVEN_LARM)) item = INVEN_LARM; + else item = INVEN_RARM; } else { /* Get an item */ -#ifdef JP - q = "¤É¤Î¥¢¥¤¥Æ¥à¤òÅꤲ¤Þ¤¹¤«? "; - s = "Åꤲ¤ë¥¢¥¤¥Æ¥à¤¬¤Ê¤¤¡£"; -#else - q = "Throw which item? "; - s = "You have nothing to throw."; -#endif - + q = _("どのアイテムを投げますか? ", "Throw which item? "); + s = _("投げるアイテムがない。", "You have nothing to throw."); if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP))) { flush(); @@ -4218,28 +3942,20 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) /* Item is cursed */ - if (cursed_p(o_ptr) && (item >= INVEN_RARM)) + if (object_is_cursed(o_ptr) && (item >= INVEN_RARM)) { /* Oops */ -#ifdef JP - msg_print("¤Õ¡¼¤à¡¢¤É¤¦¤ä¤é¼ö¤ï¤ì¤Æ¤¤¤ë¤è¤¦¤À¡£"); -#else - msg_print("Hmmm, it seems to be cursed."); -#endif + msg_print(_("ふーむ、どうやら呪われているようだ。", "Hmmm, it seems to be cursed.")); /* Nope */ return FALSE; } - if (p_ptr->inside_arena) + if (p_ptr->inside_arena && !boomerang) { - if (o_ptr->tval != 5) + if (o_ptr->tval != TV_SPIKE) { -#ifdef JP - msg_print("¥¢¥ê¡¼¥Ê¤Ç¤Ï¥¢¥¤¥Æ¥à¤ò»È¤¨¤Ê¤¤¡ª"); -#else - msg_print("You're in the arena now. This is hand-to-hand!"); -#endif + msg_print(_("アリーナではアイテムを使えない!", "You're in the arena now. This is hand-to-hand!")); msg_print(NULL); /* Nope */ @@ -4255,6 +3971,7 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) /* Extract the thrown object's flags. */ object_flags(q_ptr, flgs); + torch_flags(q_ptr, flgs); /* Distribute the charges of rods/wands between the stacks */ distribute_charges(o_ptr, q_ptr, 1); @@ -4263,7 +3980,7 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) q_ptr->number = 1; /* Description */ - object_desc(o_name, q_ptr, FALSE, 3); + object_desc(o_name, q_ptr, OD_OMIT_PREFIX); if (p_ptr->mighty_throw) mult += 3; @@ -4281,10 +3998,10 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) /* Max distance of 10-18 */ if (tdis > mul) tdis = mul; - if (shuriken) + if (shuriken >= 0) { - ty = randint0(101)-50+py; - tx = randint0(101)-50+px; + ty = randint0(101)-50+p_ptr->y; + tx = randint0(101)-50+p_ptr->x; } else { @@ -4293,11 +4010,9 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) /* Get a direction (or cancel) */ if (!get_aim_dir(&dir)) return FALSE; - project_length = 0; /* reset to default */ - /* Predict the "target" location */ - tx = px + 99 * ddx[dir]; - ty = py + 99 * ddy[dir]; + tx = p_ptr->x + 99 * ddx[dir]; + ty = p_ptr->y + 99 * ddy[dir]; /* Check for "target request" */ if ((dir == 5) && target_okay()) @@ -4305,6 +4020,8 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) tx = target_col; ty = target_row; } + + project_length = 0; /* reset to default */ } if ((q_ptr->name1 == ART_MJOLLNIR) || @@ -4319,7 +4036,7 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) inven_item_describe(item); inven_item_optimize(item); } - + /* Reduce and describe floor item */ else { @@ -4331,17 +4048,17 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) equiped_item = TRUE; p_ptr->redraw |= (PR_EQUIPPY); } - + /* Take a turn */ - energy_use = 100; + p_ptr->energy_use = 100; /* Rogue and Ninja gets bonus */ if ((p_ptr->pclass == CLASS_ROGUE) || (p_ptr->pclass == CLASS_NINJA)) - energy_use -= p_ptr->lev; + p_ptr->energy_use -= p_ptr->lev; /* Start at the player */ - y = py; - x = px; + y = p_ptr->y; + x = p_ptr->x; /* Hack -- Handle stuff */ @@ -4357,6 +4074,10 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) if (shuriken) chance *= 2; + /* Save the old location */ + prev_y = y; + prev_x = x; + /* Travel until stopped */ for (cur_dis = 0; cur_dis <= tdis; ) { @@ -4366,30 +4087,27 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) /* Calculate the new location (see "project()") */ ny[cur_dis] = y; nx[cur_dis] = x; - mmove2(&ny[cur_dis], &nx[cur_dis], py, px, ty, tx); + mmove2(&ny[cur_dis], &nx[cur_dis], p_ptr->y, p_ptr->x, ty, tx); /* Stopped by walls/doors */ - if (!cave_floor_bold(ny[cur_dis], nx[cur_dis])) + if (!cave_have_flag_bold(ny[cur_dis], nx[cur_dis], FF_PROJECT)) { hit_wall = TRUE; - break; + if ((q_ptr->tval == TV_FIGURINE) || object_is_potion(q_ptr) || !cave[ny[cur_dis]][nx[cur_dis]].m_idx) break; } - /* Advance the distance */ - cur_dis++; - /* The player can see the (on screen) missile */ - if (panel_contains(ny[cur_dis-1], nx[cur_dis-1]) && player_can_see_bold(ny[cur_dis-1], nx[cur_dis-1])) + if (panel_contains(ny[cur_dis], nx[cur_dis]) && player_can_see_bold(ny[cur_dis], nx[cur_dis])) { char c = object_char(q_ptr); byte a = object_attr(q_ptr); /* Draw, Hilite, Fresh, Pause, Erase */ - print_rel(c, a, ny[cur_dis-1], nx[cur_dis-1]); - move_cursor_relative(ny[cur_dis-1], nx[cur_dis-1]); + print_rel(c, a, ny[cur_dis], nx[cur_dis]); + move_cursor_relative(ny[cur_dis], nx[cur_dis]); Term_fresh(); Term_xtra(TERM_XTRA_DELAY, msec); - lite_spot(ny[cur_dis-1], nx[cur_dis-1]); + lite_spot(ny[cur_dis], nx[cur_dis]); Term_fresh(); } @@ -4400,10 +4118,16 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) Term_xtra(TERM_XTRA_DELAY, msec); } + /* Save the old location */ + prev_y = y; + prev_x = x; + /* Save the new location */ - x = nx[cur_dis-1]; - y = ny[cur_dis-1]; + x = nx[cur_dis]; + y = ny[cur_dis]; + /* Advance the distance */ + cur_dis++; /* Monster here, Try to hit it */ if (cave[y][x].m_idx) @@ -4411,7 +4135,6 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) cave_type *c_ptr = &cave[y][x]; monster_type *m_ptr = &m_list[c_ptr->m_idx]; - monster_race *r_ptr = &r_info[m_ptr->r_idx]; /* Check the visibility */ visible = m_ptr->ml; @@ -4420,56 +4143,15 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) hit_body = TRUE; /* Did we hit it (penalize range) */ - if (test_hit_fire(chance - cur_dis, r_ptr->ac, m_ptr->ml)) + if (test_hit_fire(chance - cur_dis, m_ptr, m_ptr->ml, o_name)) { bool fear = FALSE; - /* Assume a default death */ -#ifdef JP - cptr note_dies = "¤Ï»à¤ó¤À¡£"; -#else - cptr note_dies = " dies."; -#endif - - - /* Some monsters get "destroyed" */ - if (!monster_living(r_ptr)) - { - int i; - bool explode = FALSE; - - for (i = 0; i < 4; i++) - { - if (r_ptr->blow[i].method == RBM_EXPLODE) explode = TRUE; - } - - /* Special note at death */ - if (explode) -#ifdef JP -note_dies = "¤ÏÇúȯ¤·¤ÆÊ´¡¹¤Ë¤Ê¤Ã¤¿¡£"; -#else - note_dies = " explodes into tiny shreds."; -#endif - else -#ifdef JP - note_dies = "¤òÅݤ·¤¿¡£"; -#else - note_dies = " is destroyed."; -#endif - - } - - /* Handle unseen monster */ if (!visible) { /* Invisible monster */ -#ifdef JP - msg_format("%s¤¬Å¨¤òÊ᪤·¤¿¡£", o_name); -#else - msg_format("The %s finds a mark.", o_name); -#endif - + msg_format(_("%sが敵を捕捉した。", "The %s finds a mark."), o_name); } /* Handle visible monster */ @@ -4481,25 +4163,26 @@ note_dies = " monster_desc(m_name, m_ptr, 0); /* Message */ -#ifdef JP - msg_format("%s¤¬%s¤ËÌ¿Ã椷¤¿¡£", o_name, m_name); -#else - msg_format("The %s hits %s.", o_name, m_name); -#endif - + msg_format(_("%sが%sに命中した。", "The %s hits %s."), o_name, m_name); - /* Hack -- Track this monster race */ - if (m_ptr->ml) monster_race_track(m_ptr->ap_r_idx); + if (m_ptr->ml) + { + /* Hack -- Track this monster race */ + if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx); - /* Hack -- Track this monster */ - if (m_ptr->ml) health_track(c_ptr->m_idx); + /* Hack -- Track this monster */ + health_track(c_ptr->m_idx); + } } /* Hack -- Base damage from thrown object */ - tdam = damroll(q_ptr->dd, q_ptr->ds); + dd = q_ptr->dd; + ds = q_ptr->ds; + torch_dice(q_ptr, &dd, &ds); /* throwing a torch */ + tdam = damroll(dd, ds); /* Apply special damage XXX XXX XXX */ - tdam = tot_dam_aux(q_ptr, tdam, m_ptr, 0); - tdam = critical_shot(q_ptr->weight, q_ptr->to_h, tdam); + tdam = tot_dam_aux(q_ptr, tdam, m_ptr, 0, TRUE); + tdam = critical_shot(q_ptr->weight, q_ptr->to_h, 0, tdam); if (q_ptr->to_d > 0) tdam += q_ptr->to_d; else @@ -4533,18 +4216,11 @@ note_dies = " /* Complex message */ if (p_ptr->wizard) { -#ifdef JP - msg_format("%d/%d¤Î¥À¥á¡¼¥¸¤òÍ¿¤¨¤¿¡£", - tdam, m_ptr->hp); -#else - msg_format("You do %d (out of %d) damage.", - tdam, m_ptr->hp); -#endif - + msg_format(_("%d/%dのダメージを与えた。", "You do %d (out of %d) damage."), tdam, m_ptr->hp); } /* Hit the monster, check for death */ - if (mon_take_hit(c_ptr->m_idx, tdam, &fear, note_dies)) + if (mon_take_hit(c_ptr->m_idx, tdam, &fear, extract_note_dies(real_r_ptr(m_ptr)))) { /* Dead monster */ } @@ -4571,12 +4247,7 @@ note_dies = " monster_desc(m_name, m_ptr, 0); /* Message */ -#ifdef JP - msg_format("%^s¤Ï¶²Éݤ·¤Æƨ¤²½Ð¤·¤¿¡ª", m_name); -#else - msg_format("%^s flees in terror!", m_name); -#endif - + msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), m_name); } } } @@ -4586,6 +4257,9 @@ note_dies = " } } + /* decrease toach's fuel */ + if (hit_body) torch_lost_fuel(q_ptr); + /* Chance of breakage (during attacks) */ j = (hit_body ? breakage_chance(q_ptr) : 0); @@ -4595,19 +4269,10 @@ note_dies = " j = 100; if (!(summon_named_creature(0, y, x, q_ptr->pval, - !(cursed_p(q_ptr)) ? PM_FORCE_PET : 0L))) -#ifdef JP -msg_print("¿Í·Á¤ÏDZ¤¸¶Ê¤¬¤êºÕ¤±»¶¤Ã¤Æ¤·¤Þ¤Ã¤¿¡ª"); -#else - msg_print("The Figurine writhes and then shatters."); -#endif - - else if (cursed_p(q_ptr)) -#ifdef JP -msg_print("¤³¤ì¤Ï¤¢¤Þ¤êÎɤ¯¤Ê¤¤µ¤¤¬¤¹¤ë¡£"); -#else - msg_print("You have a bad feeling about this."); -#endif + !(object_is_cursed(q_ptr)) ? PM_FORCE_PET : 0L))) + msg_print(_("人形は捻じ曲がり砕け散ってしまった!", "The Figurine writhes and then shatters.")); + else if (object_is_cursed(q_ptr)) + msg_print(_("これはあまり良くない気がする。", "You have a bad feeling about this.")); } @@ -4618,12 +4283,7 @@ msg_print(" if (hit_body || hit_wall || (randint1(100) < j)) { /* Message */ -#ifdef JP - msg_format("%s¤ÏºÕ¤±»¶¤Ã¤¿¡ª", o_name); -#else - msg_format("The %s shatters!", o_name); -#endif - + msg_format(_("%sは砕け散った!", "The %s shatters!"), o_name); if (potion_smash_effect(0, y, x, q_ptr->k_idx)) { @@ -4632,16 +4292,11 @@ msg_print(" /* ToDo (Robert): fix the invulnerability */ if (cave[y][x].m_idx && is_friendly(&m_list[cave[y][x].m_idx]) && - !(m_ptr->invulner)) + !MON_INVULNER(m_ptr)) { char m_name[80]; monster_desc(m_name, &m_list[cave[y][x].m_idx], 0); -#ifdef JP - msg_format("%s¤ÏÅܤä¿¡ª", m_name); -#else - msg_format("%^s gets angry!", m_name); -#endif - + msg_format(_("%sは怒った!", "%^s gets angry!"), m_name); set_hostile(&m_list[cave[y][x].m_idx]); } } @@ -4662,11 +4317,11 @@ msg_print(" j = -1; if (boomerang) back_chance += 4+randint1(5); if (super_boomerang) back_chance += 100; - object_desc(o2_name, q_ptr, FALSE, 0); + object_desc(o2_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY)); if((back_chance > 30) && (!one_in_(100) || super_boomerang)) { - for (i = cur_dis-1;i>0;i--) + for (i = cur_dis - 1; i > 0; i--) { if (panel_contains(ny[i], nx[i]) && player_can_see_bold(ny[i], nx[i])) { @@ -4689,42 +4344,26 @@ msg_print(" } if((back_chance > 37) && !p_ptr->blind && (item >= 0)) { -#ifdef JP - msg_format("%s¤¬¼ê¸µ¤ËÊ֤äƤ­¤¿¡£", o2_name); -#else - msg_format("%s comes back to you.", o2_name); -#endif + msg_format(_("%sが手元に返ってきた。", "%s comes back to you."), o2_name); come_back = TRUE; } else { if (item >= 0) { -#ifdef JP - msg_format("%s¤ò¼õ¤±Â»¤Í¤¿¡ª", o2_name); -#else - msg_format("%s backs, but you can't catch!", o2_name); -#endif + msg_format(_("%sを受け損ねた!", "%s backs, but you can't catch!"), o2_name); } else { -#ifdef JP - msg_format("%s¤¬Ê֤äƤ­¤¿¡£", o2_name); -#else - msg_format("%s comes back.", o2_name); -#endif + msg_format(_("%sが返ってきた。", "%s comes back."), o2_name); } - y = py; - x = px; + y = p_ptr->y; + x = p_ptr->x; } } else { -#ifdef JP - msg_format("%s¤¬Ê֤äƤ³¤Ê¤«¤Ã¤¿¡ª", o2_name); -#else - msg_format("%s doesn't back!", o2_name); -#endif + msg_format(_("%sが返ってこなかった!", "%s doesn't back!"), o2_name); } } @@ -4769,16 +4408,269 @@ msg_print(" } /* Drop (or break) near that location */ - if (do_drop) (void)drop_near(q_ptr, j, y, x); + if (do_drop) + { + if (cave_have_flag_bold(y, x, FF_PROJECT)) + { + /* Drop (or break) near that location */ + (void)drop_near(q_ptr, j, y, x); + } + else + { + /* Drop (or break) near that location */ + (void)drop_near(q_ptr, j, prev_y, prev_x); + } + } return TRUE; } -/* +/*! + * @brief 投射処理のメインルーチン / * Throw an object from the pack or floor. + * @return なし */ void do_cmd_throw(void) { - do_cmd_throw_aux(1, FALSE, 0); + do_cmd_throw_aux(1, FALSE, -1); +} + + +#ifdef TRAVEL +/* + * Hack: travel command + */ +#define TRAVEL_UNABLE 9999 + +static int flow_head = 0; +static int flow_tail = 0; +static s16b temp2_x[MAX_SHORT]; +static s16b temp2_y[MAX_SHORT]; + +/*! + * @brief トラベル処理の記憶配列を初期化する Hack: forget the "flow" information + * @return なし + */ +void forget_travel_flow(void) +{ + int x, y; + + /* Check the entire dungeon */ + for (y = 0; y < cur_hgt; y++) + { + for (x = 0; x < cur_wid; x++) + { + /* Forget the old data */ + travel.cost[y][x] = MAX_SHORT; + } + } + + travel.y = travel.x = 0; +} + +/*! + * @brief トラベル処理中に地形に応じた移動コスト基準を返す + * @param y 該当地点のY座標 + * @param x 該当地点のX座標 + * @return コスト値 + */ +static int travel_flow_cost(int y, int x) +{ + feature_type *f_ptr = &f_info[cave[y][x].feat]; + int cost = 1; + + /* Avoid obstacles (ex. trees) */ + if (have_flag(f_ptr->flags, FF_AVOID_RUN)) cost += 1; + + /* Water */ + if (have_flag(f_ptr->flags, FF_WATER)) + { + if (have_flag(f_ptr->flags, FF_DEEP) && !p_ptr->levitation) cost += 5; + } + + /* Lava */ + if (have_flag(f_ptr->flags, FF_LAVA)) + { + int lava = 2; + if (!p_ptr->resist_fire) lava *= 2; + if (!p_ptr->levitation) lava *= 2; + if (have_flag(f_ptr->flags, FF_DEEP)) lava *= 2; + + cost += lava; + } + + /* Detected traps and doors */ + if (cave[y][x].info & (CAVE_MARK)) + { + if (have_flag(f_ptr->flags, FF_DOOR)) cost += 1; + if (have_flag(f_ptr->flags, FF_TRAP)) cost += 10; + } + + return (cost); +} + +/*! + * @brief トラベル処理の到達地点までの行程を得る処理のサブルーチン + * @param y 目標地点のY座標 + * @param x 目標地点のX座標 + * @param n 現在のコスト + * @param wall プレイヤーが壁の中にいるならばTRUE + * @return なし + */ +static void travel_flow_aux(int y, int x, int n, bool wall) +{ + cave_type *c_ptr = &cave[y][x]; + feature_type *f_ptr = &f_info[c_ptr->feat]; + int old_head = flow_head; + int add_cost = 1; + int base_cost = (n % TRAVEL_UNABLE); + int from_wall = (n / TRAVEL_UNABLE); + int cost; + + /* Ignore out of bounds */ + if (!in_bounds(y, x)) return; + + /* Ignore unknown grid except in wilderness */ + if (dun_level > 0 && !(c_ptr->info & CAVE_KNOWN)) return; + + /* Ignore "walls" and "rubble" (include "secret doors") */ + if (have_flag(f_ptr->flags, FF_WALL) || + have_flag(f_ptr->flags, FF_CAN_DIG) || + (have_flag(f_ptr->flags, FF_DOOR) && cave[y][x].mimic) || + (!have_flag(f_ptr->flags, FF_MOVE) && have_flag(f_ptr->flags, FF_CAN_FLY) && !p_ptr->levitation)) + { + if (!wall || !from_wall) return; + add_cost += TRAVEL_UNABLE; + } + else + { + add_cost = travel_flow_cost(y, x); + } + + cost = base_cost + add_cost; + + /* Ignore lower cost entries */ + if (travel.cost[y][x] <= cost) return; + + /* Save the flow cost */ + travel.cost[y][x] = cost; + + /* Enqueue that entry */ + temp2_y[flow_head] = y; + temp2_x[flow_head] = x; + + /* Advance the queue */ + if (++flow_head == MAX_SHORT) flow_head = 0; + + /* Hack -- notice overflow by forgetting new entry */ + if (flow_head == flow_tail) flow_head = old_head; + + return; +} + +/*! + * @brief トラベル処理の到達地点までの行程を得る処理のメインルーチン + * @param ty 目標地点のY座標 + * @param tx 目標地点のX座標 + * @return なし + */ +static void travel_flow(int ty, int tx) +{ + int x, y, d; + bool wall = FALSE; + feature_type *f_ptr = &f_info[cave[p_ptr->y][p_ptr->x].feat]; + + /* Reset the "queue" */ + flow_head = flow_tail = 0; + + /* is player in the wall? */ + if (!have_flag(f_ptr->flags, FF_MOVE)) wall = TRUE; + + /* Start at the target grid */ + travel_flow_aux(ty, tx, 0, wall); + + /* Now process the queue */ + while (flow_head != flow_tail) + { + /* Extract the next entry */ + y = temp2_y[flow_tail]; + x = temp2_x[flow_tail]; + + /* Forget that entry */ + if (++flow_tail == MAX_SHORT) flow_tail = 0; + + /* Ignore too far entries */ + //if (distance(ty, tx, y, x) > 100) continue; + + /* Add the "children" */ + for (d = 0; d < 8; d++) + { + /* Add that child if "legal" */ + travel_flow_aux(y + ddy_ddd[d], x + ddx_ddd[d], travel.cost[y][x], wall); + } + } + + /* Forget the flow info */ + flow_head = flow_tail = 0; +} + +/*! + * @brief トラベル処理のメインルーチン + * @return なし + */ +void do_cmd_travel(void) +{ + int x, y, i; + int dx, dy, sx, sy; + feature_type *f_ptr; + + if (travel.x != 0 && travel.y != 0 && + get_check(_("トラベルを継続しますか?", "Do you continue to travel?"))) + { + y = travel.y; + x = travel.x; + } + else if (!tgt_pt(&x, &y)) return; + + if ((x == p_ptr->x) && (y == p_ptr->y)) + { + msg_print(_("すでにそこにいます!", "You are already there!!")); + return; + } + + f_ptr = &f_info[cave[y][x].feat]; + + if ((cave[y][x].info & CAVE_MARK) && + (have_flag(f_ptr->flags, FF_WALL) || + have_flag(f_ptr->flags, FF_CAN_DIG) || + (have_flag(f_ptr->flags, FF_DOOR) && cave[y][x].mimic))) + { + msg_print(_("そこには行くことができません!", "You cannot travel there!")); + return; + } + + forget_travel_flow(); + travel_flow(y, x); + + travel.x = x; + travel.y = y; + + /* Travel till 255 steps */ + travel.run = 255; + + /* Paranoia */ + travel.dir = 0; + + /* Decides first direction */ + dx = abs(p_ptr->x - x); + dy = abs(p_ptr->y - y); + sx = ((x == p_ptr->x) || (dx < dy)) ? 0 : ((x > p_ptr->x) ? 1 : -1); + sy = ((y == p_ptr->y) || (dy < dx)) ? 0 : ((y > p_ptr->y) ? 1 : -1); + + for (i = 1; i <= 9; i++) + { + if ((sx == ddx[i]) && (sy == ddy[i])) travel.dir = i; + } } +#endif