2 * todo 単体で1000行を超えている。要分割
3 * @brief 魔法によるプレーヤーへの効果まとめ
9 #include "effect/effect-player-util.h"
10 #include "effect/effect-player.h"
11 #include "main/sound-definitions-table.h"
12 #include "player-damage.h"
14 #include "object-broken.h"
16 #include "player/mimic-info-table.h"
17 #include "realm/realm-hex.h"
18 #include "effect/spells-effect-util.h"
19 #include "player-move.h"
20 #include "player-effects.h"
21 #include "spells-status.h"
22 #include "monster-spell.h"
24 #include "object-curse.h"
25 #include "spell/spells-type.h"
27 typedef enum effect_player_check_result
31 EP_CHECK_CONTINUE = 2,
35 * @brief effect_player_type構造体を初期化する
36 * @param ep_ptr 初期化前の構造体
37 * @param who 魔法を唱えたモンスター (0ならプレーヤー自身)
39 * @param effect_type 効果属性
41 * @param monspell 効果元のモンスター魔法ID
42 * @return 初期化後の構造体ポインタ
44 static effect_player_type *initialize_effect_player(effect_player_type *ep_ptr, MONSTER_IDX who, HIT_POINT dam, EFFECT_ID effect_type, BIT_FLAGS flag, int monspell)
48 ep_ptr->get_damage = 0;
51 ep_ptr->effect_type = effect_type;
53 ep_ptr->monspell = monspell;
60 * @param target_ptr プレーヤーへの参照ポインタ
61 * @param ep_ptr プレーヤー効果構造体への参照ポインタ
62 * @return 当たったらFALSE、反射したらTRUE
64 static bool process_bolt_reflection(player_type *target_ptr, effect_player_type *ep_ptr)
66 bool can_bolt_hit = target_ptr->reflect || (((target_ptr->special_defense & KATA_FUUJIN) != 0) && !target_ptr->blind);
67 can_bolt_hit &= (ep_ptr->flag & PROJECT_REFLECTABLE) != 0;
68 can_bolt_hit &= !one_in_(10);
69 if (!can_bolt_hit) return FALSE;
72 int max_attempts = 10;
75 if (target_ptr->blind)
76 msg_print(_("何かが跳ね返った!", "Something bounces!"));
77 else if (target_ptr->special_defense & KATA_FUUJIN)
78 msg_print(_("風の如く武器を振るって弾き返した!", "The attack bounces!"));
80 msg_print(_("攻撃が跳ね返った!", "The attack bounces!"));
84 floor_type *floor_ptr = target_ptr->current_floor_ptr;
85 monster_type m_type = floor_ptr->m_list[ep_ptr->who];
88 t_y = m_type.fy - 1 + randint1(3);
89 t_x = m_type.fx - 1 + randint1(3);
91 } while (max_attempts && in_bounds2u(floor_ptr, t_y, t_x) && !projectable(target_ptr, target_ptr->y, target_ptr->x, t_y, t_x));
101 t_y = target_ptr->y - 1 + randint1(3);
102 t_x = target_ptr->x - 1 + randint1(3);
105 project(target_ptr, 0, 0, t_y, t_x, ep_ptr->dam, ep_ptr->effect_type, (PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE), ep_ptr->monspell);
106 disturb(target_ptr, TRUE, TRUE);
112 * @brief 反射・忍者の変わり身などでそもそも当たらない状況を判定する
113 * @param target_ptr プレーヤーへの参照ポインタ
114 * @param ep_ptr プレーヤー効果構造体への参照ポインタ
117 * @return 当たらなかったらFALSE、反射したらTRUE、当たったらCONTINUE
119 static ep_check_result check_continue_player_effect(player_type *target_ptr, effect_player_type *ep_ptr, POSITION y, POSITION x)
121 if (!player_bold(target_ptr, y, x))
122 return EP_CHECK_FALSE;
124 if (((target_ptr->special_defense & NINJA_KAWARIMI) != 0) &&
126 (randint0(55) < (target_ptr->lev * 3 / 5 + 20)) &&
128 (ep_ptr->who != target_ptr->riding) &&
129 kawarimi(target_ptr, TRUE))
130 return EP_CHECK_FALSE;
132 if ((ep_ptr->who == 0) || (ep_ptr->who == target_ptr->riding))
133 return EP_CHECK_FALSE;
135 if (process_bolt_reflection(target_ptr, ep_ptr))
136 return EP_CHECK_TRUE;
138 return EP_CHECK_CONTINUE;
143 * @brief 魔法を発したモンスター名を記述する
144 * @param target_ptr プレーヤーへの参照ポインタ
145 * @param ep_ptr プレーヤー効果構造体への参照ポインタ
146 * @param who_name モンスター名
149 static void describe_effect_source(player_type *target_ptr, effect_player_type *ep_ptr, concptr who_name)
153 ep_ptr->m_ptr = &target_ptr->current_floor_ptr->m_list[ep_ptr->who];
154 ep_ptr->rlev = (&r_info[ep_ptr->m_ptr->r_idx])->level >= 1 ? (&r_info[ep_ptr->m_ptr->r_idx])->level : 1;
155 monster_desc(target_ptr, ep_ptr->m_name, ep_ptr->m_ptr, 0);
156 strcpy(ep_ptr->killer, who_name);
162 case PROJECT_WHO_UNCTRL_POWER:
163 strcpy(ep_ptr->killer, _("制御できない力の氾流", "uncontrollable power storm"));
165 case PROJECT_WHO_GLASS_SHARDS:
166 strcpy(ep_ptr->killer, _("ガラスの破片", "shards of glass"));
169 strcpy(ep_ptr->killer, _("罠", "a trap"));
173 strcpy(ep_ptr->m_name, ep_ptr->killer);
178 * @brief 魔法の効果によって様々なメッセーを出力したり与えるダメージの増減を行ったりする
179 * @param target_ptr プレーヤーへの参照ポインタ
180 * @param em_ptr プレーヤー効果構造体への参照ポインタ
183 void switch_effects_player(player_type *target_ptr, effect_player_type *ep_ptr)
185 switch (ep_ptr->effect_type)
189 if (target_ptr->blind) msg_print(_("酸で攻撃された!", "You are hit by acid!"));
191 ep_ptr->get_damage = acid_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
196 if (target_ptr->blind) msg_print(_("火炎で攻撃された!", "You are hit by fire!"));
198 ep_ptr->get_damage = fire_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
203 if (target_ptr->blind) msg_print(_("冷気で攻撃された!", "You are hit by cold!"));
205 ep_ptr->get_damage = cold_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
210 if (target_ptr->blind) msg_print(_("電撃で攻撃された!", "You are hit by lightning!"));
212 ep_ptr->get_damage = elec_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
217 bool double_resist = is_oppose_pois(target_ptr);
218 if (target_ptr->blind) msg_print(_("毒で攻撃された!", "You are hit by poison!"));
220 if (target_ptr->resist_pois) ep_ptr->dam = (ep_ptr->dam + 2) / 3;
221 if (double_resist) ep_ptr->dam = (ep_ptr->dam + 2) / 3;
223 if ((!(double_resist || target_ptr->resist_pois)) && one_in_(HURT_CHANCE) && !CHECK_MULTISHADOW(target_ptr))
225 do_dec_stat(target_ptr, A_CON);
228 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
230 if (!(double_resist || target_ptr->resist_pois) && !CHECK_MULTISHADOW(target_ptr))
231 set_poisoned(target_ptr, target_ptr->poisoned + randint0(ep_ptr->dam) + 10);
237 bool double_resist = is_oppose_pois(target_ptr);
238 if (target_ptr->blind) msg_print(_("放射能で攻撃された!", "You are hit by radiation!"));
240 if (target_ptr->resist_pois) ep_ptr->dam = (2 * ep_ptr->dam + 2) / 5;
241 if (double_resist) ep_ptr->dam = (2 * ep_ptr->dam + 2) / 5;
242 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
243 if ((double_resist || target_ptr->resist_pois) || CHECK_MULTISHADOW(target_ptr))
246 set_poisoned(target_ptr, target_ptr->poisoned + randint0(ep_ptr->dam) + 10);
248 if (one_in_(5)) /* 6 */
250 msg_print(_("奇形的な変身を遂げた!", "You undergo a freakish metamorphosis!"));
251 if (one_in_(4)) /* 4 */
252 do_poly_self(target_ptr);
254 status_shuffle(target_ptr);
259 inventory_damage(target_ptr, set_acid_destroy, 2);
266 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
267 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
272 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
273 if (target_ptr->align > 10)
275 else if (target_ptr->align < -10)
277 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
282 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
283 if (target_ptr->align > 10)
285 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
290 if (target_ptr->blind)
292 msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
294 else if ((target_ptr->inventory_list[INVEN_RARM].name1 == ART_ZANTETSU) || (target_ptr->inventory_list[INVEN_LARM].name1 == ART_ZANTETSU))
296 msg_print(_("矢を斬り捨てた!", "You cut down the arrow!"));
300 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
305 if (target_ptr->blind) msg_print(_("何かとても熱いもので攻撃された!", "You are hit by something *HOT*!"));
306 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
308 if (!target_ptr->resist_sound && !CHECK_MULTISHADOW(target_ptr))
310 int plus_stun = (randint1((ep_ptr->dam > 40) ? 35 : (ep_ptr->dam * 3 / 4 + 5)));
311 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
314 if (!(target_ptr->resist_fire || is_oppose_fire(target_ptr) || target_ptr->immune_fire))
316 inventory_damage(target_ptr, set_acid_destroy, 3);
323 if (target_ptr->blind) msg_print(_("地獄の力で攻撃された!", "You are hit by nether forces!"));
324 if (target_ptr->resist_neth)
326 if (!PRACE_IS_(target_ptr, RACE_SPECTRE))
328 ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
331 else if (!CHECK_MULTISHADOW(target_ptr)) drain_exp(target_ptr, 200 + (target_ptr->exp / 100), 200 + (target_ptr->exp / 1000), 75);
333 if (PRACE_IS_(target_ptr, RACE_SPECTRE) && !CHECK_MULTISHADOW(target_ptr))
335 msg_print(_("気分がよくなった。", "You feel invigorated!"));
336 hp_player(target_ptr, ep_ptr->dam / 4);
337 learn_spell(target_ptr, ep_ptr->monspell);
341 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
348 if (target_ptr->blind) msg_print(_("何か湿ったもので攻撃された!", "You are hit by something wet!"));
349 if (CHECK_MULTISHADOW(target_ptr))
351 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
355 if (!target_ptr->resist_sound && !target_ptr->resist_water)
357 set_stun(target_ptr, target_ptr->stun + randint1(40));
359 if (!target_ptr->resist_conf && !target_ptr->resist_water)
361 set_confused(target_ptr, target_ptr->confused + randint1(5) + 5);
364 if (one_in_(5) && !target_ptr->resist_water)
366 inventory_damage(target_ptr, set_cold_destroy, 3);
369 if (target_ptr->resist_water) ep_ptr->get_damage /= 4;
371 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
376 if (target_ptr->blind) msg_print(_("無秩序の波動で攻撃された!", "You are hit by a wave of anarchy!"));
377 if (target_ptr->resist_chaos)
379 ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
382 if (CHECK_MULTISHADOW(target_ptr))
384 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
388 if (!target_ptr->resist_conf)
390 (void)set_confused(target_ptr, target_ptr->confused + randint0(20) + 10);
392 if (!target_ptr->resist_chaos)
394 (void)set_image(target_ptr, target_ptr->image + randint1(10));
397 msg_print(_("あなたの身体はカオスの力で捻じ曲げられた!", "Your body is twisted by chaos!"));
398 (void)gain_mutation(target_ptr, 0);
401 if (!target_ptr->resist_neth && !target_ptr->resist_chaos)
403 drain_exp(target_ptr, 5000 + (target_ptr->exp / 100), 500 + (target_ptr->exp / 1000), 75);
406 if (!target_ptr->resist_chaos || one_in_(9))
408 inventory_damage(target_ptr, set_elec_destroy, 2);
409 inventory_damage(target_ptr, set_fire_destroy, 2);
412 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
417 if (target_ptr->blind) msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
418 if (target_ptr->resist_shard)
420 ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
422 else if (!CHECK_MULTISHADOW(target_ptr))
424 (void)set_cut(target_ptr, target_ptr->cut + ep_ptr->dam);
427 if (!target_ptr->resist_shard || one_in_(13))
429 inventory_damage(target_ptr, set_cold_destroy, 2);
432 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
437 if (target_ptr->blind) msg_print(_("轟音で攻撃された!", "You are hit by a loud noise!"));
438 if (target_ptr->resist_sound)
440 ep_ptr->dam *= 5; ep_ptr->dam /= (randint1(4) + 7);
442 else if (!CHECK_MULTISHADOW(target_ptr))
444 int plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
445 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
448 if (!target_ptr->resist_sound || one_in_(13))
450 inventory_damage(target_ptr, set_cold_destroy, 2);
453 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
458 if (target_ptr->blind) msg_print(_("何か混乱するもので攻撃された!", "You are hit by something puzzling!"));
459 if (target_ptr->resist_conf)
461 ep_ptr->dam *= 5; ep_ptr->dam /= (randint1(4) + 7);
463 else if (!CHECK_MULTISHADOW(target_ptr))
465 (void)set_confused(target_ptr, target_ptr->confused + randint1(20) + 10);
467 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
472 if (target_ptr->blind) msg_print(_("何かさえないもので攻撃された!", "You are hit by something static!"));
473 if (target_ptr->resist_disen)
475 ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
477 else if (!CHECK_MULTISHADOW(target_ptr))
479 (void)apply_disenchant(target_ptr, 0);
481 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
486 if (target_ptr->blind) msg_print(_("何か奇妙なもので攻撃された!", "You are hit by something strange!"));
487 if (target_ptr->resist_nexus)
489 ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
491 else if (!CHECK_MULTISHADOW(target_ptr))
493 apply_nexus(ep_ptr->m_ptr, target_ptr);
496 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
501 if (target_ptr->blind) msg_print(_("運動エネルギーで攻撃された!", "You are hit by kinetic force!"));
502 if (!target_ptr->resist_sound && !CHECK_MULTISHADOW(target_ptr))
504 (void)set_stun(target_ptr, target_ptr->stun + randint1(20));
507 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
512 if (target_ptr->blind) msg_print(_("爆発があった!", "There is an explosion!"));
513 if (!target_ptr->resist_sound && !CHECK_MULTISHADOW(target_ptr))
515 (void)set_stun(target_ptr, target_ptr->stun + randint1(20));
518 if (target_ptr->resist_shard)
522 else if (!CHECK_MULTISHADOW(target_ptr))
524 (void)set_cut(target_ptr, target_ptr->cut + (ep_ptr->dam / 2));
527 if (!target_ptr->resist_shard || one_in_(12))
529 inventory_damage(target_ptr, set_cold_destroy, 3);
532 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
537 if (target_ptr->blind) msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
538 if (!CHECK_MULTISHADOW(target_ptr)) (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
540 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
545 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
546 if (target_ptr->resist_lite)
548 ep_ptr->dam *= 4; ep_ptr->dam /= (randint1(4) + 7);
550 else if (!target_ptr->blind && !target_ptr->resist_blind && !CHECK_MULTISHADOW(target_ptr))
552 (void)set_blind(target_ptr, target_ptr->blind + randint1(5) + 2);
555 if (PRACE_IS_(target_ptr, RACE_VAMPIRE) || (target_ptr->mimic_form == MIMIC_VAMPIRE))
557 if (!CHECK_MULTISHADOW(target_ptr)) msg_print(_("光で肉体が焦がされた!", "The light scorches your flesh!"));
560 else if (PRACE_IS_(target_ptr, RACE_S_FAIRY))
562 ep_ptr->dam = ep_ptr->dam * 4 / 3;
565 if (target_ptr->wraith_form) ep_ptr->dam *= 2;
566 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
568 if (!target_ptr->wraith_form || CHECK_MULTISHADOW(target_ptr))
571 target_ptr->wraith_form = 0;
572 msg_print(_("閃光のため非物質的な影の存在でいられなくなった。",
573 "The light forces you out of your incorporeal shadow form."));
575 target_ptr->redraw |= (PR_MAP | PR_STATUS);
576 target_ptr->update |= (PU_MONSTERS);
577 target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
582 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
583 if (target_ptr->resist_dark)
585 ep_ptr->dam *= 4; ep_ptr->dam /= (randint1(4) + 7);
587 if (PRACE_IS_(target_ptr, RACE_VAMPIRE) || (target_ptr->mimic_form == MIMIC_VAMPIRE) || target_ptr->wraith_form) ep_ptr->dam = 0;
589 else if (!target_ptr->blind && !target_ptr->resist_blind && !CHECK_MULTISHADOW(target_ptr))
591 (void)set_blind(target_ptr, target_ptr->blind + randint1(5) + 2);
594 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
599 if (target_ptr->blind) msg_print(_("過去からの衝撃に攻撃された!", "You are hit by a blast from the past!"));
601 if (target_ptr->resist_time)
604 ep_ptr->dam /= (randint1(4) + 7);
605 msg_print(_("時間が通り過ぎていく気がする。", "You feel as if time is passing you by."));
606 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
610 if (CHECK_MULTISHADOW(target_ptr))
612 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
616 switch (randint1(10))
624 if (target_ptr->prace == RACE_ANDROID) break;
626 msg_print(_("人生が逆戻りした気がする。", "You feel like a chunk of the past has been ripped away."));
627 lose_exp(target_ptr, 100 + (target_ptr->exp / 100) * MON_DRAIN_LIFE);
639 case 1: k = A_STR; act = _("強く", "strong"); break;
640 case 2: k = A_INT; act = _("聡明で", "bright"); break;
641 case 3: k = A_WIS; act = _("賢明で", "wise"); break;
642 case 4: k = A_DEX; act = _("器用で", "agile"); break;
643 case 5: k = A_CON; act = _("健康で", "hale"); break;
644 case 6: k = A_CHR; act = _("美しく", "beautiful"); break;
647 msg_format(_("あなたは以前ほど%sなくなってしまった...。", "You're not as %s as you used to be..."), act);
648 target_ptr->stat_cur[k] = (target_ptr->stat_cur[k] * 3) / 4;
649 if (target_ptr->stat_cur[k] < 3) target_ptr->stat_cur[k] = 3;
651 target_ptr->update |= (PU_BONUS);
656 msg_print(_("あなたは以前ほど力強くなくなってしまった...。", "You're not as powerful as you used to be..."));
657 for (int k = 0; k < A_MAX; k++)
659 target_ptr->stat_cur[k] = (target_ptr->stat_cur[k] * 7) / 8;
660 if (target_ptr->stat_cur[k] < 3) target_ptr->stat_cur[k] = 3;
663 target_ptr->update |= (PU_BONUS);
668 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
673 if (target_ptr->blind) msg_print(_("何か重いもので攻撃された!", "You are hit by something heavy!"));
674 msg_print(_("周辺の重力がゆがんだ。", "Gravity warps around you."));
676 if (!CHECK_MULTISHADOW(target_ptr))
678 teleport_player(target_ptr, 5, TELEPORT_PASSIVE);
679 if (!target_ptr->levitation)
680 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
681 if (!(target_ptr->resist_sound || target_ptr->levitation))
683 int plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
684 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
688 if (target_ptr->levitation)
690 ep_ptr->dam = (ep_ptr->dam * 2) / 3;
693 if (!target_ptr->levitation || one_in_(13))
695 inventory_damage(target_ptr, set_cold_destroy, 2);
698 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
701 case GF_DISINTEGRATE:
703 if (target_ptr->blind) msg_print(_("純粋なエネルギーで攻撃された!", "You are hit by pure energy!"));
705 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
710 if (target_ptr->blind) msg_print(_("何らかの攻撃によって気分がよくなった。", "You are hit by something invigorating!"));
712 (void)hp_player(target_ptr, ep_ptr->dam);
718 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
719 (void)set_fast(target_ptr, target_ptr->fast + randint1(5), FALSE);
725 if (target_ptr->blind) msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
726 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
731 if (target_ptr->free_act) break;
732 if (target_ptr->blind) msg_print(_("眠ってしまった!", "You fall asleep!"));
734 if (ironman_nightmare)
736 msg_print(_("恐ろしい光景が頭に浮かんできた。", "A horrible vision enters your mind."));
737 /* Have some nightmares */
738 sanity_blast(target_ptr, NULL, FALSE);
741 set_paralyzed(target_ptr, target_ptr->paralyzed + ep_ptr->dam);
749 if (target_ptr->blind) msg_print(_("魔法のオーラで攻撃された!", "You are hit by an aura of magic!"));
751 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
756 if (target_ptr->blind) msg_print(_("エネルギーの塊で攻撃された!", "You are hit by an energy!"));
758 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_FORCE, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
763 if (target_ptr->blind) msg_print(_("何かが空からあなたの頭上に落ちてきた!", "Something falls from the sky on you!"));
765 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
766 if (!target_ptr->resist_shard || one_in_(13))
768 if (!target_ptr->immune_fire) inventory_damage(target_ptr, set_fire_destroy, 2);
769 inventory_damage(target_ptr, set_cold_destroy, 2);
776 if (target_ptr->blind) msg_print(_("何か鋭く冷たいもので攻撃された!", "You are hit by something sharp and cold!"));
778 ep_ptr->get_damage = cold_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
779 if (CHECK_MULTISHADOW(target_ptr)) break;
781 if (!target_ptr->resist_shard)
783 (void)set_cut(target_ptr, target_ptr->cut + damroll(5, 8));
786 if (!target_ptr->resist_sound)
788 (void)set_stun(target_ptr, target_ptr->stun + randint1(15));
791 if ((!(target_ptr->resist_cold || is_oppose_cold(target_ptr))) || one_in_(12))
793 if (!target_ptr->immune_cold) inventory_damage(target_ptr, set_cold_destroy, 3);
800 if (target_ptr->blind) msg_print(_("何か非常に冷たいもので攻撃された!", "You are hit by something extremely cold!"));
802 if (target_ptr->mimic_form)
804 if (!(mimic_info[target_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING))
805 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
810 switch (target_ptr->prace)
824 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
833 if (CHECK_MULTISHADOW(target_ptr))
835 msg_print(_("攻撃は幻影に命中し、あなたには届かなかった。", "The attack hits Shadow, but you are unharmed!"));
840 if (target_ptr->csp == 0)
847 msg_format(_("%^sに精神エネルギーを吸い取られてしまった!", "%^s draws psychic energy from you!"), ep_ptr->m_name);
849 msg_print(_("精神エネルギーを吸い取られてしまった!", "Your psychic energy is drawn!"));
851 if (ep_ptr->dam >= target_ptr->csp)
853 ep_ptr->dam = target_ptr->csp;
855 target_ptr->csp_frac = 0;
859 target_ptr->csp -= ep_ptr->dam;
862 learn_spell(target_ptr, ep_ptr->monspell);
863 target_ptr->redraw |= (PR_MANA);
864 target_ptr->window |= (PW_PLAYER | PW_SPELL);
866 if ((ep_ptr->who <= 0) || (ep_ptr->m_ptr->hp >= ep_ptr->m_ptr->maxhp))
872 ep_ptr->m_ptr->hp += ep_ptr->dam;
873 if (ep_ptr->m_ptr->hp > ep_ptr->m_ptr->maxhp) ep_ptr->m_ptr->hp = ep_ptr->m_ptr->maxhp;
875 if (target_ptr->health_who == ep_ptr->who) target_ptr->redraw |= (PR_HEALTH);
876 if (target_ptr->riding == ep_ptr->who) target_ptr->redraw |= (PR_UHEALTH);
878 if (ep_ptr->m_ptr->ml)
880 msg_format(_("%^sは気分が良さそうだ。", "%^s appears healthier."), ep_ptr->m_name);
888 if ((randint0(100 + ep_ptr->rlev / 2) < MAX(5, target_ptr->skill_sav)) && !CHECK_MULTISHADOW(target_ptr))
890 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
891 learn_spell(target_ptr, ep_ptr->monspell);
895 if (CHECK_MULTISHADOW(target_ptr))
897 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
901 msg_print(_("霊的エネルギーで精神が攻撃された。", "Your mind is blasted by psionic energy."));
902 if (!target_ptr->resist_conf)
904 (void)set_confused(target_ptr, target_ptr->confused + randint0(4) + 4);
907 if (!target_ptr->resist_chaos && one_in_(3))
909 (void)set_image(target_ptr, target_ptr->image + randint0(250) + 150);
912 target_ptr->csp -= 50;
913 if (target_ptr->csp < 0)
916 target_ptr->csp_frac = 0;
919 target_ptr->redraw |= PR_MANA;
920 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
925 if ((randint0(100 + ep_ptr->rlev / 2) < MAX(5, target_ptr->skill_sav)) && !CHECK_MULTISHADOW(target_ptr))
927 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
928 learn_spell(target_ptr, ep_ptr->monspell);
932 if (!CHECK_MULTISHADOW(target_ptr))
934 msg_print(_("霊的エネルギーで精神が攻撃された。", "Your mind is blasted by psionic energy."));
936 target_ptr->csp -= 100;
937 if (target_ptr->csp < 0)
940 target_ptr->csp_frac = 0;
942 target_ptr->redraw |= PR_MANA;
945 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
946 if (CHECK_MULTISHADOW(target_ptr)) break;
948 if (!target_ptr->resist_blind)
950 (void)set_blind(target_ptr, target_ptr->blind + 8 + randint0(8));
953 if (!target_ptr->resist_conf)
955 (void)set_confused(target_ptr, target_ptr->confused + randint0(4) + 4);
958 if (!target_ptr->free_act)
960 (void)set_paralyzed(target_ptr, target_ptr->paralyzed + randint0(4) + 4);
963 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
965 while (randint0(100 + ep_ptr->rlev / 2) > (MAX(5, target_ptr->skill_sav)))
966 (void)do_dec_stat(target_ptr, A_INT);
967 while (randint0(100 + ep_ptr->rlev / 2) > (MAX(5, target_ptr->skill_sav)))
968 (void)do_dec_stat(target_ptr, A_WIS);
970 if (!target_ptr->resist_chaos)
972 (void)set_image(target_ptr, target_ptr->image + randint0(250) + 150);
979 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !CHECK_MULTISHADOW(target_ptr))
981 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
982 learn_spell(target_ptr, ep_ptr->monspell);
986 if (!CHECK_MULTISHADOW(target_ptr)) curse_equipment(target_ptr, 15, 0);
987 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
993 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !CHECK_MULTISHADOW(target_ptr))
995 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
996 learn_spell(target_ptr, ep_ptr->monspell);
1000 if (!CHECK_MULTISHADOW(target_ptr)) curse_equipment(target_ptr, 25, MIN(ep_ptr->rlev / 2 - 15, 5));
1001 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
1007 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !CHECK_MULTISHADOW(target_ptr))
1009 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
1010 learn_spell(target_ptr, ep_ptr->monspell);
1014 if (!CHECK_MULTISHADOW(target_ptr)) curse_equipment(target_ptr, 33, MIN(ep_ptr->rlev / 2 - 15, 15));
1015 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
1021 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !(ep_ptr->m_ptr->r_idx == MON_KENSHIROU) && !CHECK_MULTISHADOW(target_ptr))
1023 msg_print(_("しかし秘孔を跳ね返した!", "You resist the effects!"));
1024 learn_spell(target_ptr, ep_ptr->monspell);
1028 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
1029 if (!CHECK_MULTISHADOW(target_ptr)) (void)set_cut(target_ptr, target_ptr->cut + damroll(10, 10));
1036 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !CHECK_MULTISHADOW(target_ptr))
1038 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
1039 learn_spell(target_ptr, ep_ptr->monspell);
1043 if (!CHECK_MULTISHADOW(target_ptr))
1045 msg_print(_("あなたは命が薄まっていくように感じた!", "You feel your life fade away!"));
1046 curse_equipment(target_ptr, 40, 20);
1049 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->m_name, ep_ptr->monspell);
1051 if (target_ptr->chp < 1) target_ptr->chp = 1;
1066 * @brief 汎用的なビーム/ボルト/ボール系によるプレイヤーへの効果処理 / Helper function for "project()" below.
1067 * @param who 魔法を発動したモンスター(0ならばプレイヤー、負値ならば自然発生) / Index of "source" monster (zero for "player")
1068 * @param who_name 効果を起こしたモンスターの名前
1069 * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
1070 * @param y 目標Y座標 / Target y location (or location to travel "towards")
1071 * @param x 目標X座標 / Target x location (or location to travel "towards")
1072 * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
1073 * @param effect_type 効果属性 / Type of damage to apply to monsters (and objects)
1075 * @param monspell 効果元のモンスター魔法ID
1076 * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
1078 bool affect_player(MONSTER_IDX who, player_type *target_ptr, concptr who_name, int r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID effect_type, BIT_FLAGS flag, int monspell)
1080 effect_player_type tmp_effect;
1081 effect_player_type *ep_ptr = initialize_effect_player(&tmp_effect, who, dam, effect_type, flag, monspell);
1082 ep_check_result check_result = check_continue_player_effect(target_ptr, ep_ptr, y, x);
1083 if (check_result != EP_CHECK_CONTINUE) return check_result;
1085 if (ep_ptr->dam > 1600) ep_ptr->dam = 1600;
1087 ep_ptr->dam = (ep_ptr->dam + r) / (r + 1);
1088 describe_effect_source(target_ptr, ep_ptr, who_name);
1089 switch_effects_player(target_ptr, ep_ptr);
1091 revenge_store(target_ptr, ep_ptr->get_damage);
1092 if ((target_ptr->tim_eyeeye || hex_spelling(target_ptr, HEX_EYE_FOR_EYE))
1093 && (ep_ptr->get_damage > 0) && !target_ptr->is_dead && (ep_ptr->who > 0))
1095 GAME_TEXT m_name_self[80];
1096 monster_desc(target_ptr, m_name_self, ep_ptr->m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE | MD_OBJECTIVE);
1097 msg_format(_("攻撃が%s自身を傷つけた!", "The attack of %s has wounded %s!"), ep_ptr->m_name, m_name_self);
1098 project(target_ptr, 0, 0, ep_ptr->m_ptr->fy, ep_ptr->m_ptr->fx, ep_ptr->get_damage, GF_MISSILE, PROJECT_KILL, -1);
1099 if (target_ptr->tim_eyeeye) set_tim_eyeeye(target_ptr, target_ptr->tim_eyeeye - 5, TRUE);
1102 if (target_ptr->riding && ep_ptr->dam > 0)
1104 rakubadam_p = (ep_ptr->dam > 200) ? 200 : ep_ptr->dam;
1107 disturb(target_ptr, TRUE, TRUE);
1108 if ((target_ptr->special_defense & NINJA_KAWARIMI) && ep_ptr->dam && ep_ptr->who && (ep_ptr->who != target_ptr->riding))
1110 (void)kawarimi(target_ptr, FALSE);