From 314ae2799a029f34aab98a66a520c1eed28e5d9c Mon Sep 17 00:00:00 2001 From: dis Date: Tue, 23 Jan 2024 14:33:17 +0900 Subject: [PATCH] =?utf8?q?[Fix]=20C=E7=94=BB=E9=9D=A2=E7=B4=A0=E6=89=8B?= =?utf8?q?=E3=83=80=E3=83=A1=E3=83=BC=E3=82=B8=E3=82=92=E3=82=AF=E3=83=AA?= =?utf8?q?=E3=83=86=E3=82=A3=E3=82=AB=E3=83=AB=E8=80=83=E6=85=AE=E3=81=AB?= =?utf8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Issue #1989の内容。 徒手格闘クラスのC画面攻撃力表記にクリティカルが考慮されていなかったものを修正。 ただし素手攻撃の命中率算出は複雑なので概算でプレイヤーレベルの0.7倍を使用する。 クリティカル考慮にダメージ期待値の100倍を使用することに対応してcalc_expect_crit()及びapply_critical_norm_damage()を拡張した。 --- src/combat/attack-criticality.cpp | 13 +++++++------ src/combat/attack-criticality.h | 2 +- src/combat/shoot.cpp | 11 ++++++----- src/combat/shoot.h | 2 +- src/mind/monk-attack.cpp | 2 +- src/mind/monk-attack.h | 2 ++ src/view/status-first-page.cpp | 6 ++++++ 7 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/combat/attack-criticality.cpp b/src/combat/attack-criticality.cpp index 083380aad..385823635 100644 --- a/src/combat/attack-criticality.cpp +++ b/src/combat/attack-criticality.cpp @@ -21,23 +21,24 @@ * * @param k クリティカルの強度を決定する値 * @param base_dam クリティカル適用前のダメージ + * @param mult 期待値計算時のdam倍率 * @return クリティカルを適用したダメージと、クリティカル発生時に表示するメッセージと、クリティカル効果音のタプルを返す */ -std::tuple apply_critical_norm_damage(int k, int base_dam) +std::tuple 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 }; } /*! diff --git a/src/combat/attack-criticality.h b/src/combat/attack-criticality.h index fce5a86c0..bf30d73a4 100644 --- a/src/combat/attack-criticality.h +++ b/src/combat/attack-criticality.h @@ -8,6 +8,6 @@ struct player_attack_type; class PlayerType; -std::tuple apply_critical_norm_damage(int k, int base_dam); +std::tuple 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); diff --git a/src/combat/shoot.cpp b/src/combat/shoot.cpp index 5b39216da..272222d13 100644 --- a/src/combat/shoot.cpp +++ b/src/combat/shoot.cpp @@ -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; diff --git a/src/combat/shoot.h b/src/combat/shoot.h index f9056433f..4f21d0cc2 100644 --- a/src/combat/shoot.h +++ b/src/combat/shoot.h @@ -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( diff --git a/src/mind/monk-attack.cpp b/src/mind/monk-attack.cpp index 23bc1ed88..264f9b50e 100644 --- a/src/mind/monk-attack.cpp +++ b/src/mind/monk-attack.cpp @@ -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); diff --git a/src/mind/monk-attack.h b/src/mind/monk-attack.h index 4aa11a3ad..32e5ed767 100644 --- a/src/mind/monk-attack.h +++ b/src/mind/monk-attack.h @@ -1,6 +1,8 @@ #pragma once +#include 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); diff --git a/src/view/status-first-page.cpp b/src/view/status-first-page.cpp index b12ee1a1b..d112b1f04 100644 --- a/src/view/status-first-page.cpp +++ b/src/view/status-first-page.cpp @@ -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)) { -- 2.11.0