X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fcmd2.c;h=1d24fc5eb2212515eb85fda79f6783067f41eb6f;hb=ca8e0d6d1d0fea1f6e09a899e016561b6bbd079e;hp=7bbc6afad45d77ca0d4a2baa41498871a6358faf;hpb=5354093f6e1a73b3ea03e372703fffdf4947d0e1;p=hengband%2Fhengband.git diff --git a/src/cmd2.c b/src/cmd2.c index 7bbc6afad..1d24fc5eb 100644 --- a/src/cmd2.c +++ b/src/cmd2.c @@ -1,17 +1,45 @@ /* File: cmd2.c */ -/* Purpose: Movement commands (part 2) */ - /* - * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke + * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke * - * This software may be copied and distributed for educational, research, and - * not for profit purposes provided that this copyright and statement are - * included in all such copies. + * This software may be copied and distributed for educational, research, + * and not for profit purposes provided that this copyright and statement + * are included in all such copies. Other copyrights may also apply. */ +/* Purpose: Movement commands (part 2) */ + #include "angband.h" +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; +} + /* * Go up one level @@ -19,7 +47,11 @@ void do_cmd_go_up(void) { bool go_up = FALSE; - cave_type *c_ptr; + + /* Player grid */ + cave_type *c_ptr = &cave[py][px]; + feature_type *f_ptr = &f_info[c_ptr->feat]; + int up_num = 0; if (p_ptr->special_defense & KATA_MUSOU) @@ -27,12 +59,25 @@ 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)) + { +#ifdef JP + msg_print("¤³¤³¤Ë¤Ï¾å¤ê³¬Ãʤ¬¸«Åö¤¿¤é¤Ê¤¤¡£"); +#else + msg_print("I see no up staircase here."); +#endif + + 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)) @@ -43,7 +88,6 @@ void do_cmd_go_up(void) msg_print("You enter the up staircase."); #endif - leave_quest_check(); p_ptr->inside_quest = c_ptr->special; @@ -51,6 +95,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; } @@ -62,130 +111,101 @@ 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 */ + energy_use = 100; + + /* End the command */ + return; } - /* Normal up stairs */ - else if ((c_ptr->feat == FEAT_LESS) || (c_ptr->feat == FEAT_LESS_LESS)) + + if (!dun_level) { - if (!dun_level) - { - go_up = TRUE; - } - else - { - quest_type *q_ptr = &quest[p_ptr->inside_quest]; + go_up = TRUE; + } + else + { + go_up = confirm_leave_level(FALSE); + } - /* 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; - } - } + /* Cancel the command */ + if (!go_up) return; - if (go_up) - { + /* Hack -- take a turn */ + energy_use = 100; - /* Hack -- take a turn */ - energy_use = 100; + if (autosave_l) do_cmd_save_game(TRUE); - if (autosave_l) do_cmd_save_game(TRUE); + /* For a random quest */ + if (p_ptr->inside_quest && + quest[p_ptr->inside_quest].type == QUEST_TYPE_RANDOM) + { + leave_quest_check(); - if (p_ptr->inside_quest) - { - leave_quest_check(); + p_ptr->inside_quest = 0; + } - if (quest[leaving_quest].type != QUEST_TYPE_RANDOM) - { - p_ptr->inside_quest = c_ptr->special; - dun_level = 0; - } - else - { - 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(); - /* New depth */ - if (c_ptr->feat == FEAT_LESS_LESS) - { - /* Create a way back */ - prepare_change_floor_mode(CFM_UP | CFM_SHAFT); + p_ptr->inside_quest = c_ptr->special; + dun_level = 0; + up_num = 0; + } - up_num += 2; - } - else - { - /* Create a way back */ - prepare_change_floor_mode(CFM_UP); + /* For normal dungeon and random quest */ + else + { + /* New depth */ + if (have_flag(f_ptr->flags, FF_SHAFT)) + { + /* Create a way back */ + prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP | CFM_SHAFT); - up_num += 1; - } -#if 0 - if (!c_ptr->special && dungeon_type && ((dun_level - up_num + 1) > d_info[dungeon_type].mindepth) && one_in_(13)) - { - up_num++; -#ifdef JP - if (c_ptr->feat == FEAT_LESS_LESS) msg_print("Ť¤¹£Æ»¤ò¾å¤Ã¤¿¡£"); - else msg_print("Ť¤³¬Ãʤò¾å¤Ã¤¿¡£"); -#else - msg_print("These were very long stairs."); -#endif - msg_print(NULL); - } -#endif /* 0 */ + up_num = 2; + } + else + { + /* Create a way back */ + prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP); - if (dun_level-up_num+1 == 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 + up_num = 1; + } + + /* Get out from current dungeon */ + if (dun_level - up_num < d_info[dungeon_type].mindepth) + up_num = dun_level; + } - /* Success */ #ifdef JP - if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)) - msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª"); - else if (0 == dun_level) - msg_print("ÃϾå¤ËÌá¤Ã¤¿¡£"); - else - msg_print("³¬Ãʤò¾å¤Ã¤Æ¿·¤¿¤Ê¤ë̵ܤؤÈ­¤òƧ¤ßÆþ¤ì¤¿¡£"); + if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, "³¬Ãʤò¾å¤Ã¤¿"); #else - if (0 == dun_level) - msg_print("You go back to the surface."); - else - msg_print("You enter a maze of up staircases."); + if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, "climbed up the stairs to"); #endif - /* Leaving */ - p_ptr->leaving = TRUE; - } - } - else - { + /* Success */ #ifdef JP - msg_print("¤³¤³¤Ë¤Ï¾å¤ê³¬Ãʤ¬¸«Åö¤¿¤é¤Ê¤¤¡£"); + if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)) + msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª"); + else if (up_num == dun_level) + msg_print("ÃϾå¤ËÌá¤Ã¤¿¡£"); + else + msg_print("³¬Ãʤò¾å¤Ã¤Æ¿·¤¿¤Ê¤ë̵ܤؤÈ­¤òƧ¤ßÆþ¤ì¤¿¡£"); #else - msg_print("I see no up staircase here."); + if (up_num == dun_level) + msg_print("You go back to the surface."); + else + msg_print("You enter a maze of up staircases."); #endif - return; - } + /* Leaving */ + p_ptr->leaving = TRUE; } @@ -194,7 +214,10 @@ void do_cmd_go_up(void) */ void do_cmd_go_down(void) { - cave_type *c_ptr; + /* Player grid */ + cave_type *c_ptr = &cave[py][px]; + feature_type *f_ptr = &f_info[c_ptr->feat]; + bool fall_trap = FALSE; int down_num = 0; @@ -203,14 +226,32 @@ 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)) + { +#ifdef JP + msg_print("¤³¤³¤Ë¤Ï²¼¤ê³¬Ãʤ¬¸«Åö¤¿¤é¤Ê¤¤¡£"); +#else + msg_print("I see no down staircase here."); +#endif + + return; + } - if (c_ptr->feat == (FEAT_TRAP_TRAPDOOR)) fall_trap = TRUE; + if (have_flag(f_ptr->flags, FF_TRAP)) 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("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª"); @@ -220,14 +261,19 @@ void do_cmd_go_down(void) 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; } @@ -239,27 +285,24 @@ 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 */ + 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("¥À¥ó¥¸¥ç¥ó¤ÎÆþ¸ý¤ÏºÉ¤¬¤ì¤Æ¤¤¤ë¡ª"); @@ -268,13 +311,13 @@ void do_cmd_go_down(void) #endif 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); + msg_format("¤³¤³¤Ë¤Ï%s¤ÎÆþ¤ê¸ý(%d³¬ÁêÅö)¤¬¤¢¤ê¤Þ¤¹", d_name+d_info[target_dungeon].name, d_info[target_dungeon].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); + msg_format("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; #endif } @@ -282,7 +325,13 @@ void do_cmd_go_down(void) /* Save old player position */ p_ptr->oldpx = px; p_ptr->oldpy = py; - dungeon_type = (byte)c_ptr->special; + 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 */ @@ -291,32 +340,31 @@ void do_cmd_go_down(void) 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, "Í¸Í¤ËÍî¤Á¤¿"); + 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"); + 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"); #endif } if (fall_trap) { #ifdef JP - msg_print("¤ï¤¶¤ÈÍ¸Í¤ËÍî¤Á¤¿¡£"); + msg_print("¤ï¤¶¤ÈÍî¤È¤·¸Í¤ËÍî¤Á¤¿¡£"); #else msg_print("You deliberately jump through the trap door."); #endif @@ -324,7 +372,7 @@ void do_cmd_go_down(void) else { /* Success */ - if(c_ptr->feat == FEAT_ENTRANCE) + if (target_dungeon) { #ifdef JP msg_format("%s¤ØÆþ¤Ã¤¿¡£", d_text + d_info[dungeon_type].text); @@ -351,19 +399,19 @@ 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); } } } @@ -400,7 +448,7 @@ void do_cmd_search(void) /* * Determine if a grid contains a chest */ -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]; @@ -419,10 +467,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 */ @@ -446,7 +499,7 @@ 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; @@ -464,7 +517,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 @@ -499,7 +552,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. */ @@ -597,7 +650,7 @@ static void chest_trap(int y, int x, s16b o_idx) msg_print("A puff of green gas surrounds you!"); #endif - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) + if (!(p_ptr->resist_pois || IS_OPPOSE_POIS())) { (void)set_poisoned(p_ptr->poisoned + 10 + randint1(20)); } @@ -724,7 +777,7 @@ static void chest_trap(int y, int x, s16b o_idx) else { #ifdef JP - msg_print("±²´¬¤«¹çÂΤ·¡¢ÇËÎö¤·¤¿¡ª"); + msg_print("±²´¬¤¬¹çÂΤ·¡¢ÇËÎö¤·¤¿¡ª"); #else msg_print("Vortices coalesce and wreak destruction!"); #endif @@ -744,7 +797,7 @@ static void chest_trap(int y, int x, s16b o_idx) /* Message. */ #ifdef JP - msg_print("¶²¤·¤¤À¼¤¬¶Á¤¤¤¿: ¡Ö°Å°Ç¤¬Æò¤ò¤Ä¤Ä¤Þ¤ó¡ª¡×"); + msg_print("¶²¤í¤·¤¤À¼¤¬¶Á¤¤¤¿: ¡Ö°Å°Ç¤¬Æò¤ò¤Ä¤Ä¤Þ¤ó¡ª¡×"); #else msg_print("Hideous voices bid: 'Let the darkness have thee!'"); #endif @@ -920,7 +973,7 @@ static bool do_cmd_open_chest(int y, int x, s16b o_idx) */ 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)); } @@ -939,7 +992,7 @@ 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; @@ -955,8 +1008,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; @@ -994,7 +1047,7 @@ static int count_chests(int *y, int *x, bool trapped) int xx = px + 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]; @@ -1003,7 +1056,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 */ @@ -1052,7 +1105,10 @@ 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; @@ -1060,25 +1116,22 @@ static bool do_cmd_open_aux(int y, int x) /* Take a turn */ energy_use = 100; - /* Get requested grid */ - c_ptr = &cave[y][x]; - /* 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("¥É¥¢¤Ï¤¬¤Ã¤Á¤ê¤ÈÊĤ¸¤é¤ì¤Æ¤¤¤ë¤è¤¦¤À¡£"); + msg_format("%s¤Ï¤¬¤Ã¤Á¤ê¤ÈÊĤ¸¤é¤ì¤Æ¤¤¤ë¤è¤¦¤À¡£", f_name + f_info[get_feat_mimic(c_ptr)].name); #else - msg_print("The door appears to be stuck."); + msg_format("The %s appears to be stuck.", f_name + f_info[get_feat_mimic(c_ptr)].name); #endif } /* Locked door */ - else if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x01) + else if (f_ptr->power) { /* Disarm factor */ i = p_ptr->skill_dis; @@ -1088,7 +1141,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); @@ -1106,12 +1159,8 @@ static bool do_cmd_open_aux(int y, int x) msg_print("You have picked the lock."); #endif - /* 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); @@ -1140,13 +1189,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); @@ -1216,7 +1262,7 @@ 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 */ @@ -1227,13 +1273,13 @@ void do_cmd_open(void) 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 @@ -1294,40 +1340,53 @@ void do_cmd_open(void) */ 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]; - /* 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 */ +#ifdef JP + msg_print("²¿¤«¤¬¤Ä¤Ã¤«¤¨¤ÆÊĤޤé¤Ê¤¤¡£"); +#else + msg_print("There seems stuck."); +#endif + } + else + { + /* Close the door */ + cave_alter_feat(y, x, FF_CLOSE); - /* Sound */ - sound(SOUND_SHUTDOOR); + /* Broken door */ + if (old_feat == c_ptr->feat) + { + /* Message */ +#ifdef JP + msg_print("¥É¥¢¤Ï²õ¤ì¤Æ¤·¤Þ¤Ã¤Æ¤¤¤ë¡£"); +#else + msg_print("The door appears to be broken."); +#endif + } + else + { + /* Sound */ + sound(SOUND_SHUTDOOR); + } + } } /* Result */ @@ -1380,7 +1439,7 @@ 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]; @@ -1390,10 +1449,10 @@ void do_cmd_close(void) 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 @@ -1401,7 +1460,6 @@ void do_cmd_close(void) #else msg_print("You see nothing there to close."); #endif - } /* Monster in the way */ @@ -1412,12 +1470,11 @@ void do_cmd_close(void) /* Message */ #ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); + msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); #else msg_print("There is a monster in the way!"); #endif - /* Attack */ py_attack(y, x, 0); } @@ -1440,8 +1497,10 @@ void do_cmd_close(void) */ 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 @@ -1450,13 +1509,12 @@ static bool do_cmd_tunnel_test(int y, int x) msg_print("You see nothing there."); #endif - /* 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 @@ -1465,7 +1523,6 @@ static bool do_cmd_tunnel_test(int y, int x) msg_print("You see nothing there to tunnel."); #endif - /* Nope */ return (FALSE); } @@ -1475,53 +1532,21 @@ 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); -} - - - /* * Perform the basic "tunnel" command * - * Assumes that the destination is a wall, a vein, a secret - * door, or rubble. - * * 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 */ @@ -1532,266 +1557,128 @@ static bool do_cmd_tunnel_aux(int y, int x) /* 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)) + if (have_flag(f_ptr->flags, FF_PERMANENT)) { + /* Titanium */ + if (have_flag(mimic_f_ptr->flags, FF_PERMANENT)) + { #ifdef JP - msg_print("¤³¤Î´ä¤Ï¹Å¤¹¤®¤Æ·¡¤ì¤Ê¤¤¤è¤¦¤À¡£"); + msg_print("¤³¤Î´ä¤Ï¹Å¤¹¤®¤Æ·¡¤ì¤Ê¤¤¤è¤¦¤À¡£"); #else - msg_print("This seems to be permanent rock."); + msg_print("This seems to be permanent rock."); #endif + } - } - - /* No tunnelling through mountains */ - else if (feat == FEAT_MOUNTAIN) - { + /* Map border (mimiccing Permanent wall) */ + else + { #ifdef JP - msg_print("¤½¤³¤Ï·¡¤ì¤Ê¤¤!"); + msg_print("¤½¤³¤Ï·¡¤ì¤Ê¤¤!"); #else - msg_print("You can't tunnel through that!"); + 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) + /* Dig or tunnel */ + else if (have_flag(f_ptr->flags, FF_CAN_DIG)) { + /* Dig */ + if (p_ptr->skill_dig > randint0(20 * power)) + { + /* Message */ #ifdef JP - msg_print("¤½¤³¤Ï·¡¤ì¤Ê¤¤!"); + msg_format("%s¤ò¤¯¤º¤·¤¿¡£", name); #else - msg_print("You can't tunnel through that!"); + msg_format("You have removed the %s.", name); #endif - } + /* Remove the feature */ + cave_alter_feat(y, x, FF_TUNNEL); - else if (feat == FEAT_TREES) /* -KMW- */ - { - /* Chop Down */ - if ((p_ptr->skill_dig > 10 + randint0(400)) && twall(y, x, FEAT_GRASS)) - { -#ifdef JP - msg_print("ÌÚ¤òÀÚ¤êʧ¤Ã¤¿¡£"); -#else - msg_print("You have cleared away the trees."); -#endif - chg_virtue(V_DILIGENCE, 1); - chg_virtue(V_NATURE, -1); - } - - /* Keep trying */ - 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); + /* Update some things */ + p_ptr->update |= (PU_FLOW); } - - /* Keep trying */ else { - /* We may continue tunelling */ + /* Message, keep digging */ #ifdef JP - msg_print("²ÖÖ¾´ä¤ÎÊɤ˷ê¤ò·¡¤Ã¤Æ¤¤¤ë¡£"); + msg_format("%s¤ò¤¯¤º¤·¤Æ¤¤¤ë¡£", name); #else - msg_print("You tunnel into the granite wall."); + msg_format("You dig into the %s.", name); #endif more = TRUE; } } - - /* Quartz / Magma */ - else if ((feat >= FEAT_MAGMA) && - (feat <= FEAT_QUARTZ_K)) + else { - 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)); - } + bool tree = have_flag(mimic_f_ptr->flags, FF_TREE); - /* Success */ - if (okay && twall(y, x, floor_type[randint0(100)])) + /* Tunnel */ + if (p_ptr->skill_dig > power + randint0(40 * power)) { - /* 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 */ + if (tree) msg_format("%s¤òÀÚ¤êʧ¤Ã¤¿¡£", name); else { - /* Message */ -#ifdef JP msg_print("·ê¤ò·¡¤ê½ª¤¨¤¿¡£"); + p_ptr->update |= (PU_FLOW); + } #else + if (tree) msg_format("You have cleared away the %s.", name); + else + { msg_print("You have finished the tunnel."); -#endif - chg_virtue(V_DILIGENCE, 1); - chg_virtue(V_NATURE, -1); + p_ptr->update |= (PU_FLOW); } - } - - /* Failure (quartz) */ - else if (hard) - { - /* Message, continue digging */ -#ifdef JP - msg_print("ÀбѤιÛÌ®¤Ë·ê¤ò·¡¤Ã¤Æ¤¤¤ë¡£"); -#else - msg_print("You tunnel into the quartz vein."); #endif - more = TRUE; - } + /* Sound */ + if (have_flag(f_ptr->flags, FF_GLASS)) sound(SOUND_GLASS); - /* Failure (magma) */ - else - { - /* Message, continue digging */ -#ifdef JP - msg_print("ÍÏ´ä¤Î¹ÛÌ®¤Ë·ê¤ò·¡¤Ã¤Æ¤¤¤ë¡£"); -#else - msg_print("You tunnel into the magma vein."); -#endif + /* Remove the feature */ + cave_alter_feat(y, x, FF_TUNNEL); - more = TRUE; + chg_virtue(V_DILIGENCE, 1); + chg_virtue(V_NATURE, -1); } - } - /* Rubble */ - else if (feat == FEAT_RUBBLE) - { - /* Remove the rubble */ - if ((p_ptr->skill_dig > randint0(200)) && twall(y, x, floor_type[randint0(100)])) + /* Keep trying */ + else { - /* 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)) + if (tree) { - /* Create a simple object */ - place_object(y, x, FALSE, FALSE); - - /* Observe new object */ - if (player_can_see_bold(y, x)) - { + /* We may continue chopping */ #ifdef JP - msg_print("²¿¤«¤òȯ¸«¤·¤¿¡ª"); + msg_format("%s¤òÀڤäƤ¤¤ë¡£", name); #else - msg_print("You have found something!"); + msg_format("You chop away at the %s.", name); #endif - - } + /* Occasional Search XXX XXX */ + if (randint0(100) < 25) search(); } - } - - else - { - /* Message, keep digging */ -#ifdef JP - msg_print("´äÀФò¤¯¤º¤·¤Æ¤¤¤ë¡£"); -#else - msg_print("You dig in the rubble."); -#endif - - more = TRUE; - } - } - - /* Doors */ - else - { - /* Tunnel */ - if ((p_ptr->skill_dig > 30 + randint0(1200)) && twall(y, x, floor_type[randint1(100)])) - { -#ifdef JP - msg_print("·ê¤ò·¡¤ê½ª¤¨¤¿¡£"); -#else - msg_print("You have finished the tunnel."); -#endif - - } - - /* Keep trying */ - else - { - /* We may continue tunelling */ + else + { + /* We may continue tunelling */ #ifdef JP - msg_print("¥É¥¢¤Ë·ê¤ò³«¤±¤Æ¤¤¤ë¡£"); + msg_format("%s¤Ë·ê¤ò·¡¤Ã¤Æ¤¤¤ë¡£", name); #else - msg_print("You tunnel into the door."); + msg_format("You tunnel into the %s.", name); #endif + } more = TRUE; } @@ -1804,7 +1691,7 @@ static bool do_cmd_tunnel_aux(int y, int x) } /* Result */ - return (more); + return more; } @@ -1822,7 +1709,7 @@ void do_cmd_tunnel(void) int y, x, dir; cave_type *c_ptr; - byte feat; + s16b feat; bool more = FALSE; @@ -1856,13 +1743,10 @@ void do_cmd_tunnel(void) 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)) + if (have_flag(f_info[feat].flags, FF_DOOR)) { /* Message */ #ifdef JP @@ -1870,31 +1754,16 @@ void do_cmd_tunnel(void) #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))) - { - /* Message */ -#ifdef JP - msg_print("¶õµ¤¤Ï·¡¤ì¤Ê¤¤¡£"); -#else - msg_print("You cannot tunnel through air."); -#endif - } - /* 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!"); + msg_print("You can't tunnel through that."); #endif - } /* A monster is in the way */ @@ -1905,12 +1774,11 @@ void do_cmd_tunnel(void) /* Message */ #ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); + msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); #else msg_print("There is a monster in the way!"); #endif - /* Attack */ py_attack(y, x, 0); } @@ -1945,29 +1813,29 @@ 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("¥É¥¢¤Ï¤¬¤Ã¤Á¤ê¤ÈÊĤ¸¤é¤ì¤Æ¤¤¤ë¤è¤¦¤À¡£"); + msg_format("%s¤Ï¤¬¤Ã¤Á¤ê¤ÈÊĤ¸¤é¤ì¤Æ¤¤¤ë¤è¤¦¤À¡£", f_name + f_info[get_feat_mimic(c_ptr)].name); #else - msg_print("The door appears to be stuck."); + msg_format("The %s appears to be stuck.", f_name + f_info[get_feat_mimic(c_ptr)].name); #endif } /* Locked door */ - else if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x01) + else if (f_ptr->power) { /* Disarm factor */ i = p_ptr->skill_dis; @@ -1977,7 +1845,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); @@ -1995,12 +1863,8 @@ bool easy_open_door(int y, int x) msg_print("You have picked the lock."); #endif - /* 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); @@ -2029,10 +1893,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); @@ -2080,7 +1941,7 @@ 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("¥È¥é¥Ã¥×¤¬¸«¤¢¤¿¤é¤Ê¤¤¡£"); @@ -2176,47 +2037,32 @@ static bool do_cmd_disarm_aux(int y, int x, int dir) #endif /* ALLOW_EASY_DISARM -- TNB */ { - int i, j, power; + /* Get grid and contents */ + cave_type *c_ptr = &cave[y][x]; - cave_type *c_ptr; + /* Get feature */ + feature_type *f_ptr = &f_info[c_ptr->feat]; - cptr name; + /* Access trap name */ + cptr name = (f_name + f_ptr->name); + + /* Extract trap "power" */ + int power = f_ptr->power; bool more = FALSE; + /* Get the "disarm" factor */ + int i = p_ptr->skill_dis; + + int j; /* Take a turn */ energy_use = 100; - /* Get grid and contents */ - c_ptr = &cave[y][x]; - - /* Access trap name */ - name = (f_name + f_info[c_ptr->feat].name); - - /* Get the "disarm" factor */ - i = p_ptr->skill_dis; - /* 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; @@ -2233,15 +2079,11 @@ static bool do_cmd_disarm_aux(int y, int x, int dir) msg_format("You have disarmed the %s.", name); #endif - /* 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 */ @@ -2269,7 +2111,6 @@ static bool do_cmd_disarm_aux(int y, int x, int dir) msg_format("You failed to disarm the %s.", name); #endif - /* We may keep trying */ more = TRUE; } @@ -2284,7 +2125,6 @@ static bool do_cmd_disarm_aux(int y, int x, int dir) msg_format("You set off the %s!", name); #endif - #ifdef ALLOW_EASY_DISARM /* TNB */ /* Move the player onto the trap */ @@ -2360,7 +2200,7 @@ 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]; @@ -2370,10 +2210,10 @@ void do_cmd_disarm(void) 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) @@ -2392,7 +2232,7 @@ void do_cmd_disarm(void) { /* Message */ #ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); + msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); #else msg_print("There is a monster in the way!"); #endif @@ -2433,34 +2273,33 @@ void do_cmd_disarm(void) */ 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]; - /* Message */ #ifdef JP - msg_print("¥É¥¢¤ËÂÎÅö¤¿¤ê¤ò¤·¤¿¡ª"); + msg_format("%s¤ËÂÎÅö¤¿¤ê¤ò¤·¤¿¡ª", name); #else - msg_print("You smash into the door!"); + msg_format("You smash into the %s!", name); #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); - /* Compare bash power to door power XXX XXX XXX */ temp = (bash - (temp * 10)); @@ -2474,33 +2313,28 @@ static bool do_cmd_bash_aux(int y, int x, int dir) { /* Message */ #ifdef JP - msg_print("¥É¥¢¤ò²õ¤·¤¿¡ª"); + msg_format("%s¤ò²õ¤·¤¿¡ª", name); #else - msg_print("The door crashes open!"); + msg_format("The %s crashes open!", name); #endif + /* 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 */ @@ -2509,9 +2343,9 @@ static bool do_cmd_bash_aux(int y, int x, int dir) { /* Message */ #ifdef JP - msg_print("¤³¤Î¥É¥¢¤Ï´è¾æ¤À¡£"); + msg_format("¤³¤Î%s¤Ï´è¾æ¤À¡£", name); #else - msg_print("The door holds firm."); + msg_format("The %s holds firm.", name); #endif @@ -2583,7 +2417,7 @@ 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]; @@ -2593,15 +2427,14 @@ void do_cmd_bash(void) 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("¤½¤³¤Ë¤ÏÂÎÅö¤¿¤ê¤¹¤ë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); + msg_print("¤½¤³¤Ë¤ÏÂÎÅö¤¿¤ê¤¹¤ë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); #else msg_print("You see nothing there to bash."); #endif @@ -2616,7 +2449,7 @@ void do_cmd_bash(void) /* Message */ #ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); + msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); #else msg_print("There is a monster in the way!"); #endif @@ -2679,7 +2512,8 @@ 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]; @@ -2689,7 +2523,8 @@ void do_cmd_alter(void) 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; @@ -2701,39 +2536,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); } @@ -2808,7 +2636,7 @@ void do_cmd_spike(void) { int y, x, item; cave_type *c_ptr; - byte feat; + s16b feat; /* Get location */ y = py + ddy[dir]; @@ -2818,15 +2646,14 @@ void do_cmd_spike(void) 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("¤½¤³¤Ë¤Ï¤¯¤µ¤Ó¤òÂǤƤë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); + msg_print("¤½¤³¤Ë¤Ï¤¯¤µ¤Ó¤òÂǤƤë¤â¤Î¤¬¸«Åö¤¿¤é¤Ê¤¤¡£"); #else msg_print("You see nothing there to spike."); #endif @@ -2838,11 +2665,10 @@ void do_cmd_spike(void) { /* Message */ #ifdef JP - msg_print("¤¯¤µ¤Ó¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡ª"); + msg_print("¤¯¤µ¤Ó¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡ª"); #else msg_print("You have no spikes!"); #endif - } /* Is a monster in the way? */ @@ -2853,12 +2679,11 @@ void do_cmd_spike(void) /* Message */ #ifdef JP - msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); + msg_print("¥â¥ó¥¹¥¿¡¼¤¬Î©¤Á¤Õ¤µ¤¬¤Ã¤Æ¤¤¤ë¡ª"); #else msg_print("There is a monster in the way!"); #endif - /* Attack */ py_attack(y, x, 0); } @@ -2871,17 +2696,12 @@ void do_cmd_spike(void) /* Successful jamming */ #ifdef JP - msg_print("¥É¥¢¤Ë¤¯¤µ¤Ó¤òÂǤÁ¹þ¤ó¤À¡£"); + msg_format("%s¤Ë¤¯¤µ¤Ó¤òÂǤÁ¹þ¤ó¤À¡£", f_name + f_info[feat].name); #else - msg_print("You jam the door with a spike."); + msg_format("You jam the %s with a spike.", f_name + f_info[feat].name); #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++; + cave_alter_feat(y, x, FF_SPIKE); /* Use up, and describe, a single spike, from the bottom */ inven_item_increase(item, -1); @@ -2896,7 +2716,7 @@ void do_cmd_spike(void) /* * Support code for the "Walk" and "Jump" commands */ -void do_cmd_walk(int pickup) +void do_cmd_walk(bool pickup) { int dir; @@ -2939,7 +2759,7 @@ 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(py, px, FF_TOWN)) { int tmp = 120 + p_ptr->lev*10 - wilderness[py][px].level + 5; if (tmp < 1) @@ -2954,13 +2774,13 @@ void do_cmd_walk(int pickup) #endif /* 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 */ + energy_use = 100; + /* HACk -- set the encouter flag for the wilderness generation */ generate_encounter = TRUE; } @@ -3013,10 +2833,9 @@ void do_cmd_run(void) * Stay still. Search. Enter stores. * Pick up treasure if "pickup" is true. */ -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) @@ -3031,80 +2850,11 @@ 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 - - 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(py, px, mpe_mode); } @@ -3122,6 +2872,9 @@ 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) { @@ -3211,6 +2964,18 @@ 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) { @@ -3267,7 +3032,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; } @@ -3279,7 +3044,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; } @@ -3291,7 +3056,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; } @@ -3303,7 +3068,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; } @@ -3315,7 +3080,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; } @@ -3327,7 +3092,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; } @@ -3339,7 +3104,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; } @@ -3351,7 +3116,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; } @@ -3363,7 +3128,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; } @@ -3375,7 +3140,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; } @@ -3387,7 +3152,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; } @@ -3399,7 +3164,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; } @@ -3411,7 +3176,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; } @@ -3423,7 +3188,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; } @@ -3435,7 +3200,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; } @@ -3447,7 +3212,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; } @@ -3459,7 +3224,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; } @@ -3471,7 +3236,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; } @@ -3485,14 +3250,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); } } @@ -3504,14 +3269,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); } } @@ -3523,51 +3288,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); } } @@ -3588,6 +3369,9 @@ 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); } @@ -3624,8 +3408,8 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr) 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; @@ -3638,6 +3422,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 */ @@ -3653,9 +3439,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; @@ -3664,14 +3452,14 @@ 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); if ((j_ptr->sval == SV_LIGHT_XBOW) || (j_ptr->sval == SV_HEAVY_XBOW)) - chance = (p_ptr->skill_thb + ((p_ptr->weapon_exp[0][j_ptr->sval])/400 + bonus) * BTH_PLUS_ADJ); + chance = (p_ptr->skill_thb + (p_ptr->weapon_exp[0][j_ptr->sval] / 400 + bonus) * BTH_PLUS_ADJ); else - chance = (p_ptr->skill_thb + ((p_ptr->weapon_exp[0][j_ptr->sval]-4000)/200 + bonus) * BTH_PLUS_ADJ); + 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); tmul = bow_tmul(j_ptr->sval); @@ -3682,13 +3470,18 @@ 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; @@ -3697,12 +3490,55 @@ void do_cmd_fire_aux(int item, object_type *j_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 = px + 99 * ddx[dir]; + ty = py + 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, py, px, ty, tx, PROJECT_PATH|PROJECT_THRU) - 1; + project_length = 0; /* reset to default */ + /* Don't shoot at my feet */ + if (tx == px && ty == py) + { + energy_use = 0; + + /* project_length is already reset to 0 */ + + return; + } + + + /* Take a (partial) turn */ + energy_use = (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 = py; + x = px; + /* Get local object */ q_ptr = &forge; @@ -3727,38 +3563,24 @@ 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; @@ -3767,12 +3589,48 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) nx = x; mmove2(&ny, &nx, py, px, 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) + { +#ifdef JP + if (c_ptr->info & (CAVE_MARK)) msg_print("´ä¤¬ºÕ¤±»¶¤Ã¤¿¡£"); +#else + if (c_ptr->info & (CAVE_MARK)) msg_print("Wall rocks were shattered."); +#endif + /* 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)) @@ -3796,6 +3654,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; @@ -3804,6 +3685,7 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) /* Monster here, Try to hit it */ if (cave[y][x].m_idx) { + int armour; cave_type *c_ptr = &cave[y][x]; monster_type *m_ptr = &m_list[c_ptr->m_idx]; @@ -3815,7 +3697,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); @@ -3827,9 +3709,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 < 4000) amount = 80; - else if (now_exp < 6000) amount = 25; - else if ((now_exp < 7000) && (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); @@ -3838,51 +3720,31 @@ void do_cmd_fire_aux(int item, object_type *j_ptr) if (p_ptr->riding) { - if (p_ptr->skill_exp[GINOU_RIDING] < s_info[p_ptr->pclass].s_max[GINOU_RIDING] && ((p_ptr->skill_exp[GINOU_RIDING] - 1000) / 200 < r_info[m_list[p_ptr->riding].r_idx].level) && one_in_(2)) + if ((p_ptr->skill_exp[GINOU_RIDING] < s_info[p_ptr->pclass].s_max[GINOU_RIDING]) + && ((p_ptr->skill_exp[GINOU_RIDING] - (RIDING_EXP_BEGINNER * 2)) / 200 < r_info[m_list[p_ptr->riding].r_idx].level) + && one_in_(2)) { - p_ptr->skill_exp[GINOU_RIDING]+=1; + p_ptr->skill_exp[GINOU_RIDING] += 1; p_ptr->update |= (PU_BONUS); } } + /* Some shots have hit bonus */ + armour = r_ptr->ac; + if (p_ptr->concent) + { + armour *= (10 - p_ptr->concent); + armour /= 10; + } + /* 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, armour, m_ptr->ml)) { 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) @@ -3911,23 +3773,47 @@ note_dies = " msg_format("The %s hits %s.", o_name, m_name); #endif + 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_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; +#ifdef JP + msg_format("%s¤ÎµÞ½ê¤ËÆͤ­»É¤µ¤Ã¤¿¡ª", m_name); +#else + msg_format("Your shot sticked on a fatal spot of %s!", m_name); +#endif + } + 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, 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) @@ -3942,8 +3828,30 @@ note_dies = " } + /* 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_ptr->m_idx, tdam, &fear, extract_note_dies(real_r_ptr(m_ptr)))) { /* Dead monster */ } @@ -3952,7 +3860,7 @@ note_dies = " else { /* STICK TO */ - if (q_ptr->name1) + if (object_is_fixed_artifact(q_ptr)) { char m_name[80]; @@ -3991,13 +3899,66 @@ note_dies = " #endif } - if (!projectable(m_ptr->fy, m_ptr->fx, py, px)) + + set_target(m_ptr, py, px); + + /* Sniper */ + if (snipe_type == SP_RUSH) { - set_target(m_ptr, py, px); + int n = randint1(5) + 3; + int m_idx = c_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, py, px, 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_ptr->m_idx, TRUE); + + lite_spot(ny, nx); + lite_spot(oy, ox); + + 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; } @@ -4006,31 +3967,31 @@ 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); + msg_format("%s¤Ï¤É¤³¤«¤Ø¹Ô¤Ã¤¿¡£", o_name); #else - msg_format("The %s have gone to somewhere.", o_name); + 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 ]; + 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; @@ -4043,11 +4004,23 @@ 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); } @@ -4057,6 +4030,8 @@ void do_cmd_fire(void) object_type *j_ptr; cptr q, s; + is_fired = FALSE; /* not fired yet */ + /* Get the "bow" (if any) */ j_ptr = &inventory[INVEN_BOW]; @@ -4109,6 +4084,24 @@ 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) + { +#ifdef JP + msg_print("¼Í·â¤ÎÈ¿Æ°¤¬ÂΤò½±¤Ã¤¿¡£"); +#else + msg_print("A reactionary of shooting attacked you. "); +#endif + (void)set_slow(p_ptr->slow + randint0(7) + 7, FALSE); + (void)set_stun(p_ptr->stun + randint1(25)); + } } @@ -4133,10 +4126,10 @@ static bool item_tester_hook_boomerang(object_type *o_ptr) 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; @@ -4164,13 +4157,13 @@ 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 @@ -4187,10 +4180,8 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) return FALSE; } } - else - { - item = INVEN_RARM; - } + else if (buki_motteruka(INVEN_LARM)) item = INVEN_LARM; + else item = INVEN_RARM; } else { @@ -4222,7 +4213,7 @@ 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 @@ -4235,9 +4226,9 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) 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("¥¢¥ê¡¼¥Ê¤Ç¤Ï¥¢¥¤¥Æ¥à¤ò»È¤¨¤Ê¤¤¡ª"); @@ -4259,6 +4250,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); @@ -4267,7 +4259,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; @@ -4285,7 +4277,7 @@ 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; @@ -4297,8 +4289,6 @@ 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]; @@ -4309,6 +4299,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) || @@ -4323,7 +4315,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 { @@ -4335,7 +4327,7 @@ 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; @@ -4361,6 +4353,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; ) { @@ -4373,27 +4369,24 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) mmove2(&ny[cur_dis], &nx[cur_dis], py, px, 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(); } @@ -4404,10 +4397,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) @@ -4428,42 +4427,6 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken) { 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) { @@ -4491,18 +4454,23 @@ note_dies = " msg_format("The %s hits %s.", o_name, m_name); #endif + 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_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 = tot_dam_aux(q_ptr, tdam, m_ptr, 0, TRUE); tdam = critical_shot(q_ptr->weight, q_ptr->to_h, tdam); if (q_ptr->to_d > 0) tdam += q_ptr->to_d; @@ -4548,7 +4516,7 @@ note_dies = " } /* 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 */ } @@ -4590,6 +4558,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); @@ -4599,14 +4570,14 @@ note_dies = " j = 100; if (!(summon_named_creature(0, y, x, q_ptr->pval, - !(cursed_p(q_ptr)) ? PM_FORCE_PET : 0L))) + !(object_is_cursed(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)) + else if (object_is_cursed(q_ptr)) #ifdef JP msg_print("¤³¤ì¤Ï¤¢¤Þ¤êÎɤ¯¤Ê¤¤µ¤¤¬¤¹¤ë¡£"); #else @@ -4636,7 +4607,7 @@ 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); @@ -4666,11 +4637,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])) { @@ -4773,7 +4744,19 @@ 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; } @@ -4784,5 +4767,226 @@ msg_print(" */ 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]; + +/* Hack: forget the "flow" information */ +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; +} + +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); +} + +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; +} + + +static void travel_flow(int ty, int tx) +{ + int x, y, d; + bool wall = FALSE; + feature_type *f_ptr = &f_info[cave[py][px].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; +} + +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 == px) && (y == py)) + { +#ifdef JP + msg_print("¤¹¤Ç¤Ë¤½¤³¤Ë¤¤¤Þ¤¹¡ª"); +#else + msg_print("You are already there!!"); +#endif + 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))) + { +#ifdef JP + msg_print("¤½¤³¤Ë¤Ï¹Ô¤¯¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¡ª"); +#else + msg_print("You cannot travel there!"); +#endif + 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(px - x); + dy = abs(py - y); + sx = ((x == px) || (dx < dy)) ? 0 : ((x > px) ? 1 : -1); + sy = ((y == py) || (dy < dx)) ? 0 : ((y > py) ? 1 : -1); + + for (i = 1; i <= 9; i++) + { + if ((sx == ddx[i]) && (sy == ddy[i])) travel.dir = i; + } +} +#endif