OSDN Git Service

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