OSDN Git Service

[Refactor] #37353 モンスター間の打撃処理を melee1.c / melee.h へ移動.
[hengband/hengband.git] / src / monster-process.c
index 3811990..42e65d7 100644 (file)
@@ -1202,666 +1202,6 @@ static bool get_moves(MONSTER_IDX m_idx, DIRECTION *mm)
 }
 
 
-/*!
- * @brief モンスターから敵モンスターへの命中判定
- * @param power 打撃属性による基本命中値
- * @param level 攻撃側モンスターのレベル
- * @param ac 目標モンスターのAC
- * @param stun 攻撃側モンスターが朦朧状態ならTRUEを返す
- * @return 命中ならばTRUEを返す
- */
-static int check_hit2(int power, DEPTH level, ARMOUR_CLASS ac, int stun)
-{
-       int i, k;
-
-       /* Percentile dice */
-       k = randint0(100);
-
-       if (stun && one_in_(2)) return FALSE;
-
-       /* Hack -- Always miss or hit */
-       if (k < 10) return (k < 5);
-
-       /* Calculate the "attack quality" */
-       i = (power + (level * 3));
-
-       /* Power and Level compete against Armor */
-       if ((i > 0) && (randint1(i) > ((ac * 3) / 4))) return (TRUE);
-
-       /* Assume miss */
-       return (FALSE);
-}
-
-
-#define BLOW_EFFECT_TYPE_NONE  0
-#define BLOW_EFFECT_TYPE_FEAR  1
-#define BLOW_EFFECT_TYPE_SLEEP 2
-#define BLOW_EFFECT_TYPE_HEAL  3
-
-
-/*!
- * @brief モンスターから敵モンスターへの打撃攻撃処理
- * @param m_idx 攻撃側モンスターの参照ID
- * @param t_idx 目標側モンスターの参照ID
- * @return 実際に打撃処理が行われた場合TRUEを返す
- */
-static bool monst_attack_monst(MONSTER_IDX m_idx, MONSTER_IDX t_idx)
-{
-       monster_type    *m_ptr = &current_floor_ptr->m_list[m_idx];
-       monster_type    *t_ptr = &current_floor_ptr->m_list[t_idx];
-
-       monster_race    *r_ptr = &r_info[m_ptr->r_idx];
-       monster_race    *tr_ptr = &r_info[t_ptr->r_idx];
-
-       ARMOUR_CLASS ap_cnt;
-       ARMOUR_CLASS ac;
-       DEPTH rlev;
-       int pt;
-       GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
-       char            temp[MAX_NLEN];
-       bool            blinked;
-       bool            explode = FALSE, touched = FALSE, fear = FALSE, dead = FALSE;
-       POSITION y_saver = t_ptr->fy;
-       POSITION x_saver = t_ptr->fx;
-       int             effect_type;
-
-       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? */
-       bool known = (m_ptr->cdis <= MAX_SIGHT) || (t_ptr->cdis <= MAX_SIGHT);
-       bool do_silly_attack = (one_in_(2) && p_ptr->image);
-
-       /* Cannot attack self */
-       if (m_idx == t_idx) return FALSE;
-
-       /* Not allowed to attack */
-       if (r_ptr->flags1 & RF1_NEVER_BLOW) return FALSE;
-
-       if (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) return (FALSE);
-
-       /* Total armor */
-       ac = tr_ptr->ac;
-
-       /* Extract the effective monster level */
-       rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
-
-       monster_desc(m_name, m_ptr, 0);
-       monster_desc(t_name, t_ptr, 0);
-
-       /* Assume no blink */
-       blinked = FALSE;
-
-       if (!see_either && known)
-       {
-               current_floor_ptr->monster_noise = TRUE;
-       }
-
-       if (p_ptr->riding && (m_idx == p_ptr->riding)) disturb(TRUE, TRUE);
-
-       /* Scan through all four blows */
-       for (ap_cnt = 0; ap_cnt < 4; ap_cnt++)
-       {
-               bool obvious = FALSE;
-
-               HIT_POINT power = 0;
-               HIT_POINT damage = 0;
-
-               concptr act = NULL;
-
-               /* Extract the attack infomation */
-               int effect = r_ptr->blow[ap_cnt].effect;
-               int method = r_ptr->blow[ap_cnt].method;
-               int d_dice = r_ptr->blow[ap_cnt].d_dice;
-               int d_side = r_ptr->blow[ap_cnt].d_side;
-
-               if (!monster_is_valid(m_ptr)) break;
-
-               /* Stop attacking if the target dies! */
-               if (t_ptr->fx != x_saver || t_ptr->fy != y_saver)
-                       break;
-
-               /* Hack -- no more attacks */
-               if (!method) break;
-
-               if (method == RBM_SHOOT) continue;
-
-               /* Extract the attack "power" */
-               power = mbe_info[effect].power;
-
-               /* Monster hits */
-               if (!effect || check_hit2(power, rlev, ac, MON_STUNNED(m_ptr)))
-               {
-                       (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)
-                       {
-                       case RBM_HIT:
-                               {
-                                       act = _("%sを殴った。", "hits %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_TOUCH:
-                               {
-                                       act = _("%sを触った。", "touches %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_PUNCH:
-                               {
-                                       act = _("%sをパンチした。", "punches %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_KICK:
-                               {
-                                       act = _("%sを蹴った。", "kicks %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_CLAW:
-                               {
-                                       act = _("%sをひっかいた。", "claws %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_BITE:
-                               {
-                                       act = _("%sを噛んだ。", "bites %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_STING:
-                               {
-                                       act = _("%sを刺した。", "stings %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_SLASH:
-                               {
-                                       act = _("%sを斬った。", "slashes %s.");
-                                       break;
-                               }
-
-                       case RBM_BUTT:
-                               {
-                                       act = _("%sを角で突いた。", "butts %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_CRUSH:
-                               {
-                                       act = _("%sに体当りした。", "crushes %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_ENGULF:
-                               {
-                                       act = _("%sを飲み込んだ。", "engulfs %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_CHARGE:
-                               {
-                                       act = _("%sに請求書をよこした。", "charges %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_CRAWL:
-                               {
-                                       act = _("%sの体の上を這い回った。", "crawls on %s.");
-                                       touched = TRUE;
-                                       break;
-                               }
-
-                       case RBM_DROOL:
-                               {
-                                       act = _("%sによだれをたらした。", "drools on %s.");
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_SPIT:
-                               {
-                                       act = _("%sに唾を吐いた。", "spits on %s.");
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_EXPLODE:
-                               {
-                                       if (see_either) disturb(TRUE, TRUE);
-                                       act = _("爆発した。", "explodes.");
-                                       explode = TRUE;
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_GAZE:
-                               {
-                                       act = _("%sをにらんだ。", "gazes at %s.");
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_WAIL:
-                               {
-                                       act = _("%sに泣きついた。", "wails at %s.");
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_SPORE:
-                               {
-                                       act = _("%sに胞子を飛ばした。", "releases spores at %s.");
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_XXX4:
-                               {
-                                       act = _("%sにXXX4を飛ばした。", "projects XXX4's at %s.");
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_BEG:
-                               {
-                                       act = _("%sに金をせがんだ。", "begs %s for money.");
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_INSULT:
-                               {
-                                       act = _("%sを侮辱した。", "insults %s.");
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_MOAN:
-                               {
-                                       act = _("%sにむかってうめいた。", "moans at %s.");
-                                       touched = FALSE;
-                                       break;
-                               }
-
-                       case RBM_SHOW:
-                               {
-                                       act = _("%sにむかって歌った。", "sings to %s.");
-                                       touched = FALSE;
-                                       break;
-                               }
-                       }
-
-                       if (act && see_either)
-                       {
-#ifdef JP
-                               if (do_silly_attack) act = silly_attacks2[randint0(MAX_SILLY_ATTACK)];
-                               strfmt(temp, act, t_name);
-                               msg_format("%^sは%s", m_name, temp);
-#else
-                               if (do_silly_attack)
-                               {
-                                       act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
-                                       strfmt(temp, "%s %s.", act, t_name);
-                               }
-                               else strfmt(temp, act, t_name);
-                               msg_format("%^s %s", m_name, temp);
-#endif
-                       }
-
-                       /* Hack -- assume all attacks are obvious */
-                       obvious = TRUE;
-
-                       /* Roll out the damage */
-                       damage = damroll(d_dice, d_side);
-
-                       /* Assume no effect */
-                       effect_type = BLOW_EFFECT_TYPE_NONE;
-
-                       pt = GF_MISSILE;
-
-                       /* Apply appropriate damage */
-                       switch (effect)
-                       {
-                       case 0:
-                       case RBE_DR_MANA:
-                               damage = pt = 0;
-                               break;
-
-                       case RBE_SUPERHURT:
-                               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;
-                               }
-
-                               /* Fall through */
-
-                       case RBE_HURT:
-                               damage -= (damage * ((ac < 150) ? ac : 150) / 250);
-                               break;
-
-                       case RBE_POISON:
-                       case RBE_DISEASE:
-                               pt = GF_POIS;
-                               break;
-
-                       case RBE_UN_BONUS:
-                       case RBE_UN_POWER:
-                               pt = GF_DISENCHANT;
-                               break;
-
-                       case RBE_EAT_ITEM:
-                       case RBE_EAT_GOLD:
-                               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;
-
-                       case RBE_ELEC:
-                               pt = GF_ELEC;
-                               break;
-
-                       case RBE_FIRE:
-                               pt = GF_FIRE;
-                               break;
-
-                       case RBE_COLD:
-                               pt = GF_COLD;
-                               break;
-
-                       case RBE_CONFUSE:
-                               pt = GF_CONFUSION;
-                               break;
-
-                       case RBE_TERRIFY:
-                               effect_type = BLOW_EFFECT_TYPE_FEAR;
-                               break;
-
-                       case RBE_PARALYZE:
-                               effect_type = BLOW_EFFECT_TYPE_SLEEP;
-                               break;
-
-                       case RBE_SHATTER:
-                               damage -= (damage * ((ac < 150) ? ac : 150) / 250);
-                               if (damage > 23) earthquake(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;
-
-                       case RBE_TIME:
-                               pt = GF_TIME;
-                               break;
-
-                       case RBE_DR_LIFE:
-                               pt = GF_HYPODYNAMIA;
-                               effect_type = BLOW_EFFECT_TYPE_HEAL;
-                               break;
-
-                       case RBE_INERTIA:
-                               pt = GF_INERTIAL;
-                               break;
-
-                       case RBE_STUN:
-                               pt = GF_SOUND;
-                               break;
-
-                       default:
-                               pt = 0;
-                               break;
-                       }
-
-                       if (pt)
-                       {
-                               /* Do damage if not exploding */
-                               if (!explode)
-                               {
-                                       project(m_idx, 0, t_ptr->fy, t_ptr->fx,
-                                               damage, pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                               }
-
-                               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(m_idx)) && (damage > 2))
-                                       {
-                                               bool did_heal = FALSE;
-
-                                               if (m_ptr->hp < m_ptr->maxhp) did_heal = TRUE;
-
-                                               /* Heal */
-                                               m_ptr->hp += damroll(4, damage / 6);
-                                               if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
-
-                                               /* 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);
-
-                                               /* Special message */
-                                               if (see_m && did_heal)
-                                               {
-                                                       msg_format(_("%sは体力を回復したようだ。", "%^s appears healthier."), m_name);
-                                               }
-                                       }
-                                       break;
-                               }
-
-                               if (touched)
-                               {
-                                       /* Aura fire */
-                                       if ((tr_ptr->flags2 & RF2_AURA_FIRE) && m_ptr->r_idx)
-                                       {
-                                               if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK))
-                                               {
-                                                       if (see_either)
-                                                       {
-                                                               msg_format(_("%^sは突然熱くなった!", "%^s is suddenly very hot!"), m_name);
-                                                       }
-                                                       if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_FIRE;
-                                                       project(t_idx, 0, m_ptr->fy, m_ptr->fx,
-                                                               damroll (1 + ((tr_ptr->level) / 26),
-                                                               1 + ((tr_ptr->level) / 17)),
-                                                               GF_FIRE, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                                               }
-                                               else
-                                               {
-                                                       if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
-                                               }
-                                       }
-
-                                       /* Aura cold */
-                                       if ((tr_ptr->flags3 & RF3_AURA_COLD) && m_ptr->r_idx)
-                                       {
-                                               if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK))
-                                               {
-                                                       if (see_either)
-                                                       {
-                                                               msg_format(_("%^sは突然寒くなった!", "%^s is suddenly very cold!"), m_name);
-                                                       }
-                                                       if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags3 |= RF3_AURA_COLD;
-                                                       project(t_idx, 0, m_ptr->fy, m_ptr->fx,
-                                                               damroll (1 + ((tr_ptr->level) / 26),
-                                                               1 + ((tr_ptr->level) / 17)),
-                                                               GF_COLD, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                                               }
-                                               else
-                                               {
-                                                       if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
-                                               }
-                                       }
-
-                                       /* Aura elec */
-                                       if ((tr_ptr->flags2 & RF2_AURA_ELEC) && m_ptr->r_idx)
-                                       {
-                                               if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK))
-                                               {
-                                                       if (see_either)
-                                                       {
-                                                               msg_format(_("%^sは電撃を食らった!", "%^s gets zapped!"), m_name);
-                                                       }
-                                                       if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_ELEC;
-                                                       project(t_idx, 0, m_ptr->fy, m_ptr->fx,
-                                                               damroll (1 + ((tr_ptr->level) / 26),
-                                                               1 + ((tr_ptr->level) / 17)),
-                                                               GF_ELEC, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                                               }
-                                               else
-                                               {
-                                                       if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               /* Monster missed player */
-               else
-               {
-                       /* Analyze failed attacks */
-                       switch (method)
-                       {
-                       case RBM_HIT:
-                       case RBM_TOUCH:
-                       case RBM_PUNCH:
-                       case RBM_KICK:
-                       case RBM_CLAW:
-                       case RBM_BITE:
-                       case RBM_STING:
-                       case RBM_SLASH:
-                       case RBM_BUTT:
-                       case RBM_CRUSH:
-                       case RBM_ENGULF:
-                       case RBM_CHARGE:
-                               {
-                                       (void)set_monster_csleep(t_idx, 0);
-
-                                       /* Visible monsters */
-                                       if (see_m)
-                                       {
-#ifdef JP
-                                               msg_format("%sは%^sの攻撃をかわした。", t_name, m_name);
-#else
-                                               msg_format("%^s misses %s.", m_name, t_name);
-#endif
-                                       }
-
-                                       break;
-                               }
-                       }
-               }
-
-
-               /* Analyze "visible" monsters only */
-               if (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))
-                       {
-                               /* Count attacks of this type */
-                               if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR)
-                               {
-                                       r_ptr->r_blows[ap_cnt]++;
-                               }
-                       }
-               }
-       }
-
-       if (explode)
-       {
-               sound(SOUND_EXPLODE);
-
-               /* Cancel Invulnerability */
-               (void)set_monster_invulner(m_idx, 0, FALSE);
-               mon_take_hit_mon(m_idx, m_ptr->hp + 1, &dead, &fear, _("は爆発して粉々になった。", " explodes into tiny shreds."), m_idx);
-               blinked = FALSE;
-       }
-
-       /* Blink away */
-       if (blinked && m_ptr->r_idx)
-       {
-               if (teleport_barrier(m_idx))
-               {
-                       if (see_m)
-                       {
-                               msg_print(_("泥棒は笑って逃げ...ようとしたがバリアに防がれた。", "The thief flees laughing...? But magic barrier obstructs it."));
-                       }
-                       else if (known)
-                       {
-                               current_floor_ptr->monster_noise = TRUE;
-                       }
-               }
-               else
-               {
-                       if (see_m)
-                       {
-                               msg_print(_("泥棒は笑って逃げた!", "The thief flees laughing!"));
-                       }
-                       else if (known)
-                       {
-                               current_floor_ptr->monster_noise = TRUE;
-                       }
-
-                       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) ||