1 #include "effect/effect-player-resist-hurt.h"
2 #include "art-definition/art-sword-types.h"
3 #include "blue-magic/blue-magic-checker.h"
4 #include "core/hp-mp-processor.h"
5 #include "core/player-redraw-types.h"
6 #include "core/player-update-types.h"
7 #include "core/window-redrawer.h"
8 #include "inventory/inventory-damage.h"
9 #include "inventory/inventory-slot-types.h"
10 #include "mind/mind-mirror-master.h"
11 #include "monster-race/race-indice-types.h"
12 #include "mutation/mutation-investor-remover.h"
13 #include "object/object-broken.h"
14 #include "player/player-damage.h"
15 #include "player/player-race-types.h"
16 #include "player/player-race.h"
17 #include "player/player-status-flags.h"
18 #include "player/player-status-resist.h"
19 #include "spell-kind/spells-equipment.h"
20 #include "spell-kind/spells-teleport.h"
21 #include "spell/spells-status.h"
22 #include "status/bad-status-setter.h"
23 #include "status/base-status.h"
24 #include "status/element-resistance.h"
25 #include "status/experience.h"
26 #include "status/shape-changer.h"
27 #include "system/object-type-definition.h"
28 #include "view/display-messages.h"
29 #include "world/world.h"
32 void effect_player_elements(
33 player_type *target_ptr, effect_player_type *ep_ptr, concptr attack_message, HIT_POINT (*damage_func)(player_type *, HIT_POINT, concptr, int, bool))
35 if (target_ptr->blind)
36 msg_print(attack_message);
38 ep_ptr->get_damage = (*damage_func)(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
41 void effect_player_poison(player_type *target_ptr, effect_player_type *ep_ptr)
43 bool double_resist = is_oppose_pois(target_ptr);
44 if (target_ptr->blind)
45 msg_print(_("毒で攻撃された!", "You are hit by poison!"));
47 if (target_ptr->resist_pois)
48 ep_ptr->dam = (ep_ptr->dam + 2) / 3;
50 ep_ptr->dam = (ep_ptr->dam + 2) / 3;
52 if ((!(double_resist || target_ptr->resist_pois)) && one_in_(HURT_CHANCE) && !check_multishadow(target_ptr)) {
53 do_dec_stat(target_ptr, A_CON);
56 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
58 if (!(double_resist || target_ptr->resist_pois) && !check_multishadow(target_ptr))
59 set_poisoned(target_ptr, target_ptr->poisoned + randint0(ep_ptr->dam) + 10);
62 void effect_player_nuke(player_type *target_ptr, effect_player_type *ep_ptr)
64 bool double_resist = is_oppose_pois(target_ptr);
65 if (target_ptr->blind)
66 msg_print(_("放射能で攻撃された!", "You are hit by radiation!"));
68 if (target_ptr->resist_pois)
69 ep_ptr->dam = (2 * ep_ptr->dam + 2) / 5;
71 ep_ptr->dam = (2 * ep_ptr->dam + 2) / 5;
73 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
74 if ((double_resist || target_ptr->resist_pois) || check_multishadow(target_ptr))
77 set_poisoned(target_ptr, target_ptr->poisoned + randint0(ep_ptr->dam) + 10);
78 if (one_in_(5)) /* 6 */
80 msg_print(_("奇形的な変身を遂げた!", "You undergo a freakish metamorphosis!"));
81 if (one_in_(4)) /* 4 */
82 do_poly_self(target_ptr);
84 status_shuffle(target_ptr);
88 inventory_damage(target_ptr, set_acid_destroy, 2);
91 void effect_player_missile(player_type *target_ptr, effect_player_type *ep_ptr)
93 if (target_ptr->blind)
94 msg_print(_("何かで攻撃された!", "You are hit by something!"));
96 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
99 void effect_player_holy_fire(player_type *target_ptr, effect_player_type *ep_ptr)
101 if (target_ptr->blind)
102 msg_print(_("何かで攻撃された!", "You are hit by something!"));
104 if (target_ptr->align > 10)
106 else if (target_ptr->align < -10)
109 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
112 void effect_player_hell_fire(player_type *target_ptr, effect_player_type *ep_ptr)
114 if (target_ptr->blind)
115 msg_print(_("何かで攻撃された!", "You are hit by something!"));
117 if (target_ptr->align > 10)
120 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
123 void effect_player_arrow(player_type *target_ptr, effect_player_type *ep_ptr)
125 if (target_ptr->blind) {
126 msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
127 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
131 if ((target_ptr->inventory_list[INVEN_RARM].name1 == ART_ZANTETSU) || (target_ptr->inventory_list[INVEN_LARM].name1 == ART_ZANTETSU)) {
132 msg_print(_("矢を斬り捨てた!", "You cut down the arrow!"));
136 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
139 void effect_player_plasma(player_type *target_ptr, effect_player_type *ep_ptr)
141 if (target_ptr->blind)
142 msg_print(_("何かとても熱いもので攻撃された!", "You are hit by something *HOT*!"));
144 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
146 if (!target_ptr->resist_sound && !check_multishadow(target_ptr)) {
147 int plus_stun = (randint1((ep_ptr->dam > 40) ? 35 : (ep_ptr->dam * 3 / 4 + 5)));
148 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
151 if (!(target_ptr->resist_fire || is_oppose_fire(target_ptr) || is_immune_fire(target_ptr)))
152 inventory_damage(target_ptr, set_acid_destroy, 3);
155 void effect_player_nether(player_type *target_ptr, effect_player_type *ep_ptr)
157 if (target_ptr->blind)
158 msg_print(_("地獄の力で攻撃された!", "You are hit by nether forces!"));
160 if (target_ptr->resist_neth) {
161 if (!is_specific_player_race(target_ptr, RACE_SPECTRE))
163 ep_ptr->dam /= (randint1(4) + 7);
164 } else if (!check_multishadow(target_ptr))
165 drain_exp(target_ptr, 200 + (target_ptr->exp / 100), 200 + (target_ptr->exp / 1000), 75);
167 if (!is_specific_player_race(target_ptr, RACE_SPECTRE) || check_multishadow(target_ptr)) {
168 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
172 msg_print(_("気分がよくなった。", "You feel invigorated!"));
173 hp_player(target_ptr, ep_ptr->dam / 4);
174 learn_spell(target_ptr, ep_ptr->monspell);
177 void effect_player_water(player_type *target_ptr, effect_player_type *ep_ptr)
179 if (target_ptr->blind)
180 msg_print(_("何か湿ったもので攻撃された!", "You are hit by something wet!"));
181 if (check_multishadow(target_ptr)) {
182 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
186 if (!target_ptr->resist_sound && !target_ptr->resist_water) {
187 set_stun(target_ptr, target_ptr->stun + randint1(40));
189 if (!target_ptr->resist_conf && !target_ptr->resist_water) {
190 set_confused(target_ptr, target_ptr->confused + randint1(5) + 5);
193 if (one_in_(5) && !target_ptr->resist_water) {
194 inventory_damage(target_ptr, set_cold_destroy, 3);
197 if (target_ptr->resist_water)
198 ep_ptr->get_damage /= 4;
200 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
203 void effect_player_chaos(player_type *target_ptr, effect_player_type *ep_ptr)
205 if (target_ptr->blind)
206 msg_print(_("無秩序の波動で攻撃された!", "You are hit by a wave of anarchy!"));
207 if (target_ptr->resist_chaos) {
209 ep_ptr->dam /= (randint1(4) + 7);
212 if (check_multishadow(target_ptr)) {
213 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
217 if (!target_ptr->resist_conf) {
218 (void)set_confused(target_ptr, target_ptr->confused + randint0(20) + 10);
220 if (!target_ptr->resist_chaos) {
221 (void)set_image(target_ptr, target_ptr->image + randint1(10));
223 msg_print(_("あなたの身体はカオスの力で捻じ曲げられた!", "Your body is twisted by chaos!"));
224 (void)gain_mutation(target_ptr, 0);
227 if (!target_ptr->resist_neth && !target_ptr->resist_chaos) {
228 drain_exp(target_ptr, 5000 + (target_ptr->exp / 100), 500 + (target_ptr->exp / 1000), 75);
231 if (!target_ptr->resist_chaos || one_in_(9)) {
232 inventory_damage(target_ptr, set_elec_destroy, 2);
233 inventory_damage(target_ptr, set_fire_destroy, 2);
236 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
239 void effect_player_shards(player_type *target_ptr, effect_player_type *ep_ptr)
241 if (target_ptr->blind)
242 msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
243 if (target_ptr->resist_shard) {
245 ep_ptr->dam /= (randint1(4) + 7);
246 } else if (!check_multishadow(target_ptr)) {
247 (void)set_cut(target_ptr, target_ptr->cut + ep_ptr->dam);
250 if (!target_ptr->resist_shard || one_in_(13))
251 inventory_damage(target_ptr, set_cold_destroy, 2);
253 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
256 void effect_player_sound(player_type *target_ptr, effect_player_type *ep_ptr)
258 if (target_ptr->blind)
259 msg_print(_("轟音で攻撃された!", "You are hit by a loud noise!"));
260 if (target_ptr->resist_sound) {
262 ep_ptr->dam /= (randint1(4) + 7);
263 } else if (!check_multishadow(target_ptr)) {
264 int plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
265 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
268 if (!target_ptr->resist_sound || one_in_(13))
269 inventory_damage(target_ptr, set_cold_destroy, 2);
271 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
274 void effect_player_confusion(player_type *target_ptr, effect_player_type *ep_ptr)
276 if (target_ptr->blind)
277 msg_print(_("何か混乱するもので攻撃された!", "You are hit by something puzzling!"));
278 if (target_ptr->resist_conf) {
280 ep_ptr->dam /= (randint1(4) + 7);
281 } else if (!check_multishadow(target_ptr)) {
282 (void)set_confused(target_ptr, target_ptr->confused + randint1(20) + 10);
285 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
288 void effect_player_disenchant(player_type *target_ptr, effect_player_type *ep_ptr)
290 if (target_ptr->blind)
291 msg_print(_("何かさえないもので攻撃された!", "You are hit by something static!"));
292 if (target_ptr->resist_disen) {
294 ep_ptr->dam /= (randint1(4) + 7);
295 } else if (!check_multishadow(target_ptr)) {
296 (void)apply_disenchant(target_ptr, 0);
299 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
302 void effect_player_nexus(player_type *target_ptr, effect_player_type *ep_ptr)
304 if (target_ptr->blind)
305 msg_print(_("何か奇妙なもので攻撃された!", "You are hit by something strange!"));
306 if (target_ptr->resist_nexus) {
308 ep_ptr->dam /= (randint1(4) + 7);
309 } else if (!check_multishadow(target_ptr)) {
310 apply_nexus(ep_ptr->m_ptr, target_ptr);
313 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
316 void effect_player_force(player_type *target_ptr, effect_player_type *ep_ptr)
318 if (target_ptr->blind)
319 msg_print(_("運動エネルギーで攻撃された!", "You are hit by kinetic force!"));
320 if (!target_ptr->resist_sound && !check_multishadow(target_ptr)) {
321 (void)set_stun(target_ptr, target_ptr->stun + randint1(20));
324 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
327 void effect_player_rocket(player_type *target_ptr, effect_player_type *ep_ptr)
329 if (target_ptr->blind)
330 msg_print(_("爆発があった!", "There is an explosion!"));
331 if (!target_ptr->resist_sound && !check_multishadow(target_ptr)) {
332 (void)set_stun(target_ptr, target_ptr->stun + randint1(20));
335 if (target_ptr->resist_shard) {
337 } else if (!check_multishadow(target_ptr)) {
338 (void)set_cut(target_ptr, target_ptr->cut + (ep_ptr->dam / 2));
341 if (!target_ptr->resist_shard || one_in_(12)) {
342 inventory_damage(target_ptr, set_cold_destroy, 3);
345 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
348 void effect_player_inertial(player_type *target_ptr, effect_player_type *ep_ptr)
350 if (target_ptr->blind)
351 msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
352 if (!check_multishadow(target_ptr))
353 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
355 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
358 void effect_player_lite(player_type *target_ptr, effect_player_type *ep_ptr)
360 if (target_ptr->blind)
361 msg_print(_("何かで攻撃された!", "You are hit by something!"));
362 if (target_ptr->resist_lite) {
364 ep_ptr->dam /= (randint1(4) + 7);
365 } else if (!target_ptr->blind && !target_ptr->resist_blind && !check_multishadow(target_ptr)) {
366 (void)set_blind(target_ptr, target_ptr->blind + randint1(5) + 2);
369 ep_ptr->dam = ep_ptr->dam * calc_vuln_fire_rate(target_ptr) / 100;
371 if (is_specific_player_race(target_ptr, RACE_VAMPIRE) || (target_ptr->mimic_form == MIMIC_VAMPIRE)) {
372 if (!check_multishadow(target_ptr))
373 msg_print(_("光で肉体が焦がされた!", "The light scorches your flesh!"));
376 if (target_ptr->wraith_form)
378 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
380 if (!target_ptr->wraith_form || check_multishadow(target_ptr))
383 target_ptr->wraith_form = 0;
384 msg_print(_("閃光のため非物質的な影の存在でいられなくなった。", "The light forces you out of your incorporeal shadow form."));
386 target_ptr->redraw |= (PR_MAP | PR_STATUS);
387 target_ptr->update |= (PU_MONSTERS);
388 target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
391 void effect_player_dark(player_type *target_ptr, effect_player_type *ep_ptr)
393 if (target_ptr->blind)
394 msg_print(_("何かで攻撃された!", "You are hit by something!"));
395 if (target_ptr->resist_dark) {
397 ep_ptr->dam /= (randint1(4) + 7);
399 if (is_specific_player_race(target_ptr, RACE_VAMPIRE) || (target_ptr->mimic_form == MIMIC_VAMPIRE) || target_ptr->wraith_form)
401 } else if (!target_ptr->blind && !target_ptr->resist_blind && !check_multishadow(target_ptr)) {
402 (void)set_blind(target_ptr, target_ptr->blind + randint1(5) + 2);
405 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
408 static void effect_player_time_one_disability(player_type *target_ptr)
412 switch (randint1(6)) {
415 act = _("強く", "strong");
419 act = _("聡明で", "bright");
423 act = _("賢明で", "wise");
427 act = _("器用で", "agile");
431 act = _("健康で", "hale");
435 act = _("美しく", "beautiful");
439 msg_format(_("あなたは以前ほど%sなくなってしまった...。", "You're not as %s as you used to be..."), act);
440 target_ptr->stat_cur[k] = (target_ptr->stat_cur[k] * 3) / 4;
441 if (target_ptr->stat_cur[k] < 3)
442 target_ptr->stat_cur[k] = 3;
444 target_ptr->update |= (PU_BONUS);
447 static void effect_player_time_all_disabilities(player_type *target_ptr)
449 msg_print(_("あなたは以前ほど力強くなくなってしまった...。", "You're not as powerful as you used to be..."));
450 for (int k = 0; k < A_MAX; k++) {
451 target_ptr->stat_cur[k] = (target_ptr->stat_cur[k] * 7) / 8;
452 if (target_ptr->stat_cur[k] < 3)
453 target_ptr->stat_cur[k] = 3;
456 target_ptr->update |= (PU_BONUS);
459 static void effect_player_time_addition(player_type *target_ptr)
461 switch (randint1(10)) {
467 if (target_ptr->prace == RACE_ANDROID)
470 msg_print(_("人生が逆戻りした気がする。", "You feel like a chunk of the past has been ripped away."));
471 lose_exp(target_ptr, 100 + (target_ptr->exp / 100) * MON_DRAIN_LIFE);
478 effect_player_time_one_disability(target_ptr);
481 effect_player_time_all_disabilities(target_ptr);
486 void effect_player_time(player_type *target_ptr, effect_player_type *ep_ptr)
488 if (target_ptr->blind)
489 msg_print(_("過去からの衝撃に攻撃された!", "You are hit by a blast from the past!"));
491 if (target_ptr->resist_time) {
493 ep_ptr->dam /= (randint1(4) + 7);
494 msg_print(_("時間が通り過ぎていく気がする。", "You feel as if time is passing you by."));
495 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
499 if (check_multishadow(target_ptr)) {
500 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
504 effect_player_time_addition(target_ptr);
505 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
508 void effect_player_gravity(player_type *target_ptr, effect_player_type *ep_ptr)
510 if (target_ptr->blind)
511 msg_print(_("何か重いもので攻撃された!", "You are hit by something heavy!"));
512 msg_print(_("周辺の重力がゆがんだ。", "Gravity warps around you."));
514 if (!check_multishadow(target_ptr)) {
515 teleport_player(target_ptr, 5, TELEPORT_PASSIVE);
516 if (!target_ptr->levitation)
517 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
518 if (!(target_ptr->resist_sound || target_ptr->levitation)) {
519 int plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
520 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
524 if (target_ptr->levitation) {
525 ep_ptr->dam = (ep_ptr->dam * 2) / 3;
528 if (!target_ptr->levitation || one_in_(13)) {
529 inventory_damage(target_ptr, set_cold_destroy, 2);
532 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
535 void effect_player_disintegration(player_type *target_ptr, effect_player_type *ep_ptr)
537 if (target_ptr->blind)
538 msg_print(_("純粋なエネルギーで攻撃された!", "You are hit by pure energy!"));
540 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);