OSDN Git Service

[Refactor] enum spells-typeをenum class AttributeTypeに置換
[hengbandforosx/hengbandosx.git] / src / player-attack / player-attack.cpp
1 /*!
2  * @brief プレイヤーからモンスターへの打撃処理
3  * @date 2020/05/22
4  * @author Hourier
5  */
6
7 #include "player-attack/player-attack.h"
8 #include "artifact/fixed-art-types.h"
9 #include "avatar/avatar.h"
10 #include "cmd-action/cmd-attack.h"
11 #include "combat/attack-accuracy.h"
12 #include "combat/attack-criticality.h"
13 #include "combat/martial-arts-table.h"
14 #include "combat/slaying.h"
15 #include "core/player-update-types.h"
16 #include "floor/cave.h"
17 #include "floor/geometry.h"
18 #include "game-option/cheat-types.h"
19 #include "grid/feature-flag-types.h"
20 #include "inventory/inventory-slot-types.h"
21 #include "main/sound-definitions-table.h"
22 #include "main/sound-of-music.h"
23 #include "mind/mind-ninja.h"
24 #include "mind/mind-samurai.h"
25 #include "mind/monk-attack.h"
26 #include "monster-race/monster-race-hook.h"
27 #include "monster-race/monster-race.h"
28 #include "monster-race/race-flags3.h"
29 #include "monster/monster-damage.h"
30 #include "monster/monster-describer.h"
31 #include "monster/monster-status-setter.h"
32 #include "monster/monster-status.h"
33 #include "object-enchant/tr-types.h"
34 #include "object-enchant/vorpal-weapon.h"
35 #include "object-hook/hook-weapon.h"
36 #include "object/object-flags.h"
37 #include "object/tval-types.h"
38 #include "player-attack/attack-chaos-effect.h"
39 #include "player-attack/blood-sucking-processor.h"
40 #include "player-attack/player-attack-util.h"
41 #include "player-info/equipment-info.h"
42 #include "player-status/player-energy.h"
43 #include "player-status/player-hand-types.h"
44 #include "player/player-damage.h"
45 #include "player/player-skill.h"
46 #include "player/player-status-flags.h"
47 #include "realm/realm-hex-numbers.h"
48 #include "spell-kind/earthquake.h"
49 #include "spell-realm/spells-hex.h"
50 #include "sv-definition/sv-weapon-types.h"
51 #include "system/floor-type-definition.h"
52 #include "system/grid-type-definition.h"
53 #include "system/monster-race-definition.h"
54 #include "system/monster-type-definition.h"
55 #include "system/object-type-definition.h"
56 #include "system/player-type-definition.h"
57 #include "timed-effect/player-cut.h"
58 #include "timed-effect/timed-effects.h"
59 #include "util/bit-flags-calculator.h"
60 #include "view/display-messages.h"
61 #include "wizard/wizard-messages.h"
62 #include "world/world.h"
63
64 /*!
65  * @brief プレイヤーの攻撃情報を初期化する(コンストラクタ以外の分)
66  */
67 static player_attack_type *initialize_player_attack_type(
68     player_attack_type *pa_ptr, player_type *player_ptr, POSITION y, POSITION x, int16_t hand, combat_options mode, bool *fear, bool *mdeath)
69 {
70     auto floor_ptr = player_ptr->current_floor_ptr;
71     auto g_ptr = &floor_ptr->grid_array[y][x];
72     auto m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
73
74     pa_ptr->hand = hand;
75     pa_ptr->mode = mode;
76     pa_ptr->m_idx = g_ptr->m_idx;
77     pa_ptr->m_ptr = m_ptr;
78     pa_ptr->r_idx = m_ptr->r_idx;
79     pa_ptr->r_ptr = &r_info[m_ptr->r_idx];
80     pa_ptr->ma_ptr = &ma_blows[0];
81     pa_ptr->g_ptr = g_ptr;
82     pa_ptr->fear = fear;
83     pa_ptr->mdeath = mdeath;
84     pa_ptr->drain_left = MAX_VAMPIRIC_DRAIN;
85     return pa_ptr;
86 }
87
88 /*!
89  * @brief 一部職業で攻撃に倍率がかかったりすることの処理
90  * @param player_ptr プレイヤーへの参照ポインタ
91  * @param pa_ptr 直接攻撃構造体への参照ポインタ
92  */
93 static void attack_classify(player_type *player_ptr, player_attack_type *pa_ptr)
94 {
95     switch (player_ptr->pclass) {
96     case PlayerClassType::ROGUE:
97     case PlayerClassType::NINJA:
98         process_surprise_attack(player_ptr, pa_ptr);
99         return;
100     case PlayerClassType::MONK:
101     case PlayerClassType::FORCETRAINER:
102     case PlayerClassType::BERSERKER:
103         if ((empty_hands(player_ptr, true) & EMPTY_HAND_MAIN) && !player_ptr->riding)
104             pa_ptr->monk_attack = true;
105         return;
106     default:
107         return;
108     }
109 }
110
111 /*!
112  * @brief マーシャルアーツの技能値を増加させる
113  * @param player_ptr プレイヤーへの参照ポインタ
114  * @param pa_ptr 直接攻撃構造体への参照ポインタ
115  */
116 static void get_bare_knuckle_exp(player_type *player_ptr, player_attack_type *pa_ptr)
117 {
118     monster_race *r_ptr = &r_info[pa_ptr->m_ptr->r_idx];
119     if ((r_ptr->level + 10) <= player_ptr->lev)
120         return;
121
122     PlayerSkill(player_ptr).gain_martial_arts_skill_exp();
123 }
124
125 /*!
126  * @brief 装備している武器の技能値を増加させる
127  * @param player_ptr プレイヤーへの参照ポインタ
128  * @param pa_ptr 直接攻撃構造体への参照ポインタ
129  */
130 static void get_weapon_exp(player_type *player_ptr, player_attack_type *pa_ptr)
131 {
132     auto *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + pa_ptr->hand];
133
134     PlayerSkill(player_ptr).gain_melee_weapon_exp(o_ptr);
135 }
136
137 /*!
138  * @brief 直接攻撃に伴う技能値の上昇処理
139  * @param player_ptr プレイヤーへの参照ポインタ
140  * @param pa_ptr 直接攻撃構造体への参照ポインタ
141  */
142 static void get_attack_exp(player_type *player_ptr, player_attack_type *pa_ptr)
143 {
144     monster_race *r_ptr = &r_info[pa_ptr->m_ptr->r_idx];
145     object_type *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + pa_ptr->hand];
146     if (o_ptr->k_idx == 0) {
147         get_bare_knuckle_exp(player_ptr, pa_ptr);
148         return;
149     }
150
151     if (!o_ptr->is_melee_weapon() || ((r_ptr->level + 10) <= player_ptr->lev))
152         return;
153
154     get_weapon_exp(player_ptr, pa_ptr);
155 }
156
157 /*!
158  * @brief 攻撃回数を決定する
159  * @param player_ptr プレイヤーへの参照ポインタ
160  * @param pa_ptr 直接攻撃構造体への参照ポインタ
161  * @details 毒針は確定で1回
162  */
163 static void calc_num_blow(player_type *player_ptr, player_attack_type *pa_ptr)
164 {
165     if ((pa_ptr->mode == HISSATSU_KYUSHO) || (pa_ptr->mode == HISSATSU_MINEUCHI) || (pa_ptr->mode == HISSATSU_3DAN) || (pa_ptr->mode == HISSATSU_IAI))
166         pa_ptr->num_blow = 1;
167     else if (pa_ptr->mode == HISSATSU_COLD)
168         pa_ptr->num_blow = player_ptr->num_blow[pa_ptr->hand] + 2;
169     else
170         pa_ptr->num_blow = player_ptr->num_blow[pa_ptr->hand];
171
172     object_type *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + pa_ptr->hand];
173     if ((o_ptr->tval == ItemKindType::SWORD) && (o_ptr->sval == SV_POISON_NEEDLE))
174         pa_ptr->num_blow = 1;
175 }
176
177 /*!
178  * @brief 混沌属性の武器におけるカオス効果を決定する
179  * @param player_ptr プレイヤーへの参照ポインタ
180  * @param pa_ptr 直接攻撃構造体への参照ポインタ
181  * @return カオス効果
182  * @details
183  * 吸血20%、地震0.12%、混乱26.892%、テレポート・アウェイ1.494%、変身1.494% /
184  * Vampiric 20%, Quake 0.12%, Confusion 26.892%, Teleport away 1.494% and Polymorph 1.494%
185  */
186 static chaotic_effect select_chaotic_effect(player_type *player_ptr, player_attack_type *pa_ptr)
187 {
188     if (pa_ptr->flags.has_not(TR_CHAOTIC) || one_in_(2))
189         return CE_NONE;
190
191     if (one_in_(10))
192         chg_virtue(player_ptr, V_CHANCE, 1);
193
194     if (randint1(5) < 3)
195         return CE_VAMPIRIC;
196
197     if (one_in_(250))
198         return CE_QUAKE;
199
200     if (!one_in_(10))
201         return CE_CONFUSION;
202
203     return one_in_(2) ? CE_TELE_AWAY : CE_POLYMORPH;
204 }
205
206 /*!
207  * @brief 魔術属性による追加ダイス数を返す
208  * @param player_ptr プレイヤー情報への参照ポインタ
209  * @param pa_ptr プレイヤー攻撃情報への参照ポインタ
210  * @return 魔術属性効果
211  */
212 static MagicalBrandEffect select_magical_brand_effect(player_type *player_ptr, player_attack_type *pa_ptr)
213 {
214     if (pa_ptr->flags.has_not(TR_BRAND_MAGIC))
215         return MagicalBrandEffect::NONE;
216
217     if (one_in_(10))
218         chg_virtue(player_ptr, V_CHANCE, 1);
219
220     if (one_in_(5))
221         return MagicalBrandEffect::STUN;
222
223     if (one_in_(5))
224         return MagicalBrandEffect::SCARE;
225
226     if (one_in_(10))
227         return MagicalBrandEffect::DISPELL;
228
229     if (one_in_(16))
230         return MagicalBrandEffect::PROBE;
231
232     return MagicalBrandEffect::EXTRA;
233 }
234
235 /*!
236  * @brief 魔法属性による追加ダイス数を返す
237  * @param pa_ptr プレイヤー攻撃情報への参照ポインタ
238  * @return ダイス数
239  */
240 static DICE_NUMBER magical_brand_extra_dice(player_attack_type *pa_ptr)
241 {
242     switch (pa_ptr->magical_effect) {
243     case MagicalBrandEffect::NONE:
244         return 0;
245     case MagicalBrandEffect::EXTRA:
246         return 1;
247     default:
248         return 2;
249     }
250 }
251
252 /*!
253  * @brief 装備品が地震を起こすか判定
254  * @param player_ptr プレイヤー情報への参照ポインタ
255  * @param pa_ptr 直接攻撃構造体への参照ポインタ
256  * @return 地震を起こすならtrue、起こさないならfalse
257  * @details
258  * 打撃に使用する武器または武器以外の装備品が地震を起こすなら、
259  * ダメージ量が50より多いか1/7で地震を起こす
260  */
261 static bool does_equip_cause_earthquake(player_type *player_ptr, player_attack_type *pa_ptr)
262 {
263     if (!player_ptr->earthquake)
264         return false;
265
266     auto do_quake = false;
267
268     auto hand = (pa_ptr->hand == 0) ? FLAG_CAUSE_INVEN_MAIN_HAND : FLAG_CAUSE_INVEN_SUB_HAND;
269     if (any_bits(player_ptr->earthquake, hand))
270         do_quake = true;
271     else {
272         auto flags = player_ptr->earthquake;
273         reset_bits(flags, FLAG_CAUSE_INVEN_MAIN_HAND | FLAG_CAUSE_INVEN_SUB_HAND);
274         do_quake = flags != 0;
275     }
276
277     if (do_quake)
278         return pa_ptr->attack_damage > 50 || one_in_(7);
279
280     return false;
281 }
282
283 /*!
284  * @brief 手にしている装備品がフラグを持つか判定
285  * @param attacker_flags 装備状況で集計されたフラグ
286  * @param pa_ptr 直接攻撃構造体への参照ポインタ
287  * @return 持つならtrue、持たないならfalse
288  */
289 static bool does_weapon_has_flag(BIT_FLAGS &attacker_flags, player_attack_type *pa_ptr)
290 {
291     if (!attacker_flags)
292         return false;
293
294     auto hand = (pa_ptr->hand == 0) ? FLAG_CAUSE_INVEN_MAIN_HAND : FLAG_CAUSE_INVEN_SUB_HAND;
295     if (any_bits(attacker_flags, hand))
296         return true;
297
298     auto flags = attacker_flags;
299     reset_bits(flags, FLAG_CAUSE_INVEN_MAIN_HAND | FLAG_CAUSE_INVEN_SUB_HAND);
300     return flags != 0;
301 }
302
303 /*!
304  * @brief 武器による直接攻撃メインルーチン
305  * @param player_ptr プレイヤーへの参照ポインタ
306  * @param pa_ptr 直接攻撃構造体への参照ポインタ
307  * @param vorpal_cut メッタ斬りにできるかどうか
308  * @param vorpal_chance ヴォーパル倍率上昇の機会値
309  * @return 攻撃の結果、地震を起こすことになったらTRUE、それ以外はFALSE
310  */
311 static void process_weapon_attack(player_type *player_ptr, player_attack_type *pa_ptr, bool *do_quake, const bool vorpal_cut, const int vorpal_chance)
312 {
313     object_type *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + pa_ptr->hand];
314     auto dd = o_ptr->dd + player_ptr->to_dd[pa_ptr->hand] + magical_brand_extra_dice(pa_ptr);
315     pa_ptr->attack_damage = damroll(dd, o_ptr->ds + player_ptr->to_ds[pa_ptr->hand]);
316     pa_ptr->attack_damage = calc_attack_damage_with_slay(player_ptr, o_ptr, pa_ptr->attack_damage, pa_ptr->m_ptr, pa_ptr->mode, false);
317     calc_surprise_attack_damage(player_ptr, pa_ptr);
318
319     if (does_equip_cause_earthquake(player_ptr, pa_ptr) || (pa_ptr->chaos_effect == CE_QUAKE) || (pa_ptr->mode == HISSATSU_QUAKE))
320         *do_quake = true;
321
322     auto do_impact = does_weapon_has_flag(player_ptr->impact, pa_ptr);
323     if ((!(o_ptr->tval == ItemKindType::SWORD) || !(o_ptr->sval == SV_POISON_NEEDLE)) && !(pa_ptr->mode == HISSATSU_KYUSHO))
324         pa_ptr->attack_damage
325             = critical_norm(player_ptr, o_ptr->weight, o_ptr->to_h, pa_ptr->attack_damage, player_ptr->to_h[pa_ptr->hand], pa_ptr->mode, do_impact);
326
327     pa_ptr->drain_result = pa_ptr->attack_damage;
328     process_vorpal_attack(player_ptr, pa_ptr, vorpal_cut, vorpal_chance);
329     pa_ptr->attack_damage += o_ptr->to_d;
330     pa_ptr->drain_result += o_ptr->to_d;
331 }
332
333 /*!
334  * @brief 武器または素手による攻撃ダメージを計算する
335  * @param player_ptr プレイヤーへの参照ポインタ
336  * @param pa_ptr 直接攻撃構造体への参照ポインタ
337  * @param do_quake 攻撃の結果、地震を起こすことになったらTRUE、それ以外はFALSE
338  * @param vorpal_cut メッタ斬りにできるかどうか
339  * @param vorpal_change ヴォーパル倍率上昇の機会値
340  * @details 取り敢えず素手と仮定し1とする.
341  */
342 static void calc_attack_damage(player_type *player_ptr, player_attack_type *pa_ptr, bool *do_quake, const bool vorpal_cut, const int vorpal_chance)
343 {
344     object_type *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + pa_ptr->hand];
345     pa_ptr->attack_damage = 1;
346     if (pa_ptr->monk_attack) {
347         process_monk_attack(player_ptr, pa_ptr);
348         return;
349     }
350
351     if (o_ptr->k_idx) {
352         process_weapon_attack(player_ptr, pa_ptr, do_quake, vorpal_cut, vorpal_chance);
353     }
354 }
355
356 /*!
357  * @brief 武器のダメージボーナスや剣術家の技によってダメージにボーナスを与える
358  * @param player_ptr プレイヤーへの参照ポインタ
359  * @param pa_ptr 直接攻撃構造体への参照ポインタ
360  */
361 static void apply_damage_bonus(player_type *player_ptr, player_attack_type *pa_ptr)
362 {
363     pa_ptr->attack_damage += player_ptr->to_d[pa_ptr->hand];
364     pa_ptr->drain_result += player_ptr->to_d[pa_ptr->hand];
365
366     if ((pa_ptr->mode == HISSATSU_SUTEMI) || (pa_ptr->mode == HISSATSU_3DAN))
367         pa_ptr->attack_damage *= 2;
368
369     if ((pa_ptr->mode == HISSATSU_SEKIRYUKA) && !monster_living(pa_ptr->m_ptr->r_idx))
370         pa_ptr->attack_damage = 0;
371
372     auto is_cut = player_ptr->effects()->cut()->is_cut();
373     if ((pa_ptr->mode == HISSATSU_SEKIRYUKA) && !is_cut)
374         pa_ptr->attack_damage /= 2;
375 }
376
377 /*!
378  * @brief 特殊な条件でダメージが減ったり0になったりする処理
379  * @param player_ptr プレイヤーへの参照ポインタ
380  * @param pa_ptr 直接攻撃構造体への参照ポインタ
381  * @param is_zantetsu_nullified 斬鉄剣で切れないならばTRUE
382  * @param is_ej_nullified 蜘蛛相手ならばTRUE
383  * @details ダメージが0未満なら0に補正する
384  * @todo かなりのレアケースだが、右手に混沌属性の武器を持ち、左手にエクスカリバー・ジュニアを持ち、
385  * 右手の最終打撃で蜘蛛に変身したとしても、左手の攻撃でダメージが減らない気がする
386  * モンスターへの参照ポインタは変身時に変わるのにis_ej_nullifiedはその前に代入されて参照されるだけであるため
387  */
388 static void apply_damage_negative_effect(player_attack_type *pa_ptr, bool is_zantetsu_nullified, bool is_ej_nullified)
389 {
390     if (pa_ptr->attack_damage < 0)
391         pa_ptr->attack_damage = 0;
392
393     monster_race *r_ptr = &r_info[pa_ptr->m_ptr->r_idx];
394     if ((pa_ptr->mode == HISSATSU_ZANMA) && !(!monster_living(pa_ptr->m_ptr->r_idx) && (r_ptr->flags3 & RF3_EVIL))) {
395         pa_ptr->attack_damage = 0;
396     }
397
398     if (is_zantetsu_nullified) {
399         msg_print(_("こんな軟らかいものは切れん!", "You cannot cut such an elastic thing!"));
400         pa_ptr->attack_damage = 0;
401     }
402
403     if (is_ej_nullified) {
404         msg_print(_("蜘蛛は苦手だ!", "Spiders are difficult for you to deal with!"));
405         pa_ptr->attack_damage /= 2;
406     }
407 }
408
409 /*!
410  * @brief モンスターのHPを減らした後、恐怖させるか死なす (フロアから消滅させる)
411  * @param player_ptr プレイヤーへの参照ポインタ
412  * @param pa_ptr 直接攻撃構造体への参照ポインタ
413  * @return 死んだらTRUE、生きていたらFALSE
414  */
415 static bool check_fear_death(player_type *player_ptr, player_attack_type *pa_ptr, const int num, const bool is_lowlevel)
416 {
417     MonsterDamageProcessor mdp(player_ptr, pa_ptr->m_idx, pa_ptr->attack_damage, pa_ptr->fear, pa_ptr->attribute_flags);
418     if (!mdp.mon_take_hit(nullptr))
419         return false;
420
421     *(pa_ptr->mdeath) = true;
422     if ((player_ptr->pclass == PlayerClassType::BERSERKER) && player_ptr->energy_use) {
423         PlayerEnergy energy(player_ptr);
424         if (can_attack_with_main_hand(player_ptr) && can_attack_with_sub_hand(player_ptr)) {
425             ENERGY energy_use;
426             if (pa_ptr->hand) {
427                 energy_use = player_ptr->energy_use * 3 / 5 + player_ptr->energy_use * num * 2 / (player_ptr->num_blow[pa_ptr->hand] * 5);
428             } else {
429                 energy_use = player_ptr->energy_use * num * 3 / (player_ptr->num_blow[pa_ptr->hand] * 5);
430             }
431
432             energy.set_player_turn_energy(energy_use);
433         } else {
434             auto energy_use = (ENERGY)(player_ptr->energy_use * num / player_ptr->num_blow[pa_ptr->hand]);
435             energy.set_player_turn_energy(energy_use);
436         }
437     }
438
439     object_type *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + pa_ptr->hand];
440     if ((o_ptr->name1 == ART_ZANTETSU) && is_lowlevel)
441         msg_print(_("またつまらぬものを斬ってしまった...", "Sigh... Another trifling thing I've cut...."));
442
443     return true;
444 }
445
446 /*!
447  * @brief 直接攻撃が当たった時の処理
448  * @param player_ptr プレイヤーへの参照ポインタ
449  * @param pa_ptr 直接攻撃構造体への参照ポインタ
450  * @param do_quake 攻撃後に地震を起こすかどうか
451  * @param is_zantetsu_nullified 斬鉄剣で切れないならばTRUE
452  * @param is_ej_nullified 蜘蛛相手ならばTRUE
453  */
454 static void apply_actual_attack(
455     player_type *player_ptr, player_attack_type *pa_ptr, bool *do_quake, const bool is_zantetsu_nullified, const bool is_ej_nullified)
456 {
457     object_type *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + pa_ptr->hand];
458     int vorpal_chance = ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)) ? 2 : 4;
459
460     sound(SOUND_HIT);
461     print_surprise_attack(pa_ptr);
462
463     pa_ptr->flags = object_flags(o_ptr);
464     pa_ptr->chaos_effect = select_chaotic_effect(player_ptr, pa_ptr);
465     pa_ptr->magical_effect = select_magical_brand_effect(player_ptr, pa_ptr);
466     decide_blood_sucking(player_ptr, pa_ptr);
467
468     bool vorpal_cut = (pa_ptr->flags.has(TR_VORPAL) || SpellHex(player_ptr).is_spelling_specific(HEX_RUNESWORD)) && (randint1(vorpal_chance * 3 / 2) == 1)
469         && !is_zantetsu_nullified;
470     calc_attack_damage(player_ptr, pa_ptr, do_quake, vorpal_cut, vorpal_chance);
471     apply_damage_bonus(player_ptr, pa_ptr);
472     apply_damage_negative_effect(pa_ptr, is_zantetsu_nullified, is_ej_nullified);
473     mineuchi(player_ptr, pa_ptr);
474
475     pa_ptr->attack_damage = mon_damage_mod(player_ptr, pa_ptr->m_ptr, pa_ptr->attack_damage,
476         ((o_ptr->tval == ItemKindType::POLEARM) && (o_ptr->sval == SV_DEATH_SCYTHE)) || ((player_ptr->pclass == PlayerClassType::BERSERKER) && one_in_(2)));
477     critical_attack(player_ptr, pa_ptr);
478     msg_format_wizard(player_ptr, CHEAT_MONSTER, _("%dのダメージを与えた。(残りHP %d/%d(%d))", "You do %d damage. (left HP %d/%d(%d))"),
479         pa_ptr->attack_damage, pa_ptr->m_ptr->hp - pa_ptr->attack_damage, pa_ptr->m_ptr->maxhp, pa_ptr->m_ptr->max_maxhp);
480 }
481
482 /*!
483  * @brief 地震を起こす
484  * @param player_ptr プレイヤーへの参照ポインタ
485  * @param pa_ptr 直接攻撃構造体への参照ポインタ
486  * @param do_quake 攻撃後に地震を起こすかどうか
487  * @param y モンスターのY座標
488  * @param x モンスターのX座標
489  */
490 static void cause_earthquake(player_type *player_ptr, player_attack_type *pa_ptr, const bool do_quake, const POSITION y, const POSITION x)
491 {
492     if (!do_quake)
493         return;
494
495     earthquake(player_ptr, player_ptr->y, player_ptr->x, 10, 0);
496     if (player_ptr->current_floor_ptr->grid_array[y][x].m_idx == 0)
497         *(pa_ptr->mdeath) = true;
498 }
499
500 /*!
501  * @brief プレイヤーの打撃処理サブルーチン /
502  * Player attacks a (poor, defenseless) creature        -RAK-
503  * @param y 攻撃目標のY座標
504  * @param x 攻撃目標のX座標
505  * @param fear 攻撃を受けたモンスターが恐慌状態に陥ったかを返す参照ポインタ
506  * @param mdeath 攻撃を受けたモンスターが死亡したかを返す参照ポインタ
507  * @param hand 攻撃を行うための武器を持つ手
508  * @param mode 発動中の剣術ID
509  * @details
510  * If no "weapon" is available, then "punch" the monster one time.
511  */
512 void exe_player_attack_to_monster(player_type *player_ptr, POSITION y, POSITION x, bool *fear, bool *mdeath, int16_t hand, combat_options mode)
513 {
514     bool do_quake = false;
515     bool drain_msg = true;
516
517     player_attack_type tmp_attack;
518     auto pa_ptr = initialize_player_attack_type(&tmp_attack, player_ptr, y, x, hand, mode, fear, mdeath);
519
520     bool is_human = (pa_ptr->r_ptr->d_char == 'p');
521     bool is_lowlevel = (pa_ptr->r_ptr->level < (player_ptr->lev - 15));
522
523     attack_classify(player_ptr, pa_ptr);
524     get_attack_exp(player_ptr, pa_ptr);
525
526     /* Disturb the monster */
527     (void)set_monster_csleep(player_ptr, pa_ptr->m_idx, 0);
528     monster_desc(player_ptr, pa_ptr->m_name, pa_ptr->m_ptr, 0);
529
530     int chance = calc_attack_quality(player_ptr, pa_ptr);
531     object_type *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + pa_ptr->hand];
532     bool is_zantetsu_nullified = ((o_ptr->name1 == ART_ZANTETSU) && (pa_ptr->r_ptr->d_char == 'j'));
533     bool is_ej_nullified = ((o_ptr->name1 == ART_EXCALIBUR_J) && (pa_ptr->r_ptr->d_char == 'S'));
534     calc_num_blow(player_ptr, pa_ptr);
535
536     /* Attack once for each legal blow */
537     int num = 0;
538     while ((num++ < pa_ptr->num_blow) && !player_ptr->is_dead) {
539         if (!process_attack_hit(player_ptr, pa_ptr, chance))
540             continue;
541
542         pa_ptr->attribute_flags = melee_attribute(player_ptr, o_ptr, pa_ptr->mode);
543         apply_actual_attack(player_ptr, pa_ptr, &do_quake, is_zantetsu_nullified, is_ej_nullified);
544         calc_drain(pa_ptr);
545         if (check_fear_death(player_ptr, pa_ptr, num, is_lowlevel))
546             break;
547
548         /* Anger the monster */
549         if (pa_ptr->attack_damage > 0)
550             anger_monster(player_ptr, pa_ptr->m_ptr);
551
552         touch_zap_player(pa_ptr->m_ptr, player_ptr);
553         process_drain(player_ptr, pa_ptr, is_human, &drain_msg);
554         pa_ptr->can_drain = false;
555         pa_ptr->drain_result = 0;
556         change_monster_stat(player_ptr, pa_ptr, y, x, &num);
557         pa_ptr->backstab = false;
558         pa_ptr->surprise_attack = false;
559     }
560
561     if (pa_ptr->weak && !(*mdeath))
562         msg_format(_("%sは弱くなったようだ。", "%^s seems weakened."), pa_ptr->m_name);
563
564     if ((pa_ptr->drain_left != MAX_VAMPIRIC_DRAIN) && one_in_(4))
565         chg_virtue(player_ptr, V_UNLIFE, 1);
566
567     cause_earthquake(player_ptr, pa_ptr, do_quake, y, x);
568 }
569
570 /*!
571  * @brief 皆殺し(全方向攻撃)処理
572  * @param player_ptr プレイヤーへの参照ポインタ
573  */
574 void massacre(player_type *player_ptr)
575 {
576     grid_type *g_ptr;
577     monster_type *m_ptr;
578     for (DIRECTION dir = 0; dir < 8; dir++) {
579         POSITION y = player_ptr->y + ddy_ddd[dir];
580         POSITION x = player_ptr->x + ddx_ddd[dir];
581         g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
582         m_ptr = &player_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
583         if (g_ptr->m_idx && (m_ptr->ml || cave_has_flag_bold(player_ptr->current_floor_ptr, y, x, FF::PROJECT)))
584             do_cmd_attack(player_ptr, y, x, HISSATSU_NONE);
585     }
586 }