X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fmelee2.c;h=2666196654274ca4d3b5b5242391eaefc3f78990;hb=808c288f896ea243ab6a0565da8ebd55c36a9c90;hp=dd16ceeb9fef64d7c3ff956c934dde8ba10ffaa3;hpb=776e71b2edd6edf0f20908cefb87fbfe4bf293c6;p=hengband%2Fhengband.git diff --git a/src/melee2.c b/src/melee2.c index dd16ceeb9..266619665 100644 --- a/src/melee2.c +++ b/src/melee2.c @@ -60,7 +60,6 @@ static bool get_enemy_dir(int m_idx, int *mm) 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; @@ -97,18 +96,15 @@ static bool get_enemy_dir(int m_idx, int *mm) /* Monster must be 'an enemy' */ if (!are_enemies(m_ptr, t_ptr)) continue; - can_pass_wall = (((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall))) || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding))); - /* 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 */ @@ -198,7 +194,7 @@ void mon_take_hit_mon(int m_idx, int dam, bool *fear, cptr note, int who) 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); @@ -207,15 +203,18 @@ void mon_take_hit_mon(int m_idx, int dam, bool *fear, cptr note, int who) 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) { @@ -230,7 +229,7 @@ msg_format("%^s return; } - if (r_ptr->flags3 & RF3_RES_ALL) + if (r_ptr->flagsr & RFR_RES_ALL) { if(dam > 0) { @@ -258,9 +257,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; @@ -336,35 +334,21 @@ msg_format("%^s #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, @@ -377,9 +361,9 @@ msg_format("%^s (*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)))); } } @@ -456,7 +440,7 @@ static int mon_will_run(int m_idx) 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 @@ -548,7 +532,7 @@ static bool get_moves_aux2(int m_idx, int *yp, int *xp) cost = c_ptr->cost; /* Monster cannot kill or pass walls */ - if (!(((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) || (r_ptr->flags2 & RF2_KILL_WALL))) + if (!(((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding)))) { if (cost == 0) continue; if (!can_open_door && is_closed_door(c_ptr->feat)) continue; @@ -622,16 +606,15 @@ static bool get_moves_aux(int m_idx, int *yp, int *xp, bool no_flow) if (no_flow) return (FALSE); /* Monster can go through rocks */ - if ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall))) return (FALSE); - if (r_ptr->flags2 & RF2_KILL_WALL) return (FALSE); - if (!cave_floor_bold(py, px) && (cave[py][px].feat != FEAT_TREES)) return (FALSE); + if ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)) return (FALSE); + if ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding)) return (FALSE); /* Monster location */ y1 = m_ptr->fy; 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]; @@ -960,7 +943,7 @@ static bool find_safety(int m_idx, int *yp, int *xp) 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 & MFLAG2_NOFLOW)) @@ -971,11 +954,10 @@ static bool find_safety(int m_idx, int *yp, int *xp) /* 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); @@ -1017,6 +999,7 @@ static bool find_safety(int m_idx, int *yp, int *xp) 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; @@ -1025,8 +1008,6 @@ static bool find_hiding(int m_idx, int *yp, int *xp) 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++) @@ -1042,17 +1023,15 @@ static bool find_hiding(int m_idx, int *yp, int *xp) { 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); @@ -1099,7 +1078,7 @@ static bool get_moves(int m_idx, int *mm) bool will_run = mon_will_run(m_idx); cave_type *c_ptr; bool no_flow = ((m_ptr->mflag2 & MFLAG2_NOFLOW) && (cave[m_ptr->fy][m_ptr->fx].cost > 2)); - bool can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall))); + bool can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || p_ptr->pass_wall)); /* Counter attack to an enemy monster */ if (!will_run && m_ptr->target_y) @@ -1109,7 +1088,8 @@ static bool get_moves(int m_idx, int *mm) /* 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)) + 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; @@ -1120,7 +1100,7 @@ static bool get_moves(int m_idx, int *mm) 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))) { /* @@ -1143,8 +1123,7 @@ static bool get_moves(int m_idx, int *mm) c_ptr = &cave[yy][xx]; /* Check grid */ - if (((cave_floor_grid(c_ptr)) || ((c_ptr->feat & 0x60) == 0x60)) && - monster_can_cross_terrain(c_ptr->feat, r_ptr)) + if (monster_can_cross_terrain(c_ptr->feat, r_ptr, 0)) { /* One more room grid */ room++; @@ -1187,8 +1166,7 @@ static bool get_moves(int m_idx, int *mm) 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; @@ -1438,6 +1416,12 @@ static int check_hit2(int power, int level, int ac, int stun) } +#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) { @@ -1450,14 +1434,15 @@ 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? */ @@ -1472,9 +1457,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; @@ -1522,19 +1504,24 @@ static bool monst_attack_monst(int m_idx, int t_idx) /* Hack -- no more attacks */ if (!method) break; - if (blinked) /* Stop! */ - { - /* 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)) + 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) { @@ -1852,8 +1839,8 @@ act = "%s /* 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; @@ -1861,147 +1848,103 @@ act = "%s 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: - { - damage -= (damage * ((ac < 150) ? ac : 150) / 250); - 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) @@ -2010,11 +1953,22 @@ act = "%s if (!explode) { project(m_idx, 0, t_ptr->fy, t_ptr->fx, - (pt == GF_OLD_SLEEP ? r_ptr->level : damage), pt, PROJECT_KILL | PROJECT_STOP | PROJECT_MONSTER, -1); + 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; @@ -2033,13 +1987,13 @@ act = "%s 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) @@ -2047,81 +2001,75 @@ msg_format("%s /* Aura fire */ if ((tr_ptr->flags2 & RF2_AURA_FIRE) && m_ptr->r_idx) { - if (!(r_ptr->flags3 & RF3_EFF_IM_FIRE_MASK)) + if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)) { if (see_either) { - blinked = FALSE; #ifdef JP msg_format("%^s¤ÏÆÍÁ³Ç®¤¯¤Ê¤Ã¤¿¡ª", m_name); #else msg_format("%^s is suddenly very hot!", m_name); #endif - - if (see_t) 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_MONSTER, -1); + GF_FIRE, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1); } else { - if (see_m) r_ptr->r_flags3 |= (r_ptr->flags3 & RF3_EFF_IM_FIRE_MASK); + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK); } } /* Aura cold */ if ((tr_ptr->flags3 & RF3_AURA_COLD) && m_ptr->r_idx) { - if (!(r_ptr->flags3 & RF3_EFF_IM_COLD_MASK)) + if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)) { if (see_either) { - blinked = FALSE; #ifdef JP msg_format("%^s¤ÏÆÍÁ³´¨¤¯¤Ê¤Ã¤¿¡ª", m_name); #else msg_format("%^s is suddenly very cold!", m_name); #endif - - if (see_t) 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_MONSTER, -1); + GF_COLD, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1); } else { - if (see_m) r_ptr->r_flags3 |= (r_ptr->flags3 & RF3_EFF_IM_COLD_MASK); + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK); } } /* Aura elec */ if ((tr_ptr->flags2 & RF2_AURA_ELEC) && m_ptr->r_idx) { - if (!(r_ptr->flags3 & RF3_EFF_IM_ELEC_MASK)) + if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)) { if (see_either) { - blinked = FALSE; #ifdef JP msg_format("%^s¤ÏÅÅ·â¤ò¿©¤é¤Ã¤¿¡ª", m_name); #else msg_format("%^s gets zapped!", m_name); #endif - - if (see_t) 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_MONSTER, -1); + GF_ELEC, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1); } else { - if (see_m) r_ptr->r_flags3 |= (r_ptr->flags3 & RF3_EFF_IM_ELEC_MASK); + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK); } } } @@ -2147,16 +2095,18 @@ msg_format("%s 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; @@ -2166,7 +2116,7 @@ msg_format("%s /* 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)) @@ -2185,43 +2135,48 @@ msg_format("%s 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(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(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) { #ifdef JP -msg_print("Å¥ËÀ¤Ï¾Ð¤Ã¤Æƨ¤²¤¿¡ª"); + 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; } +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)); +} + + /* * Process a monster * @@ -2259,12 +2214,14 @@ static void process_monster(int m_idx) 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; @@ -2274,12 +2231,16 @@ static void process_monster(int m_idx) bool did_pass_wall; bool did_kill_wall; bool gets_angry = FALSE; - bool can_pass_wall; + bool can_cross; bool aware = TRUE; bool fear; - if ((m_idx == p_ptr->riding) && !(r_ptr->flags7 & RF7_RIDING)) + bool is_riding_mon = (m_idx == p_ptr->riding); + + bool see_m = is_seen(m_ptr); + + if (is_riding_mon && !(r_ptr->flags7 & RF7_RIDING)) { if (rakuba(0, TRUE)) { @@ -2293,7 +2254,7 @@ static void process_monster(int m_idx) } } - if ((m_ptr->mflag2 & MFLAG2_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]; @@ -2310,6 +2271,39 @@ static void process_monster(int m_idx) if (randint0(tmp) > (r_ptr->level+20)) aware = FALSE; } + /* Are there its parent? */ + if (m_ptr->parent_m_idx && !m_list[m_ptr->parent_m_idx].r_idx) + { + /* Its parent have gone, it also goes away. */ + + if (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)) { @@ -2324,7 +2318,7 @@ static void process_monster(int m_idx) if (is_pet(m_ptr) && !(m_ptr->ml)) sad = TRUE; - if (m_ptr->ml) + if (see_m) { char m_name[80]; @@ -2333,11 +2327,10 @@ static void process_monster(int m_idx) /* Oops */ #ifdef JP -msg_format("%s¤Ï¾Ã¤¨µî¤Ã¤¿¡ª", m_name); + msg_format("%s¤Ï¾Ã¤¨µî¤Ã¤¿¡ª", m_name); #else msg_format("%^s disappears!", m_name); #endif - } /* Generate treasure, etc */ @@ -2349,11 +2342,10 @@ msg_format("%s if (sad) { #ifdef JP -msg_print("¾¯¤·¤Î´ÖÈᤷ¤¤µ¤Ê¬¤Ë¤Ê¤Ã¤¿¡£"); + msg_print("¾¯¤·¤Î´ÖÈᤷ¤¤µ¤Ê¬¤Ë¤Ê¤Ã¤¿¡£"); #else msg_print("You feel sad for a moment."); #endif - } return; @@ -2367,7 +2359,7 @@ msg_print(" mon_take_hit_mon(m_idx, 1, &fear, " explodes into tiny shreds.", m_idx); #endif - if ((is_pet(m_ptr) || is_friendly(m_ptr)) && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7)) && !p_ptr->inside_battle) + if ((is_pet(m_ptr) || is_friendly(m_ptr)) && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) && !p_ptr->inside_battle) { static int riding_pinch = 0; @@ -2376,7 +2368,7 @@ msg_print(" char m_name[80]; monster_desc(m_name, m_ptr, 0); - if (m_idx == p_ptr->riding && riding_pinch < 2) + if (is_riding_mon && riding_pinch < 2) { #ifdef JP msg_format("%s¤Ï½ý¤ÎÄˤµ¤Î;¤ê¤¢¤Ê¤¿¤Î«Çû¤«¤éƨ¤ì¤è¤¦¤È¤·¤Æ¤¤¤ë¡£", m_name); @@ -2388,7 +2380,7 @@ msg_print(" } else { - if (m_idx == p_ptr->riding) + if (is_riding_mon) { #ifdef JP msg_format("%s¤Ï¤¢¤Ê¤¿¤Î«Çû¤«¤éæ½Ð¤·¤¿¡£", m_name); @@ -2405,9 +2397,10 @@ msg_print(" } } - 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); @@ -2424,7 +2417,7 @@ msg_print(" #endif } - if (m_idx == p_ptr->riding && rakuba(-1, FALSE)) + if (is_riding_mon && rakuba(-1, FALSE)) { #ifdef JP msg_print("ÃÏÌ̤ËÍî¤È¤µ¤ì¤¿¡£"); @@ -2444,21 +2437,52 @@ msg_print(" else { /* Reset the counter */ - if (m_idx == p_ptr->riding) riding_pinch = 0; + if (is_riding_mon) riding_pinch = 0; } } - /* Handle "sleep" - Still sleeping */ - if (m_ptr->csleep) return; + /* Handle "sleep" */ + if (MON_CSLEEP(m_ptr)) + { + /* Handle non-aggravation - Still sleeping */ + if (!(p_ptr->cursed & TRC_AGGRAVATE)) return; + + /* Handle aggravation */ + + /* Reset sleep counter */ + (void)set_monster_csleep(m_idx, 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 + } + + /* Hack -- Count the wakings */ + if (is_original_ap_and_seen(m_ptr) && (r_ptr->r_wake < MAX_UCHAR)) + { + r_ptr->r_wake++; + } + } /* Handle "stun" */ - if (m_ptr->stunned) + if (MON_STUNNED(m_ptr)) { /* Sometimes skip move */ if (one_in_(2)) return; } - if (p_ptr->riding == m_idx) + if (is_riding_mon) { p_ptr->update |= (PU_BONUS); } @@ -2469,25 +2493,27 @@ msg_print(" /* Paranoia... no pet uniques outside wizard mode -- TY */ if (is_pet(m_ptr) && - ((((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7)) && - ((p_ptr->align > 9 && (r_ptr->flags3 & RF3_EVIL)) || - (p_ptr->align < -9 && (r_ptr->flags3 & RF3_GOOD)))) - || (r_ptr->flags3 & RF3_RES_ALL))) + ((((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) && + monster_has_hostile_align(NULL, 10, -10, r_ptr)) + || (r_ptr->flagsr & RFR_RES_ALL))) { - gets_angry = TRUE; + gets_angry = TRUE; } if (p_ptr->inside_battle) gets_angry = FALSE; if (gets_angry) { - char m_name[80]; - monster_desc(m_name, m_ptr, 0); + if (is_pet(m_ptr) || see_m) + { + 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 suddenly becomes hostile!", m_name); + msg_format("%^s suddenly becomes hostile!", m_name); #endif + } set_hostile(m_ptr); } @@ -2521,7 +2547,7 @@ msg_format("%^s if (multiply_monster(m_idx, FALSE, (is_pet(m_ptr) ? PM_FORCE_PET : 0))) { /* Take note if visible */ - if (m_ptr->ml) + if (m_list[hack_m_idx_ii].ml && is_original_ap_and_seen(m_ptr)) { r_ptr->r_flags2 |= (RF2_MULTIPLY); } @@ -2554,7 +2580,7 @@ msg_format("%^s } } - if (count && m_ptr->ml) r_ptr->r_flags6 |= (RF6_SPECIAL); + if (count && is_original_ap_and_seen(m_ptr)) r_ptr->r_flags6 |= (RF6_SPECIAL); } } } @@ -2570,17 +2596,17 @@ msg_format("%^s { 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]; @@ -2591,42 +2617,36 @@ msg_print(" 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) { @@ -2680,28 +2700,24 @@ msg_format("%^s%s", m_name, monmessage); } } - can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != p_ptr->riding) || (p_ptr->pass_wall))); - /* Hack -- Assume no movement */ mm[0] = mm[1] = mm[2] = mm[3] = 0; mm[4] = mm[5] = mm[6] = mm[7] = 0; /* 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; @@ -2712,7 +2728,7 @@ msg_format("%^s%s", m_name, monmessage); (randint0(100) < 50)) { /* Memorize flags */ - if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_50); + if (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; @@ -2723,7 +2739,7 @@ msg_format("%^s%s", m_name, monmessage); (randint0(100) < 25)) { /* Memorize flags */ - if (m_ptr->ml) r_ptr->r_flags1 |= RF1_RAND_25; + if (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; @@ -2773,7 +2789,7 @@ msg_format("%^s%s", m_name, monmessage); } /* Find the player */ - get_moves(m_idx, mm); + (void)get_moves(m_idx, mm); /* Restore the leash */ p_ptr->pet_follow_distance = dis; @@ -2801,6 +2817,7 @@ msg_format("%^s%s", m_name, monmessage); do_turn = FALSE; do_move = FALSE; do_view = FALSE; + must_alter_to_move = FALSE; /* Assume nothing */ did_open_door = FALSE; @@ -2830,102 +2847,67 @@ msg_format("%^s%s", m_name, monmessage); /* Access that cave grid */ c_ptr = &cave[ny][nx]; + f_ptr = &f_info[c_ptr->feat]; + can_cross = monster_can_cross_terrain(c_ptr->feat, r_ptr, is_riding_mon ? CEM_RIDING : 0); /* Access that cave grid's contents */ y_ptr = &m_list[c_ptr->m_idx]; - /* Floor is open? */ - if (cave_floor_grid(c_ptr)) - { - /* Go ahead and move */ - do_move = TRUE; - } - /* Hack -- player 'in' wall */ - else if (player_bold(ny, nx)) + if (player_bold(ny, nx)) { do_move = TRUE; } + /* 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) + /* 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)) { + /* Eat through walls/doors/rubble */ do_move = TRUE; - } + if (!can_cross) must_alter_to_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 destroyed a wall (later) */ + did_kill_wall = TRUE; } - - /* Monster moves through walls (and doors) */ - else if (can_pass_wall) + /* Floor is open? */ + else if (can_cross) { - /* Pass through walls/doors/rubble */ + /* Go ahead and move */ do_move = TRUE; - /* Monster went through a wall */ - did_pass_wall = TRUE; + /* Monster moves through walls (and doors) */ + if ((r_ptr->flags2 & RF2_PASS_WALL) && (!is_riding_mon || p_ptr->pass_wall) && + have_flag(f_ptr->flags, FF_CAN_PASS)) + { + /* Monster went through a wall */ + did_pass_wall = TRUE; + } } - /* Monster destroys walls (and doors) */ - else if ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != p_ptr->riding)) + /* Handle doors and secret doors */ + else if (is_closed_door(c_ptr->feat)) { - /* Eat through walls/doors/rubble */ - do_move = TRUE; + bool may_bash = TRUE; - /* Monster destroyed a wall */ - did_kill_wall = TRUE; - - if (one_in_(GRINDNOISE)) - { -#ifdef JP -msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£"); -#else - msg_print("There is a grinding sound."); -#endif - - } - - /* Forget the wall */ - c_ptr->info &= ~(CAVE_MARK); - - /* Notice */ - cave_set_feat(ny, nx, floor_type[randint0(100)]); - - /* Note changes to viewable region */ - if (player_has_los_bold(ny, nx)) do_view = TRUE; - } - - /* Handle doors and secret doors */ - else if (is_closed_door(c_ptr->feat)) - { - bool may_bash = TRUE; - - /* Assume no move allowed */ - do_move = FALSE; + /* Assume no move allowed */ + do_move = FALSE; /* Creature can open doors. */ - if ((r_ptr->flags2 & RF2_OPEN_DOOR) && + if ((r_ptr->flags2 & RF2_OPEN_DOOR) && have_flag(f_ptr->flags, FF_OPEN) && (!is_pet(m_ptr) || (p_ptr->pet_extra_flags & PF_OPEN_DOORS))) { /* Closed doors */ - if (c_ptr->feat == FEAT_DOOR_HEAD) + if (!f_ptr->power) { /* The door is open */ did_open_door = TRUE; @@ -2933,49 +2915,48 @@ msg_print(" /* 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); @@ -2985,6 +2966,7 @@ msg_print(" /* Hack -- fall into doorway */ do_move = TRUE; + must_alter_to_move = TRUE; } } @@ -2993,19 +2975,31 @@ msg_print(" 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; } } @@ -3023,11 +3017,10 @@ msg_print(" if (c_ptr->info & CAVE_MARK) { #ifdef JP -msg_print("¼é¤ê¤Î¥ë¡¼¥ó¤¬²õ¤ì¤¿¡ª"); + msg_print("¼é¤ê¤Î¥ë¡¼¥ó¤¬²õ¤ì¤¿¡ª"); #else msg_print("The rune of protection is broken!"); #endif - } /* Forget the rune */ @@ -3060,7 +3053,7 @@ msg_print(" if (c_ptr->info & CAVE_MARK) { #ifdef JP -msg_print("¥ë¡¼¥ó¤¬Çúȯ¤·¤¿¡ª"); + msg_print("¥ë¡¼¥ó¤¬Çúȯ¤·¤¿¡ª"); #else msg_print("The rune explodes!"); #endif @@ -3071,7 +3064,7 @@ msg_print(" else { #ifdef JP -msg_print("Çúȯ¤Î¥ë¡¼¥ó¤Ï²ò½ü¤µ¤ì¤¿¡£"); + msg_print("Çúȯ¤Î¥ë¡¼¥ó¤Ï²ò½ü¤µ¤ì¤¿¡£"); #else msg_print("An explosive rune was disarmed."); #endif @@ -3092,78 +3085,95 @@ msg_print(" do_move = TRUE; } } - if (do_move && player_bold(ny, nx) && (d_info[dungeon_type].flags1 & DF1_NO_MELEE)) - { - do_move = FALSE; - } - /* Some monsters never attack */ - if (do_move && player_bold(ny, nx) && (r_ptr->flags1 & RF1_NEVER_BLOW)) - { - /* Hack -- memorize lack of attacks */ - if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_NEVER_BLOW); - - /* Do not move */ - do_move = FALSE; - } - - /* The player is in the way. Attack him. */ + /* The player is in the way */ if (do_move && player_bold(ny, nx)) { - if (!p_ptr->riding || one_in_(2)) + /* Some monsters never attack */ + if (r_ptr->flags1 & RF1_NEVER_BLOW) { - /* Do the attack */ - (void)make_attack_normal(m_idx); + /* Hack -- memorize lack of attacks */ + if (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; @@ -3171,17 +3181,73 @@ msg_print(" /* 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; @@ -3190,96 +3256,72 @@ msg_print(" /* 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(); - - /* Update stuff */ - p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE); + /* Sound */ + /* sound(SOUND_WALK); */ - /* Update the monsters */ - p_ptr->update |= (PU_DISTANCE); - - /* Update sub-windows */ - 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 */ @@ -3287,56 +3329,55 @@ msg_print(" 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]; - - /* 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; + s16b this_o_idx, next_o_idx; + bool do_take = (r_ptr->flags2 & RF2_TAKE_ITEM) ? TRUE : FALSE; - /* 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]; - u32b flg2 = 0L; - u32b flg3 = 0L; + /* Acquire object */ + object_type *o_ptr = &o_list[this_o_idx]; - char m_name[80]; - char o_name[MAX_NLEN]; + /* Acquire next object */ + next_o_idx = o_ptr->next_o_idx; + + 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, 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); @@ -3349,13 +3390,18 @@ msg_print(" 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; @@ -3365,16 +3411,16 @@ msg_print(" { /* Dump a message */ #ifdef JP -msg_format("%^s¤Ï%s¤ò½¦¤ª¤¦¤È¤·¤¿¤¬¡¢¤À¤á¤À¤Ã¤¿¡£", m_name, o_name); + msg_format("%^s¤Ï%s¤ò½¦¤ª¤¦¤È¤·¤¿¤¬¡¢¤À¤á¤À¤Ã¤¿¡£", m_name, o_name); #else -msg_format("%^s tries to pick up %s, but fails.", m_name, o_name); + msg_format("%^s tries to pick up %s, but fails.", m_name, o_name); #endif } } } /* Pick up the item */ - else if (r_ptr->flags2 & RF2_TAKE_ITEM) + else if (do_take) { /* Take note */ did_take_item = TRUE; @@ -3384,18 +3430,17 @@ msg_format("%^s tries to pick up %s, but fails.", m_name, o_name); { /* Dump a message */ #ifdef JP -msg_format("%^s¤¬%s¤ò½¦¤Ã¤¿¡£", m_name, o_name); + msg_format("%^s¤¬%s¤ò½¦¤Ã¤¿¡£", m_name, o_name); #else msg_format("%^s picks up %s.", m_name, o_name); #endif - } /* Excise the object */ 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; @@ -3421,11 +3466,10 @@ msg_format("%^s { /* Dump a message */ #ifdef JP -msg_format("%^s¤¬%s¤òÇ˲õ¤·¤¿¡£", m_name, o_name); + msg_format("%^s¤¬%s¤òÇ˲õ¤·¤¿¡£", m_name, o_name); #else msg_format("%^s destroys %s.", m_name, o_name); #endif - } /* Delete the object */ @@ -3447,7 +3491,7 @@ msg_format("%^s m_ptr->mflag2 &= ~MFLAG2_NOFLOW; /* If we haven't done anything, try casting a spell again */ - if (!do_turn && !do_move && !m_ptr->monfear && !(p_ptr->riding == m_idx) && aware) + if (!do_turn && !do_move && !MON_MONFEAR(m_ptr) && !is_riding_mon && aware) { /* Try to cast spell again */ if (r_ptr->freq_spell && randint1(100) <= r_ptr->freq_spell) @@ -3461,7 +3505,7 @@ msg_format("%^s 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); @@ -3476,7 +3520,7 @@ msg_format("%^s } /* 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); @@ -3502,13 +3546,13 @@ msg_format("%^s /* 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]; @@ -3517,17 +3561,14 @@ msg_format("%^s /* 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 (?) */ } } @@ -3582,6 +3623,7 @@ void process_monsters(void) u32b old_r_flags4 = 0L; u32b old_r_flags5 = 0L; u32b old_r_flags6 = 0L; + u32b old_r_flagsr = 0L; byte old_r_blows0 = 0; byte old_r_blows1 = 0; @@ -3611,6 +3653,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]; @@ -3685,7 +3728,7 @@ void process_monsters(void) /* Hack -- Monsters can "smell" the player from far away */ /* Note that most monsters have "aaf" of "20" or so */ else if (!(m_ptr->mflag2 & MFLAG2_NOFLOW) && - (cave_floor_bold(py, px) || (cave[py][px].feat == FEAT_TREES)) && + 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)) @@ -3709,8 +3752,8 @@ void process_monsters(void) /* Monsters move quickly in Nightmare mode */ if (ironman_nightmare) speed += 5; - if (m_ptr->fast) speed += 10; - if (m_ptr->slow) speed -= 10; + if (MON_FAST(m_ptr)) speed += 10; + if (MON_SLOW(m_ptr)) speed -= 10; } /* Give this monster some energy */ @@ -3759,6 +3802,7 @@ void process_monsters(void) (old_r_flags4 != r_ptr->r_flags4) || (old_r_flags5 != r_ptr->r_flags5) || (old_r_flags6 != r_ptr->r_flags6) || + (old_r_flagsr != r_ptr->r_flagsr) || (old_r_blows0 != r_ptr->r_blows[0]) || (old_r_blows1 != r_ptr->r_blows[1]) || (old_r_blows2 != r_ptr->r_blows[2]) || @@ -3772,106 +3816,756 @@ void process_monsters(void) } - -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; - - if (p_ptr->inside_battle) return; + bool notice = FALSE; - 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; + /* Hack -- Force good values */ + v = (v > 200) ? 200 : (v < 0) ? 0 : v; - if (m_ptr->exp >= r_ptr->next_exp) + /* Open */ + if (v) + { + if (!MON_FAST(m_ptr)) + { + mproc_add(m_idx, MTIMED_FAST); + notice = TRUE; + } + } + + /* Shut */ + else + { + if (MON_FAST(m_ptr)) + { + mproc_remove(m_idx, MTIMED_FAST); + notice = TRUE; + } + } + + /* Use the value */ + m_ptr->mtimed[MTIMED_FAST] = 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_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 = &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; + + 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; @@ -3879,10 +4573,18 @@ void monster_gain_exp(int m_idx, int s_idx) int old_r_idx = m_ptr->r_idx; byte old_sub_align = m_ptr->sub_align; + /* Hack -- Reduce the racial counter of previous monster */ + real_r_ptr(m_ptr)->cur_num--; + monster_desc(m_name, m_ptr, 0); m_ptr->r_idx = r_ptr->next_r_idx; + + /* Count the monsters on the level */ + real_r_ptr(m_ptr)->cur_num++; + m_ptr->ap_r_idx = m_ptr->r_idx; r_ptr = &r_info[m_ptr->r_idx]; + if (r_ptr->flags1 & RF1_FORCE_MAXHP) { m_ptr->max_maxhp = maxroll(r_ptr->hdice, r_ptr->hside); @@ -3917,12 +4619,38 @@ void monster_gain_exp(int m_idx, int s_idx) 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 + r_ptr->name); + msg_format("%s¤Ï%s¤Ë¿Ê²½¤·¤¿¡£", m_name, r_name + hallu_race->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 + hallu_race->name); #endif - r_info[old_r_idx].r_xtra1 |= MR1_SINKA; + } + else + { +#ifdef JP + 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); +#endif + } + } + + 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);