2 * @brief モンスターからプレーヤーへの直接攻撃をその種別において振り分ける
5 * @details 長い処理はインクルード先の別ファイルにて行っている
8 #include "monster-attack/monster-attack-switcher.h"
9 #include "monster-attack/monster-attack-status.h"
10 #include "monster-attack/monster-eating.h"
11 #include "mind/drs-types.h"
12 #include "mind/mind-mirror-master.h"
13 #include "monster/monster-status.h"
14 #include "monster/monster-update.h"
15 #include "player/player-damage.h"
16 #include "spell-kind/earthquake.h"
17 #include "spell/spells3.h"
18 #include "status/bad-status-setter.h"
19 #include "status/base-status.h"
20 #include "status/element-resistance.h"
21 #include "status/experience.h"
22 #include "system/object-type-definition.h"
23 #include "view/display-messages.h"
25 void switch_monster_blow_to_player(player_type *target_ptr, monap_type *monap_ptr)
27 switch (monap_ptr->effect) {
29 monap_ptr->obvious = TRUE;
30 monap_ptr->damage = 0;
33 case RBE_SUPERHURT: { /* AC軽減あり / Player armor reduces total damage */
34 if (((randint1(monap_ptr->rlev * 2 + 300) > (monap_ptr->ac + 200)) || one_in_(13)) && !check_multishadow(target_ptr)) {
35 int tmp_damage = monap_ptr->damage - (monap_ptr->damage * ((monap_ptr->ac < 150) ? monap_ptr->ac : 150) / 250);
36 msg_print(_("痛恨の一撃!", "It was a critical hit!"));
37 tmp_damage = MAX(monap_ptr->damage, tmp_damage * 2);
38 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, tmp_damage, monap_ptr->ddesc, -1);
43 case RBE_HURT: { /* AC軽減あり / Player armor reduces total damage */
44 monap_ptr->obvious = TRUE;
45 monap_ptr->damage -= (monap_ptr->damage * ((monap_ptr->ac < 150) ? monap_ptr->ac : 150) / 250);
46 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
50 if (monap_ptr->explode)
53 if (!(target_ptr->resist_pois || is_oppose_pois(target_ptr)) && !check_multishadow(target_ptr)) {
54 if (set_poisoned(target_ptr, target_ptr->poisoned + randint1(monap_ptr->rlev) + 5)) {
55 monap_ptr->obvious = TRUE;
59 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
60 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_POIS);
64 if (monap_ptr->explode)
67 if (!target_ptr->resist_disen && !check_multishadow(target_ptr)) {
68 if (apply_disenchant(target_ptr, 0)) {
69 update_creature(target_ptr);
70 monap_ptr->obvious = TRUE;
74 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
75 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_DISEN);
79 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
80 if (target_ptr->is_dead || check_multishadow(target_ptr))
83 for (int i = 0; i < 10; i++) {
84 INVENTORY_IDX i_idx = (INVENTORY_IDX)randint0(INVEN_PACK);
85 monap_ptr->o_ptr = &target_ptr->inventory_list[i_idx];
86 if (monap_ptr->o_ptr->k_idx == 0)
89 if (process_un_power(target_ptr, monap_ptr))
96 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
97 if (monster_confused_remaining(monap_ptr->m_ptr))
100 if (target_ptr->is_dead || check_multishadow(target_ptr))
103 monap_ptr->obvious = TRUE;
104 process_eat_gold(target_ptr, monap_ptr);
108 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
109 if (!check_eat_item(target_ptr, monap_ptr))
112 process_eat_item(target_ptr, monap_ptr);
117 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
118 if (target_ptr->is_dead || check_multishadow(target_ptr))
121 process_eat_food(target_ptr, monap_ptr);
125 monap_ptr->o_ptr = &target_ptr->inventory_list[INVEN_LITE];
126 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
127 if (target_ptr->is_dead || check_multishadow(target_ptr))
130 process_eat_lite(target_ptr, monap_ptr);
134 if (monap_ptr->explode)
137 monap_ptr->obvious = TRUE;
138 msg_print(_("酸を浴びせられた!", "You are covered in acid!"));
139 monap_ptr->get_damage += acid_dam(target_ptr, monap_ptr->damage, monap_ptr->ddesc, -1, FALSE);
140 update_creature(target_ptr);
141 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_ACID);
145 if (monap_ptr->explode)
147 monap_ptr->obvious = TRUE;
148 msg_print(_("電撃を浴びせられた!", "You are struck by electricity!"));
149 monap_ptr->get_damage += elec_dam(target_ptr, monap_ptr->damage, monap_ptr->ddesc, -1, FALSE);
150 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_ELEC);
154 if (monap_ptr->explode)
156 monap_ptr->obvious = TRUE;
157 msg_print(_("全身が炎に包まれた!", "You are enveloped in flames!"));
158 monap_ptr->get_damage += fire_dam(target_ptr, monap_ptr->damage, monap_ptr->ddesc, -1, FALSE);
159 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_FIRE);
163 if (monap_ptr->explode)
165 monap_ptr->obvious = TRUE;
166 msg_print(_("全身が冷気で覆われた!", "You are covered with frost!"));
167 monap_ptr->get_damage += cold_dam(target_ptr, monap_ptr->damage, monap_ptr->ddesc, -1, FALSE);
168 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_COLD);
172 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
173 if (target_ptr->is_dead)
176 process_blind_attack(target_ptr, monap_ptr);
177 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_BLIND);
181 if (monap_ptr->explode)
184 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
185 if (target_ptr->is_dead)
188 if (!target_ptr->resist_conf && !check_multishadow(target_ptr)) {
189 if (set_confused(target_ptr, target_ptr->confused + 3 + randint1(monap_ptr->rlev))) {
190 monap_ptr->obvious = TRUE;
194 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_CONF);
198 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
199 if (target_ptr->is_dead)
202 process_terrify_attack(target_ptr, monap_ptr);
203 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_FEAR);
207 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
209 if (target_ptr->is_dead)
212 process_paralyze_attack(target_ptr, monap_ptr);
213 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_FREE);
217 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
218 if (target_ptr->is_dead || check_multishadow(target_ptr))
221 if (do_dec_stat(target_ptr, A_STR))
222 monap_ptr->obvious = TRUE;
227 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
228 if (target_ptr->is_dead || check_multishadow(target_ptr))
231 if (do_dec_stat(target_ptr, A_INT))
232 monap_ptr->obvious = TRUE;
237 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
238 if (target_ptr->is_dead || check_multishadow(target_ptr))
241 if (do_dec_stat(target_ptr, A_WIS))
242 monap_ptr->obvious = TRUE;
247 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
248 if (target_ptr->is_dead || check_multishadow(target_ptr))
251 if (do_dec_stat(target_ptr, A_DEX))
252 monap_ptr->obvious = TRUE;
257 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
258 if (target_ptr->is_dead || check_multishadow(target_ptr))
261 if (do_dec_stat(target_ptr, A_CON))
262 monap_ptr->obvious = TRUE;
267 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
268 if (target_ptr->is_dead || check_multishadow(target_ptr))
271 if (do_dec_stat(target_ptr, A_CHR))
272 monap_ptr->obvious = TRUE;
277 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
278 if (target_ptr->is_dead || check_multishadow(target_ptr))
281 process_lose_all_attack(target_ptr, monap_ptr);
284 case RBE_SHATTER: { /* AC軽減あり / Player armor reduces total damage */
285 monap_ptr->obvious = TRUE;
286 monap_ptr->damage -= (monap_ptr->damage * ((monap_ptr->ac < 150) ? monap_ptr->ac : 150) / 250);
287 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
288 if (monap_ptr->damage > 23 || monap_ptr->explode)
289 earthquake(target_ptr, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, 8, monap_ptr->m_idx);
294 s32b d = damroll(10, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
295 monap_ptr->obvious = TRUE;
296 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
297 if (target_ptr->is_dead || check_multishadow(target_ptr))
300 (void)drain_exp(target_ptr, d, d / 10, 95);
304 s32b d = damroll(20, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
305 monap_ptr->obvious = TRUE;
306 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
307 if (target_ptr->is_dead || check_multishadow(target_ptr))
310 (void)drain_exp(target_ptr, d, d / 10, 90);
314 s32b d = damroll(40, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
315 monap_ptr->obvious = TRUE;
316 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
317 if (target_ptr->is_dead || check_multishadow(target_ptr))
320 (void)drain_exp(target_ptr, d, d / 10, 75);
324 s32b d = damroll(80, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
325 monap_ptr->obvious = TRUE;
326 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
327 if (target_ptr->is_dead || check_multishadow(target_ptr))
330 (void)drain_exp(target_ptr, d, d / 10, 50);
334 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
335 if (target_ptr->is_dead || check_multishadow(target_ptr))
338 if (!(target_ptr->resist_pois || is_oppose_pois(target_ptr))) {
339 if (set_poisoned(target_ptr, target_ptr->poisoned + randint1(monap_ptr->rlev) + 5)) {
340 monap_ptr->obvious = TRUE;
344 if ((randint1(100) < 11) && (target_ptr->prace != RACE_ANDROID)) {
345 bool perm = one_in_(10);
346 if (dec_stat(target_ptr, A_CON, randint1(10), perm)) {
347 msg_print(_("病があなたを蝕んでいる気がする。", "You feel sickly."));
348 monap_ptr->obvious = TRUE;
355 if (monap_ptr->explode)
358 process_monster_attack_time(target_ptr, monap_ptr);
359 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
363 s32b d = damroll(60, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
364 monap_ptr->obvious = TRUE;
365 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
366 if (target_ptr->is_dead || check_multishadow(target_ptr))
369 bool resist_drain = check_drain_hp(target_ptr, d);
370 process_drain_life(target_ptr, monap_ptr, resist_drain);
374 monap_ptr->obvious = TRUE;
375 process_drain_mana(target_ptr, monap_ptr);
376 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_MANA);
380 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
381 if (target_ptr->is_dead)
384 if (check_multishadow(target_ptr)) {
387 if (set_slow(target_ptr, (target_ptr->slow + 4 + randint0(monap_ptr->rlev / 10)), FALSE)) {
388 monap_ptr->obvious = TRUE;
395 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
396 if (target_ptr->is_dead)
399 process_stun_attack(target_ptr, monap_ptr);