#include "object-hook/hook-armor.h"
#include "object/item-tester-hooker.h"
#include "pet/pet-fall-off.h"
+#include "player-base/player-class.h"
+#include "player-info/samurai-data-type.h"
#include "player/attack-defense-types.h"
#include "player/player-damage.h"
#include "player/player-skill.h"
#include "system/monster-type-definition.h"
#include "system/object-type-definition.h"
#include "system/player-type-definition.h"
+#include "timed-effect/player-cut.h"
#include "timed-effect/player-stun.h"
-#include "timed-effect/timed-effects.h"
#include "util/bit-flags-calculator.h"
#include "view/display-messages.h"
-static bool check_no_blow(player_type *player_ptr, monap_type *monap_ptr)
+static bool check_no_blow(PlayerType *player_ptr, monap_type *monap_ptr)
{
auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
if (any_bits(r_ptr->flags1, RF1_NEVER_BLOW)) {
return false;
}
- if (d_info[player_ptr->dungeon_idx].flags.has(DF::NO_MELEE)) {
+ if (d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_MELEE)) {
return false;
}
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
* @return 攻撃続行ならばTRUE、打ち切りになったらFALSE
*/
-static bool check_monster_continuous_attack(player_type *player_ptr, monap_type *monap_ptr)
+static bool check_monster_continuous_attack(PlayerType *player_ptr, monap_type *monap_ptr)
{
if (!monster_is_valid(monap_ptr->m_ptr) || (monap_ptr->method == RBM_NONE)) {
return false;
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
* @return briefに書いた条件+確率が満たされたらTRUE、それ以外はFALSE
*/
-static bool effect_protecion_from_evil(player_type *player_ptr, monap_type *monap_ptr)
+static bool effect_protecion_from_evil(PlayerType *player_ptr, monap_type *monap_ptr)
{
auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
if ((player_ptr->protevil <= 0) || none_bits(r_ptr->flags3, RF3_EVIL) || (player_ptr->lev < monap_ptr->rlev) || ((randint0(100) + player_ptr->lev) <= 50)) {
}
}
-static void calc_player_cut(player_type *player_ptr, monap_type *monap_ptr)
+static void calc_player_cut(PlayerType *player_ptr, monap_type *monap_ptr)
{
if (monap_ptr->do_cut == 0) {
return;
}
- auto cut_plus = 0;
- auto criticality = calc_monster_critical(monap_ptr->d_dice, monap_ptr->d_side, monap_ptr->damage);
- switch (criticality) {
- case 0:
- cut_plus = 0;
- break;
- case 1:
- cut_plus = randint1(5);
- break;
- case 2:
- cut_plus = randint1(5) + 5;
- break;
- case 3:
- cut_plus = randint1(20) + 20;
- break;
- case 4:
- cut_plus = randint1(50) + 50;
- break;
- case 5:
- cut_plus = randint1(100) + 100;
- break;
- case 6:
- cut_plus = 300;
- break;
- default:
- cut_plus = 500;
- break;
+ auto cut_plus = PlayerCut::get_accumulation(monap_ptr->d_dice * monap_ptr->d_side, monap_ptr->damage);
+ if (cut_plus > 0) {
+ (void)BadStatusSetter(player_ptr).mod_cut(cut_plus);
}
+}
- if (cut_plus > 0) {
- (void)set_cut(player_ptr, player_ptr->cut + cut_plus);
+/*!
+ * @brief 能力値の実値を求める
+ * @param raw PlayerTypeに格納されている生値
+ * @return 実値
+ * @details AD&Dの記法に則り、19以上の値を取らなくしているので、格納方法が面倒
+ */
+static int stat_value(const int raw)
+{
+ if (raw <= 18) {
+ return raw;
}
+
+ return (raw - 18) / 10 + 18;
}
-static void calc_player_stun(player_type *player_ptr, monap_type *monap_ptr)
+/*!
+ * @brief 朦朧を蓄積させる
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param monap_ptr モンスター打撃への参照ポインタ
+ * @details
+ * 痛恨の一撃ならば朦朧蓄積ランクを1上げる.
+ * 2%の確率で朦朧蓄積ランクを1上げる.
+ * 肉体のパラメータが合計80を超える水準に強化されていたら朦朧蓄積ランクを1下げる.
+ */
+static void process_player_stun(PlayerType *player_ptr, monap_type *monap_ptr)
{
if (monap_ptr->do_stun == 0) {
return;
}
- auto stun_plus = 0;
- auto criticality = calc_monster_critical(monap_ptr->d_dice, monap_ptr->d_side, monap_ptr->damage);
- switch (criticality) {
- case 0:
- stun_plus = 0;
- break;
- case 1:
- stun_plus = randint1(5);
- break;
- case 2:
- stun_plus = randint1(5) + 10;
- break;
- case 3:
- stun_plus = randint1(10) + 20;
- break;
- case 4:
- stun_plus = randint1(15) + 30;
- break;
- case 5:
- stun_plus = randint1(20) + 40;
- break;
- case 6:
- stun_plus = 80;
- break;
- default:
- stun_plus = 150;
- break;
+ auto total = monap_ptr->d_dice * monap_ptr->d_side;
+ auto accumulation_rank = PlayerStun::get_accumulation_rank(total, monap_ptr->damage);
+ if (accumulation_rank == 0) {
+ return;
+ }
+
+ if ((total < monap_ptr->damage) && (accumulation_rank <= 6)) {
+ accumulation_rank++;
+ }
+
+ if (one_in_(50)) {
+ accumulation_rank++;
+ }
+
+ auto str = stat_value(player_ptr->stat_cur[A_STR]);
+ auto dex = stat_value(player_ptr->stat_cur[A_DEX]);
+ auto con = stat_value(player_ptr->stat_cur[A_CON]);
+ auto is_powerful_body = str + dex + con > 80;
+ if (is_powerful_body) {
+ accumulation_rank--;
}
+ auto stun_plus = PlayerStun::get_accumulation(accumulation_rank);
if (stun_plus > 0) {
- (void)set_stun(player_ptr, player_ptr->effects()->stun()->current() + stun_plus);
+ (void)BadStatusSetter(player_ptr).mod_stun(stun_plus);
}
}
-static void monster_explode(player_type *player_ptr, monap_type *monap_ptr)
+static void monster_explode(PlayerType *player_ptr, monap_type *monap_ptr)
{
if (!monap_ptr->explode) {
return;
}
sound(SOUND_EXPLODE);
- MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, monap_ptr->m_ptr->hp + 1, &monap_ptr->fear);
+ MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, monap_ptr->m_ptr->hp + 1, &monap_ptr->fear, AttributeType::NONE);
if (mdp.mon_take_hit(nullptr)) {
monap_ptr->blinked = false;
monap_ptr->alive = false;
}
}
-static void describe_attack_evasion(player_type *player_ptr, monap_type *monap_ptr)
+static void describe_attack_evasion(PlayerType *player_ptr, monap_type *monap_ptr)
{
if (!monap_ptr->m_ptr->ml) {
return;
#endif
}
-static void gain_armor_exp(player_type *player_ptr, monap_type *monap_ptr)
+static void gain_armor_exp(PlayerType *player_ptr, monap_type *monap_ptr)
{
const auto o_ptr_mh = &player_ptr->inventory_list[INVEN_MAIN_HAND];
const auto o_ptr_sh = &player_ptr->inventory_list[INVEN_SUB_HAND];
return;
}
- auto cur = player_ptr->skill_exp[SKILL_SHIELD];
- auto max = s_info[player_ptr->pclass].s_max[SKILL_SHIELD];
+ auto cur = player_ptr->skill_exp[PlayerSkillKindType::SHIELD];
+ auto max = s_info[enum2i(player_ptr->pclass)].s_max[PlayerSkillKindType::SHIELD];
if (cur >= max) {
return;
}
auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
auto target_level = r_ptr->level;
- auto increment = 0;
+ short increment = 0;
if ((cur / 100) < target_level) {
auto addition = (cur / 100 + 15) < target_level ? (target_level - (cur / 100 + 15)) : 0;
increment += 1 + addition;
}
- player_ptr->skill_exp[SKILL_SHIELD] = MIN(max, cur + increment);
+ player_ptr->skill_exp[PlayerSkillKindType::SHIELD] = std::min<short>(max, cur + increment);
player_ptr->update |= (PU_BONUS);
}
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
* @details 最大4 回/モンスター/ターン、このルーチンを通る
*/
-static bool process_monster_attack_hit(player_type *player_ptr, monap_type *monap_ptr)
+static bool process_monster_attack_hit(PlayerType *player_ptr, monap_type *monap_ptr)
{
disturb(player_ptr, true, true);
if (effect_protecion_from_evil(player_ptr, monap_ptr)) {
switch_monster_blow_to_player(player_ptr, monap_ptr);
select_cut_stun(monap_ptr);
calc_player_cut(player_ptr, monap_ptr);
- calc_player_stun(player_ptr, monap_ptr);
+ process_player_stun(player_ptr, monap_ptr);
monster_explode(player_ptr, monap_ptr);
process_aura_counterattack(player_ptr, monap_ptr);
return true;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void process_monster_attack_evasion(player_type *player_ptr, monap_type *monap_ptr)
+static void process_monster_attack_evasion(PlayerType *player_ptr, monap_type *monap_ptr)
{
switch (monap_ptr->method) {
case RBM_HIT:
* 非自明な類の打撃については、そのダメージが 0 ならば基本的に知識が増えない.
* 但し、既に一定以上の知識があれば常に知識が増える(何をされたのか察知できる).
*/
-static void increase_blow_type_seen(player_type *player_ptr, monap_type *monap_ptr, const int ap_cnt)
+static void increase_blow_type_seen(PlayerType *player_ptr, monap_type *monap_ptr, const int ap_cnt)
{
if (!is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr) || monap_ptr->do_silly_attack) {
return;
* @brief モンスターからプレイヤーへの打撃処理本体
* @return 打撃に反応してプレイヤーがその場から離脱したかどうか
*/
-static bool process_monster_blows(player_type *player_ptr, monap_type *monap_ptr)
+static bool process_monster_blows(PlayerType *player_ptr, monap_type *monap_ptr)
{
auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
for (auto ap_cnt = 0; ap_cnt < MAX_NUM_BLOWS; ap_cnt++) {
break;
}
- // effect が RBE_NONE (無効値)になることはあり得ないはずだが、万一そう
+ // effect が RaceBlowEffectType::NONE (無効値)になることはあり得ないはずだが、万一そう
// なっていたら単に攻撃を打ち切る。
// r_info.txt の "B:" トークンに effect 以降を書き忘れた場合が該当する。
- if (monap_ptr->effect == RBE_NONE) {
- plog("unexpected: monap_ptr->effect == RBE_NONE");
+ if (monap_ptr->effect == RaceBlowEffectType::NONE) {
+ plog("unexpected: monap_ptr->effect == RaceBlowEffectType::NONE");
break;
}
// フレーバーの打撃は必中扱い。それ以外は通常の命中判定を行う。
monap_ptr->ac = player_ptr->ac + player_ptr->to_a;
bool hit;
- if (monap_ptr->effect == RBE_FLAVOR) {
+ if (monap_ptr->effect == RaceBlowEffectType::FLAVOR) {
hit = true;
} else {
- const int power = mbe_info[monap_ptr->effect].power;
+ const int power = mbe_info[enum2i(monap_ptr->effect)].power;
hit = check_hit_from_monster_to_player(player_ptr, power, monap_ptr->rlev, monster_stunned_remaining(monap_ptr->m_ptr));
}
// 撃退失敗時は落馬処理、変わり身のテレポート処理を行う。
check_fall_off_horse(player_ptr, monap_ptr);
- if (player_ptr->special_defense & NINJA_KAWARIMI) {
- // 変わり身のテレポートが成功したら攻撃を打ち切り、プレイヤーが離脱した旨を返す。
- if (kawarimi(player_ptr, false))
- return true;
+
+ // 変わり身のテレポートが成功したら攻撃を打ち切り、プレイヤーが離脱した旨を返す。
+ if (kawarimi(player_ptr, false)) {
+ return true;
}
} else {
// 命中しなかった。回避時の処理、思い出処理を行う。
return false;
}
-static void postprocess_monster_blows(player_type *player_ptr, monap_type *monap_ptr)
+static void postprocess_monster_blows(PlayerType *player_ptr, monap_type *monap_ptr)
{
SpellHex spell_hex(player_ptr, monap_ptr);
spell_hex.store_vengeful_damage(monap_ptr->get_damage);
msg_format(_("%^sは恐怖で逃げ出した!", "%^s flees in terror!"), monap_ptr->m_name);
}
- if (player_ptr->special_defense & KATA_IAI) {
- set_action(player_ptr, ACTION_NONE);
- }
+ PlayerClass(player_ptr).break_samurai_stance({ SamuraiStanceType::IAI });
}
/*!
* @param m_idx 打撃を行うモンスターのID
* @return 実際に攻撃処理を行った場合TRUEを返す
*/
-bool make_attack_normal(player_type *player_ptr, MONSTER_IDX m_idx)
+bool make_attack_normal(PlayerType *player_ptr, MONSTER_IDX m_idx)
{
monap_type tmp_monap;
monap_type *monap_ptr = initialize_monap_type(player_ptr, &tmp_monap, m_idx);
monap_ptr->rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
monster_desc(player_ptr, monap_ptr->m_name, monap_ptr->m_ptr, 0);
monster_desc(player_ptr, monap_ptr->ddesc, monap_ptr->m_ptr, MD_WRONGDOER_NAME);
- if (any_bits(player_ptr->special_defense, KATA_IAI)) {
+ if (PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::IAI)) {
msg_format(_("相手が襲いかかる前に素早く武器を振るった。", "You took sen, drew and cut in one motion before %s moved."), monap_ptr->m_name);
if (do_cmd_attack(player_ptr, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, HISSATSU_IAI)) {
return true;
}
}
- auto is_kawarimi = any_bits(player_ptr->special_defense, NINJA_KAWARIMI);
auto can_activate_kawarimi = randint0(55) < (player_ptr->lev * 3 / 5 + 20);
- if (is_kawarimi && can_activate_kawarimi && kawarimi(player_ptr, true)) {
+ if (can_activate_kawarimi && kawarimi(player_ptr, true)) {
return true;
}