X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fmelee2.c;h=4ee3b46de9ab85a5d88d6efba6eaf71446e20b87;hb=2dabd068522a6433630194cea47785e2d680c294;hp=e2c7ebb0fd90189feb7472f8a421a945b734df83;hpb=e020c59a33f5b4b18b7f4cd5094b02a0d70ae92f;p=hengband%2Fhengband.git diff --git a/src/melee2.c b/src/melee2.c index e2c7ebb0f..4ee3b46de 100644 --- a/src/melee2.c +++ b/src/melee2.c @@ -210,13 +210,11 @@ void mon_take_hit_mon(int m_idx, int dam, bool *fear, cptr note, int who) } /* Wake it up */ - m_ptr->csleep = 0; - - if (r_ptr->flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE); + (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) { @@ -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 @@ -1432,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) { @@ -1445,10 +1435,11 @@ static bool monst_attack_monst(int m_idx, int t_idx) int ac, rlev, pt; char m_name[80], t_name[80]; char temp[80]; - bool blinked, heal_effect; + 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 = is_seen(m_ptr); bool see_t = is_seen(t_ptr); @@ -1519,12 +1510,17 @@ static bool monst_attack_monst(int m_idx, int t_idx) 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 */ - t_ptr->csleep = 0; + (void)set_monster_csleep(t_idx, 0); - if (tr_ptr->flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE); + 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) @@ -1843,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; @@ -1852,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 ((p_ptr->riding != m_idx) && 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) @@ -2001,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_AIMED, -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; @@ -2024,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) @@ -2133,20 +2096,17 @@ msg_format("%s case RBM_CHARGE: { /* Wake it up */ - t_ptr->csleep = 0; - - if (tr_ptr->flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE); + (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; @@ -2175,7 +2135,7 @@ 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); @@ -2202,7 +2162,7 @@ msg_format("%s mon_fight = TRUE; } - teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE, FALSE); + teleport_away(m_idx, MAX_SIGHT * 2 + 5, 0L); } return TRUE; @@ -2253,6 +2213,7 @@ static void process_monster(int m_idx) bool do_turn; bool do_move; bool do_view; + bool must_alter_to_move; bool did_open_door; bool did_bash_door; @@ -2285,7 +2246,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]; @@ -2465,7 +2426,7 @@ static void process_monster(int m_idx) } /* Handle "sleep" */ - if (m_ptr->csleep) + if (MON_CSLEEP(m_ptr)) { /* Handle non-aggravation - Still sleeping */ if (!(p_ptr->cursed & TRC_AGGRAVATE)) return; @@ -2473,9 +2434,7 @@ static void process_monster(int m_idx) /* Handle aggravation */ /* Reset sleep counter */ - m_ptr->csleep = 0; - - if (r_ptr->flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE); + (void)set_monster_csleep(m_idx, 0); /* Notice the "waking up" */ if (see_m) @@ -2495,10 +2454,6 @@ static void process_monster(int m_idx) if (m_ptr->ml) { - /* Redraw the health bar */ - if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH); - if (is_riding_mon) p_ptr->redraw |= (PR_UHEALTH); - /* Hack -- Count the wakings */ if ((r_ptr->r_wake < MAX_UCHAR) && is_original_ap(m_ptr)) { @@ -2508,7 +2463,7 @@ static void process_monster(int m_idx) } /* Handle "stun" */ - if (m_ptr->stunned) + if (MON_STUNNED(m_ptr)) { /* Sometimes skip move */ if (one_in_(2)) return; @@ -2536,13 +2491,16 @@ static void process_monster(int m_idx) 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); } @@ -2625,11 +2583,10 @@ 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 */ @@ -2647,42 +2604,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) { @@ -2742,7 +2693,7 @@ msg_format("%^s%s", m_name, monmessage); /* 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; @@ -2853,6 +2804,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; @@ -2894,12 +2846,26 @@ msg_format("%^s%s", m_name, monmessage); do_move = TRUE; } + /* Possibly a monster to attack */ else if (c_ptr->m_idx) { - /* Possibly a monster to attack */ do_move = TRUE; } + /* 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) && + (!have_flag(f_ptr->flags, FF_GLASS) || (r_ptr->flags2 & RF2_STUPID) || (m_ptr->hp >= MAX(m_ptr->maxhp / 3, 200)))) + { + /* Eat through walls/doors/rubble */ + do_move = TRUE; + if (!can_cross) must_alter_to_move = TRUE; + + /* Monster destroyed a wall (later) */ + did_kill_wall = TRUE; + } + /* Floor is open? */ else if (can_cross) { @@ -2913,31 +2879,12 @@ msg_format("%^s%s", m_name, monmessage); /* Monster went through a wall */ did_pass_wall = TRUE; } - - if ((r_ptr->flags2 & RF2_KILL_WALL) && have_flag(f_ptr->flags, FF_TUNNEL) && - !have_flag(f_ptr->flags, FF_LOS) && !have_flag(f_ptr->flags, FF_PERMANENT)) - { - /* Monster destroyed a wall (later) */ - did_kill_wall = TRUE; - } - } - - /* Monster destroys walls (and doors) */ - else if ((r_ptr->flags2 & RF2_KILL_WALL) && !is_riding_mon && - have_flag(f_ptr->flags, FF_TUNNEL) && !have_flag(f_ptr->flags, FF_PERMANENT)) - { - /* Eat through walls/doors/rubble */ - do_move = TRUE; - - /* Monster destroyed a wall (later) */ - did_kill_wall = TRUE; } /* Handle doors and secret doors */ else if (is_closed_door(c_ptr->feat)) { bool may_bash = TRUE; - feature_type *f_ptr = &f_info[c_ptr->feat]; /* Assume no move allowed */ do_move = FALSE; @@ -2985,10 +2932,17 @@ msg_format("%^s%s", m_name, monmessage); if (randint0(m_ptr->hp / 10) > f_ptr->power) { /* Message */ + if (have_flag(f_ptr->flags, FF_GLASS)) +#ifdef JP + msg_print("¥¬¥é¥¹¤¬ºÕ¤±¤ë²»¤¬¤·¤¿¡ª"); +#else + msg_print("You hear a glass was crashed!"); +#endif + else #ifdef JP - msg_print("¥É¥¢¤ò᤭³«¤±¤ë²»¤¬¤·¤¿¡ª"); + msg_print("¥É¥¢¤ò᤭³«¤±¤ë²»¤¬¤·¤¿¡ª"); #else - msg_print("You hear a door burst open!"); + msg_print("You hear a door burst open!"); #endif /* Disturb (sometimes) */ @@ -2999,6 +2953,7 @@ msg_format("%^s%s", m_name, monmessage); /* Hack -- fall into doorway */ do_move = TRUE; + must_alter_to_move = TRUE; } } @@ -3007,9 +2962,19 @@ msg_format("%^s%s", m_name, monmessage); if (did_open_door || did_bash_door) { /* Break down the door */ - if (did_bash_door && ((randint0(100) < 50) || (feat_state(c_ptr->feat, FF_OPEN) == c_ptr->feat))) + 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_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 */ @@ -3018,6 +2983,8 @@ msg_format("%^s%s", m_name, monmessage); cave_alter_feat(ny, nx, FF_OPEN); } + f_ptr = &f_info[c_ptr->feat]; + /* Handle viewable doors */ do_view = TRUE; } @@ -3122,7 +3089,7 @@ msg_format("%^s%s", m_name, monmessage); /* In anti-melee dungeon, stupid or confused monster takes useless turn */ if (do_move && (d_info[dungeon_type].flags1 & DF1_NO_MELEE)) { - if (!m_ptr->confused) + if (!MON_CONFUSED(m_ptr)) { if (!(r_ptr->flags2 & RF2_STUPID)) do_move = FALSE; else @@ -3161,7 +3128,7 @@ msg_format("%^s%s", m_name, monmessage); if (((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW) && (r_ptr->mexp * r_ptr->level > z_ptr->mexp * z_ptr->level) && can_cross && (c_ptr->m_idx != p_ptr->riding)) || - are_enemies(m_ptr, y_ptr) || m_ptr->confused) + are_enemies(m_ptr, y_ptr) || MON_CONFUSED(m_ptr)) { if (!(r_ptr->flags1 & RF1_NEVER_BLOW)) { @@ -3178,7 +3145,7 @@ msg_format("%^s%s", m_name, monmessage); /* In anti-melee dungeon, stupid or confused monster takes useless turn */ else if (d_info[dungeon_type].flags1 & DF1_NO_MELEE) { - if (m_ptr->confused) return; + 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); @@ -3202,15 +3169,65 @@ msg_format("%^s%s", m_name, monmessage); did_move_body = TRUE; /* Wake up the moved monster */ - y_ptr->csleep = 0; - - if (r_info[y_ptr->r_idx].flags7 & (RF7_LITE_MASK | RF7_DARK_MASK)) - p_ptr->update |= (PU_MON_LITE); + (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 @@ -3226,18 +3243,13 @@ msg_format("%^s%s", m_name, monmessage); /* Some monsters never move */ if (do_move && (r_ptr->flags1 & RF1_NEVER_MOVE)) { - /* Hack -- memorize lack of attacks */ + /* 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 (is_riding_mon) - { - if (!p_ptr->riding_ryoute && !(m_list[p_ptr->riding].monfear)) do_move = FALSE; - } - /* Creature has been allowed move */ if (do_move) { @@ -3246,25 +3258,9 @@ msg_format("%^s%s", m_name, monmessage); /* Take a turn */ do_turn = TRUE; - if (did_kill_wall) - { - if (one_in_(GRINDNOISE)) - { -#ifdef JP - msg_print("¥®¥·¥®¥·¤¤¤¦²»¤¬Ê¹¤³¤¨¤ë¡£"); -#else - msg_print("There is a grinding sound."); -#endif - } - - cave_alter_feat(ny, nx, FF_HURT_DISI); - - /* Note changes to viewable region */ - do_view = TRUE; - } - else if (have_flag(f_ptr->flags, FF_TREE)) + if (have_flag(f_ptr->flags, FF_TREE)) { - if (!(r_ptr->flags7 & RF7_CAN_FLY) && (!is_riding_mon || !p_ptr->levitation) && !(r_ptr->flags8 & RF8_WILD_WOOD)) + if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD)) { m_ptr->energy_need += ENERGY_NEED(); } @@ -3479,7 +3475,7 @@ msg_format("%^s%s", m_name, monmessage); m_ptr->mflag2 &= ~MFLAG2_NOFLOW; /* If we haven't done anything, try casting a spell again */ - if (!do_turn && !do_move && !m_ptr->monfear && !is_riding_mon && 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) @@ -3534,10 +3530,10 @@ msg_format("%^s%s", m_name, monmessage); /* 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 (see_m) @@ -3549,17 +3545,14 @@ msg_format("%^s%s", m_name, monmessage); /* 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 (?) */ } } @@ -3743,8 +3736,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 */ @@ -3807,6 +3800,655 @@ void process_monsters(void) } +int get_mproc_idx(int m_idx, int mproc_type) +{ + s16b *cur_mproc_list = mproc_list[mproc_type]; + int i; + + for (i = mproc_max[mproc_type] - 1; i >= 0; i--) + { + if (cur_mproc_list[i] == m_idx) return i; + } + + return -1; +} + + +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; +} + + +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--) + { + /* Access the monster */ + m_ptr = &m_list[i]; + + /* Ignore "dead" monsters */ + if (!m_ptr->r_idx) continue; + + for (cmi = 0; cmi < MAX_MTIMED; cmi++) + { + if (m_ptr->mtimed[cmi]) mproc_add(i, cmi); + } + } +} + + +/* + * 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; + + /* Hack -- Force good values */ + v = (v > 10000) ? 10000 : (v < 0) ? 0 : v; + + /* Open */ + if (v) + { + if (!MON_CSLEEP(m_ptr)) + { + mproc_add(m_idx, MTIMED_CSLEEP); + notice = TRUE; + } + } + + /* Shut */ + else + { + if (MON_CSLEEP(m_ptr)) + { + mproc_remove(m_idx, MTIMED_CSLEEP); + notice = TRUE; + } + } + + /* Use the value */ + m_ptr->mtimed[MTIMED_CSLEEP] = 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); + } + + if (r_info[m_ptr->r_idx].flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE); + + return TRUE; +} + + +/* + * 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]; + bool notice = FALSE; + + /* Hack -- Force good values */ + v = (v > 200) ? 200 : (v < 0) ? 0 : v; + + /* 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 (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 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) {