OSDN Git Service

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