2 * @brief モンスターから直接攻撃を受けた時に、プレイヤーのオーラダメージで反撃する処理
7 #include "combat/aura-counterattack.h"
8 #include "effect/attribute-types.h"
9 #include "effect/effect-characteristics.h"
10 #include "effect/effect-processor.h"
11 #include "grid/grid.h"
12 #include "inventory/inventory-slot-types.h"
13 #include "monster-attack/monster-attack-player.h"
14 #include "monster-race/monster-race.h"
15 #include "monster-race/race-flags-resistance.h"
16 #include "monster-race/race-flags3.h"
17 #include "monster-race/race-resistance-mask.h"
18 #include "monster/monster-damage.h"
19 #include "monster/monster-info.h"
20 #include "monster/monster-status.h"
21 #include "object-hook/hook-armor.h"
22 #include "player/player-status-flags.h"
23 #include "realm/realm-hex-numbers.h"
24 #include "spell-kind/spells-teleport.h"
25 #include "spell-realm/spells-hex.h"
26 #include "system/floor-type-definition.h"
27 #include "system/grid-type-definition.h"
28 #include "system/item-entity.h"
29 #include "system/monster-entity.h"
30 #include "system/monster-race-info.h"
31 #include "system/player-type-definition.h"
32 #include "view/display-messages.h"
34 static void aura_fire_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
36 if (!has_sh_fire(player_ptr) || !monap_ptr->alive || player_ptr->is_dead) {
40 auto *r_ptr = &monraces_info[monap_ptr->m_ptr->r_idx];
41 if (r_ptr->resistance_flags.has_any_of(RFR_EFF_IM_FIRE_MASK)) {
42 if (is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr)) {
43 r_ptr->r_resistance_flags.set(r_ptr->resistance_flags & RFR_EFF_IM_FIRE_MASK);
49 int dam = damroll(2, 6);
50 dam = mon_damage_mod(player_ptr, monap_ptr->m_ptr, dam, false);
51 msg_format(_("%s^は突然熱くなった!", "%s^ is suddenly very hot!"), monap_ptr->m_name);
52 MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, AttributeType::FIRE);
53 if (mdp.mon_take_hit(_("は灰の山になった。", " turns into a pile of ash."))) {
54 monap_ptr->blinked = false;
55 monap_ptr->alive = false;
59 static void aura_elec_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
61 if (!has_sh_elec(player_ptr) || !monap_ptr->alive || player_ptr->is_dead) {
65 auto *r_ptr = &monraces_info[monap_ptr->m_ptr->r_idx];
66 if (r_ptr->resistance_flags.has_any_of(RFR_EFF_IM_ELEC_MASK)) {
67 if (is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr)) {
68 r_ptr->r_resistance_flags.set(r_ptr->resistance_flags & RFR_EFF_IM_ELEC_MASK);
74 int dam = damroll(2, 6);
75 dam = mon_damage_mod(player_ptr, monap_ptr->m_ptr, dam, false);
76 msg_format(_("%s^は電撃をくらった!", "%s^ gets zapped!"), monap_ptr->m_name);
77 MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, AttributeType::ELEC);
78 if (mdp.mon_take_hit(_("は燃え殻の山になった。", " turns into a pile of cinders."))) {
79 monap_ptr->blinked = false;
80 monap_ptr->alive = false;
84 static void aura_cold_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
86 if (!has_sh_cold(player_ptr) || !monap_ptr->alive || player_ptr->is_dead) {
90 auto *r_ptr = &monraces_info[monap_ptr->m_ptr->r_idx];
91 if (r_ptr->resistance_flags.has_any_of(RFR_EFF_IM_COLD_MASK)) {
92 if (is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr)) {
93 r_ptr->r_resistance_flags.set(r_ptr->resistance_flags & RFR_EFF_IM_COLD_MASK);
99 int dam = damroll(2, 6);
100 dam = mon_damage_mod(player_ptr, monap_ptr->m_ptr, dam, false);
101 msg_format(_("%s^は冷気をくらった!", "%s^ is very cold!"), monap_ptr->m_name);
102 MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, AttributeType::COLD);
103 if (mdp.mon_take_hit(_("は凍りついた。", " was frozen."))) {
104 monap_ptr->blinked = false;
105 monap_ptr->alive = false;
109 static void aura_shards_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
111 if (!player_ptr->dustrobe || !monap_ptr->alive || player_ptr->is_dead) {
115 auto *r_ptr = &monraces_info[monap_ptr->m_ptr->r_idx];
116 if (r_ptr->resistance_flags.has_any_of(RFR_EFF_RESIST_SHARDS_MASK)) {
117 if (is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr)) {
118 r_ptr->r_resistance_flags.set(r_ptr->resistance_flags & RFR_EFF_RESIST_SHARDS_MASK);
121 int dam = damroll(2, 6);
122 dam = mon_damage_mod(player_ptr, monap_ptr->m_ptr, dam, false);
123 msg_format(_("%s^は鏡の破片をくらった!", "%s^ gets sliced!"), monap_ptr->m_name);
124 MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, AttributeType::SHARDS);
125 if (mdp.mon_take_hit(_("はズタズタになった。", " is torn to pieces."))) {
126 monap_ptr->blinked = false;
127 monap_ptr->alive = false;
131 if (player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x].is_mirror()) {
132 teleport_player(player_ptr, 10, TELEPORT_SPONTANEOUS);
136 static void aura_holy_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
138 if (!player_ptr->tim_sh_holy || !monap_ptr->alive || player_ptr->is_dead) {
142 auto *r_ptr = &monraces_info[monap_ptr->m_ptr->r_idx];
143 if (r_ptr->kind_flags.has_not(MonsterKindType::EVIL)) {
147 if (r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_ALL)) {
148 if (is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr)) {
149 r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_ALL);
155 int dam = damroll(2, 6);
156 dam = mon_damage_mod(player_ptr, monap_ptr->m_ptr, dam, false);
157 msg_format(_("%s^は聖なるオーラで傷ついた!", "%s^ is injured by holy power!"), monap_ptr->m_name);
158 MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, AttributeType::HOLY_FIRE);
159 if (mdp.mon_take_hit(_("は倒れた。", " is destroyed."))) {
160 monap_ptr->blinked = false;
161 monap_ptr->alive = false;
164 if (is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr)) {
165 r_ptr->r_kind_flags.set(MonsterKindType::EVIL);
169 static void aura_force_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
171 if (!player_ptr->tim_sh_touki || !monap_ptr->alive || player_ptr->is_dead) {
175 auto *r_ptr = &monraces_info[monap_ptr->m_ptr->r_idx];
176 if (r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_ALL)) {
177 if (is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr)) {
178 r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_ALL);
184 int dam = damroll(2, 6);
185 dam = mon_damage_mod(player_ptr, monap_ptr->m_ptr, dam, false);
186 msg_format(_("%s^が鋭い闘気のオーラで傷ついた!", "%s^ is injured by the Force"), monap_ptr->m_name);
187 MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, AttributeType::MANA);
188 if (mdp.mon_take_hit(_("は倒れた。", " is destroyed."))) {
189 monap_ptr->blinked = false;
190 monap_ptr->alive = false;
194 static void aura_shadow_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
196 if (!SpellHex(player_ptr).is_spelling_specific(HEX_SHADOW_CLOAK) || !monap_ptr->alive || player_ptr->is_dead) {
201 ItemEntity *o_armed_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND];
202 auto *r_ptr = &monraces_info[monap_ptr->m_ptr->r_idx];
203 const EnumClassFlagGroup<MonsterResistanceType> resist_flags = { MonsterResistanceType::RESIST_ALL, MonsterResistanceType::RESIST_DARK };
205 if (r_ptr->resistance_flags.has_any_of(resist_flags)) {
206 if (is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr)) {
207 r_ptr->r_resistance_flags.set(r_ptr->resistance_flags & resist_flags);
213 if (o_armed_ptr->is_valid()) {
214 int basedam = ((o_armed_ptr->dd + player_ptr->to_dd[0]) * (o_armed_ptr->ds + player_ptr->to_ds[0] + 1));
215 dam = basedam / 2 + o_armed_ptr->to_d + player_ptr->to_d[0];
218 o_armed_ptr = &player_ptr->inventory_list[INVEN_BODY];
219 if (o_armed_ptr->is_valid() && o_armed_ptr->is_cursed()) {
223 dam = mon_damage_mod(player_ptr, monap_ptr->m_ptr, dam, false);
224 msg_format(_("影のオーラが%s^に反撃した!", "Enveloping shadows attack %s^."), monap_ptr->m_name);
225 MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, dam, &monap_ptr->fear, AttributeType::DARK);
226 if (mdp.mon_take_hit(_("は倒れた。", " is destroyed."))) {
227 monap_ptr->blinked = false;
228 monap_ptr->alive = false;
232 struct attribute_table {
233 inventory_slot_type slot;
237 const int TABLE_SIZE = 4;
238 attribute_table table[TABLE_SIZE] = { { INVEN_HEAD, AttributeType::OLD_CONF }, { INVEN_SUB_HAND, AttributeType::OLD_SLEEP },
239 { INVEN_ARMS, AttributeType::TURN_ALL }, { INVEN_FEET, AttributeType::OLD_SLOW } };
241 BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
243 /* Some cursed armours gives an extra effect */
244 for (int j = 0; j < TABLE_SIZE; j++) {
245 o_armed_ptr = &player_ptr->inventory_list[table[j].slot];
246 if (o_armed_ptr->is_valid() && o_armed_ptr->is_cursed() && o_armed_ptr->is_protector()) {
247 project(player_ptr, 0, 0, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, (player_ptr->lev * 2), table[j].type, flg);
252 void process_aura_counterattack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
254 if (!monap_ptr->touched) {
258 aura_fire_by_monster_attack(player_ptr, monap_ptr);
259 aura_elec_by_monster_attack(player_ptr, monap_ptr);
260 aura_cold_by_monster_attack(player_ptr, monap_ptr);
261 aura_shards_by_monster_attack(player_ptr, monap_ptr);
262 aura_holy_by_monster_attack(player_ptr, monap_ptr);
263 aura_force_by_monster_attack(player_ptr, monap_ptr);
264 aura_shadow_by_monster_attack(player_ptr, monap_ptr);