#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"
}
/* Calculate the new location (see "project()") */
- ny = y;
- nx = x;
- mmove2(&ny, &nx, player_ptr->y, player_ptr->x, ty, tx);
+ const auto pos = mmove2({ y, x }, player_ptr->get_position(), { ty, tx });
+ ny = pos.y;
+ nx = pos.x;
/* Shatter Arrow */
if (snipe_type == SP_KILL_WALL) {
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);
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;
}
}
/* Calculate the new location (see "project()") */
- mmove2(&ny, &nx, player_ptr->y, player_ptr->x, ty, tx);
+ const auto pos_to = mmove2({ ny, nx }, player_ptr->get_position(), { ty, tx });
+ ny = pos_to.y;
+ nx = pos_to.x;
/* Stopped by wilderness boundary */
if (!in_bounds2(floor_ptr, ny, nx)) {
* @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;
}
// 通常ダメージ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;
};
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;
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;
+}