OSDN Git Service

[Refactor] race-flags#.h のインクルードを削除
[hengbandforosx/hengbandosx.git] / src / combat / shoot.cpp
index b58f93c..e43032b 100644 (file)
 #include "monster-floor/monster-move.h"
 #include "monster-race/monster-race.h"
 #include "monster-race/race-flags-resistance.h"
-#include "monster-race/race-flags1.h"
-#include "monster-race/race-flags2.h"
-#include "monster-race/race-flags3.h"
-#include "monster-race/race-flags7.h"
 #include "monster-race/race-indice-types.h"
 #include "monster-race/race-resistance-mask.h"
 #include "monster/monster-damage.h"
@@ -782,7 +778,8 @@ void exe_fire(PlayerType *player_ptr, INVENTORY_IDX i_idx, ItemEntity *j_ptr, SP
                     if (snipe_type == SP_NEEDLE) {
                         const auto is_unique = r_ptr->kind_flags.has(MonsterKindType::UNIQUE);
                         const auto fatality = randint1(r_ptr->level / (3 + sniper_concent)) + (8 - sniper_concent);
-                        if ((randint1(fatality) == 1) && !is_unique && none_bits(r_ptr->flags7, RF7_UNIQUE2)) {
+                        const auto no_instantly_death = r_ptr->resistance_flags.has(MonsterResistanceType::NO_INSTANTLY_DEATH);
+                        if ((randint1(fatality) == 1) && !is_unique && !no_instantly_death) {
                             /* Get "the monster" or "it" */
                             const auto m_name = monster_desc(player_ptr, m_ptr, 0);
 
@@ -790,6 +787,9 @@ void exe_fire(PlayerType *player_ptr, INVENTORY_IDX i_idx, ItemEntity *j_ptr, SP
                             base_dam = tdam;
                             msg_format(_("%sの急所に突き刺さった!", "Your shot hit a fatal spot of %s!"), m_name.data());
                         } else {
+                            if (no_instantly_death) {
+                                r_ptr->r_resistance_flags.set(MonsterResistanceType::NO_INSTANTLY_DEATH);
+                            }
                             tdam = 1;
                             base_dam = tdam;
                         }
@@ -1191,14 +1191,15 @@ int calc_expect_crit_shot(PlayerType *player_ptr, WEIGHT weight, int plus_ammo,
  * @brief 攻撃時クリティカルによるダメージ期待値修正計算(重量と毒針処理) / critical happens at i / 10000
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param weight 武器の重量
- * @param plus 武器のダメージ修正
+ * @param plus 武器の命中修正
  * @param dam 基本ダメージ
- * @param meichuu 命中値
+ * @param meichuu 武器以外の命中修正
  * @param dokubari 毒針処理か否か
  * @param impact 強撃かどうか
+ * @param mult 期待値計算時のdam倍率
  * @return ダメージ期待値
  */
-int calc_expect_crit(PlayerType *player_ptr, WEIGHT weight, int plus, int dam, int16_t meichuu, bool dokubari, bool impact)
+int calc_expect_crit(PlayerType *player_ptr, WEIGHT weight, int plus, int dam, int16_t meichuu, bool dokubari, bool impact, int mult)
 {
     if (dokubari) {
         return dam;
@@ -1210,11 +1211,11 @@ int calc_expect_crit(PlayerType *player_ptr, WEIGHT weight, int plus, int dam, i
     }
 
     // 通常ダメージdam、武器重量weightでクリティカルが発生した時のクリティカルダメージ期待値
-    auto calc_weight_expect_dam = [](int dam, WEIGHT weight) {
+    auto calc_weight_expect_dam = [](int dam, WEIGHT weight, int mult) {
         int sum = 0;
         for (int d = 1; d <= 650; ++d) {
             int k = weight + d;
-            sum += std::get<0>(apply_critical_norm_damage(k, dam));
+            sum += std::get<0>(apply_critical_norm_damage(k, dam, mult));
         }
         return sum / 650;
     };
@@ -1223,11 +1224,11 @@ int calc_expect_crit(PlayerType *player_ptr, WEIGHT weight, int plus, int dam, i
 
     if (impact) {
         for (int d = 1; d <= 650; ++d) {
-            num += calc_weight_expect_dam(dam, weight + d);
+            num += calc_weight_expect_dam(dam, weight + d, mult);
         }
         num /= 650;
     } else {
-        num += calc_weight_expect_dam(dam, weight);
+        num += calc_weight_expect_dam(dam, weight, mult);
     }
 
     int pow = PlayerClass(player_ptr).equals(PlayerClassType::NINJA) ? 4444 : 5000;
@@ -1241,3 +1242,94 @@ int calc_expect_crit(PlayerType *player_ptr, WEIGHT weight, int plus, int dam, i
 
     return num;
 }
+
+/*!
+ * @brief 攻撃時スレイによるダメージ期待値修正計算 / critical happens at i / 10000
+ * @param dam 基本ダメージ
+ * @param mult スレイ倍率(掛け算部分)
+ * @param div スレイ倍率(割り算部分)
+ * @param force 理力特別計算フラグ
+ * @return ダメージ期待値
+ */
+static int calc_slaydam(int dam, int mult, int div, bool force)
+{
+    int tmp;
+    if (force) {
+        tmp = dam * 60;
+        tmp *= mult * 3;
+        tmp /= div * 2;
+        tmp += dam * 60 * 2;
+        tmp /= 60;
+        return tmp;
+    }
+
+    tmp = dam * 60;
+    tmp *= mult;
+    tmp /= div;
+    tmp /= 60;
+    return tmp;
+}
+
+/*!
+ * @brief 攻撃時の期待値計算(スレイ→重量クリティカル→切れ味効果)
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param dam 基本ダメージ
+ * @param to_h 武器以外の命中修正
+ * @param o_ptr 武器への参照ポインタ
+ * @return ダメージ期待値
+ */
+uint32_t calc_expect_dice(
+    PlayerType *player_ptr, uint32_t dam, int16_t to_h, ItemEntity *o_ptr)
+{
+    auto flags = o_ptr->get_flags_known();
+    bool impact = player_ptr->impact != 0;
+
+    int vorpal_mult = 1;
+    int vorpal_div = 1;
+    const auto is_vorpal_blade = o_ptr->is_specific_artifact(FixedArtifactId::VORPAL_BLADE);
+    const auto is_chainsword = o_ptr->is_specific_artifact(FixedArtifactId::CHAINSWORD);
+    if (o_ptr->is_fully_known() && (is_vorpal_blade || is_chainsword)) {
+        /* vorpal blade */
+        vorpal_mult = 5;
+        vorpal_div = 3;
+    } else if (flags.has(TR_VORPAL)) {
+        /* vorpal flag only */
+        vorpal_mult = 11;
+        vorpal_div = 9;
+    }
+
+    // 理力
+    bool is_force = !PlayerClass(player_ptr).equals(PlayerClassType::SAMURAI);
+    is_force &= flags.has(TR_FORCE_WEAPON);
+    is_force &= player_ptr->csp > (o_ptr->dd * o_ptr->ds / 5);
+
+    dam = calc_slaydam(dam, 1, 1, is_force);
+    dam = calc_expect_crit(player_ptr, o_ptr->weight, o_ptr->to_h, dam, to_h, false, impact);
+    dam = calc_slaydam(dam, vorpal_mult, vorpal_div, false);
+    return dam;
+}
+
+/*!
+ * @brief 攻撃時の期待値計算(スレイ→重量クリティカル→切れ味効果)
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param dam 基本ダメージ
+ * @param mult スレイ倍率(掛け算部分)
+ * @param div スレイ倍率(割り算部分)
+ * @param force 理力特別計算フラグ
+ * @param weight 重量
+ * @param plus 武器命中修正
+ * @param meichuu 武器以外の命中修正
+ * @param dokubari 毒針処理か否か
+ * @param impact 強撃か否か
+ * @param vorpal_mult 切れ味倍率(掛け算部分)
+ * @param vorpal_div 切れ味倍率(割り算部分)
+ * @return ダメージ期待値
+ */
+uint32_t calc_expect_dice(
+    PlayerType *player_ptr, uint32_t dam, int mult, int div, bool force, WEIGHT weight, int plus, int16_t meichuu, bool dokubari, bool impact, int vorpal_mult, int vorpal_div)
+{
+    dam = calc_slaydam(dam, mult, div, force);
+    dam = calc_expect_crit(player_ptr, weight, plus, dam, meichuu, dokubari, impact);
+    dam = calc_slaydam(dam, vorpal_mult, vorpal_div, false);
+    return dam;
+}