OSDN Git Service

[Fix] C画面素手ダメージをクリティカル考慮に変更
authordis <dis.rogue@gmail.com>
Tue, 23 Jan 2024 05:33:17 +0000 (14:33 +0900)
committerdis <dis.rogue@gmail.com>
Tue, 23 Jan 2024 08:43:57 +0000 (17:43 +0900)
Issue #1989の内容。
徒手格闘クラスのC画面攻撃力表記にクリティカルが考慮されていなかったものを修正。
ただし素手攻撃の命中率算出は複雑なので概算でプレイヤーレベルの0.7倍を使用する。
クリティカル考慮にダメージ期待値の100倍を使用することに対応してcalc_expect_crit()及びapply_critical_norm_damage()を拡張した。

src/combat/attack-criticality.cpp
src/combat/attack-criticality.h
src/combat/shoot.cpp
src/combat/shoot.h
src/mind/monk-attack.cpp
src/mind/monk-attack.h
src/view/status-first-page.cpp

index 083380a..3858236 100644 (file)
  *
  * @param k クリティカルの強度を決定する値
  * @param base_dam クリティカル適用前のダメージ
+ * @param mult 期待値計算時のdam倍率
  * @return クリティカルを適用したダメージと、クリティカル発生時に表示するメッセージと、クリティカル効果音のタプルを返す
  */
-std::tuple<int, concptr, sound_type> apply_critical_norm_damage(int k, int base_dam)
+std::tuple<int, concptr, sound_type> apply_critical_norm_damage(int k, int base_dam, int mult)
 {
     if (k < 400) {
-        return { 2 * base_dam + 5, _("手ごたえがあった!", "It was a good hit!"), SOUND_GOOD_HIT };
+        return { 2 * base_dam + 5 * mult, _("手ごたえがあった!", "It was a good hit!"), SOUND_GOOD_HIT };
     }
     if (k < 700) {
-        return { 2 * base_dam + 10, _("かなりの手ごたえがあった!", "It was a great hit!"), SOUND_GREAT_HIT };
+        return { 2 * base_dam + 10 * mult, _("かなりの手ごたえがあった!", "It was a great hit!"), SOUND_GREAT_HIT };
     }
     if (k < 900) {
-        return { 3 * base_dam + 15, _("会心の一撃だ!", "It was a superb hit!"), SOUND_SUPERB_HIT };
+        return { 3 * base_dam + 15 * mult, _("会心の一撃だ!", "It was a superb hit!"), SOUND_SUPERB_HIT };
     }
     if (k < 1300) {
-        return { 3 * base_dam + 20, _("最高の会心の一撃だ!", "It was a *GREAT* hit!"), SOUND_STAR_GREAT_HIT };
+        return { 3 * base_dam + 20 * mult, _("最高の会心の一撃だ!", "It was a *GREAT* hit!"), SOUND_STAR_GREAT_HIT };
     }
-    return { ((7 * base_dam) / 2) + 25, _("比類なき最高の会心の一撃だ!", "It was a *SUPERB* hit!"), SOUND_STAR_SUPERB_HIT };
+    return { ((7 * base_dam) / 2) + 25 * mult, _("比類なき最高の会心の一撃だ!", "It was a *SUPERB* hit!"), SOUND_STAR_SUPERB_HIT };
 }
 
 /*!
index fce5a86..bf30d73 100644 (file)
@@ -8,6 +8,6 @@
 
 struct player_attack_type;
 class PlayerType;
-std::tuple<int, concptr, sound_type> apply_critical_norm_damage(int k, int base_dam);
+std::tuple<int, concptr, sound_type> apply_critical_norm_damage(int k, int base_dam, int mult = 1);
 int critical_norm(PlayerType *player_ptr, WEIGHT weight, int plus, int dam, int16_t meichuu, combat_options mode, bool impact = false);
 void critical_attack(PlayerType *player_ptr, player_attack_type *pa_ptr);
index 5b39216..272222d 100644 (file)
@@ -1200,9 +1200,10 @@ int calc_expect_crit_shot(PlayerType *player_ptr, WEIGHT weight, int plus_ammo,
  * @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;
@@ -1214,11 +1215,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;
     };
@@ -1227,11 +1228,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;
index f905643..4f21d0c 100644 (file)
@@ -11,7 +11,7 @@ void exe_fire(PlayerType *player_ptr, INVENTORY_IDX i_idx, ItemEntity *j_ptr, SP
 int critical_shot(PlayerType *player_ptr, WEIGHT weight, int plus_ammo, int plus_bow, int dam);
 int calc_crit_ratio_shot(PlayerType *player_ptr, int plus_ammo, int plus_bow);
 int calc_expect_crit_shot(PlayerType *player_ptr, WEIGHT weight, int plus_ammo, int plus_bow, int dam);
-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 = 1);
 uint32_t calc_expect_dice(
     PlayerType *player_ptr, uint32_t dam, int16_t to_h, ItemEntity *o_ptr);
 uint32_t calc_expect_dice(
index 23bc1ed..264f9b5 100644 (file)
@@ -174,7 +174,7 @@ static int process_monk_additional_effect(player_attack_type *pa_ptr, int *stun_
  * @param player_ptr プレイヤーへの参照ポインタ
  * @return 重さ
  */
-static WEIGHT calc_monk_attack_weight(PlayerType *player_ptr)
+WEIGHT calc_monk_attack_weight(PlayerType *player_ptr)
 {
     WEIGHT weight = 8;
     PlayerClass pc(player_ptr);
index 4aa11a3..32e5ed7 100644 (file)
@@ -1,6 +1,8 @@
 #pragma once
+#include <system/h-type.h>
 
 struct player_attack_type;
 class PlayerType;
 void process_monk_attack(PlayerType *player_ptr, player_attack_type *pa_ptr);
 bool double_attack(PlayerType *player_ptr);
+WEIGHT calc_monk_attack_weight(PlayerType *player_ptr);
index b12ee1a..d112b1f 100644 (file)
@@ -11,6 +11,7 @@
 #include "combat/shoot.h"
 #include "game-option/text-display-options.h"
 #include "inventory/inventory-slot-types.h"
+#include "mind/monk-attack.h"
 #include "mutation/mutation-flag-types.h"
 #include "object-enchant/special-object-flags.h"
 #include "object-enchant/tr-types.h"
@@ -97,6 +98,11 @@ static bool calc_weapon_damage_limit(PlayerType *player_ptr, int hand, int *dama
     } else {
         *basedam = monk_ave_damage[level][0];
     }
+    bool impact = player_ptr->impact != 0;
+    WEIGHT weight = player_ptr->lev * calc_monk_attack_weight(player_ptr);
+    int to_h = player_ptr->lev * 7 / 10; // 命中計算が煩雑なのでおよその値を使用する
+
+    *basedam = calc_expect_crit(player_ptr, weight, to_h, *basedam, player_ptr->to_h[0], false, impact, 100);
 
     damage[hand] += *basedam;
     if (o_ptr->bi_key == BaseitemKey(ItemKindType::SWORD, SV_POISON_NEEDLE)) {