OSDN Git Service

Merge pull request #794 from habu1010/feature/remove-unused-arg-monspell
[hengbandforosx/hengbandosx.git] / src / combat / aura-counterattack.cpp
1 /*!
2  * @brief モンスターから直接攻撃を受けた時に、プレーヤーのオーラダメージで反撃する処理
3  * @date 2020/05/31
4  * @author Hourier
5  */
6
7 #include "combat/aura-counterattack.h"
8 #include "effect/effect-characteristics.h"
9 #include "effect/effect-processor.h"
10 #include "grid/grid.h"
11 #include "inventory/inventory-slot-types.h"
12 #include "monster-race/monster-race.h"
13 #include "monster-race/race-flags-resistance.h"
14 #include "monster-race/race-flags3.h"
15 #include "monster/monster-info.h"
16 #include "monster/monster-status.h"
17 #include "object-hook/hook-armor.h"
18 #include "object-hook/hook-checker.h"
19 #include "player/player-status-flags.h"
20 #include "realm/realm-hex-numbers.h"
21 #include "spell-kind/spells-teleport.h"
22 #include "spell-realm/spells-hex.h"
23 #include "spell/spell-types.h"
24 #include "system/floor-type-definition.h"
25 #include "system/object-type-definition.h"
26 #include "view/display-messages.h"
27
28 static void aura_fire_by_monster_attack(player_type *target_ptr, monap_type *monap_ptr)
29 {
30     if (!has_sh_fire(target_ptr) || !monap_ptr->alive || target_ptr->is_dead)
31         return;
32
33     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
34     if ((r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK) != 0) {
35         if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
36             r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
37
38         return;
39     }
40
41     HIT_POINT dam = damroll(2, 6);
42     dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
43     msg_format(_("%^sは突然熱くなった!", "%^s is suddenly very hot!"), monap_ptr->m_name);
44     if (mon_take_hit(target_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, _("は灰の山になった。", " turns into a pile of ash."))) {
45         monap_ptr->blinked = FALSE;
46         monap_ptr->alive = FALSE;
47     }
48 }
49
50 static void aura_elec_by_monster_attack(player_type *target_ptr, monap_type *monap_ptr)
51 {
52     if (!has_sh_elec(target_ptr) || !monap_ptr->alive || target_ptr->is_dead)
53         return;
54
55     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
56     if ((r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK) != 0) {
57         if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
58             r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
59
60         return;
61     }
62
63     HIT_POINT dam = damroll(2, 6);
64     dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
65     msg_format(_("%^sは電撃をくらった!", "%^s gets zapped!"), monap_ptr->m_name);
66     if (mon_take_hit(target_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, _("は燃え殻の山になった。", " turns into a pile of cinders."))) {
67         monap_ptr->blinked = FALSE;
68         monap_ptr->alive = FALSE;
69     }
70 }
71
72 static void aura_cold_by_monster_attack(player_type *target_ptr, monap_type *monap_ptr)
73 {
74     if (!has_sh_cold(target_ptr) || !monap_ptr->alive || target_ptr->is_dead)
75         return;
76
77     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
78     if ((r_ptr->flagsr & RFR_EFF_IM_COLD_MASK) != 0) {
79         if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
80             r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
81
82         return;
83     }
84
85     HIT_POINT dam = damroll(2, 6);
86     dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
87     msg_format(_("%^sは冷気をくらった!", "%^s is very cold!"), monap_ptr->m_name);
88     if (mon_take_hit(target_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, _("は凍りついた。", " was frozen."))) {
89         monap_ptr->blinked = FALSE;
90         monap_ptr->alive = FALSE;
91     }
92 }
93
94 static void aura_shards_by_monster_attack(player_type *target_ptr, monap_type *monap_ptr)
95 {
96     if (!target_ptr->dustrobe || !monap_ptr->alive || target_ptr->is_dead)
97         return;
98
99     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
100     if ((r_ptr->flagsr & RFR_EFF_RES_SHAR_MASK) != 0) {
101         if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
102             r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_RES_SHAR_MASK);
103     } else {
104         HIT_POINT dam = damroll(2, 6);
105         dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
106         msg_format(_("%^sは鏡の破片をくらった!", "%^s gets sliced!"), monap_ptr->m_name);
107         if (mon_take_hit(target_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, _("はズタズタになった。", " is torn to pieces."))) {
108             monap_ptr->blinked = FALSE;
109             monap_ptr->alive = FALSE;
110         }
111     }
112
113     if (is_mirror_grid(&target_ptr->current_floor_ptr->grid_array[target_ptr->y][target_ptr->x]))
114         teleport_player(target_ptr, 10, TELEPORT_SPONTANEOUS);
115 }
116
117 static void aura_holy_by_monster_attack(player_type *target_ptr, monap_type *monap_ptr)
118 {
119     if (!target_ptr->tim_sh_holy || !monap_ptr->alive || target_ptr->is_dead)
120         return;
121
122     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
123     if ((r_ptr->flags3 & RF3_EVIL) == 0)
124         return;
125
126     if ((r_ptr->flagsr & RFR_RES_ALL) != 0) {
127         if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
128             r_ptr->r_flagsr |= RFR_RES_ALL;
129
130         return;
131     }
132
133     HIT_POINT dam = damroll(2, 6);
134     dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
135     msg_format(_("%^sは聖なるオーラで傷ついた!", "%^s is injured by holy power!"), monap_ptr->m_name);
136     if (mon_take_hit(target_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, _("は倒れた。", " is destroyed."))) {
137         monap_ptr->blinked = FALSE;
138         monap_ptr->alive = FALSE;
139     }
140
141     if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
142         r_ptr->r_flags3 |= RF3_EVIL;
143 }
144
145 static void aura_force_by_monster_attack(player_type *target_ptr, monap_type *monap_ptr)
146 {
147     if (!target_ptr->tim_sh_touki || !monap_ptr->alive || target_ptr->is_dead)
148         return;
149
150     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
151     if ((r_ptr->flagsr & RFR_RES_ALL) != 0) {
152         if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
153             r_ptr->r_flagsr |= RFR_RES_ALL;
154
155         return;
156     }
157
158     HIT_POINT dam = damroll(2, 6);
159     dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
160     msg_format(_("%^sが鋭い闘気のオーラで傷ついた!", "%^s is injured by the Force"), monap_ptr->m_name);
161     if (mon_take_hit(target_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, _("は倒れた。", " is destroyed."))) {
162         monap_ptr->blinked = FALSE;
163         monap_ptr->alive = FALSE;
164     }
165 }
166
167 static void aura_shadow_by_monster_attack(player_type *target_ptr, monap_type *monap_ptr)
168 {
169     if (!hex_spelling(target_ptr, HEX_SHADOW_CLOAK) || !monap_ptr->alive || target_ptr->is_dead)
170         return;
171
172     HIT_POINT dam = 1;
173     object_type *o_armed_ptr = &target_ptr->inventory_list[INVEN_MAIN_HAND];
174     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
175     if (((r_ptr->flagsr & RFR_RES_ALL) != 0) || ((r_ptr->flagsr & RFR_RES_DARK) != 0)) {
176         if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
177             r_ptr->r_flagsr |= (RFR_RES_ALL | RFR_RES_DARK);
178
179         return;
180     }
181
182     if (o_armed_ptr->k_idx) {
183         int basedam = ((o_armed_ptr->dd + target_ptr->to_dd[0]) * (o_armed_ptr->ds + target_ptr->to_ds[0] + 1));
184         dam = basedam / 2 + o_armed_ptr->to_d + target_ptr->to_d[0];
185     }
186
187     o_armed_ptr = &target_ptr->inventory_list[INVEN_BODY];
188     if ((o_armed_ptr->k_idx) && object_is_cursed(o_armed_ptr))
189         dam *= 2;
190
191     dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
192     msg_format(_("影のオーラが%^sに反撃した!", "Enveloping shadows attack %^s."), monap_ptr->m_name);
193     if (mon_take_hit(target_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, _("は倒れた。", " is destroyed."))) {
194         monap_ptr->blinked = FALSE;
195         monap_ptr->alive = FALSE;
196         return;
197     }
198
199     BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
200     EFFECT_ID typ[4][2] = { { INVEN_HEAD, GF_OLD_CONF }, { INVEN_SUB_HAND, GF_OLD_SLEEP }, { INVEN_ARMS, GF_TURN_ALL }, { INVEN_FEET, GF_OLD_SLOW } };
201
202     /* Some cursed armours gives an extra effect */
203     for (int j = 0; j < 4; j++) {
204         o_armed_ptr = &target_ptr->inventory_list[typ[j][0]];
205         if ((o_armed_ptr->k_idx) && object_is_cursed(o_armed_ptr) && object_is_armour(target_ptr, o_armed_ptr))
206             project(target_ptr, 0, 0, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, (target_ptr->lev * 2), typ[j][1], flg);
207     }
208 }
209
210 void process_aura_counterattack(player_type *target_ptr, monap_type *monap_ptr)
211 {
212     if (!monap_ptr->touched)
213         return;
214
215     aura_fire_by_monster_attack(target_ptr, monap_ptr);
216     aura_elec_by_monster_attack(target_ptr, monap_ptr);
217     aura_cold_by_monster_attack(target_ptr, monap_ptr);
218     aura_shards_by_monster_attack(target_ptr, monap_ptr);
219     aura_holy_by_monster_attack(target_ptr, monap_ptr);
220     aura_force_by_monster_attack(target_ptr, monap_ptr);
221     aura_shadow_by_monster_attack(target_ptr, monap_ptr);
222 }