OSDN Git Service

[Refactor] #38997 chg_virtue() に player_type * 引数を追加.
[hengband/hengband.git] / src / melee1.c
index 7247669..5eeeab2 100644 (file)
 #include "player-status.h"
 #include "player-race.h"
 #include "player-class.h"
+#include "player-personality.h"
 #include "view-mainwindow.h"
 #include "world.h"
+#include "spells-floor.h"
 
 
  /*!
@@ -1007,25 +1009,36 @@ static int check_hit(int power, DEPTH level, int stun)
 {
        int i, k, ac;
 
-       /* Percentile dice */
        k = randint0(100);
-
        if (stun && one_in_(2)) return FALSE;
-
-       /* Hack -- Always miss or hit */
        if (k < 10) return (k < 5);
-
-       /* Calculate the "attack quality" */
        i = (power + (level * 3));
 
-       /* Total armor */
        ac = p_ptr->ac + p_ptr->to_a;
        if (p_ptr->special_attack & ATTACK_SUIKEN) ac += (p_ptr->lev * 2);
 
-       /* Power and Level compete against Armor */
        if ((i > 0) && (randint1(i) > ((ac * 3) / 4))) return (TRUE);
+       return (FALSE);
+}
+
+/*!
+ * @brief モンスターから敵モンスターへの命中判定
+ * @param power 打撃属性による基本命中値
+ * @param level 攻撃側モンスターのレベル
+ * @param ac 目標モンスターのAC
+ * @param stun 攻撃側モンスターが朦朧状態ならTRUEを返す
+ * @return 命中ならばTRUEを返す
+ */
+static int check_hit2(int power, DEPTH level, ARMOUR_CLASS ac, int stun)
+{
+       int i, k;
 
-       /* Assume miss */
+       k = randint0(100);
+       if (stun && one_in_(2)) return FALSE;
+       if (k < 10) return (k < 5);
+       i = (power + (level * 3));
+
+       if ((i > 0) && (randint1(i) > ((ac * 3) / 4))) return (TRUE);
        return (FALSE);
 }
 
@@ -1188,7 +1201,6 @@ static void natural_attack(MONSTER_IDX m_idx, int attack, bool *fear, bool *mdea
 
        }
 
-       /* Extract monster name (or "it") */
        monster_desc(m_name, m_ptr, 0);
 
        /* Calculate the "attack quality" */
@@ -1375,7 +1387,6 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
        /* Disturb the monster */
        (void)set_monster_csleep(g_ptr->m_idx, 0);
 
-       /* Extract monster name (or "it") */
        monster_desc(m_name, m_ptr, 0);
 
        /* Calculate the "attack quality" */
@@ -1449,7 +1460,7 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
                        if ((have_flag(flgs, TR_CHAOTIC)) && one_in_(2))
                        {
                                if (one_in_(10))
-                                       chg_virtue(V_CHANCE, 1);
+                                       chg_virtue(p_ptr, V_CHANCE, 1);
 
                                if (randint1(5) < 3)
                                {
@@ -1899,7 +1910,7 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
 
                                                        drain_heal = (drain_heal * p_ptr->mutant_regenerate_mod) / 100;
 
-                                                       hp_player(drain_heal);
+                                                       hp_player(p_ptr, drain_heal);
                                                        /* We get to keep some of it! */
                                                }
                                        }
@@ -2136,13 +2147,13 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
        {
                if (one_in_(4))
                {
-                       chg_virtue(V_UNLIFE, 1);
+                       chg_virtue(p_ptr, V_UNLIFE, 1);
                }
        }
        /* Mega-Hack -- apply earthquake brand */
        if (do_quake)
        {
-               earthquake(p_ptr->y, p_ptr->x, 10);
+               earthquake(p_ptr->y, p_ptr->x, 10, 0);
                if (!current_floor_ptr->grid_array[y][x].m_idx) *mdeath = TRUE;
        }
 }
@@ -2179,7 +2190,6 @@ bool py_attack(POSITION y, POSITION x, COMBAT_OPTION_IDX mode)
                return FALSE;
        }
 
-       /* Extract monster name (or "it") */
        monster_desc(m_name, m_ptr, 0);
 
        if (m_ptr->ml)
@@ -2187,7 +2197,6 @@ bool py_attack(POSITION y, POSITION x, COMBAT_OPTION_IDX mode)
                /* Auto-Recall if possible and visible */
                if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
 
-               /* Track a new monster */
                health_track(g_ptr->m_idx);
        }
 
@@ -2217,19 +2226,19 @@ bool py_attack(POSITION y, POSITION x, COMBAT_OPTION_IDX mode)
                if (stormbringer)
                {
                        msg_format(_("黒い刃は強欲に%sを攻撃した!", "Your black blade greedily attacks %s!"), m_name);
-                       chg_virtue(V_INDIVIDUALISM, 1);
-                       chg_virtue(V_HONOUR, -1);
-                       chg_virtue(V_JUSTICE, -1);
-                       chg_virtue(V_COMPASSION, -1);
+                       chg_virtue(p_ptr, V_INDIVIDUALISM, 1);
+                       chg_virtue(p_ptr, V_HONOUR, -1);
+                       chg_virtue(p_ptr, V_JUSTICE, -1);
+                       chg_virtue(p_ptr, V_COMPASSION, -1);
                }
                else if (p_ptr->pclass != CLASS_BERSERKER)
                {
                        if (get_check(_("本当に攻撃しますか?", "Really hit it? ")))
                        {
-                               chg_virtue(V_INDIVIDUALISM, 1);
-                               chg_virtue(V_HONOUR, -1);
-                               chg_virtue(V_JUSTICE, -1);
-                               chg_virtue(V_COMPASSION, -1);
+                               chg_virtue(p_ptr, V_INDIVIDUALISM, 1);
+                               chg_virtue(p_ptr, V_HONOUR, -1);
+                               chg_virtue(p_ptr, V_JUSTICE, -1);
+                               chg_virtue(p_ptr, V_COMPASSION, -1);
                        }
                        else
                        {
@@ -2256,8 +2265,8 @@ bool py_attack(POSITION y, POSITION x, COMBAT_OPTION_IDX mode)
 
        if (MON_CSLEEP(m_ptr)) /* It is not honorable etc to attack helpless victims */
        {
-               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);
+               if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(p_ptr, V_COMPASSION, -1);
+               if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(p_ptr, V_HONOUR, -1);
        }
 
        if (p_ptr->migite && p_ptr->hidarite)
@@ -2305,7 +2314,7 @@ bool py_attack(POSITION y, POSITION x, COMBAT_OPTION_IDX mode)
                }
        }
 
-       riding_t_m_idx = g_ptr->m_idx;
+       p_ptr->riding_t_m_idx = g_ptr->m_idx;
        if (p_ptr->migite) py_attack_aux(y, x, &fear, &mdeath, 0, mode);
        if (p_ptr->hidarite && !mdeath) py_attack_aux(y, x, &fear, &mdeath, 1, mode);
 
@@ -2334,7 +2343,7 @@ bool py_attack(POSITION y, POSITION x, COMBAT_OPTION_IDX mode)
 
        if ((p_ptr->special_defense & KATA_IAI) && ((mode != HISSATSU_IAI) || mdeath))
        {
-               set_action(ACTION_NONE);
+               set_action(p_ptr, ACTION_NONE);
        }
 
        return mdeath;
@@ -2808,7 +2817,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        /* Take "poison" effect */
                                        if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()) && !CHECK_MULTISHADOW())
                                        {
-                                               if (set_poisoned(p_ptr->poisoned + randint1(rlev) + 5))
+                                               if (set_poisoned(p_ptr, p_ptr->poisoned + randint1(rlev) + 5))
                                                {
                                                        obvious = TRUE;
                                                }
@@ -2939,13 +2948,13 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                {
                                                        msg_print(_("財布が軽くなった気がする。", "Your purse feels lighter."));
                                                        msg_format(_("$%ld のお金が盗まれた!", "%ld coins were stolen!"), (long)gold);
-                                                       chg_virtue(V_SACRIFICE, 1);
+                                                       chg_virtue(p_ptr, V_SACRIFICE, 1);
                                                }
                                                else
                                                {
                                                        msg_print(_("財布が軽くなった気がする。", "Your purse feels lighter."));
                                                        msg_print(_("お金が全部盗まれた!", "All of your coins were stolen!"));
-                                                       chg_virtue(V_SACRIFICE, 2);
+                                                       chg_virtue(p_ptr, V_SACRIFICE, 2);
                                                }
 
                                                /* Redraw gold */
@@ -3005,7 +3014,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 #else
                                                msg_format("%sour %s (%c) was stolen!", ((o_ptr->number > 1) ? "One of y" : "Y"), o_name, index_to_label(i));
 #endif
-                                               chg_virtue(V_SACRIFICE, 1);
+                                               chg_virtue(p_ptr, V_SACRIFICE, 1);
                                                o_idx = o_pop();
 
                                                /* Success */
@@ -3170,7 +3179,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        /* Increase "blind" */
                                        if (!p_ptr->resist_blind && !CHECK_MULTISHADOW())
                                        {
-                                               if (set_blind(p_ptr->blind + 10 + randint1(rlev)))
+                                               if (set_blind(p_ptr, p_ptr->blind + 10 + randint1(rlev)))
                                                {
 #ifdef JP
                                                        if (m_ptr->r_idx == MON_DIO) msg_print("どうだッ!この血の目潰しはッ!");
@@ -3197,7 +3206,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        /* Increase "confused" */
                                        if (!p_ptr->resist_conf && !CHECK_MULTISHADOW())
                                        {
-                                               if (set_confused(p_ptr->confused + 3 + randint1(rlev)))
+                                               if (set_confused(p_ptr, p_ptr->confused + 3 + randint1(rlev)))
                                                {
                                                        obvious = TRUE;
                                                }
@@ -3232,7 +3241,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        }
                                        else
                                        {
-                                               if (set_afraid(p_ptr->afraid + 3 + randint1(rlev)))
+                                               if (set_afraid(p_ptr, p_ptr->afraid + 3 + randint1(rlev)))
                                                {
                                                        obvious = TRUE;
                                                }
@@ -3269,7 +3278,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        {
                                                if (!p_ptr->paralyzed)
                                                {
-                                                       if (set_paralyzed(3 + randint1(rlev)))
+                                                       if (set_paralyzed(p_ptr, 3 + randint1(rlev)))
                                                        {
                                                                obvious = TRUE;
                                                        }
@@ -3287,7 +3296,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1);
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
-                                       if (do_dec_stat(A_STR)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_STR)) obvious = TRUE;
 
                                        break;
                                }
@@ -3297,7 +3306,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1);
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
-                                       if (do_dec_stat(A_INT)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_INT)) obvious = TRUE;
 
                                        break;
                                }
@@ -3307,7 +3316,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1);
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
-                                       if (do_dec_stat(A_WIS)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_WIS)) obvious = TRUE;
 
                                        break;
                                }
@@ -3317,7 +3326,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1);
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
-                                       if (do_dec_stat(A_DEX)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_DEX)) obvious = TRUE;
 
                                        break;
                                }
@@ -3327,7 +3336,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1);
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
-                                       if (do_dec_stat(A_CON)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_CON)) obvious = TRUE;
 
                                        break;
                                }
@@ -3337,7 +3346,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1);
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
-                                       if (do_dec_stat(A_CHR)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_CHR)) obvious = TRUE;
 
                                        break;
                                }
@@ -3349,12 +3358,12 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
 
                                        /* Damage (stats) */
-                                       if (do_dec_stat(A_STR)) obvious = TRUE;
-                                       if (do_dec_stat(A_DEX)) obvious = TRUE;
-                                       if (do_dec_stat(A_CON)) obvious = TRUE;
-                                       if (do_dec_stat(A_INT)) obvious = TRUE;
-                                       if (do_dec_stat(A_WIS)) obvious = TRUE;
-                                       if (do_dec_stat(A_CHR)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_STR)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_DEX)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_CON)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_INT)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_WIS)) obvious = TRUE;
+                                       if (do_dec_stat(p_ptr, A_CHR)) obvious = TRUE;
 
                                        break;
                                }
@@ -3371,7 +3380,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        /* Radius 8 earthquake centered at the monster */
                                        if (damage > 23 || explode)
                                        {
-                                               earthquake_aux(m_ptr->fy, m_ptr->fx, 8, m_idx);
+                                               earthquake(m_ptr->fy, m_ptr->fx, 8, m_idx);
                                        }
 
                                        break;
@@ -3387,7 +3396,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
 
-                                       (void)drain_exp(d, d / 10, 95);
+                                       (void)drain_exp(p_ptr, d, d / 10, 95);
                                        break;
                                }
 
@@ -3401,7 +3410,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
 
-                                       (void)drain_exp(d, d / 10, 90);
+                                       (void)drain_exp(p_ptr, d, d / 10, 90);
                                        break;
                                }
 
@@ -3415,7 +3424,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
 
-                                       (void)drain_exp(d, d / 10, 75);
+                                       (void)drain_exp(p_ptr, d, d / 10, 75);
                                        break;
                                }
 
@@ -3429,7 +3438,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
 
-                                       (void)drain_exp(d, d / 10, 50);
+                                       (void)drain_exp(p_ptr, d, d / 10, 50);
                                        break;
                                }
 
@@ -3442,7 +3451,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        /* Take "poison" effect */
                                        if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()))
                                        {
-                                               if (set_poisoned(p_ptr->poisoned + randint1(rlev) + 5))
+                                               if (set_poisoned(p_ptr, p_ptr->poisoned + randint1(rlev) + 5))
                                                {
                                                        obvious = TRUE;
                                                }
@@ -3453,7 +3462,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        {
                                                /* 1% chance for perm. damage */
                                                bool perm = one_in_(10);
-                                               if (dec_stat(A_CON, randint1(10), perm))
+                                               if (dec_stat(p_ptr, A_CON, randint1(10), perm))
                                                {
                                                        msg_print(_("病があなたを蝕んでいる気がする。", "You feel strange sickness."));
                                                        obvious = TRUE;
@@ -3473,7 +3482,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                        {
                                                                if (p_ptr->prace == RACE_ANDROID) break;
                                                                msg_print(_("人生が逆戻りした気がする。", "You feel life has clocked back."));
-                                                               lose_exp(100 + (p_ptr->exp / 100) * MON_DRAIN_LIFE);
+                                                               lose_exp(p_ptr, 100 + (p_ptr->exp / 100) * MON_DRAIN_LIFE);
                                                                break;
                                                        }
 
@@ -3537,7 +3546,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
 
-                                       resist_drain = !drain_exp(d, d / 10, 50);
+                                       resist_drain = !drain_exp(p_ptr, d, d / 10, 50);
 
                                        /* Heal the attacker? */
                                        if (p_ptr->mimic_form)
@@ -3624,7 +3633,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        }
                                        else
                                        {
-                                               if (set_slow((p_ptr->slow + 4 + randint0(rlev / 10)), FALSE))
+                                               if (set_slow(p_ptr, (p_ptr->slow + 4 + randint0(rlev / 10)), FALSE))
                                                {
                                                        obvious = TRUE;
                                                }
@@ -3645,7 +3654,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                        }
                                        else
                                        {
-                                               if (set_stun(p_ptr->stun + 10 + randint1(r_ptr->level / 4)))
+                                               if (set_stun(p_ptr, p_ptr->stun + 10 + randint1(r_ptr->level / 4)))
                                                {
                                                        obvious = TRUE;
                                                }
@@ -3693,7 +3702,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                }
 
                                /* Apply the cut */
-                               if (cut_plus) (void)set_cut(p_ptr->cut + cut_plus);
+                               if (cut_plus) (void)set_cut(p_ptr,p_ptr->cut + cut_plus);
                        }
 
                        /* Handle stun */
@@ -3718,7 +3727,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                }
 
                                /* Apply the stun */
-                               if (stun_plus) (void)set_stun(p_ptr->stun + stun_plus);
+                               if (stun_plus) (void)set_stun(p_ptr, p_ptr->stun + stun_plus);
                        }
 
                        if (explode)
@@ -4055,7 +4064,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                msg_format("The attack of %s has wounded %s!", m_name, m_name_self);
 #endif
                project(0, 0, m_ptr->fy, m_ptr->fx, get_damage, GF_MISSILE, PROJECT_KILL, -1);
-               if (p_ptr->tim_eyeeye) set_tim_eyeeye(p_ptr->tim_eyeeye-5, TRUE);
+               if (p_ptr->tim_eyeeye) set_tim_eyeeye(p_ptr, p_ptr->tim_eyeeye-5, TRUE);
        }
 
        if ((p_ptr->counter || (p_ptr->special_defense & KATA_MUSOU)) && alive && !p_ptr->is_dead && m_ptr->ml && (p_ptr->csp > 7))
@@ -4099,7 +4108,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
        if (p_ptr->special_defense & KATA_IAI)
        {
-               set_action(ACTION_NONE);
+               set_action(p_ptr, ACTION_NONE);
        }
 
        /* Assume we attacked */
@@ -4107,6 +4116,635 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 }
 
 
+#define BLOW_EFFECT_TYPE_NONE  0
+#define BLOW_EFFECT_TYPE_FEAR  1
+#define BLOW_EFFECT_TYPE_SLEEP 2
+#define BLOW_EFFECT_TYPE_HEAL  3
+
+/*!
+ * @brief モンスターから敵モンスターへの打撃攻撃処理
+ * @param m_idx 攻撃側モンスターの参照ID
+ * @param t_idx 目標側モンスターの参照ID
+ * @return 実際に打撃処理が行われた場合TRUEを返す
+ */
+bool monst_attack_monst(MONSTER_IDX m_idx, MONSTER_IDX t_idx)
+{
+       monster_type    *m_ptr = &current_floor_ptr->m_list[m_idx];
+       monster_type    *t_ptr = &current_floor_ptr->m_list[t_idx];
+
+       monster_race    *r_ptr = &r_info[m_ptr->r_idx];
+       monster_race    *tr_ptr = &r_info[t_ptr->r_idx];
+
+       ARMOUR_CLASS ap_cnt;
+       ARMOUR_CLASS ac;
+       DEPTH rlev;
+       int pt;
+       GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
+       char            temp[MAX_NLEN];
+       bool            blinked;
+       bool            explode = FALSE, touched = FALSE, fear = FALSE, dead = FALSE;
+       POSITION y_saver = t_ptr->fy;
+       POSITION x_saver = t_ptr->fx;
+       int             effect_type;
+
+       bool see_m = is_seen(m_ptr);
+       bool see_t = is_seen(t_ptr);
+       bool see_either = see_m || see_t;
+
+       /* Can the player be aware of this attack? */
+       bool known = (m_ptr->cdis <= MAX_SIGHT) || (t_ptr->cdis <= MAX_SIGHT);
+       bool do_silly_attack = (one_in_(2) && p_ptr->image);
+
+       /* Cannot attack self */
+       if (m_idx == t_idx) return FALSE;
+
+       /* Not allowed to attack */
+       if (r_ptr->flags1 & RF1_NEVER_BLOW) return FALSE;
+
+       if (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) return (FALSE);
+
+       /* Total armor */
+       ac = tr_ptr->ac;
+
+       /* Extract the effective monster level */
+       rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
+
+       monster_desc(m_name, m_ptr, 0);
+       monster_desc(t_name, t_ptr, 0);
+
+       /* Assume no blink */
+       blinked = FALSE;
+
+       if (!see_either && known)
+       {
+               current_floor_ptr->monster_noise = TRUE;
+       }
+
+       if (p_ptr->riding && (m_idx == p_ptr->riding)) disturb(TRUE, TRUE);
+
+       /* Scan through all four blows */
+       for (ap_cnt = 0; ap_cnt < 4; ap_cnt++)
+       {
+               bool obvious = FALSE;
+
+               HIT_POINT power = 0;
+               HIT_POINT damage = 0;
+
+               concptr act = NULL;
+
+               /* Extract the attack infomation */
+               int effect = r_ptr->blow[ap_cnt].effect;
+               int method = r_ptr->blow[ap_cnt].method;
+               int d_dice = r_ptr->blow[ap_cnt].d_dice;
+               int d_side = r_ptr->blow[ap_cnt].d_side;
+
+               if (!monster_is_valid(m_ptr)) break;
+
+               /* Stop attacking if the target dies! */
+               if (t_ptr->fx != x_saver || t_ptr->fy != y_saver)
+                       break;
+
+               /* Hack -- no more attacks */
+               if (!method) break;
+
+               if (method == RBM_SHOOT) continue;
+
+               /* Extract the attack "power" */
+               power = mbe_info[effect].power;
+
+               /* Monster hits */
+               if (!effect || check_hit2(power, rlev, ac, MON_STUNNED(m_ptr)))
+               {
+                       (void)set_monster_csleep(t_idx, 0);
+
+                       if (t_ptr->ml)
+                       {
+                               /* Redraw the health bar */
+                               if (p_ptr->health_who == t_idx) p_ptr->redraw |= (PR_HEALTH);
+                               if (p_ptr->riding == t_idx) p_ptr->redraw |= (PR_UHEALTH);
+                       }
+
+                       /* Describe the attack method */
+                       switch (method)
+                       {
+                       case RBM_HIT:
+                       {
+                               act = _("%sを殴った。", "hits %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_TOUCH:
+                       {
+                               act = _("%sを触った。", "touches %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_PUNCH:
+                       {
+                               act = _("%sをパンチした。", "punches %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_KICK:
+                       {
+                               act = _("%sを蹴った。", "kicks %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_CLAW:
+                       {
+                               act = _("%sをひっかいた。", "claws %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_BITE:
+                       {
+                               act = _("%sを噛んだ。", "bites %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_STING:
+                       {
+                               act = _("%sを刺した。", "stings %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_SLASH:
+                       {
+                               act = _("%sを斬った。", "slashes %s.");
+                               break;
+                       }
+
+                       case RBM_BUTT:
+                       {
+                               act = _("%sを角で突いた。", "butts %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_CRUSH:
+                       {
+                               act = _("%sに体当りした。", "crushes %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_ENGULF:
+                       {
+                               act = _("%sを飲み込んだ。", "engulfs %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_CHARGE:
+                       {
+                               act = _("%sに請求書をよこした。", "charges %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_CRAWL:
+                       {
+                               act = _("%sの体の上を這い回った。", "crawls on %s.");
+                               touched = TRUE;
+                               break;
+                       }
+
+                       case RBM_DROOL:
+                       {
+                               act = _("%sによだれをたらした。", "drools on %s.");
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_SPIT:
+                       {
+                               act = _("%sに唾を吐いた。", "spits on %s.");
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_EXPLODE:
+                       {
+                               if (see_either) disturb(TRUE, TRUE);
+                               act = _("爆発した。", "explodes.");
+                               explode = TRUE;
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_GAZE:
+                       {
+                               act = _("%sをにらんだ。", "gazes at %s.");
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_WAIL:
+                       {
+                               act = _("%sに泣きついた。", "wails at %s.");
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_SPORE:
+                       {
+                               act = _("%sに胞子を飛ばした。", "releases spores at %s.");
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_XXX4:
+                       {
+                               act = _("%sにXXX4を飛ばした。", "projects XXX4's at %s.");
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_BEG:
+                       {
+                               act = _("%sに金をせがんだ。", "begs %s for money.");
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_INSULT:
+                       {
+                               act = _("%sを侮辱した。", "insults %s.");
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_MOAN:
+                       {
+                               act = _("%sにむかってうめいた。", "moans at %s.");
+                               touched = FALSE;
+                               break;
+                       }
+
+                       case RBM_SHOW:
+                       {
+                               act = _("%sにむかって歌った。", "sings to %s.");
+                               touched = FALSE;
+                               break;
+                       }
+                       }
+
+                       if (act && see_either)
+                       {
+#ifdef JP
+                               if (do_silly_attack) act = silly_attacks2[randint0(MAX_SILLY_ATTACK)];
+                               strfmt(temp, act, t_name);
+                               msg_format("%^sは%s", m_name, temp);
+#else
+                               if (do_silly_attack)
+                               {
+                                       act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
+                                       strfmt(temp, "%s %s.", act, t_name);
+                               }
+                               else strfmt(temp, act, t_name);
+                               msg_format("%^s %s", m_name, temp);
+#endif
+                       }
+
+                       /* Hack -- assume all attacks are obvious */
+                       obvious = TRUE;
+
+                       /* Roll out the damage */
+                       damage = damroll(d_dice, d_side);
+
+                       /* Assume no effect */
+                       effect_type = BLOW_EFFECT_TYPE_NONE;
+
+                       pt = GF_MISSILE;
+
+                       /* Apply appropriate damage */
+                       switch (effect)
+                       {
+                       case 0:
+                       case RBE_DR_MANA:
+                               damage = pt = 0;
+                               break;
+
+                       case RBE_SUPERHURT:
+                               if ((randint1(rlev * 2 + 250) > (ac + 200)) || one_in_(13))
+                               {
+                                       int tmp_damage = damage - (damage * ((ac < 150) ? ac : 150) / 250);
+                                       damage = MAX(damage, tmp_damage * 2);
+                                       break;
+                               }
+
+                               /* Fall through */
+
+                       case RBE_HURT:
+                               damage -= (damage * ((ac < 150) ? ac : 150) / 250);
+                               break;
+
+                       case RBE_POISON:
+                       case RBE_DISEASE:
+                               pt = GF_POIS;
+                               break;
+
+                       case RBE_UN_BONUS:
+                       case RBE_UN_POWER:
+                               pt = GF_DISENCHANT;
+                               break;
+
+                       case RBE_EAT_ITEM:
+                       case RBE_EAT_GOLD:
+                               if ((p_ptr->riding != m_idx) && one_in_(2)) blinked = TRUE;
+                               break;
+
+                       case RBE_EAT_FOOD:
+                       case RBE_EAT_LITE:
+                       case RBE_BLIND:
+                       case RBE_LOSE_STR:
+                       case RBE_LOSE_INT:
+                       case RBE_LOSE_WIS:
+                       case RBE_LOSE_DEX:
+                       case RBE_LOSE_CON:
+                       case RBE_LOSE_CHR:
+                       case RBE_LOSE_ALL:
+                               break;
+
+                       case RBE_ACID:
+                               pt = GF_ACID;
+                               break;
+
+                       case RBE_ELEC:
+                               pt = GF_ELEC;
+                               break;
+
+                       case RBE_FIRE:
+                               pt = GF_FIRE;
+                               break;
+
+                       case RBE_COLD:
+                               pt = GF_COLD;
+                               break;
+
+                       case RBE_CONFUSE:
+                               pt = GF_CONFUSION;
+                               break;
+
+                       case RBE_TERRIFY:
+                               effect_type = BLOW_EFFECT_TYPE_FEAR;
+                               break;
+
+                       case RBE_PARALYZE:
+                               effect_type = BLOW_EFFECT_TYPE_SLEEP;
+                               break;
+
+                       case RBE_SHATTER:
+                               damage -= (damage * ((ac < 150) ? ac : 150) / 250);
+                               if (damage > 23) earthquake(m_ptr->fy, m_ptr->fx, 8, m_idx);
+                               break;
+
+                       case RBE_EXP_10:
+                       case RBE_EXP_20:
+                       case RBE_EXP_40:
+                       case RBE_EXP_80:
+                               pt = GF_NETHER;
+                               break;
+
+                       case RBE_TIME:
+                               pt = GF_TIME;
+                               break;
+
+                       case RBE_DR_LIFE:
+                               pt = GF_HYPODYNAMIA;
+                               effect_type = BLOW_EFFECT_TYPE_HEAL;
+                               break;
+
+                       case RBE_INERTIA:
+                               pt = GF_INERTIAL;
+                               break;
+
+                       case RBE_STUN:
+                               pt = GF_SOUND;
+                               break;
+
+                       default:
+                               pt = 0;
+                               break;
+                       }
+
+                       if (pt)
+                       {
+                               /* Do damage if not exploding */
+                               if (!explode)
+                               {
+                                       project(m_idx, 0, t_ptr->fy, t_ptr->fx,
+                                               damage, pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                               }
+
+                               switch (effect_type)
+                               {
+                               case BLOW_EFFECT_TYPE_FEAR:
+                                       project(m_idx, 0, t_ptr->fy, t_ptr->fx,
+                                               damage, GF_TURN_ALL, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                                       break;
+
+                               case BLOW_EFFECT_TYPE_SLEEP:
+                                       project(m_idx, 0, t_ptr->fy, t_ptr->fx,
+                                               r_ptr->level, GF_OLD_SLEEP, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                                       break;
+
+                               case BLOW_EFFECT_TYPE_HEAL:
+                                       if ((monster_living(m_idx)) && (damage > 2))
+                                       {
+                                               bool did_heal = FALSE;
+
+                                               if (m_ptr->hp < m_ptr->maxhp) did_heal = TRUE;
+
+                                               /* Heal */
+                                               m_ptr->hp += damroll(4, damage / 6);
+                                               if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
+
+                                               /* Redraw (later) if needed */
+                                               if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+                                               if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+
+                                               /* Special message */
+                                               if (see_m && did_heal)
+                                               {
+                                                       msg_format(_("%sは体力を回復したようだ。", "%^s appears healthier."), m_name);
+                                               }
+                                       }
+                                       break;
+                               }
+
+                               if (touched)
+                               {
+                                       /* Aura fire */
+                                       if ((tr_ptr->flags2 & RF2_AURA_FIRE) && m_ptr->r_idx)
+                                       {
+                                               if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK))
+                                               {
+                                                       if (see_either)
+                                                       {
+                                                               msg_format(_("%^sは突然熱くなった!", "%^s is suddenly very hot!"), m_name);
+                                                       }
+                                                       if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_FIRE;
+                                                       project(t_idx, 0, m_ptr->fy, m_ptr->fx,
+                                                               damroll(1 + ((tr_ptr->level) / 26),
+                                                                       1 + ((tr_ptr->level) / 17)),
+                                                               GF_FIRE, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                                               }
+                                               else
+                                               {
+                                                       if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
+                                               }
+                                       }
+
+                                       /* Aura cold */
+                                       if ((tr_ptr->flags3 & RF3_AURA_COLD) && m_ptr->r_idx)
+                                       {
+                                               if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK))
+                                               {
+                                                       if (see_either)
+                                                       {
+                                                               msg_format(_("%^sは突然寒くなった!", "%^s is suddenly very cold!"), m_name);
+                                                       }
+                                                       if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags3 |= RF3_AURA_COLD;
+                                                       project(t_idx, 0, m_ptr->fy, m_ptr->fx,
+                                                               damroll(1 + ((tr_ptr->level) / 26),
+                                                                       1 + ((tr_ptr->level) / 17)),
+                                                               GF_COLD, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                                               }
+                                               else
+                                               {
+                                                       if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
+                                               }
+                                       }
+
+                                       /* Aura elec */
+                                       if ((tr_ptr->flags2 & RF2_AURA_ELEC) && m_ptr->r_idx)
+                                       {
+                                               if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK))
+                                               {
+                                                       if (see_either)
+                                                       {
+                                                               msg_format(_("%^sは電撃を食らった!", "%^s gets zapped!"), m_name);
+                                                       }
+                                                       if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_ELEC;
+                                                       project(t_idx, 0, m_ptr->fy, m_ptr->fx,
+                                                               damroll(1 + ((tr_ptr->level) / 26),
+                                                                       1 + ((tr_ptr->level) / 17)),
+                                                               GF_ELEC, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                                               }
+                                               else
+                                               {
+                                                       if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               /* Monster missed player */
+               else
+               {
+                       /* Analyze failed attacks */
+                       switch (method)
+                       {
+                       case RBM_HIT:
+                       case RBM_TOUCH:
+                       case RBM_PUNCH:
+                       case RBM_KICK:
+                       case RBM_CLAW:
+                       case RBM_BITE:
+                       case RBM_STING:
+                       case RBM_SLASH:
+                       case RBM_BUTT:
+                       case RBM_CRUSH:
+                       case RBM_ENGULF:
+                       case RBM_CHARGE:
+                       {
+                               (void)set_monster_csleep(t_idx, 0);
+
+                               /* Visible monsters */
+                               if (see_m)
+                               {
+#ifdef JP
+                                       msg_format("%sは%^sの攻撃をかわした。", t_name, m_name);
+#else
+                                       msg_format("%^s misses %s.", m_name, t_name);
+#endif
+                               }
+
+                               break;
+                       }
+                       }
+               }
+
+
+               /* Analyze "visible" monsters only */
+               if (is_original_ap_and_seen(m_ptr) && !do_silly_attack)
+               {
+                       /* Count "obvious" attacks (and ones that cause damage) */
+                       if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10))
+                       {
+                               /* Count attacks of this type */
+                               if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR)
+                               {
+                                       r_ptr->r_blows[ap_cnt]++;
+                               }
+                       }
+               }
+       }
+
+       if (explode)
+       {
+               sound(SOUND_EXPLODE);
+
+               /* Cancel Invulnerability */
+               (void)set_monster_invulner(m_idx, 0, FALSE);
+               mon_take_hit_mon(m_idx, m_ptr->hp + 1, &dead, &fear, _("は爆発して粉々になった。", " explodes into tiny shreds."), m_idx);
+               blinked = FALSE;
+       }
+
+       /* Blink away */
+       if (blinked && m_ptr->r_idx)
+       {
+               if (teleport_barrier(m_idx))
+               {
+                       if (see_m)
+                       {
+                               msg_print(_("泥棒は笑って逃げ...ようとしたがバリアに防がれた。", "The thief flees laughing...? But magic barrier obstructs it."));
+                       }
+                       else if (known)
+                       {
+                               current_floor_ptr->monster_noise = TRUE;
+                       }
+               }
+               else
+               {
+                       if (see_m)
+                       {
+                               msg_print(_("泥棒は笑って逃げた!", "The thief flees laughing!"));
+                       }
+                       else if (known)
+                       {
+                               current_floor_ptr->monster_noise = TRUE;
+                       }
+
+                       teleport_away(m_idx, MAX_SIGHT * 2 + 5, 0L);
+               }
+       }
+
+       return TRUE;
+}
+
+
+
 /*!
  * @brief モンスターが敵モンスターに行う打撃処理 /
  * Hack, based on mon_take_hit... perhaps all monster attacks on other monsters should use this?
@@ -4128,7 +4766,6 @@ void mon_take_hit_mon(MONSTER_IDX m_idx, HIT_POINT dam, bool *dead, bool *fear,
        /* Can the player be aware of this attack? */
        bool known = (m_ptr->cdis <= MAX_SIGHT);
 
-       /* Extract monster name */
        monster_desc(m_name, m_ptr, 0);
 
        /* Redraw (later) if needed */
@@ -4176,7 +4813,7 @@ void mon_take_hit_mon(MONSTER_IDX m_idx, HIT_POINT dam, bool *dead, bool *fear,
        {
                if (((r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) ||
                        (r_ptr->flags7 & RF7_NAZGUL)) &&
-                       !p_ptr->inside_battle)
+                       !p_ptr->phase_out)
                {
                        m_ptr->hp = 1;
                }
@@ -4281,7 +4918,6 @@ void mon_take_hit_mon(MONSTER_IDX m_idx, HIT_POINT dam, bool *dead, bool *fear,
 
        if (p_ptr->riding && (p_ptr->riding == m_idx) && (dam > 0))
        {
-               /* Extract monster name */
                monster_desc(m_name, m_ptr, 0);
 
                if (m_ptr->hp > m_ptr->maxhp / 3) dam = (dam + 1) / 2;