OSDN Git Service

[Refactor] #38997 chg_virtue() に player_type * 引数を追加.
[hengband/hengband.git] / src / melee1.c
index fc62913..5eeeab2 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "angband.h"
+#include "core.h"
 #include "util.h"
 
 #include "artifact.h"
 #include "monster-spell.h"
 #include "avatar.h"
 #include "realm-hex.h"
+#include "realm-song.h"
 #include "object-flavor.h"
 #include "object-hook.h"
 #include "grid.h"
-#include "player-move.h"
 #include "dungeon.h"
 #include "floor.h"
 #include "dungeon.h"
 #include "spells.h"
 #include "files.h"
+#include "player-move.h"
 #include "player-effects.h"
 #include "player-skill.h"
 #include "player-damage.h"
 #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"
 
 
  /*!
+  * @brief モンスターの打撃効力テーブル /
+  * The table of monsters' blow effects
+  */
+const mbe_info_type mbe_info[] =
+{
+       {  0, 0,             }, /* None      */
+       { 60, GF_MISSILE,    }, /* HURT      */
+       {  5, GF_POIS,       }, /* POISON    */
+       { 20, GF_DISENCHANT, }, /* UN_BONUS  */
+       { 15, GF_MISSILE,    }, /* UN_POWER  */ /* ToDo: Apply the correct effects */
+       {  5, GF_MISSILE,    }, /* EAT_GOLD  */
+       {  5, GF_MISSILE,    }, /* EAT_ITEM  */
+       {  5, GF_MISSILE,    }, /* EAT_FOOD  */
+       {  5, GF_MISSILE,    }, /* EAT_LITE  */
+       {  0, GF_ACID,       }, /* ACID      */
+       { 10, GF_ELEC,       }, /* ELEC      */
+       { 10, GF_FIRE,       }, /* FIRE      */
+       { 10, GF_COLD,       }, /* COLD      */
+       {  2, GF_MISSILE,    }, /* BLIND     */
+       { 10, GF_CONFUSION,  }, /* CONFUSE   */
+       { 10, GF_MISSILE,    }, /* TERRIFY   */
+       {  2, GF_MISSILE,    }, /* PARALYZE  */
+       {  0, GF_MISSILE,    }, /* LOSE_STR  */
+       {  0, GF_MISSILE,    }, /* LOSE_INT  */
+       {  0, GF_MISSILE,    }, /* LOSE_WIS  */
+       {  0, GF_MISSILE,    }, /* LOSE_DEX  */
+       {  0, GF_MISSILE,    }, /* LOSE_CON  */
+       {  0, GF_MISSILE,    }, /* LOSE_CHR  */
+       {  2, GF_MISSILE,    }, /* LOSE_ALL  */
+       { 60, GF_ROCKET,     }, /* SHATTER   */
+       {  5, GF_MISSILE,    }, /* EXP_10    */
+       {  5, GF_MISSILE,    }, /* EXP_20    */
+       {  5, GF_MISSILE,    }, /* EXP_40    */
+       {  5, GF_MISSILE,    }, /* EXP_80    */
+       {  5, GF_POIS,       }, /* DISEASE   */
+       {  5, GF_TIME,       }, /* TIME      */
+       {  5, GF_MISSILE,    }, /* EXP_VAMP  */
+       {  5, GF_MANA,       }, /* DR_MANA   */
+       { 60, GF_MISSILE,    }, /* SUPERHURT */
+};
+
+ /*!
   * @brief 幻覚時の打撃記述テーブル / Weird melee attack types when hallucinating
   */
 #ifdef JP
@@ -281,6 +329,168 @@ const int monk_ave_damage[PY_MAX_LEVEL + 1][3] =
   {4486, 5636, 1702},
 };
 
+/*!
+ * 腕力による攻撃回数算定値テーブル
+ * Stat Table (STR) -- help index into the "blow" table
+ */
+const byte adj_str_blow[] =
+{
+       3       /* 3 */,
+       4       /* 4 */,
+       5       /* 5 */,
+       6       /* 6 */,
+       7       /* 7 */,
+       8       /* 8 */,
+       9       /* 9 */,
+       10      /* 10 */,
+       11      /* 11 */,
+       12      /* 12 */,
+       13      /* 13 */,
+       14      /* 14 */,
+       15      /* 15 */,
+       16      /* 16 */,
+       17      /* 17 */,
+       20 /* 18/00-18/09 */,
+       30 /* 18/10-18/19 */,
+       40 /* 18/20-18/29 */,
+       50 /* 18/30-18/39 */,
+       60 /* 18/40-18/49 */,
+       70 /* 18/50-18/59 */,
+       80 /* 18/60-18/69 */,
+       90 /* 18/70-18/79 */,
+       100 /* 18/80-18/89 */,
+       110 /* 18/90-18/99 */,
+       120 /* 18/100-18/109 */,
+       130 /* 18/110-18/119 */,
+       140 /* 18/120-18/129 */,
+       150 /* 18/130-18/139 */,
+       160 /* 18/140-18/149 */,
+       170 /* 18/150-18/159 */,
+       180 /* 18/160-18/169 */,
+       190 /* 18/170-18/179 */,
+       200 /* 18/180-18/189 */,
+       210 /* 18/190-18/199 */,
+       220 /* 18/200-18/209 */,
+       230 /* 18/210-18/219 */,
+       240 /* 18/220+ */
+};
+
+
+/*!
+ * 器用さによる攻撃回数インデックステーブル
+ * Stat Table (DEX) -- index into the "blow" table
+ */
+const byte adj_dex_blow[] =
+{
+       0       /* 3 */,
+       0       /* 4 */,
+       0       /* 5 */,
+       0       /* 6 */,
+       0       /* 7 */,
+       0       /* 8 */,
+       0       /* 9 */,
+       1       /* 10 */,
+       1       /* 11 */,
+       1       /* 12 */,
+       1       /* 13 */,
+       1       /* 14 */,
+       2       /* 15 */,
+       2       /* 16 */,
+       2       /* 17 */,
+       2       /* 18/00-18/09 */,
+       3       /* 18/10-18/19 */,
+       3       /* 18/20-18/29 */,
+       3       /* 18/30-18/39 */,
+       4       /* 18/40-18/49 */,
+       4       /* 18/50-18/59 */,
+       5       /* 18/60-18/69 */,
+       5       /* 18/70-18/79 */,
+       6       /* 18/80-18/89 */,
+       6       /* 18/90-18/99 */,
+       7       /* 18/100-18/109 */,
+       7       /* 18/110-18/119 */,
+       8       /* 18/120-18/129 */,
+       8       /* 18/130-18/139 */,
+       9      /* 18/140-18/149 */,
+       9      /* 18/150-18/159 */,
+       10      /* 18/160-18/169 */,
+       10      /* 18/170-18/179 */,
+       11      /* 18/180-18/189 */,
+       11      /* 18/190-18/199 */,
+       12      /* 18/200-18/209 */,
+       12      /* 18/210-18/219 */,
+       13      /* 18/220+ */
+};
+
+
+/*!
+ * @brief
+ * 腕力、器用さに応じた攻撃回数テーブル /
+ * This table is used to help calculate the number of blows the player can
+ * make in a single round of attacks (one player current_world_ptr->game_turn) with a normal weapon.
+ * @details
+ * <pre>
+ * This number ranges from a single blow/round for weak players to up to six
+ * blows/round for powerful warriors.
+ *
+ * Note that certain artifacts and ego-items give "bonus" blows/round.
+ *
+ * First, from the player class, we extract some values:
+ *
+ * Warrior       num = 6; mul = 5; div = MAX(70, weapon_weight);
+ * Berserker     num = 6; mul = 7; div = MAX(70, weapon_weight);
+ * Mage          num = 3; mul = 2; div = MAX(100, weapon_weight);
+ * Priest        num = 5; mul = 3; div = MAX(100, weapon_weight);
+ * Mindcrafter   num = 5; mul = 3; div = MAX(100, weapon_weight);
+ * Rogue         num = 5; mul = 3; div = MAX(40, weapon_weight);
+ * Ranger        num = 5; mul = 4; div = MAX(70, weapon_weight);
+ * Paladin       num = 5; mul = 4; div = MAX(70, weapon_weight);
+ * Weaponsmith   num = 5; mul = 5; div = MAX(150, weapon_weight);
+ * Warrior-Mage  num = 5; mul = 3; div = MAX(70, weapon_weight);
+ * Chaos Warrior num = 5; mul = 4; div = MAX(70, weapon_weight);
+ * Monk          num = 5; mul = 3; div = MAX(60, weapon_weight);
+ * Tourist       num = 4; mul = 3; div = MAX(100, weapon_weight);
+ * Imitator      num = 5; mul = 4; div = MAX(70, weapon_weight);
+ * Beastmaster   num = 5; mul = 3; div = MAX(70, weapon_weight);
+ * Cavalry(Ride) num = 5; mul = 4; div = MAX(70, weapon_weight);
+ * Cavalry(Walk) num = 5; mul = 3; div = MAX(100, weapon_weight);
+ * Sorcerer      num = 1; mul = 1; div = MAX(1, weapon_weight);
+ * Archer        num = 4; mul = 2; div = MAX(70, weapon_weight);
+ * Magic eater   num = 4; mul = 2; div = MAX(70, weapon_weight);
+ * ForceTrainer  num = 4; mul = 2; div = MAX(60, weapon_weight);
+ * Mirror Master num = 3; mul = 3; div = MAX(100, weapon_weight);
+ * Ninja         num = 4; mul = 1; div = MAX(20, weapon_weight);
+ *
+ * To get "P", we look up the relevant "adj_str_blow[]" (see above),
+ * multiply it by "mul", and then divide it by "div".
+ * Increase P by 1 if you wield a weapon two-handed.
+ * Decrease P by 1 if you are a Ninja.
+ *
+ * To get "D", we look up the relevant "adj_dex_blow[]" (see above),
+ *
+ * The player gets "blows_table[P][D]" blows/round, as shown below,
+ * up to a maximum of "num" blows/round, plus any "bonus" blows/round.
+ * </pre>
+ */
+const byte blows_table[12][12] =
+{
+       /* P/D */
+       /*      0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11+ */
+       /*      3   10   15  /10  /40  /60  /80 /100 /120 /140 /160 /180  */
+       /* 0 */{        1,   1,   1,   1,   1,   2,   2,   2,   2,   3,   3,   4 },
+       /* 1 */{        1,   1,   1,   2,   2,   2,   3,   3,   3,   4,   4,   4 },
+       /* 2 */{        1,   1,   2,   2,   3,   3,   4,   4,   4,   5,   5,   5 },
+       /* 3 */{        1,   1,   2,   3,   3,   4,   4,   4,   5,   5,   5,   5 },
+       /* 4 */{        1,   1,   2,   3,   3,   4,   4,   5,   5,   5,   5,   5 },
+       /* 5 */{        1,   1,   2,   3,   4,   4,   4,   5,   5,   5,   5,   6 },
+       /* 6 */{        1,   1,   2,   3,   4,   4,   4,   5,   5,   5,   5,   6 },
+       /* 7 */{        1,   2,   2,   3,   4,   4,   4,   5,   5,   5,   5,   6 },
+       /* 8 */{        1,   2,   3,   3,   4,   4,   4,   5,   5,   5,   6,   6 },
+       /* 9 */{        1,   2,   3,   4,   4,   4,   5,   5,   5,   5,   6,   6 },
+       /* 10*/{        2,   2,   3,   4,   4,   4,   5,   5,   5,   6,   6,   6 },
+       /*11+*/{        2,   2,   3,   4,   4,   4,   5,   5,   6,   6,   6,   6 },
+};
+
  /*!
  * @brief プレイヤーからモンスターへの打撃命中判定 /
  * Determine if the player "hits" a monster (normal combat).
@@ -799,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);
+}
 
-       /* Assume miss */
+/*!
+ * @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;
+
+       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);
 }
 
@@ -980,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" */
@@ -1070,7 +1290,7 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
        monster_race    *r_ptr = &r_info[m_ptr->r_idx];
 
        /* Access the weapon */
-       object_type     *o_ptr = &inventory[INVEN_RARM + hand];
+       object_type     *o_ptr = &p_ptr->inventory_list[INVEN_RARM + hand];
 
        GAME_TEXT m_name[MAX_NLEN];
 
@@ -1148,8 +1368,8 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
        {
                if ((r_ptr->level + 10) > p_ptr->lev)
                {
-                       OBJECT_TYPE_VALUE tval = inventory[INVEN_RARM + hand].tval - TV_WEAPON_BEGIN;
-                       OBJECT_SUBTYPE_VALUE sval = inventory[INVEN_RARM + hand].sval;
+                       OBJECT_TYPE_VALUE tval = p_ptr->inventory_list[INVEN_RARM + hand].tval - TV_WEAPON_BEGIN;
+                       OBJECT_SUBTYPE_VALUE sval = p_ptr->inventory_list[INVEN_RARM + hand].sval;
                        int now_exp = p_ptr->weapon_exp[tval][sval];
                        if (now_exp < s_info[p_ptr->pclass].w_max[tval][sval])
                        {
@@ -1167,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" */
@@ -1241,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)
                                {
@@ -1691,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! */
                                                }
                                        }
@@ -1928,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;
        }
 }
@@ -1971,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)
@@ -1979,14 +2197,13 @@ 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);
        }
 
        if ((r_ptr->flags1 & RF1_FEMALE) &&
                !(p_ptr->stun || p_ptr->confused || p_ptr->image || !m_ptr->ml))
        {
-               if ((inventory[INVEN_RARM].name1 == ART_ZANTETSU) || (inventory[INVEN_LARM].name1 == ART_ZANTETSU))
+               if ((p_ptr->inventory_list[INVEN_RARM].name1 == ART_ZANTETSU) || (p_ptr->inventory_list[INVEN_LARM].name1 == ART_ZANTETSU))
                {
                        msg_print(_("拙者、おなごは斬れぬ!", "I can not attack women!"));
                        return FALSE;
@@ -2004,24 +2221,24 @@ bool py_attack(POSITION y, POSITION x, COMBAT_OPTION_IDX mode)
                !(p_ptr->stun || p_ptr->confused || p_ptr->image ||
                        p_ptr->shero || !m_ptr->ml))
        {
-               if (inventory[INVEN_RARM].name1 == ART_STORMBRINGER) stormbringer = TRUE;
-               if (inventory[INVEN_LARM].name1 == ART_STORMBRINGER) stormbringer = TRUE;
+               if (p_ptr->inventory_list[INVEN_RARM].name1 == ART_STORMBRINGER) stormbringer = TRUE;
+               if (p_ptr->inventory_list[INVEN_LARM].name1 == ART_STORMBRINGER) stormbringer = TRUE;
                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
                        {
@@ -2048,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)
@@ -2097,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);
 
@@ -2126,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;
@@ -2600,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;
                                                }
@@ -2651,7 +2868,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                i = (INVENTORY_IDX)randint0(INVEN_PACK);
 
                                                /* Obtain the item */
-                                               o_ptr = &inventory[i];
+                                               o_ptr = &p_ptr->inventory_list[i];
                                                if (!o_ptr->k_idx) continue;
 
                                                /* Drain charged wands/staffs */
@@ -2731,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 */
@@ -2784,7 +3001,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                i = (INVENTORY_IDX)randint0(INVEN_PACK);
 
                                                /* Obtain the item */
-                                               o_ptr = &inventory[i];
+                                               o_ptr = &p_ptr->inventory_list[i];
                                                if (!o_ptr->k_idx) continue;
 
                                                /* Skip artifacts */
@@ -2797,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 */
@@ -2860,7 +3077,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                /* Pick an item from the pack */
                                                i = (INVENTORY_IDX)randint0(INVEN_PACK);
 
-                                               o_ptr = &inventory[i];
+                                               o_ptr = &p_ptr->inventory_list[i];
                                                if (!o_ptr->k_idx) continue;
 
                                                /* Skip non-food objects */
@@ -2889,7 +3106,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                case RBE_EAT_LITE:
                                {
                                        /* Access the lite */
-                                       o_ptr = &inventory[INVEN_LITE];
+                                       o_ptr = &p_ptr->inventory_list[INVEN_LITE];
                                        get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1);
 
                                        if (p_ptr->is_dead || CHECK_MULTISHADOW()) break;
@@ -2962,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("どうだッ!この血の目潰しはッ!");
@@ -2989,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;
                                                }
@@ -3024,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;
                                                }
@@ -3061,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;
                                                        }
@@ -3079,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;
                                }
@@ -3089,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;
                                }
@@ -3099,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;
                                }
@@ -3109,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;
                                }
@@ -3119,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;
                                }
@@ -3129,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;
                                }
@@ -3141,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;
                                }
@@ -3163,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;
@@ -3179,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;
                                }
 
@@ -3193,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;
                                }
 
@@ -3207,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;
                                }
 
@@ -3221,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;
                                }
 
@@ -3234,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;
                                                }
@@ -3245,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;
@@ -3265,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;
                                                        }
 
@@ -3329,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)
@@ -3416,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;
                                                }
@@ -3437,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;
                                                }
@@ -3485,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 */
@@ -3510,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)
@@ -3679,7 +3896,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                if (hex_spelling(HEX_SHADOW_CLOAK) && alive && !p_ptr->is_dead)
                                {
                                        HIT_POINT dam = 1;
-                                       object_type *o_armed_ptr = &inventory[INVEN_RARM];
+                                       object_type *o_armed_ptr = &p_ptr->inventory_list[INVEN_RARM];
 
                                        if (!(r_ptr->flagsr & RFR_RES_ALL || r_ptr->flagsr & RFR_RES_DARK))
                                        {
@@ -3690,7 +3907,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                }
 
                                                /* Cursed armor makes damages doubled */
-                                               o_armed_ptr = &inventory[INVEN_BODY];
+                                               o_armed_ptr = &p_ptr->inventory_list[INVEN_BODY];
                                                if ((o_armed_ptr->k_idx) && object_is_cursed(o_armed_ptr)) dam *= 2;
 
                                                /* Modify the damage */
@@ -3716,7 +3933,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                        /* Some cursed armours gives an extra effect */
                                                        for (j = 0; j < 4; j++)
                                                        {
-                                                               o_armed_ptr = &inventory[typ[j][0]];
+                                                               o_armed_ptr = &p_ptr->inventory_list[typ[j][0]];
                                                                if ((o_armed_ptr->k_idx) && object_is_cursed(o_armed_ptr) && object_is_armour(o_armed_ptr))
                                                                        project(0, 0, m_ptr->fy, m_ptr->fx, (p_ptr->lev * 2), typ[j][1], flg, -1);
                                                        }
@@ -3768,7 +3985,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                }
 
                                /* Gain shield experience */
-                               if (object_is_armour(&inventory[INVEN_RARM]) || object_is_armour(&inventory[INVEN_LARM]))
+                               if (object_is_armour(&p_ptr->inventory_list[INVEN_RARM]) || object_is_armour(&p_ptr->inventory_list[INVEN_LARM]))
                                {
                                        int cur = p_ptr->skill_exp[GINOU_SHIELD];
                                        int max = s_info[p_ptr->pclass].s_max[GINOU_SHIELD];
@@ -3847,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))
@@ -3891,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 */
@@ -3899,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?
@@ -3920,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 */
@@ -3968,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;
                }
@@ -3992,7 +4837,7 @@ void mon_take_hit_mon(MONSTER_IDX m_idx, HIT_POINT dam, bool *dead, bool *fear,
                                /* Unseen death by normal attack */
                                if (!seen)
                                {
-                                       mon_fight = TRUE;
+                                       current_floor_ptr->monster_noise = TRUE;
                                }
                                /* Death by special attack */
                                else if (note)
@@ -4073,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;