OSDN Git Service

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