/* 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)
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;
for (i = start; ((i < start + m_max) && (i > start - m_max)); i+=plus)
{
int dummy = (i % m_max);
- bool can_pass_wall;
if (!dummy) continue;
/* Monster must be 'an enemy' */
if (!are_enemies(m_ptr, t_ptr)) continue;
- can_pass_wall = (((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall))) || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding)));
-
/* Monster must be projectable if we can't pass through walls */
- if (!can_pass_wall &&
- !projectable(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx))
+ if (((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) ||
+ ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding)))
{
- continue;
+ if (!in_disintegration_range(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) continue;
}
- if (can_pass_wall &&
- !in_disintegration_range(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx))
+ else
{
- continue;
+ if (!projectable(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) continue;
}
/* OK -- we've got a target */
* 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];
char m_name[160];
- bool seen = m_ptr->ml;
+ bool seen = is_seen(m_ptr);
/* Can the player be aware of this attack? */
bool known = (m_ptr->cdis <= MAX_SIGHT);
monster_desc(m_name, m_ptr, 0);
/* Redraw (later) if needed */
- if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
- if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+ if (m_ptr->ml)
+ {
+ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+ }
/* Wake it up */
- m_ptr->csleep = 0;
+ (void)set_monster_csleep(m_idx, 0);
if (p_ptr->riding && (m_idx == p_ptr->riding)) disturb(1, 0);
- if (m_ptr->invulner && randint0(PENETRATE_INVULNERABILITY))
+ if (MON_INVULNER(m_ptr) && randint0(PENETRATE_INVULNERABILITY))
{
if (seen)
{
return;
}
- if (r_ptr->flags3 & RF3_RES_ALL)
+ if (r_ptr->flagsr & RFR_RES_ALL)
{
if(dam > 0)
{
/* 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;
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)
{
#ifdef ALLOW_FEAR
/* Mega-Hack -- Pain cancels fear */
- if (m_ptr->monfear && (dam > 0))
+ if (MON_MONFEAR(m_ptr) && (dam > 0))
{
- int tmp = randint1(dam / 4);
-
- /* Cure a little fear */
- if (tmp < m_ptr->monfear)
- {
- /* Reduce fear */
- m_ptr->monfear -= tmp;
- }
-
- /* Cure all the fear */
- else
+ /* Cure fear */
+ if (set_monster_monfear(m_idx, MON_MONFEAR(m_ptr) - randint1(dam / 4)))
{
- /* Cure fear */
- m_ptr->monfear = 0;
-
/* No more fear */
(*fear) = FALSE;
}
}
/* Sometimes a monster gets scared by damage */
- if (!m_ptr->monfear && !(r_ptr->flags3 & RF3_NO_FEAR))
+ if (!MON_MONFEAR(m_ptr) && !(r_ptr->flags3 & RF3_NO_FEAR))
{
- int percentage;
-
/* Percentage of fully healthy */
- percentage = (100L * m_ptr->hp) / m_ptr->maxhp;
+ int percentage = (100L * m_ptr->hp) / m_ptr->maxhp;
/*
* Run (sometimes) if at 10% or less of max hit points,
(*fear) = TRUE;
/* XXX XXX XXX Hack -- Add some timed fear */
- m_ptr->monfear += (randint1(10) +
+ (void)set_monster_monfear(m_idx, (randint1(10) +
(((dam >= m_ptr->hp) && (percentage > 7)) ?
- 20 : ((11 - percentage) * 5)));
+ 20 : ((11 - percentage) * 5))));
}
}
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))
{
set_target(m_ptr, m_list[who].fy, m_list[who].fx);
}
if (m_ptr->cdis > MAX_SIGHT + 5) return (FALSE);
/* All "afraid" monsters will run away */
- if (m_ptr->monfear) return (TRUE);
+ if (MON_MONFEAR(m_ptr)) return (TRUE);
#ifdef ALLOW_TERROR
if (!in_bounds2(y, x)) continue;
/* Simply move to player */
- if ((y == py) && (x == px)) return (FALSE);
+ 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 (!(((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding))))
{
if (cost == 0) continue;
if (!can_open_door && is_closed_door(c_ptr->feat)) continue;
int i, y, x, y1, x1, best;
cave_type *c_ptr;
- bool use_sound = FALSE;
bool use_scent = FALSE;
monster_type *m_ptr = &m_list[m_idx];
if (no_flow) return (FALSE);
/* Monster can go through rocks */
- if ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall))) return (FALSE);
- if (r_ptr->flags2 & RF2_KILL_WALL) return (FALSE);
- if (!cave_floor_bold(py, px) && (cave[py][px].feat != FEAT_TREES)) return (FALSE);
+ if ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) return (FALSE);
+ if ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding)) return (FALSE);
/* Monster location */
y1 = m_ptr->fy;
x1 = m_ptr->fx;
/* Hack -- Player can see us, run towards him */
- if (player_has_los_bold(y1, x1)) return (FALSE);
+ if (player_has_los_bold(y1, x1) && projectable(py, px, y1, x1)) return (FALSE);
/* Monster grid */
c_ptr = &cave[y1][x1];
/* If we can hear noises, advance towards them */
if (c_ptr->cost)
{
- use_sound = TRUE;
best = 999;
}
c_ptr = &cave[y][x];
/* Skip locations in a wall */
- if (!cave_floor_grid(c_ptr)) continue;
+ if (!monster_can_cross_terrain(c_ptr->feat, &r_info[m_ptr->r_idx], (m_idx == p_ptr->riding) ? CEM_RIDING : 0)) continue;
/* Check for "availability" (if monsters can flow) */
- if (!(m_ptr->mflag2 & MFLAG_NOFLOW))
+ if (!(m_ptr->mflag2 & MFLAG2_NOFLOW))
{
/* Ignore grids very far from the player */
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 (!player_has_los_grid(c_ptr))
+ if (!projectable(py, px, y, x))
{
-
/* Calculate distance from player */
dis = distance(y, x, py, px);
static bool find_hiding(int m_idx, int *yp, int *xp)
{
monster_type *m_ptr = &m_list[m_idx];
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
int fy = m_ptr->fy;
int fx = m_ptr->fx;
int gy = 0, gx = 0, gdis = 999;
sint *y_offsets, *x_offsets;
-
- cave_type *c_ptr;
/* Start with adjacent locations, spread further */
for (d = 1; d < 10; d++)
{
y = fy + dy;
x = fx + dx;
-
+
/* Skip illegal locations */
if (!in_bounds(y, x)) continue;
- c_ptr = &cave[y][x];
-
/* Skip occupied locations */
- if (!cave_empty_grid(c_ptr)) continue;
+ if (!monster_can_enter(y, x, r_ptr, 0)) continue;
/* Check for hidden, available grid */
- if (!player_has_los_grid(c_ptr) && clean_shot(fy, fx, y, x, FALSE))
+ if (!projectable(py, px, y, x) && clean_shot(fy, fx, y, x, FALSE))
{
/* Calculate distance from player */
dis = distance(y, x, py, px);
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;
-
- /* Flow towards the player */
- (void)get_moves_aux(m_idx, &y2, &x2, no_flow);
+ 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));
- can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall)));
+ /* Counter attack to an enemy monster */
+ if (!will_run && m_ptr->target_y)
+ {
+ 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) &&
+ projectable(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 (!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) ||
+ ((los(m_ptr->fy, m_ptr->fx, py, px) && projectable(m_ptr->fy, m_ptr->fx, py, px)) ||
(cave[m_ptr->fy][m_ptr->fx].dist < MAX_SIGHT / 2)))
{
/*
/* 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(y, x)) 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)) &&
- monster_can_cross_terrain(c_ptr->feat, r_ptr))
+ if (monster_can_cross_terrain(c_ptr->feat, r_ptr, 0))
{
/* One more room grid */
room++;
if (!in_bounds2(y2, x2)) continue;
/* Ignore filled grids */
- c_ptr = &cave[y2][x2];
- if (!cave_empty_grid(c_ptr)) continue;
+ if (!monster_can_enter(y2, x2, r_ptr, 0)) continue;
/* Try to fill this hole */
break;
}
}
+ 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 (is_pet(m_ptr) && will_run)
{
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)
}
+#define BLOW_EFFECT_TYPE_NONE 0
+#define BLOW_EFFECT_TYPE_FEAR 1
+#define BLOW_EFFECT_TYPE_SLEEP 2
+#define BLOW_EFFECT_TYPE_HEAL 3
+
+
/* Monster attacks monster */
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 temp[80];
- bool blinked, heal_effect;
+ char temp[MAX_NLEN];
+ bool blinked;
bool explode = FALSE, touched = FALSE, fear = FALSE;
int y_saver = t_ptr->fy;
int x_saver = t_ptr->fx;
+ int effect_type;
- bool see_m = m_ptr->ml;
- bool see_t = t_ptr->ml;
+ bool see_m = is_seen(m_ptr);
+ bool see_t = is_seen(t_ptr);
bool see_either = see_m || see_t;
/* Can the player be aware of this attack? */
if (d_info[dungeon_type].flags1 & DF1_NO_MELEE) return (FALSE);
- /* Wake it up */
- t_ptr->csleep = 0;
-
/* Total armor */
ac = tr_ptr->ac;
/* Hack -- no more attacks */
if (!method) break;
- if (blinked) /* Stop! */
- {
- /* break; */
- }
-
if (method == RBM_SHOOT) continue;
/* 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;
- }
-
+ power = mbe_info[effect].power;
/* Monster hits */
- if (!effect || check_hit2(power, rlev, ac, m_ptr->stunned))
+ if (!effect || check_hit2(power, rlev, ac, MON_STUNNED(m_ptr)))
{
+ /* Wake it up */
+ (void)set_monster_csleep(t_idx, 0);
+
+ if (t_ptr->ml)
+ {
+ /* Redraw the health bar */
+ if (p_ptr->health_who == t_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (p_ptr->riding == t_idx) p_ptr->redraw |= (PR_UHEALTH);
+ }
+
/* Describe the attack method */
switch (method)
{
/* Message */
if (act && see_either)
{
+#ifdef JP
+ if (do_silly_attack) act = silly_attacks2[randint0(MAX_SILLY_ATTACK)];
+ strfmt(temp, act, t_name);
+ msg_format("%^s¤Ï%s", m_name, temp);
+#else
if (do_silly_attack)
{
act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
+ strfmt(temp, "%s %s.", act, t_name);
}
- strfmt(temp, act, t_name);
-#ifdef JP
- msg_format("%^s¤Ï%s", m_name, temp);
-#else
+ else strfmt(temp, act, t_name);
msg_format("%^s %s", m_name, temp);
#endif
-
}
/* Hack -- assume all attacks are obvious */
/* Roll out the damage */
damage = damroll(d_dice, d_side);
- /* Assume no healing effect */
- heal_effect = FALSE;
+ /* Assume no effect */
+ effect_type = BLOW_EFFECT_TYPE_NONE;
pt = GF_MISSILE;
switch (effect)
{
case 0:
- {
- damage = 0;
- pt = 0;
- break;
- }
+ case RBE_DR_MANA:
+ damage = pt = 0;
+ break;
case RBE_SUPERHURT:
+ if ((randint1(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;
- }
- }
- case RBE_HURT:
- {
- damage -= (damage * ((ac < 150) ? ac : 150) / 250);
+ int tmp_damage = damage - (damage * ((ac < 150) ? ac : 150) / 250);
+ damage = MAX(damage, tmp_damage * 2);
break;
}
+ /* Fall through */
+
+ case RBE_HURT:
+ damage -= (damage * ((ac < 150) ? ac : 150) / 250);
+ break;
+
case RBE_POISON:
case RBE_DISEASE:
- {
- pt = GF_POIS;
- break;
- }
+ pt = GF_POIS;
+ break;
case RBE_UN_BONUS:
case RBE_UN_POWER:
- {
- pt = GF_DISENCHANT;
- break;
- }
-
- case RBE_EAT_FOOD:
- case RBE_EAT_LITE:
- case RBE_DR_MANA:
- {
- pt = damage = 0;
- break;
- }
+ pt = GF_DISENCHANT;
+ break;
case RBE_EAT_ITEM:
case RBE_EAT_GOLD:
- {
- pt = damage = 0;
- if (one_in_(2)) blinked = TRUE;
- break;
- }
+ if ((p_ptr->riding != m_idx) && one_in_(2)) blinked = TRUE;
+ break;
+
+ case RBE_EAT_FOOD:
+ case RBE_EAT_LITE:
+ case RBE_BLIND:
+ case RBE_LOSE_STR:
+ case RBE_LOSE_INT:
+ case RBE_LOSE_WIS:
+ case RBE_LOSE_DEX:
+ case RBE_LOSE_CON:
+ case RBE_LOSE_CHR:
+ case RBE_LOSE_ALL:
+ break;
case RBE_ACID:
- {
- pt = GF_ACID;
- break;
- }
+ pt = GF_ACID;
+ break;
case RBE_ELEC:
- {
- pt = GF_ELEC;
- break;
- }
+ pt = GF_ELEC;
+ break;
case RBE_FIRE:
- {
- pt = GF_FIRE;
- break;
- }
+ pt = GF_FIRE;
+ break;
case RBE_COLD:
- {
- pt = GF_COLD;
- break;
- }
-
- case RBE_BLIND:
- {
- break;
- }
+ pt = GF_COLD;
+ break;
case RBE_CONFUSE:
- {
- pt = GF_CONFUSION;
- break;
- }
+ pt = GF_CONFUSION;
+ break;
case RBE_TERRIFY:
- {
- pt = GF_TURN_ALL;
- break;
- }
+ effect_type = BLOW_EFFECT_TYPE_FEAR;
+ break;
case RBE_PARALYZE:
- {
- pt = GF_OLD_SLEEP; /* sort of close... */
- break;
- }
+ effect_type = BLOW_EFFECT_TYPE_SLEEP;
+ break;
- case RBE_LOSE_STR:
- case RBE_LOSE_INT:
- case RBE_LOSE_WIS:
- case RBE_LOSE_DEX:
- case RBE_LOSE_CON:
- case RBE_LOSE_CHR:
- case RBE_LOSE_ALL:
- {
- break;
- }
case RBE_SHATTER:
- {
- if (damage > 23)
- {
- earthquake(m_ptr->fy, m_ptr->fx, 8);
- }
- break;
- }
+ damage -= (damage * ((ac < 150) ? ac : 150) / 250);
+ if (damage > 23) earthquake_aux(m_ptr->fy, m_ptr->fx, 8, m_idx);
+ break;
+
case RBE_EXP_10:
case RBE_EXP_20:
case RBE_EXP_40:
case RBE_EXP_80:
- {
- pt = GF_NETHER;
- break;
- }
+ pt = GF_NETHER;
+ break;
+
case RBE_TIME:
- {
- pt = GF_TIME;
- break;
- }
+ pt = GF_TIME;
+ break;
+
case RBE_EXP_VAMP:
- {
- pt = GF_OLD_DRAIN;
- heal_effect = TRUE;
- break;
- }
+ pt = GF_OLD_DRAIN;
+ effect_type = BLOW_EFFECT_TYPE_HEAL;
+ break;
default:
- {
- pt = 0;
- break;
- }
+ pt = 0;
+ break;
}
if (pt)
if (!explode)
{
project(m_idx, 0, t_ptr->fy, t_ptr->fx,
- (pt == GF_OLD_SLEEP ? r_ptr->level : damage), pt, PROJECT_KILL | PROJECT_STOP | PROJECT_MONSTER, -1);
+ damage, pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
}
- if (heal_effect)
+ switch (effect_type)
{
+ case BLOW_EFFECT_TYPE_FEAR:
+ project(m_idx, 0, t_ptr->fy, t_ptr->fx,
+ damage, GF_TURN_ALL, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+ break;
+
+ case BLOW_EFFECT_TYPE_SLEEP:
+ project(m_idx, 0, t_ptr->fy, t_ptr->fx,
+ r_ptr->level, GF_OLD_SLEEP, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+ break;
+
+ case BLOW_EFFECT_TYPE_HEAL:
if ((monster_living(tr_ptr)) && (damage > 2))
{
bool did_heal = FALSE;
if (see_m && did_heal)
{
#ifdef JP
-msg_format("%s¤ÏÂÎÎϤò²óÉü¤·¤¿¤è¤¦¤À¡£", m_name);
+ msg_format("%s¤ÏÂÎÎϤò²óÉü¤·¤¿¤è¤¦¤À¡£", m_name);
#else
msg_format("%^s appears healthier.", m_name);
#endif
-
}
}
+ break;
}
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)
+ {
#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 (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_FIRE;
+ project(t_idx, 0, m_ptr->fy, m_ptr->fx,
+ damroll (1 + ((tr_ptr->level) / 26),
+ 1 + ((tr_ptr->level) / 17)),
+ GF_FIRE, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+ }
+ else
+ {
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
}
- project(t_idx, 0, m_ptr->fy, m_ptr->fx,
- damroll (1 + ((tr_ptr->level) / 26),
- 1 + ((tr_ptr->level) / 17)),
- GF_FIRE, PROJECT_KILL | PROJECT_STOP | PROJECT_MONSTER, -1);
}
/* Aura cold */
- if ((tr_ptr->flags3 & RF3_AURA_COLD) &&
- !(r_ptr->flags3 & RF3_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)
+ {
#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 (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags3 |= RF3_AURA_COLD;
+ project(t_idx, 0, m_ptr->fy, m_ptr->fx,
+ damroll (1 + ((tr_ptr->level) / 26),
+ 1 + ((tr_ptr->level) / 17)),
+ GF_COLD, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+ }
+ else
+ {
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
}
- project(t_idx, 0, m_ptr->fy, m_ptr->fx,
- damroll (1 + ((tr_ptr->level) / 26),
- 1 + ((tr_ptr->level) / 17)),
- GF_COLD, PROJECT_KILL | PROJECT_STOP | PROJECT_MONSTER, -1);
}
/* Aura elec */
- if ((tr_ptr->flags2 & (RF2_AURA_ELEC)) &&
- !(r_ptr->flags3 & (RF3_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)
+ {
#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 (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_ELEC;
+ project(t_idx, 0, m_ptr->fy, m_ptr->fx,
+ damroll (1 + ((tr_ptr->level) / 26),
+ 1 + ((tr_ptr->level) / 17)),
+ GF_ELEC, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+ }
+ else
+ {
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
}
- 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);
}
-
}
}
}
case RBM_ENGULF:
case RBM_CHARGE:
{
+ /* Wake it up */
+ (void)set_monster_csleep(t_idx, 0);
+
/* Visible monsters */
if (see_m)
{
/* Message */
#ifdef JP
-msg_format("%s¤Ï%^s¤Î¹¶·â¤ò¤«¤ï¤·¤¿¡£", t_name,m_name);
+ msg_format("%s¤Ï%^s¤Î¹¶·â¤ò¤«¤ï¤·¤¿¡£", t_name,m_name);
#else
msg_format("%^s misses %s.", m_name, t_name);
#endif
-
}
break;
/* Analyze "visible" monsters only */
- if (see_m && !do_silly_attack)
+ if (is_original_ap_and_seen(m_ptr) && !do_silly_attack)
{
/* Count "obvious" attacks (and ones that cause damage) */
if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10))
sound(SOUND_EXPLODE);
/* Cancel Invulnerability */
- if (m_ptr->invulner) m_ptr->invulner = 0;
+ (void)set_monster_invulner(m_idx, 0, FALSE);
#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
-
blinked = FALSE;
}
-
/* Blink away */
- if (blinked)
+ if (blinked && m_ptr->r_idx)
{
- if (see_m)
+ if (teleport_barrier(m_idx))
{
+ if (see_m)
+ {
#ifdef JP
-msg_print("Å¥ËÀ¤Ï¾Ð¤Ã¤Æƨ¤²¤¿¡ª");
+ msg_print("Å¥ËÀ¤Ï¾Ð¤Ã¤Æƨ¤²...¤è¤¦¤È¤·¤¿¤¬¥Ð¥ê¥¢¤ËËɤ¬¤ì¤¿¡£");
#else
- msg_print("The thief flees laughing!");
+ msg_print("The thief flees laughing...? But magic barrier obstructs it.");
#endif
-
+ }
+ else if (known)
+ {
+ mon_fight = TRUE;
+ }
}
- else if (known)
+ else
{
- mon_fight = TRUE;
- }
+ if (see_m)
+ {
+#ifdef JP
+ msg_print("Å¥ËÀ¤Ï¾Ð¤Ã¤Æƨ¤²¤¿¡ª");
+#else
+ msg_print("The thief flees laughing!");
+#endif
+ }
+ else if (known)
+ {
+ mon_fight = TRUE;
+ }
- teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE);
+ teleport_away(m_idx, MAX_SIGHT * 2 + 5, 0L);
+ }
}
return TRUE;
}
-/*
- * Hack -- local "player stealth" value (see below)
- */
-static u32b noise = 0L;
+static bool check_hp_for_feat_destruction(feature_type *f_ptr, monster_type *m_ptr)
+{
+ return !have_flag(f_ptr->flags, FF_GLASS) ||
+ (r_info[m_ptr->r_idx].flags2 & RF2_STUPID) ||
+ (m_ptr->hp >= MAX(m_ptr->maxhp / 3, 200));
+}
/*
int mm[8];
cave_type *c_ptr;
+ feature_type *f_ptr;
monster_type *y_ptr;
bool do_turn;
bool do_move;
bool do_view;
+ bool must_alter_to_move;
bool did_open_door;
bool did_bash_door;
bool did_pass_wall;
bool did_kill_wall;
bool gets_angry = FALSE;
- bool can_pass_wall;
+ bool can_cross;
bool aware = TRUE;
bool fear;
- if ((m_idx == p_ptr->riding) && !(r_ptr->flags7 & RF7_RIDING))
+ bool is_riding_mon = (m_idx == p_ptr->riding);
+
+ bool see_m = is_seen(m_ptr);
+
+ if (is_riding_mon && !(r_ptr->flags7 & RF7_RIDING))
{
if (rakuba(0, TRUE))
{
}
}
- if ((m_ptr->mflag2 & MFLAG_CHAMELEON) && one_in_(13) && !m_ptr->csleep)
+ if ((m_ptr->mflag2 & MFLAG2_CHAMELEON) && one_in_(13) && !MON_CSLEEP(m_ptr))
{
choose_new_monster(m_idx, FALSE, 0);
r_ptr = &r_info[m_ptr->r_idx];
if (randint0(tmp) > (r_ptr->level+20)) aware = FALSE;
}
+ /* Are there its parent? */
+ if (m_ptr->parent_m_idx && !m_list[m_ptr->parent_m_idx].r_idx)
+ {
+ /* Its parent have gone, it also goes away. */
+
+ if (see_m)
+ {
+ char m_name[80];
+
+ /* Acquire the monster name */
+ monster_desc(m_name, m_ptr, 0);
+
+#ifdef JP
+ msg_format("%s¤Ï¾Ã¤¨µî¤Ã¤¿¡ª", m_name);
+#else
+ msg_format("%^s disappears!", m_name);
+#endif
+ }
+
+ if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname)
+ {
+ char m_name[80];
+
+ monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE);
+ do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_LOSE_PARENT, m_name);
+ }
+
+ /* Delete the monster */
+ delete_monster_idx(m_idx);
+
+ return;
+ }
+
/* Quantum monsters are odd */
if (r_ptr->flags2 & (RF2_QUANTUM))
{
if (is_pet(m_ptr) && !(m_ptr->ml))
sad = TRUE;
- if (m_ptr->ml)
+ if (see_m)
{
char m_name[80];
/* Oops */
#ifdef JP
-msg_format("%s¤Ï¾Ã¤¨µî¤Ã¤¿¡ª", m_name);
+ msg_format("%s¤Ï¾Ã¤¨µî¤Ã¤¿¡ª", m_name);
#else
msg_format("%^s disappears!", m_name);
#endif
-
}
/* Generate treasure, etc */
if (sad)
{
#ifdef JP
-msg_print("¾¯¤·¤Î´ÖÈᤷ¤¤µ¤Ê¬¤Ë¤Ê¤Ã¤¿¡£");
+ msg_print("¾¯¤·¤Î´ÖÈᤷ¤¤µ¤Ê¬¤Ë¤Ê¤Ã¤¿¡£");
#else
msg_print("You feel sad for a moment.");
#endif
-
}
return;
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;
char m_name[80];
monster_desc(m_name, m_ptr, 0);
- if (m_idx == p_ptr->riding && riding_pinch < 2)
+ if (is_riding_mon && riding_pinch < 2)
{
#ifdef JP
msg_format("%s¤Ï½ý¤ÎÄˤµ¤Î;¤ê¤¢¤Ê¤¿¤Î«Çû¤«¤éƨ¤ì¤è¤¦¤È¤·¤Æ¤¤¤ë¡£", m_name);
riding_pinch++;
disturb(1, 0);
}
- else
+ else
{
- if (m_idx == p_ptr->riding)
+ if (is_riding_mon)
{
#ifdef JP
msg_format("%s¤Ï¤¢¤Ê¤¿¤Î«Çû¤«¤éæ½Ð¤·¤¿¡£", m_name);
}
}
- if (m_ptr->ml)
+ if (see_m)
{
- 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))
+ 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) &&
+ player_has_los_bold(m_ptr->fy, m_ptr->fx) && projectable(m_ptr->fy, m_ptr->fx, py, px))
{
#ifdef JP
msg_format("%^s¡Ö¥Ô¥ó¥Á¤À¡ªÂàµÑ¤µ¤»¤Æ¤â¤é¤¦¡ª¡×", m_name);
#endif
}
- if (m_idx == p_ptr->riding && rakuba(-1, FALSE))
+ if (is_riding_mon && rakuba(-1, FALSE))
{
#ifdef JP
msg_print("ÃÏÌ̤ËÍî¤È¤µ¤ì¤¿¡£");
#endif
}
+ /* Check for quest completion */
+ check_quest_completion(m_ptr);
+
delete_monster_idx(m_idx);
return;
else
{
/* Reset the counter */
- if (m_idx == p_ptr->riding) riding_pinch = 0;
- }
-
- }
-
- /* Handle Invulnerability */
- if (m_ptr->invulner)
- {
- /* Reduce by one, note if expires */
- m_ptr->invulner--;
-
- if (!(m_ptr->invulner) && 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 invulnerable.", m_name);
-#endif
-
- m_ptr->energy_need += ENERGY_NEED();
- if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
- if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+ if (is_riding_mon) riding_pinch = 0;
}
}
- /* Handle fast */
- if (m_ptr->fast)
+ /* Handle "sleep" */
+ if (MON_CSLEEP(m_ptr))
{
- /* Reduce by one, note if expires */
- m_ptr->fast--;
-
- if (!(m_ptr->fast) && 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 fast.", m_name);
-#endif
+ /* Handle non-aggravation - Still sleeping */
+ if (!(p_ptr->cursed & TRC_AGGRAVATE)) return;
- if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
- if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
- }
- }
+ /* Handle aggravation */
- /* Handle slow */
- if (m_ptr->slow)
- {
- /* Reduce by one, note if expires */
- m_ptr->slow--;
+ /* Reset sleep counter */
+ (void)set_monster_csleep(m_idx, 0);
- if (!(m_ptr->slow) && m_ptr->ml)
+ /* Notice the "waking up" */
+ if (m_ptr->ml)
{
char m_name[80];
/* Dump a message */
#ifdef JP
-msg_format("%^s¤Ï¤â¤¦¸ºÂ®¤µ¤ì¤Æ¤¤¤Ê¤¤¡£", m_name);
+ msg_format("%^s¤¬Ìܤò³Ð¤Þ¤·¤¿¡£", m_name);
#else
- msg_format("%^s is no longer slow.", m_name);
+ msg_format("%^s wakes up.", 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);
}
- }
-
- /* Handle "sleep" */
- if (m_ptr->csleep)
- {
- u32b notice = 0;
-
- /* Hack -- handle non-aggravation */
- if (!(p_ptr->cursed & TRC_AGGRAVATE)) notice = randint0(1024);
- /* Nightmare monsters are more alert */
- if (ironman_nightmare) notice /= 2;
-
- /* Hack -- See if monster "notices" player */
- if ((notice * notice * notice) <= noise)
+ /* Hack -- Count the wakings */
+ if (is_original_ap_and_seen(m_ptr) && (r_ptr->r_wake < MAX_UCHAR))
{
- /* 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->cursed & TRC_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)
- {
- 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);
-#else
- msg_format("%^s wakes up.", m_name);
-#endif
-
-
- /* Redraw the health bar */
- if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
- if (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++;
- }
- }
- }
+ r_ptr->r_wake++;
}
-
- /* Still sleeping */
- if (m_ptr->csleep) return;
}
-
/* Handle "stun" */
- if (m_ptr->stunned)
- {
- int d = 1;
-
- /* Make a "saving throw" against stun */
- if (randint0(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 */
-#ifdef JP
-msg_format("%^s¤ÏÛ¯Û°¾õÂÖ¤«¤éΩ¤Áľ¤Ã¤¿¡£", m_name);
-#else
- msg_format("%^s is no longer stunned.", 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);
- }
- }
-
- /* Still stunned */
- if (m_ptr->stunned && one_in_(2)) return;
- }
-
-
- /* Handle confusion */
- if (m_ptr->confused)
+ if (MON_STUNNED(m_ptr))
{
- /* Amount of "boldness" */
- int d = randint1(r_ptr->level / 20 + 1);
-
- /* Still confused */
- if (m_ptr->confused > d)
- {
- /* Reduce the confusion */
- m_ptr->confused -= d;
- }
-
- /* 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);
- }
- }
+ /* Sometimes skip move */
+ if (one_in_(2)) return;
}
- if (p_ptr->riding == m_idx)
+ if (is_riding_mon)
{
p_ptr->update |= (PU_BONUS);
}
/* 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;
if (gets_angry)
{
- char m_name[80];
- monster_desc(m_name, m_ptr, 0);
-#ifdef JP
-msg_format("%^s¤ÏÆÍÁ³Å¨¤Ë¤Þ¤ï¤Ã¤¿¡ª", m_name);
-#else
- msg_format("%^s suddenly becomes hostile!", m_name);
-#endif
-
- set_hostile(m_ptr);
- }
-
- /* Handle "fear" */
- if (m_ptr->monfear)
- {
- /* Amount of "boldness" */
- int d = randint1(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
+ if (is_pet(m_ptr) || see_m)
{
- /* 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 */
+ char m_name[80];
+ monster_desc(m_name, m_ptr, is_pet(m_ptr) ? MD_ASSUME_VISIBLE : 0);
#ifdef JP
-msg_format("%^s¤Ïͦµ¤¤ò¼è¤êÌᤷ¤¿¡£", m_name);
+ msg_format("%^s¤ÏÆÍÁ³Å¨¤Ë¤Þ¤ï¤Ã¤¿¡ª", m_name);
#else
- msg_format("%^s recovers %s courage.", m_name, m_poss);
+ msg_format("%^s suddenly becomes hostile!", m_name);
#endif
-
- if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
- }
}
+
+ set_hostile(m_ptr);
}
/* Get the origin */
}
}
+ /* Hex */
+ if (multiply_barrier(m_idx)) k = 8;
+
/* Hack -- multiply slower in crowded areas */
if ((k < 4) && (!k || !randint0(k * MON_MULT_ADJ)))
{
if (multiply_monster(m_idx, FALSE, (is_pet(m_ptr) ? PM_FORCE_PET : 0)))
{
/* Take note if visible */
- if (m_ptr->ml)
+ if (m_list[hack_m_idx_ii].ml && is_original_ap_and_seen(m_ptr))
{
r_ptr->r_flags2 |= (RF2_MULTIPLY);
}
}
+ 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 && is_original_ap_and_seen(m_ptr)) r_ptr->r_flags6 |= (RF6_SPECIAL);
+ }
+ }
+ }
+ }
+
+
if (!p_ptr->inside_battle)
{
/* Hack! "Cyber" monster makes noise... */
{
if (disturb_minor) disturb(FALSE, FALSE);
#ifdef JP
-msg_print("½Å¸ü¤Ê²»¤¬Ê¹¤³¤¨¤¿¡£");
+ msg_print("½Å¸ü¤Ê²»¤¬Ê¹¤³¤¨¤¿¡£");
#else
msg_print("You hear heavy steps.");
#endif
-
}
/* Some monsters can speak */
if ((ap_r_ptr->flags2 & RF2_CAN_SPEAK) && aware &&
- one_in_(SPEAK_CHANCE) &&
- player_has_los_bold(oy, ox))
+ one_in_(SPEAK_CHANCE) &&
+ player_has_los_bold(oy, ox) &&
+ projectable(oy, ox, py, px))
{
char m_name[80];
char monmessage[1024];
monster_desc(m_name, m_ptr, 0);
else
#ifdef JP
-strcpy(m_name, "¤½¤ì");
+ strcpy(m_name, "¤½¤ì");
#else
strcpy(m_name, "It");
#endif
-
/* Select the file for monster quotes */
- if (m_ptr->monfear)
+ if (MON_MONFEAR(m_ptr))
#ifdef JP
-filename = "monfear_j.txt";
+ filename = "monfear_j.txt";
#else
filename = "monfear.txt";
#endif
-
else if (is_pet(m_ptr))
#ifdef JP
-filename = "monpet_j.txt";
+ filename = "monpet_j.txt";
#else
filename = "monpet.txt";
#endif
-
else if (is_friendly(m_ptr))
#ifdef JP
-filename = "monfrien_j.txt";
+ filename = "monfrien_j.txt";
#else
filename = "monfrien.txt";
#endif
-
else
#ifdef JP
filename = "monspeak_j.txt";
#else
filename = "monspeak.txt";
#endif
-
-
/* Get the monster line */
if (get_rnd_line(filename, m_ptr->ap_r_idx, monmessage) == 0)
{
}
}
- /* 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;
- can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall)));
+ if (aware && make_attack_spell(m_idx)) return;
+ }
+ }
/* Hack -- Assume no movement */
mm[0] = mm[1] = mm[2] = mm[3] = 0;
/* Confused -- 100% random */
- if (m_ptr->confused || !aware)
+ if (MON_CONFUSED(m_ptr) || !aware)
{
/* Try four "random" directions */
mm[0] = mm[1] = mm[2] = mm[3] = 5;
}
/* 75% random movement */
- else if ((r_ptr->flags1 & RF1_RAND_50) &&
- (r_ptr->flags1 & RF1_RAND_25) &&
+ else if (((r_ptr->flags1 & (RF1_RAND_50 | RF1_RAND_25)) == (RF1_RAND_50 | RF1_RAND_25)) &&
(randint0(100) < 75))
{
/* Memorize flags */
- if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_50);
- if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_25);
+ if (is_original_ap_and_seen(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;
(randint0(100) < 50))
{
/* Memorize flags */
- if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_50);
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags1 |= (RF1_RAND_50);
/* Try four "random" directions */
mm[0] = mm[1] = mm[2] = mm[3] = 5;
(randint0(100) < 25))
{
/* Memorize flags */
- if (m_ptr->ml) r_ptr->r_flags1 |= RF1_RAND_25;
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags1 |= RF1_RAND_25;
/* Try four "random" directions */
mm[0] = mm[1] = mm[2] = mm[3] = 5;
}
/* Find the player */
- get_moves(m_idx, mm);
+ (void)get_moves(m_idx, mm);
/* Restore the leash */
p_ptr->pet_follow_distance = dis;
do_turn = FALSE;
do_move = FALSE;
do_view = FALSE;
+ must_alter_to_move = FALSE;
/* Assume nothing */
did_open_door = FALSE;
/* Access that cave grid */
c_ptr = &cave[ny][nx];
+ f_ptr = &f_info[c_ptr->feat];
+ can_cross = monster_can_cross_terrain(c_ptr->feat, r_ptr, is_riding_mon ? CEM_RIDING : 0);
/* Access that cave grid's contents */
y_ptr = &m_list[c_ptr->m_idx];
- /* Floor is open? */
- if (cave_floor_grid(c_ptr))
- {
- /* Go ahead and move */
- do_move = TRUE;
- }
-
/* Hack -- player 'in' wall */
- else if ((ny == py) && (nx == px))
+ if (player_bold(ny, nx))
{
do_move = TRUE;
}
+ /* Possibly a monster to attack */
else if (c_ptr->m_idx)
{
- /* Possibly a monster to attack */
do_move = TRUE;
}
- /* Permanent wall */
- else if ((c_ptr->feat >= FEAT_PERM_EXTRA) &&
- (c_ptr->feat <= FEAT_PERM_SOLID))
- {
- do_move = FALSE;
- }
-
- /* Hack -- semi-transparent terrains are no obstacle */
- else if (c_ptr->feat == FEAT_TREES)
- {
- do_move = TRUE;
- }
-
- /* Hack -- semi-transparent terrains are no obstacle */
- else if ((c_ptr->feat == FEAT_MOUNTAIN) && ((r_ptr->flags2 & RF2_KILL_WALL) || (!dun_level && ((r_ptr->flags7 & RF7_CAN_FLY) || (r_ptr->flags8 & RF8_WILD_MOUNTAIN)))))
- {
- do_move = TRUE;
- }
-
-
- /* Monster moves through walls (and doors) */
- else if (can_pass_wall)
+ /* Monster destroys walls (and doors) */
+ else if ((r_ptr->flags2 & RF2_KILL_WALL) &&
+ (can_cross ? !have_flag(f_ptr->flags, FF_LOS) : !is_riding_mon) &&
+ have_flag(f_ptr->flags, FF_HURT_DISI) && !have_flag(f_ptr->flags, FF_PERMANENT) &&
+ check_hp_for_feat_destruction(f_ptr, m_ptr))
{
- /* Pass through walls/doors/rubble */
+ /* Eat through walls/doors/rubble */
do_move = TRUE;
+ if (!can_cross) must_alter_to_move = TRUE;
- /* Monster went through a wall */
- did_pass_wall = TRUE;
+ /* Monster destroyed a wall (later) */
+ did_kill_wall = TRUE;
}
- /* Monster destroys walls (and doors) */
- else if ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding))
+ /* Floor is open? */
+ else if (can_cross)
{
- /* Eat through walls/doors/rubble */
+ /* Go ahead and move */
do_move = TRUE;
- /* Monster destroyed a wall */
- did_kill_wall = TRUE;
-
- if (one_in_(GRINDNOISE))
+ /* Monster moves through walls (and doors) */
+ if ((r_ptr->flags2 & RF2_PASS_WALL) && (!is_riding_mon || p_ptr->pass_wall) &&
+ have_flag(f_ptr->flags, FF_CAN_PASS))
{
-#ifdef JP
-msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£");
-#else
- msg_print("There is a grinding sound.");
-#endif
-
+ /* Monster went through a wall */
+ did_pass_wall = TRUE;
}
-
- /* Forget the wall */
- c_ptr->info &= ~(CAVE_MARK);
-
- /* Notice */
- cave_set_feat(ny, nx, floor_type[randint0(100)]);
-
- /* Note changes to viewable region */
- if (player_has_los_bold(ny, nx)) do_view = TRUE;
}
/* Handle doors and secret doors */
do_move = FALSE;
/* Creature can open doors. */
- if ((r_ptr->flags2 & RF2_OPEN_DOOR) &&
+ if ((r_ptr->flags2 & RF2_OPEN_DOOR) && have_flag(f_ptr->flags, FF_OPEN) &&
(!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_OPEN_DOORS)))
{
/* Closed doors */
- if (c_ptr->feat == FEAT_DOOR_HEAD)
+ if (!f_ptr->power)
{
/* The door is open */
did_open_door = TRUE;
/* Do not bash the door */
may_bash = FALSE;
- /* Assume no move allowed */
- do_move = TRUE;
+ /* Take a turn */
+ do_turn = TRUE;
}
/* Locked doors (not jammed) */
- else if (c_ptr->feat < FEAT_DOOR_HEAD + 0x08)
+ else
{
- int k;
-
- /* Door power */
- k = ((c_ptr->feat - FEAT_DOOR_HEAD) & 0x07);
-
/* Try to unlock it XXX XXX XXX */
- if (randint0(m_ptr->hp / 10) > k)
+ if (randint0(m_ptr->hp / 10) > f_ptr->power)
{
/* Unlock the door */
- cave_set_feat(ny, nx, FEAT_DOOR_HEAD + 0x00);
+ cave_alter_feat(ny, nx, FF_DISARM);
/* Do not bash the door */
may_bash = FALSE;
+
+ /* Take a turn */
+ do_turn = TRUE;
}
}
}
/* Stuck doors -- attempt to bash them down if allowed */
- if (may_bash && (r_ptr->flags2 & RF2_BASH_DOOR) &&
+ if (may_bash && (r_ptr->flags2 & RF2_BASH_DOOR) && have_flag(f_ptr->flags, FF_BASH) &&
(!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_OPEN_DOORS)))
{
- int k;
-
- /* Door power */
- k = ((c_ptr->feat - FEAT_DOOR_HEAD) & 0x07);
-
/* Attempt to Bash XXX XXX XXX */
- if (randint0(m_ptr->hp / 10) > k)
+ if (check_hp_for_feat_destruction(f_ptr, m_ptr) && (randint0(m_ptr->hp / 10) > f_ptr->power))
{
/* Message */
+ if (have_flag(f_ptr->flags, FF_GLASS))
#ifdef JP
-msg_print("¥É¥¢¤òᤳ«¤±¤ë²»¤¬¤·¤¿¡ª");
+ msg_print("¥¬¥é¥¹¤¬ºÕ¤±¤ë²»¤¬¤·¤¿¡ª");
#else
- msg_print("You hear a door burst open!");
+ msg_print("You hear a glass was crashed!");
+#endif
+ else
+#ifdef JP
+ msg_print("¥É¥¢¤òᤳ«¤±¤ë²»¤¬¤·¤¿¡ª");
+#else
+ msg_print("You hear a door burst open!");
#endif
-
/* Disturb (sometimes) */
if (disturb_minor) disturb(0, 0);
/* Hack -- fall into doorway */
do_move = TRUE;
+ must_alter_to_move = TRUE;
}
}
if (did_open_door || did_bash_door)
{
/* Break down the door */
- if (did_bash_door && (randint0(100) < 50))
+ if (did_bash_door && ((randint0(100) < 50) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS)))
{
- cave_set_feat(ny, nx, FEAT_BROKEN);
+ cave_alter_feat(ny, nx, FF_BASH);
+
+ if (!m_ptr->r_idx) /* Killed by shards of glass, etc. */
+ {
+ /* Update some things */
+ p_ptr->update |= (PU_FLOW);
+ p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_BASH_DOOR);
+
+ return;
+ }
}
/* Open the door */
else
{
- cave_set_feat(ny, nx, FEAT_OPEN);
+ cave_alter_feat(ny, nx, FF_OPEN);
}
+ f_ptr = &f_info[c_ptr->feat];
+
/* Handle viewable doors */
- if (player_has_los_bold(ny, nx)) do_view = TRUE;
+ do_view = TRUE;
}
}
/* Hack -- check for Glyph of Warding */
if (do_move && is_glyph_grid(c_ptr) &&
- !((r_ptr->flags1 & RF1_NEVER_BLOW) && (py == ny) && (px == nx)))
+ !((r_ptr->flags1 & RF1_NEVER_BLOW) && player_bold(ny, nx)))
{
/* Assume no move allowed */
do_move = FALSE;
if (c_ptr->info & CAVE_MARK)
{
#ifdef JP
-msg_print("¼é¤ê¤Î¥ë¡¼¥ó¤¬²õ¤ì¤¿¡ª");
+ msg_print("¼é¤ê¤Î¥ë¡¼¥ó¤¬²õ¤ì¤¿¡ª");
#else
msg_print("The rune of protection is broken!");
#endif
-
}
/* Forget the rune */
}
}
else if (do_move && is_explosive_rune_grid(c_ptr) &&
- !((r_ptr->flags1 & RF1_NEVER_BLOW) && (py == ny) && (px == nx)))
+ !((r_ptr->flags1 & RF1_NEVER_BLOW) && player_bold(ny, nx)))
{
/* Assume no move allowed */
do_move = FALSE;
if (c_ptr->info & CAVE_MARK)
{
#ifdef JP
-msg_print("¥ë¡¼¥ó¤¬Çúȯ¤·¤¿¡ª");
+ msg_print("¥ë¡¼¥ó¤¬Çúȯ¤·¤¿¡ª");
#else
msg_print("The rune explodes!");
#endif
else
{
#ifdef JP
-msg_print("Çúȯ¤Î¥ë¡¼¥ó¤Ï²ò½ü¤µ¤ì¤¿¡£");
+ msg_print("Çúȯ¤Î¥ë¡¼¥ó¤Ï²ò½ü¤µ¤ì¤¿¡£");
#else
msg_print("An explosive rune was disarmed.");
#endif
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 (is_original_ap_and_seen(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 (!MON_CONFUSED(m_ptr))
+ {
+ if (!(r_ptr->flags2 & RF2_STUPID)) do_move = FALSE;
+ else
+ {
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_STUPID);
+ }
+ }
}
- }
- if ((c_ptr->feat >= FEAT_PATTERN_START) &&
- (c_ptr->feat <= FEAT_PATTERN_XTRA2) &&
- !do_turn && !(r_ptr->flags7 & RF7_CAN_FLY))
- {
- do_move = FALSE;
- }
+ /* The player is in the way. Attack him. */
+ if (do_move)
+ {
+ if (!p_ptr->riding || one_in_(2))
+ {
+ /* Do the attack */
+ (void)make_attack_normal(m_idx);
+
+ /* Do not move */
+ do_move = FALSE;
+ /* Took a turn */
+ do_turn = TRUE;
+ }
+ }
+ }
/* A monster is in the way */
if (do_move && c_ptr->m_idx)
{
monster_race *z_ptr = &r_info[y_ptr->r_idx];
- monster_type *m2_ptr = &m_list[c_ptr->m_idx];
/* Assume no movement */
do_move = FALSE;
/* Attack 'enemies' */
- if (((r_ptr->flags2 & (RF2_KILL_BODY)) &&
- (r_ptr->mexp * r_ptr->level > z_ptr->mexp * z_ptr->level) &&
- (cave_floor_grid(c_ptr)) &&
- (c_ptr->m_idx != p_ptr->riding)) ||
- are_enemies(m_ptr, m2_ptr) || m_ptr->confused)
+ if (((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW) &&
+ (r_ptr->mexp * r_ptr->level > z_ptr->mexp * z_ptr->level) &&
+ can_cross && (c_ptr->m_idx != p_ptr->riding)) ||
+ are_enemies(m_ptr, y_ptr) || MON_CONFUSED(m_ptr))
{
- do_move = FALSE;
+ if (!(r_ptr->flags1 & RF1_NEVER_BLOW))
+ {
+ if (r_ptr->flags2 & RF2_KILL_BODY)
+ {
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_KILL_BODY);
+ }
- if (r_ptr->flags2 & RF2_KILL_BODY) r_ptr->r_flags2 |= (RF2_KILL_BODY);
+ /* attack */
+ if (y_ptr->r_idx && (y_ptr->hp >= 0))
+ {
+ if (monst_attack_monst(m_idx, c_ptr->m_idx)) return;
- /* attack */
- if ((m2_ptr->r_idx) && (m2_ptr->hp >= 0))
- {
- if (monst_attack_monst(m_idx, cave[ny][nx].m_idx))
- return;
+ /* In anti-melee dungeon, stupid or confused monster takes useless turn */
+ else if (d_info[dungeon_type].flags1 & DF1_NO_MELEE)
+ {
+ if (MON_CONFUSED(m_ptr)) return;
+ else if (r_ptr->flags2 & RF2_STUPID)
+ {
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_STUPID);
+ return;
+ }
+ }
+ }
}
}
/* Push past weaker monsters (unless leaving a wall) */
- else if ((r_ptr->flags2 & RF2_MOVE_BODY) &&
- (r_ptr->mexp > z_ptr->mexp) && cave_floor_grid(c_ptr) &&
- (cave_floor_grid(&cave[m_ptr->fy][m_ptr->fx])) &&
- (c_ptr->m_idx != p_ptr->riding))
+ else if ((r_ptr->flags2 & RF2_MOVE_BODY) && !(r_ptr->flags1 & RF1_NEVER_MOVE) &&
+ (r_ptr->mexp > z_ptr->mexp) &&
+ can_cross && (c_ptr->m_idx != p_ptr->riding) &&
+ monster_can_cross_terrain(cave[m_ptr->fy][m_ptr->fx].feat, z_ptr, 0))
{
/* Allow movement */
do_move = TRUE;
/* Monster pushed past another monster */
did_move_body = TRUE;
+ /* Wake up the moved monster */
+ (void)set_monster_csleep(c_ptr->m_idx, 0);
+
/* XXX XXX XXX Message */
}
}
+ if (is_riding_mon)
+ {
+ if (!p_ptr->riding_ryoute && !MON_MONFEAR(&m_list[p_ptr->riding])) do_move = FALSE;
+ }
+
+ if (did_kill_wall && do_move)
+ {
+ if (one_in_(GRINDNOISE))
+ {
+ if (have_flag(f_ptr->flags, FF_GLASS))
+#ifdef JP
+ msg_print("²¿¤«¤ÎºÕ¤±¤ë²»¤¬Ê¹¤³¤¨¤ë¡£");
+#else
+ msg_print("There is a crashing sound.");
+#endif
+ else
+#ifdef JP
+ msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£");
+#else
+ msg_print("There is a grinding sound.");
+#endif
+ }
+
+ cave_alter_feat(ny, nx, FF_HURT_DISI);
+
+ if (!m_ptr->r_idx) /* Killed by shards of glass, etc. */
+ {
+ /* Update some things */
+ p_ptr->update |= (PU_FLOW);
+ p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_KILL_WALL);
+
+ return;
+ }
+
+ f_ptr = &f_info[c_ptr->feat];
+
+ /* Note changes to viewable region */
+ do_view = TRUE;
+
+ /* Take a turn */
+ do_turn = TRUE;
+ }
+
+ if (must_alter_to_move && (r_ptr->flags7 & RF7_AQUATIC))
+ {
+ if (!monster_can_cross_terrain(c_ptr->feat, r_ptr, is_riding_mon ? CEM_RIDING : 0))
+ {
+ /* Assume no move allowed */
+ do_move = FALSE;
+ }
+ }
+
/*
* Check if monster can cross terrain
* This is checked after the normal attacks
* to allow monsters to attack an enemy,
* even if it can't enter the terrain.
*/
- if (do_move && !monster_can_cross_terrain(c_ptr->feat, r_ptr))
+ if (do_move && !can_cross && !did_kill_wall && !did_bash_door)
{
/* Assume no move allowed */
do_move = FALSE;
/* Some monsters never move */
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);
+ /* Hack -- memorize lack of moves */
+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags1 |= (RF1_NEVER_MOVE);
/* Do not move */
do_move = FALSE;
}
- if (m_idx == p_ptr->riding)
- {
- if (!p_ptr->riding_ryoute && !(m_list[p_ptr->riding].monfear)) do_move = FALSE;
- }
-
/* Creature has been allowed move */
if (do_move)
{
- s16b this_o_idx, next_o_idx;
-
/* Take a turn */
do_turn = TRUE;
- /* Hack -- Update the old location */
- cave[oy][ox].m_idx = c_ptr->m_idx;
-
- if (cave[ny][nx].feat == FEAT_TREES)
+ if (have_flag(f_ptr->flags, FF_TREE))
{
- if (r_ptr->flags2 & RF2_KILL_WALL)
- {
- cave_set_feat(ny, nx, FEAT_GRASS);
-
- }
if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD))
{
m_ptr->energy_need += ENERGY_NEED();
}
}
- /* Mega-Hack -- move the old monster, if any */
- if (c_ptr->m_idx)
+ if (!is_riding_mon)
{
- /* Move the old monster */
- y_ptr->fy = oy;
- y_ptr->fx = ox;
-
- /* Update the old monster */
- update_mon(c_ptr->m_idx, TRUE);
-
- /* Wake up the moved monster */
- m_list[c_ptr->m_idx].csleep = 0;
- }
+ /* Hack -- Update the old location */
+ cave[oy][ox].m_idx = c_ptr->m_idx;
- /* Hack -- Update the new location */
- c_ptr->m_idx = m_idx;
+ /* Mega-Hack -- move the old monster, if any */
+ if (c_ptr->m_idx)
+ {
+ /* Move the old monster */
+ y_ptr->fy = oy;
+ y_ptr->fx = ox;
- /* Move the monster */
- m_ptr->fy = ny;
- m_ptr->fx = nx;
+ /* Update the old monster */
+ update_mon(c_ptr->m_idx, TRUE);
+ }
- /* Update the monster */
- update_mon(m_idx, TRUE);
+ /* Hack -- Update the new location */
+ c_ptr->m_idx = m_idx;
- if (p_ptr->riding == m_idx)
- {
- py = ny;
- px = nx;
- }
+ /* Move the monster */
+ m_ptr->fy = ny;
+ m_ptr->fx = nx;
- /* Redraw the old grid */
- lite_spot(oy, ox);
+ /* Update the monster */
+ update_mon(m_idx, TRUE);
- /* Redraw the new grid */
- lite_spot(ny, nx);
+ /* Redraw the old grid */
+ lite_spot(oy, ox);
- if (p_ptr->riding == m_idx)
+ /* Redraw the new grid */
+ lite_spot(ny, nx);
+ }
+ else
{
- verify_panel();
+ /* Sound */
+ /* sound(SOUND_WALK); */
- /* Update stuff */
- p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW);
-
- /* Update the monsters */
- p_ptr->update |= (PU_DISTANCE);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
+ /* Move the player */
+ if (!move_player_effect(ny, nx, MPE_DONT_PICKUP)) break;
}
/* Possible disturb */
if (m_ptr->ml &&
(disturb_move ||
- (disturb_near && (m_ptr->mflag & MFLAG_VIEW)) ||
+ (disturb_near && (m_ptr->mflag & MFLAG_VIEW) && projectable(py, px, m_ptr->fy, m_ptr->fx)) ||
(disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= p_ptr->lev)))
{
/* Disturb */
disturb(0, 0);
}
- /* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ /* Take or Kill objects on the floor */
+ if (c_ptr->o_idx && (r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) &&
+ (!is_pet(m_ptr) || ((p_ptr->pet_extra_flags & PF_PICKUP_ITEMS) && (r_ptr->flags2 & RF2_TAKE_ITEM))))
{
- object_type *o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
+ s16b this_o_idx, next_o_idx;
+ bool do_take = (r_ptr->flags2 & RF2_TAKE_ITEM) ? TRUE : FALSE;
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Skip gold */
- if (o_ptr->tval == TV_GOLD) continue;
-
- /*
- * Skip "real" corpses and statues, to avoid extreme
- * silliness like a novice rogue pockets full of statues
- * and corpses.
- */
- if ((o_ptr->tval == TV_CORPSE) ||
- (o_ptr->tval == TV_STATUE)) continue;
-
- /* Take or Kill objects on the floor */
- if ((r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) &&
- (!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_PICKUP_ITEMS)))
+ /* Scan all objects in the grid */
+ for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
{
- u32b flgs[TR_FLAG_SIZE];
+ u32b flgs[TR_FLAG_SIZE], flg2 = 0L, flg3 = 0L, flgr = 0L;
+ char m_name[80], o_name[MAX_NLEN];
+
+ /* Acquire object */
+ object_type *o_ptr = &o_list[this_o_idx];
- u32b flg2 = 0L;
- u32b flg3 = 0L;
+ /* Acquire next object */
+ next_o_idx = o_ptr->next_o_idx;
- char m_name[80];
- char o_name[MAX_NLEN];
+ if (do_take)
+ {
+ /* Skip gold */
+ if (o_ptr->tval == TV_GOLD) continue;
+
+ /*
+ * Skip "real" corpses and statues, to avoid extreme
+ * silliness like a novice rogue pockets full of statues
+ * and corpses.
+ */
+ if ((o_ptr->tval == TV_CORPSE) ||
+ (o_ptr->tval == TV_STATUE)) continue;
+ }
/* Extract some flags */
object_flags(o_ptr, flgs);
/* Acquire the object name */
- object_desc(o_name, o_ptr, TRUE, 3);
+ object_desc(o_name, o_ptr, 0);
/* Acquire the monster name */
- monster_desc(m_name, m_ptr, 0x04);
+ monster_desc(m_name, m_ptr, MD_INDEF_HIDDEN);
/* React to objects that hurt the monster */
- 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_KILL_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_KILL_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_EVIL)) flg3 |= (RF3_EVIL);
if (have_flag(flgs, TR_SLAY_HUMAN)) flg2 |= (RF2_HUMAN);
if (have_flag(flgs, TR_KILL_HUMAN)) flg2 |= (RF2_HUMAN);
+ if (have_flag(flgs, TR_BRAND_ACID)) flgr |= (RFR_IM_ACID);
+ if (have_flag(flgs, TR_BRAND_ELEC)) flgr |= (RFR_IM_ELEC);
+ if (have_flag(flgs, TR_BRAND_FIRE)) flgr |= (RFR_IM_FIRE);
+ if (have_flag(flgs, TR_BRAND_COLD)) flgr |= (RFR_IM_COLD);
+ if (have_flag(flgs, TR_BRAND_POIS)) flgr |= (RFR_IM_POIS);
/* The object cannot be picked up by the monster */
- if (artifact_p(o_ptr) || (r_ptr->flags3 & flg3) || (r_ptr->flags2 & flg2) ||
- (o_ptr->art_name))
+ if (object_is_artifact(o_ptr) || (r_ptr->flags3 & flg3) || (r_ptr->flags2 & flg2) ||
+ ((~(r_ptr->flagsr) & flgr) && !(r_ptr->flagsr & RFR_RES_ALL)))
{
/* Only give a message for "take_item" */
- if ((r_ptr->flags2 & (RF2_TAKE_ITEM)) && (r_ptr->flags2 & (RF2_STUPID)))
+ if (do_take && (r_ptr->flags2 & RF2_STUPID))
{
/* Take note */
did_take_item = TRUE;
{
/* Dump a message */
#ifdef JP
-msg_format("%^s¤Ï%s¤ò½¦¤ª¤¦¤È¤·¤¿¤¬¡¢¤À¤á¤À¤Ã¤¿¡£", m_name, o_name);
+ msg_format("%^s¤Ï%s¤ò½¦¤ª¤¦¤È¤·¤¿¤¬¡¢¤À¤á¤À¤Ã¤¿¡£", m_name, o_name);
#else
-msg_format("%^s tries to pick up %s, but fails.", m_name, o_name);
+ msg_format("%^s tries to pick up %s, but fails.", m_name, o_name);
#endif
}
}
}
/* Pick up the item */
- else if (r_ptr->flags2 & RF2_TAKE_ITEM)
+ else if (do_take)
{
/* Take note */
did_take_item = TRUE;
{
/* Dump a message */
#ifdef JP
-msg_format("%^s¤¬%s¤ò½¦¤Ã¤¿¡£", m_name, o_name);
+ msg_format("%^s¤¬%s¤ò½¦¤Ã¤¿¡£", m_name, o_name);
#else
msg_format("%^s picks up %s.", m_name, o_name);
#endif
-
}
/* Excise the object */
excise_object_idx(this_o_idx);
/* Forget mark */
- o_ptr->marked = 0;
+ o_ptr->marked &= OM_TOUCHED;
/* Forget location */
o_ptr->iy = o_ptr->ix = 0;
{
/* Dump a message */
#ifdef JP
-msg_format("%^s¤¬%s¤òÇ˲õ¤·¤¿¡£", m_name, o_name);
+ msg_format("%^s¤¬%s¤òÇ˲õ¤·¤¿¡£", m_name, o_name);
#else
msg_format("%^s destroys %s.", m_name, o_name);
#endif
-
}
/* Delete the object */
* 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 && !(p_ptr->riding == m_idx) && aware)
+ if (!do_turn && !do_move && !MON_MONFEAR(m_ptr) && !is_riding_mon && 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;
+ }
}
if (do_view)
{
/* Update some things */
- p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS | PU_MON_LITE);
+ p_ptr->update |= (PU_FLOW);
+
+ /* 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 (is_original_ap_and_seen(m_ptr))
{
/* Monster opened a door */
if (did_open_door) r_ptr->r_flags2 |= (RF2_OPEN_DOOR);
/* Hack -- get "bold" if out of options */
- if (!do_turn && !do_move && m_ptr->monfear && aware)
+ if (!do_turn && !do_move && MON_MONFEAR(m_ptr) && aware)
{
/* No longer afraid */
- m_ptr->monfear = 0;
+ (void)set_monster_monfear(m_idx, 0);
/* Message if seen */
- if (m_ptr->ml)
+ if (see_m)
{
char m_name[80];
/* Dump a message */
#ifdef JP
-msg_format("%^s¤ÏÀ襤¤ò·è°Õ¤·¤¿¡ª", m_name);
+ msg_format("%^s¤ÏÀ襤¤ò·è°Õ¤·¤¿¡ª", m_name);
#else
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);
}
+ if (m_ptr->ml) chg_virtue(V_COMPASSION, -1);
+
/* XXX XXX XXX Actually do something now (?) */
}
}
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;
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];
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--)
{
}
/* Hack -- Require proximity */
- if (m_ptr->cdis >= 100) continue;
+ if (m_ptr->cdis >= AAF_LIMIT) continue;
/* Access the location */
/* Flow by smell is allowed */
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;
#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 (!(m_ptr->mflag2 & MFLAG_NOFLOW) &&
- (cave_floor_bold(py, px) || (cave[py][px].feat == FEAT_TREES)) &&
+ else if (!(m_ptr->mflag2 & MFLAG2_NOFLOW) &&
+ cave_have_flag_bold(py, px, FF_MOVE) &&
(cave[py][px].when == cave[fy][fx].when) &&
(cave[fy][fx].dist < MONSTER_FLOW_DEPTH) &&
(cave[fy][fx].dist < r_ptr->aaf))
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 (MON_FAST(m_ptr)) speed += 10;
+ if (MON_SLOW(m_ptr)) speed -= 10;
}
/* Give this monster some energy */
- m_ptr->energy_need -= extract_energy[speed];
+ m_ptr->energy_need -= SPEED_TO_ENERGY(speed);
/* Not enough energy to move */
if (m_ptr->energy_need > 0) continue;
/* 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 (!p_ptr->playing || p_ptr->is_dead) break;
(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 */
}
-
-bool process_the_world(int num, int who, bool vs_player)
+int get_mproc_idx(int m_idx, int mproc_type)
{
- monster_type *m_ptr = &m_list[hack_m_idx]; /* the world monster */
-
- if(world_monster) return (FALSE);
+ s16b *cur_mproc_list = mproc_list[mproc_type];
+ int i;
- if(vs_player)
+ for (i = mproc_max[mproc_type] - 1; i >= 0; i--)
{
- char m_name[80];
- monster_desc(m_name, m_ptr, 0);
+ if (cur_mproc_list[i] == m_idx) return i;
+ }
- if (who == 1)
-#ifdef JP
- msg_print("¡Ö¡Ø¥¶¡¦¥ï¡¼¥ë¥É¡Ù¡ª»þ¤Ï»ß¤Þ¤Ã¤¿¡ª¡×");
-#else
- msg_format("%s yells 'The World! Time has stopped!'", m_name);
-#endif
- else if (who == 3)
-#ifdef JP
- msg_print("¡Ö»þ¤è¡ª¡×");
-#else
- msg_format("%s yells 'Time!'", m_name);
-#endif
- else msg_print("hek!");
+ return -1;
+}
- msg_print(NULL);
- }
- world_monster = TRUE;
+static void mproc_add(int m_idx, int mproc_type)
+{
+ if (mproc_max[mproc_type] < max_m_idx) mproc_list[mproc_type][mproc_max[mproc_type]++] = m_idx;
+}
- if (vs_player) do_cmd_redraw();
- while(num--)
+static void mproc_remove(int m_idx, int mproc_type)
+{
+ int mproc_idx = get_mproc_idx(m_idx, mproc_type);
+ if (mproc_idx >= 0) mproc_list[mproc_type][mproc_idx] = mproc_list[mproc_type][--mproc_max[mproc_type]];
+}
+
+
+/*
+ * Initialize monster process
+ */
+void mproc_init(void)
+{
+ monster_type *m_ptr;
+ int i, cmi;
+
+ /* Reset "mproc_max[]" */
+ for (cmi = 0; cmi < MAX_MTIMED; cmi++) mproc_max[cmi] = 0;
+
+ /* Process the monsters (backwards) */
+ for (i = m_max - 1; i >= 1; i--)
{
- if(!m_ptr->r_idx) break;
- process_monster(hack_m_idx);
+ /* Access the monster */
+ m_ptr = &m_list[i];
- reset_target(m_ptr);
+ /* Ignore "dead" monsters */
+ if (!m_ptr->r_idx) continue;
- /* Notice stuff */
- if (p_ptr->notice) notice_stuff();
+ for (cmi = 0; cmi < MAX_MTIMED; cmi++)
+ {
+ if (m_ptr->mtimed[cmi]) mproc_add(i, cmi);
+ }
+ }
+}
- /* Update stuff */
- if (p_ptr->update) update_stuff();
- /* Redraw stuff */
- if (p_ptr->redraw) redraw_stuff();
+/*
+ * Set "m_ptr->mtimed[MTIMED_CSLEEP]", notice observable changes
+ */
+bool set_monster_csleep(int m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
- /* Redraw stuff */
- if (p_ptr->window) window_stuff();
+ /* Hack -- Force good values */
+ v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
- /* Delay */
- if (vs_player) Term_xtra(TERM_XTRA_DELAY, 500);
+ /* Open */
+ if (v)
+ {
+ if (!MON_CSLEEP(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_CSLEEP);
+ notice = TRUE;
+ }
}
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
+ /* Shut */
+ else
+ {
+ if (MON_CSLEEP(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_CSLEEP);
+ notice = TRUE;
+ }
+ }
- /* Update monsters */
- p_ptr->update |= (PU_MONSTERS);
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_CSLEEP] = v;
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
+ if (!notice) return FALSE;
- world_monster = FALSE;
- if (vs_player || los(py, px, m_ptr->fy, m_ptr->fx))
+ if (m_ptr->ml)
{
-#ifdef JP
- msg_print("¡Ö»þ¤ÏÆ°¤¤À¤¹¡Ä¡×");
-#else
- msg_print("You feel time flowing around you once more.");
-#endif
- msg_print(NULL);
+ /* Update health bar as needed */
+ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
}
- handle_stuff();
+ if (r_info[m_ptr->r_idx].flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
- return (TRUE);
+ return TRUE;
}
-void monster_gain_exp(int m_idx, int s_idx)
+/*
+ * Set "m_ptr->mtimed[MTIMED_FAST]", notice observable changes
+ */
+bool set_monster_fast(int m_idx, int v)
{
monster_type *m_ptr = &m_list[m_idx];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- monster_race *s_ptr = &r_info[s_idx];
- int new_exp;
+ bool notice = FALSE;
- if (p_ptr->inside_battle) return;
-
- if (!r_ptr->next_exp) return;
-
- new_exp = s_ptr->mexp * s_ptr->level / (r_ptr->level + 2);
- 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;
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
- if (m_ptr->exp >= r_ptr->next_exp)
+ /* Open */
+ if (v)
{
- char m_name[80];
- int old_hp = m_ptr->hp;
- int old_maxhp = m_ptr->max_maxhp;
- int old_r_idx = m_ptr->r_idx;
- int i;
-
- monster_desc(m_name, m_ptr, 0);
- m_ptr->r_idx = r_ptr->next_r_idx;
- m_ptr->ap_r_idx = m_ptr->r_idx;
- r_ptr = &r_info[m_ptr->r_idx];
- if (r_ptr->flags1 & RF1_FORCE_MAXHP)
+ if (!MON_FAST(m_ptr))
{
- m_ptr->max_maxhp = maxroll(r_ptr->hdice, r_ptr->hside);
+ mproc_add(m_idx, MTIMED_FAST);
+ notice = TRUE;
}
- else
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_FAST(m_ptr))
{
- m_ptr->max_maxhp = damroll(r_ptr->hdice, r_ptr->hside);
+ mproc_remove(m_idx, MTIMED_FAST);
+ notice = TRUE;
}
- if (ironman_nightmare)
- {
- u32b hp = m_ptr->max_maxhp * 2L;
+ }
- m_ptr->max_maxhp = (s16b)MIN(30000, hp);
- }
- m_ptr->maxhp = m_ptr->max_maxhp;
- m_ptr->hp = old_hp * m_ptr->maxhp / old_maxhp;
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_FAST] = v;
- /* Extract the monster base speed */
- m_ptr->mspeed = r_ptr->speed;
+ if (!notice) return FALSE;
- /* Hack -- small racial variety */
- if (!(r_ptr->flags1 & RF1_UNIQUE) && !p_ptr->inside_arena)
- {
- /* Allow some small variation per monster */
- if(one_in_(4)){
- 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);
- }
- }
+ if ((p_ptr->riding == m_idx) && !p_ptr->leaving) p_ptr->update |= (PU_BONUS);
- if (m_ptr->mspeed > 199) m_ptr->mspeed = 199;
+ return TRUE;
+}
- m_ptr->exp = 0;
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_SLOW]", notice observable changes
+ */
+bool set_monster_slow(int m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_SLOW(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_SLOW);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_SLOW(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_SLOW);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_SLOW] = v;
+
+ if (!notice) return FALSE;
+
+ if ((p_ptr->riding == m_idx) && !p_ptr->leaving) p_ptr->update |= (PU_BONUS);
+
+ return TRUE;
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_STUNNED]", notice observable changes
+ */
+bool set_monster_stunned(int m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_STUNNED(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_STUNNED);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_STUNNED(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_STUNNED);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_STUNNED] = v;
+
+ return notice;
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_CONFUSED]", notice observable changes
+ */
+bool set_monster_confused(int m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_CONFUSED(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_CONFUSED);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_CONFUSED(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_CONFUSED);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_CONFUSED] = v;
+
+ return notice;
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_MONFEAR]", notice observable changes
+ */
+bool set_monster_monfear(int m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_MONFEAR(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_MONFEAR);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_MONFEAR(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_MONFEAR);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_MONFEAR] = v;
+
+ if (!notice) return FALSE;
+
+ if (m_ptr->ml)
+ {
+ /* Update health bar as needed */
+ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_INVULNER]", notice observable changes
+ */
+bool set_monster_invulner(int m_idx, int v, bool energy_need)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_INVULNER(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_INVULNER);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_INVULNER(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_INVULNER);
+ if (energy_need && !p_ptr->wild_mode) m_ptr->energy_need += ENERGY_NEED();
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_INVULNER] = v;
+
+ if (!notice) return FALSE;
+
+ if (m_ptr->ml)
+ {
+ /* Update health bar as needed */
+ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+ }
+
+ return TRUE;
+}
+
+
+static u32b csleep_noise;
+
+static void process_monsters_mtimed_aux(int m_idx, int mtimed_idx)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+
+ switch (mtimed_idx)
+ {
+ case MTIMED_CSLEEP:
+ {
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+
+ /* Assume does not wake up */
+ bool test = FALSE;
+
+ /* Hack -- Require proximity */
+ if (m_ptr->cdis < AAF_LIMIT)
+ {
+ /* Handle "sensing radius" */
+ if (m_ptr->cdis <= (is_pet(m_ptr) ? ((r_ptr->aaf > MAX_SIGHT) ? MAX_SIGHT : r_ptr->aaf) : r_ptr->aaf))
+ {
+ /* We may wake up */
+ test = TRUE;
+ }
+
+ /* Handle "sight" and "aggravation" */
+ else if ((m_ptr->cdis <= MAX_SIGHT) && (player_has_los_bold(m_ptr->fy, m_ptr->fx)))
+ {
+ /* We may wake up */
+ test = TRUE;
+ }
+ }
+
+ if (test)
+ {
+ u32b notice = randint0(1024);
+
+ /* Nightmare monsters are more alert */
+ if (ironman_nightmare) notice /= 2;
+
+ /* Hack -- See if monster "notices" player */
+ if ((notice * notice * notice) <= csleep_noise)
+ {
+ /* Hack -- amount of "waking" */
+ /* Wake up faster near the player */
+ int d = (m_ptr->cdis < AAF_LIMIT / 2) ? (AAF_LIMIT / m_ptr->cdis) : 1;
+
+ /* Hack -- amount of "waking" is affected by speed of player */
+ d = (d * SPEED_TO_ENERGY(p_ptr->pspeed)) / 10;
+ if (d < 0) d = 1;
+
+ /* Monster wakes up "a little bit" */
+
+ /* Still asleep */
+ if (!set_monster_csleep(m_idx, MON_CSLEEP(m_ptr) - d))
+ {
+ /* Notice the "not waking up" */
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ /* Hack -- Count the ignores */
+ if (r_ptr->r_ignore < MAX_UCHAR) r_ptr->r_ignore++;
+ }
+ }
+
+ /* Just woke up */
+ else
+ {
+ /* Notice the "waking up" */
+ if (m_ptr->ml)
+ {
+ char m_name[80];
+
+ /* Acquire the monster name */
+ monster_desc(m_name, m_ptr, 0);
+
+ /* Dump a message */
+#ifdef JP
+ msg_format("%^s¤¬Ìܤò³Ð¤Þ¤·¤¿¡£", m_name);
+#else
+ msg_format("%^s wakes up.", m_name);
+#endif
+ }
+
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ /* Hack -- Count the wakings */
+ if (r_ptr->r_wake < MAX_UCHAR) r_ptr->r_wake++;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case MTIMED_FAST:
+ /* Reduce by one, note if expires */
+ if (set_monster_fast(m_idx, MON_FAST(m_ptr) - 1))
+ {
+ if (is_seen(m_ptr))
+ {
+ 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 fast.", m_name);
+#endif
+ }
+ }
+ break;
+
+ case MTIMED_SLOW:
+ /* Reduce by one, note if expires */
+ if (set_monster_slow(m_idx, MON_SLOW(m_ptr) - 1))
+ {
+ if (is_seen(m_ptr))
+ {
+ 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
+ }
+ }
+ break;
+
+ case MTIMED_STUNNED:
+ {
+ int rlev = r_info[m_ptr->r_idx].level;
+
+ /* Recover from stun */
+ if (set_monster_stunned(m_idx, (randint0(10000) <= rlev * rlev) ? 0 : (MON_STUNNED(m_ptr) - 1)))
+ {
+ /* Message if visible */
+ if (is_seen(m_ptr))
+ {
+ 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 stunned.", m_name);
+#endif
+ }
+ }
+ break;
+ }
+
+ case MTIMED_CONFUSED:
+ /* Reduce the confusion */
+ if (set_monster_confused(m_idx, MON_CONFUSED(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1)))
+ {
+ /* Message if visible */
+ if (is_seen(m_ptr))
+ {
+ 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
+ }
+ }
+ break;
+
+ case MTIMED_MONFEAR:
+ /* Reduce the fear */
+ if (set_monster_monfear(m_idx, MON_MONFEAR(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1)))
+ {
+ /* Visual note */
+ if (is_seen(m_ptr))
+ {
+ char m_name[80];
+#ifndef JP
+ char m_poss[80];
+
+ /* Acquire the monster possessive */
+ monster_desc(m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
+#endif
+
+ /* 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 recovers %s courage.", m_name, m_poss);
+#endif
+ }
+ }
+ break;
+
+ case MTIMED_INVULNER:
+ /* Reduce by one, note if expires */
+ if (set_monster_invulner(m_idx, MON_INVULNER(m_ptr) - 1, TRUE))
+ {
+ if (is_seen(m_ptr))
+ {
+ 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 invulnerable.", m_name);
+#endif
+ }
+ }
+ break;
+ }
+}
+
+
+/*
+ * Process the counters of monsters (once per 10 game turns)
+ *
+ * These functions are to process monsters' counters same as player's.
+ */
+void process_monsters_mtimed(int mtimed_idx)
+{
+ int i;
+ s16b *cur_mproc_list = mproc_list[mtimed_idx];
+
+ /* Hack -- calculate the "player noise" */
+ if (mtimed_idx == MTIMED_CSLEEP) csleep_noise = (1L << (30 - p_ptr->skill_stl));
+
+ /* Process the monsters (backwards) */
+ for (i = mproc_max[mtimed_idx] - 1; i >= 0; i--)
+ {
+ /* Access the monster */
+ process_monsters_mtimed_aux(cur_mproc_list[i], mtimed_idx);
+ }
+}
+
+
+void dispel_monster_status(int m_idx)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ char m_name[80];
+
+ monster_desc(m_name, m_ptr, 0);
+ if (set_monster_invulner(m_idx, 0, TRUE))
+ {
+#ifdef JP
+ if (m_ptr->ml) msg_format("%s¤Ï¤â¤¦ÌµÅ¨¤Ç¤Ï¤Ê¤¤¡£", m_name);
+#else
+ if (m_ptr->ml) msg_format("%^s is no longer invulnerable.", m_name);
+#endif
+ }
+ if (set_monster_fast(m_idx, 0))
+ {
+#ifdef JP
+ if (m_ptr->ml) msg_format("%s¤Ï¤â¤¦²Ã®¤µ¤ì¤Æ¤¤¤Ê¤¤¡£", m_name);
+#else
+ if (m_ptr->ml) msg_format("%^s is no longer fast.", m_name);
+#endif
+ }
+ if (set_monster_slow(m_idx, 0))
+ {
+#ifdef JP
+ if (m_ptr->ml) msg_format("%s¤Ï¤â¤¦¸ºÂ®¤µ¤ì¤Æ¤¤¤Ê¤¤¡£", m_name);
+#else
+ if (m_ptr->ml) msg_format("%^s is no longer slow.", m_name);
+#endif
+ }
+}
+
+
+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_ptr, 0);
+
+ if (who == 1)
+#ifdef JP
+ msg_print("¡Ö¡Ø¥¶¡¦¥ï¡¼¥ë¥É¡Ù¡ª»þ¤Ï»ß¤Þ¤Ã¤¿¡ª¡×");
+#else
+ msg_format("%s yells 'The World! Time has stopped!'", m_name);
+#endif
+ else if (who == 3)
+#ifdef JP
+ msg_print("¡Ö»þ¤è¡ª¡×");
+#else
+ msg_format("%s yells 'Time!'", m_name);
+#endif
+ else msg_print("hek!");
+
+ msg_print(NULL);
+ }
+
+ /* This monster cast spells */
+ world_monster = hack_m_idx;
+
+ if (vs_player) do_cmd_redraw();
+
+ while(num--)
+ {
+ if(!m_ptr->r_idx) break;
+ process_monster(world_monster);
+
+ reset_target(m_ptr);
+
+ /* Notice stuff */
+ if (p_ptr->notice) notice_stuff();
+
+ /* Update stuff */
+ if (p_ptr->update) update_stuff();
+
+ /* Redraw stuff */
+ if (p_ptr->redraw) redraw_stuff();
+
+ /* Redraw stuff */
+ if (p_ptr->window) window_stuff();
+
+ /* Delay */
+ if (vs_player) Term_xtra(TERM_XTRA_DELAY, 500);
+ }
+
+ /* Redraw map */
+ p_ptr->redraw |= (PR_MAP);
+
+ /* Update monsters */
+ p_ptr->update |= (PU_MONSTERS);
+
+ /* Window stuff */
+ p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
+
+ world_monster = 0;
+ if (vs_player || (player_has_los_bold(m_ptr->fy, m_ptr->fx) && projectable(py, px, m_ptr->fy, m_ptr->fx)))
+ {
+#ifdef JP
+ msg_print("¡Ö»þ¤ÏÆ°¤¤À¤¹¡Ä¡×");
+#else
+ msg_print("You feel time flowing around you once more.");
+#endif
+ msg_print(NULL);
+ }
+
+ handle_stuff();
+
+ return (TRUE);
+}
+
+
+void monster_gain_exp(int m_idx, int s_idx)
+{
+ monster_type *m_ptr;
+ monster_race *r_ptr;
+ monster_race *s_ptr;
+ int new_exp;
+
+ /* Paranoia */
+ if (m_idx <= 0 || s_idx <= 0) return;
+
+ m_ptr = &m_list[m_idx];
+
+ /* Paranoia -- Skip dead monsters */
+ if (!m_ptr->r_idx) return;
+
+ r_ptr = &r_info[m_ptr->r_idx];
+ s_ptr = &r_info[s_idx];
+
+ if (p_ptr->inside_battle) return;
+
+ if (!r_ptr->next_exp) return;
+
+ new_exp = s_ptr->mexp * s_ptr->level / (r_ptr->level + 2);
+ 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 & MFLAG2_CHAMELEON) return;
+
+ if (m_ptr->exp >= r_ptr->next_exp)
+ {
+ char m_name[80];
+ int old_hp = m_ptr->hp;
+ int old_maxhp = m_ptr->max_maxhp;
+ int old_r_idx = m_ptr->r_idx;
+ byte old_sub_align = m_ptr->sub_align;
+
+ /* Hack -- Reduce the racial counter of previous monster */
+ real_r_ptr(m_ptr)->cur_num--;
+
+ monster_desc(m_name, m_ptr, 0);
+ m_ptr->r_idx = r_ptr->next_r_idx;
+
+ /* Count the monsters on the level */
+ real_r_ptr(m_ptr)->cur_num++;
+
+ m_ptr->ap_r_idx = m_ptr->r_idx;
+ r_ptr = &r_info[m_ptr->r_idx];
+
+ if (r_ptr->flags1 & RF1_FORCE_MAXHP)
+ {
+ m_ptr->max_maxhp = maxroll(r_ptr->hdice, r_ptr->hside);
+ }
+ else
+ {
+ m_ptr->max_maxhp = damroll(r_ptr->hdice, r_ptr->hside);
+ }
+ if (ironman_nightmare)
+ {
+ u32b hp = m_ptr->max_maxhp * 2L;
+
+ m_ptr->max_maxhp = (s16b)MIN(30000, hp);
+ }
+ m_ptr->maxhp = m_ptr->max_maxhp;
+ m_ptr->hp = old_hp * m_ptr->maxhp / old_maxhp;
+
+ /* Extract the monster base speed */
+ m_ptr->mspeed = get_mspeed(r_ptr);
+
+ /* 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
+ {
+ 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;
+ }
+
+ m_ptr->exp = 0;
if (is_pet(m_ptr) || m_ptr->ml)
{
+ if (!ignore_unview || player_can_see_bold(m_ptr->fy, m_ptr->fx))
+ {
+ if (p_ptr->image)
+ {
+ monster_race *hallu_race;
+
+ do
+ {
+ hallu_race = &r_info[randint1(max_r_idx - 1)];
+ }
+ while (!hallu_race->name || (hallu_race->flags1 & RF1_UNIQUE));
+
+#ifdef JP
+ msg_format("%s¤Ï%s¤Ë¿Ê²½¤·¤¿¡£", m_name, r_name + hallu_race->name);
+#else
+ msg_format("%^s evolved into %s.", m_name, r_name + hallu_race->name);
+#endif
+ }
+ else
+ {
#ifdef JP
- msg_format("%s¤Ï%s¤Ë¿Ê²½¤·¤¿¡£", m_name, r_name + r_ptr->name);
+ msg_format("%s¤Ï%s¤Ë¿Ê²½¤·¤¿¡£", m_name, r_name + r_ptr->name);
#else
- msg_format("%^s evolved into %s.", m_name, r_name + r_ptr->name);
+ msg_format("%^s evolved into %s.", m_name, r_name + r_ptr->name);
#endif
- r_info[old_r_idx].r_xtra1 |= MR1_SINKA;
+ }
+ }
+
+ if (!p_ptr->image) r_info[old_r_idx].r_xtra1 |= MR1_SINKA;
+
+ /* Now you feel very close to this pet. */
+ m_ptr->parent_m_idx = 0;
}
update_mon(m_idx, FALSE);
lite_spot(m_ptr->fy, m_ptr->fx);