OSDN Git Service

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