OSDN Git Service

character_xtra時でもプレイヤーの善悪を計算するようにした. 種族別で善
[hengband/hengband.git] / src / melee2.c
index 576e6b6..a1740a6 100644 (file)
@@ -97,7 +97,7 @@ static bool get_enemy_dir(int m_idx, int *mm)
                        /* Monster must be 'an enemy' */
                        if (!are_enemies(m_ptr, t_ptr)) continue;
 
-                       can_pass_wall = (((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall))) || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding)));
+                       can_pass_wall = (((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding)));
 
                        /* Monster must be projectable if we can't pass through walls */
                        if (!can_pass_wall &&
@@ -213,6 +213,8 @@ void mon_take_hit_mon(int m_idx, int dam, bool *fear, cptr note, int who)
        /* Wake it up */
        m_ptr->csleep = 0;
 
+       if (r_ptr->flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
+
        if (p_ptr->riding && (m_idx == p_ptr->riding)) disturb(1, 0);
 
        if (m_ptr->invulner && randint0(PENETRATE_INVULNERABILITY))
@@ -230,7 +232,7 @@ msg_format("%^s
                return;
        }
 
-       if (r_ptr->flags3 & RF3_RES_ALL)
+       if (r_ptr->flagsr & RFR_RES_ALL)
        {
                if(dam > 0)
                {
@@ -258,9 +260,8 @@ msg_format("%^s
        /* It is dead now... or is it? */
        if (m_ptr->hp < 0)
        {
-               if (((r_ptr->flags1 & RF1_UNIQUE) ||
-                       (r_ptr->flags7 & RF7_UNIQUE_7) ||
-                       (r_ptr->flags1 & RF1_QUESTOR)) &&
+               if (((r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) ||
+                   (r_ptr->flags7 & RF7_NAZGUL)) &&
                    !p_ptr->inside_battle)
                {
                        m_ptr->hp = 1;
@@ -548,7 +549,7 @@ static bool get_moves_aux2(int m_idx, int *yp, int *xp)
                cost = c_ptr->cost;
 
                /* Monster cannot kill or pass walls */
-               if (!(((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) || (r_ptr->flags2 & RF2_KILL_WALL)))
+               if (!(((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding))))
                {
                        if (cost == 0) continue;
                        if (!can_open_door && is_closed_door(c_ptr->feat)) continue;
@@ -622,9 +623,8 @@ static bool get_moves_aux(int m_idx, int *yp, int *xp, bool no_flow)
        if (no_flow) return (FALSE);
 
        /* Monster can go through rocks */
-       if ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall))) return (FALSE);
-       if (r_ptr->flags2 & RF2_KILL_WALL) return (FALSE);
-       if (!cave_floor_bold(py, px) && (cave[py][px].feat != FEAT_TREES)) return (FALSE);
+       if ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) return (FALSE);
+       if ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding)) return (FALSE);
 
        /* Monster location */
        y1 = m_ptr->fy;
@@ -1099,7 +1099,7 @@ static bool get_moves(int m_idx, int *mm)
        bool         will_run = mon_will_run(m_idx);
        cave_type    *c_ptr;
        bool         no_flow = ((m_ptr->mflag2 & MFLAG2_NOFLOW) && (cave[m_ptr->fy][m_ptr->fx].cost > 2));
-       bool         can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall)));
+       bool         can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall));
 
        /* Counter attack to an enemy monster */
        if (!will_run && m_ptr->target_y)
@@ -1143,8 +1143,7 @@ static bool get_moves(int m_idx, int *mm)
                                c_ptr = &cave[yy][xx];
 
                                /* Check grid */
-                               if (((cave_floor_grid(c_ptr)) || ((c_ptr->feat & 0x60) == 0x60)) &&
-                                        monster_can_cross_terrain(c_ptr->feat, r_ptr))
+                               if (monster_can_cross_terrain(c_ptr->feat, r_ptr, 0))
                                {
                                        /* One more room grid */
                                        room++;
@@ -1472,9 +1471,6 @@ static bool monst_attack_monst(int m_idx, int t_idx)
 
        if (d_info[dungeon_type].flags1 & DF1_NO_MELEE) return (FALSE);
 
-       /* Wake it up */
-       t_ptr->csleep = 0;
-
        /* Total armor */
        ac = tr_ptr->ac;
 
@@ -1535,6 +1531,11 @@ static bool monst_attack_monst(int m_idx, int t_idx)
                /* Monster hits */
                if (!effect || check_hit2(power, rlev, ac, m_ptr->stunned))
                {
+                       /* Wake it up */
+                       t_ptr->csleep = 0;
+
+                       if (tr_ptr->flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
+
                        /* Describe the attack method */
                        switch (method)
                        {
@@ -2010,7 +2011,7 @@ act = "%s
                                if (!explode)
                                {
                                        project(m_idx, 0, t_ptr->fy, t_ptr->fx,
-                                               (pt == GF_OLD_SLEEP ? r_ptr->level : damage), pt, PROJECT_KILL | PROJECT_STOP | PROJECT_MONSTER, -1);
+                                               (pt == GF_OLD_SLEEP ? r_ptr->level : damage), pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
                                }
 
                                if (heal_effect)
@@ -2045,74 +2046,85 @@ msg_format("%s
                                if (touched)
                                {
                                        /* Aura fire */
-                                       if ((tr_ptr->flags2 & RF2_AURA_FIRE) &&
-                                               !(r_ptr->flags3 & RF3_EFF_IM_FIRE_MASK) &&
-                                               m_ptr->r_idx)
+                                       if ((tr_ptr->flags2 & RF2_AURA_FIRE) && m_ptr->r_idx)
                                        {
-                                               if (see_either)
+                                               if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK))
                                                {
-                                                       blinked = FALSE;
+                                                       if (see_either)
+                                                       {
+                                                               blinked = FALSE;
 #ifdef JP
-msg_format("%^s¤ÏÆÍÁ³Ç®¤¯¤Ê¤Ã¤¿¡ª", m_name);
+                                                               msg_format("%^s¤ÏÆÍÁ³Ç®¤¯¤Ê¤Ã¤¿¡ª", m_name);
 #else
-                                                       msg_format("%^s is suddenly very hot!", m_name);
+                                                               msg_format("%^s is suddenly very hot!", m_name);
 #endif
 
-                                                       if (t_ptr->ml)
-                                                               tr_ptr->r_flags2 |= RF2_AURA_FIRE;
+                                                               if (see_t && is_original_ap(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 (see_m && is_original_ap(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
                                                }
-                                               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_MONSTER, -1);
                                        }
 
                                        /* Aura cold */
-                                       if ((tr_ptr->flags3 & RF3_AURA_COLD) &&
-                                               !(r_ptr->flags3 & RF3_EFF_IM_COLD_MASK) &&
-                                               m_ptr->r_idx)
+                                       if ((tr_ptr->flags3 & RF3_AURA_COLD) && m_ptr->r_idx)
                                        {
-                                               if (see_either)
+                                               if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK))
                                                {
-                                                       blinked = FALSE;
+                                                       if (see_either)
+                                                       {
+                                                               blinked = FALSE;
 #ifdef JP
-msg_format("%^s¤ÏÆÍÁ³´¨¤¯¤Ê¤Ã¤¿¡ª", m_name);
+                                                               msg_format("%^s¤ÏÆÍÁ³´¨¤¯¤Ê¤Ã¤¿¡ª", m_name);
 #else
-                                                       msg_format("%^s is suddenly very cold!", m_name);
+                                                               msg_format("%^s is suddenly very cold!", m_name);
 #endif
 
-                                                       if (t_ptr->ml)
-                                                               tr_ptr->r_flags3 |= RF3_AURA_COLD;
+                                                               if (see_t && is_original_ap(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 (see_m && is_original_ap(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
                                                }
-                                               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_MONSTER, -1);
                                        }
 
                                        /* Aura elec */
-                                       if ((tr_ptr->flags2 & RF2_AURA_ELEC) &&
-                                               !(r_ptr->flags3 & RF3_EFF_IM_ELEC_MASK) &&
-                                               m_ptr->r_idx)
+                                       if ((tr_ptr->flags2 & RF2_AURA_ELEC) && m_ptr->r_idx)
                                        {
-                                               if (see_either)
+                                               if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK))
                                                {
-                                                       blinked = FALSE;
+                                                       if (see_either)
+                                                       {
+                                                               blinked = FALSE;
 #ifdef JP
-msg_format("%^s¤ÏÅÅ·â¤ò¿©¤é¤Ã¤¿¡ª", m_name);
+                                                               msg_format("%^s¤ÏÅÅ·â¤ò¿©¤é¤Ã¤¿¡ª", m_name);
 #else
-                                                       msg_format("%^s gets zapped!", m_name);
+                                                               msg_format("%^s gets zapped!", m_name);
 #endif
 
-                                                       if (t_ptr->ml)
-                                                               tr_ptr->r_flags2 |= RF2_AURA_ELEC;
+                                                               if (see_t && is_original_ap(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 (see_m && is_original_ap(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
                                                }
-                                               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_MONSTER, -1);
                                        }
-
                                }
                        }
                }
@@ -2136,6 +2148,11 @@ msg_format("%^s
                        case RBM_ENGULF:
                        case RBM_CHARGE:
                                {
+                                       /* Wake it up */
+                                       t_ptr->csleep = 0;
+
+                                       if (tr_ptr->flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
+
                                        /* Visible monsters */
                                        if (see_m)
                                        {
@@ -2248,6 +2265,7 @@ static void process_monster(int m_idx)
        int             mm[8];
 
        cave_type       *c_ptr;
+       feature_type    *f_ptr;
 
        monster_type    *y_ptr;
 
@@ -2263,12 +2281,14 @@ static void process_monster(int m_idx)
        bool            did_pass_wall;
        bool            did_kill_wall;
        bool            gets_angry = FALSE;
-       bool            can_pass_wall;
+       bool            can_cross;
        bool            aware = TRUE;
 
        bool            fear;
 
-       if ((m_idx == p_ptr->riding) && !(r_ptr->flags7 & RF7_RIDING))
+       bool            is_riding_mon = (m_idx == p_ptr->riding);
+
+       if (is_riding_mon && !(r_ptr->flags7 & RF7_RIDING))
        {
                if (rakuba(0, TRUE))
                {
@@ -2299,6 +2319,31 @@ static void process_monster(int m_idx)
                if (randint0(tmp) > (r_ptr->level+20)) aware = FALSE;
        }
 
+       /* Are there its parent? */
+       if (m_ptr->parent_m_idx && !m_list[m_ptr->parent_m_idx].r_idx)
+       {
+               /* Its parent have gone, it also goes away. */
+
+               if (m_ptr->ml)
+               {
+                       char m_name[80];
+                       
+                       /* Acquire the monster name */
+                       monster_desc(m_name, m_ptr, 0);
+
+#ifdef JP
+                       msg_format("%s¤Ï¾Ã¤¨µî¤Ã¤¿¡ª", m_name);
+#else
+                       msg_format("%^s disappears!", m_name);
+#endif
+               }
+
+               /* Delete the monster */
+               delete_monster_idx(m_idx);
+
+               return;
+       }
+
        /* Quantum monsters are odd */
        if (r_ptr->flags2 & (RF2_QUANTUM))
        {
@@ -2356,7 +2401,7 @@ msg_print("
                mon_take_hit_mon(m_idx, 1, &fear, " explodes into tiny shreds.", m_idx);
 #endif
 
-       if ((is_pet(m_ptr) || is_friendly(m_ptr)) && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7)) && !p_ptr->inside_battle)
+       if ((is_pet(m_ptr) || is_friendly(m_ptr)) && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) && !p_ptr->inside_battle)
        {
                static int riding_pinch = 0;
 
@@ -2365,7 +2410,7 @@ msg_print("
                        char m_name[80];
                        monster_desc(m_name, m_ptr, 0);
 
-                       if (m_idx == p_ptr->riding && riding_pinch < 2)
+                       if (is_riding_mon && riding_pinch < 2)
                        {
 #ifdef JP
                                msg_format("%s¤Ï½ý¤ÎÄˤµ¤Î;¤ê¤¢¤Ê¤¿¤Î«Çû¤«¤éƨ¤ì¤è¤¦¤È¤·¤Æ¤¤¤ë¡£", m_name);
@@ -2377,7 +2422,7 @@ msg_print("
                        }
                        else
                        {
-                               if (m_idx == p_ptr->riding)
+                               if (is_riding_mon)
                                {
 #ifdef JP
                                        msg_format("%s¤Ï¤¢¤Ê¤¿¤Î«Çû¤«¤éæ½Ð¤·¤¿¡£", m_name);
@@ -2413,7 +2458,7 @@ msg_print("
 #endif
                                }
 
-                               if (m_idx == p_ptr->riding && rakuba(-1, FALSE))
+                               if (is_riding_mon && rakuba(-1, FALSE))
                                {
 #ifdef JP
                                        msg_print("ÃÏÌ̤ËÍî¤È¤µ¤ì¤¿¡£");
@@ -2433,12 +2478,49 @@ msg_print("
                else
                {
                        /* Reset the counter */
-                       if (m_idx == p_ptr->riding) riding_pinch = 0;
+                       if (is_riding_mon) riding_pinch = 0;
                }
        }
 
-       /* Handle "sleep" - Still sleeping */
-       if (m_ptr->csleep) return;
+       /* Handle "sleep" */
+       if (m_ptr->csleep)
+       {
+               /* Handle non-aggravation - Still sleeping */
+               if (!(p_ptr->cursed & TRC_AGGRAVATE)) return;
+
+               /* Handle aggravation */
+
+               /* Reset sleep counter */
+               m_ptr->csleep = 0;
+
+               if (r_ptr->flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
+
+               /* Notice the "waking up" */
+               if (m_ptr->ml)
+               {
+                       char m_name[80];
+
+                       /* Acquire the monster name */
+                       monster_desc(m_name, m_ptr, 0);
+
+                       /* Dump a message */
+#ifdef JP
+                       msg_format("%^s¤¬Ìܤò³Ð¤Þ¤·¤¿¡£", m_name);
+#else
+                       msg_format("%^s wakes up.", m_name);
+#endif
+
+                       /* Redraw the health bar */
+                       if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+                       if (is_riding_mon) p_ptr->redraw |= (PR_UHEALTH);
+
+                       /* Hack -- Count the wakings */
+                       if (r_ptr->r_wake < MAX_UCHAR)
+                       {
+                               r_ptr->r_wake++;
+                       }
+               }
+       }
 
        /* Handle "stun" */
        if (m_ptr->stunned)
@@ -2447,7 +2529,7 @@ msg_print("
                if (one_in_(2)) return;
        }
 
-       if (p_ptr->riding == m_idx)
+       if (is_riding_mon)
        {
                p_ptr->update |= (PU_BONUS);
        }
@@ -2458,12 +2540,11 @@ msg_print("
 
        /* Paranoia... no pet uniques outside wizard mode -- TY */
        if (is_pet(m_ptr) &&
-           ((((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7)) &&
-             ((p_ptr->align > 9 && (r_ptr->flags3 & RF3_EVIL)) ||
-             (p_ptr->align < -9 && (r_ptr->flags3 & RF3_GOOD))))
-            || (r_ptr->flags3 & RF3_RES_ALL)))
+           ((((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) &&
+             monster_has_hostile_align(NULL, 10, -10, r_ptr))
+            || (r_ptr->flagsr & RFR_RES_ALL)))
        {
-                       gets_angry = TRUE;
+               gets_angry = TRUE;
        }
 
        if (p_ptr->inside_battle) gets_angry = FALSE;
@@ -2510,7 +2591,7 @@ msg_format("%^s
                        if (multiply_monster(m_idx, FALSE, (is_pet(m_ptr) ? PM_FORCE_PET : 0)))
                        {
                                /* Take note if visible */
-                               if (m_ptr->ml)
+                               if (m_ptr->ml && m_list[hack_m_idx_ii].ml && is_original_ap(m_ptr))
                                {
                                        r_ptr->r_flags2 |= (RF2_MULTIPLY);
                                }
@@ -2543,7 +2624,7 @@ msg_format("%^s
                                                }
                                        }
 
-                                       if (count && m_ptr->ml) r_ptr->r_flags6 |= (RF6_SPECIAL);
+                                       if (count && m_ptr->ml && is_original_ap(m_ptr)) r_ptr->r_flags6 |= (RF6_SPECIAL);
                                }
                        }
                }
@@ -2669,8 +2750,6 @@ msg_format("%^s%s", m_name, monmessage);
                }
        }
 
-       can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall)));
-
        /* Hack -- Assume no movement */
        mm[0] = mm[1] = mm[2] = mm[3] = 0;
        mm[4] = mm[5] = mm[6] = mm[7] = 0;
@@ -2684,13 +2763,11 @@ msg_format("%^s%s", m_name, monmessage);
        }
 
        /* 75% random movement */
-       else if ((r_ptr->flags1 & RF1_RAND_50) &&
-                               (r_ptr->flags1 & RF1_RAND_25) &&
+       else if (((r_ptr->flags1 & (RF1_RAND_50 | RF1_RAND_25)) == (RF1_RAND_50 | RF1_RAND_25)) &&
                 (randint0(100) < 75))
        {
                /* Memorize flags */
-               if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_50);
-               if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_25);
+               if (m_ptr->ml && is_original_ap(m_ptr)) r_ptr->r_flags1 |= (RF1_RAND_50 | RF1_RAND_25);
 
                /* Try four "random" directions */
                mm[0] = mm[1] = mm[2] = mm[3] = 5;
@@ -2701,7 +2778,7 @@ msg_format("%^s%s", m_name, monmessage);
                                (randint0(100) < 50))
        {
                /* Memorize flags */
-               if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_50);
+               if (m_ptr->ml && is_original_ap(m_ptr)) r_ptr->r_flags1 |= (RF1_RAND_50);
 
                /* Try four "random" directions */
                mm[0] = mm[1] = mm[2] = mm[3] = 5;
@@ -2712,7 +2789,7 @@ msg_format("%^s%s", m_name, monmessage);
                                (randint0(100) < 25))
        {
                /* Memorize flags */
-               if (m_ptr->ml) r_ptr->r_flags1 |= RF1_RAND_25;
+               if (m_ptr->ml && is_original_ap(m_ptr)) r_ptr->r_flags1 |= RF1_RAND_25;
 
                /* Try four "random" directions */
                mm[0] = mm[1] = mm[2] = mm[3] = 5;
@@ -2819,19 +2896,14 @@ msg_format("%^s%s", m_name, monmessage);
 
                /* Access that cave grid */
                c_ptr = &cave[ny][nx];
+               f_ptr = &f_info[c_ptr->feat];
+               can_cross = monster_can_cross_terrain(c_ptr->feat, r_ptr, is_riding_mon ? CEM_RIDING : 0);
 
                /* Access that cave grid's contents */
                y_ptr = &m_list[c_ptr->m_idx];
 
-               /* Floor is open? */
-               if (cave_floor_grid(c_ptr))
-               {
-                       /* Go ahead and move */
-                       do_move = TRUE;
-               }
-
                /* Hack -- player 'in' wall */
-               else if (player_bold(ny, nx))
+               if (player_bold(ny, nx))
                {
                        do_move = TRUE;
                }
@@ -2842,79 +2914,54 @@ msg_format("%^s%s", m_name, monmessage);
                        do_move = TRUE;
                }
 
-               /* Permanent wall */
-               else if ((c_ptr->feat >= FEAT_PERM_EXTRA) &&
-                       (c_ptr->feat <= FEAT_PERM_SOLID))
-               {
-                       do_move = FALSE;
-               }
-
-               /* Hack -- semi-transparent terrains are no obstacle */
-               else if (c_ptr->feat == FEAT_TREES)
-               {
-                       do_move = TRUE;
-               }
-
-               /* Hack -- semi-transparent terrains are no obstacle */
-               else if ((c_ptr->feat == FEAT_MOUNTAIN) && ((r_ptr->flags2 & RF2_KILL_WALL) || (!dun_level && ((r_ptr->flags7 & RF7_CAN_FLY) || (r_ptr->flags8 & RF8_WILD_MOUNTAIN)))))
+               /* Floor is open? */
+               else if (can_cross)
                {
+                       /* Go ahead and move */
                        do_move = TRUE;
-               }
-
 
-               /* Monster moves through walls (and doors) */
-               else if (can_pass_wall)
-               {
-                       /* Pass through walls/doors/rubble */
-                       do_move = TRUE;
+                       /* Monster moves through walls (and doors) */
+                       if ((r_ptr->flags2 & RF2_PASS_WALL) && (!is_riding_mon || p_ptr->pass_wall) &&
+                           !have_flag(f_ptr->flags, FF_MOVE))
+                       {
+                               /* Monster went through a wall */
+                               did_pass_wall = TRUE;
+                       }
 
-                       /* Monster went through a wall */
-                       did_pass_wall = TRUE;
+                       if ((r_ptr->flags2 & RF2_KILL_WALL) && have_flag(f_ptr->flags, FF_TUNNEL) &&
+                           !have_flag(f_ptr->flags, FF_LOS) && !have_flag(f_ptr->flags, FF_PERMANENT))
+                       {
+                               /* Monster destroyed a wall (later) */
+                               did_kill_wall = TRUE;
+                       }
                }
 
                /* Monster destroys walls (and doors) */
-               else if ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding))
+               else if ((r_ptr->flags2 & RF2_KILL_WALL) && !is_riding_mon &&
+                        have_flag(f_ptr->flags, FF_TUNNEL) && !have_flag(f_ptr->flags, FF_PERMANENT))
                {
                        /* Eat through walls/doors/rubble */
                        do_move = TRUE;
 
-                       /* Monster destroyed a wall */
+                       /* Monster destroyed a wall (later) */
                        did_kill_wall = TRUE;
-
-                       if (one_in_(GRINDNOISE))
-                       {
-#ifdef JP
-msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£");
-#else
-                               msg_print("There is a grinding sound.");
-#endif
-
-                       }
-
-                       /* Forget the wall */
-                       c_ptr->info &= ~(CAVE_MARK);
-
-                       /* Notice */
-                       cave_set_feat(ny, nx, floor_type[randint0(100)]);
-
-                       /* Note changes to viewable region */
-                       if (player_has_los_bold(ny, nx)) do_view = TRUE;
                }
 
                /* Handle doors and secret doors */
                else if (is_closed_door(c_ptr->feat))
                {
                        bool may_bash = TRUE;
+                       feature_type *f_ptr = &f_info[c_ptr->feat];
 
                        /* Assume no move allowed */
                        do_move = FALSE;
 
                        /* Creature can open doors. */
-                       if ((r_ptr->flags2 & RF2_OPEN_DOOR) &&
+                       if ((r_ptr->flags2 & RF2_OPEN_DOOR) && have_flag(f_ptr->flags, FF_OPEN) &&
                                 (!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_OPEN_DOORS)))
                        {
                                /* Closed doors */
-                               if (c_ptr->feat == FEAT_DOOR_HEAD)
+                               if (!f_ptr->power)
                                {
                                        /* The door is open */
                                        did_open_door = TRUE;
@@ -2927,18 +2974,13 @@ msg_print("
                                }
 
                                /* Locked doors (not jammed) */
-                               else if (c_ptr->feat < FEAT_DOOR_HEAD + 0x08)
+                               else
                                {
-                                       int k;
-
-                                       /* Door power */
-                                       k = ((c_ptr->feat - FEAT_DOOR_HEAD) & 0x07);
-
                                        /* Try to unlock it XXX XXX XXX */
-                                       if (randint0(m_ptr->hp / 10) > k)
+                                       if (randint0(m_ptr->hp / 10) > f_ptr->power)
                                        {
                                                /* Unlock the door */
-                                               cave_set_feat(ny, nx, FEAT_DOOR_HEAD + 0x00);
+                                               cave_alter_feat(ny, nx, FF_OPEN);
 
                                                /* Do not bash the door */
                                                may_bash = FALSE;
@@ -2947,25 +2989,19 @@ msg_print("
                        }
 
                        /* Stuck doors -- attempt to bash them down if allowed */
-                       if (may_bash && (r_ptr->flags2 & RF2_BASH_DOOR) &&
+                       if (may_bash && (r_ptr->flags2 & RF2_BASH_DOOR) && have_flag(f_ptr->flags, FF_BASH) &&
                                (!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_OPEN_DOORS)))
                        {
-                               int k;
-
-                               /* Door power */
-                               k = ((c_ptr->feat - FEAT_DOOR_HEAD) & 0x07);
-
                                /* Attempt to Bash XXX XXX XXX */
-                               if (randint0(m_ptr->hp / 10) > k)
+                               if (randint0(m_ptr->hp / 10) > f_ptr->power)
                                {
                                        /* Message */
 #ifdef JP
-msg_print("¥É¥¢¤ò᤭³«¤±¤ë²»¤¬¤·¤¿¡ª");
+                                       msg_print("¥É¥¢¤ò᤭³«¤±¤ë²»¤¬¤·¤¿¡ª");
 #else
                                        msg_print("You hear a door burst open!");
 #endif
 
-
                                        /* Disturb (sometimes) */
                                        if (disturb_minor) disturb(0, 0);
 
@@ -2984,13 +3020,13 @@ msg_print("
                                /* Break down the door */
                                if (did_bash_door && (randint0(100) < 50))
                                {
-                                       cave_set_feat(ny, nx, FEAT_BROKEN);
+                                       cave_alter_feat(ny, nx, FF_BASH);
                                }
 
                                /* Open the door */
                                else
                                {
-                                       cave_set_feat(ny, nx, FEAT_OPEN);
+                                       cave_alter_feat(ny, nx, FF_OPEN);
                                }
 
                                /* Handle viewable doors */
@@ -3012,11 +3048,10 @@ msg_print("
                                if (c_ptr->info & CAVE_MARK)
                                {
 #ifdef JP
-msg_print("¼é¤ê¤Î¥ë¡¼¥ó¤¬²õ¤ì¤¿¡ª");
+                                       msg_print("¼é¤ê¤Î¥ë¡¼¥ó¤¬²õ¤ì¤¿¡ª");
 #else
                                        msg_print("The rune of protection is broken!");
 #endif
-
                                }
 
                                /* Forget the rune */
@@ -3049,7 +3084,7 @@ msg_print("
                                        if (c_ptr->info & CAVE_MARK)
                                        {
 #ifdef JP
-msg_print("¥ë¡¼¥ó¤¬Çúȯ¤·¤¿¡ª");
+                                               msg_print("¥ë¡¼¥ó¤¬Çúȯ¤·¤¿¡ª");
 #else
                                                msg_print("The rune explodes!");
 #endif
@@ -3060,7 +3095,7 @@ msg_print("
                                else
                                {
 #ifdef JP
-msg_print("Çúȯ¤Î¥ë¡¼¥ó¤Ï²ò½ü¤µ¤ì¤¿¡£");
+                                       msg_print("Çúȯ¤Î¥ë¡¼¥ó¤Ï²ò½ü¤µ¤ì¤¿¡£");
 #else
                                        msg_print("An explosive rune was disarmed.");
 #endif
@@ -3081,78 +3116,95 @@ msg_print("
                                do_move = TRUE;
                        }
                }
-               if (do_move && player_bold(ny, nx) && (d_info[dungeon_type].flags1 & DF1_NO_MELEE))
-               {
-                       do_move = FALSE;
-               }
-
-               /* Some monsters never attack */
-               if (do_move && player_bold(ny, nx) && (r_ptr->flags1 & RF1_NEVER_BLOW))
-               {
-                       /* Hack -- memorize lack of attacks */
-                       if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_NEVER_BLOW);
-
-                       /* Do not move */
-                       do_move = FALSE;
-               }
 
-               /* The player is in the way.  Attack him. */
+               /* The player is in the way */
                if (do_move && player_bold(ny, nx))
                {
-                       if (!p_ptr->riding || one_in_(2))
+                       /* Some monsters never attack */
+                       if (r_ptr->flags1 & RF1_NEVER_BLOW)
                        {
-                               /* Do the attack */
-                               (void)make_attack_normal(m_idx);
+                               /* Hack -- memorize lack of attacks */
+                               if (m_ptr->ml && is_original_ap(m_ptr)) r_ptr->r_flags1 |= (RF1_NEVER_BLOW);
 
                                /* Do not move */
                                do_move = FALSE;
+                       }
 
-                               /* Took a turn */
-                               do_turn = TRUE;
+                       /* In anti-melee dungeon, stupid or confused monster takes useless turn */
+                       if (do_move && (d_info[dungeon_type].flags1 & DF1_NO_MELEE))
+                       {
+                               if (!m_ptr->confused)
+                               {
+                                       if (!(r_ptr->flags2 & RF2_STUPID)) do_move = FALSE;
+                                       else
+                                       {
+                                               if (m_ptr->ml && is_original_ap(m_ptr)) r_ptr->r_flags2 |= (RF2_STUPID);
+                                       }
+                               }
                        }
-               }
 
-               if ((c_ptr->feat >= FEAT_PATTERN_START) &&
-                       (c_ptr->feat <= FEAT_PATTERN_XTRA2) &&
-                       !do_turn && !(r_ptr->flags7 & RF7_CAN_FLY))
-               {
-                       do_move = FALSE;
-               }
+                       /* The player is in the way.  Attack him. */
+                       if (do_move)
+                       {
+                               if (!p_ptr->riding || one_in_(2))
+                               {
+                                       /* Do the attack */
+                                       (void)make_attack_normal(m_idx);
 
+                                       /* Do not move */
+                                       do_move = FALSE;
+
+                                       /* Took a turn */
+                                       do_turn = TRUE;
+                               }
+                       }
+               }
 
                /* A monster is in the way */
                if (do_move && c_ptr->m_idx)
                {
                        monster_race *z_ptr = &r_info[y_ptr->r_idx];
-                       monster_type *m2_ptr = &m_list[c_ptr->m_idx];
 
                        /* Assume no movement */
                        do_move = FALSE;
 
                        /* Attack 'enemies' */
-                       if (((r_ptr->flags2 & (RF2_KILL_BODY)) &&
-                                 (r_ptr->mexp * r_ptr->level > z_ptr->mexp * z_ptr->level) &&
-                                 (cave_floor_grid(c_ptr)) &&
-                            (c_ptr->m_idx != p_ptr->riding)) ||
-                                are_enemies(m_ptr, m2_ptr) || m_ptr->confused)
+                       if (((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW) &&
+                                (r_ptr->mexp * r_ptr->level > z_ptr->mexp * z_ptr->level) &&
+                                can_cross && (c_ptr->m_idx != p_ptr->riding)) ||
+                               are_enemies(m_ptr, y_ptr) || m_ptr->confused)
                        {
-                               do_move = FALSE;
+                               if (!(r_ptr->flags1 & RF1_NEVER_BLOW))
+                               {
+                                       if (r_ptr->flags2 & RF2_KILL_BODY)
+                                       {
+                                               if (is_original_ap(m_ptr)) r_ptr->r_flags2 |= (RF2_KILL_BODY);
+                                       }
 
-                               if (r_ptr->flags2 & RF2_KILL_BODY) r_ptr->r_flags2 |= (RF2_KILL_BODY);
+                                       /* attack */
+                                       if (y_ptr->r_idx && (y_ptr->hp >= 0))
+                                       {
+                                               if (monst_attack_monst(m_idx, c_ptr->m_idx)) return;
 
-                               /* attack */
-                               if ((m2_ptr->r_idx) && (m2_ptr->hp >= 0))
-                               {
-                                       if (monst_attack_monst(m_idx, cave[ny][nx].m_idx))
-                                       return;
+                                               /* In anti-melee dungeon, stupid or confused monster takes useless turn */
+                                               else if (d_info[dungeon_type].flags1 & DF1_NO_MELEE)
+                                               {
+                                                       if (m_ptr->confused) return;
+                                                       else if (r_ptr->flags2 & RF2_STUPID)
+                                                       {
+                                                               if (m_ptr->ml && is_original_ap(m_ptr)) r_ptr->r_flags2 |= (RF2_STUPID);
+                                                               return;
+                                                       }
+                                               }
+                                       }
                                }
                        }
 
                        /* Push past weaker monsters (unless leaving a wall) */
                        else if ((r_ptr->flags2 & RF2_MOVE_BODY) &&
-                               (r_ptr->mexp > z_ptr->mexp) && cave_floor_grid(c_ptr) &&
-                               (cave_floor_grid(&cave[m_ptr->fy][m_ptr->fx])) &&
-                                (c_ptr->m_idx != p_ptr->riding))
+                               (r_ptr->mexp > z_ptr->mexp) &&
+                               can_cross && (c_ptr->m_idx != p_ptr->riding) &&
+                               monster_can_cross_terrain(cave[m_ptr->fy][m_ptr->fx].feat, z_ptr, 0))
                        {
                                /* Allow movement */
                                do_move = TRUE;
@@ -3170,7 +3222,7 @@ msg_print("
                 * to allow monsters to attack an enemy,
                 * even if it can't enter the terrain.
                 */
-               if (do_move && !monster_can_cross_terrain(c_ptr->feat, r_ptr))
+               if (do_move && !can_cross && !did_kill_wall)
                {
                        /* Assume no move allowed */
                        do_move = FALSE;
@@ -3180,13 +3232,13 @@ msg_print("
                if (do_move && (r_ptr->flags1 & RF1_NEVER_MOVE))
                {
                        /* Hack -- memorize lack of attacks */
-                       if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_NEVER_MOVE);
+                       if (m_ptr->ml && is_original_ap(m_ptr)) r_ptr->r_flags1 |= (RF1_NEVER_MOVE);
 
                        /* Do not move */
                        do_move = FALSE;
                }
 
-               if (m_idx == p_ptr->riding)
+               if (is_riding_mon)
                {
                        if (!p_ptr->riding_ryoute && !(m_list[p_ptr->riding].monfear)) do_move = FALSE;
                }
@@ -3202,14 +3254,25 @@ msg_print("
                        /* Hack -- Update the old location */
                        cave[oy][ox].m_idx = c_ptr->m_idx;
 
-                       if (cave[ny][nx].feat == FEAT_TREES)
+                       if (did_kill_wall)
                        {
-                               if (r_ptr->flags2 & RF2_KILL_WALL)
+                               if (one_in_(GRINDNOISE))
                                {
-                                       cave_set_feat(ny, nx, FEAT_GRASS);
-
+#ifdef JP
+                                       msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£");
+#else
+                                       msg_print("There is a grinding sound.");
+#endif
                                }
-                               if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD))
+
+                               cave_alter_feat(ny, nx, FF_HURT_DISI);
+
+                               /* Note changes to viewable region */
+                               if (player_has_los_bold(ny, nx)) do_view = TRUE;
+                       }
+                       else if (have_flag(f_ptr->flags, FF_TREE))
+                       {
+                               if (!(r_ptr->flags7 & RF7_CAN_FLY) && (!is_riding_mon || !p_ptr->ffall) && !(r_ptr->flags8 & RF8_WILD_WOOD))
                                {
                                        m_ptr->energy_need += ENERGY_NEED();
                                }
@@ -3226,7 +3289,10 @@ msg_print("
                                update_mon(c_ptr->m_idx, TRUE);
 
                                /* Wake up the moved monster */
-                               m_list[c_ptr->m_idx].csleep = 0;
+                               y_ptr->csleep = 0;
+
+                               if (r_info[y_ptr->r_idx].flags7 & (RF7_LITE_MASK | RF7_DARK_MASK))
+                                       p_ptr->update |= (PU_MON_LITE);
                        }
 
                        /* Hack -- Update the new location */
@@ -3239,7 +3305,7 @@ msg_print("
                        /* Update the monster */
                        update_mon(m_idx, TRUE);
 
-                       if (p_ptr->riding == m_idx)
+                       if (is_riding_mon)
                        {
                                py = ny;
                                px = nx;
@@ -3251,7 +3317,7 @@ msg_print("
                        /* Redraw the new grid */
                        lite_spot(ny, nx);
 
-                       if (p_ptr->riding == m_idx)
+                       if (is_riding_mon)
                        {
                                verify_panel();
 
@@ -3314,7 +3380,7 @@ msg_print("
                                        object_flags(o_ptr, flgs);
 
                                        /* Acquire the object name */
-                                       object_desc(o_name, o_ptr, TRUE, 3);
+                                       object_desc(o_name, o_ptr, 0);
 
                                        /* Acquire the monster name */
                                        monster_desc(m_name, m_ptr, MD_INDEF_HIDDEN);
@@ -3354,9 +3420,9 @@ msg_print("
                                                        {
                                                                /* Dump a message */
 #ifdef JP
-msg_format("%^s¤Ï%s¤ò½¦¤ª¤¦¤È¤·¤¿¤¬¡¢¤À¤á¤À¤Ã¤¿¡£", m_name, o_name);
+                                                               msg_format("%^s¤Ï%s¤ò½¦¤ª¤¦¤È¤·¤¿¤¬¡¢¤À¤á¤À¤Ã¤¿¡£", m_name, o_name);
 #else
-msg_format("%^s tries to pick up %s, but fails.", m_name, o_name);
+                                                               msg_format("%^s tries to pick up %s, but fails.", m_name, o_name);
 #endif
                                                        }
                                                }
@@ -3373,11 +3439,10 @@ msg_format("%^s tries to pick up %s, but fails.", m_name, o_name);
                                                {
                                                        /* Dump a message */
 #ifdef JP
-msg_format("%^s¤¬%s¤ò½¦¤Ã¤¿¡£", m_name, o_name);
+                                                       msg_format("%^s¤¬%s¤ò½¦¤Ã¤¿¡£", m_name, o_name);
 #else
                                                        msg_format("%^s picks up %s.", m_name, o_name);
 #endif
-
                                                }
 
                                                /* Excise the object */
@@ -3410,11 +3475,10 @@ msg_format("%^s
                                                {
                                                        /* Dump a message */
 #ifdef JP
-msg_format("%^s¤¬%s¤òÇ˲õ¤·¤¿¡£", m_name, o_name);
+                                                       msg_format("%^s¤¬%s¤òÇ˲õ¤·¤¿¡£", m_name, o_name);
 #else
                                                        msg_format("%^s destroys %s.", m_name, o_name);
 #endif
-
                                                }
 
                                                /* Delete the object */
@@ -3436,7 +3500,7 @@ msg_format("%^s
                m_ptr->mflag2 &= ~MFLAG2_NOFLOW;
 
        /* If we haven't done anything, try casting a spell again */
-       if (!do_turn && !do_move && !m_ptr->monfear && !(p_ptr->riding == m_idx) && aware)
+       if (!do_turn && !do_move && !m_ptr->monfear && !is_riding_mon && aware)
        {
                /* Try to cast spell again */
                if (r_ptr->freq_spell && randint1(100) <= r_ptr->freq_spell)
@@ -3457,14 +3521,15 @@ msg_format("%^s
        }
 
        /* Notice changes in view */
-       if (do_move && ((r_ptr->flags7 & (RF7_SELF_LITE_1 | RF7_SELF_LITE_2)) || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !p_ptr->inside_battle)))
+       if (do_move && ((r_ptr->flags7 & (RF7_SELF_LD_MASK | RF7_HAS_DARK_1 | RF7_HAS_DARK_2))
+               || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !p_ptr->inside_battle)))
        {
                /* Update some things */
                p_ptr->update |= (PU_MON_LITE);
        }
 
        /* Learn things from observable monster */
-       if (m_ptr->ml)
+       if (m_ptr->ml && is_original_ap(m_ptr))
        {
                /* Monster opened a door */
                if (did_open_door) r_ptr->r_flags2 |= (RF2_OPEN_DOOR);
@@ -3570,6 +3635,7 @@ void process_monsters(void)
        u32b    old_r_flags4 = 0L;
        u32b    old_r_flags5 = 0L;
        u32b    old_r_flags6 = 0L;
+       u32b    old_r_flagsr = 0L;
 
        byte    old_r_blows0 = 0;
        byte    old_r_blows1 = 0;
@@ -3599,6 +3665,7 @@ void process_monsters(void)
                old_r_flags4 = r_ptr->r_flags4;
                old_r_flags5 = r_ptr->r_flags5;
                old_r_flags6 = r_ptr->r_flags6;
+               old_r_flagsr = r_ptr->r_flagsr;
 
                /* Memorize blows */
                old_r_blows0 = r_ptr->r_blows[0];
@@ -3673,7 +3740,7 @@ void process_monsters(void)
                /* Hack -- Monsters can "smell" the player from far away */
                /* Note that most monsters have "aaf" of "20" or so */
                else if (!(m_ptr->mflag2 & MFLAG2_NOFLOW) &&
-                       (cave_floor_bold(py, px) || (cave[py][px].feat == FEAT_TREES)) &&
+                       have_flag(f_flags_bold(py, px), FF_MOVE) &&
                        (cave[py][px].when == cave[fy][fx].when) &&
                        (cave[fy][fx].dist < MONSTER_FLOW_DEPTH) &&
                        (cave[fy][fx].dist < r_ptr->aaf))
@@ -3747,6 +3814,7 @@ void process_monsters(void)
                        (old_r_flags4 != r_ptr->r_flags4) ||
                        (old_r_flags5 != r_ptr->r_flags5) ||
                        (old_r_flags6 != r_ptr->r_flags6) ||
+                       (old_r_flagsr != r_ptr->r_flagsr) ||
                        (old_r_blows0 != r_ptr->r_blows[0]) ||
                        (old_r_blows1 != r_ptr->r_blows[1]) ||
                        (old_r_blows2 != r_ptr->r_blows[2]) ||
@@ -3789,14 +3857,15 @@ bool process_the_world(int num, int who, bool vs_player)
                msg_print(NULL);
        }
 
-       world_monster = TRUE;
+       /* This monster cast spells */
+       world_monster = hack_m_idx;
 
        if (vs_player) do_cmd_redraw();
 
        while(num--)
        {
                if(!m_ptr->r_idx) break;
-               process_monster(hack_m_idx);
+               process_monster(world_monster);
 
                reset_target(m_ptr);
 
@@ -3825,7 +3894,7 @@ bool process_the_world(int num, int who, bool vs_player)
        /* Window stuff */
        p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
 
-       world_monster = FALSE;
+       world_monster = 0;
        if (vs_player || los(py, px, m_ptr->fy, m_ptr->fx))
        {
 #ifdef JP
@@ -3867,10 +3936,18 @@ void monster_gain_exp(int m_idx, int s_idx)
                int old_r_idx = m_ptr->r_idx;
                byte old_sub_align = m_ptr->sub_align;
 
+               /* Hack -- Reduce the racial counter of previous monster */
+               real_r_ptr(m_ptr)->cur_num--;
+
                monster_desc(m_name, m_ptr, 0);
                m_ptr->r_idx = r_ptr->next_r_idx;
+
+               /* Count the monsters on the level */
+               real_r_ptr(m_ptr)->cur_num++;
+
                m_ptr->ap_r_idx = m_ptr->r_idx;
                r_ptr = &r_info[m_ptr->r_idx];
+
                if (r_ptr->flags1 & RF1_FORCE_MAXHP)
                {
                        m_ptr->max_maxhp = maxroll(r_ptr->hdice, r_ptr->hside);
@@ -3911,6 +3988,9 @@ void monster_gain_exp(int m_idx, int s_idx)
                        msg_format("%^s evolved into %s.", m_name, r_name + r_ptr->name);
 #endif
                        r_info[old_r_idx].r_xtra1 |= MR1_SINKA;
+
+                       /* Now you feel very close to this pet. */
+                       m_ptr->parent_m_idx = 0;
                }
                update_mon(m_idx, FALSE);
                lite_spot(m_ptr->fy, m_ptr->fx);