OSDN Git Service

Merge pull request #3692 from Hourier/Make-GetTerrain
[hengbandforosx/hengbandosx.git] / src / effect / effect-player-resist-hurt.cpp
1 #include "effect/effect-player-resist-hurt.h"
2 #include "artifact/fixed-art-types.h"
3 #include "blue-magic/blue-magic-checker.h"
4 #include "core/window-redrawer.h"
5 #include "effect/effect-player.h"
6 #include "hpmp/hp-mp-processor.h"
7 #include "inventory/inventory-damage.h"
8 #include "inventory/inventory-slot-types.h"
9 #include "main/sound-definitions-table.h"
10 #include "main/sound-of-music.h"
11 #include "mind/mind-mirror-master.h"
12 #include "monster-race/race-indice-types.h"
13 #include "mutation/mutation-investor-remover.h"
14 #include "object-enchant/object-curse.h"
15 #include "object/object-broken.h"
16 #include "player-base/player-race.h"
17 #include "player-info/race-info.h"
18 #include "player/player-damage.h"
19 #include "player/player-status-flags.h"
20 #include "player/player-status-resist.h"
21 #include "spell-kind/spells-equipment.h"
22 #include "spell-kind/spells-teleport.h"
23 #include "spell/spells-status.h"
24 #include "status/bad-status-setter.h"
25 #include "status/base-status.h"
26 #include "status/element-resistance.h"
27 #include "status/experience.h"
28 #include "status/shape-changer.h"
29 #include "system/item-entity.h"
30 #include "system/player-type-definition.h"
31 #include "system/redrawing-flags-updater.h"
32 #include "timed-effect/player-blindness.h"
33 #include "timed-effect/timed-effects.h"
34 #include "view/display-messages.h"
35 #include "world/world.h"
36
37 // 毒を除く4元素.
38 void effect_player_elements(
39     PlayerType *player_ptr, EffectPlayerType *ep_ptr, std::string_view attack_message, int (*damage_func)(PlayerType *, int, std::string_view, bool))
40 {
41     if (player_ptr->effects()->blindness()->is_blind()) {
42         msg_print(attack_message);
43     }
44
45     ep_ptr->get_damage = (*damage_func)(player_ptr, ep_ptr->dam, ep_ptr->killer, false);
46 }
47
48 void effect_player_poison(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
49 {
50     bool double_resist = is_oppose_pois(player_ptr);
51     if (player_ptr->effects()->blindness()->is_blind()) {
52         msg_print(_("毒で攻撃された!", "You are hit by poison!"));
53     }
54
55     ep_ptr->dam = ep_ptr->dam * calc_pois_damage_rate(player_ptr) / 100;
56
57     if ((!(double_resist || has_resist_pois(player_ptr))) && one_in_(CHANCE_ABILITY_SCORE_DECREASE) && !check_multishadow(player_ptr)) {
58         do_dec_stat(player_ptr, A_CON);
59     }
60
61     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
62
63     if (!(double_resist || has_resist_pois(player_ptr)) && !check_multishadow(player_ptr)) {
64         (void)BadStatusSetter(player_ptr).mod_poison(randint0(ep_ptr->dam) + 10);
65     }
66 }
67
68 void effect_player_nuke(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
69 {
70     bool double_resist = is_oppose_pois(player_ptr);
71     if (player_ptr->effects()->blindness()->is_blind()) {
72         msg_print(_("放射能で攻撃された!", "You are hit by radiation!"));
73     }
74
75     ep_ptr->dam = ep_ptr->dam * calc_pois_damage_rate(player_ptr) / 100;
76
77     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
78     if ((double_resist || has_resist_pois(player_ptr)) || check_multishadow(player_ptr)) {
79         return;
80     }
81
82     (void)BadStatusSetter(player_ptr).mod_poison(randint0(ep_ptr->dam) + 10);
83     if (one_in_(5)) /* 6 */
84     {
85         msg_print(_("奇形的な変身を遂げた!", "You undergo a freakish metamorphosis!"));
86         if (one_in_(4)) { /* 4 */
87             do_poly_self(player_ptr);
88         } else {
89             status_shuffle(player_ptr);
90         }
91     }
92
93     if (one_in_(6)) {
94         inventory_damage(player_ptr, BreakerAcid(), 2);
95     }
96 }
97
98 void effect_player_missile(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
99 {
100     if (player_ptr->effects()->blindness()->is_blind()) {
101         msg_print(_("何かで攻撃された!", "You are hit by something!"));
102     }
103
104     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
105 }
106
107 void effect_player_holy_fire(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
108 {
109     if (player_ptr->effects()->blindness()->is_blind()) {
110         msg_print(_("何かで攻撃された!", "You are hit by something!"));
111     }
112
113     ep_ptr->dam = ep_ptr->dam * calc_holy_fire_damage_rate(player_ptr, CALC_RAND) / 100;
114
115     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
116 }
117
118 void effect_player_hell_fire(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
119 {
120     if (player_ptr->effects()->blindness()->is_blind()) {
121         msg_print(_("何かで攻撃された!", "You are hit by something!"));
122     }
123
124     ep_ptr->dam = ep_ptr->dam * calc_hell_fire_damage_rate(player_ptr, CALC_RAND) / 100;
125
126     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
127 }
128
129 void effect_player_arrow(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
130 {
131     if (player_ptr->effects()->blindness()->is_blind()) {
132         sound(SOUND_SHOOT_HIT);
133         msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
134         ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
135         return;
136     }
137
138     if (has_invuln_arrow(player_ptr)) {
139         msg_print(_("矢を斬り捨てた!", "You cut down the arrow!"));
140         return;
141     }
142
143     sound(SOUND_SHOOT_HIT);
144     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
145 }
146
147 void effect_player_plasma(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
148 {
149     if (player_ptr->effects()->blindness()->is_blind()) {
150         msg_print(_("何かとても熱いもので攻撃された!", "You are hit by something *HOT*!"));
151     }
152
153     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
154
155     if (!has_resist_sound(player_ptr) && !check_multishadow(player_ptr)) {
156         TIME_EFFECT plus_stun = (randint1((ep_ptr->dam > 40) ? 35 : (ep_ptr->dam * 3 / 4 + 5)));
157         (void)BadStatusSetter(player_ptr).mod_stun(plus_stun);
158     }
159
160     if (!(has_resist_fire(player_ptr) || is_oppose_fire(player_ptr) || has_immune_fire(player_ptr))) {
161         inventory_damage(player_ptr, BreakerAcid(), 3);
162     }
163 }
164
165 /*!
166  * @brief 地獄属性によるダメージを受ける
167  * @param player_ptr プレイヤー情報への参照ポインタ
168  * @param em_ptr プレイヤー効果情報への参照ポインタ
169  * @details
170  * 幽霊は回復する。追加効果で経験値吸収。
171  */
172
173 void effect_player_nether(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
174 {
175     if (player_ptr->effects()->blindness()->is_blind()) {
176         msg_print(_("地獄の力で攻撃された!", "You are hit by nether forces!"));
177     }
178
179     bool evaded = check_multishadow(player_ptr);
180
181     if (PlayerRace(player_ptr).equals(PlayerRaceType::SPECTRE)) {
182         if (!evaded) {
183             hp_player(player_ptr, ep_ptr->dam / 4);
184         }
185         ep_ptr->get_damage = 0;
186         return;
187     }
188
189     ep_ptr->dam = ep_ptr->dam * calc_nether_damage_rate(player_ptr, CALC_RAND) / 100;
190
191     if (!has_resist_neth(player_ptr) && !evaded) {
192         drain_exp(player_ptr, 200 + (player_ptr->exp / 100), 200 + (player_ptr->exp / 1000), 75);
193     }
194
195     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
196 }
197
198 /*!
199  * @brief 水流属性によるダメージを受ける
200  * @param player_ptr プレイヤー情報への参照ポインタ
201  * @param em_ptr プレイヤー効果情報への参照ポインタ
202  * @details
203  * 追加効果で朦朧と混乱、冷気同様のインベントリ破壊。
204  */
205 void effect_player_water(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
206 {
207     if (player_ptr->effects()->blindness()->is_blind()) {
208         msg_print(_("何か湿ったもので攻撃された!", "You are hit by something wet!"));
209     }
210
211     if (check_multishadow(player_ptr)) {
212         ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
213         return;
214     }
215
216     ep_ptr->dam = ep_ptr->dam * calc_water_damage_rate(player_ptr, CALC_RAND) / 100;
217
218     BIT_FLAGS has_res_water = has_resist_water(player_ptr);
219     BadStatusSetter bss(player_ptr);
220     if (!check_multishadow(player_ptr)) {
221         if (!has_resist_sound(player_ptr) && !has_res_water) {
222             (void)bss.mod_stun(randint1(40));
223         }
224
225         if (!has_resist_conf(player_ptr) && !has_res_water) {
226             (void)bss.mod_confusion(randint1(5) + 5);
227         }
228
229         if (one_in_(5) && !has_res_water) {
230             inventory_damage(player_ptr, BreakerCold(), 3);
231         }
232     }
233
234     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
235 }
236
237 void effect_player_chaos(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
238 {
239     if (player_ptr->effects()->blindness()->is_blind()) {
240         msg_print(_("無秩序の波動で攻撃された!", "You are hit by a wave of anarchy!"));
241     }
242
243     ep_ptr->dam = ep_ptr->dam * calc_chaos_damage_rate(player_ptr, CALC_RAND) / 100;
244     if (check_multishadow(player_ptr)) {
245         ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
246         return;
247     }
248
249     BadStatusSetter bss(player_ptr);
250     if (!has_resist_conf(player_ptr)) {
251         (void)bss.mod_confusion(randint0(20) + 10);
252     }
253
254     if (!has_resist_chaos(player_ptr)) {
255         (void)bss.mod_hallucination(randint1(10));
256         if (one_in_(3)) {
257             msg_print(_("あなたの身体はカオスの力で捻じ曲げられた!", "Your body is twisted by chaos!"));
258             (void)gain_mutation(player_ptr, 0);
259         }
260     }
261     if (!has_resist_neth(player_ptr) && !has_resist_chaos(player_ptr)) {
262         drain_exp(player_ptr, 5000 + (player_ptr->exp / 100), 500 + (player_ptr->exp / 1000), 75);
263     }
264
265     if (!has_resist_chaos(player_ptr) || one_in_(9)) {
266         inventory_damage(player_ptr, BreakerElec(), 2);
267         inventory_damage(player_ptr, BreakerFire(), 2);
268     }
269
270     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
271 }
272
273 void effect_player_shards(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
274 {
275     if (player_ptr->effects()->blindness()->is_blind()) {
276         msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
277     }
278
279     ep_ptr->dam = ep_ptr->dam * calc_shards_damage_rate(player_ptr, CALC_RAND) / 100;
280
281     if (!has_resist_shard(player_ptr) && !check_multishadow(player_ptr)) {
282         (void)BadStatusSetter(player_ptr).mod_cut(static_cast<TIME_EFFECT>(ep_ptr->dam));
283     }
284
285     if (!has_resist_shard(player_ptr) || one_in_(13)) {
286         inventory_damage(player_ptr, BreakerCold(), 2);
287     }
288
289     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
290 }
291
292 void effect_player_sound(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
293 {
294     if (player_ptr->effects()->blindness()->is_blind()) {
295         msg_print(_("轟音で攻撃された!", "You are hit by a loud noise!"));
296     }
297
298     ep_ptr->dam = ep_ptr->dam * calc_sound_damage_rate(player_ptr, CALC_RAND) / 100;
299
300     if (!has_resist_sound(player_ptr) && !check_multishadow(player_ptr)) {
301         TIME_EFFECT plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
302         (void)BadStatusSetter(player_ptr).mod_stun(plus_stun);
303     }
304
305     if (!has_resist_sound(player_ptr) || one_in_(13)) {
306         inventory_damage(player_ptr, BreakerCold(), 2);
307     }
308
309     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
310 }
311
312 void effect_player_confusion(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
313 {
314     if (player_ptr->effects()->blindness()->is_blind()) {
315         msg_print(_("何か混乱するもので攻撃された!", "You are hit by something puzzling!"));
316     }
317
318     ep_ptr->dam = ep_ptr->dam * calc_conf_damage_rate(player_ptr, CALC_RAND) / 100;
319     BadStatusSetter bss(player_ptr);
320     if (!has_resist_conf(player_ptr) && !check_multishadow(player_ptr)) {
321         (void)bss.mod_confusion(randint1(20) + 10);
322     }
323
324     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
325 }
326
327 void effect_player_disenchant(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
328 {
329     if (player_ptr->effects()->blindness()->is_blind()) {
330         msg_print(_("何かさえないもので攻撃された!", "You are hit by something static!"));
331     }
332
333     ep_ptr->dam = ep_ptr->dam * calc_disenchant_damage_rate(player_ptr, CALC_RAND) / 100;
334
335     if (!has_resist_disen(player_ptr) && !check_multishadow(player_ptr)) {
336         (void)apply_disenchant(player_ptr, 0);
337     }
338
339     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
340 }
341
342 void effect_player_nexus(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
343 {
344     if (player_ptr->effects()->blindness()->is_blind()) {
345         msg_print(_("何か奇妙なもので攻撃された!", "You are hit by something strange!"));
346     }
347
348     ep_ptr->dam = ep_ptr->dam * calc_nexus_damage_rate(player_ptr, CALC_RAND) / 100;
349
350     if (!has_resist_nexus(player_ptr) && !check_multishadow(player_ptr)) {
351         apply_nexus(ep_ptr->m_ptr, player_ptr);
352     }
353
354     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
355 }
356
357 void effect_player_force(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
358 {
359     if (player_ptr->effects()->blindness()->is_blind()) {
360         msg_print(_("運動エネルギーで攻撃された!", "You are hit by kinetic force!"));
361     }
362     if (!has_resist_sound(player_ptr) && !check_multishadow(player_ptr)) {
363         (void)BadStatusSetter(player_ptr).mod_stun(randint1(20));
364     }
365
366     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
367 }
368
369 void effect_player_rocket(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
370 {
371     if (player_ptr->effects()->blindness()->is_blind()) {
372         msg_print(_("爆発があった!", "There is an explosion!"));
373     }
374
375     BadStatusSetter bss(player_ptr);
376     if (!has_resist_sound(player_ptr) && !check_multishadow(player_ptr)) {
377         (void)bss.mod_stun(randint1(20));
378     }
379
380     ep_ptr->dam = ep_ptr->dam * calc_rocket_damage_rate(player_ptr, CALC_RAND) / 100;
381     if (!has_resist_shard(player_ptr) && !check_multishadow(player_ptr)) {
382         (void)bss.mod_cut((ep_ptr->dam / 2));
383     }
384
385     if (!has_resist_shard(player_ptr) || one_in_(12)) {
386         inventory_damage(player_ptr, BreakerCold(), 3);
387     }
388
389     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
390 }
391
392 void effect_player_inertial(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
393 {
394     if (player_ptr->effects()->blindness()->is_blind()) {
395         msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
396     }
397
398     if (!check_multishadow(player_ptr)) {
399         (void)BadStatusSetter(player_ptr).mod_deceleration(randint0(4) + 4, false);
400     }
401
402     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
403 }
404
405 void effect_player_lite(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
406 {
407     const auto is_blind = player_ptr->effects()->blindness()->is_blind();
408     if (is_blind) {
409         msg_print(_("何かで攻撃された!", "You are hit by something!"));
410     }
411
412     if (!is_blind && !has_resist_lite(player_ptr) && !has_resist_blind(player_ptr) && !check_multishadow(player_ptr)) {
413         (void)BadStatusSetter(player_ptr).mod_blindness(randint1(5) + 2);
414     }
415
416     ep_ptr->dam = ep_ptr->dam * calc_lite_damage_rate(player_ptr, CALC_RAND) / 100;
417
418     PlayerRace race(player_ptr);
419     if (race.life() == PlayerRaceLifeType::UNDEAD && race.tr_flags().has(TR_VUL_LITE)) {
420         if (!check_multishadow(player_ptr)) {
421             msg_print(_("光で肉体が焦がされた!", "The light scorches your flesh!"));
422         }
423     }
424
425     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
426
427     if (!player_ptr->wraith_form || check_multishadow(player_ptr)) {
428         return;
429     }
430
431     player_ptr->wraith_form = 0;
432     msg_print(_("閃光のため非物質的な影の存在でいられなくなった。", "The light forces you out of your incorporeal shadow form."));
433
434     auto &rfu = RedrawingFlagsUpdater::get_instance();
435     static constexpr auto flags_mwrf = {
436         MainWindowRedrawingFlag::MAP,
437         MainWindowRedrawingFlag::TIMED_EFFECT,
438     };
439     rfu.set_flags(flags_mwrf);
440     rfu.set_flag(StatusRecalculatingFlag::MONSTER_STATUSES);
441     static constexpr auto flags_swrf = {
442         SubWindowRedrawingFlag::OVERHEAD,
443         SubWindowRedrawingFlag::DUNGEON,
444     };
445     rfu.set_flags(flags_swrf);
446 }
447
448 void effect_player_dark(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
449 {
450     const auto is_blind = player_ptr->effects()->blindness()->is_blind();
451     if (is_blind) {
452         msg_print(_("何かで攻撃された!", "You are hit by something!"));
453     }
454
455     ep_ptr->dam = ep_ptr->dam * calc_dark_damage_rate(player_ptr, CALC_RAND) / 100;
456
457     auto go_blind = !is_blind;
458     go_blind &= !has_resist_blind(player_ptr);
459     go_blind &= !(has_resist_dark(player_ptr) || has_immune_dark(player_ptr));
460     go_blind &= !check_multishadow(player_ptr);
461
462     if (go_blind) {
463         (void)BadStatusSetter(player_ptr).mod_blindness(randint1(5) + 2);
464     }
465
466     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
467 }
468
469 static void effect_player_time_addition(PlayerType *player_ptr)
470 {
471     switch (randint1(10)) {
472     case 1:
473     case 2:
474     case 3:
475     case 4:
476     case 5: {
477         if (PlayerRace(player_ptr).equals(PlayerRaceType::ANDROID)) {
478             break;
479         }
480
481         msg_print(_("人生が逆戻りした気がする。", "You feel like a chunk of the past has been ripped away."));
482         lose_exp(player_ptr, 100 + (player_ptr->exp / 100) * MON_DRAIN_LIFE);
483         break;
484     }
485     case 6:
486     case 7:
487     case 8:
488     case 9:
489         msg_print(player_ptr->decrease_ability_random());
490         break;
491     case 10:
492         msg_print(player_ptr->decrease_ability_all());
493         break;
494     }
495 }
496
497 /*!
498  * @brief 時間逆転属性によるダメージを受ける
499  * @param player_ptr プレイヤー情報への参照ポインタ
500  * @param em_ptr プレイヤー効果情報への参照ポインタ
501  */
502 void effect_player_time(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
503 {
504     if (player_ptr->effects()->blindness()->is_blind()) {
505         msg_print(_("過去からの衝撃に攻撃された!", "You are hit by a blast from the past!"));
506     }
507
508     ep_ptr->dam = ep_ptr->dam * calc_time_damage_rate(player_ptr, CALC_RAND) / 100;
509
510     bool evaded = check_multishadow(player_ptr);
511
512     if (has_resist_time(player_ptr) && !evaded) {
513         msg_print(_("時間が通り過ぎていく気がする。", "You feel as if time is passing you by."));
514     }
515
516     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
517
518     if (!has_resist_time(player_ptr) && !evaded) {
519         effect_player_time_addition(player_ptr);
520     }
521 }
522
523 void effect_player_gravity(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
524 {
525     if (player_ptr->effects()->blindness()->is_blind()) {
526         msg_print(_("何か重いもので攻撃された!", "You are hit by something heavy!"));
527     }
528
529     msg_print(_("周辺の重力がゆがんだ。", "Gravity warps around you."));
530
531     if (!check_multishadow(player_ptr)) {
532         teleport_player(player_ptr, 5, TELEPORT_PASSIVE);
533         BadStatusSetter bss(player_ptr);
534         if (!player_ptr->levitation) {
535             (void)bss.mod_deceleration(randint0(4) + 4, false);
536         }
537
538         if (!(has_resist_sound(player_ptr) || player_ptr->levitation)) {
539             TIME_EFFECT plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
540             (void)bss.mod_stun(plus_stun);
541         }
542     }
543
544     ep_ptr->dam = ep_ptr->dam * calc_gravity_damage_rate(player_ptr, CALC_RAND) / 100;
545     if (!player_ptr->levitation || one_in_(13)) {
546         inventory_damage(player_ptr, BreakerCold(), 2);
547     }
548
549     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
550 }
551
552 void effect_player_disintegration(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
553 {
554     if (player_ptr->effects()->blindness()->is_blind()) {
555         msg_print(_("純粋なエネルギーで攻撃された!", "You are hit by pure energy!"));
556     }
557
558     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
559 }
560
561 void effect_player_death_ray(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
562 {
563     if (player_ptr->effects()->blindness()->is_blind()) {
564         msg_print(_("何か非常に冷たいもので攻撃された!", "You are hit by something extremely cold!"));
565     }
566
567     ep_ptr->dam = ep_ptr->dam * calc_deathray_damage_rate(player_ptr, CALC_RAND) / 100;
568     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
569 }
570
571 void effect_player_mana(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
572 {
573     if (player_ptr->effects()->blindness()->is_blind()) {
574         msg_print(_("魔法のオーラで攻撃された!", "You are hit by an aura of magic!"));
575     }
576
577     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
578 }
579
580 void effect_player_psy_spear(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
581 {
582     if (player_ptr->effects()->blindness()->is_blind()) {
583         msg_print(_("エネルギーの塊で攻撃された!", "You are hit by an energy!"));
584     }
585
586     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_FORCE, ep_ptr->dam, ep_ptr->killer);
587 }
588
589 void effect_player_meteor(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
590 {
591     if (player_ptr->effects()->blindness()->is_blind()) {
592         msg_print(_("何かが空からあなたの頭上に落ちてきた!", "Something falls from the sky on you!"));
593     }
594
595     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
596     if (!has_resist_shard(player_ptr) || one_in_(13)) {
597         if (!has_immune_fire(player_ptr)) {
598             inventory_damage(player_ptr, BreakerFire(), 2);
599         }
600         inventory_damage(player_ptr, BreakerCold(), 2);
601     }
602 }
603
604 void effect_player_icee(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
605 {
606     if (player_ptr->effects()->blindness()->is_blind()) {
607         msg_print(_("何か鋭く冷たいもので攻撃された!", "You are hit by something sharp and cold!"));
608     }
609
610     ep_ptr->get_damage = cold_dam(player_ptr, ep_ptr->dam, ep_ptr->killer, false);
611     if (check_multishadow(player_ptr)) {
612         return;
613     }
614
615     BadStatusSetter bss(player_ptr);
616     if (!has_resist_shard(player_ptr)) {
617         (void)bss.mod_cut(damroll(5, 8));
618     }
619
620     if (!has_resist_sound(player_ptr)) {
621         (void)bss.mod_stun(randint1(15));
622     }
623
624     if ((!(has_resist_cold(player_ptr) || is_oppose_cold(player_ptr))) || one_in_(12)) {
625         if (!has_immune_cold(player_ptr)) {
626             inventory_damage(player_ptr, BreakerCold(), 3);
627         }
628     }
629 }
630
631 void effect_player_hand_doom(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
632 {
633     if ((randint0(100 + ep_ptr->rlev / 2) < player_ptr->skill_sav) && !check_multishadow(player_ptr)) {
634         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
635     } else {
636         if (!check_multishadow(player_ptr)) {
637             msg_print(_("あなたは命が薄まっていくように感じた!", "You feel your life fade away!"));
638             curse_equipment(player_ptr, 40, 20);
639         }
640
641         ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->m_name);
642
643         if (player_ptr->chp < 1) {
644             player_ptr->chp = 1;
645         }
646     }
647 }
648
649 void effect_player_void(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
650 {
651     auto effect_mes = player_ptr->effects()->blindness()->is_blind() ? _("何かに身体が引っ張りこまれる!", "Something absorbs you!")
652                                                                      : _("周辺の空間が歪んだ。", "Sight warps around you.");
653     msg_print(effect_mes);
654     if (!check_multishadow(player_ptr) && !player_ptr->levitation && !player_ptr->anti_tele) {
655         (void)BadStatusSetter(player_ptr).mod_deceleration(randint0(4) + 4, false);
656     }
657
658     ep_ptr->dam = ep_ptr->dam * calc_void_damage_rate(player_ptr, CALC_RAND) / 100;
659     if (!player_ptr->levitation || one_in_(13)) {
660         inventory_damage(player_ptr, BreakerCold(), 2);
661     }
662     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
663 }
664
665 void effect_player_abyss(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
666 {
667     const auto is_blind = player_ptr->effects()->blindness()->is_blind();
668     const auto effect_mes = is_blind ? _("身体が沈み込む気がする!", "You feel you are sinking into something!")
669                                      : _("深淵があなたを誘い込んでいる!", "You are falling into the abyss!");
670     msg_print(effect_mes);
671     ep_ptr->dam = ep_ptr->dam * calc_abyss_damage_rate(player_ptr, CALC_RAND) / 100;
672     BadStatusSetter bss(player_ptr);
673     if (check_multishadow(player_ptr)) {
674         return;
675     }
676
677     if (!player_ptr->levitation) {
678         (void)bss.mod_deceleration(randint0(4) + 4, false);
679     }
680
681     if (is_blind) {
682         return;
683     }
684
685     msg_print(_("深淵から何かがあなたを覗き込んでいる!", "Something gazes at you from the abyss!"));
686     if (!has_resist_chaos(player_ptr)) {
687         (void)bss.mod_hallucination(randint1(10));
688     }
689
690     if (!has_resist_conf(player_ptr)) {
691         (void)bss.mod_confusion(randint1(10));
692     }
693
694     if (!has_resist_fear(player_ptr)) {
695         (void)bss.mod_fear(randint1(10));
696     }
697     ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
698 }