1 #include "combat/combat-options-type.h"
2 #include "combat/attack-criticality.h"
3 #include "inventory/inventory-slot-types.h"
4 #include "monster-race/monster-race.h"
5 #include "monster-race/race-flags1.h"
6 #include "monster-race/race-flags7.h"
7 #include "sv-definition/sv-weapon-types.h"
8 #include "view/display-messages.h"
11 * @brief プレイヤーからモンスターへの打撃クリティカル判定 /
12 * Critical hits (by player) Factor in weapon weight, total plusses, player melee bonus
15 * @param dam 現在算出中のダメージ値
16 * @param meichuu 打撃の基本命中力
17 * @param mode オプションフラグ
18 * @return クリティカル修正が入ったダメージ値
20 HIT_POINT critical_norm(player_type *attacker_ptr, WEIGHT weight, int plus, HIT_POINT dam, s16b meichuu, combat_options mode)
22 /* Extract "blow" power */
23 int i = (weight + (meichuu * 3 + plus * 5) + attacker_ptr->skill_thn);
26 bool is_special_option = randint1((attacker_ptr->pclass == CLASS_NINJA) ? 4444 : 5000) <= i;
27 is_special_option |= mode == HISSATSU_MAJIN;
28 is_special_option |= mode == HISSATSU_3DAN;
29 if (!is_special_option)
32 int k = weight + randint1(650);
33 if ((mode == HISSATSU_MAJIN) || (mode == HISSATSU_3DAN))
37 msg_print(_("手ごたえがあった!", "It was a good hit!"));
44 msg_print(_("かなりの手ごたえがあった!", "It was a great hit!"));
50 msg_print(_("会心の一撃だ!", "It was a superb hit!"));
56 msg_print(_("最高の会心の一撃だ!", "It was a *GREAT* hit!"));
61 msg_print(_("比類なき最高の会心の一撃だ!", "It was a *SUPERB* hit!"));
62 dam = ((7 * dam) / 2) + 25;
67 * @brief モンスター打撃のクリティカルランクを返す /
68 * Critical blow. All hits that do 95% of total possible damage,
69 * @param dice モンスター打撃のダイス数
70 * @param sides モンスター打撃の最大ダイス目
71 * @param dam プレイヤーに与えたダメージ
73 * and which also do at least 20 damage, or, sometimes, N damage.
74 * This is used only to determine "cuts" and "stuns".
76 int calc_monster_critical(DICE_NUMBER dice, DICE_SID sides, HIT_POINT dam)
78 int total = dice * sides;
79 if (dam < total * 19 / 20)
82 if ((dam < 20) && (randint0(100) >= dam))
86 if ((dam >= total) && (dam >= 40))
90 while (randint0(100) < 2)
113 * @param attacker_ptr プレーヤーへの参照ポインタ
114 * @param pa_ptr 直接攻撃構造体への参照ポインタ
117 static void ninja_critical(player_type *attacker_ptr, player_attack_type *pa_ptr)
119 monster_race *r_ptr = &r_info[pa_ptr->m_ptr->r_idx];
120 int maxhp = maxroll(r_ptr->hdice, r_ptr->hside);
121 if (one_in_(pa_ptr->backstab ? 13 : (pa_ptr->stab_fleeing || pa_ptr->surprise_attack) ? 15 : 27)) {
122 pa_ptr->attack_damage *= 5;
123 pa_ptr->drain_result *= 2;
124 msg_format(_("刃が%sに深々と突き刺さった!", "You critically injured %s!"), pa_ptr->m_name);
128 bool is_critical = ((pa_ptr->m_ptr->hp < maxhp / 2) && one_in_((attacker_ptr->num_blow[0] + attacker_ptr->num_blow[1] + 1) * 10))
129 || ((one_in_(666) || ((pa_ptr->backstab || pa_ptr->surprise_attack) && one_in_(11))) && ((r_ptr->flags1 & RF1_UNIQUE) == 0)
130 && ((r_ptr->flags7 & RF7_UNIQUE2) == 0));
134 if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE2) || (pa_ptr->m_ptr->hp >= maxhp / 2)) {
135 pa_ptr->attack_damage = MAX(pa_ptr->attack_damage * 5, pa_ptr->m_ptr->hp / 2);
136 pa_ptr->drain_result *= 2;
137 msg_format(_("%sに致命傷を負わせた!", "You fatally injured %s!"), pa_ptr->m_name);
139 pa_ptr->attack_damage = pa_ptr->m_ptr->hp + 1;
140 msg_format(_("刃が%sの急所を貫いた!", "You hit %s on a fatal spot!"), pa_ptr->m_name);
146 * @param attacker_ptr プレーヤーへの参照ポインタ
147 * @param pa_ptr 直接攻撃構造体への参照ポインタ
150 void critical_attack(player_type *attacker_ptr, player_attack_type *pa_ptr)
152 object_type *o_ptr = &attacker_ptr->inventory_list[INVEN_RARM + pa_ptr->hand];
153 monster_race *r_ptr = &r_info[pa_ptr->m_ptr->r_idx];
154 if (((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) || (pa_ptr->mode == HISSATSU_KYUSHO)) {
155 if ((randint1(randint1(r_ptr->level / 7) + 5) == 1) && !(r_ptr->flags1 & RF1_UNIQUE) && !(r_ptr->flags7 & RF7_UNIQUE2)) {
156 pa_ptr->attack_damage = pa_ptr->m_ptr->hp + 1;
157 msg_format(_("%sの急所を突き刺した!", "You hit %s on a fatal spot!"), pa_ptr->m_name);
159 pa_ptr->attack_damage = 1;
164 bool is_ninja_hit = (attacker_ptr->pclass == CLASS_NINJA) && has_melee_weapon(attacker_ptr, INVEN_RARM + pa_ptr->hand)
165 && !attacker_ptr->icky_wield[pa_ptr->hand] && ((attacker_ptr->cur_lite <= 0) || one_in_(7));
167 ninja_critical(attacker_ptr, pa_ptr);