OSDN Git Service

[Refactor] #40514 player_type の resist_disen 変数を廃止. / Abolished the resist_disen...
[hengband/hengband.git] / src / monster-attack / monster-attack-switcher.c
index e4ed138..8bba812 100644 (file)
@@ -9,6 +9,7 @@
 #include "inventory/inventory-slot-types.h"
 #include "mind/drs-types.h"
 #include "mind/mind-mirror-master.h"
+#include "monster-attack/monster-attack-lose.h"
 #include "monster-attack/monster-attack-status.h"
 #include "monster-attack/monster-eating.h"
 #include "monster/monster-status.h"
@@ -37,7 +38,7 @@ static void calc_blow_poison(player_type *target_ptr, monap_type *monap_ptr)
     if (monap_ptr->explode)
         return;
 
-    if (!(target_ptr->resist_pois || is_oppose_pois(target_ptr)) && !check_multishadow(target_ptr)
+    if (!(has_resist_pois(target_ptr) || is_oppose_pois(target_ptr)) && !check_multishadow(target_ptr)
         && set_poisoned(target_ptr, target_ptr->poisoned + randint1(monap_ptr->rlev) + 5))
         monap_ptr->obvious = TRUE;
 
@@ -57,12 +58,12 @@ static void calc_blow_disenchant(player_type *target_ptr, monap_type *monap_ptr)
     if (monap_ptr->explode)
         return;
 
-    if (!target_ptr->resist_disen && !check_multishadow(target_ptr) && apply_disenchant(target_ptr, 0)) {
+    if (!has_resist_disen(target_ptr) && !check_multishadow(target_ptr) && apply_disenchant(target_ptr, 0)) {
         update_creature(target_ptr);
         monap_ptr->obvious = TRUE;
     }
 
-    if (is_resist_disen(target_ptr))
+    if (has_resist_disen(target_ptr))
         monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
 
     monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
@@ -70,6 +71,43 @@ static void calc_blow_disenchant(player_type *target_ptr, monap_type *monap_ptr)
 }
 
 /*!
+ * @brief 魔道具吸収ダメージを計算する (消費魔力減少、呪文失敗率減少、魔道具使用能力向上があればそれぞれ-7.5%)
+ * @param target_ptr プレーヤーへの参照ポインタ
+ * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
+ * @return なし
+ * @detals 魔道具使用能力向上フラグがあれば、吸収対象のアイテムをスキャンされる回数が半分で済む
+ */
+static void calc_blow_un_power(player_type *target_ptr, monap_type *monap_ptr)
+{
+    int damage_ratio = 1000;
+    if (has_dec_mana(target_ptr))
+        damage_ratio -= 75;
+
+    if (has_easy_spell(target_ptr))
+        damage_ratio -= 75;
+
+    bool is_magic_mastery = has_magic_mastery(target_ptr) != 0;
+    if (is_magic_mastery)
+        damage_ratio -= 75;
+
+    monap_ptr->damage = monap_ptr->damage * damage_ratio / 1000;
+    monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
+    if (target_ptr->is_dead || check_multishadow(target_ptr))
+        return;
+
+    int max_draining_item = is_magic_mastery ? 5 : 10;
+    for (int i = 0; i < max_draining_item; i++) {
+        INVENTORY_IDX i_idx = (INVENTORY_IDX)randint0(INVEN_PACK);
+        monap_ptr->o_ptr = &target_ptr->inventory_list[i_idx];
+        if (monap_ptr->o_ptr->k_idx == 0)
+            continue;
+
+        if (process_un_power(target_ptr, monap_ptr))
+            break;
+    }
+}
+
+/*!
  * @brief 盲目ダメージを計算する (耐性があれば、(1d4 + 3) / 8になる)
  * @param target_ptr プレーヤーへの参照ポインタ
  * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
@@ -77,7 +115,7 @@ static void calc_blow_disenchant(player_type *target_ptr, monap_type *monap_ptr)
  */
 static void calc_blow_blind(player_type *target_ptr, monap_type *monap_ptr)
 {
-    if (is_resist_blind(target_ptr))
+    if (has_resist_blind(target_ptr))
         monap_ptr->damage = monap_ptr->damage * (randint1(4) + 3) / 8;
 
     monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
@@ -99,14 +137,14 @@ static void calc_blow_confusion(player_type *target_ptr, monap_type *monap_ptr)
     if (monap_ptr->explode)
         return;
 
-    if (is_resist_conf(target_ptr))
+    if (has_resist_conf(target_ptr))
         monap_ptr->damage = monap_ptr->damage * (randint1(4) + 3) / 8;
 
     monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
     if (target_ptr->is_dead)
         return;
 
-    if (!target_ptr->resist_conf && !check_multishadow(target_ptr) && set_confused(target_ptr, target_ptr->confused + 3 + randint1(monap_ptr->rlev)))
+    if (!has_resist_conf(target_ptr) && !check_multishadow(target_ptr) && set_confused(target_ptr, target_ptr->confused + 3 + randint1(monap_ptr->rlev)))
         monap_ptr->obvious = TRUE;
 
     update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_CONF);
@@ -120,7 +158,7 @@ static void calc_blow_confusion(player_type *target_ptr, monap_type *monap_ptr)
  */
 static void calc_blow_fear(player_type *target_ptr, monap_type *monap_ptr)
 {
-    if (is_resist_fear(target_ptr))
+    if (has_resist_fear(target_ptr))
         monap_ptr->damage = monap_ptr->damage * (randint1(4) + 3) / 8;
 
     monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
@@ -151,185 +189,104 @@ static void calc_blow_paralysis(player_type *target_ptr, monap_type *monap_ptr)
 }
 
 /*!
- * @brief ç\97\85æ°\97ã\83\80ã\83¡ã\83¼ã\82¸ã\82\92è¨\88ç®\97ã\81\99ã\82\8b (æ¯\92è\80\90æ\80§ã\81\8cã\81\82ã\82\8cã\81°ã\80\81(1d4 + 4) / 9ã\81«ã\81ªã\82\8bã\80\82äº\8cé\87\8dè\80\90æ\80§ã\81ªã\82\89æ\9b´ã\81«(1d4 + 4) / 9)
+ * @brief çµ\8cé¨\93å\80¤å\90¸å\8f\8eã\83\80ã\83¡ã\83¼ã\82¸ã\82\92è¨\88ç®\97ã\81\99ã\82\8b (çµ\8cé¨\93å\80¤ä¿\9dæ\8c\81ã\81¨å\9c°ç\8d\84è\80\90æ\80§ã\81\8cã\81\82ã\82\8cã\81°ã\80\81ã\81\9dã\82\8cã\81\9eã\82\8c-7.5%)
  * @param target_ptr プレーヤーへの参照ポインタ
  * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
  * @return なし
- * @details 10% (毒の一次耐性があれば4%、二重耐性ならば1.6%)の確率で耐久が低下し、更に1/10の確率で永久低下する
  */
-static void calc_blow_disease(player_type *target_ptr, monap_type *monap_ptr)
+static void calc_blow_drain_exp(player_type *target_ptr, monap_type *monap_ptr, const int drain_value, const int hold_exp_prob)
 {
-    if (is_resist_pois(target_ptr))
-        monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
+    s32b d = damroll(drain_value, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
+    monap_ptr->obvious = TRUE;
+    int damage_ratio = 1000;
+    if (has_hold_exp(target_ptr))
+        damage_ratio -= 75;
 
-    if (is_oppose_pois(target_ptr))
-        monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
-    
-    monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-    if (target_ptr->is_dead || check_multishadow(target_ptr))
-        return;
-
-    if (!(target_ptr->resist_pois || is_oppose_pois(target_ptr)) && set_poisoned(target_ptr, target_ptr->poisoned + randint1(monap_ptr->rlev) + 5))
-        monap_ptr->obvious = TRUE;
-
-    bool disease_possibility = randint1(100) > calc_nuke_damage_rate(target_ptr);
-    if (disease_possibility || (randint1(100) > 10) || (target_ptr->prace == RACE_ANDROID))
-        return;
-
-    bool perm = one_in_(10);
-    if (dec_stat(target_ptr, A_CON, randint1(10), perm)) {
-        msg_print(_("病があなたを蝕んでいる気がする。", "You feel sickly."));
-        monap_ptr->obvious = TRUE;
-    }
-}
-
-/*!
- * @brief 腕力低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
- * @param target_ptr プレーヤーへの参照ポインタ
- * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
- * @return なし
- */
-static void calc_blow_lose_strength(player_type *target_ptr, monap_type *monap_ptr)
-{
-    if (is_sustain_str(target_ptr))
-        monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
+    if (has_resist_neth(target_ptr))
+        damage_ratio -= 75;
 
+    monap_ptr->damage = monap_ptr->damage * damage_ratio / 1000;
     monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
     if (target_ptr->is_dead || check_multishadow(target_ptr))
         return;
 
-    if (do_dec_stat(target_ptr, A_STR))
-        monap_ptr->obvious = TRUE;
+    (void)drain_exp(target_ptr, d, d / 10, hold_exp_prob);
 }
 
 /*!
- * @brief 知能低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
+ * @brief 時間逆転ダメージを計算する (耐性があれば、(1d4 + 4) / 9になる)
  * @param target_ptr プレーヤーへの参照ポインタ
  * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
  * @return なし
  */
-static void calc_blow_lose_intelligence(player_type *target_ptr, monap_type *monap_ptr)
+static void calc_blow_time(player_type *target_ptr, monap_type *monap_ptr)
 {
-    if (is_sustain_int(target_ptr))
-        monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
-
-    monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-    if (target_ptr->is_dead || check_multishadow(target_ptr))
+    if (monap_ptr->explode)
         return;
 
-    if (do_dec_stat(target_ptr, A_INT))
-        monap_ptr->obvious = TRUE;
-}
-
-/*!
- * @brief 賢さ低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
- * @param target_ptr プレーヤーへの参照ポインタ
- * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
- * @return なし
- */
-static void calc_blow_lose_wisdom(player_type *target_ptr, monap_type *monap_ptr)
-{
-    if (is_sustain_wis(target_ptr))
-        monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
+    process_monster_attack_time(target_ptr, monap_ptr);
+    if (has_resist_time(target_ptr))
+        monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
 
     monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-    if (target_ptr->is_dead || check_multishadow(target_ptr))
-        return;
-
-    if (do_dec_stat(target_ptr, A_WIS))
-        monap_ptr->obvious = TRUE;
 }
 
 /*!
- * @brief 器用低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
+ * @brief 生命力吸収ダメージを計算する (経験値維持があれば9/10になる)
  * @param target_ptr プレーヤーへの参照ポインタ
  * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
  * @return なし
  */
-static void calc_blow_lose_dexterity(player_type *target_ptr, monap_type *monap_ptr)
+static void calc_blow_drain_life(player_type *target_ptr, monap_type *monap_ptr)
 {
-    if (is_sustain_dex(target_ptr))
-        monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
+    s32b d = damroll(60, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
+    monap_ptr->obvious = TRUE;
+    if (target_ptr->hold_exp)
+        monap_ptr->damage = monap_ptr->damage * 9 / 10;
 
     monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
     if (target_ptr->is_dead || check_multishadow(target_ptr))
         return;
 
-    if (do_dec_stat(target_ptr, A_DEX))
-        monap_ptr->obvious = TRUE;
+    bool resist_drain = check_drain_hp(target_ptr, d);
+    process_drain_life(target_ptr, monap_ptr, resist_drain);
 }
 
 /*!
- * @brief 耐久低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
+ * @brief MPダメージを計算する (消費魔力減少、呪文失敗率減少、魔道具使用能力向上があればそれぞれ-5%)
  * @param target_ptr プレーヤーへの参照ポインタ
  * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
  * @return なし
  */
-static void calc_blow_lose_constitution(player_type *target_ptr, monap_type *monap_ptr)
+static void calc_blow_drain_mana(player_type *target_ptr, monap_type *monap_ptr)
 {
-    if (is_sustain_con(target_ptr))
-        monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
-
-    monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-    if (target_ptr->is_dead || check_multishadow(target_ptr))
-        return;
-
-    if (do_dec_stat(target_ptr, A_CON))
-        monap_ptr->obvious = TRUE;
-}
+    monap_ptr->obvious = TRUE;
+    int damage_ratio = 100;
+    if (has_dec_mana(target_ptr))
+        damage_ratio -= 5;
 
-/*!
- * @brief 魅力低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
- * @param target_ptr プレーヤーへの参照ポインタ
- * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
- * @return なし
- */
-static void calc_blow_lose_charisma(player_type *target_ptr, monap_type *monap_ptr)
-{
-    if (is_sustain_chr(target_ptr))
-        monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
+    if (has_easy_spell(target_ptr))
+        damage_ratio -= 5;
 
-    monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-    if (target_ptr->is_dead || check_multishadow(target_ptr))
-        return;
+    if (has_magic_mastery(target_ptr))
+        damage_ratio -= 5;
 
-    if (do_dec_stat(target_ptr, A_CHR))
-        monap_ptr->obvious = TRUE;
+    monap_ptr->damage = monap_ptr->damage * damage_ratio / 100;
+    process_drain_mana(target_ptr, monap_ptr);
+    update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_MANA);
 }
 
-/*!
- * @brief 全能力低下ダメージを計算する (維持があれば、1つに付き-3%軽減する)
- * @param target_ptr プレーヤーへの参照ポインタ
- * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
- * @return なし
- */
-static void calc_blow_lose_all(player_type *target_ptr, monap_type *monap_ptr)
+static void calc_blow_inertia(player_type *target_ptr, monap_type *monap_ptr)
 {
-    int damage_ratio = 100;
-    if (is_sustain_str(target_ptr))
-        damage_ratio -= 3;
-
-    if (is_sustain_int(target_ptr))
-        damage_ratio -= 3;
-
-    if (is_sustain_wis(target_ptr))
-        damage_ratio -= 3;
-
-    if (is_sustain_dex(target_ptr))
-        damage_ratio -= 3;
-
-    if (is_sustain_con(target_ptr))
-        damage_ratio -= 3;
-
-    if (is_sustain_chr(target_ptr))
-        damage_ratio -= 3;
+    if ((target_ptr->fast > 0) || (target_ptr->pspeed >= 130))
+        monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
 
-    monap_ptr->damage = monap_ptr->damage * damage_ratio / 100;
     monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
     if (target_ptr->is_dead || check_multishadow(target_ptr))
         return;
 
-    process_lose_all_attack(target_ptr, monap_ptr);
+    if (set_slow(target_ptr, (target_ptr->slow + 4 + randint0(monap_ptr->rlev / 10)), FALSE))
+        monap_ptr->obvious = TRUE;
 }
 
 void switch_monster_blow_to_player(player_type *target_ptr, monap_type *monap_ptr)
@@ -361,35 +318,17 @@ void switch_monster_blow_to_player(player_type *target_ptr, monap_type *monap_pt
     case RBE_UN_BONUS:
         calc_blow_disenchant(target_ptr, monap_ptr);
         break;
-    case RBE_UN_POWER: {
-        monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-        if (target_ptr->is_dead || check_multishadow(target_ptr))
-            break;
-
-        for (int i = 0; i < 10; i++) {
-            INVENTORY_IDX i_idx = (INVENTORY_IDX)randint0(INVEN_PACK);
-            monap_ptr->o_ptr = &target_ptr->inventory_list[i_idx];
-            if (monap_ptr->o_ptr->k_idx == 0)
-                continue;
-
-            if (process_un_power(target_ptr, monap_ptr))
-                break;
-        }
-
+    case RBE_UN_POWER:
+        calc_blow_un_power(target_ptr, monap_ptr);
         break;
-    }
-    case RBE_EAT_GOLD: {
+    case RBE_EAT_GOLD:
         monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-        if (monster_confused_remaining(monap_ptr->m_ptr))
-            break;
-
-        if (target_ptr->is_dead || check_multishadow(target_ptr))
+        if (monster_confused_remaining(monap_ptr->m_ptr) || target_ptr->is_dead || check_multishadow(target_ptr))
             break;
 
         monap_ptr->obvious = TRUE;
         process_eat_gold(target_ptr, monap_ptr);
         break;
-    }
     case RBE_EAT_ITEM: {
         monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
         if (!check_eat_item(target_ptr, monap_ptr))
@@ -499,90 +438,34 @@ void switch_monster_blow_to_player(player_type *target_ptr, monap_type *monap_pt
 
         break;
     }
-    case RBE_EXP_10: {
-        s32b d = damroll(10, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
-        monap_ptr->obvious = TRUE;
-        monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-        if (target_ptr->is_dead || check_multishadow(target_ptr))
-            break;
-
-        (void)drain_exp(target_ptr, d, d / 10, 95);
+    case RBE_EXP_10:
+        calc_blow_drain_exp(target_ptr, monap_ptr, 10, 95);
         break;
-    }
-    case RBE_EXP_20: {
-        s32b d = damroll(20, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
-        monap_ptr->obvious = TRUE;
-        monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-        if (target_ptr->is_dead || check_multishadow(target_ptr))
-            break;
-
-        (void)drain_exp(target_ptr, d, d / 10, 90);
+    case RBE_EXP_20:
+        calc_blow_drain_exp(target_ptr, monap_ptr, 20, 90);
         break;
-    }
-    case RBE_EXP_40: {
-        s32b d = damroll(40, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
-        monap_ptr->obvious = TRUE;
-        monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-        if (target_ptr->is_dead || check_multishadow(target_ptr))
-            break;
-
-        (void)drain_exp(target_ptr, d, d / 10, 75);
+    case RBE_EXP_40:
+        calc_blow_drain_exp(target_ptr, monap_ptr, 40, 75);
         break;
-    }
-    case RBE_EXP_80: {
-        s32b d = damroll(80, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
-        monap_ptr->obvious = TRUE;
-        monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-        if (target_ptr->is_dead || check_multishadow(target_ptr))
-            break;
-
-        (void)drain_exp(target_ptr, d, d / 10, 50);
+    case RBE_EXP_80:
+        calc_blow_drain_exp(target_ptr, monap_ptr, 80, 50);
         break;
-    }
     case RBE_DISEASE:
-        calc_blow_didease(target_ptr, monap_ptr);
+        calc_blow_disease(target_ptr, monap_ptr);
         break;
-    case RBE_TIME: {
-        if (monap_ptr->explode)
-            break;
-
-        process_monster_attack_time(target_ptr, monap_ptr);
-        monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
+    case RBE_TIME:
+        calc_blow_time(target_ptr, monap_ptr);
         break;
-    }
-    case RBE_DR_LIFE: {
-        s32b d = damroll(60, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
-        monap_ptr->obvious = TRUE;
-        monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-        if (target_ptr->is_dead || check_multishadow(target_ptr))
-            break;
-
-        bool resist_drain = check_drain_hp(target_ptr, d);
-        process_drain_life(target_ptr, monap_ptr, resist_drain);
+    case RBE_DR_LIFE:
+        calc_blow_drain_life(target_ptr, monap_ptr);
         break;
-    }
-    case RBE_DR_MANA: {
-        monap_ptr->obvious = TRUE;
-        process_drain_mana(target_ptr, monap_ptr);
-        update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_MANA);
+    case RBE_DR_MANA:
+        calc_blow_drain_mana(target_ptr, monap_ptr);
         break;
-    }
-    case RBE_INERTIA: {
-        monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
-        if (target_ptr->is_dead)
-            break;
-
-        if (check_multishadow(target_ptr)) {
-            /* Do nothing */
-        } else {
-            if (set_slow(target_ptr, (target_ptr->slow + 4 + randint0(monap_ptr->rlev / 10)), FALSE)) {
-                monap_ptr->obvious = TRUE;
-            }
-        }
-
+    case RBE_INERTIA:
+        calc_blow_inertia(target_ptr, monap_ptr);
         break;
-    }
-    case RBE_STUN: {
+    case RBE_STUN:
         monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
         if (target_ptr->is_dead)
             break;
@@ -590,5 +473,4 @@ void switch_monster_blow_to_player(player_type *target_ptr, monap_type *monap_pt
         process_stun_attack(target_ptr, monap_ptr);
         break;
     }
-    }
 }