OSDN Git Service

一般形のナズグルに与えられるフラグUNIQUE_7をNAZGULと置き換えた. この
[hengbandforosx/hengbandosx.git] / src / melee2.c
index 42a2912..a9c36f1 100644 (file)
@@ -1,14 +1,14 @@
 /* File: melee2.c */
 
-/* Purpose: Monster spells and movement */
-
 /*
-* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
-*
-* This software may be copied and distributed for educational, research, and
-* not for profit purposes provided that this copyright and statement are
-* included in all such copies.
-*/
+ * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
+ *
+ * This software may be copied and distributed for educational, research,
+ * and not for profit purposes provided that this copyright and statement
+ * are included in all such copies.  Other copyrights may also apply.
+ */
+
+/* Purpose: Monster spells and movement */
 
 /*
 * This file has several additions to it by Keldon Jones (keldon@umr.edu)
@@ -21,8 +21,6 @@
 #define GRINDNOISE 20
 #define CYBERNOISE 20
 
-extern cptr silly_attacks[MAX_SILLY_ATTACK];
-
 /*
  * Calculate the direction to the next enemy
  */
@@ -39,7 +37,7 @@ static bool get_enemy_dir(int m_idx, int *mm)
 
        monster_type *t_ptr;
 
-       if (riding_t_m_idx && (m_ptr->fx == px) && (m_ptr->fy == py))
+       if (riding_t_m_idx && player_bold(m_ptr->fy, m_ptr->fx))
        {
                y = m_list[riding_t_m_idx].fy;
                x = m_list[riding_t_m_idx].fx;
@@ -53,8 +51,8 @@ static bool get_enemy_dir(int m_idx, int *mm)
        {
                if (p_ptr->inside_battle)
                {
-                       start = randint(m_max-1)+m_max;
-                       if(rand_int(2)) plus = -1;
+                       start = randint1(m_max-1)+m_max;
+                       if(randint0(2)) plus = -1;
                }
                else start = m_max + 1;
 
@@ -192,7 +190,7 @@ static bool get_enemy_dir(int m_idx, int *mm)
  * Hack, based on mon_take_hit... perhaps all monster attacks on
  * other monsters should use this?
  */
-void mon_take_hit_mon(bool is_psy_spear, int m_idx, int dam, bool *fear, cptr note, int who)
+void mon_take_hit_mon(int m_idx, int dam, bool *fear, cptr note, int who)
 {
        monster_type    *m_ptr = &m_list[m_idx];
 
@@ -215,9 +213,11 @@ void mon_take_hit_mon(bool is_psy_spear, int m_idx, int dam, bool *fear, cptr no
        /* 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 && rand_int(PENETRATE_INVULNERABILITY))
+       if (m_ptr->invulner && randint0(PENETRATE_INVULNERABILITY))
        {
                if (seen)
                {
@@ -232,12 +232,12 @@ msg_format("%^s
                return;
        }
 
-       if (r_ptr->flags3 & RF3_RES_ALL)
+       if (r_ptr->flagsr & RFR_RES_ALL)
        {
                if(dam > 0)
                {
                        dam /= 100;
-                       if((dam == 0) && (randint(3) == 1)) dam = 1;
+                       if((dam == 0) && one_in_(3)) dam = 1;
                }
                if (dam==0)
                {
@@ -260,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;
@@ -281,7 +280,7 @@ msg_format("%^s
 
                        if (known)
                        {
-                               monster_desc(m_name, m_ptr, 0x100);
+                               monster_desc(m_name, m_ptr, MD_TRUE_NAME);
                                /* Unseen death by normal attack */
                                if (!seen)
                                {
@@ -340,7 +339,7 @@ msg_format("%^s
        /* Mega-Hack -- Pain cancels fear */
        if (m_ptr->monfear && (dam > 0))
        {
-               int tmp = randint(dam / 4);
+               int tmp = randint1(dam / 4);
 
                /* Cure a little fear */
                if (tmp < m_ptr->monfear)
@@ -372,14 +371,14 @@ msg_format("%^s
                * Run (sometimes) if at 10% or less of max hit points,
                * or (usually) when hit for half its current hit points
                 */
-               if (((percentage <= 10) && (rand_int(10) < percentage)) ||
-                       ((dam >= m_ptr->hp) && (rand_int(100) < 80)))
+               if (((percentage <= 10) && (randint0(10) < percentage)) ||
+                       ((dam >= m_ptr->hp) && (randint0(100) < 80)))
                {
                        /* Hack -- note fear */
                        (*fear) = TRUE;
 
                        /* XXX XXX XXX Hack -- Add some timed fear */
-                       m_ptr->monfear += (randint(10) +
+                       m_ptr->monfear += (randint1(10) +
                                (((dam >= m_ptr->hp) && (percentage > 7)) ?
                                20 : ((11 - percentage) * 5)));
                }
@@ -389,10 +388,9 @@ msg_format("%^s
 
        if ((dam > 0) && !is_pet(m_ptr) && !is_friendly(m_ptr) && (who != m_idx))
        {
-               if (is_pet(&m_list[who]) && (m_ptr->target_y != py) && (m_ptr->target_x != px))
+               if (is_pet(&m_list[who]) && !player_bold(m_ptr->target_y, m_ptr->target_x))
                {
-                       m_ptr->target_y = m_list[who].fy;
-                       m_ptr->target_x = m_list[who].fx;
+                       set_target(m_ptr, m_list[who].fy, m_list[who].fx);
                }
        }
 
@@ -501,6 +499,86 @@ static int mon_will_run(int m_idx)
 
 
 /*
+ * Search spell castable grid
+ */
+static bool get_moves_aux2(int m_idx, int *yp, int *xp)
+{
+       int i, y, x, y1, x1, best = 999;
+
+       cave_type *c_ptr;
+       bool can_open_door = FALSE;
+       int now_cost;
+
+       monster_type *m_ptr = &m_list[m_idx];
+       monster_race *r_ptr = &r_info[m_ptr->r_idx];
+
+       /* Monster location */
+       y1 = m_ptr->fy;
+       x1 = m_ptr->fx;
+
+       /* Monster can already cast spell to player */
+       if (projectable(y1, x1, py, px)) return (FALSE);
+
+       /* Set current grid cost */
+       now_cost = cave[y1][x1].cost;
+       if (now_cost == 0) now_cost = 999;
+
+       /* Can monster bash or open doors? */
+       if (r_ptr->flags2 & (RF2_BASH_DOOR | RF2_OPEN_DOOR))
+       {
+               can_open_door = TRUE;
+       }
+
+       /* Check nearby grids, diagonals first */
+       for (i = 7; i >= 0; i--)
+       {
+               int cost;
+
+               /* Get the location */
+               y = y1 + ddy_ddd[i];
+               x = x1 + ddx_ddd[i];
+
+               /* Ignore locations off of edge */
+               if (!in_bounds2(y, x)) continue;
+
+               /* Simply move to player */
+               if (player_bold(y, x)) return (FALSE);
+
+               c_ptr = &cave[y][x];
+
+               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 (cost == 0) continue;
+                       if (!can_open_door && is_closed_door(c_ptr->feat)) continue;
+               }
+
+               /* Hack -- for kill or pass wall monster.. */
+               if (cost == 0) cost = 998;
+
+               if (now_cost < cost) continue;
+
+               if (!projectable(y, x, py, px)) continue;
+
+               /* Accept louder sounds */
+               if (best < cost) continue;
+               best = cost;
+
+               (*yp) = y1 + ddy_ddd[i];
+               (*xp) = x1 + ddx_ddd[i];
+       }
+
+       /* No legal move (?) */
+       if (best == 999) return (FALSE);
+
+       /* Success */
+       return (TRUE);
+}
+
+
+/*
  * Choose the "best" direction for "flowing"
  *
  * Note that ghosts and rock-eaters are never allowed to "flow",
@@ -522,17 +600,27 @@ static int mon_will_run(int m_idx)
  * being close enough to chase directly.  I have no idea what will
  * happen if you combine "smell" with low "aaf" values.
  */
-static bool get_moves_aux(int m_idx, int *yp, int *xp)
+static bool get_moves_aux(int m_idx, int *yp, int *xp, bool no_flow)
 {
-       int i, y, x, y1, x1, when = 0, cost = 999;
+       int i, y, x, y1, x1, best;
 
        cave_type *c_ptr;
+       bool use_scent = FALSE;
 
        monster_type *m_ptr = &m_list[m_idx];
        monster_race *r_ptr = &r_info[m_ptr->r_idx];
 
-       /* Monster flowing disabled */
-       if (stupid_monsters) return (FALSE);
+       /* Can monster cast attack spell? */
+       if (r_ptr->flags4 & (RF4_ATTACK_MASK) ||
+           r_ptr->flags5 & (RF5_ATTACK_MASK) ||
+           r_ptr->flags6 & (RF6_ATTACK_MASK))
+       {
+               /* Can move spell castable grid? */
+               if (get_moves_aux2(m_idx, yp, xp)) return (TRUE);
+       }
+
+       /* Monster can't 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);
@@ -543,27 +631,37 @@ static bool get_moves_aux(int m_idx, int *yp, int *xp)
        y1 = m_ptr->fy;
        x1 = m_ptr->fx;
 
+       /* Hack -- Player can see us, run towards him */
+       if (player_has_los_bold(y1, x1)) return (FALSE);
+
        /* Monster grid */
        c_ptr = &cave[y1][x1];
 
-       /* The player is not currently near the monster grid */
-       if (c_ptr->when < cave[py][px].when)
+       /* If we can hear noises, advance towards them */
+       if (c_ptr->cost)
        {
-               /* The player has never been near the monster grid */
-               if (!c_ptr->when) return (FALSE);
+               best = 999;
        }
 
-       if (c_ptr->dist > MONSTER_FLOW_DEPTH) return (FALSE);
-       if ((c_ptr->dist > r_ptr->aaf) && !m_ptr->target_y) return (FALSE);
+       /* Otherwise, try to follow a scent trail */
+       else if (c_ptr->when)
+       {
+               /* Too old smell */
+               if (cave[py][px].when - c_ptr->when > 127) return (FALSE);
 
-       /* Hack -- Player can see us, run towards him */
-       if (player_has_los_bold(y1, x1)) return (FALSE);
+               use_scent = TRUE;
+               best = 0;
+       }
+
+       /* Otherwise, advance blindly */
+       else
+       {
+               return (FALSE);
+       }
 
        /* Check nearby grids, diagonals first */
        for (i = 7; i >= 0; i--)
        {
-               int value;
-
                /* Get the location */
                y = y1 + ddy_ddd[i];
                x = x1 + ddx_ddd[i];
@@ -573,22 +671,29 @@ static bool get_moves_aux(int m_idx, int *yp, int *xp)
 
                c_ptr = &cave[y][x];
 
-               /* Ignore illegal locations */
-               if (!c_ptr->when) continue;
+               /* We're following a scent trail */
+               if (use_scent)
+               {
+                       int when = c_ptr->when;
 
-               /* Ignore ancient locations */
-               if (c_ptr->when < when) continue;
+                       /* Accept younger scent */
+                       if (best > when) continue;
+                       best = when;
+               }
 
-               if (r_ptr->flags2 & (RF2_BASH_DOOR | RF2_OPEN_DOOR))
-                       value = c_ptr->dist;
-               else value = c_ptr->cost;
+               /* We're using sound */
+               else
+               {
+                       int cost;
 
-               /* Ignore distant locations */
-               if (value > cost) continue;
+                       if (r_ptr->flags2 & (RF2_BASH_DOOR | RF2_OPEN_DOOR))
+                               cost = c_ptr->dist;
+                       else cost = c_ptr->cost;
 
-               /* Save the cost and time */
-               when = c_ptr->when;
-               cost = value;
+                       /* Accept louder sounds */
+                       if ((cost == 0) || (best < cost)) continue;
+                       best = cost;
+               }
 
                /* Hack -- Save the "twiddled" location */
                (*yp) = py + 16 * ddy_ddd[i];
@@ -596,7 +701,7 @@ static bool get_moves_aux(int m_idx, int *yp, int *xp)
        }
 
        /* No legal move (?) */
-       if (!when) return (FALSE);
+       if (best == 999 || best == 0) return (FALSE);
 
        /* Success */
        return (TRUE);
@@ -613,14 +718,10 @@ static bool get_moves_aux(int m_idx, int *yp, int *xp)
 static bool get_fear_moves_aux(int m_idx, int *yp, int *xp)
 {
        int y, x, y1, x1, fy, fx, gy = 0, gx = 0;
-       int when = 0, score = -1;
+       int score = -1;
        int i;
 
        monster_type *m_ptr = &m_list[m_idx];
-       monster_race *r_ptr = &r_info[m_ptr->r_idx];
-
-       /* Monster flowing disabled */
-       if (stupid_monsters) return (FALSE);
 
        /* Monster location */
        fy = m_ptr->fy;
@@ -630,17 +731,6 @@ static bool get_fear_moves_aux(int m_idx, int *yp, int *xp)
        y1 = fy - (*yp);
        x1 = fx - (*xp);
 
-       /* The player is not currently near the monster grid */
-       if (cave[fy][fx].when < cave[py][px].when)
-       {
-               /* No reason to attempt flowing */
-               return (FALSE);
-       }
-
-       /* Monster is too far away to use flow information */
-       if (cave[fy][fx].dist > MONSTER_FLOW_DEPTH) return (FALSE);
-       if ((cave[fy][fx].dist > r_ptr->aaf) && !m_ptr->target_y) return (FALSE);
-
        /* Check nearby grids, diagonals first */
        for (i = 7; i >= 0; i--)
        {
@@ -653,11 +743,8 @@ static bool get_fear_moves_aux(int m_idx, int *yp, int *xp)
                /* Ignore locations off of edge */
                if (!in_bounds2(y, x)) continue;
 
-               /* Ignore illegal locations */
-               if (cave[y][x].when == 0) continue;
-
-               /* Ignore ancient locations */
-               if (cave[y][x].when < when) continue;
+               /* Don't move toward player */
+               /* if (cave[y][x].dist < 3) continue; */ /* Hmm.. Need it? */
 
                /* Calculate distance of this grid from our destination */
                dis = distance(y, x, y1, x1);
@@ -672,7 +759,6 @@ static bool get_fear_moves_aux(int m_idx, int *yp, int *xp)
                if (s < score) continue;
 
                /* Save the score and time */
-               when = cave[y][x].when;
                score = s;
 
                /* Save the location */
@@ -681,7 +767,7 @@ static bool get_fear_moves_aux(int m_idx, int *yp, int *xp)
        }
 
        /* No legal move (?) */
-       if (!when) return (FALSE);
+       if (score == -1) return (FALSE);
 
        /* Find deltas */
        (*yp) = fy - gy;
@@ -851,7 +937,7 @@ static bool find_safety(int m_idx, int *yp, int *xp)
 
        sint *y_offsets;
        sint *x_offsets;
-       
+
        cave_type *c_ptr;
 
        /* Start with adjacent locations, spread further */
@@ -860,7 +946,7 @@ static bool find_safety(int m_idx, int *yp, int *xp)
                /* Get the lists of points with a distance d from (fx, fy) */
                y_offsets = dist_offsets_y[d];
                x_offsets = dist_offsets_x[d];
-               
+
                /* Check the locations */
                for (i = 0, dx = x_offsets[0], dy = y_offsets[0];
                     dx != 0 || dy != 0;
@@ -868,7 +954,7 @@ static bool find_safety(int m_idx, int *yp, int *xp)
                {
                        y = fy + dy;
                        x = fx + dx;
-                       
+
                        /* Skip illegal locations */
                        if (!in_bounds(y, x)) continue;
 
@@ -878,19 +964,19 @@ static bool find_safety(int m_idx, int *yp, int *xp)
                        if (!cave_floor_grid(c_ptr)) continue;
 
                        /* Check for "availability" (if monsters can flow) */
-                       if (!stupid_monsters && !(m_ptr->mflag2 & MFLAG_NOFLOW))
+                       if (!(m_ptr->mflag2 & MFLAG2_NOFLOW))
                        {
                                /* Ignore grids very far from the player */
-                               if (c_ptr->when < cave[py][px].when) continue;
+                               if (c_ptr->dist == 0) continue;
 
                                /* Ignore too-distant grids */
                                if (c_ptr->dist > cave[fy][fx].dist + 2 * d) continue;
                        }
                        
                        /* Check for absence of shot (more or less) */
-                       if (clean_shot(fy, fx, y, x, FALSE))
+                       if (!player_has_los_grid(c_ptr))
                        {
-                                                       
+
                                /* Calculate distance from player */
                                dis = distance(y, x, py, px);
 
@@ -899,20 +985,13 @@ static bool find_safety(int m_idx, int *yp, int *xp)
                                {
                                        gy = y;
                                        gx = x;
-                                       if (!player_has_los_grid(c_ptr))
-                                       {
-                                               gdis = dis * 5;
-                                       }
-                                       else
-                                       {
-                                               gdis = dis;
-                                       }
+                                       gdis = dis;
                                }
                        }
                }
 
                /* Check for success */
-               if (gdis > d + m_ptr->cdis)
+               if (gdis > 0)
                {
                        /* Good location */
                        (*yp) = fy - gy;
@@ -924,13 +1003,7 @@ static bool find_safety(int m_idx, int *yp, int *xp)
        }
 
        /* No safe place */
-       
-       /* Save farthest location from player in LOS of monster */
-       (*yp) = fy - gy;
-       (*xp) = fx - gx;
-       
-       /* Hack - return TRUE anyway. */
-       return (TRUE);
+       return (FALSE);
 }
 
 
@@ -1025,24 +1098,28 @@ static bool get_moves(int m_idx, int *mm)
        int          x2 = px;
        bool         done = FALSE;
        bool         will_run = mon_will_run(m_idx);
-       cave_type       *c_ptr;
-       bool         no_flow = ((m_ptr->mflag2 & MFLAG_NOFLOW) && (cave[m_ptr->fy][m_ptr->fx].cost > 2));
-       bool         can_pass_wall;
+       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)));
 
-       /* Flow towards the player */
-       if (!stupid_monsters && !no_flow)
+       /* Counter attack to an enemy monster */
+       if (!will_run && m_ptr->target_y)
        {
-               /* Flow towards the player */
-               (void)get_moves_aux(m_idx, &y2, &x2);
-       }
-
-       can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall)));
+               int t_m_idx = cave[m_ptr->target_y][m_ptr->target_x].m_idx;
 
-       /* Extract the "pseudo-direction" */
-       y = m_ptr->fy - y2;
-       x = m_ptr->fx - x2;
+               /* The monster must be an enemy, and in LOS */
+               if (t_m_idx &&
+                   are_enemies(m_ptr, &m_list[t_m_idx]) &&
+                   los(m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x))
+               {
+                       /* Extract the "pseudo-direction" */
+                       y = m_ptr->fy - m_ptr->target_y;
+                       x = m_ptr->fx - m_ptr->target_x;
+                       done = TRUE;
+               }
+       }
 
-       if (!stupid_monsters && !will_run && is_hostile(m_ptr) &&
+       if (!done && !will_run && is_hostile(m_ptr) &&
            (r_ptr->flags1 & RF1_FRIENDS) &&
            (los(m_ptr->fy, m_ptr->fx, py, px) ||
            (cave[m_ptr->fy][m_ptr->fx].dist < MAX_SIGHT / 2)))
@@ -1059,14 +1136,12 @@ static bool get_moves(int m_idx, int *mm)
                        /* Count room grids next to player */
                        for (i = 0; i < 8; i++)
                        {
-                               int x = px + ddx_ddd[i];
-                               int y = py + ddy_ddd[i];
-                               
-                               cave_type *c_ptr;
+                               int xx = px + ddx_ddd[i];
+                               int yy = py + ddy_ddd[i];
 
-                               if (!in_bounds2(yx)) continue;
-                               
-                               c_ptr = &cave[y][x];
+                               if (!in_bounds2(yy, xx)) continue;
+
+                               c_ptr = &cave[yy][xx];
 
                                /* Check grid */
                                if (((cave_floor_grid(c_ptr)) || ((c_ptr->feat & 0x60) == 0x60)) &&
@@ -1129,8 +1204,20 @@ static bool get_moves(int m_idx, int *mm)
                }
        }
 
+       if (!done)
+       {
+               /* Flow towards the player */
+               (void)get_moves_aux(m_idx, &y2, &x2, no_flow);
+
+               /* Extract the "pseudo-direction" */
+               y = m_ptr->fy - y2;
+               x = m_ptr->fx - x2;
+
+               /* Not done */
+       }
+
        /* Apply fear if possible and necessary */
-       if ((stupid_monsters || is_pet(m_ptr)) && will_run)
+       if (is_pet(m_ptr) && will_run)
        {
                /* XXX XXX Not very "smart" */
                y = (-y), x = (-x);
@@ -1139,31 +1226,32 @@ static bool get_moves(int m_idx, int *mm)
        {
                if (!done && will_run)
                {
+                       int tmp_x = (-x);
+                       int tmp_y = (-y);
+
                        /* Try to find safe place */
-                       if (!find_safety(m_idx, &y, &x))
-                       {
-                               /* This is not a very "smart" method XXX XXX */
-                               y = (-y);
-                               x = (-x);
-                       }
-                       else
+                       if (find_safety(m_idx, &y, &x))
                        {
                                /* Attempt to avoid the player */
-                               if (!stupid_monsters && !no_flow)
+                               if (!no_flow)
                                {
                                        /* Adjust movement */
-                                       (void)get_fear_moves_aux(m_idx, &y, &x);
+                                       if (get_fear_moves_aux(m_idx, &y, &x)) done = TRUE;
                                }
                        }
+
+                       if (!done)
+                       {
+                               /* This is not a very "smart" method XXX XXX */
+                               y = tmp_y;
+                               x = tmp_x;
+                       }
                }
        }
 
 
-       if (!stupid_monsters)
-       {
-               /* Check for no move */
-               if (!x && !y) return (FALSE);
-       }
+       /* Check for no move */
+       if (!x && !y) return (FALSE);
 
 
        /* Extract the "absolute distances" */
@@ -1175,15 +1263,8 @@ static bool get_moves(int m_idx, int *mm)
        if (x > 0) move_val += 4;
 
        /* Prevent the diamond maneuvre */
-       if (ay > (ax << 1))
-       {
-               move_val++;
-               move_val++;
-       }
-       else if (ax > (ay << 1))
-       {
-               move_val++;
-       }
+       if (ay > (ax << 1)) move_val += 2;
+       else if (ax > (ay << 1)) move_val++;
 
        /* Extract some directions */
        switch (move_val)
@@ -1340,7 +1421,7 @@ static int check_hit2(int power, int level, int ac, int stun)
        int i, k;
 
        /* Percentile dice */
-       k = rand_int(100);
+       k = randint0(100);
 
        if (stun && one_in_(2)) return FALSE;
 
@@ -1351,7 +1432,7 @@ static int check_hit2(int power, int level, int ac, int stun)
        i = (power + (level * 3));
 
        /* Power and Level compete against Armor */
-       if ((i > 0) && (randint(i) > ((ac * 3) / 4))) return (TRUE);
+       if ((i > 0) && (randint1(i) > ((ac * 3) / 4))) return (TRUE);
 
        /* Assume miss */
        return (FALSE);
@@ -1370,7 +1451,7 @@ static bool monst_attack_monst(int m_idx, int t_idx)
        int             ap_cnt;
        int             ac, rlev, pt;
        char            m_name[80], t_name[80];
-       char            ddesc[80], temp[80];
+       char            temp[80];
        bool            blinked, heal_effect;
        bool            explode = FALSE, touched = FALSE, fear = FALSE;
        int             y_saver = t_ptr->fy;
@@ -1392,9 +1473,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;
 
@@ -1407,9 +1485,6 @@ static bool monst_attack_monst(int m_idx, int t_idx)
        /* Get the monster name (or "it") */
        monster_desc(t_name, t_ptr, 0);
 
-       /* Get the "died from" information (i.e. "a kobold") */
-       monster_desc(ddesc, m_ptr, 0x88);
-
        /* Assume no blink */
        blinked = FALSE;
 
@@ -1450,48 +1525,19 @@ static bool monst_attack_monst(int m_idx, int t_idx)
                        /* break; */
                }
 
-               /* Extract the attack "power" */
-               switch (effect)
-               {
-               case RBE_HURT:          power = 60; break;
-               case RBE_POISON:        power =  5; break;
-               case RBE_UN_BONUS:      power = 20; break;
-               case RBE_UN_POWER:      power = 15; break;
-               case RBE_EAT_GOLD:      power =  5; break;
-               case RBE_EAT_ITEM:      power =  5; break;
-               case RBE_EAT_FOOD:      power =  5; break;
-               case RBE_EAT_LITE:      power =  5; break;
-               case RBE_ACID:          power =  0; break;
-               case RBE_ELEC:          power = 10; break;
-               case RBE_FIRE:          power = 10; break;
-               case RBE_COLD:          power = 10; break;
-               case RBE_BLIND:         power =  2; break;
-               case RBE_CONFUSE:       power = 10; break;
-               case RBE_TERRIFY:       power = 10; break;
-               case RBE_PARALYZE:      power =  2; break;
-               case RBE_LOSE_STR:      power =  0; break;
-               case RBE_LOSE_DEX:      power =  0; break;
-               case RBE_LOSE_CON:      power =  0; break;
-               case RBE_LOSE_INT:      power =  0; break;
-               case RBE_LOSE_WIS:      power =  0; break;
-               case RBE_LOSE_CHR:      power =  0; break;
-               case RBE_LOSE_ALL:      power =  2; break;
-               case RBE_SHATTER:       power = 60; break;
-               case RBE_EXP_10:        power =  5; break;
-               case RBE_EXP_20:        power =  5; break;
-               case RBE_EXP_40:        power =  5; break;
-               case RBE_EXP_80:        power =  5; break;
-               case RBE_DISEASE:       power =  5; break;
-               case RBE_TIME:          power =  5; break;
-               case RBE_EXP_VAMP:      power =  5; break;
-               case RBE_DR_MANA:       power =  5; break;
-               case RBE_SUPERHURT:     power = 60; break;
-               }
+               if (method == RBM_SHOOT) continue;
 
+               /* Extract the attack "power" */
+               power = mbe_info[effect].power;
 
                /* 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)
                        {
@@ -1788,17 +1834,19 @@ act = "%s
                        /* Message */
                        if (act && see_either)
                        {
-                               if (do_silly_attack)
-                               {
-                                       act = silly_attacks[rand_int(MAX_SILLY_ATTACK)];
-                               }
-                               strfmt(temp, act, t_name);
 #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 */
@@ -1824,7 +1872,7 @@ act = "%s
 
                        case RBE_SUPERHURT:
                                {
-                                       if ((randint(rlev*2+250) > (ac+200)) || one_in_(13)) {
+                                       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;
@@ -1862,7 +1910,7 @@ act = "%s
                        case RBE_EAT_GOLD:
                                {
                                        pt = damage = 0;
-                                       if (randint(2) == 1) blinked = TRUE;
+                                       if (one_in_(2)) blinked = TRUE;
                                        break;
                                }
 
@@ -1925,6 +1973,7 @@ act = "%s
                                }
                        case RBE_SHATTER:
                                {
+                                       damage -= (damage * ((ac < 150) ? ac : 150) / 250);
                                        if (damage > 23)
                                        {
                                                earthquake(m_ptr->fy, m_ptr->fx, 8);
@@ -1964,7 +2013,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 | PROJECT_NO_REF, -1);
+                                               (pt == GF_OLD_SLEEP ? r_ptr->level : damage), pt, PROJECT_KILL | PROJECT_STOP | PROJECT_MONSTER, -1);
                                }
 
                                if (heal_effect)
@@ -1999,74 +2048,85 @@ msg_format("%s
                                if (touched)
                                {
                                        /* Aura fire */
-                                       if ((tr_ptr->flags2 & RF2_AURA_FIRE) &&
-                                               !(r_ptr->flags3 & RF3_IM_FIRE) &&
-                                               !(r_ptr->flags3 & RF3_RES_ALL) && 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_MONSTER, -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 | PROJECT_NO_REF, -1);
                                        }
 
                                        /* Aura cold */
-                                       if ((tr_ptr->flags3 & RF3_AURA_COLD) &&
-                                               !(r_ptr->flags3 & RF3_IM_COLD) &&
-                                               !(r_ptr->flags3 & RF3_RES_ALL) && 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_MONSTER, -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 | PROJECT_NO_REF, -1);
                                        }
 
                                        /* Aura elec */
-                                       if ((tr_ptr->flags2 & (RF2_AURA_ELEC)) &&
-                                               !(r_ptr->flags3 & (RF3_IM_ELEC)) &&
-                                               !(r_ptr->flags3 & RF3_RES_ALL) && 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_MONSTER, -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 | PROJECT_NO_REF, -1);
                                        }
-
                                }
                        }
                }
@@ -2090,6 +2150,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)
                                        {
@@ -2131,9 +2196,9 @@ msg_format("%s
                if (m_ptr->invulner) m_ptr->invulner = 0;
 
 #ifdef JP
-mon_take_hit_mon(FALSE, m_idx, m_ptr->hp + 1, &fear, "¤ÏÇúȯ¤·¤ÆÊ´¡¹¤Ë¤Ê¤Ã¤¿¡£", m_idx);
+mon_take_hit_mon(m_idx, m_ptr->hp + 1, &fear, "¤ÏÇúȯ¤·¤ÆÊ´¡¹¤Ë¤Ê¤Ã¤¿¡£", m_idx);
 #else
-               mon_take_hit_mon(FALSE, m_idx, m_ptr->hp + 1, &fear, " explodes into tiny shreds.", m_idx);
+               mon_take_hit_mon(m_idx, m_ptr->hp + 1, &fear, " explodes into tiny shreds.", m_idx);
 #endif
 
 
@@ -2166,12 +2231,6 @@ msg_print("ť
 
 
 /*
- * Hack -- local "player stealth" value (see below)
- */
-static u32b noise = 0L;
-
-
-/*
  * Process a monster
  *
  * The monster is known to be within 100 grids of the player
@@ -2201,6 +2260,7 @@ static void process_monster(int m_idx)
 {
        monster_type    *m_ptr = &m_list[m_idx];
        monster_race    *r_ptr = &r_info[m_ptr->r_idx];
+       monster_race    *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
 
        int             i, d, oy, ox, ny, nx;
 
@@ -2241,7 +2301,7 @@ static void process_monster(int m_idx)
                }
        }
 
-       if ((m_ptr->mflag2 & MFLAG_CHAMELEON) && one_in_(13) && !m_ptr->csleep)
+       if ((m_ptr->mflag2 & MFLAG2_CHAMELEON) && one_in_(13) && !m_ptr->csleep)
        {
                choose_new_monster(m_idx, FALSE, 0);
                r_ptr = &r_info[m_ptr->r_idx];
@@ -2250,22 +2310,22 @@ static void process_monster(int m_idx)
        /* Players hidden in shadow are almost imperceptable. -LM- */
        if (p_ptr->special_defense & NINJA_S_STEALTH)
        {
-               int tmp = p_ptr->lev*8+50;
+               int tmp = p_ptr->lev*6+(p_ptr->skill_stl+10)*4;
                if (p_ptr->monlite) tmp /= 3;
-               if (p_ptr->aggravate) tmp /= 2;
+               if (p_ptr->cursed & TRC_AGGRAVATE) tmp /= 2;
                if (r_ptr->level > (p_ptr->lev*p_ptr->lev/20+10)) tmp /= 3;
                /* Low-level monsters will find it difficult to locate the player. */
-               if (rand_int(tmp) > (r_ptr->level+20)) aware = FALSE;
+               if (randint0(tmp) > (r_ptr->level+20)) aware = FALSE;
        }
 
        /* Quantum monsters are odd */
        if (r_ptr->flags2 & (RF2_QUANTUM))
        {
                /* Sometimes skip move */
-               if (!rand_int(2)) return;
+               if (!randint0(2)) return;
 
                /* Sometimes die */
-               if (!rand_int((m_idx % 100) + 10) && !(r_ptr->flags1 & RF1_QUESTOR))
+               if (!randint0((m_idx % 100) + 10) && !(r_ptr->flags1 & RF1_QUESTOR))
                {
                        bool sad = FALSE;
 
@@ -2310,291 +2370,107 @@ msg_print("
 
        if (m_ptr->r_idx == MON_SHURYUUDAN)
 #ifdef JP
-               mon_take_hit_mon(FALSE, m_idx, 1, &fear, "¤ÏÇúȯ¤·¤ÆÊ´¡¹¤Ë¤Ê¤Ã¤¿¡£", m_idx);
+               mon_take_hit_mon(m_idx, 1, &fear, "¤ÏÇúȯ¤·¤ÆÊ´¡¹¤Ë¤Ê¤Ã¤¿¡£", m_idx);
 #else
-               mon_take_hit_mon(FALSE, m_idx, 1, &fear, " explodes into tiny shreds.", m_idx);
+               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;
 
                if (m_ptr->hp < m_ptr->maxhp/3)
                {
-                       bool level_teleport = TRUE;
                        char m_name[80];
                        monster_desc(m_name, m_ptr, 0);
 
                        if (m_idx == p_ptr->riding && riding_pinch < 2)
                        {
 #ifdef JP
-msg_format("%s¤Ï½ý¤ÎÄˤµ¤Î;¤ê¤¢¤Ê¤¿¤Î«Çû¤«¤éƨ¤ì¤è¤¦¤È¤·¤Æ¤¤¤ë¡£", m_name);
+                               msg_format("%s¤Ï½ý¤ÎÄˤµ¤Î;¤ê¤¢¤Ê¤¿¤Î«Çû¤«¤éƨ¤ì¤è¤¦¤È¤·¤Æ¤¤¤ë¡£", m_name);
 #else
-                                       msg_format("%^s seems to be in so much pain, and trying to escape from your restriction.", m_name);
+                               msg_format("%^s seems to be in so much pain, and trying to escape from your restriction.", m_name);
 #endif
                                riding_pinch++;
-                               level_teleport = FALSE;
                                disturb(1, 0);
                        }
-                       else if (m_ptr->ml)
+                       else
                        {
                                if (m_idx == p_ptr->riding)
                                {
 #ifdef JP
-msg_format("%s¤Ï¤¢¤Ê¤¿¤Î«Çû¤«¤éæ½Ð¤·¤¿¡£", m_name);
+                                       msg_format("%s¤Ï¤¢¤Ê¤¿¤Î«Çû¤«¤éæ½Ð¤·¤¿¡£", m_name);
 #else
                                        msg_format("%^s succeeded to escape from your restriction!", m_name);
 #endif
-                               }
-                               if ((r_ptr->flags2 & RF2_CAN_SPEAK) && (m_ptr->r_idx != MON_GRIP) && (m_ptr->r_idx != MON_WOLF) && (m_ptr->r_idx != MON_FANG))
-                               {
-#ifdef JP
-msg_format("%^s¡Ö¥Ô¥ó¥Á¤À¡ªÂàµÑ¤µ¤»¤Æ¤â¤é¤¦¡ª¡×", m_name);
-#else
-                                       msg_format("%^s says 'It is the pinch! I will retreat'.", m_name);
-#endif
-                               }
-#ifdef JP
-msg_format("%^s¤¬¥Æ¥ì¥Ý¡¼¥È¡¦¥ì¥Ù¥ë¤Î´¬Êª¤òÆɤó¤À¡£", m_name);
-#else
-                               msg_format("%^s read a scroll of teleport level.", m_name);
-#endif
-#ifdef JP
-msg_format("%^s¤¬¾Ã¤¨µî¤Ã¤¿¡£", m_name);
-#else
-                               msg_format("%^s disappears.", m_name);
-#endif
-                       }
-
-                       if (level_teleport)
-                       {
-                               delete_monster_idx(m_idx);
-
-                               if (m_idx == p_ptr->riding)
-                               {
                                        if (rakuba(-1, FALSE))
                                        {
 #ifdef JP
-msg_print("ÃÏÌ̤ËÍî¤È¤µ¤ì¤¿¡£");
+                                               msg_print("ÃÏÌ̤ËÍî¤È¤µ¤ì¤¿¡£");
 #else
-                                                msg_print("You have fallen from riding pet.");
+                                               msg_print("You have fallen from riding pet.");
 #endif
                                        }
                                }
-                               return;
-                       }
-               }
-               else
-                       if (m_idx == p_ptr->riding) riding_pinch = 0;
-                       
-       }
-
-       /* Handle "sleep" */
-       if (m_ptr->csleep)
-       {
-               u32b notice = 0;
-
-               /* Hack -- handle non-aggravation */
-               if (!p_ptr->aggravate) notice = rand_int(1024);
-
-               /* Nightmare monsters are more alert */
-               if (ironman_nightmare) notice /= 2;
-
-               /* Hack -- See if monster "notices" player */
-               if ((notice * notice * notice) <= noise)
-               {
-                       /* Hack -- amount of "waking" */
-                       int d = 1;
-
-                       /* Wake up faster near the player */
-                       if (m_ptr->cdis < 50) d = (100 / m_ptr->cdis);
-
-                       /* Hack -- handle aggravation */
-                       if (p_ptr->aggravate) d = m_ptr->csleep;
-
-                       /* Still asleep */
-                       if (m_ptr->csleep > d)
-                       {
-                               /* Monster wakes up "a little bit" */
-                               m_ptr->csleep -= d;
 
-                               /* Notice the "not waking up" */
                                if (m_ptr->ml)
                                {
-                                       /* Hack -- Count the ignores */
-                                       if (r_ptr->r_ignore < MAX_UCHAR)
+                                       if ((r_ptr->flags2 & RF2_CAN_SPEAK) && (m_ptr->r_idx != MON_GRIP) && (m_ptr->r_idx != MON_WOLF) && (m_ptr->r_idx != MON_FANG))
                                        {
-                                               r_ptr->r_ignore++;
-                                       }
-                               }
-                       }
-
-                       /* Just woke up */
-                       else
-                       {
-                               /* Reset sleep counter */
-                               m_ptr->csleep = 0;
-
-                               /* 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);
+                                               msg_format("%^s¡Ö¥Ô¥ó¥Á¤À¡ªÂàµÑ¤µ¤»¤Æ¤â¤é¤¦¡ª¡×", m_name);
 #else
-                                       msg_format("%^s wakes up.", m_name);
+                                               msg_format("%^s says 'It is the pinch! I will retreat'.", m_name);
 #endif
-
-
-                                       /* Redraw the health bar */
-                                       if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
-                                       if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
-
-                                       if (r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2))
-                                               p_ptr->update |= (PU_MON_LITE);
-
-                                       /* Hack -- Count the wakings */
-                                       if (r_ptr->r_wake < MAX_UCHAR)
-                                       {
-                                               r_ptr->r_wake++;
                                        }
+#ifdef JP
+                                       msg_format("%^s¤¬¥Æ¥ì¥Ý¡¼¥È¡¦¥ì¥Ù¥ë¤Î´¬Êª¤òÆɤó¤À¡£", m_name);
+                                       msg_format("%^s¤¬¾Ã¤¨µî¤Ã¤¿¡£", m_name);
+#else
+                                       msg_format("%^s read a scroll of teleport level.", m_name);
+                                       msg_format("%^s disappears.", m_name);
+#endif
                                }
-                       }
-               }
-
-               /* Still sleeping */
-               if (m_ptr->csleep) return;
-       }
-
-
-       /* Handle "stun" */
-       if (m_ptr->stunned)
-       {
-               int d = 1;
-
-               /* Make a "saving throw" against stun */
-               if (rand_int(10000) <= r_ptr->level * r_ptr->level)
-               {
-                       /* Recover fully */
-                       d = m_ptr->stunned;
-               }
-
-               /* Hack -- Recover from stun */
-               if (m_ptr->stunned > d)
-               {
-                       /* Recover somewhat */
-                       m_ptr->stunned -= d;
-               }
-
-               /* Fully recover */
-               else
-               {
-                       /* Recover fully */
-                       m_ptr->stunned = 0;
-
-                       /* Message if visible */
-                       if (m_ptr->ml)
-                       {
-                               char m_name[80];
 
-                               /* Acquire the monster name */
-                               monster_desc(m_name, m_ptr, 0);
-
-                               /* Dump a message */
+                               if (m_idx == p_ptr->riding && rakuba(-1, FALSE))
+                               {
 #ifdef JP
-msg_format("%^s¤ÏÛ¯Û°¾õÂÖ¤«¤éΩ¤Áľ¤Ã¤¿¡£", m_name);
+                                       msg_print("ÃÏÌ̤ËÍî¤È¤µ¤ì¤¿¡£");
 #else
-                               msg_format("%^s is no longer stunned.", m_name);
+                                       msg_print("You have fallen from riding pet.");
 #endif
+                               }
 
-                               if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
-                               if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
-                       }
-               }
-
-               /* Still stunned */
-               if (m_ptr->stunned && one_in_(2)) return;
-       }
-
+                               /* Check for quest completion */
+                               check_quest_completion(m_ptr);
 
-       /* Handle confusion */
-       if (m_ptr->confused)
-       {
-               /* Amount of "boldness" */
-               int d = randint(r_ptr->level / 20 + 1);
+                               delete_monster_idx(m_idx);
 
-               /* Still confused */
-               if (m_ptr->confused > d)
-               {
-                       /* Reduce the confusion */
-                       m_ptr->confused -= d;
+                               return;
+                       }
                }
-
-               /* Recovered */
                else
                {
-                       /* No longer confused */
-                       m_ptr->confused = 0;
-
-                       /* Message if visible */
-                       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 is no longer confused.", m_name);
-#endif
-
-                               if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
-                               if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
-                       }
+                       /* Reset the counter */
+                       if (m_idx == p_ptr->riding) riding_pinch = 0;
                }
        }
 
-       /* Handle Invulnerability */
-       if (m_ptr->invulner)
+       /* Handle "sleep" */
+       if (m_ptr->csleep)
        {
-               /* Reduce by one, note if expires */
-               m_ptr->invulner--;
+               /* Handle non-aggravation - Still sleeping */
+               if (!(p_ptr->cursed & TRC_AGGRAVATE)) return;
 
-               if (!(m_ptr->invulner) && m_ptr->ml)
-               {
-                       char m_name[80];
+               /* Handle aggravation */
 
-                       /* Acquire the monster name */
-                       monster_desc(m_name, m_ptr, 0);
+               /* Reset sleep counter */
+               m_ptr->csleep = 0;
 
-                       /* Dump a message */
-#ifdef JP
-msg_format("%^s¤Ï¤â¤¦ÌµÅ¨¤Ç¤Ê¤¤¡£", m_name);
-#else
-                       msg_format("%^s is no longer invulnerable.", m_name);
-#endif
+               if (r_ptr->flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
 
-                       m_ptr->energy -= 100;
-                       if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
-                       if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
-               }
-       }
-
-       /* Handle fast */
-       if (m_ptr->fast)
-       {
-               /* Reduce by one, note if expires */
-               m_ptr->fast--;
-
-               if (!(m_ptr->fast) && m_ptr->ml)
+               /* Notice the "waking up" */
+               if (m_ptr->ml)
                {
                        char m_name[80];
 
@@ -2603,39 +2479,28 @@ msg_format("%^s
 
                        /* Dump a message */
 #ifdef JP
-msg_format("%^s¤Ï¤â¤¦²Ã®¤µ¤ì¤Æ¤¤¤Ê¤¤¡£", m_name);
+                       msg_format("%^s¤¬Ìܤò³Ð¤Þ¤·¤¿¡£", m_name);
 #else
-                       msg_format("%^s is no longer fast.", m_name);
+                       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 (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+
+                       /* Hack -- Count the wakings */
+                       if (r_ptr->r_wake < MAX_UCHAR)
+                       {
+                               r_ptr->r_wake++;
+                       }
                }
        }
 
-       /* Handle slow */
-       if (m_ptr->slow)
+       /* Handle "stun" */
+       if (m_ptr->stunned)
        {
-               /* Reduce by one, note if expires */
-               m_ptr->slow--;
-
-               if (!(m_ptr->slow) && 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 is no longer slow.", m_name);
-#endif
-
-                       if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
-                       if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
-               }
+               /* Sometimes skip move */
+               if (one_in_(2)) return;
        }
 
        if (p_ptr->riding == m_idx)
@@ -2644,17 +2509,16 @@ msg_format("%^s
        }
 
        /* No one wants to be your friend if you're aggravating */
-       if (is_friendly(m_ptr) && p_ptr->aggravate)
+       if (is_friendly(m_ptr) && (p_ptr->cursed & TRC_AGGRAVATE))
                gets_angry = TRUE;
 
        /* 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;
@@ -2672,47 +2536,6 @@ msg_format("%^s
                set_hostile(m_ptr);
        }
 
-       /* Handle "fear" */
-       if (m_ptr->monfear)
-       {
-               /* Amount of "boldness" */
-               int d = randint(r_ptr->level / 20 + 1);
-
-               /* Still afraid */
-               if (m_ptr->monfear > d)
-               {
-                       /* Reduce the fear */
-                       m_ptr->monfear -= d;
-               }
-
-               /* Recover from fear, take note if seen */
-               else
-               {
-                       /* No longer afraid */
-                       m_ptr->monfear = 0;
-
-                       /* Visual note */
-                       if (m_ptr->ml)
-                       {
-                               char m_name[80];
-                               char m_poss[80];
-
-                               /* Acquire the monster name/poss */
-                               monster_desc(m_name, m_ptr, 0);
-                               monster_desc(m_poss, m_ptr, 0x22);
-
-                               /* Dump a message */
-#ifdef JP
-msg_format("%^s¤Ïͦµ¤¤ò¼è¤êÌᤷ¤¿¡£", m_name);
-#else
-                               msg_format("%^s recovers %s courage.", m_name, m_poss);
-#endif
-
-                               if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
-                       }
-               }
-       }
-
        /* Get the origin */
        oy = m_ptr->fy;
        ox = m_ptr->fx;
@@ -2736,13 +2559,13 @@ msg_format("%^s
                }
 
                /* Hack -- multiply slower in crowded areas */
-               if ((k < 4) && (!k || !rand_int(k * MON_MULT_ADJ)))
+               if ((k < 4) && (!k || !randint0(k * MON_MULT_ADJ)))
                {
                        /* Try to multiply */
-                       if (multiply_monster(m_idx, FALSE, is_friendly(m_ptr), is_pet(m_ptr)))
+                       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);
                                }
@@ -2754,11 +2577,39 @@ msg_format("%^s
        }
 
 
+       if (r_ptr->flags6 & RF6_SPECIAL)
+       {
+               /* Hack -- Ohmu scatters molds! */
+               if (m_ptr->r_idx == MON_OHMU)
+               {
+                       if (!p_ptr->inside_arena && !p_ptr->inside_battle)
+                       {
+                               if (r_ptr->freq_spell && (randint1(100) <= r_ptr->freq_spell))
+                               {
+                                       int  k, count = 0;
+                                       int  rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
+                                       u32b p_mode = is_pet(m_ptr) ? PM_FORCE_PET : 0L;
+
+                                       for (k = 0; k < 6; k++)
+                                       {
+                                               if (summon_specific(m_idx, m_ptr->fy, m_ptr->fx, rlev, SUMMON_BIZARRE1, (PM_ALLOW_GROUP | p_mode)))
+                                               {
+                                                       if (m_list[hack_m_idx_ii].ml) count++;
+                                               }
+                                       }
+
+                                       if (count && m_ptr->ml && is_original_ap(m_ptr)) r_ptr->r_flags6 |= (RF6_SPECIAL);
+                               }
+                       }
+               }
+       }
+
+
        if (!p_ptr->inside_battle)
        {
                /* Hack! "Cyber" monster makes noise... */
-               if (m_ptr->r_idx == MON_CYBER &&
-                   (randint(CYBERNOISE) == 1) &&
+               if (m_ptr->ap_r_idx == MON_CYBER &&
+                   one_in_(CYBERNOISE) &&
                    !m_ptr->ml && (m_ptr->cdis <= MAX_SIGHT))
                {
                        if (disturb_minor) disturb(FALSE, FALSE);
@@ -2771,8 +2622,8 @@ msg_print("
                }
 
                /* Some monsters can speak */
-               if ((r_ptr->flags2 & RF2_CAN_SPEAK) && aware &&
-                       (randint(SPEAK_CHANCE) == 1) &&
+               if ((ap_r_ptr->flags2 & RF2_CAN_SPEAK) && aware &&
+                       one_in_(SPEAK_CHANCE) &&
                        player_has_los_bold(oy, ox))
                {
                        char m_name[80];
@@ -2821,7 +2672,7 @@ filename = "monfrien_j.txt";
 
 
                        /* Get the monster line */
-                       if (get_rnd_line(filename, m_ptr->r_idx, monmessage) == 0)
+                       if (get_rnd_line(filename, m_ptr->ap_r_idx, monmessage) == 0)
                        {
                                /* Say something */
 #ifdef JP
@@ -2834,14 +2685,44 @@ msg_format("%^s%s", m_name, monmessage);
                }
        }
 
-       /* Attempt to cast a spell */
-       if (aware && make_attack_spell(m_idx)) return;
+       /* Try to cast spell occasionally */
+       if (r_ptr->freq_spell && randint1(100) <= r_ptr->freq_spell)
+       {
+               bool counterattack = FALSE;
 
-       /*
-        * Attempt to cast a spell at an enemy other than the player
-        * (may slow the game a smidgeon, but I haven't noticed.)
-        */
-       if (monst_spell_monst(m_idx)) return;
+               /* Give priority to counter attack? */
+               if (m_ptr->target_y)
+               {
+                       int t_m_idx = cave[m_ptr->target_y][m_ptr->target_x].m_idx;
+
+                       /* The monster must be an enemy, and projectable */
+                       if (t_m_idx &&
+                           are_enemies(m_ptr, &m_list[t_m_idx]) &&
+                           projectable(m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x))
+                       {
+                               counterattack = TRUE;
+                       }
+               }
+
+               if (!counterattack)
+               {
+                       /* Attempt to cast a spell */
+                       if (aware && make_attack_spell(m_idx)) return;
+
+                       /*
+                        * Attempt to cast a spell at an enemy other than the player
+                        * (may slow the game a smidgeon, but I haven't noticed.)
+                        */
+                       if (monst_spell_monst(m_idx)) return;
+               }
+               else
+               {
+                       /* Attempt to do counter attack at first */
+                       if (monst_spell_monst(m_idx)) return;
+
+                       if (aware && make_attack_spell(m_idx)) return;
+               }
+       }
 
        can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall)));
 
@@ -2849,13 +2730,6 @@ msg_format("%^s%s", m_name, monmessage);
        mm[0] = mm[1] = mm[2] = mm[3] = 0;
        mm[4] = mm[5] = mm[6] = mm[7] = 0;
 
-#ifdef USE_SCRIPT
-       if (monster_move_callback(mm, m_idx))
-       {
-       }
-       else
-#endif /* USE_SCRIPT */
-
 
        /* Confused -- 100% random */
        if (m_ptr->confused || !aware)
@@ -2865,13 +2739,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) &&
-                (rand_int(100) < 75))
+       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;
@@ -2879,10 +2751,10 @@ msg_format("%^s%s", m_name, monmessage);
 
        /* 50% random movement */
        else if ((r_ptr->flags1 & RF1_RAND_50) &&
-                               (rand_int(100) < 50))
+                               (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;
@@ -2890,10 +2762,10 @@ msg_format("%^s%s", m_name, monmessage);
 
        /* 25% random movement */
        else if ((r_ptr->flags1 & RF1_RAND_25) &&
-                               (rand_int(100) < 25))
+                               (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;
@@ -2961,11 +2833,6 @@ msg_format("%^s%s", m_name, monmessage);
                get_enemy_dir(m_idx, mm);
        }
        /* Normal movement */
-       else if (stupid_monsters)
-       {
-               /* Logical moves */
-               get_moves(m_idx, mm);
-       }
        else
        {
                /* Logical moves, may do nothing */
@@ -2994,7 +2861,7 @@ msg_format("%^s%s", m_name, monmessage);
                d = mm[i];
 
                /* Hack -- allow "randomized" motion */
-               if (d == 5) d = ddd[rand_int(8)];
+               if (d == 5) d = ddd[randint0(8)];
 
                /* Get the destination */
                ny = oy + ddy[d];
@@ -3017,7 +2884,7 @@ msg_format("%^s%s", m_name, monmessage);
                }
 
                /* Hack -- player 'in' wall */
-               else if ((ny == py) && (nx == px))
+               else if (player_bold(ny, nx))
                {
                        do_move = TRUE;
                }
@@ -3067,7 +2934,7 @@ msg_format("%^s%s", m_name, monmessage);
                        /* Monster destroyed a wall */
                        did_kill_wall = TRUE;
 
-                       if (randint(GRINDNOISE) == 1)
+                       if (one_in_(GRINDNOISE))
                        {
 #ifdef JP
 msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£");
@@ -3081,18 +2948,14 @@ msg_print("
                        c_ptr->info &= ~(CAVE_MARK);
 
                        /* Notice */
-                       c_ptr->feat = floor_type[rand_int(100)];
-                       c_ptr->info &= ~(CAVE_MASK);
-                       c_ptr->info |= CAVE_FLOOR;
+                       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 (((c_ptr->feat >= FEAT_DOOR_HEAD) &&
-                         (c_ptr->feat <= FEAT_DOOR_TAIL)) ||
-                         (c_ptr->feat == FEAT_SECRET))
+               else if (is_closed_door(c_ptr->feat))
                {
                        bool may_bash = TRUE;
 
@@ -3103,9 +2966,8 @@ msg_print("
                        if ((r_ptr->flags2 & RF2_OPEN_DOOR) &&
                                 (!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_OPEN_DOORS)))
                        {
-                               /* Closed doors and secret doors */
-                               if ((c_ptr->feat == FEAT_DOOR_HEAD) ||
-                                       (c_ptr->feat == FEAT_SECRET))
+                               /* Closed doors */
+                               if (c_ptr->feat == FEAT_DOOR_HEAD)
                                {
                                        /* The door is open */
                                        did_open_door = TRUE;
@@ -3126,7 +2988,7 @@ msg_print("
                                        k = ((c_ptr->feat - FEAT_DOOR_HEAD) & 0x07);
 
                                        /* Try to unlock it XXX XXX XXX */
-                                       if (rand_int(m_ptr->hp / 10) > k)
+                                       if (randint0(m_ptr->hp / 10) > k)
                                        {
                                                /* Unlock the door */
                                                cave_set_feat(ny, nx, FEAT_DOOR_HEAD + 0x00);
@@ -3147,7 +3009,7 @@ msg_print("
                                k = ((c_ptr->feat - FEAT_DOOR_HEAD) & 0x07);
 
                                /* Attempt to Bash XXX XXX XXX */
-                               if (rand_int(m_ptr->hp / 10) > k)
+                               if (randint0(m_ptr->hp / 10) > k)
                                {
                                        /* Message */
 #ifdef JP
@@ -3173,7 +3035,7 @@ msg_print("
                        if (did_open_door || did_bash_door)
                        {
                                /* Break down the door */
-                               if (did_bash_door && (rand_int(100) < 50))
+                               if (did_bash_door && (randint0(100) < 50))
                                {
                                        cave_set_feat(ny, nx, FEAT_BROKEN);
                                }
@@ -3190,14 +3052,14 @@ msg_print("
                }
 
                /* Hack -- check for Glyph of Warding */
-               if (do_move && (c_ptr->feat == FEAT_GLYPH) &&
-                   !((r_ptr->flags1 & RF1_NEVER_BLOW) && (py == ny) && (px == nx)))
+               if (do_move && is_glyph_grid(c_ptr) &&
+                   !((r_ptr->flags1 & RF1_NEVER_BLOW) && player_bold(ny, nx)))
                {
                        /* Assume no move allowed */
                        do_move = FALSE;
 
                        /* Break the ward */
-                       if (!is_pet(m_ptr) && (randint(BREAK_GLYPH) < r_ptr->level))
+                       if (!is_pet(m_ptr) && (randint1(BREAK_GLYPH) < r_ptr->level))
                        {
                                /* Describe observable breakage */
                                if (c_ptr->info & CAVE_MARK)
@@ -3214,9 +3076,8 @@ msg_print("
                                c_ptr->info &= ~(CAVE_MARK);
 
                                /* Break the rune */
-                               c_ptr->feat = floor_type[rand_int(100)];
-                               c_ptr->info &= ~(CAVE_MASK);
-                               c_ptr->info |= CAVE_FLOOR;
+                               c_ptr->info &= ~(CAVE_OBJECT);
+                               c_ptr->mimic = 0;
 
                                /* Allow movement */
                                do_move = TRUE;
@@ -3225,8 +3086,8 @@ msg_print("
                                note_spot(ny, nx);
                        }
                }
-               else if (do_move && (c_ptr->feat == FEAT_MINOR_GLYPH) &&
-                        !((r_ptr->flags1 & RF1_NEVER_BLOW) && (py == ny) && (px == nx)))
+               else if (do_move && is_explosive_rune_grid(c_ptr) &&
+                        !((r_ptr->flags1 & RF1_NEVER_BLOW) && player_bold(ny, nx)))
                {
                        /* Assume no move allowed */
                        do_move = FALSE;
@@ -3235,7 +3096,7 @@ msg_print("
                        if (!is_pet(m_ptr))
                        {
                                /* Break the ward */
-                               if (randint(BREAK_MINOR_GLYPH) > r_ptr->level)
+                               if (randint1(BREAK_MINOR_GLYPH) > r_ptr->level)
                                {
                                        /* Describe observable breakage */
                                        if (c_ptr->info & CAVE_MARK)
@@ -3246,7 +3107,7 @@ msg_print("
                                                msg_print("The rune explodes!");
 #endif
 
-                                               project(0, 2, ny, nx, 2 * ((p_ptr->lev / 2) + damroll(7, 7)), GF_MANA, (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_REF | PROJECT_NO_HANGEKI), -1);
+                                               project(0, 2, ny, nx, 2 * (p_ptr->lev + damroll(7, 7)), GF_MANA, (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
                                        }
                                }
                                else
@@ -3262,9 +3123,9 @@ msg_print("
                                c_ptr->info &= ~(CAVE_MARK);
 
                                /* Break the rune */
-                               c_ptr->feat = floor_type[rand_int(100)];
-                               c_ptr->info &= ~(CAVE_MASK);
-                               c_ptr->info |= CAVE_FLOOR;
+                               c_ptr->info &= ~(CAVE_OBJECT);
+                               c_ptr->mimic = 0;
+
                                note_spot(ny, nx);
                                lite_spot(ny, nx);
 
@@ -3273,71 +3134,97 @@ msg_print("
                                do_move = TRUE;
                        }
                }
-               if (do_move && (ny == py) && (nx == px) && (d_info[dungeon_type].flags1 & DF1_NO_MELEE))
-               {
-                       do_move = FALSE;
-               }
-
-               /* Some monsters never attack */
-               if (do_move && (ny == py) && (nx == px) &&
-                       (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. */
-               if (do_move && (ny == py) && (nx == px))
+               /* 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;
+                               }
+                       }
+
+                       if ((c_ptr->feat >= FEAT_PATTERN_START) &&
+                               (c_ptr->feat <= FEAT_PATTERN_XTRA2) &&
+                               !do_turn && !(r_ptr->flags7 & RF7_CAN_FLY))
+                       {
+                               do_move = FALSE;
+                       }
+               }
 
                /* 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) &&
+                                cave_floor_grid(c_ptr) &&
+                                (c_ptr->m_idx != p_ptr->riding)) ||
+                               are_enemies(m_ptr, y_ptr) || m_ptr->confused)
                        {
                                do_move = FALSE;
 
-                               if (r_ptr->flags2 & RF2_KILL_BODY) r_ptr->r_flags2 |= (RF2_KILL_BODY);
-
-                               /* attack */
-                               if ((m2_ptr->r_idx) && (m2_ptr->hp >= 0))
+                               if (!(r_ptr->flags1 & RF1_NEVER_BLOW))
                                {
-                                       if (monst_attack_monst(m_idx, cave[ny][nx].m_idx))
-                                       return;
+                                       if (r_ptr->flags2 & RF2_KILL_BODY)
+                                       {
+                                               if (is_original_ap(m_ptr)) 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;
+
+                                               /* 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;
+                                                       }
+                                               }
+                                       }
                                }
                        }
 
@@ -3373,7 +3260,7 @@ 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;
@@ -3395,17 +3282,16 @@ msg_print("
                        /* Hack -- Update the old location */
                        cave[oy][ox].m_idx = c_ptr->m_idx;
 
-                       if (cave[ny][nx].feat == FEAT_TREES)
+                       if (c_ptr->feat == FEAT_TREES)
                        {
                                if (r_ptr->flags2 & RF2_KILL_WALL)
                                {
-                                       c_ptr->feat = FEAT_GRASS;
-                                       c_ptr->info &= ~(CAVE_MASK);
-                                       c_ptr->info |= CAVE_FLOOR;
+                                       cave_set_feat(ny, nx, FEAT_GRASS);
+
                                }
                                if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD))
                                {
-                                       m_ptr->energy -= 100;
+                                       m_ptr->energy_need += ENERGY_NEED();
                                }
                        }
 
@@ -3420,7 +3306,9 @@ 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_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
                        }
 
                        /* Hack -- Update the new location */
@@ -3450,19 +3338,20 @@ msg_print("
                                verify_panel();
 
                                /* Update stuff */
-                               p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW);
+                               p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE);
 
                                /* Update the monsters */
                                p_ptr->update |= (PU_DISTANCE);
 
-                               /* Window stuff */
+                               /* Update sub-windows */
                                p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
                        }
 
                        /* Possible disturb */
-                       if (m_ptr->ml && (disturb_move ||
-                               ((m_ptr->mflag & MFLAG_VIEW) &&
-                               disturb_near)))
+                       if (m_ptr->ml &&
+                           (disturb_move ||
+                            (disturb_near && (m_ptr->mflag & MFLAG_VIEW)) ||
+                            (disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= p_ptr->lev)))
                        {
                                /* Disturb */
                                if (is_hostile(m_ptr))
@@ -3495,35 +3384,45 @@ msg_print("
                                if ((r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) &&
                                         (!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_PICKUP_ITEMS)))
                                {
-                                       u32b f1, f2, f3;
+                                       u32b flgs[TR_FLAG_SIZE];
 
+                                       u32b flg2 = 0L;
                                        u32b flg3 = 0L;
 
                                        char m_name[80];
                                        char o_name[MAX_NLEN];
 
                                        /* Extract some flags */
-                                       object_flags(o_ptr, &f1, &f2, &f3);
+                                       object_flags(o_ptr, flgs);
 
                                        /* Acquire the object name */
                                        object_desc(o_name, o_ptr, TRUE, 3);
 
                                        /* Acquire the monster name */
-                                       monster_desc(m_name, m_ptr, 0x04);
+                                       monster_desc(m_name, m_ptr, MD_INDEF_HIDDEN);
 
                                        /* React to objects that hurt the monster */
-                                       if (f1 & TR1_KILL_DRAGON) flg3 |= (RF3_DRAGON);
-                                       if (f1 & TR1_SLAY_DRAGON) flg3 |= (RF3_DRAGON);
-                                       if (f1 & TR1_SLAY_TROLL)  flg3 |= (RF3_TROLL);
-                                       if (f1 & TR1_SLAY_GIANT)  flg3 |= (RF3_GIANT);
-                                       if (f1 & TR1_SLAY_ORC)    flg3 |= (RF3_ORC);
-                                       if (f1 & TR1_SLAY_DEMON)  flg3 |= (RF3_DEMON);
-                                       if (f1 & TR1_SLAY_UNDEAD) flg3 |= (RF3_UNDEAD);
-                                       if (f1 & TR1_SLAY_ANIMAL) flg3 |= (RF3_ANIMAL);
-                                       if (f1 & TR1_SLAY_EVIL)   flg3 |= (RF3_EVIL);
+                                       if (have_flag(flgs, TR_KILL_DRAGON)) flg3 |= (RF3_DRAGON);
+                                       if (have_flag(flgs, TR_SLAY_DRAGON)) flg3 |= (RF3_DRAGON);
+                                       if (have_flag(flgs, TR_SLAY_TROLL))  flg3 |= (RF3_TROLL);
+                                       if (have_flag(flgs, TR_KILL_TROLL))  flg3 |= (RF3_TROLL);
+                                       if (have_flag(flgs, TR_KILL_GIANT))  flg3 |= (RF3_GIANT);
+                                       if (have_flag(flgs, TR_SLAY_GIANT))  flg3 |= (RF3_GIANT);
+                                       if (have_flag(flgs, TR_SLAY_ORC))    flg3 |= (RF3_ORC);
+                                       if (have_flag(flgs, TR_KILL_ORC))    flg3 |= (RF3_ORC);
+                                       if (have_flag(flgs, TR_SLAY_DEMON))  flg3 |= (RF3_DEMON);
+                                       if (have_flag(flgs, TR_KILL_DEMON))  flg3 |= (RF3_DEMON);
+                                       if (have_flag(flgs, TR_SLAY_UNDEAD)) flg3 |= (RF3_UNDEAD);
+                                       if (have_flag(flgs, TR_KILL_UNDEAD)) flg3 |= (RF3_UNDEAD);
+                                       if (have_flag(flgs, TR_SLAY_ANIMAL)) flg3 |= (RF3_ANIMAL);
+                                       if (have_flag(flgs, TR_KILL_ANIMAL)) flg3 |= (RF3_ANIMAL);
+                                       if (have_flag(flgs, TR_SLAY_EVIL))   flg3 |= (RF3_EVIL);
+                                       if (have_flag(flgs, TR_KILL_EVIL))   flg3 |= (RF3_EVIL);
+                                       if (have_flag(flgs, TR_SLAY_HUMAN))  flg2 |= (RF2_HUMAN);
+                                       if (have_flag(flgs, TR_KILL_HUMAN))  flg2 |= (RF2_HUMAN);
 
                                        /* The object cannot be picked up by the monster */
-                                       if (artifact_p(o_ptr) || (r_ptr->flags3 & flg3) ||
+                                       if (artifact_p(o_ptr) || (r_ptr->flags3 & flg3) || (r_ptr->flags2 & flg2) ||
                                                (o_ptr->art_name))
                                        {
                                                /* Only give a message for "take_item" */
@@ -3567,7 +3466,7 @@ msg_format("%^s
                                                excise_object_idx(this_o_idx);
 
                                                /* Forget mark */
-                                               o_ptr->marked = FALSE;
+                                               o_ptr->marked = 0;
 
                                                /* Forget location */
                                                o_ptr->iy = o_ptr->ix = 0;
@@ -3612,17 +3511,20 @@ msg_format("%^s
        }
 
        /*
-        *  Forward movements failed, but now recieved LOS attack!
+        *  Forward movements failed, but now received LOS attack!
         *  Try to flow by smell.
         */
        if (p_ptr->no_flowed && i > 2 &&  m_ptr->target_y)
-               m_ptr->mflag2 &= ~MFLAG_NOFLOW;
+               m_ptr->mflag2 &= ~MFLAG2_NOFLOW;
 
        /* If we haven't done anything, try casting a spell again */
-       if (!do_turn && !do_move && !m_ptr->monfear && !stupid_monsters && !(p_ptr->riding == m_idx) && aware)
+       if (!do_turn && !do_move && !m_ptr->monfear && !(p_ptr->riding == m_idx) && aware)
        {
-               /* Cast spell */
-               if (make_attack_spell(m_idx)) return;
+               /* Try to cast spell again */
+               if (r_ptr->freq_spell && randint1(100) <= r_ptr->freq_spell)
+               {
+                       if (make_attack_spell(m_idx)) return;
+               }
        }
 
 
@@ -3631,17 +3533,21 @@ msg_format("%^s
        {
                /* Update some things */
                p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS | PU_MON_LITE);
+
+               /* Window stuff */
+               p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
        }
 
        /* 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);
@@ -3687,6 +3593,9 @@ msg_format("%^s
                        msg_format("%^s turns to fight!", m_name);
 #endif
 
+                       /* Redraw (later) if needed */
+                       if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+
                        chg_virtue(V_COMPASSION, -1);
                }
 
@@ -3728,7 +3637,7 @@ msg_format("%^s
  */
 void process_monsters(void)
 {
-       int             i, e;
+       int             i;
        int             fx, fy;
 
        bool            test;
@@ -3744,19 +3653,19 @@ 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;
        byte    old_r_blows2 = 0;
        byte    old_r_blows3 = 0;
 
-       byte    old_r_cast_inate = 0;
        byte    old_r_cast_spell = 0;
 
        int speed;
 
-        /* Clear monster fighting indicator */
-        mon_fight = FALSE;
+       /* Clear monster fighting indicator */
+       mon_fight = FALSE;
 
        /* Memorize old race */
        old_monster_race_idx = p_ptr->monster_race_idx;
@@ -3774,6 +3683,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];
@@ -3782,15 +3692,10 @@ void process_monsters(void)
                old_r_blows3 = r_ptr->r_blows[3];
 
                /* Memorize castings */
-               old_r_cast_inate = r_ptr->r_cast_inate;
                old_r_cast_spell = r_ptr->r_cast_spell;
        }
 
 
-       /* Hack -- calculate the "player noise" */
-       noise = (1L << (30 - p_ptr->skill_stl));
-
-
        /* Process the monsters (backwards) */
        for (i = m_max - 1; i >= 1; i--)
        {
@@ -3818,7 +3723,7 @@ void process_monsters(void)
                }
 
                /* Hack -- Require proximity */
-               if (m_ptr->cdis >= 100) continue;
+               if (m_ptr->cdis >= AAF_LIMIT) continue;
 
 
                /* Access the location */
@@ -3826,16 +3731,16 @@ void process_monsters(void)
                fy = m_ptr->fy;
 
                /* Flow by smell is allowed */
-               if (!stupid_monsters && !p_ptr->no_flowed)
+               if (!p_ptr->no_flowed)
                {
-                       m_ptr->mflag2 &= ~MFLAG_NOFLOW;
+                       m_ptr->mflag2 &= ~MFLAG2_NOFLOW;
                }
 
                /* Assume no move */
                test = FALSE;
 
                /* Handle "sensing radius" */
-               if (m_ptr->cdis <= (is_pet(m_ptr) ? (r_ptr->aaf > 20 ? 20 : r_ptr->aaf) : r_ptr->aaf))
+               if (m_ptr->cdis <= (is_pet(m_ptr) ? (r_ptr->aaf > MAX_SIGHT ? MAX_SIGHT : r_ptr->aaf) : r_ptr->aaf))
                {
                        /* We can "sense" the player */
                        test = TRUE;
@@ -3843,15 +3748,16 @@ void process_monsters(void)
 
                /* Handle "sight" and "aggravation" */
                else if ((m_ptr->cdis <= MAX_SIGHT) &&
-                       (player_has_los_bold(fy, fx) || p_ptr->aggravate))
+                       (player_has_los_bold(fy, fx) || (p_ptr->cursed & TRC_AGGRAVATE)))
                {
                        /* We can "see" or "feel" the player */
                        test = TRUE;
                }
 
+#if 0 /* (cave[py][px].when == cave[fy][fx].when) is always FALSE... */
                /* Hack -- Monsters can "smell" the player from far away */
                /* Note that most monsters have "aaf" of "20" or so */
-               else if (!stupid_monsters && !(m_ptr->mflag2 & MFLAG_NOFLOW) &&
+               else if (!(m_ptr->mflag2 & MFLAG2_NOFLOW) &&
                        (cave_floor_bold(py, px) || (cave[py][px].feat == FEAT_TREES)) &&
                        (cave[py][px].when == cave[fy][fx].when) &&
                        (cave[fy][fx].dist < MONSTER_FLOW_DEPTH) &&
@@ -3860,6 +3766,7 @@ void process_monsters(void)
                        /* We can "smell" the player */
                        test = TRUE;
                }
+#endif
                else if (m_ptr->target_y) test = TRUE;
 
                /* Do nothing */
@@ -3870,30 +3777,23 @@ void process_monsters(void)
                        speed = p_ptr->pspeed;
                else
                {
-                       speed = MIN(199, m_ptr->mspeed);
+                       speed = m_ptr->mspeed;
 
                        /* Monsters move quickly in Nightmare mode */
-                       if (ironman_nightmare)
-                       {
-                               speed = MIN(199, m_ptr->mspeed + 5);
-                       }
+                       if (ironman_nightmare) speed += 5;
 
-                       if (m_ptr->fast) speed = MIN(199, speed + 10);
-                       if (m_ptr->slow) speed = MAX(0, speed - 10);
+                       if (m_ptr->fast) speed += 10;
+                       if (m_ptr->slow) speed -= 10;
                }
 
-               e = extract_energy[speed];
-
                /* Give this monster some energy */
-               if(rand_int(60) < e)
-               m_ptr->energy += gain_energy();
-
+               m_ptr->energy_need -= SPEED_TO_ENERGY(speed);
 
                /* Not enough energy to move */
-               if (m_ptr->energy < 100) continue;
+               if (m_ptr->energy_need > 0) continue;
 
                /* Use up "some" energy */
-               m_ptr->energy -= 100;
+               m_ptr->energy_need += ENERGY_NEED();
 
 
                /* Save global index */
@@ -3902,15 +3802,14 @@ void process_monsters(void)
                /* Process the monster */
                process_monster(i);
 
-               m_ptr->target_y = 0;
-               m_ptr->target_x = 0;
+               reset_target(m_ptr);
 
                /* Give up flow_by_smell when it might useless */
                if (p_ptr->no_flowed && one_in_(3))
-                       m_ptr->mflag2 |= MFLAG_NOFLOW;
+                       m_ptr->mflag2 |= MFLAG2_NOFLOW;
 
                /* Hack -- notice death or departure */
-               if (!alive || death) break;
+               if (!p_ptr->playing || p_ptr->is_dead) break;
 
                /* Notice leaving */
                if (p_ptr->leaving) break;
@@ -3933,11 +3832,11 @@ 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]) ||
                        (old_r_blows3 != r_ptr->r_blows[3]) ||
-                       (old_r_cast_inate != r_ptr->r_cast_inate) ||
                        (old_r_cast_spell != r_ptr->r_cast_spell))
                {
                        /* Window stuff */
@@ -3950,12 +3849,14 @@ void process_monsters(void)
 
 bool process_the_world(int num, int who, bool vs_player)
 {
+       monster_type *m_ptr = &m_list[hack_m_idx];  /* the world monster */
+
        if(world_monster) return (FALSE);
 
        if(vs_player)
        {
                char m_name[80];
-               monster_desc(m_name, &m_list[hack_m_idx], 0);
+               monster_desc(m_name, m_ptr, 0);
 
                if (who == 1)
 #ifdef JP
@@ -3967,7 +3868,7 @@ bool process_the_world(int num, int who, bool vs_player)
 #ifdef JP
                        msg_print("¡Ö»þ¤è¡ª¡×");
 #else
-                       msg_format("%s yells 'Time!'", m_name);
+                       msg_format("%s yells 'Time!'", m_name);
 #endif
                else msg_print("hek!");
 
@@ -3980,26 +3881,25 @@ bool process_the_world(int num, int who, bool vs_player)
 
        while(num--)
        {
-         if(!m_list[hack_m_idx].r_idx) return (TRUE);
-         process_monster(hack_m_idx);
+               if(!m_ptr->r_idx) break;
+               process_monster(hack_m_idx);
 
-         m_list[hack_m_idx].target_y = 0;
-         m_list[hack_m_idx].target_x = 0;
+               reset_target(m_ptr);
 
-         /* Notice stuff */
-         if (p_ptr->notice) notice_stuff();
+               /* Notice stuff */
+               if (p_ptr->notice) notice_stuff();
 
-         /* Update stuff */
-         if (p_ptr->update) update_stuff();
+               /* Update stuff */
+               if (p_ptr->update) update_stuff();
 
-         /* Redraw stuff */
-         if (p_ptr->redraw) redraw_stuff();
+               /* Redraw stuff */
+               if (p_ptr->redraw) redraw_stuff();
 
-         /* Redraw stuff */
-         if (p_ptr->window) window_stuff();
+               /* Redraw stuff */
+               if (p_ptr->window) window_stuff();
 
-         /* Delay */
-         if (vs_player) Term_xtra(TERM_XTRA_DELAY, 500);
+               /* Delay */
+               if (vs_player) Term_xtra(TERM_XTRA_DELAY, 500);
        }
 
        /* Redraw map */
@@ -4012,7 +3912,7 @@ bool process_the_world(int num, int who, bool vs_player)
        p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
 
        world_monster = FALSE;
-       if (vs_player || los(py, px, m_list[hack_m_idx].fy, m_list[hack_m_idx].fx))
+       if (vs_player || los(py, px, m_ptr->fy, m_ptr->fx))
        {
 #ifdef JP
                msg_print("¡Ö»þ¤ÏÆ°¤­¤À¤¹¡Ä¡×");
@@ -4043,7 +3943,7 @@ void monster_gain_exp(int m_idx, int s_idx)
        if (m_idx == p_ptr->riding) new_exp = (new_exp + 1) / 2;
        if (!dun_level) new_exp /= 5;
        m_ptr->exp += new_exp;
-       if (m_ptr->mflag2 & MFLAG_CHAMELEON) return;
+       if (m_ptr->mflag2 & MFLAG2_CHAMELEON) return;
 
        if (m_ptr->exp >= r_ptr->next_exp)
        {
@@ -4051,11 +3951,20 @@ void monster_gain_exp(int m_idx, int s_idx)
                int old_hp = m_ptr->hp;
                int old_maxhp = m_ptr->max_maxhp;
                int old_r_idx = m_ptr->r_idx;
-               int i;
+               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);
@@ -4074,24 +3983,18 @@ void monster_gain_exp(int m_idx, int s_idx)
                m_ptr->hp = old_hp * m_ptr->maxhp / old_maxhp;
 
                /* Extract the monster base speed */
-               m_ptr->mspeed = r_ptr->speed;
+               m_ptr->mspeed = get_mspeed(r_ptr);
 
-               /* Hack -- small racial variety */
-               if (!(r_ptr->flags1 & RF1_UNIQUE) && !p_ptr->inside_arena)
+               /* Sub-alignment of a monster */
+               if (!is_pet(m_ptr) && !(r_ptr->flags3 & (RF3_EVIL | RF3_GOOD)))
+                       m_ptr->sub_align = old_sub_align;
+               else
                {
-                       /* Allow some small variation per monster */
-                 if(rand_int(4) == 1){
-                       i = extract_energy[r_ptr->speed] / 3;
-                       if (i) m_ptr->mspeed += rand_spread(0, i);
-                 }
-                 else{
-                       i = extract_energy[r_ptr->speed] / 10;
-                       if (i) m_ptr->mspeed += rand_spread(0, i);
-                 }
+                       m_ptr->sub_align = SUB_ALIGN_NEUTRAL;
+                       if (r_ptr->flags3 & RF3_EVIL) m_ptr->sub_align |= SUB_ALIGN_EVIL;
+                       if (r_ptr->flags3 & RF3_GOOD) m_ptr->sub_align |= SUB_ALIGN_GOOD;
                }
 
-               if (m_ptr->mspeed > 199) m_ptr->mspeed = 199;
-
                m_ptr->exp = 0;
 
                if (is_pet(m_ptr) || m_ptr->ml)