OSDN Git Service

branch-hexの変更をコミット。
[hengband/hengband.git] / src / cmd2.c
index 36e886e..11355bf 100644 (file)
@@ -320,7 +320,7 @@ void do_cmd_go_down(void)
                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, "fell through a trap door");
@@ -331,7 +331,7 @@ void do_cmd_go_down(void)
                if (fall_trap)
                {
 #ifdef JP
-                       msg_print("¤ï¤¶¤ÈÍ¸Í¤ËÍî¤Á¤¿¡£");
+                       msg_print("¤ï¤¶¤ÈÍî¤Ȥ·¸Í¤ËÍî¤Á¤¿¡£");
 #else
                        msg_print("You deliberately jump through the trap door.");
 #endif
@@ -434,7 +434,7 @@ 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);
@@ -739,7 +739,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
@@ -759,7 +759,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
@@ -1124,9 +1124,6 @@ static bool do_cmd_open_aux(int y, int x)
                        /* Open the door */
                        cave_alter_feat(y, x, FF_OPEN);
 
-                       /* Update some things */
-                       p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS | PU_MON_LITE);
-
                        /* Sound */
                        sound(SOUND_OPENDOOR);
 
@@ -1159,9 +1156,6 @@ static bool do_cmd_open_aux(int y, int x)
                /* Open the door */
                cave_alter_feat(y, x, FF_OPEN);
 
-               /* Update some things */
-               p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS | PU_MON_LITE);
-
                /* Sound */
                sound(SOUND_OPENDOOR);
        }
@@ -1321,8 +1315,11 @@ static bool do_cmd_close_aux(int y, int x)
        /* Open door */
        if (have_flag(f_info[old_feat].flags, FF_CLOSE))
        {
+               s16b closed_feat = feat_state(old_feat, FF_CLOSE);
+
                /* Hack -- object in the way */
-               if ((c_ptr->o_idx || (c_ptr->info & CAVE_OBJECT)) && (feat_state(old_feat, FF_CLOSE) != old_feat))
+               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
@@ -1348,9 +1345,6 @@ static bool do_cmd_close_aux(int y, int x)
                        }
                        else
                        {
-                               /* Update some things */
-                               p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS | PU_MON_LITE);
-
                                /* Sound */
                                sound(SOUND_SHUTDOOR);
                        }
@@ -1482,7 +1476,7 @@ static bool do_cmd_tunnel_test(int y, int x)
        }
 
        /* Must be a wall/door/etc */
-       if (!have_flag(f_flags_grid(c_ptr), FF_TUNNEL))
+       if (!cave_have_flag_grid(c_ptr, FF_TUNNEL))
        {
                /* Message */
 #ifdef JP
@@ -1576,7 +1570,7 @@ static bool do_cmd_tunnel_aux(int y, int x)
                        cave_alter_feat(y, x, FF_TUNNEL);
 
                        /* Update some things */
-                       p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS | PU_MON_LITE);
+                       p_ptr->update |= (PU_FLOW);
                }
                else
                {
@@ -1600,18 +1594,26 @@ static bool do_cmd_tunnel_aux(int y, int x)
                {
 #ifdef JP
                        if (tree) msg_format("%s¤òÀÚ¤êʧ¤Ã¤¿¡£", name);
-                       else msg_print("·ê¤ò·¡¤ê½ª¤¨¤¿¡£");
+                       else
+                       {
+                               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.");
+                       else
+                       {
+                               msg_print("You have finished the tunnel.");
+                               p_ptr->update |= (PU_FLOW);
+                       }
 #endif
 
+                       /* Sound */
+                       if (have_flag(f_ptr->flags, FF_GLASS)) sound(SOUND_GLASS);
+
                        /* Remove the feature */
                        cave_alter_feat(y, x, FF_TUNNEL);
 
-                       /* Update some things */
-                       p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS | PU_MON_LITE);
-
                        chg_virtue(V_DILIGENCE, 1);
                        chg_virtue(V_NATURE, -1);
                }
@@ -1823,13 +1825,9 @@ bool easy_open_door(int y, int x)
                        msg_print("You have picked the lock.");
 #endif
 
-
                        /* Open the door */
                        cave_alter_feat(y, x, FF_OPEN);
 
-                       /* Update some things */
-                       p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS | PU_MON_LITE);
-
                        /* Sound */
                        sound(SOUND_OPENDOOR);
 
@@ -1859,9 +1857,6 @@ bool easy_open_door(int y, int x)
                /* Open the door */
                cave_alter_feat(y, x, FF_OPEN);
 
-               /* Update some things */
-               p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS | PU_MON_LITE);
-
                /* Sound */
                sound(SOUND_OPENDOOR);
        }
@@ -2243,12 +2238,15 @@ static bool do_cmd_bash_aux(int y, int x, int dir)
        /* Get grid */
        cave_type       *c_ptr = &cave[y][x];
 
+       /* 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_info[c_ptr->feat].power;
+       int temp = f_ptr->power;
 
        bool            more = FALSE;
 
@@ -2282,9 +2280,11 @@ static bool do_cmd_bash_aux(int y, int x, int dir)
                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) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat))
+               if ((randint0(100) < 50) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS))
                {
                        cave_alter_feat(y, x, FF_BASH);
                }
@@ -2295,15 +2295,8 @@ static bool do_cmd_bash_aux(int y, int x, int dir)
                        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 | PU_MON_LITE);
-               p_ptr->update |= (PU_DISTANCE);
        }
 
        /* Saving throw against stun */
@@ -2728,7 +2721,7 @@ void do_cmd_walk(bool pickup)
        }
 
        /* Hack again -- Is there a special encounter ??? */
-       if (p_ptr->wild_mode && !have_flag(f_flags_bold(py, px), FF_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) 
@@ -2841,6 +2834,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)
        {
@@ -2930,6 +2926,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)
        {
@@ -2986,7 +2994,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_ANIMAL;
                                }
@@ -2998,7 +3006,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_ANIMAL;
                                }
@@ -3010,7 +3018,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_EVIL;
                                }
@@ -3022,7 +3030,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_EVIL;
                                }
@@ -3034,7 +3042,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags2 |= RF2_HUMAN;
                                }
@@ -3046,7 +3054,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags2 |= RF2_HUMAN;
                                }
@@ -3058,7 +3066,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_UNDEAD;
                                }
@@ -3070,7 +3078,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_UNDEAD;
                                }
@@ -3082,7 +3090,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_DEMON;
                                }
@@ -3094,7 +3102,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_DEMON;
                                }
@@ -3106,7 +3114,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_ORC;
                                }
@@ -3118,7 +3126,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_ORC;
                                }
@@ -3130,7 +3138,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_TROLL;
                                }
@@ -3142,7 +3150,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_TROLL;
                                }
@@ -3154,7 +3162,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_GIANT;
                                }
@@ -3166,7 +3174,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_GIANT;
                                }
@@ -3178,7 +3186,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_DRAGON;
                                }
@@ -3190,7 +3198,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 && is_original_ap(m_ptr))
+                               if (is_original_ap_and_seen(m_ptr))
                                {
                                        r_ptr->r_flags3 |= RF3_DRAGON;
                                }
@@ -3209,7 +3217,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
                                /* Notice immunity */
                                if (r_ptr->flagsr & RFR_EFF_IM_ACID_MASK)
                                {
-                                       if (m_ptr->ml && is_original_ap(m_ptr))
+                                       if (is_original_ap_and_seen(m_ptr))
                                        {
                                                r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ACID_MASK);
                                        }
@@ -3228,7 +3236,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
                                /* Notice immunity */
                                if (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)
                                {
-                                       if (m_ptr->ml && is_original_ap(m_ptr))
+                                       if (is_original_ap_and_seen(m_ptr))
                                        {
                                                r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
                                        }
@@ -3247,7 +3255,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
                                /* Notice immunity */
                                if (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)
                                {
-                                       if (m_ptr->ml && is_original_ap(m_ptr))
+                                       if (is_original_ap_and_seen(m_ptr))
                                        {
                                                r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
                                        }
@@ -3259,7 +3267,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
                                        if (r_ptr->flags3 & RF3_HURT_FIRE)
                                        {
                                                if (mult < 25) mult = 25;
-                                               if (m_ptr->ml && is_original_ap(m_ptr))
+                                               if (is_original_ap_and_seen(m_ptr))
                                                {
                                                        r_ptr->r_flags3 |= RF3_HURT_FIRE;
                                                }
@@ -3274,7 +3282,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
                                /* Notice immunity */
                                if (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)
                                {
-                                       if (m_ptr->ml && is_original_ap(m_ptr))
+                                       if (is_original_ap_and_seen(m_ptr))
                                        {
                                                r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
                                        }
@@ -3285,7 +3293,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
                                        if (r_ptr->flags3 & RF3_HURT_COLD)
                                        {
                                                if (mult < 25) mult = 25;
-                                               if (m_ptr->ml && is_original_ap(m_ptr))
+                                               if (is_original_ap_and_seen(m_ptr))
                                                {
                                                        r_ptr->r_flags3 |= RF3_HURT_COLD;
                                                }
@@ -3300,7 +3308,7 @@ static s16b tot_dam_aux_shot(object_type *o_ptr, int tdam, monster_type *m_ptr)
                                /* Notice immunity */
                                if (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK)
                                {
-                                       if (m_ptr->ml && is_original_ap(m_ptr))
+                                       if (is_original_ap_and_seen(m_ptr))
                                        {
                                                r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK);
                                        }
@@ -3323,6 +3331,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);
 }
@@ -3359,7 +3370,7 @@ 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 i, j, y, x, ny, nx, ty, tx, prev_y, prev_x;
        int tdam, tdis, thits, tmul;
        int bonus, chance;
        int cur_dis, visible;
@@ -3373,6 +3384,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 */
@@ -3388,10 +3401,12 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
                o_ptr = &o_list[0 - item];
        }
 
+       /* 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;
 
@@ -3420,10 +3435,18 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
        tdam *= tmul;
        tdam /= 100;
 
+       /* Get extra damage from concentration */
+       if (p_ptr->concent) tdam = boost_concentration_damage(tdam);
+
        /* 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;
 
@@ -3432,15 +3455,13 @@ 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;
        }
 
-       /* Start at the player */
-       y = py;
-       x = px;
-
        /* Predict the "target" location */
        tx = px + 99 * ddx[dir];
        ty = py + 99 * ddy[dir];
@@ -3452,6 +3473,9 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
                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 */
@@ -3465,6 +3489,21 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
        }
 
 
+       /* 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;
 
@@ -3489,22 +3528,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);
-
-
        /* 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;
 
@@ -3513,12 +3554,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 (!have_flag(f_flags_bold(ny, nx), FF_PROJECT) && !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))
@@ -3542,6 +3619,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;
@@ -3550,6 +3650,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];
@@ -3561,7 +3662,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);
@@ -3593,8 +3694,16 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
                                }
                        }
 
+                       /* 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;
 
@@ -3625,23 +3734,47 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
                                        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)
@@ -3656,6 +3789,28 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
 
                                }
 
+                               /* 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, extract_note_dies(real_r_ptr(m_ptr))))
                                {
@@ -3705,13 +3860,66 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
 #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;
                }
@@ -3720,31 +3928,31 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
        /* 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 (object_is_fixed_artifact(q_ptr))
-                     {
-                       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;
@@ -3757,11 +3965,23 @@ void do_cmd_fire_aux(int item, object_type *j_ptr)
 
                /* 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);
 }
 
 
@@ -3771,6 +3991,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];
 
@@ -3823,6 +4045,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));
+       }
 }
 
 
@@ -3847,7 +4087,7 @@ 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;
@@ -3884,7 +4124,7 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int 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
@@ -3901,10 +4141,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
        {
@@ -4075,6 +4313,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; )
        {
@@ -4087,27 +4329,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 (!have_flag(f_flags_bold(ny[cur_dis], nx[cur_dis]), FF_PROJECT))
+               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();
                }
 
@@ -4118,10 +4357,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)
@@ -4169,12 +4414,14 @@ bool do_cmd_throw_aux(int mult, bool boomerang, int shuriken)
                                        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 */
@@ -4314,7 +4561,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);
@@ -4348,7 +4595,7 @@ msg_print("
 
                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]))
                                {
@@ -4451,7 +4698,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;
 }
@@ -4464,3 +4723,170 @@ void do_cmd_throw(void)
 {
        do_cmd_throw_aux(1, FALSE, 0);
 }
+
+
+#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] = TRAVEL_UNABLE;
+               }
+       }
+}
+
+static bool 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;
+
+       n = n % TRAVEL_UNABLE;
+
+       /* Ignore out of bounds */
+       if (!in_bounds(y, x)) return wall;
+
+       /* Ignore "pre-stamped" entries */
+       if (travel.cost[y][x] != TRAVEL_UNABLE) return wall;
+
+       /* 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) return wall;
+       }
+       else
+       {
+               wall = FALSE;
+       }
+
+       /* Save the flow cost */
+       travel.cost[y][x] = n;
+       if (wall) travel.cost[y][x] += TRAVEL_UNABLE;
+
+       /* 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 wall;
+}
+
+
+static void travel_flow(int ty, int tx)
+{
+       int x, y, d;
+       bool wall = FALSE;
+       feature_type *f_ptr = &f_info[cave[ty][tx].feat];
+
+       /* Reset the "queue" */
+       flow_head = flow_tail = 0;
+
+       if (!have_flag(f_ptr->flags, FF_MOVE)) wall = TRUE;
+
+       /* Add the player's grid to the queue */
+       wall = 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;
+
+               /* Add the "children" */
+               for (d = 0; d < 8; d++)
+               {
+                       /* Add that child if "legal" */
+                       wall = travel_flow_aux(y + ddy_ddd[d], x + ddx_ddd[d], travel.cost[y][x] + 1, 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 (!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;
+       }
+
+       travel.x = x;
+       travel.y = y;
+
+       forget_travel_flow();
+       travel_flow(y, x);
+
+       /* 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